1 module metad.interp; 2 3 private import pegged.grammar; 4 5 private import std.variant; 6 private import std.typecons; 7 private import std.algorithm; 8 9 private import metad.compiler; 10 11 /++ 12 + The run-time verstion of the meta-compiler (meta-compiler). 13 +/ 14 15 template loadGrammarAndData(string grammarFile,string docRoot) { 16 mixin loadGrammar!(grammmarFile,docRoot); 17 auto loadGrammarAndData(string dataString) { 18 return parser(dataString); 19 } 20 } 21 22 template loadAndInterpret(string grammarFile,string docRoot,alias _Interpreter) { 23 auto loadAndInterpret(string data) { 24 auto _data = loadGrammarAndData(grammarFile,docRoot)(data); 25 return Interpreter!(_Interpreter)(_data); 26 } 27 } 28 29 template Interpreter(N) { 30 static Variant[] interpChildNodes(N nodes,ParseTree t) { 31 Variant[] result; 32 foreach(x;t.children) { 33 result~=Interpreter!N(nodes,x); 34 } 35 return result; 36 } 37 Variant[] Interpreter(N nodes,ParseTree data) { 38 if(data.name in nodes) { 39 return [nodes[data.name](data)]; 40 } 41 return interpChildNodes(nodes,data); 42 } 43 } 44 45 unittest { 46 import std.array; 47 import std.typecons; 48 import std..string; 49 import std.algorithm; 50 import std.stdio; 51 52 import pegged.grammar; 53 54 // A grammar that parses {{Template}} 55 // statements in a body of text. 56 enum _g = q{ 57 GRAMMAR(Template): 58 Doc <- Line+ :endOfInput 59 Line <- (Var / Text) 60 Var <- :LDelim ^Template :RDelim 61 LDelim <- "{{" 62 RDelim <- "}}" 63 Text <- ~((!LDelim) Char )* 64 Char <- . 65 }; 66 mixin(grammar(_g)); 67 68 // Replace these identifiers in the input 69 enum __M = "MyStruct"; 70 enum __T = "MyType"; 71 72 // some input data. 73 enum _d = q{ 74 struct {{__T}} { 75 enum v = 'v'; 76 struct {{__M}} { 77 }; 78 static {{__M}} m; 79 }; 80 }; 81 static string idParser(string s) { 82 writeln("idParser" ~ s); 83 if(s=="__T") { 84 return __T; 85 } else if (s=="__M") { 86 return __M; 87 } 88 return s; 89 } 90 // Create a compiler from the parse tree. 91 auto myInterpreter(ParseTree t) { 92 Variant delegate(ParseTree)[string] nodes; 93 //nodes["GRAMMAR.Var"] = f=>idParser(f.children[1].matches); 94 nodes["GRAMMAR.LDelim"] = f=>Variant(); 95 nodes["GRAMMAR.RDelim"] = f=>Variant(); 96 nodes["GRAMMAR.Text"] = f=>Variant(f.matches.join("")); 97 nodes["identifier"] = (f)=>Variant(idParser(f.matches.join(""))); 98 99 return Interpreter(nodes,t); 100 } 101 auto interp = myInterpreter(GRAMMAR!identifier(_d)); 102 103 import std.conv; 104 auto interpString = interp.map!(x=>x.to!string).join(""); 105 auto expected = _d.replace("{{__T}}",__T).replace("{{__M}}",__M); 106 assert(interpString == expected,"Expected: "~expected ~ "\nGot: "~interpString); 107 }