aboutsummaryrefslogtreecommitdiff
path: root/lua/step2_eval.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua/step2_eval.lua')
-rwxr-xr-xlua/step2_eval.lua79
1 files changed, 79 insertions, 0 deletions
diff --git a/lua/step2_eval.lua b/lua/step2_eval.lua
new file mode 100755
index 0000000..22ac8cf
--- /dev/null
+++ b/lua/step2_eval.lua
@@ -0,0 +1,79 @@
+#!/usr/bin/env lua
+
+local table = require('table')
+
+local readline = require('readline')
+local utils = require('utils')
+local types = require('types')
+local reader = require('reader')
+local printer = require('printer')
+local List, Vector, HashMap = types.List, types.Vector, types.HashMap
+
+-- read
+function READ(str)
+ return reader.read_str(str)
+end
+
+-- eval
+function eval_ast(ast, env)
+ if types._symbol_Q(ast) then
+ if env[ast.val] == nil then
+ types.throw("'"..ast.val.."' not found")
+ end
+ return env[ast.val]
+ elseif types._list_Q(ast) then
+ return List:new(utils.map(function(x) return EVAL(x,env) end,ast))
+ elseif types._vector_Q(ast) then
+ return Vector:new(utils.map(function(x) return EVAL(x,env) end,ast))
+ elseif types._hash_map_Q(ast) then
+ local new_hm = {}
+ for k,v in pairs(ast) do
+ new_hm[EVAL(k, env)] = EVAL(v, env)
+ end
+ return HashMap:new(new_hm)
+ else
+ return ast
+ end
+end
+
+function EVAL(ast, env)
+ --print("EVAL: "..printer._pr_str(ast,true))
+ if not types._list_Q(ast) then return eval_ast(ast, env) end
+ local args = eval_ast(ast, env)
+ local f = table.remove(args, 1)
+ return f(unpack(args))
+end
+
+-- print
+function PRINT(exp)
+ return printer._pr_str(exp, true)
+end
+
+-- repl
+local repl_env = {['+'] = function(a,b) return a+b end,
+ ['-'] = function(a,b) return a-b end,
+ ['*'] = function(a,b) return a*b end,
+ ['/'] = function(a,b) return math.floor(a/b) end}
+function rep(str)
+ return PRINT(EVAL(READ(str),repl_env))
+end
+
+if #arg > 0 and arg[1] == "--raw" then
+ readline.raw = true
+end
+
+while true do
+ line = readline.readline("user> ")
+ if not line then break end
+ xpcall(function()
+ print(rep(line))
+ end, function(exc)
+ if exc then
+ if types._malexception_Q(exc) then
+ exc = printer._pr_str(exc.val, true)
+ end
+ print("Error: " .. exc)
+ print(debug.traceback())
+ end
+ end)
+end