コンパイラの実装言語にあると良い機能

構造体とか配列とかどんな言語にも大体あるものは除きます。あくまで私の主観です。 lex/yacc/gperfなどのツール 特にyaccがないと複雑な言語のパースは大変。 バリアント 構文木の表現に一番適していると思う。 パターンマッチ コンパイラ内部はパターンマ…

純粋関数型言語の処理系を作ってみることにした

関数型言語というと型システムなどフロントエンド部に注目が集まりやすいと思いますが、私はバックエンドの実装に興味があります。 そこで小さな純粋関数型言語の処理系を作ることにしました。名前は安直ですがpurefにします。方針 勉強用の実装 飾りは付け…

構文木・レキサ・パーサ

構文木は教科書7ページに書いてあります。非常にシンプルです。Haskellのような複雑な言語も構文糖衣を取り除くと,同様の言語まで単純化されます。そんなバカなと思う人は,GHCのソースのghc/compiler/coreSyn/CoreSyn.lhsを読んでみて下さい。 レキサ/パーサ…

cppの生成するディレクティブのフラグの意味

C言語のソースをcppにかけると生成されるディレクティブの意味。 # 1 "/usr/include/math.h" 1 3 4 最初の数字はファイルの行番号で、末尾の数字は 1 : includeを開始して新たなファイルに移る (ENTERフラグ) 2 : includeを終了して元のファイルに戻る (LEAV…

電卓

