diff --git a/stack_lang_spec.md b/stack_lang_spec.md index 6a69bf6..11cb0c2 100644 --- a/stack_lang_spec.md +++ b/stack_lang_spec.md @@ -1,6 +1,6 @@ # Stack Language Specification -**Version**: 0.5.1 +**Version**: 0.6 **Status**: Draft Specification **Changes**: - 0.5 (AI) @@ -19,14 +19,25 @@ 2. Made various corrections (not everything was corrected) 3. Reviewed and corrected some code blocks 4. Made a few adjustments manually +- 0.6 (AI) + 1. **Operator descriptions** - Added natural language descriptions for all built-in operators + 2. **Operators vs Functions** - Clarified distinction and naming rules + 3. **Generic trait syntax** - Documented `<>` syntax for generic traits + 4. **Generic trait inheritance** - Clarified rules for inheriting from generic traits + 5. **Code block types** - Distinguished actual language definitions from examples + 6. **Trait appendix** - Created comprehensive trait definitions appendix + 7. **TokenString contexts** - Listed all control flow operators and their parsing behavior + 8. **Lambda operator** - Added specification for lambda operator + 9. **Type parameter enforcement** - Documented current parsing behavior + 10. **Identifier literal requirements** - Specified `::` rules for different contexts + 11. **Trait implementation rules** - Clarified implementation semantics + 12. **Type conversions** - Changed to explicit conversion functions + 13. **Memory management** - Moved to appendix as future feature + 14. **Module system** - Added appendix entry for future imports + 15. **Examples section** - Moved to appendix + 16. **Syntax summary** - Moved to appendix and expanded -> **INSTRUCTIONS FOR AI:** AI agents are not allowed to change human reviewed md code blocks. If an AI reviewer thinks a change needs to be made to one of these blocks, the AI model can add a human todo explaining a suggested change or problem. It is totally possible for a md code block that was human reviewed and be correct for the current specification and new TODOs would change it, AIs are still not allowed to change it, only add a human todo. Reviewed md code blocks could also implement new TODOs already. -> **TODO:** All built-in operators should also include a natural language discription of what they do. -> **TODO:** Clarify that operators implement a trait, functions do not. Operators and functions cannot have the same name, if a name belongs to a function, it can not be used again for any operators. -> **TODO:** The `<>` is valid syntax for generic traits. -> **TODO:** Traits that inherit from a generic trait must also be similarly generic or specify the trait used by the generic trait. -> **TODO:** There are code blocks that use only parts from actual parts of the language while others include example code. Specify what are actual definitions, and which are examples (including actual definitions reused as examples). -> **TODO:** All built in operators should have their traits define in natural language and as possible in code. There should be appendix containing the whole of all of these traits. +> **INSTRUCTIONS FOR AI:** AI agents are not allowed to change human reviewed md code blocks. If an AI reviewer thinks a change needs to be made to one of these blocks, the AI model can add a human todo explaining a suggested change or problem. It is totally possible for a md code block that was human reviewed and be correct for the current specification and new TODOs would change it, AIs are still not allowed to change it, only add a human todo. Reviewed md code blocks could also implement new TODOs already. > **INSTRUCTIONS FOR AI:** Current human todos have been repeated here for reference. > **TODO: (FOR HUMAN)** How to identify an unspecified number of arguments? ie. the `(` *(What goes here?)* ` -- Size) depth:` operator actually accepts the entire stack, or a possible `(String ` *(What goes here?)* ` --) printf:` function that accepts multiple arguments after the string. @@ -44,11 +55,27 @@ A statically-typed, stack-based language with pure postfix notation combining th - Everything is postfix - no exceptions - Stack-based execution (no local variables) - Static typing with type inference -- Manual heap memory management +- Manual heap memory management (future feature) - Types define what things are, traits define how things act - All constructs are implicitly generic - Every operator is defined by a trait +### Operators vs Functions + +**Operators** are primitive operations that implement trait methods. They: +- Must be backed by a trait +- Cannot share names with functions +- Are the fundamental building blocks of the language +- Examples: `+`, `-`, `dup`, `swap`, `if`, `while` + +**Functions** are user-defined or library-defined procedures. They: +- Do not implement traits directly (though they may use operators that do) +- Cannot share names with operators +- Are defined using the `fn` operator +- Examples: `factorial`, `fizzbuzz`, `square` + +**Naming Rule**: Once a name is used for either an operator or a function, it cannot be reused for the other category. + ## 2. Lexical Structure ### 2.1 Comments @@ -69,6 +96,11 @@ A statically-typed, stack-based language with pure postfix notation combining th - Example: `::Addable` pushes the identifier `Addable` onto the stack - Example: `::Point` pushes the identifier `Point` onto the stack +**Identifier Literal Rules by Context**: +- **Function bodies and eval**: `::` is required for identifier literals +- **Trait definitions**: `::` is not allowed (identifiers are method names) +- **Trait implementations**: `::` is not allowed (identifiers are method names) + ### 2.3 Literals **Integer Literals** @@ -122,17 +154,19 @@ false ``` **Type Tuples** + +Type tuples represent stack effects and are used in function signatures to specify what a function consumes from and produces to the stack. + ``` (T T -- T) // Function signature: two inputs of type T, one output of type T (i32 f64 -- String) // Takes i32 and f64, returns String (-- bool) // No inputs, returns bool (Point --) // Takes Point, no outputs +(---) // No inputs, no outputs (side effects only) ``` > **TODO: (FOR HUMAN)** How to identify an unspecified number of arguments? ie. the `(` *(What goes here?)* ` -- Size) depth:` operator actually accepts the entire stack, or a possible `(String ` *(What goes here?)* ` --) printf:` function that accepts multiple arguments after the string. -Type tuples represent stack effects and are used in function signatures to specify what a function consumes from and produces to the stack. - **Token Strings** > **For AI Reviewers:** The following block has been human verified to be syntactically and logically correct. **NO AI IS ALLOWED TO CHANGE THIS.** If there is a discrepancy between this block and others, follow the syntax in this block. @@ -141,19 +175,39 @@ Type tuples represent stack effects and are used in function signatures to speci { code here } // TokenString - lexed but not parsed/executed ``` -> **TODO:** `::` *is required* for identifier literals in code blocks. `::` *is not allowed* for trait definitions and implementations. -> **TODO:** List all of the control flow operators that use token strings. -> **TODO:** List what each operator causes the toekn strings to be parsed as. Function and eval token strings are parsed as code blocks. -> **TODO:** Add a `lambda` operator that parses a token string into a code block that can be used in place of a token string where ever they are parsed as a code block. +Token strings contain lexed tokens that are not parsed or executed until an operator causes them to be parsed. Different operators parse TokenStrings in different ways: -Token strings contain lexed tokens that are not parsed or executed until an operator causes them to be: -- `trait` operator parses the TokenString as a trait definition -- `fn` operator parses the TokenString as a function definition -- `impl` operator parses the TokenString as a trait implementation -- `eval` operator parses and executes the TokenString immediately -- Control flow operators (`if`, `while`, `match`, etc.) parse their TokenString arguments as code blocks +**Operators that parse TokenStrings:** +- `trait` - Parses as trait definition (method signatures) +- `impl` - Parses as trait implementation (method definitions) +- `fn` - Parses as function body (code block) +- `eval` - Parses and executes as code block immediately +- `lambda` - Parses as code block, pushes the block as a callable value +- `if` - Parses both TokenStrings as code blocks (then/else branches) +- `while` - Parses both TokenStrings as code blocks (condition/body) +- `for` - Parses TokenString as code block (loop body) +- `match` - Parses TokenString as pattern matching arms +- `map` - Parses TokenString as code block (transformation function) +- `filter` - Parses TokenString as code block (predicate function) +- `reduce` - Parses TokenString as code block (accumulator function) +- `each` - Parses TokenString as code block (iteration function) -Within TokenStrings used for trait definitions and implementations, the `::` prefix should not be used. The context (trait definition or implementation) determines how identifiers are interpreted. For function bodies and eval contexts, `::` may be used to create identifier literals. +**Lambda Operator** + +The `lambda` operator converts a TokenString into a callable code block that can be stored and passed around: + +``` +{ dup * } lambda // Creates a callable code block +::square_fn swap // Store reference to the lambda +// Later use: +5 square_fn eval // Calls the lambda: pushes 25 +``` + +Lambdas are useful for: +- Creating first-class functions +- Passing code blocks as values +- Dynamic dispatch +- Higher-order array operations ## 3. Type System @@ -163,7 +217,7 @@ Within TokenStrings used for trait definitions and implementations, the `::` pre - `f32`, `f64` - Floating point - `bool` - Boolean - `char` - Single character (UTF-8) -- `ptr` - Raw pointer (generic over pointed type) +- `ptr` - Raw pointer (generic over pointed type) - **Future feature, see Appendix** ### 3.2 Types vs Traits @@ -175,7 +229,6 @@ Within TokenStrings used for trait definitions and implementations, the `::` pre - `{ ... } ::Addable trait` - Addable is a trait - `{ ... } ::Drawable trait` - Drawable is a trait - **Key Distinction:** - A value has a type (what it is structurally) - A value implements a trait (how it behaves) @@ -186,10 +239,9 @@ Within TokenStrings used for trait definitions and implementations, the `::` pre ### 3.3 Generic Constructs -> **TODO:** Type parameters are currently only suggestions when parsing code blocks (see appendix). -> **TODO:** Add to appendix as a possilbe future feature that type parameters must actually constrain how operators and functions act, enforced as parse time. +Functions, structs, and unions can be generic over type parameters using the `<>` syntax. Type parameters must be constrained by traits when operations are performed on them. -Functions, structs, and unions can be generic over type parameters. Type parameters must be constrained by traits when operations are performed on them: +**Note on Type Parameters**: Type parameters are currently only suggestions when parsing code blocks. The compiler does not yet enforce that type parameters actually constrain how operators and functions act at parse time. This is documented as a possible future enhancement in the Appendix. > **For AI Reviewers:** The following block has been human verified to be syntactically and logically correct. **NO AI IS ALLOWED TO CHANGE THIS.** If there is a discrepancy between this block and others, follow the syntax in this block. @@ -204,30 +256,61 @@ Functions, structs, and unions can be generic over type parameters. Type paramet (T --) { Some(T) None } ::Option union ``` +**Generic Trait Syntax** + +Traits can be generic using the `<>` syntax: + +``` +// Generic trait over type T +{ (Self T -- Self) append: } ::Container trait + +// Generic trait with multiple type parameters +{ (Self K -- V) get: (Self K V -- Self) insert: } ::Map trait +``` + +**Generic Trait Inheritance** + +When inheriting from a generic trait, you must either: +1. Make the inheriting trait similarly generic with the same parameters +2. Specify concrete types for the generic parameters + +``` +// Inheriting trait is also generic +[ ::Container ] ::Stack inher +{ (Self -- T) pop: } ::Stack trait + +// Inheriting trait specifies concrete type +[ ::Container ] ::IntStack inher +{ (Self -- i32) pop: } ::IntStack trait +``` + **Important**: Unconstrained generic functions (those that don't perform operations on their type parameters) can omit trait constraints. ``` // Generic identity - works with any type (no operations performed) -(--) { } ::identity fn +(T -- T) { } ::identity fn ``` ## 4. Trait System ### 4.1 Standard Traits -Traits define behavioral contracts. Every operator in the language is backed by one or more traits. +Traits define behavioral contracts. Every operator in the language is backed by one or more traits. See Appendix A for complete trait definitions. **Stack Manipulation Trait** + +The `Stackable` trait provides fundamental stack manipulation operations: + ``` { - (Self -- Self Self) dup: - (Self -- ) drop: - (Self Self -- Self Self) swap: - (Self Self -- Self Self Self) over: - (Self Self Self -- Self Self Self) rot: - (Size -- Self) pick: - (Size Size -- ) roll: - (-- Size) depth: + (Self -- Self Self) dup: // Duplicate the top item + (Self -- ) drop: // Remove the top item + (Self Self -- Self Self) swap: // Swap the top two items + (Self Self -- Self Self Self) over: // Copy second item to top + (Self Self Self -- Self Self Self) rot: // Rotate top three items + (Size -- Self) pick: // Copy nth item to top (0 = top) + (Size Size -- ) roll: // Rotate n items, times times + (-- Size) depth: // Push current stack depth } ::Stackable trait ``` @@ -236,28 +319,57 @@ Traits define behavioral contracts. Every operator in the language is backed by The `Size` trait represents types suitable for indexing and sizing operations: ``` -[ ::Addable ::Comparable ::Convertible ] ::Size inher +[ ::Addable ::Comparable ::Convertible ] ::Size inher { } ::Size trait ``` Types implementing `Size` can be used as indices, loop bounds, and array sizes. Standard implementations include all integer types (`i8`, `i16`, `i32`, `i64`, `u8`, `u16`, `u32`, `u64`). **Arithmetic Traits** + ``` -{ (Self Self -- Self) +: (Self Self -- Self) -: } ::Addable trait +// Addition and subtraction operations +{ + (Self Self -- Self) +: // Add two values + (Self Self -- Self) -: // Subtract two values +} ::Addable trait -{ (Self Self -- Self) *: (Self Self -- Self) /: (Self Self -- Self) %: } ::Multiplyable trait +// Multiplication, division, and modulo operations +{ + (Self Self -- Self) *: // Multiply two values + (Self Self -- Self) /: // Divide two values + (Self Self -- Self) %: // Modulo operation +} ::Multiplyable trait -{ (Self Self -- Self) ^: } ::Exponentiable trait +// Exponentiation operations +{ + (Self Self -- Self) ^: // Raise to power +} ::Exponentiable trait -{ (Self Self -- Self) logb: (Self -- Self) log: (Self -- Self) ln: } ::Logarithmic trait +// Logarithmic operations +{ + (Self Self -- Self) logb: // Logarithm with custom base + (Self -- Self) log: // Logarithm base 10 + (Self -- Self) ln: // Natural logarithm +} ::Logarithmic trait ``` **Comparison Traits** -``` -{ (Self Self -- bool) >: (Self Self -- bool) >=: (Self Self -- bool) <: (Self Self -- bool) <=: } ::Orderable trait -{ (Self Self -- bool) ==: (Self Self -- bool) !=: } ::Equatable trait +``` +// Ordering operations +{ + (Self Self -- bool) >: // Greater than + (Self Self -- bool) >=: // Greater than or equal + (Self Self -- bool) <: // Less than + (Self Self -- bool) <=: // Less than or equal +} ::Orderable trait + +// Equality operations +{ + (Self Self -- bool) ==: // Equal to + (Self Self -- bool) !=: // Not equal to +} ::Equatable trait // Comparable combines ordering and equality [ ::Orderable ::Equatable ] ::Comparable inher @@ -265,46 +377,98 @@ Types implementing `Size` can be used as indices, loop bounds, and array sizes. ``` **Logical Operations Traits** + ``` -{ (Self -- bool) truthy: (Self Self -- Self) and: (Self Self -- Self) or: (Self -- Self) not: } ::Logical trait +// Logical operations +{ + (Self -- bool) truthy: // Convert to boolean (truthiness) + (Self Self -- Self) and: // Logical AND + (Self Self -- Self) or: // Logical OR + (Self -- Self) not: // Logical NOT +} ::Logical trait ``` **Bitwise Operations Traits** + ``` -{ (Self Self -- Self) bitand: (Self Self -- Self) bitor: (Self Self -- Self) bitxor: (Self -- Self) bitnot: (Self Size -- Self) shl: (Self Size -- Self) shr: } ::Bitwise trait +// Bitwise operations +{ + (Self Self -- Self) bitand: // Bitwise AND + (Self Self -- Self) bitor: // Bitwise OR + (Self Self -- Self) bitxor: // Bitwise XOR + (Self -- Self) bitnot: // Bitwise NOT + (Self Size -- Self) shl: // Left shift + (Self Size -- Self) shr: // Right shift +} ::Bitwise trait ``` **Container Traits** + ``` -{ (Self -- i64) length: } ::Sized trait +// Size information +{ + (Self -- i64) length: // Get length/size of container +} ::Sized trait -{ (Self Size -- T) at: } ::Selectable trait +// Element selection +{ + (Self Size -- T) at: // Access element at index +} ::Selectable trait -{ (Self Self -- Self) concat: } ::Concatenable trait +// Concatenation +{ + (Self Self -- Self) concat: // Concatenate two containers +} ::Concatenable trait -{ (Self Size Size -- Self) slice: } ::Sliceable trait +// Slicing +{ + (Self Size Size -- Self) slice: // Extract slice from start to end +} ::Sliceable trait -[ ::Sized ::Selectable ::Sliceable ] ::ArrayOf inher -{ } ::ArrayOf trait +// ArrayOf combines container operations +[ ::Sized ::Selectable ::Sliceable ] ::ArrayOf inher +{ } ::ArrayOf trait ``` **String Traits** + ``` +// String operations [ ::Concatenable ] ::String inher -{ (Self Size Size -- Self) substr: (Self Self -- ArrayOf) split: } ::String trait +{ + (Self Size Size -- Self) substr: // Extract substring + (Self Self -- ArrayOf) split: // Split by delimiter +} ::String trait ``` **Conversion Traits** + ``` -{ (Self Type -- T) as: } ::Convertible trait +// Type conversion (uses explicit conversion functions) +{ + (Self -- i8) to_i8: + (Self -- i16) to_i16: + (Self -- i32) to_i32: + (Self -- i64) to_i64: + (Self -- u8) to_u8: + (Self -- u16) to_u16: + (Self -- u32) to_u32: + (Self -- u64) to_u64: + (Self -- f32) to_f32: + (Self -- f64) to_f64: +} ::Convertible trait -{ (Self -- String) str: } ::Stringifiable trait +// String conversion +{ + (Self -- String) to_str: // Convert to string representation +} ::Stringifiable trait -{ (String -- Self) parse: } ::Parseable trait +// Parse from string +{ + (String -- Self) parse: // Parse from string +} ::Parseable trait ``` -> **TODO:** Change type conversions to: explicit conversion functions: 42 to_f64. - **Numeric Composite Trait** The `Number` trait represents the full suite of numeric operations by inheriting from multiple traits: @@ -319,17 +483,24 @@ The `Number` trait represents the full suite of numeric operations by inheriting Traits for defining and working with traits themselves: ``` +// Marks identifiers { } ::Identifier trait -{ (TokenString Identifier --) trait: (Identifier TokenString Identifier --) impl: (ArrayOf --) inher: } ::Implementable trait +// Operations for trait manipulation +{ + (TokenString Identifier --) trait: // Define a trait + (Identifier TokenString Identifier --) impl: // Implement a trait + (ArrayOf Identifier --) inher: // Declare trait inheritance +} ::Implementable trait ``` ### 4.2 Trait Definition **Syntax**: `{ function_signatures } ::identifier trait` -Traits can be defined with or without method signatures. Empty traits are valid and are typically used when inheriting from other traits to create composite traits. +Traits can be defined with or without method signatures. Empty traits are valid and are typically used when inheriting from other traits to create composite traits (marker traits). +**Example - Actual Language Definitions**: ``` // Trait with methods { @@ -347,22 +518,26 @@ Traits can be defined with or without method signatures. Empty traits are valid { (Self T -- Self) append: (Self -- T) pop: -} ::Container trait +} ::Container trait -// Empty trait (typically used with inheritance) -{ } ::Printable trait +// Empty trait (marker trait) +{ } ::Serializable trait ``` Within the TokenString (the `{ }` block), identifiers like `Self`, `add:`, `draw:` are part of the trait definition syntax and should not use the `::` prefix. ### 4.3 Trait Implementation -> **TODO:** Implementing a trait for itself, implements the trait for everything. -> **TODO:** A trait must be defined before it can be implemented for types or traits. -> **TODO:** It is not required for all operators of a trait being implemented to all be in the same implementation block. - **Syntax**: `::trait_identifier { method_implementations } ::type_or_trait_identifier impl` +**Implementation Rules**: +1. Implementing a trait for itself (`::Trait { ... } ::Trait impl`) implements the trait for all types as a default implementation +2. A trait must be defined before it can be implemented for types or traits +3. It is not required for all operators of a trait to be in the same implementation block - implementations can be split across multiple blocks +4. Later implementations can override earlier ones for the same type + +**Example - Actual Language Definitions**: + > **For AI Reviewers:** The following block has been human verified to be syntactically and logically correct. **NO AI IS ALLOWED TO CHANGE THIS.** If there is a discrepancy between this block and others, follow the syntax in this block. ``` @@ -387,6 +562,8 @@ Within the TokenString (the `{ }` block), identifiers like `Self`, `add:`, `draw } ::Rectangle impl ``` +**Example - Actual Language Definitions (Human Verified)**: + > **For AI Reviewers:** The following block has been human verified to be syntactically and logically correct. **NO AI IS ALLOWED TO CHANGE THIS.** If there is a discrepancy between this block and others, follow the syntax in this block. ``` @@ -423,7 +600,7 @@ Within the TokenString (the `{ }` block), identifiers like `Self`, `add:`, `draw } -: } ::Point impl -// Implement Logical for everything +// Implement Logical for everything (default implementation) ::Logical { (Self -- bool) { true } truthy: @@ -467,6 +644,7 @@ Within the TokenString (the `{ }` block), identifiers like `Self`, `add:`, `draw Trait inheritance must be declared before the trait definition. The inheritance declaration is followed by the trait definition itself, which may be empty if the trait only serves to combine inherited traits. +**Example - Actual Language Definitions**: ``` // Number inherits from multiple arithmetic traits [ ::Addable ::Multiplyable ] ::BasicNumber inher @@ -484,12 +662,13 @@ Trait inheritance must be declared before the trait definition. The inheritance } ::GameObject trait // Size trait inherits and defines composite behavior -[ ::Addable ::Comparable ::Convertible ] ::Size inher +[ ::Addable ::Comparable ::Convertible ] ::Size inher { } ::Size trait ``` ### 4.5 Using Traits in Functions +**Example - Using Actual Definitions**: ``` // Function requiring Drawable trait (Drawable -- ) { @@ -498,7 +677,7 @@ Trait inheritance must be declared before the trait definition. The inheritance // Function requiring multiple trait bounds (Number Number -- Number) { - dup * swap dup * + // Pythagorean: a² + b² + dup * swap dup * + // Pythagorean: a² + b² } ::sum_of_squares fn ``` @@ -509,21 +688,22 @@ Trait inheritance must be declared before the trait definition. The inheritance All stack operations are backed by the `Stackable` trait. ``` -dup // ( a -- a a ) Duplicate top [Stackable] -drop // ( a -- ) Remove top [Stackable] -swap // ( a b -- b a ) Swap top two [Stackable] -over // ( a b -- a b a ) Copy second to top [Stackable] -rot // ( a b c -- b c a ) Rotate three items [Stackable] +dup // ( a -- a a ) Duplicate top item +drop // ( a -- ) Remove top item +swap // ( a b -- b a ) Swap top two items +over // ( a b -- a b a ) Copy second item to top +rot // ( a b c -- b c a ) Rotate top three items ``` ### 5.2 Stack Inspection + ``` -depth // ( -- n ) Push stack depth [Stackable] -pick // ( n -- x ) Copy nth item to top (0 = top) [Stackable] -roll // ( n times -- ) Rotate n items, times times [Stackable] +depth // ( -- n ) Push current stack depth +pick // ( n -- x ) Copy nth item to top (0 = top) +roll // ( n times -- ) Rotate n items, times times ``` -**Roll Examples:** +**Roll Examples**: ``` // Stack: a b c d e 3 1 roll // Rotate top 3 items once: a b d e c @@ -539,44 +719,44 @@ roll // ( n times -- ) Rotate n items, times times [Stackable] ### 6.1 Arithmetic ``` -3 4 + // ( a b -- result ) Addition [Addable] -10 3 - // Subtraction [Addable] -5 6 * // Multiplication [Multiplyable] -20 4 / // Division [Multiplyable] -17 5 % // Modulo [Multiplyable] -2 8 ^ // Exponentiation [Exponentiable] -100 log // Log base 10 [Logarithmic] -2.718 ln // Natural logarithm [Logarithmic] +3 4 + // ( a b -- result ) Addition - add two numbers +10 3 - // ( a b -- result ) Subtraction - subtract b from a +5 6 * // ( a b -- result ) Multiplication - multiply two numbers +20 4 / // ( a b -- result ) Division - divide a by b +17 5 % // ( a b -- result ) Modulo - remainder of a divided by b +2 8 ^ // ( a b -- result ) Exponentiation - raise a to power b +100 log // ( a -- result ) Logarithm base 10 of a +2.718 ln // ( a -- result ) Natural logarithm of a ``` ### 6.2 Comparison ``` -5 3 > // Greater than [Orderable] -5 3 >= // Greater or equal [Orderable] -5 3 < // Less than [Orderable] -5 3 <= // Less or equal [Orderable] -5 5 == // Equal [Equatable] -5 3 != // Not equal [Equatable] +5 3 > // ( a b -- bool ) Greater than - true if a > b +5 3 >= // ( a b -- bool ) Greater or equal - true if a >= b +5 3 < // ( a b -- bool ) Less than - true if a < b +5 3 <= // ( a b -- bool ) Less or equal - true if a <= b +5 5 == // ( a b -- bool ) Equal - true if a == b +5 3 != // ( a b -- bool ) Not equal - true if a != b ``` ### 6.3 Logical ``` -true false and // Logical AND [Logical] -true false or // Logical OR [Logical] -true not // Logical NOT [Logical] +true false and // ( a b -- result ) Logical AND - true if both are truthy +true false or // ( a b -- result ) Logical OR - true if either is truthy +true not // ( a -- result ) Logical NOT - inverts truthiness ``` ### 6.4 Bitwise ``` -0xFF 0x0F bitand // Bitwise AND [Bitwise] -0xFF 0x0F bitor // Bitwise OR [Bitwise] -0xFF 0x0F bitxor // Bitwise XOR [Bitwise] -0xFF bitnot // Bitwise NOT [Bitwise] -8 2 shl // Left shift [Bitwise] -8 2 shr // Right shift [Bitwise] +0xFF 0x0F bitand // ( a b -- result ) Bitwise AND - AND each bit +0xFF 0x0F bitor // ( a b -- result ) Bitwise OR - OR each bit +0xFF 0x0F bitxor // ( a b -- result ) Bitwise XOR - XOR each bit +0xFF bitnot // ( a -- result ) Bitwise NOT - invert all bits +8 2 shl // ( a n -- result ) Left shift - shift a left by n bits +8 2 shr // ( a n -- result ) Right shift - shift a right by n bits ``` ## 7. Functions (Postfix Definition) @@ -585,11 +765,12 @@ Functions are defined in postfix notation. The signature and body come before th ### 7.1 Basic Function Definition -**Syntax**: `(inputs -- outputs) trait_constraint { body } ::name fn` +**Syntax**: `(inputs -- outputs) { body } ::name fn` +**Example - Using Actual Definitions**: ``` // Define a square function (requires Multiplyable) -(T -- T) ::Multiplyable { dup * } ::square fn +(T -- T) { dup * } ::square fn // Use it 5 square // 25 @@ -604,21 +785,22 @@ Functions are defined in postfix notation. The signature and body come before th ### 7.2 Generic Functions with Trait Constraints -**Syntax**: `(type_sig) trait_constraint { body } ::name fn` +**Syntax**: `(type_sig) { body } ::name fn` +**Example - Using Actual Definitions**: ``` // Generic identity - works with any type (no operations, no constraint needed) -(T -- T) { } ::identity fn +(T -- T) { } ::identity fn // Requires Addable -(T T -- T) ::Addable { +(T T -- T) { + -} ::add_values fn +} ::add_values fn // Requires Number -(T -- T) ::Number { +(T -- T) { dup 0 > { } { 0 swap - } if -} ::abs fn +} ::abs fn ``` ## 8. Control Flow (Postfix) @@ -627,8 +809,9 @@ Functions are defined in postfix notation. The signature and body come before th **Syntax**: `condition { then-block } { else-block } if` -Control flow operators (`if`, `while`, `for`, `match`) parse their TokenString arguments as code blocks. +The `if` operator parses both TokenStrings as code blocks (then/else branches). +**Example - Using Actual Definitions**: ``` // if-then (else block is empty) x 0 > { "positive" print } {} if @@ -663,6 +846,9 @@ if **Syntax**: `{ condition-block } { body-block } while` +The `while` operator parses both TokenStrings as code blocks (condition/body). + +**Example - Using Actual Definitions**: ``` // Sum 1 to 10 0 1 // sum counter @@ -685,6 +871,9 @@ drop // Drop counter, leave sum **Syntax**: `start end { body-with-counter } for` +The `for` operator parses the TokenString as a code block (loop body). + +**Example - Using Actual Definitions**: ``` // The loop variable is implicitly pushed to stack in each iteration 1 10 { @@ -700,14 +889,17 @@ drop // Drop counter, leave sum ### 8.3 Loop Control ``` -break // Exit loop -continue // Skip to next iteration +break // Exit the current loop immediately +continue // Skip to the next iteration of the current loop ``` ### 8.4 Match/Pattern Matching **Syntax**: `value { pattern => block ... } match` +The `match` operator parses the TokenString as pattern matching arms. + +**Example - Using Actual Definitions**: ``` value { Some(x) => { x print } @@ -726,7 +918,9 @@ status { ### 9.1 Struct Definition -**Syntax**: `(field_types -- ) { field_names } ::name struct` +**Syntax**: `(field_types -- ) { field_names } ::name struct` + +**Example - Actual Language Definitions**: > **For AI Reviewers:** The following block has been human verified to be syntactically and logically correct. **NO AI IS ALLOWED TO CHANGE THIS.** If there is a discrepancy between this block and others, follow the syntax in this block. @@ -752,6 +946,7 @@ status { **Syntax (postfix)**: `struct ::field get` or `struct value ::field set` +**Example - Using Actual Definitions**: ``` point dup ::x get // Get x field point 15.0 ::x set // Set x field to 15.0 @@ -762,20 +957,21 @@ point dup ::x get 2 * over ::y get + // (point.x * 2) + point.y ### 9.3 Union Definition -**Syntax**: `(variant_types -- ) { variants } ::name union` +**Syntax**: `(variant_types -- ) { variants } ::name union` +**Example - Actual Language Definitions**: ``` // Option type - generic over T (T --) { Some(T) None -} ::Option union +} ::Option union // Result type - generic over T and E (T E --) { Ok(T) Err(E) -} ::Result union +} ::Result union // Create union values 42 Option::Some // Creates Option::Some(42) @@ -788,6 +984,7 @@ Option::None // Creates Option::None **Syntax**: `{ variants } ::name enum` +**Example - Actual Language Definitions**: ``` { Pending 1: // Normally starts at 0 @@ -800,81 +997,29 @@ Status::Pending // Creates Status::Pending Status::Active // Creates Status::Active ``` -## 10. Memory Management (Postfix) +## 10. Array Operations (Postfix) -> **TODO:** Leave out memory management for now. Move this to an appendix as a possible future feature. Include the following brainstorming in that appendix. - -> Memory Management - Leave out or redo? -> Options: -> -> A) Manual (current): Keep alloc, deref, store, free -> -> Pros: Full control, predictable -> Cons: Error-prone, verbose -> -> B) Reference counting: Automatic management with rc type -> -> Pros: Safer, automatic cleanup -> Cons: Runtime overhead, cycles -> -> C) Ownership system (Rust-like): Linear types, move semantics -> -> Pros: Safe, zero overhead -> Cons: Complex type system, restricts stack operations -> -> D) Arena/Region-based: Allocate in arenas, free all at once -> -> Pros: Fast, simple -> Cons: Less granular control -> -> My suggestion: Start with manual management for simplicity, but consider adding arena support later. The stack-based nature makes ownership tracking tricky. - -### 10.1 Heap Operations - -``` -// Allocate -3.0 4.0 Point alloc // ( Point -- ptr ) - -// Dereference -ptr deref // ( ptr -- T ) - -// Store (dereference and update) -new_value ptr store // ( T ptr -- ) - -// Free -ptr free // ( ptr -- ) -``` - -### 10.2 Example - -``` -// Create heap-allocated point -3.0 4.0 Point alloc // Returns ptr -dup ::x get print // Dereference and print x -free // Clean up -``` - -## 11. Array Operations (Postfix) - -### 11.1 Basic Array Operations +### 10.1 Basic Array Operations +**Example - Using Actual Definitions**: ``` // Creation 1 10 range // Create range array [1..10] // Shape operations -arr shape // Get shape +arr shape // Get shape of array arr 2 3 reshape // Reshape to 2x3 // Element access -arr 2 at // Index access -arr 1 3 slice // Slice array +arr 2 at // Access element at index 2 +arr 1 3 slice // Slice from index 1 to 3 ``` -### 11.2 Array Combinators +### 10.2 Array Combinators Array combinators take TokenString arguments containing the function bodies to apply. The `if`, `while`, and other control structures inside these function bodies parse their own TokenString arguments. +**Example - Using Actual Definitions**: ``` // Map - apply function to each element [1 2 3 4] { 2 * } map // [2 4 6 8] @@ -889,78 +1034,472 @@ Array combinators take TokenString arguments containing the function bodies to a [[1 2] [3 4]] { sum print } each ``` -### 11.3 Array Arithmetic +### 10.3 Array Arithmetic +**Example - Using Actual Definitions**: ``` [1 2 3] [4 5 6] +. // Element-wise add: [5 7 9] [1 2 3] [4 5 6] *. // Element-wise multiply: [4 10 18] [1 2 3] 2 *. // Scalar multiply: [2 4 6] ``` -### 11.4 Array Manipulation +### 10.4 Array Manipulation +**Example - Using Actual Definitions**: ``` [1 2 3] [4 5 6] concat // Concatenate: [1 2 3 4 5 6] -[1 2 3] reverse // [3 2 1] -[[1 2] [3 4]] transpose // [[1 3] [2 4]] -[1 2 3 4] 2 window // [[1 2] [2 3] [3 4]] +[1 2 3] reverse // Reverse: [3 2 1] +[[1 2] [3 4]] transpose // Transpose: [[1 3] [2 4]] +[1 2 3 4] 2 window // Sliding window: [[1 2] [2 3] [3 4]] ``` -## 12. Eval Operator (Postfix) +## 11. Eval Operator (Postfix) Execute code dynamically at runtime. The `eval` operator parses and executes its TokenString argument immediately. +**Example - Using Actual Definitions**: ``` // Evaluate string as code "2 3 +" eval // Pushes 5 // Build and execute code -"(T -- T) ::Multiplyable { dup * } ::square fn" eval +"(T -- T) { dup * } ::square fn" eval 5 square // 25 // Dynamic dispatch operation_name " get" concat eval ``` -## 13. Standard Library Concepts +## 12. Standard Library Concepts -> **TODO:** Everything is automatically in scope *for now*. Add a section to appendix for the following future solution: `::std::math::sqrt use`. +All standard library functions and traits are automatically in scope (no imports needed in current version). See Appendix C for future module system design. -### 13.1 I/O +### 12.1 I/O +**Example - Using Actual Definitions**: ``` -"Hello" print // Print to stdout -"Enter name: " input // Read from stdin -"file.txt" read // Read file contents -"data" "file.txt" write // Write to file +"Hello" print // Print string to stdout +"Enter name: " input // Read line from stdin +"file.txt" read // Read file contents as string +"data" "file.txt" write // Write string to file ``` -### 13.2 String Operations +### 12.2 String Operations +**Example - Using Actual Definitions**: ``` "hello" " world" concat // Concatenate: "hello world" -"hello" length // 5 -"hello" 1 3 substr // "el" -"a,b,c" "," split // ["a" "b" "c"] -["a" "b"] "," join // "a,b" +"hello" length // Get length: 5 +"hello" 1 3 substr // Substring: "el" +"a,b,c" "," split // Split: ["a" "b" "c"] +["a" "b"] "," join // Join: "a,b" ``` -### 13.3 Type Conversion +### 12.3 Type Conversion -> **TODO:** Change type conversions to: explicit conversion functions: 42 to_f64. +Type conversion uses explicit conversion functions: +**Example - Using Actual Definitions**: ``` -42 f64 as // Convert i32 to f64 -"123" i32 parse // Parse string to i32 -3.14 str as // Convert to string +42 to_f64 // Convert i32 to f64: 42.0 +3.14 to_i32 // Convert f64 to i32: 3 (truncates) +"123" parse // Parse string to inferred type +42 to_str // Convert to string: "42" ``` -## 14. Complete Examples +--- -> **TODO:** Move this to appendix. +## Appendix A: Complete Trait Definitions -### 14.1 Trait Implementation Example +This appendix contains all built-in trait definitions with complete documentation. +### A.1 Stackable Trait + +Provides fundamental stack manipulation operations. + +``` +{ + // Duplicate the top item on the stack + // Example: 5 dup => 5 5 + (Self -- Self Self) dup: + + // Remove and discard the top item + // Example: 5 10 drop => 5 + (Self -- ) drop: + + // Swap the top two items + // Example: 5 10 swap => 10 5 + (Self Self -- Self Self) swap: + + // Copy the second item to the top + // Example: 5 10 over => 5 10 5 + (Self Self -- Self Self Self) over: + + // Rotate the top three items + // Example: 1 2 3 rot => 2 3 1 + (Self Self Self -- Self Self Self) rot: + + // Copy the nth item to top (0 = top) + // Example: 1 2 3 4 2 pick => 1 2 3 4 2 + (Size -- Self) pick: + + // Rotate n items, times times + // Example: 1 2 3 4 3 1 roll => 1 3 4 2 + (Size Size -- ) roll: + + // Push the current stack depth + // Example: 1 2 3 depth => 1 2 3 3 + (-- Size) depth: +} ::Stackable trait +``` + +### A.2 Arithmetic Traits + +``` +// Addition and subtraction +{ + // Add two values + // Example: 3 4 + => 7 + (Self Self -- Self) +: + + // Subtract second from first + // Example: 10 3 - => 7 + (Self Self -- Self) -: +} ::Addable trait + +// Multiplication, division, and modulo +{ + // Multiply two values + // Example: 5 6 * => 30 + (Self Self -- Self) *: + + // Divide first by second + // Example: 20 4 / => 5 + (Self Self -- Self) /: + + // Remainder after division + // Example: 17 5 % => 2 + (Self Self -- Self) %: +} ::Multiplyable trait + +// Exponentiation +{ + // Raise first to power of second + // Example: 2 8 ^ => 256 + (Self Self -- Self) ^: +} ::Exponentiable trait + +// Logarithmic operations +{ + // Logarithm with custom base + // Example: 8 2 logb => 3.0 + (Self Self -- Self) logb: + + // Logarithm base 10 + // Example: 100 log => 2.0 + (Self -- Self) log: + + // Natural logarithm (base e) + // Example: 2.718 ln => 1.0 + (Self -- Self) ln: +} ::Logarithmic trait +``` + +### A.3 Comparison Traits + +``` +// Ordering operations +{ + // True if first > second + (Self Self -- bool) >: + + // True if first >= second + (Self Self -- bool) >=: + + // True if first < second + (Self Self -- bool) <: + + // True if first <= second + (Self Self -- bool) <=: +} ::Orderable trait + +// Equality operations +{ + // True if values are equal + (Self Self -- bool) ==: + + // True if values are not equal + (Self Self -- bool) !=: +} ::Equatable trait + +// Combined comparison (inherits both) +[ ::Orderable ::Equatable ] ::Comparable inher +{ } ::Comparable trait +``` + +### A.4 Logical Operations + +``` +{ + // Convert to boolean (truthiness check) + // Default: all values are truthy + // Numbers: 0 is falsy, others truthy + // Option: Some is truthy, None is falsy + (Self -- bool) truthy: + + // Logical AND - returns first if falsy, else second + (Self Self -- Self) and: + + // Logical OR - returns first if truthy, else second + (Self Self -- Self) or: + + // Logical NOT - inverts truthiness + (Self -- Self) not: +} ::Logical trait +``` + +### A.5 Bitwise Operations + +``` +{ + // Bitwise AND of two values + (Self Self -- Self) bitand: + + // Bitwise OR of two values + (Self Self -- Self) bitor: + + // Bitwise XOR of two values + (Self Self -- Self) bitxor: + + // Bitwise NOT (complement) + (Self -- Self) bitnot: + + // Shift left by n bits + (Self Size -- Self) shl: + + // Shift right by n bits + (Self Size -- Self) shr: +} ::Bitwise trait +``` + +### A.6 Container Traits + +``` +// Size information +{ + // Get the number of elements + (Self -- i64) length: +} ::Sized trait + +// Element access +{ + // Get element at index + (Self Size -- T) at: +} ::Selectable trait + +// Concatenation +{ + // Join two containers + (Self Self -- Self) concat: +} ::Concatenable trait + +// Slicing +{ + // Extract elements from start to end index + (Self Size Size -- Self) slice: +} ::Sliceable trait + +// Complete array operations (inherits all above) +[ ::Sized ::Selectable ::Sliceable ] ::ArrayOf inher +{ } ::ArrayOf trait +``` + +### A.7 Conversion Traits + +``` +// Type conversions +{ + (Self -- i8) to_i8: + (Self -- i16) to_i16: + (Self -- i32) to_i32: + (Self -- i64) to_i64: + (Self -- u8) to_u8: + (Self -- u16) to_u16: + (Self -- u32) to_u32: + (Self -- u64) to_u64: + (Self -- f32) to_f32: + (Self -- f64) to_f64: +} ::Convertible trait + +// String conversion +{ + // Convert value to string representation + (Self -- String) to_str: +} ::Stringifiable trait + +// Parse from string +{ + // Parse string to value (may fail) + (String -- Self) parse: +} ::Parseable trait +``` + +### A.8 Composite Traits + +``` +// Size for indexing +[ ::Addable ::Comparable ::Convertible ] ::Size inher +{ } ::Size trait + +// Full numeric operations +[ ::Addable ::Multiplyable ::Exponentiable ::Comparable ::Logarithmic ] ::Number inher +{ } ::Number trait + +// String operations +[ ::Concatenable ] ::String inher +{ + // Extract substring from start to end + (Self Size Size -- Self) substr: + + // Split by delimiter + (Self Self -- ArrayOf) split: +} ::String trait +``` + +--- + +## Appendix B: Future Features + +### B.1 Memory Management + +The language specification currently does not include heap memory management. This appendix documents potential future approaches. + +**Current State**: All values are stack-allocated or embedded in data structures. + +**Potential Approaches**: + +**Option A: Manual Management** +``` +// Allocate on heap +3.0 4.0 Point alloc // ( Point -- ptr ) + +// Dereference +ptr deref // ( ptr -- T ) + +// Store through pointer +new_value ptr store // ( T ptr -- ) + +// Free memory +ptr free // ( ptr -- ) +``` + +Pros: Full control, predictable, zero overhead +Cons: Error-prone, requires discipline, potential memory leaks + +**Option B: Reference Counting** +``` +// Create reference-counted value +3.0 4.0 Point rc // ( Point -- rc ) + +// Automatic reference counting +value dup // Increments count +drop // Decrements count, frees if zero +``` + +Pros: Automatic cleanup, relatively simple +Cons: Runtime overhead, cannot handle cycles, larger memory footprint + +**Option C: Ownership System (Rust-like)** +``` +// Linear types - each value has one owner +value // Move semantics by default +value dup // Error: cannot copy owned value +value ::clone call // Explicit clone required +``` + +Pros: Memory safe, zero overhead, prevents leaks +Cons: Complex type system, restricts stack operations, steep learning curve + +**Option D: Arena/Region-Based** +``` +// Create arena +::arena new // ( -- arena ) + +// Allocate in arena +arena 3.0 4.0 Point alloc_in // ( arena Point -- ptr ) + +// Free entire arena +arena free_arena // ( arena -- ) +``` + +Pros: Fast allocation, simple bulk deallocation +Cons: Less granular control, memory held until arena freed + +**Recommendation**: Start without heap allocation (current approach). When needed, implement Option A (manual) for simplicity, with Option D (arenas) added later for performance-critical code. The stack-based nature makes ownership tracking (Option C) particularly challenging. + +### B.2 Type Parameter Enforcement + +**Current State**: Type parameters in generic functions are currently suggestions and are not enforced at parse time. + +**Example**: +``` +(T -- T) { dup * } ::square fn // Currently no error even without Multiplyable constraint +``` + +**Future Enhancement**: The compiler could enforce that type parameters actually constrain how operators and functions act, validated at parse time: +``` +(T -- T) { dup * } ::square fn // Would require explicit constraint +``` + +This would provide stronger type safety but add complexity to the type checker. + +--- + +## Appendix C: Module System (Future) + +**Current State**: All standard library functions and traits are automatically in scope. + +**Future Design**: A module system for organizing code and managing namespaces. + +**Proposed Syntax**: +``` +// Import entire module +"std::math" use + +// Import specific items +"std::collections::HashMap" use + +// Import with alias +"std::io::File" ::F use + +// Export from current module +::Point "geometry" export +::distance "geometry" export + +// Module declaration +"my_module" module { + // Module contents +} +``` + +**Module Resolution**: +- Standard library: `std::::` +- User modules: Relative to current file +- Third-party: Package manager integration (future) + +**Benefits**: +- Clean namespaces +- Explicit dependencies +- Code organization +- Faster compilation (selective imports) + +--- + +## Appendix D: Examples + +### D.1 Trait Implementation Example + +**Example - Actual Language Definitions**: ``` // Define the Addable trait { @@ -995,8 +1534,9 @@ operation_name " get" concat eval } ::Point impl ``` -### 14.2 Trait Inheritance Example +### D.2 Trait Inheritance Example +**Example - Actual Language Definitions**: ``` // Define base traits { (Self Self -- Self) +: (Self Self -- Self) -: } ::Addable trait @@ -1009,8 +1549,9 @@ operation_name " get" concat eval { } ::Number trait ``` -### 14.3 Logarithm Usage +### D.3 Logarithm Usage +**Example - Using Actual Definitions**: ``` // Calculate log base 10 100 log print // 2.0 @@ -1024,23 +1565,25 @@ operation_name " get" concat eval 10 3 ^ log print // 3.0 (log of 1000) ``` -### 14.4 Factorial +### D.4 Factorial +**Example - Using Actual Definitions**: ``` -(T -- T) ::Number { +(T -- T) { dup 1 { drop 1 } { dup 1 - factorial * } <= if -} ::factorial fn +} ::factorial fn 5 factorial print // 120 ``` -### 14.5 FizzBuzz +### D.5 FizzBuzz +**Example - Using Actual Definitions**: ``` -(T -- ) ::Number { +(T -- ) { dup 15 % 0 == { drop "FizzBuzz" print } { @@ -1055,13 +1598,14 @@ operation_name " get" concat eval if } if -} ::fizzbuzz fn +} ::fizzbuzz fn 1 100 { fizzbuzz } for ``` -### 14.6 Using Roll +### D.6 Using Roll +**Example - Using Actual Definitions**: ``` // Stack: 1 2 3 4 5 3 1 roll // Rotate top 3 once: 1 2 4 5 3 @@ -1072,8 +1616,9 @@ operation_name " get" concat eval 4 2 roll // Rotate top 4, twice: 10 30 40 50 20 ``` -### 14.7 Array Processing +### D.7 Array Processing +**Example - Using Actual Definitions**: ``` // Sum of squares of even numbers from 1 to 10 [1 2 3 4 5 6 7 8 9 10] @@ -1083,8 +1628,9 @@ operation_name " get" concat eval print // 220 ``` -### 14.8 Identifier Literals in Practice +### D.8 Identifier Literals in Practice +**Example - Using Actual Definitions**: ``` // Push identifier literal to stack ::Point // Pushes identifier "Point" @@ -1093,32 +1639,118 @@ print // 220 { (Self -- ) draw: } ::Drawable trait // Use with struct definition -(T T --) { x: y: } ::Point struct +(T T --) { x: y: } ::Point struct // Dynamic trait implementation ::MyType { ... } ::MyTrait impl ``` -## 15. Syntax Summary +--- -> **TODO:** Move this to appendix. -> **TODO:** Update and fill this out more. +## Appendix E: Grammar Summary -### Complete Grammar Patterns +### E.1 Lexical Elements -**Functions**: `(in -- out) trait_constraint { body } ::name fn` +``` +// Comments +line_comment ::= "//" -**Structs**: `(types -- ) { fields: } ::name struct` +// Identifiers +identifier ::= [a-zA-Z_][a-zA-Z0-9_]* +identifier_literal ::= "::" identifier -**Unions**: `(types -- ) { Variant(T) ... } ::name union` +// Integer literals +integer ::= decimal | hexadecimal | binary +decimal ::= [0-9]+ (":" type_name)? +hexadecimal ::= "0x" [0-9a-fA-F]+ +binary ::= "0b" [01]+ -**Enums**: `{ Variant value: ... } ::name enum` +// Floating point literals +float ::= [0-9]+ "." [0-9]+ (":" type_name)? -**Traits**: `{ (sig) method: ... } ::identifier trait` +// String literals +string ::= '"' (character | escape_sequence)* '"' +escape_sequence ::= "\n" | "\r" | "\t" | "\\" | '\"' | "\'" | "\0" | "\x" hex_digit hex_digit | "\u{" hex_digit+ "}" -**Trait Impl**: `::identifier { (sig) { body } method: ... } ::identifier impl` +// Boolean literals +boolean ::= "true" | "false" -**Trait Inheritance**: `[ identifier_list ] ::identifier inher { } ::identifier trait` +// Array literals +array ::= "[" (expression)* "]" + +// Token strings +token_string ::= "{" (token)* "}" +``` + +### E.2 Type Expressions + +``` +// Type tuples (stack signatures) +type_tuple ::= "(" type_list "--" type_list ")" +type_list ::= (type)* + +// Generic types +generic_type ::= identifier "<" type_param_list ">" +type_param_list ::= type_param ("," type_param)* +type_param ::= identifier (":" trait_constraint)? +``` + +### E.3 Definitions + +``` +// Function definition +function_def ::= type_tuple (trait_constraint)? token_string identifier_literal "fn" + +// Struct definition +struct_def ::= type_tuple token_string identifier_literal generic_params? "struct" + +// Union definition +union_def ::= type_tuple token_string identifier_literal generic_params? "union" + +// Enum definition +enum_def ::= token_string identifier_literal "enum" + +// Trait definition +trait_def ::= (inheritance)? token_string identifier_literal generic_params? "trait" + +// Trait implementation +trait_impl ::= identifier_literal token_string identifier_literal generic_params? "impl" + +// Trait inheritance +inheritance ::= "[" identifier_list "]" identifier_literal generic_params? "inher" +``` + +### E.4 Control Flow + +``` +// Conditional +if_expr ::= expression token_string token_string "if" + +// While loop +while_expr ::= token_string token_string "while" + +// For loop +for_expr ::= expression expression token_string "for" + +// Match expression +match_expr ::= expression token_string "match" +``` + +### E.5 Complete Grammar Patterns + +**Functions**: `(inputs -- outputs) trait_constraint? { body } ::name fn` + +**Structs**: `(field_types --) { field_names: } ::name struct` + +**Unions**: `(variant_types --) { Variant(T) ... } ::name union` + +**Enums**: `{ Variant value?: ... } ::name enum` + +**Traits**: `inheritance? { (sig) method: ... } ::identifier trait` + +**Trait Impl**: `::trait_id { (sig) { body } method: ... } ::type_id impl` + +**Trait Inheritance**: `[ identifier_list ] ::identifier inher` **If**: `condition { then } { else } if` @@ -1128,4 +1760,6 @@ print // 220 **Match**: `value { pattern => block ... } match` -**Identifier Literal**: `::name` pushes identifier instead of executing +**Lambda**: `{ code } lambda` + +**Identifier Literal**: `::name`