lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


It was thus said that the Great Flyer31 Test once stated:
> Hello,
> in my C code I want to define some special Lua functions, which should
> be only invoked inside a sort of "main function", and these functions
> also should NOT be invoiked inside any code blocks if...end, as well
> as not in any loops for ...end / while ...end / repeat ... until.
> 
> Witth the debug interface and lua_getinfo I can get info about the
> function currently active ... so I can restrict the invocation of this
> "special function" easily to be called only insde my "main function".
> 
> But I did not find an easy way to know, whether any "block"
> (if/for/while/do/repeat) is active. Is there a way for my C code to
> get this information?

  In general, you cannot [1]. In particular, there is no way to detect if
Lua is executing within a loop.  The following Lua code:

	x = 1
	while x < 10 do
		x = x + 1
	end

generates the following byte code (with label information added):

		vararggrep	0
		settabup	0 0 1k	; x = 1
	HERE	gettabup	0 0 0	; read x
		lti		0 10 0	; x < 10 ?
		jmp		THERE	; if false, jump to THERE
		gettabup	0 0 0	; read x
		mmbini		0 1 6 0	; add 1 to value
		settabup	0 0 0	; write to x
		jmp		HERE	; jump back
	THERE	return		0 1 1

  The "while" statement has been replaced with a variable read, a comparison
and a conditial jump.  A repeat/until statement is similar, except for the
test is usually at the bottom of the loop.  There isn't anything in the code
to say "This is a while loop" or "This is a for loop" or "This is a
repeat/until" loop.  

  It seems, from your description, what you are trying to do is write a
function for a user to call, but you don't trust the user to actually call
the function at the right time (or the right number of times).  Perhaps if
you explain what you are actually trying to do, it might elicit some better
advice.

  For example, without knowing anything else about the problem, I might
suggest:

	static bool foo_called = false;

	static int foo(lua_State *L)
	{
	  if (foo_called)
	    luaL_error(L,"I'm sorry Dave, I can't let you do that.");
	  foo_called = true;
	  /* ... rest of code */
	}

  But that would only allow the function to be called once, which may not be
what you want it do to.  In fact, I can't think of a way to do what you are
asking in any language (even Assembly, where you have complete control over
all the code being run).

  -spc

[1]	You might want to read up on the "halting problem" which will go
	into detail about what can and cannot be computed.