Advertisement
GnoX

SequenceExecutor

Jul 14th, 2014
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.89 KB | None | 0 0
  1. SequenceExecutor = Class.new()
  2.  
  3. local SequenceParser = Class.new(SequenceParser)
  4. local CommandExecutor = Class.new(CommandExecutor)
  5. local output
  6.  
  7. function SequenceExecutor.new.default()
  8.     local self = setmetatable({}, SequenceExecutor)
  9.     self.commandsLoaded = false
  10.     self.commands = ""
  11.     self.parser = SequenceParser(self)
  12.     return self
  13. end
  14.  
  15. function SequenceExecutor.new.table(t)
  16.     local self = SequenceExecutor()
  17.     self.turtleObject = t
  18.     self:loadCommands(t)
  19.     return self
  20. end
  21.  
  22. function SequenceExecutor:loadString(s)
  23.     self.parser:loadString(s)
  24. end
  25.  
  26. function SequenceExecutor:loadCommands(turtleObject)
  27.     self.commands = {
  28.         ["f"] = turtleObject.forward,
  29.         ["b"] = turtleObject.back,
  30.         ["u"] = turtleObject.up,
  31.         ["d"] = turtleObject.down,
  32.         ["r"] = turtleObject.right,
  33.         ["l"] = turtleObject.left,
  34.         ["F"] = turtleObject.dig,
  35.         ["U"] = turtleObject.digUp,
  36.         ["D"] = turtleObject.digDown,
  37.         ["-"] = turtleObject.place,
  38.         ["^"] = turtleObject.placeUp,
  39.         ["_"] = turtleObject.placeDown,
  40.         ["a"] = turtleObject.detect,
  41.         ["q"] = turtleObject.detectUp,
  42.         ["z"] = turtleObject.detectDown,
  43.         ["s"] = turtleObject.select,
  44.     }
  45.     self.commandsLoaded = true
  46. end
  47.  
  48. function SequenceExecutor:execute()
  49.     if self.commandsLoaded then
  50.         self.parser.next()
  51.  
  52.     else
  53.         error("SequenceExecutor error: Commands not loaded, use loadCommands() before execute()");
  54.     end
  55. end
  56.  
  57. function SequenceExecutor:executeAll(outputE)
  58.     output = outputE
  59.     while not self.parser:completed() do
  60.         if not outputE then
  61.             CommandExecutor(self, self.parser:next():get()):execute()
  62.         else
  63.             self.parser:next()
  64.         end
  65.     end
  66. end
  67.  
  68.  
  69. ---------------------------
  70. -- SEQUENCE PARSER CLASS --
  71. ---------------------------
  72. function SequenceParser.new.table(t)
  73.     local self = setmetatable({}, SequenceParser)
  74.     self:clear()
  75.     self.sequence = ""
  76.     self.executor = t
  77.     self.compositeStep = 0
  78.     self.postExecutors = false
  79.     self.newStep = false
  80.     return self;
  81. end
  82.  
  83. function SequenceParser:clear()
  84.     self.buffer = ""
  85.     self.condition = ""
  86.     self.command = ""
  87.     self.secondCommand = ""
  88. end
  89.  
  90. function SequenceParser.new.table.string(t, s)
  91.     local self = SequenceParser(t)
  92.     self.sequence, self.compositeSequence = s, s
  93.     return self
  94. end
  95.  
  96. function SequenceParser.new.table.string.number(t, s, n)
  97.     local self = SequenceParser(t, s)
  98.     self.compositeStop = n
  99.     self.compositeStep = 0
  100.     return self
  101. end
  102.  
  103. function SequenceParser.new.table.string.string(t, s, ts)
  104.     local self = SequenceParser(t, s)
  105.     self.toggleSequence = ts
  106.     self.postExecutionMod = 2
  107.     return self
  108. end
  109.  
  110. function SequenceParser.new.table.string.number.number(t, s, n, pem)
  111.     local self = SequenceParser(t, s)
  112.     self.postExecutionMod = pem
  113.     self.compositeStop = 0
  114.     return self
  115. end
  116.  
  117. function SequenceParser:next()
  118.     self:clear()
  119.     --    if output and self.sequence ~= "" then print("Sequence:" .. self.sequence) end
  120.     if not self.inExecution then
  121.         if self.compositeParser then
  122.             if self.compositeParser.compositeStep == self.compositeParser.compositeStop then
  123.                 self.compositeParser = false
  124.             else
  125.                 return self.compositeParser:next()
  126.             end
  127.         end
  128.  
  129.  
  130.  
  131.         if self.sequence:match("^%d*%[") then
  132.             local postExecute = {}
  133.             local n
  134.             local i = 0
  135.             self.buffer = self:extract("[", "]")
  136.  
  137.             self:removeCommandFromQueue();
  138.             while true do
  139.                 i = i + 1
  140.                 n = self.sequence:match("^%d*<")
  141.                 if n then
  142.                     n = self.sequence:match("^%d*")
  143.                     postExecute[i] = self:extract("<", ">");
  144.                     self.sequence = self.sequence:sub(postExecute[i]:len() + n:len())
  145.                     if n:len() ~= 0 then
  146.                         postExecute[i] = SequenceParser(self.executor, postExecute[i]:sub(2 + n:len(), -2), 0, tonumber(n))
  147.                     else
  148.                         self.sequence = self.sequence:sub(0, -2)
  149.                         postExecute[i] = SequenceParser(self.executor, postExecute[i]:match("<(.*);(.-)>"))
  150.                     end
  151.                 else
  152.                     break
  153.                 end
  154.             end
  155.  
  156.             local compositeMoves = self.buffer:match("%d+")
  157.             self.compositeParser = SequenceParser(self.executor, self.buffer:sub(compositeMoves:len() + 2, -2), tonumber(compositeMoves))
  158.             self.compositeParser:setPostExecutor(postExecute)
  159.             return self.compositeParser:next()
  160.         end
  161.  
  162.         self:basicDecomposition()
  163.         if output and self.buffer then print("Buffer:" .. self.buffer) sleep(.5) end
  164.     end
  165.     if self:sequenceCompleted() and self.compositeStop and self.compositeStep < self.compositeStop then
  166.         self.inExecution = true
  167.  
  168.         local leave = true;
  169.         if self.postExecutors then
  170.             for i = 1, #self.postExecutors do
  171.                 if not self.postExecutors[i].locked then
  172.                     if not self.postExecutors[i]:sequenceCompleted() then
  173.                         if (self.compositeStep + 1) % self.postExecutors[i].postExecutionMod == 0 then
  174.                             return self.postExecutors[i]:next()
  175.                         elseif self.postExecutors[i].toggleSequence then
  176.                             return self.postExecutors[i]:next()
  177.                         end
  178.                     else
  179.                         self.postExecutors[i].locked = true
  180.                         if (self.compositeStep + 1) % self.postExecutors[i].postExecutionMod == 0 then
  181.                             self.postExecutors[i]:revertSequence()
  182.                         else
  183.                             self.postExecutors[i].sequence = self.postExecutors[i].toggleSequence
  184.                         end
  185.                     end
  186.                 end
  187.             end
  188.             for i = 1, #self.postExecutors do
  189.                 self.postExecutors[i].locked = false
  190.             end
  191.         end
  192.  
  193.         self.compositeStep = self.compositeStep + 1
  194.         self:revertSequence()
  195.         self.inExecution = false
  196.     end
  197.     if not self:validateCommands() then
  198.         if not self:sequenceCompleted() then
  199.             return self:next()
  200.         else
  201.             return { get = function() return 0, "", 0, "", 0, "", false end }
  202.         end
  203.     end
  204.  
  205.  
  206.     return self
  207. end
  208.  
  209. function SequenceParser:revertSequence()
  210.     self.sequence = self.compositeSequence
  211. end
  212.  
  213. function SequenceParser:basicDecomposition()
  214.     local secondPart = ""
  215.     self.buffer = self.sequence:match("%d*!?[%a%-_^]%??")
  216.     self.command = self.buffer
  217.     if self:commandContainsCondition() then
  218.         self.condition = self.buffer:sub(0, -2)
  219.  
  220.         self.buffer = self.sequence:match("%?%d*[%a%-_^]:?")
  221.         self.command = self.buffer:sub(2, -1)
  222.  
  223.         if self.buffer:find(":") then
  224.             self.command = self.command:sub(0, -2)
  225.             self.buffer = self.sequence:match("%:%d*[%a%-_^]")
  226.             self.secondCommand = self.buffer:sub(2)
  227.             secondPart = ":" .. self.secondCommand
  228.         end
  229.         self.buffer = self.condition .. "?" .. self.command .. secondPart
  230.     end
  231.     self:removeCommandFromQueue()
  232. end
  233.  
  234. function SequenceParser:validateCommands()
  235.     return self:isValidMove(self:getMoveFromCommand(self.command))
  236.             and self:isValidMove(self:getMoveFromCommand(self.secondCommand))
  237.             and self:isValidMove(self:getMoveFromCommand(self.condition))
  238. end
  239.  
  240. function SequenceParser:extract(startTag, endTag)
  241.     local count = 0
  242.  
  243.     local start = self.sequence:find("%" .. startTag) + 1
  244.     for i = start, self.sequence:len() + 1 do
  245.         if self.sequence:sub(i, i) == startTag then
  246.             count = count + 1
  247.         elseif self.sequence:sub(i, i) == endTag then
  248.             if count == 0 then
  249.                 return self.sequence:sub(0, -1 - self.sequence:len() + i)
  250.             else
  251.                 count = count - 1
  252.             end
  253.         end
  254.     end
  255. end
  256.  
  257. function SequenceParser:sequenceCompleted()
  258.     return self.sequence == ""
  259. end
  260.  
  261. function SequenceParser:completed()
  262.     if self.compositeParser
  263.             and self.compositeParser.compositeStep == self.compositeParser.compositeStop
  264.             or not self.compositeParser
  265.             and not self.postExecutor then
  266.         return self:sequenceCompleted()
  267.     end
  268.     return false
  269. end
  270.  
  271. function SequenceParser:setPostExecutor(executors)
  272.     self.postExecutors = executors or false
  273. end
  274.  
  275. function SequenceParser:addToQueue(commands)
  276.     self.sequence = self.sequence .. commands
  277. end
  278.  
  279. function SequenceParser:commandContainsCondition()
  280.     return self.buffer and self.buffer:find("?")
  281. end
  282.  
  283. function SequenceParser:removeCommandFromQueue()
  284.     if self.buffer then
  285.         self.sequence = self.sequence:sub(self.buffer:len() + 1)
  286.     end
  287. end
  288.  
  289. function SequenceParser:isValidMove(move)
  290.     if move == "" then return true
  291.     end
  292.     for c in pairs(self.executor.commands) do
  293.         if move == c then return true
  294.         end
  295.     end
  296.     return false
  297. end
  298.  
  299. function SequenceParser:conditionNegated()
  300.     return self.condition:find("!") and true or false
  301. end
  302.  
  303. function SequenceParser:getMoveFromCommand(command)
  304.     if command then return command:match("[%a%-_^]") or "" else return ""
  305.     end
  306. end
  307.  
  308. function SequenceParser:getMoveCountFromCommand(command)
  309.     if command then return tonumber(command:match("%d*")) or 1 else return 1
  310.     end
  311. end
  312.  
  313. function SequenceParser:getCondition()
  314.     return self:getMoveFromCommand(self.condition)
  315. end
  316.  
  317. function SequenceParser:getConditionNumber()
  318.     return self:getMoveCountFromCommand(self.condition)
  319. end
  320.  
  321. function SequenceParser:getFirstMove()
  322.     return self:getMoveFromCommand(self.command)
  323. end
  324.  
  325. function SequenceParser:getFirstMoveCount()
  326.     return self:getMoveCountFromCommand(self.command)
  327. end
  328.  
  329. function SequenceParser:getSecondMove()
  330.     return self:getMoveFromCommand(self.secondCommand)
  331. end
  332.  
  333. function SequenceParser:getSecondMoveCount()
  334.     return self:getMoveCountFromCommand(self.secondCommand)
  335. end
  336.  
  337. function SequenceParser:get()
  338.     return
  339.     self:getConditionNumber(),
  340.     self:getCondition(),
  341.     self:getFirstMoveCount(),
  342.     self:getFirstMove(),
  343.     self:getSecondMoveCount(),
  344.     self:getSecondMove(),
  345.     self:conditionNegated()
  346. end
  347.  
  348. function SequenceParser:loadString(s)
  349.     self.sequence = s
  350. end
  351.  
  352.  
  353.  
  354. ----------------------------
  355. --- COMMAND PARSER CLASS ---
  356. ----------------------------
  357. function CommandExecutor.new.default()
  358.     local self = setmetatable({}, CommandExecutor)
  359.     return self
  360. end
  361.  
  362. function CommandExecutor.new.table.number.string.number.string.number.string.boolean(t, n1, c1, n2, c2, n3, c3, negated)
  363.     local self = CommandExecutor()
  364.     self.conditionNumber = n1
  365.     self.condition = c1
  366.  
  367.     self.firstNumber = n2
  368.     self.firstCommand = c2
  369.  
  370.     self.secondNumber = n3
  371.     self.secondCommand = c3
  372.  
  373.     self.conditionNegated = negated
  374.     self.executor = t;
  375.  
  376.     return self
  377. end
  378.  
  379.  
  380. function CommandExecutor:isCondition()
  381.     return self.condition ~= "";
  382. end
  383.  
  384. function CommandExecutor:getCondition()
  385.     if self:isCondition() then
  386.         local condition = self.executor.commands[self.condition](self.conditionNumber)
  387.         if self.conditionNegated then return not condition else return condition
  388.         end
  389.     else
  390.         return true
  391.     end
  392. end
  393.  
  394. function CommandExecutor:execute()
  395.     if (self.firstCommand ~= "") then
  396.         if self:getCondition() then
  397.             self.executor.commands[self.firstCommand](self.firstNumber)
  398.         elseif (self.secondCommand ~= "") then
  399.             self.executor.commands[self.secondCommand](self.secondNumber)
  400.         end
  401.     end
  402. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement