Enforce function use in a Lua source file

87 views
Skip to first unread message

bil til

unread,
Nov 1, 2025, 1:53:33 AM (6 days ago) Nov 1
to lu...@googlegroups.com
I write an application for small system microcontrollers, and I want
to use similar concepts as Arduino uses.

Mainly I the user has to present a setup function and a loop function
in the Lua code.

But I do NOT like the idea, that the user would write any more
complicated Lua coding / invoke functions in the "Lua startup code"
(out of setup function, and out of Loop function).

Is there an easy way to forbid this?

e. g.:
function setup()
... the setup code...
end

function loop()
... the loop code
end

would be fine (also before setup function there might be some
variables defined).

But I would not like the following:
... some user code here...
function setup()
... the setup code...
end

... some further code here...

function loop()
... the loop code
end

.. some further user code here...


Is it possible to instruct the Lua parser from my C code, that I do
NOT like such a "programming style", so best errors should be given in
this case? (or the Lua program schould stop during runtime with an
error if this is detected...)

Родион Горковенко

unread,
Nov 1, 2025, 2:05:53 AM (6 days ago) Nov 1
to lu...@googlegroups.com
There are a number of ways I guess, both compile-time and run-time. Probably the easiest way would be to mend the parser itself.

However your task is poorly defined. Do you want to forbid creating global variables? Sounds ridiculous as most Arduino users won't understand you.

If not, then do you want to forbid creating global variables with complicated initializer expressions?

If not, how are you going to forbid anything if anything could be done in these initializers?

Overall the whole idea seems a bit weird, like Don Quixote fighting windmills, sorry :)

--
You received this message because you are subscribed to the Google Groups "lua-l" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/lua-l/CAOnDXmEWhu5GDgE_PoAt87asaoK%3Dob2j-0-n9JKcho6BPsHuLQ%40mail.gmail.com.

bil til

unread,
Nov 1, 2025, 2:35:14 AM (6 days ago) Nov 1
to lu...@googlegroups.com
HI, thanks for fast answer.

> Do you want to forbid creating global variables?

but this was misunderstanding: Global variables are fine. Also they
can be defined outside setup function - no problem.

I just do NOT want that the Lua user somehow does more complicated
"setup programming work" outside the setup function... .

bil til

unread,
Nov 1, 2025, 2:56:11 AM (6 days ago) Nov 1
to lu...@googlegroups.com
Any code BEFORE the setup function still would be acceptable...

But I would like to prohibit any "global coding" BETWEEN setup and
loop function, and also at the end of the file (AFTER loop function).

Sean Conner

unread,
Nov 1, 2025, 3:01:20 AM (6 days ago) Nov 1
to lu...@googlegroups.com
It was thus said that the Great bil til once stated:
> I write an application for small system microcontrollers, and I want
> to use similar concepts as Arduino uses.
>
> Mainly I the user has to present a setup function and a loop function
> in the Lua code.
>
> But I do NOT like the idea, that the user would write any more
> complicated Lua coding / invoke functions in the "Lua startup code"
> (out of setup function, and out of Loop function).
>
> Is there an easy way to forbid this?

Document that this should not be done, and trust the user?

Is this allowed?

setup = function() ... end
loop = function() ... end

Would this be allowed?

x = 3
y = x * 5
foo = "There are " .. x .. " foos and " .. y .. " bars"

function setup() ... end
function loop() ... end

because that is, technically speaking, "user code" before setup() and loop()
are defined. I can continue ...

local function foo() ... end
local function bar() ... end

setup = foo
loop = bar

for a silly example.

Do I assume correctly that you do not trust users to write code?

-spc

bil til

unread,
Nov 1, 2025, 3:59:07 AM (6 days ago) Nov 1
to lu...@googlegroups.com
that would all be ok.

... and sorry for my answer to your final question ... I must admit at
least a "yes maybe sometimes" as answer on this :).

Such Lua code files of course can get quite long.

And I want to avoid the annoying problems, if the user by some
accdident e. g. has place some lua lines at the end of the file, but
this then is run as a sort of "startup code" before the setup function
is invoked... .

Sewbacca

unread,
Nov 1, 2025, 5:15:26 AM (6 days ago) Nov 1
to lu...@googlegroups.com
If the issue is ensuring that time consuming work is done only during setup time, might I suggest ditching the concept of a setup function completely?

Since Lua code is always code, you could initialize the Lua state during setup() and there run the script once. During loop() you might call the user defined loop function. This way any complicated startup code will already have been executed during setup(). If users still want a setup function you could run it immediately after the script as well.

If for some reason you need to initialize the script during startup time (i.e. for user defined configuration) and before setup(), then I guess you could set a count hook (i.e. debug.sethook('c', error, 1000)) that throws an error if too much time elapsed or too many instructions have been executed. That would force users to do any heavy work during setup(). This would be a bit awkward, but it would not require rewriting the parser.

bil til

unread,
Nov 1, 2025, 5:23:35 AM (6 days ago) Nov 1
to lu...@googlegroups.com
Ditching the setup function is a bit bad for my multitasking concept.

The task handling is very important for my app - it is resuming /
yielding all the time, and it starts with invocation of the setup
function ... .

The "out of functions" code will be run before, and I do not want that
the operator does invoke there any elaborate functions... .

I could verify at start of every function of my lib, that the
resume-yield-task-handling is already running, but this sounds a bit
cumbersome / waste of time / waste of program code... . (my lib
contains quite a bit of functions :)).

Sainan

unread,
Nov 1, 2025, 5:36:13 AM (6 days ago) Nov 1
to lu...@googlegroups.com
Why even have a setup step at all? You can choose when you start ticking the user-supplied code (resume via C or a Lua runtime wrapper). I don't see a difference between tick 1 and tick 100. The user-side part would then look something like this:

-- Optional setup code
repeat
-- Looped code
until coroutine.yield()

-- Sainan

bil til

unread,
Nov 1, 2025, 7:52:38 AM (6 days ago) Nov 1
to lu...@googlegroups.com
... I will think about it...

but it would be nice, if after the setup function only definition of
further functions would be allowed... of course not VERY important,
but wishful thinking :)... .

Luiz Henrique de Figueiredo

unread,
Nov 1, 2025, 10:54:05 AM (6 days ago) Nov 1
to lu...@googlegroups.com
If you can use a preprocessor then it should be simple to use my ltokenp for enforcing this: it is essentially pattern matching on the stream of tokens.

bil til

unread,
Nov 1, 2025, 12:31:08 PM (6 days ago) Nov 1
to lu...@googlegroups.com
Wow, this sounds great, thank you (I do not understand it completely
for now, but I would look into this later...). (it is sufficient for
me, if I have the possibility to analyze a Lua script before "burning"
it into my targets, and then give some warnings to the user in case of
possible problems, so in fact such a pre-processor solution is
perfectly fine for me).

Xavier Wang

unread,
Nov 1, 2025, 10:46:35 PM (5 days ago) Nov 1
to lu...@googlegroups.com
If you familiar the “Parsing, not validating”[1] rule, you may try a structure like this:

Just treat the whole script as “setup”, and tell users to return a function as “loop”.

E.g.

— setup
— any setup works here …

return function()
   — loop
   — any loop code here
end

It ensures the loop codes are always after any setup codes. 

And you can still run your script function (Lua script is already a normal function) in a coroutine that you can yield/suspend. 


regards,
Xavier Wang.


bil til <bilt...@gmail.com>于2025年11月1日 周六19:52写道:
--
You received this message because you are subscribed to the Google Groups "lua-l" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.

Thijs Schreijer

unread,
Nov 3, 2025, 5:04:04 AM (4 days ago) Nov 3
to lu...@googlegroups.com

On Sun, 2 Nov 2025, at 03:46, Xavier Wang wrote:
> If you familiar the “Parsing, not validating”[1] rule, you may try a structure like this:
>
> Just treat the whole script as “setup”, and tell users to return a function as “loop”.
>
> E.g.
>
> — setup
> — any setup works here …
>
> return function()
> — loop
> — any loop code here
> end
>
> It ensures the loop codes are always after any setup codes.
>
> And you can still run your script function (Lua script is already a normal function) in a coroutine that you can yield/suspend.
>
> [1]: https ://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/
>
> regards,
> Xavier Wang.

Really nice. Thx for the interesting read; "parsing, not validating".
Reply all
Reply to author
Forward
0 new messages