Factored FIND.
[forth.jl.git] / src / forth.jl
index 890cf24..37ce5d1 100644 (file)
@@ -707,10 +707,12 @@ FROMLINK_CFA = defPrimWord("LINK>", () -> begin
     return NEXT
 end)
 
+NUMCONTEXT, NUMCONTEXT_CFA = defNewVar("#CONTEXT", 1)
+
 createHeader("FORTH", 0)
 FORTH_CFA = mem[H]
 dictWrite(defPrim(() -> begin
-    mem[CONTEXT] = reg.W
+    mem[CONTEXT + mem[NUMCONTEXT] - 1] = reg.W
     return NEXT
 end, name="FORTH"))
 dictWrite(0) # cell for latest
@@ -723,41 +725,31 @@ mem[CURRENT] = FORTH_CFA
 
 CONTEXT, CONTEXT_CFA = defNewVar("CONTEXT", zeros(Int64, 10))
 mem[CONTEXT] = FORTH_CFA
-NUMCONTEXT, NUMCONTEXT_CFA = defNewVar("#CONTEXT", 1)
-
-FIND_CFA = defPrimWord("FIND", () -> begin
 
+FINDVOCAB_CFA = defPrimWord("FINDVOCAB", () -> begin
+    vocabCFA = popPS()
     countedAddr = popPS()
+
     wordAddr = countedAddr + 1
     wordLen = mem[countedAddr]
     word = lowercase(getString(wordAddr, wordLen))
 
-    context = mem[CONTEXT:(CONTEXT+mem[NUMCONTEXT]-1)]
-
+    lfa = vocabCFA+1
     lenAndFlags = 0
-    lfa = 0
 
-    for vocabCFA in reverse(context)
-        lfa = vocabCFA+1
-
-        while (lfa = mem[lfa]) > 0
-
-            lenAndFlags = mem[lfa+1]
-            len = lenAndFlags & F_LENMASK
-            hidden = (lenAndFlags & F_HIDDEN) == F_HIDDEN
-
-            if hidden || len != wordLen
-                continue
-            end
+    while (lfa = mem[lfa]) > 0
 
-            thisWord = lowercase(getString(lfa+2, len))
+        lenAndFlags = mem[lfa+1]
+        len = lenAndFlags & F_LENMASK
+        hidden = (lenAndFlags & F_HIDDEN) == F_HIDDEN
 
-            if thisWord == word
-                break
-            end
+        if hidden || len != wordLen
+            continue
         end
 
-        if lfa>0
+        thisWord = lowercase(getString(lfa+2, len))
+
+        if thisWord == word
             break
         end
     end
@@ -778,6 +770,31 @@ FIND_CFA = defPrimWord("FIND", () -> begin
     return NEXT
 end)
 
+FIND_CFA = defPrimWord("FIND", () -> begin
+
+    countedAddr = popPS()
+    context = mem[CONTEXT:(CONTEXT+mem[NUMCONTEXT]-1)]
+
+    for vocabCFA in reverse(context)
+        pushPS(countedAddr)
+        pushPS(vocabCFA)
+        callPrim(mem[FINDVOCAB_CFA])
+
+        callPrim(mem[DUP_CFA])
+        if popPS() != 0
+            return NEXT
+        else
+            popPS()
+            popPS()
+        end
+    end
+
+    pushPS(countedAddr)
+    pushPS(0)
+
+    return NEXT
+end)
+
 
 # Branching