Issue with loop and nested if statements - lua

motor = peripheral.wrap("right")
repeat
RPM = motor.getSpeed()
print("current rpm is ", RPM, "RPM. What RPM do you need?")
setrpm = tonumber(io.read())
if type(setrpm) == "number"
then
motor.setSpeed(setrpm)
goto contine
else
print("Must be a number between -256 and 256")
print("current rpm is ", RPM, "RPM. What RPM do you need?")
setrpm = tonumber(io.read())
end
::continue::
rpm = motor.getSpeed()
su = ( rpm * 16)
fe = motor.getEnergyConsumption()
print("You have set speed " , rpm, " RPM")
print("Current stress cap is now ", su, "SU")
print("Power Consumption is now ", fe, "FE/t")
until( fe > 100 )
end
Expected behavor
loop until fe=100 or more
current behavor
motor.lua:12 '=' expected near 'continue'
writing a loop of code in computercraft to ask what rpm a block needs to spin at, expected behavor is to keep looping the code endlessly till the FE>100 (for the block its looking at its imposible)

Computercraft uses Lua 5.1. goto was introduced in Lua 5.2 so you cannot use it in your script.
That aside there is no point in using it like that.
if condition then
-- block A
else
-- block B
end
After executing block A or B Lua will automatically continue after the end.
You don't have to explicitly tell Lua to do that.
In a repeat until statement there is no end after the condition. The correct syntax is:
repeat block until exp
Befor posting your problems here, at least check for typos. contine is not the label you intended to go to.
Please refer to https://www.lua.org/manual/5.1/manual.html

Related

attempt to yield across metamethod/C-call boundary AND cannot resume non-suspended coroutine in ROBLOX STUDIO when using wait (00.1)

This is my code
-- Script by supermarioclub231 as known as marioroblox102, and special thanks to jacko for some scripts things
-- idk
-- Player
local plr = game.Players:CreateLocalPlayer(0)
game:GetService("Visit")
game:GetService("RunService"):run()
plr:LoadCharacter()
-- have to do this so that the same numbers arent generated every time
math.random(); math.random(); math.random()
digits = 4 -- the amount of times to add digits to the end of the player name
prefix = "NoName "
suffix = "" -- wouldnt wanna type anything here, the digits will be added here!
for i=1, digits do
suffix = suffix .. math.random(1,9)
i = i + 1;
end
plr.Name = prefix .. suffix
-- shopium brings to you...
shirt = Instance.new("Shirt", plr)
pants = Instance.new("Pants", plr)
shirt.ShirtTemplate = "rbxasset://shirts/jared.png"
pants.PantsTemplate = "rbxasset://pants/jeans.png"
while true do
wait (0.001)
if plr.Character.Humanoid.Health <= 0 then
wait(5)
plr:LoadCharacter(true)
elseif plr.Character.Parent == nil then
wait(5)
plr:LoadCharacter(true)
end
end
everytime i run it, i get this
the line 39 is wait(000.1),
why its not working?
its supossed to do something forever
like a loop
but it gives me a error
First of all you don't have to you use math.random() three times at the start so it doesn't generate the same script everytime as thats not how it works it will generate a random number between the range you specify every time and the number may be the same every once in a while but thats why its called math.random() but I'm also working on fixing the rest of you script just wanted to tell you that. Also just use the ROBLOX Health Changed Event and the link to the wiki of that event is here.

Asterisk PBX - Infinite Loop when user disconnects while using 'Read' application from LUA

I'm configuring interactive dial plans for asterisk at the moment and because I already know some LUA I thought it'd be easier to go that route.
I have a start extension like this:
["h"] = function(c,e)
app.verbose("Hung Up")
end;
["s"] = function(c, e)
local d = 0
while d == 0 do
say:hello()
app.read("read_result", nil, 1)
d = channel["read_result"].value;
if d == 1 then
say:goodbye()
elseif d == 2 then
call:forward('front desk')
end
d = 0
end
say:goodbye()
end;
As you can see, I want to repeat the instructions say:hello() whenever
the user gives an invalid answer. However, if the user hangs up while
app.read waits for their answer, asterisk ends up in an infinite loop
since d will always be nil.
I WOULD check for d==nil to detect disconnection, but nil also shows
up when the user just presses the # pound sign during app.read.
So far I've taken to using for loops instead of while to limit the
maximum iterations that way, but I'd rather find out how to detect a disconnected
channel. I can't find any documentation on that though.
I also tried setting up a h extension, but the program won't go to it when the
user hangs up.
Asterisk Verbose Output:
[...]
-- Executing [s#test-call:1] read("PJSIP/2300-00000004", "read_result,,1") │ test.lua:3: in main chunk
-- Accepting a maximum of 1 digit. │ [C]: ?
-- User disconnected │root#cirro asterisk lua test.lua
-- Executing [s#test-call:1] read("PJSIP/2300-00000004", "read_result,,1") │Global B
-- Accepting a maximum of 1 digit. │LocalB-B->a
-- User disconnected │LocalB-A
-- Executing [s#test-call:1] read("PJSIP/2300-00000004", "read_result,,1") │LocalB-A
-- Accepting a maximum of 1 digit. │LocalB-A
-- User disconnected │root#cirro asterisk cp ~/test.call /var/spool/asterisk/outgoing
-- Executing [s#test-call:1] read("PJSIP/2300-00000004", "read_result,,1")
[...]
Thanks for any help you might be able to offer.
First of all you can see in app_read docs(and any other doc), that it return different values for incorrect execution(when channel is down).
Also this exact app offer simplified way of determine result:
core show application Read
-= Info about application 'Read' =-
[Synopsis]
Read a variable.
[Description]
Reads a #-terminated string of digits a certain number of times from the user
in to the given <variable>.
This application sets the following channel variable upon completion:
${READSTATUS}: This is the status of the read operation.
OK
ERROR
HANGUP
INTERRUPTED
SKIPPED
TIMEOUT
If that still not suite you, you can direct ask asterisk about CHANNEL(state)
PS You NEVER should write dialplan or any other program with infinite loop. Count your loops and exit at 10+. This will save ALOT of money for client.

Sleep Lua script while letting the master program continue

I am programming a plugin to a program that has integrated Lua scripting, and need to have my script check a condition every x seconds.
I have tried different methods of "sleeping" the Lua script, but all my methods so far also hang/pause the main program.
Is there a way to have my Lua script run every x seconds without pausing the master program.
You can use os.time() and os.difftime():
local waitTime = 3
if t1 == nil then t1 = os.time() end
--Check
if math.floor(os.difftime(os.time(),t1)) == waitTime then
t1 = os.time()
-- Do stuff
end
This runs your code every 3 seconds.

Lua - Couple Questions

Im a amatuer at coding. So, mind me if i face palmed some things.
Anyways, im making a alpha phase for a OS im making right? I'm making my installer. Two questions. Can i get a code off of pastebin then have my lua script download it? Two. I put the "print" part of the code in cmd. I get "Illegal characters". I dont know what went wrong. Here's my code.
--Variables
Yes = True
No = False
--Loading Screen
print ("1")
sleep(0.5)
print("2")
sleep(0.5)
print("Dowloading OS")
sleep(2)
print("Done!")
sleep(0.2)
print("Would you like to open the OS?")
end
I see a few issues with your code.
First of all, True and False are both meaningless names - which, unless you have assigned something to them earlier, are both equal to nil. Therefore, your Yes and No variables are both set to nil as well. This isn't because true and false don't exist in lua - they're just in lowercase: true and false. Creating Yes and No variables is redundant and hard to read - just use true and false directly.
Second of all, if you're using standard lua downloaded from their website, sleep is not a valid function (although it is in the Roblox version of Lua, or so I've heard). Like uppercase True and False, sleep is nil by default, so calling it won't work. Depending on what you're running this on, you'll want to use either os.execute("sleep " .. number_of_seconds) if you're on a mac, or os.execute("timeout /t " .. number_of_seconds) if you're on a PC. You might want to wrap these up into a function
function my_sleep_mac(number_of_seconds)
os.execute("sleep " .. number_of_seconds)
end
function my_sleep_PC(number_of_seconds)
os.execute("timeout /t " .. number_of_seconds)
end
As for the specific error you're experiencing, I think it's due to your end statement as the end of your program. end in lua doesn't do exactly what you think it does - it doesn't specify the end of the program. Lua can figure out where the program ends just by looking to see if there's any text left in the file. What it can't figure out without you saying it is where various sub-blocks of code end, IE the branches of if statements, functions, etc. For example, suppose you write the code
print("checking x...")
if x == 2 then
print("x is 2")
print("Isn't it awesome that x is 2?")
print("x was checked")
lua has no way of knowing whether or not that last statement, printing the x was checked, is supposed to only happen if x is 2 or always. Consequently, you need to explicitly say when various sections of code end, for which you use end. For a file, though, it's unnecessary and actually causes an error. Here's the if statement with an end introduced
print("checking x...")
if x == 2 then
print("x is 2")
print("isn't it awesome that x is 2?")
end
print("x was checked")
although lua doesn't care, it's a very good idea to indent these sections of code so that you can tell at a glance where it starts and ends:
print("checking x...")
if x == 2 then
print("x is 2")
print("isn't it awesome that x is 2?")
end
print("x was checked")
with regards to your "pastebin" problem, you're going to have to be more specific.
You can implement sleep in OS-independent (but CPU-intensive) way:
local function sleep(seconds)
local t0 = os.clock()
repeat
until os.clock() - t0 >= seconds
end

Custom interpreter

I'm trying to write an interpreter in Gforth, but it doesn't work. All I get is an infinite list of num num num num ...
: ?refill
source nip >in # =
if
refill drop
then
;
: inter
begin
?refill
bl word find dup
if
state # =
if
." comp "
,
else
." exec "
execute
then
else
dup rot count >number
if
abort
then
drop drop state #
if
." lit "
['] lit , ,
else
." num "
then
then
again
;
inter
: test 10 20 ;
Your interpreter does work, it just does not block, see the first couple of words from the output:
num exec lit lit exec num num num ...
However, you leave a 0 on the stack somewhere, thats why you create a stack overflow, you can use ~~ in the code to check the stack and track the unconsumed 0.
Bernd Paysan has introduced Recognizers to GForth, I suggest you take a look at them, as they would ease your task of writing an interpreter.

Resources