mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2025-12-06 02:40:26 -08:00
[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:
parent
cd89c1f432
commit
ae20397968
1 changed files with 28 additions and 40 deletions
68
src/c/nucl.c
68
src/c/nucl.c
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue