From eb3ea1994428e25e4866afb0ca6ad4edfce5ae8c Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Sun, 26 Jan 2025 20:33:20 -0500 Subject: [PATCH] interpret entirely in foci --- foci.c | 85 ++++++++++++++++++++++++++++++++++++---------------------- foci.h | 2 +- main.c | 23 ++-------------- 3 files changed, 56 insertions(+), 54 deletions(-) diff --git a/foci.c b/foci.c index 6168b35..60c4fca 100644 --- a/foci.c +++ b/foci.c @@ -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; } diff --git a/foci.h b/foci.h index 3f745a5..c61e302 100644 --- a/foci.h +++ b/foci.h @@ -85,7 +85,7 @@ extern int foci_getchar(void); void init(void); int depth(void); int compiling(void); -void parse_word(const char *buf, const char *s); +void interpret(void); void define(struct word_t *w); void fexit(void); // internal use only diff --git a/main.c b/main.c index 66dcce3..4429d2d 100644 --- a/main.c +++ b/main.c @@ -33,30 +33,11 @@ int foci_getchar(void) int main() { - char buf[128]; - init(); for (;;) { - char c; - do c = getchar(); - 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()); + interpret(); + printf(compiling() ? "compiled <%d>\n" : "ok <%d>\n", depth()); } return 0;