Slide 23
Slide 23 text
MinRuby インタプリタ全貌
require "minruby"
def evaluate(exp, genv, lenv)
case exp[0]
when "stmts"
last = nil
i = 1
while exp[i]
last = evaluate(exp[i], genv, lenv)
i = i + 1
end
last
when "lit"
exp[1]
when "+"
evaluate(exp[1], genv, lenv) + evaluate(exp[2], genv, lenv)
when "-"
evaluate(exp[1], genv, lenv) - evaluate(exp[2], genv, lenv)
when "*"
evaluate(exp[1], genv, lenv) * evaluate(exp[2], genv, lenv)
when "/"
evaluate(exp[1], genv, lenv) / evaluate(exp[2], genv, lenv)
when "%"
evaluate(exp[1], genv, lenv) % evaluate(exp[2], genv, lenv)
when "=="
evaluate(exp[1], genv, lenv) == evaluate(exp[2], genv, lenv)
when "<"
evaluate(exp[1], genv, lenv) < evaluate(exp[2], genv, lenv)
when "<="
evaluate(exp[1], genv, lenv) <= evaluate(exp[2], genv, lenv)
when ">"
evaluate(exp[1], genv, lenv) > evaluate(exp[2], genv, lenv)
when ">="
evaluate(exp[1], genv, lenv) >= evaluate(exp[2], genv, lenv)
when "var_ref"
lenv[exp[1]]
when "var_assign"
lenv[exp[1]] = evaluate(exp[2], genv, lenv)
when "if"
if evaluate(exp[1], genv, lenv)
evaluate(exp[2], genv, lenv)
else
evaluate(exp[3], genv, lenv) if exp[3]
end
when "while"
while evaluate(exp[1], genv, lenv)
evaluate(exp[2], genv, lenv)
end
when "func_def"
genv[exp[1]] = ["user_defined", exp[2], exp[3]]
when "func_call"
args = []
i = 0
while exp[i + 2]
args[i] = evaluate(exp[i + 2], genv, lenv)
i = i + 1
end
mhd = genv[exp[1]]
if mhd[0] == "builtin"
minruby_call(mhd[1], args)
else
new_lenv = {}
params = mhd[1]
i = 0
while params[i]
new_lenv[params[i]] = args[i]
i = i + 1
end
evaluate(mhd[2], genv, new_lenv)
end
when "ary_new"
ary = []
i = 0
while exp[i + 1]
ary[i] = evaluate(exp[i + 1], genv, lenv)
i = i + 1
end
ary
when "ary_assign"
ary = evaluate(exp[1], genv, lenv)
idx = evaluate(exp[2], genv, lenv)
val = evaluate(exp[3], genv, lenv)
ary[idx] = val
when "ary_ref"
ary = evaluate(exp[1], genv, lenv)
idx = evaluate(exp[2], genv, lenv)
ary[idx]
when "hash_new"
hsh = {}
i = 0
while exp[i + 1]
key = evaluate(exp[i + 1], genv, lenv)
val = evaluate(exp[i + 2], genv, lenv)
hsh[key] = val
i = i + 2
end
hsh
else
p("error")
pp(exp)
raise "unknown node: #{ exp[0] }"
end
end
genv = {
"p" => ["builtin", "p"],
"require" => ["builtin", "require"],
"minruby_parse" => ["builtin", "minruby_parse"],
"minruby_load" => ["builtin", "minruby_load"],
"minruby_call" => ["builtin", "minruby_call"],
}
lenv = {}
evaluate(minruby_parse(minruby_load()), genv, lenv)
空行含めて
無理なく 128 行