diff --git a/.github/workflows/deploy-docs2.yml b/.github/workflows/deploy-docs2.yml index 2432091..4997e2a 100644 --- a/.github/workflows/deploy-docs2.yml +++ b/.github/workflows/deploy-docs2.yml @@ -40,6 +40,7 @@ jobs: script_dir=docs/src/.vuepress/public/scripts lua minify.lua minify src/movescript.lua > $script_dir/movescript-min.lua lua minify.lua minify src/itemscript.lua > $script_dir/itemscript-min.lua + lua minify.lua minify src/buildscript.lua > $script_dir/buildscript-min.lua - name: Clean Up Lua Artifacts run: | diff --git a/src/buildscript.lua b/src/buildscript.lua new file mode 100644 index 0000000..148b38b --- /dev/null +++ b/src/buildscript.lua @@ -0,0 +1,91 @@ +--[[ +Buildscript - A unified set of tools that make repetitive building tasks easier +with ComputerCraft robots. + +Author: Andrew Lalis + +This module depends upon both Movescript and Itemscript. +]]-- +local movescript = require("movescript") +local itemscript = require("itemscript") + +-- The buildscript module. +local buildscript = {} +buildscript.VERSION = "0.0.1" + +-- Runs a movescript script, while ensuring that a given item is always selected. +function buildscript.runWithItem(ms_script, filterExpr) + local instructions = movescript.parse(ms_script) + for idx, instruction in pairs(instructions) do + itemscript.selectOrWait(filterExpr) + movescript.executeInstruction(instruction) + end +end + +local function parseArgValue(argSpec, str) + +end + +-- Parses arguments according to a specification table, for common building +-- scripts, and returns a table with key-value pairs for each arg. +-- The specification table should be formatted like so: +-- { +-- argName = { type = "string", required = true, idx = 1 } +-- } +function buildscript.parseArgs(args, spec) + local idxArgSpecs = {} + local namedArgSpecs = {} + for name, argSpec in pairs(spec) do + if argSpec.idx ~= nil then + -- Add this argSpec to the list of indexed arg specs for parsing first. + if type(argSpec.idx) ~= "number" or argSpec.idx < 1 do + return false, "Invalid argument specification: " .. name .. " does not have a valid numeric index." + end + idxArgSpecs[name] = argSpec + elseif argSpec.name ~= nil then + -- Otherwise, ensure that this argSpec has a name. + if type(argSpec.name) ~= "string" or #argSpec.name < 3 do + return false, "Invalid argument specification: " .. name .. " does not have a valid string name." + end + namedArgSpecs[name] = argSpec + else + return false, "Invalid argument specification: " .. name .. " doesn't have idx or name." + end + end + + local results = {} + local idx = 1 + while idx <= #args do + local parsed = false + -- Try and see if there's an idx arg spec for this index first. + for name, argSpec in pairs(idxArgSpecs) do + if argSpec.idx == idx then + local success, value = parseArgValue(argSpec, args[idx]) + if success then + results[name] = value + idxArgSpecs[name] = nil + parsed = true + break + elseif not success and argSpec.required then + return false, "Failed to parse value for " .. name .. " argument: " .. value + end + end + end + + -- If no idx arg spec could parse the argument, try a named one. + if not parsed then + if idx == #args then + return false, "Missing value for argument " .. args[idx] + end + for name, argSpec in pairs(idxArgSpecs) do + + end + end + + idx = idx + 1 + end + + return true, results +end + +return buildscript diff --git a/src/itemscript.lua b/src/itemscript.lua index 545fdb7..84fc78b 100644 --- a/src/itemscript.lua +++ b/src/itemscript.lua @@ -137,6 +137,15 @@ function itemscript.select(filterExpr) return false end +-- Selects a slot containing at least one of the given item type, or waits for +-- the user to add an item otherwise. +function itemscript.selectOrWait(filterExpr) + while not itemscript.select(filterExpr) do + print("Couldn't find at least one item matching the filter expression: \"" .. filterExpr .. "\". Please add it.") + os.pullEvent("turtle_inventory") + end +end + -- Helper function to drop items in a flexible way, using a drop function and filtering function. local function dropFiltered(dropFunction, filter) for i = 1, 16 do diff --git a/src/movescript.lua b/src/movescript.lua index a514a08..50768fe 100644 --- a/src/movescript.lua +++ b/src/movescript.lua @@ -279,12 +279,12 @@ end -- Executes a single instruction. An instruction is a table with an "action" -- and some attributes, such as if it needs fuel or not. -local function executeInstruction(instruction, settings) +function movescript.executeInstruction(instruction, settings) if instruction.type == INSTRUCTION_TYPES.repeated then debug("Executing repeated instruction " .. instruction.count .. " times.", settings) for i = 1, instruction.count do for _, nestedInstruction in pairs(instruction.instructions) do - executeInstruction(nestedInstruction, settings) + movescript.executeInstruction(nestedInstruction, settings) end end elseif instruction.type == INSTRUCTION_TYPES.instruction then @@ -428,7 +428,7 @@ function movescript.run(script, settings) debug("Executing script: " .. script, settings) local instructions = movescript.parse(script, settings) for idx, instruction in pairs(instructions) do - executeInstruction(instruction, settings) + movescript.executeInstruction(instruction, settings) end end