1--[[
2 Normalized Lua API for Lua 5.1, 5.2, 5.3 & 5.4
3 Coryright (C) 2014-2020 std.normalize authors
4]]
5--[[--
6 Purely to break internal dependency cycles without introducing
7 multiple copies of base functions used in other normalize modules.
8
9 @module std.normalize._base
10]]
11
12
13local _ENV = require 'std.normalize._strict' {
14   floor = math.floor,
15   getmetatable = getmetatable,
16   pack = table.pack or false,
17   select = select,
18   setmetatable = setmetatable,
19   tointeger = math.tointeger or false,
20   tonumber = tonumber,
21   tostring = tostring,
22   type = type,
23}
24
25
26
27--[[ =============== ]]--
28--[[ Implementation. ]]--
29--[[ =============== ]]--
30
31
32local function getmetamethod(x, n)
33   local m = (getmetatable(x) or {})[tostring(n)]
34   if type(m) == 'function' then
35      return m
36   end
37   if type((getmetatable(m) or {}).__call) == 'function' then
38      return m
39   end
40end
41
42
43local pack_mt = {
44   __len = function(self)
45      return self.n
46   end,
47}
48
49
50local pack = pack or function(...)
51   return {n=select('#', ...), ...}
52end
53
54
55local tointeger = (function(f)
56   if not f then
57      -- No host tointeger implementation, use our own.
58      return function(x)
59        if type(x) == 'number' and x - floor(x) == 0.0 then
60           return x
61        end
62      end
63
64   elseif f '1' ~= nil then
65      -- Don't perform implicit string-to-number conversion!
66      return function(x)
67         if type(x) == 'number' then
68            return tointeger(x)
69         end
70      end
71   end
72
73   -- Host tointeger is good!
74   return f
75end)(tointeger)
76
77
78
79--[[ ================= ]]--
80--[[ Public Interface. ]]--
81--[[ ================= ]]--
82
83
84return {
85   --- Return named metamethod, if callable, otherwise `nil`.
86   -- @see std.normalize.getmetamethod
87   getmetamethod = getmetamethod,
88
89   --- Return a list of given arguments, with field `n` set to the length.
90   -- @see std.normalize.pack
91   pack = function(...)
92      return setmetatable(pack(...), pack_mt)
93   end,
94
95   --- Convert to an integer and return if possible, otherwise `nil`.
96   -- @see std.normalize.math.tointeger
97   tointeger = tointeger,
98}
99