Adequate handling of EOF restored.
[forth.jl.git] / src / forth.jl
index 0803b72..a233743 100644 (file)
@@ -108,6 +108,7 @@ end
 # Handy functions for adding/retrieving strings to/from memory.
 
 getString(addr::Int64, len::Int64) = ASCIIString([Char(c) for c in mem[addr:(addr+len-1)]])
+
 function putString(str::ASCIIString, addr::Int64)
     mem[addr:(addr+length(str)-1)] = [Int64(c) for c in str]
 end
@@ -116,12 +117,18 @@ end
 
 function defPrim(f::Function; name="nameless")
     push!(primitives, f)
-    push!(primNames, replace(replace(name, "\004", "EOF"), "\n", "\\n"))
+    push!(primNames, replace(name, "\004", "EOF"))
 
     return -length(primitives)
 end
 
-callPrim(addr::Int64) = primitives[-addr]()
+function callPrim(addr::Int64)
+    if addr >=0 || -addr>length(primitives)
+        error("Attempted to execute non-existent primitive at address $addr.")
+    else
+        primitives[-addr]()
+    end
+end
 getPrimName(addr::Int64) = primNames[-addr]
 
 # Word creation functions
@@ -598,7 +605,14 @@ end)
 sources = Array{Any,1}()
 currentSource() = sources[length(sources)]
 
-EOF_CFA = defConst("EOF", 4)
+EOF = defPrimWord("\x04", () -> begin
+    close(pop!(sources))
+    if !isempty(sources)
+        return NEXT
+    else
+        return 0
+    end
+end)
 
 EMIT = defPrimWord("EMIT", () -> begin
     print(Char(popPS()))
@@ -616,7 +630,7 @@ EXPECT = defPrimWord("EXPECT", () -> begin
         putString(line[1:mem[SPAN]], addr)
     else
         mem[SPAN] = 1
-        mem[addr] = EOF
+        mem[addr] = 4 # eof
     end
 
     return NEXT
@@ -721,9 +735,9 @@ end)
 # Outer interpreter
 
 TRACE = defPrimWord("TRACE", () -> begin
-    println("Val: $(popPS())")
-    print("RS: "); printRS()
+    println("reg.W: $(reg.W) reg.IP: $(reg.IP)")
     print("PS: "); printPS()
+    print("RS: "); printRS()
     print("[paused]")
     readline()
 
@@ -936,9 +950,6 @@ IMMEDIATE = defPrimWord("IMMEDIATE", () -> begin
     return NEXT
 end, flags=F_IMMED)
 
-TICK = defWord("'",
-    [LIT, 32, WORD, FIND, TOCFA, EXIT])
-
 
 #### VM loop ####
 
@@ -950,7 +961,7 @@ elseif isfile(Pkg.dir("forth/src/lib.4th"))
     initFileName = Pkg.dir("forth/src/lib.4th")
 end
 
-function run(;initialize=false)
+function run(;initialize=true)
     # Begin with STDIN as source
     push!(sources, STDIN)
 
@@ -973,7 +984,7 @@ function run(;initialize=false)
     jmp = NEXT
     while jmp != 0
         try
-            #println("Entering prim $(getPrimName(jmp))")
+#           println("Entering prim $(getPrimName(jmp))")
             jmp = callPrim(jmp)
 
         catch ex
@@ -984,6 +995,11 @@ function run(;initialize=false)
                 close(pop!(sources))
             end
 
+            # Want backtrace in here eventually
+            println("reg.W: $(reg.W) reg.IP: $(reg.IP)")
+            print("PS: "); printPS()
+            print("RS: "); printRS()
+
             mem[STATE] = 0
             mem[NUMTIB] = 0
             reg.PSP = mem[PSP0]