mirror of
				https://github.com/Dummi26/mers.git
				synced 2025-10-31 03:45:26 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			142 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Markdown
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			142 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Markdown
		
	
	
		
			Executable File
		
	
	
	
	
| # 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>/<...>)`
 | |
| - 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>`.
 | |
|     * if `<statement_right>` returns `<type>`, `<statement_left>` has to return `&<type>`.
 | |
|     * 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.
 | |
| - 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"`
 | |
| 
 | |
| ## 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> <...>)`
 | |
|   + `<fn_name>(<arg1>, <arg2>, <...>)`
 | |
|   + `<arg1>.<fn_name>(<arg2>, <...>)`
 | |
| - 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
 | |
|   + `for <assign_to> <iterator> <statement>`
 | |
|   + 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 <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>`.
 | |
|     * 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
 | |
|   + `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.
 | |
|     * 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`
 | 
