3 local table = require('table')
5 local readline
= require('readline')
6 local utils
= require('utils')
7 local types
= require('types')
8 local reader
= require('reader')
9 local printer
= require('printer')
10 local Env
= require('env')
11 local List
, Vector
, HashMap
= types
.List
, types
.Vector
, types
.HashMap
15 return reader
.read_str(str
)
19 function eval_ast(ast
, env
)
20 if types
._symbol_Q(ast
) then
22 elseif types
._list_Q(ast
) then
23 return List
:new(utils
.map(function(x
) return EVAL(x
,env
) end,ast
))
24 elseif types
._vector_Q(ast
) then
25 return Vector
:new(utils
.map(function(x
) return EVAL(x
,env
) end,ast
))
26 elseif types
._hash_map_Q(ast
) then
28 for k
,v
in pairs(ast
) do
29 new_hm
[EVAL(k
, env
)] = EVAL(v
, env
)
31 return HashMap
:new(new_hm
)
37 function EVAL(ast
, env
)
38 --print("EVAL: "..printer._pr_str(ast,true))
39 if not types
._list_Q(ast
) then return eval_ast(ast
, env
) end
41 local a0
,a1
,a2
= ast
[1], ast
[2],ast
[3]
42 local a0sym
= types
._symbol_Q(a0
) and a0
.val
or ""
43 if 'def!' == a0sym
then
44 return env
:set(a1
, EVAL(a2
, env
))
45 elseif 'let*' == a0sym
then
46 local let_env
= Env
:new(env
)
48 let_env
:set(a1
[i
], EVAL(a1
[i
+1], let_env
))
50 return EVAL(a2
, let_env
)
52 local args
= eval_ast(ast
, env
)
53 local f
= table.remove(args
, 1)
54 return f(unpack(args
))
60 return printer
._pr_str(exp, true)
64 local repl_env
= Env
:new()
66 return PRINT(EVAL(READ(str
),repl_env
))
69 repl_env
:set(types
.Symbol
:new('+'), function(a
,b
) return a
+b
end)
70 repl_env
:set(types
.Symbol
:new('-'), function(a
,b
) return a
-b
end)
71 repl_env
:set(types
.Symbol
:new('*'), function(a
,b
) return a
*b
end)
72 repl_env
:set(types
.Symbol
:new('/'), function(a
,b
) return math
.floor(a
/b
) end)
75 line
= readline
.readline("user> ")
76 if not line
then break end
81 if types
._malexception_Q(exc
) then
82 exc
= printer
._pr_str(exc
.val
, true)
84 print("Error: " .. exc
)
85 print(debug
.traceback())