Fix lexical and dynamic binding

This commit is contained in:
2026-07-19 02:45:15 -07:00
parent f87af5efd2
commit 046b9b0c87
3 changed files with 20 additions and 12 deletions
+2 -1
View File
@@ -4,7 +4,8 @@
(print print-circular) (print print-circular)
(let ((print-circular nil)) (let ((print-circular nil)
(b t))
(test)) (test))
(print print-circular) (print print-circular)
+16 -9
View File
@@ -135,20 +135,27 @@ DEFSPECIAL(let, "let", (LispVal * bindings, LispVal *body),
"(bindings &rest body)", "") { "(bindings &rest body)", "") {
CHECK_LISTP(bindings); CHECK_LISTP(bindings);
StackFrame *stack_ref = LISP_STACK_REF(); StackFrame *stack_ref = LISP_STACK_REF();
LispVal *lexenv = Vlexical_environment;
DOLIST(binding, bindings) { DOLIST(binding, bindings) {
if (SYMBOLP(binding)) { if (CONSP(binding) && list_length_eq(binding, 2)) {
lexenv = CONS(binding, CONS(Qnil, lexenv)); if (!SYMBOLP(XCAR(binding))) {
} else if (CONSP(binding) && list_length_eq(binding, 2)) { // TODO better error
lexenv = CONS( abort();
FIRST(binding), }
CONS(Feval(SECOND(binding), Vlexical_environment), lexenv)); RPLACA(XCDR(binding), Feval(SECOND(binding), Vlexical_environment));
} else { } else if (!SYMBOLP(binding)) {
// TODO better error // TODO better error
abort(); abort();
} }
} }
push_dynamic_binding(Qlexical_environment, lexenv); push_copy_lexenv();
DOLIST(binding, bindings) {
// we already checked that all bindings are well formed
if (SYMBOLP(binding)) {
new_lexical_variable(binding, Qnil);
} else {
new_lexical_variable(FIRST(binding), SECOND(binding));
}
}
return UNWIND_AND_RETURN(stack_ref, Fprogn(body)); return UNWIND_AND_RETURN(stack_ref, Fprogn(body));
} }
+2 -2
View File
@@ -252,7 +252,7 @@ void set_lexical_variable(LispVal *name, LispVal *value) {
abort(); abort();
} }
if (DYNAMIC_SYMBOL_P(name)) { if (DYNAMIC_SYMBOL_P(name)) {
SET_SYMBOL_VALUE(name, value); push_dynamic_binding(name, value);
} else { } else {
Vlexical_environment = Fplist_put(Vlexical_environment, name, value); Vlexical_environment = Fplist_put(Vlexical_environment, name, value);
} }
@@ -265,7 +265,7 @@ void new_lexical_variable(LispVal *name, LispVal *value) {
abort(); abort();
} }
if (DYNAMIC_SYMBOL_P(name)) { if (DYNAMIC_SYMBOL_P(name)) {
SET_SYMBOL_VALUE(name, value); push_dynamic_binding(name, value);
} else { } else {
Vlexical_environment = CONS(name, CONS(value, Vlexical_environment)); Vlexical_environment = CONS(name, CONS(value, Vlexical_environment));
} }