mers/old/docs/syntax_cheat_sheet.md

142 lines
6.1 KiB
Markdown
Raw Normal View History

2023-05-24 23:35:42 +02:00
# mers syntax cheat sheet
## Types
- `bool`
- `int`
- `float`
- `string`
- tuple: `[<type1> <type2> <type3> <...>]`
- list: `[<type> ...]`
- function: `fn(<input-output-map>)` (might change? depends on implementation of generics)
- thread: `thread(<return_type>)`
- reference: `&<type>` or `&(<type1>/<type2>/<...>)`
2023-05-24 23:35:42 +02:00
- enum: `EnumName(<type>)`
- one of multiple types: `<type1>/<type2>/<type3>`
## 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 \"<insert name>\""` (escape inner double quotes with backslash)
+ all escape sequences
* `\"` double quote character
* `\\` backslash character
* `\n` newline
* `\r` carriage return
* `\t` tab
* `\0` null
- tuple
+ `[<val1> <val2> <val3> <...>]`
- list
+ `[<val1> <val2> <val3> <...> ...]` (like tuple, but `...]` instead of `]`)
- function
+ `(<arg1> <arg2> <arg3> <...>) <statement>` where `<argn>` is `<namen> <typen>`.
- thread
+ returned by the builtin function `thread()`
- reference
+ to a variable: `&<varname>`
+ 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
+ `<EnumName>: <statement>`
## Variables
- declaration and initialization
+ `<var_name> := <statement>`
+ can shadow previous variables with the same name: `x := 5 { x := 10 debug(x) } debug(x)` prints `10` and then `5`.
- assignment
+ `&<var_name> = <statement>`
* modifies the value: `x := 5 { &x = 10 debug(x) } debug(x)` prints `10` and then `10`.
+ `<statement_left> = <statement_right>`
* assigns the value returned by `<statement_right>` to the value behind the reference returned by `<statement_left>`.
2023-06-04 22:15:09 +02:00
* if `<statement_right>` returns `<type>`, `<statement_left>` has to return `&<type>`.
2023-05-24 23:35:42 +02:00
* this is why `&<var_name> = <statement>` is the way it is.
+ `***<statement_left> = <statement_right>`
* 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.
2023-05-26 20:18:09 +02:00
- destructuring
+ values can be destructured into tuples or lists (as of right now):
+ `[a, b] := [10, "some text"]` is effectively the same as `a := 10, b := "some text"`
2023-05-24 23:35:42 +02:00
## Statements
- value
+ `10`, `true`, `"text"`, `"[]"`, etc
- tuple
+ `[<statement1> <statement2> <...>]`
- list
+ `[<statement1> <statement2> <...> ...]`
- variable
+ `<var_name>` (if the name of the variable isn't a value or some other kind of statement)
- function call
+ `<fn_name>(<arg1> <arg2> <...>)`
2023-05-25 00:25:50 +02:00
+ `<fn_name>(<arg1>, <arg2>, <...>)`
+ `<arg1>.<fn_name>(<arg2>, <...>)`
2023-05-24 23:35:42 +02:00
- function definition
+ `fn <fn_name>(<arg1> <arg2> <...>) <statement>` where `<argn>` is `<namen> <typen>`
- block
+ `{ <statement1> <statement2> <...> }`
- if
+ `if <condition> <statement>` (`if true println("test")`)
+ `if <condition> <statement> else <statement>` (`if false println("test") else println("value was false")`)
- loop
+ `loop <statement>`
+ 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
2023-05-26 20:18:09 +02:00
+ `for <assign_to> <iterator> <statement>`
2023-05-24 23:35:42 +02:00
+ 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
2023-05-26 20:18:09 +02:00
+ `switch <value> { <arm1> <arm2> <...> }`
* where `<armn>` is `<typen> <assign_to> <statementn>`
* if the variable's value is of type `<typen>`, `<statementn>` will be executed with `<value>` assigned to `<assign_to>`.
2023-05-24 23:35:42 +02:00
* 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 `<typen>`, and not its original type (which may be too broad to work with)
+ `switch! <var_name> { <arm1> <arm2> <...> }`
* 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
2023-05-26 20:18:09 +02:00
+ `match { <arm1> <arm2> <...> }`
* where `<armn>` is `<(condition) statement> <assign_to> <(action) statement>`
* each arm has a condition statement, something that the matched value will be assigned to, and an action statement.
* if the value returned by the condition statement matches, the matched value is assigned to `<assign_to>` and the action statement is executed.
2023-05-24 23:35:42 +02:00
* only the first matching arm will be executed. if no arm was executed, `[]` is returned.
- fixed-indexing
+ `<statement>.n` where `n` is a fixed number (not a variable, just `0`, `1`, `2`, ...)
+ `<statement>` must return a tuple or a reference to one. `<statement>.n` then refers to the nth value in that tuple.
+ for references to a tuple, references to the inner values are returned.
- enum
+ `<EnumName>: <statement>`
- type definition
+ `type <name> <type>` (`type Message [string string]`)
- macros
+ `!(<macro_type> <...>)`
+ `!(mers { <code> })`
* compiles and runs the code at compile-time, then returns the computed value at runtime.
+ `!(mers <file_path>)` or `!(mers "<file path with spaces and \" double quotes>")`
* 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`