kenju's blog

About Programming and Mathematics

社内技術イベント"Hackarade"で Go で MinRuby の Interpreter を書いた

書いた。 https://github.com/kenju/go-minruby

Background

Cookpad 社内では、"Hackarade" と呼ばれる、全エンジニア参加を必須とする技術力向上イベントが有る。今年度第一回(トータルでは第四回)を迎える今回は、Ruby committer が講師を努めつつ、自分で MiniRuby(Ruby の機能を最小限にした API)の Interpreter を書く、というお題であった。

自分は、おそらくこの題材となっている @mame さんの "Rubyで学ぶRuby " (http://ascii.jp/elem/000/001/230/1230449/ ) を読んだことがあるし、最近 Go を書く機会を増やしているというのもあり、せっかくなので Go で MinRuby の Interpreterフルスクラッチで書くことにした。

Go で Go の Interpreter を書いて Self-hosting を目指しても良かったんだけど、さすがにそれだと他の人が書いた Interpreter と比較してみて学べる獲得量が低くなるし、別にこの日にやる必要もないと思って、MinRuby にした。

Impression

"Reading Notes of Writing An Intepreter in Go" ( http://itiskj.hatenablog.com/entry/2018/06/19/083208 ) にも書いたが、本書を読んだときに Interpreter を Go でフルスクラッチで書いたことがある。このときに得た知識や経験をもとに取り組んだ。

1日にしては、割と進んだほうだと思う。

  • Integer type
  • basic operations for Integer (+,-,*,/,,%,==,!=)
  • String type
  • Boolean type
  • basic operations for Boolean (!)
  • String type concatenation
  • () for calculation
  • builtin functions (p())
  • variables
  • if/else statements

のサポートはできた。

$ make
2018/10/05 17:14:27 Hello kenju-wagatsuma! Welcome to go-minruby!
# Integer
(=・ω・=)>> 1 + 1
2
# Builtin functions
(=・ω・=)>> p(100 * 33)
3300
# Boolean types
(=・ω・=)>> true
true
# bang
(=・ω・=)>> !false
true
(=・ω・=)>> !(10 > 5)
false
(=・ω・=)>> (5 + 10 * 2 + 15 / 3) * 2 + -10
50
# variables
(=・ω・=)>> x = 5
(=・ω・=)>> y = x
(=・ω・=)>> x + y
10
# variables & String
(=・ω・=)>> msg = "hello"
(=・ω・=)>> msg
hello
# if statement
(=・ω・=)>> if true; 10; end
10
# if/else statement
(=・ω・=)>> if (1 > 3); 10; else 20; end
20
# String concatenation
(=・ω・=)>> name = "Mr. Foo"
(=・ω・=)>> msg = "Hello, " + name + "!"
(=・ω・=)>> msg
Hello, Mr. Foo!

まずは、Integer type をサポートできるよう、一気通貫で作った。具体的には、以下のファイル群を Integer type のみサポートするよう、Unit Test とともに書いていった。

  • Lexer
  • Token
  • Parser
  • AST
  • Evaluator
    • simple REPL

これらすべてを揃えるのに午前中いっぱいかかってしまったが、後続の機能を拡張するときはすでに一通りのファイルが揃っているのでスムーズに行った。

しかし、以下の機能は残念ながら時間切れ。

  • BigInt
  • while
  • function definition
  • Array type
  • Hash type

言語処理系を書くのは、やはり楽しいもの。次は Self-hosting w/ Go を挑戦してみようと思っている。新しい言語をその言語で書く手法は、その言語についてかなり詳しくなれる(本家の API や Syntax について詳しくなるし、実際にその言語を手を通して書くわけなので、標準出力、サポートしている型の扱い、バイトや文字列処理、テストの手法など一通り身につけることができる)と思っているので、おすすめです。