changeset 269:a416e09c08ea

- Implemented D 2.0 additions. - Added keyword __traits, TOK.Traits and TraitsExpression. - Added ForeachRangeStatement, ConstType and InvariantType. - Fix: avoid infinite loop by calling nT() to skip storage class. - Fix: don't call nT() in parseVersionDeclaration.parseIdentOrInt().
author aziz
date Sat, 04 Aug 2007 18:59:04 +0000
parents c19b68a4e3db
children 764eccdf619d
files trunk/src/Expressions.d trunk/src/Keywords.d trunk/src/Parser.d trunk/src/Statements.d trunk/src/Token.d trunk/src/Types.d
diffstat 6 files changed, 271 insertions(+), 93 deletions(-) [+]
line wrap: on
line diff
--- a/trunk/src/Expressions.d	Sat Aug 04 13:23:01 2007 +0000
+++ b/trunk/src/Expressions.d	Sat Aug 04 18:59:04 2007 +0000
@@ -617,6 +617,19 @@
   }
 }
 
+version(D2)
+{
+class TraitsExpression : Expression
+{
+  Token* ident;
+  TemplateArguments targs;
+  this(typeof(ident) ident, typeof(targs) targs)
+  {
+    this.ident = ident;
+  }
+}
+}
+
 class VoidInitializer : Expression
 {
 
--- a/trunk/src/Keywords.d	Sat Aug 04 13:23:01 2007 +0000
+++ b/trunk/src/Keywords.d	Sat Aug 04 18:59:04 2007 +0000
@@ -62,7 +62,7 @@
   {TOK.Is, "is"},
   {TOK.Lazy, "lazy"},
   {TOK.Long, "long"},
-  {TOK.Macro, "macro"},
+  {TOK.Macro, "macro"}, // D2.0
   {TOK.Mixin, "mixin"},
   {TOK.Module, "module"},
   {TOK.New, "new"},
@@ -87,6 +87,7 @@
   {TOK.Template, "template"},
   {TOK.This, "this"},
   {TOK.Throw, "throw"},
+  {TOK.Traits, "__traits"}, // D2.0
   {TOK.True, "true"},
   {TOK.Try, "try"},
   {TOK.Typedef, "typedef"},
--- a/trunk/src/Parser.d	Sat Aug 04 13:23:01 2007 +0000
+++ b/trunk/src/Parser.d	Sat Aug 04 18:59:04 2007 +0000
@@ -167,7 +167,6 @@
       decl = parseAttributeSpecifier();
       break;
     // Storage classes
-    //case T.Invariant: // D 2.0
     case T.Extern,
          T.Deprecated,
          T.Override,
@@ -176,9 +175,11 @@
          //T.Static,
          T.Final,
          T.Const,
+         //T.Invariant, // D 2.0
          T.Auto,
          T.Scope:
     case_StaticAttribute:
+    case_InvariantAttribute: // D 2.0
       decl = parseStorageAttribute();
       break;
     case T.Alias:
@@ -234,6 +235,19 @@
       decl = parseDestructorDeclaration();
       break;
     case T.Invariant:
+    version(D2)
+    {
+      auto next = token;
+      lx.peek(next);
+      if (next.type == T.LParen)
+      {
+        lx.peek(next);
+        if (next.type != T.RParen)
+          goto case_Declaration;
+      }
+      else
+        goto case_InvariantAttribute;
+    }
       decl = parseInvariantDeclaration();
       break;
     case T.Unittest:
@@ -270,6 +284,7 @@
          T.Float,  T.Double,  T.Real,
          T.Ifloat, T.Idouble, T.Ireal,
          T.Cfloat, T.Cdouble, T.Creal, T.Void:
+    case_Declaration:
       decl = parseDeclaration();
       break;
     /+case T.Module:
@@ -582,7 +597,6 @@
         }
         decl = new ExternDeclaration(linkage, parse());
         break;
-      //case T.Invariant: // D 2.0
       case T.Override:
         tmp = StorageClass.Override;
         goto Lcommon;
@@ -602,8 +616,21 @@
         tmp = StorageClass.Final;
         goto Lcommon;
       case T.Const:
+      version(D2)
+      {
+        if (peekNext() == T.LParen)
+          goto case_Declaration;
+      }
         tmp = StorageClass.Const;
         goto Lcommon;
