-# Strings
-
-LITSTRING = defPrimWord("LITSTRING", () -> begin
- len = mem[reg.IP]
- reg.IP += 1
- pushPS(reg.IP)
- pushPS(len)
- reg.IP += len
-
- return NEXT
-end)
-
-TYPE = defPrimWord("TYPE", () -> begin
- len = popPS()
- addr = popPS()
- str = getString(addr, len)
- print(str)
- return NEXT
-end)
-
-# Outer interpreter
-
-EXECUTE = defPrimWord("EXECUTE", () -> begin
- reg.W = popPS()
- return mem[reg.W]
-end)
-
-type ParseError <: Exception
- wordName::ASCIIString
-end
-Base.showerror(io::IO, ex::ParseError) = print(io, "Parse error at word: '$(ex.wordName)'.")
-
-DEBUG, DEBUG_CFA = defNewVar("DEBUG", 0)
-
-INTERPRET = defPrimWord("INTERPRET", () -> begin
-
- callPrim(mem[WORD])
-
- wordName = getString(mem[reg.PSP-1], mem[reg.PSP])
- if mem[DEBUG] != 0
- println("... ", replace(replace(wordName, "\004", "EOF"), "\n", "\\n"), " ...")
- end
-
- callPrim(mem[TWODUP])
- callPrim(mem[FIND])
-
- wordAddr = mem[reg.PSP]
-
- if wordAddr>0
- # Word in dictionary
-
- isImmediate = (mem[wordAddr+1] & F_IMMED) != 0
- callPrim(mem[TOCFA])
-
- callPrim(mem[NROT]) # get rid of extra copy of word string details
- popPS()
- popPS()
-
- if mem[STATE] == 0 || isImmediate
- # Execute!
- return callPrim(mem[EXECUTE])
- else
- # Append CFA to dictionary
- callPrim(mem[COMMA])
- end
- else
- # Not in dictionary, assume number
-
- popPS()
-
- callPrim(mem[NUMBER])
-
- if popPS() != 0
- throw(ParseError(wordName))
- end
-
- if mem[STATE] == 0
- # Number already on stack!
- else
- # Append literal to dictionary
- pushPS(LIT)
- callPrim(mem[COMMA])
- callPrim(mem[COMMA])
- end
- end
-
- return NEXT
-end)
-
-QUIT = defWord("QUIT",
- [RSP0_CFA, RSPSTORE,
- INTERPRET,
- BRANCH,-2])
-
-BYE = defPrimWord("BYE", () -> begin
- return 0
-end)
-
-PROMPT = defPrimWord("PROMPT", () -> begin
- println(" ok")
-end)
-
-NL = defPrimWord("\n", () -> begin
- if mem[STATE] == 0 && currentSource() == STDIN
- callPrim(mem[PROMPT])
- end
- return NEXT
-end, flags=F_IMMED)
-
-INCLUDE = defPrimWord("INCLUDE", () -> begin
- callPrim(mem[WORD])
- wordLen = popPS()
- wordAddr = popPS()
- word = getString(wordAddr, wordLen)
-
- push!(sources, open(word, "r"))
-
- # Clear input buffer
- mem[NUMTIB] = 0
-
- return NEXT
-end)
-
-EOF_WORD = defPrimWord("\x04", () -> begin
- if currentSource() != STDIN
- close(currentSource())
- end
-
- pop!(sources)
-
- if length(sources)>0
- if currentSource() == STDIN
- callPrim(mem[PROMPT])
- end
-
- return NEXT
- else
- return 0
- end
-end, flags=F_IMMED)