From 00a6188202275afc0560df3fd7b32d6ce4f93871 Mon Sep 17 00:00:00 2001 From: "Juan J. Martinez" Date: Mon, 22 Aug 2022 09:42:00 +0100 Subject: WIP of language specification --- language.md | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 language.md (limited to 'language.md') diff --git a/language.md b/language.md new file mode 100644 index 0000000..41f6897 --- /dev/null +++ b/language.md @@ -0,0 +1,177 @@ +## Micro2 programs + +A program is a sequence of: + + * function declarations + * statements + * TODO: if-else, for, for-in, etc; with no semicolon + +Statements are delimited with semicolons (`;`), and are one of: + + * expression (e.g. `1+2`) + * function call + * lambda definition + * variable + * variable declaration + * return statement + +XXX: do we really want expressions without effects? + +## Modules + +A `micro2` file must start with the module name. +``` +# our main module (this is a comment) +module main +``` + +The module name is used by the linker. + +## Built-in types + +### Integers + +| Type | Description | Samples | +| --- | --- | --- | +| u8 | unsigned 8-bit | `123; 0xce; 0b10000;` | +| s8 | signed 8-bit | `-123;` | +| u16 | unsigned 16-bit | `65535; 0xffff;` | +| s16 | signed 16-bit | `-4096;` | + +Builting functions: + +| Function | Description | Samples | +| --- | --- | --- | +| hi | Get the MSB on a 16-bit number | `hi(0xaabb); # 0xaa`| +| lo | Get the LSB on a 16-bit number | `lo(0xaabb); # 0xbb`| + +Type conversion is explicit: +``` +var a: u8 = 10; +var b: u16 = 10; + +a + b; # error: type mismatch +u16(a) + b; # 20: u16 +``` + +### Booleans + +| Type | Description | Samples | +| --- | --- | --- | +| bool | boolean | `true; false;` | + +### Functions + +| Type | Description | Samples | +| --- | --- | --- | +| ([params]) [-> [return]] | functions | `() { return; }` | + +Functions can be defined with `def` when they have a name, or as anonymous using the lambda syntax. + +``` +def add(a: u8, b: u8): u8 { + return a + b; +} + +add(2, 8); # 10 + +``` + +Anonymous function: +``` +# increment the value passed as argument +(a: u8): u8 { + return a + 1; +}(10); # 11 + +``` + +Function are higher order functions: +``` +def apply(fn: (u8) -> u8, a: u8, b: u8): u8 { + return fn(a, b); +} + +apply(add, 2, 10); # 8 + +# using a lambda +apply((a: u8, b: u8): u8 { + return a + b; + }, + 2, 8); # 10 + +# lambdas can be assigned to variables +var double: (u8) -> u8 = (a: u8): u8 { + return a + a; +}; + +double(10); # 20 +``` + +Anomymous functions can only access local variables (closures aren't supported): +``` +def closure(a: u8): () -> u8 { + return (): u8 { + return a; # invalid return, undefined a + }; +} +``` + +Functions are exported by default, unless they are defined as private: +``` +# not exported (exported is the default) +private def dec(a: u8): u8 { + return a - 1; +} +``` + +### Special value: nil + +`nil` is a reference not pointing to a value, used for example with variables with type function. + +``` +# fn doesn't hold a reference +var fn: (u8) -> u8 = nil; + +fn(10); # runtime error +``` + +## Variables + +Variable declaration: +``` +var a: u8 = 123; +``` + +Group declaration: +``` +var ( + a: u8 = 123, + b: u16 = 1234; +); +``` + +Vaiables must be initialized, there are not default values. + +### Constants + +Constant are not variables, they don't use memory. +``` +const K: u8 = 10; +``` + +Group declaration: +``` +const ( + A: u8 = 128, + B: u16 = 4096 +); +``` + +Must be a constant expression and that can be resolved at compilation time. +``` +var a: u8 = 1; + +const A: u8 = a + 1; # error: unresolved value +``` + -- cgit v1.2.3