reintroducing dynamic opcode procedures

This commit is contained in:
Alex Shinn 2009-03-27 18:02:41 +09:00
parent c97ecdb501
commit ca62786e3e
3 changed files with 46 additions and 49 deletions

68
eval.c
View file

@ -32,6 +32,7 @@ static sexp analyze_app (sexp x, sexp context);
static sexp analyze_define (sexp x, sexp context);
static sexp analyze_var_ref (sexp x, sexp context);
static sexp analyze_set (sexp x, sexp context);
static sexp analyze_define_syntax (sexp x, sexp context);
static sexp_sint_t sexp_context_make_label (sexp context);
static void sexp_context_patch_label (sexp context, sexp_sint_t label);
@ -280,14 +281,18 @@ static sexp analyze (sexp x, sexp context) {
case CORE_QUOTE:
res = sexp_make_lit(sexp_cadr(x));
break;
case CORE_DEFINE_SYNTAX:
res = analyze_define_syntax(x, context);
break;
default:
res = sexp_compile_error("unknown core form", sexp_list1(op));
break;
}
} else if (sexp_macrop(op)) {
/* x = expand_macro(op, x, context); */
/* goto loop; */
res = sexp_compile_error("macros not yet supported", sexp_list1(x));
x = apply(sexp_macro_proc(op),
sexp_list3(x, sexp_context_env(context), sexp_macro_env(op)),
context);
goto loop;
} else if (sexp_opcodep(op)) {
res = analyze_app(sexp_cdr(x), context);
analyze_check_exception(res);
@ -396,6 +401,15 @@ static sexp analyze_set (sexp x, sexp context) {
return sexp_make_set(ref, value);
}
static sexp analyze_define_syntax (sexp x, sexp context) {
sexp name = sexp_cadr(x), cell, proc;
proc = eval_in_context(sexp_caddr(x), context);
analyze_check_exception(proc);
cell = env_cell_create(sexp_context_env(context), name, SEXP_UNDEF);
sexp_cdr(cell) = sexp_make_macro(proc, sexp_context_env(context));
return SEXP_UNDEF;
}
static sexp_sint_t sexp_context_make_label (sexp context) {
sexp_sint_t label = sexp_context_pos(context);
sexp_context_pos(context) += sizeof(sexp_uint_t);
@ -732,25 +746,24 @@ static sexp make_param_list(sexp_uint_t i) {
return res;
}
static sexp make_opcode_procedure(sexp op, sexp_uint_t i, sexp e) {
/* sexp bc, params, res; */
/* sexp_uint_t pos=0, d=0; */
/* if (i == sexp_opcode_num_args(op) && sexp_opcode_proc(op)) */
/* return sexp_opcode_proc(op); */
/* bc = sexp_alloc_tagged(sexp_sizeof(bytecode)+INIT_BCODE_SIZE, SEXP_BYTECODE); */
/* params = make_param_list(i); */
/* e = extend_env(e, params, SEXP_UNDEF); */
/* sexp_bytecode_length(bc) = INIT_BCODE_SIZE; */
/* analyze_opcode(op, sexp_cons(op, params), &bc, &pos, e, params, */
/* SEXP_NULL, SEXP_NULL, &d, 0); */
/* emit(&bc, &pos, OP_RET); */
/* shrink_bcode(&bc, pos); */
/* /\* disasm(bc); *\/ */
/* res = sexp_make_procedure(sexp_make_integer(0), sexp_make_integer(i), bc, SEXP_UNDEF); */
/* if (i == sexp_opcode_num_args(op)) */
/* sexp_opcode_proc(op) = res; */
/* return res; */
return SEXP_UNDEF;
static sexp make_opcode_procedure (sexp op, sexp_uint_t i, sexp env,
sexp *stack, sexp_sint_t top) {
sexp context, params, bc, res;
if (i == sexp_opcode_num_args(op) && sexp_opcode_proc(op))
return sexp_opcode_proc(op);
params = make_param_list(i);
context = sexp_new_context(stack);
sexp_context_top(context) = top;
sexp_context_env(context) = extend_env(env, params, SEXP_UNDEF);
generate_opcode_app(sexp_cons(op, params), context);
bc = finalize_bytecode(context);
res = sexp_make_procedure(sexp_make_integer(0),
sexp_make_integer(i),
bc,
SEXP_UNDEF);
if (i == sexp_opcode_num_args(op))
sexp_opcode_proc(op) = res;
return res;
}
/*********************** the virtual machine **************************/
@ -1032,7 +1045,7 @@ sexp vm(sexp bc, sexp cp, sexp e, sexp* stack, sexp_sint_t top) {
make_call:
if (sexp_opcodep(tmp1)) {
/* compile non-inlined opcode applications on the fly */
tmp1 = make_opcode_procedure(tmp1, i, e);
tmp1 = make_opcode_procedure(tmp1, i, e, stack, top);
if (sexp_exceptionp(tmp1)) {
_ARG1 = tmp1;
goto call_error_handler;
@ -1041,7 +1054,7 @@ sexp vm(sexp bc, sexp cp, sexp e, sexp* stack, sexp_sint_t top) {
if (! sexp_procedurep(tmp1))
sexp_raise("non procedure application", sexp_list1(tmp1));
j = i - sexp_unbox_integer(sexp_procedure_num_args(tmp1));
fprintf(stderr, "arg difference: %ld-%ld = %ld\n", i, sexp_unbox_integer(sexp_procedure_num_args(tmp1)), j);
fprintf(stderr, "\narg difference: %ld-%ld = %ld\n", i, sexp_unbox_integer(sexp_procedure_num_args(tmp1)), j);
if (j < 0)
sexp_raise("not enough args", sexp_list2(tmp1, sexp_make_integer(i)));
if (j > 0) {
@ -1338,9 +1351,10 @@ sexp make_standard_env () {
/* args ... n ret-ip ret-cp ret-fp */
sexp apply(sexp proc, sexp args, sexp context) {
sexp *stack = sexp_context_stack(context), ls;
sexp_sint_t top = sexp_context_top(context);
for (ls=args; sexp_pairp(ls); ls=sexp_cdr(ls))
stack[top++] = sexp_car(ls);
sexp_sint_t top = sexp_context_top(context), offset;
offset = top + sexp_unbox_integer(sexp_length(args));
for (ls=args; sexp_pairp(ls); ls=sexp_cdr(ls), top++)
stack[--offset] = sexp_car(ls);
stack[top] = sexp_make_integer(top);
top++;
stack[top++] = sexp_make_integer(sexp_bytecode_data(final_resumer));

19
eval.h
View file

@ -124,24 +124,7 @@ enum opcode_names {
/**************************** prototypes ******************************/
/* sexp compile(sexp params, sexp obj, sexp e, sexp fv, sexp sv, int done_p); */
/* sexp analyze_app(sexp obj, sexp *bc, sexp_uint_t *i, */
/* sexp e, sexp params, sexp fv, sexp sv, */
/* sexp_uint_t *d, int tailp); */
/* sexp analyze_lambda(sexp name, sexp formals, sexp body, */
/* sexp *bc, sexp_uint_t *i, sexp e, */
/* sexp params, sexp fv, sexp sv, sexp_uint_t *d, int tailp); */
/* void analyze_var_ref(sexp name, sexp *bc, sexp_uint_t *i, sexp e, */
/* sexp params, sexp fv, sexp sv, sexp_uint_t *d); */
/* sexp analyze_opcode(sexp op, sexp obj, sexp *bc, sexp_uint_t *i, sexp e, */
/* sexp params, sexp fv, sexp sv, sexp_uint_t *d, int tailp); */
/* sexp analyze(sexp obj, sexp *bc, sexp_uint_t *i, sexp e, */
/* sexp params, sexp fv, sexp sv, sexp_uint_t *d, int tailp); */
/* sexp analyze_sequence(sexp ls, sexp *bc, sexp_uint_t *i, sexp e, */
/* sexp params, sexp fv, sexp sv, sexp_uint_t *d, int tailp); */
/* sexp vm(sexp bc, sexp cp, sexp e, sexp* stack, sexp_sint_t top); */
sexp apply(sexp proc, sexp args, sexp context);
sexp eval_in_context(sexp expr, sexp context);
sexp eval(sexp expr, sexp env);

View file

@ -84,10 +84,10 @@
;; (append (map (lambda (x) (cons 'define x)) (cadr expr))
;; (cddr expr)))))))
;; (define-syntax let
;; (lambda (expr use-env mac-env)
;; (cons (cons 'lambda (cons (map car (cadr expr)) (cddr expr)))
;; (map cadr (cadr expr)))))
(define-syntax let
(lambda (expr use-env mac-env)
(cons (cons 'lambda (cons (map car (cadr expr)) (cddr expr)))
(map cadr (cadr expr)))))
;; (define-syntax or
;; (lambda (expr use-env mac-env)