// Step 3 void Process(Rule rule) { // Create $result variable if it was used bool usingResult = _data.OtherReferences.ContainsKey(_resultId) || _data.ProperLabels.TryGetValue(_result, false); if (usingResult && rule.ReturnType != null) { _data.ProperLabels[_result] = true; var type = rule.ReturnType; _newVarInitializers[_result] = Pair.Create(type, _codeGen.MakeInitializedVarDecl(type, false, _result)); } Visit(rule.Pred); if (_newVarInitializers.Count != 0) { var decls = _newVarInitializers.OrderBy(p => p.Key.Name).Select(p => p.Value.B); LNode decls2 = F.Call(S.Splice, decls); rule.Pred.PreAction = Pred.MergeActions(decls2, rule.Pred.PreAction); if (usingResult) { rule.Pred.PostAction = Pred.MergeActions(rule.Pred.PostAction, F.Call(S.Return, _resultId)); } } }
Pred ArgsToSeq(LNode expr, Context ctx) { List <object> objs = expr.Args.Select(node => AutoNodeToPred(node, ctx)).ToList(); Seq seq = new Seq(expr); LNode action = null; bool error = false; for (int i = 0; i < objs.Count; i++) { if (objs[i] is LNode) { var code = (LNode)objs[i]; if ((ctx == Context.And || ctx == Context.GateLeft) && !error) { error = true; _sink.Write(Severity.Error, objs[i], ctx == Context.And ? "Cannot use an action block inside an '&' or '!' predicate; these predicates are for prediction only." : "Cannot use an action block on the left side of a '=>' gate; the left side is for prediction only."); } action = Pred.MergeActions(action, code); } else // Pred { Pred pred = (Pred)objs[i]; pred.PreAction = Pred.MergeActions(action, pred.PreAction); action = null; seq.List.Add(pred); } } if (action != null) { seq.PostAction = action; } if (seq.List.Count == 1) { var contents = seq.List[0]; contents.PreAction = Pred.MergeActions(seq.PreAction, contents.PreAction); contents.PostAction = Pred.MergeActions(seq.PostAction, contents.PostAction); return(contents); } return(seq); }
public Seq(Pred one, Pred two, LNode basis = null) : base(basis) { if (one is Seq) { PreAction = one.PreAction; List.AddRange((one as Seq).List); if (List.Count > 0) { var last = List[List.Count - 1]; last.PostAction = Pred.MergeActions(last.PostAction, one.PostAction); } else { PreAction = Pred.MergeActions(PreAction, one.PostAction); } } else { List.Add(one); } if (two is Seq) { if (List.Count > 0) { var last = List[List.Count - 1]; last.PostAction = Pred.MergeActions(last.PostAction, two.PreAction); } else { PreAction = Pred.MergeActions(PreAction, two.PreAction); } List.AddRange((two as Seq).List); PostAction = Pred.MergeActions(PostAction, two.PostAction); } else { List.Add(two); } }