]> code.bitgloo.com Git - clyne/foci.git/commitdiff
isolate foci code
authorClyne Sullivan <clyne@bitgloo.com>
Fri, 24 Jan 2025 12:42:49 +0000 (07:42 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Fri, 24 Jan 2025 12:42:49 +0000 (07:42 -0500)
Makefile
foci.c [new file with mode: 0644]
foci.h [new file with mode: 0644]
main.c

index b8cdb4dd953f13e489e6bb24a403ae9b2a91d876..e3ccc3defcc5d4c177e71deb3a75d55a2c25e2fd 100644 (file)
--- 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 (file)
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 (file)
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 b9e2428096362a413fbfb008575e7d28e8da49a0..9b237e4ae569192cfc08d982f3458ca0e93fe228 100644 (file)
--- a/main.c
+++ b/main.c
-#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)();
-}
-