Example #1
0
 private void ParseRestOfEnum(SourceLocationBuilder sctx, TypeDeclaration type, List<ITypeDeclarationMember> members, TokenSet followers)
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   TypeExpression texpr = new NamedTypeExpression(new SimpleName(type.Name, type.Name.SourceLocation, false));
   this.Skip(Token.LeftBrace);
   while (this.currentToken == Token.LeftBracket || Parser.IdentifierOrNonReservedKeyword[this.currentToken]){
     this.ParseEnumMember(texpr, members, followers|Token.Comma|Token.RightBrace);
     if (this.currentToken == Token.RightBrace) break;
     this.Skip(Token.Comma);
     if (this.currentToken == Token.RightBrace) break;
   }
   sctx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
   this.Skip(Token.RightBrace);
   if (this.currentToken == Token.Semicolon)
     this.GetNextToken();
   this.SkipTo(followers);
 }
Example #2
0
 private TypeExpression ParseBaseTypeExpression(bool allowEmptyArguments, TokenSet followers) 
   //^ requires this.currentToken != Token.EndOfFile;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   TypeExpression result;
   switch(this.currentToken){
     case Token.Bool:
     case Token.Decimal:
     case Token.Sbyte:
     case Token.Byte:
     case Token.Short:
     case Token.Ushort:
     case Token.Int:
     case Token.Uint:
     case Token.Long:
     case Token.Ulong:
     case Token.Char:
     case Token.Float:
     case Token.Double:
     case Token.Object:
     case Token.String:
     case Token.Void:
       result = this.GetTypeExpressionFor(this.currentToken, this.scanner.SourceLocationOfLastScannedToken);
       this.GetNextToken();
       this.SkipTo(followers);
       break;
     default:
       Expression expr = this.ParseNamespaceOrTypeName(allowEmptyArguments, followers);
       GenericTypeInstanceExpression/*?*/ gtexpr = expr as GenericTypeInstanceExpression;
       if (gtexpr != null)
         result = gtexpr;
       else
         result = new NamedTypeExpression(expr);
       break;
   }
   return result;
 }
Example #3
0
 private Expression ParseNamespaceOrTypeName(bool allowEmptyArguments, TokenSet followers)
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
   //^ ensures result is SimpleName || result is AliasQualifiedName || result is QualifiedName || result is GenericTypeInstanceExpression;
 {
   SimpleName rootName = this.ParseSimpleName(followers|Token.Dot|Token.DoubleColon|Token.LessThan);
   Expression expression = rootName;
   if (rootName.Name.UniqueKey == this.nameTable.global.UniqueKey && this.currentToken == Token.DoubleColon)
     expression = new RootNamespaceExpression(rootName.SourceLocation);
   SourceLocationBuilder sctx = new SourceLocationBuilder(expression.SourceLocation);
   if (this.currentToken == Token.DoubleColon) {
     this.GetNextToken();
     SimpleName simpleName = this.ParseSimpleName(followers|Token.Dot|Token.LessThan);
     sctx.UpdateToSpan(simpleName.SourceLocation);
     expression = new AliasQualifiedName(expression, simpleName, sctx.GetSourceLocation());
   }
   //^ assume expression is SimpleName || expression is AliasQualifiedName; //RootNamespace will always disappear into AliasQualifiedName
 moreDots:
   while (this.currentToken == Token.Dot)
     //^ invariant expression is SimpleName || expression is AliasQualifiedName || expression is QualifiedName || expression is GenericTypeInstanceExpression;
   {
     this.GetNextToken();
     SimpleName simpleName = this.ParseSimpleName(followers|Token.Dot|Token.LessThan);
     sctx.UpdateToSpan(simpleName.SourceLocation);
     expression = new QualifiedName(expression, simpleName, sctx.GetSourceLocation());
   }
   if (this.currentToken == Token.LessThan) {
     //^ assume expression is SimpleName || expression is AliasQualifiedName || expression is QualifiedName; //Can only get back here if generic instance was followed by dot.
     TypeExpression genericType = new NamedTypeExpression(expression);
     while (this.currentToken == Token.LessThan)
       //^ invariant expression is SimpleName || expression is AliasQualifiedName || expression is QualifiedName || expression is GenericTypeInstanceExpression;
     {
       List<TypeExpression> arguments = this.ParseTypeArguments(sctx, allowEmptyArguments, followers|Token.Dot);
       expression = new GenericTypeInstanceExpression(genericType, arguments.AsReadOnly(), sctx.GetSourceLocation());
     }
     if (this.currentToken == Token.Dot) goto moreDots;
   }
   if (this.insideType && !this.insideBlock && !followers[this.currentToken])
     this.SkipTo(followers, Error.InvalidMemberDecl, this.scanner.GetTokenSource());
   else
     this.SkipTo(followers);
   return expression;
 }
