public override void GenerateAbstractCode(List <C.CsStmt> code) { HandleAction tmp; if (!String.IsNullOrEmpty(Flag)) { tmp = new LiftFlag { Flag = Flag }; tmp.GenerateAbstractCode(code); } code.Add(new C.SimpleStmt($"List<{Name}> {Target} = new List<{Name}>()")); var lambda = new C.ScheduleStmt(Name, "_" + Target); var ite = new C.IfThenElse(); var cond = $"_{Target} == null"; ite.AddBranch(cond); BaseAction?.GenerateAbstractCode(ite.GetThenBranch(cond)); if (!String.IsNullOrEmpty(Flag)) { tmp = new DropFlag { Flag = Flag }; tmp.GenerateAbstractCode(lambda.Code); } ite.AddToBranch(cond, "return Message.Perfect"); lambda.AddCode(ite); lambda.AddCode($"var {Target}1 = _{Target} as {Name};"); lambda.AddCode($"{Target}.Add({Target}1)"); lambda.AddCode("return Message.Consume"); code.Add(lambda); }
public override void GenerateAbstractCode(List <C.CsStmt> code) { // initialise lists GenerateInitialisationCode(code); foreach (var sa in SiblingActions) { if (sa is PopSeveral ps) { ps.GenerateInitialisationCode(code); } } var loop = new C.WhileStmt(); loop.Condition = "Main.Count > 0"; var ite = new C.IfThenElse($"Main.Peek() is {Name}", $"{Target}.Add(Main.Pop() as {Name})"); foreach (var sa in SiblingActions) { if (sa is PopSeveral ps) { ite.AddBranch($"Main.Peek() is {ps.Name}", $"{ps.Target}.Add(Main.Pop() as {ps.Name})"); } } ite.ElseBranch.Add(new C.SimpleStmt("break")); loop.Code.Add(ite); code.Add(loop); // reverse the order because of stack vs list differences code.Add(new C.SimpleStmt($"{Target}.Reverse()")); foreach (var sa in SiblingActions) { if (sa is PopSeveral ps) { code.Add(new C.SimpleStmt($"{ps.Target}.Reverse()")); } } // produce the rest of the code (usually push new) foreach (var sa in SiblingActions) { if (!(sa is PopSeveral)) { sa.GenerateAbstractCode(code); } } }
private static void GenerateLexBranch(SwitchCaseStmt swLex, string hpk, IReadOnlyList <string> guardFlags, IReadOnlyList <List <HandleAction> > recipes, TokenPlan reactOn, bool matchChar) { var branchLex = new List <C.CsStmt>(); Console.WriteLine($"[IR] in '{hpk}', handle {reactOn.Value}"); bool onlyWraps = true; var ite = new C.IfThenElse(); for (int i = 0; i < guardFlags.Count; i++) { if (!String.IsNullOrEmpty(guardFlags[i])) { ite.AddBranch(guardFlags[i]); } var target = String.IsNullOrEmpty(guardFlags[i]) ? branchLex : ite.GetThenBranch(guardFlags[i]); foreach (var action in recipes[i]) { if (!(action is WrapOne)) { onlyWraps = false; } if (action != null) { if (action is WrapOne) { var fake = new List <CsStmt>(); action.GenerateAbstractCode(fake); if (fake.Count == 1 && fake[0] is IfThenElse ite2) { var newcond = guardFlags[i] + " && " + ite2.FirstThenBranchKey(); ite.RenameBranch(guardFlags[i], newcond); foreach (CsStmt stmt in ite2.FirstThenBranchValue()) { ite.AddToBranch(newcond, stmt); } } else { Console.WriteLine("[ERR] This particular usage of WRAP is not supported yet"); } } else { action.GenerateAbstractCode(target); } } else { Console.WriteLine($"[B2C] Warning: no action to handle '{hpk}'/{reactOn.Value}"); } } } string flags; if (guardFlags.Count == 1) { flags = "flag " + guardFlags[0] + " is not"; } else { flags = "neither of the flags " + String.Join(", ", guardFlags) + " are"; } branchLex.Add(ite); if (!onlyWraps) { if (guardFlags.Any(f => !String.IsNullOrEmpty(f))) { ite.AddElse($"ERROR = \"{flags} lifted when expected\""); } } if (matchChar) { swLex.Branches["'" + reactOn.Value + "'"] = branchLex; } else { swLex.Branches['"' + reactOn.Value + '"'] = branchLex; } }