EOL : '\n' | ';'
Program :
Statement*
Note: some statement can be placed only on the global level, but probably it's simple to accept on parsing and then reject?
Statement :
EOL
| LetStatement
| ExpressionStatement
| FunctionDeclaration
| MacroDeclaration
FunctionDeclaration :
(TBD)
MacroDeclaration :
(TBD)
LetStatement :
'let' LeftVariable ( ':' TypeSpec )? '=' Expression EOL
ExpressionStatement :
Expression EOL
Expression :
LiteralExpression
| VariableExpression
| OperatorExpression
| CallExpression
| PipeExpression
| LambdaExpression
| MacroExpandExpression
| TupleExpression
| TupleIndexExpression
| ReturnExpression
| GroupedExpression
| BlockExpression
| IfExpression
LiteralExpression :
FloatLiteral
| IntegerLiteral
| BooleanLiteral
| StringLiteral
VariableExpression :
Identifier
| "self"
| "now"
OperatorExpression :
UnaryOperatorExpression
| BinaryOperatorExpression
| AssignExpression
UnaryOperatorExpression :
'-' Expression
| '!' Expression
BinaryOperatorExpression :
Expression '+' Expression
| Expression '-' Expression
| Expression '*' Expression
| Expression '/' Expression
| Expression '%' Expression
| Expression '^' Expression
| Expression '==' Expression
| Expression '!=' Expression
| Expression '<' Expression
| Expression '<=' Expression
| Expression '>' Expression
| Expression '>=' Expression
| Expression '||' Expression
| Expression '&&' Expression
TODO: should this be treated as statement?
AssignExpression :
Identifier '=' Expression
CallExpression :
Identifier '(' CallParams? ')' ( '@' DelaySpec )?
CallParams :
Expression ( ',' Expression )* ','?
DelaySpec :
Expression
PipeExpression :
Expression '|>' CallExpression
LambdaExpression :
'|' LambdaParams '|' Expression
LambdaParams :
LambdaArg ( ',' LambdaArg )* ','?
LambdaArg :
Identifier ( ':' TypeSpec )
MacroExpandExpression :
(TBD)
Note: single tuple doesn't allow trailing comma to distingish it from GroupedExpression
TupleExpression :
'(' Expression ',' ')'
| '(' Expression ( ',' Expression )+ ','? ')'
TupleIndexExpression :
(TBD)
ReturnExpression :
'return' Expression
GroupedExpression :
'(' Expression ')'
BlockExpression :
'{' Statement* Expression? '}'
Note: Expression
is probably needed to handle when there's no linebreak like the following case. But, this can be more nicer.
{ 10 }
{ let x = 10
x * 20 }
IfExpression :
'if' '(' Expression ')' Expression ( 'else' Expression )?