private static WhileStmt GenerateWhileStmt(WhileStmt original, Expression guard, Solution body) { var bodyList = body.State.GetAllUpdated(); var thenBody = new BlockStmt(original.Body.Tok, original.Body.EndTok, bodyList); return(new WhileStmt(original.Tok, original.EndTok, Util.Copy.CopyExpression(guard), original.Invariants, original.Decreases, original.Mod, Util.Copy.CopyBlockStmt(thenBody))); }
private ForStmt forloop() { consume(Token.Type.For); consume(Token.Type.LeftParenthesis, "Expected '(' for opening for loop specification"); DefStmt counter_definition = define(); consume(Token.Type.IdentifierSeperator, "Expected ',' at expression end"); Expression condition = expression(); consume(Token.Type.IdentifierSeperator, "Expected ',' at expression end"); Expression counter_action = expression(); consume(Token.Type.RightParenthesis, "Expected ')' for closing for loop specification"); // Create the body, along with the counter action Statement body = new BlockStmt( new List <Statement>() { statement(), new ExprStmt(counter_action) }); // Create a while statement WhileStmt while_stmt = new WhileStmt(condition, body); return(new ForStmt(counter_definition, while_stmt)); }
private IEnumerable <Solution> GenerateIfStmt(IfStmt original, Expression guard, IEnumerable <Solution> ifStmtEnum, IEnumerable <Solution> elseStmtEnum) { foreach (var @if in ifStmtEnum) { var bodyList = @if.State.GetAllUpdated(); var ifBody = new BlockStmt(original.Thn.Tok, original.Thn.EndTok, bodyList); if (elseStmtEnum != null) { foreach (var @else in elseStmtEnum) { var elseList = @else.State.GetAllUpdated(); Statement elseBody = null; // if original body was a plain else block if (original.Els is BlockStmt) { elseBody = new BlockStmt(original.Els.Tok, original.Thn.EndTok, elseList); } else // otherwise it was a 'else if' and the solution list should only contain one if stmt { elseBody = elseList[0]; } yield return(AddNewStatement(original, new IfStmt(original.Tok, original.EndTok, original.IsExistentialGuard, CopyExpression(guard), CopyBlockStmt(ifBody), elseBody))); } } else { yield return(AddNewStatement(original, new IfStmt(original.Tok, original.EndTok, original.IsExistentialGuard, CopyExpression(guard), CopyBlockStmt(ifBody), null))); } } }
public IStatement Function() { DataType returnType = Type(); Token name = Consume(TokenType.Identifier, "Expected function name."); Consume(TokenType.LeftParen, "Expected '(' after function name"); var arguments = new List <Argument>(); while (!Match(TokenType.RightParen)) { arguments.Add(Argument()); if (Match(TokenType.RightParen)) { break; } Consume(TokenType.Comma, "Expected ',' after argument name."); } // Fill DataType array var dataTypes = new DataType[arguments.Count + 1]; dataTypes[0] = returnType; for (int i = 0; i < arguments.Count; i++) { dataTypes[i + 1] = arguments[i].DataType; } Functions[name.Lexeme] = dataTypes; Consume(TokenType.LeftBrace, "Expected block after function declaration."); BlockStmt block = (BlockStmt)Block(); return(new FunctionStmt(returnType, name, arguments, block)); }
// Find tactic application and resolve it private void SearchBlockStmt(BlockStmt body) { Contract.Requires(tcce.NonNull(body)); // TODO Make sure this is an OK Thing to be doing // Currently, if the proof list is not reset, then because it is static across // calls, it will start to build up old information, and the program will go // into a loop trying to figure out new fresh names for 'existing' methods. BaseSearchStrategy.ResetProofList(); _frame.Push(new Dictionary <IVariable, Type>()); foreach (var stmt in body.Body) { if (stmt is VarDeclStmt) { var vds = stmt as VarDeclStmt; // register local variable declarations foreach (var local in vds.Locals) { try { _frame.Peek().Add(local, local.Type); } catch (Exception e) { //TODO: some error handling when target is not resolved Console.Out.WriteLine(e.Message); } } } else if (stmt is IfStmt) { var ifStmt = stmt as IfStmt; SearchIfStmt(ifStmt); } else if (stmt is WhileStmt) { var whileStmt = stmt as WhileStmt; SearchBlockStmt(whileStmt.Body); } else if (stmt is UpdateStmt) { var us = stmt as UpdateStmt; if (_state.IsTacticCall(us)) { var list = StackToDict(_frame); var result = ApplyTactic(_state, list, us); if (result != null) { _resultList.Add(us.Copy(), result.GetGeneratedCode().Copy()); } else { //TODO what should go here? } } } else if (stmt is BlockStmt) { //TODO: } } _frame.Pop(); }
public ForStmt(string label, Expr value, string variable, BlockStmt body) { Label = label; Value = value; Variable = variable; Body = body; }
private FuncDeclarationStmt MatchFuncDeclaration(string kind) { Token name = Consume(TokenType.IDENTIFIER, "Expect " + kind + " name."); Consume(TokenType.LEFT_PAREN, "Expect '(' after " + kind + " name."); List <Token> parameters = new List <Token>(); if (Check(TokenType.RIGHT_PAREN) == false) { do { if (parameters.Count >= 8) { ReportError("Cannot have more than 8 parameters."); } parameters.Add(Consume(TokenType.IDENTIFIER, "Expect parameter name.")); } while (Match(TokenType.COMMA)); } Consume(TokenType.RIGHT_PAREN, "Expect ')' after parameters."); Consume(TokenType.LEFT_BRACE, "Expect '{' before " + kind + " body."); BlockStmt body = MatchBlockStmt(); return(new FuncDeclarationStmt(name, parameters, body)); }
private void FindRemovableTypesInBlockStmt(BlockStmt blockStmt, Method method, WildCardDecreases wildCardParent, ClassDecl classDecl) { foreach (var stmt in blockStmt.Body) { FindRemovableTypesInStatement(stmt, blockStmt, method, wildCardParent, classDecl); } }
public override void VisitBlockStmt(BlockStmt x) { using (new ScopeHelper(this, x)) { base.VisitBlockStmt(x); } }
public string num(List <Statement> selectedStatements, List <AssertStmt> requires, List <AssertStmt> ensures) { HashSet <DVariable> decl; HashSet <DVariable> vars = GetVars(selectedStatements, out decl); List <Formal> ins = new List <Formal>(); foreach (var variable in vars) { ins.Add(variable.ToFormal()); } // var method = HelpFunctions.GetCurrentMethod(); List <MaybeFreeExpression> req = new List <MaybeFreeExpression>(); foreach (var x in requires) { req.Add(new MaybeFreeExpression(x.Expr)); } List <MaybeFreeExpression> ens = new List <MaybeFreeExpression>(); foreach (var x in ensures) { ens.Add(new MaybeFreeExpression(x.Expr)); } var newMethod = new Method(null, "number", false, false, new List <TypeParameter>(), ins, new List <Formal>(), req, new Specification <FrameExpression>(null, null), ens, new Specification <Microsoft.Dafny.Expression>(null, null), null, null, null); newMethod.Body = new BlockStmt(selectedStatements.First().Tok, selectedStatements.Last().EndTok, selectedStatements); string ans = Printer.MethodSignatureToString(newMethod); Statement statement = new BlockStmt(null, null, selectedStatements); ans += Printer.StatementToString(statement); return(ans); }
public override void Visit(BlockStmt stmt) { for (int i = 0; i < stmt.stmts.Count; i++) { stmt.stmts[i].Accept(this); } }
public virtual void Visit(BlockStmt stmt) { foreach (var statement in stmt.Statements) { statement.Accept(this); } }
public override void VisitBlockStmt(BlockStmt x) { Add(_binder.BindEmptyStmt(new Span(x.Span.Start, 1))); // { base.VisitBlockStmt(x); // visit nested statements Add(_binder.BindEmptyStmt(new Span(x.Span.End - 1, 1))); // } // TODO: endif; etc. }
protected override void MatchBlockStmt(BlockStmt stmt) { BeginScope(); Resolve(stmt.Statements); EndScope(); }
public virtual void Visit(BlockStmt blockStatement) { VisitNullableAttributes(blockStatement.Attributes); foreach (var statement in blockStatement.Body) { Visit(statement); } }
public virtual BlockStmt CloneBlockStmt(BlockStmt stmt) { if (stmt == null) { return null; } else { return new BlockStmt(Tok(stmt.Tok), Tok(stmt.EndTok), stmt.Body.ConvertAll(CloneStmt)); } }
internal Statement GetTacticAppStmt(int pos, BlockStmt stmts) { if (stmts.Body == null) { return(null); } return(GetTacticAppStmt(pos, stmts.Body)); }
public string Transpile(CompilerContext context) { var code = new StringBuilder(); code.AppendLine($"while({Condition.Transpile(context)}) {{ "); code.AppendLine(BlockStmt.Transpile(context)); code.AppendLine("}"); return(code.ToString()); }
public override void Visit(BlockStmt blockStatement) { var oldBlock = _block; _block = new ScopeSymbol(_block, blockStatement); oldBlock.Symbols.Add(_block); base.Visit(blockStatement); _block = oldBlock; }
/// <summary> /// LoopStmt /// WHILE LPAREN Expr RPAREN (SELICOLON | BlockStmt) /// FOR LPAREN (VarOrExprStmt | SEMICOLON) Expr? SEMICOLON ExprList? RPAREN (SELICOLON | BlockStmt) /// </summary> /// <returns></returns> private LoopStmt ParseLoopStmt() { BlockStmt body = null; Expr cond = null; if (Check(TokenType.WHILE)) { Consume(TokenType.WHILE); Consume(TokenType.LPAREN); cond = ParseExpr(); Consume(TokenType.RPAREN); if (Check(TokenType.SEMICOLON)) { Consume(TokenType.SEMICOLON); } else { body = ParseBlockStmt(); } return(LoopStmt.MakeWhile(cond, body)); } else { Consume(TokenType.FOR); Consume(TokenType.LPAREN); Stmt init = null; Expr step = null; if (!Check(TokenType.SEMICOLON)) { init = ParseVarOrExprStmt(); } else { Consume(TokenType.SEMICOLON); } if (!Check(TokenType.SEMICOLON)) { cond = ParseExpr(); } Consume(TokenType.SEMICOLON); if (!Check(TokenType.RPAREN)) { step = ParseExprList(); } Consume(TokenType.RPAREN); if (Check(TokenType.SEMICOLON)) { Consume(TokenType.SEMICOLON); } else { body = ParseBlockStmt(); } return(LoopStmt.MakeFor(init, cond, step, body)); } }
// Find tactic application and resolve it private void SearchBlockStmt(BlockStmt body) { Contract.Requires(tcce.NonNull(body)); // BaseSearchStrategy.ResetProofList(); _frame.Push(new Dictionary <IVariable, Type>()); foreach (var stmt in body.Body) { if (stmt is VarDeclStmt) { var vds = stmt as VarDeclStmt; // register local variable declarations foreach (var local in vds.Locals) { try { _frame.Peek().Add(local, local.Type); } catch (Exception e) { //TODO: some error handling when target is not resolved Console.Out.WriteLine(e.Message); } } } else if (stmt is IfStmt) { var ifStmt = stmt as IfStmt; SearchIfStmt(ifStmt); } else if (stmt is WhileStmt) { var whileStmt = stmt as WhileStmt; SearchBlockStmt(whileStmt.Body); } else if (stmt is UpdateStmt) { var us = stmt as UpdateStmt; if (_state.IsTacticCall(us)) { var list = StackToDict(_frame); var result = EvalTactic(_state, list, us); if (result != null) { _resultList.Add(us.Copy(), result.GetGeneratedCode().Copy()); } else// when no results, just return a empty stmt list { _resultList.Add(us.Copy(), new List <Statement>()); } } } else if (stmt is BlockStmt) { //TODO: } } _frame.Pop(); }
public static void PrepareFrame(BlockStmt body, ProofState state) { Contract.Requires <ArgumentNullException>(body != null, "body"); Contract.Requires <ArgumentNullException>(state != null, "state"); state.AddNewFrame(body); // call the search engine var search = new BaseSearchStrategy(state.TacticInfo.SearchStrategy, true); search.Search(state, _errorReporterDelegate); state.RemoveFrame(); }
public object Visit(BlockStmt stmt) { _scope = _scope.AddChildScope(); foreach (var statement in stmt.Statements) { statement.Accept(this); } _scope = _scope.Parent; return(null); }
public void TestReturnInFunctionWithoutValue() { var program = new ProgramNode(0, 0); program.Block = new BlockStmt(0, 0); var returnStmt = new ReturnStmt(0, 0); var funcBlock = new BlockStmt(0, 0); funcBlock.Statements.Add(returnStmt); program.Block.Statements.Add(CreateFunction("func", funcBlock)); AssertErrorContains(program, "Return statement can't be empty in a function"); }
public Value CompileBlockStmt(BlockStmt stmt) { switch (stmt) { case BlockLet s: return(CompileBlockStmt(s)); case BlockExpr e: return(CompileExpr(e.Expr)); default: throw new Exception("unknown AST node " + stmt.GetType()); } }
private BlockStmt MatchBlockStmt() { List <Stmt> stmts = new List <Stmt>(); while (Check(TokenType.RIGHT_BRACE) == false && IsAtEnd() == false) { stmts.Add(MatchDeclaration()); } Consume(TokenType.RIGHT_BRACE, "Expect '}' after block."); BlockStmt block = new BlockStmt(stmts); return(block); }
public void TestCorrectReturnInFuction() { var program = new ProgramNode(0, 0); program.Block = new BlockStmt(0, 0); var funcBlock = new BlockStmt(0, 0); var returnStmt = new ReturnStmt(0, 0); returnStmt.ReturnExpression = new IntLiteralExpr(0, 0, 0); funcBlock.Statements.Add(returnStmt); program.Block.Statements.Add(CreateFunction("func", funcBlock)); AssertNoErrors(program); }
public Emit <Func <int> > EmitByteCode(CompilerContext context, Emit <Func <int> > emiter) { var loopLabel = emiter.DefineLabel(); var outLabel = emiter.DefineLabel(); emiter.MarkLabel(loopLabel); Condition.EmitByteCode(context, emiter); emiter.BranchIfFalse(outLabel); BlockStmt.EmitByteCode(context, emiter); emiter.Branch(loopLabel); emiter.MarkLabel(outLabel); return(emiter); }
public Statement ParseFunctionCallStatement() { string function = ConsumeToken(TokenKind.Identifier).Source; ConsumeToken(TokenKind.OpenParen); var arguments = ParseArgumentList(); ConsumeToken(TokenKind.CloseParen); var call = new FunctionCallStmt { MethodName = function, Arguments = arguments.ToArray() }; switch (CurrentToken.Kind) { case TokenKind.Semicolon: ConsumeToken(); break; case TokenKind.OpenBrace: if (function.Equals("if", StringComparison.CurrentCultureIgnoreCase)) { var body = ParseBlockStatement(); BlockStmt elseBody = null; if (CurrentToken.Kind == TokenKind.Identifier && CurrentToken.Source.Equals("else", StringComparison.CurrentCultureIgnoreCase)) { ConsumeToken(); elseBody = ParseBlockStatement(); } return(new IfStmt { Function = call, Body = body, ElseBody = elseBody }); } return(new BodyFunctionStmt { Function = call, Body = ParseBlockStatement() }); default: throw new UnexpectedTokenException(CurrentToken, TokenKind.Semicolon, TokenKind.OpenBrace); } return(call); }
public void TestRedeclarationInInnerScope() { var program = new ProgramNode(0, 0); program.Block = new BlockStmt(0, 0); var declaration1 = CreateVarDeclaration("var1"); var declaration2 = CreateVarDeclaration("var2"); var innerBlock = new BlockStmt(0, 0); innerBlock.Statements.Add(declaration2); program.Block.Statements.Add(declaration1); program.Block.Statements.Add(innerBlock); AssertNoErrors(program); }
public void TestReturnOfWrongType() { var program = new ProgramNode(0, 0); program.Block = new BlockStmt(0, 0); var returnStmt = new ReturnStmt(0, 0); returnStmt.ReturnExpression = new StringLiteralExpr(0, 0, "asd"); var funcBlock = new BlockStmt(0, 0); funcBlock.Statements.Add(returnStmt); program.Block.Statements.Add(CreateFunction("func", funcBlock)); AssertErrorContains(program, "Can't return a value of type String in a function of type Int"); }
public static IEnumerable<Solution> SearchBlockStmt(BlockStmt body, Atomic atomic) { Atomic ac = atomic.Copy(); ac.DynamicContext.tacticBody = body.Body; ac.DynamicContext.ResetCounter(); List<Solution> result = new List<Solution> { new Solution(ac) }; // search strategy for body goes here while (true) { List<Solution> interm = new List<Solution>(); if (result.Count == 0) break; foreach (var solution in result) { foreach (var item in Atomic.ResolveStatement(solution)) { if (item.State.DynamicContext.isPartialyResolved) { { interm.Add(item); } yield return item; } else if (item.State.DynamicContext.GetCurrentStatement() == null) { yield return item; } else { interm.Add(item); } } } result.Clear(); result.AddRange(interm); } }
/// <summary> /// Create deep copy of BlockStmt /// </summary> /// <param name="stmt"></param> /// <returns></returns> public static BlockStmt CopyBlockStmt(BlockStmt stmt) { return new BlockStmt(stmt.Tok, stmt.EndTok, CopyStatementList(stmt.Body)); }
void CalcStmt(out Statement s) { Contract.Ensures(Contract.ValueAtReturn(out s) != null); Token x; Attributes attrs = null; CalcStmt.CalcOp op, calcOp = Microsoft.Dafny.CalcStmt.DefaultOp, resOp = Microsoft.Dafny.CalcStmt.DefaultOp; var lines = new List<Expression>(); var hints = new List<BlockStmt>(); CalcStmt.CalcOp stepOp; var stepOps = new List<CalcStmt.CalcOp>(); CalcStmt.CalcOp maybeOp; Expression e; IToken opTok; IToken danglingOperator = null; Expect(32); x = t; while (IsAttribute()) { Attribute(ref attrs); } if (StartOf(25)) { CalcOp(out opTok, out calcOp); maybeOp = calcOp.ResultOp(calcOp); // guard against non-transitive calcOp (like !=) if (maybeOp == null) { SemErr(opTok, "the main operator of a calculation must be transitive"); } resOp = calcOp; } Expect(46); while (StartOf(7)) { Expression(out e, false, true); lines.Add(e); stepOp = calcOp; danglingOperator = null; Expect(28); if (StartOf(25)) { CalcOp(out opTok, out op); maybeOp = resOp.ResultOp(op); if (maybeOp == null) { SemErr(opTok, "this operator cannot continue this calculation"); } else { stepOp = op; resOp = maybeOp; danglingOperator = opTok; } } stepOps.Add(stepOp); var subhints = new List<Statement>(); IToken hintStart = la; IToken hintEnd = hintStart; IToken t0, t1; BlockStmt subBlock; Statement subCalc; while (la.kind == _lbrace || la.kind == _calc) { if (la.kind == 46) { BlockStmt(out subBlock, out t0, out t1); hintEnd = subBlock.EndTok; subhints.Add(subBlock); } else if (la.kind == 32) { CalcStmt(out subCalc); hintEnd = subCalc.EndTok; subhints.Add(subCalc); } else SynErr(192); } var h = new BlockStmt(hintStart, hintEnd, subhints); // if the hint is empty, hintStart is the first token of the next line, but it doesn't matter because the block statement is just used as a container hints.Add(h); if (h.Body.Count != 0) { danglingOperator = null; } } Expect(47); if (danglingOperator != null) { SemErr(danglingOperator, "a calculation cannot end with an operator"); } if (lines.Count > 0) { // Repeat the last line to create a dummy line for the dangling hint lines.Add(lines[lines.Count - 1]); } s = new CalcStmt(x, t, calcOp, lines, hints, stepOps, resOp, attrs); }
public static void PrepareFrame(BlockStmt body, ProofState state) { Contract.Requires<ArgumentNullException>(body != null, "body"); Contract.Requires<ArgumentNullException>(state != null, "state"); state.AddNewFrame(body); // call the search engine var search = new BaseSearchStrategy(state.TacticInfo.SearchStrategy, true); search.Search(state, _errorReporterDelegate); state.RemoveFrame(); }
public Tuple<Method,TypeApply> GetSeqBuildMethod(Type t, SeqTree tree, List<bool> elemDimensions) { if (elemDimensions.Count == 0) { return GetSeqMethod(t, "seq_Empty"); } if (elemDimensions.Count == 2 && elemDimensions[0] && elemDimensions[1]) { return GetSeqMethod(t, "seq_Append"); } string op = "seq_" + SeqTree.TreeName(tree); DatatypeDecl seqDecl = FindDatatype("Seq"); var tok = new Bpl.Token(0, 0); tok.filename = @"!\Seq.dfy"; TypeApply tApp = Compile_SeqType((SeqType)t); Type dataType = new UserDefinedType(tok, "Seq", seqDecl, new List<Type> { ((SeqType)t).Arg }); Type elemType = ((SeqType)t).Arg; Func<string,Type,Expression> idExpr = (x, typ) => { var e = new IdentifierExpr(tok, x); e.Type = typ; e.Var = new LocalVariable(tok, tok, x, typ, false); return e; }; Func<string,List<Expression>,FunctionCallExpr> seqCall = (x, args) => { var seqOp = GetSeqOperation(t, x); FunctionCallExpr callExpr = new FunctionCallExpr( tok, "Seq_Empty", new ThisExpr(tok), tok, args); callExpr.Function = seqOp.Item1; callExpr.TypeArgumentSubstitutions = seqOp.Item2.typeArgs; return callExpr; }; Expression empty = seqCall("Seq_Empty", new List<Expression> {}); int varCount = 0; Func<SeqTree,Expression> resultRec = null; resultRec = (subtree) => { if (subtree == null) { return idExpr("s" + (varCount++), dataType); } if (subtree.buildCount >= 0) { Expression build = empty; for (int i = 0; i < subtree.buildCount; i++) { build = seqCall("Seq_Build", new List<Expression> { build, idExpr("a" + (varCount++), elemType) }); } return build; } else { return seqCall("Seq_Append", new List<Expression> { resultRec(subtree.left), resultRec(subtree.right) }); } }; Expression result = resultRec(tree); Expression post = seqCall("Seq_Equal", new List<Expression> { idExpr("s", dataType), result }); List<Statement> stmts = new List<Statement>(); for (int i = elemDimensions.Count; i > 0;) { bool isFirst = (i == elemDimensions.Count); i--; if (elemDimensions[i]) { if (isFirst) { stmts.Add(new AssignStmt(tok, tok, idExpr("s", dataType), new ExprRhs(idExpr("s" + i, dataType)))); } else { // s := seq_Append(s9, s); var selectExpr = new MemberSelectExpr(tok, new ThisExpr(tok), "seq_Append"); selectExpr.Member = FindMethod(selectExpr.MemberName); // Manually resolve here selectExpr.TypeApplication = new List<Type>() { elemType }; // Manually resolve here selectExpr.Type = new InferredTypeProxy(); // Manually resolve here CallStmt callStmt = new CallStmt(tok, tok, new List<Expression> {idExpr("s", dataType)}, selectExpr, new List<Expression> { idExpr("s" + i, dataType), idExpr("s", dataType) }); stmts.Add(callStmt); } } else { if (isFirst) { DatatypeValue nil = new DatatypeValue(tok, "Seq", "Nil", new List<Expression>() {}); nil.Type = dataType; nil.InferredTypeArgs = new List<Type> { elemType }; nil.Ctor = seqDecl.Ctors[0]; Util.Assert(nil.Ctor.Name == "Seq_Nil"); stmts.Add(new AssignStmt(tok, tok, idExpr("s", dataType), new ExprRhs(nil))); } // lemma_Seq_Cons(ai, s); var selectExpr = new MemberSelectExpr(tok, new ThisExpr(tok), "lemma_Seq_Cons"); selectExpr.Member = FindMethod(selectExpr.MemberName); // Manually resolve here selectExpr.TypeApplication = new List<Type>() { elemType }; // Manually resolve here selectExpr.Type = new InferredTypeProxy(); // Manually resolve here CallStmt callStmt = new CallStmt(tok, tok, new List<Expression> {}, selectExpr, new List<Expression> { idExpr("a" + i, elemType), idExpr("s", dataType) }); callStmt.IsGhost = true; stmts.Add(callStmt); DatatypeValue cons = new DatatypeValue(tok, "Seq", "Cons", new List<Expression>() { idExpr("a" + i, elemType), idExpr("s", dataType) }); cons.Type = dataType; cons.InferredTypeArgs = new List<Type> { elemType }; cons.Ctor = seqDecl.Ctors[1]; Util.Assert(cons.Ctor.Name == "Seq_Cons"); stmts.Add(new AssignStmt(tok, tok, idExpr("s", dataType), new ExprRhs(cons))); } } BlockStmt body = new BlockStmt(tok, tok, stmts); List<Formal> ins = new List<Formal>(); for (int i = 0; i < elemDimensions.Count; i++) { bool isSeq = elemDimensions[i]; ins.Add(new Formal(tok, (isSeq ? "s" : "a") + i, isSeq ? dataType : elemType, true, false)); } List<Formal> outs = new List<Formal> { new Formal(tok, "s", dataType, false, false) }; List<MaybeFreeExpression> reqs = new List<MaybeFreeExpression>(); List<MaybeFreeExpression> enss = new List<MaybeFreeExpression> { new MaybeFreeExpression(post) }; Specification<FrameExpression> mods = new Specification<FrameExpression>(new List<FrameExpression>(), null); Specification<Expression> decs = new Specification<Expression>(new List<Expression>(), null); Attributes attrs = new Attributes("dafnycc_conservative_seq_triggers", new List<Expression>(), null); Method m = new Method(tok, op, true, false, tApp.typeParams, ins, outs, reqs, mods, enss, decs, body, attrs, tok); m.EnclosingClass = GetSeqMethod(t, "seq_Append").Item1.EnclosingClass; return Tuple.Create(m, Compile_Method(m, tApp.typeArgs)); }
public void AddNewFrame(BlockStmt body) { Contract.Requires<ArgumentNullException>(body != null, "body"); //Contract.Requires<ArgumentNullException>(_scope.Count > 0, "scope"); _scope.Push(new Frame(_scope.Peek(), body.Body)); }
// Find tactic application and resolve it private void SearchBlockStmt(BlockStmt body) { Contract.Requires(tcce.NonNull(body)); // BaseSearchStrategy.ResetProofList(); _frame.Push(new Dictionary<IVariable, Type>()); foreach(var stmt in body.Body) { if(stmt is VarDeclStmt) { var vds = stmt as VarDeclStmt; // register local variable declarations foreach(var local in vds.Locals) { try { _frame.Peek().Add(local, local.Type); } catch(Exception e) { //TODO: some error handling when target is not resolved Console.Out.WriteLine(e.Message); } } } else if(stmt is IfStmt) { var ifStmt = stmt as IfStmt; SearchIfStmt(ifStmt); } else if(stmt is WhileStmt) { var whileStmt = stmt as WhileStmt; SearchBlockStmt(whileStmt.Body); } else if(stmt is UpdateStmt) { var us = stmt as UpdateStmt; if(_state.IsTacticCall(us)) { var list = StackToDict(_frame); var result = EvalTactic(_state, list, us); if(result != null) _resultList.Add(us.Copy(), result.GetGeneratedCode().Copy()); else {// when no results, just return a empty stmt list _resultList.Add(us.Copy(), new List<Statement>()); } } } else if(stmt is BlockStmt) { //TODO: } } _frame.Pop(); }
private void FindRemovableTypesInBlockStmt(BlockStmt blockStmt, Method method, WildCardDecreases wildCardParent, ClassDecl classDecl) { foreach (var stmt in blockStmt.Body) FindRemovableTypesInStatement(stmt, blockStmt, method, wildCardParent, classDecl); }
BlockStmt MergeBlockStmt(BlockStmt skeleton, BlockStmt oldStmt) { Contract.Requires(skeleton != null); Contract.Requires(oldStmt != null); var body = new List<Statement>(); int i = 0, j = 0; while (i < skeleton.Body.Count) { var cur = skeleton.Body[i]; if (j == oldStmt.Body.Count) { if (!(cur is SkeletonStatement)) { MergeAddStatement(cur, body); } else if (((SkeletonStatement)cur).S == null) { // the "..." matches the empty statement sequence } else { reporter.Error(MessageSource.RefinementTransformer, cur.Tok, "skeleton statement does not match old statement"); } i++; } else { var oldS = oldStmt.Body[j]; /* See how the two statements match up. * oldS cur result * ------ ------ ------ * assume E; assert ...; assert E; * assert E; assert ...; assert E; * assert E; assert E; * * assume E; assume ...; assume E; * * var x; var x := E; var x := E; * var x := *; var x := E; var x := E; * var x :| P; var x := E1; var x := E1; assert P; * var VarProduction; var VarProduction; * * x := *; x := E; x := E; * x :| P; x := E; x := E; assert P; * * modify E; modify ...; modify E; * modify E; modify ... { S } modify E { S } * modify E { S } modify ... { S' } modify E { Merge(S, S') } * * if (G) Then' else Else' if ... Then else Else if (G) Merge(Then,Then') else Merge(Else,Else') * if (*) Then' else Else' if (G) Then else Else if (G) Merge(Then,Then') else Merge(Else,Else') * * while (G) LoopSpec' Body while ... LoopSpec ... while (G) Merge(LoopSpec,LoopSpec') Body * while (G) LoopSpec' Body' while ... LoopSpec Body while (G) Merge(LoopSpec,LoopSpec') Merge(Body,Body') * while (*) LoopSpec' Body while (G) LoopSpec ... while (G) Merge(LoopSpec,LoopSpec') Body * while (*) LoopSpec' Body' while (G) LoopSpec Body while (G) Merge(LoopSpec,LoopSpec') Merge(Body,Body') * * StmtThatDoesNotMatchS; S' ... where x = e; S StatementThatDoesNotMatchS[e/x]; Merge( ... where x = e; S , S') * StmtThatMatchesS; S' ... where x = e; S StmtThatMatchesS; S' * * Note, LoopSpec must contain only invariant declarations (as the parser ensures for the first three cases). * Note, there is an implicit "...;" at the end of every block in a skeleton. */ if (cur is SkeletonStatement) { var c = (SkeletonStatement)cur; var S = c.S; if (S == null) { var nxt = i + 1 == skeleton.Body.Count ? null : skeleton.Body[i + 1]; if (nxt != null && nxt is SkeletonStatement && ((SkeletonStatement)nxt).S == null) { // "...; ...;" is the same as just "...;", so skip this one } else { SubstitutionCloner subber = null; if (c.NameReplacements != null) { var subExprs = new Dictionary<string, Expression>(); Contract.Assert(c.NameReplacements.Count == c.ExprReplacements.Count); for (int k = 0; k < c.NameReplacements.Count; k++) { if (subExprs.ContainsKey(c.NameReplacements[k].val)) { reporter.Error(MessageSource.RefinementTransformer, c.NameReplacements[k], "replacement definition must contain at most one definition for a given label"); } else subExprs.Add(c.NameReplacements[k].val, c.ExprReplacements[k]); } subber = new SubstitutionCloner(subExprs, rawCloner); } // skip up until the next thing that matches "nxt" var hoverTextA = ""; var sepA = ""; while (nxt == null || !PotentialMatch(nxt, oldS)) { // loop invariant: oldS == oldStmt.Body[j] var s = refinementCloner.CloneStmt(oldS); if (subber != null) s = subber.CloneStmt(s); body.Add(s); hoverTextA += sepA + Printer.StatementToString(s); sepA = "\n"; j++; if (j == oldStmt.Body.Count) { break; } oldS = oldStmt.Body[j]; } if (hoverTextA.Length != 0) { reporter.Info(MessageSource.RefinementTransformer, c.Tok, hoverTextA); } if (subber != null && subber.SubstitutionsMade.Count < subber.Exprs.Count) { foreach (var s in subber.SubstitutionsMade) subber.Exprs.Remove(s); reporter.Error(MessageSource.RefinementTransformer, c.Tok, "could not find labeled expression(s): " + Util.Comma(", ", subber.Exprs.Keys, x => x)); } } i++; } else if (S is AssertStmt) { var skel = (AssertStmt)S; Contract.Assert(c.ConditionOmitted); var oldAssume = oldS as PredicateStmt; if (oldAssume == null) { reporter.Error(MessageSource.RefinementTransformer, cur.Tok, "assert template does not match inherited statement"); i++; } else { // Clone the expression, but among the new assert's attributes, indicate // that this assertion is supposed to be translated into a check. That is, // it is not allowed to be just assumed in the translation, despite the fact // that the condition is inherited. var e = refinementCloner.CloneExpr(oldAssume.Expr); var attrs = refinementCloner.MergeAttributes(oldAssume.Attributes, skel.Attributes); body.Add(new AssertStmt(new Translator.ForceCheckToken(skel.Tok), new Translator.ForceCheckToken(skel.EndTok), e, skel.Proof, new Attributes("prependAssertToken", new List<Expression>(), attrs))); reporter.Info(MessageSource.RefinementTransformer, c.ConditionEllipsis, "assume->assert: " + Printer.ExprToString(e)); i++; j++; } } else if (S is AssumeStmt) { var skel = (AssumeStmt)S; Contract.Assert(c.ConditionOmitted); var oldAssume = oldS as AssumeStmt; if (oldAssume == null) { reporter.Error(MessageSource.RefinementTransformer, cur.Tok, "assume template does not match inherited statement"); i++; } else { var e = refinementCloner.CloneExpr(oldAssume.Expr); var attrs = refinementCloner.MergeAttributes(oldAssume.Attributes, skel.Attributes); body.Add(new AssumeStmt(skel.Tok, skel.EndTok, e, attrs)); reporter.Info(MessageSource.RefinementTransformer, c.ConditionEllipsis, Printer.ExprToString(e)); i++; j++; } } else if (S is IfStmt) { var skel = (IfStmt)S; Contract.Assert(c.ConditionOmitted); var oldIf = oldS as IfStmt; if (oldIf == null) { reporter.Error(MessageSource.RefinementTransformer, cur.Tok, "if-statement template does not match inherited statement"); i++; } else { var resultingThen = MergeBlockStmt(skel.Thn, oldIf.Thn); var resultingElse = MergeElse(skel.Els, oldIf.Els); var e = refinementCloner.CloneExpr(oldIf.Guard); var r = new IfStmt(skel.Tok, skel.EndTok, oldIf.IsExistentialGuard, e, resultingThen, resultingElse); body.Add(r); reporter.Info(MessageSource.RefinementTransformer, c.ConditionEllipsis, Printer.GuardToString(oldIf.IsExistentialGuard, e)); i++; j++; } } else if (S is WhileStmt) { var skel = (WhileStmt)S; var oldWhile = oldS as WhileStmt; if (oldWhile == null) { reporter.Error(MessageSource.RefinementTransformer, cur.Tok, "while-statement template does not match inherited statement"); i++; } else { Expression guard; if (c.ConditionOmitted) { guard = refinementCloner.CloneExpr(oldWhile.Guard); reporter.Info(MessageSource.RefinementTransformer, c.ConditionEllipsis, Printer.GuardToString(false, oldWhile.Guard)); } else { if (oldWhile.Guard != null) { reporter.Error(MessageSource.RefinementTransformer, skel.Guard.tok, "a skeleton while statement with a guard can only replace a while statement with a non-deterministic guard"); } guard = skel.Guard; } // Note, if the loop body is omitted in the skeleton, the parser will have set the loop body to an empty block, // which has the same merging behavior. var r = MergeWhileStmt(skel, oldWhile, guard); body.Add(r); i++; j++; } } else if (S is ModifyStmt) { var skel = (ModifyStmt)S; Contract.Assert(c.ConditionOmitted); var oldModifyStmt = oldS as ModifyStmt; if (oldModifyStmt == null) { reporter.Error(MessageSource.RefinementTransformer, cur.Tok, "modify template does not match inherited statement"); i++; } else { var mod = refinementCloner.CloneSpecFrameExpr(oldModifyStmt.Mod); BlockStmt mbody; if (oldModifyStmt.Body == null && skel.Body == null) { mbody = null; } else if (oldModifyStmt.Body == null) { mbody = skel.Body; } else if (skel.Body == null) { reporter.Error(MessageSource.RefinementTransformer, cur.Tok, "modify template must have a body if the inherited modify statement does"); mbody = null; } else { mbody = MergeBlockStmt(skel.Body, oldModifyStmt.Body); } body.Add(new ModifyStmt(skel.Tok, skel.EndTok, mod.Expressions, mod.Attributes, mbody)); reporter.Info(MessageSource.RefinementTransformer, c.ConditionEllipsis, Printer.FrameExprListToString(mod.Expressions)); i++; j++; } } else { Contract.Assume(false); // unexpected skeleton statement } } else if (cur is AssertStmt) { MergeAddStatement(cur, body); i++; } else if (cur is VarDeclStmt) { var cNew = (VarDeclStmt)cur; bool doMerge = false; Expression addedAssert = null; if (oldS is VarDeclStmt) { var cOld = (VarDeclStmt)oldS; if (LocalVarsAgree(cOld.Locals, cNew.Locals)) { var update = cNew.Update as UpdateStmt; if (update != null && update.Rhss.TrueForAll(rhs => !rhs.CanAffectPreviouslyKnownExpressions)) { // Note, we allow switching between ghost and non-ghost, since that seems unproblematic. if (cOld.Update == null) { doMerge = true; } else if (cOld.Update is AssignSuchThatStmt) { doMerge = true; addedAssert = refinementCloner.CloneExpr(((AssignSuchThatStmt)cOld.Update).Expr); } else { var updateOld = (UpdateStmt)cOld.Update; // if cast fails, there are more ConcreteUpdateStatement subclasses than expected doMerge = true; foreach (var rhs in updateOld.Rhss) { if (!(rhs is HavocRhs)) doMerge = false; } } } } } if (doMerge) { // Go ahead with the merge: body.Add(cNew); i++; j++; if (addedAssert != null) { var tok = new Translator.ForceCheckToken(addedAssert.tok); body.Add(new AssertStmt(tok, tok, addedAssert, null, null)); } } else { MergeAddStatement(cur, body); i++; } } else if (cur is AssignStmt) { var cNew = (AssignStmt)cur; var cOld = oldS as AssignStmt; if (cOld == null && oldS is UpdateStmt) { var us = (UpdateStmt)oldS; if (us.ResolvedStatements.Count == 1) { cOld = us.ResolvedStatements[0] as AssignStmt; } } bool doMerge = false; if (cOld != null && cNew.Lhs.WasResolved() && cOld.Lhs.WasResolved()) { var newLhs = cNew.Lhs.Resolved as IdentifierExpr; var oldLhs = cOld.Lhs.Resolved as IdentifierExpr; if (newLhs != null && oldLhs != null && newLhs.Name == oldLhs.Name) { if (!(cNew.Rhs is TypeRhs) && cOld.Rhs is HavocRhs) { doMerge = true; } } } if (doMerge) { // Go ahead with the merge: body.Add(cNew); i++; j++; } else { MergeAddStatement(cur, body); i++; } } else if (cur is UpdateStmt) { var nw = (UpdateStmt)cur; List<Statement> stmtGenerated = new List<Statement>(); bool doMerge = false; if (oldS is UpdateStmt) { var s = (UpdateStmt)oldS; if (LeftHandSidesAgree(s.Lhss, nw.Lhss)) { doMerge = true; stmtGenerated.Add(nw); foreach (var rhs in s.Rhss) { if (!(rhs is HavocRhs)) doMerge = false; } } } else if (oldS is AssignSuchThatStmt) { var s = (AssignSuchThatStmt)oldS; if (LeftHandSidesAgree(s.Lhss, nw.Lhss)) { doMerge = true; stmtGenerated.Add(nw); var addedAssert = refinementCloner.CloneExpr(s.Expr); var tok = new Translator.ForceCheckToken(addedAssert.tok); stmtGenerated.Add(new AssertStmt(tok, tok, addedAssert, null, null)); } } if (doMerge) { // Go ahead with the merge: Contract.Assert(cce.NonNullElements(stmtGenerated)); body.AddRange(stmtGenerated); i++; j++; } else { MergeAddStatement(cur, body); i++; } } else if (cur is IfStmt) { var cNew = (IfStmt)cur; var cOld = oldS as IfStmt; if (cOld != null && cOld.Guard == null) { var r = new IfStmt(cNew.Tok, cNew.EndTok, cNew.IsExistentialGuard, cNew.Guard, MergeBlockStmt(cNew.Thn, cOld.Thn), MergeElse(cNew.Els, cOld.Els)); body.Add(r); i++; j++; } else { MergeAddStatement(cur, body); i++; } } else if (cur is WhileStmt) { var cNew = (WhileStmt)cur; var cOld = oldS as WhileStmt; if (cOld != null && cOld.Guard == null) { var r = MergeWhileStmt(cNew, cOld, cNew.Guard); body.Add(r); i++; j++; } else { MergeAddStatement(cur, body); i++; } } else if (cur is BlockStmt) { var cNew = (BlockStmt)cur; var cOld = oldS as BlockStmt; if (cOld != null) { var r = MergeBlockStmt(cNew, cOld); body.Add(r); i++; j++; } else { MergeAddStatement(cur, body); i++; } } else { MergeAddStatement(cur, body); i++; } } } // implement the implicit "...;" at the end of each block statement skeleton var hoverText = ""; var sep = ""; for (; j < oldStmt.Body.Count; j++) { var b = oldStmt.Body[j]; body.Add(refinementCloner.CloneStmt(b)); hoverText += sep + Printer.StatementToString(b); sep = "\n"; } if (hoverText.Length != 0) { reporter.Info(MessageSource.RefinementTransformer, skeleton.EndTok, hoverText); } return new BlockStmt(skeleton.Tok, skeleton.EndTok, body); }
Method CloneMethod(Method m, List<MaybeFreeExpression> moreEnsures, Specification<Expression> decreases, BlockStmt newBody, bool checkPreviousPostconditions, Attributes moreAttributes) { Contract.Requires(m != null); Contract.Requires(decreases != null); var tps = m.TypeArgs.ConvertAll(refinementCloner.CloneTypeParam); var ins = m.Ins.ConvertAll(refinementCloner.CloneFormal); var req = m.Req.ConvertAll(refinementCloner.CloneMayBeFreeExpr); var mod = refinementCloner.CloneSpecFrameExpr(m.Mod); List<MaybeFreeExpression> ens; if (checkPreviousPostconditions) ens = m.Ens.ConvertAll(rawCloner.CloneMayBeFreeExpr); else ens = m.Ens.ConvertAll(refinementCloner.CloneMayBeFreeExpr); if (moreEnsures != null) { ens.AddRange(moreEnsures); } var body = newBody ?? refinementCloner.CloneBlockStmt(m.BodyForRefinement); if (m is Constructor) { return new Constructor(new RefinementToken(m.tok, moduleUnderConstruction), m.Name, tps, ins, req, mod, ens, decreases, body, refinementCloner.MergeAttributes(m.Attributes, moreAttributes), null, m); } else if (m is InductiveLemma) { return new InductiveLemma(new RefinementToken(m.tok, moduleUnderConstruction), m.Name, m.HasStaticKeyword, tps, ins, m.Outs.ConvertAll(refinementCloner.CloneFormal), req, mod, ens, decreases, body, refinementCloner.MergeAttributes(m.Attributes, moreAttributes), null, m); } else if (m is CoLemma) { return new CoLemma(new RefinementToken(m.tok, moduleUnderConstruction), m.Name, m.HasStaticKeyword, tps, ins, m.Outs.ConvertAll(refinementCloner.CloneFormal), req, mod, ens, decreases, body, refinementCloner.MergeAttributes(m.Attributes, moreAttributes), null, m); } else if (m is Lemma) { return new Lemma(new RefinementToken(m.tok, moduleUnderConstruction), m.Name, m.HasStaticKeyword, tps, ins, m.Outs.ConvertAll(refinementCloner.CloneFormal), req, mod, ens, decreases, body, refinementCloner.MergeAttributes(m.Attributes, moreAttributes), null, m); } else if (m is TwoStateLemma) { var two = (TwoStateLemma)m; return new TwoStateLemma(new RefinementToken(m.tok, moduleUnderConstruction), m.Name, m.HasStaticKeyword, tps, ins, m.Outs.ConvertAll(refinementCloner.CloneFormal), req, mod, ens, decreases, body, refinementCloner.MergeAttributes(m.Attributes, moreAttributes), null, m); } else { return new Method(new RefinementToken(m.tok, moduleUnderConstruction), m.Name, m.HasStaticKeyword, m.IsGhost, tps, ins, m.Outs.ConvertAll(refinementCloner.CloneFormal), req, mod, ens, decreases, body, refinementCloner.MergeAttributes(m.Attributes, moreAttributes), null, m); } }
Statement MergeElse(Statement skeleton, Statement oldStmt) { Contract.Requires(skeleton == null || skeleton is BlockStmt || skeleton is IfStmt || skeleton is SkeletonStatement); Contract.Requires(oldStmt == null || oldStmt is BlockStmt || oldStmt is IfStmt || oldStmt is SkeletonStatement); if (skeleton == null) { return refinementCloner.CloneStmt(oldStmt); } else if (skeleton is IfStmt || skeleton is SkeletonStatement) { // wrap a block statement around the if statement skeleton = new BlockStmt(skeleton.Tok, skeleton.EndTok, new List<Statement>() { skeleton }); } if (oldStmt == null) { // make it into an empty block statement oldStmt = new BlockStmt(skeleton.Tok, skeleton.EndTok, new List<Statement>()); } else if (oldStmt is IfStmt || oldStmt is SkeletonStatement) { // wrap a block statement around the if statement oldStmt = new BlockStmt(oldStmt.Tok, skeleton.EndTok, new List<Statement>() { oldStmt }); } Contract.Assert(skeleton is BlockStmt && oldStmt is BlockStmt); return MergeBlockStmt((BlockStmt)skeleton, (BlockStmt)oldStmt); }
private static Method GenerateMethod(Method oldMd, List<Statement> body, Method source = null) { var src = source ?? oldMd; var mdBody = new BlockStmt(src.Body.Tok, src.Body.EndTok, body); var type = src.GetType(); if (type == typeof(Lemma)) return new Lemma(src.tok, src.Name, src.HasStaticKeyword, src.TypeArgs, src.Ins, src.Outs, src.Req, src.Mod, src.Ens, src.Decreases, mdBody, src.Attributes, src.SignatureEllipsis); if (type == typeof(CoLemma)) return new CoLemma(src.tok, src.Name, src.HasStaticKeyword, src.TypeArgs, src.Ins, src.Outs, src.Req, src.Mod, src.Ens, src.Decreases, mdBody, src.Attributes, src.SignatureEllipsis); return new Method(src.tok, src.Name, src.HasStaticKeyword, src.IsGhost, src.TypeArgs, src.Ins, src.Outs, src.Req, src.Mod, src.Ens, src.Decreases, mdBody, src.Attributes, src.SignatureEllipsis); }
private static WhileStmt GenerateWhileStmt(WhileStmt original, Expression guard, Solution body) { var bodyList = body.State.GetAllUpdated(); var thenBody = new BlockStmt(original.Body.Tok, original.Body.EndTok, bodyList); return new WhileStmt(original.Tok, original.EndTok, Util.Copy.CopyExpression(guard), original.Invariants, original.Decreases, original.Mod, Util.Copy.CopyBlockStmt(thenBody)); }
public static IEnumerable<Solution> SearchBlockStmt(BlockStmt body, Atomic atomic) { Atomic ac = atomic.Copy(); ac.DynamicContext.tacticBody = body.Body; ac.DynamicContext.ResetCounter(); Stack<IEnumerator<Solution>> solutionStack = new Stack<IEnumerator<Solution>>(); solutionStack.Push(Atomic.ResolveStatement(new Solution(ac)).GetEnumerator()); while (true) { if (solutionStack.Count == 0) { yield break; } var solutionEnum = solutionStack.Pop(); // if the solution is fully resolved skip resolution if (!solutionEnum.MoveNext()) continue; var solution = solutionEnum.Current; solutionStack.Push(solutionEnum); if (solution.State.DynamicContext.isPartialyResolved) { solutionStack.Push(Atomic.ResolveStatement(solution).GetEnumerator()); yield return solution; } else if (solution.State.DynamicContext.GetCurrentStatement() == null) { yield return solution; } else { solutionStack.Push(Atomic.ResolveStatement(solution).GetEnumerator()); } } }
void UpdateStmt(out Statement/*!*/ s) { List<Expression> lhss = new List<Expression>(); List<AssignmentRhs> rhss = new List<AssignmentRhs>(); Expression e; AssignmentRhs r; IToken x, endTok = Token.NoToken; Attributes attrs = null; IToken suchThatAssume = null; Expression suchThat = null; Lhs(out e); x = e.tok; if (la.kind == 28 || la.kind == 46) { while (la.kind == 46) { Attribute(ref attrs); } Expect(28); endTok = t; rhss.Add(new ExprRhs(e, attrs)); } else if (la.kind == 22 || la.kind == 25 || la.kind == 95) { lhss.Add(e); while (la.kind == 22) { Get(); Lhs(out e); lhss.Add(e); } if (la.kind == 95) { Get(); x = t; Rhs(out r); rhss.Add(r); while (la.kind == 22) { Get(); Rhs(out r); rhss.Add(r); } } else if (la.kind == 25) { Get(); x = t; if (la.kind == _assume) { Expect(31); suchThatAssume = t; } Expression(out suchThat, false, true); } else SynErr(182); Expect(28); endTok = t; } else if (la.kind == 21) { Get(); SemErr(t, "invalid statement (did you forget the 'label' keyword?)"); } else SynErr(183); if (suchThat != null) { s = new AssignSuchThatStmt(x, endTok, lhss, suchThat, suchThatAssume, null); } else { if (lhss.Count == 0 && rhss.Count == 0) { s = new BlockStmt(x, endTok, new List<Statement>()); // error, give empty statement } else { s = new UpdateStmt(x, endTok, lhss, rhss); } } }
void WhileStmt(out Statement stmt) { Contract.Ensures(Contract.ValueAtReturn(out stmt) != null); IToken x; Expression guard = null; IToken guardEllipsis = null; List<MaybeFreeExpression> invariants = new List<MaybeFreeExpression>(); List<Expression> decreases = new List<Expression>(); Attributes decAttrs = null; Attributes modAttrs = null; List<FrameExpression> mod = null; BlockStmt body = null; IToken bodyEllipsis = null; IToken bodyStart = null, bodyEnd = null, endTok = Token.NoToken; List<GuardedAlternative> alternatives; stmt = dummyStmt; // to please the compiler bool isDirtyLoop = true; Expect(99); x = t; if (IsLoopSpec() || IsAlternative()) { while (StartOf(22)) { LoopSpec(invariants, decreases, ref mod, ref decAttrs, ref modAttrs); } AlternativeBlock(false, out alternatives, out endTok); stmt = new AlternativeLoopStmt(x, endTok, invariants, new Specification<Expression>(decreases, decAttrs), new Specification<FrameExpression>(mod, modAttrs), alternatives); } else if (StartOf(20)) { if (StartOf(21)) { Guard(out guard); Contract.Assume(guard == null || cce.Owner.None(guard)); } else { Get(); guardEllipsis = t; } while (StartOf(22)) { LoopSpec(invariants, decreases, ref mod, ref decAttrs, ref modAttrs); } if (la.kind == _lbrace) { BlockStmt(out body, out bodyStart, out bodyEnd); endTok = body.EndTok; isDirtyLoop = false; } else if (la.kind == _ellipsis) { Expect(59); bodyEllipsis = t; endTok = t; isDirtyLoop = false; } else if (StartOf(23)) { } else SynErr(187); if (guardEllipsis != null || bodyEllipsis != null) { if (mod != null) { SemErr(mod[0].E.tok, "'modifies' clauses are not allowed on refining loops"); } if (body == null && !isDirtyLoop) { body = new BlockStmt(x, endTok, new List<Statement>()); } stmt = new WhileStmt(x, endTok, guard, invariants, new Specification<Expression>(decreases, decAttrs), new Specification<FrameExpression>(null, null), body); stmt = new SkeletonStatement(stmt, guardEllipsis, bodyEllipsis); } else { // The following statement protects against crashes in case of parsing errors if (body == null && !isDirtyLoop) { body = new BlockStmt(x, endTok, new List<Statement>()); } stmt = new WhileStmt(x, endTok, guard, invariants, new Specification<Expression>(decreases, decAttrs), new Specification<FrameExpression>(mod, modAttrs), body); } } else SynErr(188); }
public override void Compile_FunctionAsMethod(Function function, Dictionary<TypeParameter,Type> typeArgs, Dictionary<string,TypeParameter> substArgs) { var tok = function.tok; if (Attributes.Contains(function.Attributes, "CompiledSpec")) { string specName = function.Name.Substring("CompiledSpec_".Length); function = FindFunction(specName); } bool hidden = Attributes.Contains(function.Attributes, "opaque"); Formal result = new Formal(function.tok, "__result", function.ResultType, false, function.IsGhost); string funName = function.Name; string name = FunName(DafnySpec.SimpleSanitizedName(function)); FunctionCallExpr call = new FunctionCallExpr(tok, name, new ThisExpr(tok), tok, function.Formals.ConvertAll(f => (Expression) MakeIdentifierExpr(f.Name, f.Type, f.IsGhost))); call.Function = function; call.TypeArgumentSubstitutions = typeArgs; call.Type = function.ResultType; CallStmt revealCall = null; if (hidden) { var selectExpr = new MemberSelectExpr(tok, new ThisExpr(tok), "reveal_" + function.Name); selectExpr.Member = FindMethod(selectExpr.MemberName); // Manually resolve here selectExpr.TypeApplication = new List<Type>(); // Manually resolve here selectExpr.Type = new InferredTypeProxy(); // Manually resolve here revealCall = new CallStmt(tok, tok, new List<Expression>(), selectExpr, new List<Expression>()); revealCall.IsGhost = true; ClassDecl cls = (ClassDecl)function.EnclosingClass; string fullName = "#" + function.Name + "_FULL"; function = (Function)cls.Members.Find(m => m.Name == fullName); if (function == null) { throw new Exception("internal error: could not find function " + fullName); } substArgs = new Dictionary<string,TypeParameter>(); function.TypeArgs.ForEach(t => substArgs.Add(t.Name, t)); typeArgs = typeArgs.ToDictionary(p => substArgs[p.Key.Name], p => p.Value); } Expression funBody = function.Body; BlockStmt body = null; if (funBody != null) { ReturnStmt retStmt = new ReturnStmt(tok, tok, new List<AssignmentRhs>() { new ExprRhs(funBody) }); body = new BlockStmt(tok, tok, hidden ? (new List<Statement>() { revealCall, retStmt }) : (new List<Statement>() { retStmt })); } List<Expression> ens = new List<Expression> { MakeBinaryExpr(BinaryExpr.Opcode.Eq, BinaryExpr.ResolvedOpcode.EqCommon, Type.Bool, MakeIdentifierExpr("__result", function.ResultType, function.IsGhost), call) }.Concat(function.Ens).ToList(); Method method = new Method(tok, funName, function.IsStatic, function.IsGhost, function.TypeArgs, function.Formals, new List<Formal> { result }, function.Req.ConvertAll(e => new MaybeFreeExpression(e)), new Specification<FrameExpression>(new List<FrameExpression>(), null), ens.ConvertAll(e => new MaybeFreeExpression(e)), function.Decreases, body, function.Attributes, function.SignatureEllipsis); method.EnclosingClass = function.EnclosingClass; Compile_Method(method, typeArgs); }
void BlockStmt(out BlockStmt/*!*/ block, out IToken bodyStart, out IToken bodyEnd) { Contract.Ensures(Contract.ValueAtReturn(out block) != null); List<Statement/*!*/> body = new List<Statement/*!*/>(); Expect(46); bodyStart = t; while (StartOf(15)) { Stmt(body); } Expect(47); bodyEnd = t; block = new BlockStmt(bodyStart, bodyEnd, body); }
// Find tactic application and resolve it private void SearchBlockStmt(BlockStmt body) { Contract.Requires(tcce.NonNull(body)); // TODO Make sure this is an OK Thing to be doing // Currently, if the proof list is not reset, then because it is static across // calls, it will start to build up old information, and the program will go // into a loop trying to figure out new fresh names for 'existing' methods. BaseSearchStrategy.ResetProofList(); _frame.Push(new Dictionary<IVariable, Type>()); foreach (var stmt in body.Body) { if (stmt is VarDeclStmt) { var vds = stmt as VarDeclStmt; // register local variable declarations foreach (var local in vds.Locals) { try { _frame.Peek().Add(local, local.Type); } catch (Exception e) { //TODO: some error handling when target is not resolved Console.Out.WriteLine(e.Message); } } } else if (stmt is IfStmt) { var ifStmt = stmt as IfStmt; SearchIfStmt(ifStmt); } else if (stmt is WhileStmt) { var whileStmt = stmt as WhileStmt; SearchBlockStmt(whileStmt.Body); } else if (stmt is UpdateStmt) { var us = stmt as UpdateStmt; if (_state.IsTacticCall(us)) { var list = StackToDict(_frame); var result = ApplyTactic(_state, list, us); if (result != null) { _resultList.Add(us.Copy(), result.GetGeneratedCode().Copy()); } else { //TODO what should go here? } } } else if (stmt is BlockStmt) { //TODO: } } _frame.Pop(); }
public override BlockStmt CloneBlockStmt(BlockStmt stmt) { return null; }