/// <summary> /// Get called tactic /// </summary> /// <param name="aps"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"> </exception> /// <exception cref="ArgumentException"> Provided ApplySuffix is not a tactic application</exception> public ITactic GetTactic(ApplySuffix aps) { Contract.Requires(aps != null); Contract.Requires(IsTacticCall(aps)); Contract.Ensures(Contract.Result <ITactic>() != null); return(GetTactic(Util.GetSignature(aps))); }
public static Statement UnfoldTacticExprInStmt(ProofState ps, Statement stmt, ApplySuffix aps, Expression code) { var unfolder = new TacticAppUnfolder(ps, aps, code); return(unfolder.CloneStmt(stmt)); }
public static Expression UnfoldFunction(ApplySuffix aps, ProofState ps) { if (aps.Lhs is NameSegment && ps.Members.ContainsKey((aps.Lhs as NameSegment).Name) && ps.Members[(aps.Lhs as NameSegment).Name] is Function) { var src = ps.Members[(aps.Lhs as NameSegment).Name] as Function; if (src.Formals.Count == aps.Args.Count) { //for the case when there is no arguemnt, just return a cloned body of the function if (src.Formals.Count == 0) { return(new Cloner().CloneExpr(src.Body)); } //for the cases with arguemnts. add arg to the dic var inster = new InstVar(); for (var i = 0; i < src.Formals.Count; i++) { inster._inst.Add(src.Formals[i].Name, aps.Args[i]); } return(inster.CloneExpr(src.Body)); } } ps.ReportTacticError(aps.tok, Printer.ExprToString(aps) + " can not be unfolded."); return(new Cloner().CloneExpr(aps)); }
public static Atomic GetAtomicType(ApplySuffix aps) { if (aps == null) { return(Atomic.Undefined); } return(GetAtomicType(aps.Lhs.tok)); }
public override Expression CloneApplySuffix(ApplySuffix e) { if (e.tok.pos == _aps.tok.pos) { return(_destExpr); } return(base.CloneApplySuffix(e)); }
public virtual void Visit(ApplySuffix applySuffix) { Visit(applySuffix.Lhs); foreach (var argument in applySuffix.Args) { Visit(argument); } }
private UpdateStmt GenUpdateStmt(ApplySuffix aps) { Contract.Requires(aps != null); return(new UpdateStmt(aps.tok, aps.tok, new List <Expression>(), new List <AssignmentRhs>() { new ExprRhs(aps) })); }
public override Expression CloneApplySuffix(ApplySuffix e) { if (_state.IsTacticCall(e)) { _aps = base.CloneApplySuffix(e) as ApplySuffix; return(_aps); } return(base.CloneApplySuffix(e)); }
public string GenerateConditionString(ApplySuffix expression, IDictionary <string, string> rename) { var left = GenerateConditionString(expression.Lhs, rename); var self = expression.tok.val; var rightNames = expression.Args.Select(a => GenerateConditionString(a, rename)); var right = String.Join(", ", rightNames); var close = ")"; return(left + self + right + close); }
public string GenerateString(ApplySuffix expression) { var left = GenerateString(expression.Lhs); var self = expression.tok.val; var rightNames = expression.Args.Select(a => GenerateString(a)); var right = String.Join(", ", rightNames); var close = ")"; return(left + self + right + close); }
public bool IsInlineTacticCall(ApplySuffix aps) { Contract.Requires(aps != null); var name = Util.GetSignature(aps); if (name == null) { return(false); } return(ContainInlineTactic(name)); }
private void UndfoldTacticCall(Statement stmt, ApplySuffix aps, Dictionary <IVariable, Type> varList) { // this is a top level tactic call if (IfEvalTac) { _branches.Add( TacnyInterpreter.EvalTopLevelTactic(_state.Copy(), varList, stmt, aps, _errorReporterDelegate, _state.TargetMethod.CallsTactic != _tacticCalls + 1)); _tacticCalls++; } }
public static string GetSignature(UpdateStmt us) { ExprRhs er = us.Rhss[0] as ExprRhs; if (er == null) { return(null); } ApplySuffix asx = er.Expr as ApplySuffix; return(GetSignature(asx)); }
private TriggerAnnotation AnnotateApplySuffix(ApplySuffix expr) { // This is a bit tricky. A funcall node is generally meaningful as a trigger candidate, // but when it's part of an ApplySuffix the function call itself may not resolve properly // when the second round of resolving is done after modules are duplicated. // Thus first we annotate expr and create a trigger candidate, and then we remove the // candidate matching its direct subexpression if needed. Note that function calls are not the // only possible child here; there can be DatatypeValue nodes, for example (see vstte2012/Combinators.dfy). var annotation = AnnotatePotentialCandidate(expr); // Comparing by reference is fine here. Using sets could yield a small speedup annotation.ExportedTerms.RemoveAll(term => expr.SubExpressions.Contains(term.Expr)); return annotation; }
public static NameSegment GetNameSegment(ApplySuffix aps) { Contract.Requires <ArgumentNullException>(aps != null, "aps"); var lhs = aps.Lhs as ExprDotName; if (lhs == null) { return(aps?.Lhs as NameSegment); } var edn = lhs; return(edn.Lhs as NameSegment); }
public override Expression CloneApplySuffix(ApplySuffix e) { if (IsEAtmoicCall(e)) { return(EvalEAtomExpr(e)); } else if (IsETacticCall(e)) { return(EvalETacticCall(e) as Expression); } else { return(base.CloneApplySuffix(e)); } }
public static bool CheckTacticArgs(ITactic tac, ApplySuffix aps, ProofState state, out string errMsg) { Contract.Requires(tac != null); Contract.Requires(aps != null); if (aps.Args.Count != tac.Ins.Count) { errMsg = "The number of args doesn't match the tactic definition for " + Printer.ExprToString(aps); return(false); } for (var i = 0; i < tac.Ins.Count; i++) { var name = tac.Ins[i].Type is UserDefinedType ? (tac.Ins[i].Type as UserDefinedType).Name : tac.Ins[i].Type.ToString(); switch (name) { case "bool": case "int": if (!(aps.Args[i] is NameSegment) || tac.Ins[i].Type.ToString() != aps.Args[i].Type.ToString()) { errMsg = "In arg[" + i + "], expect " + tac.Ins[i].Type + " but " + aps.Args[i] + " is found"; return(false); } break; case "term": break; case "tac": if (!CheckTypeTac(tac.Ins[i].Type as UserDefinedType, (aps.Args[i] as NameSegment).Name, state, out errMsg)) { return(false); } break; default: break; } } errMsg = ""; return(true); }
public static void renameBody(Microsoft.Dafny.Expression expr, Dictionary <string, string> rename) { if (expr == null) { return; } if (expr is ApplySuffix) { List <Microsoft.Dafny.Expression> x = new List <Microsoft.Dafny.Expression>(((ApplySuffix)expr).Args); x.ForEach(m => renameBody(m, rename)); expr = new ApplySuffix(expr.tok, ((ApplySuffix)expr).Lhs, x); } else if (expr is NameSegment) { //if (rename.ContainsKey(((NameSegment)expr).Name)) ((NameSegment)expr).Name = rename[((NameSegment)expr).Name]; } else if (expr is BinaryExpr) { renameBody(((BinaryExpr)expr).E0, rename); renameBody(((BinaryExpr)expr).E1, rename); } else if (expr is UnaryExpr) { renameBody(((UnaryExpr)expr).E, rename); } else if (expr is ChainingExpression) { renameBody(((ChainingExpression)expr).E, rename); } else if (expr is SeqSelectExpr) { renameBody(((SeqSelectExpr)expr).Seq, rename); renameBody(((SeqSelectExpr)expr).E0, rename); renameBody(((SeqSelectExpr)expr).E1, rename); } else if (expr is ParensExpression) { renameBody(((ParensExpression)expr).E, rename); } else if (expr is SeqDisplayExpr) { foreach (Microsoft.Dafny.Expression x in ((SeqDisplayExpr)expr).Elements) { renameBody(x, rename); } } }
public static void traverse(Microsoft.Dafny.Expression expr, Method me) { if (expr == null) { return; } if (expr is ApplySuffix) { List <Microsoft.Dafny.Expression> x = new List <Microsoft.Dafny.Expression>(((ApplySuffix)expr).Args); x.ForEach(m => traverse(m, me)); expr = new ApplySuffix(expr.tok, ((ApplySuffix)expr).Lhs, x); } else if (expr is NameSegment) { } else if (expr is BinaryExpr) { traverse(((BinaryExpr)expr).E0, me); traverse(((BinaryExpr)expr).E1, me); } else if (expr is UnaryExpr) { traverse(((UnaryExpr)expr).E, me); } else if (expr is ChainingExpression) { traverse(((ChainingExpression)expr).E, me); } else if (expr is SeqSelectExpr) { traverse(((SeqSelectExpr)expr).Seq, me); traverse(((SeqSelectExpr)expr).E0, me); traverse(((SeqSelectExpr)expr).E1, me); } else if (expr is ParensExpression) { traverse(((ParensExpression)expr).E, me); } else if (expr is SeqDisplayExpr) { foreach (Microsoft.Dafny.Expression x in ((SeqDisplayExpr)expr).Elements) { traverse(x, me); } } }
public ITactic GetTactic(ApplySuffix aps) { Contract.Requires(aps != null); Contract.Requires(IsTacticCall(aps)); Contract.Ensures(Contract.Result <ITactic>() != null); var name = Util.GetSignature(aps); if (ContainTVal(name)) { var nameSegment = GetTVarValue(name) as NameSegment; if (nameSegment != null) { name = nameSegment.Name; } } return(GetTactic(name)); }
private static void SetStatementName(Statement s, string oriName, string newName) { if (s is BlockStmt) { var s0 = s as BlockStmt; foreach (var ss in s0.Body) { SetStatementName(ss, oriName, newName); } } else if (s is MatchStmt) { var s0 = s as MatchStmt; foreach (var ss in s0.Cases) { foreach (var body in ss.Body) { SetStatementName(body, oriName, newName); } } } else if (s is UpdateStmt) { var ss = s as UpdateStmt; if (ss.Rhss != null) { foreach (var rhs in ss.Rhss) { Console.WriteLine("s"); if (rhs is ExprRhs && (rhs as ExprRhs).Expr is ApplySuffix && ((rhs as ExprRhs).Expr as ApplySuffix).Lhs is NameSegment && (((rhs as ExprRhs).Expr as ApplySuffix).Lhs as NameSegment).Name == oriName) { var oldAps = (rhs as ExprRhs).Expr as ApplySuffix; ApplySuffix aps = new ApplySuffix(oldAps.tok, new NameSegment(oldAps.tok, newName, null), oldAps.Args); (rhs as ExprRhs).Expr = aps; } } } } }
/// <summary> /// Deep copy updateStmt /// </summary> /// <param name="stmt"></param> /// <returns></returns> public static UpdateStmt CopyUpdateStmt(UpdateStmt stmt) { ExprRhs old_exp = stmt.Rhss[0] as ExprRhs; ApplySuffix old_aps = old_exp.Expr as ApplySuffix; LiteralExpr literal = old_exp.Expr as LiteralExpr; if (old_aps != null) { ApplySuffix aps = CopyExpression(old_aps) as ApplySuffix; return(new UpdateStmt(stmt.Tok, stmt.EndTok, CopyExpressionList(stmt.Lhss), new List <AssignmentRhs> { new ExprRhs(aps) })); } if (literal != null) { return(new UpdateStmt(stmt.Tok, stmt.EndTok, CopyExpressionList(stmt.Lhss), new List <AssignmentRhs> { new ExprRhs(CopyExpression(literal)) })); } return(null); }
public static bool CheckTacticArgsCount(ClassDecl curDecl, ApplySuffix e, out string errMsg) { Contract.Requires(curDecl != null); if (curDecl != null) { foreach (var member in curDecl.Members) { var tac = member as ITactic; if (tac != null && tac.Name == GetSignature(e)) { if (e.Args.Count != tac.Ins.Count) { errMsg = "The number of args doesn't match the tactic definition for " + Printer.ExprToString(e); return(false); } errMsg = ""; return(true); } } } errMsg = "Can't find the tactic for " + Printer.ExprToString(e); return(false); }
public override IEnumerable<ProofState> Generate(Statement statement, ProofState state) { List<List<IVariable>> args = new List<List<IVariable>>(); List<IVariable> mdIns = new List<IVariable>(); List<Expression> callArguments; IVariable lv; InitArgs(state, statement, out lv, out callArguments); state.IfVerify = true; //TODO: implement this properly //var members = state.GetLocalValue(callArguments[0] as NameSegment) as IEnumerable<MemberDecl>; //evaluate the argument (methods/lemma) var members0 = Interpreter.EvalTacnyExpression(state, callArguments[0]).GetEnumerator(); members0.MoveNext(); var members = members0.Current as List<MemberDecl>; if (members == null){ yield break; } foreach(var member in members) { MemberDecl md; mdIns.Clear(); args.Clear(); if(member is NameSegment) { //TODO: Console.WriteLine("double check this"); md = null; // md = state.GetDafnyProgram(). Members.FirstOrDefault(i => i.Key == (member as NameSegment)?.Name).Value; } else { md = member as MemberDecl; } // take the membed decl parameters var method = md as Method; if(method != null) mdIns.AddRange(method.Ins); else if(md is Microsoft.Dafny.Function) mdIns.AddRange(((Microsoft.Dafny.Function)md).Formals); else Contract.Assert(false, "In Explore Atomic call," + callArguments[0] + "is neither a Method or a Function"); //evaluate the arguemnts for the lemma to be called var instArgs = Interpreter.EvalTacnyExpression(state, callArguments[1]); foreach(var ovars in instArgs) { Contract.Assert(ovars != null, "In Explore Atomic call," + callArguments[1] + "is not variable"); List<IVariable> vars = ovars as List<IVariable> ?? new List<IVariable>(); //Contract.Assert(vars != null, Util.Error.MkErr(call_arguments[0], 1, typeof(List<IVariable>))); //for the case when no args, just add an empty list if (mdIns.Count == 0){ args.Add(new List<IVariable>()); } for(int i = 0; i < mdIns.Count; i++) { var item = mdIns[i]; args.Add(new List<IVariable>()); foreach(var arg in vars) { // get variable type Type type = state.GetDafnyVarType(arg.Name); if(type != null) { if(type is UserDefinedType && item.Type is UserDefinedType) { var udt1 = type as UserDefinedType; var udt2 = item.Type as UserDefinedType; if(udt1.Name == udt2.Name) args[i].Add(arg); } else { // if variable type and current argument types match, or the type is yet to be inferred if(item.Type.ToString() == type.ToString() || type is InferredTypeProxy) args[i].Add(arg); } } else args[i].Add(arg); } /** * if no type correct variables have been added we can safely return * because we won't be able to generate valid calls */ if(args[i].Count == 0) { Debug.WriteLine("No type matching variables were found"); yield break; } } foreach(var result in PermuteArguments(args, 0, new List<NameSegment>())) { // create new fresh list of items to remove multiple references to the same object List<Expression> newList = result.Cast<Expression>().ToList().Copy(); //TODO: need to double check wirh Vito, why can't use copy ? //Util.Copy.CopyExpressionList(result.Cast<Expression>().ToList()); ApplySuffix aps = new ApplySuffix(callArguments[0].tok, new NameSegment(callArguments[0].tok, md.Name, null), newList); if(lv != null) { var newState = state.Copy(); newState.AddTacnyVar(lv, aps); yield return newState; } else { var newState = state.Copy(); UpdateStmt us = new UpdateStmt(aps.tok, aps.tok, new List<Expression>(), new List<AssignmentRhs> { new ExprRhs(aps) }); //Printer p = new Printer(Console.Out); //p.PrintStatement(us,0); newState.AddStatement(us); yield return newState; } } } } }
public static string GetSignature(ApplySuffix aps) { Contract.Requires <ArgumentNullException>(Tcce.NonNull(aps)); Contract.Ensures(Contract.Result <string>() != null); return(aps?.Lhs.tok.val); }
public override AssignmentRhs CloneRHS(AssignmentRhs rhs) { var r = rhs as ExprRhs; if (r != null && r.Expr is ApplySuffix) { var apply = (ApplySuffix)r.Expr; var mse = apply.Lhs.Resolved as MemberSelectExpr; if (mse != null && mse.Member is FixpointLemma && ModuleDefinition.InSameSCC(context, (FixpointLemma)mse.Member)) { // we're looking at a recursive call to a fixpoint lemma Contract.Assert(apply.Lhs is NameSegment || apply.Lhs is ExprDotName); // this is the only way a call statement can have been parsed // clone "apply.Lhs", changing the inductive/co lemma to the prefix lemma; then clone "apply", adding in the extra argument Expression lhsClone; if (apply.Lhs is NameSegment) { var lhs = (NameSegment)apply.Lhs; lhsClone = new NameSegment(Tok(lhs.tok), lhs.Name + "#", lhs.OptTypeArguments == null ? null : lhs.OptTypeArguments.ConvertAll(CloneType)); } else { var lhs = (ExprDotName)apply.Lhs; lhsClone = new ExprDotName(Tok(lhs.tok), CloneExpr(lhs.Lhs), lhs.SuffixName + "#", lhs.OptTypeArguments == null ? null : lhs.OptTypeArguments.ConvertAll(CloneType)); } var args = new List<Expression>(); args.Add(k); apply.Args.ForEach(arg => args.Add(CloneExpr(arg))); var applyClone = new ApplySuffix(Tok(apply.tok), lhsClone, args); var c = new ExprRhs(applyClone); reporter.Info(MessageSource.Cloner, apply.Lhs.tok, mse.Member.Name + suffix); return c; } } return base.CloneRHS(rhs); }
public virtual Expression CloneApplySuffix(ApplySuffix e) { return new ApplySuffix(Tok(e.tok), CloneExpr(e.Lhs), e.Args.ConvertAll(CloneExpr)); }
internal bool IsETacticCall(ApplySuffix aps) { //TODO: this is for expression tactic call, e.g. funtion tactic return(false); }
public bool IsTacticCall(ApplySuffix aps) { Contract.Requires(aps != null); return(IsTacticCall(Util.GetSignature(aps))); }
public bool IsTacticCall(ApplySuffix aps) { Contract.Requires(aps != null); return IsTacticCall(Util.GetSignature(aps)); }
/// <summary> /// Initialize a new tactic state: /// case 1, inline tactic app: stmt != null, aps == null /// case 2, tactic stmt app: stmt != null, aps != null, stmt is UpdateStmt, Util.GetTacticAppExpr(stmt).tok.pos == aps.tok.pos /// case 3, tactic expr in stmt: /// stmt != null, aps != null, stmt is UpdateStmt, Util.GetTacticAppExpr(stmt).tok.pos != aps.tok.pos /// case 4, tactic expr in other expr, e.g. inv: stmt == WhileStmt, aps != null /// </summary> /// <param name="tacAps">the stmt which tactic will be expanded, it will be null in the case inv</param> /// <param name="variables">Dafny variables</param> public bool InitState(Statement stmt0, ApplySuffix aps0, Dictionary <IVariable, Dfy.Type> variables, bool ifPartial) { // clear the scope D _scope = new Stack <Frame>(); ApplySuffix aps = null; Statement stmt; List <Statement> body = new List <Statement>(); Attributes attrs, tacticAttrs; // attrs from tactic call, and the attrs from tactic definitions. Tactic tactic = null; string errMsg; if (aps0 != null) { tactic = GetTactic(aps0) as Tactic; if (!Util.CheckTacticArgs(tactic, aps0, this, out errMsg)) { ReportTacticError(aps0.tok, errMsg); } if (tactic.Outs.Count > 1) { ReportTacticError(aps0.tok, "Only one return variable is allowed: " + tactic.Name); } if (stmt0.Tok.pos != aps0.tok.pos && tactic.Outs.Count != 1) { ReportTacticError(aps0.tok, "Expect one return variable: " + tactic.Name); } //get the unresolved stmt stmt = GetTacticAppStmt(stmt0); aps = Expr.TacticAppExprFinder.GetTacticAppExpr(this, stmt); tacticAttrs = tactic.Attributes; attrs = (stmt as UpdateStmt) != null ? (stmt as UpdateStmt).Rhss[0].Attributes : null; if (tactic.Req != null) { foreach (var expr in tactic.Req) { body.Add( new TacticAssertStmt( new Token(TacnyDriver.TacticCodeTokLine, 0) { val = "tassert" }, new Token(TacnyDriver.TacticCodeTokLine, 0) { val = ";" }, expr.E, null, false)); } } body.AddRange(tactic.Body.Body); if (tactic.Ens != null) { foreach (var expr in tactic.Ens) { body.Add( new TacticAssertStmt( new Token(TacnyDriver.TacticCodeTokLine, 0) { val = "tassert" }, new Token(TacnyDriver.TacticCodeTokLine, 0) { val = ";" }, expr.E, null, false)); } } } else if (stmt0 is InlineTacticBlockStmt) { stmt = stmt0.Copy(); body = (stmt as InlineTacticBlockStmt).Body.Body; attrs = (stmt as InlineTacticBlockStmt).Attributes; tacticAttrs = null; } else { throw new Exception("Unexpceted tactic applciation statement."); } var frame = new Frame(body, ifPartial, attrs, tacticAttrs); foreach (var item in variables) { if (!frame.ContainDafnyVar(item.Key.Name)) { frame.AddDafnyVar(item.Key.Name, new VariableData { Variable = item.Key, Type = item.Value }); } else { throw new ArgumentException($"Dafny variable {item.Key.Name} is already declared in the current context"); } } if (aps != null) { for (int index = 0; index < aps.Args.Count; index++) { var arg = aps.Args[index]; if (tactic != null) { frame.AddTVar(tactic.Ins[index].Name, arg); } } foreach (var outs in tactic.Outs) { frame.AddTVar(outs.Name, null); } } _scope.Push(frame); ResetVerifyN(); TopLevelTacApp = stmt.Copy(); _tacAppExpr = aps.Copy(); if (tactic != null && (aps != null && aps.Args.Count != tactic.Ins.Count)) { ReportTacticError(stmt.Tok, $"Wrong number of method arguments (got {aps.Args.Count}, expected {tactic.Ins.Count})"); } return(_scope.Peek().FrameCtrl.enabled); }
internal Expression EvalETacticCall(ApplySuffix aps) { //fucntion expression call, yet to be supported throw new NotImplementedException(); }
/// <summary> /// Get called tactic /// </summary> /// <param name="aps"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"> </exception> /// <exception cref="ArgumentException"> Provided ApplySuffix is not a tactic application</exception> public ITactic GetTactic(ApplySuffix aps) { Contract.Requires(aps != null); Contract.Requires(IsTacticCall(aps)); Contract.Ensures(Contract.Result<ITactic>() != null); return GetTactic(Util.GetSignature(aps)); }
public static Type GetStatementType(ApplySuffix aps) { Contract.Requires(aps != null); return(GetStatementType(GetAtomicType(aps))); }
private TacticAppUnfolder(ProofState ps, ApplySuffix aps, Expression code) { _state = ps; _aps = aps; _destExpr = code; }
private UpdateStmt GenUpdateStmt(ApplySuffix aps) { Contract.Requires(aps != null); return new UpdateStmt(aps.tok, aps.tok, new List<Expression>(), new List<AssignmentRhs>() { new ExprRhs(aps) }); }
void Suffix(ref Expression e) { Contract.Requires(e != null); Contract.Ensures(e!=null); IToken id, x; Expression e0 = null; Expression e1 = null; Expression ee; bool anyDots = false; List<Expression> multipleLengths = null; bool takeRest = false; // takeRest is relevant only if multipleLengths is non-null List<Expression> multipleIndices = null; if (la.kind == 27) { DotSuffix(out id, out x); if (x != null) { // process id as a Suffix in its own right e = new ExprDotName(id, e, id.val, null); id = x; // move to the next Suffix } IToken openParen = null; List<Type> typeArgs = null; List<Expression> args = null; if (IsGenericInstantiation()) { typeArgs = new List<Type>(); GenericInstantiation(typeArgs); } else if (la.kind == 106) { HashCall(id, out openParen, out typeArgs, out args); } else if (StartOf(30)) { } else SynErr(225); e = new ExprDotName(id, e, id.val, typeArgs); if (openParen != null) { e = new ApplySuffix(openParen, e, args); } } else if (la.kind == 48) { Get(); x = t; if (StartOf(7)) { Expression(out ee, true, true); e0 = ee; if (la.kind == 137) { Get(); anyDots = true; if (StartOf(7)) { Expression(out ee, true, true); e1 = ee; } } else if (la.kind == 95) { Get(); Expression(out ee, true, true); e1 = ee; } else if (la.kind == 21) { Get(); multipleLengths = new List<Expression>(); multipleLengths.Add(e0); // account for the Expression read before the colon takeRest = true; if (StartOf(7)) { Expression(out ee, true, true); multipleLengths.Add(ee); takeRest = false; while (IsNonFinalColon()) { Expect(21); Expression(out ee, true, true); multipleLengths.Add(ee); } if (la.kind == 21) { Get(); takeRest = true; } } } else if (la.kind == 22 || la.kind == 49) { while (la.kind == 22) { Get(); Expression(out ee, true, true); if (multipleIndices == null) { multipleIndices = new List<Expression>(); multipleIndices.Add(e0); } multipleIndices.Add(ee); } } else SynErr(226); } else if (la.kind == 137) { Get(); anyDots = true; if (StartOf(7)) { Expression(out ee, true, true); e1 = ee; } } else SynErr(227); if (multipleIndices != null) { e = new MultiSelectExpr(x, e, multipleIndices); // make sure an array class with this dimensionality exists var tmp = theBuiltIns.ArrayType(multipleIndices.Count, new IntType(), true); } else { if (!anyDots && e0 == null) { /* a parsing error occurred */ e0 = dummyExpr; } Contract.Assert(anyDots || e0 != null); if (anyDots) { //Contract.Assert(e0 != null || e1 != null); e = new SeqSelectExpr(x, false, e, e0, e1); } else if (multipleLengths != null) { Expression prev = null; List<Expression> seqs = new List<Expression>(); foreach (var len in multipleLengths) { var end = prev == null ? len : new BinaryExpr(x, BinaryExpr.Opcode.Add, prev, len); seqs.Add(new SeqSelectExpr(x, false, e, prev, end)); prev = end; } if (takeRest) { seqs.Add(new SeqSelectExpr(x, false, e, prev, null)); } e = new SeqDisplayExpr(x, seqs); } else if (e1 == null) { Contract.Assert(e0 != null); e = new SeqSelectExpr(x, true, e, e0, null); } else { Contract.Assert(e0 != null); e = new SeqUpdateExpr(x, e, e0, e1); } } Expect(49); } else if (la.kind == 50) { Get(); IToken openParen = t; var args = new List<Expression>(); if (StartOf(7)) { Expressions(args); } Expect(51); e = new ApplySuffix(openParen, e, args); } else SynErr(228); }
/// <summary> /// Create a deep copy of ApplySufix /// </summary> /// <param name="oldAps"></param> /// <returns></returns> public static ApplySuffix CopyApplySuffix(ApplySuffix old_aps) { return new ApplySuffix(old_aps.tok, CopyExpression(old_aps.Lhs), CopyExpressionList(old_aps.Args)); }
void NameSegment(out Expression e) { IToken id; IToken openParen = null; List<Type> typeArgs = null; List<Expression> args = null; Ident(out id); if (IsGenericInstantiation()) { typeArgs = new List<Type>(); GenericInstantiation(typeArgs); } else if (la.kind == 106) { HashCall(id, out openParen, out typeArgs, out args); } else if (StartOf(30)) { } else SynErr(231); e = new NameSegment(id, id.val, typeArgs); if (openParen != null) { e = new ApplySuffix(openParen, e, args); } }
/// <summary> /// Generate all combinations from one permutation /// </summary> /// <param name="st"></param> /// <returns></returns> private IEnumerable<Solution> Perm(Statement st) { List<List<IVariable>> args = new List<List<IVariable>>(); List<IVariable> mdIns = new List<IVariable>(); List<Expression> callArguments; IVariable lv; InitArgs(st, out lv, out callArguments); Contract.Assert(tcce.OfSize(callArguments, 2), Error.MkErr(st, 0, 2, callArguments.Count)); foreach (var member in ResolveExpression(callArguments[0])) { Contract.Assert(member != null, Error.MkErr(callArguments[0], 1, typeof(Method))); MemberDecl md; if (member is NameSegment) { md = StaticContext.program.Members.FirstOrDefault(i => i.Key == (member as NameSegment)?.Name).Value; } else { md = member as MemberDecl; } Contract.Assert(md != null, Error.MkErr(callArguments[0], 1, typeof(MemberDecl))); // take the membed decl parameters var method = md as Method; if (method != null) mdIns.AddRange(method.Ins); else if (md is Function) mdIns.AddRange(((Function)md).Formals); else Contract.Assert(false, Error.MkErr(callArguments[0], 1, $"{typeof(Method)} or {typeof(Function)}")); foreach (var ovars in ResolveExpression(callArguments[1])) { Contract.Assert(ovars != null, Error.MkErr(callArguments[0], 1, typeof(List<IVariable>))); List<IVariable> vars = ovars as List<IVariable> ?? new List<IVariable>(); //Contract.Assert(vars != null, Util.Error.MkErr(call_arguments[0], 1, typeof(List<IVariable>))); for (int i = 0; i < mdIns.Count; i++) { var item = mdIns[i]; args.Add(new List<IVariable>()); foreach (var arg in vars) { // get variable type Type type = StaticContext.GetVariableType(arg.Name); if (type != null) { if (type is UserDefinedType && item.Type is UserDefinedType) { var udt1 = type as UserDefinedType; var udt2 = item.Type as UserDefinedType; if (udt1.Name == udt2.Name) args[i].Add(arg); } else { // if variable type and current argument types match if (item.Type.ToString() == type.ToString()) args[i].Add(arg); } } else args[i].Add(arg); } /** * if no type correct variables have been added we can safely return * because we won't be able to generate valid calls */ if (args[i].Count == 0) { Debug.WriteLine("No type matching variables were found"); yield break; } } foreach (var result in PermuteArguments(args, 0, new List<NameSegment>())) { // create new fresh list of items to remove multiple references to the same object List<Expression> newList = Util.Copy.CopyExpressionList(result.Cast<Expression>().ToList()); ApplySuffix aps = new ApplySuffix(callArguments[0].tok, new NameSegment(callArguments[0].tok, md.Name, null), newList); if (lv != null) yield return AddNewLocal(lv, aps); else { UpdateStmt us = new UpdateStmt(aps.tok, aps.tok, new List<Expression>(), new List<AssignmentRhs> { new ExprRhs(aps) }); yield return AddNewStatement(us, us); } } } } }