aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <clyne@bitgloo.com>2025-01-23 08:01:15 -0500
committerClyne Sullivan <clyne@bitgloo.com>2025-01-23 08:01:15 -0500
commit461581a84e20da8df15533e00c64236c812b3757 (patch)
tree368e426c9569e14978670391d15c112e46908627
parentc3fe00bca71fd48f9423cc9a2c319b477e556974 (diff)
initial upload
-rw-r--r--.gitignore18
-rw-r--r--Makefile2
-rw-r--r--main.c274
3 files changed, 279 insertions, 15 deletions
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;
+}
+