自由帳

@_nibral の技術ブログ

Writing An Interpreter In Go その2 (Lexer完成)

その1はこちら

1.4: '==' と '!=' の追加

1.4: Add '==' and '!=' · nibral/monkey_interpreter@0b77bb3 · GitHub

lexer/lexer.go

演算子 == と != を追加した。2文字の演算子として処理させるのではなく、=/! の後に = が続くかどうか判定する処理を入れて =, ! の処理と共存させている。golangのswitch-caseは文字列を条件に設定できるので case "==": でもいいような気がするがいったん本の通りに進めることにした。

lexer/lexer_test.go

テストケースを追加。テーブルがかなり長くなってきた。

token/token.go

識別子を追加。

1.5: REPLの実装

1.5: Implement REPL · nibral/monkey_interpreter@efce289 · GitHub

Read Eval Print LoopでREPL。Pythonを起動したときに「>>>」というプロンプトが出てきて対話的にコードを実行できるみたいなやつ。この本独自の用語かと思ったら一般的なワードだった。

ja.wikipedia.org

main.go

mainパッケージが登場、ようやくビルドして実行できるようになる。

処理としてはWelcomeメッセージを表示してreplの処理を起動するだけ。err != nilが出てくるとgolangを感じる。GoLandで書いてたらuserという変数名がインポートしたパッケージ名と競合してるという警告が出たので、replUserにリネームした。

repl/repl.go

Enterを押すたびにユーザの入力を受け取ってLexerにかけ、トークンの一覧を表示する。exitコマンドの類はつけていないので、終了するときはCtrl+Cで抜ける。

Lexerのテストで字句解析に問題がないことがわかっていても、自分で打った文がちゃんとトークンの一覧に変換されると達成感があった。

monkey_interpreter> go run .\main.go
Hello nibral! This is the Monkey programming language!
Feel free to type commands
>> let a = 1 + 2;
{Type:LET Literal:let}
{Type:IDENT Literal:a}
{Type:= Literal:=}
{Type:INT Literal:1}
{Type:+ Literal:+}
{Type:INT Literal:2}
{Type:; Literal:;}
>> :
{Type:ILLEGAL Literal::}
>>