Check in a second program, this time demonstrating basic I/O.

Also filter cycles and long byte-strings from print_value() output.
Added three new bytecodes to get the sizes of vectors, strings, and structs.
This commit is contained in:
Jesse D. McDonald 2009-11-18 22:46:23 -06:00
parent c1a0850bcf
commit 0e62641919
4 changed files with 131 additions and 13 deletions

84
cat.rla Normal file
View File

@ -0,0 +1,84 @@
;(lambda (pathname)
; (let [(fd (posix-open pathname O_RDONLY))]
; (let [(str (make-byte-string 128))]
; (let loop ()
; (let [(size (posix-read fd str (byte-string-size str)))]
; (posix-write 1 str size))
; (loop)))))
#S(#="lambda"
#(
0
#="posix-open"
#S(#="template"
; (lambda (fd)
; (letrec [(loop (lambda ()
; (let [(size (posix-read fd str (byte-string-size str)))]
; (posix-write 1 str size))
; (loop)))]
; (loop)))
#(
128
#S(#="template"
#(#="posix-read")
"\x80\x81\x83\xff" ; #(f0 f1 f3 ctx)
2
"\x00\x80\x29\x41\; (set! f0 (byte-string-size i1))
\x02\x80\x80\x00\; (set! f0 (cons f0 nil))
\x02\x80\x41\x80\; (set! f0 (cons i1 f0))
\x02\x80\x40\x80\; (set! f0 (cons i0 f0))
\x00\x81\x02\x42"; (set! f1 (unbox i2))
0x01 ; g1
0x80 ; f0
0x81 ; f1
0x43 ; i3
)
#S(#="template"
; (letrec [(loop (lambda ()
; (let [(size (posix-read fd str (byte-string-size str)))]
; (posix-write 1 str size))
; (loop)))]
; ...)
#(1 #="posix-write" 0)
"\x80\x81\x82\x40\x41" ; #(f0 f1 f2 i0 i1)
2
"\x00\x81\x03\xfd\; (set! f1 (car argv))
\x02\x80\x81\x00\; (set! f0 (cons f1 nil))
\x02\x80\x41\x80\; (set! f0 (cons i1 f0))
\x02\x80\x01\x80\; (set! f0 (cons g1 f0))
\x01\x81\x81\x03\; (set! f1 (eq? f1 g3))
\x80\x81\x00\x80\; (set! f0 (if f1 nil f0))
\x81\x81\x43\x02"; (set! f1 (if f1 i3 g2))
0x81 ; f1
0x80 ; f0
0x42 ; i2
0x44 ; i4
)
0
)
"\xfe\xff" ; i0=k, i1=ctx
5
"\x00\x80\x03\xfd\; (set! f0 (car argv))
\x04\x81\x01\x04\; (set! f1 (make-byte-string g1 g4))
\x00\x83\x18\x83\; (set! f3 (make-box f3))
\x00\x82\x1b\x02\; (set! f2 (lambda g2))
\x00\x84\x1b\x03\; (set! f4 (lambda g3))
\x40\x83\x84\x00"; (set-box! f3 f4)
0x82 ; f2
0x00 ; nil
0x40 ; i0
0x41 ; i1
)
)
#()
2
"\x02\x80\x01\x00\; (set! f0 (cons g1 nil))
\x00\x81\x03\xfd\; (set! f1 (car argv))
\x02\x80\x81\x80\; (set! f0 (cons f1 f0))
\x00\x81\x1b\x03"; (set! f1 (lambda g3))
0x02 ; g2
0x80 ; f0
0x81 ; f1
0xff ; ctx
)
; vim:set sw=2 expandtab syntax=:

View File

@ -33,6 +33,10 @@ unary-expr: up to 255, 1 out, 1 in
22 (set! out (fix- in)) ; two's complement / arithmetic negation 22 (set! out (fix- in)) ; two's complement / arithmetic negation
23 (set! out (float- in)) ; floating-point negation 23 (set! out (float- in)) ; floating-point negation
28 (set! out (vector-size in))
29 (set! out (byte-string-size in))
2a (set! out (struct-nslots in))
; ISO C floating-point ; ISO C floating-point
30 (set! out (acos in)) 30 (set! out (acos in))
31 (set! out (asin in)) 31 (set! out (asin in))

44
gc.c
View File

