3 import mal_types
as types
4 from mal_types
import (MalSym
, MalInt
, MalStr
,
6 MalList
, _list
, MalVector
, MalHashMap
, MalFunc
)
12 return reader
.read_str(str)
15 def eval_ast(ast
, env
):
16 if types
._symbol
_Q
(ast
):
17 assert isinstance(ast
, MalSym
)
19 elif types
._list
_Q
(ast
):
22 res
.append(EVAL(a
, env
))
24 elif types
._vector
_Q
(ast
):
27 res
.append(EVAL(a
, env
))
29 elif types
._hash
_map
_Q
(ast
):
31 for k
in ast
.dct
.keys():
32 new_dct
[k
] = EVAL(ast
.dct
[k
], env
)
33 return MalHashMap(new_dct
)
35 return ast
# primitive value, return unchanged
38 #print("EVAL %s" % printer._pr_str(ast))
39 if not types
._list
_Q
(ast
):
40 return eval_ast(ast
, env
)
43 if len(ast
) == 0: return ast
45 if not isinstance(a0
, MalSym
):
46 raise Exception("attempt to apply on non-symbol")
48 if u
"def!" == a0
.value
:
49 a1
, a2
= ast
[1], ast
[2]
51 return env
.set(a1
, res
)
52 elif u
"let*" == a0
.value
:
53 a1
, a2
= ast
[1], ast
[2]
55 for i
in range(0, len(a1
), 2):
56 let_env
.set(a1
[i
], EVAL(a1
[i
+1], let_env
))
57 return EVAL(a2
, let_env
)
59 el
= eval_ast(ast
, env
)
61 if isinstance(f
, MalFunc
):
62 return f
.apply(el
.values
[1:])
64 raise Exception("%s is not callable" % f
)
68 return printer
._pr
_str
(exp
)
73 return PRINT(EVAL(READ(str), env
))
76 a
, b
= args
[0], args
[1]
77 assert isinstance(a
, MalInt
)
78 assert isinstance(b
, MalInt
)
79 return MalInt(a
.value
+b
.value
)
81 a
, b
= args
[0], args
[1]
82 assert isinstance(a
, MalInt
)
83 assert isinstance(b
, MalInt
)
84 return MalInt(a
.value
-b
.value
)
86 a
, b
= args
[0], args
[1]
87 assert isinstance(a
, MalInt
)
88 assert isinstance(b
, MalInt
)
89 return MalInt(a
.value
*b
.value
)
91 a
, b
= args
[0], args
[1]
92 assert isinstance(a
, MalInt
)
93 assert isinstance(b
, MalInt
)
94 return MalInt(int(a
.value
/b
.value
))
95 repl_env
.set(_symbol(u
'+'), MalFunc(plus
))
96 repl_env
.set(_symbol(u
'-'), MalFunc(minus
))
97 repl_env
.set(_symbol(u
'*'), MalFunc(multiply
))
98 repl_env
.set(_symbol(u
'/'), MalFunc(divide
))
100 def entry_point(argv
):
103 line
= mal_readline
.readline("user> ")
104 if line
== "": continue
105 print(REP(line
, repl_env
))
106 except EOFError as e
:
110 except types
.MalException
as e
:
111 print(u
"Error: %s" % printer
._pr
_str
(e
.object, False))
112 except Exception as e
:
113 print("Error: %s" % e
)
114 #print("".join(traceback.format_exception(*sys.exc_info())))
117 # _____ Define and setup target ___
121 # Just run entry_point if not RPython compilation
123 if not sys
.argv
[0].endswith('rpython'):
124 entry_point(sys
.argv
)