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

'then' expected near 'break' error with os.loadAPI

Started by digitalEntity, 13 December 2014 - 11:10 PM
digitalEntity #1
Posted 14 December 2014 - 12:10 AM
So… it's been a long time since I've posted anything on here, and I only recently became interested in programming again.

I'm working on making an API with 2 functions in it. One takes alphanumeric input, and compiles all the characters into a single number. The other takes numeric input and "decompiles" it into the important pieces of the number, translates each number piece (separately) back into an alphanumeric, and "recompiles" it into the original alphanumeric input.

The API itself is completed, but hasn't been bug-tested… so I tried to os.loadAPI it, and it… obviously returned an error… The error is as follows, and I'll put the pastebin link after it

[string "bobtheapi"]:34: cannot use '…' outside a vararg function near '…'

http://pastebin.com/86qpSBYx

Please ignore the "print()" at the end of the Decode() function… I'm going to change that to a "return()" as soon as I have all the API loading kinks hammered out.

P.S. I know this doesn't exactly need to be said, but once we (the members who help, and myself) get this functioning, anyone can feel free to use my code for themselves… and at this point… I don't even care if you give me credit or not…
wieselkatze #2
Posted 14 December 2014 - 12:34 AM
Hi digitalEntity,

your problem is, that … is defined locally for that function. That means, that … is not available until you declare it in the function definition like so:


local function Decode( ... )
  local yourArgs = { ... }
  --# bla bla
end

Also in your pastebin code there is an end missing at the end of the code.
If you want to pass the parameters which are entered when starting the program, e.g. "yourprogram a b c" you would have to use


Decode( ... )

The former passed parameters then get 'inserted' from the shell in the function parameters. Thus getting passed into you local … variable in your function.
Edited on 13 December 2014 - 11:35 PM
digitalEntity #3
Posted 14 December 2014 - 12:38 AM
Hrmmm… ok… well I added the argument dots in the function parentheses, and the missing 'end' to close the function, but now it returns another error.

[string "bobtheapi"]:44: unexpected symbol near '['

On this one, I've got ABSOLUTELY no ideas… sorry…
Edited on 13 December 2014 - 11:41 PM
wieselkatze #4
Posted 14 December 2014 - 12:43 AM
That is, because you haven't defined key yet. You have to define and initialize a table before you can actually use it.
That means, that you have to put


local key = {}

at the top of your function.

Also I'm not really sure if you actually want this


local input = {...}
local sInput = tostring(input)

This wouldn't return the content of the table, but the 'ID' of the table. That means that sInput would e.g. be "table: 2fdg3ka7".
I think you would actually want a defined variable in your function, like so:



local function Decode( toDecode )
  if #toDecode > 2 then
    --# bla bla
  end
end

With that you could call bobtheapi.Decode( "hello world" ) and "hello world" would get passed directly to your loop. You would, of course if you use the variable name toDecode, change your code to use that variable name.
Edited on 13 December 2014 - 11:47 PM
Bomb Bloke #5
Posted 14 December 2014 - 12:45 AM
Also bear in mind that you can't define entries inside a table as "local".

If you're still having problems, be sure to update the paste when describing them.
digitalEntity #6
Posted 14 December 2014 - 12:54 AM
Huh… I thought the local key = string.sub(sInput, focus1, focus2) WAS defining the table… didn't know better I guess ;P.

But this also means that I'll likely get the same error from the nKey and char tables.

and also, wiesel, the only arguments that are supposed to be coming into the Decode function are supposed to be a single number, but maybe I should change that line to "local sInput = tostring(input[1])" just in case.

and since I can't edit the pastebin file (it was posted straight from a CC emulator I have, and therefore is "posted by a guest"), I'll post another copy under an actualy user, with the changes included. I'll edit this with the link when I've finished that.

link: http://pastebin.com/scNCH8Ak
Edited on 14 December 2014 - 12:04 AM
wieselkatze #7
Posted 14 December 2014 - 12:59 AM
Even if it's a number, it would definitely be better to use a fixed variable like toDecode - that way you won't have that unnecessary collecting and combining of arguments that, either way, are going to be just one number anyway.
Just smash your tostring() on that variable and your good to go ;)/>

Sample:


