4 #include
"readline.rexx"
6 #include
"printer.rexx"
9 read: procedure expose values
. err
/* read(str) */
10 return read_str
(arg(1))
12 eval_ast: procedure expose values
. env
. err
/* eval_ast(ast) */
17 when type
== "symb" then do
19 if env
.varname
== "" then do
20 err
= "'" || varname
|| "' not found"
25 when type
== "list" then do
28 element
= eval
(word(val
, i
))
29 if element
== "ERR" then return "ERR"
31 res
= res
|| " " || element
37 when type
== "vect" then do
40 element
= eval
(word(val
, i
))
41 if element
== "ERR" then return "ERR"
43 res
= res
|| " " || element
47 return new_vector
(res
)
49 when type
== "hash" then do
52 element
= eval
(word(val
, i
))
53 if element
== "ERR" then return "ERR"
55 res
= res
|| " " || element
59 return new_hashmap
(res
)
65 eval: procedure expose values
. env
. err
/* eval(ast) */
67 if \list?
(ast
) then return eval_ast
(ast
)
69 if words(astval
) == 0 then return ast
70 lst_obj
= eval_ast
(ast
)
71 if lst_obj
== "ERR" then return "ERR"
72 lst
= obj_val
(lst_obj
)
74 call_args
= subword(lst
, 2)
76 do i
=1 to words(call_args
)
77 element
= '"' || word(call_args
, i
) || '"'
79 call_list
= call_list
|| ', ' || element
84 interpret "res = " || f
|| "(" || call_list
|| ")"
87 print: procedure expose values
. /* print(ast) */
88 return pr_str
(arg(1), 1)
90 rep: procedure expose values
. env
. err
/* rep(str) */
92 if ast
== "ERR" then return "ERR"
94 if exp
== "ERR" then return "ERR"
97 mal_add: procedure expose values
. /* mal_add(a, b) */
98 return new_number
(obj_val
(arg(1)) + obj_val
(arg(2)))
100 mal_sub: procedure expose values
. /* mal_sub(a, b) */
101 return new_number
(obj_val
(arg(1)) - obj_val
(arg(2)))
103 mal_mul: procedure expose values
. /* mal_mul(a, b) */
104 return new_number
(obj_val
(arg(1)) * obj_val
(arg(2)))
106 mal_div: procedure expose values
. /* mal_div(a, b) */
107 return new_number
(obj_val
(arg(1)) / obj_val
(arg(2)))
113 key
= "+" ; env
.key
= "mal_add"
114 key
= "-" ; env
.key
= "mal_sub"
115 key
= "*" ; env
.key
= "mal_mul"
116 key
= "/" ; env
.key
= "mal_div"
118 do while lines() > 0 /* 1 == 1 */
119 input_line
= readline
('user> ')
120 if length(input_line
) > 0 then do
121 res
= rep
(input_line
)
123 call lineout , "Error: " || err