1
1
mirror of https://github.com/kanaka/mal.git synced 2024-09-11 13:55:55 +03:00

Julia: self-hosting.

- fix meta and swap! functions and add missing tests
- fix eval_ast of hash-maps across all steps
This commit is contained in:
Joel Martin 2015-03-31 22:42:42 -05:00
parent fc15535c69
commit 7e0bb668cf
11 changed files with 42 additions and 17 deletions

View File

@ -82,13 +82,13 @@ ns = {
:conj => nothing,
:meta => (a) -> a.meta,
:meta => (a) -> isa(a,types.MalFunc) ? a.meta : nothing,
symbol("with-meta") => with_meta,
:atom => (a) -> types.Atom(a),
symbol("atom?") => (a) -> isa(a,types.Atom),
:deref => (a) -> a.val,
:reset! => (a,b) -> a.val = b,
:swap! => (a,b,c...) -> a.val = do_apply(b, a.val, c...),
:swap! => (a,b,c...) -> a.val = do_apply(b, a.val, c),
}
end

View File

@ -30,6 +30,8 @@ function pr_str(obj, print_readably=true)
"(fn* $(pr_str(obj.params,true)) $(pr_str(obj.ast,true)))"
elseif typeof(obj) == types.Atom
"(atom $(pr_str(obj.val,true)))"
elseif typeof(obj) == Function
"#<native function: $(string(obj))>"
else
string(obj)
end

View File

@ -16,23 +16,23 @@ function eval_ast(ast, env)
get(env,ast)
elseif isa(ast, Array) || isa(ast, Tuple)
map((x) -> EVAL(x,env), ast)
elseif isa(ast, Dict)
[EVAL(x[1],env) => EVAL(x[2], env) for x=ast]
else
ast
end
end
function EVAL(ast, env)
if !isa(ast, Array)
return eval_ast(ast, env)
end
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)
let_env = Env(env)
for i = 1:2:length(ast[2])
set(let_env, ast[2][i], EVAL(ast[2][i+1], let_env))
set(let_env, ast[2][i], EVAL(ast[2][i+1], let_env))
end
EVAL(ast[3], let_env)
else

View File

@ -17,23 +17,23 @@ function eval_ast(ast, env)
get(env,ast)
elseif isa(ast, Array) || isa(ast, Tuple)
map((x) -> EVAL(x,env), ast)
elseif isa(ast, Dict)
[EVAL(x[1],env) => EVAL(x[2], env) for x=ast]
else
ast
end
end
function EVAL(ast, env)
if !isa(ast, Array)
return eval_ast(ast, env)
end
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)
let_env = Env(env)
for i = 1:2:length(ast[2])
set(let_env, ast[2][i], EVAL(ast[2][i+1], let_env))
set(let_env, ast[2][i], EVAL(ast[2][i+1], let_env))
end
EVAL(ast[3], let_env)
elseif :do == ast[1]

View File

@ -18,6 +18,8 @@ function eval_ast(ast, env)
get(env,ast)
elseif isa(ast, Array) || isa(ast, Tuple)
map((x) -> EVAL(x,env), ast)
elseif isa(ast, Dict)
[EVAL(x[1],env) => EVAL(x[2], env) for x=ast]
else
ast
end
@ -25,17 +27,15 @@ end
function EVAL(ast, env)
while true
if !isa(ast, Array)
return eval_ast(ast, env)
end
if !isa(ast, Array) return eval_ast(ast, env) end
# apply
if :def! == ast[1]
return set(env, ast[2], EVAL(ast[3], env))
elseif symbol("let*") == ast[1]
let_env = Env(env)
let_env = Env(env)
for i = 1:2:length(ast[2])
set(let_env, ast[2][i], EVAL(ast[2][i+1], let_env))
set(let_env, ast[2][i], EVAL(ast[2][i+1], let_env))
end
env = let_env
ast = ast[3]

View File

@ -18,6 +18,8 @@ function eval_ast(ast, env)
get(env,ast)
elseif isa(ast, Array) || isa(ast, Tuple)
map((x) -> EVAL(x,env), ast)
elseif isa(ast, Dict)
[EVAL(x[1],env) => EVAL(x[2], env) for x=ast]
else
ast
end

View File

@ -34,6 +34,8 @@ function eval_ast(ast, env)
get(env,ast)
elseif isa(ast, Array) || isa(ast, Tuple)
map((x) -> EVAL(x,env), ast)
elseif isa(ast, Dict)
[EVAL(x[1],env) => EVAL(x[2], env) for x=ast]
else
ast
end

View File

@ -50,6 +50,8 @@ function eval_ast(ast, env)
get(env,ast)
elseif isa(ast, Array) || isa(ast, Tuple)
map((x) -> EVAL(x,env), ast)
elseif isa(ast, Dict)
[EVAL(x[1],env) => EVAL(x[2], env) for x=ast]
else
ast
end

View File

@ -50,6 +50,8 @@ function eval_ast(ast, env)
get(env,ast)
elseif isa(ast, Array) || isa(ast, Tuple)
map((x) -> EVAL(x,env), ast)
elseif isa(ast, Dict)
[EVAL(x[1],env) => EVAL(x[2], env) for x=ast]
else
ast
end

View File

@ -50,6 +50,8 @@ function eval_ast(ast, env)
get(env,ast)
elseif isa(ast, Array) || isa(ast, Tuple)
map((x) -> EVAL(x,env), ast)
elseif isa(ast, Dict)
[EVAL(x[1],env) => EVAL(x[2], env) for x=ast]
else
ast
end

View File

@ -52,6 +52,11 @@
(meta f-wm2)
;=>{"abc" 1}
;; Meta of native functions should return nil (not fail)
(meta +)
;=>nil
;;
;; Make sure closures and metadata co-exist
(def! gen-plusX (fn* (x) (with-meta (fn* (b) (+ x b)) {"meta" 1})))
@ -119,6 +124,14 @@
(f)
;=>9
;; Testing hash-map evaluation and atoms (i.e. an env)
(def! e (atom {"+" +}))
(swap! e assoc "-" -)
( (get @e "+") 7 8)
;=>15
( (get @e "-") 11 8)
;=>3
;;
;; ------- Optional Functionality --------------