Skip to content

Commit

Permalink
Enum (#11)
Browse files Browse the repository at this point in the history
Remove some unused/broken features and add AST nodes for
pattern matching. Remove 'DefId' field from types that don't have Decl nodes.
  • Loading branch information
andy-byers authored Jul 6, 2024
1 parent 7906475 commit 0a8f670
Show file tree
Hide file tree
Showing 36 changed files with 3,766 additions and 2,119 deletions.
223 changes: 124 additions & 99 deletions GRAMMER.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,145 +4,170 @@
** use a tool to validate this...**

## Statements
```
Stmt ::= ExprStmt | WhileLoop | DoWhileLoop |
ForLoop | IfElse | Declaration |
Block .
Chunk ::= {Stmt [";"]} [LastStmt [";"]] .
Block ::= "{" Chunk "}" .
LastStmt ::= "return" [Expr] | "continue" | "break" .
ExprStmt ::= Operand "=" Expr | Call | Match .
```ebnf
Stmt = ExprStmt | WhileStmt | DoWhileStmt |
ForStmt | IfElse | Declaration |
Block .
Chunk = {Stmt [";"]} [LastStmt [";"]] .
Block = "{" Chunk "}" .
LastStmt = "return" [Expr] | "continue" | "break" .
ExprStmt = Operand "=" Expr | Call | Match .
```

### Control flow
```
IfElse ::= "if" Expr Block [{"else" IfElse} | "else" Block] .
WhileLoop ::= "while" Expr Block .
DoWhileLoop ::= "do" Block "while" Expr .
ForLoop ::= ForIn | ForNum .
ForIn ::= "for" name "in" Expr Block .
ForNum ::= "for" name "=" Expr "," Expr ["," Expr] Block .
Match ::= "match" Expr MatchBody .
MatchBody ::= "{" {MatchArm ","} MatchArm "}" .
MatchClause ::= Expr "=>" MatchArm .
MatchArm ::= Expr | Block .
```ebnf
IfElse = "if" Expr Block [{"else" IfElse} | "else" Block] .
WhileStmt = "while" Expr Block .
DoWhileStmt = "do" Block "while" Expr .
ForStmt = ForIn | ForNum .
ForIn = "for" name "in" Expr Block .
ForNum = "for" name "=" Expr "," Expr ["," Expr] Block .
```

## Declarations
## Pattern matching
```ebnf
MatchExpr = "match" Expr MatchBody .
MatchBody = "{" {MatchArm ","} MatchArm "}" .
MatchClause = Pattern "=>" MatchArm .
MatchArm = Expr | Block .
```
Declaration ::= VarDecl | FunctionDecl |
ClassDecl | EnumDecl | TypeDecl .
VarDecl ::= "let" name [":" Type] "=" Expr .
TypeDecl ::= "type" name [TypeParam] "=" Type .
TypeParam ::= "[" {name ","} name "]" .

## Paths
TODO: 'Suffixed expressions' can be split up into a path, possibly followed by a '.', '?', '(', or '{'.
TODO: The suffix after the path cannot contain '::', since any of the aformentioned tokens resolve to a value, as opposed to a type
```ebnf
Path = {Segment "::"} Segment .
Segment = name [TypeArgs] .
```

### Functions
## Patterns
```ebnf
Pattern = LiteralPat | TuplePat | StructPat |
VariantPat | PathPat | RangePat .
LiteralPat = StrPat | IntPat | BoolPat .
RangePat = Pattern RangeSep Pattern .
RangeSep = ".." | "..=" .
PatList = {Pattern ","} Pattern [","] .
TuplePat = "(" [{Pattern ","} Pattern "," [Pattern]] ")".
VariantPat = Path "(" PatList ")" .
StructPat = Path "{" PatList "}" .
PathPat = Path .
```
FunctionDecl ::= "fn" Function .
Function ::= name [TypeParam] FuncType Block .
FuncType ::= "(" [{Field ","} Field] ")" ["->" Type] .
Field ::= name ":" Type .

## Declarations
```ebnf
Declaration = VarDecl | FunctionDecl | StructDecl |
EnumDecl | TypeDecl .
VarDecl = "let" name [":" Type] "=" Expr .
TypeDecl = "type" name [Generics] "=" Type .
Generics = "[" {name ","} name "]" .
```

### Classes
### Functions
```ebnf
FunctionDecl = "fn" Function .
Function = name [Generics] FuncHead Block .
FuncHead = "(" [{Field ","} Field] ")" ["->" Type] .
Field = name ":" Type .
```
ClassDecl ::= "class" ClassType .
ClassType ::= name [TypeParam] ClassBody .
ClassBody ::= "{" {Attribute [";"]} "}" .
Attribute ::= Method | Field .
Method ::= ["static"] Function .

### Structures
```ebnf
StructDecl = "struct" name [Generics] StructBody .
StructBody = "{" {Field [";"]} "}" .
```

### Enumerators
```
EnumDecl ::= "enum" name EnumBody .
EnumBody ::= "{" [{Variant ","} Variant] "}" .
Variant ::= name [Payload] .
Payload ::= "(" {Type ","} Type ")" .
```ebnf
EnumDecl = "enum" name [Generics] EnumBody .
EnumBody = "{" [{Variant ","} Variant] "}" .
Variant = name [Payload] .
Payload = "(" {Type ","} Type ")" .
```

## Operators
```
BinOp ::= "+" | "-" | "*" | "/" |
"%" | "&" | "^" | "|" |
"<" | "<=" | ">" | ">=" |
"==" | "!=" | "&&" | "||" .
UnOp ::= "-" | "~" | "!" | "#" .
```ebnf
BinOp = "+" | "-" | "*" | "/" |
"%" | "&" | "^" | "|" |
"<" | "<=" | ">" | ">=" |
"==" | "!=" | "&&" | "||" .
UnOp = "-" | "~" | "!" | "#" .
```

## Expressions
```
Expr ::= PrimaryExpr | Expr BinOp Expr | UnOp Expr .
PrimaryExpr ::= Operand | Call | Literal | "(" Expr ")" .
Call ::= PrimaryExpr "(" [ExprList] ")" .
Operand ::= name | Index | Selector .
Index ::= PrimaryExpr "[" ExprList "]" .
Selector ::= PrimaryExpr "." name .
ExprList ::= {Expr ","} Expr .
```ebnf
Expr = PrimaryExpr | Expr BinOp Expr | UnOp Expr .
PrimaryExpr = Operand | Call | "(" Expr ")" .
Call = PrimaryExpr "(" [ExprList] ")" .
Index = PrimaryExpr "[" ExprList "]" .
Selector = PrimaryExpr "." name .
ExprList = {Expr ","} Expr .
```

## Types
```
Type ::= name [TypeArgs] | TypeLit .
TypeLit ::= FuncType | ArrayType | TupleType .
FuncType ::= "fn" "(" [TypeList] ")" ["->" Type] .
TypeList ::= {Type ","} Type
TypeArgs ::= "[" TypeList "]" .
NamedType ::= name [TypeArgs] .
ArrayType ::= "[" Type ";" int_lit "]" .
TupleType ::= "(" [Type "," [Type]] ")" .
```ebnf
Type = NamedType | TypeLit .
TypeLit = FuncType | VectorType | MapType |
TupleType | NamedType .
FuncType = "fn" "(" [TypeList] ")" ["->" Type] .
TypeList = {Type ","} Type .
TypeArgs = "[" TypeList "]" .
NamedType = name [TypeArgs] .
VectorType = "[" Type "]" .
MapType = "[" Type ":" Type "]" .
TupleType = "(" [{Type ","} Type "," [Type]] ")".
```

## Operands
```
Operand ::= Literal | name [TypeArgs] .
Literal ::= BasicLit | CompositeLit .
BasicLit ::= int_lit | bool_lit | float_lit | string_lit .
```ebnf
Operand = Path | Index | Selector | Literal .
Literal = BasicLit | CompositeLit .
BasicLit = int_lit | bool_lit | float_lit | string_lit .
```

### Composite literals
Note that the unit type is just a 0-tuple (an tuple with 0 elements).
A 1-tuple must have a trailing `,` to distinguish it from a parenthesized expression.
```
CompositeLit ::= ClassLit | ArrayLit | TupleLit | VariantLit .
ClassLit ::= NamedType "{" [ItemList [","]] "}" .
ArrayLit ::= "[" [ExprList [","]] "]" .
TupleLit ::= "(" [Expr "," [Expr [","]]] ")" .
VariantLit ::= name ["(" {Expr ","} Expr ")"] .
ItemList ::= KeyedItem {"," KeyedItem} [","] .
KeyedItem ::= [Key ":"] Expr .
Key ::= name | Expr .
```ebnf
CompositeLit = VectorLit | MapLit | TupleLit | StructLit | VariantLit .
VectorLit = "[" [ExprList [","]] "]" .
MapLit = "[" ":" "]" | "[" [ItemList [","]] "]" .
TupleLit = "(" [{Expr ","} Expr "," [Expr]] ")".
StructLit = Path "{" [ItemList [","]] "}" .
VariantLit = Path ["(" {Expr ","} Expr ")"] .
ItemList = KeyedItem {"," KeyedItem} [","] .
KeyedItem = [Key ":"] Expr .
Key = name | Expr .
```

### Integer literals
```
int_lit ::= decimal_lit | binary_lit | octal_lit | hex_lit .
decimal_lit ::= "0" | ("1" … "9") [decimal_digits] .
binary_lit ::= "0" ("b" | "B") binary_digits .
octal_lit ::= "0" ("o" | "O") octal_digits .
hex_lit ::= "0" ("x" | "X") hex_digits .
```ebnf
int_lit = decimal_lit | binary_lit | octal_lit | hex_lit .
decimal_lit = "0" | ("1" … "9") [decimal_digits] .
binary_lit = "0" ("b" | "B") binary_digits .
octal_lit = "0" ("o" | "O") octal_digits .
hex_lit = "0" ("x" | "X") hex_digits .
```

### Float literals
```
float_lit := decimal_digits "." [decimal_digits] [decimal_exponent] |
decimal_digits decimal_exponent |
"." decimal_digits [decimal_exponent] .
decimal_exponent := ("e" | "E") ["+" | "-"] decimal_digits .
```ebnf
float_lit = decimal_digits "." [decimal_digits] [decimal_exponent] |
decimal_digits decimal_exponent |
"." decimal_digits [decimal_exponent] .
decimal_exponent = ("e" | "E") ["+" | "-"] decimal_digits .
```

## Miscellaneous
```
name ::= letter {letter | decimal_digit} .
letter ::= "A" … "Z" | "a" … "z" | "_" .
decimal_digit ::= "0" … "9" .
binary_digit ::= "0" | "1" .
octal_digit ::= "0" … "7" .
hex_digit ::= "0" … "9" | "A" … "F" | "a" … "f" .
decimal_digits ::= decimal_digit {decimal_digit} .
binary_digits ::= binary_digit {binary_digit} .
octal_digits ::= octal_digit {octal_digit} .
hex_digits ::= hex_digit {hex_digit} .
```ebnf
name = letter {letter | decimal_digit} .
letter = "A" … "Z" | "a" … "z" | "_" .
decimal_digit = "0" … "9" .
binary_digit = "0" | "1" .
octal_digit = "0" … "7" .
hex_digit = "0" … "9" | "A" … "F" | "a" … "f" .
decimal_digits = decimal_digit {decimal_digit} .
binary_digits = binary_digit {binary_digit} .
octal_digits = octal_digit {octal_digit} .
hex_digits = hex_digit {hex_digit} .
```

Loading

0 comments on commit 0a8f670

Please sign in to comment.