begin while repeat
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
: test1 begin dup while 1 - dup . repeat ;
|
||||
10 test1
|
||||
|
||||
: test2 begin 1 - dup . dup 0= until ;
|
||||
10 test2
|
||||
+76
-3
@@ -82,8 +82,8 @@ static enum fh_error w_minus(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
(void) w;
|
||||
enum fh_error rv;
|
||||
uint32_t a = 0, b = 0;
|
||||
TRY(ds_pop(fh, &a));
|
||||
TRY(ds_pop(fh, &b));
|
||||
TRY(ds_pop(fh, &a));
|
||||
TRY(ds_push(fh, a - b));
|
||||
return FH_OK;
|
||||
}
|
||||
@@ -778,7 +778,6 @@ static enum fh_error w_then(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
{
|
||||
(void) w;
|
||||
enum fh_error rv;
|
||||
struct fh_instruction_s instr;
|
||||
|
||||
ENSURE_STATE(FH_STATE_COMPILE);
|
||||
|
||||
@@ -794,6 +793,76 @@ static enum fh_error w_then(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
return FH_OK;
|
||||
}
|
||||
|
||||
static enum fh_error w_until(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
{
|
||||
(void) w;
|
||||
enum fh_error rv;
|
||||
struct fh_instruction_s instr;
|
||||
|
||||
ENSURE_STATE(FH_STATE_COMPILE);
|
||||
|
||||
uint32_t destaddr = 0;
|
||||
TRY(cs_pop(fh, &destaddr));
|
||||
|
||||
instr_init(&instr, FH_INSTR_JUMPZERO, destaddr);
|
||||
TRY(fh_compile_put(fh, &instr, INSTR_SIZE));
|
||||
return FH_OK;
|
||||
}
|
||||
|
||||
static enum fh_error w_begin(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
{
|
||||
(void) w;
|
||||
enum fh_error rv;
|
||||
ENSURE_STATE(FH_STATE_COMPILE);
|
||||
TRY(cs_push(fh, fh->compile_top)); /* dest */
|
||||
return FH_OK;
|
||||
}
|
||||
|
||||
static enum fh_error w_while(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
{
|
||||
(void) w;
|
||||
enum fh_error rv;
|
||||
struct fh_instruction_s instr;
|
||||
|
||||
ENSURE_STATE(FH_STATE_COMPILE);
|
||||
|
||||
uint32_t destaddr = 0;
|
||||
TRY(cs_pop(fh, &destaddr));
|
||||
|
||||
TRY(cs_push(fh, fh->compile_top)); // orig
|
||||
TRY(cs_push(fh, destaddr)); // dest
|
||||
|
||||
instr_init(&instr, FH_INSTR_JUMPZERO, MAGICADDR_UNRESOLVED);
|
||||
TRY(fh_compile_put(fh, &instr, INSTR_SIZE));
|
||||
return FH_OK;
|
||||
}
|
||||
|
||||
static enum fh_error w_repeat(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
{
|
||||
(void) w;
|
||||
enum fh_error rv;
|
||||
struct fh_instruction_s instr;
|
||||
|
||||
ENSURE_STATE(FH_STATE_COMPILE);
|
||||
|
||||
uint32_t origaddr = 0;
|
||||
uint32_t destaddr = 0;
|
||||
TRY(cs_pop(fh, &destaddr));
|
||||
TRY(cs_pop(fh, &origaddr));
|
||||
|
||||
struct fh_instruction_s *branch_instr = (void *) &fh->compile[origaddr];
|
||||
if (branch_instr->data != MAGICADDR_UNRESOLVED) {
|
||||
LOGE("REPEAT control stack corruption");
|
||||
return FH_ERR_INTERNAL;
|
||||
}
|
||||
branch_instr->data = fh->compile_top + INSTR_SIZE;
|
||||
|
||||
instr_init(&instr, FH_INSTR_JUMP, destaddr);
|
||||
TRY(fh_compile_put(fh, &instr, INSTR_SIZE));
|
||||
|
||||
return FH_OK;
|
||||
}
|
||||
|
||||
static enum fh_error wp_setbase(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
{
|
||||
fh_setbase(fh, w->param);
|
||||
@@ -998,12 +1067,16 @@ enum fh_error register_builtin_words(struct fh_thread_s *fh)
|
||||
{"if", w_if, 1, 0},
|
||||
{"else", w_else, 1, 0},
|
||||
{"then", w_then, 1, 0},
|
||||
{"recurse", w_recurse, 1, 0},
|
||||
{"begin", w_begin, 1, 0},
|
||||
{"while", w_while, 1, 0},
|
||||
{"repeat", w_repeat, 1, 0},
|
||||
{"until", w_until, 1, 0},
|
||||
/* Syntax */
|
||||
{":", w_colon, 0, 0},
|
||||
{";", w_semicolon, 1, 0},
|
||||
{"\\", w_backslash, 1, 0}, // line comment
|
||||
{"(", w_paren, 1, 0}, // enclosed comment
|
||||
{"recurse", w_recurse, 1, 0},
|
||||
{"reset", w_reset, 1, 0},
|
||||
{"immediate", w_immediate, 1, 0},
|
||||
{"postpone", w_postpone, 1, 0},
|
||||
|
||||
Reference in New Issue
Block a user