- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
首先:是的,我对 Norvig 的 lispy
进行了非常的研究。第二:我重用了他的部分代码。
关于我的代码和我的问题。我正在用 Python 编写一个非常不惯用的 lisp 解释器,我很好奇如何编写嵌套函数定义(例如 (define square (lambda (x) (* x x)))
然后 (define SoS (lambda (x y) (+ (square x) (square y))))
) 目前这不起作用。我有点卡住了。我能做什么?
编辑:如有任何关于我的编码风格的提示或我可以做出的改进,我们将不胜感激。谢谢!
"""
FIX NESTED DEFINITIONS!
(def square (lambda (x) (* x x)))
(def SoS (lambda x y) (+ (square x) (square y)))
DOES NOT WORK!
"""
#!/usr/bin/python
import readline, sys, shlex
userFuncs = {}
userVars = {}
stdOps = "% * / - + set!".split()
def lispify(nested_lists):
return str(nested_lists).replace('[','(').replace(']',')').replace(', ',' ').replace("'",'')
def mul_arr(array):
tot = 1
for i in array: tot *= i
return tot
def div_arr(array):
tot = array[0]
for i in array[1:]: tot /= i
return tot
def sub_arr(array):
print array
if len(array) > 1: tot = array[0]
else: tot = 0-array[0]
for i in array[1:]: tot -= i
return tot
def atom(tok):
try: return int(tok)
except:
try: return float(tok)
except: return str(tok)
def pre_in(read):
tempOp = read[0]
body = read[1:]
expr = []
for i in range(len(body)-1):
if not isinstance(body[i], list) and body[i] != " ":
expr.append(str(body[i]))
expr.append(tempOp)
else:
expr.append(str(pre_in(body[i])))
expr.append(tempOp)
try:
if not isinstance(body[-1], list): expr.append(str(body[-1]))
else: expr.append(str(pre_in(body[-1])))
except: pass
if expr != None: return "("+' '.join(expr)+")"
def tok(s):
try: return shlex.split(s.replace('(',' ( ').replace(')',' ) '))
except: return s.replace('(',' ( ').replace(')',' ) ').split()
def read_from(toks):
if len(toks) == 0: raise SyntaxError('unexpected EOF')
tok = toks.pop(0)
if tok == "'":
l = []
toks.pop(0)
while toks[0] != ")": l.append(read_from(toks))
toks.pop(0)
return lispify(l)
if tok == '(':
l = []
while toks[0] != ')': l.append(read_from(toks))
toks.pop(0)
return l
elif tok == ')': raise SyntaxError('unexpected \')\'')
else: return atom(tok)
def total_eval(read):
if isinstance(read, int):
return read
elif isinstance(read, str):
if read not in stdOps:
if read in userVars:
return atom(userVars[read])
else:
return str(atom(read))
elif isinstance(read, list):
if read[0] in userFuncs:
print read[0]+" = "+userFuncs[read[0]]
exec(read[0]+" = "+userFuncs[read[0]])
return eval(read[0]+str(tuple(read[1:])))
elif read[0] == "+":
return sum([float(total_eval(i)) for i in read[1:]])
elif read[0] == "*":
return mul_arr([float(total_eval(i)) for i in read[1:]])
elif read[0] == "/":
return div_arr([float(total_eval(i)) for i in read[1:]])
elif read[0] == "-":
return sub_arr([float(total_eval(i)) for i in read[1:]])
elif read[0] == "set!" or read[0] == "setf":
userVars[read[1]] = total_eval(read[2])
return "ok"
elif read[0] == "lambda":
tempvars = ','.join(i.replace(',','') for i in read[1])
expr = read[2]
return "lambda "+str(tempvars)+": "+pre_in(expr)
elif read[0] == "def" or read[0] == "define" or read[0] == "defun":
funcName = read[1]
funcBody = read[2]
userFuncs[funcName] = total_eval(funcBody)
return "ok"
elif read[0] == "cons":
body = read[1:]
arr = body[0]
to_push = body[1]
if not isinstance(arr, list):
arr = [arr]
for i in to_push:
arr.append(i)
return lispify(arr)
elif read[0] == "append":
body = read[1:]
main = body[0]
tail = body[1:]
for i in tail:
if i != []:
main.append(i)
#print main
return lispify(main)
elif read[0] == "list":
return lispify(str([total_eval(read[1:][i]) for i in range(len(read[1:]))]))
elif read[0] == "\'" or read[0] == "quote":
return lispify(read[1:][0])
elif read[0] == "print":
return total_eval(read[1:][0])
elif not isinstance(read[0], list):
if read[0] in userFuncs:
args = read[1:]
exec(read[0]+" = "+userFuncs[read[0]])
return eval(read[0]+str(tuple([float(i) for i in args])))
else:
if read[0][0] == "lambda":
tempvars = ','.join(i.replace(',','') for i in read[0][1])
expr = read[0][2]
exec("temp = lambda "+str(tempvars)+": "+str(pre_in(expr)))
args = read[1:] if len(read[1:]) > 1 else read[1]
if isinstance(args, list): return eval("temp"+str(tuple([total_eval(i) for i in args])))
else: return eval("temp("+str(float(args))+")")
"""
while 1:
try:
a = raw_input("lisp> ")
try:
print tok(a)
print read_from(tok(a))
print total_eval(read_from(tok(a))),"\n"
except:
errorMsg = str(sys.exc_info()[1]).split()
if errorMsg[0] == "list":
print "ParseError: mismatched parentheses\n"
else:
print ' '.join(errorMsg)
print
except (EOFError, KeyboardInterrupt):
print "\nbye!"
break
"""
while 1:
a = raw_input("lisp> ")
#print tok(a)
#print read_from(tok(a))
print total_eval(read_from(tok(a)))
print
#"""
最佳答案
看看 pre_in
的输出:
>>> pre_in(read_from(tok("(+ (square x) (square y))")))
'((x) + (y))'
应该是 '(square(x) + square(y))'
。
(顺便说一句,您的示例代码包含语法错误。SoS
应定义为 (lambda (x y) (+ (square x) (square y)))
.)
关于python - 在 Python 中实现 lisp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6502795/
你们能帮帮我吗,这是我们的讲师给我们的教程问题,无论我们尝试了多少,我们实际上似乎都无法破解它。请帮忙 ; perform some type/error checking, ; then ca
在 Common Lisp 中编写、编译和测试一个函数,该函数接受一个列表并计算列表中正整数的总数。必须编译然后执行包含函数的 .lisp 文件。在编译该文件后开始传递它,列出要生成的结果的结果,从而
我是 Lisp 初学者,我很难理解为什么下面的代码会给我一个错误。 (dolist (elem '(mapcar mapcon)) (when (fboundp `
我听说 Lisp 可以让你重新定义语言本身,我也试图研究它,但没有任何地方明确的解释。有人有一个简单的例子吗? 最佳答案 Lisp 用户将 Lisp 称为 可编程编程语言 .用于符号计算 - 用符号计
Closed. This question is off-topic. It is not currently accepting answers. Learn more。 想改进这个问题吗Updat
这些是 cons 参数的不同组合的输出。我刚开始学习 lisp。有人可以帮我理解这些吗? Break 80 [81]> (CONS '(A) 'B) ((A) . B) Break 80 [81]>
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
我想问一下为什么这个功能不起作用... (defun nenum(ls) (cond ((null ls) nil) ((listp car(ls)) (nenum (rest ls)
如果我有一个原子,例如“a4”,我需要能够将 1 添加到“4”部分以使其成为 a5,但是因为它被认为是一个字符串,所以这是不可能的,所以如果我可以拆分 (a4 ) 到 ((a)(4)) 中,然后我可以
我有一个关于动态构建函数(或类似的东西)的问题。在 Java 中,我可以通过编程将一些 Source 写入字符串,编译该字符串并像函数一样执行它多次。 假设我有一些遗传算法来创建最佳代码以获取 n 个
我是 Common Lisp 的新手,正在学习教程,但无法全神贯注 (equal '(reverse (a b)) '(b a))) 返回零。 非常感谢您的协助。 M. 最佳答案 在 lisp 中引
我有一个使用列表表示的树。例如: (1 ((2 (3)) (3 (2)))) (2 ((1 (3)) (3 (1)))) (3 ((1 (2)) (2 (1)))))` 现在我需要在维护层次结构树的同
在此站点:http://www.gigamonkeys.com/book/practical-a-simple-database.html有如下列出的用户入口函数: (defun prompt-rea
我对 lisp 比较陌生,对在以下上下文中使用嵌套列表的最佳方法很好奇: 所以,我有以下功能: (defun get-p0 (points) (loop for (label x y) in
我正在为 CLOS 类编写一个函数,该函数反转所述类对象的列表元素。 我有一个返回反向列表的方法,但如何让它将对象的列表设置为该列表?我可以在存储列表的函数中有一个实例变量,然后将元素设置为那个吗?或
我知道,严格来说,没有编译语言或解释语言这回事。 但是,一般来说,LISP 是用来编写 Python、bash 脚本、批处理脚本之类的脚本的吗? 还是像 C++、JAVA 和 C# 这样的通用编程语言
在此站点 http://jatha.sourceforge.net/快速函数的示例是通过递归。是不是递归通常比 Lisp 中的迭代更快并且性能更好? 编辑:Lisp 是否比其他语言更优化递归? 最佳答
另一个新手(常见)LISP 问题: 基本上在大多数编程语言中,函数都有一种方法接收对变量的引用而不仅仅是值,即通过引用传递而不是通过值传递。比方说,为了简单起见,我想编写一个 LISP 函数来接收一个
这个问题在这里已经有了答案: How do I find the index of an element in a list in Racket? (3 个答案) 关闭 9 年前。 如果我有这样的列
我在为这个程序生成正确的输出时遇到了一些问题。我的输出几乎是正确的,但缺少一些步骤。我的代码如下: (defun kt (x y m n) ;set the
我是一名优秀的程序员,十分优秀!