# 4-Stack Toy Forth Interpreter A pure functional implementation of a toy Forth interpreter with a unique 4-stack architecture, written in JavaScript. ## Architecture This Forth interpreter features **4 separate stacks** that users can juggle between, unlike traditional single-stack Forth implementations: - **Stack 1 (Red)** - Default stack for most operations - **Stack 2 (Teal)** - Secondary stack for data organization - **Stack 3 (Blue)** - Tertiary stack for complex operations - **Stack 4 (Yellow)** - Quaternary stack for additional data ## Features ### Core Forth Operations - **Stack Manipulation**: `dup`, `swap`, `drop`, `2dup`, `2drop`, `over`, `rot`, `-rot` - **Arithmetic**: `+`, `-`, `*`, `/`, `mod` - **Comparison**: `=`, `<`, `>`, `and`, `or`, `not` - **Math Utilities**: `abs`, `negate`, `min`, `max` - **Stack Inspection**: `.s` (non-destructive), `depth` - **String Operations**: `." ... "` (print), `s" ... "` (push), `strlen`, `strcat`, `char+` - **Control Flow**: `if ... then`, `if ... else ... then`, `begin ... until` - **Help System**: `help` (comprehensive help), `doc ` (word documentation), `words` (word list) ### Multi-Stack Operations - **Stack Focus System**: `focus.red`, `focus.teal`, `focus.blue`, `focus.yellow` (or `focus.1`, `focus.2`, `focus.3`, `focus.4`) - **Move Operations**: `move.red`, `move.teal`, `move.blue`, `move.yellow` (or `move.1`, `move.2`, `move.3`, `move.4`) - **Pop Operations**: `pop.red`, `pop.teal`, `pop.blue`, `pop.yellow` (or `pop.1`, `pop.2`, `pop.3`, `pop.4`) - **Copy Operations**: `copy.red`, `copy.teal`, `copy.blue`, `copy.yellow` (or `copy.1`, `copy.2`, `copy.3`, `copy.4`) - **Move Operations**: `move` (interactive stack-to-stack movement), `move.red`, `move.teal`, `move.blue`, `move.yellow` (or `move.1`, `move.2`, `move.3`, `move.4`) - **Clear Operations**: `clear.all` (clear all stacks), `clear.focused` (clear focused stack) - **Cross-Stack Operations**: `dup.stacks`, `over.stacks`, `swap.stacks`, `nip.stacks`, `tuck.stacks`, `rot.stacks`, `2dup.stacks`, `2over.stacks`, `2swap.stacks` ### Word Definition System - **Define Words**: `: name ... ;` syntax - **List Words**: `words` command shows all available words - **User Dictionary**: Persistent storage of custom words ## Project Structure ``` foreforthfourth/ ├── index.html # Web interface ├── forth.js # Core Forth interpreter (standalone) ├── test-forth.js # Test suite for the interpreter └── README.md # This file ``` ## Testing ### Run Tests ```bash node test-forth.js ``` ### Complete Test Suite We have comprehensive test coverage including: - **Core Operations**: Stack manipulation, arithmetic, comparison, logic - **Focus System**: All focus commands and stack operations on different stacks - **String Operations**: String literals, manipulation, and type checking - **Control Flow**: Conditional execution and loops - **Multi-Stack**: Operations across all 4 stacks with focus system - **Error Handling**: Enhanced error messages and edge cases - **Help System**: Help commands and word documentation - **Word Definition**: User-defined words and compilation - **Enhanced Features**: Clear operations, move operations, focus persistence ### Test Results - **Total Tests**: 16 comprehensive test cases - **Success Rate**: 100% ✅ - **Coverage**: Complete feature coverage with edge case testing ## Web Interface Open `index.html` in a web browser to use the interactive Forth interpreter with: - Visual representation of all 4 stacks - Real-time command execution - Output history - Responsive design for mobile and desktop ## Usage Examples ### Basic Stack Operations ```forth 5 3 2 .s # Push numbers and show stack dup over # Duplicate top, copy second over top 2dup # Duplicate top two items ``` ### Arithmetic ```forth 10 3 / # Integer division (result: 3) 10 3 mod # Modulo (result: 1) -5 abs # Absolute value (result: 5) 5 negate # Negate (result: -5) ``` ### Multi-Stack Juggling ```forth 5 3 2 # Push to red stack move.teal # Move top of red to teal stack move.blue # Move top of red to blue stack ``` ### Stack Focus System The interpreter now supports operating on any of the 4 stacks using a focus system: ```forth focus.red # Set focus to Red stack (Stack 1) focus.teal # Set focus to Teal stack (Stack 2) focus.blue # Set focus to Blue stack (Stack 3) focus.yellow # Set focus to Yellow stack (Stack 4) # Number aliases also work: focus.1 # Same as focus.red focus.2 # Same as focus.teal focus.3 # Same as focus.blue focus.4 # Same as focus.yellow focus.show # Show which stack is currently focused ``` **All stack operations** (dup, swap, drop, +, -, *, /, etc.) now work on the **focused stack** instead of just the Red stack. This makes the multi-stack architecture truly powerful! **Number and Color Aliases**: All focus, push, and pop commands support both color names and numbers: ```forth # Focus commands focus.1 # Same as focus.red focus.2 # Same as focus.teal focus.3 # Same as focus.blue focus.4 # Same as focus.yellow # Move commands move.1 # Same as move.red move.2 # Same as move.teal move.3 # Same as move.blue move.4 # Same as move.yellow # Copy commands copy.1 # Same as copy.red copy.2 # Same as copy.teal copy.3 # Same as copy.blue copy.4 # Same as copy.yellow # Pop commands pop.1 # Same as pop.red pop.2 # Same as pop.teal pop.3 # Same as pop.blue pop.4 # Same as pop.yellow ``` ### Enhanced Clear Operations ```forth clear.all # Clear all stacks (same as clear) clear.focused # Clear only the currently focused stack # Example workflow: focus.teal # Focus on Teal stack 15 20 25 # Add items to Teal stack clear.focused # Clear only Teal stack focus.red # Switch to Red stack 5 10 # Add items to Red stack clear.focused # Clear only Red stack ``` ### Cross-Stack Operations The interpreter now provides comprehensive cross-stack manipulation using familiar Forth words with `.stacks` suffix: #### **Basic Cross-Stack Operations** ```forth # Duplicate top item to another stack focus.red 15 # Add item to Red stack dup.stacks # Start dup.stacks operation 2 # Enter target stack (Teal) # Result: 15 is duplicated to Teal stack # Copy second item to another stack focus.blue 10 20 30 # Add items to Blue stack over.stacks # Start over.stacks operation 1 # Enter target stack (Red) # Result: 20 is copied to Red stack # Swap top items between stacks focus.red 5 10 # Add items to Red stack swap.stacks # Start swap.stacks operation 3 # Enter target stack (Blue) # Result: Top items are swapped between Red and Blue stacks ``` #### **Advanced Cross-Stack Operations** ```forth # Move second item to another stack (remove from source) focus.teal 100 200 300 # Add items to Teal stack nip.stacks # Start nip.stacks operation 4 # Enter target stack (Yellow) # Result: 200 moved to Yellow stack, 100 and 300 remain on Teal # Tuck top item under second item on another stack focus.red 5 10 # Add items to Red stack tuck.stacks # Start tuck.stacks operation 2 # Enter target stack (Teal) # Result: 5 tucked under 10 on Teal stack # Rotate top 3 items between stacks focus.blue 1 2 3 # Add items to Blue stack rot.stacks # Start rot.stacks operation 1 # Enter target stack (Red) # Result: Top 3 items rotated between Blue and Red stacks # Duplicate top 2 items to another stack focus.yellow 50 60 # Add items to Yellow stack 2dup.stacks # Start 2dup.stacks operation 3 # Enter target stack (Blue) # Result: 50 and 60 duplicated to Blue stack # Copy second pair of items to another stack focus.red 10 20 30 40 # Add items to Red stack 2over.stacks # Start 2over.stacks operation 2 # Enter target stack (Teal) # Result: 20 and 30 copied to Teal stack # Swap top 2 pairs between stacks focus.teal 1 2 3 4 # Add items to Teal stack 2swap.stacks # Start 2swap.stacks operation 1 # Enter target stack (Red) # Result: Top 2 pairs swapped between Teal and Red stacks ``` #### **Cross-Stack Operation Workflow** All cross-stack operations follow this pattern: 1. **Set focus** to the source stack 2. **Add items** to the source stack 3. **Execute operation** (e.g., `dup.stacks`) 4. **Enter target stack** number (1-4) when prompted 5. **Operation completes** automatically This provides **true multi-stack power** while maintaining familiar Forth semantics! ### Move Operations (No Duplication) The interpreter provides several ways to **move** items between stacks without duplication: #### **Interactive Move Command** The `move` command is a **two-step interactive operation** that moves the top item from one stack to another: ```forth move # Start move operation 1 # Source stack (Red/Stack 1) 3 # Destination stack (Blue/Stack 3) # Result: Top item moved from Red to Blue stack ``` **Workflow:** 1. Type `move` to start the operation 2. Enter the **source stack number** (1-4) 3. Enter the **destination stack number** (1-4) 4. The item is **removed** from source and **added** to destination #### **Move Commands with Focus System** Use `move.` commands to move items from the focused stack to a specific target stack: ```forth focus.red # Focus on Red stack (1) 42 # Add item to Red stack move.3 # Move top item to Blue stack (3) # Result: 42 moved from Red to Blue stack focus.teal # Focus on Teal stack (2) 100 # Add item to Teal stack move.yellow # Move top item to Yellow stack (4) # Result: 100 moved from Teal to Yellow stack ``` #### **Number and Color Aliases** All move and copy commands support both number and color naming: ```forth # Move commands (remove from source) move.1 # Move to Red stack (1) move.2 # Move to Teal stack (2) move.3 # Move to Blue stack (3) move.4 # Move to Yellow stack (4) # Copy commands (keep in source) copy.1 # Copy to Red stack (1) copy.2 # Copy to Teal stack (2) copy.3 # Copy to Blue stack (3) copy.4 # Copy to Yellow stack (4) # Color aliases move.red # Move to Red stack (1) move.teal # Move to Teal stack (2) move.blue # Move to Blue stack (3) move.yellow # Move to Yellow stack (4) copy.red # Copy to Red stack (1) copy.teal # Copy to Teal stack (2) copy.blue # Copy to Blue stack (3) copy.yellow # Copy to Yellow stack (4) ``` #### **Comparison: Move vs Copy Operations** | Operation | Effect | Duplication | Use Case | |-----------|--------|-------------|----------| | `move` | **Moves** item from source to destination | ❌ No | Relocate items between stacks | | `move.{stack}` | **Moves** item from focused stack to target | ❌ No | Move from focused stack to specific stack | | `copy.{stack}` | **Copies** item from focused stack to target | ✅ Yes | Keep item on source, copy to target | | `dup.stacks` | **Copies** item from focused stack to target | ✅ Yes | Keep item on source, copy to target | | `over.stacks` | **Copies** second item from focused stack to target | ✅ Yes | Copy second item without affecting top | #### **Quick Reference: All Move and Copy Operations** | Command | From | To | Effect | |---------|------|----|---------| | `move` + source + dest | Any stack | Any stack | Move top item between specified stacks | | `move.red` / `move.1` | Focused stack | Red stack (1) | Move top item to Red stack | | `move.teal` / `move.2` | Focused stack | Teal stack (2) | Move top item to Teal stack | | `move.blue` / `move.3` | Focused stack | Blue stack (3) | Move top item to Blue stack | | `move.yellow` / `move.4` | Focused stack | Yellow stack (4) | Move top item to Yellow stack | | `copy.red` / `copy.1` | Focused stack | Red stack (1) | Copy top item to Red stack | | `copy.teal` / `copy.2` | Focused stack | Teal stack (2) | Copy top item to Teal stack | | `copy.blue` / `copy.3` | Focused stack | Blue stack (3) | Copy top item to Blue stack | | `copy.yellow` / `copy.4` | Focused stack | Yellow stack (4) | Copy top item to Yellow stack | #### **Complete Move Example** ```forth # Setup: Add items to different stacks focus.red 42 # Red stack: [42] focus.teal 100 # Teal stack: [100] focus.blue 200 # Blue stack: [200] # Move items between stacks focus.red move.2 # Move 42 from Red to Teal # Red stack: [], Teal stack: [100, 42] focus.teal move.3 # Move 100 from Teal to Blue # Teal stack: [42], Blue stack: [200, 100] # Use interactive move for complex operations move # Start move operation 3 # Source: Blue stack (3) 1 # Destination: Red stack (1) # Result: 200 moved from Blue to Red stack # Red stack: [200], Blue stack: [100] ``` ### Word Definition ```forth : double dup + ; # Define 'double' word 5 double # Use the word (result: 10) ``` ### Help System ```forth help # Show comprehensive help for all words s" dup" doc # Show detailed documentation for 'dup' words # List all available words ``` ### Comparison and Logic ```forth 5 3 > # 5 > 3 (result: -1 for true) 5 3 < # 5 < 3 (result: 0 for false) 5 3 > not # NOT (5 > 3) (result: 0) ``` ## Design Principles ### Pure Functional - **Immutable State**: All state updates return new state objects - **No Side Effects**: Functions are pure and predictable - **Functional Composition**: Operations compose naturally ### 4-Stack Architecture - **Stack Independence**: Each stack operates independently - **Flexible Data Flow**: Move data between stacks as needed - **Organized Workflows**: Use different stacks for different purposes ### ANS Forth Compatibility - **Standard Words**: Implements core ANS Forth words - **Familiar Syntax**: Standard Forth syntax and semantics - **Extensible**: Easy to add new words and functionality - **Enhanced Error Messages**: Helpful, actionable error messages with stack context and solutions ## Current Status ### **Fully Implemented Features** - **Control Flow**: `IF ... THEN`, `IF ... ELSE ... THEN`, `BEGIN ... UNTIL` constructs - **String Operations**: String literals (`."` and `s"`), manipulation (`strlen`, `strcat`, `char+`, `type`, `count`) - **Stack Focus System**: Operate on any of the 4 stacks using focus commands - **Enhanced Error Messages**: Helpful, actionable error messages with stack context - **Help System**: Comprehensive help (`help`) and word documentation (`doc`) - **Multi-Stack Operations**: Full support for all 4 stacks with focus system - **Enhanced Clear Operations**: `clear.all` and `clear.focused` commands - **Move Operations**: Interactive `move` command and `move.{stack}` commands for moving items between stacks - **Copy Operations**: `copy.{stack}` commands for copying items between stacks without removal - **Number Aliases**: All focus, move, copy, and pop commands support both color names and numbers (1-4) - **Math Utilities**: `abs`, `negate`, `min`, `max` operations ### **Advanced Capabilities** - **Universal Stack Operations**: All built-in words work on any focused stack - **Dual Naming System**: Both color names and numbers work for all commands - **Professional Error Handling**: Context-aware error messages with solutions - **Visual Focus Indicators**: UI shows which stack is currently focused - **Complete Test Coverage**: 100% test coverage of all features