Julia: step3
authorJoel Martin <github@martintribe.org>
Sun, 29 Mar 2015 20:00:27 +0000 (15:00 -0500)
committerJoel Martin <github@martintribe.org>
Wed, 1 Apr 2015 04:04:43 +0000 (23:04 -0500)
julia/env.jl [new file with mode: 0644]
julia/step2_eval.jl
julia/step3_env.jl [new file with mode: 0755]

diff --git a/julia/env.jl b/julia/env.jl
new file mode 100644 (file)
index 0000000..2cc3262
--- /dev/null
@@ -0,0 +1,41 @@
+module env
+
+export Env, set, find, get
+
+type Env
+    outer::Any
+    data::Dict{Symbol,Any}
+end
+
+function Env()
+    Env(nothing, Dict())
+end
+
+function Env(outer)
+    Env(outer, Dict())
+end
+
+function set(env::Env, k::Symbol, v)
+    env.data[k] = v
+end
+
+function find(env::Env, k::Symbol)
+    if haskey(env.data, k)
+        env
+    elseif env.outer != nothing
+        find(env.outer, k)
+    else
+        nothing
+    end
+end
+
+function get(env::Env, k::Symbol)
+    e = find(env, k)
+    if e != nothing
+        e.data[k]
+    else
+        error("'$(string(k))' not found")
+    end
+end
+
+end
index ef08139..467cff2 100755 (executable)
@@ -12,7 +12,7 @@ end
 function eval_ast(ast, env)
     if typeof(ast) == Symbol
         env[ast]
-    elseif isa(ast, Array)
+    elseif isa(ast, Array) || isa(ast, Tuple)
         map((x) -> EVAL(x,env), ast)
     else
         ast
diff --git a/julia/step3_env.jl b/julia/step3_env.jl
new file mode 100755 (executable)
index 0000000..f15cbfe
--- /dev/null
@@ -0,0 +1,79 @@
+#!/usr/bin/env julia
+
+import reader
+import printer
+using env
+
+# READ
+function READ(str)
+    reader.read_str(str)
+end
+
+# EVAL
+function eval_ast(ast, env)
+    if typeof(ast) == Symbol
+        get(env,ast)
+    elseif isa(ast, Array) || isa(ast, Tuple)
+        map((x) -> EVAL(x,env), ast)
+    else
+        ast
+    end
+end
+
+function EVAL(ast, env)
+    if !isa(ast, Array)
+        return eval_ast(ast, env)
+    end
+
+    # apply
+    if     :def! == ast[1]
+        set(env, ast[2], EVAL(ast[3], env))
+    elseif symbol("let*") == ast[1]
+        let_env = Env(env) 
+        for i = 1:2:length(ast[2])
+            set(let_env, ast[2][i], EVAL(ast[2][i+1], let_env))    
+        end
+        EVAL(ast[3], let_env)
+    else
+        el = eval_ast(ast, env)
+        f, args = el[1], el[2:end]
+        f(args...)
+    end
+end
+
+# PRINT
+function PRINT(exp)
+    printer.pr_str(exp)
+end
+
+# REPL
+repl_env = Env(nothing,
+               {:+ => +,
+                :- => -,
+                :* => *,
+                :/ => div})
+function REP(str)
+    return PRINT(EVAL(READ(str), repl_env))
+end
+
+while true
+    print("user> ")
+    flush(STDOUT)
+    line = readline(STDIN)
+    if line == ""
+        break
+    end
+    line = chomp(line)
+    try
+        println(REP(line))
+    catch e
+        if isa(e, ErrorException)
+            println("Error: $(e.msg)")
+        else
+            println("Error: $(string(e))")
+        end
+        bt = catch_backtrace()
+        Base.show_backtrace(STDERR, bt)
+        println()
+    end
+end