2 from typing
import Dict
7 from mal_types
import (
10 MalInvalidArgumentException
,
11 MalUnknownSymbolException
,
14 from mal_types
import (
25 repl_env
.set(key
, core
.ns
[key
])
28 def READ(x
: str) -> MalExpression
:
32 def eval_ast(ast
: MalExpression
, env
: Env
) -> MalExpression
:
33 if isinstance(ast
, MalSymbol
):
35 if isinstance(ast
, MalList
):
36 return MalList([EVAL(x
, env
) for x
in ast
.native()])
37 if isinstance(ast
, MalVector
):
38 return MalVector([EVAL(x
, env
) for x
in ast
.native()])
39 if isinstance(ast
, MalHash_map
):
40 new_dict
= {} # type: Dict[str, MalExpression]
41 for key
in ast
.native():
42 new_dict
[key
] = EVAL(ast
.native()[key
], env
)
43 return MalHash_map(new_dict
)
47 def EVAL(ast
: MalExpression
, env
: Env
) -> MalExpression
:
48 # print("EVAL: " + str(ast))
49 if not isinstance(ast
, MalList
):
50 return eval_ast(ast
, env
)
51 if len(ast
.native()) == 0:
53 first
= str(ast
.native()[0])
54 rest
= ast
.native()[1:]
56 key
= str(ast
.native()[1])
57 value
= EVAL(ast
.native()[2], env
)
58 return env
.set(key
, value
)
63 assert isinstance(bindings
, MalList
) or isinstance(bindings
, MalVector
)
64 bindings_list
= bindings
.native()
65 assert len(bindings_list
) % 2 == 0
66 for i
in range(0, len(bindings_list
), 2):
67 assert isinstance(bindings_list
[i
], MalSymbol
)
68 assert isinstance(bindings_list
[i
+ 1], MalExpression
)
69 let_env
.set(str(bindings_list
[i
]), EVAL(bindings_list
[i
+ 1], let_env
))
71 return EVAL(expr
, let_env
)
73 for x
in range(0, len(rest
) - 1):
75 return EVAL(rest
[len(rest
) - 1], env
)
77 condition
= EVAL(rest
[0], env
)
79 if isinstance(condition
, MalNil
) or (
80 isinstance(condition
, MalBoolean
) and condition
.native() is False
83 return EVAL(rest
[2], env
)
87 return EVAL(rest
[1], env
)
91 func_env
= Env(outer
=env
, binds
=rest
[0].native(), exprs
=x
)
92 return EVAL(rest
[1], func_env
)
94 return MalFunctionCompiled(func_body
)
96 evaled_ast
= eval_ast(ast
, env
)
97 f
= evaled_ast
.native()[0]
98 args
= evaled_ast
.native()[1:]
101 except AttributeError:
102 raise MalInvalidArgumentException(f
, "attribute error")
105 def PRINT(x
: MalExpression
) -> str:
109 def rep(x
: str) -> str:
110 return PRINT(EVAL(READ(x
), repl_env
))
113 if __name__
== "__main__":
118 line
= input("user> ")
119 readline
.add_history(line
)
122 except MalUnknownSymbolException
as e
:
123 print("'" + e
.func
+ "' not found")
124 except MalSyntaxException
as e
:
125 print("ERROR: invalid syntax: " + str(e
))