Implemented ABORT".
[forth.jl.git] / src / forth.jl
index 9668025..f10ea04 100644 (file)
@@ -13,7 +13,7 @@ mem = Array{Int64,1}(size_mem)
 primitives = Array{Function,1}()
 primNames = Array{ASCIIString,1}()
 
-# Built-in variables
+# Memory geography and built-in variables
 
 nextVarAddr = 1
 H = nextVarAddr; nextVarAddr += 1              # Next free memory address
@@ -84,6 +84,8 @@ function putString(str::ASCIIString, addr::Int64)
     mem[addr:(addr+length(str)-1)] = [Int64(c) for c in str]
 end
 
+stringAsInts(str::ASCIIString) = [Int(c) for c in collect(str)]
+
 # Primitive creation and calling functions
 
 function defPrim(f::Function; name="nameless")
@@ -726,39 +728,30 @@ mem[CURRENT] = FORTH_CFA
 CONTEXT, CONTEXT_CFA = defNewVar("CONTEXT", zeros(Int64, 10))
 mem[CONTEXT] = FORTH_CFA
 
-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
+    while (lfa = mem[lfa]) > 0
 
-            lenAndFlags = mem[lfa+1]
-            len = lenAndFlags & F_LENMASK
-            hidden = (lenAndFlags & F_HIDDEN) == F_HIDDEN
+        lenAndFlags = mem[lfa+1]
+        len = lenAndFlags & F_LENMASK
+        hidden = (lenAndFlags & F_HIDDEN) == F_HIDDEN
 
-            if hidden || len != wordLen
-                continue
-            end
-
-            thisWord = lowercase(getString(lfa+2, len))
-
-            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
@@ -779,6 +772,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
 
@@ -994,8 +1012,11 @@ INTERPRET_CFA = defWord("INTERPRET",
     EXIT_CFA])
 
 PROMPT_CFA = defPrimWord("PROMPT", () -> begin
-    if (mem[STATE] == 0 && currentSource() == STDIN)
-        println(" ok")
+    if currentSource() == STDIN
+        if mem[STATE] == 0
+            print(" ok")
+        end
+        println()
     end
 
     return NEXT