public void TestProcedureDeclarationWithoutParameters() { var programSource = new TokenList() { { TokenType.KwProcedure }, { TokenType.Identifier, "proc" }, { TokenType.LParen }, { TokenType.RParen }, { TokenType.LineTerm }, { TokenType.KwBegin }, { TokenType.Identifier, "writeln" }, { TokenType.LParen }, { TokenType.RParen }, { TokenType.KwEnd } }; Parser parser = new Parser(CreateMockScanner(programSource), new ErrorHandler()); ProgramNode program = parser.Parse(); var declr = new ProcedureDeclarationStmt(0, 0); declr.Identifier = "proc"; declr.ProcedureBlock = new BlockStmt(0, 0); var call = new CallStmt(0, 0); call.ProcedureId = "writeln"; declr.ProcedureBlock.Statements.Add(call); expected.Block.Statements.Add(declr); program.ShouldBeEquivalentTo(expected); }
public string GenerateString(CallStmt statement, int tabs) { var bob = new StringBuilder(); ApplyIndentation(bob, tabs); // Generate left hand side. if (statement.Lhs.Any()) { foreach (Expression lhs in statement.Lhs) { bob.Append(GenerateString(lhs)); bob.Append(", "); } bob.Remove(bob.Length - 2, 2); bob.Append(" " + statement.Tok.val + " "); } // Generate right hand side. bob.Append(statement.Receiver.tok.val + "("); if (statement.Args.Any()) { foreach (Expression arg in statement.Args) { bob.Append(GenerateString(arg)); bob.Append(", "); } bob.Remove(bob.Length - 2, 2); } bob.Append(")" + statement.EndTok.val); return(bob.ToString()); }
public void TestIfWithThen() { var programSource = new TokenList() { { TokenType.KwIf }, { TokenType.Identifier, "true" }, { TokenType.KwThen }, { TokenType.KwReturn }, { TokenType.KwElse }, { TokenType.Identifier, "writeln" }, { TokenType.LParen }, { TokenType.RParen } }; Parser parser = new Parser(CreateMockScanner(programSource), new ErrorHandler()); ProgramNode program = parser.Parse(); var ifStmt = new IfStmt(0, 0); ifStmt.TestExpr = new VariableExpr(0, 0, "true"); ifStmt.TrueStatement = new ReturnStmt(0, 0); var call = new CallStmt(0, 0); call.ProcedureId = "writeln"; ifStmt.FalseStatement = call; expected.Block.Statements.Add(ifStmt); program.ShouldBeEquivalentTo(expected); }
public void TestMultipleStatements() { var programSource = new TokenList() { { TokenType.KwAssert }, { TokenType.Identifier, "true" }, { TokenType.LineTerm }, { TokenType.Identifier, "writeln" }, { TokenType.LParen }, { TokenType.RParen }, { TokenType.LineTerm } }; Parser parser = new Parser(CreateMockScanner(programSource), new ErrorHandler()); ProgramNode program = parser.Parse(); var assert = new AssertStmt(0, 0); assert.AssertExpr = new VariableExpr(0, 0, "true"); var call = new CallStmt(0, 0); call.ProcedureId = "writeln"; expected.Block.Statements.Add(assert); expected.Block.Statements.Add(call); program.ShouldBeEquivalentTo(expected); }
Stmt parseCall(Exp start) { CallStmt stmtcall = new CallStmt(); stmtcall.CallExpr = start; matchSemiOrNewLine();//match(TokenKind.Semi); return(stmtcall); }
public void TestCallBeforeDeclaration() { var program = new ProgramNode(0, 0); program.Block = new BlockStmt(0, 0); var call = new CallStmt(0, 0); call.ProcedureId = "func"; program.Block.Statements.Add(call); AssertErrorContains(program, "Undeclared procedure 'func'"); }
public void TestCallWithWrongNumberOfArguments() { var program = new ProgramNode(0, 0); program.Block = new BlockStmt(0, 0); var call = new CallStmt(0, 0); call.ProcedureId = "func"; program.Block.Statements.Add(CreateFunction("func")); program.Block.Statements.Add(call); AssertErrorContains(program, "'func' takes 1 arguments, 0 given"); }
public void TestCallWithWrongArgumentType() { var program = new ProgramNode(0, 0); program.Block = new BlockStmt(0, 0); var call = new CallStmt(0, 0); call.ProcedureId = "func"; call.Arguments.Add(new StringLiteralExpr(0, 0, "asd")); program.Block.Statements.Add(CreateFunction("func")); program.Block.Statements.Add(call); AssertErrorContains(program, "'func' argument 1 expects a parameter of type Int, String given"); }
public void TestCorrectCallArguments() { var program = new ProgramNode(0, 0); program.Block = new BlockStmt(0, 0); var call = new CallStmt(0, 0); call.Arguments.Add(new IntLiteralExpr(0, 0, 1)); call.ProcedureId = "func"; program.Block.Statements.Add(CreateFunction("func")); program.Block.Statements.Add(call); AssertNoErrors(program); }
public void TestCallingVariable() { var program = new ProgramNode(0, 0); program.Block = new BlockStmt(0, 0); var declaration = CreateVarDeclaration("func"); var call = new CallStmt(0, 0); call.ProcedureId = "func"; call.Arguments.Add(new StringLiteralExpr(0, 0, "asd")); program.Block.Statements.Add(declaration); program.Block.Statements.Add(call); AssertErrorContains(program, "'func' is not defined as a function or a procedure"); }
public void TestReferenceArgumentWithoutVariable() { var program = new ProgramNode(0, 0); program.Block = new BlockStmt(0, 0); var function = CreateFunction("func"); function.Parameters[0] = new Parameter("arg1", new SimpleType(0, 0, ExprType.Int), true); var call = new CallStmt(0, 0); call.ProcedureId = "func"; call.Arguments.Add(new IntLiteralExpr(0, 0, 1)); program.Block.Statements.Add(function); program.Block.Statements.Add(call); AssertErrorContains(program, "'func' argument 1 expects a variable of type Int"); }
public void TestCallWithoutArguments() { var programSource = new TokenList() { { TokenType.Identifier, "func" }, { TokenType.LParen }, { TokenType.RParen } }; Parser parser = new Parser(CreateMockScanner(programSource), new ErrorHandler()); ProgramNode program = parser.Parse(); var call = new CallStmt(0, 0); call.ProcedureId = "func"; expected.Block.Statements.Add(call); program.ShouldBeEquivalentTo(expected); }
static string Example1() { Pirate p = new Pirate(); StringLiteral s1 = new StringLiteral("H\ae\bl\fl\vo\0 \'P\"arrot!\n"); Call c1 = new Call("print", s1); StmtList sl = new StmtList(); CallStmt cs1 = new CallStmt(c1); sl.Add(cs1); Sub main = new Sub("main", sl); p.Add(main); StringWriter sw = new StringWriter(); PirateWriter pv = new PirateWriter(sw); DynamicVisitor.accept(p, pv); return sw.ToString(); }
public void TestProcedureDeclarationWithMultipleParameters() { var programSource = new TokenList() { { TokenType.KwProcedure }, { TokenType.Identifier, "proc" }, { TokenType.LParen }, { TokenType.Identifier, "par1" }, { TokenType.Colon }, { TokenType.Identifier, "real" }, { TokenType.Comma }, { TokenType.KwVar }, { TokenType.Identifier, "par2" }, { TokenType.Colon }, { TokenType.Identifier, "string" }, { TokenType.RParen }, { TokenType.LineTerm }, { TokenType.KwBegin }, { TokenType.Identifier, "writeln" }, { TokenType.LParen }, { TokenType.RParen }, { TokenType.KwEnd } }; Parser parser = new Parser(CreateMockScanner(programSource), new ErrorHandler()); ProgramNode program = parser.Parse(); var declr = new ProcedureDeclarationStmt(0, 0); declr.Identifier = "proc"; declr.AddParameter("par1", new SimpleType(0, 0, ExprType.Real), false); declr.AddParameter("par2", new SimpleType(0, 0, ExprType.String), true); declr.ProcedureBlock = new BlockStmt(0, 0); var call = new CallStmt(0, 0); call.ProcedureId = "writeln"; declr.ProcedureBlock.Statements.Add(call); expected.Block.Statements.Add(declr); program.ShouldBeEquivalentTo(expected); }
public void TestCallWithMultipleArguments() { var programSource = new TokenList() { { TokenType.Identifier, "func" }, { TokenType.LParen }, { TokenType.IntLiteral, "2" }, { TokenType.Comma }, { TokenType.StringLiteral, "arg" }, { TokenType.RParen } }; Parser parser = new Parser(CreateMockScanner(programSource), new ErrorHandler()); ProgramNode program = parser.Parse(); var call = new CallStmt(0, 0); call.Arguments = new List <Expression>(); call.Arguments.Add(new IntLiteralExpr(0, 0, 2)); call.Arguments.Add(new StringLiteralExpr(0, 0, "arg")); call.ProcedureId = "func"; expected.Block.Statements.Add(call); program.ShouldBeEquivalentTo(expected); }
static string Example3() { Pirate p = new Pirate(); StmtList sl1 = new StmtList(); Sub joe = new Sub("joe", sl1); p.Add(joe); LocalDecl ld1 = new LocalDecl(); ld1.type = new StringType(); NamedReg name = new NamedReg(); name.name = "name"; IdList idl1 = new IdList(); idl1.Add(name); ld1.id_list = idl1; sl1.Add(ld1); Assign a1 = new Assign(); a1.lval = name; StringLiteral s1 = new StringLiteral(); s1.value = " Joe!"; a1.rval = s1; sl1.Add(a1); Assign a2 = new Assign(); StringLiteral s2 = new StringLiteral(); s2.value = "Hi!"; TmpStringReg tsr0 = new TmpStringReg(); tsr0.number = 0; a2.lval = tsr0; a2.rval = s2; sl1.Add(a2); Assign a3 = new Assign(); TmpStringReg tsr1 = new TmpStringReg(); tsr1.number = 1; BinaryCat bc1 = new BinaryCat(); bc1.a = tsr0; bc1.b = name; a3.lval = tsr1; a3.rval = bc1; sl1.Add(a3); AssignCat a4 = new AssignCat(); a4.lval = tsr1; StringLiteral s3 = new StringLiteral(); s3.value = "\n"; a4.rval = s3; sl1.Add(a4); CallStmt cs1 = new CallStmt(); Call c1 = new Call(); c1.func = "print"; c1.args = tsr1; cs1.call = c1; sl1.Add(cs1); StringWriter sw = new StringWriter(); PirateWriter pv = new PirateWriter(sw); DynamicVisitor.accept(p, pv); return sw.ToString(); }
static string Example6() { AtomExprList ael1 = new AtomExprList(); Call c1 = new Call("foo", ael1); CallStmt cs1 = new CallStmt(c1); NumLiteral n1 = new NumLiteral(3.14); TmpNumReg tnr0 = new TmpNumReg(0); Assign a1 = new Assign(tnr0, n1); TmpIntReg tir0 = new TmpIntReg(0); IntLiteral i1 = new IntLiteral(42); StringLiteral s1 = new StringLiteral("hi"); AtomExprList ael2 = new AtomExprList(); ael2.Add(tir0); ael2.Add(i1); ael2.Add(s1); Call c2 = new Call("bar", ael2); CallStmt cs2 = new CallStmt(c2); NamedReg a = new NamedReg("a"); LocalDecl ld1 = new LocalDecl(new IntType(), a); NamedReg b = new NamedReg("b"); LocalDecl ld2 = new LocalDecl(new NumType(), b); NamedReg c = new NamedReg("c"); LocalDecl ld3 = new LocalDecl(new StringType(), c); TmpNumReg tnr2 = new TmpNumReg(2); NumLiteral n2 = new NumLiteral(2.7); Assign a2 = new Assign(tnr2, n2); StringLiteral s2 = new StringLiteral("hello yourself"); AtomExprList ael3 = new AtomExprList(); ael3.Add(tnr2); ael3.Add(s2); Call c3 = new Call("baz", ael3); RegList rl4 = new RegList(); rl4.Add(a); rl4.Add(b); rl4.Add(c); Assign a3 = new Assign(rl4, c3); StmtList sl1 = new StmtList(); sl1.Add(cs1); sl1.Add(a1); sl1.Add(cs2); sl1.Add(ld1); sl1.Add(ld2); sl1.Add(ld3); sl1.Add(a2); sl1.Add(a3); Sub main = new Sub("main", sl1); StringLiteral s3 = new StringLiteral("Foo!\n"); Call c4 = new Call("print", s3); CallStmt cs3 = new CallStmt(c4); StmtList sl2 = new StmtList(); sl2.Add(cs3); Sub foo = new Sub("foo", sl2); NamedReg i = new NamedReg("i"); ParamDecl pd1 = new ParamDecl(new NumType(), i); NamedReg answer = new NamedReg("answer"); ParamDecl pd2 = new ParamDecl(new IntType(), answer); NamedReg message = new NamedReg("message"); ParamDecl pd3 = new ParamDecl(new StringType(), message); StringLiteral s4 = new StringLiteral("Bar!\n"); Call print1 = new Call("print", s4); CallStmt cs4 = new CallStmt(print1); Call print2 = new Call("print", i); CallStmt cs5 = new CallStmt(print2); StringLiteral s5 = new StringLiteral("\n"); Call print3 = new Call("print", s5); CallStmt cs6 = new CallStmt(print3); Call print4 = new Call("print", answer); CallStmt cs7 = new CallStmt(print4); CallStmt cs8 = new CallStmt(print3); Call print5 = new Call("print", message); CallStmt cs9 = new CallStmt(print5); StmtList sl3 = new StmtList(); sl3.Add(pd1); sl3.Add(pd2); sl3.Add(pd3); sl3.Add(cs4); sl3.Add(cs5); sl3.Add(cs6); sl3.Add(cs7); sl3.Add(cs8); sl3.Add(cs9); Sub bar = new Sub("bar", sl3); NamedReg e = new NamedReg("e"); ParamDecl pd4 = new ParamDecl(new NumType(), e); NamedReg msg = new NamedReg("msg"); ParamDecl pd5 = new ParamDecl(new StringType(), msg); StringLiteral s6 = new StringLiteral("Baz!\n"); Call print7 = new Call("print", s6); CallStmt cs10 = new CallStmt(print7); Call print8 = new Call("print", e); CallStmt cs11 = new CallStmt(print8); Call print9 = new Call("print", s5); CallStmt cs12 = new CallStmt(print9); Call print10 = new Call("print", msg); CallStmt cs13 = new CallStmt(print10); AtomExprList ael4 = new AtomExprList(); ael4.Add(new IntLiteral(1000)); ael4.Add(new NumLiteral(1.23)); ael4.Add(new StringLiteral("hi from baz")); ReturnStmt rs1 = new ReturnStmt(ael4); StmtList sl4 = new StmtList(); sl4.Add(pd4); sl4.Add(pd5); sl4.Add(cs10); sl4.Add(cs11); sl4.Add(cs12); sl4.Add(cs13); sl4.Add(rs1); Sub baz = new Sub("baz", sl4); Pirate p = new Pirate(); p.Add(main); p.Add(foo); p.Add(bar); p.Add(baz); StringWriter sw = new StringWriter(); PirateWriter pv = new PirateWriter(sw); DynamicVisitor.accept(p, pv); return sw.ToString(); }
TextWriter TrCallStmt(CallStmt s, string receiverReplacement, int indent) { Contract.Requires(s != null); Contract.Assert(s.Method != null); // follows from the fact that stmt has been successfully resolved StringWriter wr = new StringWriter(); if (s.Method == enclosingMethod && enclosingMethod.IsTailRecursive) { // compile call as tail-recursive // assign the actual in-parameters to temporary variables var inTmps = new List<string>(); for (int i = 0; i < s.Method.Ins.Count; i++) { Formal p = s.Method.Ins[i]; if (!p.IsGhost) { } } if (receiverReplacement != null) { // TODO: What to do here? When does this happen, what does it mean? } else if (!s.Method.IsStatic) { string inTmp = idGenerator.FreshId("_in"); inTmps.Add(inTmp); Indent(indent, wr); wr.Write("var {0} = ", inTmp); TrExpr(s.Receiver, wr, false); wr.WriteLine(";"); } for (int i = 0; i < s.Method.Ins.Count; i++) { Formal p = s.Method.Ins[i]; if (!p.IsGhost) { string inTmp = idGenerator.FreshId("_in"); inTmps.Add(inTmp); Indent(indent, wr); wr.Write("var {0} = ", inTmp); TrExpr(s.Args[i], wr, false); wr.WriteLine(";"); } } // Now, assign to the formals int n = 0; if (!s.Method.IsStatic) { Indent(indent, wr); wr.WriteLine("_this = {0};", inTmps[n]); n++; } foreach (var p in s.Method.Ins) { if (!p.IsGhost) { Indent(indent, wr); wr.WriteLine("{0} = {1};", p.CompileName, inTmps[n]); n++; } } Contract.Assert(n == inTmps.Count); // finally, the jump back to the head of the method Indent(indent, wr); wr.WriteLine("goto TAIL_CALL_START;"); } else { // compile call as a regular call var lvalues = new List<string>(); Contract.Assert(s.Lhs.Count == s.Method.Outs.Count); for (int i = 0; i < s.Method.Outs.Count; i++) { Formal p = s.Method.Outs[i]; if (!p.IsGhost) { lvalues.Add(CreateLvalue(s.Lhs[i], indent, wr)); } } var outTmps = new List<string>(); for (int i = 0; i < s.Method.Outs.Count; i++) { Formal p = s.Method.Outs[i]; if (!p.IsGhost) { string target = idGenerator.FreshId("_out"); outTmps.Add(target); Indent(indent, wr); wr.WriteLine("{0} {1};", TypeName(s.Lhs[i].Type, wr), target); } } Contract.Assert(lvalues.Count == outTmps.Count); for (int i = 0; i < s.Method.Ins.Count; i++) { Formal p = s.Method.Ins[i]; if (!p.IsGhost) { } } if (receiverReplacement != null) { Indent(indent, wr); wr.Write("@" + receiverReplacement); } else if (s.Method.IsStatic) { Indent(indent, wr); wr.Write(TypeName_Companion(s.Receiver.Type, wr)); } else { Indent(indent, wr); TrParenExpr(s.Receiver, wr, false); } wr.Write(".@{0}(", s.Method.CompileName); string sep = ""; for (int i = 0; i < s.Method.Ins.Count; i++) { Formal p = s.Method.Ins[i]; if (!p.IsGhost) { wr.Write(sep); TrExpr(s.Args[i], wr, false); sep = ", "; } } foreach (var outTmp in outTmps) { wr.Write("{0}out {1}", sep, outTmp); sep = ", "; } wr.WriteLine(");"); // assign to the actual LHSs for (int j = 0; j < lvalues.Count; j++) { Indent(indent, wr); wr.WriteLine("{0} = {1};", lvalues[j], outTmps[j]); } } return wr; }
void TrCallStmt(CallStmt s) { Contract.Requires(s != null); Contract.Assert(s.Method != null); // follows from the fact that stmt has been successfully resolved if (s.Method == enclosingMethod && enclosingMethod.IsTailRecursive) { // compile call as tail-recursive j.WriteComment("TrCallStmt tail-recursive calls not supported"); } else { // compile call as a regular call Contract.Assert(s.Lhs.Count == s.Method.Outs.Count); int OutParam = -1; for (int i = 0; i < s.Method.Outs.Count; i++) { Formal p = s.Method.Outs[i]; if (!p.IsGhost) { if (OutParam != -1) { j.WriteComment("Multiple out parameters are unsupported"); // bugbug: implement } else { OutParam = i; } } } if (OutParam != -1) { // easy - one ELet j.WriteStartArray(); j.WriteValue(KremlinAst.EAssign); // of (expr * expr) j.WriteStartArray(); TrExpr(s.Lhs[OutParam], false); } using (WriteArray()) { j.WriteValue(KremlinAst.EApp); using (WriteArray()) { // of (expr * expr list) // expr1: Function to call using (WriteArray()) { var old = j.Formatting; j.Formatting = Formatting.None; j.WriteValue(KremlinAst.EQualified); // of lident // s.Method.IsStatic() would generate a "TypeName.MethodName()" // call in C#. For Kremlin, the type name is already explicit, // so no work to do. // // For the non-static case, of s.Receiver, this would generate // a "receiver.MethodName()" call in C#. For Kremlin, we pass // the receiver as the first argument. WriteLident(s.Method); j.Formatting = old; } // expr2: list of arguments using (WriteArray()) { if (!s.Method.IsStatic) { // Pass 'this' as the first argument TrExpr(s.Receiver, false); } for (int i = 0; i < s.Method.Ins.Count; i++) { Formal p = s.Method.Ins[i]; if (!p.IsGhost) { TrExpr(s.Args[i], false); } } } } } if (OutParam != -1) { // Complete the EAssign j.WriteEndArray(); j.WriteEndArray(); } } }
void IVisitor.VisitBefore(CallStmt callStmt) { this.ParentExists(callStmt); }
public virtual void AddResolvedGhostStatement(Statement stmt) { BlockStmt block = stmt as BlockStmt; IfStmt ifStmt = stmt as IfStmt; AssertStmt assertStmt = stmt as AssertStmt; AssignStmt assignStmt = stmt as AssignStmt; CallStmt callStmt = stmt as CallStmt; VarDecl varDecl = stmt as VarDecl; CalcStmt calcStmt = stmt as CalcStmt; ForallStmt forallStmt = stmt as ForallStmt; AssignSuchThatStmt existsStmt = stmt as AssignSuchThatStmt; if (block != null) { var oldRenamer = PushRename(); block.Body.ForEach(AddGhostStatement); PopRename(oldRenamer); } else if (varDecl != null) { AddGhostVarDecl(varDecl.Name, varDecl.Type, varDecl.IsGhost); } else if (minVerify) { return; } else if (assignStmt != null) { ExprRhs expRhs = assignStmt.Rhs as ExprRhs; if (expRhs != null) { FieldSelectExpr fieldSelect = assignStmt.Lhs as FieldSelectExpr; RtlVar destVar; if (fieldSelect != null) { destVar = new RtlVar(GhostVar(fieldSelect.FieldName), true, fieldSelect.Type); } else { destVar = AsVar(assignStmt.Lhs); Util.Assert(destVar != null); } stmts.Add(new RtlGhostMove(new RtlVar[] { destVar }, new RtlExp[] { GhostExpression(expRhs.Expr) })); } else { throw new Exception("not implemented: " + assignStmt.Rhs); } } else if (callStmt != null) { AddGhostCall(callStmt.Lhs.ConvertAll(AsVar), callStmt.Args, dafnySpec.Compile_Method(callStmt.Method, callStmt.TypeArgumentSubstitutions.ToDictionary(p => p.Key, p => AppType(p.Value))), DafnySpec.IsHeapMethod(callStmt.Method)); SymdiffLinearityPoint(); } else if (ifStmt != null) { stmts.Add(new RtlGhostStmtComputed(s => "if (" + s.args[0] + ") {", new RtlExp[] { GhostExpression(ifStmt.Guard) })); Indent(); AddGhostStatement(ifStmt.Thn); Unindent(); stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0])); if (ifStmt.Els != null) { stmts.Add(new RtlGhostStmtComputed(s => "if (" + s.args[0] + ") {", new RtlExp[] { GhostExpression(new UnaryExpr(Bpl.Token.NoToken, UnaryExpr.Opcode.Not, ifStmt.Guard)) })); Indent(); AddGhostStatement(ifStmt.Els); Unindent(); stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0])); } } else if (assertStmt != null) { stmts.Add(new RtlAssert(GhostExpression(assertStmt.Expr))); } else if (forallStmt != null) { var oldRenamer = PushRename(forallStmt.BoundVars.Select(v => v.Name)); RtlExp ens = new RtlLiteral("true"); foreach (var e in forallStmt.Ens) { ens = new RtlBinary("&&", ens, GhostExpression(e.E)); } RtlExp range = (forallStmt.Range == null) ? new RtlLiteral("true") : GhostExpression(forallStmt.Range); List <RtlExp> wellFormed = GetTypeWellFormed(forallStmt.BoundVars. Select(x => Tuple.Create(GhostVar(x.Name), x.IsGhost, x.Type)).ToList()); wellFormed.ForEach(e => range = new RtlBinary("&&", e, range)); ens = new RtlBinary("==>", range, ens); string vars = String.Join(", ", forallStmt.BoundVars.Select(x => GhostVar(x.Name) + ":" + TypeString(AppType(x.Type)))); stmts.Add(new RtlGhostStmtComputed(s => "forall " + vars + "::(" + s.args[0] + ")", new List <RtlExp> { ens })); stmts.Add(new RtlGhostStmtComputed(s => "{", new RtlExp[0])); Indent(); stmts.Add(PushForall()); stmts.Add(new RtlGhostStmtComputed(s => "if (" + s.args[0] + ")", new List <RtlExp> { range })); stmts.Add(new RtlGhostStmtComputed(s => "{", new RtlExp[0])); Indent(); AddGhostStatement(forallStmt.Body); foreach (var e in forallStmt.Ens) { stmts.Add(new RtlAssert(GhostExpression(e.E))); } PopForall(); Unindent(); stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0])); Unindent(); stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0])); PopRename(oldRenamer); } else if (existsStmt != null) { List <RtlStmt> assigns = new List <RtlStmt>(); List <RtlVar> tmps = new List <RtlVar>(); List <Tuple <string, bool, Type> > varTuples = new List <Tuple <string, bool, Type> >(); var oldRenamer = PushRename(); foreach (var lhs in existsStmt.Lhss) { IdentifierExpr idExp = lhs.Resolved as IdentifierExpr; RtlVar origVar = AsVar(lhs); AddRename(idExp.Name); RtlVar renameVar = AsVar(lhs); tmps.Add(renameVar); varTuples.Add(Tuple.Create(renameVar.ToString(), true, idExp.Type)); assigns.Add(new RtlGhostMove(new RtlVar[] { origVar }, new RtlExp[] { renameVar })); } string vars = String.Join(", ", tmps.Select(x => x.getName() + ":" + TypeString(AppType(x.type)))); stmts.Add(new RtlGhostStmtComputed(s => "exists " + vars + "::(" + s.args[0] + ");", new List <RtlExp> { GetTypeWellFormedExp(varTuples.ToList(), "&&", GhostExpression(existsStmt.Expr)) })); stmts.AddRange(assigns); PopRename(oldRenamer); } else if (calcStmt != null) { Util.Assert(calcStmt.Steps.Count == calcStmt.Hints.Count); CalcStmt.BinaryCalcOp binOp = calcStmt.Op as CalcStmt.BinaryCalcOp; bool isImply = binOp != null && binOp.Op == BinaryExpr.Opcode.Imp && calcStmt.Steps.Count > 0; if (isImply) { stmts.Add(new RtlGhostStmtComputed(s => "if (" + s.args[0] + ")", new RtlExp[] { GhostExpression(CalcStmt.Lhs(calcStmt.Steps[0])) })); stmts.Add(new RtlGhostStmtComputed(s => "{", new RtlExp[0])); Indent(); } var stepCount = calcStmt.Hints.Last().Body.Count == 0 ? calcStmt.Steps.Count - 1 : calcStmt.Steps.Count; for (int i = 0; i < stepCount; i++) { if (calcStmt.Hints[i] == null) { stmts.Add(new RtlAssert(GhostExpression(calcStmt.Steps[i]))); } else { stmts.Add(new RtlGhostStmtComputed(s => "forall::(" + s.args[0] + ")", new List <RtlExp> { GhostExpression(calcStmt.Steps[i]) })); stmts.Add(new RtlGhostStmtComputed(s => "{", new RtlExp[0])); Indent(); var dict = new Dictionary <string, RtlVar>(); stmts.Add(new RtlGhostStmtComputed(s => String.Concat(dict.Values.Select( x => "var " + x.x + ":" + TypeString(x.type) + ";")), new RtlExp[0])); forallVars.Add(dict); AddGhostStatement(calcStmt.Hints[i]); forallVars.RemoveAt(forallVars.Count - 1); Unindent(); stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0])); } } if (isImply) { Unindent(); stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0])); } } else { throw new Exception("not implemented in ghost methods: " + stmt); } }
// ----- Expressions ------------------------------------------------------------- protected override void EmitNew(Type type, Bpl.IToken tok, CallStmt /*?*/ initCall, TargetWriter wr) { wr.Write("new {0}()", TypeName(type, wr, tok)); }
static string Example2() { NamedReg a = new NamedReg("a"); NamedReg b = new NamedReg("b"); NamedReg c = new NamedReg("c"); NamedReg det = new NamedReg("det"); IdList rl1 = new IdList(); rl1.Add(a); rl1.Add(b); rl1.Add(c); rl1.Add(det); LocalDecl ld1 = new LocalDecl(new NumType(), rl1); IntLiteral il3 = new IntLiteral(2); Assign a12 = new Assign(a, il3); IntLiteral il4 = new IntLiteral(-3); Assign a13 = new Assign(b, il4); IntLiteral il5 = new IntLiteral(-2); Assign a14 = new Assign(c, il5); UnaryNeg un1 = new UnaryNeg(b); TmpNumReg tnr0 = new TmpNumReg(0); Assign a1 = new Assign(tnr0, un1); TmpNumReg tnr1 = new TmpNumReg(1); BinaryMul bm1 = new BinaryMul(b, b); Assign a2 = new Assign(tnr1, bm1); TmpNumReg tnr2 = new TmpNumReg(2); IntLiteral il1 = new IntLiteral(4); BinaryMul bm2 = new BinaryMul(il1, a); Assign a3 = new Assign(tnr2, bm2); BinaryMul bm3 = new BinaryMul(tnr2, c); Assign a4 = new Assign(tnr2, bm3); TmpNumReg tnr3 = new TmpNumReg(3); IntLiteral il2 = new IntLiteral(2); BinaryMul bm4 = new BinaryMul(il2, a); Assign a5 = new Assign(tnr3, bm4); BinarySub bs1 = new BinarySub(tnr1, tnr2); Assign a6 = new Assign(det, bs1); TmpNumReg tnr4 = new TmpNumReg(4); Call sqrt = new Call("sqrt", det); Assign a7 = new Assign(tnr4, sqrt); NamedReg x1 = new NamedReg("x1"); NamedReg x2 = new NamedReg("x2"); IdList rl2 = new IdList(); rl2.Add(x1); rl2.Add(x2); LocalDecl ld2 = new LocalDecl(new NumType(), rl2); BinaryAdd ba1 = new BinaryAdd(tnr0, tnr4); Assign a8 = new Assign(x1, ba1); BinaryDiv bd1 = new BinaryDiv(x1, tnr3); Assign a9 = new Assign(x1, bd1); BinarySub bs2 = new BinarySub(tnr0, tnr4); Assign a10 = new Assign(x2, bs2); AssignDiv a11 = new AssignDiv(x2, tnr3); StringLiteral s1 = new StringLiteral("Answers to ABC formula are:\n"); Call c1 = new Call("print", s1); CallStmt print1 = new CallStmt(c1); StringLiteral s2 = new StringLiteral("x1 = "); Call c2 = new Call("print", s2); CallStmt print2 = new CallStmt(c2); Call c3 = new Call("print", x1); CallStmt print3 = new CallStmt(c3); StringLiteral s4 = new StringLiteral("\nx2 = "); Call c4 = new Call("print", s4); CallStmt print4 = new CallStmt(c4); Call c5 = new Call("print", x2); CallStmt print5 = new CallStmt(c5); StringLiteral s6 = new StringLiteral("\n"); Call c6 = new Call("print", s6); CallStmt print6 = new CallStmt(c6); StmtList sl1 = new StmtList(); sl1.Add(ld1); sl1.Add(a12); sl1.Add(a13); sl1.Add(a14); sl1.Add(a1); sl1.Add(a2); sl1.Add(a3); sl1.Add(a4); sl1.Add(a5); sl1.Add(a6); sl1.Add(a7); sl1.Add(ld2); sl1.Add(a8); sl1.Add(a9); sl1.Add(a10); sl1.Add(a11); sl1.Add(print1); sl1.Add(print2); sl1.Add(print3); sl1.Add(print4); sl1.Add(print5); sl1.Add(print6); Sub foo = new Sub("foo", sl1); Pirate p = new Pirate(); p.Add(foo); StringWriter sw = new StringWriter(); PirateWriter pv = new PirateWriter(sw); DynamicVisitor.accept(p, pv); return sw.ToString(); }
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 IVisitor.VisitAfter(CallStmt callStmt) { this.ParentExists(callStmt); }
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)); }
void StatementRegions(Statement stmt, List <IdRegion> regions, Microsoft.Dafny.Program prog, ModuleDefinition module) { Contract.Requires(stmt != null); Contract.Requires(regions != null); Contract.Requires(prog != null); IdRegion.AddRecognizedAttributes(stmt.Attributes, regions, prog); if (stmt is VarDeclStmt) { var s = (VarDeclStmt)stmt; // Add the variables here, once, and then go directly to the RHS's (without letting the sub-statements re-do the LHS's) foreach (var local in s.Locals) { IdRegion.AddRecognizedAttributes(local.Attributes, regions, prog); IdRegion.Add(regions, prog, local.Tok, local, true, (ICallable)null, module); } if (s.Update == null) { // the VarDeclStmt has no associated assignment } else if (s.Update is UpdateStmt) { var upd = (UpdateStmt)s.Update; foreach (var rhs in upd.Rhss) { foreach (var ee in rhs.SubExpressions) { ExprRegions(ee, regions, prog, module); } if (rhs is TypeRhs) { CallStmt call = ((TypeRhs)rhs).InitCall; if (call != null) { var method = call.Method; if (method != null) { if (method is Constructor) { // call token starts at the beginning of "new C()", so we need to add 4 to the length. RecordUseAndDef(prog, call.Tok, method.EnclosingClass.Name.Length + 4, method.EnclosingClass.tok); } else { RecordUseAndDef(prog, call.Tok, method.Name.Length, method.tok); } } } } } } else { var upd = (AssignSuchThatStmt)s.Update; ExprRegions(upd.Expr, regions, prog, module); } // we're done, so don't do the sub-statements/expressions again return; } else if (stmt is LetStmt) { var s = (LetStmt)stmt; foreach (var local in s.LHS.Vars) { IdRegion.Add(regions, prog, local.Tok, local, true, (ICallable)null, module); } } else if (stmt is ForallStmt) { var s = (ForallStmt)stmt; s.BoundVars.ForEach(bv => IdRegion.Add(regions, prog, bv.tok, bv, true, (ICallable)null, module)); } else if (stmt is MatchStmt) { var s = (MatchStmt)stmt; foreach (var kase in s.Cases) { kase.Arguments.ForEach(bv => { IdRegion.Add(regions, prog, bv.tok, bv, true, (ICallable)null, module); // if the arguments is an encapsulation of different boundvars from nested match cases, // add the boundvars so that they can show up in the IDE correctly if (bv.tok is MatchCaseToken) { MatchCaseToken mt = (MatchCaseToken)bv.tok; foreach (Tuple <Bpl.IToken, BoundVar, bool> entry in mt.varList) { IdRegion.Add(regions, prog, entry.Item1, entry.Item2, entry.Item3, (ICallable)null, module); } } }); } } else if (stmt is LoopStmt) { var s = (LoopStmt)stmt; if (s.Mod.Expressions != null) { s.Mod.Expressions.ForEach(fe => FrameExprRegions(fe, regions, false, prog, module)); } } else if (stmt is CalcStmt) { var s = (CalcStmt)stmt; // skip the last line, which is just a duplicate anyway for (int i = 0; i < s.Lines.Count - 1; i++) { ExprRegions(s.Lines[i], regions, prog, module); } foreach (var ss in stmt.SubStatements) { StatementRegions(ss, regions, prog, module); } return; } else if (stmt is CallStmt) { var s = (CallStmt)stmt; var method = s.Method; if (method != null) { RecordUseAndDef(prog, s.MethodSelect.tok, method.Name.Length, method.tok); } } foreach (var ee in stmt.SubExpressions) { ExprRegions(ee, regions, prog, module); } foreach (var ss in stmt.SubStatements) { StatementRegions(ss, regions, prog, module); } }
public void visit(CallStmt n) { // Validate n.obj // Validate n.mid // Validate n.args ObjType objType; MethodRec m; if (null != n.obj) { objType = (ObjType)n.obj.accept(this); ClassRec rec = symTable.getClass(objType.cid); m = symTable.getMethod(rec, n.mid); } else { m = symTable.getMethod(currClass, n.mid); } if (m == null) throw new TypeException("Method name missing from symbol table"); int paramCnt = m.paramCnt(); int argCnt = n.args.size(); if (paramCnt != argCnt) throw new TypeException(" Formals' and actuals' counts don't match: " + paramCnt + " vs. " + argCnt); VarRec param; Type t1, t2; for (int i = 0; i < paramCnt; ++i){ param = m.getParamAt(i); t1 = param.type().accept(this); t2 = n.args.elementAt(i).accept(this); if (!compatible(t1, t2)) { throw new TypeException("Formal's and actual's types not compatible: " + t1.toString() + " vs. " + t2.toString()); } } }