Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
-- The kernel of LForth: an inner interpreter, plus an outer
-- interpreter implemented as a set of new states for the inner one.

-- The inner interpreter - minimal, but very extensible.
-- The data stack and the return stack:
--   «.ds»				(to "ds")
--   «.rs»				(to "rs")
-- The "memory", implemented as a Lua array:
--   «.mem»				(to "mem")
-- Functions to add primitives and Forth words to the `forths' dictionary:
--   «.prim»				(to "prim")
--   «.compile»				(to "compile")
-- Dictionaries for the inner interpreter: heads and forths.
--   «.heads»				(to "heads")
--   «.forths»				(to "forths")
-- The "inner" states of the inner interpreter.
--   «.states.head»			(to "states.head")
--   «.states.forth»			(to "states.forth")
--   «.states.forthret»			(to "states.forthret")
-- The inner interpreter loop.
--   «.innerloop»			(to "innerloop")
-- The standard way to invoke Forth functions or primitives... the
-- tricky part is that the loop of the inner interpreter must stop
-- looping when everything is done.
--   «.invoke»				(to "invoke")

-- An extension to the inner interpreter: support for RSR words.
--   «.ss»				(to "ss")
--   «.RSR»				(to "RSR")
--   «.rsrprim»				(to "rsrprim")


-- The outer interpreter.
-- The basic parsing functions, and the array on which they operate.
--   «.p»				(to "p")
--   «.p.parseluare»			(to "p.parseluare")
--   «.getword»				(to "getword")
--   «.getuntilluare»			(to "getuntilluare")
-- The outer interpreter is implemented as two new states for the
-- inner interpreter.
--   «.states.outer_interpreter»	(to "states.outer_interpreter")
--   «.states.outer_compiler»		(to "states.outer_compiler")
-- The outer interpreter's dictionaries:
-- Words common to both the interpreter mode and the compiler mode,
--   «.dict»				(to "dict")
-- Words specific to interpreter mode,
--   «.dict_interpreter»		(to "dict_interpreter")
-- Words specific to compiler mode.
--   «.dict_compiler»			(to "dict_compiler")
-- The standard way to invoke the outer interpreter on a piece of
-- text, kind of like what `invoke' does for bytecodes.
--   «.interpret»			(to "interpret")

-- (find-angg "LFORTH/outer.lua")
-- (find-angg "LFORTH/README")


-- «ds»  (to ".ds")
ds = {}
dspush = function (v) table.insert(ds, 1, v); return v end
dspop  = function () return table.remove(ds, 1) end
-- «rs»  (to ".rs")
rs = {}
rspush = function (v) table.insert(rs, 1, v); return v end
rspop  = function () return table.remove(rs, 1) end
-- «mem»  (to ".mem")
mem = {}
mem.here = 0
mem.compile = function (...)
    for i = 1,table.getn(arg) do
      mem[mem.here] = arg[i]
      mem.here = mem.here + 1
    end
  end
-- «prim»  (to ".prim")
prim = function (name, fun) forths[name] = fun end
-- «compile»  (to ".compile")
compile = function (name, ...)
    forths[name] = mem.here
    mem.compile(unpack(arg))
  end

-- «heads»  (to ".heads")
heads = {}
heads["h_forth"] = function ()
    state = states.forth
  end
-- «forths»  (to ".forths")
forths = {}
forths["exit"] = function ()
    ip = rspop(); state = states.forthret
  end

-- «states»  (to ".states")
-- «states.head»  (to ".states.head")
states = {}
states.head = function ()
    local instr = mem[ip]; ip = ip+1; 
    heads[instr]()
  end
-- «states.forth»  (to ".states.forth")
states.forth = function ()
    local v = mem[ip]; ip = ip+1
    if type(v)=="string"   then v = forths[v] end
    if type(v)=="function" then v(); return end
    if type(v)=="number"   then
      rspush(ip)
      ip = v
      state = states.head
      return
    end
    error()
  end
-- «states.forthret»  (to ".states.forthret")
states.forthret = function ()
    if type(ip)=="number" then state = states.forth; return end
    if type(ip)=="function" then ip(); return end
    PP("forthret error: ip=", ip)
    error()
  end

-- «innerloop»  (to ".innerloop")
innerloop = function ()
    while state do
      if DBG then P(ip, mem[ip]) end
      state()
    end
  end
-- «invoke»  (to ".invoke")
invoke = function (f)
    if type(f)=="string" then f = forths[f] end
    if type(f)=="function" then f(); return end
    if type(f)=="number" then
      local oldstate, oldip = state, ip
      rspush(function () state = nil end)
      ip = f
      state = states.head
      innerloop()
      ip = oldip
      state = oldstate
      return
    end
    error()
  end
