add variables, fix negative allot not working

master
Ondřej Hruška 3 years ago
parent ef2e6943bd
commit 569536ae86
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 3
      include/fh_runtime.h
  2. 29
      src/fh_builtins_arith.c
  3. 35
      src/fh_builtins_mem.c
  4. 96
      src/fh_builtins_meta.c
  5. 17
      src/fh_runtime.c
  6. 13
      src/fh_see.c

@ -50,6 +50,9 @@ enum fb_instruction_kind {
/* DO loop initializer */ /* DO loop initializer */
FH_INSTR_DO, FH_INSTR_DO,
/* value TO var */
FH_INSTR_TO,
/* ?DO short-circuiting loop */ /* ?DO short-circuiting loop */
FH_INSTR_DO_QUESTION, FH_INSTR_DO_QUESTION,

@ -100,7 +100,7 @@ static enum fh_error w_zero_greater(struct fh_thread_s *fh, const struct fh_word
enum fh_error rv; enum fh_error rv;
uint32_t a = 0; uint32_t a = 0;
TRY(ds_pop(fh, &a)); TRY(ds_pop(fh, &a));
TRY(ds_push(fh, TOBOOL(a > 0))); TRY(ds_push(fh, TOBOOL((int32_t) a > 0)));
return FH_OK; return FH_OK;
} }
@ -132,11 +132,34 @@ static enum fh_error w_less(struct fh_thread_s *fh, const struct fh_word_s *w)
uint32_t a = 0, b = 0; uint32_t a = 0, b = 0;
TRY(ds_pop(fh, &b)); TRY(ds_pop(fh, &b));
TRY(ds_pop(fh, &a)); TRY(ds_pop(fh, &a));
TRY(ds_push(fh, TOBOOL(a < b))); TRY(ds_push(fh, TOBOOL((int32_t) a < (int32_t) b)));
return FH_OK; return FH_OK;
} }
static enum fh_error w_greater(struct fh_thread_s *fh, const struct fh_word_s *w) static enum fh_error w_greater(struct fh_thread_s *fh, const struct fh_word_s *w)
{
(void) w;
enum fh_error rv;
uint32_t a = 0, b = 0;
TRY(ds_pop(fh, &b));
TRY(ds_pop(fh, &a));
TRY(ds_push(fh, TOBOOL((int32_t) a > (int32_t) b)));
return FH_OK;
}
static enum fh_error w_u_less(struct fh_thread_s *fh, const struct fh_word_s *w)
{
(void) w;
enum fh_error rv;
uint32_t a = 0, b = 0;
TRY(ds_pop(fh, &b));
TRY(ds_pop(fh, &a));
TRY(ds_push(fh, TOBOOL(a < b)));
return FH_OK;
}
static enum fh_error w_u_greater(struct fh_thread_s *fh, const struct fh_word_s *w)
{ {
(void) w; (void) w;
enum fh_error rv; enum fh_error rv;
@ -333,9 +356,11 @@ const struct name_and_handler fh_builtins_arith[] = {
{"0<>", w_zero_not_equals, 0, 0}, {"0<>", w_zero_not_equals, 0, 0},
{"0>", w_zero_greater, 0, 0}, {"0>", w_zero_greater, 0, 0},
{"<", w_less, 0, 0}, {"<", w_less, 0, 0},
{"u<", w_u_less, 0, 0},
{"=", w_equals, 0, 0}, {"=", w_equals, 0, 0},
{"<>", w_not_equals, 0, 0}, {"<>", w_not_equals, 0, 0},
{">", w_greater, 0, 0}, {">", w_greater, 0, 0},
{"u>", w_u_greater, 0, 0},
{"1+", wp_add, 0, 1}, {"1+", wp_add, 0, 1},
{"1-", wp_add, 0, -1}, {"1-", wp_add, 0, -1},
{"2+", wp_add, 0, 2}, {"2+", wp_add, 0, 2},

@ -30,6 +30,21 @@ static enum fh_error w_store(struct fh_thread_s *fh, const struct fh_word_s *w)
return FH_OK; return FH_OK;
} }
static enum fh_error w_plus_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(fh_fetch(fh, addr, &val));
uint32_t val2 = 0;
TRY(ds_pop(fh, &val));
TRY(fh_store(fh, addr, val2 + val));
return FH_OK;
}
static enum fh_error w_two_store(struct fh_thread_s *fh, const struct fh_word_s *w) static enum fh_error w_two_store(struct fh_thread_s *fh, const struct fh_word_s *w)
{ {
(void) w; (void) w;
@ -75,7 +90,14 @@ static enum fh_error w_allot(struct fh_thread_s *fh, const struct fh_word_s *w)
enum fh_error rv; enum fh_error rv;
uint32_t count = 0; uint32_t count = 0;
TRY(ds_pop(fh, &count)); TRY(ds_pop(fh, &count));
TRY(fh_heap_reserve(fh, count, NULL)); int32_t ci = (int32_t) count;
if (ci > 0) {
TRY(fh_heap_reserve(fh, ci, NULL));
} else {
LOG("Deallot %d", count);
fh->here = WORDALIGNED((uint32_t) (int32_t)fh->here + count);
}
return FH_OK; return FH_OK;
} }
@ -117,6 +139,14 @@ static enum fh_error w_pad(struct fh_thread_s *fh, const struct fh_word_s *w)
return FH_OK; return FH_OK;
} }
static enum fh_error w_here(struct fh_thread_s *fh, const struct fh_word_s *w)
{
(void) w;
enum fh_error rv;
TRY(ds_push(fh, fh->here));
return FH_OK;
}
const struct name_and_handler fh_builtins_mem[] = { const struct name_and_handler fh_builtins_mem[] = {
{"chars", wp_mul, 0, 1}, {"chars", wp_mul, 0, 1},
{"char+", wp_add, 0, 1}, {"char+", wp_add, 0, 1},
@ -124,13 +154,14 @@ const struct name_and_handler fh_builtins_mem[] = {
{"cell+", wp_add, 0, CELL}, {"cell+", wp_add, 0, CELL},
{"@", w_fetch, 0, 0}, {"@", w_fetch, 0, 0},
{"!", w_store, 0, 0}, {"!", w_store, 0, 0},
{"+!", w_plus_store, 0, 0},
{"2!", w_two_store, 0, 0}, {"2!", w_two_store, 0, 0},
{"2@", w_two_fetch, 0, 0}, {"2@", w_two_fetch, 0, 0},
{"aligned", w_aligned, 0, 0}, {"aligned", w_aligned, 0, 0},
{"allot", w_allot, 0, 0}, {"allot", w_allot, 0, 0},
{"align", w_align, 0, 0}, {"align", w_align, 0, 0},
{",", w_comma, 0, 0}, {",", w_comma, 0, 0},
{"here", wp_const, 0, MAGICADDR_HERE}, {"here", w_here, 0, 0},
{"pad", w_pad, 0, 0}, {"pad", w_pad, 0, 0},
{ /* end marker */ } { /* end marker */ }

@ -71,6 +71,98 @@ static enum fh_error w_postpone(struct fh_thread_s *fh, const struct fh_word_s *
return FH_OK; return FH_OK;
} }
static enum fh_error w_read_value(struct fh_thread_s *fh, const struct fh_word_s *w)
{
enum fh_error rv;
ENSURE_STATE(FH_STATE_INTERPRET);
TRY(ds_push(fh, w->param));
return FH_OK;
}
static enum fh_error w_read_varaddr(struct fh_thread_s *fh, const struct fh_word_s *w)
{
enum fh_error rv;
ENSURE_STATE(FH_STATE_INTERPRET);
uint32_t addr = (void *) &w->param - (void *) &fh->heap[0]; // this is ugly
TRY(ds_push(fh, addr));
return FH_OK;
}
static enum fh_error wp_variable(struct fh_thread_s *fh, const struct fh_word_s *w)
{
(void) w;
enum fh_error rv;
ENSURE_STATE(FH_STATE_INTERPRET);
char *wordname;
size_t namelen = 0;
fh_input_consume_spaces(fh);
TRY(fh_input_read_word(fh, &wordname, &namelen));
uint32_t ptr;
uint32_t value = 0;
bool is_value = w->param == 1;
bool is_const = w->param == 2;
if (is_value || is_const) {
TRY(ds_pop(fh, &value));
}
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 = value;
new_word->handler = (is_value || is_const) ? w_read_value : w_read_varaddr;
strncpy(new_word->name, wordname, namelen);
new_word->name[namelen] = 0;
new_word->flags = (is_const ? WORDFLAG_CONSTANT : WORDFLAG_VARIABLE) | WORDFLAG_BUILTIN;
fh->dict_last = ptr;
return FH_OK;
}
static enum fh_error w_to(struct fh_thread_s *fh, const struct fh_word_s *w)
{
(void) w;
enum fh_error rv;
if (fh->state == FH_STATE_INTERPRET) {
uint32_t value;
TRY(ds_pop(fh, &value));
char *wordname;
size_t namelen = 0;
uint32_t waddr;
fh_input_consume_spaces(fh);
TRY(fh_input_read_word(fh, &wordname, &namelen));
TRY(fh_find_word(fh, wordname, namelen, &waddr));
struct fh_word_s *ww = fh_word_at(fh, waddr);
if (ww->flags & WORDFLAG_CONSTANT) {
LOGE("Cannot assign to constant!");
return FH_ERR_ILLEGAL_STORE;
}
ww->param = value;
} else if (fh->state == FH_STATE_COMPILE) {
// immediate
char *wordname;
size_t namelen = 0;
uint32_t waddr;
fh_input_consume_spaces(fh);
TRY(fh_input_read_word(fh, &wordname, &namelen));
TRY(fh_find_word(fh, wordname, namelen, &waddr));
TRY(fh_put_instr(fh, FH_INSTR_TO, waddr));
}
return FH_OK;
}
static enum fh_error w_leftbracket(struct fh_thread_s *fh, const struct fh_word_s *w) static enum fh_error w_leftbracket(struct fh_thread_s *fh, const struct fh_word_s *w)
{ {
(void) w; (void) w;
@ -172,6 +264,10 @@ const struct name_and_handler fh_builtins_meta[] = {
{"literal", w_literal, 1, 0}, {"literal", w_literal, 1, 0},
{"char", w_char, 0, 0}, {"char", w_char, 0, 0},
{"[char]", w_char, 1, 0}, {"[char]", w_char, 1, 0},
{"to", w_to, 1, 0},
{"variable", wp_variable, 1, 0},
{"value", wp_variable, 1, 1},
{"constant", wp_variable, 1, 2},
{ /* end marker */ } { /* end marker */ }
}; };

@ -193,7 +193,7 @@ enum fh_error w_user_word(struct fh_thread_s *fh, const struct fh_word_s *w0)
{ {
enum fh_error rv; enum fh_error rv;
const struct fh_word_s *w; const struct fh_word_s *w;
const struct fh_word_s *w2; struct fh_word_s *w2;
w = w0; w = w0;
call: call:
@ -220,7 +220,6 @@ enum fh_error w_user_word(struct fh_thread_s *fh, const struct fh_word_s *w0)
uint32_t addr = 0; uint32_t addr = 0;
uint32_t limit, index, index0; uint32_t limit, index, index0;
struct fh_instruction_s instr2;
switch (instr->kind) { switch (instr->kind) {
case FH_INSTR_NUMBER: case FH_INSTR_NUMBER:
TRY(ds_push(fh, instr->data)); TRY(ds_push(fh, instr->data));
@ -282,6 +281,19 @@ enum fh_error w_user_word(struct fh_thread_s *fh, const struct fh_word_s *w0)
fh->execptr = instr->data; fh->execptr = instr->data;
goto instr; goto instr;
case FH_INSTR_TO:
TRY(ds_pop(fh, &val));
w2 = fh_word_at(fh, instr->data);
LOG("Exec: %d->%s", val, w2->name);
if (w2->flags & WORDFLAG_CONSTANT) {
LOGE("Cannot assign to constant!");
return FH_ERR_ILLEGAL_STORE;
}
w2->param = val;
goto instr;
case FH_INSTR_DO: case FH_INSTR_DO:
TRY(ds_pop(fh, &index)); TRY(ds_pop(fh, &index));
TRY(ds_pop(fh, &limit)); // just make sure it exists TRY(ds_pop(fh, &limit)); // just make sure it exists
@ -388,7 +400,6 @@ enum fh_error fh_init(struct fh_thread_s *fh)
enum fh_error fh_handle_word(struct fh_thread_s *fh, uint32_t addr) enum fh_error fh_handle_word(struct fh_thread_s *fh, uint32_t addr)
{ {
struct fh_instruction_s instr;
enum fh_error rv; enum fh_error rv;
struct fh_word_s *w = fh_word_at(fh, addr); struct fh_word_s *w = fh_word_at(fh, addr);
if (fh->state == FH_STATE_COMPILE && 0 == (w->flags & WORDFLAG_IMMEDIATE)) { if (fh->state == FH_STATE_COMPILE && 0 == (w->flags & WORDFLAG_IMMEDIATE)) {

@ -38,6 +38,15 @@ static void show_word(struct fh_thread_s *fh, const struct fh_word_s *w)
} }
break; break;
case FH_INSTR_TO:
w2 = fh_word_at(fh, instr->data);
if (w2->name[0]) {
FHPRINT("To(var %s)\n", w2->name);
} else {
FHPRINT("To(var 0x%08x)\n", instr->data);
}
break;
case FH_INSTR_JUMPZERO: case FH_INSTR_JUMPZERO:
FHPRINT("JumpIfZero(dest 0x%08x)\n", instr->data); FHPRINT("JumpIfZero(dest 0x%08x)\n", instr->data);
break; break;
@ -83,12 +92,14 @@ static void show_word(struct fh_thread_s *fh, const struct fh_word_s *w)
FHPRINT("Unknown(kind 0x%08x, data 0x%08x)\n", instr->kind, instr->data); FHPRINT("Unknown(kind 0x%08x, data 0x%08x)\n", instr->kind, instr->data);
} }
} }
} else {
FHPRINT("Built-in word %s\n", w->name);
};
} else if (w->flags & WORDFLAG_VARIABLE) { } else if (w->flags & WORDFLAG_VARIABLE) {
FHPRINT("Variable %s = %d (0x%08x)\n", w->name, (int32_t)w->param, w->param); FHPRINT("Variable %s = %d (0x%08x)\n", w->name, (int32_t)w->param, w->param);
} else if (w->flags & WORDFLAG_CONSTANT) { } else if (w->flags & WORDFLAG_CONSTANT) {
FHPRINT("Constant %s = %d (0x%08x)\n", w->name, (int32_t)w->param, w->param); FHPRINT("Constant %s = %d (0x%08x)\n", w->name, (int32_t)w->param, w->param);
} }
}
} }
/** Decompile a word */ /** Decompile a word */

Loading…
Cancel
Save