+ codeWordAddr = mem[H]
+
+ dictWrite(DOCON)
+ dictWrite(val)
+
+ return codeWordAddr
+end
+
+# Threading Primitives (inner interpreter)
+
+NEXT = defPrim(() -> begin
+ reg.W = mem[reg.IP]
+ reg.IP += 1
+ return mem[reg.W]
+end, name="NEXT")
+
+DOCOL = defPrim(() -> begin
+ pushRS(reg.IP)
+ reg.IP = reg.W + 1
+ return NEXT
+end, name="DOCOL")
+
+DOVAR = defPrim(() -> begin
+ pushPS(reg.W + 1)
+ return NEXT
+end, name="DOVAR")
+
+DOCON = defPrim(() -> begin
+ pushPS(mem[reg.W + 1])
+ return NEXT
+end, name="DOVAR")
+
+EXIT_CFA = defPrimWord("EXIT", () -> begin
+ reg.IP = popRS()
+ return NEXT
+end)
+
+# Dictionary entries for core built-in variables, constants
+
+H_CFA = defExistingVar("H", H)
+
+PSP0_CFA = defConst("PSP0", PSP0)
+RSP0_CFA = defConst("RSP0", RSP0)
+
+defConst("DOCOL", DOCOL)
+defConst("DOCON", DOCON)
+defConst("DOVAR", DOVAR)
+
+defConst("DICT", DICT)
+defConst("MEMSIZE", size_mem)
+
+F_IMMED_CFA = defConst("F_IMMED", F_IMMED)
+F_HIDDEN_CFA = defConst("F_HIDDEN", F_HIDDEN)
+F_LENMASK_CFA = defConst("F_LENMASK", F_LENMASK)
+NFA_MARK_CFA = defConst("NFA_MARK", NFA_MARK)
+
+# Basic forth primitives
+
+DROP_CFA = defPrimWord("DROP", () -> begin
+ popPS()
+ return NEXT
+end)
+
+SWAP_CFA = defPrimWord("SWAP", () -> begin
+ a = popPS()
+ b = popPS()
+ pushPS(a)
+ pushPS(b)
+ return NEXT
+end)
+
+DUP_CFA = defPrimWord("DUP", () -> begin
+ ensurePSDepth(1)
+ pushPS(mem[reg.PSP])
+ return NEXT
+end)
+
+OVER_CFA = defPrimWord("OVER", () -> begin
+ ensurePSDepth(2)
+ pushPS(mem[reg.PSP-1])
+ return NEXT
+end)
+
+ROT_CFA = defPrimWord("ROT", () -> begin
+ a = popPS()
+ b = popPS()
+ c = popPS()
+ pushPS(b)
+ pushPS(a)
+ pushPS(c)
+ return NEXT
+end)
+
+NROT_CFA = defPrimWord("-ROT", () -> begin
+ a = popPS()
+ b = popPS()
+ c = popPS()
+ pushPS(a)
+ pushPS(c)
+ pushPS(b)
+ return NEXT
+end)
+
+
+TWODROP_CFA = defPrimWord("2DROP", () -> begin
+ popPS()
+ popPS()
+ return NEXT
+end)
+
+TWODUP_CFA = defPrimWord("2DUP", () -> begin
+ ensurePSDepth(2)
+ a = mem[reg.PSP-1]
+ b = mem[reg.PSP]
+ pushPS(a)
+ pushPS(b)
+ return NEXT
+end)
+
+TWOSWAP_CFA = defPrimWord("2SWAP", () -> begin
+ a = popPS()
+ b = popPS()
+ c = popPS()
+ d = popPS()
+ pushPS(b)
+ pushPS(a)
+ pushPS(d)
+ pushPS(c)
+ return NEXT
+end)
+
+TWOOVER_CFA = defPrimWord("2OVER", () -> begin
+ ensurePSDepth(4)
+ a = mem[reg.PSP-3]
+ b = mem[reg.PSP-2]
+ pushPS(a)
+ pushPS(b)
+ return NEXT
+end)
+
+QDUP_CFA = defPrimWord("?DUP", () -> begin
+ ensurePSDepth(1)
+ val = mem[reg.PSP]
+ if val != 0
+ pushPS(val)
+ end
+ return NEXT
+end)
+
+INCR_CFA = defPrimWord("1+", () -> begin
+ ensurePSDepth(1)
+ mem[reg.PSP] += 1
+ return NEXT
+end)
+
+DECR_CFA = defPrimWord("1-", () -> begin
+ ensurePSDepth(1)
+ mem[reg.PSP] -= 1
+ return NEXT
+end)
+
+INCR2_CFA = defPrimWord("2+", () -> begin
+ ensurePSDepth(1)
+ mem[reg.PSP] += 2
+ return NEXT
+end)
+
+DECR2_CFA = defPrimWord("2-", () -> begin
+ ensurePSDepth(1)
+ mem[reg.PSP] -= 2
+ return NEXT
+end)
+
+ADD_CFA = defPrimWord("+", () -> begin
+ b = popPS()
+ a = popPS()
+ pushPS(a+b)
+ return NEXT
+end)
+
+SUB_CFA = defPrimWord("-", () -> begin
+ b = popPS()
+ a = popPS()
+ pushPS(a-b)
+ return NEXT
+end)
+
+MUL_CFA = defPrimWord("*", () -> begin
+ b = popPS()
+ a = popPS()
+ pushPS(a*b)
+ return NEXT
+end)
+
+DIVMOD_CFA = defPrimWord("/MOD", () -> begin
+ b = popPS()
+ a = popPS()
+ q,r = divrem(a,b)
+ pushPS(r)
+ pushPS(q)
+ return NEXT
+end)
+
+TWOMUL_CFA = defPrimWord("2*", () -> begin
+ pushPS(popPS() << 1)
+ return NEXT
+end)
+
+TWODIV_CFA = defPrimWord("2/", () -> begin
+ pushPS(popPS() >> 1)
+ return NEXT
+end)
+
+EQ_CFA = defPrimWord("=", () -> begin
+ b = popPS()
+ a = popPS()
+ pushPS(a==b ? -1 : 0)
+ return NEXT
+end)
+
+NE_CFA = defPrimWord("<>", () -> begin
+ b = popPS()
+ a = popPS()
+ pushPS(a!=b ? -1 : 0)
+ return NEXT
+end)
+
+LT_CFA = defPrimWord("<", () -> begin
+ b = popPS()
+ a = popPS()
+ pushPS(a<b ? -1 : 0)
+ return NEXT
+end)
+
+GT_CFA = defPrimWord(">", () -> begin
+ b = popPS()
+ a = popPS()
+ pushPS(a>b ? -1 : 0)
+ return NEXT
+end)
+
+LE_CFA = defPrimWord("<=", () -> begin
+ b = popPS()
+ a = popPS()
+ pushPS(a<=b ? -1 : 0)
+ return NEXT
+end)
+
+GE_CFA = defPrimWord(">=", () -> begin
+ b = popPS()
+ a = popPS()
+ pushPS(a>=b ? -1 : 0)
+ return NEXT
+end)
+
+ZE_CFA = defPrimWord("0=", () -> begin
+ pushPS(popPS() == 0 ? -1 : 0)
+ return NEXT
+end)
+
+ZNE_CFA = defPrimWord("0<>", () -> begin
+ pushPS(popPS() != 0 ? -1 : 0)
+ return NEXT
+end)
+
+ZLT_CFA = defPrimWord("0<", () -> begin
+ pushPS(popPS() < 0 ? -1 : 0)
+ return NEXT
+end)
+
+ZGT_CFA = defPrimWord("0>", () -> begin
+ pushPS(popPS() > 0 ? -1 : 0)
+ return NEXT
+end)
+
+ZLE_CFA = defPrimWord("0<=", () -> begin
+ pushPS(popPS() <= 0 ? -1 : 0)
+ return NEXT
+end)
+
+ZGE_CFA = defPrimWord("0>=", () -> begin
+ pushPS(popPS() >= 0 ? -1 : 0)
+ return NEXT
+end)
+
+AND_CFA = defPrimWord("AND", () -> begin
+ b = popPS()
+ a = popPS()
+ pushPS(a & b)
+ return NEXT
+end)
+
+OR_CFA = defPrimWord("OR", () -> begin
+ b = popPS()
+ a = popPS()
+ pushPS(a | b)
+ return NEXT
+end)
+
+XOR_CFA = defPrimWord("XOR", () -> begin
+ b = popPS()
+ a = popPS()
+ pushPS(a $ b)
+ return NEXT
+end)
+
+INVERT_CFA = defPrimWord("INVERT", () -> begin
+ pushPS(~popPS())
+ return NEXT
+end)
+
+# Literals
+
+LIT_CFA = defPrimWord("LIT", () -> begin
+ pushPS(mem[reg.IP])
+ reg.IP += 1
+ return NEXT
+end)
+
+# Memory primitives
+
+STORE_CFA = defPrimWord("!", () -> begin
+ addr = popPS()
+ dat = popPS()
+ mem[addr] = dat
+ return NEXT
+end)
+
+FETCH_CFA = defPrimWord("@", () -> begin
+ addr = popPS()
+ pushPS(mem[addr])
+ return NEXT
+end)
+
+ADDSTORE_CFA = defPrimWord("+!", () -> begin
+ addr = popPS()
+ toAdd = popPS()
+ mem[addr] += toAdd
+ return NEXT
+end)
+
+SUBSTORE_CFA = defPrimWord("-!", () -> begin
+ addr = popPS()
+ toSub = popPS()
+ mem[addr] -= toSub
+ return NEXT
+end)
+
+
+# Return Stack
+
+TOR_CFA = defPrimWord(">R", () -> begin
+ pushRS(popPS())
+ return NEXT
+end)
+
+FROMR_CFA = defPrimWord("R>", () -> begin
+ pushPS(popRS())
+ return NEXT
+end)
+
+RFETCH_CFA = defPrimWord("R@", () -> begin
+ pushPS(mem[reg.RSP])
+ return NEXT
+end)
+
+RSPFETCH_CFA = defPrimWord("RSP@", () -> begin
+ pushPS(reg.RSP)
+ return NEXT
+end)
+
+RSPSTORE_CFA = defPrimWord("RSP!", () -> begin
+ reg.RSP = popPS()
+ return NEXT
+end)
+
+RDROP_CFA = defPrimWord("RDROP", () -> begin
+ popRS()
+ return NEXT
+end)
+
+# Parameter Stack
+
+PSPFETCH_CFA = defPrimWord("PSP@", () -> begin
+ pushPS(reg.PSP)
+ return NEXT
+end)
+
+PSPSTORE_CFA = defPrimWord("PSP!", () -> begin
+ reg.PSP = popPS()
+ return NEXT
+end)
+
+# Working Register
+
+WFETCH_CFA = defPrimWord("W@", () -> begin
+ pushPS(reg.W)
+ return NEXT
+end)
+
+WSTORE_CFA = defPrimWord("W!", () -> begin
+ reg.W = popPS()
+ return NEXT
+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)
+
+EMIT_CFA = defPrimWord("EMIT", () -> begin
+ print(Char(popPS()))
+ return NEXT
+end)
+
+function raw_mode!(mode::Bool)
+ if ccall(:jl_tty_set_mode, Int32, (Ptr{Void}, Int32), STDIN.handle, mode) != 0
+ throw("FATAL: Terminal unable to enter raw mode.")
+ end
+end
+
+function getKey()
+ raw_mode!(true)
+ byte = readbytes(STDIN, 1)[1]
+ raw_mode!(false)
+
+ if byte == 0x0d
+ return 0x0a
+ elseif byte == 127
+ return 0x08
+ else
+ return byte
+ end
+end
+
+KEY_CFA = defPrimWord("KEY", () -> begin
+ pushPS(Int(getKey()))
+ return NEXT
+end)
+
+function getLineFromSTDIN()
+
+ function getFrag(s)
+ chars = collect(s)
+ slashIdx = findlast(chars, '\\')
+
+ if slashIdx > 0
+ return join(chars[slashIdx:length(chars)])
+ else
+ return nothing
+ end
+ end