Wasp 🐝

a Lisp programming language for extremely performant and concise web assembly modules

warning: this compiler is very alpha and error messages aren't the best, but it works and language is simple!

clojure ; main.w (extern console_log [message]) (defn main "main" [] (console_log "Hello World!"))

Features

Quickstart

Wasp depends on git and rust. Make sure you have them installed before beginning.

console cargo install wasp wasp init myproject cd myproject wasp build python3 -m http.server Open up http://localhost:8000 and look in console. At this point we will have a web assembly module that has access to the standard libraries functions. More to come in this area!

If you don't have need for the standard library (or want to write your own!). This is also an option.

console wasp init myproject --no-std

At this point we will have a web assembly module with a single exported main function and nothing else.

If you think your standard library is out of date, just run wasp vendor

Lisp like its 1959

Wasp is an extremely basic language and standard library. It's primary goal right now is to be a MINIMAL Lisp that can be self hosted. Specifically: * emphasis on recursion * functions can be passed around as arguments * symbols * immutable cons data structure

clojure (cons 42 ()) ; returns the memory location of cons clojure (head (cons 42 ())) ; return the head value 42 clojure (tail (cons 42 ())) ; returns the memory location of tail

clojure (cons 1 (cons 2 (cons 3 ()))) ; returns a linked list

Other major features that are Lispy may be added in the future.

Drawing

Using wasm-module we can easily draw something to screen. Loops in wasp work differently than other languages, bbserve how this example uses recursion to rebind variables.

```clojure (extern globalgetWindow []) (extern Windowgetdocument [window]) (extern DocumentquerySelector [document query]) (extern HTMLCanvasElementgetContext [element context]) (extern CanvasRenderingContext2DsetfillStyle [canvas color]) (extern CanvasRenderingContext2DfillRect [canvas x y w h])

(def colors (data "black" "grey" "red"))

(defn main "main" [] (let [window (globalgetWindow) document (Windowgetdocument window) canvas (DocumentquerySelector document "#screen") ctx (HTMLCanvasElementgetContext canvas "2d")] (loop [x 0] (if (< x 3) (do (CanvasRenderingContext2DsetfillStyle ctx (mem32 (+ colors (* 4 x)))) (CanvasRenderingContext2DfillRect ctx (* x 10) (* x 10) 50 50 ) (recur [x (+ x 1)])))))) ```

See it working here

Mutable Global Data

It's often important for a web assembly modules to have some sort of global data that can be changed. For instance in a game we might have a high score.

```clojure (def high_score (data 0) )

(defn runmygame ... (mem32 highscore (+ (mem32 highscore) 100)
...) ```

Project Management

warning: this may change but it works Code dependencies are kept in a special folder called vendor which is populated by specific checkouts of git repositories.

For example a project.wasp containing:

bar git@github.com:richardanaya/bar.git@specific-bar

would result in these commands (roughly)

rm -rf vendor mkdir vendor git clone git@github.com:richardanaya/bar.git@specific-bar vendor/bar

when wasp vendor is called

Now, when wasp compiles your code, it does a few things.

Please try to use non conflicting names in meantime while this is fleshed out for 0.2.0

Advanced

When necessary, low level web assembly can be directly inlined ```clojure (defn-wasm memswap [i32] [i32] ; 1 input, 1 output [i32] ; int tmp = 0; ; tmp = a LOCALGET 0 LOCALSET 2 ; a = b LOCALGET 1 LOCALSET 0 ; b = tmp LOCALGET 2 LOCALSET 1 END )

(defn main "main" [] ... (memswap 10, 20) ) ```

Technical Details

Types

Functions

Testing

clojure (deftest addition (is (= 4 (+ 2 2)) "2 + 2 should be 4") (is (= 7 (+ 3 4)) "3 + 4 should be 7"))

See it working here

Why so few functions?

Wasp prefers to keep as little in the core functionality as possible, letting the standard library evolve faster and more independent community driven manner. This project currently follows a principle that if a feature can be implemented with our primitive functions, don't include it in the core compiled language and let the standard library implement it. Also that no heap based concepts be added to the core language.

Notes