Expressions
Every expression has a type that can be uniquely determined from the expression itself, provided the expression is well-formed and well-typed.
Expression ::=
| Literal
| Id
| OperatorExpr
| FunctionCall
| LabeledExpr
| LetExpr
| QuantifierExpr
| "(" Expression ")"
Literal expressions
Literal ::=
| false | true
| 0 | 1 | 2 | ...
| "|" LiteralIdentifier ":" Type "|"
The literals false and true have the built-in type bool.
Natural numbers have the built-in type int. They are unbounded integers.
A custom literal is an identifier-like token with a given type. TODO: description
Identifier expressions
Id ::=
Identifier
The given identifier denotes a variable in scope, specifically
in-, inout-, or out-parameter
mutable or immutable local variable
bound variable
Operator expressions
OperatorExpr ::=
| if Expression Expression else Expression
| Expression BinaryOp Expression
| UnaryOp Expression
BinaryOp ::=
| "<==>"
| "==>" | "<=="
| "&&" | "||"
| "==" | "!=" | "<" | "<=" | ">=" | ">"
| "+" | "-"
| "*" | "div" | "mod"
UnaryOp ::=
| "!" | "-"
Function calls
FunctionCall ::=
Identifier "(" Expression*, ")"
TODO: description
Labeled expressions
LabeledExpr ::=
Identifier ":" Expression
The Expression parses as far as possible.
TODO: description
Let expressions
LetExpr ::=
val Identifier ":=" Expression Expression
Note that there is no punctuation between the two expressions.
TODO: description
Quantifier expressions
QuantifierExpr ::=
( forall | exists ) Identifier ":" Type
Pattern*
Expression
Pattern ::=
pattern Expression+,
TODO: description