Working on getting initialization working again.
[forth.jl.git] / src / forth.jl
index 628f379..f125707 100644 (file)
@@ -604,7 +604,6 @@ end)
 
 openFiles = Dict{Int64,IOStream}()
 nextFileID = 1
-SOURCE_ID, SOURCE_ID_CFA = defNewVar("SOURCE-ID", 0)
 
 
 ## File access modes
@@ -666,6 +665,22 @@ CLOSE_FILES_CFA = defPrimWord("CLOSE-FILES", () -> begin
 end)
 
 READ_LINE_CFA = defPrimWord("READ-LINE", () -> begin
+    fid = popPS()
+    maxSize = popPS()
+    addr = popPS()
+
+    fh = openFiles[fid]
+    line = readline(fh)
+
+    eofFlag = endswith(line, '\n') ? 0 : -1
+    line = chomp(line)
+
+    putString(line, addr, maxSize)
+
+    pushPS(length(line))
+    pushPS(eofFlag)
+    pushPS(0)
+
     return NEXT
 end)
 
@@ -945,6 +960,19 @@ NUMFIB, NUMFIB_CFA = defNewVar("#FIB", 0)
 
 TOIN, TOIN_CFA = defNewVar(">IN", 0)
 
+SOURCE_ID, SOURCE_ID_CFA = defNewVar("SOURCE-ID", 0)
+
+SOURCE_CFA = defPrimWord("SOURCE", () -> begin
+    if mem[SOURCE_ID] == 0
+        pushPS(TIB)
+        pushPS(NUMTIB)
+    else
+        pushPS(FIB)
+        pushPS(NUMFIB)
+    end
+    return NEXT
+end)
+
 QUERY_CFA = defWord("QUERY",
     [TIB_CFA, LIT_CFA, 160, EXPECT_CFA,
     SPAN_CFA, FETCH_CFA, NUMTIB_CFA, STORE_CFA,
@@ -960,13 +988,9 @@ QUERY_FILE_CFA = defWord("QUERY-FILE",
 WORD_CFA = defPrimWord("WORD", () -> begin
     delim = popPS()
 
-    if mem[SOURCE_ID] == 0
-        bufferAddr = TIB
-        sizeAddr = NUMTIB
-    else
-        bufferAddr = FIB
-        sizeAddr = NUMFIB
-    end
+    callPrim(mem[SOURCE_CFA])
+    sizeAddr = popPS()
+    bufferAddr = popPS()
 
     # Chew up initial occurrences of delim
     while (mem[TOIN]<mem[sizeAddr] && mem[bufferAddr+mem[TOIN]] == delim)
@@ -1140,7 +1164,7 @@ INTERPRET_CFA = defWord("INTERPRET",
     [LIT_CFA, 32, WORD_CFA, # Read next space-delimited word
 
     DUP_CFA, FETCH_CFA, ZE_CFA, ZBRANCH_CFA, 3,
-        DROP_CFA, EXIT_CFA, # Exit if TIB is exhausted
+        DROP_CFA, EXIT_CFA, # Exit if input buffer is exhausted
 
     STATE_CFA, FETCH_CFA, ZBRANCH_CFA, 24,
         # Compiling
@@ -1185,6 +1209,22 @@ QUIT_CFA = defWord("QUIT",
     INTERPRET_CFA, PROMPT_CFA,
     BRANCH_CFA,-4])
 
+INTERPRET_CFA = defWord("INTERPRET",
+    [SOURCE_ID_CFA, FETCH_CFA, TOR_CFA, # Store current source on return stack
+
+    LIT_CFA, 32, WORD_CFA, # Read next word from current input source
+
+    FAM_RO_CFA, OPEN_FILE_CFA, DROP_CFA, # Open the file named by this word.
+
+    DUP_CFA, SOURCE_ID_CFA, STORE_CFA, # Mark this as the current source
+
+    DUP_CFA, QUERY_FILE_CFA, # Read line from file
+
+    INTERPRET_CFA,
+
+    BRANCH_CFA, -4])
+
+
 ABORT_CFA = defWord("ABORT",
     [CLOSE_FILES_CFA, PSP0_CFA, PSPSTORE_CFA, QUIT_CFA])
 
@@ -1193,6 +1233,10 @@ BYE_CFA = defPrimWord("BYE", () -> begin
     return 0
 end)
 
+EOF_CFA = defPrimWord("\x04", () -> begin
+    return 0
+end)
+
 #### VM loop ####
 
 initialized = false
@@ -1205,6 +1249,10 @@ end
 
 function run(;initialize=true)
 
+    # Start with IP pointing to first instruction of outer interpreter
+    pushRS(QUIT_CFA+1)
+
+    # Load library files
     global initialized, initFileName
     if !initialized && initialize
         if initFileName != nothing
@@ -1218,12 +1266,10 @@ function run(;initialize=true)
         end
     end
 
-    # Start with IP pointing to first instruction of outer interpreter
-    reg.IP = QUIT_CFA + 1
 
     # Primitive processing loop.
     # Everyting else is simply a consequence of this loop!
-    jmp = NEXT
+    jmp = mem[EXIT_CFA]
     while jmp != 0
         try
             #println("Entering prim $(getPrimName(jmp))")