|
|
|
@ -209,6 +209,39 @@ static enum fh_error w_s_quote(struct fh_thread_s *fh, const struct fh_word_s *w |
|
|
|
|
return FH_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static enum fh_error w_c_quote(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
|
{ |
|
|
|
|
(void) w; |
|
|
|
|
enum fh_error rv; |
|
|
|
|
size_t len; |
|
|
|
|
uint32_t addr = fh->here + (fh->state == FH_STATE_INTERPRET ? 0 : INSTR_SIZE); |
|
|
|
|
|
|
|
|
|
/* read the string straight into HEAP */ |
|
|
|
|
|
|
|
|
|
fh_input_consume_spaces(fh); |
|
|
|
|
char *start = ((char *) &fh->heap[addr]) + 1; // space for the counter
|
|
|
|
|
uint32_t maxlen = HEAP_END - addr; |
|
|
|
|
if (maxlen > 255) {
|
|
|
|
|
maxlen = 255; |
|
|
|
|
} |
|
|
|
|
TRY(fh_input_read_quotedstring(fh, w->param == 1, start, maxlen, &len)); |
|
|
|
|
fh->here = WORDALIGNED(addr + len + 1); |
|
|
|
|
fh->heap[addr] = (uint8_t) len; // char count
|
|
|
|
|
|
|
|
|
|
struct fh_instruction_s instr; |
|
|
|
|
if (fh->state == FH_STATE_INTERPRET) { |
|
|
|
|
LOG("Interpret a c-string alloc: \"%.*s\"", len, start); |
|
|
|
|
TRY(ds_push(fh, addr)); |
|
|
|
|
} else { |
|
|
|
|
LOG("Compile a c-string: \"%.*s\"", len, start); |
|
|
|
|
instr.kind = FH_INSTR_ALLOCSTR_C; |
|
|
|
|
instr.data = WORDALIGNED(len + 1); |
|
|
|
|
fh_heap_write(fh, addr - INSTR_SIZE, &instr, INSTR_SIZE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return FH_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static bool chartest_equals_or_end(char c, void *param) |
|
|
|
|
{ |
|
|
|
|
char cc = *(char*)param; |
|
|
|
@ -443,6 +476,7 @@ static enum fh_error w_to_number(struct fh_thread_s *fh, const struct fh_word_s |
|
|
|
|
|
|
|
|
|
const struct name_and_handler fh_builtins_text[] = { |
|
|
|
|
{"s\"", w_s_quote, 1, 0}, |
|
|
|
|
{"c\"", w_c_quote, 1, 0}, |
|
|
|
|
{"s\\\"", w_s_quote, 1, 1}, // escaped
|
|
|
|
|
{".\"", w_dot_quote, 1, '"'}, |
|
|
|
|
{".(", w_dot_quote, 1, ')'}, |
|
|
|
|