Slide 1

Slide 1 text

Cコンパイラ作成入門 完全版 2025/06/28 PHPカンファレンス 2025 From $this to *this — A Journey Down the Stack 低レイヤを知りたいPHPerのための 長谷川 智希 @tomzoh

Slide 2

Slide 2 text

௕୩઒ஐر ͸͕ͤΘ ͱ΋͖ @tomzoh http://www.dgcircus.com デジタルサーカス株式会社 副団長CTO ॴଐ ٕज़ΧϯϑΝϨϯεओ࠻ دߘɾஶॻ 来たれ!PHPer!We are hiring! 𝕏

Slide 3

Slide 3 text

௕୩઒ஐر ͸͕ͤΘ ͱ΋͖ @tomzoh ٕज़ΧϯϑΝϨϯεӡӦࢀՃ ֤छϓϩάϥϜ։ൃ   $16 ϨτϩήʔϜػ ిࢠ޻࡞  Ϗʔϧ αοΧʔ؍ઓ ϨϯλϧΧʔτϨʔε  ΩϟϯϐϯάΧʔʜ ϥΠϑϫʔΫ 𝕏

Slide 4

Slide 4 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 Cコンパイラ作成入門 完全版 4 From $this to *this — A Journey Down the Stack 低レイヤを知りたいPHPerのための

Slide 5

Slide 5 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 なぜCコンパイラか • ここ数年、低レイヤ大好き 5

Slide 6

Slide 6 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 なぜCコンパイラか • ここ数年、低レイヤ大好き • CPU, エミュレータ, コンパイラ, ハードウェア, … 5

Slide 7

Slide 7 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 なぜCコンパイラか • ここ数年、低レイヤ大好き • CPU, エミュレータ, コンパイラ, ハードウェア, … • どれも楽しいけど今日はコンパイラの話 5

Slide 8

Slide 8 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 なぜCコンパイラか • ここ数年、低レイヤ大好き • CPU, エミュレータ, コンパイラ, ハードウェア, … • どれも楽しいけど今日はコンパイラの話 • コンパイラは実はシンプル 5

Slide 9

Slide 9 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 なぜCコンパイラか • ここ数年、低レイヤ大好き • CPU, エミュレータ, コンパイラ, ハードウェア, … • どれも楽しいけど今日はコンパイラの話 • コンパイラは実はシンプル • 実行環境の実装を含まない 5

Slide 10

Slide 10 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 なぜCコンパイラか • ここ数年、低レイヤ大好き • CPU, エミュレータ, コンパイラ, ハードウェア, … • どれも楽しいけど今日はコンパイラの話 • コンパイラは実はシンプル • 実行環境の実装を含まない • CPU, エミュレータ, インタプリタは実行環境 5

Slide 11

Slide 11 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 なぜCコンパイラか • ここ数年、低レイヤ大好き • CPU, エミュレータ, コンパイラ, ハードウェア, … • どれも楽しいけど今日はコンパイラの話 • コンパイラは実はシンプル • 実行環境の実装を含まない • CPU, エミュレータ, インタプリタは実行環境 • テキスト to テキストのコンバータ 5

Slide 12

Slide 12 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 なぜCコンパイラか • ここ数年、低レイヤ大好き • CPU, エミュレータ, コンパイラ, ハードウェア, … • どれも楽しいけど今日はコンパイラの話 • コンパイラは実はシンプル • 実行環境の実装を含まない • CPU, エミュレータ, インタプリタは実行環境 • テキスト to テキストのコンバータ • CPU, OS, プログラミング言語実装といった低レイヤぽい要素はキッチリ含む 5

Slide 13

Slide 13 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 なぜCコンパイラか • ここ数年、低レイヤ大好き • CPU, エミュレータ, コンパイラ, ハードウェア, … • どれも楽しいけど今日はコンパイラの話 • コンパイラは実はシンプル • 実行環境の実装を含まない • CPU, エミュレータ, インタプリタは実行環境 • テキスト to テキストのコンバータ • CPU, OS, プログラミング言語実装といった低レイヤぽい要素はキッチリ含む • 低レイヤを知るのにコンパイラはうってつけの教材 5

Slide 14

Slide 14 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 前提知識 6

Slide 15

Slide 15 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 Cコンパイラの動作 7

Slide 16

Slide 16 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 Cコンパイラの動作 • みなさんも一度くらいやったことありそうな Hello, World 7

Slide 17

Slide 17 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 Cコンパイラの動作 • みなさんも一度くらいやったことありそうな Hello, World • gcc hello.c → a.out 7

Slide 18

Slide 18 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 Cコンパイラの動作 • みなさんも一度くらいやったことありそうな Hello, World • gcc hello.c → a.out • gcc Cコンパイラ 7

Slide 19

Slide 19 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 Cコンパイラの動作 • みなさんも一度くらいやったことありそうな Hello, World • gcc hello.c → a.out • gcc Cコンパイラ • hello.c C言語のソースコード(ファイル) 7

Slide 20

Slide 20 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 Cコンパイラの動作 • みなさんも一度くらいやったことありそうな Hello, World • gcc hello.c → a.out • gcc Cコンパイラ • hello.c C言語のソースコード(ファイル) • a.out 実行ファイル(機械語のバイナリ) 7

Slide 21

Slide 21 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 Cコンパイラの動作 • みなさんも一度くらいやったことありそうな Hello, World • gcc hello.c → a.out • gcc Cコンパイラ • hello.c C言語のソースコード(ファイル) • a.out 実行ファイル(機械語のバイナリ) • CコンパイラがC言語のソースコードを実行ファイルに変換している様に見える 7

Slide 22

Slide 22 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 Cコンパイラの動作 • みなさんも一度くらいやったことありそうな Hello, World • gcc hello.c → a.out • gcc Cコンパイラ • hello.c C言語のソースコード(ファイル) • a.out 実行ファイル(機械語のバイナリ) • CコンパイラがC言語のソースコードを実行ファイルに変換している様に見える • 実は2段階で変換している 7

Slide 23

Slide 23 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 Cコンパイラの動作 • みなさんも一度くらいやったことありそうな Hello, World • gcc hello.c → a.out • gcc Cコンパイラ • hello.c C言語のソースコード(ファイル) • a.out 実行ファイル(機械語のバイナリ) • CコンパイラがC言語のソースコードを実行ファイルに変換している様に見える • 実は2段階で変換している • コンパイラ: C言語のソースコード → アセンブリ言語のソースコード 7

Slide 24

Slide 24 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 Cコンパイラの動作 • みなさんも一度くらいやったことありそうな Hello, World • gcc hello.c → a.out • gcc Cコンパイラ • hello.c C言語のソースコード(ファイル) • a.out 実行ファイル(機械語のバイナリ) • CコンパイラがC言語のソースコードを実行ファイルに変換している様に見える • 実は2段階で変換している • コンパイラ: C言語のソースコード → アセンブリ言語のソースコード • アセンブラ: アセンブリ言語のソースコード → 実行ファイル(機械語のバイナリ) 7

Slide 25

Slide 25 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 機械語(マシン語) 8

Slide 26

Slide 26 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 機械語(マシン語) • CPUで直接実行できる唯一の言語 8

Slide 27

Slide 27 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 機械語(マシン語) • CPUで直接実行できる唯一の言語 • Intel CPUの機械語, Apple Siliconの機械語 のようにCPUごとに仕様が違う 8

Slide 28

Slide 28 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 機械語(マシン語) • CPUで直接実行できる唯一の言語 • Intel CPUの機械語, Apple Siliconの機械語 のようにCPUごとに仕様が違う • 言語と言うにはめちゃんこシンプルなモノ 8

Slide 29

Slide 29 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 機械語(マシン語) • CPUで直接実行できる唯一の言語 • Intel CPUの機械語, Apple Siliconの機械語 のようにCPUごとに仕様が違う • 言語と言うにはめちゃんこシンプルなモノ • データを保存する場所はレジスタ(CPU内蔵の変数的なもの)とメモリだけ 8

Slide 30

Slide 30 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 機械語(マシン語) • CPUで直接実行できる唯一の言語 • Intel CPUの機械語, Apple Siliconの機械語 のようにCPUごとに仕様が違う • 言語と言うにはめちゃんこシンプルなモノ • データを保存する場所はレジスタ(CPU内蔵の変数的なもの)とメモリだけ • 命令はすべて1命令で完結するシンプルなものだけ 8

Slide 31

Slide 31 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 機械語(マシン語) • CPUで直接実行できる唯一の言語 • Intel CPUの機械語, Apple Siliconの機械語 のようにCPUごとに仕様が違う • 言語と言うにはめちゃんこシンプルなモノ • データを保存する場所はレジスタ(CPU内蔵の変数的なもの)とメモリだけ • 命令はすべて1命令で完結するシンプルなものだけ • メモリの読み書き 8

Slide 32

Slide 32 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 機械語(マシン語) • CPUで直接実行できる唯一の言語 • Intel CPUの機械語, Apple Siliconの機械語 のようにCPUごとに仕様が違う • 言語と言うにはめちゃんこシンプルなモノ • データを保存する場所はレジスタ(CPU内蔵の変数的なもの)とメモリだけ • 命令はすべて1命令で完結するシンプルなものだけ • メモリの読み書き • レジスタ or/and メモリ間での演算・比較 8

Slide 33

Slide 33 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 機械語(マシン語) • CPUで直接実行できる唯一の言語 • Intel CPUの機械語, Apple Siliconの機械語 のようにCPUごとに仕様が違う • 言語と言うにはめちゃんこシンプルなモノ • データを保存する場所はレジスタ(CPU内蔵の変数的なもの)とメモリだけ • 命令はすべて1命令で完結するシンプルなものだけ • メモリの読み書き • レジスタ or/and メモリ間での演算・比較 • 無条件ジャンプ(goto), 条件付きジャンプ 8

Slide 34

Slide 34 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 機械語(マシン語) • CPUで直接実行できる唯一の言語 • Intel CPUの機械語, Apple Siliconの機械語 のようにCPUごとに仕様が違う • 言語と言うにはめちゃんこシンプルなモノ • データを保存する場所はレジスタ(CPU内蔵の変数的なもの)とメモリだけ • 命令はすべて1命令で完結するシンプルなものだけ • メモリの読み書き • レジスタ or/and メモリ間での演算・比較 • 無条件ジャンプ(goto), 条件付きジャンプ • if(){} とか while(){} みたいな複雑な命令は無い 8

Slide 35

Slide 35 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 機械語(マシン語) • CPUで直接実行できる唯一の言語 • Intel CPUの機械語, Apple Siliconの機械語 のようにCPUごとに仕様が違う • 言語と言うにはめちゃんこシンプルなモノ • データを保存する場所はレジスタ(CPU内蔵の変数的なもの)とメモリだけ • 命令はすべて1命令で完結するシンプルなものだけ • メモリの読み書き • レジスタ or/and メモリ間での演算・比較 • 無条件ジャンプ(goto), 条件付きジャンプ • if(){} とか while(){} みたいな複雑な命令は無い • シンプルな命令の組み合わせで実施する 8

Slide 36

Slide 36 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 シンプルさ故の難しさ 9

Slide 37

Slide 37 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 シンプルさ故の難しさ • 機械語にはシンプルな命令しか無い 9

Slide 38

Slide 38 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 シンプルさ故の難しさ • 機械語にはシンプルな命令しか無い • レジスタの数が限られる 9

Slide 39

Slide 39 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 シンプルさ故の難しさ • 機械語にはシンプルな命令しか無い • レジスタの数が限られる • スタックに入れたり出したり 9

Slide 40

Slide 40 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 シンプルさ故の難しさ • 機械語にはシンプルな命令しか無い • レジスタの数が限られる • スタックに入れたり出したり • メモリを書いたり読んだり 9

Slide 41

Slide 41 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 シンプルさ故の難しさ • 機械語にはシンプルな命令しか無い • レジスタの数が限られる • スタックに入れたり出したり • メモリを書いたり読んだり 9 int main(){ int a = 0; if (a == 0){ a = 1; } else { a = 2; } } C言語

Slide 42

Slide 42 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 シンプルさ故の難しさ • 機械語にはシンプルな命令しか無い • レジスタの数が限られる • スタックに入れたり出したり • メモリを書いたり読んだり 9 mov $4, %rcx lea -4(%rbp), %rdi mov $0, %al rep stosb lea -4(%rbp), %rax push %rax mov $0, %rax pop %rdi mov %eax, (%rdi) mov $0, %rax push %rax lea -4(%rbp), %rax mov (%rax), %eax pop %rdi cmp %edi, %eax sete %al movzb %al, %rax cmp $0, %eax je .L.else.1 lea -4(%rbp), %rax push %rax mov $1, %rax pop %rdi mov %eax, (%rdi) jmp .L.end.1 .L.else.1: lea -4(%rbp), %rax push %rax mov $2, %rax pop %rdi mov %eax, (%rdi) .L.end.1: mov $0, %rax .L.return.main: mov %rbp, %rsp pop %rbp ret アセンブリ言語 int main(){ int a = 0; if (a == 0){ a = 1; } else { a = 2; } } C言語

Slide 43

Slide 43 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 シンプルさ故の難しさ • 機械語にはシンプルな命令しか無い • レジスタの数が限られる • スタックに入れたり出したり • メモリを書いたり読んだり 9 mov $4, %rcx lea -4(%rbp), %rdi mov $0, %al rep stosb lea -4(%rbp), %rax push %rax mov $0, %rax pop %rdi mov %eax, (%rdi) mov $0, %rax push %rax lea -4(%rbp), %rax mov (%rax), %eax pop %rdi cmp %edi, %eax sete %al movzb %al, %rax cmp $0, %eax je .L.else.1 lea -4(%rbp), %rax push %rax mov $1, %rax pop %rdi mov %eax, (%rdi) jmp .L.end.1 .L.else.1: lea -4(%rbp), %rax push %rax mov $2, %rax pop %rdi mov %eax, (%rdi) .L.end.1: mov $0, %rax .L.return.main: mov %rbp, %rsp pop %rbp ret アセンブリ言語 int main(){ int a = 0; if (a == 0){ a = 1; } else { a = 2; } } C言語

Slide 44

Slide 44 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 シンプルさ故の難しさ • 機械語にはシンプルな命令しか無い • レジスタの数が限られる • スタックに入れたり出したり • メモリを書いたり読んだり 9 mov $4, %rcx lea -4(%rbp), %rdi mov $0, %al rep stosb lea -4(%rbp), %rax push %rax mov $0, %rax pop %rdi mov %eax, (%rdi) mov $0, %rax push %rax lea -4(%rbp), %rax mov (%rax), %eax pop %rdi cmp %edi, %eax sete %al movzb %al, %rax cmp $0, %eax je .L.else.1 lea -4(%rbp), %rax push %rax mov $1, %rax pop %rdi mov %eax, (%rdi) jmp .L.end.1 .L.else.1: lea -4(%rbp), %rax push %rax mov $2, %rax pop %rdi mov %eax, (%rdi) .L.end.1: mov $0, %rax .L.return.main: mov %rbp, %rsp pop %rbp ret アセンブリ言語 int main(){ int a = 0; if (a == 0){ a = 1; } else { a = 2; } } C言語 JG

Slide 45

Slide 45 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 シンプルさ故の難しさ • 機械語にはシンプルな命令しか無い • レジスタの数が限られる • スタックに入れたり出したり • メモリを書いたり読んだり 9 mov $4, %rcx lea -4(%rbp), %rdi mov $0, %al rep stosb lea -4(%rbp), %rax push %rax mov $0, %rax pop %rdi mov %eax, (%rdi) mov $0, %rax push %rax lea -4(%rbp), %rax mov (%rax), %eax pop %rdi cmp %edi, %eax sete %al movzb %al, %rax cmp $0, %eax je .L.else.1 lea -4(%rbp), %rax push %rax mov $1, %rax pop %rdi mov %eax, (%rdi) jmp .L.end.1 .L.else.1: lea -4(%rbp), %rax push %rax mov $2, %rax pop %rdi mov %eax, (%rdi) .L.end.1: mov $0, %rax .L.return.main: mov %rbp, %rsp pop %rbp ret アセンブリ言語 int main(){ int a = 0; if (a == 0){ a = 1; } else { a = 2; } } C言語 JG

Slide 46

Slide 46 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 シンプルさ故の難しさ • 機械語にはシンプルな命令しか無い • レジスタの数が限られる • スタックに入れたり出したり • メモリを書いたり読んだり 9 mov $4, %rcx lea -4(%rbp), %rdi mov $0, %al rep stosb lea -4(%rbp), %rax push %rax mov $0, %rax pop %rdi mov %eax, (%rdi) mov $0, %rax push %rax lea -4(%rbp), %rax mov (%rax), %eax pop %rdi cmp %edi, %eax sete %al movzb %al, %rax cmp $0, %eax je .L.else.1 lea -4(%rbp), %rax push %rax mov $1, %rax pop %rdi mov %eax, (%rdi) jmp .L.end.1 .L.else.1: lea -4(%rbp), %rax push %rax mov $2, %rax pop %rdi mov %eax, (%rdi) .L.end.1: mov $0, %rax .L.return.main: mov %rbp, %rsp pop %rbp ret アセンブリ言語 int main(){ int a = 0; if (a == 0){ a = 1; } else { a = 2; } } C言語 JG UIFO

Slide 47

Slide 47 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 シンプルさ故の難しさ • 機械語にはシンプルな命令しか無い • レジスタの数が限られる • スタックに入れたり出したり • メモリを書いたり読んだり 9 mov $4, %rcx lea -4(%rbp), %rdi mov $0, %al rep stosb lea -4(%rbp), %rax push %rax mov $0, %rax pop %rdi mov %eax, (%rdi) mov $0, %rax push %rax lea -4(%rbp), %rax mov (%rax), %eax pop %rdi cmp %edi, %eax sete %al movzb %al, %rax cmp $0, %eax je .L.else.1 lea -4(%rbp), %rax push %rax mov $1, %rax pop %rdi mov %eax, (%rdi) jmp .L.end.1 .L.else.1: lea -4(%rbp), %rax push %rax mov $2, %rax pop %rdi mov %eax, (%rdi) .L.end.1: mov $0, %rax .L.return.main: mov %rbp, %rsp pop %rbp ret アセンブリ言語 int main(){ int a = 0; if (a == 0){ a = 1; } else { a = 2; } } C言語 JG UIFO

Slide 48

Slide 48 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 シンプルさ故の難しさ • 機械語にはシンプルな命令しか無い • レジスタの数が限られる • スタックに入れたり出したり • メモリを書いたり読んだり 9 mov $4, %rcx lea -4(%rbp), %rdi mov $0, %al rep stosb lea -4(%rbp), %rax push %rax mov $0, %rax pop %rdi mov %eax, (%rdi) mov $0, %rax push %rax lea -4(%rbp), %rax mov (%rax), %eax pop %rdi cmp %edi, %eax sete %al movzb %al, %rax cmp $0, %eax je .L.else.1 lea -4(%rbp), %rax push %rax mov $1, %rax pop %rdi mov %eax, (%rdi) jmp .L.end.1 .L.else.1: lea -4(%rbp), %rax push %rax mov $2, %rax pop %rdi mov %eax, (%rdi) .L.end.1: mov $0, %rax .L.return.main: mov %rbp, %rsp pop %rbp ret アセンブリ言語 int main(){ int a = 0; if (a == 0){ a = 1; } else { a = 2; } } C言語 JG UIFO FMTF

Slide 49

Slide 49 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 シンプルさ故の難しさ • 機械語にはシンプルな命令しか無い • レジスタの数が限られる • スタックに入れたり出したり • メモリを書いたり読んだり • ファミコン時代はこんなのを 人間が直書きしてたのだ… 9 mov $4, %rcx lea -4(%rbp), %rdi mov $0, %al rep stosb lea -4(%rbp), %rax push %rax mov $0, %rax pop %rdi mov %eax, (%rdi) mov $0, %rax push %rax lea -4(%rbp), %rax mov (%rax), %eax pop %rdi cmp %edi, %eax sete %al movzb %al, %rax cmp $0, %eax je .L.else.1 lea -4(%rbp), %rax push %rax mov $1, %rax pop %rdi mov %eax, (%rdi) jmp .L.end.1 .L.else.1: lea -4(%rbp), %rax push %rax mov $2, %rax pop %rdi mov %eax, (%rdi) .L.end.1: mov $0, %rax .L.return.main: mov %rbp, %rsp pop %rbp ret アセンブリ言語 int main(){ int a = 0; if (a == 0){ a = 1; } else { a = 2; } } C言語 JG UIFO FMTF

Slide 50

Slide 50 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 シンプルさ故の難しさ • 機械語にはシンプルな命令しか無い • レジスタの数が限られる • スタックに入れたり出したり • メモリを書いたり読んだり • ファミコン時代はこんなのを 人間が直書きしてたのだ… • Cコンパイラ作ってるとA++なんだな〜感がある 9 mov $4, %rcx lea -4(%rbp), %rdi mov $0, %al rep stosb lea -4(%rbp), %rax push %rax mov $0, %rax pop %rdi mov %eax, (%rdi) mov $0, %rax push %rax lea -4(%rbp), %rax mov (%rax), %eax pop %rdi cmp %edi, %eax sete %al movzb %al, %rax cmp $0, %eax je .L.else.1 lea -4(%rbp), %rax push %rax mov $1, %rax pop %rdi mov %eax, (%rdi) jmp .L.end.1 .L.else.1: lea -4(%rbp), %rax push %rax mov $2, %rax pop %rdi mov %eax, (%rdi) .L.end.1: mov $0, %rax .L.return.main: mov %rbp, %rsp pop %rbp ret アセンブリ言語 int main(){ int a = 0; if (a == 0){ a = 1; } else { a = 2; } } C言語 JG UIFO FMTF

Slide 51

Slide 51 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 シンプルさ故の難しさ • 機械語にはシンプルな命令しか無い • レジスタの数が限られる • スタックに入れたり出したり • メモリを書いたり読んだり • ファミコン時代はこんなのを 人間が直書きしてたのだ… • Cコンパイラ作ってるとA++なんだな〜感がある • C言語が突然ポッとうまれたのではなく、 みんながアセンブラ書いてるという時代背景のもとで プログラミングを効率的にするために作られた感 9 mov $4, %rcx lea -4(%rbp), %rdi mov $0, %al rep stosb lea -4(%rbp), %rax push %rax mov $0, %rax pop %rdi mov %eax, (%rdi) mov $0, %rax push %rax lea -4(%rbp), %rax mov (%rax), %eax pop %rdi cmp %edi, %eax sete %al movzb %al, %rax cmp $0, %eax je .L.else.1 lea -4(%rbp), %rax push %rax mov $1, %rax pop %rdi mov %eax, (%rdi) jmp .L.end.1 .L.else.1: lea -4(%rbp), %rax push %rax mov $2, %rax pop %rdi mov %eax, (%rdi) .L.end.1: mov $0, %rax .L.return.main: mov %rbp, %rsp pop %rbp ret アセンブリ言語 int main(){ int a = 0; if (a == 0){ a = 1; } else { a = 2; } } C言語 JG UIFO FMTF

Slide 52

Slide 52 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 シンプルさ故の難しさ • 機械語にはシンプルな命令しか無い • レジスタの数が限られる • スタックに入れたり出したり • メモリを書いたり読んだり • ファミコン時代はこんなのを 人間が直書きしてたのだ… • Cコンパイラ作ってるとA++なんだな〜感がある • C言語が突然ポッとうまれたのではなく、 みんながアセンブラ書いてるという時代背景のもとで プログラミングを効率的にするために作られた感 • 現代: 「構造体とかポインタとか難しいな…」 9 mov $4, %rcx lea -4(%rbp), %rdi mov $0, %al rep stosb lea -4(%rbp), %rax push %rax mov $0, %rax pop %rdi mov %eax, (%rdi) mov $0, %rax push %rax lea -4(%rbp), %rax mov (%rax), %eax pop %rdi cmp %edi, %eax sete %al movzb %al, %rax cmp $0, %eax je .L.else.1 lea -4(%rbp), %rax push %rax mov $1, %rax pop %rdi mov %eax, (%rdi) jmp .L.end.1 .L.else.1: lea -4(%rbp), %rax push %rax mov $2, %rax pop %rdi mov %eax, (%rdi) .L.end.1: mov $0, %rax .L.return.main: mov %rbp, %rsp pop %rbp ret アセンブリ言語 int main(){ int a = 0; if (a == 0){ a = 1; } else { a = 2; } } C言語 JG UIFO FMTF

Slide 53

Slide 53 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 シンプルさ故の難しさ • 機械語にはシンプルな命令しか無い • レジスタの数が限られる • スタックに入れたり出したり • メモリを書いたり読んだり • ファミコン時代はこんなのを 人間が直書きしてたのだ… • Cコンパイラ作ってるとA++なんだな〜感がある • C言語が突然ポッとうまれたのではなく、 みんながアセンブラ書いてるという時代背景のもとで プログラミングを効率的にするために作られた感 • 現代: 「構造体とかポインタとか難しいな…」 • 当時: 「メモリアクセスがこんな楽に書けるなんて神…!」 9 mov $4, %rcx lea -4(%rbp), %rdi mov $0, %al rep stosb lea -4(%rbp), %rax push %rax mov $0, %rax pop %rdi mov %eax, (%rdi) mov $0, %rax push %rax lea -4(%rbp), %rax mov (%rax), %eax pop %rdi cmp %edi, %eax sete %al movzb %al, %rax cmp $0, %eax je .L.else.1 lea -4(%rbp), %rax push %rax mov $1, %rax pop %rdi mov %eax, (%rdi) jmp .L.end.1 .L.else.1: lea -4(%rbp), %rax push %rax mov $2, %rax pop %rdi mov %eax, (%rdi) .L.end.1: mov $0, %rax .L.return.main: mov %rbp, %rsp pop %rbp ret アセンブリ言語 int main(){ int a = 0; if (a == 0){ a = 1; } else { a = 2; } } C言語 JG UIFO FMTF

Slide 54

Slide 54 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 今回作るコンパイラ 10 機械語の バイナリ アセンブリ言語の ソースコード C言語の ソースコード • C言語のソースコードからアセンブリ言語のソースコードに変換するCコンパイラ

Slide 55

Slide 55 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 今回作るコンパイラ 10 機械語の バイナリ アセンブリ言語の ソースコード C言語の ソースコード • C言語のソースコードからアセンブリ言語のソースコードに変換するCコンパイラ • アセンブリ言語のソースコードから機械語のバイナリに変換するアセンブラは既存のものを使用する

Slide 56

Slide 56 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 今回作るコンパイラ 10 機械語の バイナリ アセンブリ言語の ソースコード C言語の ソースコード • C言語のソースコードからアセンブリ言語のソースコードに変換するCコンパイラ • アセンブリ言語のソースコードから機械語のバイナリに変換するアセンブラは既存のものを使用する • 世の中にはとてもよくできたCコンパイラ作成入門ドキュメントがある

Slide 57

Slide 57 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 今回作るコンパイラ 10 機械語の バイナリ アセンブリ言語の ソースコード C言語の ソースコード • C言語のソースコードからアセンブリ言語のソースコードに変換するCコンパイラ • アセンブリ言語のソースコードから機械語のバイナリに変換するアセンブラは既存のものを使用する • 世の中にはとてもよくできたCコンパイラ作成入門ドキュメントがある 低レイヤを知りたい人のためのCコンパイラ作成入門 / Rui Ueyamaさん https://www.sigbus.info/compilerbook

Slide 58

Slide 58 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 今回作るコンパイラ 10 機械語の バイナリ アセンブリ言語の ソースコード C言語の ソースコード • C言語のソースコードからアセンブリ言語のソースコードに変換するCコンパイラ • アセンブリ言語のソースコードから機械語のバイナリに変換するアセンブラは既存のものを使用する • 世の中にはとてもよくできたCコンパイラ作成入門ドキュメントがある 低レイヤを知りたい人のためのCコンパイラ作成入門 / Rui Ueyamaさん https://www.sigbus.info/compilerbook • だけどC言語でC言語のコンパイラを作るテキストなんだよね〜

Slide 59

Slide 59 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 今回作るコンパイラ 10 機械語の バイナリ アセンブリ言語の ソースコード C言語の ソースコード • C言語のソースコードからアセンブリ言語のソースコードに変換するCコンパイラ • アセンブリ言語のソースコードから機械語のバイナリに変換するアセンブラは既存のものを使用する • 世の中にはとてもよくできたCコンパイラ作成入門ドキュメントがある 低レイヤを知りたい人のためのCコンパイラ作成入門 / Rui Ueyamaさん https://www.sigbus.info/compilerbook • だけどC言語でC言語のコンパイラを作るテキストなんだよね〜 • C言語…PHPerの我々にはややハードルが高い

Slide 60

Slide 60 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 今回作るコンパイラ 10 機械語の バイナリ アセンブリ言語の ソースコード C言語の ソースコード • C言語のソースコードからアセンブリ言語のソースコードに変換するCコンパイラ • アセンブリ言語のソースコードから機械語のバイナリに変換するアセンブラは既存のものを使用する • 世の中にはとてもよくできたCコンパイラ作成入門ドキュメントがある 低レイヤを知りたい人のためのCコンパイラ作成入門 / Rui Ueyamaさん https://www.sigbus.info/compilerbook • だけどC言語でC言語のコンパイラを作るテキストなんだよね〜 • C言語…PHPerの我々にはややハードルが高い • のでPHPでやる

Slide 61

Slide 61 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 アセンブラ・アセンブル 11 機械語の バイナリ アセンブリ言語の ソースコード C言語の ソースコード

Slide 62

Slide 62 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 アセンブラ・アセンブル 11 アセンブラで アセンブリ言語のソースコードをアセンブルして 機械語(マシン語)のバイナリを作る 機械語の バイナリ アセンブリ言語の ソースコード C言語の ソースコード

Slide 63

Slide 63 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 アセンブラ・アセンブル 11 アセンブラで アセンブリ言語のソースコードをアセンブルして 機械語(マシン語)のバイナリを作る 機械語の バイナリ アセンブリ言語の ソースコード C言語の ソースコード .file 1 "-" .local .L..0 .align 1 .data .L..0: .byte 72 ; H .byte 101 ; e .byte 108 ; l .byte 108 ; l .byte 111 ; o .byte 44 ; , .byte 32 ; .byte 87 ; W .byte 111 ; o .byte 114 ; r .byte 108 ; l .byte 100 ; d .byte 46 ; . .byte 0 ; \0 .globl main .text main: push %rbp mov %rsp, %rbp sub $0, %rsp .loc 1 43 .loc 1 43 .loc 1 43 .loc 1 43 .loc 1 43 lea .L..0(%rip), %rax push %rax pop %rdi mov $0, %rax call printf .L.return.main: mov %rbp, %rsp pop %rbp ret アセンブリ言語のソースコード

Slide 64

Slide 64 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 アセンブラ・アセンブル 11 アセンブル アセンブラで アセンブリ言語のソースコードをアセンブルして 機械語(マシン語)のバイナリを作る 機械語の バイナリ アセンブリ言語の ソースコード C言語の ソースコード .file 1 "-" .local .L..0 .align 1 .data .L..0: .byte 72 ; H .byte 101 ; e .byte 108 ; l .byte 108 ; l .byte 111 ; o .byte 44 ; , .byte 32 ; .byte 87 ; W .byte 111 ; o .byte 114 ; r .byte 108 ; l .byte 100 ; d .byte 46 ; . .byte 0 ; \0 .globl main .text main: push %rbp mov %rsp, %rbp sub $0, %rsp .loc 1 43 .loc 1 43 .loc 1 43 .loc 1 43 .loc 1 43 lea .L..0(%rip), %rax push %rax pop %rdi mov $0, %rax call printf .L.return.main: mov %rbp, %rsp pop %rbp ret アセンブリ言語のソースコード

