Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Cookpad Hackarade #04: Create Your Own Interpreter

3,823 views

Published on

TBD

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Cookpad Hackarade #04: Create Your Own Interpreter

  1. 1. Hackarade #04 "Create your own interpreter" Yusuke Endoh (@mametter) 2018/10/05 (Fri.)
  2. 2. Today's Goal • Write a Ruby interpreter in Ruby
  3. 3. Today's Goal • Write a Ruby interpreter in Ruby ✕ eval(File.read(ARGV[0]))
  4. 4. Today's Goal • Write a Ruby interpreter in Ruby ✕ ✔ eval(File.read(ARGV[0])) evaluate( parse( File.read(ARGV[0])))
  5. 5. A simple structure of interpreter Parser Evaluator puts 3*(2+2) Program 12 Output + • Built-in features (String, Array, etc.) • Memory management (GC) • Libraries Interpreter
  6. 6. Parser • Converts a program text to "abstract syntax tree" (AST) Parser puts 3*(2+2) Program func_call AST * + "puts" 3 2 2
  7. 7. Evaluator • Runs the instruction by walking AST func_call AST * + "puts" 3 2 2 Evaluator
  8. 8. Evaluator • Runs the instruction by walking AST func_call AST *"puts" 3 Evaluator 4
  9. 9. Evaluator • Runs the instruction by walking AST func_call AST "puts" 12 Evaluator
  10. 10. Evaluator • Runs the instruction by walking AST AST nil Evaluator 12 Output
  11. 11. Today's Goal • Write a Ruby interpreter in Ruby
  12. 12. Today's Goal • Write a Ruby interpreter in Ruby – Impossible in one day!
  13. 13. Today's Goal • Write a Ruby interpreter in Ruby – Impossible in one day! • More precisely: Write a "MinRuby" interpreter in Ruby
  14. 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. 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. 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. 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
  18. 18. Focus: Evaluator Parser Evaluator puts 3*(2+2) Program 12 Output Interpreter Use "minruby" gem A skeleton code is provided
  19. 19. "minruby" gem • Provides a MinRuby parser require "minruby" p minruby_parse( "3*(2+2)" ) #=> ["*", ["lit", 3], ["+", ["lit", 2], ["lit", 2] ] ] * +3 2 2 Observe!
  20. 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. 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. 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. 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. 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. 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. 26. Answer [PR] • A book to learn Ruby by writing Ruby interpreter in Ruby – (written in Japanese)

×