Skip to content

Instantly share code, notes, and snippets.

@seki
Last active February 2, 2018 03:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seki/acd51a67067721f265e475aad96418c4 to your computer and use it in GitHub Desktop.
Save seki/acd51a67067721f265e475aad96418c4 to your computer and use it in GitHub Desktop.
minruby.succ
require "minruby"
def mark_tail(tree, genv)
case tree && tree[0]
when "func_call"
mhd = genv[tree[1]]
if mhd == nil || mhd[0] == "user_defined"
tree[0] = "tail"
end
when "stmts"
mark_tail(tree[-1], genv)
when "if"
mark_tail(tree[2], genv)
mark_tail(tree[3], genv)
end
end
def evaluate(tree, genv, lenv)
case tree[0]
when "lit"
tree[1]
when "+"
evaluate(tree[1], genv, lenv) + evaluate(tree[2], genv, lenv)
when "-"
evaluate(tree[1], genv, lenv) - evaluate(tree[2], genv, lenv)
when "*"
evaluate(tree[1], genv, lenv) * evaluate(tree[2], genv, lenv)
when "/"
evaluate(tree[1], genv, lenv) / evaluate(tree[2], genv, lenv)
when "%"
evaluate(tree[1], genv, lenv) % evaluate(tree[2], genv, lenv)
when "<"
evaluate(tree[1], genv, lenv) < evaluate(tree[2], genv, lenv)
when "<="
evaluate(tree[1], genv, lenv) <= evaluate(tree[2], genv, lenv)
when "=="
evaluate(tree[1], genv, lenv) == evaluate(tree[2], genv, lenv)
when "!="
evaluate(tree[1], genv, lenv) != evaluate(tree[2], genv, lenv)
when ">="
evaluate(tree[1], genv, lenv) >= evaluate(tree[2], genv, lenv)
when ">"
evaluate(tree[1], genv, lenv) > evaluate(tree[2], genv, lenv)
when "||"
evaluate(tree[1], genv, lenv) || evaluate(tree[2], genv, lenv)
when "&&"
evaluate(tree[1], genv, lenv) && evaluate(tree[2], genv, lenv)
when "stmts"
i = 1
last = nil
while tree[i]
last = evaluate(tree[i], genv, lenv)
i = i + 1
end
last
when "var_assign"
lenv[tree[1]] = evaluate(tree[2], genv, lenv)
when "var_ref"
lenv[tree[1]]
when "if"
if evaluate(tree[1], genv, lenv)
evaluate(tree[2], genv, lenv)
else
if tree[3]
evaluate(tree[3], genv, lenv)
end
end
when "while"
while evaluate(tree[1], genv, lenv)
evaluate(tree[2], genv, lenv)
end
when "tail"
mhd = genv[tree[1]]
new_lenv = {}
params = mhd[1]
i = 0
while params[i]
new_lenv[params[i]] = evaluate(tree[i + 2], genv, lenv)
i = i + 1
end
genv["(jump)"] = [new_lenv, mhd[2]]
true
when "func_def"
mark_tail(tree[3], genv)
genv[tree[1]] = ["user_defined", tree[2], tree[3]]
when "func_call"
mhd = genv[tree[1]]
if mhd[0] == "builtin"
args = []
i = 0
while tree[i + 2]
args[i] = evaluate(tree[i + 2], genv, lenv)
i = i + 1
end
minruby_call(mhd[1], args)
else
new_lenv = {}
params = mhd[1]
i = 0
while params[i]
new_lenv[params[i]] = evaluate(tree[i + 2], genv, lenv)
i = i + 1
end
last = evaluate(mhd[2], genv, new_lenv)
while genv["(jump)"]
new_lenv = genv["(jump)"][0]
jump = genv["(jump)"][1]
genv["(jump)"] = nil
last = evaluate(jump, genv, new_lenv)
end
last
end
when "ary_new"
ary = []
i = 0
while tree[i + 1]
ary[i] = evaluate(tree[i + 1], genv, lenv)
i = i + 1
end
ary
when "ary_ref"
ary = evaluate(tree[1], genv, lenv)
idx = evaluate(tree[2], genv, lenv)
ary[idx]
when "ary_assign"
ary = evaluate(tree[1], genv, lenv)
idx = evaluate(tree[2], genv, lenv)
val = evaluate(tree[3], genv, lenv)
ary[idx] = val
when "hash_new"
hsh = {}
i = 0
while tree[i + 1]
key = evaluate(tree[i + 1], genv, lenv)
val = evaluate(tree[i + 2], genv, lenv)
hsh[key] = val
i = i + 2
end
hsh
end
end
str = minruby_load()
tree = minruby_parse(str)
genv = {
"p" => ["builtin", "p"],
"require" => ["builtin", "require"],
"minruby_parse" => ["builtin", "minruby_parse"],
"minruby_load" => ["builtin", "minruby_load"],
"minruby_call" => ["builtin", "minruby_call"],
}
lenv = {}
evaluate(tree, genv, lenv)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment