about summary refs log tree commit diff stats
path: root/awk
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2025-01-02 08:22:55 -0500
committerelioat <elioat@tilde.institute>2025-01-02 08:22:55 -0500
commit2c154a34f478285680efeee7c15ba02116ee882d (patch)
tree2d56292f9a827352ade4ee114a2ee6fc93718384 /awk
parent9cb6522022901d118ce3afb1120c2e8456046154 (diff)
downloadtour-2c154a34f478285680efeee7c15ba02116ee882d.tar.gz
*
Diffstat (limited to 'awk')
-rwxr-xr-xawk/forth/f.awk38
-rw-r--r--awk/forth/test.forth63
2 files changed, 67 insertions, 34 deletions
diff --git a/awk/forth/f.awk b/awk/forth/f.awk
index 4d59dfc..dd8baf4 100755
--- a/awk/forth/f.awk
+++ b/awk/forth/f.awk
@@ -133,7 +133,6 @@ function process_definition(definition) {
     # Split definition into words
     split(definition, def_words, " ")
     processed = ""
-    skip_level = 0
     in_string = 0
     string_content = ""
     
@@ -168,8 +167,6 @@ function process_definition(definition) {
             processed = processed " <else>"
         } else if (word == "then") {
             processed = processed " <then>"
-        } else if (word == ";") {
-            processed = processed " ;"
         } else {
             processed = processed " " word
         }
@@ -524,7 +521,8 @@ function handle_if() {
         print "Error: Stack underflow"
         return
     }
-    cond_stack[++cond_top] = pop()  # Save condition
+    # Save condition without consuming it
+    cond_stack[++cond_top] = (stack[top] != 0)
 }
 
 # Function to handle then statement
@@ -542,7 +540,7 @@ function handle_else() {
         print "Error: Unmatched else"
         return
     }
-    cond_stack[cond_top] = !cond_stack[cond_top]  # Invert condition
+    cond_stack[cond_top] = !cond_stack[cond_top]
 }
 
 # Move the main command processing into a function
@@ -565,7 +563,7 @@ function process_line() {
                 definition = definition " " $i
             }
             # If we don't find a semicolon, keep reading lines
