近況 2020-08-31

今月の活動 (ジャッコ言語)

ジャッコ言語

vain0x/jacco-lang

前月に引き続き、ジャッコ言語の処理系の実装を進めた。

構文まわり

  • 前回書いた、構文解析の結果の持ち方についてはおおよそ書いたとおりの方針になった。古いコードは全部消した
  • 位置情報の扱いが雑で、エラー位置を特定できないケースが多すぎたので改善した。

位置情報がとれるようになったので、LSP でシンボル参照の検索などがおおよそできるようになって、編集が快適になった。(挙動は変だったり不完全だったりするけど。)

enum の設計の変更

  • enum の仕様を簡略化した
    • いままでは1つの enum に、C言語みたいな A = 1 形式のバリアント (定数バリアントという) と、Rust 風の B { x: i64 } のような構造体風のバリアント (レコードバリアントという) が混在できた
    • 混在させたいユースケースはなさそう
    • 構文的に「定数バリアントのみ」か「レコードバリアントのみ」かをみて、別種の宣言にしてしまうことにした
    • 定数バリアントとレコードバリアントが混在していたら構文エラーにする
    • 定数バリアントからなる enum はコード生成において何らかの数値型 (i64 とか) になり、レコードバリアントからなる enum はいわゆるタグつきユニオンになる

新機能など

  • use 宣言をひとまず実装した
    • ジャッコ言語で自身の字句解析をするコードを書いたところ、すべてを1つのソースファイルに突っ込むのがすでにつらくなってきているため
    • エイリアス (use によって導入されるシンボル) を解決しないまま放置していたら「ここではこの型は構造体のはず (だから Option::unwrap できる) → エイリアスでした」みたいなパターンがしばしばある
    • CPS 変換の最中にすべてのエイリアスを展開した方がよかったかもしれない
  • ジェネリクスの実装を進めている
    • おそらく単相化を導入しない考えになりつつあるので、いわゆる型消去の方針で実装を進める
    • ジェネリクスが導入した型変数は、コード生成のタイミングでC言語の void に読み替えられる
    • 型変数が最終的に具体的な型にならないので、sizeof T の値が取れなかったりする
    • 代わりにポインタ越しに持って、型のサイズを引数でもらってその分だけ memcpy するとか、比較用に関数ポインタ fn(*T, *T) -> i32 をもらっておくとかする

C言語にはない機能を作っていると楽しい。(「対応するC言語の機能に落とすだけ」の実装は虚無。)

関連記事