Work on dynamic variable

This commit is contained in:
2026-07-19 02:23:10 -07:00
parent 67b68f8c61
commit f87af5efd2
11 changed files with 285 additions and 112 deletions
+34 -10
View File
@@ -131,10 +131,13 @@ static void store_local_reference_in_frame(StackFrame *restrict frame,
}
void add_local_reference_no_recurse(StackFrame *restrict frame, LispVal *obj) {
if (!OBJECTP(obj)) {
return;
}
frame = frame->last_references;
assert(frame->kind == STACK_FRAME_LOCAL_REFERENCES);
StackFrame *current_frame = OBJECT_LOWEST_LOCAL_REFERENCE(obj);
if (OBJECTP(obj) && (!current_frame || current_frame > frame)) {
if (!current_frame || current_frame > frame) {
store_local_reference_in_frame(frame, obj);
}
}
@@ -173,7 +176,8 @@ add_local_refs_for_object_sub_vals(StackFrame *restrict frame,
case TYPE_SYMBOL: {
LispSymbol *sym = val;
add_local_ref_if_not_seen_no_recurse(frame, seen_objs, sym->name);
add_local_ref_if_not_seen_no_recurse(frame, seen_objs, sym->value);
add_local_ref_if_not_seen_no_recurse(frame, seen_objs,
SYMBOL_VALUE(sym));
add_local_ref_if_not_seen_no_recurse(frame, seen_objs, sym->function);
add_local_ref_if_not_seen_no_recurse(frame, seen_objs, sym->plist);
break;
@@ -216,6 +220,9 @@ add_local_refs_for_object_sub_vals(StackFrame *restrict frame,
}
void add_local_reference(StackFrame *restrict frame, LispVal *obj) {
if (!OBJECTP(obj)) {
return;
}
frame = frame->last_references;
assert(frame->kind == STACK_FRAME_LOCAL_REFERENCES);
add_local_reference_no_recurse(frame, obj);
@@ -231,20 +238,37 @@ void add_local_reference(StackFrame *restrict frame, LispVal *obj) {
void push_dynamic_binding(LispVal *name, LispVal *new_value) {
assert(SYMBOLP(name));
LispVal *old_val = SYMBOL_VALUE(name);
SET_SYMBOL_VALUE(name, new_value); // will throw if name is const
StackFrame *frame = PUSH_NEW_FRAME(STACK_FRAME_DYNAMIC_BINDING);
frame->dynamic_binding.symbol = name;
if (name == Qlexical_environment) {
frame->dynamic_binding.old_value = Vlexical_environment;
Vlexical_environment = new_value;
} else {
frame->dynamic_binding.old_value = SYMBOL_VALUE(name);
SET_SYMBOL_VALUE(name, new_value);
}
frame->dynamic_binding.old_value = old_val;
}
void set_lexical_variable(LispVal *name, LispVal *value) {
assert(SYMBOLP(name));
Vlexical_environment = Fplist_put(Vlexical_environment, name, value);
if (CONST_VALUE_P(name)) {
// TODO throw
abort();
}
if (DYNAMIC_SYMBOL_P(name)) {
SET_SYMBOL_VALUE(name, value);
} else {
Vlexical_environment = Fplist_put(Vlexical_environment, name, value);
}
}
void new_lexical_variable(LispVal *name, LispVal *value) {
assert(SYMBOLP(name));
if (CONST_VALUE_P(name)) {
// TODO throw
abort();
}
if (DYNAMIC_SYMBOL_P(name)) {
SET_SYMBOL_VALUE(name, value);
} else {
Vlexical_environment = CONS(name, CONS(value, Vlexical_environment));
}
}
void unwind_to(StackFrame *frame) {