#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_fetch(struct fh_thread_s *fh, const struct fh_word_s *w) { (void) w; enum fh_error rv; uint32_t addr = 0; TRY(ds_pop(fh, &addr)); uint32_t val = 0; TRY(fh_fetch(fh, addr, &val)); TRY(ds_push(fh, val)); return FH_OK; } static enum fh_error w_store(struct fh_thread_s *fh, const struct fh_word_s *w) { (void) w; enum fh_error rv; uint32_t addr = 0; TRY(ds_pop(fh, &addr)); uint32_t val = 0; TRY(ds_pop(fh, &val)); TRY(fh_store(fh, addr, val)); return FH_OK; } static enum fh_error w_two_store(struct fh_thread_s *fh, const struct fh_word_s *w) { (void) w; enum fh_error rv; uint32_t addr = 0; TRY(ds_pop(fh, &addr)); uint32_t a = 0, b = 0; TRY(ds_pop(fh, &a)); TRY(ds_pop(fh, &b)); TRY(fh_store(fh, addr, a)); TRY(fh_store(fh, addr + CELL, b)); return FH_OK; } static enum fh_error w_two_fetch(struct fh_thread_s *fh, const struct fh_word_s *w) { (void) w; enum fh_error rv; uint32_t addr = 0; TRY(ds_pop(fh, &addr)); uint32_t a = 0, b = 0; TRY(fh_fetch(fh, addr, &a)); TRY(fh_fetch(fh, addr + CELL, &b)); TRY(ds_push(fh, b)); TRY(ds_push(fh, a)); return FH_OK; } static enum fh_error w_aligned(struct fh_thread_s *fh, const struct fh_word_s *w) { (void) w; enum fh_error rv; uint32_t addr = 0; TRY(ds_pop(fh, &addr)); TRY(ds_push(fh, WORDALIGNED(addr))); return FH_OK; } static enum fh_error w_allot(struct fh_thread_s *fh, const struct fh_word_s *w) { (void) w; enum fh_error rv; uint32_t count = 0; TRY(ds_pop(fh, &count)); TRY(fh_heap_reserve(fh, count, NULL)); return FH_OK; } static enum fh_error w_comma(struct fh_thread_s *fh, const struct fh_word_s *w) { (void) w; enum fh_error rv; if (fh->here & 3) { LOGE("HERE not aligned before 'comma'"); return FH_ERR_ILLEGAL_STORE; } uint32_t value = 0; TRY(ds_pop(fh, &value)); TRY(fh_heap_put(fh, &value, CELL)); return FH_OK; } static enum fh_error w_align(struct fh_thread_s *fh, const struct fh_word_s *w) { (void) w; enum fh_error rv; fh->here = WORDALIGNED(fh->here); return FH_OK; } static enum fh_error w_pad(struct fh_thread_s *fh, const struct fh_word_s *w) { (void) w; enum fh_error rv; uint32_t addr = fh->here + PAD_OFFSET; if (addr + 84 >= HEAP_END) { LOGE("Heap overflow, PAD is too small!"); return FH_ERR_HEAP_FULL; } TRY(ds_push(fh, addr)); return FH_OK; } const struct name_and_handler fh_builtins_mem[] = { {"chars", wp_mul, 0, 1}, {"char+", wp_add, 0, 1}, {"cells", wp_mul, 0, CELL}, {"cell+", wp_add, 0, CELL}, {"@", w_fetch, 0, 0}, {"!", w_store, 0, 0}, {"2!", w_two_store, 0, 0}, {"2@", w_two_fetch, 0, 0}, {"aligned", w_aligned, 0, 0}, {"allot", w_allot, 0, 0}, {"align", w_align, 0, 0}, {",", w_comma, 0, 0}, {"here", wp_const, 0, MAGICADDR_HERE}, {"pad", w_pad, 0, 0}, { /* end marker */ } };