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

Learning lua (Thread formerly: Help resolving lua VM error)

Started by L5132, 16 May 2012 - 09:26 PM
L5132 #1
Posted 16 May 2012 - 11:26 PM
Spoiler

function setDoorColorGroup()
colors.combine(doors)
end
function SetTableUnlock()
t = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
end
function setTableLock()
t = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
end
function preparePrint()
term.clear()
term.setCursorPos(1,1)
print("L-tech Door Control System v2.0")
print("U = Unlocked, L = Locked")
print(" ")
print("#  State")
end
function checkDoor1()
if t[1] == 1
then colors.combine(doors, colors.white)
print("1  U")
else colors.subtract(doors, colors.white)
print("1  L)")
end
end
function checkDoor2()
if t[2] == 1
then colors.combine(doors, colors.orange)
print("2  U")
else colors.subtract(doors, colors.orange)
print("2  L")
end
end
function checkDoor3()
if t[3] == 1
then colors.combine(doors, colors.magenta)
print("3  U")
else colors.subtract(doors, colors.magenta)
print("3  L")
end
end
function checkDoor4()
if t[4] == 1
then colors.combine(doors, colors.lightBlue)
print("4  U")
else colors.subtract(doors, colors.lightBlue)
print("4  L")
end
end
function checkDoor5()
if t[5] == 1
then colors.combine(doors, colors.yellow)
print("5  U")
else colors.subtract(doors, colors.yellow)
print("5  L")
end
end
function checkDoor6()
if t[6] == 1
then colors.combine(doors, colors.lime)
print("6  U")
else colors.subtract(doors, colors.lime)
print("6  L")
end
end
function checkDoor7()
if t[7] == 1
then colors.combine(doors, colors.pink)
print("7  U")
else colors.subtract(doors, colors.pink)
print("7  L")
end
end
function checkDoor8()
if t[8] == 1
then colors.combine(doors, colors.gray)
print("8  U")
else colors.subtract(doors, colors.gray)
print("8  L")
end
end
function checkDoor9()
if t[9] == 1
then colors.combine(doors, colors.lightGray)
print("9  U")
else colors.subtract(doors, colors.lightGray)
print("9  L")
end
end
function checkDoor10()
if t[10] == 1
then colors.combine(doors, colors.cyan)
print("10 U")
else colors.subtract(doors, colors.cyan)
print("10 L")
end
end
function checkDoor11()
if t[11] == 1
then colors.combine(doors, colors.purple)
print("11 U")
else colors.subtract(doors, colors.purple)
print("11 L")
end
end
function checkDoor12()
if t[12] == 1
then colors.combine(doors, colors.blue)
print("12 U")
else colors.subtract(doors, colors.blue)
print("12 L")
end
end
function checkDoor13()
if t[13] == 1
then colors.combine(doors, colors.brown)
print("13 U")
else colors.subtract(doors, colors.brown)
print("13 L")
end
end
function checkDoor14()
if t[14] == 1
then colors.combine(doors, colors.green)
print("14 U")
else colors.subtract(doors, colors.green)
print("14 L")
end
end
function checkDoor15()
if t[15] == 1
then colors.combine(doors, colors.red)
print("15 U")
else colors.subtract(doors, colors.red)
print("15 L")
end
end
function checkDoor16()
if t[16] == 1
then colors.combine(doors, colors.black)
print("16 U")
else colors.subtract(doors, colors.black)
print("16 L")
end
end
function runDoorCheck()
preparePrint()
checkDoor1()
checkDoor2()
checkDoor3()
checkDoor4()
checkDoor5()
checkDoor6()
checkDoor7()
checkDoor8()
checkDoor9()
checkDoor10()
checkDoor11()
checkDoor12()
checkDoor13()
checkDoor14()
checkDoor15()
checkDoor16()
changeDoor()
end
function changeDoor()
i = read
if i == lock then
  c = t[i]+1
  setTableLock()
   changeDoor()
elseif input == unlock then
  t = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
  changeDoor()
elseif i == refresh then
  runDoorCheck()
elseif i == 1 or 2 or 3 or 4 or 5 or 6 or 7 or 8 or 9 or 10 or 11 or 12 or 13 or 14 or 15 or 16 then
  table.insert(t,i,c)
   if t[i] >= 2 then
	table.insert(t,i,0)
	 runDoorCheck()
   else
	runDoorCheck()
end
else print("Command Not Recognized")
  changeDoor()
end
end
function startup()
setDoorColorGroup()
SetTableUnlock()
runDoorCheck()
end
startup()
This code I wrote is throwing the error " doorlock2:176: vm error:
java.lang.ArrayIndexOutOfBoundsException: 256"
I would like help from people who have been working with this longer than I have to resolve it. I am running CC on minecraft 1.1 as of now since I have been running a Tekkit server since it's easier for my friends (Read: noobs) to join. Otherwise, I would not be using it, as I don't want or need a lot of what they threw in.

Anyways, the program is intended to use bundled cable on the back of the computer to control all 16 colors of insulated wire to some redpower AND gates which would open iron doors only if the computer is sending a signal and the button by the door is pressed. I would also probably switch to a password protected computer for the second signal at some point.
I've written a few other programs but this is the first time I've used tables to store variables, so if you could also help with the coding I would appreciate it.
I've been using Notepad++ to code it, its definitely much easier than the in game editor :P/>/>
Also, I have been looking into it with various searches and didn't come up with much, however I am fairly sure it is simply an error with how I coded something. Thanks, L5132
Cloudy #2
Posted 16 May 2012 - 11:33 PM
The issue is, you are running the changeDoor() function within changeDoor() - and you may be doing that fast, filling the Lua stack of functions over its limit.

Try refactoring the code so that you don't have to run changeDoor() inside changeDoor().
L5132 #3
Posted 16 May 2012 - 11:42 PM
Ah, I see where I messed up. I was going to include sleep functions, would that prevent this as well?
MysticT #4
Posted 16 May 2012 - 11:44 PM
No, using sleep wouldn't prevent that error. You need to use a loop instead of recursive functions (functions calling themselves).
So, instead of doing something like:

local function doSomething()
  -- do stuff
  doSomething()
end
You should do:

local function doSomething()
  while true do
    -- do stuff
  end
