logic.lua 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. local lg = {}
  2. local operations = {
  3. -- table index: Index in the formspec dropdown
  4. -- gate: Internal name
  5. -- short: Serialized form, single character
  6. -- fs_name: Display name, padded to 4 characters
  7. -- func: Function that applies the operation
  8. -- unary: Whether this gate only has one input
  9. { gate = "and", short = "&", fs_name = " AND", func = function(a, b) return a and b end },
  10. { gate = "or", short = "|", fs_name = " OR", func = function(a, b) return a or b end },
  11. { gate = "not", short = "~", fs_name = " NOT", func = function(a, b) return not b end, unary = true },
  12. { gate = "xor", short = "^", fs_name = " XOR", func = function(a, b) return a ~= b end },
  13. { gate = "nand", short = "?", fs_name = "NAND", func = function(a, b) return not (a and b) end },
  14. { gate = "buf", short = "_", fs_name = " =", func = function(a, b) return b end, unary = true },
  15. { gate = "xnor", short = "=", fs_name = "XNOR", func = function(a, b) return a == b end },
  16. { gate = "nor", short = "!", fs_name = " NOR", func = function(a, b) return not (a or b) end },
  17. }
  18. lg.get_operations = function()
  19. return operations
  20. end
  21. -- (de)serialize
  22. lg.serialize = function(t)
  23. local function _op(t)
  24. if t == nil then
  25. return " "
  26. elseif t.type == "io" then
  27. return t.port
  28. else -- t.type == "reg"
  29. return tostring(t.n)
  30. end
  31. end
  32. -- Serialize actions (gates) from eg. "and" to "&"
  33. local function _action(action)
  34. for i, data in ipairs(operations) do
  35. if data.gate == action then
  36. return data.short
  37. end
  38. end
  39. return " "
  40. end
  41. local s = ""
  42. for i = 1, 14 do
  43. local cur = t[i]
  44. if next(cur) ~= nil then
  45. s = s .. _op(cur.op1) .. _action(cur.action) .. _op(cur.op2) .. _op(cur.dst)
  46. end
  47. s = s .. "/"
  48. end
  49. return s
  50. end
  51. lg.deserialize = function(s)
  52. local function _op(c)
  53. if c == "A" or c == "B" or c == "C" or c == "D" then
  54. return {type = "io", port = c}
  55. elseif c == " " then
  56. return nil
  57. else
  58. return {type = "reg", n = tonumber(c)}
  59. end
  60. end
  61. -- Deserialize actions (gates) from eg. "&" to "and"
  62. local function _action(action)
  63. for i, data in ipairs(operations) do
  64. if data.short == action then
  65. return data.gate
  66. end
  67. end
  68. -- nil
  69. end
  70. local ret = {}
  71. for part in s:gmatch("(.-)/") do
  72. local parsed
  73. if part == "" then
  74. parsed = {}
  75. else
  76. parsed = {
  77. action = _action( part:sub(2,2) ),
  78. op1 = _op( part:sub(1,1) ),
  79. op2 = _op( part:sub(3,3) ),
  80. dst = _op( part:sub(4,4) ),
  81. }
  82. end
  83. ret[#ret + 1] = parsed
  84. end
  85. -- More than 14 instructions (write to all 10 regs + 4 outputs)
  86. -- will not pass the write-once requirement of the validator
  87. assert(#ret == 14)
  88. return ret
  89. end
  90. -- validation
  91. lg.validate_single = function(t, i)
  92. local function is_reg_written_to(t, n, max)
  93. for i = 1, max-1 do
  94. if next(t[i]) ~= nil
  95. and t[i].dst and t[i].dst.type == "reg"
  96. and t[i].dst.n == n then
  97. return true
  98. end
  99. end
  100. return false
  101. end
  102. local function compare_op(t1, t2, allow_same_io)
  103. if t1 == nil or t2 == nil then
  104. return false
  105. elseif t1.type ~= t2.type then
  106. return false
  107. end
  108. if t1.type == "reg" and t1.n == t2.n then
  109. return true
  110. elseif t1.type == "io" and t1.port == t2.port then
  111. return not allow_same_io
  112. end
  113. return false
  114. end
  115. local elem = t[i]
  116. local gate_data
  117. for j, data in ipairs(operations) do
  118. if data.gate == elem.action then
  119. gate_data = data
  120. break
  121. end
  122. end
  123. -- check for completeness
  124. if not gate_data then
  125. return {i = i, msg = "Gate type is required"}
  126. elseif gate_data.unary then
  127. if elem.op1 ~= nil or elem.op2 == nil or elem.dst == nil then
  128. return {i = i, msg = "Second operand (only) and destination are required"}
  129. end
  130. else
  131. if elem.op1 == nil or elem.op2 == nil or elem.dst == nil then
  132. return {i = i, msg = "Operands and destination are required"}
  133. end
  134. end
  135. -- check whether operands/destination are identical
  136. if compare_op(elem.op1, elem.op2) then
  137. return {i = i, msg = "Operands cannot be identical"}
  138. end
  139. if compare_op(elem.op1, elem.dst, true) or compare_op(elem.op2, elem.dst, true) then
  140. return {i = i, msg = "Destination and operands must be different"}
  141. end
  142. -- check whether operands point to defined registers
  143. if elem.op1 ~= nil and elem.op1.type == "reg"
  144. and not is_reg_written_to(t, elem.op1.n, i) then
  145. return {i = i, msg = "First operand is undefined register"}
  146. end
  147. if elem.op2.type == "reg" and not is_reg_written_to(t, elem.op2.n, i) then
  148. return {i = i, msg = "Second operand is undefined register"}
  149. end
  150. -- check whether destination points to undefined register
  151. if elem.dst.type == "reg" and is_reg_written_to(t, elem.dst.n, i) then
  152. return {i = i, msg = "Destination is already used register"}
  153. end
  154. return nil
  155. end
  156. lg.validate = function(t)
  157. for i = 1, 14 do
  158. if next(t[i]) ~= nil then
  159. local r = lg.validate_single(t, i)
  160. if r ~= nil then
  161. return r
  162. end
  163. end
  164. end
  165. return nil
  166. end
  167. -- interpreter
  168. lg.interpret = function(t, a, b, c, d)
  169. local function _action(s, v1, v2)
  170. for i, data in ipairs(operations) do
  171. if data.gate == s then
  172. return data.func(v1, v2)
  173. end
  174. end
  175. return false -- unknown gate
  176. end
  177. local function _op(t, regs, io_in)
  178. if t.type == "reg" then
  179. return regs[t.n]
  180. else -- t.type == "io"
  181. return io_in[t.port]
  182. end
  183. end
  184. local io_in = {A=a, B=b, C=c, D=d}
  185. local regs = {}
  186. local io_out = {}
  187. for i = 1, 14 do
  188. local cur = t[i]
  189. if next(cur) ~= nil then
  190. local v1, v2
  191. if cur.op1 ~= nil then
  192. v1 = _op(cur.op1, regs, io_in)
  193. end
  194. v2 = _op(cur.op2, regs, io_in)
  195. local result = _action(cur.action, v1, v2)
  196. if cur.dst.type == "reg" then
  197. regs[cur.dst.n] = result
  198. else -- cur.dst.type == "io"
  199. io_out[cur.dst.port] = result
  200. end
  201. end
  202. end
  203. return io_out.A, io_out.B, io_out.C, io_out.D
  204. end
  205. return lg