summaryrefslogtreecommitdiff
path: root/src/parser/grammar.peg
blob: 4bb1454c6b60511f06996a31da44896f6382305c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
Program := Statement* PROGRAM_END

Statement := Enum | Interface | Module | Expression

Module := 'EVERYTHING' _ 'CHANGED' _ 'WHEN' _ name=PASCAL_CASE _ 'EXISTS' _ SCOPE_START _ body=ModuleBody _ SCOPE_END
ModuleBody := Constructor? _? Declaration*
Constructor := 'PRACTICALLY' _ 'IMPOSSIBLE' _ 'TO' _ 'HAVE' _ module=Identifier _ 'WITHOUT' _ args=ArgList _ SCOPE_START _ body=FunctionBody _ SCOPE_END

Expression := FunctionCall | BinaryExpression | UnaryOperation | Literal | Declaration

FunctionCall := name=Identifier _ 'OF' _ args={{Expression _? COMMA _?}* Expression}

BinaryExpression := left=Expression op=BinaryOperation right=Expression
BinaryOperation := ArithmeticOperation | ComparisonOperation | BooleanOperation
ArithmeticOperation := '\+' | '\-' | '/' | '\%' | '\*\*' | '\*' | '>>' | '<<'
ComparisonOperation := '<' | '>' | '<=' | '>='
BooleanOperation := '||' | '|' | '&&' | '&'

Declaration := VarDeclaration | FunctionDeclaration
VarDeclaration := 'EXPERTS' _ 'CLAIM' _ var=CAMEL_CASE _ 'TO' _ 'BE' _ Type _ val={option=OptionMatch | 'OF' _ expr=Expression}
OptionMatch := 'WHO' _ 'IS' _ 'DATING' _ SCOPE_START _ {some=SomeMatch _ none=NoneMatch} | {none=NoneMatch _ some=SomeMatch} _ SCOPE_END
SomeMatch := 'Someone' LPAREN name=Identifier RPAREN _ 'SO' _ expr=Expression 
NoneMatch := 'Nobody' _ 'SO' _ expr=Expression

Literal := String | Integer | Float | StructInit | Identifier
String := '(["\'])(?:(?=(\\?))\2.)*?\1'
Integer := '^-?0*\d+$'
Float := '^-?\d+(\.\d+)?$'

UnaryOperation := PrefixOperation Expression | Expression PostfixOperation
PrefixOperation := '!' | '~'
PostfixOperation := LBRACKET index=POSITIVE_INT RBRACKET

StructInit := 'STUFF' _ 'MADE' _ 'OF' _ SCOPE_START _ init=Declaration* _ SCOPE_END

Type := name={PASCAL_CASE} | {name=PASCAL_CASE _ generic=Generic} | {tupleType=Type _ LBRACKET _ tupleLength=POSITIVE_INT _ RBRACKET} | union={Type _ 'OR' _ Type}
Generic := LPAREN _? generic={{Type _? COMMA _?}* Type} RPAREN

FunctionDeclaration := FunctionSignature _ SCOPE_START _ body=FunctionBody _ SCOPE_END
FunctionBody := {Expression | ReturnStatement}*
FunctionSignature := 'DISCOVER' _ 'HOW' _ 'TO' _ name=CAMEL_CASE _ 'WITH' _ args=ArgList _ 'GIVES' _ 'YOU' _ return=Type
ArgList := args={{type=Type name=CAMEL_CASE COMMA _?}* type=Type name=CAMEL_CASE}

ReturnStatement := 'SHOCKING' _ 'DEVELOPMENT' _ Expression

Interface := 'STUFF' _ 'OF' _ name=PASCAL_CASE _ 'LOOKS' _ 'LIKE' SCOPE_START methods={ FunctionSignature* }

Enum := 'ONLY' _ 'OPTIONS' _ 'OF' name=PASCAL_CASE _ 'ARE' _ SCOPE_START _ options=EnumBody* _ SCOPE_END
EnumBody := name=Identifier COMMA

Identifier := '[a-zA-Z][\w\d|\.]*'

SCOPE_START := 'RUMOR' _ 'HAS' _ 'IT'
SCOPE_END := 'END' _ 'OF' _ 'STORY'
PROGRAM_END := 'PLEASE' _ 'LIKE' _ 'AND' _ 'SUBSCRIBE'
PASCAL_CASE := '[A-Z][\w\d]*'
CAMEL_CASE := '[a-z][\w\d]*'

LPAREN := '\('
RPAREN := '\)'
LBRACKET := '\['
RBRACKET := '\]'
COMMA := ','

POSITIVE_INT := '^[1-9][0-9]*$'

_ := '\s'