Lua callback function does not work with table - lua

I am trying to change Xadow's baudrate of Uart and trying to do same thing on software PDF but everytime i get errors. I just need to know how should I write the syntax.
Here is the guide of the lua software on xadow's writer
config={}
config["bit"]=9
config["par"]=0
config["stop"]=1
config["bdr"]=9600
function uartData(uart_id,len,data)
print(data)
end
uart_id=uart.create(1,uartData(config))

uart_id = uart.create(port, cb_func [,param])
Param is an optional Lua table as described in the documentation.
You have to call:
uart_id = uart.create(1, uartData, config)
not
uart_id = uart.create(1, uartData(config))
uartData(config) would pass the return value of uartData (nil) to uart.create instead of the function variable uartData
You can simply wirte config.bit=9 instead of config["bit"]=9 btw.

Related

How to determine if sysdig field exists or handle error if it doesn't

I'm using Sysdig to capture some events and have a small chisel (LUA script) to capture and format the events as necessary. On the on_init() I'm requesting fields like so :
f_field = chisel.request_field("<field>")
My question is how can I check if a field exists before requesting it? I'm going to use a new field only just released on 0.24.1 but ideally I'd like my chisel to continue to work on older versions of sysdig without this field. I've tried wrapping the call to chisel.request_field in a pcall() like so :
ok, f_field = pcall(chisel.request_field("<field>"))
and even implementing my own "get_field" function :
function get_field(field)
ok, f = pcall(chisel.request_field(field))
if ok then return f else return nil end
end
f_field = get_field("<field>")
if f_field ~= nil then
-- do something
end
but the error ("chisel requesting nonexistent field <field>") persists.
I can't see a way to check if a field exists but I can't seem to handle the error either. I really don't want multiple versions of my scripts if possible.
Thanks
Steve H
You're almost there. Your issue is in how you're using pcall. Pcall takes a function value and any arguments you wish to call that function with. In your example you're passing the result of the request_field function call to pcall. Try this instead..
ok, f = pcall(chisel.request_field, "field")
pcall will call the chisel method with your args in a protected mode and catch any subsequent errors.

Adding labels to my programming language

Actually I am writting a programming language in Lua. It was quite fun. I've wrote a bit of standard library (stack op and simple io). Then I've thought about labels. It would look like in assembly. While and for loop aren't funny in any bit so programming in that language can be quite challenging. Here are some requirements for this system:
Label stack (or array, dictionary) must be accessible from global context.
Jump instruction handler will be in separate file.
This is how my label-handling function look like:
function handleLabel(name,currentLine)
end
I have no idea how to implement this kind of magic. First I've thought about that:
LabelLineIDS = {}
Labels = {}
Labelamount = 1;
function handleLabel(name,currentLine)
LabelLineIDS[Labelamount]=currentline
Labels[Labelamount]=name
Labelamount=Labelamount+1
end
-- In file "jump.lua":
local function has_value (tab, val)
for index, value in ipairs(tab) do
if value == val then
return index
end
end
print ("Error: Label not defined.") -- Bail out.
os.exit(1)
end
local function _onlabel()
local labelName = globalparams --Globalparams variable contain parameters to each function, at the moment
--this will contain label name. It _can_ be nil.
return LabelLineIDS[has_value(Labels, labelName)]
end
CurrLine = _onlabel() --Currline - current line that get's parsed.
--1 command per one line.
But I'm unsure is this well written or even work. Can you give me idea how to parse labels in my programming language (and write jump functions)? Or if my code is pretty ok at the moment, can you help me to improve it?
Using line counter in my parser I've decided to implement gotos like we can see in BASIC. Thanks everyone for help.

Lua: Proper Scoping with Buffer Manipulation

I'm trying to create a buffer that is built with an input. This buffer would then send the captured strings to another function in the file that would manipulate the strings and utilize it later in other function(s). The first capture is parsed as expected and is fine. I'm having an issue clearing the buffer for new string captures when new data is received. Instead, it is adding the new strings onto the original ones, leaving me unable to properly manipulate it. Here is an example of what I'm trying to do:
local buffer = ""
function action(input)
buffer = buffer..input
parse_data(buffer)
end
function parse_data(data)
obj = ""
obj_var = buffer:match("(%d).*")
if obj_var == 1 then
obj = do_some_function()
else
obj = do_some_other_function()
end
buffer = ""
end
function do_some_function()
some action
end
function do_some_other_function()
some chunk
end
I do not know where to plug a command or function to clear the file's buffer variable prior to each new send. I know that this is very very simplistic code. But I hope I conveyed what I'm trying to get done with the buffer variable. This is a plugin file that will receive the input at it's main function to build each buffer. Then depending on the input, it will report to that specific function. I've tried to place buffer = "" at the end of each function and no go. I've also tried to change the variable call in function string(buffer) to another variable but that still doesn't clear the buffer. I guess I'm more so getting confused as to the lexical scoping of the buffer and how it would be best to clear it.
Thanks for all the help.

Does Corona SDK or Lua have an 'eval' function available?

I would like to have a dynamic variable name and want to be able to eval and get the value of it and was wondering if this was available. Example on how I want to use it.
audio.play(eval("readAloudPage"..page_num)))
If the value of a global variable is sought, then try _G["readAloudPage"..page_num].
Or define
function eval(name)
return _G[name]
end
Dynamic variable names must be table fields: the globals table which is named _G, or your own table if you don't want to use globals (usually the case). Example:
local yourDynVars = {}
yourDynVars["readAloudPage"..page_num] = ...
audio.play(yourDynVars["readAloudPage"..page_num])
print( yourDynVars.readAloudPage2 ) -- not dynamic; prints nil unless page_num was 2, above
If you replace yourDynVars table by _G the only difference is that in the last line you can access the var directly:
_G["readAloudPage"..page_num] = ...
audio.play(_G["readAloudPage"..page_num])
print( readAloudPage2 ) -- not dynamic; prints nil unless page_num was 2, above
Lua's closest equivalent to eval(code) would be loadstring(code)().
Notice loadstring(code) does not execute the code, it dynamically creates a function with it. Use loadstring(code)() to create and run it.
The closest you can get is lhf's solution to use _G["readAloudPage"..page_num].
Lua provides loadstring function to convert strings to executable functions, but this function is disabled in Corona SDK (and can only be used/accessed in debug environment).

Passing session between two lua files

I want to call another lua script from my main script say like
session:execute("lua","/path/somefile.lua "..somearg1.." "..somearg2..)
its working fine and somefile.lua is executing but suppose i also want to use session there i.e. i am accessing a database in somefile.lua and want to speak a query result in somefile.lua by using session. (session:speak(queryResult)).
i also tried sending session as one of argument
session:execute("lua","/path/somefile.lua "..session)
but it gives a error "attempt to concatenate global 'session' (a userdata value)"
any advise..??
code of first lua file
session:answer();
session:setAutoHangup(false);
session:set_tts_params("flite","kal");
callerId = session:getVariable("caller_id_number");
session:execute("lua ","/etc/freeswitch/scripts/checkbal.lua "..callerId.." "..session);
session:destroy();
code for 2nd lua file
callerId=argv[1];
session=argv[2];
luasql = require "luasql.postgres";
env=assert(luasql:postgres());
con=assert(env:connect("mydb","postgres","password","127.0.0.1","5432"));
cur=assert(con:execute("select balance from bal where number='"..callerId.."'"));
session:set_tts_params("flite","kal");
row=cur:fetch({},"a");
res=row.balance;
session:speak(res);
Rig your second file to be a module that returns a function or a table of functions. Here is an example that has second file return a "speak" function that you can then re-use as many times as desired:
Code of first Lua file:
session:answer()
session:setAutoHangup(false)
session:set_tts_params("flite","kal")
callerId = session:getVariable("caller_id_number")
speak = require 'checkbal'
speak(session, callerId)
-- session:execute("lua ","/etc/freeswitch/scripts/checkbal.lua "..callerId.." "..session)
session:destroy()
Code for 2nd Lua file:
luasql = require "luasql.postgres"
local env=assert(luasql:postgres())
local con=assert(env:connect("mydb","postgres","password","127.0.0.1","5432"))
local function speak(session, callerId)
local cur = assert(con:execute("select balance from bal where number='"..callerId.."'"))
session:set_tts_params("flite","kal")
row=cur:fetch({},"a")
res=row.balance
session:speak(res)
end
return speak
Note: this is Lua: no need for semicolons.
I would consider making "session" an object (table with methods) with a "speak" method, but this is going beyond scope of this question and is not necessary, may just lead to more maintainable code later.

Resources