[apologize for the plug, but IMHO it's very relevant]
[apologize for the plug, but IMHO it's very relevant]
In something that take input one piece at a time, it'd probably still be simplest to use a coroutine. Also, everything here could be made private except new, if it mattered. I tried to make a straightforword translation of the first Python sample. It looks rather like a recursive descent parser.
local header, footer, dle = '\97', '\98', '\253'
function wait_header(s, byte)
if byte == header then s.frame = {}; return in_msg end
return wait_header
end
function in_msg(s, byte)
if byte == dle then
return after_dle
elseif byte == footer then
return table.concat(s.frame)
else
s.frame[#s.frame+1] = byte --append to frame buffer
return in_msg
end
end
function after_dle(s, byte)
s.frame[#s.frame+1] = s.adf(byte)
return in_msg
end
function new(after_dle_func)
local state, func = { adf = after_dle_func, frame = {} }, wait_header
return function(byte)
func = func(state, byte)
if type(func) == "string" then return func end
end
end
-- test --
foo = new(function(x) print "(in after_dle_func)"; return x:upper() end)
-- this is like "for /./ in string do ..."
for b in string.gmatch("foo\97frame contents\253dle\98end", ".") do
local res = foo(b)
if res then print("GOT FRAME: ", res); break end
end
> dofile("/tmp/lua-6043PeX")
(in after_dle_func)
GOT FRAME: frame contentsDle
Also, Shriram Krishnamurthi's "The Swine Before Perl" (http://www.cs.brown.edu/~sk/Publications/Talks/SwineBeforePe...) also has a good example of using tail calls to write FSMs in Scheme.Have you seen my library (http://github.com/silentbicycle/tamale) for doing Erlang-style pattern matching in Lua, BTW? I still need to document it (I'm working on briefly explaining why pattern matching matters to people who have never used it), but in the mean time, a glance at the README and the test suite should suffice.
http://www.reddit.com/r/programming/comments/9fcna/coroutine...