+      version(D2)
+      {
+      case T.Invariant: // D 2.0
+        if (peekNext() == T.LParen)
+          goto case_Declaration;
+        tmp = StorageClass.Invariant;
+        goto Lcommon;
+      }
       case T.Auto:
         tmp = StorageClass.Auto;
         goto Lcommon;
@@ -612,10 +639,12 @@
         goto Lcommon;
       Lcommon:
         addStorageClass();
-        decl = new AttributeDeclaration(token.type, parse());
+        auto tok = token.type;
         nT();
+        decl = new AttributeDeclaration(tok, parse());
         break;
       case T.Identifier:
+      case_Declaration:
         // This could be a normal Declaration or an AutoDeclaration
         decl = parseDeclaration(stc);
         break;
@@ -700,8 +729,9 @@
     case T.Protected:
     case T.Public:
     case T.Export:
+      auto tok = token.type;
       nT();
-      decl = new AttributeDeclaration(token.type, parseDeclarationsBlock());
+      decl = new AttributeDeclaration(tok, parseDeclarationsBlock());
       break;
     default:
       assert(0);
@@ -1151,7 +1181,6 @@
 
     void parseIdentOrInt(ref Token* tok)
     {
-      nT();
       if (token.type == T.Int32 ||
           token.type == T.Identifier)
       {
@@ -1811,8 +1840,9 @@
         goto Lcommon;
       Lcommon:
         addStorageClass();
-        s = new AttributeStatement(token.type, parse());
+        auto tok = token.type;
         nT();
+        s = new AttributeStatement(tok, parse());
         break;
       // TODO: allow "scope class", "abstract scope class" in function bodies?
       //case T.Class:
@@ -1923,7 +1953,7 @@
     nT();
 
     auto params = new Parameters;
-    Expression aggregate;
+    Expression e; // Aggregate or LwrExpression
 
     require(T.LParen);
     while (1)
@@ -1959,10 +1989,24 @@
       nT();
     }
     require(T.Semicolon);
-    aggregate = parseExpression();
+    e = parseExpression();
+  version(D2)
+  { //Foreach (ForeachType; LwrExpression .. UprExpression ) ScopeStatement
+    if (token.type == T.Slice)
+    {
+      // if (params.length != 1)
+        // error(MID.XYZ); // TODO: issue error msg
+      nT();
+      auto upper = parseExpression();
+      require(T.RParen);
+      auto forBody = parseScopeStatement();
+      return new ForeachRangeStatement(tok, params, e, upper, forBody);
+    }
+  }
+    // Foreach (ForeachTypeList; Aggregate) ScopeStatement
     require(T.RParen);
     auto forBody = parseScopeStatement();
-    return new ForeachStatement(tok, params, aggregate, forBody);
+    return new ForeachStatement(tok, params, e, forBody);
   }
 
   Statement parseSwitchStatement()
@@ -2691,7 +2735,25 @@
       break;
     case T.Cast:
       requireNext(T.LParen);
-      auto type = parseType();
+      Type type;
+      switch (token.type)
+      {
+      version(D2)
+      {
+      auto begin2 = token;
+      case T.Const:
+        type = new ConstType(null);
+        goto case_break;
+      case T.Invariant:
+        type = new InvariantType(null);
+      case_break:
+        nT();
+        set(type, begin2);
+        break;
+      }
+      default:
+       type = parseType();
+      }
       require(T.RParen);
       e = new CastExpression(parseUnaryExpression(), type);
       break;
@@ -3053,6 +3115,22 @@
 
       e = new TypeDotIdExpression(type, ident);
       break;
+    version(D2)
+    {
+    case T.Traits:
+      nT();
+      require(T.LParen);
+      auto id = requireId();
+      TemplateArguments args;
+      if (token.type == T.Comma)
+      {
+        args = parseTemplateArguments2();
+      }
+      else
+        require(T.RParen);
+      e = new TraitsExpression(id, args);
+      break;
+    }
     default:
       // TODO: issue error msg.
       error(MID.ExpectedButFound, "Expression", token.srcText);
@@ -3123,36 +3201,30 @@
       nT();
       set(t, begin);
       break;
