3786 lines
99 KiB
Markdown
3786 lines
99 KiB
Markdown
# Stack Language Specification
|
|
|
|
**Version**: 0.8
|
|
**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
|
|
- 0.8 (AI)
|
|
1. **Document reorganization** - Restructured for user-focused learning
|
|
2. **Section consolidation** - Moved implementation details to appendices
|
|
3. **Minimal duplication** - Added cross-references instead of repeating content
|
|
4. **Shorter sections** - Split large sections into focused subsections
|
|
5. **New appendices** - Added Standard Library and Operator references
|
|
6. **Tutorial content** - Added beginner tutorials to Appendix G
|
|
7. **Trait reference** - Consolidated all trait definitions in Appendix B
|
|
8. **Grammar simplification** - Referenced Implementable trait instead of repeating
|
|
|
|
---
|
|
|
|
## 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.
|
|
|
|
### Document Organization
|
|
|
|
This specification is organized to support both learning and reference:
|
|
|
|
**Sections 1-7** cover the fundamentals needed to write basic programs:
|
|
- Lexical structure, primitive types, basic operations
|
|
- Functions and control flow
|
|
- Data structures
|
|
|
|
**Sections 8-10** cover intermediate concepts:
|
|
- Type system formalization
|
|
- Trait system for behavioral contracts
|
|
- Generic programming
|
|
|
|
**Section 11** covers advanced topics:
|
|
- Dynamic code evaluation
|
|
- Identifier literals
|
|
- Standard library overview
|
|
|
|
**Appendices** provide complete references:
|
|
- A: Standard Library (alphabetical reference)
|
|
- B: Complete Trait Reference (all trait definitions)
|
|
- C: Complete Operator Reference (all operators)
|
|
- D: Grammar Summary
|
|
- E: Module System (future)
|
|
- F: Memory Management (future)
|
|
- G: Examples & Tutorials
|
|
|
|
### Reading Guide
|
|
|
|
**New users**: Start with Sections 1-7 to learn the language basics. Work through the tutorials in Appendix G as you go.
|
|
|
|
**Experienced programmers**: Skim Sections 1-4, focus on Sections 5-11 for language-specific features.
|
|
|
|
**Implementers**: Read all sections, paying special attention to Sections 8-10 and Appendices B-D for complete specifications.
|
|
|
|
**Reference lookup**: Use Appendices A-C for quick reference to standard library functions, traits, and operators.
|
|
|
|
---
|
|
|
|
## 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
|
|
|
|
> **Advanced Usage**: See Section 11.2 for complete identifier literal rules and context-dependent behavior.
|
|
|
|
### 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
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Primitive Types
|
|
|
|
The language provides several built-in primitive types for common values:
|
|
|
|
**Integer Types**
|
|
- `i8`, `i16`, `i32`, `i64` - Signed integers (8, 16, 32, 64 bits)
|
|
- `u8`, `u16`, `u32`, `u64` - Unsigned integers (8, 16, 32, 64 bits)
|
|
- Default integer literal type: `i64`
|
|
|
|
**Floating Point Types**
|
|
- `f32` - Single-precision floating point (32 bits)
|
|
- `f64` - Double-precision floating point (64 bits)
|
|
- Default floating point literal type: `f64`
|
|
|
|
**Other Types**
|
|
- `bool` - Boolean values (`true` or `false`)
|
|
- `char` - Single UTF-8 character
|
|
|
|
**Type Annotations**
|
|
|
|
You can explicitly annotate literal types:
|
|
```
|
|
42:i32 // 32-bit integer
|
|
3.14:f32 // 32-bit float
|
|
```
|
|
|
|
**Pointer Types**
|
|
|
|
Raw pointers (`ptr`) are a future feature. See Appendix F for the planned pointer type system.
|
|
|
|
> **Related**: See Section 8 for the complete type system, including composite types and type inference.
|
|
|
|
---
|
|
|
|
## 4. Basic Operations
|
|
|
|
### 4.1 Stack Operations
|
|
|
|
Stack manipulation is fundamental to the language. All values exist on the stack, and these operations let you rearrange them.
|
|
|
|
**Basic Manipulation**
|
|
```
|
|
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
|
|
```
|
|
|
|
**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
|
|
```
|
|
|
|
**Stack Effect Notation**: Throughout this specification, comments use stack effect notation to show what operations consume and produce. The format is `// ( before -- after )` where items on the left of `--` are consumed from the stack, and items on the right are produced.
|
|
|
|
**Examples**:
|
|
```
|
|
5 dup // => 5 5
|
|
5 10 swap // => 10 5
|
|
1 2 3 rot // => 2 3 1
|
|
1 2 3 depth // => 1 2 3 3
|
|
```
|
|
|
|
> **Implementation Details**: Stack operations implement the `::Stackable` trait. See Appendix B for the complete trait definition.
|
|
|
|
### 4.2 Arithmetic Operators
|
|
|
|
Basic arithmetic operations work on numeric types:
|
|
|
|
```
|
|
3 4 + // ( a b -- result ) Addition
|
|
10 3 - // ( a b -- result ) Subtraction
|
|
5 6 * // ( a b -- result ) Multiplication
|
|
20 4 / // ( a b -- result ) Division
|
|
17 5 % // ( a b -- result ) Modulo (remainder)
|
|
2 8 ^ // ( a b -- result ) Exponentiation
|
|
100 log // ( a -- result ) Logarithm base 10
|
|
2.718 ln // ( a -- result ) Natural logarithm
|
|
```
|
|
|
|
**Examples**:
|
|
```
|
|
10 5 + // => 15
|
|
10 3 / // => 3
|
|
10 3 % // => 1
|
|
2 10 ^ // => 1024
|
|
```
|
|
|
|
> **Implementation Details**: Arithmetic operators implement the `::Addable`, `::Multiplyable`, `::Exponentiable`, and `::Logarithmic` traits. See Appendix B for complete trait definitions and Appendix C for the full operator reference.
|
|
|
|
### 4.3 Comparison Operators
|
|
|
|
Comparison operations return boolean values:
|
|
|
|
```
|
|
5 3 > // ( a b -- bool ) Greater than
|
|
5 3 >= // ( a b -- bool ) Greater or equal
|
|
5 3 < // ( a b -- bool ) Less than
|
|
5 3 <= // ( a b -- bool ) Less or equal
|
|
5 5 == // ( a b -- bool ) Equal
|
|
5 3 != // ( a b -- bool ) Not equal
|
|
```
|
|
|
|
**Examples**:
|
|
```
|
|
10 5 > // => true
|
|
10 10 == // => true
|
|
10 5 < // => false
|
|
```
|
|
|
|
> **Implementation Details**: Comparison operators implement the `::Orderable` and `::Equatable` traits. See Appendix B for complete trait definitions.
|
|
|
|
### 4.4 Logical Operators
|
|
|
|
Logical operations work with boolean values and truthiness:
|
|
|
|
```
|
|
true false and // ( a b -- result ) Logical AND
|
|
true false or // ( a b -- result ) Logical OR
|
|
true not // ( a -- result ) Logical NOT
|
|
```
|
|
|
|
**Truthiness**: Non-boolean values can be tested for truthiness. By default, most values are truthy. Numbers are falsy when zero, `Option::None` is falsy, `Result::Err` is falsy.
|
|
|
|
**Examples**:
|
|
```
|
|
true true and // => true
|
|
true false or // => true
|
|
false not // => true
|
|
5 0 and // => 0 (falsy)
|
|
```
|
|
|
|
> **Implementation Details**: Logical operators implement the `::Logical` trait. See Appendix B for the complete trait definition and truthiness rules.
|
|
|
|
### 4.5 Bitwise Operators
|
|
|
|
Bitwise operations work on integer types:
|
|
|
|
```
|
|
0xFF 0x0F bitand // ( a b -- result ) Bitwise AND
|
|
0xFF 0x0F bitor // ( a b -- result ) Bitwise OR
|
|
0xFF 0x0F bitxor // ( a b -- result ) Bitwise XOR
|
|
0xFF bitnot // ( a -- result ) Bitwise NOT
|
|
8 2 shl // ( a n -- result ) Left shift
|
|
8 2 shr // ( a n -- result ) Right shift
|
|
```
|
|
|
|
**Examples**:
|
|
```
|
|
0xFF 0x0F bitand // => 0x0F
|
|
0xF0 0x0F bitor // => 0xFF
|
|
0xFF bitnot // => 0xFFFFFFFFFFFFFF00 (on 64-bit)
|
|
4 2 shl // => 16
|
|
```
|
|
|
|
> **Implementation Details**: Bitwise operators implement the `::Bitwise` trait. See Appendix B for the complete trait definition.
|
|
|
|
---
|
|
|
|
## 5. Functions
|
|
|
|
Functions are user-defined procedures that encapsulate reusable code. They are the primary abstraction mechanism in the language.
|
|
|
|
### 5.1 What are Functions
|
|
|
|
Functions differ from operators:
|
|
- **Operators** implement trait methods and are the fundamental building blocks
|
|
- **Functions** are user-defined procedures that use operators
|
|
- Operators and functions cannot share names
|
|
|
|
> **Related**: See Section 1 "Operators vs Functions" for a complete explanation of the distinction.
|
|
|
|
### 5.2 Defining Functions
|
|
|
|
**Syntax**: `(inputs -- outputs) { body } ::name fn`
|
|
|
|
The function signature specifies stack effects (what is consumed and produced), the body contains the implementation, and the name identifies the function.
|
|
|
|
**Examples**:
|
|
```
|
|
// Simple 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)
|
|
```
|
|
|
|
**Function Bodies**: The `{ }` braces contain a TokenString that is parsed as the function body when the function is defined. See Section 5.5 for details on TokenStrings.
|
|
|
|
> **Related**: See Section 10.2 for generic functions with type parameters.
|
|
|
|
### 5.3 Calling Functions
|
|
|
|
Functions are called by simply writing their name. The postfix notation means arguments must be on the stack before the function name:
|
|
|
|
```
|
|
// Define a function
|
|
(Number Number -- Number) { + } ::add fn
|
|
|
|
// Call it
|
|
3 4 add // => 7
|
|
|
|
// Chain functions
|
|
5 square 2 * // => 50 (square 5, then multiply by 2)
|
|
```
|
|
|
|
**Function Chaining**: Since everything is postfix, functions naturally chain left-to-right:
|
|
```
|
|
10 square 2 / 5 + // ((10²) / 2) + 5 = 55
|
|
```
|
|
|
|
### 5.4 Recursion
|
|
|
|
Functions can call themselves recursively:
|
|
|
|
```
|
|
(Number -- Number) {
|
|
dup 1 <=
|
|
{ drop 1 }
|
|
{ dup 1 - factorial * }
|
|
if
|
|
} ::factorial fn
|
|
|
|
5 factorial // => 120
|
|
```
|
|
|
|
**Stack Considerations**: Recursive functions consume stack space. Deep recursion may cause stack overflow. Consider iterative alternatives for performance-critical code.
|
|
|
|
### 5.5 Token Strings
|
|
|
|
Token strings are lexed but unparsed code blocks enclosed in `{ }`. They are parsed differently depending on which operator uses them.
|
|
|
|
**Operators that parse TokenStrings:**
|
|
- `fn` - Parses as function body (code block)
|
|
- `trait` - Parses as trait definition (method signatures)
|
|
- `impl` - Parses as trait implementation (method definitions)
|
|
- `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`, `filter`, `reduce`, `each` - Parse TokenStrings as code blocks for array operations
|
|
|
|
**Examples**:
|
|
```
|
|
// Function body (parsed by fn)
|
|
(Number -- Number) { dup * } ::square fn
|
|
|
|
// Conditional branches (parsed by if)
|
|
x 0 > { "positive" print } { "negative" print } if
|
|
|
|
// Loop body (parsed by while)
|
|
{ dup 10 < } { dup print 1 + } while
|
|
```
|
|
|
|
### 5.6 Lambda Functions
|
|
|
|
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
|
|
```
|
|
|
|
**Use Cases**:
|
|
- Creating first-class functions
|
|
- Passing code blocks as values
|
|
- Dynamic dispatch
|
|
- Higher-order operations
|
|
|
|
**Example with arrays**:
|
|
```
|
|
// Store a lambda and use it with map
|
|
{ 2 * } lambda ::double swap
|
|
[1 2 3 4] double map // => [2 4 6 8]
|
|
```
|
|
|
|
> **Related**: See Section 11.1 for the `eval` operator used to execute lambdas.
|
|
|
|
---
|
|
|
|
## 6. Control Flow
|
|
|
|
### 6.1 Conditionals
|
|
|
|
**Syntax**: `condition { then-block } { else-block } if`
|
|
|
|
The condition is evaluated first, then both code blocks are provided, followed by the `if` operator which chooses which block to execute.
|
|
|
|
**Examples**:
|
|
```
|
|
// if-then (else block is empty)
|
|
x 0 > { "positive" print } { } if
|
|
|
|
// if-then-else
|
|
x 0 >
|
|
{ "positive" print }
|
|
{ "non-positive" print }
|
|
if
|
|
|
|
// Returning values
|
|
a b >
|
|
{ a }
|
|
{ b }
|
|
if // Pushes the maximum of a and b
|
|
|
|
// Nested conditionals
|
|
x 0 >
|
|
{
|
|
y 0 >
|
|
{ "both positive" print }
|
|
{ "x positive, y not" print }
|
|
if
|
|
}
|
|
{ "x not positive" print }
|
|
if
|
|
```
|
|
|
|
**Important**: The `if` operator parses both TokenStrings as code blocks. The condition must produce a boolean value (or truthy value) before the `if` operator.
|
|
|
|
### 6.2 While Loops
|
|
|
|
**Syntax**: `{ condition-block } { body-block } while`
|
|
|
|
The while loop repeatedly evaluates the condition block and executes the body block as long as the condition is truthy.
|
|
|
|
**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
|
|
```
|
|
|
|
**Condition Evaluation**: The condition block is re-evaluated before each iteration. It should leave a boolean (or truthy) value on the stack.
|
|
|
|
### 6.3 For Loops
|
|
|
|
**Syntax**: `start end { body-with-counter } for`
|
|
|
|
The for loop iterates from `start` to `end` (inclusive), pushing the loop counter onto the stack for each iteration before executing the body.
|
|
|
|
**Examples**:
|
|
```
|
|
// Print 1 to 10
|
|
1 10 {
|
|
// Stack has loop counter on top
|
|
dup print
|
|
} for
|
|
|
|
// FizzBuzz
|
|
1 100 {
|
|
dup fizzbuzz
|
|
} for
|
|
|
|
// Accumulation
|
|
0 // accumulator
|
|
1 10 {
|
|
+ // add counter to accumulator
|
|
} for
|
|
// Result: 55 (sum of 1 to 10)
|
|
```
|
|
|
|
**Loop Counter**: The loop counter is automatically pushed onto the stack before each iteration. Your body block should consume it or clean it up.
|
|
|
|
### 6.4 Loop Control
|
|
|
|
```
|
|
break // Exit the current loop immediately
|
|
continue // Skip to the next iteration of the current loop
|
|
```
|
|
|
|
**Examples**:
|
|
```
|
|
// Break example
|
|
1 100 {
|
|
dup 50 ==
|
|
{ break }
|
|
{ dup print }
|
|
if
|
|
} for // Prints 1-49, stops at 50
|
|
|
|
// Continue example
|
|
1 10 {
|
|
dup 2 % 0 ==
|
|
{ continue }
|
|
{ dup print }
|
|
if
|
|
} for // Prints only odd numbers: 1 3 5 7 9
|
|
```
|
|
|
|
### 6.5 Pattern Matching
|
|
|
|
**Syntax**: `value { pattern => block ... } match`
|
|
|
|
Pattern matching allows you to test a value against multiple patterns and execute the corresponding block.
|
|
|
|
**Examples**:
|
|
```
|
|
// Option matching
|
|
opt_value {
|
|
Some(x) => { x print }
|
|
None => { "Nothing" print }
|
|
} match
|
|
|
|
// Multiple patterns
|
|
status {
|
|
Pending => { "Waiting" print }
|
|
Active => { "Running" print }
|
|
Complete => { "Done" print }
|
|
} match
|
|
|
|
// Result matching
|
|
result {
|
|
Ok(val) => { val process }
|
|
Err(e) => { e "Error: " swap concat print }
|
|
} match
|
|
```
|
|
|
|
**Pattern Syntax**: Patterns can match enum variants, union variants, or literal values. The matched value (if any) is bound and available in the corresponding block.
|
|
|
|
---
|
|
|
|
## 7. Data Structures
|
|
|
|
### 7.1 Structs
|
|
|
|
Structs define composite types with named fields.
|
|
|
|
**Definition Syntax**: `(field_types -- ) { field_names: } ::name<type_params>? struct`
|
|
|
|
**Examples**:
|
|
|
|
```
|
|
// Define Point struct - generic over coordinate types
|
|
(T T --) { x: y: } ::Point<T> 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<T U V> struct
|
|
|
|
10.0 20.0 30.0 Box3D
|
|
```
|
|
|
|
**Field Access**:
|
|
- **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
|
|
```
|
|
|
|
> **Note**: Structs can be generic. See Section 10.3 for details on generic data structures.
|
|
|
|
### 7.2 Unions
|
|
|
|
Unions define tagged variants, where a value is one of several possible types.
|
|
|
|
**Definition Syntax**: `(variant_types -- ) { variants } ::name<type_params>? union`
|
|
|
|
**Examples**:
|
|
```
|
|
// Option type - generic over T
|
|
(T --) {
|
|
Some(T)
|
|
None
|
|
} ::Option<T> union
|
|
|
|
// Result type - generic over T and E
|
|
(T E --) {
|
|
Ok(T)
|
|
Err(E)
|
|
} ::Result<T E> 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")
|
|
```
|
|
|
|
**Pattern Matching**: Unions are typically used with pattern matching (Section 6.5) to handle different variants.
|
|
|
|
> **Note**: Unions can be generic. See Section 10.3 for details on generic data structures.
|
|
|
|
### 7.3 Enums
|
|
|
|
Enums define a fixed set of named values with optional integer assignments.
|
|
|
|
**Definition Syntax**: `{ variants } ::name enum`
|
|
|
|
**Examples**:
|
|
```
|
|
{
|
|
Pending 1: // Explicitly set to 1
|
|
Active: // Defaults to 2 (one plus the last)
|
|
Complete 0: // Explicitly set to 0
|
|
} ::Status enum
|
|
|
|
// Usage
|
|
Status::Pending // Creates Status::Pending (value 1)
|
|
Status::Active // Creates Status::Active (value 2)
|
|
Status::Complete // Creates Status::Complete (value 0)
|
|
```
|
|
|
|
**Automatic Values**: If not specified, enum values start at 0 and increment by 1 for each subsequent variant.
|
|
|
|
### 7.4 Arrays
|
|
|
|
Arrays are homogeneous collections of values.
|
|
|
|
**Array Literals**:
|
|
```
|
|
[1 2 3 4 5] // array of i64
|
|
[1.0 2.0 3.0] // array of f64
|
|
[[1 2] [3 4]] // 2D array
|
|
```
|
|
|
|
**Basic Operations**:
|
|
```
|
|
arr 2 at // ( array index -- element ) Access element at index
|
|
arr 1 3 slice // ( array start end -- subarray ) Extract slice
|
|
arr length // ( array -- length ) Get array length
|
|
```
|
|
|
|
**Array Combinators**:
|
|
|
|
These operations take TokenString arguments containing function bodies:
|
|
|
|
```
|
|
// Map - transform 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 accumulator
|
|
[1 2 3 4] 0 { + } reduce // => 10
|
|
|
|
// Each - apply to each element (side effects)
|
|
[[1 2] [3 4]] { sum print } each
|
|
```
|
|
|
|
**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]
|
|
```
|
|
|
|
**Array Manipulation**:
|
|
```
|
|
[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]]
|
|
```
|
|
|
|
> **Implementation Details**: Array operations implement various traits including `::ArrayOf<T>`, `::Selectable<T>`, `::Sliceable`, and `::Sized`. See Appendix B for complete trait definitions and Appendix A for the full array operation reference.
|
|
|
|
---
|
|
|
|
## 8. Type System
|
|
|
|
### 8.1 Types vs Traits
|
|
|
|
The language distinguishes between types (what things are) and traits (how things behave):
|
|
|
|
**Types** define the concrete structure and memory layout:
|
|
- `Point` - A struct type with two fields
|
|
- `Rectangle` - A struct type with width and height
|
|
- `i32` - A primitive integer type
|
|
- `Option<T>` - A union type that may contain a value
|
|
|
|
**Traits** define behavioral contracts:
|
|
- `::Addable` - Types that support addition and subtraction
|
|
- `::Drawable` - Types that can be drawn
|
|
- `::Stackable` - Types that support stack operations
|
|
|
|
**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 specify types or traits in signatures
|
|
- Every operator must be backed by a trait
|
|
|
|
**Examples**:
|
|
```
|
|
// Point is a type
|
|
(T T --) { x: y: } ::Point<T> struct
|
|
|
|
// Addable is a trait
|
|
{
|
|
(Self Self -- Self) +:
|
|
(Self Self -- Self) -:
|
|
} ::Addable trait
|
|
|
|
// Point implements Addable (Point now behaves additively)
|
|
::Addable {
|
|
(Self Self -- Self) {
|
|
over ::x get over ::x get +
|
|
swap ::y get swap ::y get +
|
|
Point
|
|
} +:
|
|
// ... subtract implementation ...
|
|
} ::Point impl
|
|
```
|
|
|
|
> **Related**: See Section 9 for the complete trait system and Appendix B for all standard trait definitions.
|
|
|
|
### 8.2 Type Inference
|
|
|
|
The compiler infers types in most situations, minimizing the need for explicit type annotations.
|
|
|
|
**When Type Inference Works**:
|
|
```
|
|
42 // Inferred as i64 (default integer)
|
|
3.14 // Inferred as f64 (default float)
|
|
[1 2 3] // Inferred as array of i64
|
|
|
|
// Function return type inferred from body
|
|
(Number -- Number) { dup * } ::square fn
|
|
5 square // Compiler knows result is Number
|
|
```
|
|
|
|
**When Annotations Are Needed**:
|
|
```
|
|
42:i32 // Explicit annotation for 32-bit integer
|
|
3.14:f32 // Explicit annotation for 32-bit float
|
|
|
|
// Ambiguous generic contexts may need hints
|
|
parse // May need type context to know what to parse to
|
|
```
|
|
|
|
**Type Inference with Generics**:
|
|
```
|
|
// Type parameter T is inferred from usage
|
|
(T -- T) { } ::identity fn
|
|
|
|
5 identity // T inferred as i64
|
|
"hello" identity // T inferred as String
|
|
```
|
|
|
|
> **Related**: See Section 10 for generic programming and type parameter inference.
|
|
|
|
### 8.3 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.
|
|
|
|
**Syntax**: `(inputs -- outputs)`
|
|
|
|
**Examples**:
|
|
```
|
|
(T T -- T) // 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 with Iterable**:
|
|
|
|
For operations that need variable numbers of arguments, use the `Iterable` trait:
|
|
|
|
```
|
|
(-- Size) depth: // Zero arguments, returns stack depth
|
|
(String Iterable<Stringifiable> --) printf: // String plus iterable of printable values
|
|
(Iterable<T> -- T) sum: // Iterable of values, returns sum
|
|
```
|
|
|
|
**Examples**:
|
|
```
|
|
"x=%d, y=%d" [x y] printf // Format string with array of values
|
|
[1 2 3 4 5] sum // Sum array of numbers
|
|
depth print // No arguments needed
|
|
```
|
|
|
|
This approach keeps the type system simple without special variadic syntax.
|
|
|
|
### 8.4 Type Composition
|
|
|
|
Types can contain other types, creating composite data structures:
|
|
|
|
**Nested Structures**:
|
|
```
|
|
// Point contains two T values
|
|
(T T --) { x: y: } ::Point<T> struct
|
|
|
|
// Line contains two Points
|
|
(Point<T> Point<T> --) { start: end: } ::Line<T> struct
|
|
```
|
|
|
|
**Arrays of Types**:
|
|
```
|
|
[1 2 3] // Array of i64
|
|
[[1 2] [3 4]] // Array of arrays
|
|
[Point Point Point] // Array of Points
|
|
```
|
|
|
|
**Generic Composition**:
|
|
```
|
|
// Box contains a value of any type
|
|
(T --) { value: } ::Box<T> struct
|
|
|
|
// Option can contain any type (or nothing)
|
|
(T --) { Some(T) None } ::Option<T> union
|
|
|
|
// Nested generics
|
|
Option<Point<f64>> // Option containing a Point of f64s
|
|
```
|
|
|
|
---
|
|
|
|
## 9. Trait System
|
|
|
|
### 9.1 What are Traits
|
|
|
|
Traits define behavioral contracts - they specify what operations a type must support without dictating how those operations are implemented.
|
|
|
|
**Why Traits Exist**:
|
|
- Define common behavior across different types
|
|
- Enable generic programming with constraints
|
|
- Back every operator in the language
|
|
- Allow user-defined operators through trait implementation
|
|
|
|
**Standard Traits Overview**:
|
|
|
|
The language provides many built-in traits:
|
|
- `::Stackable` - Stack manipulation operations
|
|
- `::Addable`, `::Multiplyable` - Arithmetic operations
|
|
- `::Comparable`, `::Equatable` - Comparison operations
|
|
- `::Logical`, `::Bitwise` - Boolean and bit operations
|
|
- `::Sized`, `::Selectable<T>`, `::Sliceable` - Container operations
|
|
- `::Number` - Composite numeric operations
|
|
- And many more...
|
|
|
|
> **Complete Reference**: See Appendix B for all standard trait definitions with complete documentation.
|
|
|
|
### 9.2 Defining Traits
|
|
|
|
**Syntax**: `{ method_signatures } ::identifier<type_params>? trait`
|
|
|
|
Traits can have methods or be empty (marker traits). Empty traits are typically used with inheritance.
|
|
|
|
**Examples**:
|
|
```
|
|
// Trait with methods
|
|
{
|
|
(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<T> trait
|
|
|
|
// Empty marker trait
|
|
{ } ::Serializable trait
|
|
```
|
|
|
|
**Method Signatures**: Within the TokenString, identifiers are method names and should not use the `::` prefix.
|
|
|
|
### 9.3 Implementing Traits
|
|
|
|
**Syntax**: `::trait_identifier { method_implementations } ::type_identifier impl`
|
|
|
|
**Implementation Rules**:
|
|
1. Implementing a trait for itself (`::Trait { ... } ::Trait impl`) creates a default implementation for all types
|
|
2. A trait must be defined before it can be implemented
|
|
3. Method implementations can be split across multiple `impl` 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
|
|
```
|
|
|
|
> **More Examples**: See Appendix G for complete implementation examples and tutorials.
|
|
|
|
### 9.4 Trait Inheritance
|
|
|
|
**Syntax**: `[ identifier_list ] ::identifier<type_params>? inher { methods } ::identifier<type_params>? trait`
|
|
|
|
Trait inheritance allows a trait to include all methods from parent traits, optionally adding new methods.
|
|
|
|
**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
|
|
```
|
|
|
|
**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
|
|
[ ::Container<T> ] ::Stack<T> inher
|
|
{
|
|
(Self -- T) pop:
|
|
} ::Stack<T> trait
|
|
|
|
// Inheriting trait specifies concrete type
|
|
[ ::Container<i32> ] ::IntStack inher
|
|
{
|
|
(Self -- i32) pop:
|
|
} ::IntStack trait
|
|
```
|
|
|
|
### 9.5 Using Traits in Functions
|
|
|
|
Traits can be used as type constraints in function signatures:
|
|
|
|
**Examples**:
|
|
```
|
|
// Function requiring Drawable trait
|
|
(Drawable -- ) {
|
|
draw
|
|
} ::draw_object fn
|
|
|
|
// Function requiring Number trait
|
|
(Number Number -- Number) {
|
|
dup * swap dup * + // Pythagorean: a² + b²
|
|
} ::sum_of_squares fn
|
|
|
|
// Generic function with trait constraint
|
|
(Multiplyable -- Multiplyable) {
|
|
dup *
|
|
} ::square fn
|
|
```
|
|
|
|
**Multiple Constraints**: Use specific traits or composite traits that inherit from multiple parents:
|
|
```
|
|
// Requires both Addable and Comparable
|
|
(Number -- Number) { ... } ::some_function fn
|
|
|
|
// Number trait inherits from both, so this works
|
|
```
|
|
|
|
### 9.6 Standard Traits Overview
|
|
|
|
This section provides a brief overview of all standard traits. For complete definitions with all methods and documentation, see Appendix B.
|
|
|
|
**Stack Operations**:
|
|
- `::Stackable` - Fundamental stack manipulation (dup, drop, swap, over, rot, pick, roll, depth)
|
|
|
|
**Arithmetic**:
|
|
- `::Addable` - Addition and subtraction (+, -)
|
|
- `::Multiplyable` - Multiplication, division, modulo (*, /, %)
|
|
- `::Exponentiable` - Exponentiation (^)
|
|
- `::Logarithmic` - Logarithm operations (log, ln, logb)
|
|
- `::Number` - Composite trait combining all arithmetic and comparison
|
|
|
|
**Comparison**:
|
|
- `::Orderable` - Ordering comparisons (>, >=, <, <=)
|
|
- `::Equatable` - Equality comparisons (==, !=)
|
|
- `::Comparable` - Composite trait combining Orderable and Equatable
|
|
|
|
**Logical and Bitwise**:
|
|
- `::Logical` - Boolean operations (and, or, not, truthy)
|
|
- `::Bitwise` - Bit manipulation (bitand, bitor, bitxor, bitnot, shl, shr)
|
|
|
|
**Containers**:
|
|
- `::Sized` - Length information (length)
|
|
- `::Selectable<T>` - Element access (at)
|
|
- `::Sliceable` - Slicing operations (slice)
|
|
- `::Concatenable` - Concatenation (concat)
|
|
- `::ArrayOf<T>` - Composite array trait
|
|
- `::Iterable<T>` - Iteration support (next)
|
|
|
|
**Conversion**:
|
|
- `::Convertible` - Type conversions (to_i8, to_i16, ..., to_f32, to_f64)
|
|
- `::Stringifiable` - String conversion (to_str)
|
|
- `::Parseable` - Parse from string (parse)
|
|
|
|
**String Operations**:
|
|
- `::String` - String-specific operations (substr, split) - inherits from Concatenable
|
|
|
|
**Utilities**:
|
|
- `::Size` - Types suitable for indexing (inherits Addable, Comparable, Convertible)
|
|
- `::Identifier` - Marks identifiers
|
|
- `::Implementable` - Meta-trait for defining language constructs (trait, impl, inher)
|
|
|
|
> **Complete Reference**: See Appendix B for full trait definitions with all methods, examples, and implementation details.
|
|
|
|
---
|
|
|
|
## 10. Generic Programming
|
|
|
|
### 10.1 Type Parameters
|
|
|
|
Type parameters allow functions, structs, and traits to work with multiple types.
|
|
|
|
**Generic Syntax**: `<T>` where T is a type parameter
|
|
|
|
**Examples**:
|
|
```
|
|
// Generic struct
|
|
(T T --) { x: y: } ::Point<T> struct
|
|
|
|
// Generic union
|
|
(T --) { Some(T) None } ::Option<T> union
|
|
|
|
// Generic trait
|
|
{
|
|
(Self T -- Self) append:
|
|
} ::Container<T> trait
|
|
```
|
|
|
|
**Type Parameter Constraints**:
|
|
|
|
When operations are performed on type parameters, they must be constrained by traits:
|
|
|
|
```
|
|
// Unconstrained - no operations on T
|
|
(T -- T) { } ::identity fn
|
|
|
|
// Constrained - T must support multiplication
|
|
(T:Multiplyable -- T) { dup * } ::square fn
|
|
```
|
|
|
|
**Multiple Type Parameters**:
|
|
```
|
|
(T E --) { Ok(T) Err(E) } ::Result<T E> union
|
|
```
|
|
|
|
### 10.2 Generic Functions
|
|
|
|
Generic functions work with multiple types by using trait constraints in their type tuples.
|
|
|
|
**Syntax**: `(trait_constraints -- outputs) { body } ::name fn`
|
|
|
|
**Examples**:
|
|
```
|
|
// Generic identity - works with any type (no operations, no constraint needed)
|
|
(T -- T) { } ::identity fn
|
|
|
|
// Requires Addable trait
|
|
(Addable Addable -- Addable) {
|
|
+
|
|
} ::add_values fn
|
|
|
|
// Requires Number trait
|
|
(Number -- Number) {
|
|
dup 0 > { } { 0 swap - } if
|
|
} ::abs fn
|
|
|
|
// Multiple constraints
|
|
(Number Number -- Number) {
|
|
dup * swap dup * + // a² + b²
|
|
} ::pythagorean fn
|
|
```
|
|
|
|
**Type Inference**: The compiler infers the actual type from usage:
|
|
```
|
|
5 identity // T inferred as i64
|
|
"hello" identity // T inferred as String
|
|
3 4 add_values // Addable inferred as i64
|
|
```
|
|
|
|
### 10.3 Generic Data Structures
|
|
|
|
Structs and unions can be generic over type parameters:
|
|
|
|
**Generic Structs**:
|
|
```
|
|
// Point is generic over coordinate type
|
|
(T T --) { x: y: } ::Point<T> struct
|
|
|
|
// Use with different types
|
|
3.0 4.0 Point // Point<f64>
|
|
3 4 Point // Point<i64>
|
|
|
|
// Multiple type parameters
|
|
(T U --) { first: second: } ::Pair<T U> struct
|
|
5 "hello" Pair // Pair<i64 String>
|
|
```
|
|
|
|
**Generic Unions**:
|
|
```
|
|
// Option is generic over contained type
|
|
(T --) { Some(T) None } ::Option<T> union
|
|
|
|
42 Option::Some // Option<i64>::Some
|
|
"text" Option::Some // Option<String>::Some
|
|
Option::None // Option<T>::None (T inferred from context)
|
|
|
|
// Result with two type parameters
|
|
(T E --) { Ok(T) Err(E) } ::Result<T E> union
|
|
```
|
|
|
|
**Nested Generics**:
|
|
```
|
|
// Array of Options
|
|
[Option::Some Option::None] // Array of Option<T>
|
|
|
|
// Option of array
|
|
[1 2 3] Option::Some // Option<Array<i64>>
|
|
```
|
|
|
|
### 10.4 Generic Traits
|
|
|
|
Traits can be generic, allowing them to describe behavior parameterized over types.
|
|
|
|
**Generic Trait Syntax**:
|
|
```
|
|
// Container generic over element type
|
|
{
|
|
(Self T -- Self) append:
|
|
(Self -- T) pop:
|
|
} ::Container<T> trait
|
|
|
|
// Map generic over key and value types
|
|
{
|
|
(Self K -- V) get:
|
|
(Self K V -- Self) insert:
|
|
} ::Map<K V> trait
|
|
```
|
|
|
|
**Generic Trait Inheritance**:
|
|
|
|
When inheriting from generic traits, you must either:
|
|
1. Make the inheriting trait similarly generic
|
|
2. Specify concrete types for the generic parameters
|
|
|
|
```
|
|
// Inheriting trait is also generic
|
|
[ ::Container<T> ] ::Stack<T> inher
|
|
{
|
|
(Self -- T) peek:
|
|
} ::Stack<T> trait
|
|
|
|
// Inheriting trait specifies concrete type
|
|
[ ::Container<i32> ] ::IntStack inher
|
|
{
|
|
(Self -- i32) peek:
|
|
} ::IntStack trait
|
|
|
|
// Multiple generic inheritance
|
|
[ ::Selectable<T> ::Sized ::Sliceable ] ::ArrayOf<T> inher
|
|
{ } ::ArrayOf<T> trait
|
|
```
|
|
|
|
### 10.5 Type Parameter Enforcement
|
|
|
|
**Current Behavior**: Type parameters are currently suggestions when parsing code blocks. The compiler does not yet enforce that type parameters actually constrain how operators and functions act at parse time.
|
|
|
|
**Example**:
|
|
```
|
|
// Currently no error even without Multiplyable constraint
|
|
(T -- T) { dup * } ::square fn
|
|
|
|
// Should require constraint
|
|
(Multiplyable -- Multiplyable) { dup * } ::square fn
|
|
```
|
|
|
|
> **Future Enhancement**: See Appendix F for planned type parameter enforcement at parse time.
|
|
|
|
---
|
|
|
|
## 11. Advanced Topics
|
|
|
|
### 11.1 Dynamic Code Evaluation
|
|
|
|
The `eval` operator executes code dynamically at runtime by parsing and executing a TokenString.
|
|
|
|
**Syntax**: `{ code } eval`
|
|
|
|
**Examples**:
|
|
```
|
|
// Evaluate simple expression
|
|
"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
|
|
```
|
|
|
|
**Use Cases**:
|
|
- Building code at runtime
|
|
- Dynamic dispatch based on runtime values
|
|
- Implementing interpreters or REPLs
|
|
- Meta-programming
|
|
|
|
**Warnings**:
|
|
- Eval introduces runtime overhead (parsing)
|
|
- Type safety is reduced (types checked at eval time, not compile time)
|
|
- Security risk if evaluating untrusted code
|
|
- Use sparingly and prefer static alternatives when possible
|
|
|
|
### 11.2 Identifier Literals
|
|
|
|
Identifier literals use the `::` prefix to push an identifier as a value rather than executing it.
|
|
|
|
**Syntax**: `::name`
|
|
|
|
**Context-Dependent Rules**:
|
|
|
|
**In function bodies and eval**: `::` is required for identifier literals
|
|
```
|
|
::Point // Pushes identifier "Point"
|
|
::Addable // Pushes identifier "Addable"
|
|
```
|
|
|
|
**In trait definitions**: `::` is not allowed (identifiers are method names)
|
|
```
|
|
{
|
|
(Self -- ) draw: // "draw:" is a method name, not a literal
|
|
} ::Drawable trait
|
|
```
|
|
|
|
**In trait implementations**: `::` is not allowed (identifiers are method names)
|
|
```
|
|
::Drawable {
|
|
(Self -- ) { ... } draw: // "draw:" is a method name
|
|
} ::Rectangle impl
|
|
```
|
|
|
|
**Use Cases**:
|
|
- Defining structs: `(T T --) { x: y: } ::Point<T> struct`
|
|
- Defining traits: `{ ... } ::Drawable trait`
|
|
- Field access: `point ::x get`
|
|
- Dynamic trait operations
|
|
- Meta-programming
|
|
|
|
### 11.3 Standard Library
|
|
|
|
The standard library provides I/O, string operations, type conversions, and utility functions. All standard library functions are automatically in scope (no imports needed in current version).
|
|
|
|
**I/O Operations**:
|
|
```
|
|
"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
|
|
```
|
|
|
|
**String Operations**:
|
|
```
|
|
"hello" " world" concat // Concatenate strings
|
|
"hello" length // Get string length
|
|
"hello" 1 3 substr // Extract substring
|
|
"a,b,c" "," split // Split by delimiter
|
|
["a" "b"] "," join // Join with delimiter
|
|
```
|
|
|
|
**Type Conversion**:
|
|
```
|
|
42 to_f64 // Convert i32 to f64
|
|
3.14 to_i32 // Convert f64 to i32 (truncates)
|
|
"123" parse // Parse string to inferred type
|
|
42 to_str // Convert to string
|
|
```
|
|
|
|
**Array Operations**:
|
|
- Element access: `at`, `slice`
|
|
- Information: `length`, `shape`
|
|
- Combinators: `map`, `filter`, `reduce`, `each`
|
|
- Manipulation: `concat`, `reverse`, `transpose`, `window`
|
|
|
|
> **Complete Reference**: See Appendix A for the full standard library reference with all functions, signatures, and examples.
|
|
|
|
---
|
|
|
|
## Appendix A: Standard Library
|
|
|
|
This appendix provides a complete alphabetical reference of all standard library functions and operations.
|
|
|
|
### Standard Library Categories
|
|
|
|
**Array Operations**: at, concat, each, filter, length, map, reduce, reverse, shape, slice, transpose, window
|
|
|
|
**I/O Operations**: input, print, read, write
|
|
|
|
**String Operations**: concat, join, length, split, substr
|
|
|
|
**Type Conversion**: parse, to_i8, to_i16, to_i32, to_i64, to_u8, to_u16, to_u32, to_u64, to_f32, to_f64, to_str
|
|
|
|
**Utility Operations**: eval, lambda
|
|
|
|
### Alphabetical Reference
|
|
|
|
#### at
|
|
**Signature**: `(Selectable<T> Size -- T)`
|
|
**Trait**: Selectable<T>
|
|
**Description**: Access element at the given index.
|
|
**Example**:
|
|
```
|
|
[10 20 30] 1 at // Returns 20
|
|
```
|
|
**See Also**: slice, length
|
|
|
|
#### concat
|
|
**Signature**: `(Concatenable Concatenable -- Concatenable)`
|
|
**Trait**: Concatenable
|
|
**Description**: Concatenate two containers or strings.
|
|
**Example**:
|
|
```
|
|
[1 2 3] [4 5 6] concat // Returns [1 2 3 4 5 6]
|
|
"hello" " world" concat // Returns "hello world"
|
|
```
|
|
**See Also**: join, split
|
|
|
|
#### depth
|
|
**Signature**: `(-- Size)`
|
|
**Trait**: Stackable
|
|
**Description**: Push current stack depth onto the stack.
|
|
**Example**:
|
|
```
|
|
1 2 3 depth // Returns 1 2 3 3
|
|
```
|
|
**See Also**: pick, roll
|
|
|
|
#### drop
|
|
**Signature**: `(Self --)`
|
|
**Trait**: Stackable
|
|
**Description**: Remove and discard the top item from the stack.
|
|
**Example**:
|
|
```
|
|
5 10 drop // Returns 5
|
|
```
|
|
**See Also**: dup, swap
|
|
|
|
#### dup
|
|
**Signature**: `(Self -- Self Self)`
|
|
**Trait**: Stackable
|
|
**Description**: Duplicate the top item on the stack.
|
|
**Example**:
|
|
```
|
|
5 dup // Returns 5 5
|
|
```
|
|
**See Also**: drop, over
|
|
|
|
#### each
|
|
**Signature**: `(ArrayOf<T> TokenString --)`
|
|
**Description**: Apply function to each element (side effects).
|
|
**Example**:
|
|
```
|
|
[1 2 3] { print } each // Prints 1, 2, 3
|
|
```
|
|
**See Also**: map, filter
|
|
|
|
#### eval
|
|
**Signature**: `(TokenString --)`
|
|
**Trait**: Implementable
|
|
**Description**: Parse and execute TokenString as code.
|
|
**Example**:
|
|
```
|
|
"2 3 +" eval // Returns 5
|
|
```
|
|
**See Also**: lambda
|
|
|
|
#### filter
|
|
**Signature**: `(ArrayOf<T> TokenString -- ArrayOf<T>)`
|
|
**Description**: Keep only elements matching predicate.
|
|
**Example**:
|
|
```
|
|
[1 2 3 4 5] { 2 % 0 == } filter // Returns [2 4]
|
|
```
|
|
**See Also**: map, reduce
|
|
|
|
#### input
|
|
**Signature**: `(String -- String)`
|
|
**Description**: Print prompt and read line from stdin.
|
|
**Example**:
|
|
```
|
|
"Enter name: " input // Prompts and returns user input
|
|
```
|
|
**See Also**: print, read
|
|
|
|
#### join
|
|
**Signature**: `(ArrayOf<String> String -- String)`
|
|
**Description**: Join array of strings with delimiter.
|
|
**Example**:
|
|
```
|
|
["a" "b" "c"] "," join // Returns "a,b,c"
|
|
```
|
|
**See Also**: split, concat
|
|
|
|
#### lambda
|
|
**Signature**: `(TokenString -- Callable)`
|
|
**Trait**: Implementable
|
|
**Description**: Convert TokenString to callable code block.
|
|
**Example**:
|
|
```
|
|
{ dup * } lambda ::square swap
|
|
5 square eval // Returns 25
|
|
```
|
|
**See Also**: eval
|
|
|
|
#### length
|
|
**Signature**: `(Sized -- i64)`
|
|
**Trait**: Sized
|
|
**Description**: Get the number of elements in a container.
|
|
**Example**:
|
|
```
|
|
[1 2 3 4 5] length // Returns 5
|
|
"hello" length // Returns 5
|
|
```
|
|
**See Also**: at, slice
|
|
|
|
#### map
|
|
**Signature**: `(ArrayOf<T> TokenString -- ArrayOf<U>)`
|
|
**Description**: Transform each element with function.
|
|
**Example**:
|
|
```
|
|
[1 2 3 4] { 2 * } map // Returns [2 4 6 8]
|
|
```
|
|
**See Also**: filter, reduce, each
|
|
|
|
#### over
|
|
**Signature**: `(Self Self -- Self Self Self)`
|
|
**Trait**: Stackable
|
|
**Description**: Copy the second item to the top of the stack.
|
|
**Example**:
|
|
```
|
|
5 10 over // Returns 5 10 5
|
|
```
|
|
**See Also**: dup, swap, rot
|
|
|
|
#### parse
|
|
**Signature**: `(String -- Parseable)`
|
|
**Trait**: Parseable
|
|
**Description**: Parse string to value of inferred type.
|
|
**Example**:
|
|
```
|
|
"123" parse // Returns 123 (as appropriate numeric type)
|
|
```
|
|
**See Also**: to_str
|
|
|
|
#### pick
|
|
**Signature**: `(Size -- Self)`
|
|
**Trait**: Stackable
|
|
**Description**: Copy nth item to top (0 = top, 1 = second, etc.).
|
|
**Example**:
|
|
```
|
|
1 2 3 4 2 pick // Returns 1 2 3 4 2
|
|
```
|
|
**See Also**: roll, depth
|
|
|
|
#### print
|
|
**Signature**: `(Stringifiable --)`
|
|
**Description**: Print value to stdout.
|
|
**Example**:
|
|
```
|
|
"Hello" print // Prints: Hello
|
|
42 print // Prints: 42
|
|
```
|
|
**See Also**: input, to_str
|
|
|
|
#### read
|
|
**Signature**: `(String -- String)`
|
|
**Description**: Read file contents as string.
|
|
**Example**:
|
|
```
|
|
"file.txt" read // Returns file contents
|
|
```
|
|
**See Also**: write
|
|
|
|
#### reduce
|
|
**Signature**: `(ArrayOf<T> T TokenString -- T)`
|
|
**Description**: Fold array with accumulator function.
|
|
**Example**:
|
|
```
|
|
[1 2 3 4] 0 { + } reduce // Returns 10
|
|
```
|
|
**See Also**: map, filter
|
|
|
|
#### reverse
|
|
**Signature**: `(ArrayOf<T> -- ArrayOf<T>)`
|
|
**Description**: Reverse order of array elements.
|
|
**Example**:
|
|
```
|
|
[1 2 3] reverse // Returns [3 2 1]
|
|
```
|
|
**See Also**: transpose
|
|
|
|
#### roll
|
|
**Signature**: `(Size Size --)`
|
|
**Trait**: Stackable
|
|
**Description**: Rotate n items, times times.
|
|
**Example**:
|
|
```
|
|
1 2 3 4 3 1 roll // Rotates top 3 once: 1 3 4 2
|
|
```
|
|
**See Also**: rot, pick
|
|
|
|
#### rot
|
|
**Signature**: `(Self Self Self -- Self Self Self)`
|
|
**Trait**: Stackable
|
|
**Description**: Rotate the top three items.
|
|
**Example**:
|
|
```
|
|
1 2 3 rot // Returns 2 3 1
|
|
```
|
|
**See Also**: swap, roll
|
|
|
|
#### slice
|
|
**Signature**: `(Sliceable Size Size -- Sliceable)`
|
|
**Trait**: Sliceable
|
|
**Description**: Extract elements from start to end index.
|
|
**Example**:
|
|
```
|
|
[10 20 30 40] 1 3 slice // Returns [20 30]
|
|
```
|
|
**See Also**: at, length
|
|
|
|
#### split
|
|
**Signature**: `(String String -- ArrayOf<String>)`
|
|
**Trait**: String
|
|
**Description**: Split string by delimiter.
|
|
**Example**:
|
|
```
|
|
"a,b,c" "," split // Returns ["a" "b" "c"]
|
|
```
|
|
**See Also**: join, substr
|
|
|
|
#### substr
|
|
**Signature**: `(String Size Size -- String)`
|
|
**Trait**: String
|
|
**Description**: Extract substring from start to end index.
|
|
**Example**:
|
|
```
|
|
"hello" 1 3 substr // Returns "el"
|
|
```
|
|
**See Also**: slice, split
|
|
|
|
#### swap
|
|
**Signature**: `(Self Self -- Self Self)`
|
|
**Trait**: Stackable
|
|
**Description**: Swap the top two items on the stack.
|
|
**Example**:
|
|
```
|
|
5 10 swap // Returns 10 5
|
|
```
|
|
**See Also**: dup, rot
|
|
|
|
#### to_f32, to_f64
|
|
**Signature**: `(Convertible -- f32/f64)`
|
|
**Trait**: Convertible
|
|
**Description**: Convert value to 32-bit or 64-bit float.
|
|
**Example**:
|
|
```
|
|
42 to_f64 // Returns 42.0
|
|
```
|
|
**See Also**: to_i32, to_str
|
|
|
|
#### to_i8, to_i16, to_i32, to_i64
|
|
**Signature**: `(Convertible -- i8/i16/i32/i64)`
|
|
**Trait**: Convertible
|
|
**Description**: Convert value to signed integer type.
|
|
**Example**:
|
|
```
|
|
3.14 to_i32 // Returns 3 (truncates)
|
|
```
|
|
**See Also**: to_u32, to_f64
|
|
|
|
#### to_str
|
|
**Signature**: `(Stringifiable -- String)`
|
|
**Trait**: Stringifiable
|
|
**Description**: Convert value to string representation.
|
|
**Example**:
|
|
```
|
|
42 to_str // Returns "42"
|
|
```
|
|
**See Also**: parse, print
|
|
|
|
#### to_u8, to_u16, to_u32, to_u64
|
|
**Signature**: `(Convertible -- u8/u16/u32/u64)`
|
|
**Trait**: Convertible
|
|
**Description**: Convert value to unsigned integer type.
|
|
**Example**:
|
|
```
|
|
42 to_u32 // Returns 42 (as u32)
|
|
```
|
|
**See Also**: to_i32, to_f64
|
|
|
|
#### transpose
|
|
**Signature**: `(ArrayOf<ArrayOf<T>> -- ArrayOf<ArrayOf<T>>)`
|
|
**Description**: Transpose a 2D array (swap rows and columns).
|
|
**Example**:
|
|
```
|
|
[[1 2] [3 4]] transpose // Returns [[1 3] [2 4]]
|
|
```
|
|
**See Also**: reverse
|
|
|
|
#### window
|
|
**Signature**: `(ArrayOf<T> Size -- ArrayOf<ArrayOf<T>>)`
|
|
**Description**: Create sliding windows of given size.
|
|
**Example**:
|
|
```
|
|
[1 2 3 4] 2 window // Returns [[1 2] [2 3] [3 4]]
|
|
```
|
|
**See Also**: slice
|
|
|
|
#### write
|
|
**Signature**: `(String String --)`
|
|
**Description**: Write string to file.
|
|
**Example**:
|
|
```
|
|
"data" "file.txt" write // Writes "data" to file.txt
|
|
```
|
|
**See Also**: read
|
|
|
|
---
|
|
|
|
## Appendix B: Complete Trait Reference
|
|
|
|
This appendix contains all built-in trait definitions with complete documentation, organized alphabetically.
|
|
|
|
### Trait List
|
|
|
|
- Addable
|
|
- ArrayOf<T>
|
|
- Bitwise
|
|
- Comparable
|
|
- Concatenable
|
|
- Convertible
|
|
- Equatable
|
|
- Exponentiable
|
|
- Identifier
|
|
- Implementable
|
|
- Iterable<T>
|
|
- Logarithmic
|
|
- Logical
|
|
- Multiplyable
|
|
- Number
|
|
- Orderable
|
|
- Parseable
|
|
- Selectable<T>
|
|
- Size
|
|
- Sized
|
|
- Sliceable
|
|
- Stackable
|
|
- String
|
|
- Stringifiable
|
|
|
|
### Addable
|
|
|
|
**Generic Parameters**: None
|
|
**Inherits**: None
|
|
|
|
**Definition**:
|
|
```
|
|
{
|
|
(Self Self -- Self) +:
|
|
(Self Self -- Self) -:
|
|
} ::Addable trait
|
|
```
|
|
|
|
**Methods**:
|
|
|
|
#### +:
|
|
**Signature**: `(Self Self -- Self)`
|
|
**Description**: Add two values together.
|
|
**Example**: `3 4 + // => 7`
|
|
|
|
#### -:
|
|
**Signature**: `(Self Self -- Self)`
|
|
**Description**: Subtract second value from first.
|
|
**Example**: `10 3 - // => 7`
|
|
|
|
**Standard Implementations**: All numeric types (i8, i16, i32, i64, u8, u16, u32, u64, f32, f64)
|
|
|
|
**Related Traits**: Multiplyable, Number
|
|
|
|
**See Also**: Section 4.2 (Arithmetic Operators)
|
|
|
|
### ArrayOf<T>
|
|
|
|
**Generic Parameters**: T (element type)
|
|
**Inherits**: Sized, Selectable<T>, Sliceable
|
|
|
|
**Definition**:
|
|
```
|
|
[ ::Sized ::Selectable<T> ::Sliceable ] ::ArrayOf<T> inher
|
|
{ } ::ArrayOf<T> trait
|
|
```
|
|
|
|
**Description**: Composite trait for arrays, inheriting all container operations.
|
|
|
|
**Standard Implementations**: Array types
|
|
|
|
**Related Traits**: Sized, Selectable, Sliceable, Iterable
|
|
|
|
**See Also**: Section 7.4 (Arrays)
|
|
|
|
### Bitwise
|
|
|
|
**Generic Parameters**: None
|
|
**Inherits**: None
|
|
|
|
**Definition**:
|
|
```
|
|
{
|
|
(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
|
|
```
|
|
|
|
**Methods**:
|
|
|
|
#### bitand:
|
|
**Signature**: `(Self Self -- Self)`
|
|
**Description**: Bitwise AND of two values.
|
|
**Example**: `0xFF 0x0F bitand // => 0x0F`
|
|
|
|
#### bitor:
|
|
**Signature**: `(Self Self -- Self)`
|
|
**Description**: Bitwise OR of two values.
|
|
**Example**: `0xF0 0x0F bitor // => 0xFF`
|
|
|
|
#### bitxor:
|
|
**Signature**: `(Self Self -- Self)`
|
|
**Description**: Bitwise XOR of two values.
|
|
**Example**: `0xFF 0x0F bitxor // => 0xF0`
|
|
|
|
#### bitnot:
|
|
**Signature**: `(Self -- Self)`
|
|
**Description**: Bitwise NOT (complement) of value.
|
|
**Example**: `0xFF bitnot // => (inverted bits)`
|
|
|
|
#### shl:
|
|
**Signature**: `(Self Size -- Self)`
|
|
**Description**: Shift bits left by n positions.
|
|
**Example**: `4 2 shl // => 16`
|
|
|
|
#### shr:
|
|
**Signature**: `(Self Size -- Self)`
|
|
**Description**: Shift bits right by n positions.
|
|
**Example**: `16 2 shr // => 4`
|
|
|
|
**Standard Implementations**: Integer types (i8, i16, i32, i64, u8, u16, u32, u64)
|
|
|
|
**Related Traits**: None
|
|
|
|
**See Also**: Section 4.5 (Bitwise Operators)
|
|
|
|
### Comparable
|
|
|
|
**Generic Parameters**: None
|
|
**Inherits**: Orderable, Equatable
|
|
|
|
**Definition**:
|
|
```
|
|
[ ::Orderable ::Equatable ] ::Comparable inher
|
|
{ } ::Comparable trait
|
|
```
|
|
|
|
**Description**: Composite trait combining ordering and equality comparisons.
|
|
|
|
**Standard Implementations**: All numeric types, strings, characters
|
|
|
|
**Related Traits**: Orderable, Equatable, Size, Number
|
|
|
|
**See Also**: Section 4.3 (Comparison Operators)
|
|
|
|
### Concatenable
|
|
|
|
**Generic Parameters**: None
|
|
**Inherits**: None
|
|
|
|
**Definition**:
|
|
```
|
|
{
|
|
(Self Self -- Self) concat:
|
|
} ::Concatenable trait
|
|
```
|
|
|
|
**Methods**:
|
|
|
|
#### concat:
|
|
**Signature**: `(Self Self -- Self)`
|
|
**Description**: Join two containers or strings together.
|
|
**Example**: `"hello" " world" concat // => "hello world"`
|
|
|
|
**Standard Implementations**: Arrays, strings
|
|
|
|
**Related Traits**: String, ArrayOf
|
|
|
|
**See Also**: Section 7.4 (Arrays), Appendix A (concat)
|
|
|
|
### Convertible
|
|
|
|
**Generic Parameters**: None
|
|
**Inherits**: None
|
|
|
|
**Definition**:
|
|
```
|
|
{
|
|
(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
|
|
```
|
|
|
|
**Methods**: Provides explicit type conversion methods to all numeric types.
|
|
|
|
**Standard Implementations**: All numeric types
|
|
|
|
**Related Traits**: Stringifiable, Parseable, Size
|
|
|
|
**See Also**: Section 11.3 (Type Conversion)
|
|
|
|
### Equatable
|
|
|
|
**Generic Parameters**: None
|
|
**Inherits**: None
|
|
|
|
**Definition**:
|
|
```
|
|
{
|
|
(Self Self -- bool) ==:
|
|
(Self Self -- bool) !=:
|
|
} ::Equatable trait
|
|
```
|
|
|
|
**Methods**:
|
|
|
|
#### ==:
|
|
**Signature**: `(Self Self -- bool)`
|
|
**Description**: Test if two values are equal.
|
|
**Example**: `5 5 == // => true`
|
|
|
|
#### !=:
|
|
**Signature**: `(Self Self -- bool)`
|
|
**Description**: Test if two values are not equal.
|
|
**Example**: `5 3 != // => true`
|
|
|
|
**Standard Implementations**: All types
|
|
|
|
**Related Traits**: Orderable, Comparable
|
|
|
|
**See Also**: Section 4.3 (Comparison Operators)
|
|
|
|
### Exponentiable
|
|
|
|
**Generic Parameters**: None
|
|
**Inherits**: None
|
|
|
|
**Definition**:
|
|
```
|
|
{
|
|
(Self Self -- Self) ^:
|
|
} ::Exponentiable trait
|
|
```
|
|
|
|
**Methods**:
|
|
|
|
#### ^:
|
|
**Signature**: `(Self Self -- Self)`
|
|
**Description**: Raise first value to the power of the second.
|
|
**Example**: `2 8 ^ // => 256`
|
|
|
|
**Standard Implementations**: Numeric types
|
|
|
|
**Related Traits**: Addable, Multiplyable, Number
|
|
|
|
**See Also**: Section 4.2 (Arithmetic Operators)
|
|
|
|
### Identifier
|
|
|
|
**Generic Parameters**: None
|
|
**Inherits**: None
|
|
|
|
**Definition**:
|
|
```
|
|
{ } ::Identifier trait
|
|
```
|
|
|
|
**Description**: Marker trait for identifier types.
|
|
|
|
**Standard Implementations**: Identifier literals
|
|
|
|
**Related Traits**: Implementable
|
|
|
|
**See Also**: Section 11.2 (Identifier Literals)
|
|
|
|
### Implementable
|
|
|
|
**Generic Parameters**: None
|
|
**Inherits**: None
|
|
|
|
**Definition**:
|
|
```
|
|
{
|
|
(TokenString Identifier --) trait:
|
|
(Identifier TokenString Identifier --) impl:
|
|
(ArrayOf<Identifier> Identifier --) inher:
|
|
} ::Implementable trait
|
|
```
|
|
|
|
**Methods**:
|
|
|
|
#### trait:
|
|
**Signature**: `(TokenString Identifier --)`
|
|
**Description**: Define a new trait.
|
|
**Example**: `{ (Self -- ) draw: } ::Drawable trait`
|
|
|
|
#### impl:
|
|
**Signature**: `(Identifier TokenString Identifier --)`
|
|
**Description**: Implement a trait for a type.
|
|
**Example**: `::Drawable { ... } ::Rectangle impl`
|
|
|
|
#### inher:
|
|
**Signature**: `(ArrayOf<Identifier> Identifier --)`
|
|
**Description**: Declare trait inheritance.
|
|
**Example**: `[ ::Orderable ::Equatable ] ::Comparable inher`
|
|
|
|
**Standard Implementations**: Language-level operators
|
|
|
|
**Related Traits**: Identifier
|
|
|
|
**See Also**: Section 9 (Trait System)
|
|
|
|
### Iterable<T>
|
|
|
|
**Generic Parameters**: T (element type)
|
|
**Inherits**: None
|
|
|
|
**Definition**:
|
|
```
|
|
{
|
|
(Self -- Self Option<T>) next:
|
|
} ::Iterable<T> trait
|
|
```
|
|
|
|
**Methods**:
|
|
|
|
#### next:
|
|
**Signature**: `(Self -- Self Option<T>)`
|
|
**Description**: Get next item from iterator.
|
|
**Example**: Iterator protocol for collections
|
|
|
|
**Standard Implementations**: Arrays, ranges, iterators
|
|
|
|
**Related Traits**: ArrayOf, Selectable
|
|
|
|
**See Also**: Section 8.3 (Type Tuples - Variable Arguments)
|
|
|
|
### Logarithmic
|
|
|
|
**Generic Parameters**: None
|
|
**Inherits**: None
|
|
|
|
**Definition**:
|
|
```
|
|
{
|
|
(Self Self -- Self) logb:
|
|
(Self -- Self) log:
|
|
(Self -- Self) ln:
|
|
} ::Logarithmic trait
|
|
```
|
|
|
|
**Methods**:
|
|
|
|
#### logb:
|
|
**Signature**: `(Self Self -- Self)`
|
|
**Description**: Logarithm with custom base.
|
|
**Example**: `8 2 logb // => 3.0`
|
|
|
|
#### log:
|
|
**Signature**: `(Self -- Self)`
|
|
**Description**: Logarithm base 10.
|
|
**Example**: `100 log // => 2.0`
|
|
|
|
#### ln:
|
|
**Signature**: `(Self -- Self)`
|
|
**Description**: Natural logarithm (base e).
|
|
**Example**: `2.718 ln // => 1.0`
|
|
|
|
**Standard Implementations**: Floating point types
|
|
|
|
**Related Traits**: Exponentiable, Number
|
|
|
|
**See Also**: Section 4.2 (Arithmetic Operators)
|
|
|
|
### Logical
|
|
|
|
**Generic Parameters**: None
|
|
**Inherits**: None
|
|
|
|
**Definition**:
|
|
```
|
|
{
|
|
(Self -- bool) truthy:
|
|
(Self Self -- Self) and:
|
|
(Self Self -- Self) or:
|
|
(Self -- Self) not:
|
|
} ::Logical trait
|
|
```
|
|
|
|
**Methods**:
|
|
|
|
#### truthy:
|
|
**Signature**: `(Self -- bool)`
|
|
**Description**: Convert to boolean (truthiness check).
|
|
**Example**: `5 truthy // => true`, `0 truthy // => false`
|
|
|
|
#### and:
|
|
**Signature**: `(Self Self -- Self)`
|
|
**Description**: Logical AND - returns first if falsy, else second.
|
|
**Example**: `true false and // => false`
|
|
|
|
#### or:
|
|
**Signature**: `(Self Self -- Self)`
|
|
**Description**: Logical OR - returns first if truthy, else second.
|
|
**Example**: `true false or // => true`
|
|
|
|
#### not:
|
|
**Signature**: `(Self -- Self)`
|
|
**Description**: Logical NOT - inverts truthiness.
|
|
**Example**: `false not // => true`
|
|
|
|
**Standard Implementations**: bool, numbers, Option, Result
|
|
|
|
**Related Traits**: None
|
|
|
|
**See Also**: Section 4.4 (Logical Operators)
|
|
|
|
### Multiplyable
|
|
|
|
**Generic Parameters**: None
|
|
**Inherits**: None
|
|
|
|
**Definition**:
|
|
```
|
|
{
|
|
(Self Self -- Self) *:
|
|
(Self Self -- Self) /:
|
|
(Self Self -- Self) %:
|
|
} ::Multiplyable trait
|
|
```
|
|
|
|
**Methods**:
|
|
|
|
#### *:
|
|
**Signature**: `(Self Self -- Self)`
|
|
**Description**: Multiply two values.
|
|
**Example**: `5 6 * // => 30`
|
|
|
|
#### /:
|
|
**Signature**: `(Self Self -- Self)`
|
|
**Description**: Divide first value by second.
|
|
**Example**: `20 4 / // => 5`
|
|
|
|
#### %:
|
|
**Signature**: `(Self Self -- Self)`
|
|
**Description**: Remainder after division (modulo).
|
|
**Example**: `17 5 % // => 2`
|
|
|
|
**Standard Implementations**: All numeric types
|
|
|
|
**Related Traits**: Addable, Exponentiable, Number
|
|
|
|
**See Also**: Section 4.2 (Arithmetic Operators)
|
|
|
|
### Number
|
|
|
|
**Generic Parameters**: None
|
|
**Inherits**: Addable, Multiplyable, Exponentiable, Comparable, Logarithmic
|
|
|
|
**Definition**:
|
|
```
|
|
[ ::Addable ::Multiplyable ::Exponentiable ::Comparable ::Logarithmic ] ::Number inher
|
|
{ } ::Number trait
|
|
```
|
|
|
|
**Description**: Composite trait representing the full suite of numeric operations.
|
|
|
|
**Standard Implementations**: All numeric types (i8, i16, i32, i64, u8, u16, u32, u64, f32, f64)
|
|
|
|
**Related Traits**: Addable, Multiplyable, Exponentiable, Comparable, Logarithmic
|
|
|
|
**See Also**: Section 4.2 (Arithmetic Operators)
|
|
|
|
### Orderable
|
|
|
|
**Generic Parameters**: None
|
|
**Inherits**: None
|
|
|
|
**Definition**:
|
|
```
|
|
{
|
|
(Self Self -- bool) >:
|
|
(Self Self -- bool) >=:
|
|
(Self Self -- bool) <:
|
|
(Self Self -- bool) <=:
|
|
} ::Orderable trait
|
|
```
|
|
|
|
**Methods**:
|
|
|
|
#### >:
|
|
**Signature**: `(Self Self -- bool)`
|
|
**Description**: True if first value is greater than second.
|
|
**Example**: `5 3 > // => true`
|
|
|
|
#### >=:
|
|
**Signature**: `(Self Self -- bool)`
|
|
**Description**: True if first value is greater than or equal to second.
|
|
**Example**: `5 5 >= // => true`
|
|
|
|
#### <:
|
|
**Signature**: `(Self Self -- bool)`
|
|
**Description**: True if first value is less than second.
|
|
**Example**: `3 5 < // => true`
|
|
|
|
#### <=:
|
|
**Signature**: `(Self Self -- bool)`
|
|
**Description**: True if first value is less than or equal to second.
|
|
**Example**: `5 5 <= // => true`
|
|
|
|
**Standard Implementations**: All numeric types, strings, characters
|
|
|
|
**Related Traits**: Equatable, Comparable
|
|
|
|
**See Also**: Section 4.3 (Comparison Operators)
|
|
|
|
### Parseable
|
|
|
|
**Generic Parameters**: None
|
|
**Inherits**: None
|
|
|
|
**Definition**:
|
|
```
|
|
{
|
|
(String -- Self) parse:
|
|
} ::Parseable trait
|
|
```
|
|
|
|
**Methods**:
|
|
|
|
#### parse:
|
|
**Signature**: `(String -- Self)`
|
|
**Description**: Parse string to value of this type.
|
|
**Example**: `"123" parse // => 123`
|
|
|
|
**Standard Implementations**: All numeric types, bool
|
|
|
|
**Related Traits**: Stringifiable, Convertible
|
|
|
|
**See Also**: Appendix A (parse)
|
|
|
|
### Selectable<T>
|
|
|
|
**Generic Parameters**: T (element type)
|
|
**Inherits**: None
|
|
|
|
**Definition**:
|
|
```
|
|
{
|
|
(Self Size -- T) at:
|
|
} ::Selectable<T> trait
|
|
```
|
|
|
|
**Methods**:
|
|
|
|
#### at:
|
|
**Signature**: `(Self Size -- T)`
|
|
**Description**: Access element at given index.
|
|
**Example**: `[10 20 30] 1 at // => 20`
|
|
|
|
**Standard Implementations**: Arrays, strings
|
|
|
|
**Related Traits**: ArrayOf, Sized, Sliceable
|
|
|
|
**See Also**: Section 7.4 (Arrays)
|
|
|
|
### Size
|
|
|
|
**Generic Parameters**: None
|
|
**Inherits**: Addable, Comparable, Convertible<i64>
|
|
|
|
**Definition**:
|
|
```
|
|
[ ::Addable ::Comparable ::Convertible<i64> ] ::Size inher
|
|
{ } ::Size trait
|
|
```
|
|
|
|
**Description**: Represents types suitable for indexing and sizing operations.
|
|
|
|
**Standard Implementations**: All integer types (i8, i16, i32, i64, u8, u16, u32, u64)
|
|
|
|
**Related Traits**: Addable, Comparable, Convertible
|
|
|
|
**See Also**: Section 4.1 (Stack Operations - pick, roll)
|
|
|
|
### Sized
|
|
|
|
**Generic Parameters**: None
|
|
**Inherits**: None
|
|
|
|
**Definition**:
|
|
```
|
|
{
|
|
(Self -- i64) length:
|
|
} ::Sized trait
|
|
```
|
|
|
|
**Methods**:
|
|
|
|
#### length:
|
|
**Signature**: `(Self -- i64)`
|
|
**Description**: Get the number of elements in a container.
|
|
**Example**: `[1 2 3 4 5] length // => 5`
|
|
|
|
**Standard Implementations**: Arrays, strings
|
|
|
|
**Related Traits**: ArrayOf, Selectable, Sliceable
|
|
|
|
**See Also**: Section 7.4 (Arrays)
|
|
|
|
### Sliceable
|
|
|
|
**Generic Parameters**: None
|
|
**Inherits**: None
|
|
|
|
**Definition**:
|
|
```
|
|
{
|
|
(Self Size Size -- Self) slice:
|
|
} ::Sliceable trait
|
|
```
|
|
|
|
**Methods**:
|
|
|
|
#### slice:
|
|
**Signature**: `(Self Size Size -- Self)`
|
|
**Description**: Extract elements from start to end index.
|
|
**Example**: `[10 20 30 40] 1 3 slice // => [20 30]`
|
|
|
|
**Standard Implementations**: Arrays, strings
|
|
|
|
**Related Traits**: ArrayOf, Sized, Selectable
|
|
|
|
**See Also**: Section 7.4 (Arrays)
|
|
|
|
### Stackable
|
|
|
|
**Generic Parameters**: None
|
|
**Inherits**: None
|
|
|
|
**Definition**:
|
|
```
|
|
{
|
|
(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:
|
|
} ::Stackable trait
|
|
```
|
|
|
|
**Methods**:
|
|
|
|
#### dup:
|
|
**Signature**: `(Self -- Self Self)`
|
|
**Description**: Duplicate the top item on the stack.
|
|
**Example**: `5 dup // => 5 5`
|
|
|
|
#### drop:
|
|
**Signature**: `(Self -- )`
|
|
**Description**: Remove and discard the top item.
|
|
**Example**: `5 10 drop // => 5`
|
|
|
|
#### swap:
|
|
**Signature**: `(Self Self -- Self Self)`
|
|
**Description**: Swap the top two items.
|
|
**Example**: `5 10 swap // => 10 5`
|
|
|
|
#### over:
|
|
**Signature**: `(Self Self -- Self Self Self)`
|
|
**Description**: Copy the second item to the top.
|
|
**Example**: `5 10 over // => 5 10 5`
|
|
|
|
#### rot:
|
|
**Signature**: `(Self Self Self -- Self Self Self)`
|
|
**Description**: Rotate the top three items.
|
|
**Example**: `1 2 3 rot // => 2 3 1`
|
|
|
|
#### pick:
|
|
**Signature**: `(Size -- Self)`
|
|
**Description**: Copy nth item to top (0 = top).
|
|
**Example**: `1 2 3 4 2 pick // => 1 2 3 4 2`
|
|
|
|
#### roll:
|
|
**Signature**: `(Size Size -- )`
|
|
**Description**: Rotate n items, times times.
|
|
**Example**: `1 2 3 4 3 1 roll // => 1 3 4 2`
|
|
|
|
#### depth:
|
|
**Signature**: `(-- Size)`
|
|
**Description**: Push current stack depth.
|
|
**Example**: `1 2 3 depth // => 1 2 3 3`
|
|
|
|
**Standard Implementations**: All primitive types
|
|
|
|
**Related Traits**: None
|
|
|
|
**See Also**: Section 4.1 (Stack Operations)
|
|
|
|
### String
|
|
|
|
**Generic Parameters**: None
|
|
**Inherits**: Concatenable
|
|
|
|
**Definition**:
|
|
```
|
|
[ ::Concatenable ] ::String inher
|
|
{
|
|
(Self Size Size -- Self) substr:
|
|
(Self Self -- ArrayOf<Self>) split:
|
|
} ::String trait
|
|
```
|
|
|
|
**Methods**:
|
|
|
|
#### substr:
|
|
**Signature**: `(Self Size Size -- Self)`
|
|
**Description**: Extract substring from start to end index.
|
|
**Example**: `"hello" 1 3 substr // => "el"`
|
|
|
|
#### split:
|
|
**Signature**: `(Self Self -- ArrayOf<Self>)`
|
|
**Description**: Split string by delimiter.
|
|
**Example**: `"a,b,c" "," split // => ["a" "b" "c"]`
|
|
|
|
**Standard Implementations**: String type
|
|
|
|
**Related Traits**: Concatenable, Sized, Sliceable
|
|
|
|
**See Also**: Section 11.3 (String Operations)
|
|
|
|
### Stringifiable
|
|
|
|
**Generic Parameters**: None
|
|
**Inherits**: None
|
|
|
|
**Definition**:
|
|
```
|
|
{
|
|
(Self -- String) to_str:
|
|
} ::Stringifiable trait
|
|
```
|
|
|
|
**Methods**:
|
|
|
|
#### to_str:
|
|
**Signature**: `(Self -- String)`
|
|
**Description**: Convert value to string representation.
|
|
**Example**: `42 to_str // => "42"`
|
|
|
|
**Standard Implementations**: All types
|
|
|
|
**Related Traits**: Parseable, Convertible
|
|
|
|
**See Also**: Section 11.3 (Type Conversion)
|
|
|
|
---
|
|
|
|
## Appendix C: Complete Operator Reference
|
|
|
|
This appendix provides a complete alphabetical reference of all operators in the language.
|
|
|
|
### Operator List
|
|
|
|
`!=`, `%`, `&` (bitand), `*`, `+`, `-`, `/`, `<`, `<=`, `==`, `>`, `>=`, `^`, `|` (bitor), `and`, `at`, `bitand`, `bitnot`, `bitor`, `bitxor`, `break`, `concat`, `continue`, `depth`, `drop`, `dup`, `each`, `enum`, `eval`, `filter`, `fn`, `for`, `get`, `if`, `impl`, `inher`, `lambda`, `length`, `ln`, `log`, `logb`, `map`, `match`, `not`, `or`, `over`, `pick`, `reduce`, `reverse`, `roll`, `rot`, `set`, `shl`, `shr`, `slice`, `struct`, `substr`, `swap`, `trait`, `transpose`, `union`, `while`, `window`
|
|
|
|
### Alphabetical Operator Reference
|
|
|
|
#### !=
|
|
**Operator Type**: Comparison
|
|
**Signature**: `(Equatable Equatable -- bool)`
|
|
**Trait**: Equatable
|
|
**Description**: Test if two values are not equal.
|
|
**Example**: `5 3 != // => true`
|
|
**See Also**: ==, <, >
|
|
**Section**: 4.3 (Comparison Operators)
|
|
|
|
#### %
|
|
**Operator Type**: Arithmetic
|
|
**Signature**: `(Multiplyable Multiplyable -- Multiplyable)`
|
|
**Trait**: Multiplyable
|
|
**Description**: Remainder after division (modulo).
|
|
**Example**: `17 5 % // => 2`
|
|
**See Also**: /, *
|
|
**Section**: 4.2 (Arithmetic Operators)
|
|
|
|
#### *
|
|
**Operator Type**: Arithmetic
|
|
**Signature**: `(Multiplyable Multiplyable -- Multiplyable)`
|
|
**Trait**: Multiplyable
|
|
**Description**: Multiply two values.
|
|
**Example**: `5 6 * // => 30`
|
|
**See Also**: /, +, -
|
|
**Section**: 4.2 (Arithmetic Operators)
|
|
|
|
#### +
|
|
**Operator Type**: Arithmetic
|
|
**Signature**: `(Addable Addable -- Addable)`
|
|
**Trait**: Addable
|
|
**Description**: Add two values.
|
|
**Example**: `3 4 + // => 7`
|
|
**See Also**: -, *, /
|
|
**Section**: 4.2 (Arithmetic Operators)
|
|
|
|
#### -
|
|
**Operator Type**: Arithmetic
|
|
**Signature**: `(Addable Addable -- Addable)`
|
|
**Trait**: Addable
|
|
**Description**: Subtract second value from first.
|
|
**Example**: `10 3 - // => 7`
|
|
**See Also**: +, *, /
|
|
**Section**: 4.2 (Arithmetic Operators)
|
|
|
|
#### /
|
|
**Operator Type**: Arithmetic
|
|
**Signature**: `(Multiplyable Multiplyable -- Multiplyable)`
|
|
**Trait**: Multiplyable
|
|
**Description**: Divide first value by second.
|
|
**Example**: `20 4 / // => 5`
|
|
**See Also**: *, %, +
|
|
**Section**: 4.2 (Arithmetic Operators)
|
|
|
|
#### <
|
|
**Operator Type**: Comparison
|
|
**Signature**: `(Orderable Orderable -- bool)`
|
|
**Trait**: Orderable
|
|
**Description**: True if first value is less than second.
|
|
**Example**: `3 5 < // => true`
|
|
**See Also**: <=, >, >=
|
|
**Section**: 4.3 (Comparison Operators)
|
|
|
|
#### <=
|
|
**Operator Type**: Comparison
|
|
**Signature**: `(Orderable Orderable -- bool)`
|
|
**Trait**: Orderable
|
|
**Description**: True if first value is less than or equal to second.
|
|
**Example**: `5 5 <= // => true`
|
|
**See Also**: <, >, >=
|
|
**Section**: 4.3 (Comparison Operators)
|
|
|
|
#### ==
|
|
**Operator Type**: Comparison
|
|
**Signature**: `(Equatable Equatable -- bool)`
|
|
**Trait**: Equatable
|
|
**Description**: Test if two values are equal.
|
|
**Example**: `5 5 == // => true`
|
|
**See Also**: !=, <, >
|
|
**Section**: 4.3 (Comparison Operators)
|
|
|
|
#### >
|
|
**Operator Type**: Comparison
|
|
**Signature**: `(Orderable Orderable -- bool)`
|
|
**Trait**: Orderable
|
|
**Description**: True if first value is greater than second.
|
|
**Example**: `5 3 > // => true`
|
|
**See Also**: >=, <, <=
|
|
**Section**: 4.3 (Comparison Operators)
|
|
|
|
#### >=
|
|
**Operator Type**: Comparison
|
|
**Signature**: `(Orderable Orderable -- bool)`
|
|
**Trait**: Orderable
|
|
**Description**: True if first value is greater than or equal to second.
|
|
**Example**: `5 5 >= // => true`
|
|
**See Also**: >, <, <=
|
|
**Section**: 4.3 (Comparison Operators)
|
|
|
|
#### ^
|
|
**Operator Type**: Arithmetic
|
|
**Signature**: `(Exponentiable Exponentiable -- Exponentiable)`
|
|
**Trait**: Exponentiable
|
|
**Description**: Raise first value to power of second (exponentiation).
|
|
**Example**: `2 8 ^ // => 256`
|
|
**See Also**: log, ln, logb
|
|
**Section**: 4.2 (Arithmetic Operators)
|
|
|
|
#### and
|
|
**Operator Type**: Logical
|
|
**Signature**: `(Logical Logical -- Logical)`
|
|
**Trait**: Logical
|
|
**Description**: Logical AND - returns first if falsy, else second.
|
|
**Example**: `true false and // => false`
|
|
**See Also**: or, not
|
|
**Section**: 4.4 (Logical Operators)
|
|
|
|
#### at
|
|
**Operator Type**: Container Access
|
|
**Signature**: `(Selectable<T> Size -- T)`
|
|
**Trait**: Selectable<T>
|
|
**Description**: Access element at given index.
|
|
**Example**: `[10 20 30] 1 at // => 20`
|
|
**See Also**: slice, length
|
|
**Section**: 7.4 (Arrays)
|
|
|
|
#### bitand
|
|
**Operator Type**: Bitwise
|
|
**Signature**: `(Bitwise Bitwise -- Bitwise)`
|
|
**Trait**: Bitwise
|
|
**Description**: Bitwise AND of two values.
|
|
**Example**: `0xFF 0x0F bitand // => 0x0F`
|
|
**See Also**: bitor, bitxor, bitnot
|
|
**Section**: 4.5 (Bitwise Operators)
|
|
|
|
#### bitnot
|
|
**Operator Type**: Bitwise
|
|
**Signature**: `(Bitwise -- Bitwise)`
|
|
**Trait**: Bitwise
|
|
**Description**: Bitwise NOT (complement) of value.
|
|
**Example**: `0xFF bitnot // => (inverted bits)`
|
|
**See Also**: bitand, bitor, bitxor
|
|
**Section**: 4.5 (Bitwise Operators)
|
|
|
|
#### bitor
|
|
**Operator Type**: Bitwise
|
|
**Signature**: `(Bitwise Bitwise -- Bitwise)`
|
|
**Trait**: Bitwise
|
|
**Description**: Bitwise OR of two values.
|
|
**Example**: `0xF0 0x0F bitor // => 0xFF`
|
|
**See Also**: bitand, bitxor, bitnot
|
|
**Section**: 4.5 (Bitwise Operators)
|
|
|
|
#### bitxor
|
|
**Operator Type**: Bitwise
|
|
**Signature**: `(Bitwise Bitwise -- Bitwise)`
|
|
**Trait**: Bitwise
|
|
**Description**: Bitwise XOR of two values.
|
|
**Example**: `0xFF 0x0F bitxor // => 0xF0`
|
|
**See Also**: bitand, bitor, bitnot
|
|
**Section**: 4.5 (Bitwise Operators)
|
|
|
|
#### break
|
|
**Operator Type**: Control Flow
|
|
**Signature**: `(--)`
|
|
**Description**: Exit the current loop immediately.
|
|
**Example**: `{ true } { condition { break } { } if } while`
|
|
**See Also**: continue, while, for
|
|
**Section**: 6.4 (Loop Control)
|
|
|
|
#### concat
|
|
**Operator Type**: Container
|
|
**Signature**: `(Concatenable Concatenable -- Concatenable)`
|
|
**Trait**: Concatenable
|
|
**Description**: Concatenate two containers or strings.
|
|
**Example**: `[1 2 3] [4 5 6] concat // => [1 2 3 4 5 6]`
|
|
**See Also**: slice, reverse
|
|
**Section**: 7.4 (Arrays)
|
|
|
|
#### continue
|
|
**Operator Type**: Control Flow
|
|
**Signature**: `(--)`
|
|
**Description**: Skip to the next iteration of the current loop.
|
|
**Example**: `1 10 { dup 2 % 0 == { continue } { print } if } for`
|
|
**See Also**: break, while, for
|
|
**Section**: 6.4 (Loop Control)
|
|
|
|
#### depth
|
|
**Operator Type**: Stack Manipulation
|
|
**Signature**: `(-- Size)`
|
|
**Trait**: Stackable
|
|
**Description**: Push current stack depth onto the stack.
|
|
**Example**: `1 2 3 depth // => 1 2 3 3`
|
|
**See Also**: pick, roll
|
|
**Section**: 4.1 (Stack Operations)
|
|
|
|
#### drop
|
|
**Operator Type**: Stack Manipulation
|
|
**Signature**: `(Self --)`
|
|
**Trait**: Stackable
|
|
**Description**: Remove and discard the top item from the stack.
|
|
**Example**: `5 10 drop // => 5`
|
|
**See Also**: dup, swap
|
|
**Section**: 4.1 (Stack Operations)
|
|
|
|
#### dup
|
|
**Operator Type**: Stack Manipulation
|
|
**Signature**: `(Self -- Self Self)`
|
|
**Trait**: Stackable
|
|
**Description**: Duplicate the top item on the stack.
|
|
**Example**: `5 dup // => 5 5`
|
|
**See Also**: drop, over
|
|
**Section**: 4.1 (Stack Operations)
|
|
|
|
#### each
|
|
**Operator Type**: Array Combinator
|
|
**Signature**: `(ArrayOf<T> TokenString --)`
|
|
**Description**: Apply function to each element (side effects).
|
|
**Example**: `[1 2 3] { print } each`
|
|
**See Also**: map, filter, reduce
|
|
**Section**: 7.4 (Arrays)
|
|
|
|
#### enum
|
|
**Operator Type**: Definition
|
|
**Signature**: `(TokenString Identifier --)`
|
|
**Trait**: Implementable
|
|
**Description**: Define an enumeration type.
|
|
**Example**: `{ Pending: Active: Complete: } ::Status enum`
|
|
**See Also**: struct, union, trait
|
|
**Section**: 7.3 (Enums)
|
|
|
|
#### eval
|
|
**Operator Type**: Meta
|
|
**Signature**: `(TokenString --)`
|
|
**Trait**: Implementable
|
|
**Description**: Parse and execute TokenString as code.
|
|
**Example**: `"2 3 +" eval // => 5`
|
|
**See Also**: lambda
|
|
**Section**: 11.1 (Dynamic Code Evaluation)
|
|
|
|
#### filter
|
|
**Operator Type**: Array Combinator
|
|
**Signature**: `(ArrayOf<T> TokenString -- ArrayOf<T>)`
|
|
**Description**: Keep only elements matching predicate.
|
|
**Example**: `[1 2 3 4 5] { 2 % 0 == } filter // => [2 4]`
|
|
**See Also**: map, reduce, each
|
|
**Section**: 7.4 (Arrays)
|
|
|
|
#### fn
|
|
**Operator Type**: Definition
|
|
**Signature**: `(TypeTuple TokenString Identifier --)`
|
|
**Trait**: Implementable
|
|
**Description**: Define a function.
|
|
**Example**: `(Number -- Number) { dup * } ::square fn`
|
|
**See Also**: lambda, trait, impl
|
|
**Section**: 5.2 (Defining Functions)
|
|
|
|
#### for
|
|
**Operator Type**: Control Flow
|
|
**Signature**: `(Size Size TokenString --)`
|
|
**Description**: Loop from start to end, pushing counter each iteration.
|
|
**Example**: `1 10 { dup print } for`
|
|
**See Also**: while, break, continue
|
|
**Section**: 6.3 (For Loops)
|
|
|
|
#### get
|
|
**Operator Type**: Struct Access
|
|
**Signature**: `(Struct Identifier -- FieldValue)`
|
|
**Description**: Get field value from struct (consumes struct and field identifier).
|
|
**Example**: `point ::x get`
|
|
**See Also**: set
|
|
**Section**: 7.1 (Structs)
|
|
|
|
#### if
|
|
**Operator Type**: Control Flow
|
|
**Signature**: `(bool TokenString TokenString --)`
|
|
**Description**: Conditional execution - execute first block if true, second if false.
|
|
**Example**: `x 0 > { "positive" print } { "negative" print } if`
|
|
**See Also**: match, while
|
|
**Section**: 6.1 (Conditionals)
|
|
|
|
#### impl
|
|
**Operator Type**: Definition
|
|
**Signature**: `(Identifier TokenString Identifier --)`
|
|
**Trait**: Implementable
|
|
**Description**: Implement a trait for a type.
|
|
**Example**: `::Addable { ... } ::Point impl`
|
|
**See Also**: trait, inher
|
|
**Section**: 9.3 (Implementing Traits)
|
|
|
|
#### inher
|
|
**Operator Type**: Definition
|
|
**Signature**: `(ArrayOf<Identifier> Identifier --)`
|
|
**Trait**: Implementable
|
|
**Description**: Declare trait inheritance.
|
|
**Example**: `[ ::Orderable ::Equatable ] ::Comparable inher`
|
|
**See Also**: trait, impl
|
|
**Section**: 9.4 (Trait Inheritance)
|
|
|
|
#### lambda
|
|
**Operator Type**: Meta
|
|
**Signature**: `(TokenString -- Callable)`
|
|
**Trait**: Implementable
|
|
**Description**: Convert TokenString to callable code block.
|
|
**Example**: `{ dup * } lambda ::square swap`
|
|
**See Also**: eval, fn
|
|
**Section**: 5.6 (Lambda Functions)
|
|
|
|
#### length
|
|
**Operator Type**: Container
|
|
**Signature**: `(Sized -- i64)`
|
|
**Trait**: Sized
|
|
**Description**: Get the number of elements in a container.
|
|
**Example**: `[1 2 3 4 5] length // => 5`
|
|
**See Also**: at, slice
|
|
**Section**: 7.4 (Arrays)
|
|
|
|
#### ln
|
|
**Operator Type**: Arithmetic
|
|
**Signature**: `(Logarithmic -- Logarithmic)`
|
|
**Trait**: Logarithmic
|
|
**Description**: Natural logarithm (base e).
|
|
**Example**: `2.718 ln // => 1.0`
|
|
**See Also**: log, logb, ^
|
|
**Section**: 4.2 (Arithmetic Operators)
|
|
|
|
#### log
|
|
**Operator Type**: Arithmetic
|
|
**Signature**: `(Logarithmic -- Logarithmic)`
|
|
**Trait**: Logarithmic
|
|
**Description**: Logarithm base 10.
|
|
**Example**: `100 log // => 2.0`
|
|
**See Also**: ln, logb, ^
|
|
**Section**: 4.2 (Arithmetic Operators)
|
|
|
|
#### logb
|
|
**Operator Type**: Arithmetic
|
|
**Signature**: `(Logarithmic Logarithmic -- Logarithmic)`
|
|
**Trait**: Logarithmic
|
|
**Description**: Logarithm with custom base.
|
|
**Example**: `8 2 logb // => 3.0`
|
|
**See Also**: log, ln, ^
|
|
**Section**: 4.2 (Arithmetic Operators)
|
|
|
|
#### map
|
|
**Operator Type**: Array Combinator
|
|
**Signature**: `(ArrayOf<T> TokenString -- ArrayOf<U>)`
|
|
**Description**: Transform each element with function.
|
|
**Example**: `[1 2 3 4] { 2 * } map // => [2 4 6 8]`
|
|
**See Also**: filter, reduce, each
|
|
**Section**: 7.4 (Arrays)
|
|
|
|
#### match
|
|
**Operator Type**: Control Flow
|
|
**Signature**: `(Value TokenString --)`
|
|
**Description**: Pattern match value against multiple patterns.
|
|
**Example**: `opt { Some(x) => { x print } None => { "Nothing" print } } match`
|
|
**See Also**: if
|
|
**Section**: 6.5 (Pattern Matching)
|
|
|
|
#### not
|
|
**Operator Type**: Logical
|
|
**Signature**: `(Logical -- Logical)`
|
|
**Trait**: Logical
|
|
**Description**: Logical NOT - inverts truthiness.
|
|
**Example**: `false not // => true`
|
|
**See Also**: and, or
|
|
**Section**: 4.4 (Logical Operators)
|
|
|
|
#### or
|
|
**Operator Type**: Logical
|
|
**Signature**: `(Logical Logical -- Logical)`
|
|
**Trait**: Logical
|
|
**Description**: Logical OR - returns first if truthy, else second.
|
|
**Example**: `true false or // => true`
|
|
**See Also**: and, not
|
|
**Section**: 4.4 (Logical Operators)
|
|
|
|
#### over
|
|
**Operator Type**: Stack Manipulation
|
|
**Signature**: `(Self Self -- Self Self Self)`
|
|
**Trait**: Stackable
|
|
**Description**: Copy the second item to the top of the stack.
|
|
**Example**: `5 10 over // => 5 10 5`
|
|
**See Also**: dup, swap, rot
|
|
**Section**: 4.1 (Stack Operations)
|
|
|
|
#### pick
|
|
**Operator Type**: Stack Manipulation
|
|
**Signature**: `(Size -- Self)`
|
|
**Trait**: Stackable
|
|
**Description**: Copy nth item to top (0 = top, 1 = second, etc.).
|
|
**Example**: `1 2 3 4 2 pick // => 1 2 3 4 2`
|
|
**See Also**: roll, depth
|
|
**Section**: 4.1 (Stack Operations)
|
|
|
|
#### reduce
|
|
**Operator Type**: Array Combinator
|
|
**Signature**: `(ArrayOf<T> T TokenString -- T)`
|
|
**Description**: Fold array with accumulator function.
|
|
**Example**: `[1 2 3 4] 0 { + } reduce // => 10`
|
|
**See Also**: map, filter, each
|
|
**Section**: 7.4 (Arrays)
|
|
|
|
#### reverse
|
|
**Operator Type**: Array
|
|
**Signature**: `(ArrayOf<T> -- ArrayOf<T>)`
|
|
**Description**: Reverse order of array elements.
|
|
**Example**: `[1 2 3] reverse // => [3 2 1]`
|
|
**See Also**: transpose, concat
|
|
**Section**: 7.4 (Arrays)
|
|
|
|
#### roll
|
|
**Operator Type**: Stack Manipulation
|
|
**Signature**: `(Size Size --)`
|
|
**Trait**: Stackable
|
|
**Description**: Rotate n items, times times.
|
|
**Example**: `1 2 3 4 3 1 roll // => 1 3 4 2`
|
|
**See Also**: rot, pick
|
|
**Section**: 4.1 (Stack Operations)
|
|
|
|
#### rot
|
|
**Operator Type**: Stack Manipulation
|
|
**Signature**: `(Self Self Self -- Self Self Self)`
|
|
**Trait**: Stackable
|
|
**Description**: Rotate the top three items.
|
|
**Example**: `1 2 3 rot // => 2 3 1`
|
|
**See Also**: swap, roll
|
|
**Section**: 4.1 (Stack Operations)
|
|
|
|
#### set
|
|
**Operator Type**: Struct Access
|
|
**Signature**: `(Value Identifier -- Struct)`
|
|
**Description**: Set field value in struct (consumes value and field identifier).
|
|
**Example**: `15.0 ::x set`
|
|
**See Also**: get
|
|
**Section**: 7.1 (Structs)
|
|
|
|
#### shl
|
|
**Operator Type**: Bitwise
|
|
**Signature**: `(Bitwise Size -- Bitwise)`
|
|
**Trait**: Bitwise
|
|
**Description**: Shift bits left by n positions.
|
|
**Example**: `4 2 shl // => 16`
|
|
**See Also**: shr, bitand, bitor
|
|
**Section**: 4.5 (Bitwise Operators)
|
|
|
|
#### shr
|
|
**Operator Type**: Bitwise
|
|
**Signature**: `(Bitwise Size -- Bitwise)`
|
|
**Trait**: Bitwise
|
|
**Description**: Shift bits right by n positions.
|
|
**Example**: `16 2 shr // => 4`
|
|
**See Also**: shl, bitand, bitor
|
|
**Section**: 4.5 (Bitwise Operators)
|
|
|
|
#### slice
|
|
**Operator Type**: Container
|
|
**Signature**: `(Sliceable Size Size -- Sliceable)`
|
|
**Trait**: Sliceable
|
|
**Description**: Extract elements from start to end index.
|
|
**Example**: `[10 20 30 40] 1 3 slice // => [20 30]`
|
|
**See Also**: at, length
|
|
**Section**: 7.4 (Arrays)
|
|
|
|
#### struct
|
|
**Operator Type**: Definition
|
|
**Signature**: `(TypeTuple TokenString Identifier --)`
|
|
**Trait**: Implementable
|
|
**Description**: Define a struct type.
|
|
**Example**: `(T T --) { x: y: } ::Point<T> struct`
|
|
**See Also**: union, enum, get, set
|
|
**Section**: 7.1 (Structs)
|
|
|
|
#### substr
|
|
**Operator Type**: String
|
|
**Signature**: `(String Size Size -- String)`
|
|
**Trait**: String
|
|
**Description**: Extract substring from start to end index.
|
|
**Example**: `"hello" 1 3 substr // => "el"`
|
|
**See Also**: slice, split
|
|
**Section**: 11.3 (String Operations)
|
|
|
|
#### swap
|
|
**Operator Type**: Stack Manipulation
|
|
**Signature**: `(Self Self -- Self Self)`
|
|
**Trait**: Stackable
|
|
**Description**: Swap the top two items on the stack.
|
|
**Example**: `5 10 swap // => 10 5`
|
|
**See Also**: dup, rot
|
|
**Section**: 4.1 (Stack Operations)
|
|
|
|
#### trait
|
|
**Operator Type**: Definition
|
|
**Signature**: `(TokenString Identifier --)`
|
|
**Trait**: Implementable
|
|
**Description**: Define a new trait.
|
|
**Example**: `{ (Self -- ) draw: } ::Drawable trait`
|
|
**See Also**: impl, inher
|
|
**Section**: 9.2 (Defining Traits)
|
|
|
|
#### transpose
|
|
**Operator Type**: Array
|
|
**Signature**: `(ArrayOf<ArrayOf<T>> -- ArrayOf<ArrayOf<T>>)`
|
|
**Description**: Transpose a 2D array (swap rows and columns).
|
|
**Example**: `[[1 2] [3 4]] transpose // => [[1 3] [2 4]]`
|
|
**See Also**: reverse
|
|
**Section**: 7.4 (Arrays)
|
|
|
|
#### union
|
|
**Operator Type**: Definition
|
|
**Signature**: `(TypeTuple TokenString Identifier --)`
|
|
**Trait**: Implementable
|
|
**Description**: Define a union type with tagged variants.
|
|
**Example**: `(T --) { Some(T) None } ::Option<T> union`
|
|
**See Also**: struct, enum, match
|
|
**Section**: 7.2 (Unions)
|
|
|
|
#### while
|
|
**Operator Type**: Control Flow
|
|
**Signature**: `(TokenString TokenString --)`
|
|
**Description**: Loop while condition is truthy, executing body each iteration.
|
|
**Example**: `{ dup 10 < } { dup print 1 + } while`
|
|
**See Also**: for, break, continue, if
|
|
**Section**: 6.2 (While Loops)
|
|
|
|
#### window
|
|
**Operator Type**: Array
|
|
**Signature**: `(ArrayOf<T> Size -- ArrayOf<ArrayOf<T>>)`
|
|
**Description**: Create sliding windows of given size.
|
|
**Example**: `[1 2 3 4] 2 window // => [[1 2] [2 3] [3 4]]`
|
|
**See Also**: slice
|
|
**Section**: 7.4 (Arrays)
|
|
|
|
---
|
|
|
|
## Appendix D: Grammar Summary
|
|
|
|
This appendix provides a concise grammar reference. For complete specifications of language constructs (fn, struct, trait, impl, etc.), see the `::Implementable` trait in Appendix B.
|
|
|
|
### D.1 Lexical Grammar
|
|
|
|
**Comments**:
|
|
```
|
|
line_comment ::= "//" <any characters until newline>
|
|
```
|
|
|
|
**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)* "}"
|
|
```
|
|
|
|
### D.2 Expression Grammar
|
|
|
|
```
|
|
expression ::= literal
|
|
| identifier
|
|
| identifier_literal
|
|
| expression operator
|
|
| control_flow
|
|
| definition
|
|
|
|
literal ::= integer | float | string | boolean | array
|
|
|
|
operator ::= built_in_operator | user_defined_operator
|
|
|
|
control_flow ::= if_expr | while_expr | for_expr | match_expr
|
|
```
|
|
|
|
**Note on Operator Precedence**: Stack-based postfix notation eliminates the need for operator precedence. Operations are performed in the order they appear, operating on values already on the stack.
|
|
|
|
### D.3 Type Grammar
|
|
|
|
**Type Tuples (Stack Signatures)**:
|
|
```
|
|
type_tuple ::= "(" type_list "--" type_list ")"
|
|
| "(---)"
|
|
type_list ::= (type)*
|
|
type ::= identifier
|
|
| generic_type
|
|
| trait_constraint
|
|
|
|
generic_type ::= identifier "<" type_param_list ">"
|
|
type_param_list ::= type_param ("," type_param)*
|
|
type_param ::= identifier (":" trait_constraint)?
|
|
```
|
|
|
|
### D.4 Construct Grammar
|
|
|
|
Language constructs (fn, struct, trait, impl, enum, union, inher) are defined by operators in the `::Implementable` trait. These operators parse TokenStrings to create language-level definitions.
|
|
|
|
**High-Level Patterns**:
|
|
- Functions: `(inputs -- outputs) { body } ::name fn`
|
|
- Structs: `(field_types --) { field_names: } ::name<type_params>? struct`
|
|
- Unions: `(variant_types --) { Variant(T) ... } ::name<type_params>? union`
|
|
- Enums: `{ Variant value?: ... } ::name enum`
|
|
- Traits: `{ (sig) method: ... } ::identifier<type_params>? trait`
|
|
- Trait Impl: `::trait_id { (sig) { body } method: ... } ::type_id<type_params>? impl`
|
|
- Trait Inheritance: `[ identifier_list ] ::identifier<type_params>? inher { } ::identifier<type_params>? trait`
|
|
|
|
> **Complete Specification**: See Appendix B (`::Implementable` trait) for precise definitions of these construct operators.
|
|
|
|
---
|
|
|
|
## Appendix E: 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::<module>::<item>`
|
|
- User modules: Relative to current file
|
|
- Third-party: Package manager integration (future)
|
|
|
|
**Benefits**:
|
|
- Clean namespaces
|
|
- Explicit dependencies
|
|
- Code organization
|
|
- Faster compilation (selective imports)
|
|
|
|
---
|
|
|
|
## Appendix F: Memory Management (Future)
|
|
|
|
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.
|
|
|
|
**Pointer Types**: The `ptr` type for raw pointers is planned as a future feature and will be part of the memory management system.
|
|
|
|
**Potential Approaches**:
|
|
|
|
**Option A: Manual Management**
|
|
```
|
|
// Allocate on heap
|
|
3.0 4.0 Point alloc // ( Point -- ptr<Point> )
|
|
|
|
// Dereference
|
|
ptr deref // ( ptr<T> -- T )
|
|
|
|
// Store through pointer
|
|
new_value ptr store // ( T ptr<T> -- )
|
|
|
|
// Free memory
|
|
ptr free // ( ptr<T> -- )
|
|
```
|
|
|
|
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<Point> )
|
|
|
|
// 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<Point> )
|
|
|
|
// 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.
|
|
|
|
**Type Parameter Enforcement Enhancement**:
|
|
|
|
**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 G: Examples & Tutorials
|
|
|
|
### G.1 Tutorial: First Steps
|
|
|
|
**Hello World**:
|
|
```
|
|
"Hello, World!" print
|
|
```
|
|
|
|
**Basic Arithmetic**:
|
|
```
|
|
// Simple calculations
|
|
3 4 + // => 7
|
|
10 3 - // => 7
|
|
5 6 * // => 30
|
|
20 4 / // => 5
|
|
|
|
// Chaining operations
|
|
2 3 + 4 * // => 20 (addition happens first due to postfix order)
|
|
|
|
// Using the stack
|
|
10 dup * // => 100 (duplicate 10, then multiply)
|
|
```
|
|
|
|
**Simple Functions**:
|
|
```
|
|
// Square function
|
|
(Number -- Number) { dup * } ::square fn
|
|
5 square // => 25
|
|
|
|
// Absolute value
|
|
(Number -- Number) {
|
|
dup 0 >
|
|
{ } // If positive, do nothing
|
|
{ 0 swap - } // If negative, negate
|
|
if
|
|
} ::abs fn
|
|
|
|
-5 abs // => 5
|
|
```
|
|
|
|
**Stack Manipulation Practice**:
|
|
```
|
|
// Basic stack operations
|
|
5 dup // => 5 5
|
|
5 10 swap // => 10 5
|
|
5 10 over // => 5 10 5
|
|
1 2 3 rot // => 2 3 1
|
|
|
|
// More complex example - swap two items below top
|
|
// Stack: a b c
|
|
// Want: b a c
|
|
rot rot // First rot: b c a, Second rot: c a b... wait, that's wrong!
|
|
|
|
// Better approach:
|
|
// Stack: a b c
|
|
swap rot rot // swap: a c b, rot: c b a, rot: b a c (correct!)
|
|
```
|
|
|
|
### G.2 Tutorial: Working with Traits
|
|
|
|
**Implementing a Trait for a Custom Type**:
|
|
|
|
```
|
|
// Step 1: Define a struct
|
|
(Number Number --) { x: y: } ::Point struct
|
|
|
|
// Step 2: Implement Addable trait
|
|
::Addable {
|
|
// Add two points
|
|
(Self Self -- Self) {
|
|
over ::x get over ::x get + // Add x coordinates
|
|
swap ::y get swap ::y get + // Add y coordinates
|
|
Point // Construct new point
|
|
} +:
|
|
|
|
// Subtract two points
|
|
(Self Self -- Self) {
|
|
over ::x get over ::x get - // Subtract x coordinates
|
|
swap ::y get swap ::y get - // Subtract y coordinates
|
|
Point // Construct new point
|
|
} -:
|
|
} ::Point impl
|
|
|
|
// Step 3: Use it
|
|
3.0 4.0 Point // First point
|
|
1.0 2.0 Point // Second point
|
|
+ // => Point with x=4.0, y=6.0
|
|
```
|
|
|
|
**Using Trait Bounds**:
|
|
|
|
```
|
|
// Function that works with any Addable type
|
|
(Addable Addable Addable -- Addable) {
|
|
+ + // Add all three
|
|
} ::sum_three fn
|
|
|
|
// Works with numbers
|
|
1 2 3 sum_three // => 6
|
|
|
|
// Works with Points
|
|
1.0 2.0 Point
|
|
3.0 4.0 Point
|
|
5.0 6.0 Point
|
|
sum_three // => Point(9.0, 12.0)
|
|
```
|
|
|
|
**Understanding Standard Traits**:
|
|
|
|
```
|
|
// Number trait combines many operations
|
|
(Number Number -- Number) {
|
|
dup * swap dup * + // a² + b²
|
|
} ::pythagorean fn
|
|
|
|
3.0 4.0 pythagorean // => 25.0
|
|
|
|
// This works because Number inherits from:
|
|
// - Addable (for +)
|
|
// - Multiplyable (for *)
|
|
// - Comparable (for comparisons)
|
|
// - And more...
|
|
```
|
|
|
|
### G.3 Tutorial: Generic Programming
|
|
|
|
**Writing Generic Functions**:
|
|
|
|
```
|
|
// Generic identity - works with any type
|
|
(T -- T) { } ::identity fn
|
|
|
|
5 identity // => 5
|
|
"hello" identity // => "hello"
|
|
|
|
// Generic swap function
|
|
(T U -- U T) { swap } ::generic_swap fn
|
|
|
|
// Constrained generic - requires Comparable
|
|
(Comparable Comparable -- Comparable) {
|
|
over over >
|
|
{ } // First is larger, do nothing
|
|
{ swap } // Second is larger, swap them
|
|
if
|
|
drop // Drop the smaller value
|
|
} ::max fn
|
|
|
|
5 10 max // => 10
|
|
10 5 max // => 10
|
|
```
|
|
|
|
**Generic Data Structures**:
|
|
|
|
```
|
|
// Define a generic Pair
|
|
(T U --) { first: second: } ::Pair<T U> struct
|
|
|
|
// Use with different types
|
|
5 "hello" Pair // Pair<i64, String>
|
|
3.14 true Pair // Pair<f64, bool>
|
|
|
|
// Access fields
|
|
dup ::first get // Get first element
|
|
::second get // Get second element
|
|
|
|
// Generic Option (already defined in standard library)
|
|
(T --) { Some(T) None } ::Option<T> union
|
|
|
|
42 Option::Some // Option<i64>::Some
|
|
Option::None // Option<T>::None
|
|
```
|
|
|
|
**Trait Constraints in Generics**:
|
|
|
|
```
|
|
// This function requires the type to be Multiplyable
|
|
(T:Multiplyable -- T) {
|
|
dup *
|
|
} ::square_generic fn
|
|
|
|
// Works with any Multiplyable type
|
|
5 square_generic // => 25
|
|
3.14 square_generic // => 9.8596
|
|
|
|
// Multiple constraints using composite traits
|
|
(Number -- Number) {
|
|
dup 0 >
|
|
{ }
|
|
{ 0 swap - }
|
|
if
|
|
} ::abs_generic fn
|
|
```
|
|
|
|
### G.4 Complete Examples
|
|
|
|
#### G.4.1 Trait Implementation Example
|
|
|
|
```
|
|
// Define a trait for drawable objects
|
|
{
|
|
(Self -- ) draw:
|
|
} ::Drawable trait
|
|
|
|
// Define a Rectangle struct
|
|
(Number Number --) { width: height: } ::Rectangle struct
|
|
|
|
// Implement Drawable for Rectangle
|
|
::Drawable {
|
|
(Self -- ) {
|
|
"Drawing rectangle:" print
|
|
dup ::width get "Width: " swap concat print
|
|
::height get "Height: " swap concat print
|
|
} draw:
|
|
} ::Rectangle impl
|
|
|
|
// Use it
|
|
10.0 20.0 Rectangle draw
|
|
// Output:
|
|
// Drawing rectangle:
|
|
// Width: 10.0
|
|
// Height: 20.0
|
|
```
|
|
|
|
#### G.4.2 Trait Inheritance Example
|
|
|
|
```
|
|
// Define base traits
|
|
{
|
|
(Self Self -- Self) +:
|
|
(Self Self -- Self) -:
|
|
} ::Addable trait
|
|
|
|
{
|
|
(Self Self -- Self) *:
|
|
(Self Self -- Self) /:
|
|
} ::Multiplyable trait
|
|
|
|
// Composite trait inheriting from both
|
|
[ ::Addable ::Multiplyable ] ::BasicMath inher
|
|
{ } ::BasicMath trait
|
|
|
|
// Now any type implementing BasicMath must support +, -, *, /
|
|
// And functions can require BasicMath as a constraint
|
|
(BasicMath BasicMath -- BasicMath) {
|
|
over over * swap dup * + // (a * b) + (b * b)
|
|
} ::weird_math fn
|
|
|
|
3 4 weird_math // => 28
|
|
```
|
|
|
|
#### G.4.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
|
|
|
|
// Calculate with custom base
|
|
8 2 logb print // => 3.0 (2³ = 8)
|
|
27 3 logb print // => 3.0 (3³ = 27)
|
|
|
|
// Combine with other operations
|
|
10 3 ^ log print // => 3.0 (log of 1000)
|
|
|
|
// Logarithm laws verification
|
|
// log(a*b) = log(a) + log(b)
|
|
10 100 * log // log(1000) = 3.0
|
|
10 log 100 log + // log(10) + log(100) = 1.0 + 2.0 = 3.0
|
|
```
|
|
|
|
#### G.4.4 Factorial
|
|
|
|
```
|
|
(Number -- Number) {
|
|
dup 1 <=
|
|
{ drop 1 } // Base case: 0! = 1! = 1
|
|
{ dup 1 - factorial * } // Recursive case: n! = n * (n-1)!
|
|
if
|
|
} ::factorial fn
|
|
|
|
5 factorial print // => 120
|
|
10 factorial print // => 3628800
|
|
|
|
// Iterative version (more efficient)
|
|
(Number -- Number) {
|
|
1 swap // Start with accumulator = 1
|
|
1 swap // Start counter at 1
|
|
{ // While counter <= n
|
|
dup 3 pick <=
|
|
}
|
|
{ // Body: multiply accumulator by counter
|
|
2 pick over * // acc * counter
|
|
3 roll drop // Drop old accumulator
|
|
swap 1 + swap // Increment counter
|
|
}
|
|
while
|
|
drop // Drop counter
|
|
swap drop // Drop original n
|
|
} ::factorial_iter fn
|
|
|
|
5 factorial_iter print // => 120
|
|
```
|
|
|
|
#### G.4.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
|
|
|
|
// Print FizzBuzz for 1 to 100
|
|
1 100 { fizzbuzz } for
|
|
```
|
|
|
|
#### G.4.6 Using Roll
|
|
|
|
```
|
|
// Roll rotates the top n items, times times
|
|
// Stack: 1 2 3 4 5
|
|
|
|
// Rotate top 3 items once
|
|
3 1 roll // Stack: 1 2 4 5 3
|
|
|
|
// Start fresh: 1 2 3 4 5
|
|
// Rotate top 3 items twice
|
|
3 2 roll // Stack: 1 2 5 3 4
|
|
|
|
// Start fresh: 1 2 3 4 5
|
|
// Rotate all 5 items once
|
|
5 1 roll // Stack: 2 3 4 5 1
|
|
|
|
// Start fresh: 1 2 3 4 5
|
|
// Rotate top 4 items three times
|
|
4 3 roll // Stack: 1 4 5 2 3
|
|
|
|
// Practical use: bring nth item to top
|
|
// Stack: a b c d e
|
|
// Want to bring 'b' (index 3) to top
|
|
4 3 roll // Rotates top 4 three times: a c d e b
|
|
|
|
// Or use pick for non-destructive copy
|
|
// Stack: a b c d e
|
|
3 pick // Stack: a b c d e b (copied from index 3)
|
|
```
|
|
|
|
#### G.4.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: [2 4 6 8 10]
|
|
{ dup * } map // Square each: [4 16 36 64 100]
|
|
0 { + } reduce // Sum: 220
|
|
print
|
|
|
|
// Find maximum in array
|
|
[5 2 9 1 7 6]
|
|
dup 0 at // Start with first element
|
|
{
|
|
over over >
|
|
{ swap } // If current > max, swap
|
|
{ } // Otherwise keep max
|
|
if
|
|
drop // Drop the smaller value
|
|
} reduce
|
|
print // => 9
|
|
|
|
// Average of array
|
|
[10 20 30 40 50]
|
|
dup 0 { + } reduce // Sum: 150
|
|
swap length // Length: 5
|
|
/ // Average: 30
|
|
print
|
|
```
|
|
|
|
#### G.4.8 Identifier Literals in Practice
|
|
|
|
```
|
|
// Identifier literals are used in struct/trait definitions
|
|
// and field access
|
|
|
|
// Defining a struct requires ::StructName identifier literal
|
|
(Number Number --) { x: y: } ::Point struct
|
|
|
|
// Field access requires ::field_name identifier literal
|
|
3.0 4.0 Point
|
|
dup ::x get print // Prints: 3.0
|
|
::y get print // Prints: 4.0
|
|
|
|
// Dynamic field access (advanced)
|
|
"x" :: // Convert string to identifier
|
|
// (This would require string-to-identifier conversion, which
|
|
// may be a future feature)
|
|
|
|
// Traits use identifier literals
|
|
{ (Self -- ) draw: } ::Drawable trait
|
|
|
|
// Implementations use identifier literals
|
|
::Drawable { ... } ::Rectangle impl
|
|
|
|
// Identifier literals are NOT used inside trait/impl bodies
|
|
// (those are method names)
|
|
{
|
|
(Self -- ) { "Drawing" print } draw: // "draw:" is method name
|
|
} ::Drawable trait
|
|
```
|
|
|
|
---
|
|
|
|
**End of Stack Language Specification v0.8**
|