Page 1 of 1
Parsing string to math (loadstring)
Posted: Thu Nov 20, 2014 1:14 pm
by PartyCow
Hello.
I'm making a program/game that needs to convert a string input (mathematical function, ex. sin(x)+2).
Looking around I found the function eval, which converts string to function. This found to be exsistent in lua aswell named loadstring.
Although trying to run code, it doesn't convert string to math properly.
Code
Code: Select all
o = 0
cmd = loadstring("o = sin(4)")
love.window.setTitle(o)
Sets the title to 0 rather than whateverthehell sin(4) is.
Help appcreiated.
Thanks
Re: Parsing string to math (loadstring)
Posted: Thu Nov 20, 2014 1:59 pm
by zorg
I think you want this (untested, sorry):
Code: Select all
o = 0
cmd = loadstring("o = sin(4)") -- returns a _function_
cmd() -- call that function
love.window.setTitle(o)
or even better:
Code: Select all
f = "sin(4)"
love.window.setTitle(loadstring("return " .. f)) -- put a () after f) to actually call the loaded string
though not if you want to set it every frame... that would probably be "slow as hell".
Re: Parsing string to math (loadstring)
Posted: Thu Nov 20, 2014 8:57 pm
by PartyCow
zorg wrote:I think you want this (untested, sorry):
Code: Select all
o = 0
cmd = loadstring("o = sin(4)") -- returns a _function_
cmd() -- call that function
love.window.setTitle(o)
or even better:
Code: Select all
f = "sin(4)"
love.window.setTitle(loadstring("return " .. f))
though not if you want to set it every frame... that would probably be "slow as hell".
Works, thanks.
I now realize I managed to oversee it whoops.
Re: Parsing string to math (loadstring)
Posted: Fri Nov 21, 2014 2:22 am
by Positive07
zorg wrote:I think you want this (untested, sorry):
Code: Select all
o = 0
cmd = loadstring("o = sin(4)") -- returns a _function_
cmd() -- call that function
love.window.setTitle(o)
or even better:
Code: Select all
f = "sin(4)"
love.window.setTitle(loadstring("return " .. f))
though not if you want to set it every frame... that would probably be "slow as hell".
You said something in the first code but didnt do it in the second one haha
Code: Select all
f = "sin(4)"
love.window.setTitle(loadstring("return " .. f)())
Also if the text comes from user input then you should do a couple of things:
- If there is an error in the code the user wrote, then it shouldn't spread to your code, or else your game will crash, to do this you can use pcall:
Code: Select all
userinput = "math.sin(4); return 'a'"
func = loadstring(userinput)
ok,msg = pcall(func) --This call func, and returns true if there was no error or false if there was
if ok then --The code ran fine
if msg then
print(msg) --Prints "a"
end
else --Oops it crashed
print(msg) --ERROR Bla bla bla
end
- You dont want the user to execute dangerous code, for example if the user inputs:
Then your game wont act properly at all. To maintain the user away from your functions you can use setfenv:
Code: Select all
env = {math = math, string = string}
userinput = "love = {graphics = "a"}"
func = loadstring(userinput)
ok,msg = pcall(func)
print(love.graphics)--table 0x....
if ok then
if msg then
print(env.love.graphics) --Prints "a"
end
else
print(msg)
end
NOTE: If you want the user to use a function you have, then you should put it in the environment as I did above with math and string but this could be dangerous too, since you are just referencing a table, then if the user did this
Code: Select all
math.floor = function () return 200 end
math.floor wont do what you expect it to do, to allow the user to use math.floor while not allowing to change the behavior of YOURS math.floor you have to deep copy the math table
Code: Select all
env = {math = deepcopy(math), string = deepcopy(string)}
There are many deepcopy scripts here in the forum (Robin made an amazing one) so make a search and you'll find one
EDIT:
zorg wrote:Though you did make a minor typographical mistake: wrote "loadsting" instead of loadstring in one of your code blocks.
Thanks zorg, fixed the error
Re: Parsing string to math (loadstring)
Posted: Fri Nov 21, 2014 5:26 am
by zorg
Positive07 wrote:-snip-
Haha, you're right, i did forgot the (), my bad!
Though you did make a minor typographical mistake: wrote "loadsting" instead of loadstring in one of your code blocks.