aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorJJ2023-07-25 04:37:23 +0000
committerJJ2023-07-25 04:47:41 +0000
commitf2b9a083814f2e91f13860ae4a239630ee50040c (patch)
tree5717e3530d3f6866286a17646c102d0892ab8df1 /docs
parent10a46b468addc0fc697a1045a1de513cecf1119f (diff)
docs: initial formal description of grammar (missing scope)
Diffstat (limited to 'docs')
-rw-r--r--docs/SYNTAX.md141
1 files changed, 141 insertions, 0 deletions
diff --git a/docs/SYNTAX.md b/docs/SYNTAX.md
new file mode 100644
index 0000000..ecf7c6d
--- /dev/null
+++ b/docs/SYNTAX.md
@@ -0,0 +1,141 @@
+# Syntax: A Casual and Formal Look
+
+...
+
+## A Formal Look
+
+We now shall take a look at a more formal description of Puck's syntax. Syntax rules are described in extended Backus–Naur form (EBNF) - but most rules surrounding whitespace, and scope, and line breaks, are modified to how they would appear after a lexing step (whitespace is removed, line breaks are normalized, scope is switched to use `{` and `}`).
+
+### Identifiers
+```
+IDENT ::= LETTER (LETTER | DIGIT | '_')*
+LETTER ::= 'A'..'Z' | 'a'..'z' | '\x80'..'\xff' # todo
+DIGIT ::= '0'..'9'
+```
+
+### Literals
+```
+INT_LIT ::= '-'? (DEC_LIT | HEX_LIT | OCT_LIT | BIN_LIT)
+BIN_LIT ::= '0b' BIN_DIGIT ('_'? BIN_DIGIT)*
+OCT_LIT ::= '0o' OCT_DIGIT ('_'? OCT_DIGIT)*
+HEX_LIT ::= '0x' HEX_DIGIT ('_'? HEX_DIGIT)*
+DEC_LIT ::= DIGIT ('_'? DIGIT)*
+BIN_DIGIT ::= '0'..'1'
+OCT_DIGIT ::= '0'..'7'
+HEX_DIGIT ::= DIGIT | 'A'..'F' | 'a'..'f'
+```
+
+### Operators
+```
+OPERATOR ::= 'and' | 'or' | 'not' | 'xor' | 'shl' | 'shr' | # todo: more?
+ 'div' | 'mod' | 'rem' | 'is' | 'isnot' | OPR+
+OPR ::= '=' | '+' | '-' | '*' | '/' | '<' | '>' | # todo: more?
+ '@' | '$' | '~' | '&' | '%' | '|' |
+ '!' | '?' | '^' | '.' | ':' | '\\'
+```
+
+### 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_LIT | STRING | CHAR |
+LIST_DECL ::= '[' (EXPR (',' EXPR)*)? ']'
+ARRAY_DECL ::= '[' (EXPR (',' EXPR)*)? ']'
+TUPLE_DECL ::= '(' (IDENT '=')? EXPR (',' (IDENT '=')? EXPR)* ')'
+STRUCT_DECL ::= '{' IDENT '=' EXPR (',' IDENT '=' EXPR)* '}'
+# note: no union or enum. should struct exist? only in a structural system.
+```
+
+### Variables
+```
+DECL ::= LET_DECL | VAR_DECL | CONST_DECL
+LET_DECL ::= 'let' GROUP (':' TYPE_DESC)? '=' EXPR
+VAR_DECL ::= 'var' GROUP (':' TYPE_DESC)? ('=' EXPR)?
+CONST_DECL ::= 'pub'? 'const' GROUP (':' TYPE_DESC)? '=' EXPR
+GROUP ::= ('(' IDENT (',' IDENT)* ')') | IDENT
+```
+
+## Types and Functions
+```
+FUNC_DECL ::= SIGNATURE '=' (EXPR | STMT)
+SIGNATURE ::= 'pub'? ('pure' | 'yeet' | IDENT)? 'func' IDENT
+ ('(' (PARAMETER (',' PARAMETER)?)? ')')?
+ (':' TYPE_DESC)?
+PARAMETER ::= (IDENT (':' ('var' | 'static')? TYPE_DESC)?
+```
+
+```
+TYPE_DECL ::= 'pub'? 'type' IDENT '=' 'ref'? 'distinct'? TYPE_DESC
+TYPE_DESC ::= TUPLE_TYPE | STRUCT_TYPE | UNION_TYPE | ENUM_TYPE | INTERFACE | IDENT
+TUPLE_TYPE ::= 'tuple' '[' (IDENT ':')? TYPE_DESC (',' (IDENT ':')? TYPE_DESC)* ']'
+STRUCT_TYPE ::= 'struct' '[' 'pub'? IDENT ':' TYPE_DESC' (',' 'pub'? IDENT ':' 'TYPE_DESC')* ']'
+# note: pub in structs conflicts w/ a structural system
+UNION_TYPE ::= 'union' '[' IDENT ':' TYPE_DESC' (',' IDENT ':' 'TYPE_DESC')* ']'
+ENUM_TYPE ::= 'enum' '[' IDENT ('=' EXPR)? (',' IDENT ('=' EXPR)?)* ']'
+FUNC_TYPE ::= 'func' ('(' (PARAMETER (',' PARAMETER)?)? ')')? (':' TYPE_DESC)?
+INTERFACE ::= 'interface' '[' SIGNATURE (',' SIGNATURE)* ('for' TYPE_DESC)? ']'
+```
+
+## Control Flow
+```
+IF_EXPR ::= 'if' EXPR ':' EXPR ('elif' EXPR ':' EXPR)* 'else' ':' EXPR
+IF_STMT ::= 'if' EXPR ':' STMT ('elif' EXPR ':' STMT)* ('else' ':' STMT)?
+WHEN_EXPR ::= 'when' EXPR ':' EXPR ('else' ':' EXPR)?
+WHEN_STMT ::= 'when' EXPR ':' STMT ('else' ':' STMT)?
+BLOCK_EXPR ::= 'block' IDENT? ':' EXPR
+BLOCK_STMT ::= 'block' IDENT? ':' STMT
+MATCH_EXPR ::= 'match' EXPR ':'
+ ('case' EXPR ('where' EXPR)? (',' EXPR ('where' EXPR)?)* ':' EXPR)+
+MATCH_STMT ::= 'match' EXPR ':'
+ ('case' EXPR ('where' EXPR)? (',' EXPR ('where' EXPR)?)* ':' STMT)+
+LOOP_STMT ::= 'loop' ':' STMT
+WHILE_STMT ::= 'while' EXPR ':' STMT
+FOR_STMT ::= 'for' GROUP 'in' EXPR ':' STMT
+```
+
+## Modules
+```
+IMPORT_STMT ::= 'import' IDENT? ('/' (IDENT | '[' (IDENT (',' IDENT)*)? ']'))*
+EXPORT_STMT ::= 'export' IDENT? ('/' (IDENT | '[' (IDENT (',' IDENT)*)? ']'))*
+MODULE_STMT ::= 'module' IDENT ':' STMT
+```
+
+## Macros
+```
+MACRO_FUNC ::= IDENT '(' EXPR ')'
+MACRO_BLOCK ::= IDENT ':' EXPR # todo
+```
+
+## Calls, Statements, and Expressions
+```
+OPERATION ::= EXPR OPERATOR EXPR
+PREFIX ::= OPERATOR EXPR
+SUFFIX ::= EXPR OPERATOR
+APPLICATION ::= IDENT EXPR | IDENT PARAMS? | (IDENT | APPLICATION) '.' IDENT PARAMS?
+PARAMS ::= '(' ((IDENT '=')? EXPR (',' (IDENT '=')? EXPR)*)? ')'
+```
+
+```
+STMT ::= SINGLE_STMT | STMT+
+SINGLE_STMT ::= IF_STMT | WHEN_STMT | BLOCK_STMT | MATCH_STMT |
+ LOOP_STMT | WHILE_STMT | FOR_STMT |
+ IMPORT_STMT | EXPORT_STMT | MODULE_STMT |
+ TYPE_DECL | FUNC_DECL | (EXPR ';')
+EXPR ::= IF_EXPR | WHEN_EXPR | BLOCK_EXPR | MATCH_EXPR |
+ MACRO_FUNC | MACRO_BLOCK |
+ VALUE | APPLICATION | (STMT EXPR)
+```