Lua Ropes

lua-users home

Lua Ropes

Because strings are immutable objects in Lua, it is important to avoid creating them unnecessarily. Very often programs manipulate strings in order to create some textual output. One strategy is to avoid creating intermediate strings, and to output all the pieces of the final text in the right order. The appropriate datatype for this is the rope[1], where

 rope ::= string | list of rope 
In other words, a rope is a tree whose leaves are strings. The important operation on trees is the tree-walk, applying a procedure to each leaf.

  local function walk(x,f)
    local typ, ok, bad = type(x),true
    local errmsg = "bad type (%s), %s"
    if typ == "string" then return pcall(f,x)
    elseif typ == "table" then
      local i,n = 1,#x
      while ok and i <= n do
        ok,bad = walk(x[i],f)
        i = i+1
      end -- while
      return ok,bad
      bad = errmsg:format(typ,typ and "" or "something undefined?")
      return nil,bad
    end -- if
  end -- function

  local mt = {
    push = function (self,x)
      local function f(y)
        if y and type(y) ~= "function" then
          self[#self + 1] =y
          return f
        elseif y then
          return function (z)
            return f(y(z))
          end -- function
        end -- if
      end -- function y
      return f(x)
    end; -- function push
    walk = walk;
    flatten = function(self)
      local o = {}
      local f = function (x) o[#o + 1] = x end -- function
      return table.concat(o)
    end; -- function

  function rope()
    return setmetatable({}, {__index = mt})
  end -- function
end -- do

t,x = rope(),rope()
t:push (string.upper) "m" "r" (string.char) (32) "Smith" ;
x:push [[ Good ]] [[morning]];
t:push (x)
t:walk(io.write) --> Mr Smith Good morning
print(t:flatten()) --> Mr Smith Good morning

RecentChanges · preferences
edit · history
Last edited June 4, 2007 7:43 pm GMT (diff)