Much better GC, still a few things being missed.
This commit is contained in:
parent
2ec5d37305
commit
c21a762413
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -30,3 +30,5 @@ log*
|
||||||
\.settings/language\.settings\.xml
|
\.settings/language\.settings\.xml
|
||||||
|
|
||||||
utils_src/readprintwc/out
|
utils_src/readprintwc/out
|
||||||
|
|
||||||
|
*.dump
|
||||||
|
|
|
@ -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] );
|
||||||
|
|
34
src/init.c
34
src/init.c
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
Loading…
Reference in a new issue