internal override void WriteCode(bool writeState, Action <string> WriteLine, Func <TERM, string> DescribeCond, Func <TERM, string> DescribeReg, Func <Sequence <TERM>, string> DescribeYields, string errorCase) { var caseCodes = new Dictionary <string, string>(); var caseCodesInv = new Dictionary <string, HashSet <string> >(); string defaultCode; var caseVals = new List <string>(); StringBuilder defaultCodeSB = new StringBuilder(); defaultcase.WriteCode(writeState, x => { defaultCodeSB.AppendLine(x); return; }, DescribeCond, DescribeReg, DescribeYields, errorCase); defaultCode = defaultCodeSB.ToString(); foreach (var c in cases) { string v = DescribeCond(c.Key); if (caseCodes.ContainsKey(v)) { throw new AutomataException(AutomataExceptionKind.InvalidSwitchCase); } caseVals.Add(v); StringBuilder caseSB = new StringBuilder(); c.Value.WriteCode(writeState, x => { caseSB.AppendLine(x); return; }, DescribeCond, DescribeReg, DescribeYields, errorCase); var caseStr = caseSB.ToString(); caseCodes.Add(v, caseStr); if (!caseCodesInv.ContainsKey(caseStr)) { caseCodesInv[caseStr] = new HashSet <string>(); } caseCodesInv[caseStr].Add(v); } string inp = DescribeCond(input); HashSet <string> covered = new HashSet <string>(); WriteLine("switch (" + inp + "){"); foreach (var v in caseVals) { if (covered.Contains(v)) { continue; } string caseCode = caseCodes[v]; covered.Add(v); covered.UnionWith(caseCodesInv[caseCode]); foreach (var w in caseCodesInv[caseCode]) { WriteLine("case (" + w + "):"); } WriteLine("{" + caseCode + " break;}"); } WriteLine("default:"); WriteLine("{" + defaultCode + " break;}"); WriteLine("}"); //end of switch }
internal override void WriteCode(bool writeState, Action <string> WriteLine, Func <TERM, string> DescribeCond, Func <TERM, string> DescribeReg, Func <Sequence <TERM>, string> DescribeYields, string errorCase) { StringBuilder sb_t = new StringBuilder(); StringBuilder sb_f = new StringBuilder(); trueCase.WriteCode(writeState, (x => { sb_t.AppendLine(x); }), DescribeCond, DescribeReg, DescribeYields, errorCase); falseCase.WriteCode(writeState, (x => { sb_f.AppendLine(x); }), DescribeCond, DescribeReg, DescribeYields, errorCase); var t_str = sb_t.ToString(); var f_str = sb_f.ToString(); if (t_str.Equals(f_str)) { WriteLine(t_str); } else { string condStr = DescribeCond(condition); WriteLine("if (" + condStr + ") {"); WriteLine(t_str + "} else {"); WriteLine(f_str + "}"); } }