Variable references in strings (Was: Structs implementing interfaces in D1)

grauzone none at example.net
Tue Feb 10 03:16:55 PST 2009


Ary Borenszweig wrote:
> Tom S escribió:
>> /** Just a simple hack to have interfaces implemented by structs ... 
>> because I can :P
>> Tested on DMD 1.039 [win32], GDC (various versions) [linux32] and 
>> codepad.org
>>
>> Output:
>>
>> Entering main
>> Foo.func1 called ; val1 = 3.141590, val2 = Hello, world!
>> Foo.func2 called ; val1 = 3.141590, val2 = Hello, world!
>> Foo.func2 called ; val1 = 3.141590, val2 = Hello, world!
>> Foo.func3 called ; val1 = 3.141590, val2 = Hello, world! ; p1 = 123, 
>> p2 = some parameter
>> Leaving main
>> */
>>
>>
>> module structIface;
>>
>> extern (C) int printf(char*, ...);
>>
>>
>>
>> // ---- evil implementation
>> char[] structImplementInterface(char[] iface, char[][] funcs) {
>>     char[] res = "private {";
>>     res ~= \n"alias typeof(*this) _iface_"~iface~"_ThisType;";
>>
>>     foreach (func; funcs) {
>>         res ~= \n"static assert (is(typeof(&"~iface~".init."~func~")),
>>             `The interface "~iface~" doesn't declare a '"~func~"' 
>> function, `
>>             `thus struct `~_iface_"~iface~"_ThisType.stringof~` cannot 
>> implement it`);";
>>         res ~= \n"static void _iface_" ~ iface ~ "_func_" ~ func ~ "() 
>> {";
>>         version (GNU) {
>>             res ~= \n\t"asm { naked; sub dword ptr 4[ESP], _iface_" ~ 
>> iface ~ "_vtbl.offsetof; jmp " ~ func ~ "; }";
>>         } else {
>>             res ~= \n\t"asm { naked; sub EAX, _iface_" ~ iface ~ 
>> "_vtbl.offsetof; jmp " ~ func ~ "; }";
>>         }
>>         res ~= \n"}";
>>     }
>>     res ~= \n ~ iface ~ " as" ~ iface ~ "() {";
>>     res ~= \n\t"return cast("~iface~")cast(void*)&_iface_" ~ iface ~ 
>> "_vtbl;";
>>     res ~= \n"}";
>>
>>     res ~= \n"void** _iface_" ~ iface ~ "_vtbl = cast(void**)([";
>>     res ~= \n\t"null";        // for classinfo
>>     foreach (func; funcs) {
>>         res ~= ",\n\tcast(void*)&Foo._iface_" ~ iface ~ "_func_" ~ func;
>>     }
>>     res ~= \n"]).ptr;";
>>     res ~= "}";
>>
>>     return res;
>> }
>> // ---- end of the evil implementation
> 
> Since a lot of compile stuff is done via strings, I wish you could do 
> somehing like this in D (like in PHP):
> 
> res ~= res ~= "\n\treturn cast(${iface})cast(void*)&_iface_${iface}_vtbl;";
> 
> Much nicer and understandable. And I think it's not hard to implement: 
> when doing semantic for a string like that, parse it and search the 
> variables in the current scope and upwards (as a usual search). For this 
> to work, primitives should have a string representation, and if it's a 
> class or struct, then toString() is invoked.
> 
> It's really hard to follow a code like that, with thousands of "~".
> 
> And maybe this should only be done for strings enclosed in `, so that 
> the search is not always done.

Macros are supposed to solve that. D1.0 even has a "macro" keyword, but 
so far macros are just vaporware.



More information about the Digitalmars-d mailing list