end
L5132 #5
Posted 17 May 2012 - 12:04 AM
Spoiler
function setDoorColorGroup()
colors.combine(doors)
end
function SetTableUnlock()
t = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
end
function setTableLock()
t = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
end
function preparePrint()
term.clear()
term.setCursorPos(1,1)
print("L-tech Door Control System v2.0")
print("U = Unlocked, L = Locked")
print(" ")
print("#  State")
end
function checkDoor1()
if t[1] == 1
then colors.combine(doors, colors.white)
print("1  U")
else colors.subtract(doors, colors.white)
print("1  L)")
end
end
function checkDoor2()
if t[2] == 1
then colors.combine(doors, colors.orange)
print("2  U")
else colors.subtract(doors, colors.orange)
print("2  L")
end
end
function checkDoor3()
if t[3] == 1 
then colors.combine(doors, colors.magenta)
print("3  U")
else colors.subtract(doors, colors.magenta)
print("3  L")
end
end
function checkDoor4()
if t[4] == 1 
then colors.combine(doors, colors.lightBlue)
print("4  U")
else colors.subtract(doors, colors.lightBlue)
print("4  L")
end
end
function checkDoor5()
if t[5] == 1 
then colors.combine(doors, colors.yellow)
print("5  U")
else colors.subtract(doors, colors.yellow)
print("5  L")
end
end
function checkDoor6()
if t[6] == 1 
then colors.combine(doors, colors.lime)
print("6  U")
else colors.subtract(doors, colors.lime)
print("6  L")
end
end
function checkDoor7()
if t[7] == 1 
then colors.combine(doors, colors.pink)
print("7  U")
else colors.subtract(doors, colors.pink)
print("7  L")
end
end
function checkDoor8()
if t[8] == 1 
then colors.combine(doors, colors.gray)
print("8  U")
else colors.subtract(doors, colors.gray)
print("8  L")
end
end
function checkDoor9()
if t[9] == 1 
then colors.combine(doors, colors.lightGray)
print("9  U")
else colors.subtract(doors, colors.lightGray)
print("9  L")
end
end
function checkDoor10()
if t[10] == 1 
then colors.combine(doors, colors.cyan)
print("10 U")
else colors.subtract(doors, colors.cyan)
print("10 L")
end
end
function checkDoor11()
if t[11] == 1 
then colors.combine(doors, colors.purple)
print("11 U")
else colors.subtract(doors, colors.purple)
print("11 L")
end
end
function checkDoor12()
if t[12] == 1 
then colors.combine(doors, colors.blue)
print("12 U")
else colors.subtract(doors, colors.blue)
print("12 L")
end
end
function checkDoor13()
if t[13] == 1 
then colors.combine(doors, colors.brown)
print("13 U")
else colors.subtract(doors, colors.brown)
print("13 L")
end
end
function checkDoor14()
if t[14] == 1 
then colors.combine(doors, colors.green)
print("14 U")
else colors.subtract(doors, colors.green)
print("14 L")
end
end
function checkDoor15()
if t[15] == 1 
then colors.combine(doors, colors.red)
print("15 U")
else colors.subtract(doors, colors.red)
print("15 L")
end
end
function checkDoor16()
if t[16] == 1 
then colors.combine(doors, colors.black)
print("16 U")
else colors.subtract(doors, colors.black)
print("16 L")
end
end
function runDoorCheck()
preparePrint()
checkDoor1()
checkDoor2()
checkDoor3()
checkDoor4()
checkDoor5()
checkDoor6()
checkDoor7()
checkDoor8()
checkDoor9()
checkDoor10()
checkDoor11()
checkDoor12()
checkDoor13()
checkDoor14()
checkDoor15()
checkDoor16()
doorControlLoop()
end
function changeDoor()
i = read
if i == lock then
c = t[i]+1
t = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
elseif i == unlock then
t = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
elseif i == refresh then
runDoorCheck()
elseif i == 1 or 2 or 3 or 4 or 5 or 6 or 7 or 8 or 9 or 10 or 11 or 12 or 13 or 14 or 15 or 16 then 
table.insert(t,i,c)
if t[i] >= 2 then 
table.insert(t,i,0)
runDoorCheck()
else
runDoorCheck() 
end 
else print("Command Not Recognized")
end 
end
function doorControlLoop()
while true do 
changeDoor()
end
end
function startup()
setDoorColorGroup()
SetTableUnlock()
doorControlLoop()
end
startup()
So I revised the code, and it has also solved my original question. However, I am now encountering an error the previous error had convinced me I had solved :P/>/>
This is that on line 176, in the changeDoor() function, specifically in table.insert() I am using two variables to edit the table with the updated values, hopefully causing it to pull the new states for the redwire. However this appears to be something that is not allowed, and I would like to ask for help with that as well, thanks!
Cloudy #6
Posted 17 May 2012 - 12:38 AM
What is the exact error you are getting?

Also, I'd like to point out that this line of code
elseif i == 1 or 2 or 3 or 4 or 5 or 6 or 7 or 8 or 9 or 10 or 11 or 12 or 13 or 14 or 15 or 16 then
won't do what you think it will - it will check if i = 1, and if those numbers exist - which they of course do - so it will always return true. You will be much better doing this:
elseif i >= 1 and i <= 16 then
L5132 #7
Posted 17 May 2012 - 01:05 AM
What is the exact error you are getting?