Slide 65

Slide 65 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 アセンブラ・アセンブル 11 機械語(マシン語)のバイナリ 000000 7f 45 4c 46 02 01 01 00 000008 00 00 00 00 00 00 00 00 000010 03 00 3e 00 01 00 00 00 000018 60 10 00 00 00 00 00 00 000020 40 00 00 00 00 00 00 00 000028 e8 39 00 00 00 00 00 00 000030 00 00 00 00 40 00 38 00 000038 0d 00 40 00 24 00 23 00 000040 06 00 00 00 04 00 00 00 000048 40 00 00 00 00 00 00 00 アセンブル アセンブラで アセンブリ言語のソースコードをアセンブルして 機械語(マシン語)のバイナリを作る 機械語の バイナリ アセンブリ言語の ソースコード C言語の ソースコード .file 1 "-" .local .L..0 .align 1 .data .L..0: .byte 72 ; H .byte 101 ; e .byte 108 ; l .byte 108 ; l .byte 111 ; o .byte 44 ; , .byte 32 ; .byte 87 ; W .byte 111 ; o .byte 114 ; r .byte 108 ; l .byte 100 ; d .byte 46 ; . .byte 0 ; \0 .globl main .text main: push %rbp mov %rsp, %rbp sub $0, %rsp .loc 1 43 .loc 1 43 .loc 1 43 .loc 1 43 .loc 1 43 lea .L..0(%rip), %rax push %rax pop %rdi mov $0, %rax call printf .L.return.main: mov %rbp, %rsp pop %rbp ret アセンブリ言語のソースコード

Slide 66

Slide 66 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コンパイラ型言語 12

Slide 67

Slide 67 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コンパイラ型言語 • コンパイラ型言語: C, Go, Rust, … 12

Slide 68

Slide 68 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コンパイラ型言語 • コンパイラ型言語: C, Go, Rust, … • 仕様は違えどすべて最終的には機械語に変換される 12

Slide 69

Slide 69 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コンパイラ型言語 • コンパイラ型言語: C, Go, Rust, … • 仕様は違えどすべて最終的には機械語に変換される • この特徴はコンパイラ型言語の特徴 12

Slide 70

Slide 70 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コンパイラ型言語 • コンパイラ型言語: C, Go, Rust, … • 仕様は違えどすべて最終的には機械語に変換される • この特徴はコンパイラ型言語の特徴 • 世の中の言語にはコンパイラ型言語とインタプリタ型言語がある 12

Slide 71

Slide 71 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コンパイラ型言語 • コンパイラ型言語: C, Go, Rust, … • 仕様は違えどすべて最終的には機械語に変換される • この特徴はコンパイラ型言語の特徴 • 世の中の言語にはコンパイラ型言語とインタプリタ型言語がある 12

Slide 72

Slide 72 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コンパイラ型言語 • コンパイラ型言語: C, Go, Rust, … • 仕様は違えどすべて最終的には機械語に変換される • この特徴はコンパイラ型言語の特徴 • 世の中の言語にはコンパイラ型言語とインタプリタ型言語がある • PHP Conference Japan 2023で詳しく話をしています 12

Slide 73

Slide 73 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コンパイラ型言語 • コンパイラ型言語: C, Go, Rust, … • 仕様は違えどすべて最終的には機械語に変換される • この特徴はコンパイラ型言語の特徴 • 世の中の言語にはコンパイラ型言語とインタプリタ型言語がある • PHP Conference Japan 2023で詳しく話をしています • 資料公開しています 12

Slide 74

Slide 74 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コンパイラ型言語 • コンパイラ型言語: C, Go, Rust, … • 仕様は違えどすべて最終的には機械語に変換される • この特徴はコンパイラ型言語の特徴 • 世の中の言語にはコンパイラ型言語とインタプリタ型言語がある • PHP Conference Japan 2023で詳しく話をしています • 資料公開しています • YouTubeにもあります タイトルで検索してみて 12

Slide 75

Slide 75 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コンパイラ型言語 • コンパイラ型言語: C, Go, Rust, … • 仕様は違えどすべて最終的には機械語に変換される • この特徴はコンパイラ型言語の特徴 • 世の中の言語にはコンパイラ型言語とインタプリタ型言語がある • PHP Conference Japan 2023で詳しく話をしています • 資料公開しています • YouTubeにもあります タイトルで検索してみて • この話の最新版を7月の関西でします 12

Slide 76

Slide 76 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 インタープリタ型言語 13

Slide 77

Slide 77 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 インタープリタ型言語 • Python, Ruby, PHP… 13

Slide 78

Slide 78 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 インタープリタ型言語 • Python, Ruby, PHP… • ソースコードをパースしたあと(機械語に変換せず)そのまま実行する 13

Slide 79

Slide 79 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 インタープリタ型言語 • Python, Ruby, PHP… • ソースコードをパースしたあと(機械語に変換せず)そのまま実行する • VM / VirtualMachine: 実行環境 13

Slide 80

Slide 80 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 インタープリタ型言語 • Python, Ruby, PHP… • ソースコードをパースしたあと(機械語に変換せず)そのまま実行する • VM / VirtualMachine: 実行環境 • ソースコードをパースした結果(ASTとかバイトコードとか)を実行するプログラム 13

Slide 81

Slide 81 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 インタープリタ型言語 • Python, Ruby, PHP… • ソースコードをパースしたあと(機械語に変換せず)そのまま実行する • VM / VirtualMachine: 実行環境 • ソースコードをパースした結果(ASTとかバイトコードとか)を実行するプログラム • 機械語で書かれたプログラムなことが多い 13

Slide 82

Slide 82 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 インタープリタ型言語 • Python, Ruby, PHP… • ソースコードをパースしたあと(機械語に変換せず)そのまま実行する • VM / VirtualMachine: 実行環境 • ソースコードをパースした結果(ASTとかバイトコードとか)を実行するプログラム • 機械語で書かれたプログラムなことが多い • CPUで直接実行されるのではなくVMで実行される 13

Slide 83

Slide 83 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 インタープリタ型言語 • Python, Ruby, PHP… • ソースコードをパースしたあと(機械語に変換せず)そのまま実行する • VM / VirtualMachine: 実行環境 • ソースコードをパースした結果(ASTとかバイトコードとか)を実行するプログラム • 機械語で書かれたプログラムなことが多い • CPUで直接実行されるのではなくVMで実行される • 「嘘だ!PHPもコンパイルするでしょ!JITコンパイラとかあるし!」 13

Slide 84

Slide 84 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 インタープリタ型言語 • Python, Ruby, PHP… • ソースコードをパースしたあと(機械語に変換せず)そのまま実行する • VM / VirtualMachine: 実行環境 • ソースコードをパースした結果(ASTとかバイトコードとか)を実行するプログラム • 機械語で書かれたプログラムなことが多い • CPUで直接実行されるのではなくVMで実行される • 「嘘だ!PHPもコンパイルするでしょ!JITコンパイラとかあるし!」 • ソースコード → opcode: コンパイラ的動作 13

Slide 85

Slide 85 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 インタープリタ型言語 • Python, Ruby, PHP… • ソースコードをパースしたあと(機械語に変換せず)そのまま実行する • VM / VirtualMachine: 実行環境 • ソースコードをパースした結果(ASTとかバイトコードとか)を実行するプログラム • 機械語で書かれたプログラムなことが多い • CPUで直接実行されるのではなくVMで実行される • 「嘘だ!PHPもコンパイルするでしょ!JITコンパイラとかあるし!」 • ソースコード → opcode: コンパイラ的動作 • opcode → VM: インタプリタ的動作 13

Slide 86

Slide 86 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 インタープリタ型言語 • Python, Ruby, PHP… • ソースコードをパースしたあと(機械語に変換せず)そのまま実行する • VM / VirtualMachine: 実行環境 • ソースコードをパースした結果(ASTとかバイトコードとか)を実行するプログラム • 機械語で書かれたプログラムなことが多い • CPUで直接実行されるのではなくVMで実行される • 「嘘だ!PHPもコンパイルするでしょ!JITコンパイラとかあるし!」 • ソースコード → opcode: コンパイラ的動作 • opcode → VM: インタプリタ的動作 • 現代は「コンパイラ型/インタープリタ型」とばっくり切り分けられないことも 13

Slide 87

Slide 87 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 PHPで作るCコンパイラ実装 • GitHubでソースコード公開してます • hasegawa-tomoki/pcc https://github.com/hasegawa-tomoki/pcc 14

Slide 88

Slide 88 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 PHPで作るCコンパイラ実装 • GitHubでソースコード公開してます • hasegawa-tomoki/pcc https://github.com/hasegawa-tomoki/pcc 14

Slide 89

Slide 89 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 PHPで作るCコンパイラ実装 • GitHubでソースコード公開してます • hasegawa-tomoki/pcc https://github.com/hasegawa-tomoki/pcc • 実装済みの機能は /ctests/test/*.c を見て頂けると… 14

Slide 90

Slide 90 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 PHPで作るCコンパイラ実装 • GitHubでソースコード公開してます • hasegawa-tomoki/pcc https://github.com/hasegawa-tomoki/pcc • 実装済みの機能は /ctests/test/*.c を見て頂けると… 14 alignof.c alloca.c arith.c asm.c bitfield.c builtin.c cast.c commonsym.c compat.c complit.c const.c constexpr.c control.c decl.c enum.c extern.c float.c function.c generic.c initializer.c line.c literal.c macro.c offsetof.c pointer.c sizeof.c stdhdr.c string.c struct.c tls.c typedef.c typeof.c unicode.c union.c usualconv.c varargs.c variable.c vla.c

Slide 91

Slide 91 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 PHPで作るCコンパイラ実装 • GitHubでソースコード公開してます • hasegawa-tomoki/pcc https://github.com/hasegawa-tomoki/pcc • 実装済みの機能は /ctests/test/*.c を見て頂けると… • ひととおりの変数・関数定義、制御構造は実装済み 14 alignof.c alloca.c arith.c asm.c bitfield.c builtin.c cast.c commonsym.c compat.c complit.c const.c constexpr.c control.c decl.c enum.c extern.c float.c function.c generic.c initializer.c line.c literal.c macro.c offsetof.c pointer.c sizeof.c stdhdr.c string.c struct.c tls.c typedef.c typeof.c unicode.c union.c usualconv.c varargs.c variable.c vla.c

Slide 92

Slide 92 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 PHPで作るCコンパイラ実装 • GitHubでソースコード公開してます • hasegawa-tomoki/pcc https://github.com/hasegawa-tomoki/pcc • 実装済みの機能は /ctests/test/*.c を見て頂けると… • ひととおりの変数・関数定義、制御構造は実装済み • fl oatの実装まで自分でやって、それ以降をAIに実装してもらってる 14 alignof.c alloca.c arith.c asm.c bitfield.c builtin.c cast.c commonsym.c compat.c complit.c const.c constexpr.c control.c decl.c enum.c extern.c float.c function.c generic.c initializer.c line.c literal.c macro.c offsetof.c pointer.c sizeof.c stdhdr.c string.c struct.c tls.c typedef.c typeof.c unicode.c union.c usualconv.c varargs.c variable.c vla.c

Slide 93

Slide 93 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 PHPで作るCコンパイラ実装 • GitHubでソースコード公開してます • hasegawa-tomoki/pcc https://github.com/hasegawa-tomoki/pcc • 実装済みの機能は /ctests/test/*.c を見て頂けると… • ひととおりの変数・関数定義、制御構造は実装済み • fl oatの実装まで自分でやって、それ以降をAIに実装してもらってる • オプション系 -M とか -MT とかを作ってる 14 alignof.c alloca.c arith.c asm.c bitfield.c builtin.c cast.c commonsym.c compat.c complit.c const.c constexpr.c control.c decl.c enum.c extern.c float.c function.c generic.c initializer.c line.c literal.c macro.c offsetof.c pointer.c sizeof.c stdhdr.c string.c struct.c tls.c typedef.c typeof.c unicode.c union.c usualconv.c varargs.c variable.c vla.c

Slide 94

Slide 94 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 Cコンパイラ作成入門 完全版 15 From $this to *this — A Journey Down the Stack 低レイヤを知りたいPHPerのための

Slide 95

Slide 95 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 インクリメンタルな開発 16

Slide 96

Slide 96 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 インクリメンタルな開発 • Cコンパイラ、とても高度なので最初からすべての機能を作るのは難しい 16

Slide 97

Slide 97 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 インクリメンタルな開発 • Cコンパイラ、とても高度なので最初からすべての機能を作るのは難しい • 難易度的な問題とモチベーション的な問題 16

Slide 98

Slide 98 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 インクリメンタルな開発 • Cコンパイラ、とても高度なので最初からすべての機能を作るのは難しい • 難易度的な問題とモチベーション的な問題 • 低レイヤを知りたい人のためのCコンパイラ作成入門では インクリメンタルに開発を進める 16

Slide 99

Slide 99 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 インクリメンタルな開発 • Cコンパイラ、とても高度なので最初からすべての機能を作るのは難しい • 難易度的な問題とモチベーション的な問題 • 低レイヤを知りたい人のためのCコンパイラ作成入門では インクリメンタルに開発を進める • 少しずつ機能を作っていく 16

Slide 100

Slide 100 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 インクリメンタルな開発 • Cコンパイラ、とても高度なので最初からすべての機能を作るのは難しい • 難易度的な問題とモチベーション的な問題 • 低レイヤを知りたい人のためのCコンパイラ作成入門では インクリメンタルに開発を進める • 少しずつ機能を作っていく • テストコードもいっしょに作っていく 16

Slide 101

Slide 101 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 インクリメンタルな開発 • Cコンパイラ、とても高度なので最初からすべての機能を作るのは難しい • 難易度的な問題とモチベーション的な問題 • 低レイヤを知りたい人のためのCコンパイラ作成入門では インクリメンタルに開発を進める • 少しずつ機能を作っていく • テストコードもいっしょに作っていく • テストコードがとても便利 16

Slide 102

Slide 102 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 インクリメンタルな開発 • Cコンパイラ、とても高度なので最初からすべての機能を作るのは難しい • 難易度的な問題とモチベーション的な問題 • 低レイヤを知りたい人のためのCコンパイラ作成入門では インクリメンタルに開発を進める • 少しずつ機能を作っていく • テストコードもいっしょに作っていく • テストコードがとても便利 • 実装時: 「このコミットで何を作っているか」がわかる, C言語の細かい仕様がわかる 16

Slide 103

Slide 103 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 インクリメンタルな開発 • Cコンパイラ、とても高度なので最初からすべての機能を作るのは難しい • 難易度的な問題とモチベーション的な問題 • 低レイヤを知りたい人のためのCコンパイラ作成入門では インクリメンタルに開発を進める • 少しずつ機能を作っていく • テストコードもいっしょに作っていく • テストコードがとても便利 • 実装時: 「このコミットで何を作っているか」がわかる, C言語の細かい仕様がわかる • リファクタリング時: ふつうに便利 16

Slide 104

Slide 104 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 インクリメンタルな開発 • Cコンパイラ、とても高度なので最初からすべての機能を作るのは難しい • 難易度的な問題とモチベーション的な問題 • 低レイヤを知りたい人のためのCコンパイラ作成入門では インクリメンタルに開発を進める • 少しずつ機能を作っていく • テストコードもいっしょに作っていく • テストコードがとても便利 • 実装時: 「このコミットで何を作っているか」がわかる, C言語の細かい仕様がわかる • リファクタリング時: ふつうに便利 • AI開発的な観点: 正しい実装ができたかの担保に便利 16

Slide 105

Slide 105 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 プログラム実行と終了コード 17

Slide 106

Slide 106 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 プログラム実行と終了コード • C言語というと Hello World が最初のプログラムの感じがある 17

Slide 107

Slide 107 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 プログラム実行と終了コード • C言語というと Hello World が最初のプログラムの感じがある • けど、画面に文字を表示するって実は結構たいへん 17

Slide 108

Slide 108 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 プログラム実行と終了コード • C言語というと Hello World が最初のプログラムの感じがある • けど、画面に文字を表示するって実は結構たいへん • 最初のうちは終了コードを出力に使う 17

Slide 109

Slide 109 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 プログラム実行と終了コード • C言語というと Hello World が最初のプログラムの感じがある • けど、画面に文字を表示するって実は結構たいへん • 最初のうちは終了コードを出力に使う • PHPでも exit(0) とかするアレ 17

Slide 110

Slide 110 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 プログラム実行と終了コード • C言語というと Hello World が最初のプログラムの感じがある • けど、画面に文字を表示するって実は結構たいへん • 最初のうちは終了コードを出力に使う • PHPでも exit(0) とかするアレ • 終了コードはシェルで $? で参照できる 17

Slide 111

Slide 111 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 プログラム実行と終了コード • C言語というと Hello World が最初のプログラムの感じがある • けど、画面に文字を表示するって実は結構たいへん • 最初のうちは終了コードを出力に使う • PHPでも exit(0) とかするアレ • 終了コードはシェルで $? で参照できる 17 ➜ cat the-anser.php

Slide 112

Slide 112 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: 最初のコンパイラ

Slide 113

Slide 113 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: 最初のコンパイラ • 極限までシンプルなCコンパイラ

Slide 114

Slide 114 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: 最初のコンパイラ • 極限までシンプルなCコンパイラ • 実装する機能は整数だけ

Slide 115

Slide 115 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: 最初のコンパイラ • 極限までシンプルなCコンパイラ • 実装する機能は整数だけ • 整数を(終了コードとして)出力する実行ファイルを作る

Slide 116

Slide 116 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: 最初のコンパイラ • 極限までシンプルなCコンパイラ • 実装する機能は整数だけ • 整数を(終了コードとして)出力する実行ファイルを作る • exit(42); よりもっとシンプルな形

Slide 117

Slide 117 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: 最初のコンパイラ • 極限までシンプルなCコンパイラ • 実装する機能は整数だけ • 整数を(終了コードとして)出力する実行ファイルを作る • exit(42); よりもっとシンプルな形 • 引数としてC言語(みたいなの)のソースコードを受け取り、 アセンブリ言語のソースコードを出力するCコンパイラ

Slide 118

Slide 118 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: 最初のコンパイラ • 極限までシンプルなCコンパイラ • 実装する機能は整数だけ • 整数を(終了コードとして)出力する実行ファイルを作る • exit(42); よりもっとシンプルな形 • 引数としてC言語(みたいなの)のソースコードを受け取り、 アセンブリ言語のソースコードを出力するCコンパイラ ➜ php pcc.php 42 > tmp.s ➜ cc -o tmp tmp.s ➜ ./tmp ➜ echo $? 42 コンパイラ

Slide 119

Slide 119 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: 最初のコンパイラ • 極限までシンプルなCコンパイラ • 実装する機能は整数だけ • 整数を(終了コードとして)出力する実行ファイルを作る • exit(42); よりもっとシンプルな形 • 引数としてC言語(みたいなの)のソースコードを受け取り、 アセンブリ言語のソースコードを出力するCコンパイラ ➜ php pcc.php 42 > tmp.s ➜ cc -o tmp tmp.s ➜ ./tmp ➜ echo $? 42 コンパイラ C言語の ソースコード

Slide 120

Slide 120 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: 最初のコンパイラ • 極限までシンプルなCコンパイラ • 実装する機能は整数だけ • 整数を(終了コードとして)出力する実行ファイルを作る • exit(42); よりもっとシンプルな形 • 引数としてC言語(みたいなの)のソースコードを受け取り、 アセンブリ言語のソースコードを出力するCコンパイラ ➜ php pcc.php 42 > tmp.s ➜ cc -o tmp tmp.s ➜ ./tmp ➜ echo $? 42 コンパイラ C言語の ソースコード アセンブリ言語の ソースコード

Slide 121

Slide 121 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: 最初のコンパイラ • 極限までシンプルなCコンパイラ • 実装する機能は整数だけ • 整数を(終了コードとして)出力する実行ファイルを作る • exit(42); よりもっとシンプルな形 • 引数としてC言語(みたいなの)のソースコードを受け取り、 アセンブリ言語のソースコードを出力するCコンパイラ • アセンブリ言語のソースコードをアセンブルしてできた実行ファイルは 終了コードとしてソースコードの整数をそのまま返す ➜ php pcc.php 42 > tmp.s ➜ cc -o tmp tmp.s ➜ ./tmp ➜ echo $? 42 コンパイラ C言語の ソースコード アセンブリ言語の ソースコード

Slide 122

Slide 122 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: 最初のコンパイラ • 極限までシンプルなCコンパイラ • 実装する機能は整数だけ • 整数を(終了コードとして)出力する実行ファイルを作る • exit(42); よりもっとシンプルな形 • 引数としてC言語(みたいなの)のソースコードを受け取り、 アセンブリ言語のソースコードを出力するCコンパイラ • アセンブリ言語のソースコードをアセンブルしてできた実行ファイルは 終了コードとしてソースコードの整数をそのまま返す ➜ php pcc.php 42 > tmp.s ➜ cc -o tmp tmp.s ➜ ./tmp ➜ echo $? 42 コンパイラ C言語の ソースコード アセンブル アセンブリ言語の ソースコード

Slide 123

Slide 123 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: 最初のコンパイラ • 極限までシンプルなCコンパイラ • 実装する機能は整数だけ • 整数を(終了コードとして)出力する実行ファイルを作る • exit(42); よりもっとシンプルな形 • 引数としてC言語(みたいなの)のソースコードを受け取り、 アセンブリ言語のソースコードを出力するCコンパイラ • アセンブリ言語のソースコードをアセンブルしてできた実行ファイルは 終了コードとしてソースコードの整数をそのまま返す ➜ php pcc.php 42 > tmp.s ➜ cc -o tmp tmp.s ➜ ./tmp ➜ echo $? 42 コンパイラ C言語の ソースコード 実行ファイル アセンブル アセンブリ言語の ソースコード

Slide 124

Slide 124 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: 最初のコンパイラ • 極限までシンプルなCコンパイラ • 実装する機能は整数だけ • 整数を(終了コードとして)出力する実行ファイルを作る • exit(42); よりもっとシンプルな形 • 引数としてC言語(みたいなの)のソースコードを受け取り、 アセンブリ言語のソースコードを出力するCコンパイラ • アセンブリ言語のソースコードをアセンブルしてできた実行ファイルは 終了コードとしてソースコードの整数をそのまま返す ➜ php pcc.php 42 > tmp.s ➜ cc -o tmp tmp.s ➜ ./tmp ➜ echo $? 42 コンパイラ C言語の ソースコード 終了コード 実行ファイル アセンブル アセンブリ言語の ソースコード

Slide 125

Slide 125 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 ➜ php pcc.php 42 > tmp.s ➜ cc -o tmp tmp.s ➜ ./tmp ➜ echo $? 42 出力すべきアセンブリ言語のソースコード 19

Slide 126

Slide 126 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 ➜ php pcc.php 42 > tmp.s ➜ cc -o tmp tmp.s ➜ ./tmp ➜ echo $? 42 出力すべきアセンブリ言語のソースコード 19 42 を出力する 実行ファイル

Slide 127

Slide 127 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 ➜ php pcc.php 42 > tmp.s ➜ cc -o tmp tmp.s ➜ ./tmp ➜ echo $? 42 出力すべきアセンブリ言語のソースコード 19 アセンブリ言語の ソースコード 42 を出力する 実行ファイル

Slide 128

Slide 128 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 .globl main main: mov $42, %rax ret ➜ php pcc.php 42 > tmp.s ➜ cc -o tmp tmp.s ➜ ./tmp ➜ echo $? 42 出力すべきアセンブリ言語のソースコード 19 アセンブリ言語の ソースコード 42 を出力する 実行ファイル

Slide 129

Slide 129 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 .globl main main: mov $42, %rax ret ➜ php pcc.php 42 > tmp.s ➜ cc -o tmp tmp.s ➜ ./tmp ➜ echo $? 42 出力すべきアセンブリ言語のソースコード • アセンブリ言語のコードで42のところを動的に出力す れば「整数だけ実装されたCコンパイラ」になる 19 アセンブリ言語の ソースコード 42 を出力する 実行ファイル

Slide 130

Slide 130 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 .globl main main: mov $42, %rax ret ➜ php pcc.php 42 > tmp.s ➜ cc -o tmp tmp.s ➜ ./tmp ➜ echo $? 42 出力すべきアセンブリ言語のソースコード • アセンブリ言語のコードで42のところを動的に出力す れば「整数だけ実装されたCコンパイラ」になる • レジスタ 19 アセンブリ言語の ソースコード 42 を出力する 実行ファイル

Slide 131

Slide 131 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 .globl main main: mov $42, %rax ret ➜ php pcc.php 42 > tmp.s ➜ cc -o tmp tmp.s ➜ ./tmp ➜ echo $? 42 出力すべきアセンブリ言語のソースコード • アセンブリ言語のコードで42のところを動的に出力す れば「整数だけ実装されたCコンパイラ」になる • レジスタ • %rax というのが rax レジスタのこと 19 アセンブリ言語の ソースコード 42 を出力する 実行ファイル

Slide 132

Slide 132 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 .globl main main: mov $42, %rax ret ➜ php pcc.php 42 > tmp.s ➜ cc -o tmp tmp.s ➜ ./tmp ➜ echo $? 42 出力すべきアセンブリ言語のソースコード • アセンブリ言語のコードで42のところを動的に出力す れば「整数だけ実装されたCコンパイラ」になる • レジスタ • %rax というのが rax レジスタのこと • CPUが持っている変数みたいなもの 19 アセンブリ言語の ソースコード 42 を出力する 実行ファイル

Slide 133

Slide 133 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 .globl main main: mov $42, %rax ret ➜ php pcc.php 42 > tmp.s ➜ cc -o tmp tmp.s ➜ ./tmp ➜ echo $? 42 出力すべきアセンブリ言語のソースコード • アセンブリ言語のコードで42のところを動的に出力す れば「整数だけ実装されたCコンパイラ」になる • レジスタ • %rax というのが rax レジスタのこと • CPUが持っている変数みたいなもの • プログラム実行が終わった時の rax レジスタの 中身が実行ファイルの終了コードになる (LinuxやmacOSでは) 19 アセンブリ言語の ソースコード 42 を出力する 実行ファイル

Slide 134

Slide 134 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 .globl main main: mov $42, %rax ret ➜ php pcc.php 42 > tmp.s ➜ cc -o tmp tmp.s ➜ ./tmp ➜ echo $? 42 出力すべきアセンブリ言語のソースコード • アセンブリ言語のコードで42のところを動的に出力す れば「整数だけ実装されたCコンパイラ」になる • レジスタ • %rax というのが rax レジスタのこと • CPUが持っている変数みたいなもの • プログラム実行が終わった時の rax レジスタの 中身が実行ファイルの終了コードになる (LinuxやmacOSでは) • rax レジスタに 42 を入れて ret すれば良い 19 アセンブリ言語の ソースコード 42 を出力する 実行ファイル

Slide 135

Slide 135 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 .globl main main: mov $42, %rax ret ➜ php pcc.php 42 > tmp.s ➜ cc -o tmp tmp.s ➜ ./tmp ➜ echo $? 42 出力すべきアセンブリ言語のソースコード • アセンブリ言語のコードで42のところを動的に出力す れば「整数だけ実装されたCコンパイラ」になる • レジスタ • %rax というのが rax レジスタのこと • CPUが持っている変数みたいなもの • プログラム実行が終わった時の rax レジスタの 中身が実行ファイルの終了コードになる (LinuxやmacOSでは) • rax レジスタに 42 を入れて ret すれば良い • mov $42, %rax = rax レジスタに42を入れる 19 アセンブリ言語の ソースコード 42 を出力する 実行ファイル

Slide 136

Slide 136 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: PHPでの実装 20

Slide 137

Slide 137 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: PHPでの実装 20 return main($argc, $argv); function main(int $argc = null, array $argv = null): int { if ($argc != 2) { printf("引数の個数が正しくありません\n"); return 1; } printf(".globl main\n"); printf("main:\n"); printf(" mov %%rax, \$%d\n", intval($argv[1])); printf(" ret\n"); return 0; }

Slide 138

Slide 138 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: PHPでの実装 • めちゃシンプル 20 return main($argc, $argv); function main(int $argc = null, array $argv = null): int { if ($argc != 2) { printf("引数の個数が正しくありません\n"); return 1; } printf(".globl main\n"); printf("main:\n"); printf(" mov %%rax, \$%d\n", intval($argv[1])); printf(" ret\n"); return 0; }

Slide 139

Slide 139 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: PHPでの実装 • めちゃシンプル • ほぼ printf() 20 return main($argc, $argv); function main(int $argc = null, array $argv = null): int { if ($argc != 2) { printf("引数の個数が正しくありません\n"); return 1; } printf(".globl main\n"); printf("main:\n"); printf(" mov %%rax, \$%d\n", intval($argv[1])); printf(" ret\n"); return 0; }

Slide 140

Slide 140 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: PHPでの実装 • めちゃシンプル • ほぼ printf() 20 return main($argc, $argv); function main(int $argc = null, array $argv = null): int { if ($argc != 2) { printf("引数の個数が正しくありません\n"); return 1; } printf(".globl main\n"); printf("main:\n"); printf(" mov %%rax, \$%d\n", intval($argv[1])); printf(" ret\n"); return 0; } .globl main main: mov %rax, $42 ret • ↑を出力する

Slide 141

Slide 141 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: PHPでの実装 • めちゃシンプル • ほぼ printf() 20 return main($argc, $argv); function main(int $argc = null, array $argv = null): int { if ($argc != 2) { printf("引数の個数が正しくありません\n"); return 1; } printf(".globl main\n"); printf("main:\n"); printf(" mov %%rax, \$%d\n", intval($argv[1])); printf(" ret\n"); return 0; } .globl main main: mov %rax, $42 ret • ↑を出力する • これが第一歩目のCコンパイラ

Slide 142

Slide 142 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: テストコード • このテキスト、テストコードが付いてくる 21

Slide 143

Slide 143 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: テストコード • このテキスト、テストコードが付いてくる 21 #!/bin/bash assert() { expected="$1" input="$2" php pcc.php "$input" > tmp.s cc -o tmp tmp.s ./tmp actual="$?" if [ "$actual" = "$expected" ]; then echo "$input => $actual" else echo "$input => $expected expected, but got $actual" exit 1 fi } assert 0 0 assert 42 42 echo OK

Slide 144

Slide 144 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: テストコード • このテキスト、テストコードが付いてくる • シェルスクリプトで assert() を定義 21 #!/bin/bash assert() { expected="$1" input="$2" php pcc.php "$input" > tmp.s cc -o tmp tmp.s ./tmp actual="$?" if [ "$actual" = "$expected" ]; then echo "$input => $actual" else echo "$input => $expected expected, but got $actual" exit 1 fi } assert 0 0 assert 42 42 echo OK

Slide 145

