diff options
-rwxr-xr-x | awk/scheme/scheme/bin/compiler.awk | 6 | ||||
-rwxr-xr-x | awk/scheme/scheme/bin/repl | 7 | ||||
-rwxr-xr-x | awk/scheme/scheme/bin/vm.awk | 142 |
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 |