Example #4
0
    private void ParseOperator(List<ITypeDeclarationMember> members, 
      List<SourceCustomAttribute>/*?*/ attributes, List<ModifierToken> modifiers, TypeExpression/*?*/ resultType, SourceLocationBuilder sctx, TokenSet followers)
      //^ requires this.currentToken == Token.Explicit || this.currentToken == Token.Implicit || this.currentToken == Token.Operator;
      //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
    {
      MethodDeclaration.Flags flags = MethodDeclaration.Flags.SpecialName;
      TypeMemberVisibility visibility = this.ConvertToTypeMemberVisibility(modifiers);
      this.LookForModifier(modifiers, Token.Abstract, Error.InvalidModifier);
      if (this.LookForModifier(modifiers, Token.Extern, Error.None)) flags |= MethodDeclaration.Flags.External;
      this.LookForModifier(modifiers, Token.New, Error.InvalidModifier);
      this.LookForModifier(modifiers, Token.Override, Error.InvalidModifier);
      this.LookForModifier(modifiers, Token.Readonly, Error.InvalidModifier);
      this.LookForModifier(modifiers, Token.Sealed, Error.InvalidModifier);
      if (this.LookForModifier(modifiers, Token.Static, Error.None)) flags |= MethodDeclaration.Flags.Static;
      if (this.LookForModifier(modifiers, Token.Unsafe, Error.None)) flags |= MethodDeclaration.Flags.Unsafe;
      this.LookForModifier(modifiers, Token.Virtual, Error.InvalidModifier);
      this.LookForModifier(modifiers, Token.Volatile, Error.InvalidModifier);


      NameDeclaration opName = new NameDeclaration(this.nameTable.EmptyName, this.scanner.SourceLocationOfLastScannedToken);
      SourceLocationBuilder ctx = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
      ISourceLocation symCtx = this.scanner.SourceLocationOfLastScannedToken;
      bool canBeBinary = false;
      bool canBeUnary = false;
      switch (this.currentToken) {
        case Token.Explicit:
          this.GetNextToken();
          ctx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
          opName = this.GetNameDeclarationFor("op_Explicit", ctx.GetSourceLocation());
          this.Skip(Token.Operator);
          if (resultType != null && this.currentToken == Token.LeftParenthesis)
            this.HandleError(opName.SourceLocation, Error.BadOperatorSyntax, "explicit");
          else
            resultType = this.ParseTypeExpression(false, false, followers|Token.LeftParenthesis);
          canBeUnary = true;
          break;
        case Token.Implicit:
          this.GetNextToken();
          ctx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
          opName = this.GetNameDeclarationFor("op_Implicit", ctx.GetSourceLocation());
          this.Skip(Token.Operator);
          if (resultType != null && this.currentToken == Token.LeftParenthesis)
            this.HandleError(opName.SourceLocation, Error.BadOperatorSyntax, "implicit");
          else
            resultType = this.ParseTypeExpression(false, false, followers|Token.LeftParenthesis);
          canBeUnary = true;
          break;
        case Token.Operator: 
          this.GetNextToken();
          symCtx = this.scanner.SourceLocationOfLastScannedToken;
          ctx.UpdateToSpan(symCtx);
          this.GetOperatorName(ref opName, ref canBeBinary, ref canBeUnary, ctx.GetSourceLocation());
          if (this.currentToken != Token.EndOfFile) this.GetNextToken();
          if (resultType == null) {
            this.HandleError(Error.BadOperatorSyntax2, ctx.GetSourceLocation().Source);
            if (this.currentToken != Token.LeftParenthesis)
              resultType = this.ParseTypeExpression(false, false, followers|Token.LeftParenthesis);
            else
              resultType = new NamedTypeExpression(this.RootQualifiedNameFor(Token.Void));
          }
          break;
        default:
          //^ assert false;
          break;
      }
      //Parse the parameter list
      List<Ast.ParameterDeclaration> parameters = new List<Ast.ParameterDeclaration>();
      this.ParseParameters(parameters, Token.RightParenthesis, followers|Token.LeftBrace|Token.Semicolon|Token.Requires|Token.Modifies|Token.Ensures|Token.Where|Token.Throws);
      switch (parameters.Count) {
        case 1:
          if (!canBeUnary)
            this.HandleError(symCtx, Error.OvlUnaryOperatorExpected);
          if (canBeBinary && opName != null) {
            if (opName.Value == "op_Addition") opName = this.GetNameDeclarationFor("op_UnaryPlus", opName.SourceLocation);
            else if (opName.Value == "op_Subtraction") opName = this.GetNameDeclarationFor("op_UnaryNegation", opName.SourceLocation);
          }
          break;
        case 2:
          if (!canBeBinary)
            if (canBeUnary)
              this.HandleError(symCtx, Error.WrongParsForUnaryOp, opName.SourceLocation.Source);
            else
              this.HandleError(symCtx, Error.OvlBinaryOperatorExpected);
          break;
        default:
          if (canBeBinary)
            this.HandleError(symCtx, Error.WrongParsForBinOp, opName.SourceLocation.Source);
          else if (canBeUnary)
            this.HandleError(symCtx, Error.WrongParsForUnaryOp, opName.SourceLocation.Source);
          else
            this.HandleError(symCtx, Error.OvlBinaryOperatorExpected);
          break;
      }
      ctx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);

      //bool swallowedSemicolonAlready = false;
      //this.ParseMethodContract(oper, followers|Token.LeftBrace|Token.Semicolon, ref swallowedSemicolonAlready);
      BlockStatement body = this.ParseBody(followers);
      //^ assert followers[this.currentToken] || this.currentToken == Token.EndOfFile;
      sctx.UpdateToSpan(body.SourceLocation);

      MethodDeclaration method = new MethodDeclaration(attributes, flags, visibility, 
        resultType, null, opName, null, parameters, null, body, sctx.GetSourceLocation());
      members.Add(method);
      //^ assume followers[this.currentToken] || this.currentToken == Token.EndOfFile;
    }