Slide 145 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: テストコード • このテキスト、テストコードが付いてくる • シェルスクリプトで assert() を定義 • 引数を2つとる 21 #!/bin/bash assert() { expected="$1" input="$2" php pcc.php "$input" > tmp.s cc -o tmp tmp.s ./tmp actual="$?" if [ "$actual" = "$expected" ]; then echo "$input => $actual" else echo "$input => $expected expected, but got $actual" exit 1 fi } assert 0 0 assert 42 42 echo OK

Slide 146

Slide 146 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: テストコード • このテキスト、テストコードが付いてくる • シェルスクリプトで assert() を定義 • 引数を2つとる • 1つめは期待する値(expected) 21 #!/bin/bash assert() { expected="$1" input="$2" php pcc.php "$input" > tmp.s cc -o tmp tmp.s ./tmp actual="$?" if [ "$actual" = "$expected" ]; then echo "$input => $actual" else echo "$input => $expected expected, but got $actual" exit 1 fi } assert 0 0 assert 42 42 echo OK

Slide 147

Slide 147 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: テストコード • このテキスト、テストコードが付いてくる • シェルスクリプトで assert() を定義 • 引数を2つとる • 1つめは期待する値(expected) • 2つめはソースコード 21 #!/bin/bash assert() { expected="$1" input="$2" php pcc.php "$input" > tmp.s cc -o tmp tmp.s ./tmp actual="$?" if [ "$actual" = "$expected" ]; then echo "$input => $actual" else echo "$input => $expected expected, but got $actual" exit 1 fi } assert 0 0 assert 42 42 echo OK

Slide 148

Slide 148 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: テストコード • このテキスト、テストコードが付いてくる • シェルスクリプトで assert() を定義 • 引数を2つとる • 1つめは期待する値(expected) • 2つめはソースコード • ソースコードをコンパイル・実行して期待する値と 比較する 21 #!/bin/bash assert() { expected="$1" input="$2" php pcc.php "$input" > tmp.s cc -o tmp tmp.s ./tmp actual="$?" if [ "$actual" = "$expected" ]; then echo "$input => $actual" else echo "$input => $expected expected, but got $actual" exit 1 fi } assert 0 0 assert 42 42 echo OK

Slide 149

Slide 149 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP1: テストコード • このテキスト、テストコードが付いてくる • シェルスクリプトで assert() を定義 • 引数を2つとる • 1つめは期待する値(expected) • 2つめはソースコード • ソースコードをコンパイル・実行して期待する値と 比較する • テストケースとして 0 と 42 をコンパイルして 実行、期待する値と比較している 21 #!/bin/bash assert() { expected="$1" input="$2" php pcc.php "$input" > tmp.s cc -o tmp tmp.s ./tmp actual="$?" if [ "$actual" = "$expected" ]; then echo "$input => $actual" else echo "$input => $expected expected, but got $actual" exit 1 fi } assert 0 0 assert 42 42 echo OK

Slide 150

Slide 150 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP2: 加減算の実装 • STEP1で整数だけ扱えるコンパイラができた 22

Slide 151

Slide 151 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP2: 加減算の実装 • STEP1で整数だけ扱えるコンパイラができた • STEP2として加減算を実装する 22

Slide 152

Slide 152 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP2: 加減算の実装 • STEP1で整数だけ扱えるコンパイラができた • STEP2として加減算を実装する 22 ➜ php pcc.php '1+5-2' > addsub.s ➜ cc -o addsub addsub.s ➜ ./addsub ➜ echo $? 4

Slide 153

Slide 153 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP2: 加減算の実装 • STEP1で整数だけ扱えるコンパイラができた • STEP2として加減算を実装する • アセンブリ言語に add, sub がある 22 ➜ php pcc.php '1+5-2' > addsub.s ➜ cc -o addsub addsub.s ➜ ./addsub ➜ echo $? 4

Slide 154

Slide 154 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP2: 加減算の実装 • STEP1で整数だけ扱えるコンパイラができた • STEP2として加減算を実装する • アセンブリ言語に add, sub がある • rax レジスタに指定した値を足す/引く 22 ➜ php pcc.php '1+5-2' > addsub.s ➜ cc -o addsub addsub.s ➜ ./addsub ➜ echo $? 4

Slide 155

Slide 155 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP2: 加減算の実装 • STEP1で整数だけ扱えるコンパイラができた • STEP2として加減算を実装する • アセンブリ言語に add, sub がある • rax レジスタに指定した値を足す/引く • 1 + 5 - 2 ならアセンブリ言語でこうなる: 22 ➜ php pcc.php '1+5-2' > addsub.s ➜ cc -o addsub addsub.s ➜ ./addsub ➜ echo $? 4

Slide 156

Slide 156 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP2: 加減算の実装 • STEP1で整数だけ扱えるコンパイラができた • STEP2として加減算を実装する • アセンブリ言語に add, sub がある • rax レジスタに指定した値を足す/引く • 1 + 5 - 2 ならアセンブリ言語でこうなる: 22 .globl main main: mov $1, %rax add $5, %rax sub $2, %rax ret ➜ php pcc.php '1+5-2' > addsub.s ➜ cc -o addsub addsub.s ➜ ./addsub ➜ echo $? 4

Slide 157

Slide 157 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP2: 加減算の実装 • STEP1で整数だけ扱えるコンパイラができた • STEP2として加減算を実装する • アセンブリ言語に add, sub がある • rax レジスタに指定した値を足す/引く • 1 + 5 - 2 ならアセンブリ言語でこうなる: • raxレジスタに 1 を入れる 22 .globl main main: mov $1, %rax add $5, %rax sub $2, %rax ret ➜ php pcc.php '1+5-2' > addsub.s ➜ cc -o addsub addsub.s ➜ ./addsub ➜ echo $? 4

Slide 158

Slide 158 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP2: 加減算の実装 • STEP1で整数だけ扱えるコンパイラができた • STEP2として加減算を実装する • アセンブリ言語に add, sub がある • rax レジスタに指定した値を足す/引く • 1 + 5 - 2 ならアセンブリ言語でこうなる: • raxレジスタに 1 を入れる • raxレジスタに 5 を足す 22 .globl main main: mov $1, %rax add $5, %rax sub $2, %rax ret ➜ php pcc.php '1+5-2' > addsub.s ➜ cc -o addsub addsub.s ➜ ./addsub ➜ echo $? 4

Slide 159

Slide 159 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP2: 加減算の実装 • STEP1で整数だけ扱えるコンパイラができた • STEP2として加減算を実装する • アセンブリ言語に add, sub がある • rax レジスタに指定した値を足す/引く • 1 + 5 - 2 ならアセンブリ言語でこうなる: • raxレジスタに 1 を入れる • raxレジスタに 5 を足す • raxレジスタから 2 を引く 22 .globl main main: mov $1, %rax add $5, %rax sub $2, %rax ret ➜ php pcc.php '1+5-2' > addsub.s ➜ cc -o addsub addsub.s ➜ ./addsub ➜ echo $? 4

Slide 160

Slide 160 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP2: 加減算の実装 • STEP1で整数だけ扱えるコンパイラができた • STEP2として加減算を実装する • アセンブリ言語に add, sub がある • rax レジスタに指定した値を足す/引く • 1 + 5 - 2 ならアセンブリ言語でこうなる: • raxレジスタに 1 を入れる • raxレジスタに 5 を足す • raxレジスタから 2 を引く • プログラム終了 (→ 終了コードとして 1 + 5 - 2 の計算結果 4 が返る) 22 .globl main main: mov $1, %rax add $5, %rax sub $2, %rax ret ➜ php pcc.php '1+5-2' > addsub.s ➜ cc -o addsub addsub.s ➜ ./addsub ➜ echo $? 4

Slide 161

Slide 161 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP2: 加減算の実装 23 [$number, $string] = extLeadNumber($argv[1]); printf(" mov\$%d%%rax\n", $number); while(strlen($string)){ if (str_starts_with($string, '+')){ $string = substr($string, 1); [$number, $string] = extLeadNumber($string); printf(" add\$%d, %%rax\n", $number); continue; } if (str_starts_with($string, '-')){ $string = substr($string, 1); [$number, $string] = extLeadNumber($string); printf(" sub \$%d, %%rax\n", $number); continue; } fprintf(STDERR, "予期しない文字です: %s\n", $string); return 1; } printf(" ret\n");

Slide 162

Slide 162 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP2: 加減算の実装 • 与えられたソースコードを前から順に 見て処理していく 23 [$number, $string] = extLeadNumber($argv[1]); printf(" mov\$%d%%rax\n", $number); while(strlen($string)){ if (str_starts_with($string, '+')){ $string = substr($string, 1); [$number, $string] = extLeadNumber($string); printf(" add\$%d, %%rax\n", $number); continue; } if (str_starts_with($string, '-')){ $string = substr($string, 1); [$number, $string] = extLeadNumber($string); printf(" sub \$%d, %%rax\n", $number); continue; } fprintf(STDERR, "予期しない文字です: %s\n", $string); return 1; } printf(" ret\n");

Slide 163

Slide 163 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP2: 加減算の実装 • 与えられたソースコードを前から順に 見て処理していく 23 [$number, $string] = extLeadNumber($argv[1]); printf(" mov\$%d%%rax\n", $number); while(strlen($string)){ if (str_starts_with($string, '+')){ $string = substr($string, 1); [$number, $string] = extLeadNumber($string); printf(" add\$%d, %%rax\n", $number); continue; } if (str_starts_with($string, '-')){ $string = substr($string, 1); [$number, $string] = extLeadNumber($string); printf(" sub \$%d, %%rax\n", $number); continue; } fprintf(STDERR, "予期しない文字です: %s\n", $string); return 1; } printf(" ret\n"); .globl main main: mov $1, %rax add $5, %rax sub $2, %rax ret 1 + 5 - 2

Slide 164

Slide 164 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP2: 加減算の実装 • 与えられたソースコードを前から順に 見て処理していく • ソースコード先頭の数字と残りの文 字列を取得 23 [$number, $string] = extLeadNumber($argv[1]); printf(" mov\$%d%%rax\n", $number); while(strlen($string)){ if (str_starts_with($string, '+')){ $string = substr($string, 1); [$number, $string] = extLeadNumber($string); printf(" add\$%d, %%rax\n", $number); continue; } if (str_starts_with($string, '-')){ $string = substr($string, 1); [$number, $string] = extLeadNumber($string); printf(" sub \$%d, %%rax\n", $number); continue; } fprintf(STDERR, "予期しない文字です: %s\n", $string); return 1; } printf(" ret\n"); .globl main main: mov $1, %rax add $5, %rax sub $2, %rax ret 1 + 5 - 2

Slide 165

Slide 165 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP2: 加減算の実装 • 与えられたソースコードを前から順に 見て処理していく • ソースコード先頭の数字と残りの文 字列を取得 • 数字を rax レジスタに入れるコード を出力 23 [$number, $string] = extLeadNumber($argv[1]); printf(" mov\$%d%%rax\n", $number); while(strlen($string)){ if (str_starts_with($string, '+')){ $string = substr($string, 1); [$number, $string] = extLeadNumber($string); printf(" add\$%d, %%rax\n", $number); continue; } if (str_starts_with($string, '-')){ $string = substr($string, 1); [$number, $string] = extLeadNumber($string); printf(" sub \$%d, %%rax\n", $number); continue; } fprintf(STDERR, "予期しない文字です: %s\n", $string); return 1; } printf(" ret\n"); .globl main main: mov $1, %rax add $5, %rax sub $2, %rax ret 1 + 5 - 2

Slide 166

Slide 166 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP2: 加減算の実装 • 与えられたソースコードを前から順に 見て処理していく • ソースコード先頭の数字と残りの文 字列を取得 • 数字を rax レジスタに入れるコード を出力 • "+" 数字や、"-" 数字 を繰り返す add %rax, $[数字] sub %rax, $[数字] 23 [$number, $string] = extLeadNumber($argv[1]); printf(" mov\$%d%%rax\n", $number); while(strlen($string)){ if (str_starts_with($string, '+')){ $string = substr($string, 1); [$number, $string] = extLeadNumber($string); printf(" add\$%d, %%rax\n", $number); continue; } if (str_starts_with($string, '-')){ $string = substr($string, 1); [$number, $string] = extLeadNumber($string); printf(" sub \$%d, %%rax\n", $number); continue; } fprintf(STDERR, "予期しない文字です: %s\n", $string); return 1; } printf(" ret\n"); .globl main main: mov $1, %rax add $5, %rax sub $2, %rax ret 1 + 5 - 2

Slide 167

Slide 167 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP2: 加減算の実装 • 与えられたソースコードを前から順に 見て処理していく • ソースコード先頭の数字と残りの文 字列を取得 • 数字を rax レジスタに入れるコード を出力 • "+" 数字や、"-" 数字 を繰り返す add %rax, $[数字] sub %rax, $[数字] • ret を出力 23 [$number, $string] = extLeadNumber($argv[1]); printf(" mov\$%d%%rax\n", $number); while(strlen($string)){ if (str_starts_with($string, '+')){ $string = substr($string, 1); [$number, $string] = extLeadNumber($string); printf(" add\$%d, %%rax\n", $number); continue; } if (str_starts_with($string, '-')){ $string = substr($string, 1); [$number, $string] = extLeadNumber($string); printf(" sub \$%d, %%rax\n", $number); continue; } fprintf(STDERR, "予期しない文字です: %s\n", $string); return 1; } printf(" ret\n"); .globl main main: mov $1, %rax add $5, %rax sub $2, %rax ret 1 + 5 - 2

Slide 168

Slide 168 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP2: テストコード 24 #!/bin/bash : assert 0 0 assert 42 42 assert 21 "5+20-4" echo OK

Slide 169

Slide 169 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP2: テストコード • 実装した加減算をテストケースに追加 24 #!/bin/bash : assert 0 0 assert 42 42 assert 21 "5+20-4" echo OK

Slide 170

Slide 170 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 STEP2: テストコード • 実装した加減算をテストケースに追加 • 整数と加減算を処理できるCコンパイラが完成 24 #!/bin/bash : assert 0 0 assert 42 42 assert 21 "5+20-4" echo OK

Slide 171

Slide 171 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 25

Slide 172

Slide 172 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 テキストベースのパーサの限界 • 加減算ではソースコードを文字列として扱い、 先頭から1文字ずつ見てアセンブリ言語のソースコードに 変換していった 26

Slide 173

Slide 173 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 テキストベースのパーサの限界 • 加減算ではソースコードを文字列として扱い、 先頭から1文字ずつ見てアセンブリ言語のソースコードに 変換していった • 1 + 5 - 2 26

Slide 174

Slide 174 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 テキストベースのパーサの限界 • 加減算ではソースコードを文字列として扱い、 先頭から1文字ずつ見てアセンブリ言語のソースコードに 変換していった • 1 + 5 - 2 26 .globl main main: mov $1, %rax add $5, %rax sub $2, %rax ret

Slide 175

Slide 175 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 テキストベースのパーサの限界 • 加減算ではソースコードを文字列として扱い、 先頭から1文字ずつ見てアセンブリ言語のソースコードに 変換していった • 1 + 5 - 2 • 数字や記号が入ってくる順番とアセンブリ言語として書き出す 順番が同じだった 26 .globl main main: mov $1, %rax add $5, %rax sub $2, %rax ret

Slide 176

Slide 176 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 テキストベースのパーサの限界 • 加減算ではソースコードを文字列として扱い、 先頭から1文字ずつ見てアセンブリ言語のソースコードに 変換していった • 1 + 5 - 2 • 数字や記号が入ってくる順番とアセンブリ言語として書き出す 順番が同じだった • カッコ () や乗除が入ってくるとそうはいかなくなる 26 .globl main main: mov $1, %rax add $5, %rax sub $2, %rax ret

Slide 177

Slide 177 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 テキストベースのパーサの限界 • 加減算ではソースコードを文字列として扱い、 先頭から1文字ずつ見てアセンブリ言語のソースコードに 変換していった • 1 + 5 - 2 • 数字や記号が入ってくる順番とアセンブリ言語として書き出す 順番が同じだった • カッコ () や乗除が入ってくるとそうはいかなくなる • 5 + 6 * 7 26 .globl main main: mov $1, %rax add $5, %rax sub $2, %rax ret

Slide 178

Slide 178 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 テキストベースのパーサの限界 • 加減算ではソースコードを文字列として扱い、 先頭から1文字ずつ見てアセンブリ言語のソースコードに 変換していった • 1 + 5 - 2 • 数字や記号が入ってくる順番とアセンブリ言語として書き出す 順番が同じだった • カッコ () や乗除が入ってくるとそうはいかなくなる • 5 + 6 * 7 26 .globl main main: mov $1, %rax add $5, %rax sub $2, %rax ret .globl main main: mov $6, %rax imul $7, %rax add $5, %rax ret

Slide 179

Slide 179 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 言語仕様を効率的に実装する工夫 • 今回のCコンパイラは3つの役割にわけてソースコードをコンパイルする 27

Slide 180

Slide 180 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 言語仕様を効率的に実装する工夫 • 今回のCコンパイラは3つの役割にわけてソースコードをコンパイルする • トークナイザ 27

Slide 181

Slide 181 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 言語仕様を効率的に実装する工夫 • 今回のCコンパイラは3つの役割にわけてソースコードをコンパイルする • トークナイザ • パーサ 27

Slide 182

Slide 182 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 言語仕様を効率的に実装する工夫 • 今回のCコンパイラは3つの役割にわけてソースコードをコンパイルする • トークナイザ • パーサ • コードジェネレータ 27

Slide 183

Slide 183 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 言語仕様を効率的に実装する工夫 • 今回のCコンパイラは3つの役割にわけてソースコードをコンパイルする • トークナイザ • パーサ • コードジェネレータ • 世の中のコンパイラはだいたいこの3つの役割で実現されている 27

Slide 184

Slide 184 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 プログラム言語っぽさ 28

Slide 185

Slide 185 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 プログラム言語っぽさ • トークナイザ → パーサ → コードジェネレータ 28

Slide 186

Slide 186 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 プログラム言語っぽさ • トークナイザ → パーサ → コードジェネレータ • プログラム言語ぽいのはトークナイザとパーサ 28

Slide 187

Slide 187 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 プログラム言語っぽさ • トークナイザ → パーサ → コードジェネレータ • プログラム言語ぽいのはトークナイザとパーサ • = 言語仕様を実装しているのはトークナイザとパーサ 28

Slide 188

Slide 188 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 プログラム言語っぽさ • トークナイザ → パーサ → コードジェネレータ • プログラム言語ぽいのはトークナイザとパーサ • = 言語仕様を実装しているのはトークナイザとパーサ • コードジェネレータはCPUに依存する 28

Slide 189

Slide 189 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 プログラム言語っぽさ • トークナイザ → パーサ → コードジェネレータ • プログラム言語ぽいのはトークナイザとパーサ • = 言語仕様を実装しているのはトークナイザとパーサ • コードジェネレータはCPUに依存する • Intel用コードジェネレータ, Apple Silicon用コードジェネレータ, … のように 差し替えると別のCPU用のコンパイラになる 28

Slide 190

Slide 190 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 プログラム言語っぽさ • トークナイザ → パーサ → コードジェネレータ • プログラム言語ぽいのはトークナイザとパーサ • = 言語仕様を実装しているのはトークナイザとパーサ • コードジェネレータはCPUに依存する • Intel用コードジェネレータ, Apple Silicon用コードジェネレータ, … のように 差し替えると別のCPU用のコンパイラになる • トークナイザとパーサの実装はCPUの知識が無くても何とかなる 28

Slide 191

Slide 191 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 プログラム言語っぽさ • トークナイザ → パーサ → コードジェネレータ • プログラム言語ぽいのはトークナイザとパーサ • = 言語仕様を実装しているのはトークナイザとパーサ • コードジェネレータはCPUに依存する • Intel用コードジェネレータ, Apple Silicon用コードジェネレータ, … のように 差し替えると別のCPU用のコンパイラになる • トークナイザとパーサの実装はCPUの知識が無くても何とかなる • ので、CPUに詳しくない方は、まずはコードジェネレータのところは「そういうもん」と思って そのまま写しちゃっても良いのでは 28

Slide 192

Slide 192 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 プログラム言語っぽさ • トークナイザ → パーサ → コードジェネレータ • プログラム言語ぽいのはトークナイザとパーサ • = 言語仕様を実装しているのはトークナイザとパーサ • コードジェネレータはCPUに依存する • Intel用コードジェネレータ, Apple Silicon用コードジェネレータ, … のように 差し替えると別のCPU用のコンパイラになる • トークナイザとパーサの実装はCPUの知識が無くても何とかなる • ので、CPUに詳しくない方は、まずはコードジェネレータのところは「そういうもん」と思って そのまま写しちゃっても良いのでは • それでも十分プログラム言語づくりっぽい面白さは味わえる 28

Slide 193

Slide 193 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 トークナイザ 29

Slide 194

Slide 194 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 トークナイザ • ソースコードを分割してトークン化する 29

Slide 195

Slide 195 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 トークナイザ • ソースコードを分割してトークン化する • トークナイズ 29

Slide 196

Slide 196 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 トークナイザ • ソースコードを分割してトークン化する • トークナイズ • 字句解析 29

Slide 197

Slide 197 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 トークナイザ • ソースコードを分割してトークン化する • トークナイズ • 字句解析 • トークンの種類 29

Slide 198

Slide 198 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 トークナイザ • ソースコードを分割してトークン化する • トークナイズ • 字句解析 • トークンの種類 識別子 変数名 関数名 29

Slide 199

Slide 199 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 トークナイザ • ソースコードを分割してトークン化する • トークナイズ • 字句解析 • トークンの種類 識別子 変数名 関数名 記号 != <= += ++ ( ) … 29

Slide 200

Slide 200 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 トークナイザ • ソースコードを分割してトークン化する • トークナイズ • 字句解析 • トークンの種類 識別子 変数名 関数名 記号 != <= += ++ ( ) … キーワード return if else … 29

Slide 201

Slide 201 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 トークナイザ • ソースコードを分割してトークン化する • トークナイズ • 字句解析 • トークンの種類 識別子 変数名 関数名 記号 != <= += ++ ( ) … キーワード return if else … 文字列, 数字 "Hello, World" 30 0xff 1.06e2 … 29

Slide 202

Slide 202 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 トークナイズ例 30 int main(void){ for (int i = 0; i <= 100; i++){ int FizzBuzz = i % 15; int Fizz = i % 3; int Buzz = i % 5; if (i % 15 == 0 && i != 0){ printf("FizzBuzz: %d\n", i); } else if (i % 3 == 0 && i != 0){ printf("Fizz: %d\n", i); } else if (i % 5 == 0 && i != 0){ printf("Buzz: %d\n", i); } else { printf("i: %d\n", i); } } return 0; }

Slide 203

Slide 203 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 トークナイズ例 30 int main(void){ for (int i = 0; i <= 100; i++){ int FizzBuzz = i % 15; int Fizz = i % 3; int Buzz = i % 5; if (i % 15 == 0 && i != 0){ printf("FizzBuzz: %d\n", i); } else if (i % 3 == 0 && i != 0){ printf("Fizz: %d\n", i); } else if (i % 5 == 0 && i != 0){ printf("Buzz: %d\n", i); } else { printf("i: %d\n", i); } } return 0; }

Slide 204

