13. Today's Goal
• Write a Ruby interpreter in Ruby
– Impossible in one day!
• More precisely:
Write a "MinRuby" interpreter in Ruby
14. Today's Goal
• Write a Ruby interpreter in Ruby
– Impossible in one day!
• More precisely:
Write a "MinRuby" interpreter in Ruby
– Runs a program written in MinRuby
(Target language)
– Is written in Ruby (Host language)
15. MinRuby
• Very small subset of Ruby
– Arithmetic, comparison:
– Statements, variables:
– Branches, loop:
– Function call:
– Function definition:
– Array and Hash:
1+2*3 42>40
x=42; x=x+1; p(x)
if x < 2 while x < 10
func(1,2) p(42)
def func(x,y); …; end
a=[1,2,3]; a[1]=42; p(a[0])
3*4==5+7
h={}; h["foo"]="bar"; p(h["foo"])
16. MinRuby
• Very small subset of Ruby
– Arithmetic, comparison:
– Statements, variables:
– Branches, loop:
– Function call:
– Function definition:
– Array and Hash:
• Class? Method call? Block? Not needed.
1+2*3 42>40
x=42; x=x+1; p(x)
if x < 2 while x < 10
func(1,2) p(42)
def func(x,y); …; end
a=[1,2,3]; a[1]=42; p(a[0])
3*4==5+7
h={}; h["foo"]="bar"; p(h["foo"])
17. Your task
• Write "interp.rb"
• Check if it works as the same as Ruby
# test1-1.rb
p(1 + 1)
def parse(src); …; end
def evaluate(tree); …; end
evaluate(parse(File.read(ARGV[0])))
$ ruby test1-1.rb
2
$ ruby interp.rb test1-1.rb
2
20. A evaluator skeleton
• MinRuby interpreter with many "holes"
# An implementation of the evaluator
def evaluate(exp, env)
case exp[0]
when "+"
evaluate(exp[1], env) + evaluate(exp[2], env)
when "-"
raise(NotImplementedError) # Problem 1
…
end
end
evaluate(minruby_parse(minruby_load()), {})
21. Your task
• Complete "interp.rb" and pass all
test programs ("test*-*.rb")
$ ruby interp.rb test1-1.rb
2
$ ruby interp.rb test1-2.rb
Traceback (most recent call last):
2: from interp.rb:168:in `<main>'
1: from interp.rb:94:in `evaluate'
interp.rb:23:in `evaluate': NotImplementedError
Fix it!
22. Problems 1..6
1. Arithmetics (test1-*.rb)
2. Statements and variables (test2-*.rb)
3. Branches and loops (test3-*.rb)
4. Function calls (test4-*.rb)
5. User-defined functions (test5-*.rb)
6. Arrays and Hashes (test6-*.rb)
– You can implement and test them in turn
23. Problem 7
• Self-Hosting
– Write a MinRuby interpreter in MinRuby
• MinRuby is limited but still powerful to
implement a MinRuby interpreter!
$ ruby interp.rb interp.rb test1-1.rb
ary.each do |x|
...
end
i = 0
while ary[i]
x = ary[i]
...
end
$ ruby interp.rb interp.rb interp.rb test1-1.rb
24. Advanced Problems
• Write your own MinRuby parser
• Support advanced features
– Blocks, class/modules, eval, callcc, …
– Increment, lazy eval., type analysis, …
• Write a XXX interpreter in XXX
– MinSwift, Kotlin, Python, JavaScript, …
• Do true self-hosting
– Write a MinRuby parser in MinRuby
• Write a MinRuby compiler in Ruby
25. Good luck!
• The files and details are available at:
– https://github.com/mame/cookpad-
hackarade-minruby/
• Feel free to ask me any questions
– Or some experts
26. Answer [PR]
• A book to learn Ruby
by writing Ruby
interpreter in Ruby
– (written in Japanese)