From 1788a581c9533c9231f7d5d44e2631a36dc92e47 Mon Sep 17 00:00:00 2001 From: "Juan J. Martinez" Date: Wed, 31 Aug 2022 12:06:33 +0100 Subject: Manage the TODO with the language spec --- TODO.md | 27 ------- language.md | 243 +++++++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 217 insertions(+), 53 deletions(-) delete mode 100644 TODO.md diff --git a/TODO.md b/TODO.md deleted file mode 100644 index e2395c6..0000000 --- a/TODO.md +++ /dev/null @@ -1,27 +0,0 @@ -# TODO - -It is undecided when these are "done" (e.g. does it include the code generation?). - -Language features: - > not in order - * [ ] basic operators - * [ ] type system - * [ ] explicit type conversion - * [ ] functions (return) - * [ ] anonymous functions (lambdas) - * [ ] loops (while-like, infinite, break, continue) - * [ ] basic integer types: u8, s8, u16, s16 - * [ ] equality, comparison operators - * [ ] logic operators - * [ ] bitwise operators - * [ ] variables - * [ ] constants - * [ ] if-else - * [ ] built-in functions support (run-time) - * [ ] arrays - * [ ] strings (zero ended array of u8) - * [ ] for-in - * [ ] structures - * [ ] inline asm - * [ ] extern functions - diff --git a/language.md b/language.md index de4b87d..1092a57 100644 --- a/language.md +++ b/language.md @@ -1,4 +1,22 @@ -## Micro2 programs +# Overview + +TODO + +This is an example of a program: + +``` +def fib(n: u16): u16 { + if n < 2 { + return n; + } else { + return fib(n - 1) + fib(n - 2); + } +} + +fib(20); # 6765 +``` + +## Programs A program is a sequence of: @@ -17,6 +35,8 @@ Statements are delimited with semicolons (`;`), and are one of: XXX: do we really want expressions without effects? +TODO: entry point; `main` to be C compatible? + ## Modules A `micro2` file must start with the module name. @@ -27,6 +47,55 @@ module main The module name is used by the linker. +TODO: "import" and use modules. + +## Variables + +Variable declaration: +``` +var a: u8 = 123; +``` + +Group declaration: +``` +var ( + a: u8 = 123, + b: u16 = 1234 +); +``` + +Variables must be initialized, there are not default values, with the exception of structures that is optional. + +Variables can refer to a memory address with `@` operator and the data on that address will be used as initialization: +``` +var p: u8 = @0x8000; + +p; # whatever byte is in address 0x8000 (peek) +p = 0; # byte at 0x8000 is now 0 (poke) +``` + +### Constants + +Constant are immutable values and no memory is allocated for them: +``` +const K: u8 = 10; +``` + +Group declaration: +``` +const ( + A: u8 = 128, + B: u16 = 4096 +); +``` + +Must be resolved at compilation time. +``` +var a: u8 = 1; + +const A: u8 = a + 1; # error: unresolved value +``` + ## Built-in types ### Integers @@ -38,13 +107,20 @@ The module name is used by the linker. | u16 | unsigned 16-bit | `65535; 0xffff;` | | s16 | signed 16-bit | `-4096;` | -Builting functions: +Built-in 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`| +`hi` and `lo` can also be used with references (functions, structures and arrays): +``` +def fn() { return; } + +hi(fn); # MSB of fn address +``` + Type conversion is explicit: ``` var a: u8 = 10; @@ -56,17 +132,20 @@ u16(a) + b; # 20: u16 ### Booleans +Logic operators result on a boolean type. + | Type | Description | Samples | | --- | --- | --- | -| bool | boolean | `true; false;` | +| bool | boolean | `true; false; 1 == 1;` | ### Functions | Type | Description | Samples | | --- | --- | --- | -| ([parameters]) [-> [return]] | functions | `() { return; }` | +| ([parameters]) -> [return] | functions | `(a: u8) -> u8 { return a + 1; }` | +| ([parameters]) | functions (no return value) | `() { return; }` | -Functions can be defined with `def` when they have a name, or as anonymous using the lambda syntax. +Functions can be declared with `def` when they have a name, or as anonymous using the lambda syntax. ``` def add(a: u8, b: u8): u8 { @@ -125,9 +204,19 @@ private def dec(a: u8): u8 { } ``` +Function variables use references: +``` +def fn() { return; } + +# fn and fn2 refer to the same function +var fn2: () = fn; +``` + ### Special value: nil -`nil` is a reference not pointing to a value, used for example on variables with type function. +`nil` is a reference not pointing to a value, used for example on variables with type function or structure. + +Using a *nil* reference will result in a runtime error. ``` # fn doesn't hold a reference @@ -136,42 +225,144 @@ var fn: (u8) -> u8 = nil; fn(10); # runtime error ``` -## Variables +### Structures + +Structures can be used to group data and functions. + +Structure can be declared with `def` and provide values for the grouped data. Those values will be used when allocating an instance. + +Any variable or function declared in the structure can be accessed like a local variable inside the structure, and in the instances using the dot (`.`) operator. -Variable declaration: ``` -var a: u8 = 123; +def A { + # constants can be part of an structure as well + const INC: u8 = 1; + + var ( + n: u8 = 100, + m: bool = false, + dec: (u8) -> u8 = nil + ); + + # it is possible to define functions local + # to a structure + def inc(): u8 { + n = n + INC; + return n; + } +} + +# instantiate structure A +var a: A; + +a.n; # 100 +a.m; # false +a.dec; # nil + +a.inc(); # 101 +a.inc(); # 102 + +a.n; # 102 ``` -Group declaration: +Variables of type structure handle a reference: + ``` -var ( - a: u8 = 123, - b: u16 = 1234; -); +var b: A = a; + +# b points to the same data as a +b.inc(); # 103 +a.n; # 103 + +# c doesn't hold a reference to an instance of A +var c: A = nil; ``` -Variables must be initialized, there are not default values. +Recursive structures are not supported and local structures can't be used as return value in a function. -### Constants +### Arrays -Constant are immutable values and no memory is allocated for them: +Arrays are zero based and are supported for all types. + +XXX: including arrays? e.g. `[10][10]u8`. + +Array size is a numeric literal or a constant expression (must be known at compilation type), and all the elements on an array must be of the same type. + +Arrays are initialised to literals with `[` and `]` providing a list of values. ``` -const K: u8 = 10; +# array of 5 u8 +var arr: [5]u8 = [0, 0, 0, 0, 0]; ``` -Group declaration: +It is possible so initialize the array providing one single value that will be used for all the elements: ``` -const ( - A: u8 = 128, - B: u16 = 4096 -); +# this is equivalent to the previous example using [ and ] +var arr: [5]u8 = 0; ``` -Must be resolved at compilation time. +The array size is optional when initializing using literals: ``` -var a: u8 = 1; +var xs: []bool = [true, true, false]; -const A: u8 = a + 1; # error: unresolved value +len(xs); # 3 + +var xs2: []bool = true; # error: missing array size +``` + +Array elements can be accessed using `[]`: +``` +var arr: [5]u8 = 0; + +arr[0]; # 0 +arr[0] = 100; +arr[0]; # 100 ``` +Variables of type array handle a reference. +``` +# arr and arr2 refer to the same array +var arr2: [5]u8 = arr; +``` + +Local arrays can't be used as return value in a function. +``` +def fn(): [5]u8 { + var local [5]u8 = 0; + return local; # error: returning a local value of type array +} +``` + +Built-in functions: + +| Function | Description | Samples | +| --- | --- | --- | +| len | get the length of an array as u16 | `len(arr); # 5`| + +### Strings + +TODO: a zero ended array of u8 with special initializers + +## Operators + +TODO + +## Flow control + +TODO + +* if-else +* loops (while-like, infinite, break, continue) +* for-in + +## External functions + +TODO + +* is this "import"? +* calling conventions? +* namespace support? + +## In-line ASM + +TODO + -- cgit v1.2.3