2 from typing
import Dict
6 from mal_types
import (
9 MalInvalidArgumentException
,
10 MalUnknownSymbolException
,
13 from mal_types
import MalInt
, MalList
, MalFunctionCompiled
, MalVector
, MalHash_map
16 repl_env
.set("+", MalFunctionCompiled(lambda a
: MalInt(a
[0].native() + a
[1].native())))
17 repl_env
.set("-", MalFunctionCompiled(lambda a
: MalInt(a
[0].native() - a
[1].native())))
18 repl_env
.set("*", MalFunctionCompiled(lambda a
: MalInt(a
[0].native() * a
[1].native())))
20 "/", MalFunctionCompiled(lambda a
: MalInt(int(a
[0].native() / a
[1].native())))
24 def READ(x
: str) -> MalExpression
:
28 def eval_ast(ast
: MalExpression
, env
: Env
) -> MalExpression
:
29 if isinstance(ast
, MalSymbol
):
31 if isinstance(ast
, MalList
):
32 return MalList([EVAL(x
, env
) for x
in ast
.native()])
33 if isinstance(ast
, MalVector
):
34 return MalVector([EVAL(x
, env
) for x
in ast
.native()])
35 if isinstance(ast
, MalHash_map
):
36 new_dict
= {} # type: Dict[str, MalExpression]
37 for key
in ast
.native():
38 new_dict
[key
] = EVAL(ast
.native()[key
], env
)
39 return MalHash_map(new_dict
)
44 def EVAL(ast
: MalExpression
, env
: Env
) -> MalExpression
:
45 if not isinstance(ast
, MalList
):
46 return eval_ast(ast
, env
)
47 if len(ast
.native()) == 0:
49 first
= str(ast
.native()[0])
50 rest
= ast
.native()[1:]
52 key
= str(ast
.native()[1])
53 value
= EVAL(ast
.native()[2], env
)
54 return env
.set(key
, value
)
59 assert isinstance(bindings
, MalList
) or isinstance(bindings
, MalVector
)
60 bindings_list
= bindings
.native()
61 assert len(bindings_list
) % 2 == 0
62 for i
in range(0, len(bindings_list
), 2):
63 assert isinstance(bindings_list
[i
], MalSymbol
)
64 assert isinstance(bindings_list
[i
+ 1], MalExpression
)
65 let_env
.set(str(bindings_list
[i
]), EVAL(bindings_list
[i
+ 1], let_env
))
67 return EVAL(expr
, let_env
)
68 evaled_ast
= eval_ast(ast
, env
)
69 f
= evaled_ast
.native()[0]
70 args
= evaled_ast
.native()[1:]
73 except AttributeError:
74 raise MalInvalidArgumentException(f
, "attribute error")
77 def PRINT(x
: MalExpression
) -> str:
81 def rep(x
: str) -> str:
82 return PRINT(EVAL(READ(x
), repl_env
))
85 if __name__
== "__main__":
90 line
= input("user> ")
91 readline
.add_history(line
)
94 except MalUnknownSymbolException
as e
:
95 print("'" + e
.func
+ "' not found")
96 except MalSyntaxException
as e
:
97 print("ERROR: invalid syntax: " + str(e
))