interpret entirely in foci

main
Clyne 4 weeks ago
parent 9307097160
commit eb3ea19944
Signed by: clyne
GPG Key ID: 3267C8EBF3F9AFC7

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

@ -85,7 +85,7 @@ extern int foci_getchar(void);
void init(void); void init(void);
int depth(void); int depth(void);
int compiling(void); int compiling(void);
void parse_word(const char *buf, const char *s); void interpret(void);
void define(struct word_t *w); void define(struct word_t *w);
void fexit(void); // internal use only void fexit(void); // internal use only

@ -33,30 +33,11 @@ int foci_getchar(void)
int main() int main()
{ {
char buf[128];
init(); init();
for (;;) { for (;;) {
char c; interpret();
do c = getchar(); printf(compiling() ? "compiled <%d>\n" : "ok <%d>\n", depth());
while (!isgraph(c));
char *s = buf;
do {
*s++ = c;
c = getchar();
} while (isgraph(c));
bool eol = c == '\n' || c == '\r';
*s = '\0';
if (strcmp(buf, "bye") == 0)
break;
parse_word(buf, s);
if (eol)
printf(compiling() ? "compiled <%d>\n" : "ok <%d>\n", depth());
} }
return 0; return 0;

Loading…
Cancel
Save