From 6124b7b5e687eff120507dccfe98b72b7ddb702d Mon Sep 17 00:00:00 2001 From: Philipp Janda Date: Fri, 16 Jan 2015 17:07:02 +0100 Subject: add new fields to math library --- README.md | 9 ++++- compat53.lua | 77 ++++++++++++++++++++++++++++++++++++-- tests/test.lua | 116 ++++++++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 165 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index d870827..7099702 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,8 @@ your project: * `string.pack`, `string.packsize`, and `string.unpack` if the `struct` module is available. (`struct` is not 100% compatible to Lua 5.3's string packing!) +* `math.maxinteger` and `math.mininteger`, `math.tointeger`, `math.type`, + and `math.ult` ### C @@ -107,8 +109,11 @@ For Lua 5.1 additionally: ## What's not implemented -* the new Lua functions of Lua 5.3 -* the table library doesn't respect metamethods yet +* bit operators +* integer division operator +* `table.move` +* `coroutine.isyieldable` +* `ipairs` and the `table` library don't respect metamethods yet * Lua 5.1: `_ENV`, `goto`, labels, ephemeron tables, etc. See [`lua-compat-5.2`][2] for a detailed list. * the following C API functions/macros: diff --git a/compat53.lua b/compat53.lua index 98e1a3d..0346cb7 100644 --- a/compat53.lua +++ b/compat53.lua @@ -3,10 +3,13 @@ local lua_version = _VERSION:sub(-3) if lua_version ~= "5.3" then -- load utf8 library - utf8 = require("compat53.utf8") - package.loaded["utf8"] = utf8 - if lua_version == "5.1" then - utf8.charpattern = "[%z\1-\127\194-\244][\128-\191]*" + local ok, utf8lib = pcall(require, "compat53.utf8") + if ok then + utf8 = utf8lib + package.loaded["utf8"] = utf8lib + if lua_version == "5.1" then + utf8lib.charpattern = "[%z\1-\127\194-\244][\128-\191]*" + end end -- use Roberto's struct module for string packing/unpacking for now @@ -20,5 +23,71 @@ if lua_version ~= "5.3" then string.unpack = struct.unpack end + + -- update math library + do + local maxint, minint = 1, 0 + + while maxint+1 > maxint and 2*maxint > maxint do + maxint = maxint * 2 + end + if 2*maxint <= maxint then + maxint = 2*maxint-1 + minint = -maxint-1 + else + maxint = maxint + minint = -maxint + end + math.maxinteger = maxint + math.mininteger = minint + + local _type = type + function math.tointeger(n) + if _type(n) == "number" and n <= maxint and n >= minint and n % 1 == 0 then + return n + end + return nil + end + + function math.type(n) + if _type(n) == "number" then + if n <= maxint and n >= minint and n % 1 == 0 then + return "integer" + else + return "float" + end + else + return nil + end + end + + local _error = error + local function checkinteger(x, i, f) + local t = _type(x) + if t ~= "number" then + _error("bad argument #"..i.." to '"..f.. + "' (number expected, got "..t..")", 0) + elseif x > maxint or x < minint or x % 1 ~= 0 then + _error("bad argument #"..i.." to '"..f.. + "' (number has no integer representation)", 0) + else + return x + end + end + + function math.ult(m, n) + m = checkinteger(m, "1", "math.ult") + n = checkinteger(n, "2", "math.ult") + if m >= 0 and n < 0 then + return true + elseif m < 0 and n >= 0 then + return false + else + return m < n + end + end + end + end +-- vi: set expandtab softtabstop=3 shiftwidth=3 : diff --git a/tests/test.lua b/tests/test.lua index cc07ee8..ac415bc 100755 --- a/tests/test.lua +++ b/tests/test.lua @@ -1,63 +1,106 @@ #!/usr/bin/env lua -local mod = require( "testmod" ) -local F +local F, ___ do local type, unpack = type, table.unpack or unpack - function F( ... ) - local args, n = { ... }, select( '#', ... ) + function F(...) + local args, n = { ... }, select('#', ...) for i = 1, n do - local t = type( args[ i ] ) + local t = type(args[i]) if t ~= "string" and t ~= "number" and t ~= "boolean" then - args[ i ] = t + args[i] = t end end - return unpack( args, 1, n ) + return unpack(args, 1, n) + end + local sep = ("="):rep(70) + function ___() + print(sep) end end +print( "testing Lua API ..." ) +package.path = "../?.lua;"..package.path +require("compat53") +___'' +print("math.maxinteger", math.maxinteger+1 > math.maxinteger) +print("math.mininteger", math.mininteger-1 < math.mininteger) + + +___'' +print("math.tointeger", math.tointeger(0)) +print("math.tointeger", math.tointeger(math.pi)) +print("math.tointeger", math.tointeger("hello")) +print("math.tointeger", math.tointeger(math.maxinteger+2.0)) +print("math.tointeger", math.tointeger(math.mininteger*2.0)) + + +___'' +print("math.type", math.type(0)) +print("math.type", math.type(math.pi)) +print("math.type", math.type("hello")) + + +___'' +print("math.ult", math.ult(1, 2), math.ult(2, 1)) +print("math.ult", math.ult(-1, 2), math.ult(2, -1)) +print("math.ult", math.ult(-1, -2), math.ult(-2, -1)) +print("math.ult", pcall(math.ult, "x", 2)) +print("math.ult", pcall(math.ult, 1, 2.1)) +___'' + + -print( mod.isinteger( 1 ) ) -print( mod.isinteger( 0 ) ) -print( mod.isinteger( 1234567 ) ) -print( mod.isinteger( 12.3 ) ) -print( mod.isinteger( math.huge ) ) -print( mod.isinteger( math.sqrt( -1 ) ) ) +print("testing C API ...") +local mod = require("testmod") +___'' +print(mod.isinteger(1)) +print(mod.isinteger(0)) +print(mod.isinteger(1234567)) +print(mod.isinteger(12.3)) +print(mod.isinteger(math.huge)) +print(mod.isinteger(math.sqrt(-1))) -print( mod.rotate( 1, 1, 2, 3, 4, 5, 6 ) ) -print( mod.rotate(-1, 1, 2, 3, 4, 5, 6 ) ) -print( mod.rotate( 4, 1, 2, 3, 4, 5, 6 ) ) -print( mod.rotate( -4, 1, 2, 3, 4, 5, 6 ) ) +___'' +print(mod.rotate(1, 1, 2, 3, 4, 5, 6)) +print(mod.rotate(-1, 1, 2, 3, 4, 5, 6)) +print(mod.rotate(4, 1, 2, 3, 4, 5, 6)) +print(mod.rotate(-4, 1, 2, 3, 4, 5, 6)) -print( mod.strtonum( "+123" ) ) -print( mod.strtonum( " 123 " ) ) -print( mod.strtonum( "-1.23" ) ) -print( mod.strtonum( " 123 abc" ) ) -print( mod.strtonum( "jkl" ) ) +___'' +print(mod.strtonum("+123")) +print(mod.strtonum(" 123 ")) +print(mod.strtonum("-1.23")) +print(mod.strtonum(" 123 abc")) +print(mod.strtonum("jkl")) +___'' local a, b, c = mod.requiref() -print( type( a ), type( b ), type( c ), +print( type(a), type(b), type(c), a.boolean, b.boolean, c.boolean, - type( requiref1 ), type( requiref2 ), type( requiref3 ) ) + type(requiref1), type(requiref2), type(requiref3)) +___'' local proxy, backend = {}, {} -setmetatable( proxy, { __index = backend, __newindex = backend } ) -print( rawget( proxy, 1 ), rawget( backend, 1 ) ) -print( mod.getseti( proxy, 1 ) ) -print( rawget( proxy, 1 ), rawget( backend, 1 ) ) -print( mod.getseti( proxy, 1 ) ) -print( rawget( proxy, 1 ), rawget( backend, 1 ) ) +setmetatable(proxy, { __index = backend, __newindex = backend }) +print(rawget(proxy, 1), rawget(backend, 1)) +print(mod.getseti(proxy, 1)) +print(rawget(proxy, 1), rawget(backend, 1)) +print(mod.getseti(proxy, 1)) +print(rawget(proxy, 1), rawget(backend, 1)) -- tests for Lua 5.1 +___'' print(mod.tonumber(12)) print(mod.tonumber("12")) print(mod.tonumber("0")) print(mod.tonumber(false)) print(mod.tonumber("error")) +___'' print(mod.tointeger(12)) print(mod.tointeger("12")) print(mod.tointeger("0")) @@ -67,6 +110,7 @@ print( "bbb" ) print(mod.tointeger(false)) print(mod.tointeger("error")) +___'' print(mod.len("123")) print(mod.len({ 1, 2, 3})) print(pcall(mod.len, true)) @@ -76,34 +120,44 @@ print(mod.len(ud)) meta.__len = function() return true end print(pcall(mod.len, ud)) +___'' print(mod.copy(true, "string", {}, 1)) +___'' print(mod.rawxetp()) print(mod.rawxetp("I'm back")) +___'' print(F(mod.globals()), mod.globals() == _G) +___'' local t = {} print(F(mod.subtable(t))) local x, msg = mod.subtable(t) print(F(x, msg, x == t.xxx)) +___'' print(F(mod.udata())) print(mod.udata("nosuchtype")) +___'' print(F(mod.uservalue())) +___'' print(mod.getupvalues()) +___'' print(mod.absindex("hi", true)) +___'' print(mod.tolstring("string")) local t = setmetatable({}, { __tostring = function(v) return "mytable" end }) -print(mod.tolstring( t ) ) +print(mod.tolstring(t)) local t = setmetatable({}, { __tostring = function(v) return nil end }) print(pcall(mod.tolstring, t)) +___'' -- cgit v1.2.3-55-g6feb