end
end
+function ensurePSCapacity(toAdd::Int64)
+ if reg.PSP + toAdd >= PSP0 + size_PS
+ error("Parameter stack overflow.")
+ end
+end
+
function ensureRSDepth(depth::Int64)
if reg.RSP - RSP0 < depth
error("Return stack underflow.")
end
end
+function ensureRSCapacity(toAdd::Int64)
+ if reg.RSP + toAdd >= RSP0 + size_RS
+ error("Return stack overflow.")
+ end
+end
+
function pushRS(val::Int64)
+ ensureRSCapacity(1)
mem[reg.RSP+=1] = val
end
end
function pushPS(val::Int64)
+ ensurePSCapacity(1)
+
mem[reg.PSP += 1] = val
end
# I/O
-sources = Array{Any,1}()
-currentSource() = sources[length(sources)]
-
-CLOSEFILES_CFA = defPrimWord("CLOSEFILES", () -> begin
- while currentSource() != STDIN
- close(pop!(sources))
- end
-
- return NEXT
-end)
-
-EOF_CFA = defPrimWord("\x04", () -> begin
- if currentSource() != STDIN
- close(pop!(sources))
- return NEXT
- else
- return 0
- end
-end)
+openFiles = Dict{Int64,IOStream}()
+nextFileID = 1
+SOURCE_ID, SOURCE_ID_CFA = defNewVar("SOURCE-ID", 0)
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)
return NEXT
end, flags=F_IMMED)
+CODE_CFA = defPrimWord("CODE", () -> begin
+ pushPS(32)
+ callPrim(mem[WORD_CFA])
+ callPrim(mem[HEADER_CFA])
+
+ exprString = "() -> begin\n"
+ while true
+ if mem[TOIN] >= mem[NUMTIB]
+ exprString = string(exprString, "\n")
+ if currentSource() == STDIN
+ println()
+ end
+
+ pushPS(TIB)
+ pushPS(160)
+ callPrim(mem[EXPECT_CFA])
+ mem[NUMTIB] = mem[SPAN]
+ mem[TOIN] = 0
+ end
+
+ pushPS(32)
+ callPrim(mem[WORD_CFA])
+ cAddr = popPS()
+ thisWord = getString(cAddr+1, mem[cAddr])
+
+ if uppercase(thisWord) == "END-CODE"
+ break
+ end
+
+ exprString = string(exprString, " ", thisWord)
+ end
+ exprString = string(exprString, "\nreturn NEXT\nend")
+
+ func = eval(parse(exprString))
+ dictWrite(defPrim(func))
+
+ return NEXT
+end)
+
# Outer Interpreter
EXECUTE_CFA = defPrimWord("EXECUTE", () -> begin
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)