This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
lifewcody's profile picture

Command based table

Started by lifewcody, 19 June 2015 - 01:26 AM
lifewcody #1
Posted 19 June 2015 - 03:26 AM
I know the title is a little weird but I don't know how to explain this.

In the program the user types in a command (service stop test)

In the table I have:


{
  [ "service" ] = {
    [ "stop" ] = function(args)
	  print(args)
    end,
  },
}

What I need to do is to look through the table and see that "service" is a table and to check if stop is there. If stop is there and is a function, run it with the argument "test". I also need it to do it for (lets say) 100 tables before it gets to the actual function.

Any help is appreciated, I have redone the code multiple times and I am out of ideas.
Bomb Bloke #2
Posted 19 June 2015 - 03:51 AM
Well, let's say the user types in "service stop test" - we want to examine that one word at a time, so we might use string.gmatch to iterate through the words and dump them into separate indexes of a table:

local command = "service stop test"

local words = {}
for word in command:gmatch("%S+") do words[#words + 1] = word end

-- words[1] == "service"
-- words[2] == "stop"
-- words[3] == "test"

Now we can use that new table to help us iterate through your original table:

local commands = {
  [ "service" ] = {
    [ "stop" ] = function(...)
          print(...)
    end,
  },
}

local curIndex = commands  -- Set curIndex to the pointer to the "commands" table.
for i = 1, #words do
	if type(curIndex[words[i]]) == "table" then
		curIndex = curIndex[words[i]]  -- Shift curIndex to point to the sub-table we found.
		
	elseif type(curIndex[words[i]]) == "function" then
		curIndex[words[i]](unpack(words, i + 1))  -- Run the function, supplying the remaining words as arguments.
		break

	else error("Word not in commands table!") end
end
lifewcody #3
Posted 19 June 2015 - 03:59 AM
Well, let's say the user types in "service stop test" - we want to examine that one word at a time, so we might use string.gmatch to iterate through the words and dump them into separate indexes of a table:

local command = "service stop test"

local words = {}
for word in command:gmatch("%S+") do words[#words + 1] = word end

-- words[1] == "service"
-- words[2] == "stop"
-- words[3] == "test"

Now we can use that new table to help us iterate through your original table:

local commands = {
  [ "service" ] = {
	[ "stop" ] = function(...)
		  print(...)
	end,
  },
}

local curIndex = commands  -- Set curIndex to the pointer to the "commands" table.
for i = 1, #words do
	if type(curIndex[words[i]]) == "table" then
		curIndex = curIndex[words[i]]  -- Shift curIndex to point to the sub-table we found.
		
	elseif type(curIndex[words[i]]) == "function" then
		curIndex[words[i]](unpack(words, i + 1))  -- Run the function, supplying the remaining words as arguments.
		break

	else error("Word not in commands table!") end
end

You are the bomb (pun intended)

I had something along the lines of what you had but I didn't shift while it was looking through it.

Thank you so much!!!!

Edit: So I overcame that problem, now I need to combine files that have tables in them as so:

file1:

[ "test" ] = {
  [ "command" ] = function()
    print("Test command good")
  end,
}

file2:

[ "hey" ] = {
  [ "there" ] = function()
    print("hey there partner!")
  end,
}

final result:

{
  [ "test" ] = {
    [ "command" ] = function()
      print("Test command good")
    end,
  },
  [ "hey" ] = {
    [ "there" ] = function()
      print("hey there partner!")
    end,
  },
}

Right now I have this code:


local cDir = fs.combine(dir, 'test')
  local commandList = fs.list(cDir)
  for k, v in pairs(commandList) do
 
    local h = fs.open(fs.combine(cDir, v), 'r')
    local contents = h.readAll()
    h.close()
   
    commands[v] = contents
	   
  end

but this wouldn't work if the file name was changed.
Edited on 19 June 2015 - 02:33 AM