# Stack Language Specification v0.1 ## 1. Overview A statically-typed, stack-based language with 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 - All operations are postfix (RPN) - Stack-based execution (no local variables) - Static typing with type inference - Manual heap memory management - C-like syntax style adapted to postfix notation - Functions manipulate the stack directly ## 2. Lexical Structure ### 2.1 Comments ``` // Single-line comment ``` ### 2.2 Identifiers - Start with letter or underscore: `[a-zA-Z_][a-zA-Z0-9_]*` - Case-sensitive ### 2.3 Literals **Integer Literals** ``` 42 // i32 (default) 42i64 // i64 0xFF // hexadecimal 0b1010 // binary ``` **Floating Point Literals** ``` 3.14 // f64 (default) 3.14f32 // 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 ``` ## 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 to type T ### 3.2 Compound Types **Arrays** ``` [T; N] // Fixed-size array [T] // Dynamic array (heap-allocated) ``` **Structs** ``` struct Point { x: f64, y: f64, } ``` **Tagged Unions** ``` union Result { Ok(T), Err(E), } ``` ### 3.3 Type Inference Types are inferred where possible but can be explicitly annotated: ``` 42 :i64 // Annotate literal x get :f32 // Annotate stack value ``` ## 4. Stack Operations ### 4.1 Stack Manipulation ``` dup // ( a -- a a ) Duplicate top drop // ( a -- ) Remove top swap // ( a b -- b a ) Swap top two over // ( a b -- a b a ) Copy second to top rot // ( a b c -- b c a ) Rotate three items -rot // ( a b c -- c a b ) Rotate three items reverse 2dup // ( a b -- a b a b ) Duplicate top two 2drop // ( a b -- ) Drop top two nip // ( a b -- b ) Drop second tuck // ( a b -- b a b ) Copy top below second ``` ### 4.2 Stack Inspection ``` depth // ( -- n ) Push stack depth pick // ( n -- x ) Copy nth item to top (0 = top) roll // ( n -- ) Move nth item to top ``` ## 5. Operators (Postfix) ### 5.1 Arithmetic ``` 3 4 + // ( a b -- result ) Addition 10 3 - // Subtraction 5 6 * // Multiplication 20 4 / // Division 17 5 % // Modulo 2 8 ** // Exponentiation ``` ### 5.2 Comparison ``` 5 3 > // Greater than 5 3 >= // Greater or equal 5 3 < // Less than 5 3 <= // Less or equal 5 5 == // Equal 5 3 != // Not equal ``` ### 5.3 Logical ``` true false && // Logical AND true false || // Logical OR true ! // Logical NOT ``` ### 5.4 Bitwise ``` 0xFF 0x0F & // Bitwise AND 0xFF 0x0F | // Bitwise OR 0xFF 0x0F ^ // Bitwise XOR 0xFF ~ // Bitwise NOT 8 2 << // Left shift 8 2 >> // Right shift ``` ## 6. Functions Functions consume arguments from the stack and push results to the stack. ### 6.1 Function Definition ``` fn add_point : (Point Point -- Point) { // Stack: p1 p2 swap .x get // p2.x swap .x get // p1.x + // sum_x swap .y get // p2.y swap .y get // p1.y + // sum_y Point::new // Create new Point } ``` ### 6.2 Function Signature Format: `(input_types -- output_types)` ``` fn square : (i32 -- i32) { dup * } fn divmod : (i32 i32 -- i32 i32) { 2dup / -rot % } fn no_op : (-- ) { // Takes nothing, returns nothing } ``` ### 6.3 Generic Functions ``` fn identity : (T -- T) { // Simply returns the input } fn swap_pair : (T U -- U T) { swap } ``` ## 7. Control Flow ### 7.1 Conditionals ``` // if-then condition if { // Executed if true } // if-then-else x 0 > if { // Positive } else { // Non-positive } ``` ### 7.2 Loops **While Loop** ``` // While condition is true { condition } while { // Loop body } // Example: sum 1 to 10 0 1 // sum counter { dup 10 <= } while { 2dup + // Add counter to sum swap 1 + swap // Increment counter } drop // Drop counter, leave sum ``` **For Loop (Range-based)** ``` 1 10 for i { i print } // Equivalent to: 1 10 range each { print } ``` ### 7.3 Loop Control ``` break // Exit loop continue // Skip to next iteration ``` ## 8. Memory Management ### 8.1 Stack vs Heap - Stack: Automatic, fixed-size types - Heap: Manual, dynamic allocations ### 8.2 Heap Operations ``` // Allocate Point::new heap_alloc // ( Point -- ptr ) // Dereference ptr @ // ( ptr -- T ) // Store value ptr ! // ( T ptr -- ) // Free ptr free // ( ptr -- ) ``` ### 8.3 Example ``` // Create heap-allocated point 3.0 4.0 Point::new heap_alloc // ptr dup .x get print // Print x (3.0) free // Clean up ``` ## 9. Data Structures ### 9.1 Struct Definition and Usage ``` struct Rectangle { width: f64, height: f64, } // Constructor (auto-generated) 10.0 20.0 Rectangle::new // Create Rectangle // Field access (postfix) rect .width get // Get width rect .width 15.0 set // Set width // Method-like functions fn Rectangle::area : (Rectangle -- f64) { dup .width get swap .height get * } // Usage rect Rectangle::area // Calculate area ``` ### 9.2 Tagged Unions ``` union Option { Some(T), None, } // Construction 42 Option::Some // Create Some(42) Option::None // Create None // Pattern matching value match { Some(x) => { x print }, None => { "Nothing" print }, } ``` ### 9.3 Enums ``` enum Status { Pending, Active, Complete, } Status::Active // Create enum value ``` ## 10. Traits Traits define shared behavior across types. ### 10.1 Trait Definition ``` trait Drawable { fn draw : (Self -- ); } trait Add { fn add : (Self T -- Self); } ``` ### 10.2 Trait Implementation ``` impl Drawable for Rectangle { fn draw : (Rectangle -- ) { "Drawing rectangle" print dup .width get print .height get print } } impl Add for Point { fn add : (Point Point -- Point) { // Implementation from earlier swap .x get swap .x get + swap .y get swap .y get + Point::new } } ``` ### 10.3 Trait Bounds ``` fn draw_twice : (T -- ) { dup draw draw } ``` ## 11. Array Operations (Uiua-inspired) ### 11.1 Basic Array Operations ``` // Creation [1 2 3 4 5] range // Create range array // Shape operations arr shape // Get shape arr [2 3] reshape // Reshape to 2x3 // Element access arr 2 @ // Index access arr [1 3] slice // Slice array ``` ### 11.2 Array Combinators ``` // Map [1 2 3 4] { 2 * } map // [2 4 6 8] // Filter [1 2 3 4 5] { 2 % 0 == } filter // [2 4] // Reduce [1 2 3 4] 0 { + } reduce // 10 // Each (apply to each element) [[1 2] [3 4]] { sum } each // [3 7] ``` ### 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] ++ // 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 Execute code dynamically at runtime. ``` // Evaluate string as code "2 3 +" eval // Pushes 5 // Build and execute code "fn square : (i32 -- i32) { dup * }" eval 5 square // 25 // Dynamic dispatch operation_name " get" ++ eval // Call function by name ``` **Security Note**: Eval should be used carefully as it can execute arbitrary code. ## 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" ++ // 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 to_f64 // Convert i32 to f64 "123" parse_i32 // Parse string to i32 3.14 to_string // Convert to string ``` ## 14. Example Programs ### 14.1 Factorial ``` fn factorial : (i32 -- i32) { dup 1 <= if { drop 1 } else { dup 1 - factorial * } } 5 factorial print // 120 ``` ### 14.2 FizzBuzz ``` fn fizzbuzz : (i32 -- ) { dup 15 % 0 == if { drop "FizzBuzz" print } else { dup 3 % 0 == if { drop "Fizz" print } else { dup 5 % 0 == if { drop "Buzz" print } else { print } } } } 1 100 for i { i fizzbuzz } ``` ### 14.3 Using Structs and Traits ``` struct Circle { radius: f64, } impl Drawable for Circle { fn draw : (Circle -- ) { "Circle with radius: " print .radius get print } } fn Circle::area : (Circle -- f64) { .radius get 2.0 ** 3.14159 * } // Usage 5.0 Circle::new dup draw // Draw the circle Circle::area print // Print area ``` ### 14.4 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 ``` ## 15. Implementation Notes ### 15.1 Type Checking - Perform static type checking with full type inference - Track stack types at compile time - Ensure function signatures match actual stack effects ### 15.2 Interpreter Design - Value stack: runtime execution stack - Type stack: compile-time type tracking - Call stack: function call management - Heap: global allocator ### 15.3 Future Compilation - Compile to bytecode for interpretation - Potential LLVM backend for native compilation - Stack optimization for register allocation ## 16. Syntax Summary ### Stack Manipulation ``` dup drop swap over rot pick roll ``` ### Arithmetic (postfix) ``` a b + a b - a b * a b / a b % a b ** ``` ### Comparison ``` a b < a b > a b <= a b >= a b == a b != ``` ### Control Flow ``` cond if { ... } cond if { ... } else { ... } { cond } while { ... } start end for var { ... } ``` ### Functions ``` fn name : (inputs -- outputs) { body } fn name : (T U -- U) { body } ``` ### Memory ``` value heap_alloc ptr @ value ptr ! ptr free ``` ### Arrays ``` [1 2 3] arr { fn } map arr { fn } filter arr init { fn } reduce ``` --- **Version**: 0.1 **Status**: Draft Specification **License**: Define your license here