Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RubyでつくるRubyみたいな言語のコンパイラ

Takashi Hatakeyama
September 07, 2024
49

 RubyでつくるRubyみたいな言語のコンパイラ

コンパイラ初学者が、Rubyみたいな言語のコンパイラをRubyで作る話です。

Takashi Hatakeyama

September 07, 2024
Tweet

Transcript

  1. TinyRuby の紹介 こんな感じのRubyみたいなプログラミング言語 # # sample.rb # def fib(n) if

    n < 2 n else fib(n-1) + fib(n-2) end end # 10番目のフィボナッチ数を計算 p fib(10) 7
  2. TinyRuby のビルドと実行 こんな感じにビルドする # コンパイルしてアセンブリを出力 $ ruby tinyrubyc.rb sample.rb >

    sample.s # アセンブリをアセンブルして実行ファイルを作成 $ gcc sample.s libtinyruby.c # 実行 $ ./a.out 55 8
  3. GCCの -S オプション 出力されたアセンブリコード $ gcc -S -masm=intel test.c $

    cat test.s .intel_syntax noprefix .text .globl return_100 .type return_100, @function return_100: push rbp mov rbp, rsp mov eax, 100 pop rbp ret 15
  4. 汎用レジスタ一覧 x86-64 の 16 本の 64 ビット汎用レジスタ レジスタ名 用途 レジスタ名

    用途 RAX 関数の戻り値など R8 関数の第五引数など RBX R9 関数の第六引数など RCX 関数の第四引数など R10 一時データ置き場 RDX 関数の第三引数など R11 一時データ置き場 RSI 関数の第二引数など R12 RDI 関数の第一引数など R13 RBP ベースポインタ R14 RSP スタックポインタ R15 18
  5. (x86-64 での) 関数の引数の渡し方 最初の6つの引数は、RDI, RSI, RDX, RCX, R8, R9 レジスタに渡す

    7つ目以降の引数は、スタックに積む (x86-64 での) 関数の戻り値の返し方 戻り値は、RAX レジスタに返す 20
  6. 🚦テスト駆動開発 (TDD) シェルスクリプトでテストを書いて、1機能ずつ実装していく # 整数リテラル assert 4649 'p 4649' #

    四則演算 assert 20 'p 10 + 20 - 30 * 4 / 12' assert 60 'p 10 + 20 + 30' assert 40 'p 30 + 20 - 10' assert 200 'p 10 * 20' assert 33 'p 99 / 3' # 複文 assert 4649 '1 + 1; p 4649' # 変数 assert 10 'a = 10; p a' assert 30 'a = 10; b = 20; p a + b' 23