8 return reader_read_str
(str
)
11 function eval_ast
(ast
, env
, i
, idx
, len
, new_idx
, ret
)
15 ret = env_get(env, ast)
22 len = types_heap[idx]["len"]
23 new_idx = types_allocate()
24 for (i = 0; i < len; ++i) {
25 ret = EVAL(types_addref(types_heap[idx][i]), env)
27 types_heap[new_idx]["len"] = i
28 types_release(substr(ast, 1, 1) new_idx)
31 types_heap[new_idx][i] = ret
33 types_heap[new_idx]["len"] = len
34 return substr(ast, 1, 1) new_idx
37 new_idx = types_allocate()
38 for (i in types_heap[idx]) {
40 ret = EVAL(types_addref(types_heap[idx][i]), env)
42 types_release("{" new_idx)
45 types_heap[new_idx][i] = ret
54 function EVAL_def(ast, env, idx, sym, ret, len)
57 if (types_heap[idx]["len"] != 3) {
58 len = types_heap[idx]["len"]
61 return "!\"Invalid argument length for 'def!
'. Expects exactly 2 arguments, supplied" (len - 1) "."
63 sym = types_heap[idx][1]
67 return "!\"Incompatible type for argument 1 of 'def!'. Expects symbol, supplied " types_typename
(sym
) "."
69 ret = EVAL
(types_addref
(types_heap
[idx
][2]), env
)
71 env_set
(env
, sym
, ret
)
79 function EVAL_let
(ast
, env
, idx
, params
, params_idx
, params_len
, new_env
, i
, sym
, ret
, body
, len
)
82 if (types_heap
[idx
]["len"] != 3) {
83 len = types_heap
[idx
]["len"]
86 return "!\"Invalid argument length for 'let*'. Expects exactly 2 arguments, supplied " (len
- 1) "."
88 params = types_heap
[idx
][1]
89 if (params !~
/^
[([]/) {
92 return "!\"Incompatible type for argument 1 of 'let*'. Expects list or vector, supplied " types_typename
(params
) "."
94 params_idx =
substr(params
, 2)
95 params_len = types_heap
[params_idx
]["len"]
96 if (params_len %
2 != 0) {
99 return "!\"Invalid elements count for argument 1 of 'let*'. Expects even number of elements, supplied " params_len
"."
101 new_env = env_new
(env
)
103 for (i =
0; i
< params_len
; i
+=
2) {
104 sym = types_heap
[params_idx
][i
]
108 return "!\"Incompatible type for odd element of argument 1 of 'let
*'. Expects symbol, supplied " types_typename(sym) "."
110 ret = EVAL(types_addref(types_heap[params_idx][i + 1]), new_env)
116 env_set(new_env, sym, ret)
118 types_addref(body = types_heap[idx][2])
120 ret = EVAL(body, new_env)
125 function EVAL(ast, env, new_ast, ret, idx, f, f_idx)
129 ret = eval_ast(ast, env)
135 if (types_heap[idx]["len"] == 0) {
139 switch (types_heap[idx][0]) {
141 return EVAL_def(ast, env)
143 return EVAL_let(ast, env)
145 new_ast = eval_ast(ast, env)
148 if (new_ast ~ /^!/) {
151 idx = substr(new_ast, 2)
152 f = types_heap[idx][0]
156 types_release(new_ast)
159 types_release(new_ast)
160 return "!\"First element of list must be function, supplied " types_typename(f) "."
165 function PRINT(expr, str)
167 str = printer_pr_str(expr, 1)
172 function rep(str, ast, expr)
178 expr = EVAL(ast, repl_env)
185 function add(idx, lhs, rhs)
187 if (types_heap[idx]["len"] != 3) {
188 return "!\"Invalid argument length for builtin function '+'. Expects exactly 2 arguments, supplied " (types_heap[idx]["len"] - 1) "."
190 lhs = types_heap[idx][1]
192 return "!\"Incompatible type for argument 1 of builtin function '+'. Expects number, supplied " types_typename(lhs) "."
194 rhs = types_heap[idx][2]
196 return "!\"Incompatible type for argument 2 of builtin function '+'. Expects number, supplied " types_typename(rhs) "."
198 return "+" (substr(lhs, 2) + substr(rhs, 2))
201 function subtract(idx, lhs, rhs)
203 if (types_heap[idx]["len"] != 3) {
204 return "!\"Invalid argument length for builtin function '-'. Expects exactly 2 arguments, supplied " (types_heap[idx]["len"] - 1) "."
206 lhs = types_heap[idx][1]
208 return "!\"Incompatible type for argument 1 of builtin function '-'. Expects number, supplied " types_typename(lhs) "."
210 rhs = types_heap[idx][2]
212 return "!\"Incompatible type for argument 2 of builtin function '-'. Expects number, supplied " types_typename(rhs) "."
214 return "+" (substr(lhs, 2) - substr(rhs, 2))
217 function multiply(idx, lhs, rhs)
219 if (types_heap[idx]["len"] != 3) {
220 return "!\"Invalid argument length for builtin function '*'. Expects exactly 2 arguments, supplied " (types_heap[idx]["len"] - 1) "."
222 lhs = types_heap[idx][1]
224 return "!\"Incompatible type for argument 1 of builtin function '*'. Expects number, supplied " types_typename(lhs) "."
226 rhs = types_heap[idx][2]
228 return "!\"Incompatible type for argument 2 of builtin function '*'. Expects number, supplied " types_typename(rhs) "."
230 return "+" (substr(lhs, 2) * substr(rhs, 2))
233 function divide(idx, lhs, rhs)
235 if (types_heap[idx]["len"] != 3) {
236 return "!\"Invalid argument length for builtin function '/'. Expects exactly 2 arguments, supplied " (types_heap[idx]["len"] - 1) "."
238 lhs = types_heap[idx][1]
240 return "!\"Incompatible type for argument 1 of builtin function '/'. Expects number, supplied " types_typename(lhs) "."
242 rhs = types_heap[idx][2]
244 return "!\"Incompatible type for argument 2 of builtin function '/'. Expects number, supplied " types_typename(rhs) "."
246 return "+" int(substr(lhs, 2) / substr(rhs, 2))
249 function main(str, ret)
252 env_set(repl_env, "'+", "&add
")
253 env_set(repl_env, "'-", "&subtract")
254 env_set(repl_env, "'*", "&multiply
")
255 env_set(repl_env, "'/", "÷")
259 if (getline str <= 0) {
264 print "ERROR: " printer_pr_str(substr(ret, 2))