big refactor and add DO-LOOP and DO-+LOOP and LEAVE
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#ifndef FORTH_H
|
||||
#define FORTH_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user