動機
Rustのwasm_bindgen
は色々と制約が多いのが課題で、あまり好きではなかった。
wasm_bindgen
は本当に屑で糞です。少しの事やるのに死ぬほど冗長なコードになる
かといってAssemblyScriptやEmscriptenは環境構築が面倒で使う気にはなりません。
ということで自分好みのWebアセンブリ向け言語を作り始めた。
プロジェクト名は「Mystia」と言います(特に深い意味は無い)。
特徴
そこそこ強力な型推論
コンパイル時に厳密に型チェックされ、基本的に注釈は全く無しでも動きます!
--summary
オプションで型推論の結果を表示できます。
Rust/OCamlライクな文法
というかデザインは完全に私の思想になっています。
関数定義と代入は明示的にlet
で行い、最後の式はreturn
無しでも値を返します。
コンパイラ
LLVMは使わず、抽象構文木から直接WAT(WebAssembly Text Format)を生成します。
Rustで実装しましたが、いずれはセルフホスティングも出来るようにしたい。
コード量も割とコンパクトです。
他言語連携
JavaScriptとのFFI(Foreign Function Interface)も作りました。
型情報を元にWASMのメモリから値を読み込んでいます。
REPL
対話実行環境はNode製です
Playground
インストール/環境構築不要でブラウザ上で動かせます。
ぜひ試してみてください!
実用性
アプリもちゃんと書けます
type Elm = int;
load new_elm(tag: str, parent: Elm): Elm;
load upd_elm(id: Elm, prop: str, content: str): void;
load evt_elm(id: Elm, name: str, func: str): void;
load concat(a: str, b: str): str;
load to_str(n: num): str;
pub let model = @{
title: "Counter App",
count: 0,
layout: @{
panel: null
}
};
let view() = {
let formatted = "Number: " + (model.count as str);
upd_elm(model.layout.panel, "innerHTML", formatted)
};
pub let inc_btn() = {
let model.count + 1;
view()
};
pub let inc_key(key_code: int) = {
if key_code == 39 then {
let model.count + 1
} else if key_code == 37 then {
let model.count - 1
};
view()
};
let app() = {
let frame = new_elm("div", null);
upd_elm(frame, "style", "margin: 100px");
evt_elm(frame, "keydown", "inc_key");
let title = new_elm("h1", frame);
upd_elm(title, "innerHTML", model.title);
let model.layout.panel = new_elm("p", frame);
upd_elm(model.layout.panel, "style", "font-family: monospace");
view();
let btn = new_elm("button", frame);
upd_elm(btn, "innerHTML", "Increment");
upd_elm(btn, "className", "button");
evt_elm(btn, "click", "inc_btn")
};
app();
model.title
目標
制約が少なく自由度の高いWASM向け言語の選択肢となる事を目指しています。
また、今年のU-22プログラミングコンテストに応募予定です。
最後までご覧頂きありがとうございました!