[nucl] use the data stack

This commit is contained in:
Daniel Kochmański 2025-05-28 11:08:51 +02:00
parent 5eec810592
commit 3db21bec37

View file

@ -83,6 +83,52 @@ void smoke_bytecodes (void)
cl_object ecl_make_nucl_stream(FILE *f);
/* -- Lali-ho I/O starts here ----------------------------------------------- */
/* GC won't catch pointers from constexpr symbols unless registered as root. */
static cl_object nucl_fp = ecl_cast_ptr(cl_object,&(ecl_constexpr_symbol(ecl_stp_special, "*FP*", ECL_NIL)));
#define open_nucl_frame(name) \
const cl_env_ptr the_env = ecl_process_env(); \
struct ecl_stack_frame nucl_frame_aux; \
cl_object name = ecl_cast_ptr(cl_object, &nucl_frame_aux); \
ecl_stack_frame_open(the_env, name, 0); \
ecl_bds_bind(the_env, nucl_fp, name);
#define close_nucl_frame(name) \
ecl_bds_unwind1(the_env); \
ecl_stack_frame_close(name);
static cl_object
nucl_stack_frame(void)
{
const cl_env_ptr the_env = ecl_process_env();
return ECL_SYM_VAL(the_env, nucl_fp);
}
static cl_index
nucl_frame_size(cl_object fp)
{
return fp->frame.size;
}
static void
nucl_stack_push(cl_object object)
{
cl_object frame = nucl_stack_frame();
frame->frame.size++;
frame->frame.sp++;
ecl_stack_frame_push(frame, object);
}
static cl_object
nucl_stack_pop(void)
{
cl_object frame = nucl_stack_frame();
frame->frame.size--;
frame->frame.sp--;
return ECL_STACK_POP_UNSAFE(frame->frame.env);
}
cl_object
nucl_alloc_base_string(cl_index s)
{
@ -98,34 +144,38 @@ nucl_alloc_base_string(cl_index s)
}
cl_object
nucl_stack_to_string(cl_object stack)
nucl_stack_to_string(void)
{
cl_index size = stack->vector.fillp, idx;
cl_object frame = nucl_stack_frame();
cl_index size = nucl_frame_size(frame), idx=0;
cl_object self = nucl_alloc_base_string(size);
for(idx=0; idx<size; idx++)
self->base_string.self[idx] = ECL_CHAR_CODE(stack->vector.self.t[idx]);
loop_across_frame_fifo(elt, frame) {
self->base_string.self[idx++] = ECL_CHAR_CODE(elt);
} end_loop_across_frame();
return self;
}
cl_object
nucl_stack_to_list(cl_object stack)
nucl_stack_to_list(void)
{
cl_index size = stack->vector.fillp, idx;
cl_object frame = nucl_stack_frame();
cl_index size = nucl_frame_size(frame), idx=0;
cl_object self = ECL_NIL;
loop_across_stack_filo(elt, stack) {
loop_across_frame_filo(elt, frame) {
self = ecl_cons(elt, self);
} end_loop_across_stack();
} end_loop_across_frame();
return self;
}
cl_object
nucl_stack_to_fixnum(cl_object stack)
nucl_stack_to_fixnum(void)
{
cl_index size = stack->vector.fillp, idx;
cl_object frame = nucl_stack_frame();
cl_index size = nucl_frame_size(frame);
cl_object self = ECL_NIL;
intmax_t acc = 0;
int dig;
loop_across_stack_fifo(elt, stack) {
loop_across_frame_fifo(elt, frame) {
acc *= 10;
switch(ECL_CHAR_CODE(elt)) {
case '0': case '1': case '2': case '3': case '4':
@ -137,18 +187,19 @@ nucl_stack_to_fixnum(cl_object stack)
}
if (acc>MOST_POSITIVE_FIXNUM)
ecl_internal_error("Integer is too big!");
} end_loop_across_stack();
} end_loop_across_frame();
return ecl_make_fixnum((cl_fixnum)acc);
}
cl_object
nucl_stack_to_hexnum(cl_object stack)
nucl_stack_to_hexnum(void)
{
cl_index size = stack->vector.fillp, idx;
cl_object frame = nucl_stack_frame();
cl_index size = nucl_frame_size(frame);
cl_object self = ECL_NIL;
intmax_t acc = 0;
int dig;
loop_across_stack_fifo(elt, stack) {
loop_across_frame_fifo(elt, frame) {
acc *= 16;
switch(ECL_CHAR_CODE(elt)) {
case '0': case '1': case '2': case '3': case '4':
@ -166,7 +217,7 @@ nucl_stack_to_hexnum(cl_object stack)
}
if (acc>MOST_POSITIVE_FIXNUM)
ecl_internal_error("Integer is too big!");
} end_loop_across_stack();
} end_loop_across_frame();
return ecl_make_fixnum((cl_fixnum)acc);
}
@ -190,37 +241,39 @@ nucl_write_string(cl_object strm, cl_object s)
void
nucl_write_fixnum(cl_object strm, cl_object s)
{
cl_object stack = ecl_make_stack(0), c=ECL_NIL;
open_nucl_frame(frame);
cl_object c=ECL_NIL;
cl_fixnum value = ecl_fixnum(s), dig;
if(value<0) value = -value;
do {
dig = value%10;
ecl_stack_push(stack, ECL_CODE_CHAR(dig+'0'));
nucl_stack_push(ECL_CODE_CHAR(dig+'0'));
value /= 10;
} while(value!=0);
if(ecl_fixnum(s) < 0)
ecl_stack_push(stack, ECL_CODE_CHAR('-'));
loop_across_stack_filo(elt, stack) {
nucl_stack_push(ECL_CODE_CHAR('-'));
loop_across_frame_filo(elt, frame) {
si_write_char(strm, elt);
} end_loop_across_stack();
} end_loop_across_frame();
close_nucl_frame(frame);
}
cl_object
void
nucl_read_until(cl_object strm, cl_fixnum delim)
{
cl_object stack = ecl_make_stack(0), c=ECL_NIL;
while (!Null(c = si_read_char(strm, ECL_NIL))) {
ecl_stack_push(stack, c);
if(ECL_CHAR_CODE(c) == delim) break;
cl_object frame = nucl_stack_frame();
cl_object ch = ECL_NIL;
while (!Null(ch = si_read_char(strm, ECL_NIL))) {
nucl_stack_push(ch);
if(ECL_CHAR_CODE(ch) == delim) break;
}
return stack;
}
cl_object
nucl_read_line(cl_object strm)
{
cl_object stack = nucl_read_until(strm, '\n');
return nucl_stack_to_string(stack);
nucl_read_until(strm, '\n');
return nucl_stack_to_string();
}
/* Ad-hoc printer */
@ -316,24 +369,23 @@ default_reader(int narg, cl_object strm, cl_object ch)
simpler interpretation -- digit first means a fixnum, otherwise a symbol.
If the first digit is 0, then it must be a hexadecimal number, i.e 0xff. */
struct ecl_readtable_entry *entry = nucl_readtable_get(rtable, ECL_CHAR_CODE(ch));
cl_object stack = ecl_make_stack(0);
ecl_stack_push(stack, ch);
nucl_stack_push(ch);
while (!Null(ch = si_read_char(strm, ECL_NIL))) {
entry = nucl_readtable_get(rtable, ECL_CHAR_CODE(ch));
switch (entry->syntax_type) {
case cat_constituent:
ecl_stack_push(stack, ch);
nucl_stack_push(ch);
break;
case cat_terminating:
si_unread_char(strm, ch);
return stack;
return ECL_NIL;
case cat_whitespace:
return stack;
return ECL_NIL;
default:
ecl_internal_error("Expecting too much, aren't we?");
}
}
return stack;
return ECL_NIL;
}
static cl_object
@ -345,7 +397,8 @@ comment_reader(int narg, cl_object strm, cl_object c)
static cl_object
lparen_reader(int narg, cl_object strm, cl_object c)
{
cl_object stack = ecl_make_stack(0), object;
open_nucl_frame(frame);
cl_object object;
cl_object delim = ECL_CODE_CHAR(')');
do {
object = nucl_accept(strm, delim);
@ -354,9 +407,11 @@ lparen_reader(int narg, cl_object strm, cl_object c)
else if(ecl_eql(object, delim))
break;
else
ecl_stack_push(stack, object);
nucl_stack_push(object);
} while(1);
return nucl_stack_to_list(stack);
object = nucl_stack_to_list();
close_nucl_frame(frame);
return object;
}
static cl_object
@ -368,25 +423,24 @@ rparen_reader(int narg, cl_object strm, cl_object c)
static cl_object
symbol_reader(int narg, cl_object strm, cl_object c)
{
cl_object stack = default_reader(2, strm, c);
cl_object string = nucl_stack_to_string(stack);
default_reader(2, strm, c);
cl_object string = nucl_stack_to_string();
return ecl_cons(ECL_CODE_CHAR('T'), string);
}
static cl_object
string_reader(int narg, cl_object strm, cl_object c)
{
cl_object stack = nucl_read_until(strm, ECL_CHAR_CODE(c));
ecl_stack_popu(stack);
return nucl_stack_to_string(stack);
nucl_read_until(strm, ECL_CHAR_CODE(c));
nucl_stack_pop(); /* remove delimiter */
return nucl_stack_to_string();
}
static cl_object
fixnum_reader(int narg, cl_object strm, cl_object c)
{
cl_object stack = default_reader(2, strm, c);
cl_object result = nucl_stack_to_fixnum(stack);
return result;
default_reader(2, strm, c);
return nucl_stack_to_fixnum();
}
static cl_object
@ -399,9 +453,8 @@ hexnum_reader(int narg, cl_object strm, cl_object c)
si_unread_char(strm, ch);
return ecl_make_fixnum(0);
} else {
cl_object stack = default_reader(2, strm, c);
cl_object result = nucl_stack_to_hexnum(stack);
return result;
default_reader(2, strm, c);
return nucl_stack_to_hexnum();
}
}
@ -485,8 +538,8 @@ skip_whitespace(cl_object strm, cl_object delim)
static cl_object
nucl_accept(cl_object strm, cl_object delim)
{
open_nucl_frame(frame);
struct ecl_readtable_entry *entry = NULL;
cl_object stack = ecl_make_stack(0);
cl_object ch = ECL_NIL;
cl_object result = ECL_NIL;
ch = skip_whitespace(strm, delim);
@ -509,6 +562,7 @@ nucl_accept(cl_object strm, cl_object delim)
default:
ecl_internal_error("Expecting too much, aren't we?");
}
close_nucl_frame(frame);
return result;
}