#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; }
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;
}
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;
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;
while (*s)
foci_putchar(*s++);
foci_putchar(' ');
+}
+NAKED
+void dot()
+{
+ STASH;
+ dotimpl(*sp);
RESTORE;
++sp;
NEXT;
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";
*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;
}