Warning: this is an htmlized version!
The original is across this link,
and the conversion rules are here.
-- The inner (bytecode) interpreter - minimal version
-- (find-angg "LFORTH/README" "inner-mini")

ds = {}
dspush = function (v) table.insert(ds, 1, v); return v end
dspop  = function () return table.remove(ds, 1) end

rs = {}
rspush = function (v) table.insert(rs, 1, v); return v end
rspop  = function () return table.remove(rs, 1) end

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

iiforths = {}
iiforths.exit = function ()
    ip = rspop()
    if type(ip) ~= "number" then iistate = iistates.specialip end
  end

iiheads = {}
iiheads.h_forth = function () iistate = iistates.forth end

iistates = {}
iistates.head = function ()
    local instr = mem[ip]; ip = ip+1; 
    iiheads[instr]()
  end
iistates.forth = function ()
    local instr = mem[ip]; ip = ip+1
    local def = iiforths[instr]
    if     type(def) == "function" then def()
    elseif type(def) == "number"   then
      rspush(ip)
      ip = def
      iistate = iistates.head
    else
      error()
    end
  end
iistates.specialip = function ()
    if     type(ip) == "function" then ip()
    elseif type(ip) == "number"   then iistate = iistates.forth
    elseif type(ip) == "nil"      then iistate = nil
    else error()
    end
  end

innerloop = function ()
    while iistate do
      if DBG then P(ip, mem[ip]) end
      iistate()
    end
  end