Grauly

CC_IEC-OS lib2

May 7th, 2021
649
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- Copyright (c) 2016 John Schember <john@nachtimwald.com>
  2. --
  3. -- Permission is hereby granted, free of charge, to any person obtaining
  4. -- a copy of this software and associated documentation files (the "Software"),
  5. -- to deal in the Software without restriction, including without limitation
  6. -- the rights to use, copy, modify, merge, publish, distribute, sublicense,
  7. -- and/or sell copies of the Software, and to permit persons to whom the
  8. -- Software is furnished to do so, subject to the following conditions:
  9. --
  10. -- The above copyright notice and this permission notice shall be included in
  11. -- all copies or substantial portions of the Software.
  12. --
  13. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  18. -- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  19. -- DEALINGS IN THE SOFTWARE.
  20.  
  21. --- Fixed width unsigned integers backed by Lua's number type.
  22. --
  23. -- Maximum size is limited by the underlying number type size.
  24. -- The detault size Lua uses is a 64 bit signed integer. Due to
  25. -- overflow being used to handle wrapping nothing bigger than a
  26. -- 32 bit unsigned integer can be supported/represented with this
  27. -- backing type. In order to use larger than 32 bit unsigned integers
  28. -- the BigNum backed uintb type needs to be used.
  29. --
  30. -- The size limitations Lua's number type imposes is why there is not
  31. -- a public new function and instead a uintn must be created using
  32. -- one of the fixed size functions, u32, u16, and u8.
  33. --
  34. -- Also, while Lua's number type is a 64 bit signed type it is possible
  35. -- to compile Lua with a smaller number size. If a smaller size is used
  36. -- this could make u32 and friends stop functioning properly. However,
  37. -- changing the number size is a conscious choice made at compile time.
  38. -- As such, it is known to the programmer limitations that changing
  39. -- the number size imposes.
  40.  
  41. local M = {}
  42. local M_mt = {}
  43.  
  44. -- Private
  45.  
  46. --- Get the input in a workable form.
  47. --
  48. -- The order of input will not necessarily reflect the output. A swapped flag
  49. -- will be returned to indicate that a, b are being returned b, a. The input
  50. -- input is normalized into uint, number as the return values.
  51. --
  52. -- The unit returned is a new object and intended to be returned by the caller.
  53. --
  54. -- @param a Input.
  55. -- @param b Input.
  56. --
  57. -- @return unit, number, swapped.
  58. local function get_inputs(a, b)
  59.     local swapped = false
  60.  
  61.     if not M.isuint(a) then
  62.         a, b = b, a
  63.         swapped = true
  64.     end
  65.  
  66.     if M.isuint(b) then
  67.         b = b._val
  68.     else
  69.         b = tonumber(b)
  70.     end
  71.    
  72.     return a:copy(), b, swapped
  73. end
  74.  
  75. local function reduce_range(o)
  76.     if o._val == o._max then
  77.         o._val = 0
  78.     elseif o._val < 0 or o._val > o._max then
  79.         o._val = o._val % o._max
  80.     end
  81. end
  82.  
  83. -- M_mt
  84.  
  85. M_mt.__index = M
  86. M_mt.__add =
  87.     function(a, b)
  88.         local s
  89.  
  90.         a, b, s = get_inputs(a, b)
  91.  
  92.         if s then
  93.             a._val = b + a._val
  94.         else
  95.             a._val = a._val + b
  96.         end
  97.  
  98.         reduce_range(a)
  99.         return a
  100.     end
  101. M_mt.__sub =
  102.     function(a, b)
  103.         local s
  104.  
  105.         a, b, s = get_inputs(a, b)
  106.  
  107.         if s then
  108.             a._val = b - a._val
  109.         else
  110.             a._val = a._val - b
  111.         end
  112.  
  113.         reduce_range(a)
  114.         return a
  115.     end
  116. M_mt.__mul =
  117.     function(a, b)
  118.         a, b = get_inputs(a, b)
  119.  
  120.         a._val = a._val * b
  121.  
  122.         reduce_range(a)
  123.         return a
  124.     end
  125. M_mt.__div =
  126.     function(a, b)
  127.         return a // b
  128.     end
  129. M_mt.__mod =
  130.     function(a, b)
  131.         local s
  132.  
  133.         a, b, s = get_inputs(a, b)
  134.  
  135.         if s then
  136.             a._val = b % a._val
  137.         else
  138.             a._val = a._val % b
  139.         end
  140.  
  141.         reduce_range(a)
  142.         return a
  143.     end
  144. M_mt.__pow =
  145.     function(a, b)
  146.         local s
  147.  
  148.         a, b, s = get_inputs(a, b)
  149.  
  150.         if s then
  151.             a._val = b ^ a._val
  152.         else
  153.             a._val = a._val ^ b
  154.         end
  155.  
  156.         reduce_range(a)
  157.         return a
  158.     end
  159. M_mt.__unm =
  160.     function(a)
  161.         a = a:copy()
  162.  
  163.         a._val = -a._val
  164.  
  165.         reduce_range(a)
  166.         return a
  167.     end
  168. M_mt.__idiv =
  169.     function(a, b)
  170.         local s
  171.  
  172.         a, b, s = get_inputs(a, b)
  173.         if s and b == 0 then
  174.             a._val = 0
  175.             return a
  176.         end
  177.         -- if b == 0 then divide by 0 exception, let it happen.
  178.  
  179.         if s then
  180.             a._val = b // a._val
  181.         else
  182.             a._val = a._val // b
  183.         end
  184.  
  185.         reduce_range(a)
  186.         return a
  187.     end
  188. M_mt.__band =
  189.     function(a, b)
  190.         a, b = get_inputs(a, b)
  191.  
  192.         a._val = a._val & b
  193.  
  194.         reduce_range(a)
  195.         return a
  196.     end
  197. M_mt.__bor =
  198.     function(a, b)
  199.         a, b = get_inputs(a, b)
  200.  
  201.         a._val = a._val | b
  202.  
  203.         reduce_range(a)
  204.         return a
  205.     end
  206. M_mt.__bxor =
  207.     function(a, b)
  208.         a, b = get_inputs(a, b)
  209.  
  210.         a._val = a._val ~ b
  211.  
  212.         reduce_range(a)
  213.         return a
  214.     end
  215. M_mt.__bnot =
  216.     function(a)
  217.         a = a:copy()
  218.  
  219.         a._val = ~a._val
  220.  
  221.         reduce_range(a)
  222.         return a
  223.     end
  224. M_mt.__shl =
  225.     function(a, b)
  226.         local s
  227.  
  228.         a, b, s = get_inputs(a, b)
  229.  
  230.         if s then
  231.             a._val = b << a._val
  232.         else
  233.             a._val = a._val << b
  234.         end
  235.  
  236.         reduce_range(a)
  237.         return a
  238.     end
  239. M_mt.__shr =
  240.     function(a, b)
  241.         local s
  242.  
  243.         a, b, s = get_inputs(a, b)
  244.  
  245.         if s then
  246.             a._val = b >> a._val
  247.         else
  248.             a._val = a._val >> b
  249.         end
  250.  
  251.         reduce_range(a)
  252.         return a
  253.     end
  254. M_mt.__concat =
  255.     function(a, b)
  256.         if M.isuint(a) and M.isuint(b) then
  257.             return a._val..b._val
  258.         elseif M.isuint(a) and not M.isuint(b) then
  259.             return a._val..b
  260.         end
  261.         return a..b._val
  262.     end
  263. M_mt.__len =
  264.     function(a)
  265.         return a._bits
  266.     end
  267. M_mt.__eq =
  268.     function(a, b)
  269.         a, b = get_inputs(a, b)
  270.         return a._val == b
  271.     end
  272. M_mt.__lt =
  273.     function(a, b)
  274.         local s
  275.  
  276.         a, b, s = get_inputs(a, b)
  277.         if s then
  278.             return a._val > b
  279.         end
  280.         return a._val < b
  281.     end
  282. M_mt.__le =
  283.     function(a, b)
  284.         if a < b or a == b then
  285.             return true
  286.         end
  287.         return false
  288.     end
  289. M_mt.__tostring =
  290.     function(a)
  291.         return tostring(a._val)
  292.     end
  293.  
  294. -- Private
  295.  
  296. local function new(bits, n)
  297.     local o = setmetatable({}, M_mt)
  298.     o._bits = bits
  299.     o._max = 1 << o._bits
  300.  
  301.     if n == nil then
  302.         n = 0
  303.     end
  304.     if M.isuint(n) then
  305.         o._val = n._val
  306.     else
  307.         o._val = tonumber(n)
  308.     end
  309.  
  310.     reduce_range(o)
  311.     return o
  312. end
  313.  
  314. -- Static
  315.  
  316. function M.isuint(t)
  317.     if type(t) == "table" and getmetatable(t) == M_mt then
  318.         return true
  319.     end
  320.     return false
  321. end
  322.  
  323. function M.u8(v)
  324.     return new(8, v)
  325. end
  326.  
  327. function M.u16(v)
  328.     return new(16, v)
  329. end
  330.  
  331. function M.u32(v)
  332.     return new(32, v)
  333. end
  334.  
  335. -- M
  336.  
  337. function M:copy()
  338.     return new(self._bits, self._val)
  339. end
  340.  
  341. function M:set(n)
  342.     if M.isuint(n) then
  343.         self._val = n._val
  344.     else
  345.         self._val = tonumber(n)
  346.     end
  347.     reduce_range(self)
  348. end
  349.  
  350. function M:swape()
  351.     local v
  352.     local n = 0
  353.     local t
  354.  
  355.     v = self:asbytearray()
  356.     for i=1,#v//2 do
  357.         t = v[i]
  358.         v[i] = v[#v-i+1]
  359.         v[#v-i+1] = t
  360.     end
  361.  
  362.     t = {}
  363.     for i=#v,1,-1 do
  364.         t[#t+1] = v[i]
  365.     end
  366.  
  367.     for i=1,#t do
  368.         n = n | (t[i] << i*8-8)
  369.     end
  370.  
  371.     return new(self._bits, n)
  372. end
  373.  
  374. function M:asnumber()
  375.     return self._val
  376. end
  377.  
  378. function M:ashex(width)
  379.     local f = "%"
  380.     if width ~= nil then
  381.         f = f .. "0" .. tostring(width)
  382.     end
  383.     f = f .. "X"
  384.     return f:format(self._val)
  385. end
  386.  
  387. function M:asbytearray()
  388.     local t = {}
  389.  
  390.     for i=self._bits-8,0,-8 do
  391.         t[#t+1] = (self._val >> i) & 0xFF
  392.     end
  393.  
  394.     return t
  395. end
  396.  
  397. function M:asbytestring()
  398.     local b
  399.  
  400.     b = self:asbytearray()
  401.     for i=1,#b do
  402.         b[i] = string.char(b[i])
  403.     end
  404.     return table.concat(b)
  405. end
  406.  
  407. return M
  408.  
RAW Paste Data