#include #include "fh_error.h" #include "fh_runtime.h" #include "fh_mem.h" #include "fh_stack.h" #include "fh_print.h" #include "fh_builtins.h" static enum fh_error w_colon(struct fh_thread_s *fh, const struct fh_word_s *w) { (void) w; enum fh_error rv; ENSURE_STATE(FH_STATE_INTERPRET); char *wordname = NULL; size_t namelen = 0; fh_input_consume_spaces(fh); TRY(fh_input_read_word(fh, &wordname, &namelen)); LOG("Name: %.*s", namelen, wordname); fh_setstate(fh, FH_STATE_COMPILE, 0); uint32_t ptr; TRY(fh_heap_reserve(fh, DICTWORD_SIZE, &ptr)); struct fh_word_s *new_word = fh_word_at(fh, ptr); new_word->previous = fh->dict_last; new_word->param = fh->here; new_word->handler = w_user_word; strncpy(new_word->name, wordname, namelen); new_word->name[namelen] = 0; new_word->flags = WORDFLAG_WORD; fh->dict_last = ptr; return FH_OK; } static enum fh_error w_forget(struct fh_thread_s *fh, const struct fh_word_s *w) { (void) w; enum fh_error rv; ENSURE_STATE(FH_STATE_INTERPRET); char *wordname = NULL; size_t namelen = 0; fh_input_consume_spaces(fh); TRY(fh_input_read_word(fh, &wordname, &namelen)); LOG("Name to forget: %.*s", namelen, wordname); uint32_t addr; TRY(fh_find_word(fh, wordname, namelen, &addr)); struct fh_word_s *removedword = fh_word_at(fh, addr); fh->dict_last = removedword->previous; return FH_OK; } static enum fh_error w_postpone(struct fh_thread_s *fh, const struct fh_word_s *w) { (void) w; enum fh_error rv; ENSURE_STATE(FH_STATE_COMPILE); char *wordname; size_t namelen = 0; fh_input_consume_spaces(fh); TRY(fh_input_read_word(fh, &wordname, &namelen)); TRY(fh_postpone_word(fh, wordname, namelen)); return FH_OK; } static enum fh_error w_leftbracket(struct fh_thread_s *fh, const struct fh_word_s *w) { (void) w; ENSURE_STATE(FH_STATE_COMPILE); fh_setstate(fh, FH_STATE_INTERPRET, 0); return FH_OK; } static enum fh_error w_rightbracket(struct fh_thread_s *fh, const struct fh_word_s *w) { (void) w; ENSURE_STATE(FH_STATE_INTERPRET); fh_setstate(fh, FH_STATE_COMPILE, 0); return FH_OK; } static enum fh_error w_literal(struct fh_thread_s *fh, const struct fh_word_s *w) { (void) w; enum fh_error rv; ENSURE_STATE(FH_STATE_COMPILE); uint32_t val; TRY(ds_pop(fh, &val)); TRY(fh_put_instr(fh, FH_INSTR_NUMBER, val)); return FH_OK; } static enum fh_error w_semicolon(struct fh_thread_s *fh, const struct fh_word_s *w0) { (void) w0; enum fh_error rv; ENSURE_STATE(FH_STATE_COMPILE); TRY(fh_put_instr(fh, FH_INSTR_ENDWORD, 0)); /* Return to interpret state */ fh_setstate(fh, FH_STATE_INTERPRET, 0); // XXX if there was another definition previously and it was used in some other compiled function, // that old implementation will still be called. return FH_OK; } static enum fh_error w_immediate(struct fh_thread_s *fh, const struct fh_word_s *w) { (void) w; enum fh_error rv; if (fh->dict_last == 0) { LOGE("Dict is empty, cannot modify previous word!"); return FH_ERR_INVALID_STATE; } fh_word_at(fh, fh->dict_last)->flags |= WORDFLAG_IMMEDIATE; return FH_OK; } static enum fh_error w_backslash(struct fh_thread_s *fh, const struct fh_word_s *w) { (void) w; fh_setsubstate(fh, FH_SUBSTATE_LINE_COMMENT); return FH_OK; } static enum fh_error w_paren(struct fh_thread_s *fh, const struct fh_word_s *w) { (void) w; fh_setsubstate(fh, FH_SUBSTATE_PAREN_COMMENT); return FH_OK; } static enum fh_error w_char(struct fh_thread_s *fh, const struct fh_word_s *w) { (void) w; enum fh_error rv; char *wordname = NULL; size_t namelen = 0; fh_input_consume_spaces(fh); TRY(fh_input_read_word(fh, &wordname, &namelen)); TRY(ds_push(fh, (char) *wordname)); return FH_OK; } const struct name_and_handler fh_builtins_meta[] = { {":", w_colon, 0, 0}, {";", w_semicolon, 1, 0}, {"forget", w_forget, 1, 0}, {"\\", w_backslash, 1, 0}, // line comment {"(", w_paren, 1, 0}, // enclosed comment {"immediate", w_immediate, 0, 0}, {"postpone", w_postpone, 1, 0}, {"[", w_leftbracket, 1, 0}, {"]", w_rightbracket, 1, 0}, {"literal", w_literal, 1, 0}, {"char", w_char, 0, 0}, {"[char]", w_char, 1, 0}, { /* end marker */ } };