[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: strfind "bug"
- From: Edgar Toernig <froese@...>
- Date: Wed, 19 Dec 2001 15:04:35 +0100
"Reuben Thomas,,,690081" wrote:
>
> > Sigh, another example of the arg handling ad hockery...
>
> Indeed; this is one of the several reasons I think it would be good for even
> the standard Lua libraries to be written using tolua (or a similar tool),
> and for this practice to be encouraged for everyone.
I wouldn't go that far. IMHO, the wish for a tool like tolua for simple
tasks show that the API is too complex.
> The Lua API could probably be simplified even further if it were only
> intended for writers of binding tools, and the annoying bugs that tend
> to crop up (especially with stack handling) would go away.
In fact, I like the stack handling. It's a simple concecpt that works
pretty well. What's wrong is how arguments are passed and handled. That
has already been simplified by moving the upvalues aways from the stack.
IMO the next step would be to make the arg-handling similar to that in
Lua itself (where it's simple enough, isn't it?).
The problem is, that C functions are always handled like Lua vararg
functions (function foo(...) body end) and that the C arg-fetching
functions check arg.n. I.e luaL_opt_number works like this:
function luaL_opt_number(args, argno, default)
if args.n < argno then
return args[argno]
else
return default
end
end
and used like this (strfind as an example):
function strfind(...)
...
local init = luaL_opt_number(arg, 3, 1)
if arg.n > 3 ... then simple_string_search...
...
end
Noone would do this in Lua. You would write:
function strfind(s,p,init,nopattern)
...
init = init or 1
if nopattern ... then simple_string_search...
...
end
So why do it in C? This is how I would change the C-API:
- lua_pushcclosure gets an additional argument: the number of
arguments expected by the functions. This number (nargs) is
saved in the closure structure for later use.
(Associated functions/structures are changed too)
- when calling a C function the VM checks whether there are less
arguments on the stack then the closure wants (gettop<nargs).
In that case it pushes additional nils on the stack until there
are enough arguments (gettop==nargs). If there are already
enough or even more arguments on the stack it does nothing.
Then the function is called.
- All functions that check for optional arguments (like luaL_opt_-
number) will decide that the argument is not present if it is nil.
That is: no check against gettop>argno but against isnil(stack[argno]).
- lua_isnull is removed.
That's all! C functions behave the same as Lua functions. Seems to
work pretty well in Sol ;-)
> > function strfind(a,b,c,d)
> > c = c or 1 -- c has a similar problem...
> [...]
> I'll add the function above to my standard library, along with the
> wrapper for tinsert we discussed a while ago.
Then you have more to do. Just a simple eye-grep over lbaselib gives
these functions that need this kind of wrapper:
- tonumber
- error
- newtype
- globals (even slightly buggy when called with no args)
- settagmethod
- collectgarbage
- dostring
- loadstring
- dofile
- loadfile
- call
- assert
- tinsert
- tremove
- sort
There are more when considering luaL_check_any calls...
Ciao, ET.