LUA - ZeroBrane IDE: Compile feature - lua

in ZeroBrane Studio if I use "Project - complile (F7)" - what exactly does happen?
Will there be a standalone .exe created from my Lua code ?
And if so - in which directory ?
I use Windows 10.
(Couldn't find any information in the documention)

From what I see by a quick look into the source code it simply checks whether the code has any errors by loading it using loadstring which compiles the file.
There is no output file, just some text output about any errors.
But that's just an assumption. Feel free to check if this is actually the function called when you click that button.
https://github.com/pkulchenko/ZeroBraneStudio/blob/5daf55d79449431ca9794f6b8a65476dc203b780/src/editor
function CompileProgram(editor, params)
local params = {
jumponerror = (params or {}).jumponerror ~= false,
reportstats = (params or {}).reportstats ~= false,
keepoutput = (params or {}).keepoutput,
}
local doc = ide:GetDocument(editor)
local filePath = doc:GetFilePath() or doc:GetFileName()
local loadstring = loadstring or load
local func, err = loadstring(StripShebang(editor:GetTextDyn()), '#'..filePath)
local line = not func and tonumber(err:match(":(%d+)%s*:")) or nil
if not params.keepoutput then ClearOutput() end
compileTotal = compileTotal + 1
if func then
compileOk = compileOk + 1
if params.reportstats then
ide:Print(TR("Compilation successful; %.0f%% success rate (%d/%d).")
:format(compileOk/compileTotal*100, compileOk, compileTotal))
end
else
ide:GetOutput():Activate()
ide:Print(TR("Compilation error").." "..TR("on line %d"):format(line)..":")
ide:Print((err:gsub("\n$", "")))
-- check for escapes invalid in LuaJIT/Lua 5.2 that are allowed in Lua 5.1
if err:find('invalid escape sequence') then
local s = editor:GetLineDyn(line-1)
local cleaned = s
:gsub('\\[abfnrtv\\"\']', ' ')
:gsub('(\\x[0-9a-fA-F][0-9a-fA-F])', function(s) return string.rep(' ', #s) end)
:gsub('(\\%d%d?%d?)', function(s) return string.rep(' ', #s) end)
:gsub('(\\z%s*)', function(s) return string.rep(' ', #s) end)
local invalid = cleaned:find("\\")
if invalid then
ide:Print(TR("Consider removing backslash from escape sequence '%s'.")
:format(s:sub(invalid,invalid+1)))
end
end
if line and params.jumponerror and line-1 ~= editor:GetCurrentLine() then
editor:GotoLine(line-1)
end
end
return func ~= nil -- return true if it compiled ok
end

Related

LUA unexpected symbol near ')'

fivem
local loaded = false
function loadTxd(source, args, raw)
local txd = CreateRuntimeTxd('duiTxd')
local duiObj = CreateDui('https://media.discordapp.net/attachments/813996951066116097/854844624114548786/lcd_sign1.gif', 4096, 1024)
_G.duiObj = duiObj
local dui = GetDuiHandle(duiObj)
local tx = CreateRuntimeTextureFromDuiHandle(txd, 'duiTex', dui)
AddReplaceTexture('bus', 'lcd_sign_1', 'duiTxd', 'duiTex')
end)
Citizen.CreateThread function loadTxd(source, args, raw)
while loaded == false do
Wait(0)
local playerCar = GetVehiclePedIsIn(GetPlayerPed(-1))
if playerCar ~= 0 then
if GetEntityModel(playerCar) == GetHashKey('bus') then
loadTxd()
loaded = true
end
end
if not loaded then
local veh = nil
for veh in EnumerateVehicles() do
if GetEntityModel(playerCar) == GetHashKey('bus') then
loadTxd()
loaded = true
break
end
end
end
end
end)
says it lua5.3: ...Desktop/rextester_linux_2.0/usercode/29524824/source.lua:10: unexpected symbol near ')' but I can't find it anywhere I even tried deleting the whole line 10 and pasting all the code back in and then putting the end) on line 10
There are a few syntax errors here:
The extra ) after end on line 10, which is the error you're seeing
An opening parenthesis is missing after Citizen.CreateThread
When you write function foo(...), that's equivalent to writing foo = function(...). You can't give a function a name when you're using it inline, like you are with the one you're passing to Citizen.CreateThread.
So, to fix the syntax errors, the middle part of your code (lines 10–12) should read:
...
end
Citizen.CreateThread(function(source, args, raw)
...

Lua function returns string, but calling function gets nil

I'm writing a function for Nodemcu (esp8266) Lua to build command strings from UART (someone typing). When it finishes capturing characters, it's supposed to return the string to the calling function, but the calling function only gets nil. I'm new to Lua, What am I missing?
local function getcmd()
local t = { }
local cmd
-- Callback function
uart.on("data", 0, function(data)
if data~='\r' then
--Echo input
t[#t+1] = data
uart.write(0,t[#t])
-- BACKSPACE/DEL
if t[#t] == '' then
t[#t] = nil
t[#t] = nil
end
-- NEED <TAB> handling here too
else
--Disables callback
--uart.on("data")
-- Print table, convert to string.
for i = 1, #t do
uart.write(0, t[i])
if i==1 then
cmd = tostring(t[i])
else
cmd = cmd .. tostring(t[i])
end
end
t = { }
if cmd ~= nil then
uart.write(0, "Before Return> "..cmd)
-- type() String
return cmd
end
end
end,0)
end
local function config()
local cmdstr
-- Testing
cmdstr = getcmd()
print("func() "..getcmd())
if cmdstr ~= nil then
uart.write(0, cmdstr.."> ")
end
end
Thanks to #EgorSkriptunoff for helping me understand what was happening.
Below is the code that works (so far). What I tried was a While loop around the event handler inside of getcmd(). This fails because it stops execution of all the background events that keep things like wifi and other essential functions that keep the ESP8266 running, so it crashes/reboots repeatedly.
What I did instead of returning from getcmd() was call config() directly and pass it the input I collected in the event handler, like this: config(cmd)
The potential problem is, the event handler is still running since it never reached the end and that could cause some stack/memory issues if I don't return from config() before calling another function.
Anyway, here is the code that is working for the moment:
function getcmd()
local t = { }
cmd=nil
uart.on("data", 0, function(data)
if data~='\r' then
--Echo input
t[#t+1] = data
uart.write(0,t[#t])
-- BACKSPACE/DEL
if t[#t] == 'BS' then
t[#t] = nil
t[#t] = nil
end
else
--uart.on("data")
if #t ~= nil then
uart.write(0,"\r\n"..#t.."\r\n")
end
for i = 1, #t do
uart.write(0, t[i])
if i==1 then
cmd = tostring(t[i])
else
cmd = cmd .. tostring(t[i])
end
end
t = { }
if cmd ~= nil then
-- Calling config() here doesn't allow event handler on.uart() to end.
config(cmd)
end
end
end,0)
end
------------------------------------------------------
function config(cmd)
print("\r<<"..cmd..">>\r")
-- Now parse cmd and return.
end

Does Luci have print function?

I want to print my parsing value at Luci.
Here is my code.
local val = {}
mm = Map("test", translate("For TEST"))
test=mm:section(TypedSection, "test", translate("TEST"))
test.anonymous = true
test.addremove = false
rssis = test:option(DummyValue, "rssi", translate("RSSI"))
t = test:option(DummyValue, "tx", translate("TX"))
r = test:option(DummyValue, "rx", translate("RX"))
local f = io.popen("iwpriv wlan0 stat")
for line in f:lines() do
for s in line:gmatch("(%S+)%s") do
table.insert(val, s)
end
for i, v in ipairs(val) do
end
end
f:close()
rssis:value(val[35])
if val[41] == "6M" then
t:value(val[41], translate("Disconnect"))
else
t:value(33, translate("Good"))
end
if val[49] == "6M" then
r:value(val[49], translate("DIsconnect"))
else
r:value(33, translate("GOOD"))
end
return mm
I saw the DummyValue which Creates a readonly field in the form.
So I used it instead of print function.
However it has errors "attempt to index global 'rssis' (a nil value)"
Only in lua file(not used for Luci) If i used the print function, it has no error. Does Luci has print function?
There is a luci.util.perror("blah blah") function that prints to the syslog.
you can then use the shell command "logread" to display in a console.
I guess this is what you need to debug your code.

Scanning folders using lua

I'm trying to get the name of all the file saved in two folders, the name are saved as :
1.lua 2.lua 3.lua 4.lua and so on
the folders name are :
first folder : "/const/"
second folder: "/virt/"
what I'm trying to do is only get the number of the files and this works but not in the right order, when I get the 17 file for example I get the 17th delivered from the function before the 15 and this causes for me a problem here the code of the function that I'm using :
local virt_path = "/virt/"
local const_path = "/const"
local fs = require "lfs"
local const = {}
for num = 1, (numberoffile)do -- numberoffile is predfined and can't be change
const[num] = assert(
dofile (const_path .. mkfilename(num)),
"Failed to load constant ".. num ..".")
end
local function file_number() --this is the function that causes me a headach
local ci, co, num = ipairs(const)
local vi, vo, _ = fs.dir(virt_path)
local function vix(o)
local file = vi(o)
if file == nil then return nil end
local number = file:match("^(%d+).lua$")
if number == nil then return vix(o) end
return tonumber(number)
end
local function iter(o, num)
return ci(o.co, num) or vix(o.vo, num)
end
return iter, {co=co, vo=vo}, num
end
As I said the function delive the need return values but not the right Arithmetic order.
any idea what I'm doing wrong here ?
I use my path[1] library.
1 We fill table with filenames
local t = {}
for f in path.each("./*.lua", "n") do
t[#t + 1] = tonumber((path.splitext(f)))
end
table.sort(t)
for _, i in ipairs(t) do
-- do work
end
2 We check if files exists
for i = 1, math.huge do
local p = "./" .. i .. ".lua"
if not path.exists(p) then break end
-- do work
end
[1] https://github.com/moteus/lua-path

Is This A lua Variable Scope Issue (and how can it be solved)?

A very strange error, showing an object is nil.
the code in subject is
while pbs:HasNext() do
local char = self.DecodeCharacter(pbs)
...
One would think, that if pbs:HasNext() is true, it means that, pbs is not nil, whatsoever.
However, the print(pbs) - the first line of HTMLEntityCodec:DecodeCharacter prints nil
function HTMLEntityCodec:DecodeCharacter(pbs)
print(pbs)
...
The entire file dumped below, it was stripped from 1800+ lines to 110 so it can be clear for SO users to get he context. But that stripping took away all logic from the code, so do not get confused by that.
#!/usr/bin/env lua
function Inherits( baseClass )
local new_class = {}
local class_mt = { __index = new_class }
function new_class:create()
local newinst = {}
setmetatable( newinst, class_mt )
return newinst
end
if baseClass then
setmetatable( new_class, { __index = baseClass } )
end
return new_class
end
-------------------------------------------
-- PushbackString
-------------------------------------------
PushbackString = Inherits({})
function PushbackString:Init(input)
self.input = input
self.pushback = nil
self.temp = nil
self.index = 0
self.mark = 0
end
-- Mark the current index, so the client can reset() to it if need be.
function PushbackString:HasNext()
return true
end
function PushbackString:Mark ()
self.temp = self.pushback
self.mark = self.index
end
BaseCodec = Inherits({})
function BaseCodec:Decode(input)
local buff = ''
local pbs = PushbackString:create()
pbs:Init(input)
while pbs:HasNext() do
local char = self.DecodeCharacter(pbs)
if char ~= nil then
buff = buff .. char
else
buff = buff .. pbs:Next()
end
end
return buff
end
HTMLEntityCodec = Inherits(BaseCodec)
-- HTMLEntityCodec.classname = ('HTMLEntityCodec')
function HTMLEntityCodec:DecodeCharacter(pbs)
print(pbs)
pbs:Mark()
end
DefaultEncoder = Inherits({})
function DefaultEncoder:Init(codecs)
self.html_codec = HTMLEntityCodec:create()
end
function DefaultEncoder:TestInput(input , strict)
print ("\n----------------8<----------------8<----------------\n")
print ("Input:\t" .. input)
-- default value
if strict == nil then strict = true end
-- nothing to do
if input == nil then return nil end
local working = input
local codecs_found = {}
local found_count = 0
local clean = false
while not clean do
clean = true
old = working
working = self.html_codec:Decode( working )
if old ~= working then
print ("Warning:\tINTRUSION DETECTED")
end
end
print ("Output:\t".. working)
return working
end
local default_encoder = DefaultEncoder:create()
default_encoder:Init()
default_encoder:TestInput("%25", true)
----------8<-----------8<--------------8<----------------
END OF FILE
Console Output:
tzury#1005:~/devel/lua$ lua problem.lua
----------------8<----------------8<----------------
Input: %25
nil
lua: problem.lua:70: attempt to index local 'pbs' (a nil value)
stack traceback:
problem.lua:70: in function 'DecodeCharacter'
problem.lua:54: in function 'Decode'
problem.lua:96: in function 'TestInput'
problem.lua:109: in main chunk
[C]: ?
In your code, the crash happens on this line:
local char = self.DecodeCharacter(pbs)
The problem is that you are calling DecodeCharacter with incorrect number of arguments.
Solution: call it like this (notice the colon):
local char = self:DecodeCharacter(pbs)
Explanation:
When you define functions in Lua using the colon (:), you are using a syntax sugar which hides an implicit first argument named self. Definitions like:
function HTMLEntityCodec:DecodeCharacter(pbs) ... end
Are actually 'translated' to this:
HTMLEntityCodec.DecodeCharacter = function (self, pbs) ... end
When you call the function, you either need to pass the self argument yourself, or use the colon call to supply it automatically. In your code (self.DecodeCharacter(pbs)), you are passing pbs which ends up as self in HTMLEntityCodec.DecodeCharacter, and pbs ends up being nil. Both following calls are equivalent and should solve the issue:
local char = self.DecodeCharacter(self, pbs)
local char = self:DecodeCharacter(pbs)

Resources