begin while repeat

master
Ondřej Hruška 3 years ago
parent 2f0f1877fe
commit 5dc19b88ed
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 5
      loops.forth
  2. 79
      src/fh_builtins.c

@ -0,0 +1,5 @@
: test1 begin dup while 1 - dup . repeat ;
10 test1
: test2 begin 1 - dup . dup 0= until ;
10 test2

@ -82,8 +82,8 @@ static enum fh_error w_minus(struct fh_thread_s *fh, const struct fh_word_s *w)
(void) w; (void) w;
enum fh_error rv; enum fh_error rv;
uint32_t a = 0, b = 0; uint32_t a = 0, b = 0;
TRY(ds_pop(fh, &a));
TRY(ds_pop(fh, &b)); TRY(ds_pop(fh, &b));
TRY(ds_pop(fh, &a));
TRY(ds_push(fh, a - b)); TRY(ds_push(fh, a - b));
return FH_OK; 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; (void) w;
enum fh_error rv; enum fh_error rv;
struct fh_instruction_s instr;
ENSURE_STATE(FH_STATE_COMPILE); 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; 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) static enum fh_error wp_setbase(struct fh_thread_s *fh, const struct fh_word_s *w)
{ {
fh_setbase(fh, w->param); 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}, {"if", w_if, 1, 0},
{"else", w_else, 1, 0}, {"else", w_else, 1, 0},
{"then", w_then, 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 */ /* Syntax */
{":", w_colon, 0, 0}, {":", w_colon, 0, 0},
{";", w_semicolon, 1, 0}, {";", w_semicolon, 1, 0},
{"\\", w_backslash, 1, 0}, // line comment {"\\", w_backslash, 1, 0}, // line comment
{"(", w_paren, 1, 0}, // enclosed comment {"(", w_paren, 1, 0}, // enclosed comment
{"recurse", w_recurse, 1, 0},
{"reset", w_reset, 1, 0}, {"reset", w_reset, 1, 0},
{"immediate", w_immediate, 1, 0}, {"immediate", w_immediate, 1, 0},
{"postpone", w_postpone, 1, 0}, {"postpone", w_postpone, 1, 0},

Loading…
Cancel
Save