diff options
| author | Joel Martin <github@martintribe.org> | 2014-04-10 20:48:26 -0500 |
|---|---|---|
| committer | Joel Martin <github@martintribe.org> | 2014-04-10 20:48:26 -0500 |
| commit | 136e5690eec17aa90c35e3fccd8ad6100acd9356 (patch) | |
| tree | d7928b0a74ec74cc6d007dc47cce24aec7750e09 | |
| parent | f705f0fce151863091ad77753105f0d15270edec (diff) | |
| download | mal-136e5690eec17aa90c35e3fccd8ad6100acd9356.tar.gz mal-136e5690eec17aa90c35e3fccd8ad6100acd9356.zip | |
Ruby: step2_eval
| -rw-r--r-- | ruby/step2_eval.rb | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/ruby/step2_eval.rb b/ruby/step2_eval.rb new file mode 100644 index 0000000..9cbae24 --- /dev/null +++ b/ruby/step2_eval.rb @@ -0,0 +1,58 @@ +require "readline" +require "types" +require "reader" +require "printer" + +# read +def READ(str) + return read_str(str) +end + +# eval +def eval_ast(ast, env) + return case ast + when Symbol + raise "'" + ast.to_s + "' not found" if not env.key? ast + env[ast] + when List + List.new ast.map{|a| EVAL(a, env)} + when Vector + Vector.new ast.map{|a| EVAL(a, env)} + else + ast + end +end + +def EVAL(ast, env) + if not ast.is_a? List + return eval_ast(ast, env) + end + + # apply list + el = eval_ast(ast, env) + f = el[0] + return f[*el.drop(1)] +end + +# print +def PRINT(exp) + return _pr_str(exp, true) +end + +# repl +repl_env = {} +REP = lambda {|str| PRINT(EVAL(READ(str), repl_env)) } + +repl_env[:+] = lambda {|a,b| a + b} +repl_env[:-] = lambda {|a,b| a - b} +repl_env[:*] = lambda {|a,b| a * b} +repl_env[:/] = lambda {|a,b| a / b} + +while line = Readline.readline("user> ", true) + begin + puts REP[line] + rescue Exception => e + puts "Error: #{e}" + puts "\t#{e.backtrace.join("\n\t")}" + end +end |
