# I/O
-sources = Array{Any,1}()
-currentSource() = sources[length(sources)]
+openFiles = Dict{Int64,IOStream}()
+nextFileID = 1
+SOURCE_ID, SOURCE_ID_CFA = defNewVar("SOURCE-ID", 0)
-CLOSEFILES_CFA = defPrimWord("CLOSEFILES", () -> begin
- while currentSource() != STDIN
- close(pop!(sources))
+
+## File access modes
+FAM_RO = 0
+FAM_WO = 1
+FAM_RO_CFA = defConst("R/O", FAM_RO)
+FAM_WO_CFA = defConst("W/O", FAM_WO)
+
+function fileOpener(create::Bool)
+ fnameLen = popPS()
+ fnameAddr = popPS()
+ fam = popPS()
+
+ fname = getString(fnameAddr, fnameLen)
+
+ if create && !isfile(fname)
+ pushPS(0)
+ pushPS(-1) # error
+ return NEXT
end
+ if (fam == FAM_RO)
+ mode = "r"
+ else
+ mode = "w"
+ end
+
+ openFiles[nextFileID] = open(fname, mode)
+ pushPS(nextFileID)
+ 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)
-EOF_CFA = defPrimWord("\x04", () -> begin
- if currentSource() != STDIN
- close(pop!(sources))
- return NEXT
- else
- return 0
+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()))
maxLen = popPS()
addr = popPS()
- if currentSource() == STDIN
- line = getLineFromSTDIN()
- else
- if !eof(currentSource())
- line = chomp(readline(currentSource()))
- else
- line = "\x04" # eof
- end
- end
+ line = getLineFromSTDIN()
mem[SPAN] = min(length(line), maxLen)
putString(line, addr, maxLen)
exprString = "() -> begin\n"
while true
if mem[TOIN] >= mem[NUMTIB]
- println()
exprString = string(exprString, "\n")
+ if currentSource() == STDIN
+ println()
+ end
pushPS(TIB)
pushPS(160)
EXIT_CFA])
PROMPT_CFA = defPrimWord("PROMPT", () -> begin
- if currentSource() == STDIN
- if mem[STATE] == 0
- print(" ok")
- end
- println()
+ if mem[STATE] == 0
+ print(" ok")
end
+ println()
return NEXT
end)
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!")