|
|
|
@ -362,7 +362,13 @@ static enum fh_error w_colon(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
|
enum fh_error rv; |
|
|
|
|
ENSURE_STATE(FH_STATE_INTERPRET); |
|
|
|
|
|
|
|
|
|
fh_setstate(fh, FH_STATE_COMPILE, FH_SUBSTATE_COLON_NAME); |
|
|
|
|
char *wordname = NULL; |
|
|
|
|
size_t namelen = 0; |
|
|
|
|
fh_input_consume_spaces(fh); |
|
|
|
|
TRY(fh_input_read_word(fh, &wordname, &namelen)); |
|
|
|
|
LOG("Name: %.*s", namelen, wordname); |
|
|
|
|
|
|
|
|
|
fh_setstate(fh, FH_STATE_COMPILE, 0); |
|
|
|
|
|
|
|
|
|
uint32_t ptr; |
|
|
|
|
TRY(fh_heap_reserve(fh, DICTWORD_SIZE, &ptr)); |
|
|
|
@ -371,6 +377,9 @@ static enum fh_error w_colon(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
|
new_word->previous = fh->dict_last; |
|
|
|
|
new_word->param = fh->here; |
|
|
|
|
new_word->handler = w_user_word; |
|
|
|
|
strncpy(new_word->name, wordname, namelen); |
|
|
|
|
new_word->name[namelen] = 0; |
|
|
|
|
|
|
|
|
|
fh->dict_last = ptr; |
|
|
|
|
|
|
|
|
|
return FH_OK; |
|
|
|
@ -379,9 +388,15 @@ static enum fh_error w_colon(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
|
static enum fh_error w_postpone(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
|
{ |
|
|
|
|
(void) w; |
|
|
|
|
enum fh_error rv; |
|
|
|
|
ENSURE_STATE(FH_STATE_COMPILE); |
|
|
|
|
|
|
|
|
|
fh_setsubstate(fh, FH_SUBSTATE_POSTPONE_NAME); |
|
|
|
|
char *wordname; |
|
|
|
|
size_t namelen = 0; |
|
|
|
|
fh_input_consume_spaces(fh); |
|
|
|
|
TRY(fh_input_read_word(fh, &wordname, &namelen)); |
|
|
|
|
TRY(fh_postpone_word(fh, wordname, namelen)); |
|
|
|
|
|
|
|
|
|
return FH_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -770,16 +785,43 @@ static enum fh_error w_exit(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
|
static enum fh_error w_s_quote(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
|
{ |
|
|
|
|
(void) w; |
|
|
|
|
fh_setsubstate(fh, FH_SUBSTATE_S_QUOTE); |
|
|
|
|
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]; |
|
|
|
|
TRY(fh_input_read_quotedstring(fh, w->param == 1, start, HEAP_END - addr, &len)); |
|
|
|
|
fh->here = WORDALIGNED(addr + len); |
|
|
|
|
|
|
|
|
|
struct fh_instruction_s instr; |
|
|
|
|
if (fh->state == FH_STATE_INTERPRET) { |
|
|
|
|
LOG("Interpret a string alloc: \"%.*s\"", len, start); |
|
|
|
|
TRY(ds_push(fh, addr)); |
|
|
|
|
TRY(ds_push(fh, len)); |
|
|
|
|
} else { |
|
|
|
|
LOG("Compile a string: \"%.*s\"", len, start); |
|
|
|
|
instr_init(&instr, FH_INSTR_ALLOCSTR, len); |
|
|
|
|
fh_heap_write(fh, addr - INSTR_SIZE, &instr, INSTR_SIZE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return FH_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//static enum fh_error w_char(struct fh_thread_s *fh, const struct fh_word_s *w)
|
|
|
|
|
//{
|
|
|
|
|
// (void) w;
|
|
|
|
|
// fh_setsubstate(fh, FH_SUBSTATE_CHAR);
|
|
|
|
|
// return FH_OK;
|
|
|
|
|
//}
|
|
|
|
|
static enum fh_error w_char(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
|
{ |
|
|
|
|
(void) w; |
|
|
|
|
enum fh_error rv; |
|
|
|
|
|
|
|
|
|
char *wordname = NULL; |
|
|
|
|
size_t namelen = 0; |
|
|
|
|
fh_input_consume_spaces(fh); |
|
|
|
|
TRY(fh_input_read_word(fh, &wordname, &namelen)); |
|
|
|
|
TRY(ds_push(fh, (char) *wordname)); |
|
|
|
|
return FH_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static enum fh_error w_error_word0(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
|
{ |
|
|
|
@ -792,7 +834,26 @@ static enum fh_error w_error_word0(struct fh_thread_s *fh, const struct fh_word_ |
|
|
|
|
static enum fh_error w_dot_quote(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
|
{ |
|
|
|
|
(void) w; |
|
|
|
|
fh_setsubstate(fh, FH_SUBSTATE_DOT_QUOTE); |
|
|
|
|
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, but don't advance the heap pointer, so the string is immediately discarded again */ |
|
|
|
|
|
|
|
|
|
fh_input_consume_spaces(fh); |
|
|
|
|
char *start = (char *) &fh->heap[addr]; |
|
|
|
|
TRY(fh_input_read_quotedstring(fh, w->param == 1, start, HEAP_END - addr, &len)); |
|
|
|
|
|
|
|
|
|
struct fh_instruction_s instr; |
|
|
|
|
if (fh->state == FH_STATE_INTERPRET) { |
|
|
|
|
FHPRINT("%.*s", (int) len, start); |
|
|
|
|
} else { |
|
|
|
|
LOG("Compile a string: \"%.*s\"", len, start); |
|
|
|
|
instr_init(&instr, FH_INSTR_TYPESTR, len); |
|
|
|
|
fh_heap_write(fh, addr - INSTR_SIZE, &instr, INSTR_SIZE); |
|
|
|
|
fh->here = WORDALIGNED(addr + len); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return FH_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -983,7 +1044,11 @@ static enum fh_error w_emit(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
|
static enum fh_error w_see(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
|
{ |
|
|
|
|
enum fh_error rv; |
|
|
|
|
fh_setsubstate(fh, FH_SUBSTATE_SEE_NAME); |
|
|
|
|
char *wordname; |
|
|
|
|
size_t namelen = 0; |
|
|
|
|
fh_input_consume_spaces(fh); |
|
|
|
|
TRY(fh_input_read_word(fh, &wordname, &namelen)); |
|
|
|
|
TRY(fh_see_word(fh, wordname, namelen)); |
|
|
|
|
return FH_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1147,11 +1212,13 @@ enum fh_error register_builtin_words(struct fh_thread_s *fh) |
|
|
|
|
const struct name_and_handler builtins[] = { |
|
|
|
|
{"", w_error_word0, 1, 0}, |
|
|
|
|
/* Weird meta stuff */ |
|
|
|
|
{"immediate", w_immediate, 1, 0}, |
|
|
|
|
{"immediate", w_immediate, 0, 0}, |
|
|
|
|
{"postpone", w_postpone, 1, 0}, |
|
|
|
|
{"[", w_leftbracket, 1, 0}, |
|
|
|
|
{"]", w_rightbracket, 1, 0}, |
|
|
|
|
{"literal", w_literal, 1, 0}, |
|
|
|
|
{"char", w_char, 0, 0}, |
|
|
|
|
{"[char]", w_char, 1, 0}, |
|
|
|
|
/* Runtime stats */ |
|
|
|
|
{"depth", w_depth, 0, 0}, |
|
|
|
|
{"unused", w_unused, 0, 0}, |
|
|
|
@ -1161,7 +1228,9 @@ enum fh_error register_builtin_words(struct fh_thread_s *fh) |
|
|
|
|
{"bye", w_bye, 0, 0}, |
|
|
|
|
/* Strings & Chars */ |
|
|
|
|
{"s\"", w_s_quote, 1, 0}, |
|
|
|
|
{"s\\\"", w_s_quote, 1, 1}, // escaped
|
|
|
|
|
{".\"", w_dot_quote, 1, 0}, |
|
|
|
|
{".\\\"", w_dot_quote, 1, 1}, // escaped, this is non-standard
|
|
|
|
|
// {"char", w_char, 1, 0},
|
|
|
|
|
/* Pointers */ |
|
|
|
|
{"@", w_fetch, 0, 0}, |
|
|
|
|