-/+
-    case T.Identifier, T.Dot:
-      tident = new IdentifierType([token.identifier]);
-      nT();
-      // TODO: parse template instance
-//       if (token.type == T.Not)
-//         parse template instance
-    Lident:
-      while (token.type == T.Dot)
-      {
-        nT();
-        tident ~= requireIdentifier();
-      // TODO: parse template instance
-//       if (token.type == T.Not)
-//         parse template instance
-      }
-      t = tident;
-      break;
-    case T.Typeof:
-      requireNext(T.LParen);
-      tident = new TypeofType(parseExpression());
-      require(T.RParen);
-      goto Lident;
-+/
     case T.Identifier, T.Typeof, T.Dot:
       t = parseDotListType();
       break;
-    //case T.Const, T.Invariant:
-      // TODO: implement D 2.0 type constructors
-      //break;
+    version(D2)
+    {
+    case T.Const:
+      // const ( Type )
+      nT();
+      require(T.LParen);
+      t = parseType();
+      require(T.RParen);
+      t = new ConstType(t);
+      set(t, begin);
+      break;
+    case T.Invariant:
+      // invariant ( Type )
+      nT();
+      require(T.LParen);
+      t = parseType();
+      require(T.RParen);
+      t = new InvariantType(t);
+      set(t, begin);
+      break;
+    }
     default:
       // TODO: issue error msg.
       error(MID.ExpectedButFound, "BasicType", token.srcText);
@@ -3354,30 +3426,79 @@
       nT();
       return set(params, begin);
     }
-//     StorageClass stc;
 
     while (1)
     {
       auto paramBegin = token;
-//       stc = StorageClass.In;
       Token* stcTok;
+      StorageClass stc, tmp;
+
+      if (token.type == T.Ellipses)
+      {
+        nT();
+        params ~= set(new Parameter(null, null, null, null), paramBegin);
+        break; // Exit loop.
+      }
+
+    Lstc_loop:
       switch (token.type)
       {
-      /+case T.In:   stc = StorageClass.In;   nT(); goto default;
-      case T.Out:  stc = StorageClass.Out;  nT(); goto default;
-      case T.Inout:
-      case T.Ref:  stc = StorageClass.Ref;  nT(); goto default;
-      case T.Lazy: stc = StorageClass.Lazy; nT(); goto default;+/
-      // TODO: D 2.0 invariant/const/final/scope
+      version(D2)
+      {
+      case T.Invariant: // D2.0
+        if (peekNext() == T.LParen)
+          goto default;
+        tmp = StorageClass.Invariant;
+        goto Lcommon;
+      case T.Const: // D2.0
+        if (peekNext() == T.LParen)
+          goto default;
+        tmp = StorageClass.Const;
+        goto Lcommon;
+      case T.Final: // D2.0
+        tmp = StorageClass.Final;
+        goto Lcommon;
+      case T.Scope: // D2.0
+        tmp = StorageClass.Scope;
+        goto Lcommon;
+      case T.Static: // D2.0
+        tmp = StorageClass.Static;
+        goto Lcommon;
+      case T.In:
+        tmp = StorageClass.In;
+        goto Lcommon;
+      case T.Out:
+        tmp = StorageClass.In;
+        goto Lcommon;
+      case T.Inout, T.Ref:
+        tmp = StorageClass.Ref;
+        goto Lcommon;
+      case T.Lazy:
+        tmp = StorageClass.Lazy;
+        goto Lcommon;
+      Lcommon:
+        if (stc & tmp)
+        {
+          error(MID.RedundantStorageClass, token.srcText);
+        }
+        else
+          stc |= tmp;
+        nT();
+        goto Lstc_loop;
+      }
+      else // else body of version(D2)
+      {
       case T.In, T.Out, T.Inout, T.Ref, T.Lazy:
         stcTok = token;
         nT();
         goto default;
-      case T.Ellipses:
-        nT();
-        params ~= set(new Parameter(stcTok, null, null, null), paramBegin);
-        break; // Exit loop.
+      }
       default:
+      version(D2)
+      {
+        if (stc != StorageClass.None)
+          stcTok = begin;
+      }
         Token* ident;
         auto type = parseDeclarator(ident, true);
 
@@ -3444,7 +3565,46 @@
     set(args, begin);
     return args;
   }
-
+version(D2)
+{
+  TemplateArguments parseTemplateArguments2()
+  {
+    assert(token.type == T.Comma);
+    nT();
+    auto begin = token;
+    auto args = new TemplateArguments;
+
+    if (token.type != T.RParen)
+    {
+      while (1)
+      {
+        bool success;
+        auto typeArgument = try_(parseType(), success);
+        if (success)
+        {
+          // TemplateArgument:
+          //         Type
+          //         Symbol
+          args ~= typeArgument;
+        }
+        else
+        {
+          // TemplateArgument:
+          //         AssignExpression
+          args ~= parseAssignExpression();
+        }
+        if (token.type != T.Comma)
+          break; // Exit loop.
+        nT();
+      }
+    }
+    else
+      error(MID.ExpectedButFound, "Type/Expression", ")");
+    require(T.RParen);
+    set(args, begin);
+    return args;
+  }
+} // version(D2)
   TemplateParameters parseTemplateParameterList()
   {
     auto begin = token;
--- a/trunk/src/Statements.d	Sat Aug 04 13:23:01 2007 +0000
+++ b/trunk/src/Statements.d	Sat Aug 04 18:59:04 2007 +0000
@@ -165,6 +165,26 @@
   }
 }
 
