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