Also, I'd like to point out that this line of code
elseif i == 1 or 2 or 3 or 4 or 5 or 6 or 7 or 8 or 9 or 10 or 11 or 12 or 13 or 14 or 15 or 16 then
won't do what you think it will - it will check if i = 1, and if those numbers exist - which they of course do - so it will always return true. You will be much better doing this:
elseif i &amp;gt;= 1 and i &amp;lt;= 16 then
Ah, sorry about that. I am getting the error " doorlock:176: bad argument: number expected, got function "
And as to you pointing out the numbers, I had been doing what you suggested, but it threw an error, I will try it again, however. I take it that that would essentially cripple the program since it would always default to that option? Thanks for helping so quickly!

EDIT: I just edited the file and ran it, the exact error I am getting on line 175 where I changed the list of numbers to "i &amp;gt;= 1 and i &amp;lt;=16" and it is throwing the error
"doorlock:175: attempt to compare function with number"
EDIT2: I also realized what that error meant and corrected it, now I think I may be on my way to fixing this thing.
MysticT #8
Posted 17 May 2012 - 01:12 AM
I think you forgot the quotes for the strings and the parentheses for the read() call in these lines:

...
i = read -- missing ()
if i == lock then -- should be "lock" (with quotes)
c = t[i]+1
t = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
elseif i == unlock then -- again the quotes. "unlock"
t = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
elseif i == refresh then -- "refresh"
runDoorCheck()
elseif i == 1 or 2 or 3 or 4 or 5 or 6 or 7 or 8 or 9 or 10 or 11 or 12 or 13 or 14 or 15 or 16 then -- what cloudy said, and i is a string, so compare with strings or convert to number
table.insert(t,i,c) -- the if returns always true, and you assigned the function read to the variable i, that's why you get the error
if t[i] >= 2 then
table.insert(t,i,0)
runDoorCheck()
else
runDoorCheck()
end
else print("Command Not Recognized")
end
end
...
L5132 #9
Posted 17 May 2012 - 01:21 AM
I think you forgot the quotes for the strings and the parentheses for the read() call in these lines:
Spoiler

