add new features to readme

This commit is contained in:
2022-02-26 12:14:31 +01:00
parent e608d3bb4b
commit 5f316cf17d
2 changed files with 84 additions and 3 deletions

View File

@@ -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 ### Types
There are four types in WebAssembly and therefore CurlyWas: 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. 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
Functions look like this: Functions look like this:
@@ -296,15 +316,65 @@ non-zero integer.
#### Memory load/store #### 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. `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. 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:
```
<load-ins>(<base-address>[, <offset>, [<align>]])
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 `<load-ins>` 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`.
```
<store-ins>(<value>, <base-address>[, <offset>, [<align>]])
offset and align defaults are the same as the load intrinsics.
```
with `<store-ins>` 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 <address> {
...
}
```
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 #### Advanced sequencing

View File

@@ -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 { for f in &script.functions {
let params = f.params.iter().map(|(_, t)| *t).collect(); let params = f.params.iter().map(|(_, t)| *t).collect();
if let Some(fnc) = context.functions.get(&f.name) { if let Some(fnc) = context.functions.get(&f.name) {