diff options
author | elioat <elioat@tilde.institute> | 2025-01-02 08:22:55 -0500 |
---|---|---|
committer | elioat <elioat@tilde.institute> | 2025-01-02 08:22:55 -0500 |
commit | 2c154a34f478285680efeee7c15ba02116ee882d (patch) | |
tree | 2d56292f9a827352ade4ee114a2ee6fc93718384 /awk | |
parent | 9cb6522022901d118ce3afb1120c2e8456046154 (diff) | |
download | tour-2c154a34f478285680efeee7c15ba02116ee882d.tar.gz |
*
Diffstat (limited to 'awk')
-rwxr-xr-x | awk/forth/f.awk | 38 | ||||
-rw-r--r-- | awk/forth/test.forth | 63 |
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 ; |