Files
alunizaje/android/tools/zbstudio.app/Contents/ZeroBraneStudio/lualibs/luainspect/types.lua
Andros Fenollosa 892d89c7f1 Order files
2016-11-12 12:27:08 +01:00

131 lines
3.2 KiB
Lua

local T = {} -- types
-- istype[o] iff o represents a type (i.e. set of values)
T.istype = {}
-- iserror[o] iff o represents an error type (created via T.error).
T.iserror = {}
-- istabletype[o] iff o represents a table type (created by T.table).
T.istabletype = {}
-- Number type
T.number = {}
setmetatable(T.number, T.number)
function T.number.__tostring(self)
return 'number'
end
T.istype[T.number] = true
-- String type
T.string = {}
setmetatable(T.string, T.string)
function T.string.__tostring(self)
return 'string'
end
T.istype[T.string] = true
-- Boolean type
T.boolean = {}
setmetatable(T.boolean, T.boolean)
function T.boolean.__tostring(self)
return 'boolean'
end
T.istype[T.boolean] = true
-- Table type
function T.table(t)
T.istype[t] = true
T.istabletype[t] = true
return t
end
-- Universal type. This is a superset of all other types.
T.universal = {}
setmetatable(T.universal, T.universal)
function T.universal.__tostring(self)
return 'unknown'
end
T.istype[T.universal] = true
-- nil type. Represents `nil` but can be stored in tables.
T['nil'] = {}
setmetatable(T['nil'], T['nil'])
T['nil'].__tostring = function(self)
return 'nil'
end
T.istype[T['nil']] = true
-- None type. Represents a non-existent value, in a similar way
-- that `none` is used differently from `nil` in the Lua C API.
T.none = {}
setmetatable(T.none, T.none)
function T.none.__tostring(self)
return 'none'
end
T.istype[T.none] = true
-- Error type
local CError = {}; CError.__index = CError
function CError.__tostring(self) return "error:" .. tostring(self.value) end
function T.error(val)
local self = setmetatable({value=val}, CError)
T.istype[self] = true
T.iserror[self] = true
return self
end
-- Gets a type that is a superset of the two given types.
function T.superset_types(a, b)
if T.iserror[a] then return a end
if T.iserror[b] then return b end
if rawequal(a, b) then -- note: including nil == nil
return a
elseif type(a) == 'string' or a == T.string then
if type(b) == 'string' or b == T.string then
return T.string
else
return T.universal
end
elseif type(a) == 'number' or a == T.number then
if type(b) == 'number' or b == T.number then
return T.number
else
return T.universal
end
elseif type(a) == 'boolean' or a == T.boolean then
if type(b) == 'boolean' or b == T.boolean then
return T.boolean
else
return T.universal
end
else
return T.universal -- IMPROVE
end
end
--[[TESTS:
assert(T.superset_types(2, 2) == 2)
assert(T.superset_types(2, 3) == T.number)
assert(T.superset_types(2, T.number) == T.number)
assert(T.superset_types(T.number, T.string) == T.universal)
print 'DONE'
--]]
-- Determines whether type `o` certainly evaluates to true (true),
-- certainly evaluates to false (false) or could evaluate to either
-- true of false ('?').
function T.boolean_cast(o)
if T.iserror[o] then -- special case
return '?'
elseif o == nil or o == false or o == T['nil'] then -- all subsets of {nil, false}
return false
elseif o == T.universal or o == T.boolean then -- all supersets of boolean
return '?'
else -- all subsets of universal - {nil, false}
return true
end
end
return T