Much better GC, still a few things being missed.

This commit is contained in:
Simon Brooke 2018-12-29 20:03:06 +00:00
parent 2ec5d37305
commit c21a762413
6 changed files with 55 additions and 15 deletions

2
.gitignore vendored
View file

@ -30,3 +30,5 @@ log*
\.settings/language\.settings\.xml \.settings/language\.settings\.xml
utils_src/readprintwc/out utils_src/readprintwc/out
*.dump

View file

@ -567,6 +567,7 @@ struct cons_pointer lisp_divide( struct
struct cons_pointer one = make_integer( 1 ); struct cons_pointer one = make_integer( 1 );
struct cons_pointer ratio = struct cons_pointer ratio =
make_ratio( frame_pointer, frame->arg[0], one ); make_ratio( frame_pointer, frame->arg[0], one );
inc_ref( ratio );
result = result =
divide_ratio_ratio( frame_pointer, ratio, divide_ratio_ratio( frame_pointer, ratio,
frame->arg[1] ); frame->arg[1] );

View file

@ -30,15 +30,35 @@
void bind_function( wchar_t *name, struct cons_pointer ( *executable ) void bind_function( wchar_t *name, struct cons_pointer ( *executable )
( struct stack_frame *, ( struct stack_frame *,
struct cons_pointer, struct cons_pointer ) ) { struct cons_pointer, struct cons_pointer ) ) {
deep_bind( c_string_to_lisp_symbol( name ), struct cons_pointer n = c_string_to_lisp_symbol( name );
make_function( NIL, executable ) ); inc_ref(n);
/* TODO: where a function is not compiled from source, we could cache
* the name on the source pointer. Would make stack frames potentially
* more readable and aid debugging generally. */
deep_bind( n, make_function( NIL, executable ) );
dec_ref(n);
} }
void bind_special( wchar_t *name, struct cons_pointer ( *executable ) void bind_special( wchar_t *name, struct cons_pointer ( *executable )
( struct stack_frame *, ( struct stack_frame *,
struct cons_pointer, struct cons_pointer ) ) { struct cons_pointer, struct cons_pointer ) ) {
deep_bind( c_string_to_lisp_symbol( name ), struct cons_pointer n = c_string_to_lisp_symbol( name );
make_special( NIL, executable ) ); inc_ref(n);
deep_bind( n, make_special( NIL, executable ) );
dec_ref(n);
}
void bind_value( wchar_t *name, struct cons_pointer value) {
struct cons_pointer n = c_string_to_lisp_symbol( name );
inc_ref(n);
deep_bind( n, value );
dec_ref(n);
} }
int main( int argc, char *argv[] ) { int main( int argc, char *argv[] ) {
@ -87,8 +107,8 @@ int main( int argc, char *argv[] ) {
/* /*
* privileged variables (keywords) * privileged variables (keywords)
*/ */
deep_bind( c_string_to_lisp_symbol( L"nil" ), NIL ); bind_value( L"nil" , NIL );
deep_bind( c_string_to_lisp_symbol( L"t" ), TRUE ); bind_value( L"t" , TRUE );
/* /*
* primitive function operations * primitive function operations
@ -139,8 +159,6 @@ int main( int argc, char *argv[] ) {
repl( stdin, stdout, stderr, show_prompt ); repl( stdin, stdout, stderr, show_prompt );
debug_print(L"Freeing oblist\n", DEBUG_BOOTSTRAP); debug_print(L"Freeing oblist\n", DEBUG_BOOTSTRAP);
debug_printf(DEBUG_BOOTSTRAP, L"Oblist has %u references\n", pointer2cell(oblist).count);
debug_dump_object(oblist, DEBUG_BOOTSTRAP);
dec_ref(oblist); dec_ref(oblist);
debug_dump_object(oblist, DEBUG_BOOTSTRAP); debug_dump_object(oblist, DEBUG_BOOTSTRAP);

View file

@ -145,6 +145,7 @@ void free_cell( struct cons_pointer pointer ) {
break; break;
case EXCEPTIONTV: case EXCEPTIONTV:
dec_ref( cell->payload.exception.message ); dec_ref( cell->payload.exception.message );
dec_ref( cell->payload.exception.frame );
break; break;
case FUNCTIONTV: case FUNCTIONTV:
dec_ref( cell->payload.function.source ); dec_ref( cell->payload.function.source );

View file

@ -198,7 +198,6 @@ eval_lambda( struct cons_space_object cell, struct stack_frame *frame,
debug_println(DEBUG_LAMBDA); debug_println(DEBUG_LAMBDA);
struct cons_pointer new_env = env; struct cons_pointer new_env = env;
inc_ref(new_env);
struct cons_pointer names = cell.payload.lambda.args; struct cons_pointer names = cell.payload.lambda.args;
struct cons_pointer body = cell.payload.lambda.body; struct cons_pointer body = cell.payload.lambda.body;
@ -214,6 +213,8 @@ eval_lambda( struct cons_space_object cell, struct stack_frame *frame,
names = c_cdr( names ); names = c_cdr( names );
} }
inc_ref(new_env);
/* TODO: if there's more than `args_in_frame` arguments, bind those too. */ /* TODO: if there's more than `args_in_frame` arguments, bind those too. */
} else if ( symbolp( names ) ) { } else if ( symbolp( names ) ) {
/* if `names` is a symbol, rather than a list of symbols, /* if `names` is a symbol, rather than a list of symbols,
@ -232,6 +233,7 @@ eval_lambda( struct cons_space_object cell, struct stack_frame *frame,
} }
new_env = bind( names, vals, new_env ); new_env = bind( names, vals, new_env );
inc_ref(new_env);
} }
while ( !nilp( body ) ) { while ( !nilp( body ) ) {
@ -242,6 +244,10 @@ eval_lambda( struct cons_space_object cell, struct stack_frame *frame,
debug_print_object(sexpr, DEBUG_LAMBDA); debug_print_object(sexpr, DEBUG_LAMBDA);
debug_println( DEBUG_LAMBDA); debug_println( DEBUG_LAMBDA);
/* if a result is not the terminal result in the lambda, it's a
* side effect, and needs to be GCed */
if (!nilp(result)) dec_ref(result);
result = eval_form( frame, frame_pointer, sexpr, new_env ); result = eval_form( frame, frame_pointer, sexpr, new_env );
} }

View file

@ -130,20 +130,32 @@ struct cons_pointer print( FILE * output, struct cons_pointer pointer ) {
} }
fwprintf( output, L"%ld%", cell.payload.integer.value ); fwprintf( output, L"%ld%", cell.payload.integer.value );
break; break;
case LAMBDATV: case LAMBDATV: {
print( output, make_cons( c_string_to_lisp_symbol( L"lambda" ), struct cons_pointer to_print = make_cons( c_string_to_lisp_symbol( L"lambda" ),
make_cons( cell.payload.lambda.args, make_cons( cell.payload.lambda.args,
cell.payload. cell.payload.
lambda.body ) ) ); lambda.body ));
inc_ref(to_print);
print( output, to_print );
dec_ref(to_print);
}
break; break;
case NILTV: case NILTV:
fwprintf( output, L"nil" ); fwprintf( output, L"nil" );
break; break;
case NLAMBDATV: case NLAMBDATV: {
print( output, make_cons( c_string_to_lisp_symbol( L"nlambda" ), struct cons_pointer to_print = make_cons( c_string_to_lisp_symbol( L"nlambda" ),
make_cons( cell.payload.lambda.args, make_cons( cell.payload.lambda.args,
cell.payload. cell.payload.
lambda.body ) ) ); lambda.body ));
inc_ref(to_print);
print( output, to_print );
dec_ref(to_print);
}
break; break;
case RATIOTV: case RATIOTV:
print( output, cell.payload.ratio.dividend ); print( output, cell.payload.ratio.dividend );