diff --git a/src/c/nucl.c b/src/c/nucl.c index df651568d..63cbba9b2 100644 --- a/src/c/nucl.c +++ b/src/c/nucl.c @@ -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; idxbase_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; }