From 6afc9be7ae803bfba9486317b199f4976cfb9f81 Mon Sep 17 00:00:00 2001 From: VorTechnix <45538536+VorTechnix@users.noreply.github.com> Date: Fri, 14 Jul 2023 07:20:21 -0700 Subject: [PATCH] refinement of axis parser --- .../utils/parse/axes_parser.lua | 160 ++++++++++++------ 1 file changed, 110 insertions(+), 50 deletions(-) diff --git a/worldeditadditions_core/utils/parse/axes_parser.lua b/worldeditadditions_core/utils/parse/axes_parser.lua index e9dc624..9bcc00c 100644 --- a/worldeditadditions_core/utils/parse/axes_parser.lua +++ b/worldeditadditions_core/utils/parse/axes_parser.lua @@ -98,7 +98,7 @@ end -- @returns: Key Instance: returns keyword type, processed keyword content and signed number (or nil) function parse.keyword(str) if type(str) ~= "string" then - return key_instance.new("err", "Error: \""..tostring(str).."\" is not a string.", 404) + return "err", "Error: \""..tostring(str).."\" is not a string.", 404 elseif keywords.compass[str] then str = keywords.compass[str] end @@ -110,15 +110,17 @@ function parse.keyword(str) local axes = parse.axis(str) if axes then - return key_instance.new("axis", axes, sign) + return "axis", axes, sign elseif keywords.dir[str] then - return key_instance.new("dir", keywords.dir[str], sign) + return "dir", keywords.dir[str], sign elseif keywords.mirroring[str] then - return key_instance.new("rev", "mirroring") - else return key_instance.new("err", "Error: \""..str.."\" is not a valid axis, direction or keyword.", 422) + return "rev", "mirroring" + else + return "err", "Error: \""..str.."\" is not a valid axis, direction or keyword.", 422 end end + --- Creates a vector with a length of (@param: value * @param: sign) -- on each axis in @param: axes. -- @param: axes: Table: List of axes to set @@ -139,81 +141,139 @@ end -- @param: sum: Bool | String | nil: Return a single vector by summing the 2 output vectors together -- @returns: Vector3, [Vector3]: returns min, max Vector3s or sum Vector3 (if @param: sum ~= nil) -- if error: @returns: false, String: error message -function parse.keytable(tbl, facing, sum) +function parse.keytable_old(tbl, facing, sum) local min, max = Vector3.new(), Vector3.new() - local expected, tmp = 1, {axes = {}, num = 0, sign = 1, mirror = false} - function tmp:reset() self.axis, self.sign = "", 1 end + local expected = 1 + local tmp = {axes = {}, num = 0, sign = 1, mirror = false} - for i,v in ipairs(tbl) do - if v:sub(1,1) == "+" then v = v:sub(2) end + function tmp:reset() + self.axis, self.sign = "", 1 + end + + for i, v in ipairs(tbl) do + if v:sub(1, 1) == "+" then + v = v:sub(2) + end + tmp.num = parse.num(v) - if expected == 1 then -- Mode 1 of state machine - -- State machine expects string + + if expected == 1 then if tmp.num then - -- If this is a number treat as all axes and add to appropriate vector if tmp.num * tmp.sign >= 0 then max = max:add(parse.vectorize({"x","y","z"}, tmp.num, tmp.sign)) else min = min:add(parse.vectorize({"x","y","z"}, tmp.num, tmp.sign)) end - -- We are still looking for axes so the state machine should remain - -- in Mode 1 for the next iteration else - -- Else parse.keyword - local key_inst = parse.keyword(v) - -- Stop if error and return message - if key_inst:is_error() then return false, key_inst.entry end - -- Check key type and process further - if key_inst.type == "axis" then - tmp.axes = key_inst.entry - tmp.sign = key_inst.sign - elseif key_inst.type == "dir" then - tmp.axes = {facing[key_inst.entry].axis} - tmp.sign = facing[key_inst.entry].sign * key_inst.sign - elseif key_inst.type == "rev" then + local key_type, key_entry, key_sign = parse.keyword(v) + + if key_type == "axis" then + tmp.axes = key_entry + tmp.sign = key_sign + elseif key_type == "dir" then + tmp.axes = {facing[key_entry].axis} + tmp.sign = facing[key_entry].sign * key_sign + elseif key_type == "rev" then tmp.mirror = true else - -- If key type is error or unknown throw error and stop - if key_inst.type == "err" then - return false, key_inst.entry - else - return false, "Error: Unknown Key Instance type \"".. - tostring(key_inst.type).."\". Contact the devs!" - end + return false, key_entry end - expected = 2 -- Toggle state machine to expect number (Mode 2) + + expected = 2 end - - else -- Mode 2 of state machine - -- State machine expects number + else if tmp.num then - -- If this is a number process num and add to appropriate vector if tmp.num * tmp.sign >= 0 then max = max:add(parse.vectorize(tmp.axes, tmp.num, tmp.sign)) else min = min:add(parse.vectorize(tmp.axes, tmp.num, tmp.sign)) end - expected = 1 -- Toggle state machine to expect string (Mode 1) + expected = 1 else - -- Else throw an error and stop everything - return false, "Error: Expected number after \""..tostring(tbl[i-1]).. - "\", got \""..tostring(v).."\"." + return false, "Error: Expected number after \""..tostring(tbl[i-1]).."\". Got \""..tostring(v).."\"." end - end -- End of state machine - - end -- End of main for loop + end + end - -- Handle Mirroring if tmp.mirror and not sum then max = max:max(min:abs()) min = max:multiply(-1) end - if sum then return min:add(max) - else return min, max end - + if sum then + return min:add(max) + else + return min, max + end end +function parse.keytable(tbl, facing, sum) + local min, max = Vector3.new(), Vector3.new() + local expected = 1 + local tmp = {axes = {}, num = 0, sign = 1, mirror = false} + + function tmp:reset() + self.axis, self.sign = "", 1 + end + + local function processNumber(num, axes, sign) + if num * sign >= 0 then + max = max:add(parse.vectorize(axes, num, sign)) + else + min = min:add(parse.vectorize(axes, num, sign)) + end + end + + for i, v in ipairs(tbl) do + if v:sub(1, 1) == "+" then + v = v:sub(2) + end + + tmp.num = parse.num(v) + + if expected == 1 then + if tmp.num then + processNumber(tmp.num, {"x", "y", "z"}, tmp.sign) + else + local key_type, key_entry, key_sign = parse.keyword(v) + + if key_type == "axis" then + tmp.axes = key_entry + tmp.sign = key_sign + elseif key_type == "dir" then + tmp.axes = {facing[key_entry].axis} + tmp.sign = facing[key_entry].sign * key_sign + elseif key_type == "rev" then + tmp.mirror = true + else + return false, key_entry + end + + expected = 2 + end + else + if tmp.num then + processNumber(tmp.num, tmp.axes, tmp.sign) + expected = 1 + else + return false, "Error: Expected number after \""..tostring(tbl[i-1]).."\". Got \""..tostring(v).."\"." + end + end + end + + if tmp.mirror and not sum then + max = max:max(min:abs()) + min = max:multiply(-1) + end + + if sum then + return min:add(max) + else + return min, max + end +end + + return { keyword = parse.keyword, keytable = parse.keytable,