mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-20 06:09:18 +02:00
fixing closures
This commit is contained in:
parent
b49a12e48b
commit
560cd92cec
1 changed files with 27 additions and 16 deletions
37
eval.c
37
eval.c
|
@ -605,33 +605,47 @@ void compile_general_app (sexp app, sexp context) {
|
|||
}
|
||||
|
||||
void compile_lambda (sexp lambda, sexp context) {
|
||||
sexp fv, ctx, flags, bc, len, ref, vec, prev_lambda, prev_fv;
|
||||
sexp fv, ls, ctx, flags, bc, len, ref, vec, prev_lambda, prev_fv;
|
||||
sexp_uint_t k;
|
||||
prev_lambda = sexp_context_lambda(context);
|
||||
prev_fv = sexp_lambdap(prev_lambda) ? sexp_lambda_fv(prev_lambda) : SEXP_NULL;
|
||||
fv = sexp_lambda_fv(lambda);
|
||||
ctx = sexp_new_context(sexp_context_stack(context));
|
||||
sexp_context_lambda(ctx) = lambda;
|
||||
/* box mutable vars */
|
||||
for (ls=sexp_lambda_sv(lambda); sexp_pairp(ls); ls=sexp_cdr(ls)) {
|
||||
k = sexp_list_index(sexp_lambda_params(lambda), sexp_car(ls));
|
||||
if (k >= 0) {
|
||||
emit(OP_LOCAL_REF, ctx);
|
||||
emit_word(k, ctx);
|
||||
emit_push(sexp_car(ls), ctx);
|
||||
emit(OP_CONS, ctx);
|
||||
emit(OP_LOCAL_SET, ctx);
|
||||
emit_word(k, ctx);
|
||||
emit(OP_DROP, ctx);
|
||||
}
|
||||
}
|
||||
compile_one(sexp_lambda_body(lambda), ctx);
|
||||
flags = sexp_make_integer(sexp_listp(sexp_lambda_params(lambda)) ? 0 : 1);
|
||||
len = sexp_length(sexp_lambda_params(lambda));
|
||||
bc = finalize_bytecode(ctx);
|
||||
if (sexp_nullp(fv)) {
|
||||
/* shortcut, no free vars */
|
||||
vec = sexp_make_vector(sexp_make_integer(0), SEXP_UNDEF);
|
||||
compile_lit(sexp_make_procedure(flags, len, bc, vec), context);
|
||||
} else {
|
||||
/* push the closed vars */
|
||||
emit_push(SEXP_UNDEF, context);
|
||||
emit_push(len, context);
|
||||
emit_push(sexp_length(fv), context);
|
||||
emit(OP_MAKE_VECTOR, context);
|
||||
sexp_context_depth(context)--;
|
||||
for (k=0; sexp_pairp(fv); fv=sexp_cdr(fv), k++) {
|
||||
ref = sexp_car(fv);
|
||||
compile_non_global_ref(sexp_ref_name(ref), sexp_ref_cell(ref),
|
||||
prev_lambda, prev_fv, context, 1);
|
||||
prev_lambda, prev_fv, context, 0);
|
||||
emit_push(sexp_make_integer(k), context);
|
||||
emit(OP_LOCAL_REF, context);
|
||||
emit_word(3, context);
|
||||
emit_word(-5, context);
|
||||
emit(OP_VECTOR_SET, context);
|
||||
emit(OP_DROP, context);
|
||||
sexp_context_depth(context)--;
|
||||
|
@ -647,7 +661,8 @@ void compile_lambda (sexp lambda, sexp context) {
|
|||
sexp insert_free_var (sexp x, sexp fv) {
|
||||
sexp name=sexp_ref_name(x), loc=sexp_ref_loc(x), ls;
|
||||
for (ls=fv; sexp_pairp(ls); ls=sexp_cdr(ls))
|
||||
if (name == sexp_caar(ls) && loc == sexp_cdar(ls))
|
||||
if ((name == sexp_ref_name(sexp_car(ls)))
|
||||
&& (loc == sexp_ref_loc(sexp_car(ls))))
|
||||
return fv;
|
||||
return sexp_cons(x, fv);
|
||||
}
|
||||
|
@ -785,10 +800,14 @@ sexp vm(sexp bc, sexp cp, sexp e, sexp* stack, sexp_sint_t top) {
|
|||
ip += sizeof(sexp);
|
||||
break;
|
||||
case OP_VECTOR_REF:
|
||||
if (! sexp_vectorp(_ARG1))
|
||||
sexp_raise("vector-ref: not a vector", sexp_list1(_ARG1));
|
||||
_ARG2 = sexp_vector_ref(_ARG1, _ARG2);
|
||||
top--;
|
||||
break;
|
||||
case OP_VECTOR_SET:
|
||||
if (! sexp_vectorp(_ARG1))
|
||||
sexp_raise("vector-set!: not a vector", sexp_list1(_ARG1));
|
||||
sexp_vector_set(_ARG1, _ARG2, _ARG3);
|
||||
_ARG3 = SEXP_UNDEF;
|
||||
top-=2;
|
||||
|
@ -1136,18 +1155,14 @@ sexp vm(sexp bc, sexp cp, sexp e, sexp* stack, sexp_sint_t top) {
|
|||
_ARG1 = (i == EOF) ? SEXP_EOF : sexp_make_character(i);
|
||||
break;
|
||||
case OP_RET:
|
||||
/* if (top<4) */
|
||||
/* goto end_loop; */
|
||||
fp = (sexp_sint_t) _ARG2;
|
||||
cp = _ARG3;
|
||||
ip = (unsigned char*) sexp_unbox_integer(_ARG4);
|
||||
i = sexp_unbox_integer(_ARG5);
|
||||
stack[top-i-5] = _ARG1;
|
||||
top = top-i-4;
|
||||
fprintf(stderr, "returning to %p (i=%ld)\n", ip, i);
|
||||
break;
|
||||
case OP_DONE:
|
||||
fprintf(stderr, "done!\n");
|
||||
goto end_loop;
|
||||
default:
|
||||
sexp_raise("unknown opcode", sexp_list1(sexp_make_integer(*(ip-1))));
|
||||
|
@ -1369,12 +1384,8 @@ int main (int argc, char **argv) {
|
|||
sexp_uint_t i, quit=0, init_loaded=0;
|
||||
|
||||
scheme_init();
|
||||
/* stack = (sexp*) sexp_alloc(sizeof(sexp) * INIT_STACK_SIZE); */
|
||||
env = make_standard_env();
|
||||
interaction_environment = env;
|
||||
/* bc = sexp_alloc_tagged(sexp_sizeof(bytecode)+16, SEXP_BYTECODE); */
|
||||
/* sexp_bytecode_length(bc) = 16; */
|
||||
/* i = 0; */
|
||||
context = sexp_new_context(NULL);
|
||||
emit_push(SEXP_UNDEF, context);
|
||||
emit(OP_DONE, context);
|
||||
|
|
Loading…
Add table
Reference in a new issue