Skip to content

MarkLagodych/walc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

137 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WebAssembly to Lambda Calculus compiler

WALC /wɑlts/ compiles stand-alone modules in WebAssembly into pure untyped lambda expressions.

The input modules are only allowed to use custom WALC functions to input a byte, output a byte, and exit, see example programs written in Rust.

The output lambda expressions are in human-readable WALC format, which just uses square brackets instead of the lambda symbol. There is even a one-line script to convert it to the standard mathematical notation.

All lambda calculus semantics and purity is preserved. In order to perform I/O, the interpreter decodes the program as an I/O command, executes the command, supplies encoded user input if needed, and repeats again.

See example interpreters written in Lua and TypeScript in under 300 LOC that are optimized for running lambda calculus for a long time without speed and memory usage degradation.

You can run some example lambda expressions with:

interp/lambda.ts examples/walc/hello.walc

You might also utilize overview notes as a starting point for digging into the codebase.

Enjoy!

Build & run

cargo run -- INPUT.wasm -o OUTPUT.walc

or install it globally:

cargo install --path .
walc INPUT.wasm -o OUTPUT.walc

Examples

Example Rust programs are here.

Build

  1. Install the WASM toolchain for Rust:

    rustup target add wasm32v1-none

    You can also experiment with the standard wasm32-unknown-unknown toolchain, even though its feature set is unstable and in the future it might extend beyond what WALC supports:

    rustup target add wasm32-unknown-unknown
  2. Build for release. You can use the provided Makefile that will tell Cargo to also install all the .wasm files into the examples/rust/bin directory:

    make -C examples/rust

    Or, for the wasm32-unknown-unknown target:

    make -C examples/rust TARGET=wasm32-unknown-unknown

Run

Example:

mkdir bin
walc examples/rust/bin/mandelbrot.wasm -o bin/mandelbrot.walc
tools/lambda.ts bin/mandelbrot.walc

Output:

              ..............................:::::!?:!!:............
           ...............................:::::::!?@!:::::............
         ..............................:::::::?@@@@@@?!::::::...........
       .............................::::::::::?@@@@@@@!:::::::::..........
      ..........................:::::??@!::@@??@@@@@@@??!@:::::@::.........
    ......................::::::::::::@@@@@@@@@@@@@@@@@@@@@?@@@@!::..........
   ..................:::::::::::::::?!@@@@@@@@@@@@@@@@@@@@@@@@@!::::..........
  ...............::!:::::::::::::::?@@@@@@@@@@@@@@@@@@@@@@@@@@@@::::...........
  ............::::::@!!!:!@!:::::!?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@::...........
 ..........::::::::::?@@@@@@@@@?!?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??::............
 ........::::::::::!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?:::............
 ..:...:::::::::!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?::::............
:?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?!:::::............
 ..:...:::::::::!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?::::............
 ........::::::::::!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?:::............
 ..........::::::::::?@@@@@@@@@?!?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??::............
  ............::::::@!!!:!@!:::::!?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@::...........
  ...............::!:::::::::::::::?@@@@@@@@@@@@@@@@@@@@@@@@@@@@::::...........
   ..................:::::::::::::::?!@@@@@@@@@@@@@@@@@@@@@@@@@!::::..........
    ......................::::::::::::@@@@@@@@@@@@@@@@@@@@@?@@@@!::..........
      ..........................:::::??@!::@@??@@@@@@@??!@:::::@::.........
       .............................::::::::::?@@@@@@@!:::::::::..........
         ..............................:::::::?@@@@@@?!::::::...........
           ...............................:::::::!?@!:::::............

Note that this particular example typically takes around 15 minutes or so to run, however, it does not require much memory.

Feature support

WALC supports:

WALC does not support:

  • Dynamic type checking and bounds checking.

    Only division by zero and signed division overflow are checked. Other checks are ignored for efficiency, even though this is non-compliant behavior.

  • Floating-point arithmetic.

    Given the scope of the project, there is simply no point in implementing this.

    To avoid as much compilation problems as possible, floats are stored as integers. Reinterpreting conversions between floats and integers are replaced with nops and any other operations are replaced with traps. This behavior might be useful when you use a standard function like printf that can use floats internally, but your program never invokes it with any float values.

About

WebAssembly to Lambda Calculus Compiler

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Contributors