big refactor and add DO-LOOP and DO-+LOOP and LEAVE

This commit is contained in:
2021-11-17 00:06:09 +01:00
parent f74d157a7c
commit ef2e6943bd
19 changed files with 1746 additions and 1453 deletions
+29
View File
@@ -7,6 +7,35 @@
#ifndef FORTH_FH_BUILTINS_H
#define FORTH_FH_BUILTINS_H
struct name_and_handler {
const char *name;
word_exec_t handler;
bool immediate;
uint32_t param;
};
enum fh_error fh_register_words_from_array(struct fh_thread_s *fh, const struct name_and_handler *p);
enum fh_error register_builtin_words(struct fh_thread_s *fh);
#define TOBOOL(a) ((a) == 0 ? 0 : 0xFFFFFFFF)
#define ENSURE_STATE(__state) do { \
if (fh->state != (__state)) { \
return FH_ERR_INVALID_STATE; \
} \
} while (0)
extern const struct name_and_handler fh_builtins_control[];
extern const struct name_and_handler fh_builtins_arith[];
extern const struct name_and_handler fh_builtins_stack[];
extern const struct name_and_handler fh_builtins_mem[];
extern const struct name_and_handler fh_builtins_meta[];
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
+2
View File
@@ -30,6 +30,8 @@ void fh_heap_write(struct fh_thread_s *fh, uint32_t addr, const void *src, uint3
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);
enum fh_error fh_put_instr(struct fh_thread_s *fh, enum fb_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);
+55 -8
View File
@@ -44,6 +44,21 @@ enum fb_instruction_kind {
/* Jump if zero */
FH_INSTR_JUMPZERO,
/* Loop exit */
FH_INSTR_LEAVE,
/* DO loop initializer */
FH_INSTR_DO,
/* ?DO short-circuiting loop */
FH_INSTR_DO_QUESTION,
/* Loop end instr */
FH_INSTR_LOOP,
/* Loop end instr with custom step */
FH_INSTR_LOOP_PLUS,
/* Postponed word */
FH_INSTR_POSTPONED_WORD,
};
@@ -88,17 +103,25 @@ enum fh_substate {
FH_SUBSTATE_MAX,
};
/** Marks a dictionary entry that is a word */
#define WORDFLAG_WORD 0x01
/** Indicates that this is a built-in instruction and not a word call */
#define WORDFLAG_BUILTIN 0x01
#define WORDFLAG_BUILTIN 0x02
/** Indicates that this instruction should always be treated as interpreted */
#define WORDFLAG_IMMEDIATE 0x02
#define WORDFLAG_IMMEDIATE 0x04
/** Variable or value stored in the dictionary */
#define WORDFLAG_VARIABLE 0x08
/** Constant with a value assigned */
#define WORDFLAG_CONSTANT 0x10
/** Word struct as they are stored in the dictionary */
struct fh_word_s {
/** Linked list pointer to previous word */
uint32_t previous;
/** Word name */
char name[MAX_NAME_LEN]; // XXX this wastes RAM!
/**
* Handler function.
* Builtin functions use pre-defined native handlers.
@@ -106,7 +129,10 @@ struct fh_word_s {
* bytecode at 'start' address of the compile-memory area.
*/
word_exec_t handler;
/** Word flags, using WORDFLAG_ defines */
uint32_t flags;
/** Start address in case of user words, or param for builtins */
uint32_t param;
};
@@ -155,12 +181,21 @@ struct fh_thread_s {
/** The numeric base register */
uint32_t base;
/** Loop variable I */
uint32_t loop_i;
/** Loop variable J */
uint32_t loop_j;
};
#define HEAP_END (HEAP_SIZE - WORDBUF_SIZE - INPUT_BUFFER_SIZE)
#define WORDBUF_ADDR HEAP_END
#define INPUTBUF_ADDR (HEAP_END + WORDBUF_SIZE)
enum fh_error fh_loop_nest(struct fh_thread_s *fh, uint32_t indexvalue);
enum fh_error fh_loop_unnest(struct fh_thread_s *fh);
enum fh_error fh_add_word(const struct fh_word_s *w, struct fh_thread_s *fh);
void fh_setstate(struct fh_thread_s *fh, enum fh_state state, enum fh_substate substate);
@@ -178,6 +213,7 @@ enum fh_error fh_postpone_word(
size_t wordlen
);
/** Show disassembly of a dictionary word */
enum fh_error fh_see_word(
struct fh_thread_s *fh,
const char *name,
@@ -209,12 +245,23 @@ _Static_assert(WORDALIGNED(1024) == 1024, "word align");
if (FH_OK != (rv = (x))) return rv; \
} while (0)
enum fh_error fh_handle_ascii_word(
struct fh_thread_s *fh,
const char *name,
size_t wordlen
);
/**
* Execute a dictionary word from a definition stored at the given address
* @param fh
* @param addr
* @return
*/
enum fh_error fh_handle_word(struct fh_thread_s *fh, uint32_t addr);
/**
* Find a word in the dict
*
* @param fh
* @param name - name, may be NUL terminated
* @param wordlen - length, use 0 for strlen
* @param addr_out the word address is output here, if given
* @return success
*/
enum fh_error fh_find_word(struct fh_thread_s *fh, const char *name, size_t wordlen, uint32_t *addr_out);
#endif //FORTH_FH_RUNTIME_H
+2
View File
@@ -18,6 +18,8 @@ static inline enum fh_error cs_peek_n(struct fh_thread_s *fh, uint32_t *out, int
return ds_peek_n(fh, out, n);
}
enum fh_error rs_poke_n(struct fh_thread_s *fh, uint32_t value, int n);
/** Peek top of data stack */
static inline enum fh_error ds_peek(struct fh_thread_s *fh, uint32_t *out)
{
+1
View File
@@ -7,6 +7,7 @@
#ifndef FORTH_H
#define FORTH_H
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>