...
i = read -- missing ()
if i == lock then -- should be "lock" (with quotes)
c = t[i]+1
t = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
elseif i == unlock then -- again the quotes. "unlock"
t = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
elseif i == refresh then -- "refresh"
runDoorCheck()
elseif i == 1 or 2 or 3 or 4 or 5 or 6 or 7 or 8 or 9 or 10 or 11 or 12 or 13 or 14 or 15 or 16 then -- what cloudy said, and i is a string, so compare with strings or convert to number
table.insert(t,i,c) -- the if returns always true, and you assigned the function read to the variable i, that's why you get the error
if t[i] >= 2 then
table.insert(t,i,0)
runDoorCheck()
else
runDoorCheck()
end
else print("Command Not Recognized")
end
end
...
Yep, that's what I had done, and I also went back to using some of the functions at the top of the program instead of independently setting the table down below now.
And as to the rest of your fixes, those are probably what caused almost all of the errors. I guess that's what comes from writing the majority of this on a netbook during the school day and not being able to test until I had reached the code in the first post, lol :P/>/>
L5132 #10
Posted 17 May 2012 - 05:00 AM
Ok, thanks for the help! I got the program working exactly as intended, the final code ended up being
Spoiler
function setDoorColorGroup()
doors = colors.combine(doors)
end
function setTableUnlock()
t = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
end
function setTableLock()
t = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
end
function preparePrint()
term.clear()
term.setCursorPos(1,1)
print("L-tech Door Control System v2.0")
print("U = Unlocked, L = Locked")
print(" ")
print("#  State")
end
function checkDoor1()
if t[1] == 1
then doors = colors.combine(doors, colors.white)
print("1  U")
else doors = colors.subtract(doors, colors.white)
print("1  L")
end
end
function checkDoor2()
if t[2] == 1
then doors = colors.combine(doors, colors.orange)
print("2  U")
else doors = colors.subtract(doors, colors.orange)
print("2  L")
end
end
function checkDoor3()
if t[3] == 1 
then doors = colors.combine(doors, colors.magenta)
print("3  U")
else doors = colors.subtract(doors, colors.magenta)
print("3  L")
end
end
function checkDoor4()
if t[4] == 1 
then doors = colors.combine(doors, colors.lightBlue)
print("4  U")
else doors = colors.subtract(doors, colors.lightBlue)
print("4  L")
end
end
function checkDoor5()
if t[5] == 1 
then doors = colors.combine(doors, colors.yellow)
print("5  U")
else doors = colors.subtract(doors, colors.yellow)
print("5  L")
end
end
function checkDoor6()
if t[6] == 1 
then doors = colors.combine(doors, colors.lime)
print("6  U")
else doors = colors.subtract(doors, colors.lime)
print("6  L")
end
end
function checkDoor7()
if t[7] == 1 
then doors = colors.combine(doors, colors.pink)
print("7  U")
else doors = colors.subtract(doors, colors.pink)
print("7  L")
end
end
function checkDoor8()
if t[8] == 1 
then doors = colors.combine(doors, colors.gray)
print("8  U")
else doors = colors.subtract(doors, colors.gray)
print("8  L")
end
end
function checkDoor9()
if t[9] == 1 
then doors = colors.combine(doors, colors.lightGray)
print("9  U")
else doors = colors.subtract(doors, colors.lightGray)
print("9  L")
end
end
function checkDoor10()
if t[10] == 1 
then doors = colors.combine(doors, colors.cyan)
print("10 U")
else doors = colors.subtract(doors, colors.cyan)
print("10 L")
end
end
function checkDoor11()
if t[11] == 1 
then doors = colors.combine(doors, colors.purple)
print("11 U")
else doors = colors.subtract(doors, colors.purple)
print("11 L")
end
end
function checkDoor12()
if t[12] == 1 
then doors = colors.combine(doors, colors.blue)
print("12 U")
else doors = colors.subtract(doors, colors.blue)
print("12 L")
end
end
function checkDoor13()
if t[13] == 1 
then doors = colors.combine(doors, colors.brown)
print("13 U")
else doors = colors.subtract(doors, colors.brown)
print("13 L")
end
end
function checkDoor14()
if t[14] == 1 
then doors = colors.combine(doors, colors.green)
print("14 U")
else doors = colors.subtract(doors, colors.green)
print("14 L")
end
end
function checkDoor15()
if t[15] == 1 
then doors = colors.combine(doors, colors.red)
print("15 U")
else doors = colors.subtract(doors, colors.red)
print("15 L")
end
end
function checkDoor16()
if t[16] == 1 
then doors = colors.combine(doors, colors.black)
print("16 U")
else doors = colors.subtract(doors, colors.black)
print("16 L")
end
end
function runDoorCheck()
preparePrint()
checkDoor1()
checkDoor2()
checkDoor3()
checkDoor4()
checkDoor5()
checkDoor6()
checkDoor7()
checkDoor8()
checkDoor9()
checkDoor10()
checkDoor11()
checkDoor12()
checkDoor13()
checkDoor14()
checkDoor15()
checkDoor16()
sleep(.001)
redstone.setBundledOutput("back", doors)
doorControlLoop()
end
function DoorCheck()
preparePrint()
checkDoor1()
checkDoor2()
checkDoor3()
checkDoor4()
checkDoor5()
checkDoor6()
checkDoor7()
checkDoor8()
checkDoor9()
checkDoor10()
checkDoor11()
checkDoor12()
checkDoor13()
checkDoor14()
checkDoor15()
checkDoor16()
sleep(.001)
redstone.setBundledOutput("back", doors)
end
function changeDoor()
i = io.read()
checki()
checkIf2()
if i == "lock" then
setTableLock()
elseif i == "unlock" then
setTableUnlock()
elseif i == "refresh" then
DoorCheck()
else 
end 
end 
function doorControlLoop()
while true do 
changeDoor()
sleep(0)
runDoorCheck()
end
end
function checki()
if i == "1" then
t[1] = t[1]+1
elseif i == "2" then
t[2] = t[2]+1
elseif i == "3" then
t[3] = t[3]+1
elseif i == "4" then
t[4] = t[4]+1
elseif i == "5" then
t[5] = t[5]+1
elseif i == "6" then 
t[6] = t[6]+1
elseif i == "7" then
t[7] = t[7]+1
elseif i == "8" then
t[8] = t[8]+1
elseif i == "9" then
t[9] = t[9]+1
elseif i == "10" then
t[10] = t[10]+1
elseif i == "11" then
t[11] = t[11]+1
elseif i == "12" then
t[12] = t[12]+1
elseif i == "13" then
t[13] = t[13]+1
elseif i == "14" then
t[14] = t[14]+1
elseif i == "15" then
t[15] = t[15]+1
elseif i == "16" then
t[16] = t[16]+1
end
end
function checkIf2()
if t[1] >= 2 then
t[1] = 0
elseif t[2] >= 2 then 
t[2] = 0
elseif t[3] >= 2 then 
t[3] = 0
elseif t[4] >= 2 then 
t[4] = 0
elseif t[5] >= 2 then 
t[5] = 0
elseif t[6] >= 2 then 
t[6] = 0
elseif t[7] >= 2 then 
t[7] = 0
elseif t[8] >= 2 then 
t[8] = 0
elseif t[9] >= 2 then 
t[9] = 0
elseif t[10] >= 2 then 
t[10] = 0
elseif t[11] >= 2 then 
t[11] = 0
elseif t[12] >= 2 then 
t[12] = 0
elseif t[13] >= 2 then 
t[13] = 0
elseif t[14] >= 2 then 
t[14] = 0
elseif t[15] >= 2 then 
t[15] = 0
elseif t[16] >= 2 then 
t[16] = 0
end
end
function startup()
setDoorColorGroup()
setTableUnlock()
runDoorCheck()
end
startup()
As you may have noticed, being new to programming I called a ton of functions that I am sure I could have avoided with a little thought, I am wondering if I did alright at programming this. To test if it was functioning correctly, I was using bundled cable on the back splitting to each of the 16 colors of insulated wire with the corresponding colored lamp attached to give a visual for how it was working.
*cringes at self for double posting*
Cloudy #11
Posted 17 May 2012 - 12:28 PM
Hey, as far as I've concerned, if your code works you've succeeded. However, I think you under use tables. For instance, checkDoor could have been made into one function with a table defined containing the door colour. When you'd pass an argument to checkDoor it would check the correct door.

Also, checki checks each value in a table, where you could use the pairs or ipairs iterator to do it in a loop, instead of checking each value in the table manually.

Food for thought for future learning :P/>/>
L5132 #12
Posted 17 May 2012 - 06:10 PM
Hey, as far as I've concerned, if your code works you've succeeded. However, I think you under use tables. For instance, checkDoor could have been made into one function with a table defined containing the door colour. When you'd pass an argument to checkDoor it would check the correct door.

Also, checki checks each value in a table, where you could use the pairs or ipairs iterator to do it in a loop, instead of checking each value in the table manually.

Food for thought for future learning :P/>/>
Thanks for the advice. I am actually writing this program in anticipation of needing it soon, although I currently do not. Seeing as I essentially wrote this to learn how to use tables in the first place I am going to take your advice and try to use tables and otherwise condense the program. I am not sure if I mentioned this but lua is the first programming language I have tried to learn and so far I find it rather nice and fairly easy to understand now that I realize what some of the errors mean. If it's alright I think I will keep this thread open to updates if I need help with anything. Also, I changed the thread title since I figured that was probably making my issues seem more serious than they are. I really do appreciate the help you guys are giving me, and if there's anything in particular you think I should check out feel free to mention it.