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
|