[nucl] words operate directly on the stack

In the first sketch they operated on stack frames, but this approach was flawed
because a) leaving things on the stack above frame prevented it from growing
leading to an internal error, b) closing the frame wiped all values deposited on
the stack that were above the frame base.
This commit is contained in:
Daniel Kochmański 2025-06-03 21:35:47 +02:00
parent cd89c1f432
commit ae20397968

View file

@ -850,24 +850,21 @@ nucl_append_dictionary(cl_object symbol, cl_object value)
/* -- Default words --------------------------------------------------------- */
cl_object nucl_word_print_frame(int narg) {
cl_object frame = nucl_stack_frame();
cl_index ssize = nucl_stack_size();
cl_object size = ecl_make_fixnum(ssize);
nucl_write_cstr("[");
nucl_write_object(size);
nucl_write_cstr("] ");
loop_across_frame_fifo(elt, frame) {
cl_object nucl_word_print_dictionary(int narg) {
cl_env_ptr the_env = ecl_core.first_env;
cl_object dict = ECL_SYM_VAL(the_env, nucl_dt);
loop_across_stack_fifo(elt, dict) {
nucl_write_object(elt);
nucl_write_cstr(" ");
} end_loop_across_frame();
return size;
} end_loop_across_stack();
return ECL_NIL;
}
cl_object nucl_word_print_stack(int narg) {
const cl_env_ptr the_env = ecl_process_env();
cl_index ssize = nucl_stack_size();
cl_object size = ecl_make_fixnum(ECL_STACK_INDEX(the_env));
cl_index ssize = ECL_STACK_INDEX(the_env);
/* the stack always has 0 at the beginning */
cl_object size = ecl_make_fixnum(ssize);
cl_object *ptr;
nucl_write_cstr("[");
nucl_write_object(size);
@ -881,24 +878,15 @@ cl_object nucl_word_print_stack(int narg) {
return size;
}
cl_object nucl_word_print_dictionary(int narg) {
cl_env_ptr the_env = ecl_core.first_env;
cl_object dict = ECL_SYM_VAL(the_env, nucl_dt);
loop_across_stack_fifo(elt, dict) {
nucl_write_object(elt);
nucl_write_cstr(" ");
} end_loop_across_stack();
return ECL_NIL;
}
/* FIXME manipulate directly the stack. */
cl_object nucl_word_pop_print(int narg) {
cl_index ssize = nucl_stack_size();
if(ssize == 0) {
const cl_env_ptr the_env = ecl_process_env();
cl_index ssize = ECL_STACK_INDEX(the_env);
/* INV the first element 0 is always present. */
if(ssize <= 1) {
nucl_write_cstr("error: stack underflow");
return ECL_NIL;
} else {
cl_object elt = nucl_stack_pop();
cl_object elt = ECL_STACK_POP_UNSAFE(the_env);
nucl_write_object(elt);
nucl_write_cstr(" ");
return elt;
@ -906,11 +894,8 @@ cl_object nucl_word_pop_print(int narg) {
}
cl_object nucl_word_test(int narg) {
cl_env_ptr the_env = ecl_core.first_env;
cl_object elt = ecl_make_fixnum(ECL_STACK_INDEX(the_env));
nucl_write_object(elt);
nucl_write_cstr(" ");
return elt;
nucl_write_cstr("Test call\n");
return ECL_NIL;
}
ecl_def_function(_nucl_word_ps, nucl_word_print_stack, static, const);
@ -930,10 +915,10 @@ static const cl_object _nucl_sym_fed = make_dict_entry(";", ECL_UNBOUND);
static cl_object nucl_dictionary_default_entries[] = {
_nucl_sym_def,
_nucl_sym_fed,
make_dict_entry(",", _nucl_word_tt),
make_dict_entry(".", _nucl_word_dp),
make_dict_entry(".S", _nucl_word_ps),
make_dict_entry(".D", _nucl_word_pd),
make_dict_entry(".S", _nucl_word_ps),
make_dict_entry(".", _nucl_word_dp),
make_dict_entry(",", _nucl_word_tt),
NULL,
};
@ -1051,8 +1036,10 @@ cl_object nucl_process_token (cl_object token)
cl_object nucl_process_command ()
{
cl_object result = limited_reader(ECL_CODE_CHAR('\n'));
cl_object command;
cl_object result, command;
if (Null(get_definition_p())) open_nucl_frame();
result = limited_reader(ECL_CODE_CHAR('\n'));
/* Processing of the command is straightforward. First we clean up the stack
frame by moving it to a list, and then we process individual entries until.
Complete definitions are not pushed back onto the stack, only words. */
@ -1069,8 +1056,12 @@ cl_object nucl_process_command ()
/* Now if we are in not in a middle of the definition compile anonymous word
from the current stack and call it. Otherwise leave the stack be. */
if(Null(get_definition_p())) {
const cl_env_ptr the_env = ecl_process_env();
struct ecl_stack_frame aux_frame[1];
cl_object frame = ecl_cast_ptr(cl_object, aux_frame);
cl_object word = nucl_compile_definition();
cl_object frame = nucl_stack_frame();
close_nucl_frame();
ecl_stack_frame_open(the_env, frame, 0);
ecl_interpret(frame, ECL_NIL, word);
}
return result;
@ -1085,8 +1076,6 @@ void nucl_repl (void)
init_nucl_reader();
init_nucl_dictionary();
init_nucl_dictionary_entries();
cl_object frame = open_nucl_frame(); /* top level frame */
do {
if(Null(get_definition_p()))
nucl_write_cstr("nucl> ");
@ -1096,7 +1085,6 @@ void nucl_repl (void)
if(Null(get_definition_p()))
nucl_write_cstr("... ok\n");
} while(result != ECL_EOF);
close_nucl_frame();
nucl_write_cstr("... bye\n");
}