Fix lexical and dynamic binding
This commit is contained in:
+2
-1
@@ -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
@@ -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
@@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user