Grammar

AST ::= Namespace+

Namespace ::= ExternC* StructDecl* Method*

ExternC ::= "externc" ( MethodDecl | StructDecl) StringConst

Struct

StructDecl ::= "struct" StructType '{' StructMember* '}'

StructMember ::= Type Id ';'

Method

Method ::= MethodDecl StmtBlock

MethodDecl ::= "fn" Id '(' DeclArg* ')' arrow Type

DeclArg ::= Type Id?

Types

Type ::= BasicType | TypeParam | ArrayType

BasicType ::= SimpleType | '(' SubrType ')'

SimpleType ::= PrimitiveType | StructType

PrimitiveType ::= IntType | "float" | "char" | "bool"

IntType ::= "int" | "uint" | "uint8" | "int8" | "uint16" | "int16" | "uint32" | "int32" | "uint64" | "int64"

SubrType ::= '(' Type* ')' arrow Type

StructType ::= uppercase alphanumeric* ('<' Type (',' Type)* '>')? | "#"

TypeParam ::= "?T" digit

ArrayType ::= '[' Type ']'

Statements

StmtBlock ::= '{' Stmt* '}'

Stmt ::= ( Call ';' ) | whileStmt | ifStmt | forStmt | switchStmt | returnStmt | assignStmt | mAssignStmt | "break" ';' | "continue" ';'

whileStmt ::= "while" Expr StmtBlock

forStmt ::= "for" Id "in" Range StmtBlock

ifStmt ::= "if" Expr StmtBlock ("else" StmtBlock)?

Call ::= Variable '(' (Expr (, Expr)*)? ')'

returnStmt ::= "return" Expr? ';'

assignStmt ::= Type? Variable '=' Expr? ';'

mAssignStmt ::= MDirect '=' Expr ';'

switchStmt ::= "switch" Expr '{' caseStmt* '}'

caseStmt ::= "case" ConstValue StmtBlock?

Expressions

Expr ::= UnOpTerm (Op UnOpTerm)*

UnOpTerm ::= Op Term

Term ::= ConstValue | StringConst | Call | '(' Expr ')' | Variable | Lambda | MDirect

Lambda ::= '(' Id (',' Id)* ')' arrow Expr

Range ::= Expr ".." Expr

Variable ::= SimpleVar ('.' Variable)?

SimpleVar ::= Id ('[' Expr ']')*

MDirect ::= '[' Expr ']'

Const

ArrayConstant ::= '[' Expr (',' Expr)* ']'

ConstValue ::= BoolConst | IntConst | BinConst | HexConst | CharConst | FloatConst

Helpers

arrow         ::= "->" | "~>"

lowercase     ::= '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'

uppercase     ::= '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'

digit         ::= '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'

alphanumeric  ::= lowercase | uppercase | digit

Op            ::= "+" | "-" | "*" | "/" | "%" | "<<" | ">>" | "|" | "&" | "^" | "||" | "&&"

Id            ::= lowercase (lowercase | '_' | digit)*