Move system variables to a structure.
This commit is contained in:
@ -27,12 +27,24 @@
|
||||
: +! ( n a -- ) swap over @ + swap ! ;
|
||||
: bye 0 sysexit ;
|
||||
|
||||
( Dictionary and Cells )
|
||||
: here ( -- a ) 'heap @ ;
|
||||
: allot ( n -- ) 'heap +! ;
|
||||
( Cells )
|
||||
: cell+ ( n -- n ) cell + ;
|
||||
: cells ( n -- n ) cell * ;
|
||||
: cell/ ( n -- n ) cell / ;
|
||||
|
||||
( System Variables )
|
||||
: 'tib ( -- a ) 'sys 0 cells + ;
|
||||
: #tib ( -- a ) 'sys 1 cells + ;
|
||||
: >in ( -- a ) 'sys 2 cells + ;
|
||||
: state ( -- a ) 'sys 3 cells + ;
|
||||
: base ( -- a ) 'sys 4 cells + ;
|
||||
: 'heap ( -- a ) 'sys 5 cells + ;
|
||||
: last ( -- a ) 'sys 6 cells + ;
|
||||
: 'throw ( -- a ) 'sys 7 cells + ;
|
||||
|
||||
( Dictionary )
|
||||
: here ( -- a ) 'heap @ ;
|
||||
: allot ( n -- ) 'heap +! ;
|
||||
: aligned ( a -- a ) cell 1 - dup >r + r> invert and ;
|
||||
: align here aligned here - allot ;
|
||||
: , ( n -- ) here ! cell allot ;
|
||||
|
||||
@ -3,11 +3,12 @@
|
||||
#define FIND(name) find(name, sizeof(name) - 1)
|
||||
#define LOWER(ch) ((ch) & 95)
|
||||
|
||||
static cell_t *g_heap;
|
||||
static const char *g_tib;
|
||||
static cell_t g_ntib, g_tin = 0;
|
||||
static cell_t *g_last = 0, g_base = 10, g_state = 0, g_throw = 0;
|
||||
static cell_t g_DOLIT_XT, g_DOEXIT_XT;
|
||||
static struct {
|
||||
const char *tib;
|
||||
cell_t ntib, tin, state, base;
|
||||
cell_t *heap, *last, tthrow;
|
||||
cell_t DOLIT_XT, DOEXIT_XT;
|
||||
} g_sys;
|
||||
|
||||
static cell_t convert(const char *pos, cell_t n, cell_t *ret) {
|
||||
*ret = 0;
|
||||
@ -20,8 +21,8 @@ static cell_t convert(const char *pos, cell_t n, cell_t *ret) {
|
||||
d = LOWER(d) - 7;
|
||||
if (d < 10) { return 0; }
|
||||
}
|
||||
if (d >= (uintptr_t) g_base) { return 0; }
|
||||
*ret = *ret * g_base + d;
|
||||
if (d >= (uintptr_t) g_sys.base) { return 0; }
|
||||
*ret = *ret * g_sys.base + d;
|
||||
++pos;
|
||||
}
|
||||
if (negate) { *ret = -*ret; }
|
||||
@ -34,7 +35,7 @@ static cell_t same(const char *a, const char *b, cell_t len) {
|
||||
}
|
||||
|
||||
static cell_t find(const char *name, cell_t len) {
|
||||
cell_t *pos = g_last;
|
||||
cell_t *pos = g_sys.last;
|
||||
cell_t clen = CELL_LEN(len);
|
||||
while (pos) {
|
||||
if (len == pos[-3] &&
|
||||
@ -47,21 +48,21 @@ static cell_t find(const char *name, cell_t len) {
|
||||
}
|
||||
|
||||
static void create(const char *name, cell_t length, cell_t flags, void *op) {
|
||||
memcpy(g_heap, name, length); // name
|
||||
g_heap += CELL_LEN(length);
|
||||
*g_heap++ = length; // length
|
||||
*g_heap++ = (cell_t) g_last; // link
|
||||
*g_heap++ = flags; // flags
|
||||
g_last = g_heap;
|
||||
*g_heap++ = (cell_t) op; // code
|
||||
memcpy(g_sys.heap, name, length); // name
|
||||
g_sys.heap += CELL_LEN(length);
|
||||
*g_sys.heap++ = length; // length
|
||||
*g_sys.heap++ = (cell_t) g_sys.last; // link
|
||||
*g_sys.heap++ = flags; // flags
|
||||
g_sys.last = g_sys.heap;
|
||||
*g_sys.heap++ = (cell_t) op; // code
|
||||
}
|
||||
|
||||
static cell_t parse(cell_t sep, cell_t *ret) {
|
||||
while (g_tin < g_ntib && g_tib[g_tin] == sep) { ++g_tin; }
|
||||
*ret = (cell_t) (g_tib + g_tin);
|
||||
while (g_tin < g_ntib && g_tib[g_tin] != sep) { ++g_tin; }
|
||||
cell_t len = g_tin - (*ret - (cell_t) g_tib);
|
||||
if (g_tin < g_ntib) { ++g_tin; }
|
||||
while (g_sys.tin < g_sys.ntib && g_sys.tib[g_sys.tin] == sep) { ++g_sys.tin; }
|
||||
*ret = (cell_t) (g_sys.tib + g_sys.tin);
|
||||
while (g_sys.tin < g_sys.ntib && g_sys.tib[g_sys.tin] != sep) { ++g_sys.tin; }
|
||||
cell_t len = g_sys.tin - (*ret - (cell_t) g_sys.tib);
|
||||
if (g_sys.tin < g_sys.ntib) { ++g_sys.tin; }
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -71,8 +72,8 @@ static cell_t *eval1(cell_t *sp, cell_t *call) {
|
||||
cell_t len = parse(' ', &name);
|
||||
cell_t xt = find((const char *) name, len);
|
||||
if (xt) {
|
||||
if (g_state && !(((cell_t *) xt)[-1] & 1)) { // bit 0 of flags is immediate
|
||||
*g_heap++ = xt;
|
||||
if (g_sys.state && !(((cell_t *) xt)[-1] & 1)) { // bit 0 of flags is immediate
|
||||
*g_sys.heap++ = xt;
|
||||
} else {
|
||||
*call = xt;
|
||||
}
|
||||
@ -80,24 +81,24 @@ static cell_t *eval1(cell_t *sp, cell_t *call) {
|
||||
cell_t n;
|
||||
cell_t ok = convert((const char *) name, len, &n);
|
||||
if (ok) {
|
||||
if (g_state) {
|
||||
*g_heap++ = g_DOLIT_XT;
|
||||
*g_heap++ = n;
|
||||
if (g_sys.state) {
|
||||
*g_sys.heap++ = g_sys.DOLIT_XT;
|
||||
*g_sys.heap++ = n;
|
||||
} else {
|
||||
*++sp = n;
|
||||
}
|
||||
} else {
|
||||
*++sp = -1;
|
||||
*call = g_throw;
|
||||
*call = g_sys.tthrow;
|
||||
}
|
||||
}
|
||||
return sp;
|
||||
}
|
||||
|
||||
static void ueforth(const char *src, cell_t src_len) {
|
||||
g_heap = malloc(HEAP_SIZE);
|
||||
register cell_t *sp = g_heap; g_heap += STACK_SIZE;
|
||||
register cell_t *rp = g_heap; g_heap += STACK_SIZE;
|
||||
g_sys.heap = malloc(HEAP_SIZE);
|
||||
register cell_t *sp = g_sys.heap; g_sys.heap += STACK_SIZE;
|
||||
register cell_t *rp = g_sys.heap; g_sys.heap += STACK_SIZE;
|
||||
register cell_t tos = 0, *ip, t, w;
|
||||
dcell_t d;
|
||||
udcell_t ud;
|
||||
@ -106,15 +107,16 @@ static void ueforth(const char *src, cell_t src_len) {
|
||||
PLATFORM_OPCODE_LIST
|
||||
OPCODE_LIST
|
||||
#undef X
|
||||
g_last[-1] = 1; // Make ; IMMEDIATE
|
||||
g_DOLIT_XT = FIND("DOLIT");
|
||||
g_DOEXIT_XT = FIND("EXIT");
|
||||
ip = g_heap;
|
||||
*g_heap++ = FIND("EVAL1");
|
||||
*g_heap++ = FIND("BRANCH");
|
||||
*g_heap++ = (cell_t) ip;
|
||||
g_tib = src;
|
||||
g_ntib = src_len;
|
||||
g_sys.last[-1] = 1; // Make ; IMMEDIATE
|
||||
g_sys.DOLIT_XT = FIND("DOLIT");
|
||||
g_sys.DOEXIT_XT = FIND("EXIT");
|
||||
ip = g_sys.heap;
|
||||
*g_sys.heap++ = FIND("EVAL1");
|
||||
*g_sys.heap++ = FIND("BRANCH");
|
||||
*g_sys.heap++ = (cell_t) ip;
|
||||
g_sys.base = 10;
|
||||
g_sys.tib = src;
|
||||
g_sys.ntib = src_len;
|
||||
NEXT;
|
||||
#define X(name, op, code) op: code; NEXT;
|
||||
PLATFORM_OPCODE_LIST
|
||||
|
||||
@ -52,7 +52,8 @@ typedef uint64_t udcell_t;
|
||||
X("0BRANCH", OP_ZBRANCH, if (!tos) ip = (cell_t *) *ip; else ++ip; DROP) \
|
||||
X("DONEXT", OP_DONEXT, if ((*rp)--) ip = (cell_t *) *ip; else (--rp, ++ip)) \
|
||||
X("DOLIT", OP_DOLIT, DUP; tos = *(cell_t *) ip++) \
|
||||
X("ALITERAL", OP_ALITERAL, *g_heap++ = g_DOLIT_XT; *g_heap++ = tos; DROP) \
|
||||
X("ALITERAL", OP_ALITERAL, *g_sys.heap++ = g_sys.DOLIT_XT; \
|
||||
*g_sys.heap++ = tos; DROP) \
|
||||
X("CELL", OP_CELL, DUP; tos = sizeof(cell_t)) \
|
||||
X("FIND", OP_FIND, tos = find((const char *) *sp, tos); --sp) \
|
||||
X("PARSE", OP_PARSE, DUP; tos = parse(tos, sp)) \
|
||||
@ -60,24 +61,17 @@ typedef uint64_t udcell_t;
|
||||
if (!tos) --sp) \
|
||||
X("CREATE", OP_CREATE, t = parse(32, &tmp); \
|
||||
create((const char *) tmp, t, 0, && OP_DOCREATE); \
|
||||
*g_heap++ = 0) \
|
||||
X("DOES>", OP_DOES, *g_last = (cell_t) && OP_DODOES; \
|
||||
g_last[1] = (cell_t) ip; goto OP_EXIT) \
|
||||
X("IMMEDIATE", OP_IMMEDIATE, g_last[-1] |= 1) \
|
||||
X("'HEAP", OP_HEAP, DUP; tos = (cell_t) &g_heap) \
|
||||
X("STATE", OP_STATE, DUP; tos = (cell_t) &g_state) \
|
||||
X("BASE", OP_BASE, DUP; tos = (cell_t) &g_base) \
|
||||
X("LAST", OP_LAST, DUP; tos = (cell_t) &g_last) \
|
||||
X("'TIB", OP_TIB, DUP; tos = (cell_t) &g_tib) \
|
||||
X("#TIB", OP_NTIB, DUP; tos = (cell_t) &g_ntib) \
|
||||
X(">IN", OP_TIN, DUP; tos = (cell_t) &g_tin) \
|
||||
X("'THROW", OP_TTHROW, DUP; tos = (cell_t) &g_throw) \
|
||||
*g_sys.heap++ = 0) \
|
||||
X("DOES>", OP_DOES, *g_sys.last = (cell_t) && OP_DODOES; \
|
||||
g_sys.last[1] = (cell_t) ip; goto OP_EXIT) \
|
||||
X("IMMEDIATE", OP_IMMEDIATE, g_sys.last[-1] |= 1) \
|
||||
X("'SYS", OP_SYS, DUP; tos = (cell_t) &g_sys) \
|
||||
X(":", OP_COLON, t = parse(32, &tmp); \
|
||||
create((const char *) tmp, t, 0, && OP_DOCOL); \
|
||||
g_state = -1) \
|
||||
g_sys.state = -1) \
|
||||
X("EVAL1", OP_EVAL1, DUP; sp = eval1(sp, &tmp); \
|
||||
DROP; if (tmp) (w = tmp); \
|
||||
if (tmp) goto **(void **) w) \
|
||||
X("EXIT", OP_EXIT, ip = (void *) *rp--) \
|
||||
X(";", OP_SEMICOLON, *g_heap++ = g_DOEXIT_XT; g_state = 0) \
|
||||
X(";", OP_SEMICOLON, *g_sys.heap++ = g_sys.DOEXIT_XT; g_sys.state = 0) \
|
||||
|
||||
|
||||
Reference in New Issue
Block a user