Work on dynamic variable
This commit is contained in:
+34
-10
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user