inspection system with custom script (document)

The Lua scripting language allows you to give your plugin more advanced features.

Moderator: Plugin Moderators

User avatar
Ølsken
Former Bearbear65
Reactions:
Posts: 4979
Joined: Fri Feb 10, 2017 14:53
Plugins: Show
Version: Beta
Phone model: Samsung S10

Platform

Plugin Creator

inspection system with custom script (document)

#1

Post by Ølsken » Wed Jan 01, 2020 10:27

Hello everyone!
Today I present you with a custom inspect system with a custom script to inspect. :lua:
Note: this is not a tutorial but just a weird documentation of what you can do.
For now the script is very limited but it can be expanded much more. But for size sake there is only 1 script function (i.e. '?')
a script would look like this:

Code: Select all

"?[value]:s;" <-- make sure is inside quotes and ends with a semi-colon
?: this is the find function.
':s': this is the string type
':n': this is the number type
':k': this is the key type
':inum,:instr': is obsolete as ':n,:s' does the same function, but is also a bit buggy with getType() function.

Code: Select all

local bear = {}

local validFunctions = {"?","!","@","$","#","&"} --create valid functions
local validTypes = {":s",":n",":k",":in",":inum",":instr"}--create valid types

function bearErrors(errLocation,errType,errMesg) --creates custom errors
  return "![bearError-"..errLocation.."-"..errType.."]: "..errMesg.."\n"..debug.traceback()
end

function bear:new(...) --creates a new bear object
  local newObj = {}
  setmetatable(newObj,self)
  self.__index = self
  local contents = ...
  self.contents = contents or nil
  return newObj
end

function bear:open(index) --opens the selected bear object
  if index ~= nil then
    for key, value in pairs(self.contents) do
      if index:lower() == "all" then --if 'all' prints all key & values 
        print(key..": "..value.." ("..type(value)..")")
      elseif tonumber(index) == key then --prints the value of specific key
        print(key..": "..value.." ("..type(value)..")")
      end
    end
  end
  return self.contents
end

function checkBearSyntax(keywords) --checks the syntax of custom script
  local scriptFun, scriptValue, scriptType, scriptInnerType
  local funIsValid = false
  local typeIsValid = false
  local innerIsValid = false
  local blueprint = {} --table to store results
  for i = 1,#keywords do
    --uses regex to get components of script
    scriptFun = keywords[i]:match("([^.]+)%[") --matches characters before first [
    assert(scriptFun ~= nil, bearErrors("script","syntax","Expected script function got nil. Check bear:inspect(>fun[val]:type)."))
    scriptValue = keywords[i]:match("%[(.+)%]") --matches characters between [ and ]
    assert(scriptValue ~= nil, bearErrors("script","syntax","Expected script value got nil. Check bear:inspect(fun[>val]:type)."))
    scriptType = keywords[i]:match("%](:.+)%;") --matches characters between ] and ;
    scriptInnerType = keywords[i]:match("%]:+.+(:.+)%;") --matches characters between : and ;
    if scriptInnerType ~= nil then
      scriptType = scriptType:gsub(scriptInnerType,"")--removes script inner typr from script type
    end
    for i = 1,#validFunctions do --checks if script function is valid
      if scriptFun:lower() == validFunctions[i] then
        funIsValid = true
      end
    end
    if scriptType ~= nil then --checks if script type is valid if not equal to nil
      for i = 1,#validTypes do
        if scriptType:lower() == validTypes[i] then
          typeIsValid = true
        end
        if scriptInnerType ~= nil then --checks if script inner type is valid only if script type is valid
          if scriptInnerType:lower() == validTypes[i] then
            innerIsValid = true
          end
        else --if script inner type is nil give default state
          innerIsValid = true
          scriptInnerType = "unidentified"
        end
      end
    else --if script type is nil give default state
      typeIsValid = true
      innerIsValid = true
      scriptType = "unidentified"
      scriptInnerType = "unidentified"
    end
    --throw error is function, type or inner type is invalid
    assert(funIsValid == true, bearErrors("script","syntax","Invalid script function: '"..scriptFun.."' is not a valid function"))
    assert(typeIsValid == true, bearErrors("script","syntax","Invalid script type: '"..scriptType.."' is not a valid type"))
    assert(innerIsValid == true, bearErrors("script","syntax","Invalid script inner type: '"..scriptInnerType.."' is not a valid inner type"))
    --inserts components in table
    table.insert(blueprint,scriptFun)
    table.insert(blueprint,scriptValue)
    table.insert(blueprint,scriptType)
    table.insert(blueprint,scriptInnerType)
    --resets values for next loop
    funIsValid = false
    typeIsValid = false
    innerIsValid = false
  end
  return blueprint
end

function getType(st) --gets type of script type
  st = st:lower()
  if st == ":s" or st == "unidentified" then
    return "string"
  elseif st == ":n" then
    return "number"
  elseif st == ":k" then
    return "key"
  elseif st == ":instr" or st == ":in" then
    return "string value of key"
  elseif st == ":inum" then
    return "number value of key"
  end
end

function bear:inspect(script) --inspect bear (table)
  local keywords = {}
  for words in script:gmatch("([^%;]+%;)") do --matches a word that ends with ;
    adjustedWord = words:gsub(" ","") --removes unnecessary whitespace
    table.insert(keywords,adjustedWord)
  end
  local blueprint = checkBearSyntax(keywords)
  local results = {} --puts boolen of result of search in table
  for i = 0,#blueprint/4-1 do
    local found = false
    if blueprint[1+4*i] == "?" then -- ? means search
      if blueprint[3+4*i]:lower() == ":s" or blueprint[3+4*i]:lower() == "unidentified" then --search for string with the same value in table
        for k = 1,#self.contents do
          if tostring(blueprint[2+4*i]) == self.contents[k] then
            print("'"..blueprint[2+4*i].."'".." exits ".."(as "..getType(blueprint[3+4*i])..") at position: "..k)
            table.insert(results,true)
            found = true
          end
        end
      elseif blueprint[3+4*i]:lower() == ":n" then --search for number with the same value in table
        for k = 1,#self.contents do
          if tonumber(blueprint[2+4*i]) == self.contents[k] then
            print("'"..blueprint[2+4*i].."'".." exits ".."(as "..getType(blueprint[3+4*i])..") at position: "..k)
            table.insert(results,true)
            found = true
          end
        end
      elseif blueprint[3+4*i]:lower() == ":k" then--search for key with the same value in table
        local count = 1
        for key, value in pairs(self.contents) do
          if blueprint[2+4*i] == key and blueprint[4+4*i] == "unidentified" then --searches for key
            print("'"..blueprint[2+4*i].."'".." exits ".."(as "..getType(blueprint[3+4*i])..") at position: "..count)
            table.insert(results,true)
            found = true
          elseif tostring(blueprint[2+4*i]) == value and blueprint[4+4*i]:lower() == ":in" or blueprint[4+4*i]:lower() == ":instr" then --searches for the string value inside a key
            print("'"..blueprint[2+4*i].."'".." exits ".."(as a "..getType(blueprint[4+4*i])..") with the key of: "..key.." at position: "..count)
            table.insert(results,true)
            found = true
          elseif tonumber(blueprint[2+4*i]) == value and blueprint[4+4*i]:lower() == ":inum" then --searches for the number value inside a key
            print("'"..blueprint[2+4*i].."'".." exits ".."(as a "..getType(blueprint[4+4*i])..") value with the key of: "..key.." at position: "..count)
            table.insert(results,true)
            found = true
          end
          count = count + 1
        end
      end
    end
    if not found then --returns when no matches were found
      print("This bear does not hold the "..(getType(blueprint[4+4*i]) == "unidentified" and getType(blueprint[3+4*i]) or getType(blueprint[4+4*i]))..": '"..blueprint[2+4*i].."'")
      table.insert(results,false)
    end
  end
  return results
end

new_bear = bear:new{1,2,3,"4","5","?!","bear",fish = "salmon",amount = 3} --creates new bear and stores values inside

new_bear:open("all")
--[[ prints all values
1: 1 (number)
2: 2 (number)
3: 3 (number)
4: 4 (string)
5: 5 (string)
6: ?! (string)
7: bear (string)
fish: salmon (string)
amount: 3 (number)
--]]
new_bear:open("3")
--[[ prints value and key in 3rd postion
3: 3 (number)
--]]

new_bear:inspect("?[bear]:s; ?[3]:s; ?[4]:s; ?[fish]:k; ?[3]:k:inum;")
--[[ prints results of bear inspection
'bear' exits (as string) at position: 7
This bear does not hold the string: '3' although the bear contained the value 3 it was finding for a string of 3 that doesn't exist
'4' exits (as string) at position: 4
'fish' exits (as key) at position: 8
'3' exits (as a number value of key) value with the key of: 3 at position: 3
'3' exits (as a number value of key) value with the key of: amount at position: 9
--]]

for k, v in pairs(new_bear:inspect("?[bear]:s; ?[3]:s; ?[4]:s; ?[fish]:k; ?[3]:k:inum;")) do
  print(v)
end
--[[ prints boolen of the result above
true
false
true
true
true
true
--]]

if new_bear:inspect("?[bear]:s; ?[3]:s; ?[4]:s; ?[fish]:k; ?[3]:k:inum;")[3] == true then
  print("works!")
end
--[[ can also be used in a condition too
works!
--]]
ImageJust my opinion

Return to “Lua Scripting”