Grammar

AST ::= Namespace+

Namespace ::= EnumDecl* StructDecl* Method*

Enum

EnumDecl ::= "enum" uppercase+ '{' EnumMember+ '}'

EnumMember ::= EnumValue '=' ConstValue ';'

EnumValue ::= uppercase+

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 | PointerType | #

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

SimpleType ::= PrimitiveType | StructType

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

IntType ::= "int" | "uint" | "uint8" | "int8"

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

StructType ::= uppercase alphanumeric*

TypeParam ::= "?T" digit

ArrayType ::= '[' Type ']'

PointerType ::= '*' Type

Statements

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

Stmt ::= ( Call ';' ) | whileStmt | ifStmt | forStmt | returnStmt | assignStmt | LocalVarDeclStmt | "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? LValue '=' Expr';'

LocalVarDeclStmt ::= 'local' Type Id ';'


Expressions

LValue ::= Variable | Deref

Expr ::= UnOpTerm (Op UnOpTerm)*

UnOpTerm ::= AddressOf | Deref | Op Term

AddressOf ::= '&' Term

Deref ::= '*' Term

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

Range ::= Expr ".." Expr

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

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

Const

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

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

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)*