今日ふと高校時代に電卓遊びにハマっていた事を思い出したので、メモしておきます。√のない計算機でNの平方根を求めたい場合は [N(数字)][M+]と押したあと [MR][x][MR][-][N][/][2][/][MR][M-]を繰り返します。 Nのm乗根の場合は [N][M+]と押したあと [MR][x…

rowl1言語コンパイラをコンパイルするコンパイラ作成中

ようやくブートストラッピングの次のステップであるrowl1言語開発に着手しました。rowl1言語コンパイラはrowlVM上で動作するプログラムとして作成します。 rowl1コンパイラ記述言語のアセンブリ言語のアセンブラ http://github.com/nineties 中のrowl-assemb…

これまでの進捗の整理

アセンブリ(gas)でrowl0言語のコンパイラを作成した rowl0言語でrowl1言語のコンパイラ(型システム含む)を実装したが、バグ多発でいったん白紙に戻す。 rowl0言語でLISP風rowl-core言語のインタプリタを作成した rowl-core言語でvm記述言語を定義しvm記述言…

実行可能ファイルのフォーマット

実行可能ファイル(拡張子.rlx)からのロード・実行を実装しました。http://github.com/nineties/rowl/commit/c454fd019919dee0526ecc96b256091ca1da9771実行可能ファイルのフォーマットは先頭から 1ワード : ファイルの総バイト数(=N) 1ワード : グローバル参…

rowlVM/GC ブロック・ページの管理(再考)

今朝書いたのは綺麗ではなかったので考えなおします。多分車輪の再発明だと思いますが。 ポイントはページ⇔ページデスクリプタ間のアドレス変換のシンプル化です。 ページデスクリプタ・ページの配置を以下のようにします。 |<---------------------- 1 Mbyt…

rowlVM/GC ブロック・ページの管理

この論文 Compacting Garbage Collection with Ambiguous Roots ではあらかじめ固定長のメモリブロックがあって個定数のページがあるような実装になっているので直します。 GHCのアロケータ実装を参考にしています。まず、メモリはブロック単位(1Mbyte)でア…

データ型の定義

現在rowlVMにGCを実装中です。型のない言語で書いているのもあって、コードは汚くなってきましたがこのままいきます。 実装するGCは速度が気になりますが、とりあえずはMostly Copying GCで行こうと思います。下を参考にして、自分なりに修正をして実装しま…

マシンレジスタ割り当て

現在のマシンレジスタの割り当て状況のメモ。 %eax 汎用レジスタ %ebx 汎用レジスタ %ecx プログラムカウンタ %edx ゼロレジスタ(常に0が入っている) %esi スタックポインタ %edi ベースポインタ %ebxと%esi,%ediの値は保存しなければならない為関数の先頭…

組み込み型・命令(暫定)

コンパイラ・インタプリタ作成に特化した型・命令(consセルやビット配列)を用意して個性を出す方針。1バイトで足りるだろうか。組み込み型 ブール型 整数 (8bit・16bit・32bit・64bit) 浮動小数点数 (単精度・倍精度) 以上非ボックス化型 シンボル consセル …

関数が定義できるようになった。

rowlVM上で関数定義が出来るようになりました。 以下はfibonacciの定義。バイトコード長は22バイトです。今は手書きだけど、後でコンパイラ作ります。 (byte[] 100 fib @(assemble `( arg0 imm_i3 isub (if_lt hoge) arg0 imm_i1 isub (vcall 0 4) ; 0番(fib…

rowl VM/GC の実装

現在VM/GCの実装中です。 これまでの開発経過です。 1. rowl-coreインタプリタを開発 LISPの様なS式で書かれたrowl-core言語を処理する簡易インタプリタを以前作ったrowl0で実装しました。 言語機能が低いうちはインタプリタの方が簡単に作れるので、開発を…

VM/GCを作る。

2週間のんびりrowl-coreを作っていましたが、大体出来上がってきました。LISPもどきのインタプリタです。非常に雑な実装(識別子テーブルとか関数コールとか)ですが、使い捨てなのでこれでいいです。さて、次の作業はVMとGCの作成です。本当はパーサ作ったり…

今後の開発計画

現状 アセンブリ実装のrowl0完了 → rowl0実装のrowl1開発中 rowl1の開発もほぼ終了し、rowl2のコードを書き始めているという段階。 けれども、rowl1で高級な機能(クロージャや多重定義)を導入しようとしてバグが多発してきたので一旦ここで計画の見直しを行…

オーバーロードを実装した

久々の機能追加。 import stdlib; f: () { return 1; }; f: (x!int) { return x; }; export main: () { x : f (); y : f (1); exit(ExitSuccess); }; などが実行できるようにした。引数の型が同一で戻り値のみの型が違う関数の定義はできない。(エラーチェッ…

情報理工のポスターの暗号(?)を解読しよう。

[追記]解かれた様ですhttp://twitter.com/kinaba/status/13109925805 http://twitter.com/kinaba/status/13109851142で東大の情報理工学系研究科のポスターの中に これぞ情報科学の真髄といえるような文字列。 http://twitter.com/hagiya/status/9520249396 …

結婚指輪

このブログには書いていなかったけど実は私は新婚なのです。 今日は結婚指輪ができあがったので博物館の後に受け取りに行きました。入籍より2週間遅くなってしまいました。

科博オープンラボレポート

年に一度の[イベント]新宿分館 オープンラボ「博物館の裏側」(2010, 国立科学博物館新宿分館)に行ってきました。 実を言うと上野本館と併せて国立科学博物館に行くのは3週間連続だったりします。 画像を一部載せます。軽めのグロ画像があるので注意。 新…

Hello Worldが書けない

fortranコンパイラを作らなきゃならないので勉強開始。まずはHello World write(*,*) 'Hello World' end 必ず頭に6つスペースを入れる コンパイル % gfortran hello.f -o hello 実行 % ./hello Hello World 一見うまく動いたように見えるがHello Worldの先頭…

レジスタ割り当て断念

現在の簡便なレジスタ割り当てだと、複雑な関数でレジスタが足りなくなって失敗してしまう。名前換えとかに手を出すのは泥沼化する危険があるので、rowl1ではスタックベースの実行方法にすることにした。

クロージャが動いた

以下のコードが動くようになった! import stdlib; make_counter: (n) { return () { return n++; } }; export main: () { counter : make_counter(1); x : counter() + counter() + counter(); sys_exit(x); (% -> 6 %) }; 実装は非常に辛かった。まだ相互…

条件分岐を一部実装した

こんな感じのコードが実行出来る様になった。 import stdlib; fib: (n) { if (n) { return n * fib(n-1); }; return 1; }; export main: () { exit(fib(3)); }; if(n)の部分はまだ比較演算子を実装していない為。 コンパイルすると _fib.LT1ii: pushl %ebp m…

大域脱出する関数の型

例外やexitなどの関数の型をどう扱えば良いか困った。OCamlだと val exit : int -> 'a Haskellだと exitWith :: ExitCode -> IO a みたいに多相型を返して任意の型と単一化できるようにするのが普通のようだけど、rowlはreturnで値を返すのでこれができない…

分割コンパイルができるようになった

export/import/external宣言を実装した. (% test.rl %) export type hoge : A | B (int) ; export plus: (x, y) { return x + y; }; みたいなコードをコンパイルするとヘッダファイルが自動生成される. (% test.rli generated by rlc1 %) type hoge : A | …

variantが書けるようになった

こんな感じで。 type test : A | B (int) | C (char, int) ; export main: () { x : A; y : B (2); z : C ('a', 0); syscall(1, 0); }; パターンマッチはまだ実装していない。というか実はまだif文すら未実装。 Cのunionみたいにサイズが最大であるCに合わせ…

科博行ってきた

ものづくり展 MONODZUKURI EXHIBITIONが今日までだというので行ってきた。 面白かった。Rubyも展示されていたけどNaClのパンフと30秒位の動画のみだった。ちょっと地味だった。久しぶりに科博行ったんで一通り回ってきたけど、やっぱり計算機の展示はたまら…

名前付きフィールドを一部実装

以下の様なコードがコンパイルできるようになった。右辺値としての一部だけ実装。 f: () { return (x:1, y:2); }; export main: () { p : f(); syscall(1, p.x + p.y); }; クロージャを実装すればオブジェクト指向っぽいコードも書けるようになる。