🙆♀️
Go言語でつくるインタプリタを写経した話
本
レポジトリ
動機
- OS、コンパイラ作れるってかっこいい
- 趣味なので、WEB以外のプログミングがしたい
- 2018年プログラミング言語Goを読んだ直後あたりに発売されて飛びついた。
- その後、仕事が忙しくなったり、途中で理解できなくなって断念。
- 今回は、まず完走することを最優先とした
- 何度かレポジトリを新しくして、2024年年末に完走。
本書でやること
- Go言語を用いて、C言語風(JS風?)な構文のMonkeyプログミング言語を実行できるインタープリタを作っていく
- Go言語のサードパーティライブラリは使用していない
- テスト駆動で開発を進めていく
- Monkeyプログミング言語の特徴
- C言語風(JS風?)な構文
- 変数束縛
- サポートするデータ型
- 整数
- 真偽値
- 文字列
- 配列
- ハッシュ(辞書)
- 算術式
- 組み込み関数
- 変数に束縛する形での関数定義
- クロージャ
- インタープリタの機能を実装していく
- トークン(データ型、予約語やソースコードの中に出てくる記号(+,-))などの定義
const ( ILLEGAL = "ILLEGAL" // 規則違反 EOF = "EOF" // ファイルの終端 // 識別子(変数名・関数名) : ユーザが宣言する名前 IDENT = "IDENT" // リテラル : 扱うデータの型 INT = "INT" STRING = "STRING" // 演算子 : 使用できる演算子 ASSIGN = "=" PLUS = "+" MINUS = "-" BANG = "!" ASTERISK = "*" SLASH = "/" // 比較演算子 : 使用できる比較演算子 EQ = "==" NOT_EQ = "!=" LT = "<" GT = ">" // デリミタ(区切り文字) : コード上の区切り文字 COMMA = "," SEMICOLON = ";" LPAREN = "(" RPAREN = ")" LBRACE = "{" RBRACE = "}" LBRACKET = "[" RBRACKET = "]" COLON = ":" // キーワード : コード上で使用する予約語 FUNCTION = "FUNCTION" // 関数定義 LET = "LET" // 変数定義 TRUE = "TRUE" // 真 FALSE = "FALSE" // 偽 IF = "IF" // 構文構造使用: 条件分岐 ELSE = "ELSE" // 構文構造使用: 条件分岐 RETURN = "RETURN" // 構文構造使用: 関数からの戻り値 ) // トークンを表す構造体 type Token struct { Type TokenType // トークンの種類 Literal string // トークン文字列( 変数名 や + , - などの文字列 ) } // 予約語のマップ // .. 予約語は、言語の構文構造に使用するキーワード // .. 予約語は、変数名や関数名として使用できない var keywords = map[string]TokenType{ "fn": FUNCTION, "let": LET, "true": TRUE, "false": FALSE, "if": IF, "else": ELSE, "return": RETURN, }
- 字句解析器の実装
- 入力 : ソースコード
- 出力 : トークン列
- 構文解析器の実装
- 入力 : トークン列
- 出力 : 抽象構文木
- 評価器の実装
- 入力 : 抽象構文木
- 出力 : ソースコードの命令の実行
2025年〜2026年 でやりたこと
- 低レイヤを知りたい人のためのCコンパイラ作成入門
- コンパイラ 第2版: 原理・技法・ツール
- ガベージコレクション: 自動的メモリ管理を構成する理論と実装
- Pythonで「Go言語でつくるインタプリタ」を写経する
- Rustで「Go言語でつくるインタプリタ」を写経する
- Python自体のソースコードを読んだみたい
Discussion