Slide 204 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 トークナイズ例 30 int main(void){ for (int i = 0; i <= 100; i++){ int FizzBuzz = i % 15; int Fizz = i % 3; int Buzz = i % 5; if (i % 15 == 0 && i != 0){ printf("FizzBuzz: %d\n", i); } else if (i % 3 == 0 && i != 0){ printf("Fizz: %d\n", i); } else if (i % 5 == 0 && i != 0){ printf("Buzz: %d\n", i); } else { printf("i: %d\n", i); } } return 0; } ※ 図は雰囲気です。実際のトークン列とは異なります。 キーワード int 識別子 main 記号 ( キーワード void 記号 ) 記号 { キーワード for 記号 ( キーワード int 識別子 i 記号 = 文字列・数字 0 記号 ; 識別子 i 記号 <= 文字列・数字 100 記号 ; 識別子 i 記号 ++ 記号 ; 記号 )

Slide 205

Slide 205 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 パーサ 31

Slide 206

Slide 206 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 パーサ • トークン列から抽象構文木(abstract syntax tree / AST)を作る 31

Slide 207

Slide 207 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 パーサ • トークン列から抽象構文木(abstract syntax tree / AST)を作る • 構文解析 31

Slide 208

Slide 208 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 パーサ • トークン列から抽象構文木(abstract syntax tree / AST)を作る • 構文解析 • 出現順 → 処理すべき順 の変換 31

Slide 209

Slide 209 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 パーサ • トークン列から抽象構文木(abstract syntax tree / AST)を作る • 構文解析 • 出現順 → 処理すべき順 の変換 31 キーワード for 記号 ( キーワード int 識別子 i 記号 = 文字列・数字 0 記号 ; 識別子 i 記号 <= 文字列・数字 100 記号 ; 識別子 i 記号 ++ 記号 ; 記号 )

Slide 210

Slide 210 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 パーサ • トークン列から抽象構文木(abstract syntax tree / AST)を作る • 構文解析 • 出現順 → 処理すべき順 の変換 31 /%@'03 /%@"44*(/ /%@7"3J /%@/6. JOJU /%@-& DPOE /%@7"3J /%@/6. /%@" JOD ※ 図は雰囲気です。実際のトークン列/ASTとは異なります。 キーワード for 記号 ( キーワード int 識別子 i 記号 = 文字列・数字 0 記号 ; 識別子 i 記号 <= 文字列・数字 100 記号 ; 識別子 i 記号 ++ 記号 ; 記号 )

Slide 211

Slide 211 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コードジェネレータ 32

Slide 212

Slide 212 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コードジェネレータ • ASTからアセンブリ言語のソース コードを作る 32

Slide 213

Slide 213 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コードジェネレータ • ASTからアセンブリ言語のソース コードを作る • ASTのノードタイプごとにアセン ブリ言語に変換していく 32

Slide 214

Slide 214 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コードジェネレータ • ASTからアセンブリ言語のソース コードを作る • ASTのノードタイプごとにアセン ブリ言語に変換していく • 処理すべき順に整理されているの で淡々と処理する感じになる 32

Slide 215

Slide 215 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コードジェネレータ • ASTからアセンブリ言語のソース コードを作る • ASTのノードタイプごとにアセン ブリ言語に変換していく • 処理すべき順に整理されているの で淡々と処理する感じになる 32 .file 1 "-" .local .L..0 .align 1 .data .L..0: .byte 72 ; H .byte 101 ; e .byte 108 ; l .byte 108 ; l .byte 111 ; o .byte 44 ; , .byte 32 ; .byte 87 ; W .byte 111 ; o .byte 114 ; r .byte 108 ; l .byte 100 ; d .byte 46 ; . .byte 0 ; \0 .globl main .text main: push %rbp mov %rsp, %rbp sub $0, %rsp .loc 1 43 lea .L..0(%rip), %rax push %rax pop %rdi mov $0, %rax call printf .L.return.main: mov %rbp, %rsp pop %rbp ret アセンブリ言語のソースコード

Slide 216

Slide 216 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コードジェネレータ • ASTからアセンブリ言語のソース コードを作る • ASTのノードタイプごとにアセン ブリ言語に変換していく • 処理すべき順に整理されているの で淡々と処理する感じになる • printf() の羅列 32 .file 1 "-" .local .L..0 .align 1 .data .L..0: .byte 72 ; H .byte 101 ; e .byte 108 ; l .byte 108 ; l .byte 111 ; o .byte 44 ; , .byte 32 ; .byte 87 ; W .byte 111 ; o .byte 114 ; r .byte 108 ; l .byte 100 ; d .byte 46 ; . .byte 0 ; \0 .globl main .text main: push %rbp mov %rsp, %rbp sub $0, %rsp .loc 1 43 lea .L..0(%rip), %rax push %rax pop %rdi mov $0, %rax call printf .L.return.main: mov %rbp, %rsp pop %rbp ret アセンブリ言語のソースコード

Slide 217

Slide 217 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 ここまでのまとめ 33 #include int main(){ printf("Hello, World."); } C言語のソースコード • C言語のソースコードをCコンパイラでコンパ イルしてアセンブリ言語のソースコードを作る 実行ファイル アセンブリ言語の ソースコード C言語の ソースコード

Slide 218

Slide 218 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 ここまでのまとめ 33 コンパイル #include int main(){ printf("Hello, World."); } C言語のソースコード • C言語のソースコードをCコンパイラでコンパ イルしてアセンブリ言語のソースコードを作る 実行ファイル アセンブリ言語の ソースコード C言語の ソースコード

Slide 219

Slide 219 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 ここまでのまとめ 33 コンパイル #include int main(){ printf("Hello, World."); } C言語のソースコード .file 1 "-" .local .L..0 .align 1 .data .L..0: .byte 72 ; H .byte 101 ; e .byte 108 ; l .byte 108 ; l .byte 111 ; o .byte 44 ; , .byte 32 ; .byte 87 ; W .byte 111 ; o .byte 114 ; r .byte 108 ; l .byte 100 ; d .byte 46 ; . .byte 0 ; \0 .globl main .text main: push %rbp mov %rsp, %rbp sub $0, %rsp .loc 1 43 lea .L..0(%rip), %rax push %rax pop %rdi mov $0, %rax call printf .L.return.main: mov %rbp, %rsp pop %rbp ret アセンブリ言語のソースコード • C言語のソースコードをCコンパイラでコンパ イルしてアセンブリ言語のソースコードを作る 実行ファイル アセンブリ言語の ソースコード C言語の ソースコード

Slide 220

Slide 220 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 ここまでのまとめ 33 コンパイル #include int main(){ printf("Hello, World."); } C言語のソースコード .file 1 "-" .local .L..0 .align 1 .data .L..0: .byte 72 ; H .byte 101 ; e .byte 108 ; l .byte 108 ; l .byte 111 ; o .byte 44 ; , .byte 32 ; .byte 87 ; W .byte 111 ; o .byte 114 ; r .byte 108 ; l .byte 100 ; d .byte 46 ; . .byte 0 ; \0 .globl main .text main: push %rbp mov %rsp, %rbp sub $0, %rsp .loc 1 43 lea .L..0(%rip), %rax push %rax pop %rdi mov $0, %rax call printf .L.return.main: mov %rbp, %rsp pop %rbp ret アセンブリ言語のソースコード • C言語のソースコードをCコンパイラでコンパ イルしてアセンブリ言語のソースコードを作る • Cコンパイラはトークナイザ, パーサ, コードジ ェネレータの3機能で構成する 実行ファイル アセンブリ言語の ソースコード C言語の ソースコード

Slide 221

Slide 221 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 言語仕様と生成規則 • コンパイラを作るにはトークナイザ、パーサ、コードジェネレータを作れば良い 34

Slide 222

Slide 222 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 言語仕様と生成規則 • コンパイラを作るにはトークナイザ、パーサ、コードジェネレータを作れば良い • トークナイザとコードジェネレータは比較的単純 34

Slide 223

Slide 223 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 言語仕様と生成規則 • コンパイラを作るにはトークナイザ、パーサ、コードジェネレータを作れば良い • トークナイザとコードジェネレータは比較的単純 • パーサは言語仕様そのものであり複雑なのでうかつに作ると言語仕様の拡張・変更に対 応できなくなったりする 34

Slide 224

Slide 224 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 言語仕様と生成規則 • コンパイラを作るにはトークナイザ、パーサ、コードジェネレータを作れば良い • トークナイザとコードジェネレータは比較的単純 • パーサは言語仕様そのものであり複雑なのでうかつに作ると言語仕様の拡張・変更に対 応できなくなったりする • そもそも言語仕様をどう定義する? 34

Slide 225

Slide 225 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 言語仕様と生成規則 • コンパイラを作るにはトークナイザ、パーサ、コードジェネレータを作れば良い • トークナイザとコードジェネレータは比較的単純 • パーサは言語仕様そのものであり複雑なのでうかつに作ると言語仕様の拡張・変更に対 応できなくなったりする • そもそも言語仕様をどう定義する? • 生成規則を使うと良い 34

Slide 226

Slide 226 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 プログラム言語仕様の定義 35

Slide 227

Slide 227 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 EBNF • プログラム言語の生成規則を記述するための記法 EBNF (Extended Backus-Naur form) 36

Slide 228

Slide 228 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 EBNF • プログラム言語の生成規則を記述するための記法 EBNF (Extended Backus-Naur form) 36 expr = num ("+" num | "-" num)* numは数値を表す記号

Slide 229

Slide 229 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 EBNF • プログラム言語の生成規則を記述するための記法 EBNF (Extended Backus-Naur form) 36 expr は num から始まって "+" num または "-" num が0回以上続く expr = num ("+" num | "-" num)* numは数値を表す記号

Slide 230

Slide 230 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 EBNF • プログラム言語の生成規則を記述するための記法 EBNF (Extended Backus-Naur form) 36 expr は num から始まって "+" num または "-" num が0回以上続く expr = num ("+" num | "-" num)* numは数値を表す記号 1 1 + 5 1 + 5 - 2

Slide 231

Slide 231 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 演算の優先順位の表現 37

Slide 232

Slide 232 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 演算の優先順位の表現 37 expr = mul ("+" mul | "-" mul)* mul = num ("*" num | "/" num)*

Slide 233

Slide 233 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 演算の優先順位の表現 37 expr = mul ("+" mul | "-" mul)* mul = num ("*" num | "/" num)* expr を処理するには先に mul を処理する必要がある

Slide 234

Slide 234 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 演算の優先順位の表現 37 expr = mul ("+" mul | "-" mul)* mul = num ("*" num | "/" num)* expr を処理するには先に mul を処理する必要がある ➡ 四則演算の優先順位を表現できた

Slide 235

Slide 235 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 演算の優先順位の表現 37 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" expr = mul ("+" mul | "-" mul)* mul = num ("*" num | "/" num)* expr を処理するには先に mul を処理する必要がある ➡ 四則演算の優先順位を表現できた

Slide 236

Slide 236 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 演算の優先順位の表現 37 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" • 上記で num だったところが primary になった expr = mul ("+" mul | "-" mul)* mul = num ("*" num | "/" num)* expr を処理するには先に mul を処理する必要がある ➡ 四則演算の優先順位を表現できた

Slide 237

Slide 237 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 演算の優先順位の表現 37 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" • 上記で num だったところが primary になった • primary は num or カッコで括られた expr expr = mul ("+" mul | "-" mul)* mul = num ("*" num | "/" num)* expr を処理するには先に mul を処理する必要がある ➡ 四則演算の優先順位を表現できた

Slide 238

Slide 238 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 演算の優先順位の表現 37 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" • 上記で num だったところが primary になった • primary は num or カッコで括られた expr expr = mul ("+" mul | "-" mul)* mul = num ("*" num | "/" num)* expr を処理するには先に mul を処理する必要がある ➡ 四則演算の優先順位を表現できた ➡ カッコの優先順位を表現できた

Slide 239

Slide 239 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 もうちょっと育ったEBNF 38 program = stmt* stmt = "return" expr ";" | "if" "(" expr ")" stmt ("else" stmt)? | "{" compound-stmt | expr-stmt compound-stmt = stmt* "}" expr-stmt = expr? ";" expr = assign assign = equality ("=" assign)? equality = relational ("==" relational | "!=" relational)* relational = add ("<" add | "<=" add | ">" add | ">=" add)* add = mul ("+" mul | "-" mul)* mul = unary ("*" unary | "/" unary)* unary = ("+" | "-") unary | primary primary = "(" expr ")" | ident | number

Slide 240

Slide 240 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 もうちょっと育ったEBNF 38 program = stmt* stmt = "return" expr ";" | "if" "(" expr ")" stmt ("else" stmt)? | "{" compound-stmt | expr-stmt compound-stmt = stmt* "}" expr-stmt = expr? ";" expr = assign assign = equality ("=" assign)? equality = relational ("==" relational | "!=" relational)* relational = add ("<" add | "<=" add | ">" add | ">=" add)* add = mul ("+" mul | "-" mul)* mul = unary ("*" unary | "/" unary)* unary = ("+" | "-") unary | primary primary = "(" expr ")" | ident | number EBNFで言語仕様がすべて表現できる(誇張を含みます)

Slide 241

Slide 241 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 EBNFベースのパーサ実装 39

Slide 242

Slide 242 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 ENBFの実装方針 40

Slide 243

Slide 243 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 ENBFの実装方針 • EBNFに出てくるワード(非終端記号)を関数1つにマップしていくとパーサが作りやすい 40

Slide 244

Slide 244 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 ENBFの実装方針 • EBNFに出てくるワード(非終端記号)を関数1つにマップしていくとパーサが作りやすい 40 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")"

Slide 245

Slide 245 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 ENBFの実装方針 • EBNFに出てくるワード(非終端記号)を関数1つにマップしていくとパーサが作りやすい 40 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" • この場合、expr(), mul(), primary(), num() を作る

Slide 246

Slide 246 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 ENBFの実装方針 • EBNFに出てくるワード(非終端記号)を関数1つにマップしていくとパーサが作りやすい 40 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" • この場合、expr(), mul(), primary(), num() を作る • それぞれ Node のインスタンスを返す

Slide 247

Slide 247 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 ENBFの実装方針 • EBNFに出てくるワード(非終端記号)を関数1つにマップしていくとパーサが作りやすい 40 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" • この場合、expr(), mul(), primary(), num() を作る • それぞれ Node のインスタンスを返す /%@'03 /%@"44*(/ /%@7"3J /%@/6. JOJU /%

Slide 248

Slide 248 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 ENBFの実装方針 • EBNFに出てくるワード(非終端記号)を関数1つにマップしていくとパーサが作りやすい 40 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" • この場合、expr(), mul(), primary(), num() を作る • それぞれ Node のインスタンスを返す • 一番上の Node (expr) をコードジェネレータに渡す /%@'03 /%@"44*(/ /%@7"3J /%@/6. JOJU /%

Slide 249

Slide 249 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 primary() $this->tokenizer トークン列を保持 consume('(') カーソルの場所が ( ならカーソルを進めてtrueを 返す ( でなければ false を返して何もしない expect(')') カーソルの場所が ) ならカーソルを進める ) でなければエラー newNodeNum(int $num) ノードタイプ ND_NUM のノードを作る 41 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" public function primary(): Node { if ($this->tokenizer->consume('(')){ $node = $this->expr(); $this->tokenizer->expect(')'); return $node; } return Node::newNodeNum( $this->tokenizer->expectNumber()); } expectNumber() カーソルの場所が数値なら数値を返す 数値でなければエラー NodeKind::ND_NUM val = 10

Slide 250

Slide 250 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 primary() $this->tokenizer トークン列を保持 consume('(') カーソルの場所が ( ならカーソルを進めてtrueを 返す ( でなければ false を返して何もしない expect(')') カーソルの場所が ) ならカーソルを進める ) でなければエラー newNodeNum(int $num) ノードタイプ ND_NUM のノードを作る 41 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" public function primary(): Node { if ($this->tokenizer->consume('(')){ $node = $this->expr(); $this->tokenizer->expect(')'); return $node; } return Node::newNodeNum( $this->tokenizer->expectNumber()); } expectNumber() カーソルの場所が数値なら数値を返す 数値でなければエラー NodeKind::ND_NUM val = 10

Slide 251

Slide 251 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 primary() $this->tokenizer トークン列を保持 consume('(') カーソルの場所が ( ならカーソルを進めてtrueを 返す ( でなければ false を返して何もしない expect(')') カーソルの場所が ) ならカーソルを進める ) でなければエラー newNodeNum(int $num) ノードタイプ ND_NUM のノードを作る 41 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" public function primary(): Node { if ($this->tokenizer->consume('(')){ $node = $this->expr(); $this->tokenizer->expect(')'); return $node; } return Node::newNodeNum( $this->tokenizer->expectNumber()); } expectNumber() カーソルの場所が数値なら数値を返す 数値でなければエラー NodeKind::ND_NUM val = 10

Slide 252

Slide 252 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 mul() 42 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" public function mul(): Node { $node = $this->primary(); for (;;){ if ($this->tokenizer->consume('*')){ $node = Node::newNode( NodeKind::ND_MUL, $node, $this->primary()); } elseif ($this->tokenizer->consume('/')){ $node = Node::newNode( NodeKind::ND_DIV, $node, $this->primary()); } else { return $node; } } }

Slide 253

Slide 253 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 mul() • primary からはじまる 42 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" public function mul(): Node { $node = $this->primary(); for (;;){ if ($this->tokenizer->consume('*')){ $node = Node::newNode( NodeKind::ND_MUL, $node, $this->primary()); } elseif ($this->tokenizer->consume('/')){ $node = Node::newNode( NodeKind::ND_DIV, $node, $this->primary()); } else { return $node; } } }

Slide 254

Slide 254 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 mul() • primary からはじまる • "*" primary か "/" primary を 0回以上繰り返す 42 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" public function mul(): Node { $node = $this->primary(); for (;;){ if ($this->tokenizer->consume('*')){ $node = Node::newNode( NodeKind::ND_MUL, $node, $this->primary()); } elseif ($this->tokenizer->consume('/')){ $node = Node::newNode( NodeKind::ND_DIV, $node, $this->primary()); } else { return $node; } } }

Slide 255

Slide 255 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 mul() • primary からはじまる • "*" primary か "/" primary を 0回以上繰り返す 42 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" public function mul(): Node { $node = $this->primary(); for (;;){ if ($this->tokenizer->consume('*')){ $node = Node::newNode( NodeKind::ND_MUL, $node, $this->primary()); } elseif ($this->tokenizer->consume('/')){ $node = Node::newNode( NodeKind::ND_DIV, $node, $this->primary()); } else { return $node; } } } public static function newNode( NodeKind $nodeKind, Node $lhs, Node $rhs): Node

Slide 256

Slide 256 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 mul() • primary からはじまる • "*" primary か "/" primary を 0回以上繰り返す 42 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" public function mul(): Node { $node = $this->primary(); for (;;){ if ($this->tokenizer->consume('*')){ $node = Node::newNode( NodeKind::ND_MUL, $node, $this->primary()); } elseif ($this->tokenizer->consume('/')){ $node = Node::newNode( NodeKind::ND_DIV, $node, $this->primary()); } else { return $node; } } } public static function newNode( NodeKind $nodeKind, Node $lhs, Node $rhs): Node NodeKind::ND_MUL NodeKind::ND_NUM NodeKind::ND_NUM val = 10 val = 3 lhs rhs 10 * 3

Slide 257

Slide 257 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 expr() 43 public function expr(): Node { $node = $this->mul(); for (;;){ if ($this->tokenizer->consume('+')){ $node = Node::newNode(NodeKind::ND_ADD, $node, $this->mul()); } elseif ($this->tokenizer->consume('-')){ $node = Node::newNode(NodeKind::ND_SUB, $node, $this->mul()); } else { return $node; } } } expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")"

Slide 258

Slide 258 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 expr() • mul からはじまる 43 public function expr(): Node { $node = $this->mul(); for (;;){ if ($this->tokenizer->consume('+')){ $node = Node::newNode(NodeKind::ND_ADD, $node, $this->mul()); } elseif ($this->tokenizer->consume('-')){ $node = Node::newNode(NodeKind::ND_SUB, $node, $this->mul()); } else { return $node; } } } expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")"

Slide 259

Slide 259 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 expr() • mul からはじまる • "+" mul か "-" mul を 0回以上繰り返す 43 public function expr(): Node { $node = $this->mul(); for (;;){ if ($this->tokenizer->consume('+')){ $node = Node::newNode(NodeKind::ND_ADD, $node, $this->mul()); } elseif ($this->tokenizer->consume('-')){ $node = Node::newNode(NodeKind::ND_SUB, $node, $this->mul()); } else { return $node; } } } expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")"

Slide 260

Slide 260 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 expr() • mul からはじまる • "+" mul か "-" mul を 0回以上繰り返す • これで四則演算ができるパーサが 完成 43 public function expr(): Node { $node = $this->mul(); for (;;){ if ($this->tokenizer->consume('+')){ $node = Node::newNode(NodeKind::ND_ADD, $node, $this->mul()); } elseif ($this->tokenizer->consume('-')){ $node = Node::newNode(NodeKind::ND_SUB, $node, $this->mul()); } else { return $node; } } } expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")"

Slide 261

Slide 261 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 expr() • mul からはじまる • "+" mul か "-" mul を 0回以上繰り返す • これで四則演算ができるパーサが 完成 43 public function expr(): Node { $node = $this->mul(); for (;;){ if ($this->tokenizer->consume('+')){ $node = Node::newNode(NodeKind::ND_ADD, $node, $this->mul()); } elseif ($this->tokenizer->consume('-')){ $node = Node::newNode(NodeKind::ND_SUB, $node, $this->mul()); } else { return $node; } } } expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" NodeKind::ND_MUL NodeKind::ND_NUM NodeKind::ND_NUM val = 10 val = 3 lhs rhs NodeKind::ND_ADD NodeKind::ND_NUM val = 3 lhs rhs

Slide 262

Slide 262 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 expr() • mul からはじまる • "+" mul か "-" mul を 0回以上繰り返す • これで四則演算ができるパーサが 完成 43 public function expr(): Node { $node = $this->mul(); for (;;){ if ($this->tokenizer->consume('+')){ $node = Node::newNode(NodeKind::ND_ADD, $node, $this->mul()); } elseif ($this->tokenizer->consume('-')){ $node = Node::newNode(NodeKind::ND_SUB, $node, $this->mul()); } else { return $node; } } } expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" NodeKind::ND_MUL NodeKind::ND_NUM NodeKind::ND_NUM val = 10 val = 3 lhs rhs NodeKind::ND_ADD NodeKind::ND_NUM val = 3 lhs rhs 10 * 3 + 3

Slide 263

Slide 263 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コードジェネレータの実装 44

Slide 264

Slide 264 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コードジェネレータの実装 45 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")"

Slide 265

Slide 265 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コードジェネレータの実装 45 public static function main( int $argc = null, array $argv = null): int { if ($argc != 2) { printf("引数の個数が正しくありません\n"); return 1; } $tokenizer = new Tokenizer($argv[1]); $tokenizer->tokenize(); $parser = new Ast\Parser($tokenizer); $node = $parser->expr(); printf(".globl main\n"); printf("main:\n"); self::gen($node); printf(" pop %%rax\n"); printf(" ret\n"); return 0; } expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")"

Slide 266

Slide 266 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コードジェネレータの実装 ① トークナイザ ソースコードをトークン化する 45 public static function main( int $argc = null, array $argv = null): int { if ($argc != 2) { printf("引数の個数が正しくありません\n"); return 1; } $tokenizer = new Tokenizer($argv[1]); $tokenizer->tokenize(); $parser = new Ast\Parser($tokenizer); $node = $parser->expr(); printf(".globl main\n"); printf("main:\n"); self::gen($node); printf(" pop %%rax\n"); printf(" ret\n"); return 0; } expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" 1

Slide 267

Slide 267 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コードジェネレータの実装 ① トークナイザ ソースコードをトークン化する ② パーサ トークン列を expr としてパースする 45 public static function main( int $argc = null, array $argv = null): int { if ($argc != 2) { printf("引数の個数が正しくありません\n"); return 1; } $tokenizer = new Tokenizer($argv[1]); $tokenizer->tokenize(); $parser = new Ast\Parser($tokenizer); $node = $parser->expr(); printf(".globl main\n"); printf("main:\n"); self::gen($node); printf(" pop %%rax\n"); printf(" ret\n"); return 0; } expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" 2

Slide 268

Slide 268 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コードジェネレータの実装 ① トークナイザ ソースコードをトークン化する ② パーサ トークン列を expr としてパースする ③ コードジェネレータ 45 public static function main( int $argc = null, array $argv = null): int { if ($argc != 2) { printf("引数の個数が正しくありません\n"); return 1; } $tokenizer = new Tokenizer($argv[1]); $tokenizer->tokenize(); $parser = new Ast\Parser($tokenizer); $node = $parser->expr(); printf(".globl main\n"); printf("main:\n"); self::gen($node); printf(" pop %%rax\n"); printf(" ret\n"); return 0; } expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" 3

Slide 269

Slide 269 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コードジェネレータの実装 ① トークナイザ ソースコードをトークン化する ② パーサ トークン列を expr としてパースする ③ コードジェネレータ ④ exprノードからアセンブリ言語を作る 45 public static function main( int $argc = null, array $argv = null): int { if ($argc != 2) { printf("引数の個数が正しくありません\n"); return 1; } $tokenizer = new Tokenizer($argv[1]); $tokenizer->tokenize(); $parser = new Ast\Parser($tokenizer); $node = $parser->expr(); printf(".globl main\n"); printf("main:\n"); self::gen($node); printf(" pop %%rax\n"); printf(" ret\n"); return 0; } expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" 3 4

Slide 270

Slide 270 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 gen($node) 46 public static function gen(Node $node): void { if ($node->kind == NodeKind::ND_NUM) { printf(" push \$%d\n", $node->val); return; } self::gen($node->lhs); self::gen($node->rhs); printf(" pop %%rdi\n"); printf(" pop %%rax\n"); switch ($node->kind){ case NodeKind::ND_ADD: printf(" add %%rax, %%rdi\n"); break; case NodeKind::ND_SUB: printf(" sub %%rax, %%rdi\n"); break; case NodeKind::ND_MUL: printf(" imul %%rax, %%rdi\n"); break; case NodeKind::ND_DIV: printf(" cqo\n"); printf(" idiv %%rdi\n"); break; } printf(" push %%rax\n"); }

Slide 271

Slide 271 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 gen($node) • ノードをアセンブリ言語に変換 46 public static function gen(Node $node): void { if ($node->kind == NodeKind::ND_NUM) { printf(" push \$%d\n", $node->val); return; } self::gen($node->lhs); self::gen($node->rhs); printf(" pop %%rdi\n"); printf(" pop %%rax\n"); switch ($node->kind){ case NodeKind::ND_ADD: printf(" add %%rax, %%rdi\n"); break; case NodeKind::ND_SUB: printf(" sub %%rax, %%rdi\n"); break; case NodeKind::ND_MUL: printf(" imul %%rax, %%rdi\n"); break; case NodeKind::ND_DIV: printf(" cqo\n"); printf(" idiv %%rdi\n"); break; } printf(" push %%rax\n"); }

Slide 272

Slide 272 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 gen($node) • ノードをアセンブリ言語に変換 • push / pop 46 public static function gen(Node $node): void { if ($node->kind == NodeKind::ND_NUM) { printf(" push \$%d\n", $node->val); return; } self::gen($node->lhs); self::gen($node->rhs); printf(" pop %%rdi\n"); printf(" pop %%rax\n"); switch ($node->kind){ case NodeKind::ND_ADD: printf(" add %%rax, %%rdi\n"); break; case NodeKind::ND_SUB: printf(" sub %%rax, %%rdi\n"); break; case NodeKind::ND_MUL: printf(" imul %%rax, %%rdi\n"); break; case NodeKind::ND_DIV: printf(" cqo\n"); printf(" idiv %%rdi\n"); break; } printf(" push %%rax\n"); }

Slide 273

Slide 273 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 gen($node) • ノードをアセンブリ言語に変換 • push / pop • スタックに値を積む / 取り出す 46 public static function gen(Node $node): void { if ($node->kind == NodeKind::ND_NUM) { printf(" push \$%d\n", $node->val); return; } self::gen($node->lhs); self::gen($node->rhs); printf(" pop %%rdi\n"); printf(" pop %%rax\n"); switch ($node->kind){ case NodeKind::ND_ADD: printf(" add %%rax, %%rdi\n"); break; case NodeKind::ND_SUB: printf(" sub %%rax, %%rdi\n"); break; case NodeKind::ND_MUL: printf(" imul %%rax, %%rdi\n"); break; case NodeKind::ND_DIV: printf(" cqo\n"); printf(" idiv %%rdi\n"); break; } printf(" push %%rax\n"); }

Slide 274

Slide 274 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 gen($node) • ノードをアセンブリ言語に変換 • push / pop • スタックに値を積む / 取り出す • 機械語では処理の切れ目でスタック経由で 値を受け渡しすることが多い 46 public static function gen(Node $node): void { if ($node->kind == NodeKind::ND_NUM) { printf(" push \$%d\n", $node->val); return; } self::gen($node->lhs); self::gen($node->rhs); printf(" pop %%rdi\n"); printf(" pop %%rax\n"); switch ($node->kind){ case NodeKind::ND_ADD: printf(" add %%rax, %%rdi\n"); break; case NodeKind::ND_SUB: printf(" sub %%rax, %%rdi\n"); break; case NodeKind::ND_MUL: printf(" imul %%rax, %%rdi\n"); break; case NodeKind::ND_DIV: printf(" cqo\n"); printf(" idiv %%rdi\n"); break; } printf(" push %%rax\n"); }

Slide 275

Slide 275 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 gen($node) • ノードをアセンブリ言語に変換 • push / pop • スタックに値を積む / 取り出す • 機械語では処理の切れ目でスタック経由で 値を受け渡しすることが多い 46 public static function gen(Node $node): void { if ($node->kind == NodeKind::ND_NUM) { printf(" push \$%d\n", $node->val); return; } self::gen($node->lhs); self::gen($node->rhs); printf(" pop %%rdi\n"); printf(" pop %%rax\n"); switch ($node->kind){ case NodeKind::ND_ADD: printf(" add %%rax, %%rdi\n"); break; case NodeKind::ND_SUB: printf(" sub %%rax, %%rdi\n"); break; case NodeKind::ND_MUL: printf(" imul %%rax, %%rdi\n"); break; case NodeKind::ND_DIV: printf(" cqo\n"); printf(" idiv %%rdi\n"); break; } printf(" push %%rax\n"); } NodeKind::ND_MUL NodeKind::ND_NUM NodeKind::ND_NUM val = 10 val = 3 lhs rhs 10 * 3

Slide 276

Slide 276 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 gen($node) • ノードをアセンブリ言語に変換 • push / pop • スタックに値を積む / 取り出す • 機械語では処理の切れ目でスタック経由で 値を受け渡しすることが多い 46 public static function gen(Node $node): void { if ($node->kind == NodeKind::ND_NUM) { printf(" push \$%d\n", $node->val); return; } self::gen($node->lhs); self::gen($node->rhs); printf(" pop %%rdi\n"); printf(" pop %%rax\n"); switch ($node->kind){ case NodeKind::ND_ADD: printf(" add %%rax, %%rdi\n"); break; case NodeKind::ND_SUB: printf(" sub %%rax, %%rdi\n"); break; case NodeKind::ND_MUL: printf(" imul %%rax, %%rdi\n"); break; case NodeKind::ND_DIV: printf(" cqo\n"); printf(" idiv %%rdi\n"); break; } printf(" push %%rax\n"); } NodeKind::ND_MUL NodeKind::ND_NUM NodeKind::ND_NUM val = 10 val = 3 lhs rhs 10 * 3

Slide 277

Slide 277 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 gen($node) • ノードをアセンブリ言語に変換 • push / pop • スタックに値を積む / 取り出す • 機械語では処理の切れ目でスタック経由で 値を受け渡しすることが多い 46 public static function gen(Node $node): void { if ($node->kind == NodeKind::ND_NUM) { printf(" push \$%d\n", $node->val); return; } self::gen($node->lhs); self::gen($node->rhs); printf(" pop %%rdi\n"); printf(" pop %%rax\n"); switch ($node->kind){ case NodeKind::ND_ADD: printf(" add %%rax, %%rdi\n"); break; case NodeKind::ND_SUB: printf(" sub %%rax, %%rdi\n"); break; case NodeKind::ND_MUL: printf(" imul %%rax, %%rdi\n"); break; case NodeKind::ND_DIV: printf(" cqo\n"); printf(" idiv %%rdi\n"); break; } printf(" push %%rax\n"); } NodeKind::ND_MUL NodeKind::ND_NUM NodeKind::ND_NUM val = 10 val = 3 lhs rhs 10 * 3 加減乗除ノード

Slide 278

Slide 278 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 gen($node) • ノードをアセンブリ言語に変換 • push / pop • スタックに値を積む / 取り出す • 機械語では処理の切れ目でスタック経由で 値を受け渡しすることが多い 46 public static function gen(Node $node): void { if ($node->kind == NodeKind::ND_NUM) { printf(" push \$%d\n", $node->val); return; } self::gen($node->lhs); self::gen($node->rhs); printf(" pop %%rdi\n"); printf(" pop %%rax\n"); switch ($node->kind){ case NodeKind::ND_ADD: printf(" add %%rax, %%rdi\n"); break; case NodeKind::ND_SUB: printf(" sub %%rax, %%rdi\n"); break; case NodeKind::ND_MUL: printf(" imul %%rax, %%rdi\n"); break; case NodeKind::ND_DIV: printf(" cqo\n"); printf(" idiv %%rdi\n"); break; } printf(" push %%rax\n"); } NodeKind::ND_MUL NodeKind::ND_NUM NodeKind::ND_NUM val = 10 val = 3 lhs rhs 10 * 3 加減乗除ノード lhsの処理

Slide 279

Slide 279 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 gen($node) • ノードをアセンブリ言語に変換 • push / pop • スタックに値を積む / 取り出す • 機械語では処理の切れ目でスタック経由で 値を受け渡しすることが多い 46 public static function gen(Node $node): void { if ($node->kind == NodeKind::ND_NUM) { printf(" push \$%d\n", $node->val); return; } self::gen($node->lhs); self::gen($node->rhs); printf(" pop %%rdi\n"); printf(" pop %%rax\n"); switch ($node->kind){ case NodeKind::ND_ADD: printf(" add %%rax, %%rdi\n"); break; case NodeKind::ND_SUB: printf(" sub %%rax, %%rdi\n"); break; case NodeKind::ND_MUL: printf(" imul %%rax, %%rdi\n"); break; case NodeKind::ND_DIV: printf(" cqo\n"); printf(" idiv %%rdi\n"); break; } printf(" push %%rax\n"); } 数字ノード NodeKind::ND_MUL NodeKind::ND_NUM NodeKind::ND_NUM val = 10 val = 3 lhs rhs 10 * 3 加減乗除ノード lhsの処理

Slide 280

Slide 280 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 gen($node) • ノードをアセンブリ言語に変換 • push / pop • スタックに値を積む / 取り出す • 機械語では処理の切れ目でスタック経由で 値を受け渡しすることが多い 46 public static function gen(Node $node): void { if ($node->kind == NodeKind::ND_NUM) { printf(" push \$%d\n", $node->val); return; } self::gen($node->lhs); self::gen($node->rhs); printf(" pop %%rdi\n"); printf(" pop %%rax\n"); switch ($node->kind){ case NodeKind::ND_ADD: printf(" add %%rax, %%rdi\n"); break; case NodeKind::ND_SUB: printf(" sub %%rax, %%rdi\n"); break; case NodeKind::ND_MUL: printf(" imul %%rax, %%rdi\n"); break; case NodeKind::ND_DIV: printf(" cqo\n"); printf(" idiv %%rdi\n"); break; } printf(" push %%rax\n"); } 数字ノード NodeKind::ND_MUL NodeKind::ND_NUM NodeKind::ND_NUM val = 10 val = 3 lhs rhs 10 * 3 加減乗除ノード 定数をスタックに乗せる lhsの処理

Slide 281

Slide 281 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 gen($node) • ノードをアセンブリ言語に変換 • push / pop • スタックに値を積む / 取り出す • 機械語では処理の切れ目でスタック経由で 値を受け渡しすることが多い 46 public static function gen(Node $node): void { if ($node->kind == NodeKind::ND_NUM) { printf(" push \$%d\n", $node->val); return; } self::gen($node->lhs); self::gen($node->rhs); printf(" pop %%rdi\n"); printf(" pop %%rax\n"); switch ($node->kind){ case NodeKind::ND_ADD: printf(" add %%rax, %%rdi\n"); break; case NodeKind::ND_SUB: printf(" sub %%rax, %%rdi\n"); break; case NodeKind::ND_MUL: printf(" imul %%rax, %%rdi\n"); break; case NodeKind::ND_DIV: printf(" cqo\n"); printf(" idiv %%rdi\n"); break; } printf(" push %%rax\n"); } NodeKind::ND_MUL NodeKind::ND_NUM NodeKind::ND_NUM val = 10 val = 3 lhs rhs 10 * 3 加減乗除ノード lhsの処理

Slide 282

Slide 282 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 gen($node) • ノードをアセンブリ言語に変換 • push / pop • スタックに値を積む / 取り出す • 機械語では処理の切れ目でスタック経由で 値を受け渡しすることが多い 46 public static function gen(Node $node): void { if ($node->kind == NodeKind::ND_NUM) { printf(" push \$%d\n", $node->val); return; } self::gen($node->lhs); self::gen($node->rhs); printf(" pop %%rdi\n"); printf(" pop %%rax\n"); switch ($node->kind){ case NodeKind::ND_ADD: printf(" add %%rax, %%rdi\n"); break; case NodeKind::ND_SUB: printf(" sub %%rax, %%rdi\n"); break; case NodeKind::ND_MUL: printf(" imul %%rax, %%rdi\n"); break; case NodeKind::ND_DIV: printf(" cqo\n"); printf(" idiv %%rdi\n"); break; } printf(" push %%rax\n"); } NodeKind::ND_MUL NodeKind::ND_NUM NodeKind::ND_NUM val = 10 val = 3 lhs rhs 10 * 3 加減乗除ノード rhsの処理

Slide 283

Slide 283 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 gen($node) • ノードをアセンブリ言語に変換 • push / pop • スタックに値を積む / 取り出す • 機械語では処理の切れ目でスタック経由で 値を受け渡しすることが多い 46 public static function gen(Node $node): void { if ($node->kind == NodeKind::ND_NUM) { printf(" push \$%d\n", $node->val); return; } self::gen($node->lhs); self::gen($node->rhs); printf(" pop %%rdi\n"); printf(" pop %%rax\n"); switch ($node->kind){ case NodeKind::ND_ADD: printf(" add %%rax, %%rdi\n"); break; case NodeKind::ND_SUB: printf(" sub %%rax, %%rdi\n"); break; case NodeKind::ND_MUL: printf(" imul %%rax, %%rdi\n"); break; case NodeKind::ND_DIV: printf(" cqo\n"); printf(" idiv %%rdi\n"); break; } printf(" push %%rax\n"); } NodeKind::ND_MUL NodeKind::ND_NUM NodeKind::ND_NUM val = 10 val = 3 lhs rhs 10 * 3 加減乗除ノード スタックから値を 2つ取り出す

Slide 284

Slide 284 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 gen($node) • ノードをアセンブリ言語に変換 • push / pop • スタックに値を積む / 取り出す • 機械語では処理の切れ目でスタック経由で 値を受け渡しすることが多い 46 public static function gen(Node $node): void { if ($node->kind == NodeKind::ND_NUM) { printf(" push \$%d\n", $node->val); return; } self::gen($node->lhs); self::gen($node->rhs); printf(" pop %%rdi\n"); printf(" pop %%rax\n"); switch ($node->kind){ case NodeKind::ND_ADD: printf(" add %%rax, %%rdi\n"); break; case NodeKind::ND_SUB: printf(" sub %%rax, %%rdi\n"); break; case NodeKind::ND_MUL: printf(" imul %%rax, %%rdi\n"); break; case NodeKind::ND_DIV: printf(" cqo\n"); printf(" idiv %%rdi\n"); break; } printf(" push %%rax\n"); } NodeKind::ND_MUL NodeKind::ND_NUM NodeKind::ND_NUM val = 10 val = 3 lhs rhs 10 * 3 加減乗除ノード 2つの値を使って 演算する

Slide 285

Slide 285 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 gen($node) • ノードをアセンブリ言語に変換 • push / pop • スタックに値を積む / 取り出す • 機械語では処理の切れ目でスタック経由で 値を受け渡しすることが多い 46 public static function gen(Node $node): void { if ($node->kind == NodeKind::ND_NUM) { printf(" push \$%d\n", $node->val); return; } self::gen($node->lhs); self::gen($node->rhs); printf(" pop %%rdi\n"); printf(" pop %%rax\n"); switch ($node->kind){ case NodeKind::ND_ADD: printf(" add %%rax, %%rdi\n"); break; case NodeKind::ND_SUB: printf(" sub %%rax, %%rdi\n"); break; case NodeKind::ND_MUL: printf(" imul %%rax, %%rdi\n"); break; case NodeKind::ND_DIV: printf(" cqo\n"); printf(" idiv %%rdi\n"); break; } printf(" push %%rax\n"); } NodeKind::ND_MUL NodeKind::ND_NUM NodeKind::ND_NUM val = 10 val = 3 lhs rhs 10 * 3 加減乗除ノード 計算結果(raxレジスタ)の値を スタックに乗せる

Slide 286

Slide 286 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 一連の処理 ① トークナイザ ソースコードをトークン化する ② パーサ トークン列を expr としてパースする ③ コードジェネレータ ④ exprノードからアセンブリ言語を作る 47 public static function main( int $argc = null, array $argv = null): int { if ($argc != 2) { printf("引数の個数が正しくありません\n"); return 1; } $tokenizer = new Tokenizer($argv[1]); $tokenizer->tokenize(); $parser = new Ast\Parser($tokenizer); $node = $parser->expr(); printf(".globl main\n"); printf("main:\n"); self::gen($node); printf(" pop %%rax\n"); printf(" ret\n"); return 0; } expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" 3 4

Slide 287

Slide 287 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 一連の処理 ① トークナイザ ソースコードをトークン化する ② パーサ トークン列を expr としてパースする ③ コードジェネレータ ④ exprノードからアセンブリ言語を作る • 生成されたアセンブリ言語では最後に exprノードの結果をスタックに積んでる 47 public static function main( int $argc = null, array $argv = null): int { if ($argc != 2) { printf("引数の個数が正しくありません\n"); return 1; } $tokenizer = new Tokenizer($argv[1]); $tokenizer->tokenize(); $parser = new Ast\Parser($tokenizer); $node = $parser->expr(); printf(".globl main\n"); printf("main:\n"); self::gen($node); printf(" pop %%rax\n"); printf(" ret\n"); return 0; } expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" 3 4

Slide 288

Slide 288 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 一連の処理 ① トークナイザ ソースコードをトークン化する ② パーサ トークン列を expr としてパースする ③ コードジェネレータ ④ exprノードからアセンブリ言語を作る • 生成されたアセンブリ言語では最後に exprノードの結果をスタックに積んでる ⑤ スタックから値を1つ取り出して rax レジスタに入れて終了 47 public static function main( int $argc = null, array $argv = null): int { if ($argc != 2) { printf("引数の個数が正しくありません\n"); return 1; } $tokenizer = new Tokenizer($argv[1]); $tokenizer->tokenize(); $parser = new Ast\Parser($tokenizer); $node = $parser->expr(); printf(".globl main\n"); printf("main:\n"); self::gen($node); printf(" pop %%rax\n"); printf(" ret\n"); return 0; } expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" 3 5 4

Slide 289

Slide 289 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 ここまでのあらすじ 48 10 * 3 ソースコード NodeKind::ND_MUL NodeKind::ND_NUM NodeKind::ND_NUM val = 10 val = 3 lhs rhs AST .globl main main: push $10 push $3 pop %rdi pop %rax imul %rax, %rdi push %rax pop %rax ret コンパイル結果 NUM 3 RSV * NUM 10 EOF トークン列 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" EBNF

Slide 290

Slide 290 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 ここまでのあらすじ EBNFで定義された言語仕様をもとに 48 10 * 3 ソースコード NodeKind::ND_MUL NodeKind::ND_NUM NodeKind::ND_NUM val = 10 val = 3 lhs rhs AST .globl main main: push $10 push $3 pop %rdi pop %rax imul %rax, %rdi push %rax pop %rax ret コンパイル結果 NUM 3 RSV * NUM 10 EOF トークン列 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" EBNF

Slide 291

Slide 291 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 ここまでのあらすじ EBNFで定義された言語仕様をもとに トークナイザがソースコードをトークン列化 48 10 * 3 ソースコード NodeKind::ND_MUL NodeKind::ND_NUM NodeKind::ND_NUM val = 10 val = 3 lhs rhs AST .globl main main: push $10 push $3 pop %rdi pop %rax imul %rax, %rdi push %rax pop %rax ret コンパイル結果 NUM 3 RSV * NUM 10 EOF トークン列 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" EBNF

Slide 292

Slide 292 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 ここまでのあらすじ EBNFで定義された言語仕様をもとに トークナイザがソースコードをトークン列化 パーサがAST化して 48 10 * 3 ソースコード NodeKind::ND_MUL NodeKind::ND_NUM NodeKind::ND_NUM val = 10 val = 3 lhs rhs AST .globl main main: push $10 push $3 pop %rdi pop %rax imul %rax, %rdi push %rax pop %rax ret コンパイル結果 NUM 3 RSV * NUM 10 EOF トークン列 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" EBNF

Slide 293

Slide 293 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 ここまでのあらすじ EBNFで定義された言語仕様をもとに トークナイザがソースコードをトークン列化 パーサがAST化して コードジェネレータがアセンブリ言語ソース化した 48 10 * 3 ソースコード NodeKind::ND_MUL NodeKind::ND_NUM NodeKind::ND_NUM val = 10 val = 3 lhs rhs AST .globl main main: push $10 push $3 pop %rdi pop %rax imul %rax, %rdi push %rax pop %rax ret コンパイル結果 NUM 3 RSV * NUM 10 EOF トークン列 expr = mul ("+" mul | "-" mul)* mul = primary ("*" primary | "/" primary)* primary = num | "(" expr ")" EBNF

Slide 294

Slide 294 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 最適化 49 .globl main main: push $10 push $3 pop %rdi pop %rax imul %rax, %rdi push %rax pop %rax ret コンパイル結果

Slide 295

Slide 295 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 最適化 • 素直にコンパイルされたアセンブリ言語のソース 49 .globl main main: push $10 push $3 pop %rdi pop %rax imul %rax, %rdi push %rax pop %rax ret コンパイル結果

Slide 296

Slide 296 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 最適化 • 素直にコンパイルされたアセンブリ言語のソース • push → push → pop → pop みたいなところがある 49 .globl main main: push $10 push $3 pop %rdi pop %rax imul %rax, %rdi push %rax pop %rax ret コンパイル結果

Slide 297

Slide 297 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 最適化 • 素直にコンパイルされたアセンブリ言語のソース • push → push → pop → pop みたいなところがある 49 .globl main main: push $10 push $3 pop %rdi pop %rax imul %rax, %rdi push %rax pop %rax ret コンパイル結果

Slide 298

Slide 298 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 最適化 • 素直にコンパイルされたアセンブリ言語のソース • push → push → pop → pop みたいなところがある • ここは結果として rdi レジスタや rax レジスタに 値を設定したいだけなので mov $3, %rdi とか mov $10, %rax とかすれば良く、 メモリアクセスが不要になって高速化する 49 .globl main main: push $10 push $3 pop %rdi pop %rax imul %rax, %rdi push %rax pop %rax ret コンパイル結果

Slide 299

Slide 299 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 最適化 • 素直にコンパイルされたアセンブリ言語のソース • push → push → pop → pop みたいなところがある • ここは結果として rdi レジスタや rax レジスタに 値を設定したいだけなので mov $3, %rdi とか mov $10, %rax とかすれば良く、 メモリアクセスが不要になって高速化する • こいういうのがコンパイラの最適化 49 .globl main main: push $10 push $3 pop %rdi pop %rax imul %rax, %rdi push %rax pop %rax ret コンパイル結果

Slide 300

Slide 300 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 Cコンパイラのゴール • EBNFを少しずつ大きくしていけばCコンパイラは育っていく 50

Slide 301

Slide 301 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 Cコンパイラのゴール • EBNFを少しずつ大きくしていけばCコンパイラは育っていく • コンパイラを育てていけばそのうち自分自身をコンパイルできる様になる 50

Slide 302

Slide 302 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 Cコンパイラのゴール • EBNFを少しずつ大きくしていけばCコンパイラは育っていく • コンパイラを育てていけばそのうち自分自身をコンパイルできる様になる • セルフホストという 50

Slide 303

Slide 303 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 Cコンパイラのゴール • EBNFを少しずつ大きくしていけばCコンパイラは育っていく • コンパイラを育てていけばそのうち自分自身をコンパイルできる様になる • セルフホストという • (趣味の)コンパイラの到達点 50

Slide 304

Slide 304 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 Cコンパイラのゴール • EBNFを少しずつ大きくしていけばCコンパイラは育っていく • コンパイラを育てていけばそのうち自分自身をコンパイルできる様になる • セルフホストという • (趣味の)コンパイラの到達点 • 今回はPHPで書いてるのでセルフホストには至らない 50

Slide 305

Slide 305 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 Cコンパイラのゴール • EBNFを少しずつ大きくしていけばCコンパイラは育っていく • コンパイラを育てていけばそのうち自分自身をコンパイルできる様になる • セルフホストという • (趣味の)コンパイラの到達点 • 今回はPHPで書いてるのでセルフホストには至らない • …PHPはCで書かれている訳で… 50

Slide 306

Slide 306 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 Cコンパイラのゴール • EBNFを少しずつ大きくしていけばCコンパイラは育っていく • コンパイラを育てていけばそのうち自分自身をコンパイルできる様になる • セルフホストという • (趣味の)コンパイラの到達点 • 今回はPHPで書いてるのでセルフホストには至らない • …PHPはCで書かれている訳で… • これでPHPのソースをコンパイル出来たら面白いかも…? 50

Slide 307

Slide 307 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 Cコンパイラのゴール • EBNFを少しずつ大きくしていけばCコンパイラは育っていく • コンパイラを育てていけばそのうち自分自身をコンパイルできる様になる • セルフホストという • (趣味の)コンパイラの到達点 • 今回はPHPで書いてるのでセルフホストには至らない • …PHPはCで書かれている訳で… • これでPHPのソースをコンパイル出来たら面白いかも…? • 「PHPで作ったCコンパイラでコンパイルしたPHPでCコンパイラを動かして…」の 無限ループ 50

Slide 308

Slide 308 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 セルフホストまでの道 51

Slide 309

Slide 309 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 セルフホストまでの道 • chibiccのリポジトリでは合計316コミットある 51

Slide 310

Slide 310 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 セルフホストまでの道 • chibiccのリポジトリでは合計316コミットある 51 90d1f7f Make struct member access to work with `=` and `?:` 982041f Update README b35d148 Add __attribute__((aligned(N)) for struct declaration 44bea4c Add __attribute__((packed)) 395308c redefinition 2ed3fda Add test/thirdparty/cpython.sh 0a5d08c Complete stdatomic.h d69a11d Add _Atomic and atomic ++, -- and op= operators 80ea9d4 Add atomic_exchange ca27455 Add atomic_compare_exchange fb49370 Add scripts to test third-party apps 469f159 Add -Xlinker option d1bc9a4 Add -Wl, option c8df787 Add -L option 4e5de36 Add -shared option 1e9b6dd Add -static option f10bceb [GNU] Add #include_next a6c6622 [GNU] Add "#pragma once" d48d9e5 Add include guard optimization c0f0614 Cache file search results 86785fc Add -fpic and -fPIC options c3edffb Add -MMD option 7aa72e4 Add -MQ option fb5cfe5 Add -MD option db850f3 Add -MT option 57c1d4e Add -MP option 95d5a46 Add -MF option d0c4667 Add -M option f694413 Use hashmap for keyword lookup 655954e Use hashmap for block-scope lookup 30520e5 Use hashmap for macro name lookup 0aad326 Add string hashmap f0c98e0 [GNU] Treat labels-as-values as compile-time constant 4f165ec [GNU] Support labels-as-values 3d5550e [GNU] Support array range designator d90c73b [GNU] Support case ranges e0bf168 Add long double d56dd2f Recognize .a and .so files 8d130ab Emit size and type for symbols c32f0e2 Add -s option bc25279 Add -l option b0109a3 Do not define __STDC_NO_VLA__ 2fa8f48 Support sizeof(typename) where typename is a VLA 07f9010 Add pointer arithmetic for VLA e8667af Add sizeof() for VLA 77275c5 Add alloca() 4064871 Make -E to imply -xc ee0a951 Add -x option 8f5ff07 Add -include option b377284 Add thread-local variable 6d344ed Add -fcommon and -fno-common flags 85e46b1 Add tentative definition 1b99bad Add offsetof 11fc259 Add -idirafter option 6a2dc5a Use __attribute__((format(print, ...))) to find programming errors e5f4ca9 Do not emit static inline functions if referenced by no one 31087f8 Handle inline functions as static functions a253516 Add basic "asm" statement e28a612 [GNU] Add ?: operator with omitted operand aee7891 [GNU] Allow sizeof() 1faab48 Add _Generic 1433b40 [GNU] Add __builtin_types_compatible_p 7d80a51 Add typeof 007e526 [GNU] Support GCC-style variadic macro 74ec9f6 Ignore #pragma 083c275 [GNU] Handle ,##__VA_ARG__ 3381448 Add __VA_OPT__ 3a10c8a [GNU] Add __BASE_FILE__ macro 922604a [GNU] Add __TIMESTAMP__ macro aaf20fb [GNU] Add line marker directive c61c0d0 Add #line 37998be Improve error message for multibyte characters 95eb5b0 Handle struct designator for anonymous struct member 31dc1df Add union designated initializer 67f5834 Add struct designated initializer 691c4fa [GNU] Allow to omit "=" in designated initializers 835cd24 Allow array designators to initialize incomplete arrays c618c3b Add array designated initializer 2b2fa25 Skip UTF-8 BOM markers 2382777 Allow to concatenate regular string literals with L/u/U string literals adb8b98 [GNU] Accept $ as an identifier character 0e5d250 Allow multibyte UTF-8 character in identifier e4491b8 Define __STDC_UTF_{16,32}__ macros 6adba75 Add UTF-32 string literal initializer 36230e0 Add UTF-16 string literal initializer cae061a Add wide string literal c467ee6 Add UTF-32 string literal 9cabe1f Add UTF-16 string literal 57b21fe Add UTF-8 string literal 2dac3af Add UTF-32 character literal 454618c Add UTF-16 character literal a57c661 Accept multibyte character as wide character literal c31886a Add \u and \U escape sequences 74bcec5 Canonicalize newline character 0e77f3d [GNU] Add __COUNTER__ macro e27417f Add __DATE__ and __TIME__ macros c3075b3 Add anonymous struct and union 9c36dd7 Make "main" to implicitly return 0 5257ee0 Make an array of at least 16 bytes long to have alignment of at least 16 bytes 2c91da5 Turn on -Wall compiler flag and fix compiler warnings b1fdddf Ignore -O, -W and -g and other flags 2bdc6b8 Write to an in-memory buffer before writing to an actual output file c302a96 Do not allow to obtain an address of a bitfield 17ea802 Handle zero-width bitfield member 54c2b3b Handle op=-style assignments to bitfields 441a89b Support global struct bitfield initializer cc852fe Add bitfield be8b6f6 Add -U option fc69f5c Add -D option 3f2c2d5 Tokenize numeric tokens as pp-numbers e0b5da3 Dereferencing a function shouldn't do anything 603de50 Add va_copy() b6d3cd0 Allow variadic function to take more than 6 parameters d7bad96 Allow to define a function returning a struct c72df1c Allow to call a fucntion returning a struct d63b1f4 Allow struct argument 5e0f8c4 Allow struct parameter 9021f7f Support passed-on-stack parameters b29f052 Support passed-on-stack arguments 12a9e75 Self-host: including preprocessor, chibicc can compile itself 5322ea8 Add va_arg() 7cbfd11 Add stdarg.h, stdbool.h, stddef.h, stdalign.h and float.h 7746e4e Recognize wide character literal ab4f1e1 Concatenate adjacent string literals 82ba010 [GNU] Add __FUNCTION__ ba6b4b6 Add __func__ dc01f94 Add __VA_ARGS__ 6f17071 Add __FILE__ and __LINE__ 5f5a850 Add predefine macros such as __STDC__ e7fdc2e Add #error a939a7a Add default include paths a1dd621 Add -I option d85fc4f Add #include <...> b33fe0e Support line continuation 8075582 Preserve newline and space during macro expansion a8d76ad Replace remaining identifiers with 0 in macro constexpr 5cb2f89 Add defined() macro operator 769b5a0 Use chibicc's preprocessor for all tests 8f561ae Add macro token-pasting operator (##) 8f6f792 Add macro stringizing operator (#) 1313fc6 Do not expand a token more than once for the same funclike macro c7d7ce0 Allow parenthesized expressions as macro arguments dd4306c Allow empty macro arguments b9ad3e4 Add multi-arity funclike #define dec3b3f Add zero-arity funclike #define 1f80f58 Add #ifdef and #ifndef acce002 Do not expand a token more than once for the same objlike macro 2651448 Expand macros in the #if and #elif argument context 9ad60e4 Add #undef 97d33ad Add objlike #define e7a1857 Add #elif c6e81d2 Add #else aa570f3 Skip nested #if in a skipped #if-clause bf6ff92 Add #if and #endif d138864 Add -E option ec149f6 Skip extra tokens after `#include "..."` d367510 Add #include "..." 146c7b3 Add the null directive 1e1ea39 Add a do-nothing preprocessor 8b726b5 Run "ld" unless -c is given b833cd0 Accept multiple input files 140b433 Run "as" command unless -S is given f3d9613 Split cc1 from compiler driver 53e8103 Add usual arithmetic conversion for function pointer c5953ba Decay a function to a pointer in the func param context d06a8ac Add function pointer 5d15431 Add stage2 build 9bf9612 Add "long double" as an alias for "double" ffea421 Add flonum constant expression e452cf7 Support variadic function with floating-point parameters 8b14859 Implement default argument promotion for float c6b3056 Allow to define a function that takes/returns flonums 8ec1ebf Allow to call a function that takes/returns flonums 0ce1093 Handle flonum for if, while, do, !, ?:, || and && 83f76eb Add flonum +, -, * and / cf9ceec Add flonum ==, !=, < and <= 29de46a Add "float" and "double" local variables and casts 1e57f72 Add floating-point constant 1fad259 Allow to omit parameter name in function declaration 93d1277 Ignore "static" and "const" in array-dimensions b773554 Ignore const, volatile, auto, register, restrict or _Noreturn. 7ba6fe8 Handle unsigned types in the constant expression 6880a39 When comparing two pointers, treat them as unsigned 8b8f3de Use long or ulong instead of int for some expressions aaf1045 Add U, L and LL suffixes 34ab83b Add unsigned integral types 3f59ce7 Add `signed` keyword 197689a Check the number of function arguments 754a24f Add va_start to support variadic functions 58fc861 Allow to call a variadic function dcd4579 Handle a function returning bool, char or short 6a0ed71 Align stack frame to 16 byte boundaries ee252e6 Add do ... while eb85527 Add static global variables 30b3e21 Add return that doesn't take any value 127056d Add compound literals 319772b Add static local variables 310a87e [GNU] Allow a variable as an operand of _Alignof 9df5178 Add _Alignof and _Alignas 2764745 Handle extern declarations in a block 006a45c Add extern 157356c Align global variables 7a1f816 Accept `void` as a parameter list cd688a8 Allow to initialize struct flexible array member 824543b Add flexible array member 3d216e3 Emit uninitialized global data to .bss instead of .data fde464c Allow extraneous comma at the end of enum or initializer list a58958c Allow extraneous braces for scalar initializer efa0f33 Allow parentheses in initializers to be omitted 1eae5ae Handle union initializers for global variable eeb62b6 Add struct initializer for global variable bbfe3f4 Add global initializer for scalar and string 483b194 Handle union initializers for local variables aca19dd Allow to initialize a struct with other struct e9d2c46 Handle struct initializers for local variables 5b95533 Allow to omit array length if an initializer is given 0d71737 Add string literal initializer a754732 Skip excess initializer elements ae0a37d Initialize excess array elements with zero 22dd560 Support local variable initializers 79f5de2 Add constant expression 447ee09 Add ?: operator d0c0cb7 Add <<, >>, <<= and >>= 044d9ae Add switch-case 3c83dfd Add continue statement b3047f2 Add break statement a4be55b Resolve conflict between labels and typedefs 6116cae Add goto and labeled statement 61a1055 Add a notion of an incomplete struct type 7963221 Decay an array to a pointer in the func param context 29ed294 Add a notion of an incomplete array type f30f781 Add && and || 8644006 Add &, |, ^, &=, |= and ^= daa7398 Add % and %= 46a96d6 Add ~ operator 6b88bcb Add ! operator 7df934d Add hexadecimal, octal and binary number literals e8ca48c Add post ++ and -- 47f1937 Add pre ++ and -- 01a94c0 Add +=, -=, *= and /= a4fea2b Allow for-loops to define local variables 736232f Support file-scope functions 48ba265 Add enum aa0accc Add character literal 44bba96 Add _Bool type fdc80bc Handle function argument type conversion 818352a Handle return type conversion 9e211cb Report an error on undefined/undeclared functions 8b430a6 Implement usual arithmetic conversion cfc4fa9 Add type cast cb81a37 Use 32 bit registers for char, short and int 67543ea Make sizeof to accept not only an expression but also a typename a6b82da Add typedef f46370e Add `long long` as an alias for `long` 287906a Handle complex type declarations correctly 8c3503b Add void type 74e3acc Add function declaration a817b23 Add nested type declarators 9d48eef Add short type 43c2f08 Add long type 5831eda Change size of int from 8 to 4 bef0543 Add struct assignment 11e3841 Add union f0a018a Add -> operator e1e831e Support struct tags dfec115 Align local variables 9443e4b Align struct members f814033 Add struct e6307ad Add comma operator 1c91d19 Emit .file and .loc assembler directives 6647ad9 Precompute line number for each token cd832a3 Rewrite tests in shell script in C ca8b243 Handle block scope 6c0a429 Add line and block comments a0388ba Add -o and --help options 7b8528f Refactor -- no functionality change d9ea597 Read code from a file instead of argv[1] 9dae234 [GNU] Add statement expression c2cc1d3 Add \x 699d2b7 Add \ ad7749f Add \a, \b, \t, \n \v, \f, \r and \e 35a0bcd Refactoring: Add a utility function 4cedda2 Add string literal be38d63 Add char type a4d3223 Add global variables 0b76634 Merge Function with Var 3e55caf Add sizeof 648646b Add [] operator 3ce1b2d Add arrays of arrays 8b6395d Add one dimensional arrays aacc0cf Support function definition up to 6 parameters 6cb4220 Support zero-arity function definition 964b1d2 Support function call with up to 6 arguments 30a3992 Support zero-arity function calls b4e82cf Add keyword "int" and make variable definition mandatory a6bc4ab Make pointer arithmetic work 863e2b8 Add unary & and * 3d86277 Add a representative node to each Node to improve error messages 5b142b1 Add LICENSE and README.md 1f3eb34 Add "while" statement f5d480f Add "for" statement 72b8415 Add "if" statement ff8912c Add null statement 18ac283 Add { ... } 6cc1c1f Add "return" statement 482c26b Support multi-letter local variables 1f9f3ad Support single-letter local variables 76cae0a Accept multiple statements separated by semicolons 725badf Split main.c into multiple small files 25b4b85 Add ==, !=, <= and >= operators bf9ab52 Add unary plus and minus 84cfcaf Add *, / and () cc5a6d9 Improve error message a1ab0ff Add a tokenizer to allow space characters between tokens bf7081f Add + and - operators 0522e2d Compile an integer to an exectuable that exits with the given number

Slide 311

Slide 311 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 セルフホストまでの道 • chibiccのリポジトリでは合計316コミットある • pccは4月時点で138コミットまで進んでた 51 90d1f7f Make struct member access to work with `=` and `?:` 982041f Update README b35d148 Add __attribute__((aligned(N)) for struct declaration 44bea4c Add __attribute__((packed)) 395308c redefinition 2ed3fda Add test/thirdparty/cpython.sh 0a5d08c Complete stdatomic.h d69a11d Add _Atomic and atomic ++, -- and op= operators 80ea9d4 Add atomic_exchange ca27455 Add atomic_compare_exchange fb49370 Add scripts to test third-party apps 469f159 Add -Xlinker option d1bc9a4 Add -Wl, option c8df787 Add -L option 4e5de36 Add -shared option 1e9b6dd Add -static option f10bceb [GNU] Add #include_next a6c6622 [GNU] Add "#pragma once" d48d9e5 Add include guard optimization c0f0614 Cache file search results 86785fc Add -fpic and -fPIC options c3edffb Add -MMD option 7aa72e4 Add -MQ option fb5cfe5 Add -MD option db850f3 Add -MT option 57c1d4e Add -MP option 95d5a46 Add -MF option d0c4667 Add -M option f694413 Use hashmap for keyword lookup 655954e Use hashmap for block-scope lookup 30520e5 Use hashmap for macro name lookup 0aad326 Add string hashmap f0c98e0 [GNU] Treat labels-as-values as compile-time constant 4f165ec [GNU] Support labels-as-values 3d5550e [GNU] Support array range designator d90c73b [GNU] Support case ranges e0bf168 Add long double d56dd2f Recognize .a and .so files 8d130ab Emit size and type for symbols c32f0e2 Add -s option bc25279 Add -l option b0109a3 Do not define __STDC_NO_VLA__ 2fa8f48 Support sizeof(typename) where typename is a VLA 07f9010 Add pointer arithmetic for VLA e8667af Add sizeof() for VLA 77275c5 Add alloca() 4064871 Make -E to imply -xc ee0a951 Add -x option 8f5ff07 Add -include option b377284 Add thread-local variable 6d344ed Add -fcommon and -fno-common flags 85e46b1 Add tentative definition 1b99bad Add offsetof 11fc259 Add -idirafter option 6a2dc5a Use __attribute__((format(print, ...))) to find programming errors e5f4ca9 Do not emit static inline functions if referenced by no one 31087f8 Handle inline functions as static functions a253516 Add basic "asm" statement e28a612 [GNU] Add ?: operator with omitted operand aee7891 [GNU] Allow sizeof() 1faab48 Add _Generic 1433b40 [GNU] Add __builtin_types_compatible_p 7d80a51 Add typeof 007e526 [GNU] Support GCC-style variadic macro 74ec9f6 Ignore #pragma 083c275 [GNU] Handle ,##__VA_ARG__ 3381448 Add __VA_OPT__ 3a10c8a [GNU] Add __BASE_FILE__ macro 922604a [GNU] Add __TIMESTAMP__ macro aaf20fb [GNU] Add line marker directive c61c0d0 Add #line 37998be Improve error message for multibyte characters 95eb5b0 Handle struct designator for anonymous struct member 31dc1df Add union designated initializer 67f5834 Add struct designated initializer 691c4fa [GNU] Allow to omit "=" in designated initializers 835cd24 Allow array designators to initialize incomplete arrays c618c3b Add array designated initializer 2b2fa25 Skip UTF-8 BOM markers 2382777 Allow to concatenate regular string literals with L/u/U string literals adb8b98 [GNU] Accept $ as an identifier character 0e5d250 Allow multibyte UTF-8 character in identifier e4491b8 Define __STDC_UTF_{16,32}__ macros 6adba75 Add UTF-32 string literal initializer 36230e0 Add UTF-16 string literal initializer cae061a Add wide string literal c467ee6 Add UTF-32 string literal 9cabe1f Add UTF-16 string literal 57b21fe Add UTF-8 string literal 2dac3af Add UTF-32 character literal 454618c Add UTF-16 character literal a57c661 Accept multibyte character as wide character literal c31886a Add \u and \U escape sequences 74bcec5 Canonicalize newline character 0e77f3d [GNU] Add __COUNTER__ macro e27417f Add __DATE__ and __TIME__ macros c3075b3 Add anonymous struct and union 9c36dd7 Make "main" to implicitly return 0 5257ee0 Make an array of at least 16 bytes long to have alignment of at least 16 bytes 2c91da5 Turn on -Wall compiler flag and fix compiler warnings b1fdddf Ignore -O, -W and -g and other flags 2bdc6b8 Write to an in-memory buffer before writing to an actual output file c302a96 Do not allow to obtain an address of a bitfield 17ea802 Handle zero-width bitfield member 54c2b3b Handle op=-style assignments to bitfields 441a89b Support global struct bitfield initializer cc852fe Add bitfield be8b6f6 Add -U option fc69f5c Add -D option 3f2c2d5 Tokenize numeric tokens as pp-numbers e0b5da3 Dereferencing a function shouldn't do anything 603de50 Add va_copy() b6d3cd0 Allow variadic function to take more than 6 parameters d7bad96 Allow to define a function returning a struct c72df1c Allow to call a fucntion returning a struct d63b1f4 Allow struct argument 5e0f8c4 Allow struct parameter 9021f7f Support passed-on-stack parameters b29f052 Support passed-on-stack arguments 12a9e75 Self-host: including preprocessor, chibicc can compile itself 5322ea8 Add va_arg() 7cbfd11 Add stdarg.h, stdbool.h, stddef.h, stdalign.h and float.h 7746e4e Recognize wide character literal ab4f1e1 Concatenate adjacent string literals 82ba010 [GNU] Add __FUNCTION__ ba6b4b6 Add __func__ dc01f94 Add __VA_ARGS__ 6f17071 Add __FILE__ and __LINE__ 5f5a850 Add predefine macros such as __STDC__ e7fdc2e Add #error a939a7a Add default include paths a1dd621 Add -I option d85fc4f Add #include <...> b33fe0e Support line continuation 8075582 Preserve newline and space during macro expansion a8d76ad Replace remaining identifiers with 0 in macro constexpr 5cb2f89 Add defined() macro operator 769b5a0 Use chibicc's preprocessor for all tests 8f561ae Add macro token-pasting operator (##) 8f6f792 Add macro stringizing operator (#) 1313fc6 Do not expand a token more than once for the same funclike macro c7d7ce0 Allow parenthesized expressions as macro arguments dd4306c Allow empty macro arguments b9ad3e4 Add multi-arity funclike #define dec3b3f Add zero-arity funclike #define 1f80f58 Add #ifdef and #ifndef acce002 Do not expand a token more than once for the same objlike macro 2651448 Expand macros in the #if and #elif argument context 9ad60e4 Add #undef 97d33ad Add objlike #define e7a1857 Add #elif c6e81d2 Add #else aa570f3 Skip nested #if in a skipped #if-clause bf6ff92 Add #if and #endif d138864 Add -E option ec149f6 Skip extra tokens after `#include "..."` d367510 Add #include "..." 146c7b3 Add the null directive 1e1ea39 Add a do-nothing preprocessor 8b726b5 Run "ld" unless -c is given b833cd0 Accept multiple input files 140b433 Run "as" command unless -S is given f3d9613 Split cc1 from compiler driver 53e8103 Add usual arithmetic conversion for function pointer c5953ba Decay a function to a pointer in the func param context d06a8ac Add function pointer 5d15431 Add stage2 build 9bf9612 Add "long double" as an alias for "double" ffea421 Add flonum constant expression e452cf7 Support variadic function with floating-point parameters 8b14859 Implement default argument promotion for float c6b3056 Allow to define a function that takes/returns flonums 8ec1ebf Allow to call a function that takes/returns flonums 0ce1093 Handle flonum for if, while, do, !, ?:, || and && 83f76eb Add flonum +, -, * and / cf9ceec Add flonum ==, !=, < and <= 29de46a Add "float" and "double" local variables and casts 1e57f72 Add floating-point constant 1fad259 Allow to omit parameter name in function declaration 93d1277 Ignore "static" and "const" in array-dimensions b773554 Ignore const, volatile, auto, register, restrict or _Noreturn. 7ba6fe8 Handle unsigned types in the constant expression 6880a39 When comparing two pointers, treat them as unsigned 8b8f3de Use long or ulong instead of int for some expressions aaf1045 Add U, L and LL suffixes 34ab83b Add unsigned integral types 3f59ce7 Add `signed` keyword 197689a Check the number of function arguments 754a24f Add va_start to support variadic functions 58fc861 Allow to call a variadic function dcd4579 Handle a function returning bool, char or short 6a0ed71 Align stack frame to 16 byte boundaries ee252e6 Add do ... while eb85527 Add static global variables 30b3e21 Add return that doesn't take any value 127056d Add compound literals 319772b Add static local variables 310a87e [GNU] Allow a variable as an operand of _Alignof 9df5178 Add _Alignof and _Alignas 2764745 Handle extern declarations in a block 006a45c Add extern 157356c Align global variables 7a1f816 Accept `void` as a parameter list cd688a8 Allow to initialize struct flexible array member 824543b Add flexible array member 3d216e3 Emit uninitialized global data to .bss instead of .data fde464c Allow extraneous comma at the end of enum or initializer list a58958c Allow extraneous braces for scalar initializer efa0f33 Allow parentheses in initializers to be omitted 1eae5ae Handle union initializers for global variable eeb62b6 Add struct initializer for global variable bbfe3f4 Add global initializer for scalar and string 483b194 Handle union initializers for local variables aca19dd Allow to initialize a struct with other struct e9d2c46 Handle struct initializers for local variables 5b95533 Allow to omit array length if an initializer is given 0d71737 Add string literal initializer a754732 Skip excess initializer elements ae0a37d Initialize excess array elements with zero 22dd560 Support local variable initializers 79f5de2 Add constant expression 447ee09 Add ?: operator d0c0cb7 Add <<, >>, <<= and >>= 044d9ae Add switch-case 3c83dfd Add continue statement b3047f2 Add break statement a4be55b Resolve conflict between labels and typedefs 6116cae Add goto and labeled statement 61a1055 Add a notion of an incomplete struct type 7963221 Decay an array to a pointer in the func param context 29ed294 Add a notion of an incomplete array type f30f781 Add && and || 8644006 Add &, |, ^, &=, |= and ^= daa7398 Add % and %= 46a96d6 Add ~ operator 6b88bcb Add ! operator 7df934d Add hexadecimal, octal and binary number literals e8ca48c Add post ++ and -- 47f1937 Add pre ++ and -- 01a94c0 Add +=, -=, *= and /= a4fea2b Allow for-loops to define local variables 736232f Support file-scope functions 48ba265 Add enum aa0accc Add character literal 44bba96 Add _Bool type fdc80bc Handle function argument type conversion 818352a Handle return type conversion 9e211cb Report an error on undefined/undeclared functions 8b430a6 Implement usual arithmetic conversion cfc4fa9 Add type cast cb81a37 Use 32 bit registers for char, short and int 67543ea Make sizeof to accept not only an expression but also a typename a6b82da Add typedef f46370e Add `long long` as an alias for `long` 287906a Handle complex type declarations correctly 8c3503b Add void type 74e3acc Add function declaration a817b23 Add nested type declarators 9d48eef Add short type 43c2f08 Add long type 5831eda Change size of int from 8 to 4 bef0543 Add struct assignment 11e3841 Add union f0a018a Add -> operator e1e831e Support struct tags dfec115 Align local variables 9443e4b Align struct members f814033 Add struct e6307ad Add comma operator 1c91d19 Emit .file and .loc assembler directives 6647ad9 Precompute line number for each token cd832a3 Rewrite tests in shell script in C ca8b243 Handle block scope 6c0a429 Add line and block comments a0388ba Add -o and --help options 7b8528f Refactor -- no functionality change d9ea597 Read code from a file instead of argv[1] 9dae234 [GNU] Add statement expression c2cc1d3 Add \x 699d2b7 Add \ ad7749f Add \a, \b, \t, \n \v, \f, \r and \e 35a0bcd Refactoring: Add a utility function 4cedda2 Add string literal be38d63 Add char type a4d3223 Add global variables 0b76634 Merge Function with Var 3e55caf Add sizeof 648646b Add [] operator 3ce1b2d Add arrays of arrays 8b6395d Add one dimensional arrays aacc0cf Support function definition up to 6 parameters 6cb4220 Support zero-arity function definition 964b1d2 Support function call with up to 6 arguments 30a3992 Support zero-arity function calls b4e82cf Add keyword "int" and make variable definition mandatory a6bc4ab Make pointer arithmetic work 863e2b8 Add unary & and * 3d86277 Add a representative node to each Node to improve error messages 5b142b1 Add LICENSE and README.md 1f3eb34 Add "while" statement f5d480f Add "for" statement 72b8415 Add "if" statement ff8912c Add null statement 18ac283 Add { ... } 6cc1c1f Add "return" statement 482c26b Support multi-letter local variables 1f9f3ad Support single-letter local variables 76cae0a Accept multiple statements separated by semicolons 725badf Split main.c into multiple small files 25b4b85 Add ==, !=, <= and >= operators bf9ab52 Add unary plus and minus 84cfcaf Add *, / and () cc5a6d9 Improve error message a1ab0ff Add a tokenizer to allow space characters between tokens bf7081f Add + and - operators 0522e2d Compile an integer to an exectuable that exits with the given number 4月 138/316

Slide 312

Slide 312 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 セルフホストまでの道 • chibiccのリポジトリでは合計316コミットある • pccは4月時点で138コミットまで進んでた • 196コミットでchibiccとしてはセルフホストできる模様 51 90d1f7f Make struct member access to work with `=` and `?:` 982041f Update README b35d148 Add __attribute__((aligned(N)) for struct declaration 44bea4c Add __attribute__((packed)) 395308c redefinition 2ed3fda Add test/thirdparty/cpython.sh 0a5d08c Complete stdatomic.h d69a11d Add _Atomic and atomic ++, -- and op= operators 80ea9d4 Add atomic_exchange ca27455 Add atomic_compare_exchange fb49370 Add scripts to test third-party apps 469f159 Add -Xlinker option d1bc9a4 Add -Wl, option c8df787 Add -L option 4e5de36 Add -shared option 1e9b6dd Add -static option f10bceb [GNU] Add #include_next a6c6622 [GNU] Add "#pragma once" d48d9e5 Add include guard optimization c0f0614 Cache file search results 86785fc Add -fpic and -fPIC options c3edffb Add -MMD option 7aa72e4 Add -MQ option fb5cfe5 Add -MD option db850f3 Add -MT option 57c1d4e Add -MP option 95d5a46 Add -MF option d0c4667 Add -M option f694413 Use hashmap for keyword lookup 655954e Use hashmap for block-scope lookup 30520e5 Use hashmap for macro name lookup 0aad326 Add string hashmap f0c98e0 [GNU] Treat labels-as-values as compile-time constant 4f165ec [GNU] Support labels-as-values 3d5550e [GNU] Support array range designator d90c73b [GNU] Support case ranges e0bf168 Add long double d56dd2f Recognize .a and .so files 8d130ab Emit size and type for symbols c32f0e2 Add -s option bc25279 Add -l option b0109a3 Do not define __STDC_NO_VLA__ 2fa8f48 Support sizeof(typename) where typename is a VLA 07f9010 Add pointer arithmetic for VLA e8667af Add sizeof() for VLA 77275c5 Add alloca() 4064871 Make -E to imply -xc ee0a951 Add -x option 8f5ff07 Add -include option b377284 Add thread-local variable 6d344ed Add -fcommon and -fno-common flags 85e46b1 Add tentative definition 1b99bad Add offsetof 11fc259 Add -idirafter option 6a2dc5a Use __attribute__((format(print, ...))) to find programming errors e5f4ca9 Do not emit static inline functions if referenced by no one 31087f8 Handle inline functions as static functions a253516 Add basic "asm" statement e28a612 [GNU] Add ?: operator with omitted operand aee7891 [GNU] Allow sizeof() 1faab48 Add _Generic 1433b40 [GNU] Add __builtin_types_compatible_p 7d80a51 Add typeof 007e526 [GNU] Support GCC-style variadic macro 74ec9f6 Ignore #pragma 083c275 [GNU] Handle ,##__VA_ARG__ 3381448 Add __VA_OPT__ 3a10c8a [GNU] Add __BASE_FILE__ macro 922604a [GNU] Add __TIMESTAMP__ macro aaf20fb [GNU] Add line marker directive c61c0d0 Add #line 37998be Improve error message for multibyte characters 95eb5b0 Handle struct designator for anonymous struct member 31dc1df Add union designated initializer 67f5834 Add struct designated initializer 691c4fa [GNU] Allow to omit "=" in designated initializers 835cd24 Allow array designators to initialize incomplete arrays c618c3b Add array designated initializer 2b2fa25 Skip UTF-8 BOM markers 2382777 Allow to concatenate regular string literals with L/u/U string literals adb8b98 [GNU] Accept $ as an identifier character 0e5d250 Allow multibyte UTF-8 character in identifier e4491b8 Define __STDC_UTF_{16,32}__ macros 6adba75 Add UTF-32 string literal initializer 36230e0 Add UTF-16 string literal initializer cae061a Add wide string literal c467ee6 Add UTF-32 string literal 9cabe1f Add UTF-16 string literal 57b21fe Add UTF-8 string literal 2dac3af Add UTF-32 character literal 454618c Add UTF-16 character literal a57c661 Accept multibyte character as wide character literal c31886a Add \u and \U escape sequences 74bcec5 Canonicalize newline character 0e77f3d [GNU] Add __COUNTER__ macro e27417f Add __DATE__ and __TIME__ macros c3075b3 Add anonymous struct and union 9c36dd7 Make "main" to implicitly return 0 5257ee0 Make an array of at least 16 bytes long to have alignment of at least 16 bytes 2c91da5 Turn on -Wall compiler flag and fix compiler warnings b1fdddf Ignore -O, -W and -g and other flags 2bdc6b8 Write to an in-memory buffer before writing to an actual output file c302a96 Do not allow to obtain an address of a bitfield 17ea802 Handle zero-width bitfield member 54c2b3b Handle op=-style assignments to bitfields 441a89b Support global struct bitfield initializer cc852fe Add bitfield be8b6f6 Add -U option fc69f5c Add -D option 3f2c2d5 Tokenize numeric tokens as pp-numbers e0b5da3 Dereferencing a function shouldn't do anything 603de50 Add va_copy() b6d3cd0 Allow variadic function to take more than 6 parameters d7bad96 Allow to define a function returning a struct c72df1c Allow to call a fucntion returning a struct d63b1f4 Allow struct argument 5e0f8c4 Allow struct parameter 9021f7f Support passed-on-stack parameters b29f052 Support passed-on-stack arguments 12a9e75 Self-host: including preprocessor, chibicc can compile itself 5322ea8 Add va_arg() 7cbfd11 Add stdarg.h, stdbool.h, stddef.h, stdalign.h and float.h 7746e4e Recognize wide character literal ab4f1e1 Concatenate adjacent string literals 82ba010 [GNU] Add __FUNCTION__ ba6b4b6 Add __func__ dc01f94 Add __VA_ARGS__ 6f17071 Add __FILE__ and __LINE__ 5f5a850 Add predefine macros such as __STDC__ e7fdc2e Add #error a939a7a Add default include paths a1dd621 Add -I option d85fc4f Add #include <...> b33fe0e Support line continuation 8075582 Preserve newline and space during macro expansion a8d76ad Replace remaining identifiers with 0 in macro constexpr 5cb2f89 Add defined() macro operator 769b5a0 Use chibicc's preprocessor for all tests 8f561ae Add macro token-pasting operator (##) 8f6f792 Add macro stringizing operator (#) 1313fc6 Do not expand a token more than once for the same funclike macro c7d7ce0 Allow parenthesized expressions as macro arguments dd4306c Allow empty macro arguments b9ad3e4 Add multi-arity funclike #define dec3b3f Add zero-arity funclike #define 1f80f58 Add #ifdef and #ifndef acce002 Do not expand a token more than once for the same objlike macro 2651448 Expand macros in the #if and #elif argument context 9ad60e4 Add #undef 97d33ad Add objlike #define e7a1857 Add #elif c6e81d2 Add #else aa570f3 Skip nested #if in a skipped #if-clause bf6ff92 Add #if and #endif d138864 Add -E option ec149f6 Skip extra tokens after `#include "..."` d367510 Add #include "..." 146c7b3 Add the null directive 1e1ea39 Add a do-nothing preprocessor 8b726b5 Run "ld" unless -c is given b833cd0 Accept multiple input files 140b433 Run "as" command unless -S is given f3d9613 Split cc1 from compiler driver 53e8103 Add usual arithmetic conversion for function pointer c5953ba Decay a function to a pointer in the func param context d06a8ac Add function pointer 5d15431 Add stage2 build 9bf9612 Add "long double" as an alias for "double" ffea421 Add flonum constant expression e452cf7 Support variadic function with floating-point parameters 8b14859 Implement default argument promotion for float c6b3056 Allow to define a function that takes/returns flonums 8ec1ebf Allow to call a function that takes/returns flonums 0ce1093 Handle flonum for if, while, do, !, ?:, || and && 83f76eb Add flonum +, -, * and / cf9ceec Add flonum ==, !=, < and <= 29de46a Add "float" and "double" local variables and casts 1e57f72 Add floating-point constant 1fad259 Allow to omit parameter name in function declaration 93d1277 Ignore "static" and "const" in array-dimensions b773554 Ignore const, volatile, auto, register, restrict or _Noreturn. 7ba6fe8 Handle unsigned types in the constant expression 6880a39 When comparing two pointers, treat them as unsigned 8b8f3de Use long or ulong instead of int for some expressions aaf1045 Add U, L and LL suffixes 34ab83b Add unsigned integral types 3f59ce7 Add `signed` keyword 197689a Check the number of function arguments 754a24f Add va_start to support variadic functions 58fc861 Allow to call a variadic function dcd4579 Handle a function returning bool, char or short 6a0ed71 Align stack frame to 16 byte boundaries ee252e6 Add do ... while eb85527 Add static global variables 30b3e21 Add return that doesn't take any value 127056d Add compound literals 319772b Add static local variables 310a87e [GNU] Allow a variable as an operand of _Alignof 9df5178 Add _Alignof and _Alignas 2764745 Handle extern declarations in a block 006a45c Add extern 157356c Align global variables 7a1f816 Accept `void` as a parameter list cd688a8 Allow to initialize struct flexible array member 824543b Add flexible array member 3d216e3 Emit uninitialized global data to .bss instead of .data fde464c Allow extraneous comma at the end of enum or initializer list a58958c Allow extraneous braces for scalar initializer efa0f33 Allow parentheses in initializers to be omitted 1eae5ae Handle union initializers for global variable eeb62b6 Add struct initializer for global variable bbfe3f4 Add global initializer for scalar and string 483b194 Handle union initializers for local variables aca19dd Allow to initialize a struct with other struct e9d2c46 Handle struct initializers for local variables 5b95533 Allow to omit array length if an initializer is given 0d71737 Add string literal initializer a754732 Skip excess initializer elements ae0a37d Initialize excess array elements with zero 22dd560 Support local variable initializers 79f5de2 Add constant expression 447ee09 Add ?: operator d0c0cb7 Add <<, >>, <<= and >>= 044d9ae Add switch-case 3c83dfd Add continue statement b3047f2 Add break statement a4be55b Resolve conflict between labels and typedefs 6116cae Add goto and labeled statement 61a1055 Add a notion of an incomplete struct type 7963221 Decay an array to a pointer in the func param context 29ed294 Add a notion of an incomplete array type f30f781 Add && and || 8644006 Add &, |, ^, &=, |= and ^= daa7398 Add % and %= 46a96d6 Add ~ operator 6b88bcb Add ! operator 7df934d Add hexadecimal, octal and binary number literals e8ca48c Add post ++ and -- 47f1937 Add pre ++ and -- 01a94c0 Add +=, -=, *= and /= a4fea2b Allow for-loops to define local variables 736232f Support file-scope functions 48ba265 Add enum aa0accc Add character literal 44bba96 Add _Bool type fdc80bc Handle function argument type conversion 818352a Handle return type conversion 9e211cb Report an error on undefined/undeclared functions 8b430a6 Implement usual arithmetic conversion cfc4fa9 Add type cast cb81a37 Use 32 bit registers for char, short and int 67543ea Make sizeof to accept not only an expression but also a typename a6b82da Add typedef f46370e Add `long long` as an alias for `long` 287906a Handle complex type declarations correctly 8c3503b Add void type 74e3acc Add function declaration a817b23 Add nested type declarators 9d48eef Add short type 43c2f08 Add long type 5831eda Change size of int from 8 to 4 bef0543 Add struct assignment 11e3841 Add union f0a018a Add -> operator e1e831e Support struct tags dfec115 Align local variables 9443e4b Align struct members f814033 Add struct e6307ad Add comma operator 1c91d19 Emit .file and .loc assembler directives 6647ad9 Precompute line number for each token cd832a3 Rewrite tests in shell script in C ca8b243 Handle block scope 6c0a429 Add line and block comments a0388ba Add -o and --help options 7b8528f Refactor -- no functionality change d9ea597 Read code from a file instead of argv[1] 9dae234 [GNU] Add statement expression c2cc1d3 Add \x 699d2b7 Add \ ad7749f Add \a, \b, \t, \n \v, \f, \r and \e 35a0bcd Refactoring: Add a utility function 4cedda2 Add string literal be38d63 Add char type a4d3223 Add global variables 0b76634 Merge Function with Var 3e55caf Add sizeof 648646b Add [] operator 3ce1b2d Add arrays of arrays 8b6395d Add one dimensional arrays aacc0cf Support function definition up to 6 parameters 6cb4220 Support zero-arity function definition 964b1d2 Support function call with up to 6 arguments 30a3992 Support zero-arity function calls b4e82cf Add keyword "int" and make variable definition mandatory a6bc4ab Make pointer arithmetic work 863e2b8 Add unary & and * 3d86277 Add a representative node to each Node to improve error messages 5b142b1 Add LICENSE and README.md 1f3eb34 Add "while" statement f5d480f Add "for" statement 72b8415 Add "if" statement ff8912c Add null statement 18ac283 Add { ... } 6cc1c1f Add "return" statement 482c26b Support multi-letter local variables 1f9f3ad Support single-letter local variables 76cae0a Accept multiple statements separated by semicolons 725badf Split main.c into multiple small files 25b4b85 Add ==, !=, <= and >= operators bf9ab52 Add unary plus and minus 84cfcaf Add *, / and () cc5a6d9 Improve error message a1ab0ff Add a tokenizer to allow space characters between tokens bf7081f Add + and - operators 0522e2d Compile an integer to an exectuable that exits with the given number chibicc セルフホスト 196/316 4月 138/316

Slide 313

Slide 313 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 セルフホストまでの道 • chibiccのリポジトリでは合計316コミットある • pccは4月時点で138コミットまで進んでた • 196コミットでchibiccとしてはセルフホストできる模様 • 今はAIの力を借りてここらへんまできました 51 90d1f7f Make struct member access to work with `=` and `?:` 982041f Update README b35d148 Add __attribute__((aligned(N)) for struct declaration 44bea4c Add __attribute__((packed)) 395308c redefinition 2ed3fda Add test/thirdparty/cpython.sh 0a5d08c Complete stdatomic.h d69a11d Add _Atomic and atomic ++, -- and op= operators 80ea9d4 Add atomic_exchange ca27455 Add atomic_compare_exchange fb49370 Add scripts to test third-party apps 469f159 Add -Xlinker option d1bc9a4 Add -Wl, option c8df787 Add -L option 4e5de36 Add -shared option 1e9b6dd Add -static option f10bceb [GNU] Add #include_next a6c6622 [GNU] Add "#pragma once" d48d9e5 Add include guard optimization c0f0614 Cache file search results 86785fc Add -fpic and -fPIC options c3edffb Add -MMD option 7aa72e4 Add -MQ option fb5cfe5 Add -MD option db850f3 Add -MT option 57c1d4e Add -MP option 95d5a46 Add -MF option d0c4667 Add -M option f694413 Use hashmap for keyword lookup 655954e Use hashmap for block-scope lookup 30520e5 Use hashmap for macro name lookup 0aad326 Add string hashmap f0c98e0 [GNU] Treat labels-as-values as compile-time constant 4f165ec [GNU] Support labels-as-values 3d5550e [GNU] Support array range designator d90c73b [GNU] Support case ranges e0bf168 Add long double d56dd2f Recognize .a and .so files 8d130ab Emit size and type for symbols c32f0e2 Add -s option bc25279 Add -l option b0109a3 Do not define __STDC_NO_VLA__ 2fa8f48 Support sizeof(typename) where typename is a VLA 07f9010 Add pointer arithmetic for VLA e8667af Add sizeof() for VLA 77275c5 Add alloca() 4064871 Make -E to imply -xc ee0a951 Add -x option 8f5ff07 Add -include option b377284 Add thread-local variable 6d344ed Add -fcommon and -fno-common flags 85e46b1 Add tentative definition 1b99bad Add offsetof 11fc259 Add -idirafter option 6a2dc5a Use __attribute__((format(print, ...))) to find programming errors e5f4ca9 Do not emit static inline functions if referenced by no one 31087f8 Handle inline functions as static functions a253516 Add basic "asm" statement e28a612 [GNU] Add ?: operator with omitted operand aee7891 [GNU] Allow sizeof() 1faab48 Add _Generic 1433b40 [GNU] Add __builtin_types_compatible_p 7d80a51 Add typeof 007e526 [GNU] Support GCC-style variadic macro 74ec9f6 Ignore #pragma 083c275 [GNU] Handle ,##__VA_ARG__ 3381448 Add __VA_OPT__ 3a10c8a [GNU] Add __BASE_FILE__ macro 922604a [GNU] Add __TIMESTAMP__ macro aaf20fb [GNU] Add line marker directive c61c0d0 Add #line 37998be Improve error message for multibyte characters 95eb5b0 Handle struct designator for anonymous struct member 31dc1df Add union designated initializer 67f5834 Add struct designated initializer 691c4fa [GNU] Allow to omit "=" in designated initializers 835cd24 Allow array designators to initialize incomplete arrays c618c3b Add array designated initializer 2b2fa25 Skip UTF-8 BOM markers 2382777 Allow to concatenate regular string literals with L/u/U string literals adb8b98 [GNU] Accept $ as an identifier character 0e5d250 Allow multibyte UTF-8 character in identifier e4491b8 Define __STDC_UTF_{16,32}__ macros 6adba75 Add UTF-32 string literal initializer 36230e0 Add UTF-16 string literal initializer cae061a Add wide string literal c467ee6 Add UTF-32 string literal 9cabe1f Add UTF-16 string literal 57b21fe Add UTF-8 string literal 2dac3af Add UTF-32 character literal 454618c Add UTF-16 character literal a57c661 Accept multibyte character as wide character literal c31886a Add \u and \U escape sequences 74bcec5 Canonicalize newline character 0e77f3d [GNU] Add __COUNTER__ macro e27417f Add __DATE__ and __TIME__ macros c3075b3 Add anonymous struct and union 9c36dd7 Make "main" to implicitly return 0 5257ee0 Make an array of at least 16 bytes long to have alignment of at least 16 bytes 2c91da5 Turn on -Wall compiler flag and fix compiler warnings b1fdddf Ignore -O, -W and -g and other flags 2bdc6b8 Write to an in-memory buffer before writing to an actual output file c302a96 Do not allow to obtain an address of a bitfield 17ea802 Handle zero-width bitfield member 54c2b3b Handle op=-style assignments to bitfields 441a89b Support global struct bitfield initializer cc852fe Add bitfield be8b6f6 Add -U option fc69f5c Add -D option 3f2c2d5 Tokenize numeric tokens as pp-numbers e0b5da3 Dereferencing a function shouldn't do anything 603de50 Add va_copy() b6d3cd0 Allow variadic function to take more than 6 parameters d7bad96 Allow to define a function returning a struct c72df1c Allow to call a fucntion returning a struct d63b1f4 Allow struct argument 5e0f8c4 Allow struct parameter 9021f7f Support passed-on-stack parameters b29f052 Support passed-on-stack arguments 12a9e75 Self-host: including preprocessor, chibicc can compile itself 5322ea8 Add va_arg() 7cbfd11 Add stdarg.h, stdbool.h, stddef.h, stdalign.h and float.h 7746e4e Recognize wide character literal ab4f1e1 Concatenate adjacent string literals 82ba010 [GNU] Add __FUNCTION__ ba6b4b6 Add __func__ dc01f94 Add __VA_ARGS__ 6f17071 Add __FILE__ and __LINE__ 5f5a850 Add predefine macros such as __STDC__ e7fdc2e Add #error a939a7a Add default include paths a1dd621 Add -I option d85fc4f Add #include <...> b33fe0e Support line continuation 8075582 Preserve newline and space during macro expansion a8d76ad Replace remaining identifiers with 0 in macro constexpr 5cb2f89 Add defined() macro operator 769b5a0 Use chibicc's preprocessor for all tests 8f561ae Add macro token-pasting operator (##) 8f6f792 Add macro stringizing operator (#) 1313fc6 Do not expand a token more than once for the same funclike macro c7d7ce0 Allow parenthesized expressions as macro arguments dd4306c Allow empty macro arguments b9ad3e4 Add multi-arity funclike #define dec3b3f Add zero-arity funclike #define 1f80f58 Add #ifdef and #ifndef acce002 Do not expand a token more than once for the same objlike macro 2651448 Expand macros in the #if and #elif argument context 9ad60e4 Add #undef 97d33ad Add objlike #define e7a1857 Add #elif c6e81d2 Add #else aa570f3 Skip nested #if in a skipped #if-clause bf6ff92 Add #if and #endif d138864 Add -E option ec149f6 Skip extra tokens after `#include "..."` d367510 Add #include "..." 146c7b3 Add the null directive 1e1ea39 Add a do-nothing preprocessor 8b726b5 Run "ld" unless -c is given b833cd0 Accept multiple input files 140b433 Run "as" command unless -S is given f3d9613 Split cc1 from compiler driver 53e8103 Add usual arithmetic conversion for function pointer c5953ba Decay a function to a pointer in the func param context d06a8ac Add function pointer 5d15431 Add stage2 build 9bf9612 Add "long double" as an alias for "double" ffea421 Add flonum constant expression e452cf7 Support variadic function with floating-point parameters 8b14859 Implement default argument promotion for float c6b3056 Allow to define a function that takes/returns flonums 8ec1ebf Allow to call a function that takes/returns flonums 0ce1093 Handle flonum for if, while, do, !, ?:, || and && 83f76eb Add flonum +, -, * and / cf9ceec Add flonum ==, !=, < and <= 29de46a Add "float" and "double" local variables and casts 1e57f72 Add floating-point constant 1fad259 Allow to omit parameter name in function declaration 93d1277 Ignore "static" and "const" in array-dimensions b773554 Ignore const, volatile, auto, register, restrict or _Noreturn. 7ba6fe8 Handle unsigned types in the constant expression 6880a39 When comparing two pointers, treat them as unsigned 8b8f3de Use long or ulong instead of int for some expressions aaf1045 Add U, L and LL suffixes 34ab83b Add unsigned integral types 3f59ce7 Add `signed` keyword 197689a Check the number of function arguments 754a24f Add va_start to support variadic functions 58fc861 Allow to call a variadic function dcd4579 Handle a function returning bool, char or short 6a0ed71 Align stack frame to 16 byte boundaries ee252e6 Add do ... while eb85527 Add static global variables 30b3e21 Add return that doesn't take any value 127056d Add compound literals 319772b Add static local variables 310a87e [GNU] Allow a variable as an operand of _Alignof 9df5178 Add _Alignof and _Alignas 2764745 Handle extern declarations in a block 006a45c Add extern 157356c Align global variables 7a1f816 Accept `void` as a parameter list cd688a8 Allow to initialize struct flexible array member 824543b Add flexible array member 3d216e3 Emit uninitialized global data to .bss instead of .data fde464c Allow extraneous comma at the end of enum or initializer list a58958c Allow extraneous braces for scalar initializer efa0f33 Allow parentheses in initializers to be omitted 1eae5ae Handle union initializers for global variable eeb62b6 Add struct initializer for global variable bbfe3f4 Add global initializer for scalar and string 483b194 Handle union initializers for local variables aca19dd Allow to initialize a struct with other struct e9d2c46 Handle struct initializers for local variables 5b95533 Allow to omit array length if an initializer is given 0d71737 Add string literal initializer a754732 Skip excess initializer elements ae0a37d Initialize excess array elements with zero 22dd560 Support local variable initializers 79f5de2 Add constant expression 447ee09 Add ?: operator d0c0cb7 Add <<, >>, <<= and >>= 044d9ae Add switch-case 3c83dfd Add continue statement b3047f2 Add break statement a4be55b Resolve conflict between labels and typedefs 6116cae Add goto and labeled statement 61a1055 Add a notion of an incomplete struct type 7963221 Decay an array to a pointer in the func param context 29ed294 Add a notion of an incomplete array type f30f781 Add && and || 8644006 Add &, |, ^, &=, |= and ^= daa7398 Add % and %= 46a96d6 Add ~ operator 6b88bcb Add ! operator 7df934d Add hexadecimal, octal and binary number literals e8ca48c Add post ++ and -- 47f1937 Add pre ++ and -- 01a94c0 Add +=, -=, *= and /= a4fea2b Allow for-loops to define local variables 736232f Support file-scope functions 48ba265 Add enum aa0accc Add character literal 44bba96 Add _Bool type fdc80bc Handle function argument type conversion 818352a Handle return type conversion 9e211cb Report an error on undefined/undeclared functions 8b430a6 Implement usual arithmetic conversion cfc4fa9 Add type cast cb81a37 Use 32 bit registers for char, short and int 67543ea Make sizeof to accept not only an expression but also a typename a6b82da Add typedef f46370e Add `long long` as an alias for `long` 287906a Handle complex type declarations correctly 8c3503b Add void type 74e3acc Add function declaration a817b23 Add nested type declarators 9d48eef Add short type 43c2f08 Add long type 5831eda Change size of int from 8 to 4 bef0543 Add struct assignment 11e3841 Add union f0a018a Add -> operator e1e831e Support struct tags dfec115 Align local variables 9443e4b Align struct members f814033 Add struct e6307ad Add comma operator 1c91d19 Emit .file and .loc assembler directives 6647ad9 Precompute line number for each token cd832a3 Rewrite tests in shell script in C ca8b243 Handle block scope 6c0a429 Add line and block comments a0388ba Add -o and --help options 7b8528f Refactor -- no functionality change d9ea597 Read code from a file instead of argv[1] 9dae234 [GNU] Add statement expression c2cc1d3 Add \x 699d2b7 Add \ ad7749f Add \a, \b, \t, \n \v, \f, \r and \e 35a0bcd Refactoring: Add a utility function 4cedda2 Add string literal be38d63 Add char type a4d3223 Add global variables 0b76634 Merge Function with Var 3e55caf Add sizeof 648646b Add [] operator 3ce1b2d Add arrays of arrays 8b6395d Add one dimensional arrays aacc0cf Support function definition up to 6 parameters 6cb4220 Support zero-arity function definition 964b1d2 Support function call with up to 6 arguments 30a3992 Support zero-arity function calls b4e82cf Add keyword "int" and make variable definition mandatory a6bc4ab Make pointer arithmetic work 863e2b8 Add unary & and * 3d86277 Add a representative node to each Node to improve error messages 5b142b1 Add LICENSE and README.md 1f3eb34 Add "while" statement f5d480f Add "for" statement 72b8415 Add "if" statement ff8912c Add null statement 18ac283 Add { ... } 6cc1c1f Add "return" statement 482c26b Support multi-letter local variables 1f9f3ad Support single-letter local variables 76cae0a Accept multiple statements separated by semicolons 725badf Split main.c into multiple small files 25b4b85 Add ==, !=, <= and >= operators bf9ab52 Add unary plus and minus 84cfcaf Add *, / and () cc5a6d9 Improve error message a1ab0ff Add a tokenizer to allow space characters between tokens bf7081f Add + and - operators 0522e2d Compile an integer to an exectuable that exits with the given number chibicc セルフホスト 196/316 4月 138/316 イマココ ???/316

Slide 314

Slide 314 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 セルフホストまでの道 • chibiccのリポジトリでは合計316コミットある • pccは4月時点で138コミットまで進んでた • 196コミットでchibiccとしてはセルフホストできる模様 • 今はAIの力を借りてここらへんまできました • chibiccのフォーク fuhsnn/slimcc ではPHPを コンパイルできるらしい (Rui Ueyamaさん情報) • https://github.com/fuhsnn/slimcc 51 90d1f7f Make struct member access to work with `=` and `?:` 982041f Update README b35d148 Add __attribute__((aligned(N)) for struct declaration 44bea4c Add __attribute__((packed)) 395308c redefinition 2ed3fda Add test/thirdparty/cpython.sh 0a5d08c Complete stdatomic.h d69a11d Add _Atomic and atomic ++, -- and op= operators 80ea9d4 Add atomic_exchange ca27455 Add atomic_compare_exchange fb49370 Add scripts to test third-party apps 469f159 Add -Xlinker option d1bc9a4 Add -Wl, option c8df787 Add -L option 4e5de36 Add -shared option 1e9b6dd Add -static option f10bceb [GNU] Add #include_next a6c6622 [GNU] Add "#pragma once" d48d9e5 Add include guard optimization c0f0614 Cache file search results 86785fc Add -fpic and -fPIC options c3edffb Add -MMD option 7aa72e4 Add -MQ option fb5cfe5 Add -MD option db850f3 Add -MT option 57c1d4e Add -MP option 95d5a46 Add -MF option d0c4667 Add -M option f694413 Use hashmap for keyword lookup 655954e Use hashmap for block-scope lookup 30520e5 Use hashmap for macro name lookup 0aad326 Add string hashmap f0c98e0 [GNU] Treat labels-as-values as compile-time constant 4f165ec [GNU] Support labels-as-values 3d5550e [GNU] Support array range designator d90c73b [GNU] Support case ranges e0bf168 Add long double d56dd2f Recognize .a and .so files 8d130ab Emit size and type for symbols c32f0e2 Add -s option bc25279 Add -l option b0109a3 Do not define __STDC_NO_VLA__ 2fa8f48 Support sizeof(typename) where typename is a VLA 07f9010 Add pointer arithmetic for VLA e8667af Add sizeof() for VLA 77275c5 Add alloca() 4064871 Make -E to imply -xc ee0a951 Add -x option 8f5ff07 Add -include option b377284 Add thread-local variable 6d344ed Add -fcommon and -fno-common flags 85e46b1 Add tentative definition 1b99bad Add offsetof 11fc259 Add -idirafter option 6a2dc5a Use __attribute__((format(print, ...))) to find programming errors e5f4ca9 Do not emit static inline functions if referenced by no one 31087f8 Handle inline functions as static functions a253516 Add basic "asm" statement e28a612 [GNU] Add ?: operator with omitted operand aee7891 [GNU] Allow sizeof() 1faab48 Add _Generic 1433b40 [GNU] Add __builtin_types_compatible_p 7d80a51 Add typeof 007e526 [GNU] Support GCC-style variadic macro 74ec9f6 Ignore #pragma 083c275 [GNU] Handle ,##__VA_ARG__ 3381448 Add __VA_OPT__ 3a10c8a [GNU] Add __BASE_FILE__ macro 922604a [GNU] Add __TIMESTAMP__ macro aaf20fb [GNU] Add line marker directive c61c0d0 Add #line 37998be Improve error message for multibyte characters 95eb5b0 Handle struct designator for anonymous struct member 31dc1df Add union designated initializer 67f5834 Add struct designated initializer 691c4fa [GNU] Allow to omit "=" in designated initializers 835cd24 Allow array designators to initialize incomplete arrays c618c3b Add array designated initializer 2b2fa25 Skip UTF-8 BOM markers 2382777 Allow to concatenate regular string literals with L/u/U string literals adb8b98 [GNU] Accept $ as an identifier character 0e5d250 Allow multibyte UTF-8 character in identifier e4491b8 Define __STDC_UTF_{16,32}__ macros 6adba75 Add UTF-32 string literal initializer 36230e0 Add UTF-16 string literal initializer cae061a Add wide string literal c467ee6 Add UTF-32 string literal 9cabe1f Add UTF-16 string literal 57b21fe Add UTF-8 string literal 2dac3af Add UTF-32 character literal 454618c Add UTF-16 character literal a57c661 Accept multibyte character as wide character literal c31886a Add \u and \U escape sequences 74bcec5 Canonicalize newline character 0e77f3d [GNU] Add __COUNTER__ macro e27417f Add __DATE__ and __TIME__ macros c3075b3 Add anonymous struct and union 9c36dd7 Make "main" to implicitly return 0 5257ee0 Make an array of at least 16 bytes long to have alignment of at least 16 bytes 2c91da5 Turn on -Wall compiler flag and fix compiler warnings b1fdddf Ignore -O, -W and -g and other flags 2bdc6b8 Write to an in-memory buffer before writing to an actual output file c302a96 Do not allow to obtain an address of a bitfield 17ea802 Handle zero-width bitfield member 54c2b3b Handle op=-style assignments to bitfields 441a89b Support global struct bitfield initializer cc852fe Add bitfield be8b6f6 Add -U option fc69f5c Add -D option 3f2c2d5 Tokenize numeric tokens as pp-numbers e0b5da3 Dereferencing a function shouldn't do anything 603de50 Add va_copy() b6d3cd0 Allow variadic function to take more than 6 parameters d7bad96 Allow to define a function returning a struct c72df1c Allow to call a fucntion returning a struct d63b1f4 Allow struct argument 5e0f8c4 Allow struct parameter 9021f7f Support passed-on-stack parameters b29f052 Support passed-on-stack arguments 12a9e75 Self-host: including preprocessor, chibicc can compile itself 5322ea8 Add va_arg() 7cbfd11 Add stdarg.h, stdbool.h, stddef.h, stdalign.h and float.h 7746e4e Recognize wide character literal ab4f1e1 Concatenate adjacent string literals 82ba010 [GNU] Add __FUNCTION__ ba6b4b6 Add __func__ dc01f94 Add __VA_ARGS__ 6f17071 Add __FILE__ and __LINE__ 5f5a850 Add predefine macros such as __STDC__ e7fdc2e Add #error a939a7a Add default include paths a1dd621 Add -I option d85fc4f Add #include <...> b33fe0e Support line continuation 8075582 Preserve newline and space during macro expansion a8d76ad Replace remaining identifiers with 0 in macro constexpr 5cb2f89 Add defined() macro operator 769b5a0 Use chibicc's preprocessor for all tests 8f561ae Add macro token-pasting operator (##) 8f6f792 Add macro stringizing operator (#) 1313fc6 Do not expand a token more than once for the same funclike macro c7d7ce0 Allow parenthesized expressions as macro arguments dd4306c Allow empty macro arguments b9ad3e4 Add multi-arity funclike #define dec3b3f Add zero-arity funclike #define 1f80f58 Add #ifdef and #ifndef acce002 Do not expand a token more than once for the same objlike macro 2651448 Expand macros in the #if and #elif argument context 9ad60e4 Add #undef 97d33ad Add objlike #define e7a1857 Add #elif c6e81d2 Add #else aa570f3 Skip nested #if in a skipped #if-clause bf6ff92 Add #if and #endif d138864 Add -E option ec149f6 Skip extra tokens after `#include "..."` d367510 Add #include "..." 146c7b3 Add the null directive 1e1ea39 Add a do-nothing preprocessor 8b726b5 Run "ld" unless -c is given b833cd0 Accept multiple input files 140b433 Run "as" command unless -S is given f3d9613 Split cc1 from compiler driver 53e8103 Add usual arithmetic conversion for function pointer c5953ba Decay a function to a pointer in the func param context d06a8ac Add function pointer 5d15431 Add stage2 build 9bf9612 Add "long double" as an alias for "double" ffea421 Add flonum constant expression e452cf7 Support variadic function with floating-point parameters 8b14859 Implement default argument promotion for float c6b3056 Allow to define a function that takes/returns flonums 8ec1ebf Allow to call a function that takes/returns flonums 0ce1093 Handle flonum for if, while, do, !, ?:, || and && 83f76eb Add flonum +, -, * and / cf9ceec Add flonum ==, !=, < and <= 29de46a Add "float" and "double" local variables and casts 1e57f72 Add floating-point constant 1fad259 Allow to omit parameter name in function declaration 93d1277 Ignore "static" and "const" in array-dimensions b773554 Ignore const, volatile, auto, register, restrict or _Noreturn. 7ba6fe8 Handle unsigned types in the constant expression 6880a39 When comparing two pointers, treat them as unsigned 8b8f3de Use long or ulong instead of int for some expressions aaf1045 Add U, L and LL suffixes 34ab83b Add unsigned integral types 3f59ce7 Add `signed` keyword 197689a Check the number of function arguments 754a24f Add va_start to support variadic functions 58fc861 Allow to call a variadic function dcd4579 Handle a function returning bool, char or short 6a0ed71 Align stack frame to 16 byte boundaries ee252e6 Add do ... while eb85527 Add static global variables 30b3e21 Add return that doesn't take any value 127056d Add compound literals 319772b Add static local variables 310a87e [GNU] Allow a variable as an operand of _Alignof 9df5178 Add _Alignof and _Alignas 2764745 Handle extern declarations in a block 006a45c Add extern 157356c Align global variables 7a1f816 Accept `void` as a parameter list cd688a8 Allow to initialize struct flexible array member 824543b Add flexible array member 3d216e3 Emit uninitialized global data to .bss instead of .data fde464c Allow extraneous comma at the end of enum or initializer list a58958c Allow extraneous braces for scalar initializer efa0f33 Allow parentheses in initializers to be omitted 1eae5ae Handle union initializers for global variable eeb62b6 Add struct initializer for global variable bbfe3f4 Add global initializer for scalar and string 483b194 Handle union initializers for local variables aca19dd Allow to initialize a struct with other struct e9d2c46 Handle struct initializers for local variables 5b95533 Allow to omit array length if an initializer is given 0d71737 Add string literal initializer a754732 Skip excess initializer elements ae0a37d Initialize excess array elements with zero 22dd560 Support local variable initializers 79f5de2 Add constant expression 447ee09 Add ?: operator d0c0cb7 Add <<, >>, <<= and >>= 044d9ae Add switch-case 3c83dfd Add continue statement b3047f2 Add break statement a4be55b Resolve conflict between labels and typedefs 6116cae Add goto and labeled statement 61a1055 Add a notion of an incomplete struct type 7963221 Decay an array to a pointer in the func param context 29ed294 Add a notion of an incomplete array type f30f781 Add && and || 8644006 Add &, |, ^, &=, |= and ^= daa7398 Add % and %= 46a96d6 Add ~ operator 6b88bcb Add ! operator 7df934d Add hexadecimal, octal and binary number literals e8ca48c Add post ++ and -- 47f1937 Add pre ++ and -- 01a94c0 Add +=, -=, *= and /= a4fea2b Allow for-loops to define local variables 736232f Support file-scope functions 48ba265 Add enum aa0accc Add character literal 44bba96 Add _Bool type fdc80bc Handle function argument type conversion 818352a Handle return type conversion 9e211cb Report an error on undefined/undeclared functions 8b430a6 Implement usual arithmetic conversion cfc4fa9 Add type cast cb81a37 Use 32 bit registers for char, short and int 67543ea Make sizeof to accept not only an expression but also a typename a6b82da Add typedef f46370e Add `long long` as an alias for `long` 287906a Handle complex type declarations correctly 8c3503b Add void type 74e3acc Add function declaration a817b23 Add nested type declarators 9d48eef Add short type 43c2f08 Add long type 5831eda Change size of int from 8 to 4 bef0543 Add struct assignment 11e3841 Add union f0a018a Add -> operator e1e831e Support struct tags dfec115 Align local variables 9443e4b Align struct members f814033 Add struct e6307ad Add comma operator 1c91d19 Emit .file and .loc assembler directives 6647ad9 Precompute line number for each token cd832a3 Rewrite tests in shell script in C ca8b243 Handle block scope 6c0a429 Add line and block comments a0388ba Add -o and --help options 7b8528f Refactor -- no functionality change d9ea597 Read code from a file instead of argv[1] 9dae234 [GNU] Add statement expression c2cc1d3 Add \x 699d2b7 Add \ ad7749f Add \a, \b, \t, \n \v, \f, \r and \e 35a0bcd Refactoring: Add a utility function 4cedda2 Add string literal be38d63 Add char type a4d3223 Add global variables 0b76634 Merge Function with Var 3e55caf Add sizeof 648646b Add [] operator 3ce1b2d Add arrays of arrays 8b6395d Add one dimensional arrays aacc0cf Support function definition up to 6 parameters 6cb4220 Support zero-arity function definition 964b1d2 Support function call with up to 6 arguments 30a3992 Support zero-arity function calls b4e82cf Add keyword "int" and make variable definition mandatory a6bc4ab Make pointer arithmetic work 863e2b8 Add unary & and * 3d86277 Add a representative node to each Node to improve error messages 5b142b1 Add LICENSE and README.md 1f3eb34 Add "while" statement f5d480f Add "for" statement 72b8415 Add "if" statement ff8912c Add null statement 18ac283 Add { ... } 6cc1c1f Add "return" statement 482c26b Support multi-letter local variables 1f9f3ad Support single-letter local variables 76cae0a Accept multiple statements separated by semicolons 725badf Split main.c into multiple small files 25b4b85 Add ==, !=, <= and >= operators bf9ab52 Add unary plus and minus 84cfcaf Add *, / and () cc5a6d9 Improve error message a1ab0ff Add a tokenizer to allow space characters between tokens bf7081f Add + and - operators 0522e2d Compile an integer to an exectuable that exits with the given number chibicc セルフホスト 196/316 4月 138/316 イマココ ???/316

Slide 315

Slide 315 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 セルフホストまでの道 • chibiccのリポジトリでは合計316コミットある • pccは4月時点で138コミットまで進んでた • 196コミットでchibiccとしてはセルフホストできる模様 • 今はAIの力を借りてここらへんまできました • chibiccのフォーク fuhsnn/slimcc ではPHPを コンパイルできるらしい (Rui Ueyamaさん情報) • https://github.com/fuhsnn/slimcc • chibiccの316コミットにさらに564コミット積んでるんすけど… 51 90d1f7f Make struct member access to work with `=` and `?:` 982041f Update README b35d148 Add __attribute__((aligned(N)) for struct declaration 44bea4c Add __attribute__((packed)) 395308c redefinition 2ed3fda Add test/thirdparty/cpython.sh 0a5d08c Complete stdatomic.h d69a11d Add _Atomic and atomic ++, -- and op= operators 80ea9d4 Add atomic_exchange ca27455 Add atomic_compare_exchange fb49370 Add scripts to test third-party apps 469f159 Add -Xlinker option d1bc9a4 Add -Wl, option c8df787 Add -L option 4e5de36 Add -shared option 1e9b6dd Add -static option f10bceb [GNU] Add #include_next a6c6622 [GNU] Add "#pragma once" d48d9e5 Add include guard optimization c0f0614 Cache file search results 86785fc Add -fpic and -fPIC options c3edffb Add -MMD option 7aa72e4 Add -MQ option fb5cfe5 Add -MD option db850f3 Add -MT option 57c1d4e Add -MP option 95d5a46 Add -MF option d0c4667 Add -M option f694413 Use hashmap for keyword lookup 655954e Use hashmap for block-scope lookup 30520e5 Use hashmap for macro name lookup 0aad326 Add string hashmap f0c98e0 [GNU] Treat labels-as-values as compile-time constant 4f165ec [GNU] Support labels-as-values 3d5550e [GNU] Support array range designator d90c73b [GNU] Support case ranges e0bf168 Add long double d56dd2f Recognize .a and .so files 8d130ab Emit size and type for symbols c32f0e2 Add -s option bc25279 Add -l option b0109a3 Do not define __STDC_NO_VLA__ 2fa8f48 Support sizeof(typename) where typename is a VLA 07f9010 Add pointer arithmetic for VLA e8667af Add sizeof() for VLA 77275c5 Add alloca() 4064871 Make -E to imply -xc ee0a951 Add -x option 8f5ff07 Add -include option b377284 Add thread-local variable 6d344ed Add -fcommon and -fno-common flags 85e46b1 Add tentative definition 1b99bad Add offsetof 11fc259 Add -idirafter option 6a2dc5a Use __attribute__((format(print, ...))) to find programming errors e5f4ca9 Do not emit static inline functions if referenced by no one 31087f8 Handle inline functions as static functions a253516 Add basic "asm" statement e28a612 [GNU] Add ?: operator with omitted operand aee7891 [GNU] Allow sizeof() 1faab48 Add _Generic 1433b40 [GNU] Add __builtin_types_compatible_p 7d80a51 Add typeof 007e526 [GNU] Support GCC-style variadic macro 74ec9f6 Ignore #pragma 083c275 [GNU] Handle ,##__VA_ARG__ 3381448 Add __VA_OPT__ 3a10c8a [GNU] Add __BASE_FILE__ macro 922604a [GNU] Add __TIMESTAMP__ macro aaf20fb [GNU] Add line marker directive c61c0d0 Add #line 37998be Improve error message for multibyte characters 95eb5b0 Handle struct designator for anonymous struct member 31dc1df Add union designated initializer 67f5834 Add struct designated initializer 691c4fa [GNU] Allow to omit "=" in designated initializers 835cd24 Allow array designators to initialize incomplete arrays c618c3b Add array designated initializer 2b2fa25 Skip UTF-8 BOM markers 2382777 Allow to concatenate regular string literals with L/u/U string literals adb8b98 [GNU] Accept $ as an identifier character 0e5d250 Allow multibyte UTF-8 character in identifier e4491b8 Define __STDC_UTF_{16,32}__ macros 6adba75 Add UTF-32 string literal initializer 36230e0 Add UTF-16 string literal initializer cae061a Add wide string literal c467ee6 Add UTF-32 string literal 9cabe1f Add UTF-16 string literal 57b21fe Add UTF-8 string literal 2dac3af Add UTF-32 character literal 454618c Add UTF-16 character literal a57c661 Accept multibyte character as wide character literal c31886a Add \u and \U escape sequences 74bcec5 Canonicalize newline character 0e77f3d [GNU] Add __COUNTER__ macro e27417f Add __DATE__ and __TIME__ macros c3075b3 Add anonymous struct and union 9c36dd7 Make "main" to implicitly return 0 5257ee0 Make an array of at least 16 bytes long to have alignment of at least 16 bytes 2c91da5 Turn on -Wall compiler flag and fix compiler warnings b1fdddf Ignore -O, -W and -g and other flags 2bdc6b8 Write to an in-memory buffer before writing to an actual output file c302a96 Do not allow to obtain an address of a bitfield 17ea802 Handle zero-width bitfield member 54c2b3b Handle op=-style assignments to bitfields 441a89b Support global struct bitfield initializer cc852fe Add bitfield be8b6f6 Add -U option fc69f5c Add -D option 3f2c2d5 Tokenize numeric tokens as pp-numbers e0b5da3 Dereferencing a function shouldn't do anything 603de50 Add va_copy() b6d3cd0 Allow variadic function to take more than 6 parameters d7bad96 Allow to define a function returning a struct c72df1c Allow to call a fucntion returning a struct d63b1f4 Allow struct argument 5e0f8c4 Allow struct parameter 9021f7f Support passed-on-stack parameters b29f052 Support passed-on-stack arguments 12a9e75 Self-host: including preprocessor, chibicc can compile itself 5322ea8 Add va_arg() 7cbfd11 Add stdarg.h, stdbool.h, stddef.h, stdalign.h and float.h 7746e4e Recognize wide character literal ab4f1e1 Concatenate adjacent string literals 82ba010 [GNU] Add __FUNCTION__ ba6b4b6 Add __func__ dc01f94 Add __VA_ARGS__ 6f17071 Add __FILE__ and __LINE__ 5f5a850 Add predefine macros such as __STDC__ e7fdc2e Add #error a939a7a Add default include paths a1dd621 Add -I option d85fc4f Add #include <...> b33fe0e Support line continuation 8075582 Preserve newline and space during macro expansion a8d76ad Replace remaining identifiers with 0 in macro constexpr 5cb2f89 Add defined() macro operator 769b5a0 Use chibicc's preprocessor for all tests 8f561ae Add macro token-pasting operator (##) 8f6f792 Add macro stringizing operator (#) 1313fc6 Do not expand a token more than once for the same funclike macro c7d7ce0 Allow parenthesized expressions as macro arguments dd4306c Allow empty macro arguments b9ad3e4 Add multi-arity funclike #define dec3b3f Add zero-arity funclike #define 1f80f58 Add #ifdef and #ifndef acce002 Do not expand a token more than once for the same objlike macro 2651448 Expand macros in the #if and #elif argument context 9ad60e4 Add #undef 97d33ad Add objlike #define e7a1857 Add #elif c6e81d2 Add #else aa570f3 Skip nested #if in a skipped #if-clause bf6ff92 Add #if and #endif d138864 Add -E option ec149f6 Skip extra tokens after `#include "..."` d367510 Add #include "..." 146c7b3 Add the null directive 1e1ea39 Add a do-nothing preprocessor 8b726b5 Run "ld" unless -c is given b833cd0 Accept multiple input files 140b433 Run "as" command unless -S is given f3d9613 Split cc1 from compiler driver 53e8103 Add usual arithmetic conversion for function pointer c5953ba Decay a function to a pointer in the func param context d06a8ac Add function pointer 5d15431 Add stage2 build 9bf9612 Add "long double" as an alias for "double" ffea421 Add flonum constant expression e452cf7 Support variadic function with floating-point parameters 8b14859 Implement default argument promotion for float c6b3056 Allow to define a function that takes/returns flonums 8ec1ebf Allow to call a function that takes/returns flonums 0ce1093 Handle flonum for if, while, do, !, ?:, || and && 83f76eb Add flonum +, -, * and / cf9ceec Add flonum ==, !=, < and <= 29de46a Add "float" and "double" local variables and casts 1e57f72 Add floating-point constant 1fad259 Allow to omit parameter name in function declaration 93d1277 Ignore "static" and "const" in array-dimensions b773554 Ignore const, volatile, auto, register, restrict or _Noreturn. 7ba6fe8 Handle unsigned types in the constant expression 6880a39 When comparing two pointers, treat them as unsigned 8b8f3de Use long or ulong instead of int for some expressions aaf1045 Add U, L and LL suffixes 34ab83b Add unsigned integral types 3f59ce7 Add `signed` keyword 197689a Check the number of function arguments 754a24f Add va_start to support variadic functions 58fc861 Allow to call a variadic function dcd4579 Handle a function returning bool, char or short 6a0ed71 Align stack frame to 16 byte boundaries ee252e6 Add do ... while eb85527 Add static global variables 30b3e21 Add return that doesn't take any value 127056d Add compound literals 319772b Add static local variables 310a87e [GNU] Allow a variable as an operand of _Alignof 9df5178 Add _Alignof and _Alignas 2764745 Handle extern declarations in a block 006a45c Add extern 157356c Align global variables 7a1f816 Accept `void` as a parameter list cd688a8 Allow to initialize struct flexible array member 824543b Add flexible array member 3d216e3 Emit uninitialized global data to .bss instead of .data fde464c Allow extraneous comma at the end of enum or initializer list a58958c Allow extraneous braces for scalar initializer efa0f33 Allow parentheses in initializers to be omitted 1eae5ae Handle union initializers for global variable eeb62b6 Add struct initializer for global variable bbfe3f4 Add global initializer for scalar and string 483b194 Handle union initializers for local variables aca19dd Allow to initialize a struct with other struct e9d2c46 Handle struct initializers for local variables 5b95533 Allow to omit array length if an initializer is given 0d71737 Add string literal initializer a754732 Skip excess initializer elements ae0a37d Initialize excess array elements with zero 22dd560 Support local variable initializers 79f5de2 Add constant expression 447ee09 Add ?: operator d0c0cb7 Add <<, >>, <<= and >>= 044d9ae Add switch-case 3c83dfd Add continue statement b3047f2 Add break statement a4be55b Resolve conflict between labels and typedefs 6116cae Add goto and labeled statement 61a1055 Add a notion of an incomplete struct type 7963221 Decay an array to a pointer in the func param context 29ed294 Add a notion of an incomplete array type f30f781 Add && and || 8644006 Add &, |, ^, &=, |= and ^= daa7398 Add % and %= 46a96d6 Add ~ operator 6b88bcb Add ! operator 7df934d Add hexadecimal, octal and binary number literals e8ca48c Add post ++ and -- 47f1937 Add pre ++ and -- 01a94c0 Add +=, -=, *= and /= a4fea2b Allow for-loops to define local variables 736232f Support file-scope functions 48ba265 Add enum aa0accc Add character literal 44bba96 Add _Bool type fdc80bc Handle function argument type conversion 818352a Handle return type conversion 9e211cb Report an error on undefined/undeclared functions 8b430a6 Implement usual arithmetic conversion cfc4fa9 Add type cast cb81a37 Use 32 bit registers for char, short and int 67543ea Make sizeof to accept not only an expression but also a typename a6b82da Add typedef f46370e Add `long long` as an alias for `long` 287906a Handle complex type declarations correctly 8c3503b Add void type 74e3acc Add function declaration a817b23 Add nested type declarators 9d48eef Add short type 43c2f08 Add long type 5831eda Change size of int from 8 to 4 bef0543 Add struct assignment 11e3841 Add union f0a018a Add -> operator e1e831e Support struct tags dfec115 Align local variables 9443e4b Align struct members f814033 Add struct e6307ad Add comma operator 1c91d19 Emit .file and .loc assembler directives 6647ad9 Precompute line number for each token cd832a3 Rewrite tests in shell script in C ca8b243 Handle block scope 6c0a429 Add line and block comments a0388ba Add -o and --help options 7b8528f Refactor -- no functionality change d9ea597 Read code from a file instead of argv[1] 9dae234 [GNU] Add statement expression c2cc1d3 Add \x 699d2b7 Add \ ad7749f Add \a, \b, \t, \n \v, \f, \r and \e 35a0bcd Refactoring: Add a utility function 4cedda2 Add string literal be38d63 Add char type a4d3223 Add global variables 0b76634 Merge Function with Var 3e55caf Add sizeof 648646b Add [] operator 3ce1b2d Add arrays of arrays 8b6395d Add one dimensional arrays aacc0cf Support function definition up to 6 parameters 6cb4220 Support zero-arity function definition 964b1d2 Support function call with up to 6 arguments 30a3992 Support zero-arity function calls b4e82cf Add keyword "int" and make variable definition mandatory a6bc4ab Make pointer arithmetic work 863e2b8 Add unary & and * 3d86277 Add a representative node to each Node to improve error messages 5b142b1 Add LICENSE and README.md 1f3eb34 Add "while" statement f5d480f Add "for" statement 72b8415 Add "if" statement ff8912c Add null statement 18ac283 Add { ... } 6cc1c1f Add "return" statement 482c26b Support multi-letter local variables 1f9f3ad Support single-letter local variables 76cae0a Accept multiple statements separated by semicolons 725badf Split main.c into multiple small files 25b4b85 Add ==, !=, <= and >= operators bf9ab52 Add unary plus and minus 84cfcaf Add *, / and () cc5a6d9 Improve error message a1ab0ff Add a tokenizer to allow space characters between tokens bf7081f Add + and - operators 0522e2d Compile an integer to an exectuable that exits with the given number chibicc セルフホスト 196/316 4月 138/316 イマココ ???/316

Slide 316

Slide 316 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 セルフホストまでの道 • chibiccのリポジトリでは合計316コミットある • pccは4月時点で138コミットまで進んでた • 196コミットでchibiccとしてはセルフホストできる模様 • 今はAIの力を借りてここらへんまできました • chibiccのフォーク fuhsnn/slimcc ではPHPを コンパイルできるらしい (Rui Ueyamaさん情報) • https://github.com/fuhsnn/slimcc • chibiccの316コミットにさらに564コミット積んでるんすけど… • どのコミットでPHPコンパイルできるかわからないけど… 51 90d1f7f Make struct member access to work with `=` and `?:` 982041f Update README b35d148 Add __attribute__((aligned(N)) for struct declaration 44bea4c Add __attribute__((packed)) 395308c redefinition 2ed3fda Add test/thirdparty/cpython.sh 0a5d08c Complete stdatomic.h d69a11d Add _Atomic and atomic ++, -- and op= operators 80ea9d4 Add atomic_exchange ca27455 Add atomic_compare_exchange fb49370 Add scripts to test third-party apps 469f159 Add -Xlinker option d1bc9a4 Add -Wl, option c8df787 Add -L option 4e5de36 Add -shared option 1e9b6dd Add -static option f10bceb [GNU] Add #include_next a6c6622 [GNU] Add "#pragma once" d48d9e5 Add include guard optimization c0f0614 Cache file search results 86785fc Add -fpic and -fPIC options c3edffb Add -MMD option 7aa72e4 Add -MQ option fb5cfe5 Add -MD option db850f3 Add -MT option 57c1d4e Add -MP option 95d5a46 Add -MF option d0c4667 Add -M option f694413 Use hashmap for keyword lookup 655954e Use hashmap for block-scope lookup 30520e5 Use hashmap for macro name lookup 0aad326 Add string hashmap f0c98e0 [GNU] Treat labels-as-values as compile-time constant 4f165ec [GNU] Support labels-as-values 3d5550e [GNU] Support array range designator d90c73b [GNU] Support case ranges e0bf168 Add long double d56dd2f Recognize .a and .so files 8d130ab Emit size and type for symbols c32f0e2 Add -s option bc25279 Add -l option b0109a3 Do not define __STDC_NO_VLA__ 2fa8f48 Support sizeof(typename) where typename is a VLA 07f9010 Add pointer arithmetic for VLA e8667af Add sizeof() for VLA 77275c5 Add alloca() 4064871 Make -E to imply -xc ee0a951 Add -x option 8f5ff07 Add -include option b377284 Add thread-local variable 6d344ed Add -fcommon and -fno-common flags 85e46b1 Add tentative definition 1b99bad Add offsetof 11fc259 Add -idirafter option 6a2dc5a Use __attribute__((format(print, ...))) to find programming errors e5f4ca9 Do not emit static inline functions if referenced by no one 31087f8 Handle inline functions as static functions a253516 Add basic "asm" statement e28a612 [GNU] Add ?: operator with omitted operand aee7891 [GNU] Allow sizeof() 1faab48 Add _Generic 1433b40 [GNU] Add __builtin_types_compatible_p 7d80a51 Add typeof 007e526 [GNU] Support GCC-style variadic macro 74ec9f6 Ignore #pragma 083c275 [GNU] Handle ,##__VA_ARG__ 3381448 Add __VA_OPT__ 3a10c8a [GNU] Add __BASE_FILE__ macro 922604a [GNU] Add __TIMESTAMP__ macro aaf20fb [GNU] Add line marker directive c61c0d0 Add #line 37998be Improve error message for multibyte characters 95eb5b0 Handle struct designator for anonymous struct member 31dc1df Add union designated initializer 67f5834 Add struct designated initializer 691c4fa [GNU] Allow to omit "=" in designated initializers 835cd24 Allow array designators to initialize incomplete arrays c618c3b Add array designated initializer 2b2fa25 Skip UTF-8 BOM markers 2382777 Allow to concatenate regular string literals with L/u/U string literals adb8b98 [GNU] Accept $ as an identifier character 0e5d250 Allow multibyte UTF-8 character in identifier e4491b8 Define __STDC_UTF_{16,32}__ macros 6adba75 Add UTF-32 string literal initializer 36230e0 Add UTF-16 string literal initializer cae061a Add wide string literal c467ee6 Add UTF-32 string literal 9cabe1f Add UTF-16 string literal 57b21fe Add UTF-8 string literal 2dac3af Add UTF-32 character literal 454618c Add UTF-16 character literal a57c661 Accept multibyte character as wide character literal c31886a Add \u and \U escape sequences 74bcec5 Canonicalize newline character 0e77f3d [GNU] Add __COUNTER__ macro e27417f Add __DATE__ and __TIME__ macros c3075b3 Add anonymous struct and union 9c36dd7 Make "main" to implicitly return 0 5257ee0 Make an array of at least 16 bytes long to have alignment of at least 16 bytes 2c91da5 Turn on -Wall compiler flag and fix compiler warnings b1fdddf Ignore -O, -W and -g and other flags 2bdc6b8 Write to an in-memory buffer before writing to an actual output file c302a96 Do not allow to obtain an address of a bitfield 17ea802 Handle zero-width bitfield member 54c2b3b Handle op=-style assignments to bitfields 441a89b Support global struct bitfield initializer cc852fe Add bitfield be8b6f6 Add -U option fc69f5c Add -D option 3f2c2d5 Tokenize numeric tokens as pp-numbers e0b5da3 Dereferencing a function shouldn't do anything 603de50 Add va_copy() b6d3cd0 Allow variadic function to take more than 6 parameters d7bad96 Allow to define a function returning a struct c72df1c Allow to call a fucntion returning a struct d63b1f4 Allow struct argument 5e0f8c4 Allow struct parameter 9021f7f Support passed-on-stack parameters b29f052 Support passed-on-stack arguments 12a9e75 Self-host: including preprocessor, chibicc can compile itself 5322ea8 Add va_arg() 7cbfd11 Add stdarg.h, stdbool.h, stddef.h, stdalign.h and float.h 7746e4e Recognize wide character literal ab4f1e1 Concatenate adjacent string literals 82ba010 [GNU] Add __FUNCTION__ ba6b4b6 Add __func__ dc01f94 Add __VA_ARGS__ 6f17071 Add __FILE__ and __LINE__ 5f5a850 Add predefine macros such as __STDC__ e7fdc2e Add #error a939a7a Add default include paths a1dd621 Add -I option d85fc4f Add #include <...> b33fe0e Support line continuation 8075582 Preserve newline and space during macro expansion a8d76ad Replace remaining identifiers with 0 in macro constexpr 5cb2f89 Add defined() macro operator 769b5a0 Use chibicc's preprocessor for all tests 8f561ae Add macro token-pasting operator (##) 8f6f792 Add macro stringizing operator (#) 1313fc6 Do not expand a token more than once for the same funclike macro c7d7ce0 Allow parenthesized expressions as macro arguments dd4306c Allow empty macro arguments b9ad3e4 Add multi-arity funclike #define dec3b3f Add zero-arity funclike #define 1f80f58 Add #ifdef and #ifndef acce002 Do not expand a token more than once for the same objlike macro 2651448 Expand macros in the #if and #elif argument context 9ad60e4 Add #undef 97d33ad Add objlike #define e7a1857 Add #elif c6e81d2 Add #else aa570f3 Skip nested #if in a skipped #if-clause bf6ff92 Add #if and #endif d138864 Add -E option ec149f6 Skip extra tokens after `#include "..."` d367510 Add #include "..." 146c7b3 Add the null directive 1e1ea39 Add a do-nothing preprocessor 8b726b5 Run "ld" unless -c is given b833cd0 Accept multiple input files 140b433 Run "as" command unless -S is given f3d9613 Split cc1 from compiler driver 53e8103 Add usual arithmetic conversion for function pointer c5953ba Decay a function to a pointer in the func param context d06a8ac Add function pointer 5d15431 Add stage2 build 9bf9612 Add "long double" as an alias for "double" ffea421 Add flonum constant expression e452cf7 Support variadic function with floating-point parameters 8b14859 Implement default argument promotion for float c6b3056 Allow to define a function that takes/returns flonums 8ec1ebf Allow to call a function that takes/returns flonums 0ce1093 Handle flonum for if, while, do, !, ?:, || and && 83f76eb Add flonum +, -, * and / cf9ceec Add flonum ==, !=, < and <= 29de46a Add "float" and "double" local variables and casts 1e57f72 Add floating-point constant 1fad259 Allow to omit parameter name in function declaration 93d1277 Ignore "static" and "const" in array-dimensions b773554 Ignore const, volatile, auto, register, restrict or _Noreturn. 7ba6fe8 Handle unsigned types in the constant expression 6880a39 When comparing two pointers, treat them as unsigned 8b8f3de Use long or ulong instead of int for some expressions aaf1045 Add U, L and LL suffixes 34ab83b Add unsigned integral types 3f59ce7 Add `signed` keyword 197689a Check the number of function arguments 754a24f Add va_start to support variadic functions 58fc861 Allow to call a variadic function dcd4579 Handle a function returning bool, char or short 6a0ed71 Align stack frame to 16 byte boundaries ee252e6 Add do ... while eb85527 Add static global variables 30b3e21 Add return that doesn't take any value 127056d Add compound literals 319772b Add static local variables 310a87e [GNU] Allow a variable as an operand of _Alignof 9df5178 Add _Alignof and _Alignas 2764745 Handle extern declarations in a block 006a45c Add extern 157356c Align global variables 7a1f816 Accept `void` as a parameter list cd688a8 Allow to initialize struct flexible array member 824543b Add flexible array member 3d216e3 Emit uninitialized global data to .bss instead of .data fde464c Allow extraneous comma at the end of enum or initializer list a58958c Allow extraneous braces for scalar initializer efa0f33 Allow parentheses in initializers to be omitted 1eae5ae Handle union initializers for global variable eeb62b6 Add struct initializer for global variable bbfe3f4 Add global initializer for scalar and string 483b194 Handle union initializers for local variables aca19dd Allow to initialize a struct with other struct e9d2c46 Handle struct initializers for local variables 5b95533 Allow to omit array length if an initializer is given 0d71737 Add string literal initializer a754732 Skip excess initializer elements ae0a37d Initialize excess array elements with zero 22dd560 Support local variable initializers 79f5de2 Add constant expression 447ee09 Add ?: operator d0c0cb7 Add <<, >>, <<= and >>= 044d9ae Add switch-case 3c83dfd Add continue statement b3047f2 Add break statement a4be55b Resolve conflict between labels and typedefs 6116cae Add goto and labeled statement 61a1055 Add a notion of an incomplete struct type 7963221 Decay an array to a pointer in the func param context 29ed294 Add a notion of an incomplete array type f30f781 Add && and || 8644006 Add &, |, ^, &=, |= and ^= daa7398 Add % and %= 46a96d6 Add ~ operator 6b88bcb Add ! operator 7df934d Add hexadecimal, octal and binary number literals e8ca48c Add post ++ and -- 47f1937 Add pre ++ and -- 01a94c0 Add +=, -=, *= and /= a4fea2b Allow for-loops to define local variables 736232f Support file-scope functions 48ba265 Add enum aa0accc Add character literal 44bba96 Add _Bool type fdc80bc Handle function argument type conversion 818352a Handle return type conversion 9e211cb Report an error on undefined/undeclared functions 8b430a6 Implement usual arithmetic conversion cfc4fa9 Add type cast cb81a37 Use 32 bit registers for char, short and int 67543ea Make sizeof to accept not only an expression but also a typename a6b82da Add typedef f46370e Add `long long` as an alias for `long` 287906a Handle complex type declarations correctly 8c3503b Add void type 74e3acc Add function declaration a817b23 Add nested type declarators 9d48eef Add short type 43c2f08 Add long type 5831eda Change size of int from 8 to 4 bef0543 Add struct assignment 11e3841 Add union f0a018a Add -> operator e1e831e Support struct tags dfec115 Align local variables 9443e4b Align struct members f814033 Add struct e6307ad Add comma operator 1c91d19 Emit .file and .loc assembler directives 6647ad9 Precompute line number for each token cd832a3 Rewrite tests in shell script in C ca8b243 Handle block scope 6c0a429 Add line and block comments a0388ba Add -o and --help options 7b8528f Refactor -- no functionality change d9ea597 Read code from a file instead of argv[1] 9dae234 [GNU] Add statement expression c2cc1d3 Add \x 699d2b7 Add \ ad7749f Add \a, \b, \t, \n \v, \f, \r and \e 35a0bcd Refactoring: Add a utility function 4cedda2 Add string literal be38d63 Add char type a4d3223 Add global variables 0b76634 Merge Function with Var 3e55caf Add sizeof 648646b Add [] operator 3ce1b2d Add arrays of arrays 8b6395d Add one dimensional arrays aacc0cf Support function definition up to 6 parameters 6cb4220 Support zero-arity function definition 964b1d2 Support function call with up to 6 arguments 30a3992 Support zero-arity function calls b4e82cf Add keyword "int" and make variable definition mandatory a6bc4ab Make pointer arithmetic work 863e2b8 Add unary & and * 3d86277 Add a representative node to each Node to improve error messages 5b142b1 Add LICENSE and README.md 1f3eb34 Add "while" statement f5d480f Add "for" statement 72b8415 Add "if" statement ff8912c Add null statement 18ac283 Add { ... } 6cc1c1f Add "return" statement 482c26b Support multi-letter local variables 1f9f3ad Support single-letter local variables 76cae0a Accept multiple statements separated by semicolons 725badf Split main.c into multiple small files 25b4b85 Add ==, !=, <= and >= operators bf9ab52 Add unary plus and minus 84cfcaf Add *, / and () cc5a6d9 Improve error message a1ab0ff Add a tokenizer to allow space characters between tokens bf7081f Add + and - operators 0522e2d Compile an integer to an exectuable that exits with the given number chibicc セルフホスト 196/316 4月 138/316 イマココ ???/316

Slide 317

Slide 317 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 セルフホストまでの道 • chibiccのリポジトリでは合計316コミットある • pccは4月時点で138コミットまで進んでた • 196コミットでchibiccとしてはセルフホストできる模様 • 今はAIの力を借りてここらへんまできました • chibiccのフォーク fuhsnn/slimcc ではPHPを コンパイルできるらしい (Rui Ueyamaさん情報) • https://github.com/fuhsnn/slimcc • chibiccの316コミットにさらに564コミット積んでるんすけど… • どのコミットでPHPコンパイルできるかわからないけど… • やるんすか…?自分…ライフワーク級だな… 51 90d1f7f Make struct member access to work with `=` and `?:` 982041f Update README b35d148 Add __attribute__((aligned(N)) for struct declaration 44bea4c Add __attribute__((packed)) 395308c redefinition 2ed3fda Add test/thirdparty/cpython.sh 0a5d08c Complete stdatomic.h d69a11d Add _Atomic and atomic ++, -- and op= operators 80ea9d4 Add atomic_exchange ca27455 Add atomic_compare_exchange fb49370 Add scripts to test third-party apps 469f159 Add -Xlinker option d1bc9a4 Add -Wl, option c8df787 Add -L option 4e5de36 Add -shared option 1e9b6dd Add -static option f10bceb [GNU] Add #include_next a6c6622 [GNU] Add "#pragma once" d48d9e5 Add include guard optimization c0f0614 Cache file search results 86785fc Add -fpic and -fPIC options c3edffb Add -MMD option 7aa72e4 Add -MQ option fb5cfe5 Add -MD option db850f3 Add -MT option 57c1d4e Add -MP option 95d5a46 Add -MF option d0c4667 Add -M option f694413 Use hashmap for keyword lookup 655954e Use hashmap for block-scope lookup 30520e5 Use hashmap for macro name lookup 0aad326 Add string hashmap f0c98e0 [GNU] Treat labels-as-values as compile-time constant 4f165ec [GNU] Support labels-as-values 3d5550e [GNU] Support array range designator d90c73b [GNU] Support case ranges e0bf168 Add long double d56dd2f Recognize .a and .so files 8d130ab Emit size and type for symbols c32f0e2 Add -s option bc25279 Add -l option b0109a3 Do not define __STDC_NO_VLA__ 2fa8f48 Support sizeof(typename) where typename is a VLA 07f9010 Add pointer arithmetic for VLA e8667af Add sizeof() for VLA 77275c5 Add alloca() 4064871 Make -E to imply -xc ee0a951 Add -x option 8f5ff07 Add -include option b377284 Add thread-local variable 6d344ed Add -fcommon and -fno-common flags 85e46b1 Add tentative definition 1b99bad Add offsetof 11fc259 Add -idirafter option 6a2dc5a Use __attribute__((format(print, ...))) to find programming errors e5f4ca9 Do not emit static inline functions if referenced by no one 31087f8 Handle inline functions as static functions a253516 Add basic "asm" statement e28a612 [GNU] Add ?: operator with omitted operand aee7891 [GNU] Allow sizeof() 1faab48 Add _Generic 1433b40 [GNU] Add __builtin_types_compatible_p 7d80a51 Add typeof 007e526 [GNU] Support GCC-style variadic macro 74ec9f6 Ignore #pragma 083c275 [GNU] Handle ,##__VA_ARG__ 3381448 Add __VA_OPT__ 3a10c8a [GNU] Add __BASE_FILE__ macro 922604a [GNU] Add __TIMESTAMP__ macro aaf20fb [GNU] Add line marker directive c61c0d0 Add #line 37998be Improve error message for multibyte characters 95eb5b0 Handle struct designator for anonymous struct member 31dc1df Add union designated initializer 67f5834 Add struct designated initializer 691c4fa [GNU] Allow to omit "=" in designated initializers 835cd24 Allow array designators to initialize incomplete arrays c618c3b Add array designated initializer 2b2fa25 Skip UTF-8 BOM markers 2382777 Allow to concatenate regular string literals with L/u/U string literals adb8b98 [GNU] Accept $ as an identifier character 0e5d250 Allow multibyte UTF-8 character in identifier e4491b8 Define __STDC_UTF_{16,32}__ macros 6adba75 Add UTF-32 string literal initializer 36230e0 Add UTF-16 string literal initializer cae061a Add wide string literal c467ee6 Add UTF-32 string literal 9cabe1f Add UTF-16 string literal 57b21fe Add UTF-8 string literal 2dac3af Add UTF-32 character literal 454618c Add UTF-16 character literal a57c661 Accept multibyte character as wide character literal c31886a Add \u and \U escape sequences 74bcec5 Canonicalize newline character 0e77f3d [GNU] Add __COUNTER__ macro e27417f Add __DATE__ and __TIME__ macros c3075b3 Add anonymous struct and union 9c36dd7 Make "main" to implicitly return 0 5257ee0 Make an array of at least 16 bytes long to have alignment of at least 16 bytes 2c91da5 Turn on -Wall compiler flag and fix compiler warnings b1fdddf Ignore -O, -W and -g and other flags 2bdc6b8 Write to an in-memory buffer before writing to an actual output file c302a96 Do not allow to obtain an address of a bitfield 17ea802 Handle zero-width bitfield member 54c2b3b Handle op=-style assignments to bitfields 441a89b Support global struct bitfield initializer cc852fe Add bitfield be8b6f6 Add -U option fc69f5c Add -D option 3f2c2d5 Tokenize numeric tokens as pp-numbers e0b5da3 Dereferencing a function shouldn't do anything 603de50 Add va_copy() b6d3cd0 Allow variadic function to take more than 6 parameters d7bad96 Allow to define a function returning a struct c72df1c Allow to call a fucntion returning a struct d63b1f4 Allow struct argument 5e0f8c4 Allow struct parameter 9021f7f Support passed-on-stack parameters b29f052 Support passed-on-stack arguments 12a9e75 Self-host: including preprocessor, chibicc can compile itself 5322ea8 Add va_arg() 7cbfd11 Add stdarg.h, stdbool.h, stddef.h, stdalign.h and float.h 7746e4e Recognize wide character literal ab4f1e1 Concatenate adjacent string literals 82ba010 [GNU] Add __FUNCTION__ ba6b4b6 Add __func__ dc01f94 Add __VA_ARGS__ 6f17071 Add __FILE__ and __LINE__ 5f5a850 Add predefine macros such as __STDC__ e7fdc2e Add #error a939a7a Add default include paths a1dd621 Add -I option d85fc4f Add #include <...> b33fe0e Support line continuation 8075582 Preserve newline and space during macro expansion a8d76ad Replace remaining identifiers with 0 in macro constexpr 5cb2f89 Add defined() macro operator 769b5a0 Use chibicc's preprocessor for all tests 8f561ae Add macro token-pasting operator (##) 8f6f792 Add macro stringizing operator (#) 1313fc6 Do not expand a token more than once for the same funclike macro c7d7ce0 Allow parenthesized expressions as macro arguments dd4306c Allow empty macro arguments b9ad3e4 Add multi-arity funclike #define dec3b3f Add zero-arity funclike #define 1f80f58 Add #ifdef and #ifndef acce002 Do not expand a token more than once for the same objlike macro 2651448 Expand macros in the #if and #elif argument context 9ad60e4 Add #undef 97d33ad Add objlike #define e7a1857 Add #elif c6e81d2 Add #else aa570f3 Skip nested #if in a skipped #if-clause bf6ff92 Add #if and #endif d138864 Add -E option ec149f6 Skip extra tokens after `#include "..."` d367510 Add #include "..." 146c7b3 Add the null directive 1e1ea39 Add a do-nothing preprocessor 8b726b5 Run "ld" unless -c is given b833cd0 Accept multiple input files 140b433 Run "as" command unless -S is given f3d9613 Split cc1 from compiler driver 53e8103 Add usual arithmetic conversion for function pointer c5953ba Decay a function to a pointer in the func param context d06a8ac Add function pointer 5d15431 Add stage2 build 9bf9612 Add "long double" as an alias for "double" ffea421 Add flonum constant expression e452cf7 Support variadic function with floating-point parameters 8b14859 Implement default argument promotion for float c6b3056 Allow to define a function that takes/returns flonums 8ec1ebf Allow to call a function that takes/returns flonums 0ce1093 Handle flonum for if, while, do, !, ?:, || and && 83f76eb Add flonum +, -, * and / cf9ceec Add flonum ==, !=, < and <= 29de46a Add "float" and "double" local variables and casts 1e57f72 Add floating-point constant 1fad259 Allow to omit parameter name in function declaration 93d1277 Ignore "static" and "const" in array-dimensions b773554 Ignore const, volatile, auto, register, restrict or _Noreturn. 7ba6fe8 Handle unsigned types in the constant expression 6880a39 When comparing two pointers, treat them as unsigned 8b8f3de Use long or ulong instead of int for some expressions aaf1045 Add U, L and LL suffixes 34ab83b Add unsigned integral types 3f59ce7 Add `signed` keyword 197689a Check the number of function arguments 754a24f Add va_start to support variadic functions 58fc861 Allow to call a variadic function dcd4579 Handle a function returning bool, char or short 6a0ed71 Align stack frame to 16 byte boundaries ee252e6 Add do ... while eb85527 Add static global variables 30b3e21 Add return that doesn't take any value 127056d Add compound literals 319772b Add static local variables 310a87e [GNU] Allow a variable as an operand of _Alignof 9df5178 Add _Alignof and _Alignas 2764745 Handle extern declarations in a block 006a45c Add extern 157356c Align global variables 7a1f816 Accept `void` as a parameter list cd688a8 Allow to initialize struct flexible array member 824543b Add flexible array member 3d216e3 Emit uninitialized global data to .bss instead of .data fde464c Allow extraneous comma at the end of enum or initializer list a58958c Allow extraneous braces for scalar initializer efa0f33 Allow parentheses in initializers to be omitted 1eae5ae Handle union initializers for global variable eeb62b6 Add struct initializer for global variable bbfe3f4 Add global initializer for scalar and string 483b194 Handle union initializers for local variables aca19dd Allow to initialize a struct with other struct e9d2c46 Handle struct initializers for local variables 5b95533 Allow to omit array length if an initializer is given 0d71737 Add string literal initializer a754732 Skip excess initializer elements ae0a37d Initialize excess array elements with zero 22dd560 Support local variable initializers 79f5de2 Add constant expression 447ee09 Add ?: operator d0c0cb7 Add <<, >>, <<= and >>= 044d9ae Add switch-case 3c83dfd Add continue statement b3047f2 Add break statement a4be55b Resolve conflict between labels and typedefs 6116cae Add goto and labeled statement 61a1055 Add a notion of an incomplete struct type 7963221 Decay an array to a pointer in the func param context 29ed294 Add a notion of an incomplete array type f30f781 Add && and || 8644006 Add &, |, ^, &=, |= and ^= daa7398 Add % and %= 46a96d6 Add ~ operator 6b88bcb Add ! operator 7df934d Add hexadecimal, octal and binary number literals e8ca48c Add post ++ and -- 47f1937 Add pre ++ and -- 01a94c0 Add +=, -=, *= and /= a4fea2b Allow for-loops to define local variables 736232f Support file-scope functions 48ba265 Add enum aa0accc Add character literal 44bba96 Add _Bool type fdc80bc Handle function argument type conversion 818352a Handle return type conversion 9e211cb Report an error on undefined/undeclared functions 8b430a6 Implement usual arithmetic conversion cfc4fa9 Add type cast cb81a37 Use 32 bit registers for char, short and int 67543ea Make sizeof to accept not only an expression but also a typename a6b82da Add typedef f46370e Add `long long` as an alias for `long` 287906a Handle complex type declarations correctly 8c3503b Add void type 74e3acc Add function declaration a817b23 Add nested type declarators 9d48eef Add short type 43c2f08 Add long type 5831eda Change size of int from 8 to 4 bef0543 Add struct assignment 11e3841 Add union f0a018a Add -> operator e1e831e Support struct tags dfec115 Align local variables 9443e4b Align struct members f814033 Add struct e6307ad Add comma operator 1c91d19 Emit .file and .loc assembler directives 6647ad9 Precompute line number for each token cd832a3 Rewrite tests in shell script in C ca8b243 Handle block scope 6c0a429 Add line and block comments a0388ba Add -o and --help options 7b8528f Refactor -- no functionality change d9ea597 Read code from a file instead of argv[1] 9dae234 [GNU] Add statement expression c2cc1d3 Add \x 699d2b7 Add \ ad7749f Add \a, \b, \t, \n \v, \f, \r and \e 35a0bcd Refactoring: Add a utility function 4cedda2 Add string literal be38d63 Add char type a4d3223 Add global variables 0b76634 Merge Function with Var 3e55caf Add sizeof 648646b Add [] operator 3ce1b2d Add arrays of arrays 8b6395d Add one dimensional arrays aacc0cf Support function definition up to 6 parameters 6cb4220 Support zero-arity function definition 964b1d2 Support function call with up to 6 arguments 30a3992 Support zero-arity function calls b4e82cf Add keyword "int" and make variable definition mandatory a6bc4ab Make pointer arithmetic work 863e2b8 Add unary & and * 3d86277 Add a representative node to each Node to improve error messages 5b142b1 Add LICENSE and README.md 1f3eb34 Add "while" statement f5d480f Add "for" statement 72b8415 Add "if" statement ff8912c Add null statement 18ac283 Add { ... } 6cc1c1f Add "return" statement 482c26b Support multi-letter local variables 1f9f3ad Support single-letter local variables 76cae0a Accept multiple statements separated by semicolons 725badf Split main.c into multiple small files 25b4b85 Add ==, !=, <= and >= operators bf9ab52 Add unary plus and minus 84cfcaf Add *, / and () cc5a6d9 Improve error message a1ab0ff Add a tokenizer to allow space characters between tokens bf7081f Add + and - operators 0522e2d Compile an integer to an exectuable that exits with the given number chibicc セルフホスト 196/316 4月 138/316 イマココ ???/316

Slide 318

Slide 318 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 まとめ 52

Slide 319

Slide 319 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 まとめ 53 長谷川 智希 @tomzoh

Slide 320

Slide 320 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 まとめ • Cコンパイラを書くとプログラム言語がどのように解釈されて、 CPUでどのように実行されるかが理解できる 53 長谷川 智希 @tomzoh

Slide 321

Slide 321 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 まとめ • Cコンパイラを書くとプログラム言語がどのように解釈されて、 CPUでどのように実行されるかが理解できる • Cコンパイラは難しくない 53 長谷川 智希 @tomzoh

Slide 322

Slide 322 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 まとめ • Cコンパイラを書くとプログラム言語がどのように解釈されて、 CPUでどのように実行されるかが理解できる • Cコンパイラは難しくない • ゼロから書くのは難しいかもだけど、 低レイヤを知りたい人のためのCコンパイラ作成入門を読んだり、 chibiccのコミットを追ったりすればだいぶハードルは下がる 53 長谷川 智希 @tomzoh

Slide 323

Slide 323 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 まとめ • Cコンパイラを書くとプログラム言語がどのように解釈されて、 CPUでどのように実行されるかが理解できる • Cコンパイラは難しくない • ゼロから書くのは難しいかもだけど、 低レイヤを知りたい人のためのCコンパイラ作成入門を読んだり、 chibiccのコミットを追ったりすればだいぶハードルは下がる • コンパイラがわかればインタープリタも共通部分多いのでわかる 53 長谷川 智希 @tomzoh

Slide 324

Slide 324 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 まとめ • Cコンパイラを書くとプログラム言語がどのように解釈されて、 CPUでどのように実行されるかが理解できる • Cコンパイラは難しくない • ゼロから書くのは難しいかもだけど、 低レイヤを知りたい人のためのCコンパイラ作成入門を読んだり、 chibiccのコミットを追ったりすればだいぶハードルは下がる • コンパイラがわかればインタープリタも共通部分多いのでわかる • CPUで機械語がどう実行されるかも気になりません? 53 長谷川 智希 @tomzoh

Slide 325

Slide 325 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 まとめ • Cコンパイラを書くとプログラム言語がどのように解釈されて、 CPUでどのように実行されるかが理解できる • Cコンパイラは難しくない • ゼロから書くのは難しいかもだけど、 低レイヤを知りたい人のためのCコンパイラ作成入門を読んだり、 chibiccのコミットを追ったりすればだいぶハードルは下がる • コンパイラがわかればインタープリタも共通部分多いのでわかる • CPUで機械語がどう実行されるかも気になりません? • エミュレータは真逆で実行環境だけがあるのでまた別の味がありますよ 53 長谷川 智希 @tomzoh

Slide 326

Slide 326 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 まとめ • Cコンパイラを書くとプログラム言語がどのように解釈されて、 CPUでどのように実行されるかが理解できる • Cコンパイラは難しくない • ゼロから書くのは難しいかもだけど、 低レイヤを知りたい人のためのCコンパイラ作成入門を読んだり、 chibiccのコミットを追ったりすればだいぶハードルは下がる • コンパイラがわかればインタープリタも共通部分多いのでわかる • CPUで機械語がどう実行されるかも気になりません? • エミュレータは真逆で実行環境だけがあるのでまた別の味がありますよ • 今日のトークをきっかけにみなさんが低レイヤを楽しめるように なったら嬉しく思います! 53 長谷川 智希 @tomzoh

Slide 327

Slide 327 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 54

Slide 328

Slide 328 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 54

Slide 329

Slide 329 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コンパイラ 54

Slide 330

Slide 330 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コンパイラ みんなもつくって 54

Slide 331

Slide 331 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 コンパイラ みんなもつくって たのしもう 54

Slide 332

Slide 332 text

長谷川智希 @tomzoh 低レイヤを知りたいPHPerのためのCコンパイラ作成入門 完全版 まとめ • Cコンパイラを書くとプログラム言語がどのように解釈されて、 CPUでどのように実行されるかが理解できる • Cコンパイラは難しくない • ゼロから書くのは難しいかもだけど、低レイヤを知りたい人のためのC コンパイラ作成入門を読んだり、chibiccのコミットを追えばだいぶハー ドルは下がる • コンパイラがわかればインタープリタも共通部分多いのでわかる • CPUで機械語がどう実行されるかも気になりません? • エミュレータは真逆で実行環境だけがあるのでまた別の味がありますよ • 今日のトークをきっかけにみなさんが低レイヤを楽しめるように なったら嬉しく思います! 55 長谷川 智希 @tomzoh