🙆‍♀️

Go言語でつくるインタプリタを写経した話

2025/01/10に公開

レポジトリ

動機

  • 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年 でやりたこと

Discussion