Substack https://aljamal.substack.com/p/homoiconic-python
atom=lambda x:not isinstance(x,list)
eq=lambda x,y:x == y
car=lambda x:x[0]
cdr=lambda x:x[1:]
cons=lambda x,y:[x,y] if atom(y) else [x]+y
append=lambda x,y:x+y
def eval(x):
if atom(x): return x
elif eq(car(x),'quote'): return car(cdr(x))
elif eq(car(x),'atom'): return atom(eval(car(cdr(x))))
elif eq(car(x),'eq'): return eq(eval(car(cdr(x))),
eval(car(cdr(cdr(x)))))
elif eq(car(x),'car'): return car(eval(car(cdr(x))))
elif eq(car(x),'cdr'): return cdr(eval(car(cdr(x))))
elif eq(car(x),'cons'): return cons(eval(car(cdr(x))),
eval(car(cdr(cdr(x)))))
elif eq(car(x),'cond'):
for i in cdr(x):
if eval(car(i)):
return eval(car(cdr(i)))
return []
def e(x):
try:print(eval(x))
except Exception as e:print(e)
e([atom])
e(42)
e(['quote',[10,20]])
e(['atom',1])
e(['atom',['quote',1]])
e(['atom',['quote',[1,2,3]]])
e(['eq',1,1])
e(['eq',1,2])
e(['car',['quote',[1000,20]]])
e(['cdr',['quote',[10,20,1.1]]])
e(['car',['car',['cdr',['cdr',
['cdr',['quote',[1,2,10,[50,100]]]]]]]])
e(['cons',1,['quote',[10,20]]])
e(['cons',['quote',[1,2]],['quote',[10,20]]])
e(['cond',
[['eq', 1, 1], 'true'],
[['atom', ['quote', 2]], 'false'],
['t', 'default']
])
e(['cond',
[['atom', ['quote', 2]], 'cake'],
['t', 'default']
])
e(['cond',
[['atom', ['quote',[1,2]]], 'false'],
['t', 'default']
])
atom=lambda x:not isinstance(x,list)
eq=lambda x,y:x == y
car=lambda x:x[0]
cdr=lambda x:x[1:]
cons=lambda x,y:[x,y] if atom(y) else [x]+y
append=lambda x,y:x+y
#assoc=lambda x,y:(car(y) if eq(car(car(y)),x) else assoc(x,cdr(y))) if y else []
assoc=lambda x,y:car([cdr(i) for i in y if eq(car(i),x)] or [x])
#pairlis=lambda x,y:cons(cons(car(x),car(y)),pairlis(cdr(x),cdr(y))) if x and y else []
pairlis=lambda x,y:[cons(x[i],y[i]) for i in range(len(x))]
def eval(x,y):
if atom(x):return assoc(x,y)
elif atom(car(x)):
if eq(car(x),'quote'):return car(cdr(x))
elif eq(car(x),'atom'):return atom(eval(car(cdr(x)),y))
elif eq(car(x),'eq'):return eq(eval(car(cdr(x)),y),eval(car(cdr(cdr(x))),y))
elif eq(car(x),'car'):return car(eval(car(cdr(x)),y))
elif eq(car(x),'cdr'):return cdr(eval(car(cdr(x)),y))
elif eq(car(x),'cons'):return cons(eval(car(cdr(x)),y),eval(car(cdr(cdr(x))),y))
elif eq(car(x),'cond'):
for i in cdr(x):
if eval(car(i),y):return eval(car(cdr(i)),y)
else:return eval(cons(assoc(car(x),y),[eval(i,y) for i in cdr(x)]),y)
elif eq(car(car(x)),'lambda'):return eval(car(cdr(cdr(car(x)))),
append(pairlis(car(cdr(car(x))),[eval(i,y) for i in cdr(x)]),y))
def e(x):
try:print(eval(x,[]))
except Exception as e:print(e)
e([atom]) # error
e(42)
e(['quote',[10,20]])
e(['atom',1])
e(['atom',['quote',1]])
e(['atom',['quote',[1,2,3]]])
e(['eq',1,1])
e(['eq',1,2])
e(['car',['quote',[1000,20]]])
e(['cdr',['quote',[10,20,1.1]]])
e(['car',['car',['cdr',['cdr',['cdr',['quote',[1,2,10,[50,100]]]]]]]])
e(['cons',1,['quote',[10,20]]])
e(['cons',['quote',[1,2]],['quote',[10,20]]])
e(['cond',
[['eq', 1, 1], 'true'],
[['atom', ['quote', 2]], 'false'],
['t', 'default']
])
e(['cond',
[['atom', ['quote', 2]], 'cake'],
['t', 'default']
])
e(['cond',
[['atom', ['quote',[1,2]]], 'false'],
['t', 'default']
])
e([['lambda', ['x'], ['car', 'x']], ['quote', [1, 2, 3]]])
e([['lambda', ['x'], ['cdr', 'x']], ['quote', [1, 2, 3]]])
e([['lambda', ['x','y'], ['cons', 'x','y']],5,['quote', [1, 2, 3]]])
not in 'cond', but you're right. corrected, thanks.