Прежде всего хочу заметить, что настолько больших возможностей по расширению языка, как в Lisp'ах, никакой другой язык не предоставляет. Но в некоторых языках, в том числе в Python,
можно немного поколдовать с кодом на этапе его разбора.
dumb_translator.pyimport ast
import sys
class DumbLisp(ast.NodeTransformer):
def fix(self, source, result):
ast.copy_location(result, source)
ast.fix_missing_locations(result)
return result
def visit_Expr(self, node):
if isinstance(node.value, ast.Tuple):
t = node.value
if isinstance(t.elts[0], ast.Name):
if t.elts[0].id == 'newif':
_else = [ast.Expr(value=t.elts[3])] if len(t.elts) == 4 else []
_if = ast.If(test=t.elts[1],
body=[ast.Expr(value=t.elts[2])],
orelse=_else)
self.generic_visit(_if)
return self.fix(node, _if)
elif t.elts[0].id == 'define':
assign = ast.Assign(targets=[ast.Name(id=t.elts[1].id, ctx=ast.Store())],
value=t.elts[2])
return self.fix(node, assign)
else:
call = ast.Expr(value=ast.Call(func=t.elts[0], args=t.elts[1:], keywords=[]))
return self.fix(node, call)
return node
with open(sys.argv[1]) as fh:
tree = ast.parse(fh.read())
DumbLisp().visit(tree)
code = compile(tree, filename=sys.argv[1], mode="exec")
exec(code)
test.dl(define, a, 1)
(newif, a == 1, (print, 'Yes'), (print, 'No'))
Запускаем
python dumb_translator.py test.dl
Естественно, пример предельно простой, а потому в качестве s-форм приходится использовать кортежи. Но есть полноценный фронтенд компилятора Python, транслирующий в python-байткод диалект Lisp близкий к Clojure -
Hy.