Treat a normal function as variadic?
Jarrett Billingsley
kb3ctd2 at yahoo.com
Wed May 30 08:32:16 PDT 2007
Robin Allen Wrote:
>
> Basically, I need a way to treat a non-variadic function as if it were
> variadic. I'm asking because I'm writing a scripting language, and I
> want to make normal D functions callable from the script, where the
> number of arguments given isn't known at compile time.
This is probably a bad idea. If your scripting language doesn't pass enough arguments, or passes too many arguments, things can go horribly awry. Furthermore, the calling conventions for non-variadic and variadic functions are completely different: see the calling conventions section in http://www.digitalmars.com/d/abi.html. And to top it off, anything you do with this will be grossly non-portable.
What would be a lot safer, more portable, and probably easier to implement would be an automatically-generated (using templates) shim function which would convert the scripting language params into native params and call the function. Something like this:
import std.traits;
template WrapFunc(alias func)
{
void WrapFunc(ScriptObj[] params, ScriptObj retVal)
{
alias ParameterTypeTuple!(func) Args;
Args args;
if(params.length != args.length)
throw new Exception("Function " ~ func.stringof ~ " called with incorrect number of parameters");
foreach(i, arg; args)
args[i] = params[i].convertTo!(typeof(args[i]));
static if(is(ReturnType!(func) == void))
{
func(args);
retVal.setNothing();
}
else
{
ReturnType!(func) ret = func(args);
retVal.convertFrom!(typeof(ret))(ret);
}
}
}
int foo(int x, char[] y)
{
writefln("foo: ", x, ", ", y);
}
...
ScriptHost.registerFunction(&WrapFunc(foo));
Designing your ScriptObj struct/class to be templated makes the whole process much easier as well.
More information about the Digitalmars-d-learn
mailing list