Open14

自作言語 eb

uint256_tuint256_t

https://github.com/maekawatoshiki/eb

数年ぶりに自作言語を作りたい。
今の所、

  • スクリプト言語
  • 見やすい
  • JITできる
  • 漸進的型付け
  • Rust製
  • 他のアプリに組み込める
  • JITバックエンドにCraneliftを使いたい
  • GCどうしようかなぁ
  • 関数ごとに並列でコンパイル(遅延させる)すれば、プログラムが大きくなってもモッサリしない?
  • そもそもそんなに大きなプログラム向けじゃないかもね

という感じの構想。

uint256_tuint256_t

文法の構想

func fact(x i32) i32:
    if x == 1:
        return 1;;
    return x * fact(x - 1);;

// main関数は必要なのか?
func main():
    x := fact(10);
    print(x);;

;;がブロックの閉じカッコ(})のような役割を果たす。
PythonやHaskellの、インデントでブロックを表現する文法は、見た目は好きだけど、インデントが崩れると上手く機能しないから個人的にはあまり好きではない。だけど、curly bracket {} を使うとなんとなくスクリプト言語っぽくない。

uint256_tuint256_t
func fact(x):
    if x <= 2: return 1;;
    return fact(x - 1) + fact(x - 2);;

関数引数の型を省略したいけど、これじゃあ動的型になっちゃうなあ。

と思ったけど、これはreturn 1のおかげでfactの返り値の型がi32(int?)とわかるのか。
xの型はわからないか。

星にゃーん星にゃーん

型推論をすれば、 x - 1 から x がi32だと分かったりしそうです(言語設計によりますが)

uint256_tuint256_t

-がOCamlみたいに、整数に対する演算子だとわかっていればできそうですね。(floatでも同じ演算子を使いたい)

星にゃーん星にゃーん

演算子のオーバーロードと数値型の型推論を組み合わせるのはやや面倒ですね……綺麗にやろうとするとRustのTraitみたいな仕組みが必要になるかも。四則演算に限るとかなら、それだけ特別扱いすることもできますが、どちらにせよオーバーロードっぽいことは必要になりそう……(めんどくさそう)

uint256_tuint256_t

いい感じの妥協点を見つけたいですね。(-.とか+.みたいな演算子を使いたくないんですよね...)

uint256_tuint256_t
type Pair:
    x i32,
    y i32 ;;
type Option<T>:
    | Some(T)
    | None ;;
type Node:
    val i32,
    left Node,
    right Node ;;

こういうことできるのかなぁ。(型を調べるのがめんどくさいときに使えそう)
言語じゃなくてLintのやることか。

type A:
   a: `f(123)` ;; // f(123)の値の型
uint256_tuint256_t

参照型のことを考えないといけない。GCが必要なのか、線形型とかで頑張るのか。
スクリプト言語だからライフタイム・パズルをしたくない。

一色聡一郎一色聡一郎

この仕様ならJITしなくても普通に機械語へコンパイルできそうな気がする。

uint256_tuint256_t

はい、シングルバイナリも吐けるようにしようと思っています。(書くの忘れてました)