diff --git a/README.md b/README.md index 597165f..0e44d0a 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,14 @@ Then run it on [MicroW8](https://exoticorn.github.io/microw8/v0.1pre2) */ ``` +### Include + +Other sourcefiles can be included with the `include` top level statement: + +``` +include "platform_imports.cwa" +``` + ### Types There are four types in WebAssembly and therefore CurlyWas: @@ -138,6 +146,18 @@ can use it. However, exporting global variable is not yet supported in CurlyWas. The type is optional, if missing it is inferred from the init value. +### Constants + +Constants can be declared in the global scope: + +``` +const name[: type] = value; +``` + +`value` has to be an expression evaluating to a constant value. It may reference other constants. + +The type is optional, but if given has to match the type of `value`. + ### Functions Functions look like this: @@ -296,15 +316,65 @@ non-zero integer. #### Memory load/store -To read from memory you specify a memory location as `base?offset` or `base!offset`. `?` reads a byte and `!` reads a 32bit word. +To read from memory you specify a memory location as `base?offset`, `base!offset` or `base$offset`. `?` reads a byte, `!` reads a 32bit word +and `$` reads a 32bit float. `base` can be any expression that evaluates to an `i32` while `offset` has to be a constant `i32` value. The effective memory address is the sum of both. -Writing to memory looks just like an assignment to a memory location: `base?offset = expressoin` and `base!offset = expression`. +Writing to memory looks just like an assignment to a memory location: `base?offset = expression`, `base!offset = expression` and `base$offset = expression`. When reading/writing 32bit words you need to make sure the address is 4-byte aligned. -These compile to `i32.load8_u`, `i32.load`, `i32.store8` and `i32.store`. Other WASM load/store instructions will be implemented as intrinsics, but aren't yet. +These compile to `i32.load8_u`, `i32.load`, `f32.load`, `i32.store8`, `i32.store` and `f32.store`. + +In addition, all wasm memory instructions are available as intrinsics: + +``` +([, , []]) + +offset defaults to 0, align to the natural alignment: 0 for 8bit loads, 1 for 16bit, 2 for 32 bit and 3 for 64bit. +``` + +with `` being one of `i32.load`, `i32.load8_u`, `i32.load8_s`, `i32.load16_u`, `i32.load16_s`, +`i64.load`, `i64.load8_u`, `i64.load8_s`, `i64.load16_u`, `i64.load16_s`, `i32.load32_u`, `i32.load32_s`, +`f32.load` and `f64.load`. + +``` +(, [, , []]) + +offset and align defaults are the same as the load intrinsics. +``` +with `` being one of `i32.store`, `i32.store8`, `i32.store16`, `i64.store`, `i64.store8`, +`i64.store16`, `i64.store32`, `f32.store` and `f64.store`. + +#### Data + +Data sections are written in `data` blocks: + +``` +data
{ + ... +} +``` + +The content of such a block is loaded at the given address at module start. + +Inside the data block you can include 8, 16, 32, 64, f32 or f64 values: + +``` +i8(1, 255) i16(655350) i32(0x12345678) i64(0x1234567890abcdefi64) f32(1.0, 3.141) f64(0.5f64) +``` + +Strings: +``` +"First line" i8(13, 10) "Second line" +``` + +And binary files: + +``` +file("font.bin") +``` #### Advanced sequencing diff --git a/src/typecheck.rs b/src/typecheck.rs index 826f27a..17abab8 100644 --- a/src/typecheck.rs +++ b/src/typecheck.rs @@ -104,6 +104,17 @@ pub fn tc_script(script: &mut ast::Script, sources: &Sources) -> Result<()> { } } + for c in &mut script.consts { + tc_const(&mut c.value, sources)?; + if c.value.type_ != c.type_ { + if c.type_.is_some() { + result = type_mismatch(c.type_, &c.span, c.value.type_, &c.value.span, sources); + } else { + c.type_ = c.value.type_; + } + } + } + for f in &script.functions { let params = f.params.iter().map(|(_, t)| *t).collect(); if let Some(fnc) = context.functions.get(&f.name) {