# Stack Language Specification **Version**: 0.7.1 **Status**: Draft Specification **Changes**: - 0.5 (AI) 1. **Escape sequences** - Added a complete list of escape sequences for string literals 2. **Type Tuples** - Defined them as function signatures representing stack effects 3. **Control flow TokenStrings** - Clarified that `if`, `while`, `match`, etc. use TokenStrings 4. **Generic constructs** - Clarified that generics need trait constraints when operations are performed 5. **Stack manipulation traits** - Combined into a single `Stackable` trait 6. **Size trait** - Added proper definition inheriting from `Addable`, `Comparable`, and `Convertible` 7. **Empty traits** - Clarified that traits can be empty (especially when used with inheritance) 8. **Trait inheritance** - Fixed syntax to require both `inher` and `trait` declarations 9. **Array combinators** - Clarified that the functions inside parse their TokenStrings 10. **`::` in TokenStrings** - Clarified it should NOT be used in trait/impl contexts - 0.5.1 (Human) 1. Created TODOs 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 - 0.6.1 (AI) 1. **Variadic arguments** - Decision: Use array syntax for variable arguments (no special variadic syntax yet) 2. **Inheritance before trait** - Decision: Yes, inheritance declarations must come before trait definition 3. **`inher` operator** - Decision: No, merge inheritance into trait operator (removed `inher`) 4. **Separate `inher` vs `impl`** - Decision: Keep them separate (impl is for implementations only) - 0.6.2 (Human) 1. Created TODOs 2. Made various corrections (not everything was corrected) 3. Reviewed and corrected some code blocks 4. Made a few adjustments manually 5. Reversed removing `inher` - 0.7 (AI) 1. **Operator definition** - Clarified that operators can be user/library defined via trait implementation 2. **Generic function syntax** - Fixed to use trait constraints in type tuple, not generic parameters 3. **Variable arguments with Iterable** - Changed array syntax to Iterable trait for variable args 4. **Example classifications** - Cleaned up "Actual Language Definitions" vs examples distinction 5. **Struct field access** - Clarified that get and set consume their arguments 6. **Section 6 rename** - Renamed "Operators (Postfix)" to "Built-in Operators" 7. **Module syntax** - Added `::` prefix for module imports 8. **Module alias options** - Added multiple alias syntax options - 0.7.1 (Human) 1. Formatting changes - 0.7.2 (Human) 1. Removed AI editing restrictions of reviewed code blocks --- ## 1. Overview A statically-typed, stack-based language with pure postfix notation combining the execution model of HP's RPL, the type system of C and Rust, and modern array operations from Uiua. ### Design Principles - Everything is postfix - no exceptions - Stack-based execution (no local variables) - Static typing with type inference - 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 operations that implement trait methods. They can be: - Built-in primitive operations provided by the language - User-defined operations implementing custom trait methods - Library-defined operations - All operators must be backed by a trait - Cannot share names with functions - Are the fundamental building blocks of the language - Examples: `+`, `-`, `dup`, `swap`, `if`, `while` (built-in); custom operators via trait implementation **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 ``` // Single-line comment ``` ### 2.2 Identifiers **Regular Identifiers** - Start with letter or underscore: `[a-zA-Z_][a-zA-Z0-9_]*` - Case-sensitive - When encountered, identifiers are executed immediately **Identifier Literals** - Prefix with `::` to push the identifier itself onto the stack instead of executing it - Syntax: `::name` pushes the identifier `name` as a value - 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** ``` 42 // i64 (default) 42:i32 // Annotate as i32 0xFF // hexadecimal 0b1010 // binary ``` **Floating Point Literals** ``` 3.14 // f64 (default) 3.14:f32 // Annotate as f32 ``` **String Literals** ``` "hello world" "escape sequences: \n \t \\ \"" ``` **Escape Sequences** - `\n` - Newline (LF) - `\r` - Carriage return (CR) - `\t` - Tab - `\\` - Backslash - `\"` - Double quote - `\'` - Single quote - `\0` - Null character - `\xNN` - Hexadecimal byte (e.g., `\x41` for 'A') - `\u{NNNN}` - Unicode code point (e.g., `\u{1F600}` for 😀) **Boolean Literals** ``` true false ``` **Array Literals** ``` [1 2 3 4 5] // array of i32 [1.0 2.0 3.0] // array of f64 [[1 2] [3 4]] // 2D array ``` **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) ``` **Variable Arguments**: For operations that need variable numbers of arguments, use the `Iterable` trait: ``` (-- Size) depth: // Zero arguments, returns stack depth (String Iterable --) printf: // String plus iterable of printable values (Iterable -- T) sum: // Iterable of values, returns sum ``` This approach: - Keeps the type system simple (no special variadic syntax) - Works with arrays, ranges, and other iterable types - Trait-based, consistent with language design **Usage Examples**: ``` "x=%d, y=%d, z=%d" [x y z] printf // Format string with array of values [1 2 3 4 5] sum // Sum array of numbers 1 100 range sum // Sum range (also iterable) depth print // No arguments needed ``` **Token Strings** ``` { code here } // TokenString - lexed but not parsed/executed ``` 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: **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) **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 ### 3.1 Primitive Types - `i8`, `i16`, `i32`, `i64` - Signed integers - `u8`, `u16`, `u32`, `u64` - Unsigned integers - `f32`, `f64` - Floating point - `bool` - Boolean - `char` - Single character (UTF-8) - `ptr` - Raw pointer (generic over pointed type) - **Future feature, see Appendix** ### 3.2 Types vs Traits **Types** define the concrete structure and memory layout: - `Point struct` - Point is a type - `Rectangle struct` - Rectangle is a type **Traits** define behavioral contracts - how things act: - `{ ... } ::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) - Types are concrete; traits are interfaces - Functions can be generic over traits - Functions can have types and traits defined as return types - Every operator must be backed by a trait ### 3.3 Generic Constructs 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. **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. ``` // Function generic over any type with Multiplyable constraint (T -- T) { dup * } ::square fn // Struct generic over field type T (T T --) { x: y: } ::Point struct // Union generic over variant type T (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) (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. See Appendix A for complete trait definitions. **Stack Manipulation Trait** The `Stackable` trait provides fundamental stack manipulation operations: ``` { (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, the item before the size is 1) (Size Size -- ) roll: // Rotate n items, times times (-- Size) depth: // Push current stack depth } ::Stackable trait ``` **Size Trait** The `Size` trait represents types suitable for indexing and sizing operations: ``` [ ::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** ``` // Addition and subtraction operations { (Self Self -- Self) +: // Add two values (Self Self -- Self) -: // Subtract two values } ::Addable 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 // Exponentiation operations { (Self Self -- Self) ^: // Raise to power } ::Exponentiable 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** ``` // 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 { } ::Comparable trait ``` **Logical Operations Traits** ``` // 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** ``` // 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** ``` // Size information { (Self -- i64) length: // Get length/size of container } ::Sized trait // Element selection { (Self Size -- T) at: // Access element at index } ::Selectable trait // Concatenation { (Self Self -- Self) concat: // Concatenate two containers } ::Concatenable trait // Slicing { (Self Size Size -- Self) slice: // Extract slice from start to end } ::Sliceable trait // ArrayOf combines container operations [ ::Sized ::Selectable ::Sliceable ] ::ArrayOf inher { } ::ArrayOf trait ``` **String Traits** ``` // String operations [ ::Concatenable ] ::String inher { (Self Size Size -- Self) substr: // Extract substring (Self Self -- ArrayOf) split: // Split by delimiter } ::String trait ``` **Conversion Traits** ``` // 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 // String conversion { (Self -- String) to_str: // Convert to string representation } ::Stringifiable trait // Parse from string { (String -- Self) parse: // Parse from string } ::Parseable trait ``` **Numeric Composite Trait** The `Number` trait represents the full suite of numeric operations by inheriting from multiple traits: ``` [ ::Addable ::Multiplyable ::Exponentiable ::Comparable ::Logarithmic ] ::Number inher { } ::Number trait ``` **Meta-Traits** Traits for defining and working with traits themselves: ``` // Marks identifiers { } ::Identifier 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 (marker traits). **Examples**: ``` // Trait with methods (no inheritance) { (Self -- ) draw: } ::Drawable trait // Trait with multiple methods { (Self Self -- Self) add: (Self Self -- Self) sub: (Self -- Self) neg: } ::Numeric trait // Generic trait { (Self T -- Self) append: (Self -- T) pop: } ::Container trait // Empty trait (marker trait, no inheritance) { } ::Serializable trait // Trait with inheritance (no additional methods) [ ::Orderable ::Equatable ] ::Comparable inher { } ::Comparable trait // Trait with inheritance and additional methods [ ::Drawable ::Transformable ] ::GameObject inher { (Self -- ) update: (Self -- ) destroy: } ::GameObject 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 **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 **Examples**: ``` // Implement Addable for i32 ::Addable { (Self Self -- Self) { // Native addition implementation } +: (Self Self -- Self) { // Native subtraction implementation } -: } ::i32 impl // Implement Drawable for Rectangle ::Drawable { (Self -- ) { "Drawing rectangle" print dup ::width get print ::height get print } draw: } ::Rectangle impl ``` ``` // Implement Addable for Point ::Addable { (Self Self -- Self) { over ::x get over ::x get + 3 pick ::y get 3 pick ::y get + Point } +: (Self Addable -- Self) { over ::x get over + 3 pick ::y get 3 pick + Point } +: (Addable Self -- Self) { over over ::x get + 3 pick 3 pick ::y get + Point } +: (Self Self -- Self) { over ::x get over ::x get - 3 pick ::y get 3 pick ::y get - Point } -: (Self Addable -- Self) { over ::x get over - 3 pick ::y get 3 pick - Point } -: } ::Point impl // Implement Logical for everything (default implementation) ::Logical { (Self -- bool) { true } truthy: (Self Self -- Self) { over truthy { } { swap } if drop } and: (Self Self -- Self) { over truthy { swap } { } if drop } or: } ::Logical impl // Overload Logical for bool ::Logical { (Self -- Self) { } truthy: } ::bool impl // Overload Logical for Numeric ::Logical { (Self -- bool) { 0 != } truthy: } ::Number impl // Overload Logical for Option ::Logical { (Self -- bool) { { Some(_) => { true } None => { false } } match } truthy: } ::Option impl // Overload Logical for Result ::Logical { (Self -- bool) { { Ok(_) => { true } Err(_) => { false } } match } truthy: } ::Result impl ``` ### 4.4 Trait Inheritance **Syntax**: `[ identifier_list ] ::identifier? inher { methods } ::identifier? trait` Trait inheritance is specified by providing an array of trait identifiers, followed by the trait identifier and the `inher` operator, then the trait body and trait definition. **Examples**: ``` // Combine multiple arithmetic traits [ ::Addable ::Multiplyable ] ::BasicNumber inher { } ::BasicNumber trait // Full Number inherits everything numeric [ ::Addable ::Multiplyable ::Exponentiable ::Comparable ::Logarithmic ] ::Number inher { } ::Number trait // Inheritance with additional methods [ ::Drawable ::Transformable ::Collidable ] ::GameObject inher { (Self -- ) update: (Self -- ) destroy: } ::GameObject trait // Size trait with composite behavior [ ::Addable ::Comparable ::Convertible ] ::Size inher { } ::Size trait // String trait inheriting and adding methods [ ::Concatenable ] ::String inher { (Self Size Size -- Self) substr: (Self Self -- ArrayOf) split: } ::String trait ``` **Generic Trait Inheritance**: When inheriting from generic traits, you must either make the inheriting trait similarly generic or specify concrete types: ``` // Inheriting trait is also generic (generic parameter matches) [ ::Container ] ::Stack inher { (Self -- T) pop: } ::Stack trait // Inheriting trait specifies concrete type [ ::Container ] ::IntStack inher { (Self -- i32) pop: } ::IntStack trait // Multiple generic inheritance [ ::Selectable ::Sized ::Sliceable ] ::ArrayOf inher { } ::ArrayOf trait ``` ### 4.5 Using Traits in Functions **Examples**: ``` // Function requiring Drawable trait (Drawable -- ) { draw } ::draw_twice fn // Function requiring multiple trait bounds (Number Number -- Number) { dup * swap dup * + // Pythagorean: a² + b² } ::sum_of_squares fn ``` ## 5. Stack Operations ### 5.1 Stack Manipulation All stack operations are backed by the `Stackable` trait. ``` 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 current stack depth pick // ( n -- x ) Copy nth item to top (0 = top) roll // ( n times -- ) Rotate n items, times times ``` **Roll Examples**: ``` // Stack: a b c d e 3 1 roll // Rotate top 3 items once: a b d e c 3 2 roll // Rotate top 3 items twice: a b e c d 5 1 roll // Rotate all 5 items once: b c d e a 4 3 roll // Rotate top 4 items three times: a d e c b ``` ## 6. Built-in Operators Every operator is backed by a trait and must be implemented for types that use it. ### 6.1 Arithmetic ``` 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 > // ( 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 // ( 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 // ( 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 Functions are defined in postfix notation. The signature and body come before the name. ### 7.1 Basic Function Definition **Syntax**: `(inputs -- outputs) { body } ::name fn` **Examples**: ``` // Define a square function (requires Multiplyable trait) (Multiplyable -- Multiplyable) { dup * } ::square fn // Use it 5 square // 25 // Multiple inputs and outputs (Number Number -- Number Number) { over over / swap % } ::divmod fn 10 3 divmod // 3 1 (quotient remainder) ``` ### 7.2 Generic Functions with Trait Constraints **Syntax**: `(type_sig) { body } ::name fn` **Examples**: ``` // Generic identity - works with any type (no operations, no constraint needed) (T -- T) { } ::identity fn // Requires Addable - use trait name in type tuple (Addable Addable -- Addable) { + } ::add_values fn // Requires Number (Number -- Number) { dup 0 > { } { 0 swap - } if } ::abs fn ``` ## 8. Control Flow ### 8.1 Conditionals **Syntax**: `condition { then-block } { else-block } if` The `if` operator parses both TokenStrings as code blocks (then/else branches). **Examples**: ``` // if-then (else block is empty) x 0 > { "positive" print } {} if // if-then-else x 0 > { "positive" print } { "non-positive" print } if // The condition comes first, then both blocks, then 'if' a b > { a } { b } if // Nested x 0 > { y 0 > { "both positive" print } { "x positive, y not" print } if } { "x not positive" print } if ``` ### 8.2 Loops **While Loop** **Syntax**: `{ condition-block } { body-block } while` The `while` operator parses both TokenStrings as code blocks (condition/body). **Examples**: ``` // Sum 1 to 10 0 1 // sum counter { dup 10 <= } // condition block { // body block over over + // Add counter to sum swap 1 + swap // Increment counter } while drop // Drop counter, leave sum // Infinite loop with break { true } { // body condition { break } {} if } while ``` **For Loop** **Syntax**: `start end { body-with-counter } for` The `for` operator parses the TokenString as a code block (loop body). **Examples**: ``` // The loop variable is implicitly pushed to stack in each iteration 1 10 { // Stack has loop counter on top dup print } for // More complex 1 100 { dup fizzbuzz } for ``` ### 8.3 Loop Control ``` 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. **Examples**: ``` value { Some(x) => { x print } None => { "Nothing" print } } match // With multiple patterns status { Pending => { "Waiting" print } Active => { "Running" print } Complete => { "Done" print } } match ``` ## 9. Data Structures ### 9.1 Struct Definition **Syntax**: `(field_types -- ) { field_names } ::name struct` **Examples**: ``` // Define Point struct - generic over coordinate types (T T --) { x: y: } ::Point struct // Use with specific types 3.0 4.0 Point // Creates Point with f64 fields 3 4 Point // Creates Point with i64 fields // More complex struct (T U V --) { width: height: depth: } ::Box3D struct 10.0 20.0 30.0 Box3D ``` ### 9.2 Struct Field Access **Syntax**: - **get**: `struct ::field get` consumes struct and field identifier, returns field value - **set**: `value ::field set` consumes value and field identifier, returns modified struct **Examples**: ``` point ::x get // Get x field (consumes point and ::x) 15.0 ::x set // Set x field to 15.0 (consumes value and ::x) // Chaining with duplication point dup ::x get 2 * over ::y get + // (point.x * 2) + point.y ``` ### 9.3 Union Definition **Syntax**: `(variant_types -- ) { variants } ::name union` **Examples**: ``` // Option type - generic over T (T --) { Some(T) None } ::Option union // Result type - generic over T and E (T E --) { Ok(T) Err(E) } ::Result union // Create union values 42 Option::Some // Creates Option::Some(42) Option::None // Creates Option::None "success" Result::Ok // Creates Result::Ok("success") "error" Result::Err // Creates Result::Err("error") ``` ### 9.4 Enum Definition **Syntax**: `{ variants } ::name enum` **Examples**: ``` { Pending 1: // Normally starts at 0 Active: // Defaults to 2 (one plus the last) Complete 0: } ::Status enum // Usage Status::Pending // Creates Status::Pending Status::Active // Creates Status::Active ``` ## 10. Array Operations ### 10.1 Basic Array Operations **Examples**: ``` // Creation 1 10 range // Create range array [1..10] // Shape operations arr shape // Get shape of array arr 2 3 reshape // Reshape to 2x3 // Element access arr 2 at // Access element at index 2 arr 1 3 slice // Slice from index 1 to 3 ``` ### 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. **Examples**: ``` // Map - apply function to each element [1 2 3 4] { 2 * } map // [2 4 6 8] // Filter - keep elements matching predicate [1 2 3 4 5] { 2 % 0 == } filter // [2 4] // Reduce - fold with function [1 2 3 4] 0 { + } reduce // 10 // Each - apply to each element (side effects) [[1 2] [3 4]] { sum print } each ``` ### 10.3 Array Arithmetic **Examples**: ``` [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] ``` ### 10.4 Array Manipulation **Examples**: ``` [1 2 3] [4 5 6] concat // Concatenate: [1 2 3 4 5 6] [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]] ``` ## 11. Eval Operator Execute code dynamically at runtime. The `eval` operator parses and executes its TokenString argument immediately. **Examples**: ``` // Evaluate string as code "2 3 +" eval // Pushes 5 // Build and execute code "(Multiplyable -- Multiplyable) { dup * } ::square fn" eval 5 square // 25 // Dynamic dispatch operation_name " get" concat eval ``` ## 12. Standard Library All standard library functions and traits are automatically in scope (no imports needed in current version). See Appendix C for future module system design. ### 12.1 I/O **Examples**: ``` "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 ``` ### 12.2 String Operations **Examples**: ``` "hello" " world" concat // Concatenate: "hello world" "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" ``` ### 12.3 Type Conversion Type conversion uses explicit conversion functions: **Examples**: ``` 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" ``` --- ## Appendix A: Complete Trait Definitions 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 // Iterable { // Get next item (Self -- Self Option) next: } ::Iterable 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: ``` (Multiplyable -- Multiplyable) { dup * } ::square fn // Enforced 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 (using :: prefix) ::std::math use // Import specific items ::std::collections::HashMap use // Import with alias - Option 1: Inline alias ::std::io::File ::F as use // Import with alias - Option 2: Separate alias operator ::std::io::File ::F use_as // Import with alias - Option 3: Block syntax { ::std::io::File ::F as } 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 ``` // Define the Addable trait { (Self Self -- Self) +: (Self Self -- Self) -: } ::Addable trait // Implement for i32 ::Addable { (Self Self -- Self) { // Native addition } +: (Self Self -- Self) { // Native subtraction } -: } ::i32 impl // Implement for Point ::Addable { (Self Self -- Self) { over ::x get over ::x get + swap ::y get swap ::y get + Point } +: (Self Self -- Self) { over ::x get over ::x get - swap ::y get swap ::y get - Point } -: } ::Point impl ``` ### D.2 Trait Inheritance Example ``` // Define base traits { (Self Self -- Self) +: (Self Self -- Self) -: } ::Addable trait { (Self Self -- Self) *: (Self Self -- Self) /: } ::Multiplyable trait { (Self Self -- Self) ^: } ::Exponentiable trait { (Self Self -- Self) logb: (Self -- Self) log: (Self -- Self) ln: } ::Logarithmic trait // Number inherits from multiple traits [ ::Addable ::Multiplyable ::Exponentiable ::Comparable ::Logarithmic ] ::Number inher { } ::Number trait ``` ### D.3 Logarithm Usage ``` // Calculate log base 10 100 log print // 2.0 1000 log print // 3.0 // Calculate natural logarithm 2.718 ln print // ~1.0 7.389 ln print // ~2.0 // Combine with other operations 10 3 ^ log print // 3.0 (log of 1000) ``` ### D.4 Factorial ``` (Number -- Number) { dup 1 { drop 1 } { dup 1 - factorial * } <= if } ::factorial fn 5 factorial print // 120 ``` ### D.5 FizzBuzz ``` (Number -- ) { dup 15 % 0 == { drop "FizzBuzz" print } { dup 3 % 0 == { drop "Fizz" print } { dup 5 % 0 == { drop "Buzz" print } { print } if } if } if } ::fizzbuzz fn 1 100 { fizzbuzz } for ``` ### D.6 Using Roll ``` // Stack: 1 2 3 4 5 3 1 roll // Rotate top 3 once: 1 2 4 5 3 3 2 roll // Rotate top 3 twice: 1 2 5 3 4 // More complex example 10 20 30 40 50 4 2 roll // Rotate top 4, twice: 10 30 40 50 20 ``` ### D.7 Array Processing ``` // Sum of squares of even numbers from 1 to 10 [1 2 3 4 5 6 7 8 9 10] { 2 % 0 == } filter // Keep even numbers { dup * } map // Square each 0 { + } reduce // Sum print // 220 ``` ### D.8 Identifier Literals in Practice ``` // Push identifier literal to stack ::Point // Pushes identifier "Point" // Use with trait definition { (Self -- ) draw: } ::Drawable trait // Use with struct definition (T T --) { x: y: } ::Point struct // Dynamic trait implementation ::MyType { ... } ::MyTrait impl ``` --- ## Appendix E: Grammar Summary ### E.1 Lexical Elements ``` // Comments line_comment ::= "//" // Identifiers identifier ::= [a-zA-Z_][a-zA-Z0-9_]* identifier_literal ::= "::" identifier // Integer literals integer ::= decimal | hexadecimal | binary decimal ::= [0-9]+ (":" type_name)? hexadecimal ::= "0x" [0-9a-fA-F]+ binary ::= "0b" [01]+ // Floating point literals float ::= [0-9]+ "." [0-9]+ (":" type_name)? // String literals string ::= '"' (character | escape_sequence)* '"' escape_sequence ::= "\n" | "\r" | "\t" | "\\" | '\"' | "\'" | "\0" | "\x" hex_digit hex_digit | "\u{" hex_digit+ "}" // Boolean literals boolean ::= "true" | "false" // 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 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) { body } ::name fn` **Structs**: `(field_types --) { field_names: } ::name struct` **Unions**: `(variant_types --) { Variant(T) ... } ::name union` **Enums**: `{ Variant value?: ... } ::name enum` **Traits**: `{ (sig) method: ... } ::identifier? trait` **Trait Impl**: `::trait_id { (sig) { body } method: ... } ::type_id? impl` **Trait Inheritance**: `[ identifier_list ] ::identifier inher { } ::identifier trait` **If**: `condition { then } { else } if` **While**: `{ condition } { body } while` **For**: `start end { body } for` **Match**: `value { pattern => block ... } match` **Lambda**: `{ code } lambda` **Identifier Literal**: `::name`