778 lines
15 KiB
Markdown
778 lines
15 KiB
Markdown
# Stack Language Specification v0.2
|
|
|
|
## 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
|
|
|
|
## 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)
|
|
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
|
|
```
|
|
|
|
## 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:
|
|
```
|
|
Drawable trait // Drawable is a trait
|
|
Addable trait // Addable 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
|
|
|
|
### 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. 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 and // Logical AND
|
|
true false or // Logical OR
|
|
true not // Logical NOT
|
|
```
|
|
|
|
### 5.4 Bitwise
|
|
```
|
|
0xFF 0x0F bitand // Bitwise AND
|
|
0xFF 0x0F bitor // Bitwise OR
|
|
0xFF 0x0F bitxor // Bitwise XOR
|
|
0xFF bitnot // Bitwise NOT
|
|
8 2 shl // Left shift
|
|
8 2 shr // Right shift
|
|
```
|
|
|
|
## 6. Functions (Postfix Definition)
|
|
|
|
Functions are defined in postfix notation. The signature and body come before the name.
|
|
|
|
### 6.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) {
|
|
2dup / -rot %
|
|
} divmod fn
|
|
|
|
10 3 divmod // 3 1 (quotient remainder)
|
|
```
|
|
|
|
### 6.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 copyable
|
|
(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 Numeric {
|
|
dup U as +
|
|
} add_converted fn
|
|
```
|
|
|
|
### 6.3 Function Examples
|
|
|
|
```
|
|
// No-op function
|
|
(-- ) {} noop fn
|
|
|
|
// Factorial (recursive)
|
|
(i32 -- i32) {
|
|
dup 1 { drop 1 } { dup 1 - factorial * } <= if
|
|
} factorial fn
|
|
|
|
// Constrained generic
|
|
(T -- T) Numeric {
|
|
dup 0 > { } { 0 T as - } if
|
|
} abs fn
|
|
```
|
|
|
|
## 7. Control Flow (Postfix)
|
|
|
|
### 7.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
|
|
```
|
|
|
|
### 7.2 Loops
|
|
|
|
**While Loop**
|
|
|
|
**Syntax**: `{ condition-block } { body-block } while`
|
|
|
|
```
|
|
// Sum 1 to 10
|
|
0 1 // sum counter
|
|
{ dup 10 <= } // condition block
|
|
{ // body block
|
|
2dup + // 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
|
|
```
|
|
|
|
### 7.3 Loop Control
|
|
```
|
|
break // Exit loop
|
|
continue // Skip to next iteration
|
|
```
|
|
|
|
### 7.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
|
|
```
|
|
|
|
## 8. Data Structures (Postfix)
|
|
|
|
### 8.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
|
|
```
|
|
|
|
### 8.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
|
|
```
|
|
|
|
### 8.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")
|
|
```
|
|
|
|
### 8.4 Enum Definition
|
|
|
|
**Syntax**: `() { variants } name enum`
|
|
|
|
```
|
|
() {
|
|
Pending
|
|
Active
|
|
Complete
|
|
} Status enum
|
|
|
|
// Usage
|
|
Pending // Creates Status::Pending
|
|
Active // Creates Status::Active
|
|
```
|
|
|
|
## 9. Traits (Postfix)
|
|
|
|
### 9.1 Trait Definition
|
|
|
|
**Syntax**: `{ function_signatures } name trait`
|
|
|
|
```
|
|
// Simple trait
|
|
{
|
|
(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
|
|
```
|
|
|
|
### 9.2 Trait Implementation
|
|
|
|
**Syntax**: `type { method_implementations } trait impl`
|
|
|
|
```
|
|
// Implement Drawable for Rectangle
|
|
Rectangle {
|
|
(Rectangle -- ) {
|
|
"Drawing rectangle" print
|
|
dup width get print
|
|
height get print
|
|
} draw:
|
|
} Drawable impl
|
|
|
|
// Implement Numeric for Point
|
|
Point {
|
|
(Point Point -- Point) {
|
|
over x get over x get +
|
|
-rot y get swap y get +
|
|
Point
|
|
} add:
|
|
|
|
(Point Point -- Point) {
|
|
over x get over x get -
|
|
-rot y get swap y get -
|
|
Point
|
|
} sub:
|
|
|
|
(Point -- Point) {
|
|
dup x get 0 swap - x set
|
|
dup y get 0 swap - y set
|
|
} neg:
|
|
} Numeric impl
|
|
```
|
|
|
|
### 9.3 Using Traits in Functions
|
|
|
|
```
|
|
// Function requiring Drawable trait
|
|
(T -- ) Drawable {
|
|
draw
|
|
} draw_twice fn
|
|
|
|
// Multiple trait requirements
|
|
(T -- T) Numeric Copyable {
|
|
dup abs swap dup * +
|
|
} complex_calc fn
|
|
```
|
|
|
|
## 10. Memory Management (Postfix)
|
|
|
|
### 10.1 Heap Operations
|
|
|
|
```
|
|
// Allocate
|
|
3.0 4.0 Point alloc // ( Point -- ptr<Point> )
|
|
|
|
// Dereference
|
|
ptr deref // ( ptr<T> -- T )
|
|
|
|
// Store (dereference and update)
|
|
new_value ptr store // ( T ptr<T> -- )
|
|
|
|
// Free
|
|
ptr free // ( ptr<T> -- )
|
|
```
|
|
|
|
### 10.2 Example
|
|
|
|
```
|
|
// Create heap-allocated point
|
|
3.0 4.0 Point alloc // Returns ptr<Point>
|
|
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 Factorial
|
|
|
|
```
|
|
(i32 -- i32) {
|
|
dup 1
|
|
{ drop 1 }
|
|
{ dup 1 - factorial * }
|
|
<= if
|
|
} factorial fn
|
|
|
|
5 factorial print // 120
|
|
```
|
|
|
|
### 14.2 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.3 Point with Traits
|
|
|
|
```
|
|
// Define Point struct
|
|
(T T --) { x: y: } Point struct
|
|
|
|
// Define Drawable trait
|
|
{ (Self -- ) draw: } Drawable trait
|
|
|
|
// Implement Drawable for Point
|
|
Point {
|
|
(Point -- ) {
|
|
"Point(" print
|
|
dup x get print
|
|
", " print
|
|
y get print
|
|
")" print
|
|
} draw:
|
|
} Drawable impl
|
|
|
|
// Define distance function (requires Numeric)
|
|
(T T -- T) Numeric {
|
|
over x get over x get - dup *
|
|
swap y get swap y get - dup *
|
|
+ sqrt
|
|
} distance fn
|
|
|
|
// Usage
|
|
3.0 4.0 Point
|
|
5.0 12.0 Point
|
|
distance print // 13.0
|
|
```
|
|
|
|
### 14.4 Generic Container
|
|
|
|
```
|
|
// Define a generic stack container
|
|
(T --) {
|
|
items:
|
|
size:
|
|
} Stack struct
|
|
|
|
// Push function
|
|
(Stack T -- Stack) {
|
|
over items get swap concat
|
|
over size get 1 +
|
|
Stack
|
|
} stack_push fn
|
|
|
|
// Pop function (returns Stack and popped value)
|
|
(Stack -- Stack T) {
|
|
dup items get
|
|
dup length 1 -
|
|
over length 1 - at // Get last item
|
|
-rot 0 swap 1 - slice // Remove last item
|
|
over size get 1 -
|
|
Stack
|
|
swap
|
|
} stack_pop fn
|
|
|
|
// Usage
|
|
[] 0 Stack // Empty stack
|
|
42 stack_push
|
|
100 stack_push
|
|
stack_pop drop // Pop and discard value
|
|
```
|
|
|
|
### 14.5 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
|
|
|
|
// More complex: find max of absolute differences
|
|
[1 5 2 8 3]
|
|
[2 3 7 4 6]
|
|
{ - abs } map2 // Element-wise abs difference
|
|
0 { max } reduce // Find maximum
|
|
print // 4
|
|
```
|
|
|
|
### 14.6 Result Type Usage
|
|
|
|
```
|
|
// Define Result union
|
|
(T E --) { Ok(T) Err(E) } Result union
|
|
|
|
// Function that returns Result
|
|
(i32 i32 -- Result) {
|
|
dup 0 ==
|
|
{ drop "Division by zero" Err }
|
|
{ / Ok }
|
|
if
|
|
} safe_div fn
|
|
|
|
// Use it
|
|
10 2 safe_div {
|
|
Ok(x) => { x print }
|
|
Err(e) => { "Error: " print e print }
|
|
} match
|
|
```
|
|
|
|
## 15. Syntax Summary
|
|
|
|
### Complete Grammar Patterns
|
|
|
|
**Functions**: `(in -- out) constraints { body } name fn`
|
|
|
|
**Structs**: `(types -- ) { fields: } name struct`
|
|
|
|
**Unions**: `(types -- ) { Variant(T) ... } name union`
|
|
|
|
**Enums**: `() { Variant ... } name enum`
|
|
|
|
**Traits**: `{ (sig) method: ... } name trait`
|
|
|
|
**Trait Impl**: `Type { (sig) { body } method: ... } Trait impl`
|
|
|
|
**If**: `condition { then } { else } if`
|
|
|
|
**While**: `{ condition } { body } while`
|
|
|
|
**For**: `start end { body } for`
|
|
|
|
**Match**: `value { pattern => block ... } match`
|
|
|
|
---
|
|
|
|
**Version**: 0.2
|
|
**Status**: Draft Specification - Pure Postfix Edition |