aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <clyne@bitgloo.com>2025-01-25 07:50:34 -0500
committerClyne Sullivan <clyne@bitgloo.com>2025-01-25 07:50:34 -0500
commitcf190433cba21a61a9f42367c39862198a2eb761 (patch)
tree2c70dd1685fa4321e19b2aab323b9fed5e13720d
parent8f4f89d5b67ae72eb55535ff8d744f5983b32737 (diff)
tick and execute
-rw-r--r--foci.c68
1 files changed, 53 insertions, 15 deletions
diff --git a/foci.c b/foci.c
index d957c57..edf964f 100644
--- a/foci.c
+++ b/foci.c
@@ -17,7 +17,6 @@
#include "foci.h"
#include <stdlib.h> // strtol
-#include <string.h> // strncmp
#define END_OF(arr) ((arr) + (sizeof((arr)) / sizeof(*(arr))))
@@ -46,6 +45,7 @@ NAKED void compname(void)
static int ch;
STASH;
+ *(unsigned char *)here = 0;
for (;;) {
ch = foci_getchar();
@@ -55,12 +55,41 @@ NAKED void compname(void)
*(unsigned char *)here += 1;
((char *)here)[*(unsigned char *)here] = ch;
}
- here = (intptr_t *)((intptr_t)here + *(unsigned char *)here);
RESTORE;
+ *--sp = *(unsigned char *)here;
NEXT;
}
+int compare(const char *a, const char *b, int l)
+{
+ for (; l--; a++, b++) {
+ if (*a != *b)
+ return 1;
+ }
+
+ return 0;
+}
+
+NAKED
+void lookup()
+{
+ static struct word_t *l;
+
+ STASH;
+ for (l = latest; l; l = l->prev) {
+ if (*(char *)here == (l->attr & ATTR_LEN) &&
+ !compare((char *)((intptr_t)here + 1), l->name, *(char *)here))
+ {
+ break;
+ }
+ }
+ RESTORE;
+
+ *--sp = (intptr_t)l;
+ NEXT;
+}
+
N(dup, "dup", 0) { --sp; sp[0] = sp[1]; NEXT; }
N(drop, "drop", &w_dup) { ++sp; NEXT; }
N(swap, "swap", &w_drop) { tmp = sp[0]; sp[0] = sp[1]; sp[1] = tmp; NEXT; }
@@ -71,14 +100,16 @@ N(poke, "!", &w_peek) { *(intptr_t *)sp[0] = sp[1]; sp += 2; NEXT; }
N(cpeek, "c@", &w_poke) { *sp = *(char *)*sp; NEXT; }
N(cpoke, "c!", &w_cpeek) { *(char *)sp[0] = (char)sp[1]; sp += 2; NEXT; }
N(add, "+", &w_cpoke) { sp[1] += sp[0]; ++sp; NEXT; }
-N(sub, "-", &w_add) { sp[1] -= sp[0]; ++sp; NEXT; }
+W(addto, "+!", &w_add) dup, peek, rot, add, swap, poke, END
+N(sub, "-", &w_addto) { sp[1] -= sp[0]; ++sp; NEXT; }
N(mul, "*", &w_sub) { sp[1] *= sp[0]; ++sp; NEXT; }
N(ndiv, "/", &w_mul) { sp[1] /= sp[0]; ++sp; NEXT; }
N(mod, "mod", &w_ndiv) { sp[1] %= sp[0]; ++sp; NEXT; }
N(and, "and", &w_mod) { sp[1] &= sp[0]; ++sp; NEXT; }
N(or, "or", &w_and) { sp[1] |= sp[0]; ++sp; NEXT; }
N(xor, "xor", &w_or) { sp[1] ^= sp[0]; ++sp; NEXT; }
-C(intr, "[", &w_xor) { state = 0; NEXT; }
+N(compname, "_c", &w_xor) ;
+C(intr, "[", &w_compname) { state = 0; NEXT; }
N(comp, "]", &w_intr) { state = -1; NEXT; }
N(comma, ",", &w_comp) { *here++ = *sp++; NEXT; }
W(cell, "cell", &w_comma) LIT(sizeof(*sp)), END
@@ -86,7 +117,8 @@ W(cellp, "cell+", &w_cell) FTH(cell), add, END
W(cells, "cells", &w_cellp) FTH(cell), mul, END
W(dict, "_d", &w_cells) LIT(dict), END
W(here, "here", &w_dict) LIT(&here), peek, END
-W(latest, "latest", &w_here) LIT(&latest), peek, END
+W(allot, "allot", &w_here) LIT(&here), FTH(addto), END
+W(latest, "latest", &w_allot) LIT(&latest), peek, END
W(negate, "negate", &w_latest) LIT(-1), mul, END
W(invert, "invert", &w_negate) LIT(-1), xor, END
W(dec, "1-", &w_invert) LIT(1), sub, END
@@ -95,8 +127,8 @@ W(aligned, "aligned", &w_inc) LIT(sizeof(*sp) - 1), add, LIT(~(sizeof(*sp) - 1
and, END
W(align, "align", &w_aligned) FTH(here), FTH(aligned), LIT(&here), poke, END
W(colon, ":", &w_align) FTH(here), LIT(0), comma, FTH(latest), comma,
- compname, FTH(align), dup, FTH(here), swap,
- poke, comp, END
+ compname, FTH(allot), FTH(align), dup,
+ FTH(here), swap, poke, comp, END
I(semic, ";", &w_colon) LIT(fexit), comma, LIT(&latest), poke, intr, END
I(literal, "literal", &w_semic) LIT(push), comma, comma, END
N(b, "_b", &w_literal) { ++pp; pp = (intptr_t **)*pp; NEXT; }
@@ -104,7 +136,9 @@ N(bz, "_bz", &w_literal) { ++pp; if (!*sp++) { pp = (intptr_t **)*pp; } N
I(fif, "if", &w_b) LIT(bz), comma, FTH(here), LIT(0), comma, END
I(then, "then", &w_fif) FTH(here), LIT(sizeof(intptr_t)), sub, swap, poke, END
I(felse, "else", &w_then) LIT(b), comma, FTH(here), LIT(0), comma, swap, FTH(then), END
-#define LATEST &w_felse
+W(tick, "\'", &w_felse) compname, drop, lookup, peek, END
+N(execute, "execute", &w_tick) { pp = (intptr_t **)*sp++ - 1; NEXT; }
+#define LATEST &w_execute
void call(void *ptr)
{
@@ -112,16 +146,20 @@ void call(void *ptr)
((void (*)())*pp)();
}
-void parse_word(const char *buf, const char *s)
+struct word_t *lookup_p(const char *s, int len)
{
- struct word_t *l;
- for (l = latest; l; l = l->prev) {
- const int ln = l->attr & ATTR_LEN;
-
- if (s - buf == ln && !strncmp(buf, l->name, ln))
- break;
+ for (struct word_t *l = latest; l; l = l->prev) {
+ if (len == (l->attr & ATTR_LEN) && !compare(s, l->name, len))
+ return l;
}
+ return 0;
+}
+
+void parse_word(const char *buf, const char *s)
+{
+ struct word_t *l = lookup_p(buf, s - buf);
+
tmp = saved_tmp;
sp = saved_sp;
rp = saved_rp;