GLaDOS Language Grammar

BNF (Backus-Naur Form) specification

// ============================================================================
//                     GLaDOS Language - BNF Grammar
// ============================================================================

// ============================================================================
// PROGRAM STRUCTURE
// ============================================================================

<program>           ::= <instruction>*

<instruction>       ::= <var_decl> ";"
                      | <func_decl>
                      | <assignment> ";"
                      | <field_assign> ";"
                      | <if_stmt>
                      | <while_stmt>
                      | <for_stmt>
                      | <match_stmt>
                      | <try_stmt>
                      | <return_stmt> ";"
                      | <throw_stmt> ";"
                      | <break_stmt> ";"
                      | <continue_stmt> ";"
                      | <import_stmt> ";"
                      | <struct_decl>
                      | <class_decl>
                      | <macro_decl>
                      | <expr> ";"

// ============================================================================
// TYPES
// ============================================================================

<type>              ::= "Int" | "Bool" | "String" | "Void"
                      | "List" | "Map" | "Lambda" | "Any"
                      | <identifier>

// ============================================================================
// VARIABLE DECLARATION AND ASSIGNMENT
// ============================================================================

<var_decl>          ::= "var" <identifier> ":" <type> ("=" <expr>)?

<assignment>        ::= <identifier> "=" <expr>

<field_assign>      ::= <expr> "." <identifier> "=" <expr>

// ============================================================================
// FUNCTION DECLARATION
// ============================================================================

<func_decl>         ::= "def" <identifier> "(" <params>? ")" "->" <type>
                        "{" <instruction>* "}"

<params>            ::= <param> ("," <param>)*

<param>             ::= <identifier> ":" <type>
                      | "..." <identifier> ":" <type>

// ============================================================================
// CONTROL FLOW
// ============================================================================

<if_stmt>           ::= "if" "(" <expr> ")" "{" <instruction>* "}" <else_clause>?

<else_clause>       ::= "else" "{" <instruction>* "}"
                      | "else" <if_stmt>

<while_stmt>        ::= "while" "(" <expr> ")" "{" <instruction>* "}"

<for_stmt>          ::= "for" "(" <identifier> "in" <expr> ")" "{" <instruction>* "}"

<break_stmt>        ::= "break"

<continue_stmt>     ::= "continue"

<return_stmt>       ::= "return" <expr>?

// ============================================================================
// PATTERN MATCHING
// ============================================================================

<match_stmt>        ::= "match" "(" <expr> ")" "{" <match_case>+ "}"

<match_case>        ::= <pattern> "=>" "{" <instruction>* "}"
                      | <pattern> "=>" <expr> ";"

<pattern>           ::= <integer> | <string> | <bool>
                      | <identifier>
                      | "_"
                      | "[" (<pattern> ("," <pattern>)*)? "]"

// ============================================================================
// EXCEPTION HANDLING
// ============================================================================

<try_stmt>          ::= "try" "{" <instruction>* "}"
                        "catch" "(" <identifier> ")" "{" <instruction>* "}"

<throw_stmt>        ::= "throw" <expr>

// ============================================================================
// IMPORTS
// ============================================================================

<import_stmt>       ::= "import" <string> ("as" <identifier>)?
                      | "from" <string> "import" "(" <identifier> ("," <identifier>)* ")"
                      | "from" <string> "import" "*"

// ============================================================================
// STRUCT DECLARATION
// ============================================================================

<struct_decl>       ::= "struct" <identifier> "{" <struct_member>* "}"

<struct_member>     ::= <identifier> ":" <type> ";"

// ============================================================================
// CLASS DECLARATION
// ============================================================================

<class_decl>        ::= "class" <identifier> ("extends" <identifier>)?
                        "{" <class_member>* "}"

<class_member>      ::= <visibility>? <identifier> ":" <type> ";"
                      | <visibility>? <method_decl>

<visibility>        ::= "public" | "private"

<method_decl>       ::= "def" <identifier> "(" <params>? ")" "->" <type>
                        "{" <instruction>* "}"
                      | "def" "~" <identifier> "(" ")" "->" "Void"
                        "{" <instruction>* "}"

// ============================================================================
// MACROS
// ============================================================================

<macro_decl>        ::= "#define" <identifier> ("(" <identifier> ("," <identifier>)* ")")? <expr>

// ============================================================================
// EXPRESSIONS
// ============================================================================

<expr>              ::= <ternary>

<ternary>           ::= <logic_or> ("?" <expr> ":" <expr>)?

<logic_or>          ::= <logic_and> ("or" <logic_and>)*

<logic_and>         ::= <equality> ("and" <equality>)*

<equality>          ::= <comparison> (("==" | "!=") <comparison>)*

<comparison>        ::= <term> (("<" | "<=" | ">" | ">=") <term>)*

<term>              ::= <factor> (("+" | "-") <factor>)*

<factor>            ::= <unary> (("*" | "/" | "%") <unary>)*

<unary>             ::= ("-" | "not") <unary>
                      | <postfix>

<postfix>           ::= <primary> <postfix_op>*

<postfix_op>        ::= "(" <args>? ")"
                      | "[" <expr> "]"
                      | "." <identifier>
                      | "." <identifier> "(" <args>? ")"
                      | "++"
                      | "--"

<primary>           ::= <literal>
                      | <identifier>
                      | "(" <expr> ")"
                      | <lambda_expr>
                      | <list_literal>
                      | <map_literal>
                      | "{" <instruction>* "}"

// ============================================================================
// LITERALS
// ============================================================================

<literal>           ::= <integer>
                      | <float>
                      | <string>
                      | <char>
                      | "true" | "false"

<integer>           ::= [0-9]+

<float>             ::= [0-9]+ "." [0-9]+

<string>            ::= '"' <any_char>* '"'

<char>              ::= "'" <any_char> "'"

<list_literal>      ::= "[" (<expr> ("," <expr>)*)? "]"

<map_literal>       ::= "{" (<expr> ":" <expr> ("," <expr> ":" <expr>)*)? "}"

// ============================================================================
// LAMBDA EXPRESSIONS
// ============================================================================

<lambda_expr>       ::= "(" <params>? ")" "=>" "{" <instruction>* "}"
                      | "(" <params>? ")" "=>" <expr>

// ============================================================================
// FUNCTION CALLS
// ============================================================================

<args>              ::= <expr> ("," <expr>)*

// ============================================================================
// IDENTIFIERS
// ============================================================================

<identifier>        ::= [a-zA-Z_] [a-zA-Z0-9_]*

// ============================================================================
// COMMENTS
// ============================================================================

<comment>           ::= "//" <any_char>* <newline>

// ============================================================================
// OPERATORS
// ============================================================================
//
// Arithmetic:    + - * / %
// Comparison:    == != < <= > >=
// Logical:       and or not
// Assignment:    =
// Ternary:       ? :
// Access:        . []
// Increment:     ++ --
// Lambda:        =>
// Type:          ->

// ============================================================================
// RESERVED KEYWORDS
// ============================================================================
//
// if else while for in return break continue match
// def var
// true false
// Int Bool String Void List Map Lambda Any
// struct class extends public private
// try catch throw
// import from as
// and or not
// #define