+version(D2)
+{
+class ForeachRangeStatement : Statement
+{
+  TOK tok;
+  Parameters params;
+  Expression lower, upper;
+  Statement forBody;
+
+  this(TOK tok, Parameters params, Expression lower, Expression upper, Statement forBody)
+  {
+    this.tok = tok;
+    this.params = params;
+    this.lower = lower;
+    this.upper = upper;
+    this.forBody = forBody;
+  }
+}
+}
+
 class SwitchStatement : Statement
 {
   Expression condition;
--- a/trunk/src/Token.d	Sat Aug 04 13:23:01 2007 +0000
+++ b/trunk/src/Token.d	Sat Aug 04 18:59:04 2007 +0000
@@ -83,11 +83,11 @@
   Double,Else,Enum,Export,Extern,False,Final,
   Finally,Float,For,Foreach,Foreach_reverse,Function,Goto,
   Idouble,If,Ifloat,Import,In,Inout,Int,
-  Interface,Invariant,Ireal,Is,Lazy,Long,Macro,
+  Interface,Invariant,Ireal,Is,Lazy,Long,Macro/+D2.0+/,
   Mixin,Module,New,Null,Out,Override,Package,
-  Pragma,Private,Protected,Public,Real,Ref,Return,
+  Pragma,Private,Protected,Public,Real,Ref/+D2.0+/,Return,
   Scope,Short,Static,Struct,Super,Switch,Synchronized,
-  Template,This,Throw,True,Try,Typedef,Typeid,
+  Template,This,Throw,Traits/+D2.0+/,True,Try,Typedef,Typeid,
   Typeof,Ubyte,Ucent,Uint,Ulong,Union,Unittest,
   Ushort,Version,Void,Volatile,Wchar,While,With,
 
--- a/trunk/src/Types.d	Sat Aug 04 13:23:01 2007 +0000
+++ b/trunk/src/Types.d	Sat Aug 04 18:59:04 2007 +0000
@@ -224,6 +224,8 @@
   Identifier,
   Typeof,
   TemplateInstance,
+  Const, // D2
+  Invariant, // D2
 }
 
 class Type : Node
@@ -267,34 +269,6 @@
   }
 }
 
-/+
-class IdentifierType : Type
-{
-  string[] idents;
-
-  this(string[] idents)
-  {
-    super(TID.Identifier, null);
-    this.idents = idents;
-  }
-
-  this(string ident)
-  {
-    super(TID.Identifier, null);
-  }
-
-  this(TID tid)
-  {
-    super(tid);
-  }
-
-  void opCatAssign(string ident)
-  {
-    this.idents ~= ident;
-  }
-}
-+/
-
 class IdentifierType : Type
 {
   Token* ident;
@@ -304,17 +278,6 @@
     this.ident = ident;
   }
 }
-/+
-class TypeofType : IdentifierType
-{
-  Expression e;
-  this(Expression e)
-  {
-    super(TID.Typeof);
-    this.e = e;
-  }
-}
-+/
 
 class TypeofType : Type
 {
@@ -388,3 +351,24 @@
     super(TID.Delegate, func);
   }
 }
+
+version(D2)
+{
+class ConstType : Type
+{
+  this(Type t)
+  {
+    // If t is null: cast(const)
+    super(TID.Const, t);
+  }
+}
+
+class InvariantType : Type
+{
+  this(Type t)
+  {
+    // If t is null: cast(invariant)
+    super(TID.Invariant, t);
+  }
+}
+} // version(D2)