From 46653666f02d06f7ae6a82c1d8da841ea6e7c848 Mon Sep 17 00:00:00 2001 From: mark Date: Wed, 24 May 2023 23:35:42 +0200 Subject: [PATCH] updated readme and docs --- README.md | 1 + docs/syntax_cheat_sheet.md | 136 +++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 docs/syntax_cheat_sheet.md diff --git a/README.md b/README.md index 2a4865c..9c9d2a4 100755 --- a/README.md +++ b/README.md @@ -31,4 +31,5 @@ Now, create a new text file (or choose one from the examples) and run it: `mers ## Docs +[syntax cheat sheet](docs/syntax_cheat_sheet.md) [intro](docs/intro.md) diff --git a/docs/syntax_cheat_sheet.md b/docs/syntax_cheat_sheet.md new file mode 100644 index 0000000..52f78a8 --- /dev/null +++ b/docs/syntax_cheat_sheet.md @@ -0,0 +1,136 @@ +# mers syntax cheat sheet + +## Types + +- `bool` +- `int` +- `float` +- `string` +- tuple: `[ <...>]` +- list: `[ ...]` +- function: `fn()` (might change? depends on implementation of generics) +- thread: `thread()` +- reference: `&` +- enum: `EnumName()` +- one of multiple types: `//` + +## Values + +- bool + + `true` or `false` +- int + + decimal: `2`, `+2`, `-5`, `0`, ... +- float + + decimal: `1.5`, `0.5`, `-5.2`, `2.0`, ... (this is recommended for compatability and clarity) + + whole numbers: `1.0`, `1.`, ... (may break with future updates) + + numbers from 0 to 1: `.5` would be ambiguous following tuples, so is not supported. +- string + + `"my string"` (double quotes) + + `"it's called \"\""` (escape inner double quotes with backslash) + + all escape sequences + * `\"` double quote character + * `\\` backslash character + * `\n` newline + * `\r` carriage return + * `\t` tab + * `\0` null +- tuple + + `[ <...>]` +- list + + `[ <...> ...]` (like tuple, but `...]` instead of `]`) +- function + + `( <...>) ` where `` is ` `. +- thread + + returned by the builtin function `thread()` +- reference + + to a variable: `&` + + to something else: usually using `get()` or its equivalent on a reference to a container instead of the container itself: `&list.get()` instead of `list.get()` +- enum + + `: ` + +## Variables + +- declaration and initialization + + ` := ` + + can shadow previous variables with the same name: `x := 5 { x := 10 debug(x) } debug(x)` prints `10` and then `5`. +- assignment + + `& = ` + * modifies the value: `x := 5 { &x = 10 debug(x) } debug(x)` prints `10` and then `10`. + + ` = ` + * assigns the value returned by `` to the value behind the reference returned by ``. + * if `` returns `, `` has to return `&`. + * this is why `& = ` is the way it is. + + `*** = ` + * same as before, but performs dereferences: `&&&&int` becomes `&int` (minus 3 references because 3 `*`s), so a value of type `int` can be assigned to it. + +## Statements + +- value + + `10`, `true`, `"text"`, `"[]"`, etc +- tuple + + `[ <...>]` +- list + + `[ <...> ...]` +- variable + + `` (if the name of the variable isn't a value or some other kind of statement) +- function call + + `( <...>)` +- function definition + + `fn ( <...>) ` where `` is ` ` +- block + + `{ <...> }` +- if + + `if ` (`if true println("test")`) + + `if else ` (`if false println("test") else println("value was false")`) +- loop + + `loop ` + + if the statement returns a value that matches, the loop will end and return the matched value + + the loop's return type is the match of the return type of the statement +- for loop + + `for ` + + in each iteration, the variable will be initialized with a value from the iterator. + + iterators can be lists, tuples, or functions. + + for function iterators, as long as the returned value matches, the matched value will be used. if the value doesn't match, the loop ends. + + if the statement returns a value that matches, the loop will end and return the matched value + + the loop's return type is the match of the return type of the statement or `[]` (if the loop ends because the iterator ended) +- switch + + `switch { <...> }` + * where `` is ` ` + * if the variable's value is of type ``, `` will be executed. + * if the variables type is included multiple times, only the first match will be executed. + * within the statement of an arm, the variables type is that specified in ``, and not its original type (which may be too broad to work with) + + `switch! { <...> }` + * same as above, but all types the variable could have must be covered + * the additional `[]` in the return type isn't added here since it is impossible not to run the statement of one of the arms. +- match + + `match { <...> }` + * where `` is ` ` + * each arm has a condition statement an an action statement. + * if the value returned by the condition statement matches, the matched value is assigned to the variable and the action statement is executed. + * only the first matching arm will be executed. if no arm was executed, `[]` is returned. +- fixed-indexing + + `.n` where `n` is a fixed number (not a variable, just `0`, `1`, `2`, ...) + + `` must return a tuple or a reference to one. `.n` then refers to the nth value in that tuple. + + for references to a tuple, references to the inner values are returned. +- enum + + `: ` +- type definition + + `type ` (`type Message [string string]`) +- macros + + `!( <...>)` + + `!(mers { })` + * compiles and runs the code at compile-time, then returns the computed value at runtime. + + `!(mers )` or `!(mers "")` + * same as above, but reads code from a file instead + * path can be relative + +## Matching + +- values that don't match + + `[]` + + `false` +- values that match + + `[v]` -> `v` + + `v` -> `v` unless otherwise specified +- invalid + + `[v1 v2]` or any tuple whose length isn't `0` or `1`