277 lines
5.4 KiB
Plaintext
277 lines
5.4 KiB
Plaintext
|
grammar Meow;
|
||
|
|
||
|
file
|
||
|
: importStatement* declaration* EOF
|
||
|
;
|
||
|
|
||
|
importStatement
|
||
|
: ImportKeyword importpath=StringLiteral (AsKeyword importname=Identifier)? ';'
|
||
|
;
|
||
|
|
||
|
declaration
|
||
|
: function ';'?
|
||
|
| constraintDeclaration ';'?
|
||
|
| structDeclaration ';'?
|
||
|
| enumDeclaration ';'?
|
||
|
| tupleDeclaration ';'?
|
||
|
| typeAlias ';'?
|
||
|
;
|
||
|
|
||
|
structDeclaration
|
||
|
: StructKeyword name=Identifier (genericParameters constraint*)? structType
|
||
|
;
|
||
|
|
||
|
enumDeclaration
|
||
|
: EnumKeyword name=Identifier (genericParameters constraint*)? enumType
|
||
|
;
|
||
|
|
||
|
tupleDeclaration
|
||
|
: TupleKeyword name=Identifier (genericParameters constraint*)? tupleType
|
||
|
;
|
||
|
|
||
|
typeAlias
|
||
|
: TypeKeyword name=Identifier genericParameters? '=' typeReference
|
||
|
;
|
||
|
|
||
|
|
||
|
constraintDeclaration
|
||
|
: ConstraintKeyword name=Identifier types+=Identifier+ '{' constraintRule* '}'
|
||
|
;
|
||
|
|
||
|
constraintRule
|
||
|
: embedConstraintRule
|
||
|
| functionConstraintRule
|
||
|
;
|
||
|
|
||
|
embedConstraintRule
|
||
|
: ConstraintKeyword name=Identifier types+=typeReference+ ';'
|
||
|
;
|
||
|
|
||
|
functionConstraintRule
|
||
|
: name=Identifier constraintFunctionParameters functionReturn? ';'
|
||
|
;
|
||
|
|
||
|
constraintFunctionParameters
|
||
|
: '(' (typeReference (',' typeReference)*)? ')'
|
||
|
;
|
||
|
|
||
|
function
|
||
|
: attribute* pub=PubKeyword? FnKeyword name=Identifier functionParameters functionReturn? functionBody
|
||
|
| attribute* pub=PubKeyword? FnKeyword name=Identifier genericParameters functionParameters functionReturn? constraint* functionBody
|
||
|
;
|
||
|
|
||
|
|
||
|
attribute
|
||
|
: '[' name=Identifier ('(' (attributeValue (',' attributeValue)*)? ')')? ']'
|
||
|
;
|
||
|
|
||
|
attributeValue
|
||
|
: literal
|
||
|
| id=Identifier
|
||
|
;
|
||
|
|
||
|
literal
|
||
|
: stringLiteral
|
||
|
| numericLiteral
|
||
|
| boolLiteral
|
||
|
| characterLiteral
|
||
|
;
|
||
|
stringLiteral: val=StringLiteral;
|
||
|
numericLiteral: val=NumericLiteral;
|
||
|
boolLiteral: val=BoolLiteral;
|
||
|
characterLiteral: val=CharacterLiteral;
|
||
|
|
||
|
genericParameters
|
||
|
: '<' (name+=Identifier (',' name+=Identifier)*) '>'
|
||
|
;
|
||
|
|
||
|
|
||
|
functionParameters
|
||
|
: '(' (functionParameter (',' functionParameter)*)? ')'
|
||
|
;
|
||
|
|
||
|
functionParameter
|
||
|
: typeReference name=Identifier
|
||
|
;
|
||
|
|
||
|
functionReturn
|
||
|
: '->' (typeReference (',' typeReference)*)
|
||
|
;
|
||
|
|
||
|
constraint
|
||
|
: WhereKeyword name=Identifier typenames+=Identifier+
|
||
|
;
|
||
|
|
||
|
functionBody
|
||
|
: '{' statement* expression? '}'
|
||
|
;
|
||
|
|
||
|
|
||
|
typeReference
|
||
|
: nonPointerTypeReference pointer='*'?
|
||
|
;
|
||
|
|
||
|
nonPointerTypeReference
|
||
|
: typeName
|
||
|
| arrayType
|
||
|
| tupleType
|
||
|
| StructKeyword structType
|
||
|
| EnumKeyword enumType
|
||
|
;
|
||
|
|
||
|
typeName
|
||
|
: (importName=Identifier ':')? name+=Identifier ('<' genericType+=typeName (',' genericType+=typeName)* '>')? ('@' name+=Identifier)*
|
||
|
;
|
||
|
|
||
|
arrayType
|
||
|
: '[' typeReference (';' length=NumericLiteral)? ']'
|
||
|
;
|
||
|
|
||
|
tupleType
|
||
|
: '(' typeReference (',' typeReference)* ')'
|
||
|
;
|
||
|
|
||
|
structType
|
||
|
: '{' structMember* '}'
|
||
|
;
|
||
|
|
||
|
structMember
|
||
|
: typeReference name=Identifier ';'
|
||
|
;
|
||
|
|
||
|
enumType
|
||
|
: '{' enumMember (',' enumMember)* ','? '}'
|
||
|
;
|
||
|
|
||
|
enumMember
|
||
|
: name=Identifier ('(' typeReference ')')?
|
||
|
;
|
||
|
|
||
|
|
||
|
statement
|
||
|
: breakStatement
|
||
|
| continueStatement
|
||
|
| returnStatement
|
||
|
| loopStatement
|
||
|
| expressionStatement
|
||
|
;
|
||
|
|
||
|
breakStatement
|
||
|
: BreakKeyword label=Identifier? ';'
|
||
|
;
|
||
|
continueStatement
|
||
|
: ContinueKeyword label=Identifier? ';'
|
||
|
;
|
||
|
returnStatement
|
||
|
: ReturnKeyword expression? ';'
|
||
|
;
|
||
|
loopStatement
|
||
|
: LoopKeyword '{' statement* '}'
|
||
|
| LoopKeyword condition=expression '{' statement* '}'
|
||
|
| LoopKeyword init=expression? ';' condition=expression? ';' increment=expression? '{' statement* '}'
|
||
|
;
|
||
|
|
||
|
expressionStatement
|
||
|
: expression ';'
|
||
|
;
|
||
|
|
||
|
|
||
|
/*
|
||
|
todo: use C operator precedence: https://en.cppreference.com/w/c/language/operator_precedence
|
||
|
|
||
|
binary operators:
|
||
|
== != > >= < <=
|
||
|
||
|
||
|
&&
|
||
|
+ -
|
||
|
* / %
|
||
|
&
|
||
|
|
|
||
|
^
|
||
|
<<
|
||
|
>>
|
||
|
|
||
|
unary operators:
|
||
|
+
|
||
|
-
|
||
|
~
|
||
|
!
|
||
|
|
||
|
|
||
|
assignment:
|
||
|
=
|
||
|
+=
|
||
|
-=
|
||
|
/=
|
||
|
*=
|
||
|
%=
|
||
|
&=
|
||
|
|=
|
||
|
^=
|
||
|
<<=
|
||
|
>>=
|
||
|
|
||
|
|
||
|
*/
|
||
|
expression
|
||
|
: addExpression
|
||
|
;
|
||
|
|
||
|
addExpression
|
||
|
: multExpression ((op='+'|op='-') multExpression)*
|
||
|
;
|
||
|
|
||
|
multExpression
|
||
|
: terminalExpression ((op='*'|op='/'|op='%') terminalExpression)*
|
||
|
;
|
||
|
|
||
|
terminalExpression
|
||
|
: literal
|
||
|
| structConstructor
|
||
|
| arrayConstructor
|
||
|
| enumConstructor
|
||
|
| functionCall
|
||
|
| ifExpression
|
||
|
| switchExpression
|
||
|
| blockExpression
|
||
|
| parenthesisExpression
|
||
|
;
|
||
|
|
||
|
///////////////////////////
|
||
|
|
||
|
ImportKeyword: 'import';
|
||
|
AsKeyword: 'as';
|
||
|
PubKeyword: 'pub';
|
||
|
FnKeyword: 'fn';
|
||
|
WhereKeyword: 'where';
|
||
|
ConstraintKeyword: 'constraint';
|
||
|
StructKeyword: 'struct';
|
||
|
EnumKeyword: 'enum';
|
||
|
TupleKeyword: 'tuple';
|
||
|
TypeKeyword: 'type';
|
||
|
BreakKeyword: 'break';
|
||
|
ContinueKeyword: 'continue';
|
||
|
ReturnKeyword: 'return';
|
||
|
LoopKeyword: 'loop';
|
||
|
|
||
|
|
||
|
|
||
|
// start with letters (upper or lower case) followed by any alphanumeric symbol
|
||
|
Identifier: [a-zA-Z_][a-zA-Z_0-9]*;
|
||
|
|
||
|
|
||
|
|
||
|
NumericLiteral: DecimalNumberLiteral /*| HexadecimalNumberLiteral | OctalNumberLiteral | BinaryNumberLiteral*/;
|
||
|
|
||
|
fragment DecimalNumberLiteral: DecimalNumberPart ('.' DecimalNumberPart)? | '.' DecimalNumberPart;
|
||
|
fragment DecimalNumberPart: [0-9] [0-9_]*;
|
||
|
BoolLiteral: 'true' | 'false' ;
|
||
|
CharacterLiteral: '\'' (CharacterEscape | ~['\\]) '\'';
|
||
|
fragment CharacterEscape: '\\\'' | '\\\\';
|
||
|
StringLiteral: '"' (StringEscape | ~[\\"])*? '"';
|
||
|
fragment StringEscape: '\\"' | '\\\\';
|
||
|
|
||
|
// comments and white space -> ignored
|
||
|
BLOCK_COMMENT: '/*' .*? '*/' -> channel(HIDDEN);
|
||
|
LINE_COMMENT: '//' ~[\n]* -> channel(HIDDEN);
|
||
|
WS: [ \t\r\n\f]+ -> channel(HIDDEN);
|