# Stack Language Specification v0.4 ## 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 - Types define what things **are**, traits define how things **act** - All constructs are implicitly generic - **Every operator is defined by a trait** ## 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 ### 2.3 Literals **Integer Literals** ``` 42 // i32 (default) 42 i64 // Annotate as i64 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 \\ \"" ``` **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 ``` **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: - `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 Within TokenStrings, the `::` prefix may be used for clarity when referring to traits, though it's not strictly required since the context determines how identifiers are interpreted. ## 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) ### 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 both types and traits - **Every operator must be backed by a trait** ### 3.3 All Constructs are Generic Every function, struct, and union is implicitly generic. Constraints are specified via traits: ``` // Function generic over any type T (T -- T) { dup * } square fn // Function requiring T to implement Addable trait (T T -- T) Addable { + } add_two fn // Struct generic over field types (T T --) { x: y: } Point struct // Union generic over variant types (T --) { Some(T) None } Option union ``` ## 4. Trait System ### 4.1 Standard Traits Traits define behavioral contracts. Every operator in the language is backed by one or more traits. **Stack Manipulation Traits** ``` { (Self -- Self Self) dup: } Duplicable trait { (Self -- ) drop: } Droppable trait { (Self Self -- Self Self) swap: } Swappable trait { (Self Self -- Self Self Self) over: } Overable trait { (Self Self Self -- Self Self Self) rot: } Rotatable trait { (i32 -- Self) pick: } Pickable trait { (i32 i32 -- ) roll: } Rollable trait { (-- i32) depth: } Inspectable trait ``` **Arithmetic Traits** ``` { (Self Self -- Self) +: (Self Self -- Self) -: } Addable trait { (Self Self -- Self) *: (Self Self -- Self) /: (Self Self -- Self) %: } Multiplyable trait { (Self Self -- Self) ^: } Exponentiable trait { (Self -- Self) log: } Logarithmic trait // log base 10 { (Self -- Self) ln: } NaturalLogarithmic trait // natural log ``` **Comparison Traits** ``` { (Self Self -- bool) >: (Self Self -- bool) >=: (Self Self -- bool) <: (Self Self -- bool) <=: } Orderable trait { (Self Self -- bool) ==: (Self Self -- bool) !=: } Equatable trait // Comparable combines ordering and equality [ Orderable Equatable ] Comparable inher ``` **Logical Operations Traits** ``` { (Self Self -- Self) and: (Self Self -- Self) or: (Self -- Self) not: } Logical trait ``` **Bitwise Operations Traits** ``` { (Self Self -- Self) bitand: (Self Self -- Self) bitor: (Self Self -- Self) bitxor: (Self -- Self) bitnot: (Self i32 -- Self) shl: (Self i32 -- Self) shr: } Bitwise trait ``` **Container Traits** ``` { (-- Self) create: (Self i32 -- T) at: (Self -- i32) length: } ArrayOf trait { (Self Self -- Self) concat: } Concatenable trait { (Self i32 i32 -- Self) slice: } Sliceable trait ``` **String Traits** ``` { (Self Self -- Self) concat: (Self -- i32) length: (Self i32 i32 -- Self) substr: (Self Self -- ArrayOf[Self]) split: } Stringable trait ``` **Conversion Traits** ``` { (Self T -- U) as: } Convertible trait { (Self -- String) str: } Stringifiable trait { (String -- Self) parse: } 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 NaturalLogarithmic ] Number inher ``` **Meta-Traits** Traits for defining and working with traits themselves: ``` { (-- TokenString) name: } Identifier trait { (-- Self) push: } Pushable trait { (TokenString Identifier --) trait: (Identifier TokenString Identifier --) impl: (ArrayOf[Identifier] Identifier --) inher: } Implementable trait ``` ### 4.2 Trait Definition **Syntax**: `{ function_signatures } identifier trait` The identifier can be provided as an identifier literal (`::Name`) or as a regular identifier on the stack. ``` // Using identifier literal { (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 ``` Within the TokenString (the `{ }` block), identifiers like `Self`, `add:`, `draw:` are part of the trait definition syntax. When referencing existing traits within the definition, you may use `::TraitName` for clarity, though the context makes it clear they are trait references. ### 4.3 Trait Implementation **Syntax**: `identifier { method_implementations } identifier impl` ``` // Implement Addable for i32 ::i32 { (Self Self -- Self) { // Native addition implementation } +: (Self Self -- Self) { // Native subtraction implementation } -: } ::Addable impl // Implement Drawable for Rectangle ::Rectangle { (Rectangle -- ) { "Drawing rectangle" print dup width get print height get print } draw: } ::Drawable impl // Implement Addable for Point ::Point { (Point Point -- Point) { over x get over x get + swap y get swap y get + Point } +: (Point Point -- Point) { over x get over x get - swap y get swap y get - Point } -: } ::Addable impl ``` ### 4.4 Trait Inheritance **Syntax**: `[ identifier_list ] identifier inher` ``` // Number inherits from multiple arithmetic traits [ ::Addable ::Multiplyable ] ::BasicNumber inher // Full Number inherits everything numeric [ ::Addable ::Multiplyable ::Exponentiable ::Comparable ::Logarithmic ::NaturalLogarithmic ] ::Number inher // Complex inheritance [ ::Drawable ::Transformable ::Collidable ] ::GameObject inher ``` ### 4.5 Using Traits in Functions ``` // Function requiring Drawable trait (T -- ) Drawable { draw } draw_twice fn // Multiple trait requirements (T -- T) Number Copyable { dup abs swap dup * + } complex_calc fn // Using identifier literals (T T -- T) ::Addable { + } add_values fn ``` ## 5. Stack Operations ### 5.1 Stack Manipulation All stack operations are backed by traits. ``` dup // ( a -- a a ) Duplicate top [Duplicable] drop // ( a -- ) Remove top [Droppable] swap // ( a b -- b a ) Swap top two [Swappable] over // ( a b -- a b a ) Copy second to top [Overable] rot // ( a b c -- b c a ) Rotate three items [Rotatable] ``` ### 5.2 Stack Inspection ``` depth // ( -- n ) Push stack depth [Inspectable] pick // ( n -- x ) Copy nth item to top (0 = top) [Pickable] roll // ( n times -- ) Rotate n items, times times [Rollable] ``` **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. Operators (Postfix) **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 [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 [NaturalLogarithmic] ``` ### 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] ``` ### 6.3 Logical ``` true false and // Logical AND [Logical] true false or // Logical OR [Logical] true not // Logical NOT [Logical] ``` ### 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] ``` ## 7. Functions (Postfix Definition) 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` ``` // Define a square function (i32 -- i32) { dup * } square fn // Use it 5 square // 25 // Multiple inputs and outputs (i32 i32 -- i32 i32) { over over / swap % } divmod fn 10 3 divmod // 3 1 (quotient remainder) ``` ### 7.2 Generic Functions with Trait Constraints **Syntax**: `(type_sig) trait_constraints { body } name fn` ``` // Generic identity - works with any type (T -- T) {} identity fn // Requires T to be Addable (T T -- T) Addable { + } add_values fn // Multiple trait constraints (T U -- U T) Copyable Swappable { swap } swap_generic fn // Multiple type parameters with different traits (T U -- T) Addable Number { dup U as + } add_converted fn // Using identifier literals for clarity (T -- T) ::Number { dup 0 > { } { 0 T as - } if } abs fn ``` ## 8. Control Flow (Postfix) ### 8.1 Conditionals **Syntax**: `condition { then-block } { else-block } if` ``` // 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 max set // 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` ``` // 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 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 loop continue // Skip to next iteration ``` ### 8.4 Match/Pattern Matching **Syntax**: `value { pattern => block ... } match` ``` 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 (Postfix) ### 9.1 Struct Definition **Syntax**: `(field_types -- ) { field_names } name struct` ``` // 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 i32 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 (postfix)**: `struct field get` or `struct value field set` ``` point x get // Get x field point 15.0 x set // Set x field to 15.0 // Chaining point x get 2 * y get + // (point.x * 2) + point.y ``` ### 9.3 Union Definition **Syntax**: `(variant_types -- ) { variants } name union` ``` // 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 Some // Creates Option::Some(42) None // Creates Option::None "success" Ok // Creates Result::Ok("success") "error" Err // Creates Result::Err("error") ``` ### 9.4 Enum Definition **Syntax**: `() { variants } name enum` ``` () { Pending Active Complete } Status enum // Usage Pending // Creates Status::Pending Active // Creates Status::Active ``` ## 10. Memory Management (Postfix) ### 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 ``` // Creation 1 10 range // Create range array [1..10] // Shape operations arr shape // Get shape arr 2 3 reshape // Reshape to 2x3 // Element access arr 2 at // Index access arr 1 3 slice // Slice array ``` ### 11.2 Array Combinators ``` // 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 ``` ### 11.3 Array Arithmetic ``` [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 ``` [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]] ``` ## 12. Eval Operator (Postfix) Execute code dynamically at runtime. ``` // Evaluate string as code "2 3 +" eval // Pushes 5 // Build and execute code "(i32 -- i32) { dup * } square fn" eval 5 square // 25 // Dynamic dispatch operation_name " get" concat eval ``` ## 13. Standard Library Concepts ### 13.1 I/O ``` "Hello" print // Print to stdout "Enter name: " input // Read from stdin "file.txt" read // Read file contents "data" "file.txt" write // Write to file ``` ### 13.2 String Operations ``` "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" ``` ### 13.3 Type Conversion ``` 42 f64 as // Convert i32 to f64 "123" i32 parse // Parse string to i32 3.14 str as // Convert to string ``` ## 14. Complete Examples ### 14.1 Trait Implementation Example ``` // Define the Addable trait using identifier literal { (Self Self -- Self) +: (Self Self -- Self) -: } ::Addable trait // Implement for i32 ::i32 { (Self Self -- Self) { // Native addition } +: (Self Self -- Self) { // Native subtraction } -: } ::Addable impl // Implement for Point ::Point { (Point Point -- Point) { over x get over x get + swap y get swap y get + Point } +: (Point Point -- Point) { over x get over x get - swap y get swap y get - Point } -: } ::Addable impl ``` ### 14.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) log: } ::Logarithmic trait { (Self -- Self) ln: } ::NaturalLogarithmic trait // Number inherits from multiple traits [ ::Addable ::Multiplyable ::Exponentiable ::Logarithmic ::NaturalLogarithmic ] ::Number inher ``` ### 14.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) ``` ### 14.4 Factorial ``` (i32 -- i32) { dup 1 { drop 1 } { dup 1 - factorial * } <= if } factorial fn 5 factorial print // 120 ``` ### 14.5 FizzBuzz ``` (i32 -- ) { 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 ``` ### 14.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 ``` ### 14.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 ``` ### 14.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 ``` ## 15. Syntax Summary ### Complete Grammar Patterns **Functions**: `(in -- out) trait_constraints { body } name fn` **Structs**: `(types -- ) { fields: } name struct` **Unions**: `(types -- ) { Variant(T) ... } name union` **Enums**: `() { Variant ... } name enum` **Traits**: `{ (sig) method: ... } identifier trait` **Trait Impl**: `identifier { (sig) { body } method: ... } identifier impl` **Trait Inheritance**: `[ identifier_list ] identifier inher` **If**: `condition { then } { else } if` **While**: `{ condition } { body } while` **For**: `start end { body } for` **Match**: `value { pattern => block ... } match` **Identifier Literal**: `::name` pushes identifier instead of executing --- **Version**: 0.3 **Status**: Draft Specification - Trait-Backed Operations with Identifier Literals