Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
コンパイラ作りの魅力を語る / Making compilers is fun
Search
DQNEO
March 30, 2019
Programming
8.8k
10
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
コンパイラ作りの魅力を語る / Making compilers is fun
PHPerKaigi 2019で、C/Goコンパイラを作る過程で学んだことについて話しました。
DQNEO
March 30, 2019
More Decks by DQNEO
See All by DQNEO
英和辞書付きGo言語仕様書 / Word Wise Go Spec
dqneo
1
640
Go言語低レイヤー入門 Hello world が 画面に表示されるまで / Introduction to low level programming in Go
dqneo
8
2k
入門Go言語仕様 / Go Specification Untyped Constants
dqneo
1
1.4k
入門Go言語仕様 Underlying Type / Go Language Underlying Type
dqneo
9
5.5k
How to write a self hosted Go compiler from scratch (Gophercon 2020)
dqneo
3
1.8k
もっと気軽にOSSに Pull Requestを出そう!/ Let's make a PR to OSS more easily
dqneo
6
8.6k
Goコンパイラをゼロから作ってセルフホスト達成するまで / How I wrote a self hosted Go compiler from scratch
dqneo
15
15k
コンパイラをつくってみよう / How to make a compiler
dqneo
9
13k
Goのmapとheapを自作してみた / How to create your own map and heap in Go
dqneo
0
3.3k
Other Decks in Programming
See All in Programming
Next.js: The final boss of Web Performance
guaca
0
400
そのデザイントークン、Flutterでも同じ見た目になりますか?
nakamizu
0
330
仕様駆動開発入門 (何を作るかを先に決めて渡す) | 目指せ Kiro マスター 05
inariku
PRO
2
120
Web3Dライブラリを作ってVue Custom Rendererの仕組みを理解しよう / lets learn vue custom renderer by making 3d library
drumath2237
1
130
AIで開発が速くなった先で、開発チームは何を目指すか
shihochan
1
2k
あなたの await、OS まで届いてる? strace で覗く JavaScript の非同期
hasutosasaki
1
2.3k
Coding with AI: How to trust the storyteller (AWS Community Day Adria, Ljubljana 2026)
slobodan
0
140
AI時代のFlutter品質設計 — アプリ品質を守るQuality Layers
omatty198
0
370
私なりのハーネスエンジニアリング ~独自の言語処理系の開発を通して~
seosoft
0
200
Getting Started with Vibe Coding
miccheng
0
200
Enforcing Your Architecture with Unit Tests in the AI Era (Swift Connection X)
steliosf
PRO
1
160
當我們開始不讀 Code - AI Agent 時代,Code Review 與 Clean Code 還剩下什麼?
jame2408
1
370
Featured
See All Featured
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.6k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.9k
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
Believing is Seeing
oripsolob
1
270
Leo the Paperboy
mayatellez
11
2.5k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
4
1.2k
Accessibility Awareness
sabderemane
1
290
Crafting Experiences
bethany
1
430
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
330
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
600
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.2k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.7k
Transcript
コンパイラ作りの 魅力を語る @DQNEO phperkaigi 2019.3.30
自己紹介 @DQNEO どきゅねお アメリカ版メルカリを開発しています • PHPer • C初心者 • Go中級者
目次 • デモ • コンパイラとは何か?何をしているのか? • なんで作ろうと思ったのか? • どうやって作ったのか?
趣味: コンパイラ作り Cコンパイラ https://github.com/DQNEO/8cc.go 8ccをGoに移植したもの Goコンパイラ https://github.com/DQNEO/minigo Goで書いたGoコンパイラ
デモ: Cコンパイラ Fizz Buzz
デモ: Goコンパイラ Fizz Buzz
PHPerとCコンパイラ <?php php-src (C) C compiler Assembly Binary /usr/bin/php スクリプト
処理系
コンパイラとは何か
コンパイラとは何か 広義: 言語Xのコードを言語Yに変換するソフトウェア 狭義: 言語Xのコードを低レベル言語(アセンブリ/機械語 /etc)に変換するプログラム
コンパイラは 何をしているのか
Cコンパイラ (8cc) int sum(int a, int b) { return a
+ b; } sum: push %rbp mov %rsp, %rbp push %rdi push %rsi mov -8(%rbp), %rax mov -16(%rbp), %rcx add %rcx, %rax leave ret C言語 GNU assembler
コンパイラを作ってわかったこと アセンブリの知識が必要
コンパイラを作ってわかったこと • (多くの)コンパイラはアセンブリを吐く • アセンブリを理解し読み書きするスキル必要 = CPUのはたらきを理解すること
sum: push %rbp mov %rsp, %rbp push %rdi push %rsi
mov -8(%rbp), %rax mov -16(%rbp), %rcx add %rcx, %rax leave ret アセンブリ言語 ≒ マシン語 • 各行がCPUへの「命令」 • どの行も、ハードウェア に対して副作用を生じる (レジスタ(後述)またはメ モリ上のデータを変更す る)
sum: push %rbp mov %rsp, %rbp push %rdi push %rsi
mov -8(%rbp), %rax mov -16(%rbp), %rcx add %rcx, %rax leave ret GNU Assembler CPUへの命令
sum: push %rbp mov %rsp, %rbp push %rdi push %rsi
mov -8(%rbp), %rax mov -16(%rbp), %rcx add %rcx, %rax leave ret GNU assembler メモリ 読み書き
sum: push %rbp mov %rsp, %rbp push %rdi push %rsi
mov -8(%rbp), %rax mov -16(%rbp), %rcx add %rcx, %rax leave ret GNU assembler レジスタ 読み書き
コンパイラを作ってわかったこと “レジスタ”が主役 ※私の主観です
CPU内にある超高速な一時記憶装置 CPU ← レジスタ “レジスタ”が主役 出典: http://ftp.procmail.org/~sskulrat/Courses/2006F-170/lectures/chap14/part1.html
Cコンパイラ (8cc) int sum(int a, int b) { return a
+ b; } sum: push %rbp mov %rsp, %rbp push %rdi push %rsi mov -8(%rbp), %rax mov -16(%rbp), %rcx add %rcx, %rax leave ret C GNU Assembler 関数 → 関数 変数 → メモリ何番目
コンパイラを作ってわかったこと • C言語上の関数はアセンブリ上でも関数 • アセンブリには変数がない。 ◦ ハードウェア(メモリ/レジスタ)に「書く、読む」 • 「書き込む」「読み取る」という動作が基本
値とは何か
高級言語視点 値: 式を評価すると得られる もの 1;
mov $1, %rax 低級言語視点
値とは何か 1; mov $1, %rax C GNU assembler
値とは何か 式を評価して値を得る ↓ ある手続きを実行した際に、ハード ウェアのある場所に値を書き込む
値とは副作用である ※私個人の考えです
値とは何か 8ccの場合、一連の処理の最後に必 ずraxに値を書き込む約束になってい る。 raxが保持しているデータ、 これが「値」の実体
式を評価して値を得る x + y; mov -8(%rbp), %rax mov -16(%rbp), %rcx
add %rcx, %rax 演算の結果をraxに書き込む
隠れた副作用 実はrcxに副作用が残ったまま。 コンパイラ側で、このrcx値は再利用しないよう に気をつける。 これにより、副作用が1個(式の結果が1値)のよ うに見せかけている。 x + y; mov
-8(%rbp), %rax mov -16(%rbp), %rcx add %rcx, %rax
関数の戻り値 int sum(int x, int y) { return x +
y; } sum: push %rbp mov %rsp, %rbp push %rdi push %rsi mov -8(%rbp), %rax mov -16(%rbp), %rcx add %rcx, %rax leave ret raxに値を書き込ん で関数を抜ける。 これが戻り値。 受け取る側は、rax から値を読み出す。 int sum(int x, int y) { return x + y; }
関数の戻り値 int sum(int x, int y) { return x +
y; } sum: push %rbp mov %rsp, %rbp push %rdi push %rsi mov -8(%rbp), %rax mov -16(%rbp), %rcx add %rcx, %rax leave ret int sum(int x, int y) { return x + y; } 「純粋な関数」 も、ハードウェア レベルでは副作 用がある
コンパイラを作ってわかったこと • if文とfor文は仕組みがほぼ同じ ◦ 条件判定とジャンプ • ローカル変数とグローバル変数は扱いが全然 違う • 「スタック」とローカル変数の関係
コンパイラ作りで得たもの1 • アセンブラの読み書き能力 • 字句解析・構文解析の知識 • 対象言語(C,Go)の仕様に詳しくなった
コンパイラ作りで得たもの2 • 原典にあたる習慣 ◦ 言語仕様書 ◦ Intel CPUマニュアル ◦ gdb,
gasマニュアル
Intel® 64 and IA-32 Architectures Software Developer’s Manual
コンパイラ作りで得たもの3 • Segmentation Fault に負けない心 ◦ gdb/gccなどのコンパイラツール系スキル
None
簡単なC/Goのコードな ら 脳内コンパイルできる
何でコンパイラを作ろうと思っ たのか?
もともとは普通の PHPアプリケーション 開発者だった
コンパイラ知識ゼロからのスタート • 字句解析・構文解析の解説を読んでも理解不能 • C,Goもそんなに詳しくない 「プログラムが動く原理を知りたい」
Rebuild.fm153回 https://rebuild.fm/153/ Rui Ueyama さんが Cコンパイラ(8cc)を作った話 きっかけ めちゃくちゃ面白い!!
• C言語製Cコンパイラ • スクラッチから開発 • インクリメンタル開発 8cc https://github.com/rui314/8cc
さっそく git clone
8cc 1コミット目 #include <stdio.h> #include <stdlib.h> int main(int argc, char
**argv) { int val; if (scanf("%d", &val) == EOF) { perror("scanf"); exit(1); } printf("\t.text\n\t" ".global mymain\n" "mymain:\n\t" "mov $%d, %%eax\n\t" "ret\n", val); return 0; } #include <stdio.h> extern int mymain(void); int main(int argc, char **argv) { int val = mymain(); printf("%d\n", val); return 0; } https://github.com/rui314/8cc/commit/3764b2071b9601067b81976d80175a0851d0f209
なんとなくわかる! しかし、ただ読んでるだけでは身につ かなそう Goに移植してみよう!
1コミット移植してみた https://github.com/DQNEO/8cc.go/commit/b711967431 07e50e0ac945383abc5b2c3bf2e302 動いた! 8cc.go (Goへの移植)
8ccのコミット履歴を1個ずつ • テストの追加分を見る • そのテストをパスするC実装を自力でやってみる • 無理なら正解をチラ見する • 自力でCで再現する •
無理なら写経 • Goに移植する 延々と繰り返す 8cc.go (Goへの移植)
• 5ヶ月半毎日継続 • 95コミット移植完了 • 基本的な文法はだいたい動く 8cc.go (Goへの移植)
移植で見えてきた問題点 • 8ccの字句読み取りの設計が複雑 • 9ccはきれいに設計できてる • 自分でもゼロから設計してみたい!
Goコンパイラ開発 • 試しにGoでGoのtokenizerを書いてみた • あっさり動いた!感動! → その勢いでGoコンパイラ開発に突入
minigo (Goコンパイラ) • 1日目:足し算が動いた! • 2日目:引き算・掛け算・関数呼び出しが動いた! • 5日目: helloworld.go が動いた!
minigo (Goコンパイラ) • 1ヶ月後:FizzBuzzが動いた!
• 5ヶ月後:自分自身のコンパイルに成功! (時間があればデモ) minigo (Goコンパイラ)
野望 • 夏〜秋ごろにセルフホスト達成予定 • 来年のアメリカのGopherConに応募するぞ
コンパイラはいいぞ
ご清聴 ありがとうございました