Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
bootstrap
Search
Koichi Nakamura
June 06, 2015
Programming
47
15k
bootstrap
第11回 カーネル/VM 探検隊
Koichi Nakamura
June 06, 2015
Tweet
Share
More Decks by Koichi Nakamura
See All by Koichi Nakamura
エッジDLデバイスの選定において考慮すること ML@Loft
nineties
2
1.5k
Deep Learning推論を高速化するソフトウェア技術
nineties
9
8.3k
What is Actcast? / actcast-en
nineties
2
710
Actcast紹介資料 / actcast-ja
nineties
4
2.2k
Ideinの紹介 @ DLLab 推論ナイト
nineties
11
3.9k
Convolutionの数理とアルゴリズム
nineties
10
18k
Convolutionのアルゴリズム
nineties
1
1.8k
Creating a language using only assembly language
nineties
54
48k
Other Decks in Programming
See All in Programming
Pulsar2 を雰囲気で使ってみよう
anoken
0
240
Rails アプリ地図考 Flush Cut
makicamel
1
120
Amazon S3 TablesとAmazon S3 Metadataを触ってみた / 20250201-jawsug-tochigi-s3tables-s3metadata
kasacchiful
0
160
プログラミング言語学習のススメ / why-do-i-learn-programming-language
yashi8484
0
130
メンテが命: PHPフレームワークのコンテナ化とアップグレード戦略
shunta27
0
110
時計仕掛けのCompose
mkeeda
1
290
CNCF Project の作者が考えている OSS の運営
utam0k
6
710
仕様変更に耐えるための"今の"DRY原則を考える / Rethinking the "Don't repeat yourself" for resilience to specification changes
mkmk884
0
110
チームリードになって変わったこと
isaka1022
0
200
GoとPHPのインターフェイスの違い
shimabox
2
180
ASP. NET CoreにおけるWebAPIの最新情報
tomokusaba
0
370
Java Webフレームワークの現状 / java web framework at burikaigi
kishida
9
2.2k
Featured
See All Featured
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
7k
Why You Should Never Use an ORM
jnunemaker
PRO
55
9.2k
Optimising Largest Contentful Paint
csswizardry
34
3.1k
Rebuilding a faster, lazier Slack
samanthasiow
80
8.8k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.1k
Thoughts on Productivity
jonyablonski
69
4.5k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
33
2.8k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
40
2k
Docker and Python
trallard
44
3.3k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Visualization
eitanlees
146
15k
Transcript
アセンブリ言語のみで 言語処理系を作った話 (原題: ブートストラッピングで言語処理系を作った話) 第11回 カーネル/VM探検隊 中村 晃一
本日の資料・コード •https://speakerdeck.com/nineties/bootstrap •https://github.com/nineties/amber
自己紹介 • 中村晃一(@9_ties) • IoTデバイスを作っています • idein.jp • 課外活動 •
圏論勉強会、パターン認識・機械学習勉強会などの講師
処理系作りが趣味でした • 学生実験でコンパイラ係に • O’CamlでminCamlコンパイラを作ったり • Haskellでも作りました github.com/nineties/Choco • 大学院では最適化コンパイラの研究をしました
• 特殊なプロセッサの為のコンパイラを書いたり • 型推論器を書いたり
自分の言語を作ろうと思いました • 言語名: 最初はrowl ⇒ 後にamber • ただ作るだけでなくその過程を楽しみたい • どうやったら楽しめるだろうか?
縛りを入れて作ろう • ルール 1. 実装言語はアセンブリ言語のみ 2. 既存ライブラリは使ってはならない 3. コード生成ツールは使ってはならない libcなど
Cなどの高級言語 flex/bisonなど
作戦:ブートストラッピング アセンブリ言語でちょっと高級な言語1の処理系を書く 言語1でもうちょっと高級な言語2の処理系を書く 言語kでamberの処理系を書く amberでamberの処理系を書く 今ココ(暫らく放置中)
何の意味があるの? • 純粋に楽しみとして • 知識・技術・ノウハウを磨くのに役に立つかも • 効率の良い学習方法ではありませんが・・・ • ツール群を作った先人への尊敬と感謝が芽生える
以下ダイジェストでお見せします
1.アセンブリで言語「rowl0」を実装
アセンブリより少し高級な言語を作ります • 言語名: rowl0 • コンパイラ名: rlc
トークンの正規表現から
状態遷移図を書いて
状態遷移表にして
レキサを作ります
文法をBNFで書いたら
再帰降下法でパーサを作ります
コード生成はパースと同時にやりました • この時点でメモリ管理を実装 するのは面倒 ⇒ 構文木作るの面倒 コード生成
最初の言語「rowl0」が完成! • 変数管理が出来ない • 関数引数はp0,p1,p2,... • ローカル変数はallocate(n)でスタックメモ リを確保し x0,x1,x2,...で参照
2.「rowl0」でLISP系言語「rowl-core」を実装
一旦LISPを作る事にしました • 言語名: rowl-core • インタプリタ名: rlci • 実装が容易 •
メタプログラミングによる生産性向上
さっきと同じ感じでレキサ・パーサを作る
アセンブリよりかなり記述が楽
evalも作っていきます。
メモリ管理はまだしません • mmapしか使えないので負担が大きい 1. 不要になったメモリは回収しない 2. 足りなくなったら新たに確保 3. 動かし続けるといつか死ぬ •
次の世代のコンパイルだけ出来ればあと不要なので良しとした malloc, free
LISP系言語「rowl-core」が完成! • lambdaやmapが使えたり • マクロが使える!
3.「rowl-core」で「VM記述言語」を作る
次の世代では仮想マシンを導入します。 • その為の「VM記述用言語」を作成。 • LISPの強みを生かして、言語内DSLとして作成 • レキサ・パーサの実装は不要!
こんな感じでVM用コンパイラを書きます
今回は高階関数とかも使えます • 生産性がぐっと向上!
4.「VM記述言語」で仮想マシン「rlvm」を実装
言語内DSLでVMのコードを書いていきます
ガベコレもようやく実装します • コピーGCにしました
組み込み関数も作っていきます
ここでメタプログラミングの活用例を紹介します • 以下は、VMの命令セットのテーブル
命令テーブルから色々自動生成します • 命令の追加・削除を自 動的に反映 • LISPだとこういう仕組み 作るのが楽な気がする vm_instructions VMのevalループ リンカ
ディスアセンブラ アセンブラ amber内部で使うアセンブラ
命令セットを作っていきます
浮動小数点数演算や
多倍長整数演算なども用意しました
例外機構なども作ります
継続も作ってみました
仮想マシン「rlvm」が完成! • 186命令 • スタックマシン • コピーGC • 例外機構 •
shift/reset限定継続 • 浮動小数点数演算、多倍長整数演算
5.VM用ツールチェインを作る
VMは出来たがプログラミング環境がない • VM上のツールチェインを作る • VM用中級言語「rowl1」 • アセンブラ • コンパイラ •
リンカ • ディスアセンブラ
言語・アセンブラ・コンパイラを作ります • これらは次世代で捨てるので「rowl-core」の言語内DSLにします
リンカ、ディスアセンブラを作ります • 「rowl1」で記述し、これら自身もVM上で動くように実装 • リンカはメモリを食うのでGCのある環境でやりたかった
ディスアセンブラの出力はこんな感じ
VM上でプログラミングが可能に! • 分割コンパイルが出来る • デバッグもしやすい • メモリも潤沢に使える • 例外とかも使える •
普通の事が出来るようになっただけ・・・でも達成感がとても大きい!
6.「rowl1」で「amber」を実装
いよいよamberの実装に入ります • 動的スクリプティング言語として作る • インスタンスベースオブジェクト指向 • 先ほど作った「rlvm」上で動作
アセンブラを作ります • さっき作ったアセンブラは プログラム実行前にコンパイル • これは、プログラム実行時に その場でコンパイル • アドレスはバックパッチ
オブジェクトシステムを作ります • スロット、メッセージ、 ペアレントへの委譲
オブジェクトシステム上に中核機能を作っていきます • 動的パターンマッチングエンジンと • 部分関数関数の融合メカニズム
この上にコンパイラを作ります • コンパイラ自体を通常のオブジェクトとして実装 VM オブジェクトシステム パターンマッチングエンジン コンパイラ amberのコアシステム 構文木のマッチング リソース管理
クロージャ変換も実装しました
この上にパーサを作ります • 実行時にパーサをコンパイル • 各パーサは通常のオブジェクト(クロージャ) VM オブジェクトシステム パターンマッチングエンジン コンパイラ amberのコアシステム
コンパイル パーサ
とてもシンプルな文法 1. リテラルは式である 2. hがシンボル、e1,..,en (n>=0) が式の時h{e1, ..., en}も式である 3.
以上で定まるもののみがamberの式である • これと、あるトリックを後で組み合わせる
Packrat法で実装します • 後のトリックのため • 従ってレキサ不要
浮動小数点数のエンコード・デコードは苦労します • libcが無いので自分で作ります • 先ほど作った多倍長整数演算が必要になります “3.14” 0x40091eb851eb851f stortod, sprintf
amberが完成! • 動的スクリプティング言語 • VM上で動作 • インスタンスベースオブジェクト指向 • 動的パターンマッチングエンジンと部分関数融合が中核機能 •
レキシカルクロージャ • すごく高級になってきた!
7. 「amber」の標準ライブラリを作る
amberのテーマは自己拡張性 • amberの文法は標準ライブラリで定義されている • amber/lib/syntax/parse.ab • 起動時に自身の文法を構築する
起動時はリテラルとh{e1,..,en}という文法だけ
amberの文法を定義する為の文法を定義する
今定義された文法でamberの文法を定義する
続いてマクロシステムを作る
マクロで更に文法を増強
リッチな構文が使えるようになりました
オブジェクトシステムも増強します
継承などが使えるようになりました
ここで開発停止です • 更新予定はありません • 以下でインタプリタが起動(Linuxのみ) • makeのログで以上のブートストラッピングの過程を見てみましょう % git clone
https://github.com/nineties/amber.git % cd amber % make; sudo make install % amber
まとめ rowl0 rlc rlci rowl-core as VM記述言語 rlvm rowl1 リンカ
ディスアセン ブラ コンパイラ コンパイラ amber インタプリタ 実装 実装 実行 言語 ツール • 大分高級な所まで到達出来たので満足
None