1 /// Author: Aziz Köksal 2 /// License: GPL3 3 /// $(Maturity low) 4 module dil.ast.Meta; 5 6 import dil.String; 7 import common; 8 9 /// Generates code declaring variables with the correct type and value, 10 /// which are then passed on to ctor(). 11 /// 12 /// E.g.: makeNewClass("Expression", "Token*") 13 /// --- 14 /// assert(argtypes.length == args.length); 15 /// assert(argtypes.length == 2); 16 /// assert(argtypes[0] == typeid(Expression)); 17 /// auto _0 = *cast(Expression*)args[0]; 18 /// assert(argtypes[1] == typeid(Token*)); 19 /// auto _1 = *cast(Token**)args[1]; 20 /// auto node = ctor(_0,_1,); 21 /// --- 22 char[] makeNewClass(cstring[] argtypes) 23 { 24 char[] args = "assert(argtypes.length == args.length);\n" ~ 25 "assert(argtypes.length == " ~ itoa(argtypes.length) ~ ");\n"; 26 char[] ctorArgs; 27 foreach (i, t; argtypes) 28 { 29 auto istr = itoa(i); 30 args ~= 31 "assert(argtypes[" ~ istr ~ "] == typeid(" ~ t ~ "));\n" ~ 32 "auto _" ~ istr ~ " = *cast(" ~ t ~ "*)args[" ~ istr ~ "];\n"; 33 ctorArgs ~= "_" ~ istr ~ ","; 34 } 35 return args ~ "auto node = ctor(" ~ ctorArgs ~ ");"; 36 } 37 38 //pragma(msg, makeNewClass(["A","B","C"])); 39 40 /// Provides functions for constructing a class from run-time arguments. 41 mixin template createMethod() 42 { 43 alias Class = typeof(this); 44 45 static Class ctor(Class.CTTI_Types args) 46 { 47 return new Class(args); 48 } 49 50 static Class create(TypeInfo[] argtypes, void*[] args) 51 { 52 mixin(makeNewClass(Class.CTTI_TypeStrs)); 53 return node; 54 } 55 } 56 57 /// Provides a collection of methods. 58 mixin template methods() 59 { 60 mixin copyMethod; 61 mixin createMethod; 62 } 63 64 /// Generates information on Node members, which is used to generate code 65 /// for copying or visiting methods. 66 /// 67 /// E.g.: 68 /// --- 69 /// static enum CTTI_Members = ["una","args",]; 70 /// static enum CTTI_MayBeNull = [false,true,]; 71 /// static alias CTTI_Types = Tuple!(typeof(una),typeof(args),); 72 /// static enum CTTI_TypeStrs = [typeof(una).stringof,typeof(args).stringof,]; 73 /// --- 74 char[] memberInfo(string[] members...) 75 { 76 char[] names, mayBeNull, types, typeStrs; 77 foreach (m; members) 78 { 79 auto isOpt = m[$-1] == '?'; 80 m = isOpt ? m[0..$-1] : m; // Strip '?'. 81 names ~= '"' ~ m ~ `",`; 82 mayBeNull ~= (isOpt ? "true" : "false") ~ ","; 83 types ~= "typeof(" ~ m ~ "),"; 84 typeStrs ~= "typeof(" ~ m ~ ").stringof,"; 85 } 86 return "static enum CTTI_Members = [" ~ names ~ "];\n" ~ 87 "static enum CTTI_MayBeNull = [" ~ mayBeNull ~ "];\n" ~ 88 "static alias CTTI_Types = Tuple!(" ~ types ~ ");\n" ~ 89 "static enum CTTI_TypeStrs = [" ~ typeStrs ~ "];\n"; 90 } 91 92 //pragma(msg, memberInfo("una", "args?"));