-- programs entrypoints Module; Module . Module ::= [Binding] ; BindingDeclaration . Binding ::= Declaration; BindingDefinition . Binding ::= Definition; BindingPragma . Binding ::= "{#" Pragma "#}"; -- BindingComment . Binding ::= Comment; DeclarationNamed . Declaration ::= Name ":" Type; DeclarationAnonymous . Declaration ::= Type; DefinitionNamed . Definition ::= Name "=" Expression; DefinitionAnonymous . Definition ::= Expression; TypeName . Type ::= Name; TypeApplication . Type ::= Type Type; TypeAbstraction . Type ::= Type "->" Type; TypeImplicit . Type ::= "{{" [Declaration] "}}"; TypeRecord . Type ::= "{" [Declaration] "}"; TypeAlternative . Type ::= "[" [Declaration] "]"; TypeParens . Type ::= "(" Type ")"; -- TODO: Do I want wildcards to be stored separately in the AST from -- non-wildcards? Wilcards are identifiers that start with a -- lower-case letter. token Name ((letter | '_' | '\'') (letter | digit | '.' | '-' | '_' | '\'')*); -- Perhaps not the best rule. Pragmas are basically comments, but I -- *do* want them to appear in the AST. Pragma . Pragma ::= [ Name ]; -- TODO: We are using separators because we cannot simply use newlines -- as separators because it would disallow breaking up bindings across -- multiple lines. What we really want is some sort of non-increasing -- indentation level support. So that can correctly parse e.g.: -- id -- = x -- -> x separator Binding ","; separator Declaration ","; separator Definition ","; separator nonempty Type ","; separator nonempty Name " "; -- TODO: Does not support my idea of `--` marking the beginning of a -- comment *block* which is terminated when the level of indentation -- matches the comment start marker. -- Comment . Comment ::= "--" [Name]; -- layout "--"; -- layout "->"; comment "--"; comment "{-" "-}"; -- Only difference from types is that expression do not contain -- declarations but only definition ExpressionName . Expression ::= Name; ExpressionLiteral . Expression ::= NumericLiteral; ExpressionApplication . Expression ::= Expression Expression; ExpressionAbstraction . Expression ::= Expression "->" Expression; ExpressionImplicit . Expression ::= "{{" Module "}}"; ExpressionRecord . Expression ::= "{" Module "}"; ExpressionAlternative . Expression ::= "[" Module "]"; ExpressionParens . Expression ::= "(" Expression ")"; token NumericLiteral ((digit+ '.'? digit*) | (digit* '.'? digit+) ('e' digit+)?) -- -- programs ------------------------------------------------ -- entrypoints Prog ; -- Program. Prog ::= [TopDef] ; -- FnDef. TopDef ::= Type Ident "(" [Arg] ")" Blk ; -- separator nonempty TopDef "" ; -- Argument. Arg ::= Type Ident; -- separator Arg "," ; -- -- statements ---------------------------------------------- -- Block. Blk ::= "{" [Stmt] "}" ; -- separator Stmt "" ; -- Empty. Stmt ::= ";" ; -- BStmt. Stmt ::= Blk ; -- Decl. Stmt ::= Type [Item] ";" ; -- NoInit. Item ::= Ident ; -- Init. Item ::= Ident "=" Expr ; -- InitObj. Item ::= Ident "=" "new" Constructor ; -- separator nonempty Item "," ; -- Ass. Stmt ::= Expr5 "=" Expr ";" ; -- Incr. Stmt ::= Ident "++" ";" ; -- Decr. Stmt ::= Ident "--" ";" ; -- Ret. Stmt ::= "return" Expr ";" ; -- VRet. Stmt ::= "return" ";" ; -- Cond. Stmt ::= "if" "(" Expr ")" Stmt ; -- CondElse. Stmt ::= "if" "(" Expr ")" Stmt "else" Stmt ; -- While. Stmt ::= "while" "(" Expr ")" Stmt ; -- For. Stmt ::= "for" "(" Type Ident ":" Expr ")" Stmt ; -- SExp. Stmt ::= Expr ";" ; -- TypeCon. Constructor ::= Type ; -- ArrayCon. Constructor ::= Constructor "[" Expr "]" ; -- Indx. Index ::= "[" Expr "]" ; -- -- Types --------------------------------------------------- -- Int. Type ::= "int" ; -- Doub. Type ::= "double" ; -- Bool. Type ::= "boolean" ; -- Void. Type ::= "void" ; -- Array. Type ::= Type "[]" ; -- internal String. Type ::= "string" ; -- internal Fun. Type ::= Type "(" [Type] ")" ; -- separator Type "," ; -- -- Expressions --------------------------------------------- -- EVar. Expr6 ::= Ident ; -- ELitInt. Expr6 ::= Integer ; -- ELitDoub. Expr6 ::= Double; -- ELitTrue. Expr6 ::= "true" ; -- ELitFalse. Expr6 ::= "false" ; -- EApp. Expr6 ::= Ident "(" [Expr] ")" ; -- EString. Expr6 ::= String ; -- Dot. Expr6 ::= Expr6 "." Ident ; -- EIndex. Expr6 ::= Expr6 Index; -- Neg. Expr5 ::= "-" Expr6 ; -- Not. Expr5 ::= "!" Expr6 ; -- EMul. Expr4 ::= Expr4 MulOp Expr5 ; -- EAdd. Expr3 ::= Expr3 AddOp Expr4 ; -- ERel. Expr2 ::= Expr2 RelOp Expr3 ; -- EAnd. Expr1 ::= Expr2 "&&" Expr1 ; -- EOr. Expr ::= Expr1 "||" Expr ; -- internal EAnn. Expr ::= "{-" Type "-}" Expr ; -- coercions Expr 6 ; -- separator Expr "," ; -- -- operators ----------------------------------------------- -- Plus. AddOp ::= "+" ; -- Minus. AddOp ::= "-" ; -- Times. MulOp ::= "*" ; -- Div. MulOp ::= "/" ; -- Mod. MulOp ::= "%" ; -- LTH. RelOp ::= "<" ; -- LE. RelOp ::= "<=" ; -- GTH. RelOp ::= ">" ; -- GE. RelOp ::= ">=" ; -- EQU. RelOp ::= "==" ; -- NE. RelOp ::= "!=" ; -- -- comments ------------------------------------------------ -- comment "#" ; -- comment "//" ; -- comment "/*" "*/" ;