# Syntax: A Casual and Formal Look > ! This section is **incomplete**. Proceed with caution. ## Reserved Keywords The following keywords are reserved: - variables: `let` `var` `const` - control flow: `if` `then` `elif` `else` - pattern matching: `match` `of` - error handling: `try` `catch` `finally` - loops: `while` `do` `for` `in` - blocks: `loop` `block` `break` `continue` `return` - modules: `pub` `mod` `use` `as` - functions: `func` `varargs` - metaprogramming: `macro` `quote` `static` `when` - ownership: `lent` `mut` `ref` `refc` - types: `type` `distinct` `struct` `tuple` `union` `enum` `class` - reserved: - `impl` `object` `interface` `concept` `auto` `empty` `effect` `case` - `suspend` `resume` `spawn` `pool` `thread` `closure` - `cyclic` `acyclic` `sink` `move` `destroy` `copy` `trace` `deepcopy` The following identifiers are in use by the standard prelude: - logic: `not` `and` `or` `xor` `shl` `shr` `div` `mod` `rem` - logic: `+` `-` `*` `/` `<` `>` `<=` `>=` `==` `!=` `is` - async: `async` `await` - types: `int` `uint` `float` - `i8` `i16` `i32` `i64` `i128` - `u8` `u16` `u32` `u64` `u128` - `f32` `f64` `f128` - `dec64` `dec128` - types: `bool` `byte` `char` `str` - types: `void` `never` - strings: `&` (string append) The following punctuation is taken: - `=` (assignment) - `.` (chaining) - `,` (parameters) - `;` (statements) - `:` (types) - `#` (comment) - `@` (attributes) - `_` (unused bindings) - `|` (generics) - `\` (string/char escaping) - `()` (parameters, tuples) - `[]` (generics, lists) - `{}` (scope, structs) - `""` (strings) - `''` (chars) - ``` `` ``` (unquoting) - unused: `~` `$` `%` ## A Formal Grammar We now shall take a look at a more formal description of Puck's syntax. Syntax rules are described in [extended Backus–Naur form](https://en.wikipedia.org/wiki/Extended_Backus–Naur_form) (EBNF): however, most rules surrounding whitespace, and scope, and line breaks, are modified to how they would appear after a lexing step. ### Identifiers ``` Ident ::= (Letter | '_') (Letter | Digit | '_')* Letter ::= 'A'..'Z' | 'a'..'z' | '\x80'..'\xff' # todo Digit ::= '0'..'9' ``` ### Literals ``` Int ::= '-'? (DecLit | HexLit | OctLit | BinLit) Float ::= '-'? DecLit '.' DecLit BinLit ::= '0b' BinDigit ('_'? BinDigit)* OctLit ::= '0o' OctDigit ('_'? OctDigit)* HexLit ::= '0x' HexDigit ('_'? HexDigit)* DecLit ::= Digit ('_'? Digit)* BinDigit ::= '0'..'1' OctDigit ::= '0'..'7' HexDigit ::= Digit | 'A'..'F' | 'a'..'f' ``` ### Chars, Strings, and Comments ``` CHAR ::= '\'' (PRINT - '\'' | '\\\'')* '\'' STRING ::= SINGLE_LINE_STRING | MULTI_LINE_STRING COMMENT ::= SINGLE_LINE_COMMENT | MULTI_LINE_COMMENT | EXPRESSION_COMMENT SINGLE_LINE_STRING ::= '"' (PRINT - '"' | '\\"')* '"' MULTI_LINE_STRING ::= '"""' (PRINT | '\n' | '\r')* '"""' SINGLE_LINE_COMMENT ::= '#' PRINT* MULTI_LINE_COMMENT ::= '#[' (PRINT | '\n' | '\r' | MULTI_LINE_COMMENT)* ']#' EXPRESSION_COMMENT ::= '#;' SINGLE_STMT PRINT ::= LETTER | DIGIT | OPR | '"' | '#' | "'" | '(' | ')' | # notably the dual of OPR ',' | ';' | '[' | ']' | '_' | '`' | '{' | '}' | ' ' | '\t' ``` ### Values ``` Value ::= Int | Float | String | Char | Array | Tuple | Struct Array ::= '[' (Expr (',' Expr)*)? ']' Tuple ::= '(' (Ident ':')? Expr (',' (Ident ':')? Expr)* ')' Struct ::= '{' Ident ':' Expr (',' Ident ':' Expr)* '}' ``` ### Variables ``` Decl ::= Let | Var | Const | Func | Type Let ::= 'let' Pattern (':' Type)? '=' Expr Var ::= 'var' Pattern (':' Type)? ('=' Expr)? Const ::= 'pub'? 'const' Pattern (':' Type)? '=' Expr Pattern ::= Char | String | Number | Float | Ident | '(' Pattern (',' Pattern)* ')' Ident '(' Pattern (',' Pattern)* ')' ``` ### Declarations ``` Func ::= 'pub'? 'func' Ident Generics? Parameters? (':' Type)? '=' Body Macro ::= 'pub'? 'macro' Ident Generics? Parameters? (':' Type)? '=' Body Generics ::= '[' Ident (':' Type)? (',' Ident (':' Type)?)* ']' Parameters ::= '(' Ident (':' Type)? (',' Ident (':' Type)?)* ')' ``` All arguments to functions must have a type. This is resolved at the semantic level, however. (Arguments to macros may lack types. This signifies a generic node.) ### Types ``` TypeDecl ::= 'pub'? 'type' Ident Generics? '=' Type Type ::= TypeStruct | TypeTuple | TypeEnum | TypeUnion | TypeClass | (Modifier* (Type | ('[' Type ']'))) TypeStruct ::= 'struct' ('[' Ident ':' Type (',' Ident ':' Type)* ']')? TypeUnion ::= 'union' ('[' Ident ':' Type (',' Ident ':' Type)* ']')? TypeTuple ::= 'tuple' ('[' (Ident ':')? Type (',' (Ident ':')? Type)* ']')? TypeEnum ::= 'enum' ('[' Ident ('=' Expr)? (',' Ident ('=' Expr)?)* ']')? TypeClass ::= 'class' ('[' Signature (',' Signature)* ']')? Modifier ::= 'distinct' | 'ref' | 'refc' | 'ptr' | 'lent' | 'mut' | 'static' Signature ::= Ident Generics? ('(' Type (',' Type)* ')')? (':' Type)? ``` ## Control Flow ``` If ::= 'if' Expr 'then' Body ('elif' Expr 'then' Body)* ('else' Body)? When ::= 'when' Expr 'then' Body ('elif' Expr 'then' Body)* ('else' Body)? Try ::= 'try' Body ('except' Ident ('as' Ident)? (',' Ident ('as' Ident)?)*) 'then' Body)+ ('finally' Body)? Match ::= 'match' Expr ('of' Pattern (',' Pattern)* ('where' Expr)? 'then' Body)+ While ::= 'while' Expr 'do' Body For ::= 'for' Pattern 'in' Expr 'do' Body Loop ::= 'loop' Body Block ::= 'block' Ident? Body Static ::= 'static' Body Quote ::= 'quote' QuoteBody ``` ## Modules ``` Mod ::= 'pub'? 'mod' Ident Body Use ::= 'use' Ident ('.' Ident)* ('.' ('[' Ident (',' Ident)* ']'))? ``` ### Operators ``` Operator ::= 'and' | 'or' | 'not' | 'xor' | 'shl' | 'shr' | 'div' | 'mod' | 'rem' | 'is' | 'in' | Opr+ Opr ::= '=' | '+' | '-' | '*' | '/' | '<' | '>' | '@' | '$' | '~' | '&' | '%' | '|' | '!' | '?' | '^' | '.' | ':' | '\\' ``` ## Calls and Expressions ``` Call ::= Ident ('[' Call (',' Call)* ']')? ('(' (Ident '=')? Call (',' (Ident '=')? Call)* ')')? | Ident Call (',' Call)* | Call Operator Call? | Call Body Expr ::= Let | Var | Const | Func | Type | Mod | Use | Block | Static | For | While | Loop | If | When | Try | Match | Call Body ::= Expr | (Expr (';' Expr)*) ``` --- References: - [Statements vs. Expressions](https://www.joshwcomeau.com/javascript/statements-vs-expressions/) - [Swift's Lexical Structure](https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html) - [The Nim Programming Language](https://nim-lang.github.io/Nim/manual.html) - [Pietro's Notes on Compilers](https://pgrandinetti.github.io/compilers/)