Skip to content

kanaka/wam

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

wam: WebAssembly Macro language and processor

wam syntax

Wam syntax is a near superset of wat syntax that is more convenient for human developers to write directly.

The one place where wam is not a strict superset of wat is that it does not supports numeric indexes for globals, functions, and local references. But this is okay because index based references are much less useful to humans than they are to computers.

The following extensions to the wat syntax are supported:

  • The call operation can be omitted if the function is specified by name.
  • i32 and f32 constants can be specified directly without wrapping with i32.const or f32.const. Floating point literals must include a decimal point.
  • Local variables can be specified directly without wrapping with local.get.
  • Static strings can be specified inline. All static strings in the code will be de-duplicated, they will be added to a global data section, pointer variables will be created that index into the data section and the original static inline string will be replaced with a lookup relative to $memoryBase.
  • AND and OR macros that implement i32 boolean logic operations which support 1 or more conditions and that are short-circuiting.
  • STATIC_ARRAY macro that allocates the specified number of bytes as a static array in the data section. Note this creates an static global array in the data section at build time not at runtime (i.e. it does not dynamically allocate memory). STATIC_ARRAY takes an optional second argument that specifies the byte alignment. The default alignment is 1 (e.g. unaligned).
  • CHR macro that converts a 1 byte string into a character (i.e. i32.const) value.
  • LET macro that combines functionality from locals and local.set into a single construct that allow more concise declaration and initialization of i32 values.

wamp: wam processor

Current functionality:

  • Processes wam syntax into standard wat syntax support.
  • Automatically adds memory and memoryBase definitions if they aren't already defined or imported. Memory size defaults to 256 but can be changed via --memorySize command line parameter.
  • Supports combining multiple modules into a single module.
  • Retains whitespace and comments from original wam file(s).
  • Implemented as a small JavaScript/Node program that can be fairly easy extended with additional macro definitions.

Future functionality:

  • Support user-defined (data ...) sections. You can currently accomplish approximately the same thing with the STATIC_ARRAY or STRING macros in your code.
  • Add an elif construct (complex conditionals currently are become highly indented and hard to read)
  • Allow bare names for global variables in addition to locals by implementing some limited lexical scope.
  • Proper resolving/linking/checking of imports and exports when multiple files are specified.

Example

In the examples/ directory is a fizzbuzz example that makes use of wam syntax. Use wamp to convert the example to wat source.

./wamp examples/fizzbuzz.wam examples/print.wam > fizzbuzz.wat

Examine the wam files and the resulting wat to see what processing and macro expansion was performanced by wamp. The wat source can be compiled to a wasm module using the wasm-as assembler from binaryen.

wasm-as fizzbuzz.wat -o fizzbuzz.wasm

The wasm module can be executed using the wac/wace WebAssembly interpreter:

wace ./fizzbuzz.wasm

Examples of wam and equivalent wat:

wam wat
($myfun)
(call $myfun)
7
(i32.const 7)
$myvar
(local.get $myvar)
(CHR "A")
(i32.const 0x40)
"my string"
(global $S_STRING_7  i32 (i32.const 73))
(data ... "my string\00" ...)
...
(i32.add (global.get $memoryBase)
(global.get $S_STRING_7))
(STATIC_ARRAY 6)
(global $S_STATIC_ARRAY_8  i32 (i32.const 80))
(data ... "\00\00\00\00\00\00" ...)
...
(i32.add (global.get $memoryBase)
(global.get $S_STATIC_ARRAY_8))
(AND 7 8)
(if i32 (i32.const 7)
(if i32 (i32.const 8) (i32.const 1) (i32.const 0))
(i32.const 0))
(OR 7 8)
(if i32 (i32.const 7)
(i32.const 1)
(if i32 (i32.const 8) (i32.const 1) (i32.const 0)))
(LET $i 7
$j (i32.add $i 1))
(local $i i32 $j i32)
(local.set $i (i32.const 7)
(local.set $j (i32.add (local.get $i) (i32.const 1)))

License

MPL-2.0 (see ./LICENSE)

About

WebAssembly Macro language and processor

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published