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!")
)
console
wasp build
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
At this point we will have a web assembly module with a single exported main function and nothing else
wasp add std https://github.com/wasmlang/std.git
wasp build
At this point we will have a web assembly module that has alot more access to the standard libraries functions and a default.
Using wasm-module we can easily draw something to screen.
```clojure (extern globalgetWindow []) (extern Windowgetdocument [window]) (extern DocumentquerySelector [document query]) (extern HTMLCanvasElementgetContext [element context]) (extern CanvasRenderingContext2DfillRect [canvas x y w h])
(defn main "main" [] (let [ window (globalgetWindow) document (Windowgetdocument window) canvas (DocumentquerySelector document "#screen") ctx (HTMLCanvasElementgetContext canvas "2d") ] (CanvasRenderingContext2DfillRect ctx 0 0 50 50) ) ) ```
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)
...
)
```
Code dependencies are kept in a special folder called vendor
which is populated by:
* copies of other folders on your system
* specific checkouts of git repositories.
For example a project.wasp
containing:
foo = ../../foo
bar = git@github.com:richardanaya/bar.git@specific-bar
would result in these commands (roughly)
mkdir vendor
cp -R ../../foo vendor/foo
git clone git@github.com:richardanaya/bar.git@specific-bar vendor/bar
when wasp build
is called
Now, when wasp compiles your code, it does a few things.
project.wasp
, one folder at a time all files ending in .w are loaded from each vendor/<dependency-name>
and its subfolders.vendor
are loadedFor example with project.wasp
foo = git@github.com:richardanaya/foo.git
assume my package foo
has a function in its file at vendor/foo/foo.w
:
clojure
...
(defn foo [] 123)
...
in my main.w
I also have a foo
function:
clojure
...
(defn foo [] 42)
...
because the vendor files are loaded in order before the main.w
file in my project, I can override behavior from my vendor files resulting in a foo
that returns 42 in my compile code.
This puts an onus on package makers to use good function names that properly include the namespace your package, but also gives the flexability to override very deep behavior pretty much anywhere.
wasp build --verbose
Can help you see what is shadowed if you have concerns.
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) ) ```
-1
, 0
, 42
)"hello world!"
)":hello_world"
)true
false
)()
)(data 1 true :hey (data :more-data ())
). Use this for embedding raw data into your application memory on startup.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.
()