|
|
@ -368,7 +368,7 @@ static enum fh_error w_colon(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
} |
|
|
|
} |
|
|
|
struct fh_word_s *new_word = &fh->dict[fh->dict_top]; |
|
|
|
struct fh_word_s *new_word = &fh->dict[fh->dict_top]; |
|
|
|
new_word->index = fh->dict_top; |
|
|
|
new_word->index = fh->dict_top; |
|
|
|
new_word->start = fh->compile_top; |
|
|
|
new_word->start = fh->here; |
|
|
|
new_word->handler = w_user_word; |
|
|
|
new_word->handler = w_user_word; |
|
|
|
|
|
|
|
|
|
|
|
return FH_OK; |
|
|
|
return FH_OK; |
|
|
@ -409,7 +409,7 @@ static enum fh_error w_literal(struct fh_thread_s *fh, const struct fh_word_s *w |
|
|
|
uint32_t val; |
|
|
|
uint32_t val; |
|
|
|
TRY(ds_pop(fh, &val)); |
|
|
|
TRY(ds_pop(fh, &val)); |
|
|
|
instr_init(&instr, FH_INSTR_NUMBER, val); |
|
|
|
instr_init(&instr, FH_INSTR_NUMBER, val); |
|
|
|
TRY(fh_compile_put(fh, &instr, INSTR_SIZE)); |
|
|
|
TRY(fh_heap_put(fh, &instr, INSTR_SIZE)); |
|
|
|
|
|
|
|
|
|
|
|
return FH_OK; |
|
|
|
return FH_OK; |
|
|
|
} |
|
|
|
} |
|
|
@ -423,7 +423,7 @@ static enum fh_error w_semicolon(struct fh_thread_s *fh, const struct fh_word_s |
|
|
|
ENSURE_STATE(FH_STATE_COMPILE); |
|
|
|
ENSURE_STATE(FH_STATE_COMPILE); |
|
|
|
|
|
|
|
|
|
|
|
instr_init(&instr, FH_INSTR_ENDWORD, 0); |
|
|
|
instr_init(&instr, FH_INSTR_ENDWORD, 0); |
|
|
|
TRY(fh_compile_put(fh, &instr, INSTR_SIZE)); |
|
|
|
TRY(fh_heap_put(fh, &instr, INSTR_SIZE)); |
|
|
|
|
|
|
|
|
|
|
|
/* Return to interpret state */ |
|
|
|
/* Return to interpret state */ |
|
|
|
fh_setstate(fh, FH_STATE_INTERPRET, 0); |
|
|
|
fh_setstate(fh, FH_STATE_INTERPRET, 0); |
|
|
@ -472,7 +472,7 @@ static enum fh_error w_recurse(struct fh_thread_s *fh, const struct fh_word_s *w |
|
|
|
ENSURE_STATE(FH_STATE_COMPILE); |
|
|
|
ENSURE_STATE(FH_STATE_COMPILE); |
|
|
|
|
|
|
|
|
|
|
|
instr_init(&instr, FH_INSTR_WORD, fh->dict_top); |
|
|
|
instr_init(&instr, FH_INSTR_WORD, fh->dict_top); |
|
|
|
TRY(fh_compile_put(fh, &instr, INSTR_SIZE)); |
|
|
|
TRY(fh_heap_put(fh, &instr, INSTR_SIZE)); |
|
|
|
|
|
|
|
|
|
|
|
return FH_OK; |
|
|
|
return FH_OK; |
|
|
|
} |
|
|
|
} |
|
|
@ -724,7 +724,7 @@ static enum fh_error w_type(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
TRY(ds_pop(fh, &count)); |
|
|
|
TRY(ds_pop(fh, &count)); |
|
|
|
TRY(ds_pop(fh, &addr)); |
|
|
|
TRY(ds_pop(fh, &addr)); |
|
|
|
|
|
|
|
|
|
|
|
FHPRINT("%.*s", count, &fh->heap[addr]); |
|
|
|
FHPRINT("%.*s", count, fh_str_at(fh, addr)); |
|
|
|
return FH_OK; |
|
|
|
return FH_OK; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -850,9 +850,9 @@ static enum fh_error w_if(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
|
|
|
|
|
|
|
|
ENSURE_STATE(FH_STATE_COMPILE); |
|
|
|
ENSURE_STATE(FH_STATE_COMPILE); |
|
|
|
|
|
|
|
|
|
|
|
TRY(cs_push(fh, fh->compile_top)); |
|
|
|
TRY(cs_push(fh, fh->here)); |
|
|
|
instr_init(&instr, FH_INSTR_JUMPZERO, MAGICADDR_UNRESOLVED); |
|
|
|
instr_init(&instr, FH_INSTR_JUMPZERO, MAGICADDR_UNRESOLVED); |
|
|
|
TRY(fh_compile_put(fh, &instr, INSTR_SIZE)); |
|
|
|
TRY(fh_heap_put(fh, &instr, INSTR_SIZE)); |
|
|
|
return FH_OK; |
|
|
|
return FH_OK; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -866,17 +866,17 @@ static enum fh_error w_else(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
|
|
|
|
|
|
|
|
uint32_t ifaddr = 0; |
|
|
|
uint32_t ifaddr = 0; |
|
|
|
TRY(cs_pop(fh, &ifaddr)); |
|
|
|
TRY(cs_pop(fh, &ifaddr)); |
|
|
|
struct fh_instruction_s *if_instr = (void *) &fh->compile[ifaddr]; |
|
|
|
struct fh_instruction_s *if_instr = fh_instr_at(fh, ifaddr); |
|
|
|
if (if_instr->data != MAGICADDR_UNRESOLVED) { |
|
|
|
if (if_instr->data != MAGICADDR_UNRESOLVED) { |
|
|
|
LOGE("IF-ELSE control stack corruption"); |
|
|
|
LOGE("IF-ELSE control stack corruption"); |
|
|
|
return FH_ERR_INTERNAL; |
|
|
|
return FH_ERR_INTERNAL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if_instr->data = fh->compile_top + INSTR_SIZE; |
|
|
|
if_instr->data = fh->here + INSTR_SIZE; |
|
|
|
|
|
|
|
|
|
|
|
TRY(cs_push(fh, fh->compile_top)); |
|
|
|
TRY(cs_push(fh, fh->here)); |
|
|
|
instr_init(&instr, FH_INSTR_JUMP, MAGICADDR_UNRESOLVED); |
|
|
|
instr_init(&instr, FH_INSTR_JUMP, MAGICADDR_UNRESOLVED); |
|
|
|
TRY(fh_compile_put(fh, &instr, INSTR_SIZE)); |
|
|
|
TRY(fh_heap_put(fh, &instr, INSTR_SIZE)); |
|
|
|
return FH_OK; |
|
|
|
return FH_OK; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -889,13 +889,13 @@ static enum fh_error w_then(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
|
|
|
|
|
|
|
|
uint32_t ifaddr = 0; |
|
|
|
uint32_t ifaddr = 0; |
|
|
|
TRY(cs_pop(fh, &ifaddr)); |
|
|
|
TRY(cs_pop(fh, &ifaddr)); |
|
|
|
struct fh_instruction_s *if_instr = (void *) &fh->compile[ifaddr]; |
|
|
|
struct fh_instruction_s *if_instr = fh_instr_at(fh, ifaddr); |
|
|
|
if (if_instr->data != MAGICADDR_UNRESOLVED) { |
|
|
|
if (if_instr->data != MAGICADDR_UNRESOLVED) { |
|
|
|
LOGE("IF-ELSE control stack corruption"); |
|
|
|
LOGE("IF-ELSE control stack corruption"); |
|
|
|
return FH_ERR_INTERNAL; |
|
|
|
return FH_ERR_INTERNAL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if_instr->data = fh->compile_top; |
|
|
|
if_instr->data = fh->here; |
|
|
|
return FH_OK; |
|
|
|
return FH_OK; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -911,7 +911,7 @@ static enum fh_error w_until(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
TRY(cs_pop(fh, &destaddr)); |
|
|
|
TRY(cs_pop(fh, &destaddr)); |
|
|
|
|
|
|
|
|
|
|
|
instr_init(&instr, FH_INSTR_JUMPZERO, destaddr); |
|
|
|
instr_init(&instr, FH_INSTR_JUMPZERO, destaddr); |
|
|
|
TRY(fh_compile_put(fh, &instr, INSTR_SIZE)); |
|
|
|
TRY(fh_heap_put(fh, &instr, INSTR_SIZE)); |
|
|
|
return FH_OK; |
|
|
|
return FH_OK; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -920,7 +920,7 @@ static enum fh_error w_begin(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
(void) w; |
|
|
|
(void) w; |
|
|
|
enum fh_error rv; |
|
|
|
enum fh_error rv; |
|
|
|
ENSURE_STATE(FH_STATE_COMPILE); |
|
|
|
ENSURE_STATE(FH_STATE_COMPILE); |
|
|
|
TRY(cs_push(fh, fh->compile_top)); /* dest */ |
|
|
|
TRY(cs_push(fh, fh->here)); /* dest */ |
|
|
|
return FH_OK; |
|
|
|
return FH_OK; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -935,11 +935,11 @@ static enum fh_error w_while(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
uint32_t destaddr = 0; |
|
|
|
uint32_t destaddr = 0; |
|
|
|
TRY(cs_pop(fh, &destaddr)); |
|
|
|
TRY(cs_pop(fh, &destaddr)); |
|
|
|
|
|
|
|
|
|
|
|
TRY(cs_push(fh, fh->compile_top)); // orig
|
|
|
|
TRY(cs_push(fh, fh->here)); // orig
|
|
|
|
TRY(cs_push(fh, destaddr)); // dest
|
|
|
|
TRY(cs_push(fh, destaddr)); // dest
|
|
|
|
|
|
|
|
|
|
|
|
instr_init(&instr, FH_INSTR_JUMPZERO, MAGICADDR_UNRESOLVED); |
|
|
|
instr_init(&instr, FH_INSTR_JUMPZERO, MAGICADDR_UNRESOLVED); |
|
|
|
TRY(fh_compile_put(fh, &instr, INSTR_SIZE)); |
|
|
|
TRY(fh_heap_put(fh, &instr, INSTR_SIZE)); |
|
|
|
return FH_OK; |
|
|
|
return FH_OK; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -956,15 +956,15 @@ static enum fh_error w_repeat(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
TRY(cs_pop(fh, &destaddr)); |
|
|
|
TRY(cs_pop(fh, &destaddr)); |
|
|
|
TRY(cs_pop(fh, &origaddr)); |
|
|
|
TRY(cs_pop(fh, &origaddr)); |
|
|
|
|
|
|
|
|
|
|
|
struct fh_instruction_s *branch_instr = (void *) &fh->compile[origaddr]; |
|
|
|
struct fh_instruction_s *branch_instr = fh_instr_at(fh, origaddr); |
|
|
|
if (branch_instr->data != MAGICADDR_UNRESOLVED) { |
|
|
|
if (branch_instr->data != MAGICADDR_UNRESOLVED) { |
|
|
|
LOGE("REPEAT control stack corruption"); |
|
|
|
LOGE("REPEAT control stack corruption"); |
|
|
|
return FH_ERR_INTERNAL; |
|
|
|
return FH_ERR_INTERNAL; |
|
|
|
} |
|
|
|
} |
|
|
|
branch_instr->data = fh->compile_top + INSTR_SIZE; |
|
|
|
branch_instr->data = fh->here + INSTR_SIZE; |
|
|
|
|
|
|
|
|
|
|
|
instr_init(&instr, FH_INSTR_JUMP, destaddr); |
|
|
|
instr_init(&instr, FH_INSTR_JUMP, destaddr); |
|
|
|
TRY(fh_compile_put(fh, &instr, INSTR_SIZE)); |
|
|
|
TRY(fh_heap_put(fh, &instr, INSTR_SIZE)); |
|
|
|
|
|
|
|
|
|
|
|
return FH_OK; |
|
|
|
return FH_OK; |
|
|
|
} |
|
|
|
} |
|
|
@ -981,7 +981,7 @@ static enum fh_error w_again(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
TRY(cs_pop(fh, &destaddr)); |
|
|
|
TRY(cs_pop(fh, &destaddr)); |
|
|
|
|
|
|
|
|
|
|
|
instr_init(&instr, FH_INSTR_JUMP, destaddr); |
|
|
|
instr_init(&instr, FH_INSTR_JUMP, destaddr); |
|
|
|
TRY(fh_compile_put(fh, &instr, INSTR_SIZE)); |
|
|
|
TRY(fh_heap_put(fh, &instr, INSTR_SIZE)); |
|
|
|
|
|
|
|
|
|
|
|
return FH_OK; |
|
|
|
return FH_OK; |
|
|
|
} |
|
|
|
} |
|
|
@ -1031,7 +1031,7 @@ static enum fh_error w_unused(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
{ |
|
|
|
{ |
|
|
|
(void) w; |
|
|
|
(void) w; |
|
|
|
enum fh_error rv; |
|
|
|
enum fh_error rv; |
|
|
|
TRY(ds_push(fh, HEAP_SIZE - fh->heap_top)); |
|
|
|
TRY(ds_push(fh, HEAP_SIZE - fh->here)); |
|
|
|
return FH_OK; |
|
|
|
return FH_OK; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1126,7 +1126,7 @@ static enum fh_error w_comma(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
(void) w; |
|
|
|
(void) w; |
|
|
|
enum fh_error rv; |
|
|
|
enum fh_error rv; |
|
|
|
|
|
|
|
|
|
|
|
if (fh->heap_top & 3) { |
|
|
|
if (fh->here & 3) { |
|
|
|
LOGE("HERE not aligned before 'comma'"); |
|
|
|
LOGE("HERE not aligned before 'comma'"); |
|
|
|
return FH_ERR_ILLEGAL_STORE; |
|
|
|
return FH_ERR_ILLEGAL_STORE; |
|
|
|
} |
|
|
|
} |
|
|
@ -1141,7 +1141,7 @@ static enum fh_error w_align(struct fh_thread_s *fh, const struct fh_word_s *w) |
|
|
|
{ |
|
|
|
{ |
|
|
|
(void) w; |
|
|
|
(void) w; |
|
|
|
enum fh_error rv; |
|
|
|
enum fh_error rv; |
|
|
|
fh->heap_top = WORDALIGNED(fh->heap_top); |
|
|
|
fh->here = WORDALIGNED(fh->here); |
|
|
|
return FH_OK; |
|
|
|
return FH_OK; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|