A bit of abstraction.
[forth.jl.git] / src / forth.jl
index 57fda1b..da7321b 100644 (file)
@@ -109,21 +109,27 @@ F_IMMED = 32
 F_HIDDEN = 64
 NFA_MARK = 128
 
+function dictWrite(ints::Array{Int64,1})
+    mem[mem[H]:(mem[H]+length(ints)-1)] = ints
+    mem[H] += length(ints)
+end
+dictWrite(int::Int64) = dictWrite([int])
+dictWriteString(string::ASCIIString) = dictWrite([Int64(c) for c in string])
+
 function createHeader(name::AbstractString, flags::Int64)
     mem[mem[H]] = mem[mem[CURRENT]]
     mem[mem[CURRENT]] = mem[H]
     mem[H] += 1
 
-    mem[mem[H]] = length(name) | flags | NFA_MARK; mem[H] += 1
-    putString(name, mem[H]); mem[H] += length(name)
+    dictWrite(length(name) | flags | NFA_MARK)
+    dictWriteString(name)
 end
 
 function defPrimWord(name::AbstractString, f::Function; flags::Int64=0)
     createHeader(name, flags)
 
     codeWordAddr = mem[H]
-    mem[codeWordAddr] = defPrim(f, name=name)
-    mem[H] += 1
+    dictWrite(defPrim(f, name=name))
 
     return codeWordAddr
 end
@@ -132,13 +138,9 @@ function defWord(name::AbstractString, wordAddrs::Array{Int64,1}; flags::Int64=0
     createHeader(name, flags)
 
     addr = mem[H]
-    mem[mem[H]] = DOCOL
-    mem[H] += 1
+    dictWrite(DOCOL)
 
-    for wordAddr in wordAddrs
-        mem[mem[H]] = wordAddr
-        mem[H] += 1
-    end
+    dictWrite(wordAddrs)
 
     return addr
 end
@@ -159,8 +161,8 @@ function defNewVar(name::AbstractString, initial::Array{Int64,1}; flags::Int64=0
     codeWordAddr = mem[H]
     varAddr = mem[H] + 1
 
-    mem[mem[H]] = DOVAR; mem[H] += 1
-    mem[mem[H]:(mem[H]+length(initial)-1)] = initial; mem[H] += length(initial)
+    dictWrite(DOVAR)
+    dictWrite(initial)
 
     return varAddr, codeWordAddr
 end
@@ -173,8 +175,8 @@ function defConst(name::AbstractString, val::Int64; flags::Int64=0)
 
     codeWordAddr = mem[H]
 
-    mem[mem[H]] = DOCON; mem[H] += 1
-    mem[mem[H]] = val; mem[H] += 1
+    dictWrite(DOCON)
+    dictWrite(val)
 
     return codeWordAddr
 end
@@ -211,7 +213,8 @@ end)
 # Dictionary entries for core built-in variables, constants
 
 H_CFA = defExistingVar("H", H)
-#LATEST_CFA = defExistingVar("LATEST", LATEST)
+FORTH_CFA = defExistingVar("FORTH", FORTH)
+CURRENT_CFA = defExistingVar("CURRENT", CURRENT)
 
 PSP0_CFA = defConst("PSP0", PSP0)
 RSP0_CFA = defConst("RSP0", RSP0)
@@ -708,7 +711,6 @@ end)
 
 TOBODY_CFA = defWord(">BODY", [INCR_CFA, EXIT_CFA])
 
-FORTH_CFA = defExistingVar("FORTH", FORTH)
 CONTEXT, CONTEXT_CFA = defNewVar("CONTEXT", zeros(Int64, 100))
 mem[CONTEXT] = FORTH_CFA
 NUMCONTEXT, NUMCONTEXT_CFA = defNewVar("#CONTEXT", 1)
@@ -720,7 +722,7 @@ FIND_CFA = defPrimWord("FIND", () -> begin
     wordLen = mem[countedAddr]
     word = lowercase(getString(wordAddr, wordLen))
 
-    context = mem[CONTEXT:(CONTEXT+mem[NUMCONTEXT])]
+    context = mem[CONTEXT:(CONTEXT+mem[NUMCONTEXT]-1)]
 
     lenAndFlags = 0
     lfa = 0
@@ -729,7 +731,8 @@ FIND_CFA = defPrimWord("FIND", () -> begin
         callPrim(mem[vocabCFA])
         lfa = popPS()
 
-        while lfa > 0
+        while (lfa = mem[lfa]) > 0
+
             lenAndFlags = mem[lfa+1]
             len = lenAndFlags & F_LENMASK
             hidden = (lenAndFlags & F_HIDDEN) == F_HIDDEN
@@ -738,14 +741,11 @@ FIND_CFA = defPrimWord("FIND", () -> begin
                 continue
             end
 
-            thisAddr = latest+2
-            thisWord = lowercase(getString(thisAddr, len))
+            thisWord = lowercase(getString(lfa+2, len))
 
-            if lowercase(thisWord) == lowercase(word)
+            if thisWord == word
                 break
             end
-
-            lfa = mem[lfa]
         end
 
         if lfa>0