+ZBRANCH = defPrimWord("0BRANCH", () -> begin
+ if (popPS() == 0)
+ reg.IP += mem[reg.IP]
+ else
+ reg.IP += 1
+ end
+
+ return NEXT
+end)
+
+# 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
+
+TRACE = defPrimWord("TRACE", () -> begin
+ println("reg.W: $(reg.W) reg.IP: $(reg.IP)")
+ print("PS: "); printPS()
+ print("RS: "); printRS()
+ print("[paused]")
+ readline()
+
+ return NEXT
+end)
+
+COMMA = defPrimWord(",", () -> begin
+ mem[mem[HERE]] = popPS()
+ mem[HERE] += 1
+
+ return NEXT
+end)
+
+BTICK = defWord("[']",
+ [FROMR, DUP, INCR, TOR, FETCH, EXIT])
+
+EXECUTE = defPrimWord("EXECUTE", () -> begin
+ reg.W = popPS()
+ return mem[reg.W]
+end)
+
+TIB_CFA = defConst("TIB", TIB)
+NUMTIB, NUMTIB_CFA = defNewVar("#TIB", 0)
+TOIN, TOIN_CFA = defNewVar(">IN", 0)
+
+QUERY = defWord("QUERY",
+ [TIB_CFA, LIT, 160, EXPECT,
+ SPAN_CFA, FETCH, NUMTIB_CFA, STORE,
+ LIT, 0, TOIN_CFA, STORE,
+ EXIT])
+
+WORD = defPrimWord("WORD", () -> begin
+ delim = popPS()
+
+ # Chew up initial occurrences of delim
+ while (mem[TOIN]<mem[NUMTIB] && mem[TIB+mem[TOIN]] == delim)
+ mem[TOIN] += 1
+ end
+
+ countAddr = mem[HERE]
+ addr = mem[HERE]+1
+
+ # Start reading in word
+ count = 0
+ while (mem[TOIN]<mem[NUMTIB])
+ mem[addr] = mem[TIB+mem[TOIN]]
+ mem[TOIN] += 1
+
+ if (mem[addr] == delim)
+ break
+ end
+
+ count += 1
+ addr += 1
+ end
+
+ # Record count
+ mem[countAddr] = count
+ pushPS(countAddr)
+
+ return NEXT
+end)
+
+PARSE = defPrimWord("PARSE", () -> begin
+ delim = popPS()
+
+ # Chew up initial occurrences of delim
+ addr = mem[HERE]
+
+ # Start reading input stream
+ count = 0
+ while (mem[TOIN]<mem[NUMTIB])
+ mem[addr] = mem[TIB+mem[TOIN]]
+ mem[TOIN] += 1
+
+ if (mem[addr] == delim)
+ break
+ end
+
+ count += 1
+ addr += 1
+ end
+
+ pushPS(addr)
+ pushPS(count)
+
+ return NEXT
+end)
+
+BYE = defPrimWord("BYE", () -> begin
+ println("Bye!")
+ return 0
+end)
+
+STATE, STATE_CFA = defNewVar("STATE", 0)
+
+INTERPRET = defWord("INTERPRET",
+ [LIT, 32, WORD, # Read next space-delimited word
+
+ DUP, FETCH, ZE, ZBRANCH, 3,
+ DROP, EXIT, # Exit if TIB is exhausted
+
+ STATE_CFA, FETCH, ZBRANCH, 31,
+ # Compiling
+ DUP, FIND, QDUP, ZBRANCH, 19,
+
+ # Found word.
+ SWAP, DROP,
+ DUP, TOCFA, SWAP, INCR, FETCH, LIT, F_IMMED, AND, ZBRANCH, 4,
+ # Immediate: Execute!
+ EXECUTE, BRANCH, -33,
+
+ # Not immediate: Compile!
+ COMMA, BRANCH, -36,
+
+ # No word found, parse number
+ NUMBER, BTICK, LIT, COMMA, COMMA, BRANCH, -43,
+
+ # Interpreting
+ DUP, FIND, QDUP, ZBRANCH, 7,
+
+ # Found word. Execute!
+ SWAP, DROP, TOCFA, EXECUTE, BRANCH, -54,
+
+ # No word found, parse number and leave on stack
+ NUMBER, BRANCH, -57,
+ EXIT]
+)
+
+PROMPT = defPrimWord("PROMPT", () -> begin
+ if (mem[STATE] == 0 && currentSource() == STDIN)
+ println(" ok")
+ end
+
+ return NEXT
+end)
+
+QUIT = defWord("QUIT",
+ [LIT, 0, STATE_CFA, STORE,
+ LIT, 0, NUMTIB_CFA, STORE,
+ RSP0_CFA, FETCH, RSPSTORE,
+ QUERY,
+ INTERPRET, PROMPT,
+ BRANCH,-4])
+
+ABORT = defWord("ABORT",
+ [PSP0_CFA, FETCH, PSPSTORE, QUIT])
+
+INCLUDE = defPrimWord("INCLUDE", () -> begin
+ pushPS(32)
+ callPrim(mem[WORD])
+ wordAddr = popPS()+1
+ wordLen = mem[wordAddr-1]
+ word = getString(wordAddr, wordLen)
+
+ push!(sources, open(word, "r"))
+
+ # Clear input buffer
+ mem[NUMTIB] = 0
+
+ return NEXT
+end)
+
+# Compilation
+
+HEADER = defPrimWord("HEADER", () -> begin
+ wordAddr = popPS()+1
+ wordLen = mem[wordAddr-1]
+ word = getString(wordAddr, wordLen)
+
+ createHeader(word, 0)
+
+ return NEXT
+end)
+
+LBRAC = defPrimWord("[", () -> begin
+ mem[STATE] = 0
+ return NEXT
+end, flags=F_IMMED)
+
+RBRAC = defPrimWord("]", () -> begin
+ mem[STATE] = 1
+ return NEXT
+end, flags=F_IMMED)
+
+HIDDEN = defPrimWord("HIDDEN", () -> begin
+ addr = popPS() + 1
+ mem[addr] = mem[addr] $ F_HIDDEN
+ return NEXT
+end)
+
+HIDE = defWord("HIDE",
+ [LIT, 32, WORD,
+ FIND,
+ HIDDEN,
+ EXIT])
+
+COLON = defWord(":",
+ [LIT, 32, WORD,
+ HEADER,
+ LIT, DOCOL, COMMA,
+ LATEST_CFA, FETCH, HIDDEN,
+ RBRAC,
+ EXIT])
+
+SEMICOLON = defWord(";",
+ [LIT, EXIT, COMMA,
+ LATEST_CFA, FETCH, HIDDEN,
+ LBRAC,
+ EXIT], flags=F_IMMED)
+
+IMMEDIATE = defPrimWord("IMMEDIATE", () -> begin
+ lenAndFlagsAddr = mem[LATEST] + 1
+ mem[lenAndFlagsAddr] = mem[lenAndFlagsAddr] $ F_IMMED
+ return NEXT
+end, flags=F_IMMED)
+
+