WAT (WebAssembly Text Format) を少し拡張して、人間にとって書きやすく malloc / free や GC の実装で役立つことを目指した中間レベルの言語です。
WAT と同じく S 式で記述し、コンパイラを用いて WASM (バイナリ形式) に変換したうえで、各種 WASM ランタイムで実行できます。
i32.add
, i32.mul
, i32.store
を用いた単純な関数定義をコンパイルできるようにしました。
これから let
, set!
特殊形式と型推論を実装しようとしています。
WAXT :
(func add-and-store ([addr : i32] [x : i32] [y : i32])
(i32.store addr (+ x y)))
WAT (コンパイル後) :
(module
(memory 1)
(func $add-and-store (export "add-and-store")
(param $addr i32) (param $x i32) (param $y i32)
(i32.store
(local.get $addr)
(i32.add (local.get $x) (local.get $y)))))
デフォルトですべての引数・束縛はイミュータブルであり、再代入はコンパイルエラーとなります。
(func foo i32 ([x : i32] [y : i32])
(let [x' (+ x 2) y' (+ y 3)]
(* x' y')))
$
プレフィックス付きの引数・束縛はミュータブルとなり、 set!
特殊形式による再代入が許可されます。
(func bar i32 ([$x : i32] [$y : i32])
(set! $x (+ $x 2))
(set! $y (+ $y 3))
(* $x $y))
example
ディレクトリ内にコード例があり、それらは以下のコマンドでコンパイルできます。
dotnet run --project src/Waxt.Cli -- example/noop.waxt
dotnet run --project src/Waxt.Cli -- example/return-i32.waxt
dotnet run --project src/Waxt.Cli -- example/add-and-store.waxt
./test.sh
graph TB
Token-->Location
Lexer-->Location
Lexer-->Token
UntypedAst-->Location
UntypedAst-->Type
Parser-->Location
Parser-->Token
Parser-->UntypedAst
TypedAst-->Location
TypedAst-->Type
TypeChecker-->Location
TypeChecker-->Type
TypeChecker-->TypedAst
TypeChecker-->UntypedAst
CodeGen-->TypedAst
CodeGen-->Wasm
Compiler-->Lexer
Compiler-->Location
Compiler-->Parser
Compiler-->TypeChecker
Compiler-->TypedAst
Compiler-->CodeGen
Cli-->Compiler