# the dictionary.
#
# Simple linear addressing is used with one exception: references to primitive code
-# blocks, which are represented as anonymous functions, appear the negative index
-# into the primitives array which contains only these functions.
+# blocks, which are represented as anonymous functions, appear as negative indicies
+# into the primitives array which contains these functions.
mem = Array{Int64,1}(size_mem)
primitives = Array{Function,1}()
PSP::Int64 # Parameter/data stack pointer
IP::Int64 # Instruction pointer
W::Int64 # Working register
+
+ source::Any # Input stream in use
end
-reg = Reg(mem[RSP0], mem[PSP0], 0, 0)
+reg = Reg(mem[RSP0], mem[PSP0], 0, 0, STDIN)
-# Stack manipulation
+# Stack manipulation functions
type StackUnderflow <: Exception end
KEY = defPrimWord("KEY", () -> begin
if mem[TOIN] >= mem[NUMTIB]
mem[TOIN] = 0
- line = readline()
+
+ if reg.source != STDIN && eof(reg.source)
+ reg.source = STDIN
+ end
+
+ line = readline(reg.source)
mem[NUMTIB] = length(line)
putString(line, TIB)
end
INTERPRET,
BRANCH,-2])
+BYE = defPrimWord("BYE", () -> begin
+ return 0
+end)
+
NL = defPrimWord("\n", () -> begin
if mem[STATE] == 0
println(" ok")
return NEXT
end)
-BYE = defPrimWord("BYE", () -> begin
- return 0
+INCLUDE = defPrimWord("INCLUDE", () -> begin
+
+ callPrim(mem[WORD])
+ wordLen = popPS()
+ wordAddr = popPS()
+ word = getString(wordAddr, wordLen)
+
+ println("Reading from $word...")
+
+ reg.source = open(word, "r")
+
+ # Clear input buffer
+ mem[NUMTIB] = 0
+
+ return NEXT
end)
#### VM loop ####
-function runVM()
+function run()
# Start with IP pointing to first instruction of outer interpreter
reg.IP = QUIT + 1