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

Turn user input to code?

Started by KidBrine, 12 April 2019 - 03:50 AM
KidBrine #1
Posted 12 April 2019 - 05:50 AM
The goal is to have something that works along the lines of

Code = read()
executeCode(Code)
but obviously that isn't how it works
I would like to know if that;s possible without writing it to a file.

EDIT I would delete this but i can't i solved the issue using loadstring()
Edited on 12 April 2019 - 04:00 AM
InDieTasten #2
Posted 12 April 2019 - 08:40 AM
You can implement executeCode like the following


function executeCode(codeAsString)
  local func, err = loadstring(codeAsString)
  if not func then error(err) else func() end
end

loadstring turns the string into a lua function (essentially parsing it), and calling the function will run the code
Edited on 12 April 2019 - 06:40 AM
GopherAtl #3
Posted 12 April 2019 - 12:50 PM
Actually throwing errors on user-entered code like that seems a bad idea, typos happen and you'll have to handle it gracefully or just have the program crash every time the user doesn't get the code they're entering perfect the first time. You'll want to use pcall() to call the function once loadstring() has done the parsing, I'd recommend something more like this:


function executeCode(codeString)
    --try to parse the string as code
    local func,err=loadstring(codeString)
    local success=false
    --did we succeed?
    if func then
   	 --have a func, safely call it and catch the result
        success,err = pcall(func)
    end

    return success,err
end

Simple use example:

while true do
    write("]")
    local succ,err=executeCode(read())
    if succ then
        print("code executed!")
    else
        print("error:"..err)
    end
end
Edited on 12 April 2019 - 10:53 AM
KidBrine #4
Posted 13 April 2019 - 01:00 AM
You can implement executeCode like the following


function executeCode(codeAsString)
  local func, err = loadstring(codeAsString)
  if not func then error(err) else func() end
end

loadstring turns the string into a lua function (essentially parsing it), and calling the function will run the code
if the user input looked something like this as a string "print('Hello')" then i could just have the code look like this essentially pcall(loadstring("Print('Hello')")())

If you had read the full post before replying you would have seen that the only reason the thread still exists is because i can't delete it myself.
Edited on 12 April 2019 - 11:01 PM
InDieTasten #5
Posted 13 April 2019 - 01:26 AM
If you had read the full post before replying you would have seen that the only reason the thread still exists is because i can't delete it myself.

True, I only read the original post as part of my email notifications and didn't check for the update. But deleting posts, just because they've been solved reduces the use of theses posts. Other people might run into your post when googling for similar issues, so keeping the post and answers, even if answered yourself, might help someone in the future.
GopherAtl #6
Posted 13 April 2019 - 01:44 AM
what he said. I did see your edit, and added on additional info that seemed highly relevant. AAP is an archive resource as well as a live one.
Edited on 12 April 2019 - 11:44 PM
ZagKalidor #7
Posted 24 April 2019 - 03:41 PM
Hey guys,

how do I manage this loadstring() thing to get a true bolean value for, maybe modem methods, like example:


block=peripheral.wrap("left")
a = "isWireless()"
answer = loadstring ("block." .. a)
print (answer)

instead of

>>function 725678bla…

Thanks in advance
Zag
Edited on 24 April 2019 - 01:45 PM
Luca_S #8
Posted 24 April 2019 - 04:19 PM
Hey guys,

how do I manage this loadstring() thing to get a true bolean value for, maybe modem methods, like example:


block=peripheral.wrap("left")
a = "isWireless()"
answer = loadstring ("block." .. a)
print (answer)

instead of

>>function 725678bla…

Thanks in advance
Zag

loadstring returns a callable function, so you need to do this:

block=peripheral.wrap("left")
a = "isWireless()"
answer = loadstring ("block." .. a)()
print (answer)

Although this does seem like an instance of the XY-Problem and what you really want to do is index a table using a variable, you can do the following to achieve that:


block=peripheral.wrap("left")
a = "isWireless" --'Notice how I'm not including brackets
answer = block[a]() -- This is the same as block.isWireless()
print(answer)

Also for this specific case you can also just use peripheral.call:

answer = peripheral.call("left", "isWireless")
print(answer)
Edited on 24 April 2019 - 02:24 PM
ZagKalidor #9
Posted 24 April 2019 - 06:16 PM
Oh man, thats great.

Thank you so much Luca. Made my day :D/>

Greetings from Germany to Germany…
Edited on 24 April 2019 - 04:17 PM