about summary refs log tree commit diff stats
path: root/forth/foreforthfourth/forth.js
diff options
context:
space:
mode:
Diffstat (limited to 'forth/foreforthfourth/forth.js')
-rw-r--r--forth/foreforthfourth/forth.js1973
1 files changed, 1973 insertions, 0 deletions
diff --git a/forth/foreforthfourth/forth.js b/forth/foreforthfourth/forth.js
new file mode 100644
index 0000000..af133ea
--- /dev/null
+++ b/forth/foreforthfourth/forth.js
@@ -0,0 +1,1973 @@
+// Pure functional approach to Forth interpreter state
+const createInitialState = () => ({
+    stacks: [[], [], [], []],
+    dictionary: new Map(),
+    output: [],
+    compilingWord: null,
+    compilingDefinition: [],
+    stringMode: false,
+    currentString: '',
+    stringPushMode: false,
+    skipMode: false,
+    skipCount: 0,
+    loopStart: null,
+    loopBack: false,
+    focusedStack: 0,        // New: 0=Red, 1=Teal, 2=Blue, 3=Yellow
+    moveInProgress: false,  // For move operation
+    moveFromStack: null,    // For move operation
+    crossStackInProgress: false,  // For cross-stack operations
+    crossStackOperation: null,    // Type of cross-stack operation
+    crossStackData: null         // Data for cross-stack operation
+});
+
+// Pure function to update state
+const updateState = (state, updates) => ({
+    ...state,
+    ...updates
+});
+
+// Stack operations
+const pushToStack = (stacks, stackIndex, value) => {
+    const newStacks = stacks.map((stack, i) => 
+        i === stackIndex ? [...stack, value] : stack
+    );
+    return newStacks;
+};
+
+const popFromStack = (stacks, stackIndex) => {
+    const newStacks = stacks.map((stack, i) => 
+        i === stackIndex ? stack.slice(0, -1) : stack
+    );
+    const value = stacks[stackIndex][stacks[stackIndex].length - 1];
+    return { stacks: newStacks, value };
+};
+
+const moveBetweenStacks = (stacks, fromStack, toStack) => {
+    if (stacks[fromStack].length === 0) return { stacks, value: null };
+    const { stacks: newStacks, value } = popFromStack(stacks, fromStack);
+    return { stacks: pushToStack(newStacks, toStack, value), value };
+};
+
+const popAndPrint = (state, stackIndex) => {
+    if (state.stacks[stackIndex].length === 0) {
+        return updateState(state, { output: [...state.output, `Stack ${stackIndex + 1} is empty`] });
+    }
+    const { stacks, value } = popFromStack(state.stacks, stackIndex);
+    return updateState(state, {
+        stacks,
+        output: [...state.output, `Stack ${stackIndex + 1}: ${value}`]
+    });
+};
+
+// Helper function to get focused stack name
+const getFocusedStackName = (focusedStack) => {
+    const stackNames = ['Red (1)', 'Teal (2)', 'Blue (3)', 'Yellow (4)'];
+    return stackNames[focusedStack];
+};
+
+// Helper function to execute cross-stack operations
+const executeCrossStackOperation = (state, sourceIndex, targetIndex) => {
+    const operation = state.crossStackOperation;
+    const data = state.crossStackData;
+    
+    switch (operation) {
+        case 'dup':
+            return updateState(state, {
+                stacks: pushToStack(state.stacks, targetIndex, data.top),
+                output: [...state.output, `Duplicated ${data.top} from ${getFocusedStackName(sourceIndex)} to ${getFocusedStackName(targetIndex)}`]
+            });
+            
+        case 'over':
+            return updateState(state, {
+                stacks: pushToStack(state.stacks, targetIndex, data.second),
+                output: [...state.output, `Copied ${data.second} from ${getFocusedStackName(sourceIndex)} to ${getFocusedStackName(targetIndex)}`]
+            });
+            
+        case 'swap':
+            // Create new stacks array
+            const newStacks = state.stacks.map((stack, i) => [...stack]);
+            
+            // Get top 2 items from source stack (don't remove)
+            const sourceTop = newStacks[sourceIndex][newStacks[sourceIndex].length - 1];
+            const sourceSecond = newStacks[sourceIndex][newStacks[sourceIndex].length - 2];
+            
+            // Add source items to target stack in order: top, second
+            newStacks[targetIndex].push(sourceTop);
+            newStacks[targetIndex].push(sourceSecond);
+            
+            // Source stack remains unchanged (no popping/pushing)
+            
+            return updateState(state, {
+                stacks: newStacks,
+                output: [...state.output, `Copied top 2 items from ${getFocusedStackName(sourceIndex)} to ${getFocusedStackName(targetIndex)}`]
+            });
+            
+        case 'nip':
+            // Create new stacks array
+            const nipStacks = state.stacks.map((stack, i) => [...stack]);
+            
+            // Remove second item from source stack
+            nipStacks[sourceIndex].splice(-2, 1);
+            
+            // Add second item to target stack
+            nipStacks[targetIndex].push(data.second);
+            
+            return updateState(state, {
+                stacks: nipStacks,
+                output: [...state.output, `Moved second item ${data.second} from ${getFocusedStackName(sourceIndex)} to ${getFocusedStackName(targetIndex)}`]
+            });
+            
+        case 'tuck':
+            // Create new stacks array
+            const tuckStacks = state.stacks.map((stack, i) => [...stack]);
+            
+            // Remove top item from source stack
+            const tuckTop = tuckStacks[sourceIndex].pop();
+            
+            // Add items to target stack in tuck order: top, second, top
+            tuckStacks[targetIndex].push(tuckTop);
+            tuckStacks[targetIndex].push(data.second);
+            tuckStacks[targetIndex].push(tuckTop);
+            
+            // Don't add top item back to source stack - tuck removes it
+            
+            return updateState(state, {
+                stacks: tuckStacks,
+                output: [...state.output, `Tucked ${tuckTop} under ${data.second} on ${getFocusedStackName(targetIndex)}`]
+            });
+            
+        case 'rot':
+            // Create new stacks array
+            const rotStacks = state.stacks.map((stack, i) => [...stack]);
+            
+            // Remove top 3 items from source stack
+            // For stack [1, 2, 3], top=3, second=2, third=1
+            const rotTop = rotStacks[sourceIndex].pop();      // 3
+            const rotSecond = rotStacks[sourceIndex].pop();   // 2
+            const rotThird = rotStacks[sourceIndex].pop();    // 1
+            
+            // Add 3 items to target stack in rotated order: third, first, second
+            rotStacks[targetIndex].push(rotThird);
+            rotStacks[targetIndex].push(rotTop);
+            rotStacks[targetIndex].push(rotSecond);
+            
+            // Add 3 items back to source stack in rotated order: third, first, second
+            rotStacks[sourceIndex].push(rotThird);
+            rotStacks[sourceIndex].push(rotTop);
+            rotStacks[sourceIndex].push(rotSecond);
+            
+            return updateState(state, {
+                stacks: rotStacks,
+                output: [...state.output, `Rotated top 3 items between ${getFocusedStackName(sourceIndex)} and ${getFocusedStackName(targetIndex)}`]
+            });
+            
+        case '2dup':
+            // Create new stacks array
+            const dup2Stacks = state.stacks.map((stack, i) => [...stack]);
+            
+            // Get top 2 items from source stack (don't remove)
+            const dup2Top = dup2Stacks[sourceIndex][dup2Stacks[sourceIndex].length - 1];
+            const dup2Second = dup2Stacks[sourceIndex][dup2Stacks[sourceIndex].length - 2];
+            
+            // Add 2 items to target stack (preserve order: second, top)
+            dup2Stacks[targetIndex].push(dup2Second);
+            dup2Stacks[targetIndex].push(dup2Top);
+            
+            // Source stack remains unchanged (no popping/pushing)
+            
+            return updateState(state, {
+                stacks: dup2Stacks,
+                output: [...state.output, `Duplicated top 2 items from ${getFocusedStackName(sourceIndex)} to ${getFocusedStackName(targetIndex)}`]
+            });
+            
+        case '2over':
+            // Create new stacks array
+            const over2Stacks = state.stacks.map((stack, i) => [...stack]);
+            
+            // Get second pair of items from source stack (don't remove)
+            // For stack [10, 20, 30, 40], second pair is [20, 30]
+            const over2Second = over2Stacks[sourceIndex][over2Stacks[sourceIndex].length - 3];
+            const over2Third = over2Stacks[sourceIndex][over2Stacks[sourceIndex].length - 2];
+            
+            // Add 2 items to target stack (preserve order: third, second)
+            over2Stacks[targetIndex].push(over2Third);
+            over2Stacks[targetIndex].push(over2Second);
+            
+            return updateState(state, {
+                stacks: over2Stacks,
+                output: [...state.output, `Copied second pair of items from ${getFocusedStackName(sourceIndex)} to ${getFocusedStackName(targetIndex)}`]
+            });
+            
+        case '2swap':
+            // Create new stacks array
+            const swap2Stacks = state.stacks.map((stack, i) => [...stack]);
+            
+            // Get top 4 items from source stack (don't remove)
+            const sourceItems = [
+                swap2Stacks[sourceIndex][swap2Stacks[sourceIndex].length - 1], // top
+                swap2Stacks[sourceIndex][swap2Stacks[sourceIndex].length - 2], // second
+                swap2Stacks[sourceIndex][swap2Stacks[sourceIndex].length - 3], // third
+                swap2Stacks[sourceIndex][swap2Stacks[sourceIndex].length - 4]  // fourth
+            ];
+            
+            // Add source items to target stack in order: fourth, third, second, top
+            swap2Stacks[targetIndex].push(sourceItems[3]); // fourth
+            swap2Stacks[targetIndex].push(sourceItems[2]); // third
+            swap2Stacks[targetIndex].push(sourceItems[1]); // second
+            swap2Stacks[targetIndex].push(sourceItems[0]); // top
+            
+            // Source stack remains unchanged (no popping/pushing)
+            
+            return updateState(state, {
+                stacks: swap2Stacks,
+                output: [...state.output, `Copied top 2 pairs of items from ${getFocusedStackName(sourceIndex)} to ${getFocusedStackName(targetIndex)}`]
+            });
+            
+        default:
+            return updateState(state, {
+                output: [...state.output, `Error: Unknown cross-stack operation: ${operation}`]
+            });
+    }
+};
+
+// Built-in words with documentation
+const builtinWords = {
+    // Stack focus commands
+    'focus.red': {
+        fn: (state) => updateState(state, { 
+            focusedStack: 0,
+            output: [...state.output, 'Focus set to Red stack (Stack 1)']
+        }),
+        doc: 'Set focus to Red stack (Stack 1)',
+        stack: '( -- )'
+    },
+    'focus.1': {
+        fn: (state) => updateState(state, { 
+            focusedStack: 0,
+            output: [...state.output, 'Focus set to Red stack (Stack 1)']
+        }),
+        doc: 'Set focus to Red stack (Stack 1)',
+        stack: '( -- )'
+    },
+    'focus.teal': {
+        fn: (state) => updateState(state, { 
+            focusedStack: 1,
+            output: [...state.output, 'Focus set to Teal stack (Stack 2)']
+        }),
+        doc: 'Set focus to Teal stack (Stack 2)',
+        stack: '( -- )'
+    },
+    'focus.2': {
+        fn: (state) => updateState(state, { 
+            focusedStack: 1,
+            output: [...state.output, 'Focus set to Teal stack (Stack 2)']
+        }),
+        doc: 'Set focus to Teal stack (Stack 2)',
+        stack: '( -- )'
+    },
+    'focus.blue': {
+        fn: (state) => updateState(state, { 
+            focusedStack: 2,
+            output: [...state.output, 'Focus set to Blue stack (Stack 3)']
+        }),
+        doc: 'Set focus to Blue stack (Stack 3)',
+        stack: '( -- )'
+    },
+    'focus.3': {
+        fn: (state) => updateState(state, { 
+            focusedStack: 2,
+            output: [...state.output, 'Focus set to Blue stack (Stack 3)']
+        }),
+        doc: 'Set focus to Blue stack (Stack 3)',
+        stack: '( -- )'
+    },
+    'focus.yellow': {
+        fn: (state) => updateState(state, { 
+            focusedStack: 3,
+            output: [...state.output, 'Focus set to Yellow stack (Stack 4)']
+        }),
+        doc: 'Set focus to Yellow stack (Stack 4)',
+        stack: '( -- )'
+    },
+    'focus.4': {
+        fn: (state) => updateState(state, { 
+            focusedStack: 3,
+            output: [...state.output, 'Focus set to Yellow stack (Stack 4)']
+        }),
+        doc: 'Set focus to Yellow stack (Stack 4)',
+        stack: '( -- )'
+    },
+    'focus.show': {
+        fn: (state) => {
+            const stackNames = ['Red (1)', 'Teal (2)', 'Blue (3)', 'Yellow (4)'];
+            return updateState(state, { 
+                output: [...state.output, `Currently focused on: ${stackNames[state.focusedStack]}`]
+            });
+        },
+        doc: 'Show which stack is currently focused',
+        stack: '( -- )'
+    },
+    
+    // Stack manipulation for focused stack
+    'dup': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                const stackNames = ['Red (1)', 'Teal (2)', 'Blue (3)', 'Yellow (4)'];
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on dup - ${stackNames[state.focusedStack]} is empty. Use numbers or strings to add items first.`] 
+                });
+            }
+            const top = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 1];
+            return updateState(state, {
+                stacks: pushToStack(state.stacks, state.focusedStack, top)
+            });
+        },
+        doc: 'Duplicate the top item on the stack',
+        stack: '( x -- x x )'
+    },
+
+    'swap': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                const stackNames = ['Red (1)', 'Teal (2)', 'Blue (3)', 'Yellow (4)'];
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on swap - ${stackNames[state.focusedStack]} needs 2 items, but has ${state.stacks[state.focusedStack].length}. Add more items first.`] 
+                });
+            }
+            const newStacks = state.stacks.map((stack, i) => [...stack]);
+            const a = newStacks[state.focusedStack].pop();
+            const b = newStacks[state.focusedStack].pop();
+            newStacks[state.focusedStack].push(a);
+            newStacks[state.focusedStack].push(b);
+            return updateState(state, { stacks: newStacks });
+        },
+        doc: 'Exchange the top two items on the stack',
+        stack: '( x1 x2 -- x2 x1 )'
+    },
+
+    'drop': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on drop - ${getFocusedStackName(state.focusedStack)} is empty. Nothing to remove.`] 
+                });
+            }
+            const { stacks } = popFromStack(state.stacks, state.focusedStack);
+            return updateState(state, { stacks });
+        },
+        doc: 'Remove the top item from the stack',
+        stack: '( x -- )'
+    },
+
+    '2drop': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on 2drop - Stack 1 (Red) needs 2 items, but has ${state.stacks[state.focusedStack].length}. Add more items first.`] 
+                });
+            }
+            const { stacks: stacks1 } = popFromStack(state.stacks, state.focusedStack);
+            const { stacks } = popFromStack(stacks1, 0);
+            return updateState(state, { stacks });
+        },
+        doc: 'Remove the top two items from the stack',
+        stack: '( x1 x2 -- )'
+    },
+
+    'over': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on over - Stack 1 (Red) needs 2 items, but has ${state.stacks[state.focusedStack].length}. Add more items first.`] 
+                });
+            }
+            const second = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 2];
+            return updateState(state, {
+                stacks: pushToStack(state.stacks, state.focusedStack, second)
+            });
+        },
+        doc: 'Copy the second item on the stack to the top',
+        stack: '( x1 x2 -- x1 x2 x1 )'
+    },
+
+    '2dup': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on 2dup - Stack 1 (Red) needs 2 items, but has ${state.stacks[state.focusedStack].length}. Add more items first.`] 
+                });
+            }
+            const top = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 1];
+            const second = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 2];
+            const newStacks = pushToStack(state.stacks, state.focusedStack, second);
+            return updateState(state, {
+                stacks: pushToStack(newStacks, state.focusedStack, top)
+            });
+        },
+        doc: 'Duplicate the top two items on the stack',
+        stack: '( x1 x2 -- x1 x2 x1 x2 )'
+    },
+
+    'rot': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 3) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on rot - Stack 1 (Red) needs 3 items, but has ${state.stacks[state.focusedStack].length}. Add more items first.`] 
+                });
+            }
+            const newStacks = state.stacks.map((stack, i) => [...stack]);
+            const a = newStacks[state.focusedStack].pop();
+            const b = newStacks[state.focusedStack].pop();
+            const c = newStacks[state.focusedStack].pop();
+            newStacks[state.focusedStack].push(b);
+            newStacks[state.focusedStack].push(a);
+            newStacks[state.focusedStack].push(c);
+            return updateState(state, { stacks: newStacks });
+        },
+        doc: 'Rotate the top three items on the stack',
+        stack: '( x1 x2 x3 -- x2 x3 x1 )'
+    },
+
+    '-rot': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 3) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on -rot - Stack 1 (Red) needs 3 items, but has ${state.stacks[state.focusedStack].length}. Add more items first.`] 
+                });
+            }
+            const newStacks = state.stacks.map((stack, i) => [...stack]);
+            const a = newStacks[state.focusedStack].pop();
+            const b = newStacks[state.focusedStack].pop();
+            const c = newStacks[state.focusedStack].pop();
+            newStacks[state.focusedStack].push(a);
+            newStacks[state.focusedStack].push(c);
+            newStacks[state.focusedStack].push(b);
+            return updateState(state, { stacks: newStacks });
+        },
+        doc: 'Rotate the top three items on the stack (reverse of rot)',
+        stack: '( x1 x2 x3 -- x3 x1 x2 )'
+    },
+
+    // Cross-stack operations
+    'dup.stacks': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on dup.stacks - ${getFocusedStackName(state.focusedStack)} is empty. Add an item first.`] 
+                });
+            }
+            return updateState(state, {
+                crossStackInProgress: true,
+                crossStackOperation: 'dup',
+                crossStackData: { top: state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 1] },
+                output: [...state.output, `Enter destination stack (1-4) to duplicate to:`]
+            });
+        },
+        doc: 'Duplicate top item from focused stack to another stack',
+        stack: '( x -- x x ) (interactive)'
+    },
+
+    'over.stacks': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on over.stacks - ${getFocusedStackName(state.focusedStack)} needs 2 items, but has ${state.stacks[state.focusedStack].length}. Add more items first.`] 
+                });
+            }
+            const second = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 2];
+            return updateState(state, {
+                crossStackInProgress: true,
+                crossStackOperation: 'over',
+                crossStackData: { second },
+                output: [...state.output, `Enter destination stack (1-4) to copy second item to:`]
+            });
+        },
+        doc: 'Copy second item from focused stack to another stack',
+        stack: '( x1 x2 -- x1 x2 x1 ) (interactive)'
+    },
+
+    'swap.stacks': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on swap.stacks - ${getFocusedStackName(state.focusedStack)} needs 2 items, but has ${state.stacks[state.focusedStack].length}. Add more items first.`] 
+                });
+            }
+            const top = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 1];
+            const second = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 2];
+            return updateState(state, {
+                crossStackInProgress: true,
+                crossStackOperation: 'swap',
+                crossStackData: { top, second },
+                output: [...state.output, `Enter target stack (1-4) to swap with:`]
+            });
+        },
+        doc: 'Swap top items between focused stack and another stack',
+        stack: '( x1 x2 -- x2 x1 ) (interactive)'
+    },
+
+    'nip.stacks': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on nip.stacks - ${getFocusedStackName(state.focusedStack)} needs 2 items, but has ${state.stacks[state.focusedStack].length}. Add more items first.`] 
+                });
+            }
+            const top = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 1];
+            const second = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 2];
+            return updateState(state, {
+                crossStackInProgress: true,
+                crossStackOperation: 'nip',
+                crossStackData: { top, second },
+                output: [...state.output, `Enter destination stack (1-4) to move second item to:`]
+            });
+        },
+        doc: 'Move second item from focused stack to another stack (remove from source)',
+        stack: '( x1 x2 -- x1 ) (interactive)'
+    },
+
+    'tuck.stacks': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on tuck.stacks - ${getFocusedStackName(state.focusedStack)} needs 2 items, but has ${state.stacks[state.focusedStack].length}. Add more items first.`] 
+                });
+            }
+            const top = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 1];
+            const second = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 2];
+            return updateState(state, {
+                crossStackInProgress: true,
+                crossStackOperation: 'tuck',
+                crossStackData: { top, second },
+                output: [...state.output, `Enter destination stack (1-4) to tuck top item under second item:`]
+            });
+        },
+        doc: 'Tuck top item under second item on another stack',
+        stack: '( x1 x2 -- x2 x1 x2 ) (interactive)'
+    },
+
+    'rot.stacks': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 3) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on rot.stacks - ${getFocusedStackName(state.focusedStack)} needs 3 items, but has ${state.stacks[state.focusedStack].length}. Add more items first.`] 
+                });
+            }
+            const first = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 3];
+            const second = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 2];
+            const third = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 1];
+            return updateState(state, {
+                crossStackInProgress: true,
+                crossStackOperation: 'rot',
+                crossStackData: { first, second, third },
+                output: [...state.output, `Enter destination stack (1-4) to rotate with:`]
+            });
+        },
+        doc: 'Rotate top 3 items between focused stack and another stack',
+        stack: '( x1 x2 x3 -- x2 x3 x1 ) (interactive)'
+    },
+
+    '2dup.stacks': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on 2dup.stacks - ${getFocusedStackName(state.focusedStack)} needs 2 items, but has ${state.stacks[state.focusedStack].length}. Add more items first.`] 
+                });
+            }
+            const top = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 1];
+            const second = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 2];
+            return updateState(state, {
+                crossStackInProgress: true,
+                crossStackOperation: '2dup',
+                crossStackData: { top, second },
+                output: [...state.output, `Enter destination stack (1-4) to duplicate top 2 items to:`]
+            });
+        },
+        doc: 'Duplicate top 2 items from focused stack to another stack',
+        stack: '( x1 x2 -- x1 x2 x1 x2 ) (interactive)'
+    },
+
+    '2over.stacks': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 4) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on 2over.stacks - ${getFocusedStackName(state.focusedStack)} needs 4 items, but has ${state.stacks[state.focusedStack].length}. Add more items first.`] 
+                });
+            }
+            return updateState(state, {
+                crossStackInProgress: true,
+                crossStackOperation: '2over',
+                crossStackData: {},
+                output: [...state.output, `Enter destination stack (1-4) to copy second pair of items to:`]
+            });
+        },
+        doc: 'Copy second pair of items from focused stack to another stack',
+        stack: '( x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2 ) (interactive)'
+    },
+
+    '2swap.stacks': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 4) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on 2swap.stacks - ${getFocusedStackName(state.focusedStack)} needs 4 items, but has ${state.stacks[state.focusedStack].length}. Add more items first.`] 
+                });
+            }
+            const first = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 4];
+            const second = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 3];
+            const third = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 2];
+            const fourth = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 1];
+            return updateState(state, {
+                crossStackInProgress: true,
+                crossStackOperation: '2swap',
+                crossStackData: { first, second, third, fourth },
+                output: [...state.output, `Enter destination stack (1-4) to swap top 2 pairs with:`]
+            });
+        },
+        doc: 'Swap top 2 pairs of items between focused stack and another stack',
+        stack: '( x1 x2 x3 x4 -- x3 x4 x1 x2 ) (interactive)'
+    },
+
+    // Arithmetic operations on stack 1
+    '+': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on + - ${getFocusedStackName(state.focusedStack)} needs 2 numbers, but has ${state.stacks[state.focusedStack].length}. Add more numbers first.`] 
+                });
+            }
+            const { stacks: stacks1, value: b } = popFromStack(state.stacks, state.focusedStack);
+            const { stacks: stacks2, value: a } = popFromStack(stacks1, state.focusedStack);
+            return updateState(state, {
+                stacks: pushToStack(stacks2, state.focusedStack, a + b)
+            });
+        },
+        doc: 'Add the top two numbers on the stack',
+        stack: '( n1 n2 -- n3 )'
+    },
+
+    '-': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on - - Stack 1 (Red) needs 2 numbers, but has ${state.stacks[state.focusedStack].length}. Add more numbers first.`] 
+                });
+            }
+            const { stacks: stacks1, value: b } = popFromStack(state.stacks, state.focusedStack);
+            const { stacks: stacks2, value: a } = popFromStack(stacks1, state.focusedStack);
+            return updateState(state, {
+                stacks: pushToStack(stacks2, state.focusedStack, a - b)
+            });
+        },
+        doc: 'Subtract the top number from the second number on the stack',
+        stack: '( n1 n2 -- n3 )'
+    },
+
+    '*': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on * - Stack 1 (Red) needs 2 numbers, but has ${state.stacks[state.focusedStack].length}. Add more numbers first.`] 
+                });
+            }
+            const { stacks: stacks1, value: b } = popFromStack(state.stacks, state.focusedStack);
+            const { stacks: stacks2, value: a } = popFromStack(stacks1, state.focusedStack);
+            return updateState(state, {
+                stacks: pushToStack(stacks2, state.focusedStack, a * b)
+            });
+        },
+        doc: 'Multiply the top two numbers on the stack',
+        stack: '( n1 n2 -- n3 )'
+    },
+
+    '/': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on / - Stack 1 (Red) needs 2 numbers, but has ${state.stacks[state.focusedStack].length}. Add more numbers first.`] 
+                });
+            }
+            const { stacks: stacks1, value: b } = popFromStack(state.stacks, state.focusedStack);
+            const { stacks: stacks2, value: a } = popFromStack(stacks1, state.focusedStack);
+            if (b === 0) {
+                return updateState(state, { 
+                    stacks: pushToStack(pushToStack(stacks2, state.focusedStack, a), state.focusedStack, b),
+                    output: [...state.output, 'Error: Division by zero - Cannot divide by zero. Check your divisor before dividing.'] 
+                });
+            }
+            return updateState(state, {
+                stacks: pushToStack(stacks2, state.focusedStack, Math.floor(a / b))
+            });
+        },
+        doc: 'Divide the second number by the top number on the stack (integer division)',
+        stack: '( n1 n2 -- n3 )'
+    },
+
+    'mod': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on mod - Stack 1 (Red) needs 2 numbers, but has ${state.stacks[state.focusedStack].length}. Add more numbers first.`] 
+                });
+            }
+            const { stacks: stacks1, value: b } = popFromStack(state.stacks, state.focusedStack);
+            const { stacks: stacks2, value: a } = popFromStack(stacks1, state.focusedStack);
+            if (b === 0) {
+                return updateState(state, { 
+                    stacks: pushToStack(pushToStack(stacks2, state.focusedStack, a), state.focusedStack, b),
+                    output: [...state.output, 'Error: Modulo by zero - Cannot calculate remainder when dividing by zero. Check your divisor first.'] 
+                });
+            }
+            return updateState(state, {
+                stacks: pushToStack(stacks2, state.focusedStack, a % b)
+            });
+        },
+        doc: 'Return the remainder of dividing the second number by the top number',
+        stack: '( n1 n2 -- n3 )'
+    },
+
+    'abs': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on abs - Stack 1 (Red) is empty. Add a number first.`] 
+                });
+            }
+            const { stacks, value } = popFromStack(state.stacks, state.focusedStack);
+            return updateState(state, {
+                stacks: pushToStack(stacks, state.focusedStack, Math.abs(value))
+            });
+        },
+        doc: 'Return the absolute value of the top number on the stack',
+        stack: '( n -- |n| )'
+    },
+
+    'negate': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on negate - ${getFocusedStackName(state.focusedStack)} is empty. Add a number first.`] 
+                });
+            }
+            const { stacks, value } = popFromStack(state.stacks, state.focusedStack);
+            return updateState(state, {
+                stacks: pushToStack(stacks, state.focusedStack, -value)
+            });
+        },
+        doc: 'Return the negative of the top number on the stack',
+        stack: '( n -- -n )'
+    },
+
+    'min': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on min - Stack 1 (Red) needs 2 numbers, but has ${state.stacks[state.focusedStack].length}. Add more numbers first.`] 
+                });
+            }
+            const { stacks: stacks1, value: b } = popFromStack(state.stacks, state.focusedStack);
+            const { stacks: stacks2, value: a } = popFromStack(stacks1, state.focusedStack);
+            return updateState(state, {
+                stacks: pushToStack(stacks2, state.focusedStack, Math.min(a, b))
+            });
+        },
+        doc: 'Return the smaller of the top two numbers on the stack',
+        stack: '( n1 n2 -- n3 )'
+    },
+
+    'max': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on max - Stack 1 (Red) needs 2 numbers, but has ${state.stacks[state.focusedStack].length}. Add more numbers first.`] 
+                });
+            }
+            const { stacks: stacks1, value: b } = popFromStack(state.stacks, state.focusedStack);
+            const { stacks: stacks2, value: a } = popFromStack(stacks1, state.focusedStack);
+            return updateState(state, {
+                stacks: pushToStack(stacks2, state.focusedStack, Math.max(a, b))
+            });
+        },
+        doc: 'Return the larger of the top two numbers on the stack',
+        stack: '( n1 n2 -- n3 )'
+    },
+
+    // Comparison and logic
+    '=': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on = - Stack 1 (Red) needs 2 values, but has ${state.stacks[state.focusedStack].length}. Add more values first.`] 
+                });
+            }
+            const { stacks: stacks1, value: b } = popFromStack(state.stacks, state.focusedStack);
+            const { stacks: stacks2, value: a } = popFromStack(stacks1, state.focusedStack);
+            return updateState(state, {
+                stacks: pushToStack(stacks2, state.focusedStack, a === b ? -1 : 0)
+            });
+        },
+        doc: 'Return true (-1) if the top two numbers are equal, false (0) otherwise',
+        stack: '( n1 n2 -- flag )'
+    },
+
+    '<': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on < - Stack 1 (Red) needs 2 values, but has ${state.stacks[state.focusedStack].length}. Add more values first.`] 
+                });
+            }
+            const { stacks: stacks1, value: b } = popFromStack(state.stacks, state.focusedStack);
+            const { stacks: stacks2, value: a } = popFromStack(stacks1, state.focusedStack);
+            return updateState(state, {
+                stacks: pushToStack(stacks2, state.focusedStack, a < b ? -1 : 0)
+            });
+        },
+        doc: 'Return true (-1) if the second number is less than the top number, false (0) otherwise',
+        stack: '( n1 n2 -- flag )'
+    },
+
+    '>': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on > - Stack 1 (Red) needs 2 values, but has ${state.stacks[state.focusedStack].length}. Add more values first.`] 
+                });
+            }
+            const { stacks: stacks1, value: b } = popFromStack(state.stacks, state.focusedStack);
+            const { stacks: stacks2, value: a } = popFromStack(stacks1, state.focusedStack);
+            return updateState(state, {
+                stacks: pushToStack(stacks2, state.focusedStack, a > b ? -1 : 0)
+            });
+        },
+        doc: 'Return true (-1) if the second number is greater than the top number, false (0) otherwise',
+        stack: '( n1 n2 -- flag )'
+    },
+
+    'and': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on and - Stack 1 (Red) needs 2 values, but has ${state.stacks[state.focusedStack].length}. Add more values first.`] 
+                });
+            }
+            const { stacks: stacks1, value: b } = popFromStack(state.stacks, state.focusedStack);
+            const { stacks: stacks2, value: a } = popFromStack(stacks1, state.focusedStack);
+            return updateState(state, {
+                stacks: pushToStack(stacks2, state.focusedStack, a && b ? -1 : 0)
+            });
+        },
+        doc: 'Return true (-1) if both top two values are true, false (0) otherwise',
+        stack: '( x1 x2 -- flag )'
+    },
+
+    'or': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on or - Stack 1 (Red) needs 2 values, but has ${state.stacks[state.focusedStack].length}. Add more values first.`] 
+                });
+            }
+            const { stacks: stacks1, value: b } = popFromStack(state.stacks, state.focusedStack);
+            const { stacks: stacks2, value: a } = popFromStack(stacks1, state.focusedStack);
+            return updateState(state, {
+                stacks: pushToStack(stacks2, state.focusedStack, a || b ? -1 : 0)
+            });
+        },
+        doc: 'Return true (-1) if either of the top two values is true, false (0) otherwise',
+        stack: '( x1 x2 -- flag )'
+    },
+
+    'not': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on not - Stack 1 (Red) is empty. Add a value first.`] 
+                });
+            }
+            const { stacks, value } = popFromStack(state.stacks, state.focusedStack);
+            return updateState(state, {
+                stacks: pushToStack(stacks, state.focusedStack, value ? 0 : -1)
+            });
+        },
+        doc: 'Return true (-1) if the top value is false, false (0) if it is true',
+        stack: '( x -- flag )'
+    },
+
+    // Stack inspection
+    '.s': {
+        fn: (state) => {
+            const stackStr = state.stacks[state.focusedStack].length === 0 ? 'empty' : state.stacks[0].join(' ');
+            return updateState(state, {
+                output: [...state.output, `Stack 1 (red): ${stackStr}`]
+            });
+        },
+        doc: 'Display the contents of the red stack (non-destructive)',
+        stack: '( -- )'
+    },
+
+    'depth': {
+        fn: (state) => {
+            return updateState(state, {
+                stacks: pushToStack(state.stacks, state.focusedStack, state.stacks[state.focusedStack].length)
+            });
+        },
+        doc: 'Push the number of items on the red stack',
+        stack: '( -- n )'
+    },
+
+    '.': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on . - Stack 1 (Red) is empty. Nothing to print.`] 
+                });
+            }
+            const { stacks, value } = popFromStack(state.stacks, state.focusedStack);
+            return updateState(state, {
+                stacks,
+                output: [...state.output, value.toString()]
+            });
+        },
+        doc: 'Pop and print the top item from the red stack',
+        stack: '( x -- )'
+    },
+
+    // Multi-stack operations
+    'move.red': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on move.red - ${getFocusedStackName(state.focusedStack)} is empty. Nothing to move.`] 
+                });
+            }
+            const { stacks, value } = popFromStack(state.stacks, state.focusedStack);
+            return updateState(state, {
+                stacks: pushToStack(stacks, 0, value)
+            });
+        },
+        doc: 'Move top item from focused stack to red stack (removes from focused stack)',
+        stack: '( x -- )'
+    },
+
+    'move.1': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on move.1 - ${getFocusedStackName(state.focusedStack)} is empty. Nothing to move.`] 
+                });
+            }
+            const { stacks, value } = popFromStack(state.stacks, state.focusedStack);
+            return updateState(state, {
+                stacks: pushToStack(stacks, 0, value)
+            });
+        },
+        doc: 'Move top item from focused stack to red stack (Stack 1) (removes from focused stack)',
+        stack: '( x -- )'
+    },
+
+    'move.teal': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on move.teal - ${getFocusedStackName(state.focusedStack)} is empty. Nothing to move.`] 
+                });
+            }
+            const { stacks, value } = popFromStack(state.stacks, state.focusedStack);
+            return updateState(state, {
+                stacks: pushToStack(stacks, 1, value)
+            });
+        },
+        doc: 'Move top item from focused stack to teal stack (removes from focused stack)',
+        stack: '( x -- )'
+    },
+
+    'move.2': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on move.2 - ${getFocusedStackName(state.focusedStack)} is empty. Nothing to move.`] 
+                });
+            }
+            const { stacks, value } = popFromStack(state.stacks, state.focusedStack);
+            return updateState(state, {
+                stacks: pushToStack(stacks, 1, value)
+            });
+        },
+        doc: 'Move top item from focused stack to teal stack (Stack 2) (removes from focused stack)',
+        stack: '( x -- )'
+    },
+
+    'move.blue': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on move.blue - ${getFocusedStackName(state.focusedStack)} is empty. Nothing to move.`] 
+                });
+            }
+            const { stacks, value } = popFromStack(state.stacks, state.focusedStack);
+            return updateState(state, {
+                stacks: pushToStack(stacks, 2, value)
+            });
+        },
+        doc: 'Move top item from focused stack to blue stack (removes from focused stack)',
+        stack: '( x -- )'
+    },
+
+    'move.3': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on move.3 - ${getFocusedStackName(state.focusedStack)} is empty. Nothing to move.`] 
+                });
+            }
+            const { stacks, value } = popFromStack(state.stacks, state.focusedStack);
+            return updateState(state, {
+                stacks: pushToStack(stacks, 2, value)
+            });
+        },
+        doc: 'Move top item from focused stack to blue stack (Stack 3) (removes from focused stack)',
+        stack: '( x -- )'
+    },
+
+    'move.yellow': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on move.yellow - ${getFocusedStackName(state.focusedStack)} is empty. Nothing to move.`] 
+                });
+            }
+            const { stacks, value } = popFromStack(state.stacks, state.focusedStack);
+            return updateState(state, {
+                stacks: pushToStack(stacks, 3, value)
+            });
+        },
+        doc: 'Move top item from focused stack to yellow stack (removes from focused stack)',
+        stack: '( x -- )'
+    },
+
+    'move.4': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on move.4 - ${getFocusedStackName(state.focusedStack)} is empty. Nothing to move.`] 
+                });
+            }
+            const { stacks, value } = popFromStack(state.stacks, state.focusedStack);
+            return updateState(state, {
+                stacks: pushToStack(stacks, 3, value)
+            });
+        },
+        doc: 'Move top item from focused stack to yellow stack (Stack 4) (removes from focused stack)',
+        stack: '( x -- )'
+    },
+
+    // Copy operations (keep item in source stack)
+    'copy.red': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on copy.red - ${getFocusedStackName(state.focusedStack)} is empty. Nothing to copy.`] 
+                });
+            }
+            const top = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 1];
+            return updateState(state, {
+                stacks: pushToStack(state.stacks, 0, top)
+            });
+        },
+        doc: 'Copy top item from focused stack to red stack (keeps item on focused stack)',
+        stack: '( x -- x )'
+    },
+
+    'copy.1': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on copy.1 - ${getFocusedStackName(state.focusedStack)} is empty. Nothing to copy.`] 
+                });
+            }
+            const top = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 1];
+            return updateState(state, {
+                stacks: pushToStack(state.stacks, 0, top)
+            });
+        },
+        doc: 'Copy top item from focused stack to red stack (Stack 1) (keeps item on focused stack)',
+        stack: '( x -- x )'
+    },
+
+    'copy.teal': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on copy.teal - ${getFocusedStackName(state.focusedStack)} is empty. Nothing to copy.`] 
+                });
+            }
+            const top = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 1];
+            return updateState(state, {
+                stacks: pushToStack(state.stacks, 1, top)
+            });
+        },
+        doc: 'Copy top item from focused stack to teal stack (keeps item on focused stack)',
+        stack: '( x -- x )'
+    },
+
+    'copy.2': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on copy.2 - ${getFocusedStackName(state.focusedStack)} is empty. Nothing to copy.`] 
+                });
+            }
+            const top = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 1];
+            return updateState(state, {
+                stacks: pushToStack(state.stacks, 1, top)
+            });
+        },
+        doc: 'Copy top item from focused stack to teal stack (Stack 2) (keeps item on focused stack)',
+        stack: '( x -- x )'
+    },
+
+    'copy.blue': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on copy.blue - ${getFocusedStackName(state.focusedStack)} is empty. Nothing to copy.`] 
+                });
+            }
+            const top = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 1];
+            return updateState(state, {
+                stacks: pushToStack(state.stacks, 2, top)
+            });
+        },
+        doc: 'Copy top item from focused stack to blue stack (keeps item on focused stack)',
+        stack: '( x -- x )'
+    },
+
+    'copy.3': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on copy.3 - ${getFocusedStackName(state.focusedStack)} is empty. Nothing to copy.`] 
+                });
+            }
+            const top = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 1];
+            return updateState(state, {
+                stacks: pushToStack(state.stacks, 2, top)
+            });
+        },
+        doc: 'Copy top item from focused stack to blue stack (Stack 3) (keeps item on focused stack)',
+        stack: '( x -- x )'
+    },
+
+    'copy.yellow': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on copy.yellow - ${getFocusedStackName(state.focusedStack)} is empty. Nothing to copy.`] 
+                });
+            }
+            const top = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 1];
+            return updateState(state, {
+                stacks: pushToStack(state.stacks, 3, top)
+            });
+        },
+        doc: 'Copy top item from focused stack to yellow stack (keeps item on focused stack)',
+        stack: '( x -- x )'
+    },
+
+    'copy.4': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on copy.4 - ${getFocusedStackName(state.focusedStack)} is empty. Nothing to copy.`] 
+                });
+            }
+            const top = state.stacks[state.focusedStack][state.stacks[state.focusedStack].length - 1];
+            return updateState(state, {
+                stacks: pushToStack(state.stacks, 3, top)
+            });
+        },
+        doc: 'Copy top item from focused stack to yellow stack (Stack 4) (keeps item on focused stack)',
+        stack: '( x -- x )'
+    },
+
+    'pop.red': {
+        fn: (state) => popAndPrint(state, 0),
+        doc: 'Pop and print top item from red stack',
+        stack: '( x -- )'
+    },
+
+    'pop.1': {
+        fn: (state) => popAndPrint(state, 0),
+        doc: 'Pop and print top item from red stack (Stack 1)',
+        stack: '( x -- )'
+    },
+
+    'pop.teal': {
+        fn: (state) => popAndPrint(state, 1),
+        doc: 'Pop and print top item from teal stack',
+        stack: '( x -- )'
+    },
+
+    'pop.2': {
+        fn: (state) => popAndPrint(state, 1),
+        doc: 'Pop and print top item from teal stack (Stack 2)',
+        stack: '( x -- )'
+    },
+
+    'pop.blue': {
+        fn: (state) => popAndPrint(state, 2),
+        doc: 'Pop and print top item from blue stack',
+        stack: '( x -- )'
+    },
+
+    'pop.3': {
+        fn: (state) => popAndPrint(state, 2),
+        doc: 'Pop and print top item from blue stack (Stack 3)',
+        stack: '( x -- )'
+    },
+
+    'pop.yellow': {
+        fn: (state) => popAndPrint(state, 3),
+        doc: 'Pop and print top item from yellow stack',
+        stack: '( x -- )'
+    },
+
+    'pop.4': {
+        fn: (state) => popAndPrint(state, 3),
+        doc: 'Pop and print top item from yellow stack (Stack 4)',
+        stack: '( x -- )'
+    },
+
+    // Move operations
+    'move': {
+        fn: (state) => {
+            return updateState(state, {
+                moveInProgress: true,
+                moveFromStack: null,
+                output: [...state.output, 'Enter source stack (1-4) to move from:']
+            });
+        },
+        doc: 'Move top item from one stack to another (interactive: source, then destination)',
+        stack: '( -- ) (interactive)'
+    },
+
+    // Utility words
+    'clear': {
+        fn: (state) => updateState(state, {
+            stacks: [[], [], [], []],
+            output: [...state.output, 'All stacks cleared']
+        }),
+        doc: 'Clear all four stacks',
+        stack: '( -- )'
+    },
+    
+    'clear.all': {
+        fn: (state) => updateState(state, {
+            stacks: [[], [], [], []],
+            output: [...state.output, 'All stacks cleared']
+        }),
+        doc: 'Clear all four stacks (alias for clear)',
+        stack: '( -- )'
+    },
+    
+    'clear.focused': {
+        fn: (state) => {
+            const stackNames = ['Red (1)', 'Teal (2)', 'Blue (3)', 'Yellow (4)'];
+            const newStacks = state.stacks.map((stack, i) => 
+                i === state.focusedStack ? [] : stack
+            );
+            return updateState(state, {
+                stacks: newStacks,
+                output: [...state.output, `${stackNames[state.focusedStack]} cleared`]
+            });
+        },
+        doc: 'Clear only the currently focused stack',
+        stack: '( -- )'
+    },
+
+    // String operations
+    '."': {
+        fn: (state) => {
+            return updateState(state, {
+                stringMode: true,
+                currentString: '',
+                stringPushMode: false
+            });
+        },
+        doc: 'Begin a string literal that will be printed to output',
+        stack: '( -- )'
+    },
+
+    's"': {
+        fn: (state) => {
+            return updateState(state, {
+                stringMode: true,
+                currentString: '',
+                stringPushMode: true
+            });
+        },
+        doc: 'Begin a string literal that will be pushed to the stack',
+        stack: '( -- )'
+    },
+
+    'type': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on type - Stack 1 (Red) needs 2 items (address and length), but has ${state.stacks[state.focusedStack].length}. Add more items first.`] 
+                });
+            }
+            const { stacks: stacks1, value: length } = popFromStack(state.stacks, state.focusedStack);
+            const { stacks: stacks2, value: string } = popFromStack(stacks1, 0);
+            return updateState(state, {
+                stacks: stacks2,
+                output: [...state.output, string.toString()]
+            });
+        },
+        doc: 'Print a string from the stack (takes length and string address)',
+        stack: '( addr len -- )'
+    },
+
+    'count': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on count - Stack 1 (Red) is empty. Add a string first.`] 
+                });
+            }
+            const { stacks, value } = popFromStack(state.stacks, state.focusedStack);
+            if (typeof value === 'string') {
+                const newStacks = pushToStack(stacks, state.focusedStack, value.length);
+                return updateState(state, {
+                    stacks: pushToStack(newStacks, state.focusedStack, value)
+                });
+            } else {
+                const newStacks = pushToStack(stacks, state.focusedStack, 0);
+                return updateState(state, {
+                    stacks: pushToStack(newStacks, state.focusedStack, '')
+                });
+            }
+        },
+        doc: 'Extract string info from counted string (returns length and address)',
+        stack: '( c-addr -- c-addr u )'
+    },
+
+    'char+': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on char+ - Stack 1 (Red) needs 2 items (string and offset), but has ${state.stacks[state.focusedStack].length}. Add more items first.`] 
+                });
+            }
+            const { stacks: stacks1, value: offset } = popFromStack(state.stacks, state.focusedStack);
+            const { stacks: stacks2, value: string } = popFromStack(stacks1, 0);
+            if (typeof string === 'string') {
+                return updateState(state, {
+                    stacks: pushToStack(stacks2, state.focusedStack, string + String.fromCharCode(offset))
+                });
+            } else {
+                return updateState(state, {
+                    stacks: pushToStack(pushToStack(stacks2, state.focusedStack, string), 0, offset),
+                    output: [...state.output, `Error: char+ requires string on stack - Got ${typeof string}, expected string. Use s" to create strings.`]
+                });
+            }
+        },
+        doc: 'Add a character to a string using ASCII offset',
+        stack: '( c-addr1 char -- c-addr2 )'
+    },
+
+    'strlen': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on strlen - Stack 1 (Red) is empty. Add a string first.`] 
+                });
+            }
+            const { stacks, value } = popFromStack(state.stacks, state.focusedStack);
+            if (typeof value === 'string') {
+                return updateState(state, {
+                    stacks: pushToStack(stacks, state.focusedStack, value.length)
+                });
+            } else {
+                return updateState(state, {
+                    stacks: pushToStack(stacks, state.focusedStack, 0),
+                    output: [...state.output, `Error: strlen requires string on stack - Got ${typeof value}, expected string. Use s" to create strings.`]
+                });
+            }
+        },
+        doc: 'Get the length of a string on the stack',
+        stack: '( str -- len )'
+    },
+
+    'strcat': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length < 2) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on strcat - Stack 1 (Red) needs 2 strings, but has ${state.stacks[state.focusedStack].length}. Add more strings first.`] 
+                });
+            }
+            const { stacks: stacks1, value: str2 } = popFromStack(state.stacks, state.focusedStack);
+            const { stacks: stacks2, value: str1 } = popFromStack(stacks1, 0);
+            if (typeof str1 === 'string' && typeof str2 === 'string') {
+                return updateState(state, {
+                    stacks: pushToStack(stacks2, state.focusedStack, str1 + str2)
+                });
+            } else {
+                return updateState(state, {
+                    stacks: pushToStack(pushToStack(stacks2, state.focusedStack, str1), 0, str2),
+                    output: [...state.output, `Error: strcat requires two strings - Got ${typeof str1} and ${typeof str2}. Use s" to create strings.`]
+                });
+            }
+        },
+        doc: 'Concatenate two strings from the stack',
+        stack: '( str1 str2 -- str3 )'
+    },
+
+    // Control flow
+    'if': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on if - Stack 1 (Red) is empty. Add a condition value first.`] 
+                });
+            }
+            const { stacks, value } = popFromStack(state.stacks, state.focusedStack);
+            if (value === 0) {
+                // Skip until THEN or ELSE
+                return updateState(state, {
+                    stacks,
+                    skipMode: true,
+                    skipCount: 0
+                });
+            }
+            return updateState(state, {
+                stacks
+            });
+        },
+        doc: 'Begin conditional execution - if top of stack is false (0), skip to THEN',
+        stack: '( flag -- )'
+    },
+
+    'else': {
+        fn: (state) => {
+            if (state.skipMode) {
+                return updateState(state, {
+                    skipCount: state.skipCount + 1
+                });
+            }
+            // Skip until THEN
+            return updateState(state, {
+                skipMode: true,
+                skipCount: 0
+            });
+        },
+        doc: 'Begin alternative branch in conditional execution',
+        stack: '( -- )'
+    },
+
+    'then': {
+        fn: (state) => {
+            if (state.skipMode && state.skipCount > 0) {
+                return updateState(state, {
+                    skipCount: state.skipCount - 1
+                });
+            } else if (state.skipMode) {
+                return updateState(state, {
+                    skipMode: false,
+                    skipCount: 0
+                });
+            }
+            return state;
+        },
+        doc: 'End conditional execution block',
+        stack: '( -- )'
+    },
+
+    'begin': {
+        fn: (state) => {
+            return updateState(state, {
+                loopStart: state.output.length
+            });
+        },
+        doc: 'Mark the beginning of a loop',
+        stack: '( -- )'
+    },
+
+    'until': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on until - Stack 1 (Red) is empty. Add a condition value first.`] 
+                });
+            }
+            const { stacks, value } = popFromStack(state.stacks, state.focusedStack);
+            if (value === 0) {
+                // Loop back to BEGIN
+                return updateState(state, {
+                    stacks,
+                    loopBack: true
+                });
+            }
+            return updateState(state, {
+                stacks
+            });
+        },
+        doc: 'End a loop - if top of stack is false (0), loop back to BEGIN',
+        stack: '( flag -- )'
+    },
+
+    // Help and documentation
+    'help': {
+        fn: (state) => {
+            const builtinWordNames = Object.keys(builtinWords);
+            const userWords = Array.from(state.dictionary.keys());
+            const allWords = [...builtinWordNames, ...userWords];
+            
+            const builtinList = builtinWordNames.map(name => {
+                const word = builtinWords[name];
+                return `${name} ${word.stack} - ${word.doc}`;
+            });
+            
+            const userList = userWords.length > 0 ? userWords.join(' ') : 'none';
+            
+            return updateState(state, {
+                output: [
+                    ...state.output,
+                    '=== 4-Stack Forth Interpreter Help ===',
+                    '',
+                    'Built-in words:',
+                    ...builtinList,
+                    '',
+                    'User defined words: ' + userList,
+                    '',
+                    'Total words: ' + allWords.length,
+                    '',
+                    'Use "doc <word>" to get detailed help for a specific word',
+                    'Use "words" to see just the word names'
+                ]
+            });
+        },
+        doc: 'Display comprehensive help information for all available words',
+        stack: '( -- )'
+    },
+
+    'doc': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on doc - Stack 1 (Red) is empty. Add a word name first (e.g., s" dup" doc).`] 
+                });
+            }
+            const { stacks, value: wordName } = popFromStack(state.stacks, state.focusedStack);
+            
+            // Check built-in words first
+            if (builtinWords[wordName]) {
+                const word = builtinWords[wordName];
+                return updateState(state, {
+                    stacks,
+                    output: [
+                        ...state.output,
+                        `=== ${wordName} ===`,
+                        `Stack effect: ${word.stack}`,
+                        `Description: ${word.doc}`,
+                        `Type: Built-in word`
+                    ]
+                });
+            }
+            
+            // Check user-defined words
+            if (state.dictionary.has(wordName)) {
+                const definition = state.dictionary.get(wordName);
+                return updateState(state, {
+                    stacks,
+                    output: [
+                        ...state.output,
+                        `=== ${wordName} ===`,
+                        `Definition: ${definition.join(' ')}`,
+                        `Type: User-defined word`
+                    ]
+                });
+            }
+            
+            return updateState(state, {
+                stacks,
+                output: [...state.output, `Word '${wordName}' not found`]
+            });
+        },
+        doc: 'Display documentation for a specific word',
+        stack: '( "word" -- )'
+    },
+
+    'words': {
+        fn: (state) => {
+            const builtinWordNames = Object.keys(builtinWords);
+            const userWords = Array.from(state.dictionary.keys());
+            const allWords = [...builtinWordNames, ...userWords];
+            
+            const builtinList = builtinWordNames.join(' ');
+            const userList = userWords.length > 0 ? userWords.join(' ') : 'none';
+            
+            return updateState(state, {
+                output: [
+                    ...state.output,
+                    'Built-in words: ' + builtinList,
+                    'User defined words: ' + userWords.join(' '),
+                    'Total words: ' + allWords.length
+                ]
+            });
+        },
+        doc: 'List all available words (built-in and user-defined)',
+        stack: '( -- )'
+    }
+};
+
+// Help and documentation commands (defined outside builtinWords to avoid circular reference)
+const helpCommands = {
+    'help': {
+        fn: (state) => {
+            const builtinWordNames = Object.keys(builtinWords);
+            const userWords = Array.from(state.dictionary.keys());
+            const allWords = [...builtinWordNames, ...userWords];
+            
+            const builtinList = builtinWordNames.map(name => {
+                const word = builtinWords[name];
+                return `${name} ${word.stack} - ${word.doc}`;
+            });
+            
+            const userList = userWords.length > 0 ? userWords.join(' ') : 'none';
+            
+            return updateState(state, {
+                output: [
+                    ...state.output,
+                    '=== 4-Stack Forth Interpreter Help ===',
+                    '',
+                    'Built-in words:',
+                    ...builtinList,
+                    '',
+                    'User defined words: ' + userList,
+                    '',
+                    'Total words: ' + allWords.length,
+                    '',
+                    'Use "doc <word>" to get detailed help for a specific word',
+                    'Use "words" to see just the word names'
+                ]
+            });
+        },
+        doc: 'Display comprehensive help information for all available words',
+        stack: '( -- )'
+    },
+
+    'doc': {
+        fn: (state) => {
+            if (state.stacks[state.focusedStack].length === 0) {
+                return updateState(state, { 
+                    output: [...state.output, `Error: Stack underflow on doc - Stack 1 (Red) is empty. Add a word name first (e.g., s" dup" doc).`] 
+                });
+            }
+            const { stacks, value: wordName } = popFromStack(state.stacks, state.focusedStack);
+            
+            // Check built-in words first
+            if (builtinWords[wordName]) {
+                const word = builtinWords[wordName];
+                return updateState(state, {
+                    stacks,
+                    output: [
+                        ...state.output,
+                        `=== ${wordName} ===`,
+                        `Stack effect: ${word.stack}`,
+                        `Description: ${word.doc}`,
+                        `Type: Built-in word`
+                    ]
+                });
+            }
+            
+            // Check user-defined words
+            if (state.dictionary.has(wordName)) {
+                const definition = state.dictionary.get(wordName);
+                return updateState(state, {
+                    stacks,
+                    output: [
+                        ...state.output,
+                        `=== ${wordName} ===`,
+                        `Definition: ${definition.join(' ')}`,
+                        `Type: User-defined word`
+                    ]
+                });
+            }
+            
+            return updateState(state, {
+                stacks,
+                output: [...state.output, `Word '${wordName}' not found`]
+            });
+        },
+        doc: 'Display documentation for a specific word',
+        stack: '( "word" -- )'
+    }
+};
+
+// Parse and execute Forth input
+const parseAndExecute = (state, input) => {
+    const tokens = input.trim().split(/\s+/).filter(token => token.length > 0);
+    return tokens.reduce(executeToken, state);
+};
+
+// Execute a single token
+const executeToken = (state, token) => {
+    // Handle string mode
+    if (state.stringMode) {
+        // Check if this token contains the closing quote
+        const quoteIndex = token.indexOf('"');
+        if (quoteIndex !== -1) {
+            // Token contains closing quote
+            const beforeQuote = token.substring(0, quoteIndex);
+            const afterQuote = token.substring(quoteIndex + 1);
+            
+            // Add the part before the quote to the string
+            const finalString = state.currentString + (state.currentString ? ' ' : '') + beforeQuote;
+            
+            // End string mode and handle based on mode
+            let newState;
+            if (state.stringPushMode) {
+                // Push mode: add string to stack
+                newState = updateState(state, {
+                    stringMode: false,
+                    currentString: '',
+                    stringPushMode: false,
+                    stacks: pushToStack(state.stacks, state.focusedStack, finalString)
+                });
+            } else {
+                // Print mode: add to output
+                newState = updateState(state, {
+                    stringMode: false,
+                    currentString: '',
+                    stringPushMode: false,
+                    output: [...state.output, finalString]
+                });
+            }
+            
+            // If there's content after the quote, process it
+            if (afterQuote.trim()) {
+                newState = ForthInterpreter.parseAndExecute(newState, afterQuote);
+            }
+            
+            return newState;
+        } else {
+            // Add to current string
+            return updateState(state, {
+                currentString: state.currentString + (state.currentString ? ' ' : '') + token
+            });
+        }
+    }
+
+    // Handle skip mode (for control flow)
+    if (state.skipMode) {
+        if (token === 'if' || token === 'begin') {
+            return updateState(state, {
+                skipCount: state.skipCount + 1
+            });
+        } else if (token === 'then' || token === 'until') {
+            if (state.skipCount > 0) {
+                return updateState(state, {
+                    skipCount: state.skipCount - 1
+                });
+            } else {
+                return updateState(state, {
+                    skipMode: false,
+                    skipCount: 0
+                });
+            }
+        } else if (token === 'else') {
+            if (state.skipCount === 0) {
+                // Switch to skipping ELSE branch
+                return updateState(state, {
+                    skipMode: true,
+                    skipCount: 0
+                });
+            }
+        }
+        // Skip this token
+        return state;
+    }
+
+    // Handle move operation state machine
+    if (state.moveInProgress) {
+        if (state.moveFromStack === null) {
+            // Expecting source stack number
+            const from = parseInt(token);
+            if (isNaN(from) || from < 1 || from > 4) {
+                return updateState(state, {
+                    moveInProgress: false,
+                    moveFromStack: null,
+                    output: [...state.output, `Error: Invalid source stack ${from} - Must be 1, 2, 3, or 4.`]
+                });
+            }
+            if (state.stacks[from - 1].length === 0) {
+                return updateState(state, {
+                    moveInProgress: false,
+                    moveFromStack: null,
+                    output: [...state.output, `Error: Stack ${from} is empty - Nothing to move. Add items to stack ${from} first.`]
+                });
+            }
+            return updateState(state, {
+                moveInProgress: true,
+                moveFromStack: from - 1, // Convert to 0-based index
+                output: [...state.output, `Moving from stack ${from}. Enter destination stack (1-4):`]
+            });
+        } else {
+            // Expecting destination stack number
+            const to = parseInt(token);
+            if (isNaN(to) || to < 1 || to > 4) {
+                return updateState(state, {
+                    moveInProgress: false,
+                    moveFromStack: null,
+                    output: [...state.output, `Error: Invalid destination stack ${to} - Must be 1, 2, 3, or 4.`]
+                });
+            }
+            const toIndex = to - 1; // Convert to 0-based index
+            const fromIndex = state.moveFromStack;
+            
+            // Reset move state
+            const newState = updateState(state, {
+                moveInProgress: false,
+                moveFromStack: null
+            });
+            
+            // Perform the move
+            const { stacks, value } = popFromStack(newState.stacks, fromIndex);
+            return updateState(newState, {
+                stacks: pushToStack(stacks, toIndex, value),
+                output: [...newState.output, `Moved ${value} from stack ${fromIndex + 1} to stack ${toIndex + 1}`]
+            });
+        }
+    }
+
+    // Handle cross-stack operations state machine
+    if (state.crossStackInProgress) {
+        if (state.crossStackOperation === null) {
+            // This shouldn't happen, but handle gracefully
+            return updateState(state, {
+                crossStackInProgress: false,
+                crossStackOperation: null,
+                crossStackData: null,
+                output: [...state.output, 'Error: Cross-stack operation state corrupted']
+            });
+        }
+        
+        // Expecting target stack number
+        const target = parseInt(token);
+        if (isNaN(target) || target < 1 || target > 4) {
+            return updateState(state, {
+                crossStackInProgress: false,
+                crossStackOperation: null,
+                crossStackData: null,
+                output: [...state.output, `Error: Invalid target stack ${target} - Must be 1, 2, 3, or 4.`]
+            });
+        }
+        
+        const targetIndex = target - 1; // Convert to 0-based index
+        const sourceIndex = state.focusedStack;
+        
+        // Execute the cross-stack operation (don't clear state yet)
+        const result = executeCrossStackOperation(state, sourceIndex, targetIndex);
+        
+        // Clear cross-stack state after execution
+        return updateState(result, {
+            crossStackInProgress: false,
+            crossStackOperation: null,
+            crossStackData: null
+        });
+    }
+
+    // Handle word definition compilation
+    if (state.compilingWord !== null) {
+        if (token === ';') {
+            const newDictionary = new Map(state.dictionary);
+            newDictionary.set(state.compilingWord, [...state.compilingDefinition]);
+            return updateState(state, {
+                dictionary: newDictionary,
+                compilingWord: null,
+                compilingDefinition: [],
+                output: [...state.output, `Word '${state.compilingWord}' defined`]
+            });
+        }
+        
+        // If we're expecting a name, capture it
+        if (state.compilingWord === 'EXPECTING_NAME') {
+            return updateState(state, {
+                compilingWord: token,
+                compilingDefinition: []
+            });
+        }
+        
+        // Otherwise, add to definition
+        return updateState(state, {
+            compilingDefinition: [...state.compilingDefinition, token]
+        });
+    }
+
+    // Handle word definition start
+    if (token === ':') {
+        return updateState(state, {
+            compilingWord: 'EXPECTING_NAME',
+            compilingDefinition: []
+        });
+    }
+
+    // Check if it's a built-in word
+    if (builtinWords[token]) {
+        return builtinWords[token].fn(state);
+    }
+
+    // Check if it's a user-defined word
+    if (state.dictionary.has(token)) {
+        const definition = state.dictionary.get(token);
+        return definition.reduce(executeToken, state);
+    }
+
+    // Check if it's a number
+    const num = parseFloat(token);
+    if (!isNaN(num)) {
+        return updateState(state, {
+            stacks: pushToStack(state.stacks, state.focusedStack, num)
+        });
+    }
+
+
+
+    // Check if it's a cross-stack operation
+    if (token.endsWith('.stacks')) {
+        const baseOperation = token.replace('.stacks', '');
+        if (builtinWords[token]) {
+            return builtinWords[token].fn(state);
+        }
+    }
+
+    // Unknown token
+    return updateState(state, {
+        output: [...state.output, `Error: Unknown word '${token}' - Use 'help' to see all available words, or 'doc <word>' for specific help.`]
+    });
+};
+
+// Export for use in other modules or testing
+if (typeof module !== 'undefined' && module.exports) {
+    module.exports = {
+        createInitialState,
+        parseAndExecute,
+        executeToken,
+        builtinWords,
+        updateState,
+        pushToStack,
+        popFromStack
+    };
+} else if (typeof window !== 'undefined') {
+    // Browser environment
+    window.ForthInterpreter = {
+        createInitialState,
+        parseAndExecute,
+        executeToken,
+        builtinWords,
+        updateState,
+        pushToStack,
+        popFromStack
+    };
+}