Rytl
挫折中。
言語名について
Rytl is Toy Language
コンセプト
簡潔に書ける
記述量が少ない
覚えることが少ない
エラーがわかりやすい
関数型言語
パターンマッチが楽しい
GCあり
型推論あり
関数型の型あり言語
サブプロジェクト
ちょっと大幅に変えたい
lexer, parserをを自動生成させる
バックエンドにLLVMを使用する
バックエンドの勉強をしたい
概要
目標はセルフホスト
↑を実現するために必要な機能を揃えていく
monkey-nimを眺めて必要そうな機能を列挙する
これが達成できれば、だいぶ前からあった言語処理系よりももっと大きな文脈での「フレームワークを使ってエンジニアリングをする側ではなく、フレームワークを作る側になる」という目標も達成できる
セルフホストとかどうでもよくてLLVM触りたい、みたいな気分になってきたmrsekut.icon
関数型の型あり言語
学びたいこと
GCを作る
意味解析を行う
型推論を行う
パターンマッチを実装する
vscode
syntax highlightやりたい
wasmのplayground
サブプロジェクト
思想
TypeScript大好きマンとしては、まずany的な型で安全でない状態で小さいスコープで一旦動かしてから、型を付けていく
ようなことができたら便利そうなんだがどうなんだろう
現状の課題
これはプログラミングの普遍的な話だが、
変数名を考えるのが大変、とか
設計
できる限りインクリメンタルに作る
性に合っているから
参考になる言語のリポジトリをメモる
Juliaのようにインタプリタで?を打つことでドキュメントを見れるようにしたい
型の表現
RustやHaskellのような型表現だと
printするときにその型にあったものを定義する必要がある
一方でjsでは全てobjectで表現するので、いつでもどこでもconsoleで出力することができる
↑こっちのほうがよくね??
たとえばどんなデメリットが有るのか
新しい構文を追加する手順
lexerにテストを追加
TokenKindにTokenを登録
lexer()に処理の追加
parserにテストを追加
Astに追加
いんたぷりた
途中で思ったことをメモする
例えば、
欲を言えば、数理的な論理を入れたい
モナド
ヒルベルト
moduleシステムを簡単にしたい
typescriptはめっちゃ簡単。慣れてるだけ?
関数のAST
テストコードが型宣言になる
code:maru
tokenizeNumber :: 123 -> 123
tokenizeNumber :: "ooo" -> error
code:rytl
// 構想
Int -> Int
fib := match =>
0 => 0
1 => 1
n => fib(n-1) + fib(n-2)
無名関数
code:rytl
x => x + x
進める
四則演算
優先順位を付ける
↑文字列で実行
実際に、.mrseファイルを読み込む
進め方(仮)
ホスト言語のテストコードとして自作言語のLexerを書く
つまり、ほぼ同時に2つの言語で同じ物を書いていく
流石に無理か。
じゃあ小さい関数などを作れるようにするのを最初の目的にし、そこからはLexer、Parserを作りながら言語をデザインしていく
困ったこと、改善点、作り始める前に決めておけばよかったことなど
自作言語でのセルフホストインタプリタの実装は以下が参考になる
Lexer
Parserとは分離する
事前に全て字句解析し、その後Parserに渡す
Token構造体はどんな情報を保持するか
Tokenの種類
そのTokenの値
Intの場合は数値、など
Stringの場合はその文字列、など
場合によっては、hccのように↑この型ごとにここのプロパティを増やしていかないといけないかもしれない 全ての型に必要ではない
インデントの深さ?
Pythonのlexerを参考
Tokenの長さ?
次のToken?
変数、関数定義
型の追加
パターンマッチの追加
型推論の追加
など、nimのときと同じ道程で作っていく
変数をサポート(暗黙で全てint扱い)
関数呼び出しをサポート
文字型を追加
初歩的な型宣言をサポート
ポインタ型を追加
配列型を追加
配列の初期化式をサポート
if文を追加
関数定義をサポート
forループを追加
return文を追加
ポインタ型への代入をサポート
==追加
配列演算と配列の添字をサポート
++, --, !追加
パターンマッチの実装とかが大変そう
文字列型の追加
組み込み関数の追加
実装
code:rytl
// fizzbuzz
// 構想
Int -> String
fizzbuzz n:= Int -> String
match mod n
15 => "fizzbuzz"
3 => "fizz"
5 => "buzz"
_ => String n