Skip to content

A lisp inspired functional programming language which compiles to WebAssembly

License

Notifications You must be signed in to change notification settings

stefanhts/wacket

Repository files navigation

wacket

Running wacket

  1. Get everything installed (see this section)
  2. Write your program in program.wkt
  3. Run make
  4. Start your server (see Getting Server Running)
  5. Click the run button, or enter input (for readbyte programs) and then click run
  6. The output of the program should display under the run button

Prerequisites

Make sure you have the following installed:

Getting Server Running

  1. npm install
  2. cd server
  3. node index.js
  4. navigate to http://localhost:3000

Quick-start

  1. Write some wacket (for example, into program.wkt)
  2. make program.wat (optional)
  3. make program.wasm
  4. In the frontend, enter any input and click Run.

Compiling a test

Run make tests/{folder}/{number}.wasm to compile to main.wasm in the server/ folder, which can then be run from the frontend.

Errors

Kind of error What it means Who is most likely responsible
Compile errors that start with read: wacket syntax error programmer
Compile errors that start with WAT parse error: compiler has generated a poorly formed wat AST, or the pretty printer is non-comprehensive compiler writer
Compile errors that include contract violation (or other racket errors) compiler has an error in it compiler writer
Compile errors that cite .wat files (eg: ....wat:20:10: error:) wat generated by the pretty printer is malformed compiler writer
Runtime errors (the frontend says RUNTIME ERROR) the wacket code written has some error in it programmer
JavaScript runtime errors, that don't say RUNTIME ERROR in the frontend the wasm code generated an unexpected runtime error compiler writer

Target Language: WebAssembly

We need to write to .wat which is the WebAssembly Text format. From there we can use wat2wasm to turn that into the actual assembly code which can run in the browser.

WebAssembly Text Format (.wat)

Compiling from WebAssembly Text format (.wat) to WebAssembly Binary format (.wasm)

The Runtime system

Our runtime system is written in JavaScript, which can interface with compiled WASM bidirectionally. There is a minimal HTML file to act as an interface to the runtime system. This must be exposed to localhost with a web server, because modern browsers don't allow for accessing arbitrary files in the filesystem.

Source Language: wacket

We'll be aiming to implement all the features present in Loot, the reduced version of Racket created in class already. This should allow for the re-use of much of the compiler infrastructure, like the lexer, parser, and AST.

class github repo

note on .wkt files

They start with #lang wacket. This caused my syntax checker to tell me:

standard-module-name-resolver: collection not found
  for module path: wacket/lang/reader
  collection: "wacket/lang"
  in collection directories:
   /home/chris/.racket/8.4/collects
   /usr/share/racket/collects/

To fix this problem, I navigated to /usr/share/racket/collects/ and ran the command sudo ln -s racket/ wacket. This tricks the syntax checker because it looks at /usr/share/racket/collects/wacket, but it's really just a symbolic link to /usr/share/racket/collects/racket.

Alternatively, your syntax checker may fail to do anything at all, because of the unrecognized .wkt file extension.

TODO

  • Case
  • Cond
  • Pattern Matching
  • Tail recursion
  • Lambdas with arbitrary signatures
  • update the wat AST in the README to reflect more recent changes
  • More detailed RTS printing for heap structures
  • Arity checking

Complete

  • Pretty printer
  • Makefile
  • Integers
  • Prim1
  • If
  • types
  • Cons
  • Box
  • Prim2
  • Functions
  • Lets
  • Prim0
  • IO
  • Strings
  • Vectors
  • Lambdas with one argument

wat AST

Note: [list of Things] may be empty in this representation.

Note 2: This is not up to date. See wat/ast.rkt for the most up to date AST.

type Module = (Module [list of Definitions])

type Definition = Import
                | Export
                | Func
                | Start

type Start = (Start funcname)

;; imports have a 2 level namespace: module then function
type Import = (Import modulename funcname FuncSignature)

;; name is what the RTS will see, ExportFuncSignature is what we use internally
type Export = (Export name ExportFuncSignature)

type ExportFuncSignature = (ExportFuncSignature name)

type Func = (Func FuncSignature [list of Locals] Body)

type FuncSignature = (FuncSignature name? [list of Params] Result?)

type Param = (Param name? Type)

type Result = (Result Type)

type Local = (Local name? Type)

type Type = i32
          | i64
          | f32
          | f64

type Body = (Body [list of Instructions])

type Instruction = (Inst name [list of Instructions])
                 | Const

type Const = (Const v)

Memory Accessing

An instance of memory in WASM is allocated in blocks of 64KB of storage, so a single block should be more than enough for Wacket.

I found this article to have the best (and really only) example of manipulating memory in .wat files.

Implementation

Instead of rbx, we will use the global variable defined by heap-name to store the next available address on the heap. This is a global variable with the internal name generated by (gensym 'heap).

Some specifics to note:

  • Addressing must be done with i32. Practically, this isn't an issue, since indexing must start at 0, but it's simply another thing to keep in mind.
  • Becuase the heap is a byte array, each value still occupies 8 "positions" on the heap, so we need to increment the heap pointer by 8 each time. This means the logic is actually pretty much the same as in racket.
  • Just like in class, the cons cell starts with the cdr and is followed by the car 8 bytes later.
  • The StoreHeap struct requires the address to be on WASM's stack beforehand. This is so the car and cdr can be stored right next to each other in memory.

About

A lisp inspired functional programming language which compiles to WebAssembly

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published