diff options
Diffstat (limited to 'compat53')
| -rw-r--r-- | compat53/module.lua | 98 |
1 files changed, 77 insertions, 21 deletions
diff --git a/compat53/module.lua b/compat53/module.lua index 4450bd5..c4fc515 100644 --- a/compat53/module.lua +++ b/compat53/module.lua | |||
| @@ -9,8 +9,11 @@ if lua_version < "5.3" then | |||
| 9 | -- cache globals in upvalues | 9 | -- cache globals in upvalues |
| 10 | local error, ipairs, pairs, pcall, require, select, setmetatable, type = | 10 | local error, ipairs, pairs, pcall, require, select, setmetatable, type = |
| 11 | error, ipairs, pairs, pcall, require, select, setmetatable, type | 11 | error, ipairs, pairs, pcall, require, select, setmetatable, type |
| 12 | local debug, math, package, string, table = | 12 | local debug, io, math, package, string, table = |
| 13 | debug, math, package, string, table | 13 | debug, io, math, package, string, table |
| 14 | local io_lines = io.lines | ||
| 15 | local io_read = io.read | ||
| 16 | local unpack = lua_version == "5.1" and unpack or table.unpack | ||
| 14 | 17 | ||
| 15 | -- create module table | 18 | -- create module table |
| 16 | M = {} | 19 | M = {} |
| @@ -21,6 +24,7 @@ if lua_version < "5.3" then | |||
| 21 | setmetatable(M, M_meta) | 24 | setmetatable(M, M_meta) |
| 22 | 25 | ||
| 23 | -- create subtables | 26 | -- create subtables |
| 27 | M.io = setmetatable({}, { __index = io }) | ||
| 24 | M.math = setmetatable({}, { __index = math }) | 28 | M.math = setmetatable({}, { __index = math }) |
| 25 | M.string = setmetatable({}, { __index = string }) | 29 | M.string = setmetatable({}, { __index = string }) |
| 26 | M.table = setmetatable({}, { __index = table }) | 30 | M.table = setmetatable({}, { __index = table }) |
| @@ -148,15 +152,13 @@ if lua_version < "5.3" then | |||
| 148 | 152 | ||
| 149 | 153 | ||
| 150 | -- assert should allow non-string error objects | 154 | -- assert should allow non-string error objects |
| 151 | do | 155 | function M.assert(cond, ...) |
| 152 | function M.assert(cond, ...) | 156 | if cond then |
| 153 | if cond then | 157 | return cond, ... |
| 154 | return cond, ... | 158 | elseif select('#', ...) > 0 then |
| 155 | elseif select('#', ...) > 0 then | 159 | error((...), 0) |
| 156 | error((...), 0) | 160 | else |
| 157 | else | 161 | error("assertion failed!", 0) |
| 158 | error("assertion failed!", 0) | ||
| 159 | end | ||
| 160 | end | 162 | end |
| 161 | end | 163 | end |
| 162 | 164 | ||
| @@ -180,13 +182,63 @@ if lua_version < "5.3" then | |||
| 180 | end | 182 | end |
| 181 | 183 | ||
| 182 | 184 | ||
| 185 | -- make '*' optional for io.read and io.lines | ||
| 186 | do | ||
| 187 | local function addasterisk(fmt) | ||
| 188 | if type(fmt) == "string" and fmt:sub(1, 1) ~= "*" then | ||
| 189 | return "*"..fmt | ||
| 190 | else | ||
| 191 | return fmt | ||
| 192 | end | ||
| 193 | end | ||
| 194 | |||
| 195 | function M.io.read(...) | ||
| 196 | local n = select('#', ...) | ||
| 197 | for i = 1, n do | ||
| 198 | local a = select(i, ...) | ||
| 199 | local b = addasterisk(a) | ||
| 200 | -- as an optimization we only allocate a table for the | ||
| 201 | -- modified format arguments when we have a '*' somewhere. | ||
| 202 | if a ~= b then | ||
| 203 | local args = { ... } | ||
| 204 | args[i] = b | ||
| 205 | for j = i+1, n do | ||
| 206 | args[j] = addasterisk(args[j]) | ||
| 207 | end | ||
| 208 | return io_read(unpack(args, 1, n)) | ||
| 209 | end | ||
| 210 | end | ||
| 211 | return io_read(...) | ||
| 212 | end | ||
| 213 | |||
| 214 | -- PUC-Rio Lua 5.1 uses a different implementation for io.lines! | ||
| 215 | function M.io.lines(...) | ||
| 216 | local n = select('#', ...) | ||
| 217 | for i = 2, n do | ||
| 218 | local a = select(i, ...) | ||
| 219 | local b = addasterisk(a) | ||
| 220 | -- as an optimization we only allocate a table for the | ||
| 221 | -- modified format arguments when we have a '*' somewhere. | ||
| 222 | if a ~= b then | ||
| 223 | local args = { ... } | ||
| 224 | args[i] = b | ||
| 225 | for j = i+1, n do | ||
| 226 | args[j] = addasterisk(args[j]) | ||
| 227 | end | ||
| 228 | return io_lines(unpack(args, 1, n)) | ||
| 229 | end | ||
| 230 | end | ||
| 231 | return io_lines(...) | ||
| 232 | end | ||
| 233 | end | ||
| 234 | |||
| 235 | |||
| 183 | -- update table library (if C module not available) | 236 | -- update table library (if C module not available) |
| 184 | if not table_ok then | 237 | if not table_ok then |
| 185 | local table_concat = table.concat | 238 | local table_concat = table.concat |
| 186 | local table_insert = table.insert | 239 | local table_insert = table.insert |
| 187 | local table_remove = table.remove | 240 | local table_remove = table.remove |
| 188 | local table_sort = table.sort | 241 | local table_sort = table.sort |
| 189 | local table_unpack = lua_version == "5.1" and unpack or table.unpack | ||
| 190 | 242 | ||
| 191 | function M.table.concat(list, sep, i, j) | 243 | function M.table.concat(list, sep, i, j) |
| 192 | local mt = gmt(list) | 244 | local mt = gmt(list) |
| @@ -344,7 +396,7 @@ if lua_version < "5.3" then | |||
| 344 | i, j = i or 1, j or (has_len and mt.__len(list)) or #list | 396 | i, j = i or 1, j or (has_len and mt.__len(list)) or #list |
| 345 | return unpack_helper(list, i, j) | 397 | return unpack_helper(list, i, j) |
| 346 | else | 398 | else |
| 347 | return table_unpack(list, i, j) | 399 | return unpack(list, i, j) |
| 348 | end | 400 | end |
| 349 | end | 401 | end |
| 350 | end -- update table library | 402 | end -- update table library |
| @@ -358,9 +410,9 @@ if lua_version < "5.3" then | |||
| 358 | #setmetatable({}, { __len = function() return 1 end }) == 1 | 410 | #setmetatable({}, { __len = function() return 1 end }) == 1 |
| 359 | 411 | ||
| 360 | -- cache globals in upvalues | 412 | -- cache globals in upvalues |
| 361 | local load, loadfile, loadstring, setfenv, unpack, xpcall = | 413 | local load, loadfile, loadstring, setfenv, xpcall = |
| 362 | load, loadfile, loadstring, setfenv, unpack, xpcall | 414 | load, loadfile, loadstring, setfenv, xpcall |
| 363 | local coroutine, io, os = coroutine, io, os | 415 | local coroutine, os = coroutine, os |
| 364 | local coroutine_create = coroutine.create | 416 | local coroutine_create = coroutine.create |
| 365 | local coroutine_resume = coroutine.resume | 417 | local coroutine_resume = coroutine.resume |
| 366 | local coroutine_running = coroutine.running | 418 | local coroutine_running = coroutine.running |
| @@ -382,7 +434,6 @@ if lua_version < "5.3" then | |||
| 382 | 434 | ||
| 383 | -- create subtables | 435 | -- create subtables |
| 384 | M.coroutine = setmetatable({}, { __index = coroutine }) | 436 | M.coroutine = setmetatable({}, { __index = coroutine }) |
| 385 | M.io = setmetatable({}, { __index = io }) | ||
| 386 | M.os = setmetatable({}, { __index = os }) | 437 | M.os = setmetatable({}, { __index = os }) |
| 387 | M.package = setmetatable({}, { __index = package }) | 438 | M.package = setmetatable({}, { __index = package }) |
| 388 | 439 | ||
| @@ -734,8 +785,6 @@ if lua_version < "5.3" then | |||
| 734 | return helper(st, st.f:read(unpack(st, 1, st.n))) | 785 | return helper(st, st.f:read(unpack(st, 1, st.n))) |
| 735 | end | 786 | end |
| 736 | 787 | ||
| 737 | local valid_format = { ["*l"] = true, ["*n"] = true, ["*a"] = true } | ||
| 738 | |||
| 739 | function M.io.lines(fname, ...) | 788 | function M.io.lines(fname, ...) |
| 740 | local doclose, file, msg | 789 | local doclose, file, msg |
| 741 | if fname ~= nil then | 790 | if fname ~= nil then |
| @@ -746,8 +795,15 @@ if lua_version < "5.3" then | |||
| 746 | end | 795 | end |
| 747 | local st = { f=file, doclose=doclose, n=select('#', ...), ... } | 796 | local st = { f=file, doclose=doclose, n=select('#', ...), ... } |
| 748 | for i = 1, st.n do | 797 | for i = 1, st.n do |
| 749 | if type(st[i]) ~= "number" and not valid_format[st[i]] then | 798 | local t = type(st[i]) |
| 750 | error("bad argument #"..(i+1).." to 'for iterator' (invalid format)", 2) | 799 | if t == "string" then |
| 800 | local fmt = st[i]:match("^%*?([aln])") | ||
| 801 | if not fmt then | ||
| 802 | error("bad argument #"..(i+1).." to 'for iterator' (invalid format)", 2) | ||
| 803 | end | ||
| 804 | st[i] = "*"..fmt | ||
| 805 | elseif t ~= "number" then | ||
| 806 | error("bad argument #"..(i+1).." to 'for iterator' (invalid format)", 2) | ||
| 751 | end | 807 | end |
| 752 | end | 808 | end |
| 753 | return lines_iterator, st | 809 | return lines_iterator, st |
