reformat code, some cleaning
This commit is contained in:
@@ -36,7 +36,9 @@ extern const struct name_and_handler fh_builtins_text[];
|
||||
extern const struct name_and_handler fh_builtins_system[];
|
||||
|
||||
enum fh_error wp_const(struct fh_thread_s *fh, const struct fh_word_s *w);
|
||||
|
||||
enum fh_error wp_mul(struct fh_thread_s *fh, const struct fh_word_s *w);
|
||||
|
||||
enum fh_error wp_add(struct fh_thread_s *fh, const struct fh_word_s *w);
|
||||
|
||||
#endif //FORTH_FH_BUILTINS_H
|
||||
|
||||
@@ -26,15 +26,21 @@ enum fh_error fh_heap_reserve(
|
||||
size_t len,
|
||||
uint32_t *addr
|
||||
);
|
||||
|
||||
void fh_heap_write(struct fh_thread_s *fh, uint32_t addr, const void *src, uint32_t len);
|
||||
|
||||
enum fh_error fh_heap_put(struct fh_thread_s *fh, const void *src, uint32_t len);
|
||||
|
||||
void fh_heap_copy(struct fh_thread_s *fh, uint32_t addr, uint32_t srcaddr, uint32_t len);
|
||||
|
||||
void fh_heap_copyptr(struct fh_thread_s *fh, uint32_t addr, char *source, uint32_t len);
|
||||
|
||||
enum fh_error fh_put_instr(struct fh_thread_s *fh, enum fh_instruction_kind kind, uint32_t data);
|
||||
|
||||
char *fh_str_at(struct fh_thread_s *fh, uint32_t addr);
|
||||
|
||||
struct fh_instruction_s *fh_instr_at(struct fh_thread_s *fh, uint32_t addr);
|
||||
|
||||
struct fh_word_s *fh_word_at(struct fh_thread_s *fh, uint32_t addr);
|
||||
|
||||
#endif //FORTH_FH_MEM_H
|
||||
|
||||
@@ -267,7 +267,8 @@ enum fh_error fh_init(struct fh_thread_s *fh);
|
||||
|
||||
enum fh_error fh_process_line(struct fh_thread_s *fh, const char *linebuf, size_t len);
|
||||
|
||||
static inline uint32_t word_addr(struct fh_thread_s *fh, const struct fh_word_s *w) {
|
||||
static inline uint32_t word_addr(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
{
|
||||
return (uint32_t) ((void *) w - (void *) &fh->heap[0]);
|
||||
}
|
||||
|
||||
|
||||
+13
-3
@@ -11,14 +11,18 @@ enum fh_error ds_roll(struct fh_thread_s *fh, int n);
|
||||
|
||||
/** Peek n-th element of data stack, 0=topmost */
|
||||
enum fh_error ds_peek_n(struct fh_thread_s *fh, uint32_t *out, int n);
|
||||
|
||||
/** Peek n-th element of return stack, 0=topmost */
|
||||
enum fh_error rs_peek_n(struct fh_thread_s *fh, uint32_t *out, int n);
|
||||
|
||||
/** Peek n-th element of control stack, 0=topmost */
|
||||
static inline enum fh_error cs_peek_n(struct fh_thread_s *fh, uint32_t *out, int n) {
|
||||
static inline enum fh_error cs_peek_n(struct fh_thread_s *fh, uint32_t *out, int n)
|
||||
{
|
||||
return ds_peek_n(fh, out, n);
|
||||
}
|
||||
|
||||
enum fh_error ds_push_dw(struct fh_thread_s *fh, uint64_t in);
|
||||
|
||||
enum fh_error ds_pop_dw(struct fh_thread_s *fh, uint64_t *out);
|
||||
|
||||
enum fh_error rs_poke_n(struct fh_thread_s *fh, uint32_t value, int n);
|
||||
@@ -42,14 +46,20 @@ static inline enum fh_error cs_peek(struct fh_thread_s *fh, uint32_t *out)
|
||||
}
|
||||
|
||||
enum fh_error ds_pop(struct fh_thread_s *fh, uint32_t *out);
|
||||
|
||||
enum fh_error rs_pop(struct fh_thread_s *fh, uint32_t *out);
|
||||
static inline enum fh_error cs_pop(struct fh_thread_s *fh, uint32_t *out) {
|
||||
|
||||
static inline enum fh_error cs_pop(struct fh_thread_s *fh, uint32_t *out)
|
||||
{
|
||||
return ds_pop(fh, out);
|
||||
}
|
||||
|
||||
enum fh_error ds_push(struct fh_thread_s *fh, uint32_t in);
|
||||
|
||||
enum fh_error rs_push(struct fh_thread_s *fh, uint32_t in);
|
||||
static inline enum fh_error cs_push(struct fh_thread_s *fh, uint32_t in) {
|
||||
|
||||
static inline enum fh_error cs_push(struct fh_thread_s *fh, uint32_t in)
|
||||
{
|
||||
return ds_push(fh, in);
|
||||
}
|
||||
|
||||
|
||||
+18
-28
@@ -277,15 +277,6 @@ enum fh_error wp_mul(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
return FH_OK;
|
||||
}
|
||||
|
||||
static enum fh_error wp_div(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
{
|
||||
enum fh_error rv;
|
||||
uint32_t a = 0;
|
||||
TRY(ds_pop(fh, &a));
|
||||
TRY(ds_push(fh, (int32_t) a / (int32_t) w->param));
|
||||
return FH_OK;
|
||||
}
|
||||
|
||||
static enum fh_error w_2div(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
{
|
||||
(void) w;
|
||||
@@ -328,9 +319,9 @@ static enum fh_error w_star_slash_mod(struct fh_thread_s *fh, const struct fh_wo
|
||||
return FH_ERR_ARITH;
|
||||
}
|
||||
|
||||
int64_t product = ((int64_t) (int32_t)a * (int64_t) (int32_t)b);
|
||||
int64_t v = product / (int64_t) (int32_t)c;
|
||||
int64_t m = product % (int64_t) (int32_t)c;
|
||||
const int64_t product = ((int64_t) (int32_t) a * (int64_t) (int32_t) b);
|
||||
const int64_t v = product / (int64_t) (int32_t) c;
|
||||
const int64_t m = product % (int64_t) (int32_t) c;
|
||||
|
||||
TRY(ds_push(fh, (uint32_t) (int32_t) m));
|
||||
TRY(ds_push(fh, (uint32_t) (int32_t) v));
|
||||
@@ -360,7 +351,7 @@ static enum fh_error w_abs(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
uint32_t a = 0;
|
||||
TRY(ds_pop(fh, &a));
|
||||
|
||||
int32_t sa = (int32_t) a; // TODO is this right?
|
||||
int32_t sa = (int32_t) a;
|
||||
|
||||
if (sa < 0) { sa = -sa; }
|
||||
|
||||
@@ -400,8 +391,8 @@ static enum fh_error w_slash_mod(struct fh_thread_s *fh, const struct fh_word_s
|
||||
return FH_ERR_ARITH;
|
||||
}
|
||||
|
||||
int32_t rem = (int32_t)a % (int32_t)b;
|
||||
int32_t div = (int32_t)a / (int32_t)b;
|
||||
const int32_t rem = (int32_t) a % (int32_t) b;
|
||||
const int32_t div = (int32_t) a / (int32_t) b;
|
||||
|
||||
TRY(ds_push(fh, rem));
|
||||
TRY(ds_push(fh, div));
|
||||
@@ -420,7 +411,7 @@ static enum fh_error w_mod(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
return FH_ERR_ARITH;
|
||||
}
|
||||
|
||||
int32_t rem = (int32_t)a % (int32_t)b;
|
||||
const int32_t rem = (int32_t) a % (int32_t) b;
|
||||
|
||||
TRY(ds_push(fh, rem));
|
||||
return FH_OK;
|
||||
@@ -433,8 +424,8 @@ static enum fh_error w_s_to_d(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
uint32_t a = 0;
|
||||
TRY(ds_pop(fh, &a));
|
||||
|
||||
int32_t as = (int32_t) a; // because of sign extend
|
||||
int64_t a64 = as;
|
||||
const int32_t as = (int32_t) a; // because of sign extend
|
||||
const int64_t a64 = as;
|
||||
|
||||
TRY(ds_push_dw(fh, (uint64_t) a64));
|
||||
return FH_OK;
|
||||
@@ -449,7 +440,7 @@ static enum fh_error w_m_star(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
TRY(ds_pop(fh, &b));
|
||||
|
||||
// make signed and then sign extend
|
||||
int64_t res = (int64_t) (int32_t) a * (int64_t) (int32_t) b;
|
||||
const int64_t res = (int64_t) (int32_t) a * (int64_t) (int32_t) b;
|
||||
|
||||
TRY(ds_push_dw(fh, (uint64_t) res));
|
||||
return FH_OK;
|
||||
@@ -464,7 +455,7 @@ static enum fh_error w_um_star(struct fh_thread_s *fh, const struct fh_word_s *w
|
||||
TRY(ds_pop(fh, &b));
|
||||
|
||||
// make signed and then sign extend
|
||||
uint64_t res = (uint64_t) a * (uint64_t) b;
|
||||
const uint64_t res = (uint64_t) a * (uint64_t) b;
|
||||
|
||||
TRY(ds_push_dw(fh, res));
|
||||
return FH_OK;
|
||||
@@ -473,13 +464,12 @@ static enum fh_error w_um_star(struct fh_thread_s *fh, const struct fh_word_s *w
|
||||
// Copied from https://stackoverflow.com/a/51457071/2180189
|
||||
void floor_div64(int64_t *q, int64_t *r, int64_t a, int64_t b)
|
||||
{
|
||||
int64_t q0 = a / b;
|
||||
int64_t r0 = a % b;
|
||||
const int64_t q0 = a / b;
|
||||
const int64_t r0 = a % b;
|
||||
if (b > 0) {
|
||||
*q = r0 >= 0 ? q0 : q0 - 1;
|
||||
*r = r0 >= 0 ? r0 : r0 + b;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
*q = r0 <= 0 ? q0 : q0 - 1;
|
||||
*r = r0 <= 0 ? r0 : r0 + b;
|
||||
}
|
||||
@@ -521,8 +511,8 @@ static enum fh_error w_um_mod(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
TRY(ds_pop(fh, &div));
|
||||
TRY(ds_pop_dw(fh, &num));
|
||||
|
||||
uint64_t res = num / (uint64_t)div;
|
||||
uint64_t rem = num % (uint64_t)div;
|
||||
const uint64_t res = num / (uint64_t) div;
|
||||
const uint64_t rem = num % (uint64_t) div;
|
||||
|
||||
if ((uint64_t) (uint32_t) rem != rem) {
|
||||
LOGE("Remainder too large");
|
||||
@@ -547,8 +537,8 @@ static enum fh_error w_sm_rem(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
TRY(ds_pop(fh, (uint32_t *) &div));
|
||||
TRY(ds_pop_dw(fh, (uint64_t *) &num));
|
||||
|
||||
int64_t res = num / (int64_t)div;
|
||||
int64_t rem = num % (int64_t)div;
|
||||
const int64_t res = num / (int64_t) div;
|
||||
const int64_t rem = num % (int64_t) div;
|
||||
|
||||
if ((int64_t) (int32_t) rem != rem) {
|
||||
LOGE("Remainder too large");
|
||||
|
||||
@@ -225,7 +225,6 @@ static enum fh_error wp_ij(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
}
|
||||
|
||||
|
||||
|
||||
static enum fh_error w_case(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
{
|
||||
(void) w;
|
||||
|
||||
@@ -117,13 +117,13 @@ static enum fh_error w_buffer_colon(struct fh_thread_s *fh, const struct fh_word
|
||||
size_t namelen = 0;
|
||||
fh_input_consume_spaces(fh);
|
||||
TRY(fh_input_read_word(fh, &wordname, &namelen));
|
||||
LOG("Buffer name: %.*s", namelen, wordname);
|
||||
LOG("Buffer name: %.*s", (int) namelen, wordname);
|
||||
|
||||
uint32_t ptr;
|
||||
TRY(fh_heap_reserve(fh, DICTWORD_SIZE + count, &ptr));
|
||||
|
||||
struct fh_word_s *new_word = fh_word_at(fh, ptr);
|
||||
if (!new_word) return FH_ERR_INTERNAL;
|
||||
if (!new_word) { return FH_ERR_INTERNAL; }
|
||||
new_word->previous = fh->dict_last;
|
||||
new_word->param = ptr + DICTWORD_SIZE;
|
||||
new_word->handler = rt_read_buffer_addr;
|
||||
@@ -219,7 +219,6 @@ static enum fh_error w_c_fetch(struct fh_thread_s *fh, const struct fh_word_s *w
|
||||
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;
|
||||
}
|
||||
|
||||
+43
-60
@@ -10,7 +10,7 @@ static enum fh_error w_colon(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
size_t namelen = 0;
|
||||
fh_input_consume_spaces(fh);
|
||||
TRY(fh_input_read_word(fh, &wordname, &namelen));
|
||||
LOG("Name: %.*s", namelen, wordname);
|
||||
LOG("Name: %.*s", (int) namelen, wordname);
|
||||
|
||||
fh_setstate(fh, FH_STATE_COMPILE, 0);
|
||||
|
||||
@@ -18,7 +18,7 @@ static enum fh_error w_colon(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
TRY(fh_heap_reserve(fh, DICTWORD_SIZE, &ptr));
|
||||
|
||||
struct fh_word_s *new_word = fh_word_at(fh, ptr);
|
||||
if (!new_word) return FH_ERR_INTERNAL;
|
||||
if (!new_word) { return FH_ERR_INTERNAL; }
|
||||
new_word->previous = fh->dict_last;
|
||||
new_word->param = fh->here;
|
||||
new_word->handler = w_user_word;
|
||||
@@ -48,13 +48,13 @@ static enum fh_error w_marker(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
size_t namelen = 0;
|
||||
fh_input_consume_spaces(fh);
|
||||
TRY(fh_input_read_word(fh, &wordname, &namelen));
|
||||
LOG("Marker name: %.*s", namelen, wordname);
|
||||
LOG("Marker name: %.*s", (int) namelen, wordname);
|
||||
|
||||
uint32_t ptr;
|
||||
TRY(fh_heap_reserve(fh, DICTWORD_SIZE, &ptr));
|
||||
|
||||
struct fh_word_s *new_word = fh_word_at(fh, ptr);
|
||||
if (!new_word) return FH_ERR_INTERNAL;
|
||||
if (!new_word) { return FH_ERR_INTERNAL; }
|
||||
new_word->previous = fh->dict_last;
|
||||
new_word->param = fh->dict_last;
|
||||
new_word->handler = rt_marker;
|
||||
@@ -81,7 +81,7 @@ static enum fh_error w_colon_noname(struct fh_thread_s *fh, const struct fh_word
|
||||
TRY(fh_heap_reserve(fh, DICTWORD_SIZE, &ptr));
|
||||
|
||||
struct fh_word_s *new_word = fh_word_at(fh, ptr);
|
||||
if (!new_word) return FH_ERR_INTERNAL;
|
||||
if (!new_word) { return FH_ERR_INTERNAL; }
|
||||
//new_word->previous = MAGICADDR_DICTFIRST;
|
||||
new_word->previous = fh->dict_last;
|
||||
new_word->param = fh->here;
|
||||
@@ -103,7 +103,7 @@ static enum fh_error w_does(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
|
||||
if (fh->executing_compiled) {
|
||||
struct fh_word_s *last_word = fh_word_at(fh, fh->dict_last);
|
||||
if (!last_word) return FH_ERR_INTERNAL;
|
||||
if (!last_word) { return FH_ERR_INTERNAL; }
|
||||
last_word->param = fh->execptr + INSTR_SIZE;
|
||||
last_word->handler = w_user_word;
|
||||
last_word->flags = WORDFLAG_WORD | WORDFLAG_CREATED;
|
||||
@@ -119,7 +119,7 @@ static enum fh_error w_does(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
fh_setstate(fh, FH_STATE_COMPILE, 0);
|
||||
|
||||
struct fh_word_s *last_word = fh_word_at(fh, fh->dict_last);
|
||||
if (!last_word) return FH_ERR_INTERNAL;
|
||||
if (!last_word) { return FH_ERR_INTERNAL; }
|
||||
|
||||
last_word->handler = w_user_word;
|
||||
last_word->param = fh->here;
|
||||
@@ -138,13 +138,13 @@ static enum fh_error w_forget(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
size_t namelen = 0;
|
||||
fh_input_consume_spaces(fh);
|
||||
TRY(fh_input_read_word(fh, &wordname, &namelen));
|
||||
LOG("Name to forget: %.*s", namelen, wordname);
|
||||
LOG("Name to forget: %.*s", (int) namelen, wordname);
|
||||
|
||||
uint32_t addr;
|
||||
TRY(fh_find_word(fh, wordname, namelen, &addr));
|
||||
|
||||
struct fh_word_s *removedword = fh_word_at(fh, addr);
|
||||
if (!removedword) return FH_ERR_INTERNAL;
|
||||
if (!removedword) { return FH_ERR_INTERNAL; }
|
||||
fh->dict_last = removedword->previous;
|
||||
return FH_OK;
|
||||
}
|
||||
@@ -210,7 +210,7 @@ static enum fh_error wp_variable(struct fh_thread_s *fh, const struct fh_word_s
|
||||
TRY(fh_heap_reserve(fh, DICTWORD_SIZE, &ptr));
|
||||
|
||||
struct fh_word_s *new_word = fh_word_at(fh, ptr);
|
||||
if (!new_word) return FH_ERR_INTERNAL;
|
||||
if (!new_word) { return FH_ERR_INTERNAL; }
|
||||
new_word->previous = fh->dict_last;
|
||||
new_word->param = value;
|
||||
new_word->handler = (is_value || is_const) ? rt_read_value : rt_read_varaddr;
|
||||
@@ -247,7 +247,7 @@ static enum fh_error w_to(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
TRY(fh_find_word(fh, wordname, namelen, &waddr));
|
||||
|
||||
struct fh_word_s *ww = fh_word_at(fh, waddr);
|
||||
if (!ww) return FH_ERR_INTERNAL;
|
||||
if (!ww) { return FH_ERR_INTERNAL; }
|
||||
|
||||
if (ww->flags & WORDFLAG_WORD) {
|
||||
LOGE("Cannot assign to dictionary word param field!");
|
||||
@@ -352,15 +352,13 @@ static enum fh_error w_compile_comma(struct fh_thread_s *fh, const struct fh_wor
|
||||
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;
|
||||
}
|
||||
|
||||
struct fh_word_s *word = fh_word_at(fh, fh->dict_last);
|
||||
if (!word) return FH_ERR_INTERNAL;
|
||||
if (!word) { return FH_ERR_INTERNAL; }
|
||||
word->flags |= WORDFLAG_IMMEDIATE;
|
||||
|
||||
return FH_OK;
|
||||
@@ -432,7 +430,7 @@ static enum fh_error w_to_body(struct fh_thread_s *fh, const struct fh_word_s *w
|
||||
|
||||
uint32_t xt;
|
||||
TRY(ds_pop(fh, &xt)); // xt is now a dict entry (hopefully)
|
||||
TRY(ds_push(fh, xt + DICTWORD_SIZE)); // XXX should it still point here if DOES> was used?
|
||||
TRY(ds_push(fh, xt + DICTWORD_SIZE));
|
||||
return FH_OK;
|
||||
}
|
||||
|
||||
@@ -467,7 +465,7 @@ static enum fh_error w_word(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
fh_store_char(fh, WORDBUF_ADDR, (char) len);
|
||||
fh_heap_copyptr(fh, WORDBUF_ADDR + 1, out, len);
|
||||
|
||||
LOG("Word found: \"%.*s\"", len, out);
|
||||
LOG("Word found: \"%.*s\"", (int) len, out);
|
||||
|
||||
TRY(ds_push(fh, WORDBUF_ADDR));
|
||||
return FH_OK;
|
||||
@@ -503,7 +501,7 @@ static enum fh_error w_create(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
TRY(fh_heap_reserve(fh, DICTWORD_SIZE, &ptr));
|
||||
|
||||
struct fh_word_s *new_word = fh_word_at(fh, ptr);
|
||||
if (!new_word) return FH_ERR_INTERNAL;
|
||||
if (!new_word) { return FH_ERR_INTERNAL; }
|
||||
new_word->previous = fh->dict_last;
|
||||
new_word->param = fh->here;
|
||||
new_word->handler = rt_read_value;
|
||||
@@ -537,7 +535,7 @@ static enum fh_error w_find(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
}
|
||||
|
||||
struct fh_word_s *word = fh_word_at(fh, addr);
|
||||
if (!word) return FH_ERR_INTERNAL;
|
||||
if (!word) { return FH_ERR_INTERNAL; }
|
||||
|
||||
TRY(ds_push(fh, addr));
|
||||
TRY(ds_push(fh, (word->flags & WORDFLAG_IMMEDIATE) ? 1 : -1));
|
||||
@@ -617,56 +615,41 @@ static enum fh_error w_env_query(struct fh_thread_s *fh, const struct fh_word_s
|
||||
if (EQ(str, "/COUNTED-STRING", len)) {
|
||||
TRY(ds_push(fh, 255));
|
||||
TRY(ds_push(fh, 1));
|
||||
}
|
||||
else if (EQ(str, "/HOLD", len)) {
|
||||
} else if (EQ(str, "/HOLD", len)) {
|
||||
TRY(ds_push(fh, WORDBUF_SIZE));
|
||||
TRY(ds_push(fh, 1));
|
||||
}
|
||||
else if (EQ(str, "/PAD", len)) {
|
||||
} else if (EQ(str, "/PAD", len)) {
|
||||
TRY(ds_push(fh, MIN_PAD_SIZE));
|
||||
TRY(ds_push(fh, 1));
|
||||
}
|
||||
else if (EQ(str, "ADDRESS-UNIT-BITS", len)) {
|
||||
} else if (EQ(str, "ADDRESS-UNIT-BITS", len)) {
|
||||
TRY(ds_push(fh, 8));
|
||||
TRY(ds_push(fh, 1));
|
||||
}
|
||||
else if (EQ(str, "FLOORED", len)) {
|
||||
TRY(ds_push(fh, TOBOOL(1))); // FIXME is it?
|
||||
TRY(ds_push(fh, 1));
|
||||
}
|
||||
else if (EQ(str, "MAX-CHAR", len)) {
|
||||
TRY(ds_push(fh, 255));
|
||||
TRY(ds_push(fh, 1));
|
||||
}
|
||||
else if (EQ(str, "MAX-D", len)) {
|
||||
// TODO update when double arith is properly implemented
|
||||
TRY(ds_push(fh, 0));
|
||||
}
|
||||
else if (EQ(str, "MAX-UD", len)) {
|
||||
// TODO update when double arith is properly implemented
|
||||
TRY(ds_push(fh, 0));
|
||||
}
|
||||
else if (EQ(str, "MAX-N", len)) {
|
||||
TRY(ds_push(fh, 0x7FFFFFFFULL));
|
||||
TRY(ds_push(fh, 1));
|
||||
}
|
||||
else if (EQ(str, "MAX-U", len)) {
|
||||
TRY(ds_push(fh, 0xFFFFFFFFULL));
|
||||
TRY(ds_push(fh, 1));
|
||||
}
|
||||
else if (EQ(str, "RETURN-STACK-CELLS", len)) {
|
||||
TRY(ds_push(fh, RETURN_STACK_DEPTH));
|
||||
TRY(ds_push(fh, 1));
|
||||
}
|
||||
else if (EQ(str, "STACK-CELLS", len)) {
|
||||
TRY(ds_push(fh, DATA_STACK_DEPTH));
|
||||
TRY(ds_push(fh, 1));
|
||||
}
|
||||
else if (EQ(str, "CORE", len)) {
|
||||
} else if (EQ(str, "FLOORED", len)) {
|
||||
TRY(ds_push(fh, TOBOOL(1)));
|
||||
TRY(ds_push(fh, 1));
|
||||
}
|
||||
else {
|
||||
} else if (EQ(str, "MAX-CHAR", len)) {
|
||||
TRY(ds_push(fh, 255));
|
||||
TRY(ds_push(fh, 1));
|
||||
} else if (EQ(str, "MAX-D", len)) {
|
||||
TRY(ds_push_dw(fh, 0x7FFFFFFFFFFFFFFFULL));
|
||||
} else if (EQ(str, "MAX-UD", len)) {
|
||||
TRY(ds_push_dw(fh, 0xFFFFFFFFFFFFFFFFULL));
|
||||
} else if (EQ(str, "MAX-N", len)) {
|
||||
TRY(ds_push(fh, 0x7FFFFFFFULL));
|
||||
TRY(ds_push(fh, 1));
|
||||
} else if (EQ(str, "MAX-U", len)) {
|
||||
TRY(ds_push(fh, 0xFFFFFFFFULL));
|
||||
TRY(ds_push(fh, 1));
|
||||
} else if (EQ(str, "RETURN-STACK-CELLS", len)) {
|
||||
TRY(ds_push(fh, RETURN_STACK_DEPTH));
|
||||
TRY(ds_push(fh, 1));
|
||||
} else if (EQ(str, "STACK-CELLS", len)) {
|
||||
TRY(ds_push(fh, DATA_STACK_DEPTH));
|
||||
TRY(ds_push(fh, 1));
|
||||
} else if (EQ(str, "CORE", len)) {
|
||||
TRY(ds_push(fh, TOBOOL(1)));
|
||||
TRY(ds_push(fh, 1));
|
||||
} else {
|
||||
TRY(ds_push(fh, 0));
|
||||
}
|
||||
|
||||
|
||||
+21
-21
@@ -8,7 +8,7 @@ static enum fh_error pop_addr_len(struct fh_thread_s *fh, uint32_t *addr, uint32
|
||||
|
||||
if (*addr >= HEAP_SIZE) { // not HEAP_END, because this can point into other buffers too
|
||||
LOGE("heap string pointer out of bounds!");
|
||||
return FH_ERR_NOT_APPLICABLE; // TODO better code
|
||||
return FH_ERR_ILLEGAL_FETCH;
|
||||
}
|
||||
return FH_OK;
|
||||
}
|
||||
@@ -81,7 +81,6 @@ static enum fh_error w_dot(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
}
|
||||
|
||||
|
||||
|
||||
static enum fh_error w_dot_r(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
{
|
||||
(void) w;
|
||||
@@ -124,7 +123,7 @@ static enum fh_error w_type(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
uint32_t count = 0, addr = 0;
|
||||
TRY(pop_addr_len(fh, &addr, &count));
|
||||
const char *str = fh_str_at(fh, addr);
|
||||
if (!str) return FH_ERR_INTERNAL;
|
||||
if (!str) { return FH_ERR_INTERNAL; }
|
||||
FHPRINT("%.*s", count, str);
|
||||
return FH_OK;
|
||||
}
|
||||
@@ -137,7 +136,7 @@ static enum fh_error w_fill(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
TRY(ds_pop(fh, &ch));
|
||||
TRY(pop_addr_len(fh, &addr, &count));
|
||||
const char *str = fh_str_at(fh, addr);
|
||||
if (!str) return FH_ERR_INTERNAL;
|
||||
if (!str) { return FH_ERR_INTERNAL; }
|
||||
if (count > 0) {
|
||||
memset((void *) str, (uint8_t) ch, count);
|
||||
}
|
||||
@@ -185,6 +184,7 @@ static enum fh_error w_emit(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
|
||||
static enum fh_error w_see(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
{
|
||||
(void) w;
|
||||
enum fh_error rv;
|
||||
char *wordname;
|
||||
size_t namelen = 0;
|
||||
@@ -210,10 +210,10 @@ static enum fh_error w_s_quote(struct fh_thread_s *fh, const struct fh_word_s *w
|
||||
|
||||
struct fh_instruction_s instr;
|
||||
if (fh->state == FH_STATE_INTERPRET) {
|
||||
LOG("Interpret a string alloc: \"%.*s\"", len, start);
|
||||
LOG("Interpret a string alloc: \"%.*s\"", (int) len, start);
|
||||
TRY(push_addr_len(fh, addr, len));
|
||||
} else {
|
||||
LOG("Compile a string: \"%.*s\"", len, start);
|
||||
LOG("Compile a string: \"%.*s\"", (int) len, start);
|
||||
instr.kind = FH_INSTR_ALLOCSTR;
|
||||
instr.data = len;
|
||||
fh_heap_write(fh, addr - INSTR_SIZE, &instr, INSTR_SIZE);
|
||||
@@ -243,10 +243,10 @@ static enum fh_error w_c_quote(struct fh_thread_s *fh, const struct fh_word_s *w
|
||||
|
||||
struct fh_instruction_s instr;
|
||||
if (fh->state == FH_STATE_INTERPRET) {
|
||||
LOG("Interpret a c-string alloc: \"%.*s\"", len, start);
|
||||
LOG("Interpret a c-string alloc: \"%.*s\"", (int) len, start);
|
||||
TRY(ds_push(fh, addr));
|
||||
} else {
|
||||
LOG("Compile a c-string: \"%.*s\"", len, start);
|
||||
LOG("Compile a c-string: \"%.*s\"", (int) len, start);
|
||||
instr.kind = FH_INSTR_ALLOCSTR_C;
|
||||
instr.data = WORDALIGNED(len + 1);
|
||||
fh_heap_write(fh, addr - INSTR_SIZE, &instr, INSTR_SIZE);
|
||||
@@ -292,12 +292,11 @@ static enum fh_error w_dot_quote(struct fh_thread_s *fh, const struct fh_word_s
|
||||
}
|
||||
}
|
||||
|
||||
struct fh_instruction_s instr;
|
||||
if (fh->state == FH_STATE_INTERPRET) {
|
||||
FHPRINT("%.*s", (int) len, start);
|
||||
// the string is invalidated immediately, heap pointer is NOT advanced.
|
||||
} else {
|
||||
LOG("Compile a string: \"%.*s\"", len, start);
|
||||
LOG("Compile a string: \"%.*s\"", (int) len, start);
|
||||
TRY(fh_put_instr(fh, FH_INSTR_TYPESTR, len));
|
||||
fh->here = WORDALIGNED(addr + len); // at the end of the string
|
||||
}
|
||||
@@ -308,7 +307,6 @@ static enum fh_error w_dot_quote(struct fh_thread_s *fh, const struct fh_word_s
|
||||
static enum fh_error w_less_hash(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
{
|
||||
(void) w;
|
||||
enum fh_error rv;
|
||||
fh->pictnumptr = WORDBUF_LASTCHAR_ADDR;
|
||||
return FH_OK;
|
||||
}
|
||||
@@ -318,7 +316,6 @@ static enum fh_error w_hash_greater(struct fh_thread_s *fh, const struct fh_word
|
||||
(void) w;
|
||||
enum fh_error rv;
|
||||
|
||||
|
||||
uint64_t dummy;
|
||||
TRY(ds_pop_dw(fh, &dummy));
|
||||
|
||||
@@ -331,7 +328,8 @@ static enum fh_error w_hash_greater(struct fh_thread_s *fh, const struct fh_word
|
||||
return FH_OK;
|
||||
}
|
||||
|
||||
static enum fh_error pictnum_prepend_char(struct fh_thread_s *fh, char c) {
|
||||
static enum fh_error pictnum_prepend_char(struct fh_thread_s *fh, char c)
|
||||
{
|
||||
enum fh_error rv;
|
||||
if (fh->pictnumptr < WORDBUF_ADDR) {
|
||||
return FH_ERR_PICTNUM_FULL;
|
||||
@@ -342,14 +340,16 @@ static enum fh_error pictnum_prepend_char(struct fh_thread_s *fh, char c) {
|
||||
return FH_OK;
|
||||
}
|
||||
|
||||
static char dig2char(uint64_t digit) {
|
||||
static char dig2char(uint64_t digit)
|
||||
{
|
||||
char repr;
|
||||
if (digit < 10) {
|
||||
repr = '0' + digit;
|
||||
repr = (char)('0' + (char)digit);
|
||||
} else if (digit < 36) {
|
||||
repr = 'A' + (digit - 10);
|
||||
repr = (char)('A' + ((char)digit - 10));
|
||||
} else {
|
||||
repr = '?'; // XXX bad base?
|
||||
// This shouldn't happen
|
||||
repr = '?';
|
||||
}
|
||||
return repr;
|
||||
}
|
||||
@@ -417,9 +417,9 @@ static enum fh_error w_holds(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
uint32_t count = 0, addr = 0;
|
||||
TRY(pop_addr_len(fh, &addr, &count));
|
||||
const char *str = fh_str_at(fh, addr);
|
||||
if (!str) return FH_ERR_INTERNAL;
|
||||
if (!str) { return FH_ERR_INTERNAL; }
|
||||
|
||||
for(int i=count-1; i>=0; i--) {
|
||||
for (int i = (int)count - 1; i >= 0; i--) {
|
||||
TRY(pictnum_prepend_char(fh, str[i]));
|
||||
}
|
||||
|
||||
@@ -451,7 +451,7 @@ static enum fh_error w_to_number(struct fh_thread_s *fh, const struct fh_word_s
|
||||
uint32_t count = 0, addr = 0;
|
||||
TRY(pop_addr_len(fh, &addr, &count));
|
||||
const char *str = fh_str_at(fh, addr);
|
||||
if (!str) return FH_ERR_INTERNAL;
|
||||
if (!str) { return FH_ERR_INTERNAL; }
|
||||
|
||||
LOG("parse num from str: %.*s", count, str);
|
||||
|
||||
@@ -481,7 +481,7 @@ static enum fh_error w_to_number(struct fh_thread_s *fh, const struct fh_word_s
|
||||
val = (val * (uint64_t) fh->base) + (uint64_t) conv;
|
||||
}
|
||||
|
||||
LOG("parsed num: %d", val);
|
||||
LOG("parsed num: %d", (int)val);
|
||||
TRY(ds_push_dw(fh, val));
|
||||
TRY(push_addr_len(fh, addr + i, count - i));
|
||||
return FH_OK;
|
||||
|
||||
+11
-6
@@ -17,7 +17,8 @@ void fh_align(struct fh_thread_s *fh)
|
||||
fh->here = WORDALIGNED(fh->here);
|
||||
}
|
||||
|
||||
void fh_setbase(struct fh_thread_s *fh, uint32_t base) {
|
||||
void fh_setbase(struct fh_thread_s *fh, uint32_t base)
|
||||
{
|
||||
LOG("set BASE = %d", base);
|
||||
fh->base = base;
|
||||
}
|
||||
@@ -158,14 +159,15 @@ void fh_heap_write(struct fh_thread_s *fh, uint32_t addr, const void *src, uint3
|
||||
memcpy(&fh->heap[addr], src, len);
|
||||
}
|
||||
|
||||
enum fh_error fh_put_instr(struct fh_thread_s *fh, enum fh_instruction_kind kind, uint32_t data) {
|
||||
enum fh_error fh_put_instr(struct fh_thread_s *fh, enum fh_instruction_kind kind, uint32_t data)
|
||||
{
|
||||
fh_align(fh);
|
||||
|
||||
struct fh_instruction_s instr = {
|
||||
.kind = kind,
|
||||
.data = data,
|
||||
};
|
||||
LOG("\x1b[90mAppend instr %s, data 0x%08x at 0x%08x\x1b[m", instr_name(kind), data, fh->here);
|
||||
LOG("\x1b[90mAppend instr %s, data 0x%08x at 0x%08x\x1b[m", instr_name(kind), data, (uint32_t) fh->here);
|
||||
return fh_heap_put(fh, &instr, INSTR_SIZE);
|
||||
}
|
||||
|
||||
@@ -193,7 +195,8 @@ void fh_heap_copyptr(struct fh_thread_s *fh, uint32_t addr, char * source, uint3
|
||||
}
|
||||
|
||||
|
||||
char *fh_str_at(struct fh_thread_s *fh, uint32_t addr) {
|
||||
char *fh_str_at(struct fh_thread_s *fh, uint32_t addr)
|
||||
{
|
||||
if (addr >= HEAP_SIZE) {
|
||||
LOGE("fh_str_at out of bounds! 0x%08x", addr);
|
||||
return NULL;
|
||||
@@ -201,7 +204,8 @@ char *fh_str_at(struct fh_thread_s *fh, uint32_t addr) {
|
||||
return (char *) &fh->heap[addr];
|
||||
}
|
||||
|
||||
struct fh_instruction_s *fh_instr_at(struct fh_thread_s *fh, uint32_t addr) {
|
||||
struct fh_instruction_s *fh_instr_at(struct fh_thread_s *fh, uint32_t addr)
|
||||
{
|
||||
if (addr >= HEAP_END) {
|
||||
LOGE("fh_instr_at out of bounds! 0x%08x", addr);
|
||||
return NULL;
|
||||
@@ -209,7 +213,8 @@ struct fh_instruction_s *fh_instr_at(struct fh_thread_s *fh, uint32_t addr) {
|
||||
return (void *) &fh->heap[addr];
|
||||
}
|
||||
|
||||
struct fh_word_s *fh_word_at(struct fh_thread_s *fh, uint32_t addr) {
|
||||
struct fh_word_s *fh_word_at(struct fh_thread_s *fh, uint32_t addr)
|
||||
{
|
||||
if (addr >= HEAP_END) {
|
||||
LOGE("fh_word_at out of bounds! 0x%08x", addr);
|
||||
return NULL;
|
||||
|
||||
+43
-19
@@ -42,7 +42,7 @@ enum fh_error fh_handle_ascii_word(
|
||||
}
|
||||
}
|
||||
|
||||
long v = strtol(name, &endptr, base); // XXX if base is 0, this will use auto-detection
|
||||
long v = strtol(name, &endptr, base); // if base is 0, this will use auto-detection
|
||||
if (errno != 0 || (endptr - name) != wordlen) {
|
||||
LOGE("Unknown word and fail to parse as number: \"%.*s\"", (int) wordlen, name);
|
||||
return FH_ERR_UNKNOWN_WORD;
|
||||
@@ -61,7 +61,8 @@ enum fh_error fh_handle_ascii_word(
|
||||
}
|
||||
|
||||
|
||||
void fh_input_consume_matching(struct fh_thread_s *fh, chartest_t test, void* param) {
|
||||
void fh_input_consume_matching(struct fh_thread_s *fh, chartest_t test, void *param)
|
||||
{
|
||||
char *rp = (char *) &fh->heap[INPUTBUF_ADDR + fh->inputptr];
|
||||
while (test(*rp, param)) {
|
||||
rp++;
|
||||
@@ -69,7 +70,8 @@ void fh_input_consume_matching(struct fh_thread_s *fh, chartest_t test, void* pa
|
||||
}
|
||||
}
|
||||
|
||||
void fh_input_consume_spaces(struct fh_thread_s *fh) {
|
||||
void fh_input_consume_spaces(struct fh_thread_s *fh)
|
||||
{
|
||||
char *rp = (char *) &fh->heap[INPUTBUF_ADDR + fh->inputptr];
|
||||
while (isspace(*rp)) {
|
||||
rp++;
|
||||
@@ -104,11 +106,13 @@ static bool chartest_space_or_end(char c, void *param)
|
||||
return isspace(c) || c == 0;
|
||||
}
|
||||
|
||||
enum fh_error fh_input_read_word(struct fh_thread_s *fh, char **out, size_t *len) {
|
||||
enum fh_error fh_input_read_word(struct fh_thread_s *fh, char **out, size_t *len)
|
||||
{
|
||||
return fh_input_read_delimited(fh, out, len, chartest_space_or_end, NULL);
|
||||
}
|
||||
|
||||
enum fh_error fh_input_read_quotedstring(struct fh_thread_s *fh, bool escaped, char *outbuf, size_t capacity, size_t *out_len) {
|
||||
enum fh_error fh_input_read_quotedstring(struct fh_thread_s *fh, bool escaped, char *outbuf, size_t capacity, size_t *out_len)
|
||||
{
|
||||
char *rp = (char *) &fh->heap[INPUTBUF_ADDR + fh->inputptr];
|
||||
bool next_escaped = false;
|
||||
size_t remains = capacity;
|
||||
@@ -157,24 +161,44 @@ enum fh_error fh_input_read_quotedstring(struct fh_thread_s *fh, bool escaped, c
|
||||
} else {
|
||||
next_escaped = false;
|
||||
switch (c) {
|
||||
case 'a': c = 7; break;
|
||||
case 'b': c = 8; break;
|
||||
case 'e': c = 27; break;
|
||||
case 'f': c = 12; break;
|
||||
case 'l': c = 10; break;
|
||||
case 'a':
|
||||
c = 7;
|
||||
break;
|
||||
case 'b':
|
||||
c = 8;
|
||||
break;
|
||||
case 'e':
|
||||
c = 27;
|
||||
break;
|
||||
case 'f':
|
||||
c = 12;
|
||||
break;
|
||||
case 'l':
|
||||
c = 10;
|
||||
break;
|
||||
case 'm':
|
||||
case 'n':
|
||||
if (remains < 2) goto full;
|
||||
if (remains < 2) { goto full; }
|
||||
*outbuf++ = '\r';
|
||||
*outbuf++ = '\n';
|
||||
remains -= 2;
|
||||
len += 2;
|
||||
goto skip;
|
||||
case 'q': c = '"'; break;
|
||||
case 'r': c = '\r'; break;
|
||||
case 't': c = '\t'; break;
|
||||
case 'v': c = '\v'; break;
|
||||
case 'z': c = 0; break; // XXX this will cause problems!
|
||||
case 'q':
|
||||
c = '"';
|
||||
break;
|
||||
case 'r':
|
||||
c = '\r';
|
||||
break;
|
||||
case 't':
|
||||
c = '\t';
|
||||
break;
|
||||
case 'v':
|
||||
c = '\v';
|
||||
break;
|
||||
case 'z':
|
||||
c = 0;
|
||||
break; // this will cause problems with string printing
|
||||
case 'x':
|
||||
hex = 0;
|
||||
hexdigits = 2;
|
||||
@@ -280,11 +304,11 @@ enum fh_error fh_process_line(struct fh_thread_s *fh, const char *linebuf, size_
|
||||
} else {
|
||||
if (EQ(rp, "\\", length)) {
|
||||
// discard to EOL
|
||||
LOG("Discard \"%.*s\"", fh->inputlen - fh->inputptr + length, rp);
|
||||
LOG("Discard \"%.*s\"", (int)(fh->inputlen - fh->inputptr + length), rp);
|
||||
goto done;
|
||||
}
|
||||
|
||||
LOG("Discard \"%.*s\"", length, rp);
|
||||
LOG("Discard \"%.*s\"", (int) length, rp);
|
||||
}
|
||||
|
||||
if (!end) {
|
||||
@@ -296,7 +320,7 @@ enum fh_error fh_process_line(struct fh_thread_s *fh, const char *linebuf, size_
|
||||
end = strchr(rp, ')');
|
||||
if (end) {
|
||||
length = end - rp;
|
||||
LOG("Discard inline comment: \"%.*s\"", length, rp);
|
||||
LOG("Discard inline comment: \"%.*s\"", (int)length, rp);
|
||||
fh_setsubstate(fh, FH_SUBSTATE_NONE);
|
||||
ReadPos += length + 1;
|
||||
} else {
|
||||
|
||||
+7
-3
@@ -46,7 +46,8 @@ static const char *instrnames[FH_INSTR_MAX] = {
|
||||
};
|
||||
|
||||
|
||||
const char *instr_name(enum fh_instruction_kind kind) {
|
||||
const char *instr_name(enum fh_instruction_kind kind)
|
||||
{
|
||||
if (kind >= FH_INSTR_MAX) {
|
||||
return "Unknown";
|
||||
} else {
|
||||
@@ -68,7 +69,7 @@ enum fh_error fh_add_word(const struct fh_word_s *w, struct fh_thread_s *fh)
|
||||
|
||||
// thread it onto the linked list
|
||||
struct fh_word_s *word = fh_word_at(fh, ptr);
|
||||
if (!word) return FH_ERR_INTERNAL;
|
||||
if (!word) { return FH_ERR_INTERNAL; }
|
||||
word->previous = fh->dict_last;
|
||||
fh->dict_last = ptr;
|
||||
|
||||
@@ -373,6 +374,9 @@ enum fh_error w_user_word(struct fh_thread_s *fh, const struct fh_word_s *w0)
|
||||
goto end;
|
||||
}
|
||||
goto instr;
|
||||
|
||||
default:
|
||||
LOGE("Run handler not implemented for instr opcode %d", instr->kind);
|
||||
}
|
||||
|
||||
end:
|
||||
@@ -401,7 +405,7 @@ enum fh_error fh_handle_word(struct fh_thread_s *fh, uint32_t addr)
|
||||
{
|
||||
enum fh_error rv;
|
||||
struct fh_word_s *w = fh_word_at(fh, addr);
|
||||
if (!w) return FH_ERR_INTERNAL;
|
||||
if (!w) { return FH_ERR_INTERNAL; }
|
||||
if (fh->state == FH_STATE_COMPILE && 0 == (w->flags & WORDFLAG_IMMEDIATE)) {
|
||||
LOG("\x1b[34m[%s] Compile word:\x1b[m %s", stateshort[fh->state], w->name);
|
||||
TRY(fh_put_instr(fh, FH_INSTR_WORD, addr));
|
||||
|
||||
+1
-1
@@ -132,7 +132,7 @@ static void show_word(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
}
|
||||
} else {
|
||||
FHPRINT("Built-in word %s\n", w->name);
|
||||
};
|
||||
}
|
||||
} else if (w->flags & WORDFLAG_VARIABLE) {
|
||||
FHPRINT("Variable %s, value %d (0x%08x)\n", w->name, (int32_t) w->param, w->param);
|
||||
} else if (w->flags & WORDFLAG_CONSTANT) {
|
||||
|
||||
Reference in New Issue
Block a user