about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2025-01-20 15:24:46 -0500
committerelioat <elioat@tilde.institute>2025-01-20 15:24:46 -0500
commit3efb47fd3d1eba1169fbfab957e8afd7ed8ce89d (patch)
treed3f3fbcfb5e3e9211a0fdbbddefa7f0ac279c743
parent9b52c8b8523f8c97b97a6808e93f752a4742272a (diff)
downloadtour-3efb47fd3d1eba1169fbfab957e8afd7ed8ce89d.tar.gz
-rwxr-xr-xawk/scheme/scheme/bin/compiler.awk6
-rwxr-xr-xawk/scheme/scheme/bin/repl7
-rwxr-xr-xawk/scheme/scheme/bin/vm.awk142
3 files changed, 135 insertions, 20 deletions
diff --git a/awk/scheme/scheme/bin/compiler.awk b/awk/scheme/scheme/bin/compiler.awk
index 615ee41..e7e8081 100755
--- a/awk/scheme/scheme/bin/compiler.awk
+++ b/awk/scheme/scheme/bin/compiler.awk
@@ -346,6 +346,10 @@ function compile_let(args,    bindings, body, binding_array, nbindings, i, var,
 }
 
 function compile_define(args,    name, params, body, param_array, nparams, i, paren_start, paren_end) {
+    # Set flag for global definition
+    print "PUSH_CONST B:1"
+    print "STORE from_define"  # Must match exactly what vm_store checks for
+    
     # Find the function name (everything up to the first space)
     i = index(args, " ")
     if (i == 0) error("Malformed define expression")
@@ -385,7 +389,7 @@ function compile_define(args,    name, params, body, param_array, nparams, i, pa
         }
         print "RETURN"
     } else {
-        # It's a variable definition
+        # Variable definition
         debug("Defining variable: " name " with value: " args)
         compile_expr(args)  # Compile the value
         print "STORE " name  # Store the variable
diff --git a/awk/scheme/scheme/bin/repl b/awk/scheme/scheme/bin/repl
index 7649a64..14a10cf 100755
--- a/awk/scheme/scheme/bin/repl
+++ b/awk/scheme/scheme/bin/repl
@@ -37,6 +37,7 @@ cleanup() {
     rm -rf "$TMPDIR"
     if [ "$1" != "keep_state" ]; then
         rm -f "$STATE_FILE"
+        rm -f "/tmp/scheme_vm.env"
     fi
 }
 trap "cleanup" EXIT
@@ -46,6 +47,12 @@ INPUT_FILE="$TMPDIR/input.scm"
 ASM_FILE="$TMPDIR/output.asm"
 DEBUG_FILE="$TMPDIR/debug.out"
 
+# Initialize/clear state files at REPL start
+if [ "$#" -eq 0 ]; then  # Only for interactive mode
+    : > "/tmp/scheme_vm.state"
+    : > "/tmp/scheme_vm.env"
+fi
+
 # Function to handle evaluation
 evaluate_expression() {
     local input="$1"
diff --git a/awk/scheme/scheme/bin/vm.awk b/awk/scheme/scheme/bin/vm.awk
index 41189be..cb2b992 100755
--- a/awk/scheme/scheme/bin/vm.awk
+++ b/awk/scheme/scheme/bin/vm.awk
@@ -62,6 +62,32 @@ BEGIN {
 
     # Global function storage
     delete FUNCTIONS  # Our own function storage array
+
+    # Environment persistence
+    ENV_STATE_FILE = "/tmp/scheme_vm.env"
+    if (PERSIST) {
+        debug("Loading environment state from: " ENV_STATE_FILE)
+        if ((getline line < ENV_STATE_FILE) >= 0) {
+            do {
+                if (line ~ /^ENV /) {
+                    sub(/^ENV /, "", line)
+                    name = line
+                    sub(/ .*$/, "", name)
+                    val = line
+                    sub(/^[^ ]+ /, "", val)
+                    
+                    debug("Loaded env var: " name " = " val)
+                    
+                    env_name[env_size] = name
+                    env_val[env_size] = val
+                    env_size++
+                }
+            } while ((getline line < ENV_STATE_FILE) > 0)
+            close(ENV_STATE_FILE)
+        }
+    }
+
+    normal_exit = 0  # Track if we exited normally via HALT
 }
 
 # Debug output function
@@ -277,8 +303,15 @@ function execute(instr) {
         print peek()
     }
     else if (op == "HALT") {
+        normal_exit = 1  # Mark that we're exiting normally
         if (stack_ptr > 0) {
-            print peek()
+            result = peek()
+        }
+        if (PERSIST) {
+            save_state()
+        }
+        if (result) {
+            print result
         }
         exit(0)
     }
@@ -318,25 +351,41 @@ END {
         execute(program[pc++])
     }
     
-    # Print final result if any and we haven't HALTed
-    if (stack_ptr > 0) {
-        print peek()
-    }
-
-    # Save state if persistence is enabled
-    if (PERSIST) {
-        debug("Saving state to: " STATE_FILE)
-        for (i = 0; i < func_size; i++) {
-            debug("Saving function: " func_name[i])
-            print "FUNC " func_name[i] " " func_code[i] > STATE_FILE
-        }
-        close(STATE_FILE)
+    # Only save state if we didn't halt normally
+    if (!normal_exit && PERSIST) {
+        save_state()
     }
 }
 
-# Add new VM operations
+# Modify vm_store to handle global variables more consistently
 function vm_store(name) {
     debug("Storing " peek() " as " name " at env_size: " env_size)
+    
+    # If this is from a define, mark it as global
+    if (lookup_no_error("from_define")) {  # Check if from_define is set
+        name = "__global_" name
+        # Clear the flag
+        for (i = env_size - 1; i >= 0; i--) {
+            if (env_name[i] == "from_define") {
+                env_size--  # Remove the flag
+                break
+            }
+        }
+        
+        # Remove any previous definition of this global
+        for (i = env_size - 1; i >= 0; i--) {
+            if (env_name[i] == name) {
+                # Shift everything down to remove the old definition
+                for (j = i; j < env_size - 1; j++) {
+                    env_name[j] = env_name[j + 1]
+                    env_val[j] = env_val[j + 1]
+                }
+                env_size--
+                break
+            }
+        }
+    }
+    
     # Store in current environment frame
     env_name[env_size] = name
     env_val[env_size] = peek()
@@ -348,16 +397,32 @@ function vm_store(name) {
 function vm_pop_env() {
     if (env_size <= 0) error("Environment underflow")
     debug("Popping environment at size: " env_size)
+    
+    # Don't pop if this is a global definition (from define)
+    if (env_name[env_size-1] ~ /^__global_/) {
+        debug("Keeping global definition: " env_name[env_size-1])
+        return
+    }
+    
     debug("Removing: " env_name[env_size-1] " = " env_val[env_size-1])
     env_size--
 }
 
-function vm_lookup(name,    i) {
+# Modify vm_lookup to be more explicit about global lookups
+function vm_lookup(name,    i, global_name) {
     debug("Looking up " name " in environment of size: " env_size)
     dump_env()
+    
+    # First try looking up with global prefix
+    global_name = "__global_" name
     for (i = env_size - 1; i >= 0; i--) {
+        if (env_name[i] == global_name) {
+            debug("Found global " name " = " env_val[i] " at position " i)
+            push(env_val[i])
+            return
+        }
         if (env_name[i] == name) {
-            debug("Found " name " = " env_val[i] " at position " i)
+            debug("Found local " name " = " env_val[i] " at position " i)
             push(env_val[i])
             return
         }
@@ -451,10 +516,49 @@ function vm_return() {
     }
 }
 
-# New helper function to dump environment state
+# Add debug function to dump environment in a more readable format
 function dump_env(    i) {
     debug("Environment dump:")
     for (i = 0; i < env_size; i++) {
-        debug("  " i ": " env_name[i] " = " env_val[i])
+        debug(sprintf("  %d: %s = %s", i, env_name[i], env_val[i]))
+    }
+}
+
+# Add flag for define statements
+function compile_define(args,    name, params, body, param_array, nparams, i, paren_start, paren_end) {
+    # Set flag to mark this as a global definition
+    print "PUSH_CONST B:1"  # Push true
+    print "STORE __from_define"
+    
+    # ... rest of existing compile_define function ...
+}
+
+# Add helper function for looking up without error
+function lookup_no_error(name,    i) {
+    for (i = env_size - 1; i >= 0; i--) {
+        if (env_name[i] == name) {
+            return 1
+        }
+    }
+    return 0
+}
+
+# Add new function to handle state saving
+function save_state() {
+    debug("Saving state to: " STATE_FILE)
+    for (i = 0; i < func_size; i++) {
+        debug("Saving function: " func_name[i])
+        print "FUNC " func_name[i] " " func_code[i] > STATE_FILE
+    }
+    close(STATE_FILE)
+
+    # Save environment state
+    debug("Saving environment state to: " ENV_STATE_FILE)
+    for (i = 0; i < env_size; i++) {
+        if (env_name[i] ~ /^__global_/) {  # Only save global variables
+            debug("Saving env var: " env_name[i] " = " env_val[i])
+            print "ENV " env_name[i] " " env_val[i] > ENV_STATE_FILE
+        }
     }
+    close(ENV_STATE_FILE)
 }
\ No newline at end of file