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:
parent
fc15535c69
commit
7e0bb668cf
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 --------------
|
||||
|
Loading…
Reference in New Issue
Block a user