Skip to content

Instantly share code, notes, and snippets.

@jmettraux
Created March 17, 2009 09:36
Show Gist options
  • Save jmettraux/80424 to your computer and use it in GitHub Desktop.
Save jmettraux/80424 to your computer and use it in GitHub Desktop.
--
-- lena.lua
--
--
-- work queue operations
queue = {}
function enqueue (task)
queue[#queue + 1] = task
--print('. enqueued', task[1], task[2])
end
function dequeue ()
return table.remove(queue, 1)
end
--
-- expression pool
pool = {}
counter = 0
--
-- expression implementations
flow_expression = {
store_self = function (self)
pool[self.id] = self
end,
flag_workitem = function (self, workitem)
workitem.fei = self.id
end,
reply_to_parent = function (self, workitem)
pool[self.id] = nil
self:flag_workitem(workitem)
if self.parent_id ~= nil then
enqueue({ 'reply', self.parent_id, workitem })
end
end
}
-- <echo>
echo_exp = {
apply = function (self, workitem)
print(self.children[1])
self:reply_to_parent(workitem)
end
}
setmetatable(echo_exp, { __index = flow_expression })
-- <sequence>
sequence_exp = {
pointer = 0,
apply = function (self, workitem)
self.reply(self, workitem)
end,
reply = function (self, workitem)
self:flag_workitem(workitem)
self.pointer = self.pointer + 1
local next_child = self.children[self.pointer]
if next_child then
enqueue({ 'apply', next_child, workitem })
else
self:reply_to_parent(workitem)
end
end,
}
setmetatable(sequence_exp, { __index = flow_expression })
--
-- expression map
expressions = {
echo = echo_exp,
sequence = sequence_exp
}
--
-- expression lookup / creation
function new_expression (fei, parent_id)
local name = fei[1]
local class = expressions[name]
counter = counter + 1
local expression = {
id = counter,
parent_id = parent_id,
name = name,
attributes = fei[2],
children = fei[3]
}
setmetatable(expression, { __index = class })
pool[counter] = expression
return expression
end
function get_expression (fei, parent_id)
if type(fei) == 'number' then
return pool[fei]
else
return new_expression(fei, parent_id)
end
end
--
-- worker coroutine
worker = coroutine.create(function ()
while true do
local task = dequeue()
if task == nil then
coroutine.yield()
else
local direction = task[1]
local fei = task[2]
local workitem = task[3]
local exp = get_expression(fei, workitem.fei)
exp[direction](exp, workitem)
end
end
end)
--
-- launching a process
enqueue({
'apply',
{ 'sequence', {}, {
{ 'echo', {}, { 'hello' } },
{ 'echo', {}, { 'world' } }
} }, -- process definition
{} -- workitem
})
--
-- trigger the worker
coroutine.resume(worker)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment