private Expression ParseSpecCastExpression(TokenSet followers, bool savedInSpecCode, SourceLocationBuilder slb) { if (this.CurrentTokenStartsTypeExpression()) { TypeExpression targetType = this.ParseTypeExpression(followers | Token.RightParenthesis); this.SkipOutOfSpecBlock(savedInSpecCode, TS.UnaryStart | followers); var valueToCast = this.ParseUnaryExpression(followers); slb.UpdateToSpan(valueToCast.SourceLocation); return new VccCast(valueToCast, targetType, slb); } if (this.currentToken == Token.Unchecked) { this.GetNextToken(); this.SkipOutOfSpecBlock(savedInSpecCode, TS.UnaryStart | followers); var uncheckedExpr = this.ParseUnaryExpression(followers); slb.UpdateToSpan(uncheckedExpr.SourceLocation); return new UncheckedExpression(uncheckedExpr, slb); } if (this.currentToken == Token.Identifier) { var id = this.scanner.GetIdentifierString(); //if (id.StartsWith("\\") && this.castlikeFunctions.ContainsKey(id.Substring(1))) // id = id.Substring(1); if (id == "atomic_op" || this.castlikeFunctions.ContainsKey(id)) { var methodName = id == "atomic_op" ? "" : this.castlikeFunctions[id]; var savedResultIsKeyword = this.resultIsAKeyword; this.resultIsAKeyword = (id == "atomic_op"); var isVarArgs = methodName.StartsWith("\\castlike_va_"); this.GetNextToken(); List<Expression> exprs = this.currentToken == Token.RightParenthesis ? new List<Expression>() : this.ParseExpressionList(Token.Comma, followers | Token.RightParenthesis); this.resultIsAKeyword = savedResultIsKeyword; this.SkipOutOfSpecBlock(savedInSpecCode, TS.UnaryStart | followers); if (isVarArgs) { slb.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken); var argList = new VccMethodCall(this.GetSimpleNameFor("\\argument_tuple"), exprs.ToArray(), slb.GetSourceLocation()); exprs.Clear(); exprs.Add(argList); } var expr = this.ParseUnaryExpression(followers); slb.UpdateToSpan(expr.SourceLocation); if (id == "atomic_op") { exprs.Add(expr); var atomicOp = new VccAtomicOp(this.GetSimpleNameFor("_vcc_atomic_op"), exprs.AsReadOnly(), slb); var atomicOpBlock = new VccAtomicOpBlock(new List<Statement>(0), atomicOp, slb); return new BlockExpression(atomicOpBlock, atomicOp, slb); } exprs.Insert(0, expr); return new VccMethodCall(this.GetSimpleNameFor(methodName), exprs, slb); } this.HandleError(Error.SyntaxError, this.scanner.GetTokenSource()); this.SkipOutOfSpecBlock(savedInSpecCode, followers); return new DummyExpression(slb); } this.HandleError(Error.SyntaxError, this.scanner.GetTokenSource()); this.SkipOutOfSpecBlock(savedInSpecCode, followers); return new DummyExpression(slb); }
protected override Statement ParseSpecStatements(TokenSet followers) { var scannerState = scanner.MakeSnapshot(); bool savedInSpecCode = this.SkipIntoSpecBlock(); switch (this.currentToken) { case Token.SpecUnwrapping: return this.ParseUnwrappingStatement(followers, savedInSpecCode); case Token.SpecAtomic: return this.ParseAtomic(followers, savedInSpecCode); case Token.Unchecked: return this.ParseUncheckedExpressionStatement(followers, savedInSpecCode); case Token.SpecEnsures: case Token.SpecReads: case Token.SpecRequires: case Token.SpecDecreases: case Token.SpecWrites: return this.ParseBlockWithContracts(followers, savedInSpecCode); case Token.Identifier: var id = this.scanner.GetIdentifierString(); if (this.functionContractExtensions.ContainsKey(id)) { return this.ParseBlockWithContracts(followers, savedInSpecCode); } if (id == "ghost_atomic") return this.ParseGhostAtomic(followers, savedInSpecCode); if (id == "pure") return this.ParseBlockWithPureModifier(followers, savedInSpecCode); if (this.declspecExtensions.ContainsKey(id)) { var specifiers = new List<Specifier>(); this.ParseSpecTypeModifierList(specifiers, followers | Token.RightParenthesis); this.SkipOutOfSpecBlock(savedInSpecCode, followers | TS.DeclaratorStart); return StatementGroup.Create(this.ParseLocalDeclaration(specifiers, followers)); } if (id == "atomic_op" || this.castlikeFunctions.ContainsKey(id)) { this.LeaveSpecBlock(savedInSpecCode); scanner.RevertToSnapshot(scannerState); this.currentToken = Token.Specification; if (id == "atomic_op") this.resultIsAKeyword = true; Expression expr = this.ParseExpression(true, false, followers | Token.Semicolon); this.resultIsAKeyword = false; var eStat = new ExpressionStatement(expr, new SourceLocationBuilder(expr.SourceLocation)); this.SkipSemiColonAfterDeclarationOrStatement(followers); return eStat; } break; } var statements = new List<Statement>(); TokenSet followersOrRightParenOrSpecStmt = followers | Token.RightParenthesis | STS.SimpleSpecStatment; while (STS.SimpleSpecStatment[this.currentToken] || (this.currentToken == Token.Identifier && this.statementLikeFunctions.ContainsKey(this.scanner.GetIdentifierString()))) { SourceLocationBuilder slb; switch (this.currentToken) { case Token.SpecGhost: slb = this.GetSourceLocationBuilderForLastScannedToken(); this.GetNextToken(); var stmt = this.ParseStatement(followersOrRightParenOrSpecStmt); slb.UpdateToSpan(stmt.SourceLocation); StatementGroup.AddStatementOrGroupToList(DeepWrapInSpecStmt(stmt, slb), statements); break; case Token.SpecAssert: statements.Add(this.ParseAssert(followersOrRightParenOrSpecStmt)); break; case Token.SpecAssume: statements.Add(this.ParseSingleArgSpecStatement(followersOrRightParenOrSpecStmt, (expr, sl) => new AssumeStatement(expr, sl))); break; case Token.Identifier: var keyword = this.scanner.GetIdentifierString(); var name = this.GetSimpleNameFor(this.statementLikeFunctions[keyword]); this.GetNextToken(); slb = new SourceLocationBuilder(name.SourceLocation); var parameters = new List<Expression>(); if (this.currentToken != Token.RightParenthesis) { this.ParseExpressionList(parameters, Token.Comma, true, followers | Token.RightParenthesis); slb.UpdateToSpan(parameters[parameters.Count - 1].SourceLocation); } var call = new VccMethodCall(name, parameters.AsReadOnly(), slb); var exprStmt = new ExpressionStatement(call); statements.Add(DeepWrapInSpecStmt(exprStmt, slb)); break; } this.SkipSemicolonsInSpecBlock(STS.SimpleSpecStatment | Token.Identifier | Token.RightParenthesis); } this.SkipOutOfSpecBlock(savedInSpecCode, followers); return StatementGroup.Create(statements); }