-            while (definition !~ /;/) {
+            while (definition !~ /;$/) {  # Changed to match semicolon at end
                 if ((getline) <= 0) break
                 gsub(/\(.*\)/, "")  # Remove comments
                 gsub(/^[[:space:]]+/, "")
@@ -573,7 +571,7 @@ function process_line() {
                 definition = definition " " $0
             }
             # Remove the semicolon
-            sub(/[[:space:]]*;.*$/, "", definition)
+            sub(/[[:space:]]*;[[:space:]]*$/, "", definition)
             
             if (definition != "") {
                 define_word(word_name, definition)
@@ -695,24 +693,24 @@ function process_line() {
                             else if (command == "<if>") {
                                 handle_if()
                                 if (!cond_stack[cond_top]) {
+                                    drop()  # Now consume the condition value
                                     # Skip until matching then/else
                                     skip_level = 1
                                     while (skip_level > 0 && j < length(cmd)) {
                                         j++
-                                        if (cmd[j] == "<if>") {
-                                            skip_level++
-                                            print "DEBUG: Nested if, level=" skip_level
-                                        }
-                                        if (cmd[j] == "<then>") {
+                                        if (j >= length(cmd)) break
+                                        if (cmd[j] == "<if>") skip_level++
+                                        else if (cmd[j] == "<then>") {
                                             skip_level--
-                                            print "DEBUG: Found then, level=" skip_level
+                                            if (skip_level == 0) break
                                         }
-                                        if (cmd[j] == "<else>" && skip_level == 1) {
+                                        else if (cmd[j] == "<else>" && skip_level == 1) {
                                             skip_level = 0
-                                            print "DEBUG: Found matching else"
                                             break
                                         }
                                     }
+                                } else {
+                                    drop()  # Consume the condition value only after checking it
                                 }
                             }
                             else if (command == "<else>") {
@@ -722,8 +720,12 @@ function process_line() {
                                     skip_level = 1
                                     while (skip_level > 0 && j < length(cmd)) {
                                         j++
+                                        if (j >= length(cmd)) break
                                         if (cmd[j] == "<if>") skip_level++
-                                        if (cmd[j] == "<then>") skip_level--
+                                        else if (cmd[j] == "<then>") {
+                                            skip_level--
+                                            if (skip_level == 0) break
+                                        }
                                     }
                                 }
                             }
@@ -737,7 +739,9 @@ function process_line() {
                                     str = str (str == "" ? "" : " ") cmd[j]
                                     j++
                                 }
-                                print_string(str)
+                                if (cond_stack[cond_top] != 0) {  # Only print if inside a true condition
+                                    print_string(str)
+                                }
                                 j++  # Skip past </string>
                             }
                             else if (words[command] == "<") less_than()
diff --git a/awk/forth/test.forth b/awk/forth/test.forth
index ef8a4c7..2d4197b 100644
--- a/awk/forth/test.forth
+++ b/awk/forth/test.forth
@@ -67,27 +67,56 @@ variable counter
 increment-counter
 counter @ test 6
 
-testing Conditionals - basic if/then
-: test-if-1 ( n -- ) 5 > if ." Greater than 5" then ;
-6 test-if-1 ( should print "Greater than 5" )
-4 test-if-1 ( should print nothing )
-
-testing Conditionals - if/else/then
-: test-if-2 ( n -- ) 5 > if ." Greater than 5" else ." Less than or equal to 5" then ;
-6 test-if-2 ( should print "Greater than 5" )
-4 test-if-2 ( should print "Less than or equal to 5" )
-
-testing Conditionals - nested if/then
-: test-if-3 ( n -- ) 
+testing Basic conditional - if/then
+: test-if-1 ( n -- n ) dup 5 > if ." Greater than 5" then ;
+6 test-if-1 test 6 ( should print "Greater than 5" and leave 6 )
+4 test-if-1 test 4 ( should print nothing and leave 4 )
+
+testing Basic conditional - if/else/then
+: test-if-2 ( n -- n ) dup 5 > if ." Greater" else ." Less=" then ;
+6 test-if-2 test 6 ( should print "Greater" and leave 6 )
+4 test-if-2 test 4 ( should print "Less=" and leave 4 )
+5 test-if-2 test 5 ( should print "Less=" and leave 5 )
+
+testing Nested conditionals
+: test-if-3 ( n -- n ) 
     dup 10 > if 
         dup 20 > if 
-            ." Greater than 20"
+            ." >20 "
         then
-        ." Greater than 10"
+        ." >10 "
     then ;
-25 test-if-3 ( should print "Greater than 20Greater than 10" )
-15 test-if-3 ( should print "Greater than 10" )
-5 test-if-3  ( should print nothing )
+25 test-if-3 test 25 ( should print ">20 >10 " and leave 25 )
+15 test-if-3 test 15 ( should print ">10 " and leave 15 )
+5 test-if-3 test 5   ( should print nothing and leave 5 )
+
+testing Conditional with stack operations
+: test-if-4 ( n -- n n ) 
+    dup 5 > if 
+        dup 
+    then ;
+6 test-if-4 swap test 6 test 6 ( should leave 6 6 )
+4 test-if-4 test 4 ( should leave just 4 )
+
+testing Complex nested conditionals
+: test-if-5 ( n -- n )
+    dup 0 < if
+        ." negative "
+    else
+        dup 100 > if
+            ." big "
+        else 
+            dup 50 > if
+                ." medium "
+            else
+                ." small "
+            then
+        then
+    then ;
+-5 test-if-5 test -5 ( should print "negative " )
+150 test-if-5 test 150 ( should print "big " )
+75 test-if-5 test 75 ( should print "medium " )
+25 test-if-5 test 25 ( should print "small " )
 
 testing Conditionals in word definitions
 : abs-test ( n -- |n| ) dup 0 < if negate then ;