Add bytecodes to skip the rest of a block based on a condition.
Should simplify error-handling and sequences of primitive tests. Also, automatically instantiate templates used in the tail-call lambda & cont'n fields.
This commit is contained in:
parent
6dd02a5d6e
commit
f542fa2bd5
|
|
@ -137,15 +137,19 @@ conditional: 1 out, 3 in
|
||||||
; 0x80 <= AA <= 0xf7 (f0-f119)
|
; 0x80 <= AA <= 0xf7 (f0-f119)
|
||||||
AA (set! AA (if in1 in2 in3)) ; in3 if in1 == #f, in2 otherwise
|
AA (set! AA (if in1 in2 in3)) ; in3 if in1 == #f, in2 otherwise
|
||||||
statement: up to 64 (40..7f), 3 in
|
statement: up to 64 (40..7f), 3 in
|
||||||
|
; unary statements
|
||||||
|
40 (goto-end-if in1)
|
||||||
|
41 (goto-end-unless in1)
|
||||||
|
|
||||||
; binary statements
|
; binary statements
|
||||||
40 (set-box! in in) ; box value
|
50 (set-box! in1 in2) ; box value
|
||||||
41 (set-car! in in) ; pair value
|
51 (set-car! in1 in2) ; pair value
|
||||||
42 (set-cdr! in in) ; pair value
|
52 (set-cdr! in1 in2) ; pair value
|
||||||
|
|
||||||
; ternary statements
|
; ternary statements
|
||||||
60 (vector-set! in in in) ; vector n value, 0 <= n < nelem
|
60 (vector-set! in1 in2 in3) ; vector n value, 0 <= n < nelem
|
||||||
61 (byte-string-set! in in in) ; string n value, 0 <= n < nbytes
|
61 (byte-string-set! in1 in2 in3) ; string n value, 0 <= n < nbytes
|
||||||
62 (struct-set! in in in) ; struct n value, 0 <= n < nslots
|
62 (struct-set! in1 in2 in3) ; struct n value, 0 <= n < nslots
|
||||||
|
|
||||||
in:
|
in:
|
||||||
nil (00000000) [g0, always NIL]
|
nil (00000000) [g0, always NIL]
|
||||||
|
|
|
||||||
27
interp.c
27
interp.c
|
|
@ -300,10 +300,18 @@ static void run_byte_code(interp_state_t *state)
|
||||||
|
|
||||||
switch (bytes[0])
|
switch (bytes[0])
|
||||||
{
|
{
|
||||||
|
bool cond;
|
||||||
case 0x00 ... 0x3f: /* expression */
|
case 0x00 ... 0x3f: /* expression */
|
||||||
set_output(state, bytes[1], eval_expression(state, bytes[0], bytes[2], bytes[3]));
|
set_output(state, bytes[1], eval_expression(state, bytes[0], bytes[2], bytes[3]));
|
||||||
break;
|
break;
|
||||||
case 0x40 ... 0x7f: /* statement */
|
case 0x40 ... 0x41: /* goto-end-if, goto-end-unless */
|
||||||
|
cond = _get_boolean(get_input(state, bytes[1]));
|
||||||
|
if ((bytes[0] & 1) ? !cond : cond)
|
||||||
|
{
|
||||||
|
goto break_for_loop;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x42 ... 0x7f: /* statement */
|
||||||
run_statement(state, bytes[0], bytes[1], bytes[2], bytes[3]);
|
run_statement(state, bytes[0], bytes[1], bytes[2], bytes[3]);
|
||||||
break;
|
break;
|
||||||
case 0x80 ... 0xff: /* conditional */
|
case 0x80 ... 0xff: /* conditional */
|
||||||
|
|
@ -313,6 +321,7 @@ static void run_byte_code(interp_state_t *state)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break_for_loop:
|
||||||
|
|
||||||
unregister_gc_root(&bc_root);
|
unregister_gc_root(&bc_root);
|
||||||
}
|
}
|
||||||
|
|
@ -326,6 +335,10 @@ static void perform_tail_call(interp_state_t *state)
|
||||||
new_ctx = get_input(state, get_fixnum(_LAMBDA_SLOT(state->lambda.value, CONTEXT)));
|
new_ctx = get_input(state, get_fixnum(_LAMBDA_SLOT(state->lambda.value, CONTEXT)));
|
||||||
new_k = get_input(state, get_fixnum(_LAMBDA_SLOT(state->lambda.value, CONTINUATION)));
|
new_k = get_input(state, get_fixnum(_LAMBDA_SLOT(state->lambda.value, CONTINUATION)));
|
||||||
|
|
||||||
|
/* If new lambda or continuation is a template, instantiate it here. */
|
||||||
|
new_lambda = make_lambda(state, new_lambda);
|
||||||
|
new_k = make_lambda(state, new_k);
|
||||||
|
|
||||||
state->lambda.value = new_lambda;
|
state->lambda.value = new_lambda;
|
||||||
state->argv.value = new_argv;
|
state->argv.value = new_argv;
|
||||||
state->ctx.value = new_ctx;
|
state->ctx.value = new_ctx;
|
||||||
|
|
@ -483,7 +496,11 @@ static value_t eval_unary_expression(interp_state_t *state, uint8_t subcode, uin
|
||||||
static void run_statement(interp_state_t *state, uint8_t code, uint8_t in1, uint8_t in2, uint32_t in3)
|
static void run_statement(interp_state_t *state, uint8_t code, uint8_t in1, uint8_t in2, uint32_t in3)
|
||||||
{
|
{
|
||||||
ST1 = get_input(state, in1);
|
ST1 = get_input(state, in1);
|
||||||
|
|
||||||
|
if (code >= 0x50)
|
||||||
|
{
|
||||||
ST2 = get_input(state, in2);
|
ST2 = get_input(state, in2);
|
||||||
|
}
|
||||||
|
|
||||||
if (code >= 0x60)
|
if (code >= 0x60)
|
||||||
{
|
{
|
||||||
|
|
@ -492,12 +509,14 @@ static void run_statement(interp_state_t *state, uint8_t code, uint8_t in1, uint
|
||||||
|
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
case 0x40: get_box(ST1)->value = ST2; WRITE_BARRIER(ST1); break;
|
/* 0x40 and 0x41 (goto-end-if, goto-end-unless) are handled by run_byte_code() directly. */
|
||||||
case 0x41: get_pair(ST1)->car = ST2; WRITE_BARRIER(ST1); break;
|
case 0x50: get_box(ST1)->value = ST2; WRITE_BARRIER(ST1); break;
|
||||||
case 0x42: get_pair(ST1)->cdr = ST2; WRITE_BARRIER(ST1); break;
|
case 0x51: get_pair(ST1)->car = ST2; WRITE_BARRIER(ST1); break;
|
||||||
|
case 0x52: get_pair(ST1)->cdr = ST2; WRITE_BARRIER(ST1); break;
|
||||||
case 0x60: vector_set(ST1, get_fixnum(ST2), ST3); break;
|
case 0x60: vector_set(ST1, get_fixnum(ST2), ST3); break;
|
||||||
case 0x61: byte_string_set(ST1, get_fixnum(ST2), (char)get_fixnum(ST3)); break;
|
case 0x61: byte_string_set(ST1, get_fixnum(ST2), (char)get_fixnum(ST3)); break;
|
||||||
case 0x62: struct_set(ST1, get_fixnum(ST2), ST3); break;
|
case 0x62: struct_set(ST1, get_fixnum(ST2), ST3); break;
|
||||||
|
default: release_assert(NOTREACHED("Invalid statement bytecode."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,20 +52,18 @@
|
||||||
"\x80"
|
"\x80"
|
||||||
2
|
2
|
||||||
"\x09\x80\x40\x01\; (set! f0 (fix- i0 g1))
|
"\x09\x80\x40\x01\; (set! f0 (fix- i0 g1))
|
||||||
\x02\x80\x80\x00\; (set! f0 (cons f0 nil))
|
\x02\x80\x80\x00"; (set! f0 (cons f0 nil))
|
||||||
\x00\x81\x1b\x02"; (set! f1 (lambda g2))
|
|
||||||
0x03 ; g3
|
0x03 ; g3
|
||||||
0x80 ; f0
|
0x80 ; f0
|
||||||
0xfe ; ctx
|
0xfe ; ctx
|
||||||
0x81 ; f1
|
0x02 ; g2
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
#()
|
#()
|
||||||
2
|
2
|
||||||
"\x00\x80\x03\xfd\; (set! f0 (car argv))
|
"\x00\x80\x03\xfd\; (set! f0 (car argv))
|
||||||
\x0d\x81\x80\x01\; (set! f1 (fix< f0 g1))
|
\x0d\x81\x80\x01\; (set! f1 (fix< f0 g1))
|
||||||
\x81\x81\x02\x03\; (set! f1 (if f1 g2 g3))
|
\x81\x81\x02\x03"; (set! f1 (if f1 g2 g3))
|
||||||
\x00\x81\x1b\x81"; (set! f1 (lambda f1))
|
|
||||||
0x81 ; f1
|
0x81 ; f1
|
||||||
0x00 ; nil
|
0x00 ; nil
|
||||||
0xfe ; ctx
|
0xfe ; ctx
|
||||||
|
|
|
||||||
|
|
@ -36,13 +36,12 @@
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
"\xff" ; k
|
"\xff" ; k
|
||||||
2
|
1
|
||||||
"\x00\x80\x03\xfd\; (set! f0 (car argv))
|
"\x00\x80\x03\xfd"; (set! f0 (car argv))
|
||||||
\x00\x81\x1b\x01"; (set! f1 (lambda g1))
|
|
||||||
0x80 ; f0
|
0x80 ; f0
|
||||||
0x00 ; nil
|
0x00 ; nil
|
||||||
0xfe ; ctx
|
0xfe ; ctx
|
||||||
0x81 ; f1
|
0x01 ; g1
|
||||||
)
|
)
|
||||||
#t
|
#t
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -13,17 +13,6 @@
|
||||||
; (lambda () (foldl fn (fn (car lst) init) (cdr lst))
|
; (lambda () (foldl fn (fn (car lst) init) (cdr lst))
|
||||||
; (lambda () init))))
|
; (lambda () init))))
|
||||||
#(
|
#(
|
||||||
#S(#="template"
|
|
||||||
; (lambda () init)
|
|
||||||
#(#f)
|
|
||||||
"\x81" ; f1
|
|
||||||
1
|
|
||||||
"\x02\x80\x40\x00"; (set! f0 (cons i0 nil))
|
|
||||||
0xff ; k
|
|
||||||
0x80 ; f0
|
|
||||||
0x01 ; g1
|
|
||||||
0x01 ; g1
|
|
||||||
)
|
|
||||||
#S(#="template"
|
#S(#="template"
|
||||||
; (lambda ()
|
; (lambda ()
|
||||||
; (let/cc k
|
; (let/cc k
|
||||||
|
|
@ -53,26 +42,39 @@
|
||||||
2
|
2
|
||||||
"\x02\x80\x41\x00\; (set! f0 (cons i1 nil))
|
"\x02\x80\x41\x00\; (set! f0 (cons i1 nil))
|
||||||
\x00\x81\x03\x42\; (set! f1 (car i2))
|
\x00\x81\x03\x42\; (set! f1 (car i2))
|
||||||
\x02\x80\x81\x80\; (set! f0 (cons f1 f0))
|
\x02\x80\x81\x80"; (set! f0 (cons f1 f0))
|
||||||
\x00\x81\x1b\x01"; (set! f1 (lambda g1))
|
|
||||||
0x40 ; i0
|
0x40 ; i0
|
||||||
0x80 ; f0
|
0x80 ; f0
|
||||||
0xfe ; ctx
|
0xfe ; ctx
|
||||||
0x81 ; f1
|
0x01 ; g1
|
||||||
|
)
|
||||||
|
#S(#="template"
|
||||||
|
; (lambda () init)
|
||||||
|
#(#f)
|
||||||
|
"\x81" ; f1
|
||||||
|
1
|
||||||
|
"\x02\x80\x40\x00"; (set! f0 (cons i0 nil))
|
||||||
|
0xff ; k
|
||||||
|
0x80 ; f0
|
||||||
|
0x01 ; g1
|
||||||
|
0x01 ; g1
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
#()
|
#()
|
||||||
4
|
6
|
||||||
"\x00\x80\x03\xfd\; (set! f0 (car argv)) ; f0=fn
|
"\x00\x80\x03\xfd\; (set! f0 (car argv)) ; f0=fn
|
||||||
\x00\x82\x04\xfd\; (set! f2 (cdr argv))
|
\x00\x82\x04\xfd\; (set! f2 (cdr argv))
|
||||||
\x00\x81\x03\x82\; (set! f1 (car f2)) ; f1=init
|
\x00\x81\x03\x82\; (set! f1 (car f2)) ; f1=init
|
||||||
\x00\x82\x04\x82\; (set! f2 (cdr f2))
|
\x00\x82\x04\x82\; (set! f2 (cdr f2))
|
||||||
\x00\x82\x03\x82\; (set! f2 (car f2)) ; f2=lst
|
\x00\x82\x03\x82\; (set! f2 (car f2)) ; f2=lst
|
||||||
|
\x00\x84\x01\x01\; (set! f4 g1)
|
||||||
|
\x00\x85\x01\x00\; (set! f5 nil)
|
||||||
\x00\x83\x0b\x82\; (set! f3 (pair? f2))
|
\x00\x83\x0b\x82\; (set! f3 (pair? f2))
|
||||||
\x83\x83\x02\x01\; (set! f3 (if f3 g2 g1))
|
\x40\x83\x00\x00\; (goto-end-if f3)
|
||||||
\x00\x83\x1b\x83"; (set! f0 (lambda f3))
|
\x00\x84\x01\xff\; (set! f4 k)
|
||||||
0x83 ; f0
|
\x02\x85\x81\x00"; (set! f5 (cons f1 nil))
|
||||||
0x00 ; nil
|
0x84 ; f4
|
||||||
|
0x85 ; f5
|
||||||
0xfe ; ctx
|
0xfe ; ctx
|
||||||
0xff ; k
|
0xff ; k
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -15,17 +15,6 @@
|
||||||
; (foldr fn init (cdr lst))))
|
; (foldr fn init (cdr lst))))
|
||||||
; (lambda () init))))
|
; (lambda () init))))
|
||||||
#(
|
#(
|
||||||
#S(#="template"
|
|
||||||
; (lambda () init)
|
|
||||||
#(#f)
|
|
||||||
"\x81" ; f1
|
|
||||||
1
|
|
||||||
"\x02\x80\x40\x00"; (set! f0 (cons i0 nil))
|
|
||||||
0xff ; k
|
|
||||||
0x80 ; f0
|
|
||||||
0x01 ; g1
|
|
||||||
0x01 ; g1
|
|
||||||
)
|
|
||||||
#S(#="template"
|
#S(#="template"
|
||||||
; (lambda ()
|
; (lambda ()
|
||||||
; (let/cc k
|
; (let/cc k
|
||||||
|
|
@ -50,31 +39,33 @@
|
||||||
#=0 ; foldr
|
#=0 ; foldr
|
||||||
)
|
)
|
||||||
"\x80\x81\x82" ; f0=fn f1=init f2=lst
|
"\x80\x81\x82" ; f0=fn f1=init f2=lst
|
||||||
4
|
3
|
||||||
"\x00\x80\x04\x42\; (set! f0 (cdr i2))
|
"\x00\x80\x04\x42\; (set! f0 (cdr i2))
|
||||||
\x00\x81\x03\x42\; (set! f1 (car i2))
|
\x00\x81\x03\x42\; (set! f1 (car i2))
|
||||||
\x00\x82\x1b\x01\; (set! f2 (lambda g1))
|
\x02\x82\x80\x00\; (set! f2 (cons f0 nil))
|
||||||
\x02\x83\x80\x00\; (set! f3 (cons f0 nil))
|
\x02\x82\x41\x82\; (set! f2 (cons i1 f2))
|
||||||
\x02\x83\x41\x83\; (set! f3 (cons i1 f3))
|
\x02\x82\x40\x82"; (set! f2 (cons i0 f2))
|
||||||
\x02\x83\x40\x83"; (set! f3 (cons i0 f3))
|
|
||||||
0x02 ; g2
|
0x02 ; g2
|
||||||
0x83 ; f3
|
|
||||||
0xfe ; ctx
|
|
||||||
0x82 ; f2
|
0x82 ; f2
|
||||||
|
0xfe ; ctx
|
||||||
|
0x01 ; g1
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
#()
|
#()
|
||||||
4
|
6
|
||||||
"\x00\x80\x03\xfd\; (set! f0 (car argv)) ; f0=fn
|
"\x00\x80\x03\xfd\; (set! f0 (car argv)) ; f0=fn
|
||||||
\x00\x82\x04\xfd\; (set! f2 (cdr argv))
|
\x00\x82\x04\xfd\; (set! f2 (cdr argv))
|
||||||
\x00\x81\x03\x82\; (set! f1 (car f2)) ; f1=init
|
\x00\x81\x03\x82\; (set! f1 (car f2)) ; f1=init
|
||||||
\x00\x82\x04\x82\; (set! f2 (cdr f2))
|
\x00\x82\x04\x82\; (set! f2 (cdr f2))
|
||||||
\x00\x82\x03\x82\; (set! f2 (car f2)) ; f2=lst
|
\x00\x82\x03\x82\; (set! f2 (car f2)) ; f2=lst
|
||||||
|
\x00\x84\x01\x01\; (set! f4 g1)
|
||||||
|
\x00\x85\x01\x00\; (set! f5 nil)
|
||||||
\x00\x83\x0b\x82\; (set! f3 (pair? f2))
|
\x00\x83\x0b\x82\; (set! f3 (pair? f2))
|
||||||
\x83\x83\x02\x01\; (set! f3 (if f3 g2 g1))
|
\x40\x83\x00\x00\; (goto-end-if f3)
|
||||||
\x00\x83\x1b\x83"; (set! f3 (lambda f3))
|
\x00\x84\x01\xff\; (set! f4 k)
|
||||||
0x83 ; f3
|
\x02\x85\x81\x00"; (set! f5 (cons f1 nil))
|
||||||
0x00 ; nil
|
0x84 ; f4
|
||||||
|
0x85 ; f5
|
||||||
0xfe ; ctx
|
0xfe ; ctx
|
||||||
0xff ; k
|
0xff ; k
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue