We have a large amount of hand-written Wasm code. It might be easier to maintain it if we could write it using a more concise syntax, with some syntactic sugar and type inference. This would involve writing a tool that can type-check the code and translate it to and from standard Wasm (possibly with source maps).
Some ideas:
Introduce local variables when they are first used rather than at the beginning of functions.
Use a single namespace for globals, locals, and functions, so that one can just write x instead of (local.get $x), (global.get $x) or (ref.func $x).
Recover missing type information through type inference: write e1 + e2 instead of (in32.add e1 e2), write e.m instead of (struct.get $t $m e).
We could write it like this using a Rust-like syntax:
fn string_compare(p1: &eq, p2: &eq) -> i32 {
if p1 == p2 { return 0 }
let s1 = p1 as &string;
let s2 = p2 as &string;
let l1 = array_len(s1);
let l2 = array_len(s2);
let len = l1 <=u l2?l1:l2;
for (let i = 0; i <s len; i++) {
let c1 = unsigned(s1[i]);
let c2 = unsigned(s2[i]);
if c1 <u c2 { return -1 }
if c1 >u c2 { return 1 }
if l1 <u l2 { return -1 }
if l1 >u l2 { return 1 }
0
}
Or with an OCaml-like syntax:
let string_compare (p1: eq ref) (p2: eq ref) : i32 =
if p1 == p2 then return 0;
let s1 :> string ref = p1 in
let s2 :> string ref = p2 in
let l1 = array_len s1 in
let l2 = array_len s2 in
let len = select l1 l2 (l1 <=u l2) in
let i = 0 in
while i <s len do
let c1 = unsigned s1.[i] in
let c2 = unsigned s2.[i] in
if c1 <u c2 then return -1;
if c1 >u c2 then return 1;
i := i + 1
done;
if l1 <u l2 then return -1;
if l1 >u l2 then return 1;
0
We have a large amount of hand-written Wasm code. It might be easier to maintain it if we could write it using a more concise syntax, with some syntactic sugar and type inference. This would involve writing a tool that can type-check the code and translate it to and from standard Wasm (possibly with source maps).
Some ideas:
x
instead of(local.get $x)
,(global.get $x)
or(ref.func $x)
.e1 + e2
instead of(in32.add e1 e2)
, writee.m
instead of(struct.get $t $m e)
.For instance, consider this function:
We could write it like this using a Rust-like syntax:
Or with an OCaml-like syntax: