about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2025-01-11 21:53:17 -0500
committerelioat <elioat@tilde.institute>2025-01-11 21:53:17 -0500
commit4825666a8086801df1577e0e54b5f85f7b6cf175 (patch)
treeba019b86492319292196b97269c52c731c35e8c1
parenta9aa0889034ff0cf40b47c4110b6948d4bec2470 (diff)
downloadtour-4825666a8086801df1577e0e54b5f85f7b6cf175.tar.gz
*
-rwxr-xr-xawk/forth/f.awk510
-rwxr-xr-xawk/forth/old/f.awk344
-rw-r--r--awk/forth/old/test.forth (renamed from awk/forth/test.forth)0
3 files changed, 572 insertions, 282 deletions
diff --git a/awk/forth/f.awk b/awk/forth/f.awk
index eed9774..cf50dcf 100755
--- a/awk/forth/f.awk
+++ b/awk/forth/f.awk
@@ -1,344 +1,290 @@
 #!/usr/bin/awk -f
 
-# Forth interpreter in AWK
-
 BEGIN {
-    print "Welcome to the AWK Forth Interpreter!"
-    print "Type your commands below. Use 'bye' to quit."
-    # Initialize variables
-    top = -1  # Initialize stack pointer
+    # Initialize stacks and dictionaries
+    stack_ptr = 0
+    dict_size = 0
     
-    # Initialize the dictionary with basic words
-    words["+"] = "+"
-    words["-"] = "-"
-    words["*"] = "*"
-    words["/"] = "/"
-    words["dup"] = "dup"
-    words["over"] = "over"
-    words["swap"] = "swap"
-    words["."] = "."
-    words["bye"] = "bye"
-    words["rot"] = "rot"
-    words["drop"] = "drop"
-    words["nip"] = "nip"
-    words["tuck"] = "tuck"
-    words["roll"] = "roll"
-    words["pick"] = "pick"
-    words["negate"] = "negate"
-    words["abs"] = "abs"
-    words["max"] = "max"
-    words["min"] = "min"
-    words["mod"] = "mod"
-    words["="] = "="
-    words["see"] = "see"
-    words["if"] = "if"
-    words["then"] = "then"
-    words["else"] = "else"
-    words[">"] = ">"
-    words["<"] = "<"
+    # Built-in words are stored with their function names
+    dict["+"] = "math_add"
+    dict["-"] = "math_sub"
+    dict["*"] = "math_mul"
+    dict["/"] = "math_div"
+    dict["."] = "stack_print"
+    dict[".s"] = "stack_show"
+    dict["dup"] = "stack_dup"
+    dict["drop"] = "stack_drop"
+    dict["swap"] = "stack_swap"
+    dict["over"] = "stack_over"
+    dict["rot"] = "stack_rot"
+    dict["="] = "compare_eq"
+    dict["<"] = "compare_lt"
+    dict[">"] = "compare_gt"
+    dict["bye"] = "exit_program"
+    dict["words"] = "list_words"
     
-    # Add handlers for all words
-    handlers["+"] = "add"
-    handlers["-"] = "subtract"
-    handlers["*"] = "multiply"
-    handlers["/"] = "divide"
-    handlers["dup"] = "dup"
-    handlers["over"] = "over"
-    handlers["swap"] = "swap"
-    handlers["."] = "print_top"
-    handlers["<"] = "less_than"
-    handlers[">"] = "greater_than"
-    handlers["rot"] = "rot"
-    handlers["drop"] = "drop"
-    handlers["nip"] = "nip"
-    handlers["tuck"] = "tuck"
-    handlers["roll"] = "roll"
-    handlers["pick"] = "pick"
-    handlers["negate"] = "negate"
-    handlers["abs"] = "abs"
-    handlers["max"] = "max"
-    handlers["min"] = "min"
-    handlers["mod"] = "mod"
-    handlers["="] = "equals"
-    handlers["if"] = "handle_if"
-    handlers["then"] = "handle_then"
-    handlers["else"] = "handle_else"
-    handlers["bye"] = "bye"
-    handlers["see"] = "see"
-
-    # Add descriptions for words
-    desc["+"] = "( n1 n2 -- sum ) Add top two numbers"
-    desc["-"] = "( n1 n2 -- diff ) Subtract top number from second"
-    desc["*"] = "( n1 n2 -- prod ) Multiply top two numbers"
-    desc["/"] = "( n1 n2 -- quot ) Divide second by top"
-    desc["dup"] = "( n -- n n ) Duplicate top of stack"
-    desc["over"] = "( n1 n2 -- n1 n2 n1 ) Copy second item to top"
-    desc["swap"] = "( n1 n2 -- n2 n1 ) Swap top two items"
-    desc["rot"] = "( n1 n2 n3 -- n2 n3 n1 ) Rotate top three items"
-    desc["drop"] = "( n -- ) Discard top item"
-    desc["nip"] = "( n1 n2 -- n2 ) Remove second item"
-    desc["tuck"] = "( n1 n2 -- n2 n1 n2 ) Copy top item below second"
-    desc["roll"] = "( nk ... n1 n0 k -- nk-1 ... n1 n0 nk ) Move kth item to top"
-    desc["pick"] = "( nk ... n1 n0 k -- nk ... n1 n0 nk ) Copy kth item to top"
-    desc["negate"] = "( n -- -n ) Negate number"
-    desc["abs"] = "( n -- |n| ) Absolute value"
-    desc["max"] = "( n1 n2 -- max ) Maximum of top two numbers"
-    desc["min"] = "( n1 n2 -- min ) Minimum of top two numbers"
-    desc["mod"] = "( n1 n2 -- rem ) Remainder of n1/n2"
-    desc["="] = "( n1 n2 -- flag ) Test if equal, leaves 1 if true, 0 if false"
-    desc["if"] = "( flag -- ) Begin conditional execution"
-    desc["then"] = "( -- ) End conditional execution"
-    desc["else"] = "( -- ) Execute if previous condition was false"
-    desc[">"] = "( n1 n2 -- flag ) Returns true if n1 is greater than n2"
-    desc["<"] = "( n1 n2 -- flag ) Returns true if n1 is less than n2"
-    desc["bye"] = "( -- ) Exit the interpreter"
-    desc["see"] = "( -- ) Show definition of a word"
-
-    # Initialize condition stack
-    cond_top = -1
-
-    # Mark these as compile-only words
-    compile_only["if"] = 1
-    compile_only["then"] = 1
-    compile_only["else"] = 1
-}
-
-# Stack operations
-function push(value) {
-    stack[++top] = value
+    # State flags
+    compiling = 0
+    current_def = ""
+    def_name = ""
+    
+    # If no input file specified, enter REPL mode
+    if (ARGC == 1) {
+        repl()
+    }
 }
 
-function pop() {
-    if (top < 0) {
-        print "Error: Stack underflow"
-        return 0
+# Handle file input
+{
+    if (FILENAME ~ /\.forth$/) {
+        interpret($0)
     }
-    return stack[top--]
 }
 
-function check_stack(min_items, error_msg) {
-    if (top < min_items - 1) {
-        print error_msg ? error_msg : "Error: Not enough values on stack"
-        return 0
+function repl() {
+    print "Welcome to the f.awk, a naive forth interpreter. Use 'bye' to exit."
+    while (1) {
+        printf "f> "
+        if (getline input < "/dev/tty" <= 0) break
+        interpret(input)
     }
-    return 1
 }
 
-# Binary operations
-function binary_op(operation) {
-    if (!check_stack(2)) return
-    second = pop()
-    first = pop()
-    if (operation == "+") push(first + second)
-    else if (operation == "-") push(first - second)
-    else if (operation == "*") push(first * second)
-    else if (operation == "/") {
-        if (second == 0) {
-            print "Error: Division by zero"
-            push(first)
-            push(second)
-            return
+function interpret(line) {
+    n = split(line, words, /[ \t]+/)
+    
+    for (i = 1; i <= n; i++) {
+        word = words[i]
+        if (word == "") continue
+        
+        if (word == ":") {
+            compiling = 1
+            i++
+            def_name = words[i]
+            current_def = ""
+            continue
         }
-        push(first / second)
+        
+        if (compiling) {
+            if (word == ";") {
+                dict[def_name] = "word " current_def
+                compiling = 0
+                continue
+            }
+            current_def = current_def " " word
+            continue
+        }
+        
+        execute_word(word)
     }
-    else if (operation == "mod") push(first % second)
-    else if (operation == "=") push(first == second ? 1 : 0)
-    else if (operation == "<") push(first < second ? 1 : 0)
-    else if (operation == ">") push(first > second ? 1 : 0)
 }
 
-# Handler functions
-function add() { binary_op("+") }
-function subtract() { binary_op("-") }
-function multiply() { binary_op("*") }
-function divide() { binary_op("/") }
-function mod() { binary_op("mod") }
-function equals() { binary_op("=") }
-function less_than() { binary_op("<") }
-function greater_than() { binary_op(">") }
-
-function dup() {
-    if (!check_stack(1)) return
-    push(stack[top])
+function execute_word(word) {
+    if (word ~ /^-?[0-9]+$/) {
+        push(word + 0)
+    } else if (word in dict) {
+        if (dict[word] ~ /^word /) {
+            # User-defined word
+            sequence = substr(dict[word], 6)
+            split(sequence, subwords, " ")
+            for (sw in subwords) {
+                if (subwords[sw] != "") {
+                    execute_word(subwords[sw])
+                }
+            }
+        } else {
+            # Built-in word
+            if (dict[word] == "math_add") math_add()
+            else if (dict[word] == "math_sub") math_sub()
+            else if (dict[word] == "math_mul") math_mul()
+            else if (dict[word] == "math_div") math_div()
+            else if (dict[word] == "stack_print") stack_print()
+            else if (dict[word] == "stack_show") stack_show()
+            else if (dict[word] == "stack_dup") stack_dup()
+            else if (dict[word] == "stack_drop") stack_drop()
+            else if (dict[word] == "stack_swap") stack_swap()
+            else if (dict[word] == "stack_over") stack_over()
+            else if (dict[word] == "stack_rot") stack_rot()
+            else if (dict[word] == "compare_eq") compare_eq()
+            else if (dict[word] == "compare_lt") compare_lt()
+            else if (dict[word] == "compare_gt") compare_gt()
+            else if (word == "bye") exit_program()
+            else if (word == "words") list_words()
+        }
+    } else {
+        print "Error: Unknown word '" word "'"
+    }
 }
 
-function over() {
-    if (!check_stack(2)) return
-    push(stack[top - 1])
+# Stack operations
+function push(val) {
+    stack[stack_ptr++] = val
 }
 
-function swap() {
-    if (!check_stack(2)) return
-    temp = pop()
-    second = pop()
-    push(temp)
-    push(second)
+function pop() {
+    if (stack_ptr <= 0) {
+        print "Error: Stack underflow"
+        return 0
+    }
+    return stack[--stack_ptr]
 }
 
-function rot() {
-    if (!check_stack(3)) return
-    third = pop()
-    second = pop()
-    first = pop()
-    push(second)
-    push(third)
-    push(first)
+# Math operations
+function math_add() {
+    if (stack_ptr < 2) {
+        print "Error: Stack underflow"
+        return
+    }
+    b = pop()
+    a = pop()
+    push(a + b)
 }
 
-function drop() {
-    if (!check_stack(1)) return
-    top--
+function math_sub() {
+    if (stack_ptr < 2) {
+        print "Error: Stack underflow"
+        return
+    }
+    b = pop()
+    a = pop()
+    push(a - b)
 }
 
-function nip() {
-    if (!check_stack(2)) return
-    temp = stack[top]
-    drop()
-    drop()
-    push(temp)
+function math_mul() {
+    if (stack_ptr < 2) {
+        print "Error: Stack underflow"
+        return
+    }
+    b = pop()
+    a = pop()
+    push(a * b)
 }
 
-function tuck() {
-    if (!check_stack(2)) return
-    temp = pop()
-    second = pop()
-    push(temp)
-    push(second)
-    push(temp)
+function math_div() {
+    if (stack_ptr < 2) {
+        print "Error: Stack underflow"
+        return
+    }
+    b = pop()
+    if (b == 0) {
+        print "Error: Division by zero"
+        return
+    }
+    a = pop()
+    push(int(a / b))
 }
 
-function roll() {
-    if (!check_stack(1)) return
-    n = int(pop())
-    if (!check_stack(n)) return
-    if (n <= 0) return
-
-    temp = stack[top - n + 1]
-    for (i = top - n + 1; i < top; i++) {
-        stack[i] = stack[i + 1]
+# Stack manipulation
+function stack_print() {
+    if (stack_ptr < 1) {
+        print "Error: Stack underflow"
+        return
     }
-    stack[top] = temp
+    print pop()
 }
 
-function pick() {
-    if (!check_stack(1)) return
-    n = int(pop())
-    if (!check_stack(n)) return
-    if (n < 0) return
-    push(stack[top - n])
+function stack_show() {
+    print "<", stack_ptr, "> "
+    for (i = 0; i < stack_ptr; i++) {
+        printf "%s ", stack[i]
+    }
+    print ""
 }
 
-function negate() {
-    if (!check_stack(1)) return
-    push(-pop())
+function stack_dup() {
+    if (stack_ptr < 1) {
+        print "Error: Stack underflow"
+        return
+    }
+    val = stack[stack_ptr - 1]
+    push(val)
 }
 
-function abs() {
-    if (!check_stack(1)) return
-    n = pop()
-    push(n < 0 ? -n : n)
+function stack_drop() {
+    if (stack_ptr < 1) {
+        print "Error: Stack underflow"
+        return
+    }
+    pop()
 }
 
-function max() {
-    if (!check_stack(2)) return
+function stack_swap() {
+    if (stack_ptr < 2) {
+        print "Error: Stack underflow"
+        return
+    }
     b = pop()
     a = pop()
-    push(a > b ? a : b)
+    push(b)
+    push(a)
 }
 
-function min() {
-    if (!check_stack(2)) return
+function stack_over() {
+    if (stack_ptr < 2) {
+        print "Error: Stack underflow"
+        return
+    }
     b = pop()
     a = pop()
-    push(a < b ? a : b)
+    push(a)
+    push(b)
+    push(a)
 }
 
-function print_top() {
-    if (!check_stack(1)) return
-    print stack[top]
-    drop()
+function stack_rot() {
+    if (stack_ptr < 3) {
+        print "Error: Stack underflow"
+        return
+    }
+    c = pop()
+    b = pop()
+    a = pop()
+    push(b)
+    push(c)
+    push(a)
 }
 
-function bye() {
-    exit
+# Comparison operations
+function compare_eq() {
+    if (stack_ptr < 2) {
+        print "Error: Stack underflow"
+        return
+    }
+    b = pop()
+    a = pop()
+    push(a == b ? -1 : 0)
 }
 
-function see(word) {
-    if (!(word in words)) {
-        print "Error: Word '" word "' not found"
+function compare_lt() {
+    if (stack_ptr < 2) {
+        print "Error: Stack underflow"
         return
     }
-    if (word in desc) {
-        print desc[word]
-    }
-    if (word in raw_definitions) {
-        print ": " word " " raw_definitions[word] " ;"
-    }
+    b = pop()
+    a = pop()
+    push(a < b ? -1 : 0)
 }
 
-# Main processing function
-function execute_word(word) {
-    if (word in handlers) {
-        handler = handlers[word]
-        if (handler == "bye") exit
-        else if (handler == "see") {
-            if (i + 1 <= NF) see($(++i))
-            else print "Error: see requires a word name"
-        }
-        else if (handler == "add") add()
-        else if (handler == "subtract") subtract()
-        else if (handler == "multiply") multiply()
-        else if (handler == "divide") divide()
-        else if (handler == "dup") dup()
-        else if (handler == "over") over()
-        else if (handler == "swap") swap()
-        else if (handler == "print_top") print_top()
-        else if (handler == "less_than") less_than()
-        else if (handler == "greater_than") greater_than()
-        else if (handler == "rot") rot()
-        else if (handler == "drop") drop()
-        else if (handler == "nip") nip()
-        else if (handler == "tuck") tuck()
-        else if (handler == "roll") roll()
-        else if (handler == "pick") pick()
-        else if (handler == "negate") negate()
-        else if (handler == "abs") abs()
-        else if (handler == "max") max()
-        else if (handler == "min") min()
-        else if (handler == "mod") mod()
-        else if (handler == "equals") equals()
-        else if (handler == "handle_if") handle_if()
-        else if (handler == "handle_then") handle_then()
-        else if (handler == "handle_else") handle_else()
-        else {
-            print "Error: Handler '" handler "' not implemented"
-            return 0
-        }
-        return 1
+function compare_gt() {
+    if (stack_ptr < 2) {
+        print "Error: Stack underflow"
+        return
     }
-    return 0
+    b = pop()
+    a = pop()
+    push(a > b ? -1 : 0)
 }
 
-# Process each line of input
-{
-    if (NF > 0) {
-        # Remove comments and normalize whitespace
-        gsub(/\(.*\)/, "")
-        gsub(/^[[:space:]]+/, "")
-        gsub(/[[:space:]]+$/, "")
-        gsub(/[[:space:]]+/, " ")
+# New function to handle exiting the program
+function exit_program() {
+    print "Exiting program."
+    exit 0
+}
 
-        # Process each token
-        for (i = 1; i <= NF; i++) {
-            if ($i ~ /^-?[0-9]+$/) {
-                push($i)
-            } else if ($i in words) {
-                if (!execute_word($i)) {
-                    print "Error: Failed to execute word '" $i "'"
-                }
-            } else {
-                print "Error: Unknown word '" $i "'"
-            }
-        }
+# New function to list all available words
+function list_words() {
+    print "Available words:"
+    for (w in dict) {
+        print w
     }
 }
\ No newline at end of file
diff --git a/awk/forth/old/f.awk b/awk/forth/old/f.awk
new file mode 100755
index 0000000..eed9774
--- /dev/null
+++ b/awk/forth/old/f.awk
@@ -0,0 +1,344 @@
+#!/usr/bin/awk -f
+
+# Forth interpreter in AWK
+
+BEGIN {
+    print "Welcome to the AWK Forth Interpreter!"
+    print "Type your commands below. Use 'bye' to quit."
+    # Initialize variables
+    top = -1  # Initialize stack pointer
+    
+    # Initialize the dictionary with basic words
+    words["+"] = "+"
+    words["-"] = "-"
+    words["*"] = "*"
+    words["/"] = "/"
+    words["dup"] = "dup"
+    words["over"] = "over"
+    words["swap"] = "swap"
+    words["."] = "."
+    words["bye"] = "bye"
+    words["rot"] = "rot"
+    words["drop"] = "drop"
+    words["nip"] = "nip"
+    words["tuck"] = "tuck"
+    words["roll"] = "roll"
+    words["pick"] = "pick"
+    words["negate"] = "negate"
+    words["abs"] = "abs"
+    words["max"] = "max"
+    words["min"] = "min"
+    words["mod"] = "mod"
+    words["="] = "="
+    words["see"] = "see"
+    words["if"] = "if"
+    words["then"] = "then"
+    words["else"] = "else"
+    words[">"] = ">"
+    words["<"] = "<"
+    
+    # Add handlers for all words
+    handlers["+"] = "add"
+    handlers["-"] = "subtract"
+    handlers["*"] = "multiply"
+    handlers["/"] = "divide"
+    handlers["dup"] = "dup"
+    handlers["over"] = "over"
+    handlers["swap"] = "swap"
+    handlers["."] = "print_top"
+    handlers["<"] = "less_than"
+    handlers[">"] = "greater_than"
+    handlers["rot"] = "rot"
+    handlers["drop"] = "drop"
+    handlers["nip"] = "nip"
+    handlers["tuck"] = "tuck"
+    handlers["roll"] = "roll"
+    handlers["pick"] = "pick"
+    handlers["negate"] = "negate"
+    handlers["abs"] = "abs"
+    handlers["max"] = "max"
+    handlers["min"] = "min"
+    handlers["mod"] = "mod"
+    handlers["="] = "equals"
+    handlers["if"] = "handle_if"
+    handlers["then"] = "handle_then"
+    handlers["else"] = "handle_else"
+    handlers["bye"] = "bye"
+    handlers["see"] = "see"
+
+    # Add descriptions for words
+    desc["+"] = "( n1 n2 -- sum ) Add top two numbers"
+    desc["-"] = "( n1 n2 -- diff ) Subtract top number from second"
+    desc["*"] = "( n1 n2 -- prod ) Multiply top two numbers"
+    desc["/"] = "( n1 n2 -- quot ) Divide second by top"
+    desc["dup"] = "( n -- n n ) Duplicate top of stack"
+    desc["over"] = "( n1 n2 -- n1 n2 n1 ) Copy second item to top"
+    desc["swap"] = "( n1 n2 -- n2 n1 ) Swap top two items"
+    desc["rot"] = "( n1 n2 n3 -- n2 n3 n1 ) Rotate top three items"
+    desc["drop"] = "( n -- ) Discard top item"
+    desc["nip"] = "( n1 n2 -- n2 ) Remove second item"
+    desc["tuck"] = "( n1 n2 -- n2 n1 n2 ) Copy top item below second"
+    desc["roll"] = "( nk ... n1 n0 k -- nk-1 ... n1 n0 nk ) Move kth item to top"
+    desc["pick"] = "( nk ... n1 n0 k -- nk ... n1 n0 nk ) Copy kth item to top"
+    desc["negate"] = "( n -- -n ) Negate number"
+    desc["abs"] = "( n -- |n| ) Absolute value"
+    desc["max"] = "( n1 n2 -- max ) Maximum of top two numbers"
+    desc["min"] = "( n1 n2 -- min ) Minimum of top two numbers"
+    desc["mod"] = "( n1 n2 -- rem ) Remainder of n1/n2"
+    desc["="] = "( n1 n2 -- flag ) Test if equal, leaves 1 if true, 0 if false"
+    desc["if"] = "( flag -- ) Begin conditional execution"
+    desc["then"] = "( -- ) End conditional execution"
+    desc["else"] = "( -- ) Execute if previous condition was false"
+    desc[">"] = "( n1 n2 -- flag ) Returns true if n1 is greater than n2"
+    desc["<"] = "( n1 n2 -- flag ) Returns true if n1 is less than n2"
+    desc["bye"] = "( -- ) Exit the interpreter"
+    desc["see"] = "( -- ) Show definition of a word"
+
+    # Initialize condition stack
+    cond_top = -1
+
+    # Mark these as compile-only words
+    compile_only["if"] = 1
+    compile_only["then"] = 1
+    compile_only["else"] = 1
+}
+
+# Stack operations
+function push(value) {
+    stack[++top] = value
+}
+
+function pop() {
+    if (top < 0) {
+        print "Error: Stack underflow"
+        return 0
+    }
+    return stack[top--]
+}
+
+function check_stack(min_items, error_msg) {
+    if (top < min_items - 1) {
+        print error_msg ? error_msg : "Error: Not enough values on stack"
+        return 0
+    }
+    return 1
+}
+
+# Binary operations
+function binary_op(operation) {
+    if (!check_stack(2)) return
+    second = pop()
+    first = pop()
+    if (operation == "+") push(first + second)
+    else if (operation == "-") push(first - second)
+    else if (operation == "*") push(first * second)
+    else if (operation == "/") {
+        if (second == 0) {
+            print "Error: Division by zero"
+            push(first)
+            push(second)
+            return
+        }
+        push(first / second)
+    }
+    else if (operation == "mod") push(first % second)
+    else if (operation == "=") push(first == second ? 1 : 0)
+    else if (operation == "<") push(first < second ? 1 : 0)
+    else if (operation == ">") push(first > second ? 1 : 0)
+}
+
+# Handler functions
+function add() { binary_op("+") }
+function subtract() { binary_op("-") }
+function multiply() { binary_op("*") }
+function divide() { binary_op("/") }
+function mod() { binary_op("mod") }
+function equals() { binary_op("=") }
+function less_than() { binary_op("<") }
+function greater_than() { binary_op(">") }
+
+function dup() {
+    if (!check_stack(1)) return
+    push(stack[top])
+}
+
+function over() {
+    if (!check_stack(2)) return
+    push(stack[top - 1])
+}
+
+function swap() {
+    if (!check_stack(2)) return
+    temp = pop()
+    second = pop()
+    push(temp)
+    push(second)
+}
+
+function rot() {
+    if (!check_stack(3)) return
+    third = pop()
+    second = pop()
+    first = pop()
+    push(second)
+    push(third)
+    push(first)
+}
+
+function drop() {
+    if (!check_stack(1)) return
+    top--
+}
+
+function nip() {
+    if (!check_stack(2)) return
+    temp = stack[top]
+    drop()
+    drop()
+    push(temp)
+}
+
+function tuck() {
+    if (!check_stack(2)) return
+    temp = pop()
+    second = pop()
+    push(temp)
+    push(second)
+    push(temp)
+}
+
+function roll() {
+    if (!check_stack(1)) return
+    n = int(pop())
+    if (!check_stack(n)) return
+    if (n <= 0) return
+
+    temp = stack[top - n + 1]
+    for (i = top - n + 1; i < top; i++) {
+        stack[i] = stack[i + 1]
+    }
+    stack[top] = temp
+}
+
+function pick() {
+    if (!check_stack(1)) return
+    n = int(pop())
+    if (!check_stack(n)) return
+    if (n < 0) return
+    push(stack[top - n])
+}
+
+function negate() {
+    if (!check_stack(1)) return
+    push(-pop())
+}
+
+function abs() {
+    if (!check_stack(1)) return
+    n = pop()
+    push(n < 0 ? -n : n)
+}
+
+function max() {
+    if (!check_stack(2)) return
+    b = pop()
+    a = pop()
+    push(a > b ? a : b)
+}
+
+function min() {
+    if (!check_stack(2)) return
+    b = pop()
+    a = pop()
+    push(a < b ? a : b)
+}
+
+function print_top() {
+    if (!check_stack(1)) return
+    print stack[top]
+    drop()
+}
+
+function bye() {
+    exit
+}
+
+function see(word) {
+    if (!(word in words)) {
+        print "Error: Word '" word "' not found"
+        return
+    }
+    if (word in desc) {
+        print desc[word]
+    }
+    if (word in raw_definitions) {
+        print ": " word " " raw_definitions[word] " ;"
+    }
+}
+
+# Main processing function
+function execute_word(word) {
+    if (word in handlers) {
+        handler = handlers[word]
+        if (handler == "bye") exit
+        else if (handler == "see") {
+            if (i + 1 <= NF) see($(++i))
+            else print "Error: see requires a word name"
+        }
+        else if (handler == "add") add()
+        else if (handler == "subtract") subtract()
+        else if (handler == "multiply") multiply()
+        else if (handler == "divide") divide()
+        else if (handler == "dup") dup()
+        else if (handler == "over") over()
+        else if (handler == "swap") swap()
+        else if (handler == "print_top") print_top()
+        else if (handler == "less_than") less_than()
+        else if (handler == "greater_than") greater_than()
+        else if (handler == "rot") rot()
+        else if (handler == "drop") drop()
+        else if (handler == "nip") nip()
+        else if (handler == "tuck") tuck()
+        else if (handler == "roll") roll()
+        else if (handler == "pick") pick()
+        else if (handler == "negate") negate()
+        else if (handler == "abs") abs()
+        else if (handler == "max") max()
+        else if (handler == "min") min()
+        else if (handler == "mod") mod()
+        else if (handler == "equals") equals()
+        else if (handler == "handle_if") handle_if()
+        else if (handler == "handle_then") handle_then()
+        else if (handler == "handle_else") handle_else()
+        else {
+            print "Error: Handler '" handler "' not implemented"
+            return 0
+        }
+        return 1
+    }
+    return 0
+}
+
+# Process each line of input
+{
+    if (NF > 0) {
+        # Remove comments and normalize whitespace
+        gsub(/\(.*\)/, "")
+        gsub(/^[[:space:]]+/, "")
+        gsub(/[[:space:]]+$/, "")
+        gsub(/[[:space:]]+/, " ")
+
+        # Process each token
+        for (i = 1; i <= NF; i++) {
+            if ($i ~ /^-?[0-9]+$/) {
+                push($i)
+            } else if ($i in words) {
+                if (!execute_word($i)) {
+                    print "Error: Failed to execute word '" $i "'"
+                }
+            } else {
+                print "Error: Unknown word '" $i "'"
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/awk/forth/test.forth b/awk/forth/old/test.forth
index a1f4f50..a1f4f50 100644
--- a/awk/forth/test.forth
+++ b/awk/forth/old/test.forth