www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Automatic function body writing howto?

reply Oleg B <code.viator gmail.com> writes:
I want declare only signature of function and build body code by 
CTFE.

module mdl;
import std.stdio;
import std.traits;
import std.string;

enum autofnc;

 autofnc
{
	int foo(int);
	int bar(int);
}

void main()
{
	writeln(foo(12));
}

mixin cfuncR;

mixin template cfuncR()
{
	mixin impl!(getSymbolsByUDA!(mdl, autofnc));

	mixin template impl(funcs...)
	{
		static if (funcs.length == 1)
		{
			mixin("pragma(msg, typeof(%1$s)); // !!! here I get _error_
			ReturnType!%1$s %1$s(Parameters!%1$s vals) { return vals[0] * 
2; }".format(__traits(identifier, funcs[0]));
		}
		else
		{
			mixin impl!(funcs[0..$/2]);
			mixin impl!(funcs[$/2..$]);
		}
	}
}

I get this output:

/usr/include/dmd/phobos/std/traits.d-mixin-7671(7671): 
Deprecation: mdl.object is not visible from module traits
/usr/include/dmd/phobos/std/traits.d-mixin-7671(7671): 
Deprecation: mdl.std is not visible from module traits
mdl.d-mixin-29(30): Error: template instance 
std.traits.ReturnType!(foo) does not match template declaration 
ReturnType(func...) if (func.length == 1 && isCallable!func)
mdl.d-mixin-29(30): Error: template instance Parameters!foo does 
not match template declaration Parameters(func...) if 
(func.length == 1 && isCallable!func)
_error_
mdl.d(34): Error: mixin mdl.cfuncR!().impl!(foo, bar).impl!(foo) 
error instantiating
mdl.d-mixin-29(30): Error: template instance 
std.traits.ReturnType!(bar) does not match template declaration 
ReturnType(func...) if (func.length == 1 && isCallable!func)
mdl.d-mixin-29(30): Error: template instance Parameters!bar does 
not match template declaration Parameters(func...) if 
(func.length == 1 && isCallable!func)
_error_
mdl.d(35): Error: mixin mdl.cfuncR!().impl!(foo, bar).impl!(bar) 
error instantiating
mdl.d(23): Error: mixin mdl.cfuncR!().impl!(foo, bar) error 
instantiating
mdl.d(19): Error: mixin mdl.cfuncR!() error instantiating
Failed: ["dmd", "-v", "-o-", "mdl.d", "-I."]

I think 'template instance std.traits.ReturnType!(foo) does not 
match template declaration' because 'foo' is '_error_' on it's 
instancing moment. But I don't understand why 'foo' is '_error_'.

But if I replace '%1$s' in building function name to '_%1$s' 
pragma(msg, foo) works normal and compiler behavior is 
predictable (defined '_foo', but 'foo' has no body and can't 
linked):

/usr/include/dmd/phobos/std/traits.d-mixin-7671(7671): 
Deprecation: mdl.object is not visible from module traits
/usr/include/dmd/phobos/std/traits.d-mixin-7671(7671): 
Deprecation: mdl.std is not visible from module traits
int(int)
int(int)
/usr/include/dmd/phobos/std/traits.d-mixin-7671(7671): 
Deprecation: mdl.object is not visible from module traits
/usr/include/dmd/phobos/std/traits.d-mixin-7671(7671): 
Deprecation: mdl.std is not visible from module traits
int(int)
int(int)
/tmp/.rdmd-1000/rdmd-mdl.d-9F3ADBC813DCE463C0EFA2CA038B009E/objs/mdl.o: In
function `_Dmain':
mdl.d:(.text._Dmain+0xa): undefined reference to `_D3mdl3fooFiZi'
collect2: error: ld returned 1 exit status
Error: linker exited with status 1

But if I wrote this code by hands:

ReturnType!foo foo(Parameters!foo vals) { return vals[0] * 2; }
ReturnType!bar bar(Parameters!bar vals) { return vals[0] * 2; }

all works fine!!

What am I doing wrong?

dmd 2.074
ldc 1.3.0 (main compiler, because can cross compile to arm)
Aug 16
parent reply Meta <jared771 gmail.com> writes:
It's hard to tell offhand but I would recommend that you extract 
the inner string into a function that generates that string, 
allowing you to print out the finished product before mixing it 
in.
Aug 16
parent Oleg B <code.viator gmail.com> writes:
On Wednesday, 16 August 2017 at 22:48:59 UTC, Meta wrote:
 It's hard to tell offhand but I would recommend that you 
 extract the inner string into a function that generates that 
 string, allowing you to print out the finished product before 
 mixing it in.
It's have a same result...
Aug 17