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 }