invoke_ = function (f, stateafter)
    if type(f)=="string" then f = forths[f] end
    if type(f)=="function" then f(); return end
    if type(f)=="number" then
      rspush(function () state = stateafter end)
      ip = f
      state = states.head
      return
    end
    error()
  end



-- «ss»  (to ".ss")
ss = {}
sspush = function (v) table.insert(ss, 1, v); return v end
sspop  = function () return table.remove(ss, 1) end
-- «RSR»  (to ".RSR")
heads["h_rsr"] = function ()
    sspush(rspop())
    rspush(function () ip = sspop() end)
  end
-- «rsrprim»  (to ".rsrprim")
rsrprim = function (rname, sname, fun)
    prim(sname, fun)
    compile(rname, "h_rsr", "h_forth", sname, "exit")
  end


-- Tests for the inner interpreter:
-- (find-angg "LFORTH/README" "kernel-innertest1")
-- (find-angg "LFORTH/README" "kernel-innertestrsr")




-- «p»  (to ".p")
p = {}
p.pos = 0
-- p.text = ??
-- «p.parseluare»  (to ".p.parseluare")
p.parseluare = function (errfunction, luare)
    local arr = pack(string.find(p.text, luare, p.pos+1))
    if arr[1] == nil then return errfunction(luare) end
    local startre = table.remove(arr, 1)
    local endre   = table.remove(arr, 1)
    if DBG then
      P(p.pos, luare, startre-p.pos-1, endre-startre+1, unpack(arr))
    end
    return startre-p.pos-1, endre-startre+1, unpack(arr)
  end
-- «getword»  (to ".getword")
getword = function ()
  local _, nspaces = p.parseluare(nil, "^[ \t]*")
  p.pos = p.pos + nspaces
  local __, dpos, word = p.parseluare(nil, "^([^ \t\n]*)")
  if dpos == 0 then _, dpos, word = p.parseluare(nil, "^(\n?)") end
  p.pos = p.pos + dpos
  return word
end
-- «getuntilluare»  (to ".getuntilluare")
getuntilluare = function (errfunction, luare)
  local arr = pack(p.parseluare(errfunction, luare))
  local _, len = table.remove(arr, 1), table.remove(arr, 1)
  p.pos = p.pos+_+len
  return unpack(arr)
end

-- «states.outer_interpreter»  (to ".states.outer_interpreter")
states.outer_interpreter = function ()
    word = getword()
    local immed = dict_interpreter[word] or dict[word] or forths[word]
    if immed then invoke_(immed, states.outer_interpreter); return end
    local n = tonumber(word)
    if n then dspush(n); return end
    unkown(word)
  end
-- «states.outer_compiler»  (to ".states.outer_compiler")
states.outer_compiler = function ()
    word = getword()
    local immed = dict_compiler[word] or dict[word]
    if immed then invoke_(immed, states.outer_compiler); return end
    if forths[word] then mem.compile(word); return end
    local n = tonumber(word)
    if n then mem.compile("lit", n); return end
    unkown(word)
  end

-- «dict»  (to ".dict")
dict = {}
dict[""] = function () ip = rspop(); state = states.forthret end	-- EOF
dict["\n"] = function () end			-- just skip the newline
dict["[lua"] = function ()
    assert(loadstring(getuntilluare(nil, "^(.-)lua%]")))()
  end
-- «dict_interpreter»  (to ".dict_interpreter")
dict_interpreter = {}
dict_interpreter[":lua"] = function ()
    local word, code = getword(), getuntilluare(nil, "^(.-)lua;")
    forths[word] = assert(loadstring(code))
  end
dict_interpreter[":"] = function ()
    compile(getword(), "h_forth")
    state = states.outer_compiler
  end
-- «dict_compiler»  (to ".dict_compiler")
dict_compiler = {}
dict_compiler[";"] = function ()
    mem.compile("exit")
    state = states.outer_interpreter
  end

-- «interpret»  (to ".interpret")
-- (to "test2")
interpret  = function (str)
    local oldstate = state; interpret_(str, nil); innerloop(); state = oldstate
  end
interpret_ = function (str, stateafter)
    p.text = str
    p.pos = 0
    state = states.outer_interpreter
    rspush(function () state = stateafter end)
  end



-- prim("dup",  function () dspush(ds[1]) end)
-- prim("*",    function () ds[2] = ds[2]*ds[1]; dspop() end)
-- prim("swap", function () ds[2], ds[1] = ds[1], ds[2] end)
-- prim("drop", function () dspop() end)
-- prim(".",    function () print(dspop()) end)
-- prim("..",   function () ds[2] = ds[2]..ds[1]; dspop() end)