mirror of
https://github.com/Dummi26/mers.git
synced 2025-10-24 02:06:26 +02:00
6.1 KiB
Executable File
6.1 KiB
Executable File
mers syntax cheat sheet
Types
boolintfloatstring- 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
trueorfalse
- int
- decimal:
2,+2,-5,0, ...
- decimal:
- 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:
.5would be ambiguous following tuples, so is not supported.
- decimal:
- string
"my string"(double quotes)"it's called \"<insert name>\""(escape inner double quotes with backslash)- all escape sequences
\"double quote character\\backslash character\nnewline\rcarriage return\ttab\0null
- 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()
- returned by the builtin function
- 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 oflist.get()
- to a variable:
- 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)prints10and then5.
- assignment
&<var_name> = <statement>- modifies the value:
x := 5 { &x = 10 debug(x) } debug(x)prints10and then10.
- modifies the value:
<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.
- assigns the value returned by
***<statement_left> = <statement_right>- same as before, but performs dereferences:
&&&&intbecomes&int(minus 3 references because 3*s), so a value of typeintcan be assigned to it.
- same as before, but performs dereferences:
- destructuring
- values can be destructured into tuples or lists (as of right now):
[a, b] := [10, "some text"]is effectively the same asa := 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)
- where
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.
- where
- fixed-indexing
<statement>.nwherenis a fixed number (not a variable, just0,1,2, ...)<statement>must return a tuple or a reference to one.<statement>.nthen 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]->vv->vunless otherwise specified
- invalid
[v1 v2]or any tuple whose length isn't0or1