From 461581a84e20da8df15533e00c64236c812b3757 Mon Sep 17 00:00:00 2001
From: Clyne Sullivan <clyne@bitgloo.com>
Date: Thu, 23 Jan 2025 08:01:15 -0500
Subject: initial upload

---
 .gitignore |  18 +---
 Makefile   |   2 +
 main.c     | 274 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 279 insertions(+), 15 deletions(-)
 create mode 100644 Makefile
 create mode 100644 main.c

diff --git a/.gitignore b/.gitignore
index cd531cf..93fffd4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,6 @@
+main
+.sw*
+
 # ---> C
 # Prerequisites
 *.d
@@ -37,18 +40,3 @@
 *.x86_64
 *.hex
 
-# Debug files
-*.dSYM/
-*.su
-*.idb
-*.pdb
-
-# Kernel Module Compile Results
-*.mod*
-*.cmd
-.tmp_versions/
-modules.order
-Module.symvers
-Mkfile.old
-dkms.conf
-
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..b8cdb4d
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,2 @@
+all:
+	gcc -O3 -ggdb -g3 main.c -o main -Wall -Wextra #-flto
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..440ceff
--- /dev/null
+++ b/main.c
@@ -0,0 +1,274 @@
+#include <stdint.h>
+#include <stdio.h>
+
+#define NAKED __attribute__((naked))
+
+#define END_OF(arr) ((arr) + (sizeof((arr)) / sizeof(*(arr))))
+#define NEXT        { goto *(*++pp); }
+
+#define LIT(x)  push, (void *)(x)
+#define FTH(w)  enter, (w##_body)
+#define EXIT    doexit
+
+#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 END    EXIT, };
+
+#define W(name, tname, prev) WORD(name, tname, prev, 0)
+#define N(name, tname, prev) WORD(name, tname, prev, ATTR_NATIVE)
+#define I(name, tname, prev) WORD(name, tname, prev, ATTR_IMMEDIATE)
+
+struct word_t
+{
+    const void **body;
+    struct word_t *prev;
+    unsigned char attr;
+    char name[];
+} __attribute__ ((packed));
+
+intptr_t dstack[32];
+intptr_t **rstack[32];
+intptr_t dict[8192];
+
+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 push()
+{
+    *--sp = (intptr_t)*++pp;
+    NEXT;
+}
+
+NAKED
+void sp_at()
+{
+    *sp = (intptr_t)sp;
+    sp = sp - 1;
+    NEXT;
+}
+
+NAKED
+void enter()
+{
+    *--rp = ++pp;
+    pp = (intptr_t **)*pp;
+    goto *(*pp);
+}
+
+void doexit()
+{
+    if (rp < END_OF(rstack)) {
+        pp = *rp++;
+        NEXT;
+    }
+
+    pp = 0;
+}
+
+intptr_t state = 0;
+intptr_t *here = dict;
+
+NAKED void  drop() { ++sp;                 NEXT; }
+NAKED void  swap() { tmp = sp[0]; sp[0] = sp[1]; sp[1] = tmp; NEXT; }
+NAKED void   add() { sp[1] += sp[0]; ++sp; NEXT; }
+NAKED void   sub() { sp[1] -= sp[0]; ++sp; NEXT; }
+NAKED void   mul() { sp[1] *= sp[0]; ++sp; NEXT; }
+NAKED void   div() { sp[1] /= sp[0]; ++sp; NEXT; }
+NAKED void   mod() { sp[1] %= sp[0]; ++sp; NEXT; }
+NAKED void   and() { sp[1] &= sp[0]; ++sp; NEXT; }
+NAKED void    or() { sp[1] |= sp[0]; ++sp; NEXT; }
+NAKED void   xor() { sp[1] ^= sp[0]; ++sp; NEXT; }
+NAKED void  cell() { *--sp = sizeof(*sp);  NEXT; }
+NAKED void  peek() { *sp = *(intptr_t *)*sp; NEXT; }
+NAKED void  poke() { *(intptr_t *)sp[0] = sp[1]; sp -= 2; NEXT; }
+NAKED void cpeek() { *sp = *(char *)*sp; NEXT; }
+NAKED void cpoke() { *(char *)sp[0] = sp[1]; sp -= 2; NEXT; }
+NAKED void  comp() { state = -1; NEXT; }
+NAKED void  intr() { state = 0; NEXT; }
+NAKED void   dot() { printf("%ld ", *sp++); NEXT; }
+NAKED void comma() { *here++ = *sp++; NEXT; }
+
+NAKED void align() {
+    here = (intptr_t *)(((intptr_t)here + sizeof(intptr_t) - 1)
+        & ~(sizeof(intptr_t) - 1));
+    NEXT;
+}
+
+NAKED void colon()
+{
+    extern struct word_t *latest;
+    static int ch;
+
+    tmp = (intptr_t)here++; // body
+    *here++ = (intptr_t)latest;
+
+    STASH;
+    for (;;) {
+        ch = getchar();
+
+        if (ch <= 0x20)
+            break;
+
+        *(unsigned char *)here += 1;
+        ((char *)here)[*(unsigned char *)here] = ch;
+    }
+    RESTORE;
+
+    here = (intptr_t *)(((intptr_t)here + sizeof(intptr_t) - 1)
+        & ~(sizeof(intptr_t) - 1));
+    *(intptr_t *)tmp = (intptr_t)here;
+    NEXT;
+}
+
+//W(two,  "2",            &w_dup)  LIT(2), FTH(dup), END
+
+W(dup,   "dup",         0)        sp_at, peek,      END
+W(drop,  "drop",        &w_dup)   drop,             END
+W(swap,  "swap",        &w_drop)  swap,             END
+W(peek,  "@",           &w_swap)  peek,             END
+W(poke,  "!",           &w_peek)  poke,             END
+W(cpeek, "c@",          &w_poke)  cpeek,            END
+W(cpoke, "c!",          &w_cpeek) cpoke,            END
+W(add,   "+",           &w_cpoke) add,              END
+W(sub,   "-",           &w_add)   sub,              END
+W(mul,   "*",           &w_sub)   mul,              END
+W(div,   "/",           &w_mul)   div,              END
+W(mod,   "mod",         &w_div)   mod,              END
+W(and,   "and",         &w_mod)   and,              END
+W(or,    "or",          &w_and)   or,               END
+W(xor,   "xor",         &w_or)    xor,              END
+W(cell,  "cell",        &w_xor)   cell,             END
+W(cellp, "cell+",       &w_cell)  cell, add,        END
+W(cells, "cells",       &w_cellp) cell, mul,        END
+W(dict,  "_d",          &w_cells) LIT(dict),        END
+W(here,  "here",        &w_dict)  LIT(&here), peek, END
+I(intr,  "[",           &w_here)  intr,             END
+W(comp,  "]",           &w_intr)  comp,             END
+W(dot,   ".",           &w_comp)  dot,              END
+W(colon, ":",           &w_dot)   colon,            END
+W(align, "align",       &w_colon) align,            END
+W(comma, ",",           &w_align) comma,            END
+struct word_t *latest = &w_comma;
+
+void init()
+{
+    sp = END_OF(dstack);
+    rp = END_OF(rstack);
+    pp = 0;
+}
+
+void dump()
+{
+    //printf("IP: %ld\n", (intptr_t)pp);
+
+    printf("DS: ");
+    intptr_t *it = END_OF(dstack) - 1;
+    while (it >= sp) {
+        printf("%ld ", *it);
+        --it;
+    }
+    putchar('\n');
+
+    //printf("RS: ");
+    //intptr_t ***rt = END_OF(rstack) - 1;
+    //while (rt >= rp) {
+    //    printf("%ld ", (intptr_t)*rt);
+    //    --rt;
+    //}
+    //putchar('\n');
+}
+
+void call(void *ptr)
+{
+    pp = ptr;
+    ((void (*)())*pp)();
+}
+
+//struct word_t
+//{
+//    const void **body;
+//    struct word_t *prev;
+//    unsigned char attr;
+//    char name[];
+//} __attribute__ ((packed));
+
+//NAKED void key() { *--sp = getchar(); NEXT; }
+
+#include <ctype.h>
+#include <string.h>
+
+extern long strtol(char *, char **, int);
+
+int base = 10;
+
+int main()
+{
+    char buf[128];
+
+    init();
+
+    for (;;) {
+        //dump();
+        printf("> ");
+
+        char c;
+        do c = getchar();
+        while (!isgraph(c));
+
+        char *s = buf;
+        do {
+            *s++ = c;
+            c = getchar();
+        } while (isgraph(c));
+        *s = '\0';
+
+        if (strcmp(buf, "bye") == 0)
+            break;
+
+        struct word_t *l;
+        for (l = latest; l; l = l->prev) {
+            if (strncmp(buf, l->name, l->attr & ATTR_LEN) == 0)
+                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)) {
+                *here++ = (intptr_t)l->body;
+            } else {
+                call(l->body);
+            }
+        }
+
+        puts(state ? "compiled" : "ok");
+    }
+
+    return 0;
+}
+
-- 
cgit v1.2.3