diff --git a/stack_lang_spec_v04.md b/stack_lang_spec_v04.md index 1010fd7..8cb2f98 100644 --- a/stack_lang_spec_v04.md +++ b/stack_lang_spec_v04.md @@ -30,15 +30,15 @@ A statically-typed, stack-based language with pure postfix notation combining th **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 +- Example: `::Addable` pushes the identifier `Addable` onto the stack +- Example: `::Point` pushes the identifier `Point` onto the stack ### 2.3 Literals **Integer Literals** ``` -42 // i32 (default) -42 i64 // Annotate as i64 +42 // i64 (default) +42:i32 // Annotate as i32 0xFF // hexadecimal 0b1010 // binary ``` @@ -46,7 +46,7 @@ A statically-typed, stack-based language with pure postfix notation combining th **Floating Point Literals** ``` 3.14 // f64 (default) -3.14 f32 // Annotate as f32 +3.14:f32 // Annotate as f32 ``` **String Literals** @@ -55,6 +55,8 @@ A statically-typed, stack-based language with pure postfix notation combining th "escape sequences: \n \t \\ \"" ``` +> **TODO:** List all escape sequences. + **Boolean Literals** ``` true @@ -68,6 +70,8 @@ false [[1 2] [3 4]] // 2D array ``` +> **TODO:** Define Type Tuples: `(T T -- T)`. + **Token Strings** ``` { code here } // TokenString - lexed but not parsed/executed @@ -79,7 +83,13 @@ Token strings contain lexed tokens that are not parsed or executed until an oper - `impl` operator parses the TokenString as a trait implementation - `eval` operator parses and executes the TokenString immediately -Within TokenStrings, the `::` prefix may be used for clarity when referring to traits, though it's not strictly required since the context determines how identifiers are interpreted. +Within TokenStrings, the `::` prefix may be used, though it's not strictly required since the context (trait definition or implementation, or function definition or eval) determines how identifiers are interpreted. + +> **TODO:** `::` should not be allowed for traits and implementations. + +> **TODO:** `if`, `while`, `match`, etc. also use Token Strings + +> **TODO: (FOR HUMAN)** Should `::` be required for identifier literals in functions? ## 3. Type System @@ -106,30 +116,32 @@ Rectangle struct // Rectangle is a type ``` **Key Distinction:** -- A value **has** a type (what it is structurally) -- A value **implements** a trait (how it behaves) +- A value has a type (what it is structurally) +- A value implements a trait (how it behaves) - Types are concrete; traits are interfaces -- Functions can be generic over both types and traits -- **Every operator must be backed by a trait** +- Functions can be generic over traits +- Functions can have types and traits defined as return types +- Every operator must be backed by a trait ### 3.3 All Constructs are Generic +> **TODO:** Constructs are not all Generic. + Every function, struct, and union is implicitly generic. Constraints are specified via traits: ``` // Function generic over any type T -(T -- T) { dup * } square fn - -// Function requiring T to implement Addable trait -(T T -- T) Addable { + } add_two fn +(T -- T) { dup * } ::square fn // Struct generic over field types -(T T --) { x: y: } Point struct +(T T --) { x: y: } ::Point struct // Union generic over variant types -(T --) { Some(T) None } Option union +(T --) { Some(T) None } ::Option union ``` +> **TODO:** `(T -- T) { dup * } ::square fn` would be illegal as the use of `*` requires `Multiplyable`. + ## 4. Trait System ### 4.1 Standard Traits @@ -138,78 +150,93 @@ Traits define behavioral contracts. Every operator in the language is backed by **Stack Manipulation Traits** ``` -{ (Self -- Self Self) dup: } Duplicable trait -{ (Self -- ) drop: } Droppable trait -{ (Self Self -- Self Self) swap: } Swappable trait -{ (Self Self -- Self Self Self) over: } Overable trait -{ (Self Self Self -- Self Self Self) rot: } Rotatable trait -{ (i32 -- Self) pick: } Pickable trait -{ (i32 i32 -- ) roll: } Rollable trait -{ (-- i32) depth: } Inspectable trait +{ (-- Self) push: } ::Pushable trait +{ (Self -- Self Self) dup: } ::Duplicable trait +{ (Self -- ) drop: } ::Droppable trait +{ (Self Self -- Self Self) swap: } ::Swappable trait +{ (Self Self -- Self Self Self) over: } ::Overable trait +{ (Self Self Self -- Self Self Self) rot: } ::Rotatable trait +{ (Size -- Self) pick: } ::Pickable trait +{ (Size Size -- ) roll: } ::Rollable trait +{ (-- i64) depth: } ::Inspectable trait ``` +> **TODO: (FOR HUMAN)** Can a type tuple have no parameters? + +> **TODO:** Stack manipulation should use one trait. + +> **TODO:** Add a `Size` trait that inherits from `Addable`, `Comparable`, and `Convertible`. + **Arithmetic Traits** ``` -{ (Self Self -- Self) +: (Self Self -- Self) -: } Addable trait +{ (Self Self -- Self) +: (Self Self -- Self) -: } ::Addable trait -{ (Self Self -- Self) *: (Self Self -- Self) /: (Self Self -- Self) %: } Multiplyable trait +{ (Self Self -- Self) *: (Self Self -- Self) /: (Self Self -- Self) %: } ::Multiplyable trait -{ (Self Self -- Self) ^: } Exponentiable trait +{ (Self Self -- Self) ^: } ::Exponentiable trait -{ (Self -- Self) log: } Logarithmic trait // log base 10 - -{ (Self -- Self) ln: } NaturalLogarithmic trait // natural log +{ (Self Self -- Self) logb: (Self -- Self) log: (Self -- Self) ln: } ::Logarithmic trait ``` **Comparison Traits** ``` -{ (Self Self -- bool) >: (Self Self -- bool) >=: (Self Self -- bool) <: (Self Self -- bool) <=: } Orderable trait +{ (Self Self -- bool) >: (Self Self -- bool) >=: (Self Self -- bool) <: (Self Self -- bool) <=: } ::Orderable trait -{ (Self Self -- bool) ==: (Self Self -- bool) !=: } Equatable trait +{ (Self Self -- bool) ==: (Self Self -- bool) !=: } ::Equatable trait // Comparable combines ordering and equality -[ Orderable Equatable ] Comparable inher +[ ::Orderable ::Equatable ] ::Comparable inher +{ } ::Comparable trait ``` **Logical Operations Traits** ``` -{ (Self Self -- Self) and: (Self Self -- Self) or: (Self -- Self) not: } Logical trait +{ (Self -- bool) truthy: (Self Self -- Self) and: (Self Self -- Self) or: (Self -- Self) not: } ::Logical trait ``` **Bitwise Operations Traits** ``` -{ (Self Self -- Self) bitand: (Self Self -- Self) bitor: (Self Self -- Self) bitxor: (Self -- Self) bitnot: (Self i32 -- Self) shl: (Self i32 -- Self) shr: } Bitwise trait +{ (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 ``` **Container Traits** ``` -{ (-- Self) create: (Self i32 -- T) at: (Self -- i32) length: } ArrayOf trait +{ (Self -- i64) length: } ::Sized trait -{ (Self Self -- Self) concat: } Concatenable trait +{ (Self Size -- T) at: } ::Selectable trait -{ (Self i32 i32 -- Self) slice: } Sliceable trait +{ (Self Self -- Self) concat: } ::Concatenable trait + +{ (Self Size Size -- Self) slice: } ::Sliceable trait + +[ ::Sized ::Selectable ::Sliceable ] ::ArrayOf inher +{ } ::ArrayOf trait ``` **String Traits** ``` -{ (Self Self -- Self) concat: (Self -- i32) length: (Self i32 i32 -- Self) substr: (Self Self -- ArrayOf[Self]) split: } Stringable trait +[ ::Concatenable ] ::String inher +{ (Self Size Size -- Self) substr: (Self Self -- ArrayOf) split: } ::String trait ``` **Conversion Traits** ``` -{ (Self T -- U) as: } Convertible trait +{ (Self Type -- T) as: } ::Convertible trait -{ (Self -- String) str: } Stringifiable trait +{ (Self -- String) str: } ::Stringifiable trait -{ (String -- Self) parse: } Parseable trait +{ (String -- Self) parse: } ::Parseable trait ``` +> **TODO: (FOR HUMAN)** Type conversion may need to work a different way? + **Numeric Composite Trait** The `Number` trait represents the full suite of numeric operations by inheriting from multiple traits: ``` -[ Addable Multiplyable Exponentiable Comparable Logarithmic NaturalLogarithmic ] Number inher +[ Addable Multiplyable Exponentiable Comparable Logarithmic ] ::Number inher +{ } ::Number inher ``` **Meta-Traits** @@ -217,18 +244,16 @@ The `Number` trait represents the full suite of numeric operations by inheriting Traits for defining and working with traits themselves: ``` -{ (-- TokenString) name: } Identifier trait +{ } ::Identifier trait -{ (-- Self) push: } Pushable trait - -{ (TokenString Identifier --) trait: (Identifier TokenString Identifier --) impl: (ArrayOf[Identifier] Identifier --) inher: } Implementable trait +{ (TokenString Identifier --) trait: (Identifier TokenString Identifier --) impl: (ArrayOf Identifier --) inher: } ::Implementable trait ``` +> **TODO: (FOR HUMAN)** Can traits be completely empty (no inher and empty trait)? + ### 4.2 Trait Definition -**Syntax**: `{ function_signatures } identifier trait` - -The identifier can be provided as an identifier literal (`::Name`) or as a regular identifier on the stack. +**Syntax**: `{ function_signatures } ::identifier trait` ``` // Using identifier literal @@ -252,57 +277,116 @@ The identifier can be provided as an identifier literal (`::Name`) or as a regul Within the TokenString (the `{ }` block), identifiers like `Self`, `add:`, `draw:` are part of the trait definition syntax. When referencing existing traits within the definition, you may use `::TraitName` for clarity, though the context makes it clear they are trait references. +> **TODO:** Again, `::` should not be allowed in the Token String for traits and implementations. + ### 4.3 Trait Implementation -**Syntax**: `identifier { method_implementations } identifier impl` +**Syntax**: `identifier { method_implementations } ::identifier impl` ``` // Implement Addable for i32 -::i32 { +::Addable { (Self Self -- Self) { // Native addition implementation } +: - + (Self Self -- Self) { // Native subtraction implementation } -: -} ::Addable impl +} ::i32 impl // Implement Drawable for Rectangle -::Rectangle { - (Rectangle -- ) { +::Drawable { + (Self -- ) { "Drawing rectangle" print - dup width get print - height get print + dup ::width get print + ::height get print } draw: -} ::Drawable impl +} ::Rectangle impl +``` +> **Note:** The following block has been human verified to be syntactically and logically correct. + +``` // Implement Addable for Point -::Point { - (Point Point -- Point) { - over x get over x get + - swap y get swap y get + +::Addable { + (Self Self -- Self) { + over ::x get over ::x get + + 3 pick ::y get 3 pick ::y get + Point } +: - - (Point Point -- Point) { - over x get over x get - - swap y get swap y get - + + (Self Addable -- Self) { + over ::x get over + + 3 pick ::y get 3 pick + + Point + } +: + + (Addable Self -- Self) { + over over ::x get + + 3 pick 3 pick ::y get + + Point + } +: + + (Self Self -- Self) { + over ::x get over ::x get - + 3 pick ::y get 3 pick ::y get - Point } -: -} ::Addable impl + + (Self Addable -- Self) { + over ::x get over - + 3 pick ::y get 3 pick - + Point + } -: +} ::Point impl + +// Implement Logical for everything +::Logical { + (Self -- bool) { true } truthy: + + (Self Self -- Self) { + over truthy { } { swap } if drop + } and: + + (Self Self -- Self) { + over truthy { swap } { } if drop + } or: +} ::Logical impl + +// Overload Logical for bool +::Logical { + (Self -- Self) { } truthy: +} ::bool impl + +// Overload Logical for Numeric +::Logical { + (Self -- bool) { 0 != } truthy: +} ::Number impl + +// Overload Logical for Option +::Logical { + (Self -- bool) { { Some(_) => { true } None => { false } } match } truthy: +} ::Option impl + +// Overload Logical for Result +::Logical { + (Self -- bool) { { Ok(_) => { true } Err(_) => { false } } match } truthy: +} ::Result impl ``` ### 4.4 Trait Inheritance **Syntax**: `[ identifier_list ] identifier inher` +> **TODO:** `inher` must be before `trait` and must have a `trait`. + ``` // Number inherits from multiple arithmetic traits [ ::Addable ::Multiplyable ] ::BasicNumber inher // Full Number inherits everything numeric -[ ::Addable ::Multiplyable ::Exponentiable ::Comparable ::Logarithmic ::NaturalLogarithmic ] ::Number inher +[ ::Addable ::Multiplyable ::Exponentiable ::Comparable ::Logarithmic ] ::Number inher // Complex inheritance [ ::Drawable ::Transformable ::Collidable ] ::GameObject inher @@ -312,19 +396,9 @@ Within the TokenString (the `{ }` block), identifiers like `Self`, `add:`, `draw ``` // Function requiring Drawable trait -(T -- ) Drawable { +(Drawable -- ) { draw -} draw_twice fn - -// Multiple trait requirements -(T -- T) Number Copyable { - dup abs swap dup * + -} complex_calc fn - -// Using identifier literals -(T T -- T) ::Addable { - + -} add_values fn +} ::draw_twice fn ``` ## 5. Stack Operations @@ -371,7 +445,7 @@ roll // ( n times -- ) Rotate n items, times times [Rollable] 17 5 % // Modulo [Multiplyable] 2 8 ^ // Exponentiation [Exponentiable] 100 log // Log base 10 [Logarithmic] -2.718 ln // Natural logarithm [NaturalLogarithmic] +2.718 ln // Natural logarithm [Logarithmic] ``` ### 6.2 Comparison @@ -414,46 +488,35 @@ Functions are defined in postfix notation. The signature and body come before th ``` // Define a square function -(i32 -- i32) { dup * } square fn +(Number -- Number) { dup * } ::square fn // Use it 5 square // 25 // Multiple inputs and outputs -(i32 i32 -- i32 i32) { +(Number Number -- Number Number) { over over / swap % -} divmod fn +} ::divmod fn 10 3 divmod // 3 1 (quotient remainder) ``` ### 7.2 Generic Functions with Trait Constraints -**Syntax**: `(type_sig) trait_constraints { body } name fn` +**Syntax**: `(type_sig) { body } name fn` ``` // Generic identity - works with any type -(T -- T) {} identity fn +(T -- T) { } ::identity fn -// Requires T to be Addable -(T T -- T) Addable { +// Requires Addable +(Addable Addable -- Addable) { + -} add_values fn +} ::add_values fn -// Multiple trait constraints -(T U -- U T) Copyable Swappable { - swap -} swap_generic fn - -// Multiple type parameters with different traits -(T U -- T) Addable Number { - dup U as + -} add_converted fn - -// Using identifier literals for clarity -(T -- T) ::Number { +(Number -- Number) { dup 0 > { } { 0 T as - } if -} abs fn +} ::abs fn ``` ## 8. Control Flow (Postfix) @@ -476,7 +539,7 @@ if a b > { a } { b } -if max set +if // Nested x 0 > @@ -563,18 +626,18 @@ status { ``` // Define Point struct - generic over coordinate types -(T T --) { x: y: } Point struct +(T T --) { x: y: } ::Point struct // Use with specific types 3.0 4.0 Point // Creates Point with f64 fields -3 4 Point // Creates Point with i32 fields +3 4 Point // Creates Point with i64 fields // More complex struct (T U V --) { width: height: depth: -} Box3D struct +} ::Box3D struct 10.0 20.0 30.0 Box3D ``` @@ -584,11 +647,11 @@ status { **Syntax (postfix)**: `struct field get` or `struct value field set` ``` -point x get // Get x field -point 15.0 x set // Set x field to 15.0 +point ::x get // Get x field +point 15.0 ::x set // Set x field to 15.0 // Chaining -point x get 2 * y get + // (point.x * 2) + point.y +point ::x get 2 * over ::y get + // (point.x * 2) + point.y ``` ### 9.3 Union Definition @@ -600,39 +663,41 @@ point x get 2 * y get + // (point.x * 2) + point.y (T --) { Some(T) None -} Option union +} ::Option union // Result type - generic over T and E (T E --) { Ok(T) Err(E) -} Result union +} ::Result union // Create union values -42 Some // Creates Option::Some(42) -None // Creates Option::None -"success" Ok // Creates Result::Ok("success") -"error" Err // Creates Result::Err("error") +42 Option::Some // Creates Option::Some(42) +Option::None // Creates Option::None +"success" Result::Ok // Creates Result::Ok("success") +"error" Result::Err // Creates Result::Err("error") ``` ### 9.4 Enum Definition -**Syntax**: `() { variants } name enum` +**Syntax**: `{ variants } name enum` ``` -() { - Pending - Active - Complete -} Status enum +{ + Pending 1: // Normally starts at 0 + Active: // Defaults to 2 (one plus the last) + Complete 0: +} ::Status enum // Usage -Pending // Creates Status::Pending -Active // Creates Status::Active +Status::Pending // Creates Status::Pending +Status::Active // Creates Status::Active ``` ## 10. Memory Management (Postfix) +> **TODO: (FOR HUMAN)** Leave out or redo how memory management is done? + ### 10.1 Heap Operations ``` @@ -677,6 +742,8 @@ arr 1 3 slice // Slice array ### 11.2 Array Combinators +> **TODO:** Funcs don't parse, the `if`, `while`, etc. inside do. + ``` // Map - apply function to each element [1 2 3 4] { 2 * } map // [2 4 6 8] @@ -726,6 +793,8 @@ operation_name " get" concat eval ## 13. Standard Library Concepts +> **TODO: (FOR HUMAN)** How are imports done? Is everything automatically in scope? + ### 13.1 I/O ``` @@ -747,6 +816,8 @@ operation_name " get" concat eval ### 13.3 Type Conversion +> **TODO:** Again, conversions need to be re-done. + ``` 42 f64 as // Convert i32 to f64 "123" i32 parse // Parse string to i32 @@ -755,6 +826,8 @@ operation_name " get" concat eval ## 14. Complete Examples +> **TODO:** These need to be reviewed for correctness. + ### 14.1 Trait Implementation Example ``` @@ -925,5 +998,5 @@ print // 220 --- -**Version**: 0.3 -**Status**: Draft Specification - Trait-Backed Operations with Identifier Literals \ No newline at end of file +**Version**: 0.4 +**Status**: Draft Specification