implement exit

master
Ondřej Hruška 3 years ago
parent bc6d7e5d25
commit 8c006a0d87
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 3
      exit.forth
  2. 1
      include/fh_runtime.h
  3. 14
      src/fh_builtins.c
  4. 11
      src/fh_runtime.c

@ -0,0 +1,3 @@
: foo 1 . exit 2 . ;
: bar foo foo ;
bar

@ -75,6 +75,7 @@ enum fh_substate {
FH_SUBSTATE_DOTQUOTE,
FH_SUBSTATE_PARENCOMMENT,
FH_SUBSTATE_LINECOMMENT,
FH_SUBSTATE_EXIT,
FH_SUBSTATE_MAX,
};

@ -516,7 +516,7 @@ static enum fh_error w_abort(struct fh_thread_s *fh, const struct fh_word_s *w)
fh->data_stack_top = 0;
fh->return_stack_top = 0;
fh->state = FH_STATE_QUIT;
fh_setstate(fh, FH_STATE_QUIT, 0);
return FH_OK;
}
@ -526,7 +526,16 @@ static enum fh_error w_quit(struct fh_thread_s *fh, const struct fh_word_s *w)
(void) w;
fh->return_stack_top = 0;
fh->state = FH_STATE_QUIT;
fh_setstate(fh, FH_STATE_QUIT, 0);
return FH_OK;
}
static enum fh_error w_exit(struct fh_thread_s *fh, const struct fh_word_s *w)
{
(void) w;
fh_setsubstate(fh, FH_SUBSTATE_EXIT);
return FH_OK;
}
@ -711,6 +720,7 @@ enum fh_error register_builtin_words(struct fh_thread_s *fh)
/* Control flow */
{"abort", w_abort, 0, 0},
{"quit", w_quit, 0, 0},
{"exit", w_exit, 0, 0},
/* Syntax */
{":", w_colon, 0, 0},
{";", w_semicolon, 1, 0},

@ -27,6 +27,7 @@ static const char *substatenames[FH_SUBSTATE_MAX] = {
[FH_SUBSTATE_DOTQUOTE] = "DOTQUOTE",
[FH_SUBSTATE_PARENCOMMENT] = "PARENCOMMENT",
[FH_SUBSTATE_LINECOMMENT] = "LINECOMMENT",
[FH_SUBSTATE_EXIT] = "EXIT",
};
/** Add a word to the dictionary. */
@ -90,7 +91,7 @@ enum fh_error w_user_word(struct fh_thread_s *fh, const struct fh_word_s *w0)
// make sure it's aligned
fh->execptr = WORDALIGNED(fh->execptr);
const struct fh_instruction_s *instr = (const struct fh_instruction_s *) &fh->compile[fh->execptr];
fh->execptr += sizeof(struct fh_instruction_s);
fh->execptr += INSTR_SIZE;
uint32_t strl;
uint32_t addr = 0;
@ -134,6 +135,14 @@ enum fh_error w_user_word(struct fh_thread_s *fh, const struct fh_word_s *w0)
if (w2->builtin) {
LOG("Exec: builtin-word %s", w2->name);
w2->handler(fh, w2);
if (fh->substate == FH_SUBSTATE_EXIT) {
fh_setsubstate(fh, 0);
LOG("Exec: early return");
TRY(rs_pop(fh, &fh->execptr));
if (fh->execptr == MAGICADDR_INTERACTIVE) {
goto end;
}
}
goto instr;
} else {
LOG("Exec: user-word %s (CALL)", w2->name);

Loading…
Cancel
Save