|
|
|
@ -28,11 +28,10 @@ static intptr_t dict[1000] = {
|
|
|
|
|
#define LATEST dict[2]
|
|
|
|
|
#define begin dict[3]
|
|
|
|
|
static intptr_t *here = &begin;
|
|
|
|
|
static char *in;
|
|
|
|
|
|
|
|
|
|
static intptr_t saved_tmp;
|
|
|
|
|
static intptr_t * saved_sp;
|
|
|
|
|
static intptr_t *** saved_rp;
|
|
|
|
|
static intptr_t ** saved_pp;
|
|
|
|
|
|
|
|
|
|
NAKED void enter(void) { *--rp = ++pp; pp = (intptr_t **)*pp; goto *(*pp); }
|
|
|
|
|
NAKED void push(void) { *--sp = (intptr_t)*++pp; NEXT; }
|
|
|
|
@ -40,22 +39,21 @@ NAKED void push(void) { *--sp = (intptr_t)*++pp; NEXT; }
|
|
|
|
|
|
|
|
|
|
NAKED void compname(void)
|
|
|
|
|
{
|
|
|
|
|
static int ch;
|
|
|
|
|
|
|
|
|
|
STASH;
|
|
|
|
|
*(unsigned char *)here = 0;
|
|
|
|
|
for (;;) {
|
|
|
|
|
ch = foci_getchar();
|
|
|
|
|
|
|
|
|
|
if (ch <= 0x20)
|
|
|
|
|
for (; *in <= ' '; in++) {
|
|
|
|
|
if (*in == '\0')
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (; *in > ' '; in++) {
|
|
|
|
|
*(unsigned char *)here += 1;
|
|
|
|
|
((char *)here)[*(unsigned char *)here] = ch;
|
|
|
|
|
((char *)here)[*(unsigned char *)here] = *in;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RESTORE;
|
|
|
|
|
*--sp = *(unsigned char *)here;
|
|
|
|
|
|
|
|
|
|
NEXT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -71,6 +69,9 @@ int compare(const char *a, const char *b, int l)
|
|
|
|
|
|
|
|
|
|
const struct word_t *lookup_p(const char *s, int len)
|
|
|
|
|
{
|
|
|
|
|
if (len < 1)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
for (const struct word_t *l = (const struct word_t *)LATEST; l; l = l->prev) {
|
|
|
|
|
if (len == (l->attr & ATTR_LEN) && !compare(s, l->name, len))
|
|
|
|
|
return l;
|
|
|
|
@ -147,19 +148,25 @@ W(hex, "hex", &w_decimal) LIT(16), LIT(&BASE), poke, END
|
|
|
|
|
N(dot, ".", &w_hex) ;
|
|
|
|
|
#define LATEST_INIT &w_dot
|
|
|
|
|
|
|
|
|
|
void call(void *ptr)
|
|
|
|
|
void enter_forth(void *ptr)
|
|
|
|
|
{
|
|
|
|
|
STASH;
|
|
|
|
|
sp = saved_sp;
|
|
|
|
|
rp = saved_rp;
|
|
|
|
|
pp = ptr;
|
|
|
|
|
|
|
|
|
|
((void (*)())*pp)();
|
|
|
|
|
|
|
|
|
|
saved_sp = sp;
|
|
|
|
|
saved_rp = rp;
|
|
|
|
|
RESTORE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NAKED
|
|
|
|
|
void dot()
|
|
|
|
|
__attribute__((noinline))
|
|
|
|
|
static void dotimpl(intptr_t n)
|
|
|
|
|
{
|
|
|
|
|
static char dotbuf[16];
|
|
|
|
|
|
|
|
|
|
STASH;
|
|
|
|
|
intptr_t n = *sp;
|
|
|
|
|
char *s = dotbuf + sizeof(dotbuf);
|
|
|
|
|
int neg = n < 0;
|
|
|
|
|
if (neg) n *= -1;
|
|
|
|
@ -172,7 +179,13 @@ void dot()
|
|
|
|
|
while (*s)
|
|
|
|
|
foci_putchar(*s++);
|
|
|
|
|
foci_putchar(' ');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NAKED
|
|
|
|
|
void dot()
|
|
|
|
|
{
|
|
|
|
|
STASH;
|
|
|
|
|
dotimpl(*sp);
|
|
|
|
|
RESTORE;
|
|
|
|
|
++sp;
|
|
|
|
|
NEXT;
|
|
|
|
@ -201,24 +214,19 @@ intptr_t parse_number(const char *s, const char **endp, int b)
|
|
|
|
|
return neg ? n * -1 : n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void parse_word(const char *buf, const char *s)
|
|
|
|
|
static void parse_word(const char *start, const char *end)
|
|
|
|
|
{
|
|
|
|
|
const struct word_t *l = lookup_p(buf, s - buf);
|
|
|
|
|
|
|
|
|
|
tmp = saved_tmp;
|
|
|
|
|
sp = saved_sp;
|
|
|
|
|
rp = saved_rp;
|
|
|
|
|
pp = saved_pp;
|
|
|
|
|
const struct word_t *l = lookup_p(start, end - start);
|
|
|
|
|
|
|
|
|
|
if (l == 0) {
|
|
|
|
|
const char *end;
|
|
|
|
|
intptr_t n = parse_number(buf, &end, BASE);
|
|
|
|
|
if (*end == '\0') {
|
|
|
|
|
const char *nend;
|
|
|
|
|
intptr_t n = parse_number(start, &nend, BASE);
|
|
|
|
|
if (nend == end) {
|
|
|
|
|
if (state) {
|
|
|
|
|
*here++ = (intptr_t)push;
|
|
|
|
|
*here++ = n;
|
|
|
|
|
} else {
|
|
|
|
|
*--sp = n;
|
|
|
|
|
*--saved_sp = n;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
const char *err = "word not found";
|
|
|
|
@ -234,22 +242,35 @@ void parse_word(const char *buf, const char *s)
|
|
|
|
|
*here++ = (intptr_t)l->body[0];
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
call(l->body);
|
|
|
|
|
enter_forth(l->body);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
saved_tmp = tmp;
|
|
|
|
|
saved_sp = sp;
|
|
|
|
|
saved_rp = rp;
|
|
|
|
|
saved_pp = pp;
|
|
|
|
|
void interpret(void)
|
|
|
|
|
{
|
|
|
|
|
static char buf[128];
|
|
|
|
|
char *s = buf - 1;
|
|
|
|
|
|
|
|
|
|
do *++s = foci_getchar();
|
|
|
|
|
while (*s && *s != '\n' && *s != '\r');
|
|
|
|
|
*s = '\0';
|
|
|
|
|
|
|
|
|
|
char *start = buf;
|
|
|
|
|
for (in = buf; in <= s; in++) {
|
|
|
|
|
if (*in <= ' ') {
|
|
|
|
|
if (start != in)
|
|
|
|
|
parse_word(start, in);
|
|
|
|
|
|
|
|
|
|
start = in + 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void init(void)
|
|
|
|
|
{
|
|
|
|
|
saved_tmp = 0;
|
|
|
|
|
saved_sp = END_OF(dstack);
|
|
|
|
|
saved_rp = END_OF(rstack);
|
|
|
|
|
saved_pp = 0;
|
|
|
|
|
|
|
|
|
|
LATEST = (intptr_t)LATEST_INIT;
|
|
|
|
|
}
|
|
|
|
|