FAM_RO_CFA = defConst("R/O", FAM_RO)
FAM_WO_CFA = defConst("W/O", FAM_WO)
-OPEN_FILE_CFA = defPrimWord("OPEN-FILE", () -> begin
+function fileOpener(create::Bool)
fnameLen = popPS()
fnameAddr = popPS()
fam = popPS()
fname = getString(fnameAddr, fnameLen)
- if (!isfile(fname))
+ if create && !isfile(fname)
pushPS(0)
pushPS(-1) # error
return NEXT
pushPS(0)
nextFileID += 1
+end
+OPEN_FILE_CFA = defPrimWord("OPEN-FILE", () -> begin
+ fileOpener(false)
return NEXT
end);
CREATE_FILE_CFA = defPrimWord("CREATE-FILE", () -> begin
+ fileOpener(true)
+ return NEXT
+end);
+
+CLOSE_FILE_CFA = defPrimWord("CLOSE-FILE", () -> begin
+ fid = popPS()
+ close(openFiles[fid])
+ delete!(openFiles, fid)
return NEXT
end)
+CLOSE_FILES_CFA = defPrimWord("CLOSE-FILES", () -> begin
+ for fh in values(openFiles)
+ close(fh)
+ end
+ empty!(openFiles)
+
+ return NEXT
+end)
+
+
EMIT_CFA = defPrimWord("EMIT", () -> begin
print(Char(popPS()))
return NEXT
BRANCH_CFA,-4])
ABORT_CFA = defWord("ABORT",
- [CLOSEFILES_CFA, PSP0_CFA, PSPSTORE_CFA, QUIT_CFA])
+ [CLOSE_FILES_CFA, PSP0_CFA, PSPSTORE_CFA, QUIT_CFA])
BYE_CFA = defPrimWord("BYE", () -> begin
println("\nBye!")
return 0
end)
-# File I/O
-
-INCLUDE_CFA = defPrimWord("INCLUDE", () -> begin
- pushPS(32)
- callPrim(mem[WORD_CFA])
- wordAddr = popPS()+1
- wordLen = mem[wordAddr-1]
- word = getString(wordAddr, wordLen)
-
- fname = word
- if !isfile(fname)
- fname = Pkg.dir("forth","src",word)
- if !isfile(fname)
- error("No file named $word found in current directory or package source directory.")
- end
- end
- push!(sources, open(fname, "r"))
-
- # Clear input buffer
- mem[NUMTIB] = 0
-
- return NEXT
-end)
-
-
#### VM loop ####
initialized = false
end
function run(;initialize=true)
- # Begin with STDIN as source
- push!(sources, STDIN)
global initialized, initFileName
if !initialized && initialize
if initFileName != nothing
print("Including definitions from $initFileName...")
- push!(sources, open(initFileName, "r"))
+
+ # TODO
+
initialized = true
else
println("No library file found. Only primitive words available.")
showerror(STDOUT, ex)
println()
- while !isempty(sources) && currentSource() != STDIN
- close(pop!(sources))
- end
-
# QUIT
reg.IP = ABORT_CFA + 1
jmp = NEXT