3 local sig = require 'signal'
4 local irc = require 'irc'
8 local channel = "#doytest"
9 local network = "irc.freenode.org"
13 local function create_env()
17 collectgarbage = collectgarbage,
20 getmetatable = getmetatable,
22 loadstring = loadstring,
31 setmetatable = setmetatable,
37 coroutine = coroutine,
45 eval = function(target, from, code)
46 code = code:gsub("^=", "return ")
47 local fn, err = loadstring(code)
49 irc.say(target, from .. ": Error loading code: " .. code .. err:match(".*(:.-)$"))
52 setfenv(fn, envs[from])
53 sig.signal("ALRM", error)
55 local result = {pcall(fn)}
57 sig.signal("ALRM", "default")
58 local success = table.remove(result, 1)
60 local err = result[1]:match(".*: (.-)$")
61 if err == "ALRM" then err = "timed out" end
62 irc.say(target, from .. ": Error running code: " .. code ..
65 if result[1] == nil then
66 irc.say(target, from .. ": nil")
68 for i, v in ipairs(result) do result[i] = tostring(v) end
69 irc.say(target, from .. ": " .. table.concat(result, ", "))
74 clear = function(target, from)
75 irc.say(target, from .. ": Clearing your environment")
76 envs[from] = create_env()
78 help = function(target, from, arg)
79 if arg == "" or not arg then
80 irc.say(target, from .. ": Commands: !clear, !eval, !help")
81 elseif arg == "eval" then
82 irc.say(target, from .. ": Evaluates a Lua statement in your own persistent environment")
83 elseif arg == "clear" then
84 irc.say(target, from .. ": Clears your personal environment")
89 irc.register_callback("connect", function()
93 irc.register_callback("channel_msg", function(channel, from, message)
94 message = message:gsub("^" .. nick .. "[:,>] ", "!eval ")
95 local is_cmd, cmd, arg = message:match("^(!)([%w_]+) ?(.-)$")
96 if is_cmd and commands[cmd] then
97 envs[from] = envs[from] or create_env()
98 commands[cmd](channel.name, from, arg)
102 irc.register_callback("private_msg", function(from, message)
103 message = message:gsub("^" .. nick .. "[:,>] ", "!eval ")
104 local is_cmd, cmd, arg = message:match("^(!)([%w_]+) ?(.-)$")
105 envs[from] = envs[from] or create_env()
106 if is_cmd and commands[cmd] then
107 commands[cmd](from, from, arg)
109 commands["eval"](from, from, message)
113 irc.register_callback("nick_change", function(from, old_nick)
114 if envs[old_nick] and not envs[from] then
115 envs[from] = envs[old_nick]
120 irc.connect{network = network, nick = nick}