Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Cookpad Hackarade #04: Create Your Own Interpreter

5 190 vues

Publié le

TBD

Publié dans : Technologie
  • Identifiez-vous pour voir les commentaires

  • Soyez le premier à aimer ceci

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)

×