Example #5
0
    private Expression ParseImplementedInterfacePlusName(ref NameDeclaration name, bool allowThis, TokenSet followers)
      //^ ensures result is SimpleName || result is QualifiedName;
      //^ ensures result is QualifiedName ==> (((QualifiedName)result).Qualifier is SimpleName || 
      //^ ((QualifiedName)result).Qualifier is QualifiedName || ((QualifiedName)result).Qualifier is GenericTypeInstanceExpression);
    {
      Expression implementedInterface = new SimpleName(name, name.SourceLocation, false);
      while (this.currentToken == Token.Dot || this.currentToken == Token.LessThan) 
        //^ invariant implementedInterface is SimpleName || implementedInterface is QualifiedName;

        //The following invariant does not hold, it seems. Fix it.
        //^ invariant implementedInterface is QualifiedName ==> (((QualifiedName)implementedInterface).Qualifier is SimpleName || 
        //^ ((QualifiedName)implementedInterface).Qualifier is QualifiedName || ((QualifiedName)implementedInterface).Qualifier is GenericTypeInstanceExpression);
      {
        if (this.currentToken == Token.LessThan) {
          //^ assume implementedInterface is SimpleName || implementedInterface is QualifiedName;
          TypeExpression genericType = new NamedTypeExpression(implementedInterface);
          SourceLocationBuilder ctx = new SourceLocationBuilder(implementedInterface.SourceLocation);
          List<TypeExpression> typeArguments = this.ParseTypeArguments(ctx, false, followers|Token.Dot|Token.LeftBrace);
          implementedInterface = new GenericTypeInstanceExpression(genericType, typeArguments, ctx);
        }
        this.Skip(Token.Dot);
        if (this.currentToken == Token.This && allowThis) {
          name = this.GetNameDeclarationFor("Item", this.scanner.SourceLocationOfLastScannedToken);
        } else {
          if (!Parser.IdentifierOrNonReservedKeyword[this.currentToken])
            this.SkipTo(followers|Parser.IdentifierOrNonReservedKeyword|Token.LeftBrace, Error.ExpectedIdentifier);
          name = this.ParseNameDeclaration();
        }
        SourceLocationBuilder ctx1 = new SourceLocationBuilder(implementedInterface.SourceLocation);
        ctx1.UpdateToSpan(name.SourceLocation);
        implementedInterface = new QualifiedName(implementedInterface, new SimpleName(name, name.SourceLocation, false), ctx1);
      }
      return implementedInterface;
    }
Example #6
0
 private Statement ParseForEach(SourceLocationBuilder slb, TokenSet followers)
   //^ requires this.currentToken == Token.Each;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   this.GetNextToken();
   NameDeclaration variableName = this.ParseNameDeclaration();
   this.Skip(Token.In);
   Expression collection = this.ParseExpression(followers|Token.EndOfLine);
   this.Skip(Token.EndOfLine);
   BlockStatement body = this.ParseStatementBlock(followers|Token.Next);
   slb.UpdateToSpan(body.SourceLocation);
   TypeExpression variableType = new NamedTypeExpression(new SimpleName(this.nameTable.GetNameFor("var"), SourceDummy.SourceLocation, false));
   ForEachStatement result = new ForEachStatement(variableType, variableName, collection, body, slb);
   this.SkipClosingKeyword(Token.Next, followers);
   return result;
 }