|
|
@ -61,50 +61,30 @@ static enum fh_error w_does(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
{ |
|
|
|
{ |
|
|
|
(void) w; |
|
|
|
(void) w; |
|
|
|
enum fh_error rv; |
|
|
|
enum fh_error rv; |
|
|
|
bool crazy = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (fh->executing_compiled) { |
|
|
|
if (fh->executing_compiled) {
|
|
|
|
LOG("DOES> in compiled code. OK but weird"); |
|
|
|
struct fh_word_s *last_word = fh_word_at(fh, fh->dict_last); |
|
|
|
//FIXME make this less shitty
|
|
|
|
if (!last_word) return FH_ERR_INTERNAL; |
|
|
|
|
|
|
|
last_word->param = fh->execptr + INSTR_SIZE; |
|
|
|
// FIXME this works correctly, but the test fails, because it assumes
|
|
|
|
last_word->handler = w_user_word; |
|
|
|
// that compiled DOES> just changes some pointer in the dict entry,
|
|
|
|
last_word->flags = WORDFLAG_WORD | WORDFLAG_CREATED; |
|
|
|
// whereas we do it by generating helper instructions.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
crazy = 1; |
|
|
|
|
|
|
|
goto banana; |
|
|
|
|
|
|
|
banana2: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// We are in :NONAME or : NAME.
|
|
|
|
|
|
|
|
// This word should be compiled.
|
|
|
|
|
|
|
|
TRY(fh_put_instr(fh, FH_INSTR_JUMP, fh->execptr + INSTR_SIZE)); // skip two forward
|
|
|
|
|
|
|
|
// next instr run is the ENDWORD emitted at compile time
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return FH_OK; |
|
|
|
return FH_OK; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (fh->state == FH_STATE_COMPILE) { |
|
|
|
if (fh->state == FH_STATE_COMPILE) { |
|
|
|
TRY(fh_put_instr(fh, FH_INSTR_WORD, (void*)w - (void*)&fh->heap[0])); // call the DOES word
|
|
|
|
TRY(fh_put_instr(fh, FH_INSTR_WORD, (void*)w - (void*)&fh->heap[0])); // call the DOES word
|
|
|
|
TRY(fh_put_instr(fh, FH_INSTR_ENDWORD, 1)); |
|
|
|
TRY(fh_put_instr(fh, FH_INSTR_ENDWORD, 1)); // synthetic exit so we dont also run the "postponed" DOES> content
|
|
|
|
return FH_OK; |
|
|
|
return FH_OK; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fh_setstate(fh, FH_STATE_COMPILE, 0); |
|
|
|
fh_setstate(fh, FH_STATE_COMPILE, 0); |
|
|
|
|
|
|
|
|
|
|
|
banana: |
|
|
|
|
|
|
|
struct fh_word_s *last_word = fh_word_at(fh, fh->dict_last); |
|
|
|
struct fh_word_s *last_word = fh_word_at(fh, fh->dict_last); |
|
|
|
if (!last_word) return FH_ERR_INTERNAL; |
|
|
|
if (!last_word) return FH_ERR_INTERNAL; |
|
|
|
|
|
|
|
|
|
|
|
last_word->handler = w_user_word; |
|
|
|
last_word->handler = w_user_word; |
|
|
|
last_word->param = fh->here; // + CELL; // skip the one cell used to hold data. this is a shitty hack
|
|
|
|
last_word->param = fh->here; |
|
|
|
last_word->flags = WORDFLAG_WORD; |
|
|
|
last_word->flags = WORDFLAG_WORD | WORDFLAG_CREATED; |
|
|
|
|
|
|
|
|
|
|
|
uint32_t dptr = fh->here; |
|
|
|
|
|
|
|
//TRY(fh_heap_reserve(fh, CELL, NULL));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TRY(fh_put_instr(fh, FH_INSTR_NUMBER, dptr)); // put pointer to the reserved cell
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (crazy) goto banana2; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return FH_OK; |
|
|
|
return FH_OK; |
|
|
|
} |
|
|
|
} |
|
|
|