+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, RSPSTORE,
+ QUERY,
+ INTERPRET, PROMPT,
+ BRANCH,-4])
+
+ABORT = defWord("ABORT",
+ [PSP0_CFA, 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