Root: Item*
Item: LetItem | TypeItem
LetItem: let
Ident Arg* (:
Type)? =
Expr
Arg: Ident | (
Ident :
Type )
TypeItem: type
Ident TypeArg* =
Type
TypeArg: Ident (TODO: add type bounds?)
Type: TypePath | Fn | Record | Enum | Tuple
TypePath: Ident (.
Ident)* TypeArg*
Fn: Type ->
Type
Record: {
(Ident :
Type ,
)* }
)
Enum: EnumVar (|
EnumVar)* (TODO: allow empty enums?)
EnumVar: Ident Type?
Tuple: (
(Type ,
)* )
Expr: Call | Binop | Unary | TupleExpr | RecordExpr | Lambda | Index | IfElse | For | While | Block | Lit | Update | Paren
ExprPath: Ident (.
Ident)*
ExprParened: ExprPath | Block | Lit | Paren
Call: ExprPath ExprParened*
Index: ExprParened [
Expr ]
Binop, Unary, use pratt parsing with corresponding operator precedence
Block: {
ExprStmt* }
IfElse: if
Expr then
Expr (else
Expr)?
For: for
Ident in Expr Block
While: while
Expr Block
Lambda: \
Ident* =
Expr
TupleExpr: (
(Expr ,
)* )
RecordExpr: {
(Ident :
Expr ,
)* }
Update: ExprPath :=
Expr
Paren: (
Expr )
ExprStmt: Expr | Item
Lit: IntLit | FlaotLit | StringLit | true
| false
(define bool as an enum?)
Ident: refer to unicode-xid