#!/usr/bin/lua
-- Sidef executor in Lua
String = setmetatable({
__index = function(self, i)
return String[i]
end,
concat = function(self, arg)
return String(self.value .. arg.value)
end,
say = function(self)
self:concat(String("\n")):print();
end,
print = function(self)
io.write(self.value);
end,
},
{
__call = function(self, val)
return setmetatable({value = val}, String)
end
});
function execute_expr(statement)
local self_obj = statement['self'];
if (type(self_obj) == "table" and getmetatable(self_obj) == nil) then
self_obj = execute(self_obj);
end
if (statement['call'] ~= nil) then
for i = 1, #(statement['call']) do
local call = statement['call'][i];
local meth = call['method'];
if (call['arg'] ~= nil) then
local args = {};
local call_args = call['arg'];
for i = 1, #call_args do
local arg = call_args[i];
if (type(arg) == "table" and getmetatable(arg) == nil) then
arg = execute_expr(arg);
end
args[i] = arg;
end
self_obj = self_obj[meth](self_obj, unpack(args));
else
self_obj = self_obj[meth](self_obj);
end
end
end
return self_obj;
end
function execute(structure)
local results = {};
for i = 1, #(structure['main']) do
local statement = structure['main'][i];
results[i] = execute_expr(statement);
end
return results[#results];
end
local ast = {
main = {
{
call = {{method = "print"}},
self = {
main = {
{
call = {{method = "concat", arg = {{self = String("llo")}}}},
self = String("he"),
}
},
}
},
{
call = {{method = "say"}},
self = String(" world!");
},
}
}
execute(ast);