file
file = { declaration } , [ return ] ;
file is referencing:
If the return statement is given, importing the file becomes valid and loads the returned values.
expression
expression = assignement ;
Items referencing expression:
expression is referencing:
assignement
assignement
= identifier ,
{ "[" , expression , "]"
| "." , identifier
} , { ( "=" | "+=" | "-=" | "*=" | "/=" | "%=" ) ,
combiner }
| combiner
;
Items referencing assignement:
assignement is referencing:
Assignements assign the right of the expression to the left identifier, either directly or adds/subtracts/divides/applies the modulo operator.
They evaluate to their new value, which makes this valid syntax: foo = bar += 1
combiner
combiner = equality , { ( "and" | "or" ) , equality } ;
Items referencing combiner:
combiner is referencing:
equality
equality = comparison , { ( "==" | "!=" ) , comparison } ;
Items referencing equality:
equality is referencing:
comparison
comparison = range , { ( ">" | "<" | ">=" | "<=" ) , range } ;
Items referencing comparison:
comparison is referencing:
range
range
= term
| term , ".." , term
| term , ".."
| ".." , term
;
Items referencing range:
range is referencing:
term
term = factor , { ( "+" | "-" ) , factor } ;
Items referencing term:
term is referencing:
factor
factor = unary , { ( "*" | "/" | "%" ) , unary } ;
Items referencing factor:
factor is referencing:
unary
unary = { "-" | "!" } , error_handling ;
Items referencing unary:
unary is referencing:
error_handling
error_handling = { "~" | "?" } , properties ;
Items referencing error_handling:
error_handling is referencing:
!
transforms the given value into an error value.
?
unwraps an error to it's value, or returns the error if it is an error.
properties
properties = primary , { field_access | index | call } ;
Items referencing properties:
properties is referencing:
field_access
field_access = "." , identifier ;
Items referencing field_access:
field_access is referencing:
index
index = "[" , expression , "]" ;
Items referencing index:
index is referencing:
call
call = "(" , [ arguments ] , ")" ;
Items referencing call:
call is referencing:
arguments
arguments = expression , { "," , expression } ;
Items referencing arguments:
arguments is referencing:
primary
primary
= number | string
| identifier | "true"
| "false" | "nil"
| "(" , expression , ")" | block
| map | function
| if | check
| while | for
;
Items referencing primary:
primary is referencing:
number
number = digit , { digit | "_" } , "." ,
{ digit | "_" }- ;
Items referencing number:
number is referencing:
string
string
= '"' , { char } , '"'
| "'" , { char } , "'"
;
Items referencing string:
string is referencing:
Both ' and " can be used to delimit a string. They achieve the same thing.
block
block = "{" , { statement } , "}" , [ "?" ] ;
Items referencing block:
block is referencing:
map
map = "|" , [ map_values ] , "|" ;
Items referencing map:
map is referencing:
There are multiple types of syntax to define values in a map:
- Identifier - value (
| foo = "bar" |
): Assign the string"bar"
to the fieldfoo
. - Same-name identifiers (
| foo |
): Is the same as| foo = foo |
. - Expression - value (
[2 + 3] = foo - 2
): Assignsfoo - 2
to5
.
map_values
map_values = map_value , { "," , map_value } ;
Items referencing map_values:
map_values is referencing:
map_value
map_value
= identifier
| identifier , "=" , expression
| "[" , expression , "]" , "=" , expression
;
Items referencing map_value:
map_value is referencing:
function
function = "fn" , [ "?" ] , "(" , [ parameters ] ,
")" , expression ;
Items referencing function:
function is referencing:
parameters
parameters = identifier , [ "?" ] , { "," , identifier , [ "?" ] } ;
Items referencing parameters:
parameters is referencing:
if
if = "if" , [ "?" ] , "(" , expression , ")" ,
expression , { "else" , "if" , "(" , expression , ")" ,
expression } ,
"else" , expression ;
Items referencing if:
if is referencing:
check
check = "check" , [ "?" ] , "(" , expression , ")" ,
[ "as" , identifier , [ "?" ] ] , expression ,
[ "else" , expression ] ;
Items referencing check:
check is referencing:
while
while = "while" , [ "?" ] , "(" , expression , ")" ,
expression ;
Items referencing while:
while is referencing:
for
for = "for" , [ "?" ] , "(" , identifier , [ "?" ] ,
"in" , expression , ")" , expression ;
Items referencing for:
for is referencing:
identifier
identifier =
( lowercase_letter
| uppercase_letter
| "_"
) ,
{ lowercase_letter
| uppercase_letter
| digit
| "_"
} ;
Items referencing identifier:
identifier is referencing:
lowercase_letter
lowercase_letter
= "a" | "b" | "c" | "d" | "e" | "f" | "g"
| "h" | "i" | "j" | "k" | "l" | "m" | "n"
| "o" | "p" | "q" | "r" | "s" | "t" | "u"
| "v" | "w" | "x" | "y" | "z"
;
Items referencing lowercase_letter:
uppercase_letter
uppercase_letter
= "A" | "B" | "C" | "D" | "E" | "F" | "G"
| "H" | "I" | "J" | "K" | "L" | "M" | "N"
| "O" | "P" | "Q" | "R" | "S" | "T" | "U"
| "V" | "W" | "X" | "Y" | "Z"
;
Items referencing uppercase_letter:
digit
digit
= "1" | "2" | "3" | "4" | "5" | "6" | "7"
| "8" | "9" | "0"
;
Items referencing digit:
statement
statement =
( expression
| "break"
| "continue"
| return
| ev
| declaration
) , ";" ;
Items referencing statement:
statement is referencing:
return
return = "return" , [ expression ] ;
Items referencing return:
return is referencing:
ev
ev = "->" , [ expression ] ;
Items referencing ev:
ev is referencing:
ev
makes the inner-most block that contains the ev-statement evaluate to the given expression. If no ev-statement is reached within a block, the block evaluates to nil
.
declaration
declaration = ( "let" | "const" ) , identifier ,
[ "?" ] , "=" , expression ;
Items referencing declaration:
declaration is referencing: