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