]> code.bitgloo.com Git - clyne/foci.git/commitdiff
add do loop, immediate; branchless fexit
authorClyne Sullivan <clyne@bitgloo.com>
Tue, 28 Jan 2025 12:40:23 +0000 (07:40 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Tue, 28 Jan 2025 12:40:23 +0000 (07:40 -0500)
README.md
foci.c
foci.h

index 721d29f3f81fbd95f2cdce0549698d90a5ed5dcd..91d2a9d4b28515142799e08566282f801a37dfb9 100644 (file)
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
 
 Register usage is the only platform-specific requirement; otherwise, `foci` is written in 100% portable C. There is active support for x86\_64, ARM Cortex-M, and MSP430 architectures.
 
-`foci` compiles to a binary object that can easily be linked into another application. Code size is generally a few kilobytes, while RAM usage is primarily set by the size of `foci`'s two stacks and dictionary.
+`foci` compiles to a binary object that can easily be linked into another application. Code size is less than 5 kB, while RAM usage is in the hundreds of bytes (primarily influenced by the configured stack and dictionary sizes).
 
 ## Available words
 
@@ -12,7 +12,7 @@ Register usage is the only platform-specific requirement; otherwise, `foci` is w
 dup drop swap rot -rot over tuck @ ! c@ c! + +! - * / mod and or xor = < [ ] ,
 cell cell+ cells base here allot latest negate invert 1- 1+ aligned align : ;
 literal if then else ' ['] execute decimal hex . emit begin until again while
-repeat >r r> 2>r 2r>
+repeat >r r> 2>r 2r> r@ do loop i immediate
 ```
 
 ## Build instructions
diff --git a/foci.c b/foci.c
index 2488c9c38a3fb3b76ffcbcf99e6613d2df97b662..fdf7d76012d6e28260539ab0d1fd631be567e695 100644 (file)
--- a/foci.c
+++ b/foci.c
@@ -32,7 +32,10 @@ static intptr_t ***saved_rp;
 
 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 fexit(void) { pp = *rp++; NEXT; }
+
+void fend(void) {}
+static const void * const fend_b[2] = { 0, fend };
 
 NAKED void compname(void)
 {
@@ -161,7 +164,23 @@ N(pushr2, "2>r",    &w_popr)    { *--rp = (intptr_t **)sp[1];
                                   *--rp = (intptr_t **)sp[0]; sp += 2; NEXT; }
 N(popr2,  "2r>",    &w_pushr2)  { *--sp = (intptr_t)rp[1];
                                   *--sp = (intptr_t)rp[0]; rp += 2; NEXT; }
-#define LATEST_INIT &w_popr2
+N(rpeek,  "r@",     &w_popr2)   { *--sp = (intptr_t)*rp; NEXT; }
+N(i,      "i",      &w_rpeek)   { *--sp = (intptr_t)*rp; NEXT; }
+I(fdo,    "do",     &w_i)       LIT(pushr2), comma, FTH(begin), END
+I(loop,   "loop",   &w_fdo)     LIT(popr), comma,
+                                LIT(enter), comma,
+                                LIT(inc_body), comma,
+                                LIT(rpeek), comma,
+                                LIT(over), comma,
+                                LIT(eq), comma,
+                                LIT(swap), comma,
+                                LIT(pushr), comma,
+                                FTH(until),
+                                LIT(popr2), comma,
+                                LIT(drop), comma, LIT(drop), comma, END
+W(immediate, "immediate", &w_loop) FTH(latest), LIT(2 * sizeof(intptr_t)), add,
+                                   LIT(ATTR_IMMEDIATE), over, cpeek, or, swap, cpoke, END
+#define LATEST_INIT &w_immediate
 
 void enter_forth(const void *ptr)
 {
@@ -170,6 +189,7 @@ void enter_forth(const void *ptr)
     rp = saved_rp;
     pp = ptr;
 
+    *--rp = (intptr_t **)fend_b;
     ((void (*)())*pp)();
 
     saved_sp = sp;
@@ -303,6 +323,11 @@ int depth(void)
     return END_OF(dstack) - saved_sp;
 }
 
+int rdepth(void)
+{
+    return END_OF(rstack) - saved_rp;
+}
+
 int compiling(void)
 {
     return STATE;
diff --git a/foci.h b/foci.h
index b666b96fa3e5485e0ef922272a738816874a7764..aae49463d7f156def61fa65985b5699339e7dde8 100644 (file)
--- a/foci.h
+++ b/foci.h
@@ -92,6 +92,7 @@ extern int  foci_getchar(void);
 
 void init(intptr_t *dictmem);
 int depth(void);
+int rdepth(void);
 int compiling(void);
 void interpret(void);
 void define(struct word_t *w);