implement C"

master
Ondřej Hruška 3 years ago
parent 3c90303589
commit c0c88ebd42
  1. 5
      include/fh_runtime.h
  2. 34
      src/fh_builtins_text.c
  3. 16
      src/fh_runtime.c
  4. 14
      src/fh_see.c

@ -35,6 +35,11 @@ enum fh_instruction_kind {
/** This is the `s"` instruction, the length (u32) and string data immediately follow */ /** This is the `s"` instruction, the length (u32) and string data immediately follow */
FH_INSTR_ALLOCSTR, FH_INSTR_ALLOCSTR,
/** This is the `c"` instruction, the length (u32) and string data immediately follow.
* The string data already contains the length prefix.
*/
FH_INSTR_ALLOCSTR_C,
/** This is the `."` instruction, same format as above. */ /** This is the `."` instruction, same format as above. */
FH_INSTR_TYPESTR, FH_INSTR_TYPESTR,

@ -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; 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) static bool chartest_equals_or_end(char c, void *param)
{ {
char cc = *(char*)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[] = { const struct name_and_handler fh_builtins_text[] = {
{"s\"", w_s_quote, 1, 0}, {"s\"", w_s_quote, 1, 0},
{"c\"", w_c_quote, 1, 0},
{"s\\\"", w_s_quote, 1, 1}, // escaped {"s\\\"", w_s_quote, 1, 1}, // escaped
{".\"", w_dot_quote, 1, '"'}, {".\"", w_dot_quote, 1, '"'},
{".(", w_dot_quote, 1, ')'}, {".(", w_dot_quote, 1, ')'},

@ -344,18 +344,24 @@ enum fh_error w_user_word(struct fh_thread_s *fh, const struct fh_word_s *w0)
TRY(ds_pop(fh, &val)); // discard the tested value TRY(ds_pop(fh, &val)); // discard the tested value
goto instr; goto instr;
/* special case for strings stored in compile memory */
case FH_INSTR_ALLOCSTR: case FH_INSTR_ALLOCSTR:
case FH_INSTR_TYPESTR:
strl = instr->data; strl = instr->data;
if (instr->kind == FH_INSTR_ALLOCSTR) {
LOG("\x1b[35mExec: alloc-str\x1b[m \"%.*s\"", strl, fh_str_at(fh, fh->execptr)); LOG("\x1b[35mExec: alloc-str\x1b[m \"%.*s\"", strl, fh_str_at(fh, fh->execptr));
TRY(ds_push(fh, fh->execptr)); // give pointer directly into the definition TRY(ds_push(fh, fh->execptr)); // give pointer directly into the definition
TRY(ds_push(fh, strl)); TRY(ds_push(fh, strl));
} else { fh->execptr += strl;
goto instr;
case FH_INSTR_ALLOCSTR_C:
LOG("\x1b[35mExec: alloc-str-c\x1b[m \"%.*s\"", fh->heap[fh->execptr], fh_str_at(fh, fh->execptr+1));
TRY(ds_push(fh, fh->execptr));
fh->execptr += instr->data;
goto instr;
case FH_INSTR_TYPESTR:
strl = instr->data;
LOG("\x1b[35mExec: type-str\x1b[m \"%.*s\"", strl, fh_str_at(fh, fh->execptr)); LOG("\x1b[35mExec: type-str\x1b[m \"%.*s\"", strl, fh_str_at(fh, fh->execptr));
FHPRINT("%.*s", (int) strl, fh_str_at(fh, fh->execptr)); FHPRINT("%.*s", (int) strl, fh_str_at(fh, fh->execptr));
}
fh->execptr += strl; fh->execptr += strl;
goto instr; goto instr;

@ -100,15 +100,21 @@ static void show_word(struct fh_thread_s *fh, const struct fh_word_s *w)
/* special case for strings stored in compile memory */ /* special case for strings stored in compile memory */
case FH_INSTR_ALLOCSTR: case FH_INSTR_ALLOCSTR:
case FH_INSTR_TYPESTR:
strl = instr->data; strl = instr->data;
if (instr->kind == FH_INSTR_ALLOCSTR) {
FHPRINT("AllocStr(\"%.*s\")\n", strl, fh_str_at(fh, execptr)); FHPRINT("AllocStr(\"%.*s\")\n", strl, fh_str_at(fh, execptr));
execptr += strl; execptr += strl;
} else { break;
case FH_INSTR_TYPESTR:
strl = instr->data;
FHPRINT("PrintStr(\"%.*s\")\n", strl, fh_str_at(fh, execptr)); FHPRINT("PrintStr(\"%.*s\")\n", strl, fh_str_at(fh, execptr));
execptr += strl; execptr += strl;
} break;
case FH_INSTR_ALLOCSTR_C:
strl = instr->data;
FHPRINT("AllocStrC(%d, \"%.*s\")\n", fh->heap[execptr], fh->heap[execptr], fh_str_at(fh, execptr + 1));
execptr += strl;
break; break;
case FH_INSTR_ENDWORD: case FH_INSTR_ENDWORD:

Loading…
Cancel
Save