+TELL = defPrimWord("TELL", () -> 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