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. 16
      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_DOTQUOTE,
FH_SUBSTATE_PARENCOMMENT, FH_SUBSTATE_PARENCOMMENT,
FH_SUBSTATE_LINECOMMENT, FH_SUBSTATE_LINECOMMENT,
FH_SUBSTATE_EXIT,
FH_SUBSTATE_MAX, 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->data_stack_top = 0;
fh->return_stack_top = 0; fh->return_stack_top = 0;
fh->state = FH_STATE_QUIT; fh_setstate(fh, FH_STATE_QUIT, 0);
return FH_OK; 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; (void) w;
fh->return_stack_top = 0; 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; return FH_OK;
} }
@ -709,8 +718,9 @@ enum fh_error register_builtin_words(struct fh_thread_s *fh)
{"space", w_space, 0, 0}, {"space", w_space, 0, 0},
{"dump", w_dump, 0, 0}, {"dump", w_dump, 0, 0},
/* Control flow */ /* Control flow */
{"abort", w_abort, 0, 0}, {"abort", w_abort, 0, 0},
{"quit", w_quit, 0, 0}, {"quit", w_quit, 0, 0},
{"exit", w_exit, 0, 0},
/* Syntax */ /* Syntax */
{":", w_colon, 0, 0}, {":", w_colon, 0, 0},
{";", w_semicolon, 1, 0}, {";", w_semicolon, 1, 0},

@ -27,6 +27,7 @@ static const char *substatenames[FH_SUBSTATE_MAX] = {
[FH_SUBSTATE_DOTQUOTE] = "DOTQUOTE", [FH_SUBSTATE_DOTQUOTE] = "DOTQUOTE",
[FH_SUBSTATE_PARENCOMMENT] = "PARENCOMMENT", [FH_SUBSTATE_PARENCOMMENT] = "PARENCOMMENT",
[FH_SUBSTATE_LINECOMMENT] = "LINECOMMENT", [FH_SUBSTATE_LINECOMMENT] = "LINECOMMENT",
[FH_SUBSTATE_EXIT] = "EXIT",
}; };
/** Add a word to the dictionary. */ /** 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 // make sure it's aligned
fh->execptr = WORDALIGNED(fh->execptr); fh->execptr = WORDALIGNED(fh->execptr);
const struct fh_instruction_s *instr = (const struct fh_instruction_s *) &fh->compile[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 strl;
uint32_t addr = 0; 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) { if (w2->builtin) {
LOG("Exec: builtin-word %s", w2->name); LOG("Exec: builtin-word %s", w2->name);
w2->handler(fh, w2); 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; goto instr;
} else { } else {
LOG("Exec: user-word %s (CALL)", w2->name); LOG("Exec: user-word %s (CALL)", w2->name);

Loading…
Cancel
Save