1 module epsilon.soag.protocol;
2 
3 import EAG = epsilon.eag;
4 import runtime;
5 import SOAG = epsilon.soag.soag;
6 import std.stdio;
7 
8 const standardLevel = 1;
9 const outRuleData = 2;
10 const outSymOccData = 3;
11 const outAffOccData = 4;
12 int Level;
13 File output;
14 
15 void WriteAffixVariables(int i) @safe
16 {
17     if (i < 0)
18     {
19         if (EAG.Var[-i].Num < 0)
20         {
21             output.write("!");
22         }
23         output.write(EAG.VarRepr(-i), EAG.Var[-i].Num);
24     }
25     else
26     {
27         for (int MA = 1; MA <= EAG.MAlt[EAG.NodeBuf[i]].Arity; ++MA)
28         {
29             WriteAffixVariables(EAG.NodeBuf[i + MA]);
30         }
31     }
32 }
33 
34 void WriteAffix(int i) @safe
35 {
36     if (i < 0)
37     {
38         if (EAG.Var[-i].Num < 0)
39         {
40             output.write("!");
41         }
42         output.write(EAG.VarRepr(-i), "(", EAG.Var[-i].Num, ") ");
43     }
44     else
45     {
46         int a = 0;
47         int m = EAG.MAlt[EAG.NodeBuf[i]].Right;
48 
49         while (EAG.MembBuf[m] != EAG.nil)
50         {
51             if (EAG.MembBuf[m] < 0)
52             {
53                 output.write(EAG.symbolTable.symbol(EAG.MTerm[-EAG.MembBuf[m]].Id), " ");
54             }
55             else
56             {
57                 ++a;
58                 WriteAffix(EAG.NodeBuf[i + a]);
59             }
60             ++m;
61         }
62     }
63 }
64 
65 void WriteAffOcc(int a) @safe
66 {
67     int p;
68     p = SOAG.AffOcc[a].ParamBufInd;
69     output.write(EAG.ParamBuf[p].isDef ? "-" : "+");
70     if (EAG.ParamBuf[p].Affixform < 0)
71     {
72         output.write(EAG.VarRepr(-EAG.ParamBuf[p].Affixform));
73         output.write("(", EAG.Var[-EAG.ParamBuf[p].Affixform].Num, ") ");
74     }
75     else
76     {
77         WriteAffix(EAG.ParamBuf[p].Affixform);
78     }
79     if (EAG.ParamBuf[p + 1].Affixform != EAG.nil)
80         output.write(", ");
81 }
82 
83 void WriteSymOcc(int s) @safe
84 {
85     output.write(EAG.HNontRepr(SOAG.SymOcc[s].SymInd));
86     output.write("< ");
87     for (int i = SOAG.SymOcc[s].AffOcc.Beg; i <= SOAG.SymOcc[s].AffOcc.End; ++i)
88     {
89         WriteAffOcc(i);
90     }
91     output.write(" >");
92     output.flush;
93 }
94 
95 void WriteAffOccData(int s) @safe
96 {
97     output.write("AffOcc[", s, "]: ");
98     WriteAffOcc(s);
99     output.writeln;
100     output.write("  Variables: ");
101     WriteAffixVariables(EAG.ParamBuf[SOAG.AffOcc[s].ParamBufInd].Affixform);
102     output.writeln;
103     output.write("         ParamBufInd: ");
104     output.write(SOAG.AffOcc[s].ParamBufInd);
105     output.writeln;
106     output.write("           SymOccInd: ");
107     output.write(SOAG.AffOcc[s].SymOccInd);
108     output.writeln;
109     output.write("    AffOccNum.InRule: ");
110     output.write(SOAG.AffOcc[s].AffOccNum.InRule);
111     output.writeln;
112     output.write("     AffOccNum.InSym: ");
113     output.write(SOAG.AffOcc[s].AffOccNum.InSym);
114     output.writeln;
115 }
116 
117 void WriteSymOccData(int s) @safe
118 {
119     output.write("SymOcc[", s, "]: ");
120     WriteSymOcc(s);
121     output.writeln;
122     output.writeln("         SymInd: ", SOAG.SymOcc[s].SymInd);
123     output.writeln("        RuleInd: ", SOAG.SymOcc[s].RuleInd);
124     output.writeln("           Next: ", SOAG.SymOcc[s].Next);
125     output.writeln("     AffOcc.Beg: ", SOAG.SymOcc[s].AffOcc.Beg);
126     output.writeln("           .End: ", SOAG.SymOcc[s].AffOcc.End);
127 }
128 
129 void WriteRuleData(int r) @safe
130 {
131     output.writeln("Rule[", r, "]:");
132     output.writeln("     SymOcc.Beg: ", SOAG.Rule[r].SymOcc.Beg);
133     output.writeln("           .End: ", SOAG.Rule[r].SymOcc.End);
134     output.writeln("     AffOcc.Beg: ", SOAG.Rule[r].AffOcc.Beg);
135     output.writeln("           .End: ", SOAG.Rule[r].AffOcc.End);
136 }
137 
138 void WriteRule(int r) @safe
139 {
140     output.write("Rule ", r, " : ");
141     for (int i = SOAG.Rule[r].SymOcc.Beg; i <= SOAG.Rule[r].SymOcc.End; ++i)
142     {
143         WriteSymOcc(i);
144         if (i == SOAG.Rule[r].SymOcc.Beg)
145         {
146             output.write(" : ");
147         }
148     }
149     output.writeln(".");
150     if (Level >= outRuleData)
151     {
152         WriteRuleData(r);
153     }
154     if (Level >= outSymOccData)
155     {
156         for (int i = SOAG.Rule[r].SymOcc.Beg; i <= SOAG.Rule[r].SymOcc.End; ++i)
157         {
158             WriteSymOccData(i);
159         }
160     }
161     if (Level >= outAffOccData)
162     {
163         for (int i = SOAG.Rule[r].AffOcc.Beg; i <= SOAG.Rule[r].AffOcc.End; ++i)
164         {
165             WriteAffOccData(i);
166         }
167     }
168 }
169 
170 void WriteRules() @safe
171 {
172     output.flush;
173     for (int i = SOAG.firstRule; i < SOAG.NextRule; ++i)
174     {
175         WriteRule(i);
176         output.flush;
177     }
178 }
179 
180 void WriteRulesL2() @safe
181 {
182     Level = outRuleData;
183     WriteRules;
184 }
185 
186 void WriteRulesL3() @safe
187 {
188     Level = outSymOccData;
189     WriteRules;
190 }
191 
192 void WriteRulesL4() @safe
193 {
194     Level = outAffOccData;
195     WriteRules;
196 }
197 
198 void WriteSymOccs() @safe
199 {
200     for (int i = SOAG.firstSymOcc; i < SOAG.NextSymOcc; ++i)
201     {
202         WriteSymOccData(i);
203         output.flush;
204     }
205 }
206 
207 void WriteAffOccs() @safe
208 {
209     for (int i = SOAG.firstAffOcc; i < SOAG.NextAffOcc; ++i)
210     {
211         WriteAffOccData(i);
212         output.flush;
213     }
214 }
215 
216 void WriteTDP(int r)
217 {
218     if (SOAG.IsEvaluatorRule(r))
219     {
220         for (int i = SOAG.Rule[r].AffOcc.Beg; i <= SOAG.Rule[r].AffOcc.End; ++i)
221         {
222             output.write(i - SOAG.Rule[r].AffOcc.Beg);
223             output.write(" | ");
224             output.write(EAG.ParamBuf[SOAG.AffOcc[i].ParamBufInd].isDef ? "DEF " : "APPL");
225             output.write(" | ");
226             output.write(EAG.HNontRepr(SOAG.SymOcc[SOAG.AffOcc[i].SymOccInd].SymInd));
227             output.write(" | {");
228             for (int j = SOAG.Rule[r].AffOcc.Beg; j <= SOAG.Rule[r].AffOcc.End; ++j)
229             {
230                 if (SOAG.Rule[r].TDP[SOAG.AffOcc[i].AffOccNum.InRule][SOAG.AffOcc[j].AffOccNum.InRule])
231                     output.write(SOAG.AffOcc[j].AffOccNum.InRule, " ");
232             }
233             output.writeln("}");
234         }
235     }
236     else
237     {
238         output.writeln(r, " is not an evaluator rule");
239     }
240 }
241 
242 void WriteTDPs()
243 {
244     for (int i = SOAG.firstRule; i < SOAG.NextRule; ++i)
245     {
246         WriteRule(i);
247         WriteTDP(i);
248     }
249 }
250 
251 void WriteVSRule(int R) @safe
252 {
253     if (SOAG.Rule[R].VS.Beg > SOAG.Rule[R].VS.End)
254     {
255         output.write("keine Visit-Sequenzen; Regel: ", R);
256     }
257     else
258     {
259         foreach (i; SOAG.Rule[R].VS.Beg .. SOAG.Rule[R].VS.End + 1)
260         {
261             SOAG.Instruction I = SOAG.VS[i];
262 
263             if (auto visit = cast(SOAG.Visit) I)
264             {
265                 output.write("Visit;   SymOcc: ", visit.SymOcc);
266                 output.write(" VisitNo: ", visit.VisitNo);
267             }
268             else if (auto leave = cast(SOAG.Leave) I)
269             {
270                 output.write("Leave; SymOcc: ");
271                 output.write(" VisitNo: ", leave.VisitNo);
272             }
273             else if (auto call = cast(SOAG.Call) I)
274             {
275                 output.write("Call; SymOcc: ", call.SymOcc);
276             }
277             else
278             {
279                 output.write("NOP;");
280             }
281             output.writeln;
282             output.flush;
283         }
284     }
285 }
286 
287 void WriteVS() @safe
288 {
289     foreach (r; SOAG.firstRule .. SOAG.NextRule)
290     {
291         WriteVSRule(r);
292         output.writeln;
293         output.flush;
294     }
295 }
296 
297 void CheckVS() @safe
298 {
299     bool found = false;
300 
301     foreach (r; SOAG.firstRule .. SOAG.NextRule)
302     {
303         foreach (i; SOAG.Rule[r].VS.Beg .. SOAG.Rule[r].VS.End + 1)
304         {
305             foreach (j; SOAG.Rule[r].VS.Beg .. SOAG.Rule[r].VS.End + 1)
306             {
307                 if (i != j)
308                 {
309                     if (SOAG.isEqual(SOAG.VS[i], SOAG.VS[j]))
310                     {
311                         found = true;
312                         output.writeln("Doppelter VS-Eintrag:");
313                         output.writeln("Regel: ", r);
314                         WriteVSRule(r);
315                     }
316                 }
317             }
318         }
319     }
320     if (!found)
321         output.writeln("kein Doppelter VS-Eintrag gefunden.");
322 }
323 
324 void WriteAffPos(int SymInd) @safe
325 {
326     for (int i = SOAG.Sym[SymInd].AffPos.Beg; i <= SOAG.Sym[SymInd].AffPos.End; ++i)
327     {
328         output.writeln("  AffixPos", i);
329         output.write("    PartNum: ", SOAG.PartNum[i]);
330         if (SOAG.StorageName != null)
331         {
332             output.write("    StorageType: ");
333             if (SOAG.StorageName[i] < 0)
334                 output.write("GlobalVar", -SOAG.StorageName[i]);
335             else if (SOAG.StorageName[i] > 0)
336                 output.write("Stack", SOAG.StorageName[i]);
337             else
338                 output.write("normal");
339         }
340         output.writeln;
341     }
342 }
343 
344 void WriteSym(int S) @safe
345 {
346     output.writeln("Symbol ", EAG.HNontRepr(S), ":");
347     output.writeln("  FirstOcc: ", SOAG.Sym[S].FirstOcc);
348     WriteAffPos(S);
349     output.writeln("  MaxPart: ", SOAG.Sym[S].MaxPart);
350 }
351 
352 void WriteSyms() @safe
353 {
354     foreach (i; SOAG.firstSym .. SOAG.NextSym)
355         WriteSym(i);
356 }
357 
358 static this() nothrow
359 {
360     output = stdout;
361     Level = standardLevel;
362 }