aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <clyne@bitgloo.com>2025-01-24 07:42:49 -0500
committerClyne Sullivan <clyne@bitgloo.com>2025-01-24 07:42:49 -0500
commit2a4573613033a4fe2ad520fe31e53d35a54d65b7 (patch)
treed8de6cb9b1eec31a20758e01814f5ea530a51569
parent1d3ef290df57710e487f72b861edb147ccfee90b (diff)
isolate foci code
-rw-r--r--Makefile6
-rw-r--r--foci.c168
-rw-r--r--foci.h62
-rw-r--r--main.c190
4 files changed, 241 insertions, 185 deletions
diff --git a/Makefile b/Makefile
index b8cdb4d..e3ccc3d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,2 +1,6 @@
+CC := gcc
+CFLAGS := -O3 -ggdb -g3 -Wall -Wextra
+
all:
- gcc -O3 -ggdb -g3 main.c -o main -Wall -Wextra #-flto
+ $(CC) $(CFLAGS) -c foci.c
+ $(CC) $(CFLAGS) main.c foci.o -o main
diff --git a/foci.c b/foci.c
new file mode 100644
index 0000000..bcb8ae5
--- /dev/null
+++ b/foci.c
@@ -0,0 +1,168 @@
+#include "foci.h"
+
+#include <stdio.h> // puts
+#include <stdlib.h> // strtol
+#include <string.h> // strncmp
+
+#define END_OF(arr) ((arr) + (sizeof((arr)) / sizeof(*(arr))))
+
+static intptr_t dstack[32];
+static intptr_t **rstack[32];
+static intptr_t dict[8192] = {
+ 0, 10
+};
+#define state dict[0]
+#define base dict[1]
+#define begin dict[2]
+static intptr_t *here = &begin;
+static struct word_t *latest;
+
+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; }
+ void fexit(void) { if (rp < END_OF(rstack)) { pp = *rp++; NEXT; } }
+
+NAKED void compname(void)
+{
+ static int ch;
+
+ STASH;
+ for (;;) {
+ extern int getchar(void);
+ ch = getchar();
+
+ if (ch <= 0x20)
+ break;
+
+ *(unsigned char *)here += 1;
+ ((char *)here)[*(unsigned char *)here] = ch;
+ }
+ here = (intptr_t *)((intptr_t)here + *(unsigned char *)here);
+ RESTORE;
+
+ 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; }
+N(rot, "rot", &w_swap) { tmp = sp[0]; sp[0] = sp[2]; sp[2] = sp[1];
+ sp[1] = tmp; NEXT; }
+N(peek, "@", &w_rot) { *sp = *(intptr_t *)*sp; NEXT; }
+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; }
+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(comp, "]", &w_intr) { state = -1; NEXT; }
+N(comma, ",", &w_comp) { *here++ = *sp++; NEXT; }
+W(cell, "cell", &w_comma) LIT(sizeof(*sp)), END
+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(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
+W(inc, "1+", &w_dec) LIT(1), add, END
+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
+I(semic, ";", &w_colon) LIT(fexit), comma, LIT(&latest), poke, intr, END
+I(literal, "literal", &w_semic) LIT(push), comma, comma, END
+#define LATEST &w_literal
+
+void call(void *ptr)
+{
+ pp = ptr;
+ ((void (*)())*pp)();
+}
+
+void parse_word(const char *buf, const char *s)
+{
+ 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;
+ }
+
+ tmp = saved_tmp;
+ sp = saved_sp;
+ rp = saved_rp;
+ pp = saved_pp;
+
+ if (l == 0) {
+ char *end;
+ long n = strtol(buf, &end, base);
+ if (*end == '\0') {
+ if (state) {
+ *here++ = (intptr_t)push;
+ *here++ = n;
+ } else {
+ *--sp = n;
+ }
+ } else {
+ puts("word not found");
+ }
+ } else {
+ if (state && !(l->attr & ATTR_IMMEDIATE)) {
+ if (!(l->attr & ATTR_NATIVE)) {
+ *here++ = (intptr_t)enter;
+ *here++ = (intptr_t)l->body;
+ } else {
+ *here++ = (intptr_t)l->body[0];
+ }
+ } else {
+ call(l->body);
+ }
+ }
+
+ saved_tmp = tmp;
+ saved_sp = sp;
+ saved_rp = rp;
+ saved_pp = pp;
+}
+
+void init(void)
+{
+ saved_tmp = 0;
+ saved_sp = END_OF(dstack);
+ saved_rp = END_OF(rstack);
+ saved_pp = 0;
+
+ latest = LATEST;
+}
+
+int depth(void)
+{
+ return END_OF(dstack) - saved_sp;
+}
+
+int compiling(void)
+{
+ return state;
+}
+
+void define(struct word_t *w)
+{
+ w->prev = latest;
+ latest = w;
+}
+
diff --git a/foci.h b/foci.h
new file mode 100644
index 0000000..3305652
--- /dev/null
+++ b/foci.h
@@ -0,0 +1,62 @@
+#ifndef FOCI_H
+#define FOCI_H
+
+#include <stdint.h>
+
+#define NAKED __attribute__((naked))
+
+#define ATTR_NATIVE (1 << 7)
+#define ATTR_IMMEDIATE (1 << 6)
+#define ATTR_LEN (0x3F)
+
+#define WORD(name, tname, prev, attr) \
+ extern const void *name##_body[]; \
+ struct word_t w_##name = { \
+ name##_body, prev, attr + sizeof(tname) - 1, tname \
+ }; \
+ const void *name##_body[] = {
+#define LIT(x) push, (void *)(x)
+#define FTH(w) enter, (w##_body)
+#define END fexit, };
+#define NATIVE(name, tname, prev, attr) \
+ extern const void *name##_body[]; \
+ NAKED void name(void); \
+ struct word_t w_##name = { \
+ name##_body, prev, \
+ (attr | ATTR_NATIVE) + sizeof(tname) - 1, tname \
+ }; \
+ const void *name##_body[] = { name, fexit }; \
+ NAKED void name(void)
+
+#define W(name, tname, prev) WORD(name, tname, prev, 0)
+#define I(name, tname, prev) WORD(name, tname, prev, ATTR_IMMEDIATE)
+#define N(name, tname, prev) NATIVE(name, tname, prev, 0)
+#define C(name, tname, prev) NATIVE(name, tname, prev, ATTR_IMMEDIATE)
+
+#define STASH asm("push %r12; push %r13; push %r14; push %r15")
+#define RESTORE asm("pop %r15; pop %r14; pop %r13; pop %r12")
+#define NEXT { goto *(*++pp); }
+
+struct word_t
+{
+ const void **body;
+ struct word_t *prev;
+ unsigned char attr;
+ char name[];
+} __attribute__ ((packed));
+
+register intptr_t tmp asm("r12");
+register intptr_t * sp asm("r13"); // pointer to stack cells
+register intptr_t *** rp asm("r14"); // stack of pp
+register intptr_t ** pp asm("r15"); // pointer to ip
+
+void init(void);
+int depth(void);
+int compiling(void);
+void parse_word(const char *buf, const char *s);
+void define(struct word_t *w);
+
+void fexit(void); // internal use only
+
+#endif // FOCI_H
+
diff --git a/main.c b/main.c
index b9e2428..9b237e4 100644
--- a/main.c
+++ b/main.c
@@ -1,139 +1,10 @@
-#include <stdint.h>
-
-#define NAKED __attribute__((naked))
-#define END_OF(arr) ((arr) + (sizeof((arr)) / sizeof(*(arr))))
-
-#define ATTR_NATIVE (1 << 7)
-#define ATTR_IMMEDIATE (1 << 6)
-#define ATTR_LEN (0x3F)
-
-#define WORD(name, tname, prev, attr) \
- extern const void *name##_body[]; \
- struct word_t w_##name = { \
- name##_body, prev, attr + sizeof(tname) - 1, tname \
- }; \
- const void *name##_body[] = {
-#define LIT(x) push, (void *)(x)
-#define FTH(w) enter, (w##_body)
-#define END fexit, };
-#define NATIVE(name, tname, prev, attr) \
- extern const void *name##_body[]; \
- NAKED void name(void); \
- struct word_t w_##name = { \
- name##_body, prev, \
- (attr | ATTR_NATIVE) + sizeof(tname) - 1, tname \
- }; \
- const void *name##_body[] = { name, fexit }; \
- NAKED void name(void)
-
-#define W(name, tname, prev) WORD(name, tname, prev, 0)
-#define I(name, tname, prev) WORD(name, tname, prev, ATTR_IMMEDIATE)
-#define N(name, tname, prev) NATIVE(name, tname, prev, 0)
-#define C(name, tname, prev) NATIVE(name, tname, prev, ATTR_IMMEDIATE)
-
-#define NEXT { goto *(*++pp); }
-
-struct word_t
-{
- const void **body;
- struct word_t *prev;
- unsigned char attr;
- char name[];
-} __attribute__ ((packed));
-
-static intptr_t dstack[32];
-static intptr_t **rstack[32];
-static intptr_t dict[8192] = {
- 0, 10
-};
-#define state dict[0]
-#define base dict[1]
-#define begin dict[2]
-static intptr_t *here = &begin;
-static struct word_t *latest;
-
-register intptr_t tmp asm("r12");
-register intptr_t * sp asm("r13"); // pointer to stack cells
-register intptr_t *** rp asm("r14"); // stack of pp
-register intptr_t ** pp asm("r15"); // pointer to ip
-
-#define STASH asm("push %r12; push %r13; push %r14; push %r15")
-#define RESTORE asm("pop %r15; pop %r14; pop %r13; pop %r12")
-
-NAKED void dot(void);
-NAKED void enter(void) { *--rp = ++pp; pp = (intptr_t **)*pp; goto *(*pp); }
-NAKED void push(void) { *--sp = (intptr_t)*++pp; NEXT; }
- void fexit(void) { if (rp < END_OF(rstack)) { pp = *rp++; NEXT; } }
-
-NAKED void compname(void)
-{
- static int ch;
-
- STASH;
- for (;;) {
- extern int getchar(void);
- ch = getchar();
-
- if (ch <= 0x20)
- break;
-
- *(unsigned char *)here += 1;
- ((char *)here)[*(unsigned char *)here] = ch;
- }
- here = (intptr_t *)((intptr_t)here + *(unsigned char *)here);
- RESTORE;
-
- 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; }
-N(rot, "rot", &w_swap) { tmp = sp[0]; sp[0] = sp[2]; sp[2] = sp[1];
- sp[1] = tmp; NEXT; }
-N(peek, "@", &w_rot) { *sp = *(intptr_t *)*sp; NEXT; }
-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; }
-N(mul, "*", &w_sub) { sp[1] *= sp[0]; ++sp; NEXT; }
-N(div, "/", &w_mul) { sp[1] /= sp[0]; ++sp; NEXT; }
-N(mod, "mod", &w_div) { 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(comp, "]", &w_intr) { state = -1; NEXT; }
-N(comma, ",", &w_comp) { *here++ = *sp++; NEXT; }
-W(cell, "cell", &w_comma) LIT(sizeof(*sp)), END
-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
-N(dot, ".", &w_latest) ;
-W(negate, "negate", &w_dot) LIT(-1), mul, END
-W(invert, "invert", &w_negate) LIT(-1), xor, END
-W(dec, "1-", &w_invert) LIT(1), sub, END
-W(inc, "1+", &w_dec) LIT(1), add, END
-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
-I(semic, ";", &w_colon) LIT(fexit), comma, LIT(&latest), poke, intr, END
-I(literal, "literal", &w_semic) LIT(push), comma, comma, END
-#define LATEST &w_literal
+#include "foci.h"
#include <ctype.h>
#include <stdio.h>
#include <string.h>
-extern long strtol(char *, char **, int);
-
-NAKED void dot() {
+N(dot, ".", 0) {
STASH;
printf("%ld ", *sp);
RESTORE;
@@ -141,13 +12,12 @@ NAKED void dot() {
NEXT;
}
-static void call(void *ptr);
-static void init(void);
-
int main()
+{
char buf[128];
init();
+ define(&w_dot);
for (;;) {
char c;
@@ -164,59 +34,11 @@ int main()
if (strcmp(buf, "bye") == 0)
break;
- struct word_t *l;
- for (l = latest; l; l = l->prev) {
- const int ln = l->attr & ATTR_LEN;
+ parse_word(buf, s);
- if (s - buf == ln && !strncmp(buf, l->name, ln))
- break;
- }
-
- if (l == 0) {
- char *end;
- long n = strtol(buf, &end, base);
- if (*end == '\0') {
- if (state) {
- *here++ = (intptr_t)push;
- *here++ = n;
- } else {
- *--sp = n;
- }
- } else {
- puts("word not found");
- }
- } else {
- if (state && !(l->attr & ATTR_IMMEDIATE)) {
- if (!(l->attr & ATTR_NATIVE)) {
- *here++ = (intptr_t)enter;
- *here++ = (intptr_t)l->body;
- } else {
- *here++ = (intptr_t)l->body[0];
- }
- } else {
- call(l->body);
- }
- }
-
- printf(state ? "compiled <%ld>\n" : "ok <%ld>\n",
- (END_OF(dstack) - sp));
+ printf(compiling() ? "compiled <%d>\n" : "ok <%d>\n", depth());
}
return 0;
}
-void init(void)
-{
- sp = END_OF(dstack);
- rp = END_OF(rstack);
- pp = 0;
-
- latest = LATEST;
-}
-
-void call(void *ptr)
-{
- pp = ptr;
- ((void (*)())*pp)();
-}
-