From 8c006a0d87d04f52e82b49d15b222850d278273e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Sat, 13 Nov 2021 20:22:24 +0100 Subject: [PATCH] implement exit --- exit.forth | 3 +++ include/fh_runtime.h | 1 + src/fh_builtins.c | 16 +++++++++++++--- src/fh_runtime.c | 11 ++++++++++- 4 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 exit.forth diff --git a/exit.forth b/exit.forth new file mode 100644 index 0000000..5ece9ac --- /dev/null +++ b/exit.forth @@ -0,0 +1,3 @@ +: foo 1 . exit 2 . ; +: bar foo foo ; +bar diff --git a/include/fh_runtime.h b/include/fh_runtime.h index 0ded4e7..473064a 100644 --- a/include/fh_runtime.h +++ b/include/fh_runtime.h @@ -75,6 +75,7 @@ enum fh_substate { FH_SUBSTATE_DOTQUOTE, FH_SUBSTATE_PARENCOMMENT, FH_SUBSTATE_LINECOMMENT, + FH_SUBSTATE_EXIT, FH_SUBSTATE_MAX, }; diff --git a/src/fh_builtins.c b/src/fh_builtins.c index 6148a59..f4a99bd 100644 --- a/src/fh_builtins.c +++ b/src/fh_builtins.c @@ -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; } @@ -709,8 +718,9 @@ enum fh_error register_builtin_words(struct fh_thread_s *fh) {"space", w_space, 0, 0}, {"dump", w_dump, 0, 0}, /* Control flow */ - {"abort", w_abort, 0, 0}, + {"abort", w_abort, 0, 0}, {"quit", w_quit, 0, 0}, + {"exit", w_exit, 0, 0}, /* Syntax */ {":", w_colon, 0, 0}, {";", w_semicolon, 1, 0}, diff --git a/src/fh_runtime.c b/src/fh_runtime.c index bd35291..4cdea08 100644 --- a/src/fh_runtime.c +++ b/src/fh_runtime.c @@ -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);