aboutsummaryrefslogtreecommitdiffstats
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c190
1 files changed, 6 insertions, 184 deletions
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)();
-}
-