grammar plsm; module: MODULE identifier ';' moduleImport* moduleStmt*; moduleImport: IMPORT importName ';'; importName: identifier ('/' identifier)*; moduleStmt: let | fnDecl | fnDef | traitDef | typeDef; traitDef: TRAIT identifier '=' identifier ';' | TRAIT identifier '=' '{' (fnDecl)* '}' ';'; typeDef: TYPE identifier '=' type ';' | TYPE identifier '=' ('(' fnDefArgs ')')? '{' (fnDecl | fnDef)* '}' ';'; fnDef: FN identifier '[' fnDefArgs? ']' type '=' expr ';'; fnDefArgs: identifier type (',' identifier type)*; fnDecl: FN identifier '[' fnDeclArgs? ']' type ';'; fnDeclArgs: identifier? type (',' identifier? type)*; let: LET identifier type? '=' expr ';'; exprStmt: expr ';'; type: type1; // novisit type1: type0 | '(' type ')' | '(' tupleTypeList ')' // tuple | '[' typeList? ']' '->' type; // closure type0: identifier | identifier '{' typeList '}'; // generic tupleTypeList: type (',' type)+; typeList: type (',' type)*; expr: expr3; // novisit expr3: expr2 | '[' identifierList? ']' '->' expr // closure | '{' blockStmt* (expr ';') '}'; expr2: expr1 | expr2 operator expr1; // binary expr expr1: expr0 | operator expr0; // unary expr expr0: literal | identifier | expr0 '[' exprList? ']' // fn call | '(' expr ')' | '(' tupleExprList ')' // tuple | expr0 '.' identifier; // property accessor blockStmt: let | exprStmt | fnDef; tupleExprList: expr (',' expr)+; exprList: expr (',' expr)*; identifierList: identifier (',' identifier)*; literal: NULL='null' | INT_LIT | FLOAT_LIT; operator: '=' | '->' | OPERATOR; identifier: keyword | IDENTIFIER; keyword: BINOP | FN | IMPORT | LET | MODULE | NATIVE | TRAIT | TYPE | UNOP; INT_LIT: [0-9]+ | '0x' [0-9a-fA-F]+ | '0o' [0-7]+ | '0b' [01]+; FLOAT_LIT: [0-9]+ '.' | [0-9]* '.' [0-9]+; OPERATOR: ('+'|'-'|'*'|'/'|'%'|'!'|'&'|'$'|'ยง'|'|'|'='|'<'|'>'|'?'|'~'|'#'|':'|'^'|'\\'|'.')+; BINOP: 'binop'; FN: 'fn'; IMPORT: 'import'; LET: 'let'; MODULE: 'module'; NATIVE: 'native'; TRAIT: 'trait'; TYPE: 'type'; UNOP: 'unop'; IDENTIFIER: [a-zA-Z_] [a-zA-Z0-9_]*; WHITESPACE: [ \r\n\t]+ -> skip;