local function Decode( toDecode )
  local sInput, key, nKey, char = tostring( toDecode ), {}, {}, {}
  if #sInput >2 then
	local count = (#sInput - 1)/2
	
	for i = 1, count do
	  key[i] = string.sub(sInput, #sInput-1, #sInput)
	  nKey[i] = tonumber(key[i])
	  toDecode = (toDecode - nKey[i])/100
	  sInput = tostring( toDecode )
	end
	for i = 1, count do
	  char[i] = key.getName(key[i])
	end
	x = char[#char]
	for i, #char-1 do
	  x = x.. char[#char-i]
	end
	print(x)
  end
end

Don't know if that's working - I didn't go thorugh the logic of that function.
Also by looking at that, I noticed that key.getName(key) would result in an attempt to call nil error - even if you defined that function before. That is, because local key = {} overrides that function. And as there isn't a getName() function in key, that would error out
Edited on 14 December 2014 - 12:07 AM
digitalEntity #8
Posted 14 December 2014 - 01:06 AM
added the link to my above post. Now I've managed to wind up with a new error…

[string "bobtheapi"]:56: '<name>' expected near '#'
wieselkatze #9
Posted 14 December 2014 - 01:09 AM
That's, because you've written the loop the wrong way. Use


for i = 1, #char-1 do --# Or 0 or whatever

instead of this


for i, #char-1 do
Edited on 14 December 2014 - 12:12 AM
Dog #10
Posted 14 December 2014 - 01:19 AM
Huh… I thought the local key = string.sub(sInput, focus1, focus2) WAS defining the table…
For future reference…typically, you localize a variable when you declare it, then use it; like so…

local key = { } --# declare the variable and make it local (in this case also assign it to a blank table)
... --# other code
key[i] = string.sub(sInput, focus1, focus2)
... --# more code
In your case wieselkatze already fixed that for you in the code a couple posts above.
Edited on 14 December 2014 - 12:20 AM
digitalEntity #11
Posted 14 December 2014 - 01:33 AM
ok. so, the i = 1 thing worked, (I had copied that portion off my phone app earlier, and I had completely missed the =1 bit lol… anywho… with a few other tweaks (listed below) it's made it into the API loading stage, and now I'm just trying to fix other bugs lol…

removed the 'local' tag from the functions themselves. Was: <local function Encode()> now: <function Encode()>
wasn't able to call the functions from the Lua command line.

changed <function Decode(…) | local input = {…}> to <function Decode(input) | local nInput = tonumber(input[1])
there was an error of the "doing arithmetic on a table" sort, and I figured I'd add the tonumber because I've been consistently unsure as to whether or not input[1] would actually come out as a number or a string, so I figured I'd prep for either eventuality and just make make it both with the nInput and sInput vars

changed previous mentions of variable "input" to "nInput" where needed

will edit based on new results. pastebin edited with above changes.

Edit: errored at the <nInput = tonumber(input[1])> line, :34: attempt to index local 'input' (a number value)
removed the tonumber around it, no effect, changed it back…
Edited on 14 December 2014 - 12:37 AM
Bomb Bloke #12
Posted 14 December 2014 - 01:42 AM
You're trying to index into the "input" variable as though it were a table. It's not a table, it's a number.
digitalEntity #13
Posted 14 December 2014 - 01:44 AM
but don't arguments always produce a table? or does that change if a) there's only 1 argument and/or B)/> you directly make the arguments into a variable?

edit: well I guess not, I removed the [1] from all mentions if input, and it fixed THAT error, but now it's giving me :53: attempt to index global 'key' (a nil value)

I think that's a throwback to what wiesel was saying earlier, that I need to change the name of table 'key' because it would cause some errors with the original key API
Edited on 14 December 2014 - 12:48 AM
valithor #14
Posted 14 December 2014 - 03:01 AM
-snip

Posting from phone sorry if it is hard to read.

I can not see where you are actually ever defining the key table, and on line 53 you are attempting to use the sKey table, which is localized to the for loop above it.

When you define something as local that variable can only be used in the current code block and any that come from it. So those variables in the for loop beginning at line 39 exist only in that loop, and because of that can not be used any where else.

On line 48 and 49 you redefine both of those variables as local to that loop. It is generally a good idea to only define a variable with local in front of it once.

What Wiesel was actually saying was that you are attempting to use key.getName as a function, but it does not exist. Also in his example he defined key as a table, which would overwrite the function (if it even existed). I might be mistaken but I do not think there is actually a "key" API. I am pretty sure it is "keys"

As I said sorry if it is hard to understand writing this on my phone.

Edit: you are using key.getName while the API is keys. Use keys.getName instead.
Edit2: this was based on the code at http://pastebin.com/scNCH8Ak
Edited on 14 December 2014 - 02:07 AM
digitalEntity #15
Posted 14 December 2014 - 03:22 AM
the writing was fine (but the quote didn't go through as you might've hoped). And you guys were right. the function key.getName doesn't exist, because I misspelled the name of the api… it's keys.getName… yes I know… all I did was miss an s lol…

technically, the api is working… when I load it, I get no errors. When I attempt to translate a number into alphanumerics, I TECHNICALLY get no errors… but it turns out that the 'char' table has been populated with nil values… and that's not what's supposed to happen…

Edit: at the end of it, I made it print the following variables, in this order:
key[1]
nKey[1]
nInput
sInput
char[1]
x

the results were as follows
nil
nil
1
1
nil
nil

Edit 2: Holy crap, the fails are phenomenal… the problem was that the tables 'key', 'nKey', and 'char' were constantly being reset to blank, because they were declared as a blank table WITHIN the for loops, and therefore, every iteration of the for loop, they emptied themselves… I feel so stupid now… It's working fine now… now I just need to edit some parts of an existing API so that the resulting password comes out as 1a2b3, rather than oneatwobthree…
Edited on 14 December 2014 - 12:47 PM
digitalEntity #16
Posted 14 December 2014 - 01:53 PM
ALRIGHT GUYS!!! here's the final program link

http://pastebin.com/fiexDX2w

P.S. anybody know what would happen if I replaced some variables in the keys API? if not, I'll have to experiment for myself lol
Bomb Bloke #17
Posted 14 December 2014 - 10:26 PM
They'd be set back to their default values when the computer rebooted, but until then, any scripts which relied on those particular default values may potentially malfunction if you were to run them.

Adding values, as opposed to replacing values, would come with next to no risk. They'd still be cleared on reboot, though.
digitalEntity #18
Posted 15 December 2014 - 01:33 AM
well the variable values I'm thinking of are just strings in a table, and I'd edit it in the actual mod files, where it wouldn't change every time I rebooted.