getString(addr::Int64, len::Int64) = AbstractString([Char(c) for c in mem[addr:(addr+len-1)]])
+function putString(str::AbstractString, addr::Int64)
+ mem[addr:(addr+length(str)-1)] = [Int64(c) for c in str]
+end
+
function putString(str::AbstractString, addr::Int64, maxLen::Int64)
len = min(length(str), maxLen)
mem[addr:(addr+len-1)] = [Int64(c) for c in str]
FAM_WO_CFA = defConst("W/O", FAM_WO)
function fileOpener(create::Bool)
+ fam = popPS()
fnameLen = popPS()
fnameAddr = popPS()
- fam = popPS()
fname = getString(fnameAddr, fnameLen)
mode = "w"
end
+ global nextFileID
openFiles[nextFileID] = open(fname, mode)
pushPS(nextFileID)
pushPS(0)
fid = popPS()
close(openFiles[fid])
delete!(openFiles, fid)
+
+ pushPS(0) # Result code 0
return NEXT
end)
end
empty!(openFiles)
+ pushPS(0) # Result code 0
return NEXT
end)
eofFlag = endswith(line, '\n') ? 0 : -1
line = chomp(line)
+ println("Reading: $line");
+
putString(line, addr, maxSize)
pushPS(length(line))
TIB_CFA = defConst("TIB", TIB)
NUMTIB, NUMTIB_CFA = defNewVar("#TIB", 0)
-FIB_CFA = defConst("FIB", TIB)
+FIB_CFA = defConst("FIB", FIB)
NUMFIB, NUMFIB_CFA = defNewVar("#FIB", 0)
+IB_CFA = defPrimWord("IB", () -> begin
+ pushPS(mem[SOURCE_ID] == 0 ? TIB : FIB)
+ return NEXT
+end)
+
+NUMIB_CFA = defPrimWord("#IB", () -> begin
+ pushPS(mem[SOURCE_ID] == 0 ? NUMTIB : NUMFIB)
+ return NEXT
+end)
+
TOIN, TOIN_CFA = defNewVar(">IN", 0)
SOURCE_ID, SOURCE_ID_CFA = defNewVar("SOURCE-ID", 0)
LIT_CFA, 0, TOIN_CFA, STORE_CFA,
EXIT_CFA])
+EOF_FLAG, EOF_FLAG_CFA = defNewVar("EOF-FLAG", 0)
+
+# ( fid -- )
+# EOF-FLAG is set to true if EOF is reached
QUERY_FILE_CFA = defWord("QUERY-FILE",
[FIB_CFA, LIT_CFA, 160, ROT_CFA, READ_LINE_CFA,
- DROP_CFA, SWAP_CFA,
+ DROP_CFA, EOF_FLAG_CFA, STORE_CFA,
NUMFIB_CFA, STORE_CFA,
+ LIT_CFA, 0, TOIN_CFA, STORE_CFA,
EXIT_CFA])
WORD_CFA = defPrimWord("WORD", () -> begin
mem[countAddr] = count
pushPS(countAddr)
+ println("Processing word: '$(getString(countAddr+1,mem[countAddr]))' (state $(mem[STATE]))")
+
return NEXT
end)
[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
end)
QUIT_CFA = defWord("QUIT",
- [LIT_CFA, 0, STATE_CFA, STORE_CFA,
- LIT_CFA, 0, NUMTIB_CFA, STORE_CFA,
- RSP0_CFA, RSPSTORE_CFA,
- QUERY_CFA,
- INTERPRET_CFA, PROMPT_CFA,
- BRANCH_CFA,-4])
+ [LIT_CFA, 0, STATE_CFA, STORE_CFA, # Set mode to interpret
+ LIT_CFA, 0, SOURCE_ID_CFA, STORE_CFA, # Set terminal as input stream
+ LIT_CFA, 0, NUMTIB_CFA, STORE_CFA, # Clear the input buffer
+ RSP0_CFA, RSPSTORE_CFA, # Clear the return stack
+ QUERY_CFA, # Read line of input
+ INTERPRET_CFA, PROMPT_CFA, # Interpret line
+ BRANCH_CFA,-4]) # Loop
+
+INCLUDED_CFA = defWord("INCLUDED",
+ [LIT_CFA, 0, STATE_CFA, STORE_CFA, # Set mode to interpret
+ FAM_RO_CFA, OPEN_FILE_CFA, DROP_CFA, # Open the file
+ SOURCE_ID_CFA, FETCH_CFA, SWAP_CFA, # Store current source on stack
+ SOURCE_ID_CFA, STORE_CFA, # Mark this as the current source
+ SOURCE_ID_CFA, FETCH_CFA, QUERY_FILE_CFA, # Read line from file
+ INTERPRET_CFA, # Interpret line
+ EOF_FLAG_CFA, FETCH_CFA, ZBRANCH_CFA, -7, # Loop if not EOF
+ SOURCE_ID_CFA, FETCH_CFA,
+ CLOSE_FILE_CFA, DROP_CFA, # Close file
+ SOURCE_ID_CFA, STORE_CFA, # Restore input source
+ EXIT_CFA])
+
+INCLUDE_CFA = defWord("INCLUDE", [LIT_CFA, 32, WORD_CFA,
+ DUP_CFA, INCR_CFA,
+ SWAP_CFA, FETCH_CFA,
+ INCLUDED_CFA, EXIT_CFA]);
+
ABORT_CFA = defWord("ABORT",
- [CLOSE_FILES_CFA, PSP0_CFA, PSPSTORE_CFA, QUIT_CFA])
+ [CLOSE_FILES_CFA, DROP_CFA, PSP0_CFA, PSPSTORE_CFA, QUIT_CFA])
BYE_CFA = defPrimWord("BYE", () -> begin
println("\nBye!")
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
print("Including definitions from $initFileName...")
- # TODO
+ putString(initFileName, mem[H])
+ pushPS(mem[H])
+ pushPS(length(initFileName))
+ pushRS(INCLUDED_CFA+1)
initialized = true
else
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))")
+ print("Entering prim $(getPrimName(jmp)), PS: ")
+ printPS()
+
jmp = callPrim(jmp)
catch ex