All tests passing except 'apply', which is genuinely broken; I'm not yet sure
what's wrong.
This commit is contained in:
parent
f988147bb2
commit
ba4a31c25a
|
@ -90,9 +90,9 @@ void make_cons_page( ) {
|
||||||
|
|
||||||
initialised_cons_pages++;
|
initialised_cons_pages++;
|
||||||
} else {
|
} else {
|
||||||
fprintf( stderr,
|
fwprintf( stderr,
|
||||||
"FATAL: Failed to allocate memory for cons page %d\n",
|
L"FATAL: Failed to allocate memory for cons page %d\n",
|
||||||
initialised_cons_pages );
|
initialised_cons_pages );
|
||||||
exit( 1 );
|
exit( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ void make_cons_page( ) {
|
||||||
*/
|
*/
|
||||||
void dump_pages( FILE * output ) {
|
void dump_pages( FILE * output ) {
|
||||||
for ( int i = 0; i < initialised_cons_pages; i++ ) {
|
for ( int i = 0; i < initialised_cons_pages; i++ ) {
|
||||||
fprintf( output, "\nDUMPING PAGE %d\n", i );
|
fwprintf( output, L"\nDUMPING PAGE %d\n", i );
|
||||||
|
|
||||||
for ( int j = 0; j < CONSPAGESIZE; j++ ) {
|
for ( int j = 0; j < CONSPAGESIZE; j++ ) {
|
||||||
dump_object( output, ( struct cons_pointer ) {
|
dump_object( output, ( struct cons_pointer ) {
|
||||||
|
@ -123,19 +123,21 @@ void free_cell( struct cons_pointer pointer ) {
|
||||||
|
|
||||||
if ( !check_tag( pointer, FREETAG ) ) {
|
if ( !check_tag( pointer, FREETAG ) ) {
|
||||||
if ( cell->count == 0 ) {
|
if ( cell->count == 0 ) {
|
||||||
|
fwprintf( stderr, L"Freeing cell\n" );
|
||||||
|
dump_object( stderr, pointer );
|
||||||
strncpy( &cell->tag.bytes[0], FREETAG, 4 );
|
strncpy( &cell->tag.bytes[0], FREETAG, 4 );
|
||||||
cell->payload.free.car = NIL;
|
cell->payload.free.car = NIL;
|
||||||
cell->payload.free.cdr = freelist;
|
cell->payload.free.cdr = freelist;
|
||||||
freelist = pointer;
|
freelist = pointer;
|
||||||
} else {
|
} else {
|
||||||
fprintf( stderr,
|
fwprintf( stderr,
|
||||||
"Attempt to free cell with %d dangling references at page %d, offset %d\n",
|
L"Attempt to free cell with %d dangling references at page %d, offset %d\n",
|
||||||
cell->count, pointer.page, pointer.offset );
|
cell->count, pointer.page, pointer.offset );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf( stderr,
|
fwprintf( stderr,
|
||||||
"Attempt to free cell which is already FREE at page %d, offset %d\n",
|
L"Attempt to free cell which is already FREE at page %d, offset %d\n",
|
||||||
pointer.page, pointer.offset );
|
pointer.page, pointer.offset );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,12 +168,12 @@ struct cons_pointer allocate_cell( char *tag ) {
|
||||||
cell->payload.cons.cdr = NIL;
|
cell->payload.cons.cdr = NIL;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf( stderr,
|
fwprintf( stderr,
|
||||||
"Allocated cell of type '%s' at %d, %d \n", tag,
|
L"Allocated cell of type '%s' at %d, %d \n", tag,
|
||||||
result.page, result.offset );
|
result.page, result.offset );
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
fprintf( stderr, "WARNING: Allocating non-free cell!" );
|
fwprintf( stderr, L"WARNING: Allocating non-free cell!" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,9 +80,8 @@ void dump_object( FILE * output, struct cons_pointer pointer ) {
|
||||||
L"\t\tCons cell: car at page %d offset %d, cdr at page %d offset %d, count %u\n",
|
L"\t\tCons cell: car at page %d offset %d, cdr at page %d offset %d, count %u\n",
|
||||||
cell.payload.cons.car.page,
|
cell.payload.cons.car.page,
|
||||||
cell.payload.cons.car.offset,
|
cell.payload.cons.car.offset,
|
||||||
cell.payload.cons.cdr.page,
|
cell.payload.cons.cdr.page,
|
||||||
cell.payload.cons.cdr.offset,
|
cell.payload.cons.cdr.offset, cell.count );
|
||||||
cell.count);
|
|
||||||
break;
|
break;
|
||||||
case INTEGERTV:
|
case INTEGERTV:
|
||||||
fwprintf( output,
|
fwprintf( output,
|
||||||
|
@ -102,8 +101,7 @@ void dump_object( FILE * output, struct cons_pointer pointer ) {
|
||||||
L"\t\tString cell: character '%1c' (%1d) next at page %2d offset %3d, count %u\n",
|
L"\t\tString cell: character '%1c' (%1d) next at page %2d offset %3d, count %u\n",
|
||||||
cell.payload.string.character,
|
cell.payload.string.character,
|
||||||
cell.payload.string.cdr.page,
|
cell.payload.string.cdr.page,
|
||||||
cell.payload.string.cdr.offset,
|
cell.payload.string.cdr.offset, cell.count );
|
||||||
cell.count );
|
|
||||||
fwprintf( output, L"\t\t value: " );
|
fwprintf( output, L"\t\t value: " );
|
||||||
print( output, pointer );
|
print( output, pointer );
|
||||||
fwprintf( output, L"\n" );
|
fwprintf( output, L"\n" );
|
||||||
|
@ -113,8 +111,7 @@ void dump_object( FILE * output, struct cons_pointer pointer ) {
|
||||||
L"\t\tSymbol cell: character '%1c' (%1d) next at page %2d offset %3d, count %u\n",
|
L"\t\tSymbol cell: character '%1c' (%1d) next at page %2d offset %3d, count %u\n",
|
||||||
cell.payload.string.character,
|
cell.payload.string.character,
|
||||||
cell.payload.string.cdr.page,
|
cell.payload.string.cdr.page,
|
||||||
cell.payload.string.cdr.offset,
|
cell.payload.string.cdr.offset, cell.count );
|
||||||
cell.count );
|
|
||||||
fwprintf( output, L"\t\t value:" );
|
fwprintf( output, L"\t\t value:" );
|
||||||
print( output, pointer );
|
print( output, pointer );
|
||||||
fwprintf( output, L"\n" );
|
fwprintf( output, L"\n" );
|
||||||
|
@ -208,8 +205,7 @@ struct cons_pointer make_symbol( wint_t c, struct cons_pointer tail ) {
|
||||||
*/
|
*/
|
||||||
struct cons_pointer
|
struct cons_pointer
|
||||||
make_special( struct cons_pointer src, struct cons_pointer ( *executable )
|
make_special( struct cons_pointer src, struct cons_pointer ( *executable )
|
||||||
( struct stack_frame * frame,
|
( struct stack_frame * frame, struct cons_pointer env ) ) {
|
||||||
struct cons_pointer env ) ) {
|
|
||||||
struct cons_pointer pointer = allocate_cell( SPECIALTAG );
|
struct cons_pointer pointer = allocate_cell( SPECIALTAG );
|
||||||
struct cons_space_object *cell = &pointer2cell( pointer );
|
struct cons_space_object *cell = &pointer2cell( pointer );
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,7 @@ void bind_function( char *name, struct cons_pointer ( *executable )
|
||||||
}
|
}
|
||||||
|
|
||||||
void bind_special( char *name, struct cons_pointer ( *executable )
|
void bind_special( char *name, struct cons_pointer ( *executable )
|
||||||
( struct cons_pointer s_expr, struct cons_pointer env,
|
( struct stack_frame * frame, struct cons_pointer env ) ) {
|
||||||
struct stack_frame * frame ) ) {
|
|
||||||
deep_bind( c_string_to_lisp_symbol( name ),
|
deep_bind( c_string_to_lisp_symbol( name ),
|
||||||
make_special( NIL, executable ) );
|
make_special( NIL, executable ) );
|
||||||
}
|
}
|
||||||
|
@ -87,6 +86,7 @@ int main( int argc, char *argv[] ) {
|
||||||
bind_function( "equal", &lisp_equal );
|
bind_function( "equal", &lisp_equal );
|
||||||
bind_function( "read", &lisp_read );
|
bind_function( "read", &lisp_read );
|
||||||
bind_function( "print", &lisp_print );
|
bind_function( "print", &lisp_print );
|
||||||
|
bind_function( "type", &lisp_type );
|
||||||
|
|
||||||
bind_function( "add", &lisp_add );
|
bind_function( "add", &lisp_add );
|
||||||
bind_function( "multiply", &lisp_multiply );
|
bind_function( "multiply", &lisp_multiply );
|
||||||
|
|
|
@ -80,6 +80,7 @@ eval_cons( struct stack_frame *frame, struct cons_pointer env ) {
|
||||||
|
|
||||||
struct stack_frame *fn_frame = make_empty_frame( frame, env );
|
struct stack_frame *fn_frame = make_empty_frame( frame, env );
|
||||||
fn_frame->arg[0] = c_car( frame->arg[0] );
|
fn_frame->arg[0] = c_car( frame->arg[0] );
|
||||||
|
inc_ref( fn_frame->arg[0] );
|
||||||
struct cons_pointer fn_pointer = lisp_eval( fn_frame, env );
|
struct cons_pointer fn_pointer = lisp_eval( fn_frame, env );
|
||||||
free_stack_frame( fn_frame );
|
free_stack_frame( fn_frame );
|
||||||
|
|
||||||
|
@ -187,6 +188,7 @@ lisp_apply( struct stack_frame *frame, struct cons_pointer env ) {
|
||||||
|
|
||||||
struct stack_frame *fn_frame = make_empty_frame( frame, env );
|
struct stack_frame *fn_frame = make_empty_frame( frame, env );
|
||||||
fn_frame->arg[0] = frame->arg[0];
|
fn_frame->arg[0] = frame->arg[0];
|
||||||
|
inc_ref( fn_frame->arg[0] );
|
||||||
struct cons_pointer fn_pointer = lisp_eval( fn_frame, env );
|
struct cons_pointer fn_pointer = lisp_eval( fn_frame, env );
|
||||||
free_stack_frame( fn_frame );
|
free_stack_frame( fn_frame );
|
||||||
|
|
||||||
|
@ -256,8 +258,7 @@ lisp_car( struct stack_frame *frame, struct cons_pointer env ) {
|
||||||
result = make_string( cell.payload.string.character, NIL );
|
result = make_string( cell.payload.string.character, NIL );
|
||||||
} else {
|
} else {
|
||||||
struct cons_pointer message =
|
struct cons_pointer message =
|
||||||
c_string_to_lisp_string
|
c_string_to_lisp_string( "Attempt to take CAR of non sequence" );
|
||||||
( "Attempt to take CAR of non sequence" );
|
|
||||||
result = lisp_throw( message, frame );
|
result = lisp_throw( message, frame );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,8 +282,7 @@ lisp_cdr( struct stack_frame *frame, struct cons_pointer env ) {
|
||||||
result = cell.payload.string.cdr;
|
result = cell.payload.string.cdr;
|
||||||
} else {
|
} else {
|
||||||
struct cons_pointer message =
|
struct cons_pointer message =
|
||||||
c_string_to_lisp_string
|
c_string_to_lisp_string( "Attempt to take CDR of non sequence" );
|
||||||
( "Attempt to take CDR of non sequence" );
|
|
||||||
result = lisp_throw( message, frame );
|
result = lisp_throw( message, frame );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,6 +333,7 @@ lisp_read( struct stack_frame *frame, struct cons_pointer env ) {
|
||||||
return read( input );
|
return read( input );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (print expr)
|
* (print expr)
|
||||||
* (print expr write-stream)
|
* (print expr write-stream)
|
||||||
|
@ -352,6 +353,27 @@ lisp_print( struct stack_frame *frame, struct cons_pointer env ) {
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Lisp type of the single argument.
|
||||||
|
* @param frame My stack frame.
|
||||||
|
* @param env My environment (ignored).
|
||||||
|
* @return As a Lisp string, the tag of the object which is the argument.
|
||||||
|
*/
|
||||||
|
struct cons_pointer
|
||||||
|
lisp_type( struct stack_frame *frame, struct cons_pointer env ) {
|
||||||
|
char *buffer = malloc( TAGLENGTH + 1 );
|
||||||
|
memset( buffer, 0, TAGLENGTH + 1 );
|
||||||
|
struct cons_space_object cell = pointer2cell( frame->arg[0] );
|
||||||
|
strncpy( buffer, cell.tag.bytes, TAGLENGTH );
|
||||||
|
|
||||||
|
struct cons_pointer result = c_string_to_lisp_string( buffer );
|
||||||
|
free( buffer );
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: make this do something sensible somehow.
|
* TODO: make this do something sensible somehow.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -48,6 +48,14 @@ struct cons_pointer lisp_read( struct stack_frame *frame,
|
||||||
struct cons_pointer env );
|
struct cons_pointer env );
|
||||||
struct cons_pointer lisp_print( struct stack_frame *frame,
|
struct cons_pointer lisp_print( struct stack_frame *frame,
|
||||||
struct cons_pointer env );
|
struct cons_pointer env );
|
||||||
|
/**
|
||||||
|
* Get the Lisp type of the single argument.
|
||||||
|
* @param frame My stack frame.
|
||||||
|
* @param env My environment (ignored).
|
||||||
|
* @return As a Lisp string, the tag of the object which is the argument.
|
||||||
|
*/
|
||||||
|
struct cons_pointer
|
||||||
|
lisp_type( struct stack_frame *frame, struct cons_pointer env );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* neither, at this stage, really
|
* neither, at this stage, really
|
||||||
|
|
|
@ -84,8 +84,8 @@ struct stack_frame *make_stack_frame( struct stack_frame *previous,
|
||||||
struct stack_frame *arg_frame = make_empty_frame( previous, env );
|
struct stack_frame *arg_frame = make_empty_frame( previous, env );
|
||||||
arg_frame->arg[0] = cell.payload.cons.car;
|
arg_frame->arg[0] = cell.payload.cons.car;
|
||||||
result->arg[i] = lisp_eval( arg_frame, env );
|
result->arg[i] = lisp_eval( arg_frame, env );
|
||||||
free_stack_frame( arg_frame );
|
|
||||||
inc_ref( result->arg[i] );
|
inc_ref( result->arg[i] );
|
||||||
|
free_stack_frame( arg_frame );
|
||||||
|
|
||||||
args = cell.payload.cons.cdr;
|
args = cell.payload.cons.cdr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
expected='1'
|
expected='1'
|
||||||
actual=`echo "(apply 'add '(1))"| target/psse 2> /dev/null | head -1`
|
actual=`echo "(apply add '(1))"| target/psse 2> /dev/null | head -1`
|
||||||
|
|
||||||
if [ "${expected}" = "${actual}" ]
|
if [ "${expected}" = "${actual}" ]
|
||||||
then
|
then
|
||||||
|
|
Loading…
Reference in a new issue