1 set_path
, get_env
("YORICK_MAL_PATH") + ":" + get_path
()
12 func eval_ast
(ast
, env
)
15 if
(type
== MalSymbol
) {
16 return env_get
(env
, ast.val
)
17 } else if
(type
== MalList
) {
19 if
(numberof
(seq
) == 0) return ast
20 res
= array
(pointer
, numberof
(seq
))
21 for
(i
= 1; i
<= numberof
(seq
); ++i
) {
22 e
= EVAL
(*seq
(i
), env
)
23 if
(structof
(e
) == MalError
) return e
26 return MalList
(val
=&res)
27 } else if
(type
== MalVector
) {
29 if
(numberof
(seq
) == 0) return ast
30 res
= array
(pointer
, numberof
(seq
))
31 for
(i
= 1; i
<= numberof
(seq
); ++i
) {
32 e
= EVAL
(*seq
(i
), env
)
33 if
(structof
(e
) == MalError
) return e
36 return MalVector
(val
=&res)
37 } else if
(type
== MalHashmap
) {
39 if
(numberof
(*h.keys
) == 0) return ast
41 for
(i
= 1; i
<= numberof
(*h.keys
); ++i
) {
42 new_key
= EVAL
(hashmap_key_to_obj
((*h.keys
)(i
)), env
)
43 if
(structof
(new_key
) == MalError
) return new_key
44 new_val
= EVAL
(*((*h.vals
)(i
)), env
)
45 if
(structof
(new_val
) == MalError
) return new_val
46 hash_set
, res
, hashmap_obj_to_key
(new_key
), new_val
48 return MalHashmap
(val
=&res)
55 if
(structof
(ast
) == MalError
) return ast
56 if
(structof
(ast
) != MalList
) return eval_ast
(ast
, env
)
58 if
(numberof
(lst
) == 0) return ast
61 new_value
= EVAL
(*lst
(3), env
)
62 if
(structof
(new_value
) == MalError
) return new_value
63 return env_set
(env
, lst
(2)->val
, new_value
)
64 } else if
(a1
== "let*") {
65 let_env
= env_new
(&env)
66 args_lst
= *(lst
(2)->val
)
67 for
(i
= 1; i
<= numberof
(args_lst
); i
+= 2) {
68 var_name
= args_lst
(i
)->val
69 var_value
= EVAL
(*args_lst
(i
+ 1), let_env
)
70 if
(structof
(var_value
) == MalError
) return var_value
71 env_set
, let_env
, var_name
, var_value
76 } else if
(a1
== "do") {
77 for
(i
= 2; i
< numberof
(lst
); ++i
) {
78 ret
= EVAL
(*lst
(i
), env
)
79 if
(structof
(ret
) == MalError
) return ret
81 ast
= *lst
(numberof
(lst
))
83 } else if
(a1
== "if") {
84 cond_val
= EVAL
(*lst
(2), env
)
85 if
(structof
(cond_val
) == MalError
) return cond_val
86 if
((structof
(cond_val
) == MalNil
) ||
(structof
(cond_val
) == MalFalse
)) {
87 if
(numberof
(lst
) > 3) {
96 } else if
(a1
== "fn*") {
97 return MalFunction
(env
=&env, binds=lst(2)->val, ast=lst(3))
99 el
= eval_ast
(ast
, env
)
100 if
(structof
(el
) == MalError
) return el
102 if
(structof
(*seq
(1)) == MalNativeFunction
) {
103 args
= (numberof
(seq
) > 1) ? seq
(2:) : []
104 return call_core_fn
(seq
(1)->val
, args
)
105 } else if
(structof
(*seq
(1)) == MalFunction
) {
107 exprs
= numberof
(seq
) > 1 ? seq
(2:) : []
108 fn_env
= env_new
(fn.env
, binds
=*fn.binds
, exprs
=exprs
)
113 return MalError
(message
="Unknown function type")
121 if
(structof
(exp
) == MalError
) return exp
122 return pr_str
(exp
, 1)
127 return EVAL
(READ(str
), env
)
132 return PRINT
(EVAL
(READ(str
), env
))
137 repl_env
= env_new
(pointer
(0))
139 // core.i
: defined using Yorick
140 core_symbols
= h_keys
(core_ns
)
141 for
(i
= 1; i
<= numberof
(core_symbols
); ++i
) {
142 env_set
, repl_env
, core_symbols
(i
), MalNativeFunction
(val
=core_symbols
(i
))
145 // core.mal
: defined using the language itself
146 RE
, "(def! not (fn* (a) (if a false true)))", repl_env
148 stdin_file
= open
("/dev/stdin", "r")
150 write
, format
="%s", "user> "
151 line
= rdline
(stdin_file
, prompt
="")
153 if
(strlen
(line
) > 0) {
154 result
= REP
(line
, repl_env
)
155 if
(structof
(result
) == MalError
) write
, format
="Error: %s\n", result.message
156 else write
, format
="%s\n", result