@ -911,8 +911,25 @@ void _release_assert(bool expr, const char *str, const char *file, int line)
} }
} }
void fprint_value(FILE *f, value_t v) typedef struct seen_value
{ {
value_t value;
struct seen_value *prev;
} seen_value_t;
static void _fprint_value(FILE *f, value_t v, seen_value_t *seen)
{
seen_value_t new_seen = { v, seen };
for (seen_value_t *sv = seen; sv; sv = sv->prev)
{
if (v == sv->value)
{
fputs("#<cycle>", f);
return;
}
}
if (v == NIL) if (v == NIL)
{ {
fputs("nil", f); fputs("nil", f);
@ -936,26 +953,26 @@ void fprint_value(FILE *f, value_t v)
else if (is_box(v)) else if (is_box(v))
{ {
fputs("#&", f); fputs("#&", f);
fprint_value(f, _get_box(v)->value); _fprint_value(f, _get_box(v)->value, &new_seen);
} }
else if (is_pair(v)) else if (is_pair(v))
{ {
fputc('(', f); fputc('(', f);
fprint_value(f, _get_pair(v)->car); _fprint_value(f, _get_pair(v)->car, &new_seen);
v = _get_pair(v)->cdr; v = _get_pair(v)->cdr;
while (is_pair(v)) while (is_pair(v))
{ {
fputc(' ', f); fputc(' ', f);
fprint_value(f, _get_pair(v)->car); _fprint_value(f, _get_pair(v)->car, &new_seen);
v = _get_pair(v)->cdr; v = _get_pair(v)->cdr;
} }
if (v != NIL) if (v != NIL)
{ {
fputs(" . ", f); fputs(" . ", f);
fprint_value(f, v); _fprint_value(f, v, &new_seen);
} }
fputc(')', f); fputc(')', f);
@ -967,7 +984,7 @@ void fprint_value(FILE *f, value_t v)
for (size_t i = 0; i < _get_vector(v)->size; ++i) for (size_t i = 0; i < _get_vector(v)->size; ++i)
{ {
if (i != 0) fputc(' ', f); if (i != 0) fputc(' ', f);
fprint_value(f, _get_vector(v)->elements[i]); _fprint_value(f, _get_vector(v)->elements[i], &new_seen);
} }
fputc(')', f); fputc(')', f);
@ -986,6 +1003,12 @@ void fprint_value(FILE *f, value_t v)
fputc(str->bytes[i], f); fputc(str->bytes[i], f);
else else
fprintf(f, "\\x%.2X", (int)str->bytes[i]); fprintf(f, "\\x%.2X", (int)str->bytes[i]);
if (i >= 20)
{
fputs("...", f);
break;
}
} }
fputc('"', f); fputc('"', f);
@ -1001,7 +1024,7 @@ void fprint_value(FILE *f, value_t v)
for (size_t i = 0; i < _get_struct(v)->nslots; ++i) for (size_t i = 0; i < _get_struct(v)->nslots; ++i)
{ {
fputc(' ', f); fputc(' ', f);
fprint_value(f, _get_struct(v)->slots[i]); _fprint_value(f, _get_struct(v)->slots[i], &new_seen);
} }
fputc(')', f); fputc(')', f);
@ -1009,7 +1032,7 @@ void fprint_value(FILE *f, value_t v)
else if (is_weak_box(v)) else if (is_weak_box(v))
{ {
fputs("#W&", f); fputs("#W&", f);
fprint_value(f, _get_weak_box(v)->value); _fprint_value(f, _get_weak_box(v)->value, &new_seen);
} }
else if (is_float(v)) else if (is_float(v))
{ {
@ -1025,6 +1048,11 @@ void fprint_value(FILE *f, value_t v)
} }
} }
void fprint_value(FILE *f, value_t v)
{
_fprint_value(f, v, NULL);
}
void fprint_gc_stats(FILE *f) void fprint_gc_stats(FILE *f)
{ {
if (gc_stats.collections > 0) if (gc_stats.collections > 0)

View File

@ -285,17 +285,16 @@ static void run_byte_code(interp_state_t *state)
switch (bytes[0]) switch (bytes[0])
{ {
case 0 ... 63: /* 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 64 ... 127: /* statement */ case 0x40 ... 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 128 ... 255: /* conditional */ case 0x80 ... 0xff: /* conditional */
set_output(state, bytes[0], set_output(state, bytes[0],
get_input(state, _get_boolean(get_input(state, bytes[1])) get_input(state, _get_boolean(get_input(state, bytes[1]))
? bytes[2] ? bytes[2] : bytes[3]));
: bytes[3]));
break; break;
} }
} }
@ -405,6 +404,9 @@ static value_t eval_unary_expression(interp_state_t *state, uint8_t subcode, uin
case 0x21: return fixnum_value(~get_fixnum(ST1)); case 0x21: return fixnum_value(~get_fixnum(ST1));
case 0x22: return fixnum_value(-get_fixnum(ST1)); case 0x22: return fixnum_value(-get_fixnum(ST1));
case 0x23: return make_float(-get_float(ST1)); case 0x23: return make_float(-get_float(ST1));
case 0x28: return fixnum_value(get_vector(ST1)->size);
case 0x29: return fixnum_value(get_byte_string(ST1)->size);
case 0x2a: return fixnum_value(get_struct(ST1)->nslots);
case 0x30: return make_float(acos(get_float(ST1))); case 0x30: return make_float(acos(get_float(ST1)));
case 0x31: return make_float(asin(get_float(ST1))); case 0x31: return make_float(asin(get_float(ST1)));
case 0x32: return make_float(atan(get_float(ST1))); case 0x32: return make_float(atan(get_float(ST1)));