changeset 486:bd176bc73e43

Fixed a few things in the Parser. Refactored some code that used parseArguments() to using parseExpressionList(). Added calls to set() and tidied up the code of the Parser a bit. Fixed parsing DotIdentifier in parseAsmPrimaryExpression(). Added charLiteral member to class CharExpression. Added class InformationManager. Added member infoMan to class Scope.
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Sat, 01 Dec 2007 18:22:56 +0100
parents ea8c7459f1c4
children bccca748d745
files trunk/src/dil/Declarations.d trunk/src/dil/Expressions.d trunk/src/dil/Information.d trunk/src/dil/Parser.d trunk/src/dil/Scope.d
diffstat 5 files changed, 147 insertions(+), 106 deletions(-) [+]
line wrap: on
line diff
--- a/trunk/src/dil/Declarations.d	Fri Nov 30 20:17:29 2007 +0100
+++ b/trunk/src/dil/Declarations.d	Sat Dec 01 18:22:56 2007 +0100
@@ -8,6 +8,7 @@
 import dil.Types;
 import dil.Statements;
 import dil.Token;
+import dil.Scope;
 
 abstract class Declaration : Node
 {
@@ -17,6 +18,13 @@
     super(NodeCategory.Declaration);
     this.hasBody = hasBody;
   }
+
+  void semantic(Scope sc)
+  {
+//     foreach (node; this.children)
+//       if (node.category == NodeCategory.Declaration)
+//         (cast(Declaration)cast(void*)node).semantic(sc);
+  }
 }
 
 class Declarations : Declaration
@@ -32,6 +40,11 @@
     this.children ~= d;
   }
 
+  void opCatAssign(Declaration[] decls)
+  {
+    this.children ~= decls;
+  }
+
   void opCatAssign(Declarations ds)
   {
     this.children ~= ds.children;
--- a/trunk/src/dil/Expressions.d	Fri Nov 30 20:17:29 2007 +0100
+++ b/trunk/src/dil/Expressions.d	Sat Dec 01 18:22:56 2007 +0100
@@ -695,9 +695,11 @@
 
 class CharExpression : Expression
 {
-  this()
+  Token* charLiteral;
+  this(Token* charLiteral)
   {
     mixin(set_kind);
+    this.charLiteral = charLiteral;
   }
 }
 
--- a/trunk/src/dil/Information.d	Fri Nov 30 20:17:29 2007 +0100
+++ b/trunk/src/dil/Information.d	Sat Dec 01 18:22:56 2007 +0100
@@ -53,6 +53,11 @@
   }
 }
 
+class InformationManager
+{
+  Information[] info;
+}
+
 final class Location
 {
   char[] filePath;
@@ -99,7 +104,7 @@
     this.filePath = filePath;
   }
 
-  /+
+  /++
     This is a primitive method to count the number of characters in a string.
     Unicode compound characters and other special characters are not
     taken into account.
--- a/trunk/src/dil/Parser.d	Fri Nov 30 20:17:29 2007 +0100
+++ b/trunk/src/dil/Parser.d	Sat Dec 01 18:22:56 2007 +0100
@@ -188,9 +188,9 @@
       DeclDef
       DeclDefs
   +/
-  Declarations parseDeclarationDefinitions()
+  Declaration[] parseDeclarationDefinitions()
   {
-    auto decls = new Declarations;
+    Declaration[] decls;
     while (token.type != T.EOF)
       decls ~= parseDeclarationDefinition();
     return decls;
@@ -823,15 +823,10 @@
 
       if (token.type == T.Comma)
       {
-        // Parse at least one argument.
         nT();
-        args ~= parseAssignExpression();
+        args = parseExpressionList();
       }
-
-      if (token.type == T.Comma)
-        args ~= parseArguments(T.RParen);
-      else
-        require(T.RParen);
+      require(T.RParen);
 
       if (token.type == T.Semicolon)
       {
@@ -1072,10 +1067,11 @@
       }
       nT(); // Skip protection attribute.
     LparseBasicType:
+      auto begin = token;
       auto type = parseBasicType();
       //if (type.tid != TID.DotList)
         // TODO: issue error msg. base classes can only be one or more identifiers or template instances separated by dots.
-      bases ~= new BaseClass(prot, type);
+      bases ~= set(new BaseClass(prot, type), begin);
       if (token.type != T.Comma)
         break;
       nT();
@@ -1437,10 +1433,11 @@
   DotListExpression parseDotListExpression()
   {
     assert(token.type == T.Identifier || token.type == T.Dot || token.type == T.Typeof);
+    auto begin = token;
     Expression[] identList;
     if (token.type == T.Dot)
     {
-      identList ~= new IdentifierExpression(token);
+      identList ~= set(new IdentifierExpression(token), begin);
       nT();
     }
     else if (token.type == T.Typeof)
@@ -1448,7 +1445,8 @@
       requireNext(T.LParen);
       auto type = new TypeofType(parseExpression());
       require(T.RParen);
-      identList ~= new TypeofExpression(type);
+      set(type, begin);
+      identList ~= set(new TypeofExpression(type), begin);
       if (token.type != T.Dot)
         goto Lreturn;
       nT();
@@ -1456,16 +1454,16 @@
 
     while (1)
     {
-      auto begin2 = token;
+      begin = token;
       auto ident = requireId();
       Expression e;
       if (token.type == T.Not && peekNext() == T.LParen) // Identifier !( TemplateArguments )
       {
         nT(); // Skip !.
-        e = set(new TemplateInstanceExpression(ident, parseTemplateArguments()), begin2);
+        e = set(new TemplateInstanceExpression(ident, parseTemplateArguments()), begin);
       }
       else // Identifier
-        e = set(new IdentifierExpression(ident), begin2);
+        e = set(new IdentifierExpression(ident), begin);
 
       identList ~= e;
 
@@ -1512,8 +1510,9 @@
     else if (token.type == T.Typeof)
     {
       requireNext(T.LParen);
-      identList ~= set(new TypeofType(parseExpression()), begin);
+      auto type = new TypeofType(parseExpression());
       require(T.RParen);
+      identList ~= set(type, begin);
       if (token.type != T.Dot)
         goto Lreturn;
       nT();
@@ -1834,7 +1833,7 @@
          T.Float,  T.Double,  T.Real,
          T.Ifloat, T.Idouble, T.Ireal,
          T.Cfloat, T.Cdouble, T.Creal, T.Void:+/
-    case T.Traits:
+    case T.Traits: // D2.0
     // Tokens that can start a UnaryExpression:
     case T.AndBinary,
          T.PlusPlus,
@@ -1855,14 +1854,15 @@
       if (token.isSpecialToken)
         goto case_parseExpressionStatement;
 
-      // Assert that this isn't a valid expression.
-      assert(
-        delegate bool(){
-          bool success;
-          auto expression = try_(&parseExpression, success);
-          return success;
-        }() == false, "Any token that could start a valid expression must have been caught by a case statement in parseStatement()."
-      );
+      if (token.type != T.Dollar)
+        // Assert that this isn't a valid expression.
+        assert(
+          delegate bool(){
+            bool success;
+            auto expression = try_(&parseExpression, success);
+            return success;
+          }() == false, "Didn't expect valid expression."
+        );
 
       // Report error: it's an illegal statement.
       error(MID.ExpectedButFound, "Statement", token.srcText);
@@ -1874,7 +1874,7 @@
     return s;
   }
 
-  /+
+  /++
     ScopeStatement:
         NoScopeStatement
   +/
@@ -1883,7 +1883,7 @@
     return new ScopeStatement(parseNoScopeStatement());
   }
 
-  /+
+  /++
     NoScopeStatement:
         NonEmptyStatement
         BlockStatement
@@ -1893,6 +1893,7 @@
   +/
   Statement parseNoScopeStatement()
   {
+    auto begin = token;
     Statement s;
     if (token.type == T.LBrace)
     {
@@ -1901,20 +1902,20 @@
       while (token.type != T.RBrace && token.type != T.EOF)
         ss ~= parseStatement();
       require(T.RBrace);
-      s = ss;
+      s = set(ss, begin);
     }
     else if (token.type == T.Semicolon)
     {
       error(MID.ExpectedButFound, "non-empty statement", ";");
-      s = new EmptyStatement();
       nT();
+      s = set(new EmptyStatement(), begin);
     }
     else
       s = parseStatement();
     return s;
   }
 
-  /+
+  /++
     NoScopeOrEmptyStatement:
         ;
         NoScopeStatement
@@ -1923,8 +1924,9 @@
   {
     if (token.type == T.Semicolon)
     {
+      auto begin = token;
       nT();
-      return new EmptyStatement();
+      return set(new EmptyStatement(), begin);
     }
     else
       return parseNoScopeStatement();
@@ -1938,9 +1940,7 @@
     void addStorageClass()
     {
       if (stc & tmp)
-      {
         error(MID.RedundantStorageClass, token.srcText);
-      }
       else
         stc |= tmp;
     }
@@ -2195,16 +2195,21 @@
     return new SwitchStatement(condition, switchBody);
   }
 
-  Statement parseCaseDefaultBody()
+  /++
+    Helper function for parsing the body of
+    a default or case statement.
+  +/
+  Statement parseCaseOrDefaultBody()
   {
     // This function is similar to parseNoScopeStatement()
+    auto begin = token;
     auto s = new Statements();
     while (token.type != T.Case &&
-            token.type != T.Default &&
-            token.type != T.RBrace &&
-            token.type != T.EOF)
+           token.type != T.Default &&
+           token.type != T.RBrace &&
+           token.type != T.EOF)
       s ~= parseStatement();
-    return new ScopeStatement(s);
+    return set(new ScopeStatement(s), begin);
   }
 
   Statement parseCaseStatement()
@@ -2219,7 +2224,7 @@
     } while (token.type == T.Comma)
     require(T.Colon);
 
-    auto caseBody = parseCaseDefaultBody();
+    auto caseBody = parseCaseOrDefaultBody();
     return new CaseStatement(values, caseBody);
   }
 
@@ -2228,7 +2233,8 @@
     assert(token.type == T.Default);
     nT();
     require(T.Colon);
-    return new DefaultStatement(parseCaseDefaultBody());
+    auto defaultBody = parseCaseOrDefaultBody();
+    return new DefaultStatement(defaultBody);
   }
 
   Statement parseContinueStatement()
@@ -2335,9 +2341,11 @@
       if (token.type == T.LParen)
       {
         nT();
+        auto begin = token;
         Token* ident;
         auto type = parseDeclarator(ident, true);
         param = new Parameter(null, type, ident, null);
+        set(param, begin);
         require(T.RParen);
       }
       catchBodies ~= new CatchBody(param, parseNoScopeStatement());
@@ -2347,8 +2355,10 @@
 
     if (token.type == T.Finally)
     {
+      auto begin = token;
       nT();
       finBody = new FinallyBody(parseNoScopeStatement());
+      set(finBody, begin);
     }
 
     if (catchBodies.length == 0 && finBody is null)
@@ -2423,15 +2433,10 @@
 
     if (token.type == T.Comma)
     {
-      // Parse at least one argument.
       nT();
-      args ~= parseAssignExpression();
+      args = parseExpressionList();
     }
-
-    if (token.type == T.Comma)
-      args ~= parseArguments(T.RParen);
-    else
-      require(T.RParen);
+    require(T.RParen);
 
     pragmaBody = parseNoScopeOrEmptyStatement();
 
@@ -3021,19 +3026,17 @@
         break;
       default:
         // DotIdentifier
-        auto begin2 = token;
         Expression[] identList;
-        goto LenterLoop;
-        while (token.type == T.Dot)
+        while (1)
         {
-          nT();
-          begin2 = token;
+          auto begin2 = token;
           auto ident = requireId();
-        LenterLoop:
-          e = new IdentifierExpression(token);
-          nT();
+          e = new IdentifierExpression(ident);
           set(e, begin2);
           identList ~= e;
+          if (token.type != T.Dot)
+            break;
+          nT(); // Skip dot.
         }
         e = new DotListExpression(identList);
       }
@@ -3144,8 +3147,8 @@
 
   Expression parseOrOrExpression()
   {
+    alias parseAndAndExpression parseNext;
     auto begin = token;
-    alias parseAndAndExpression parseNext;
     auto e = parseNext();
     while (token.type == T.OrLogical)
     {
@@ -3159,8 +3162,8 @@
 
   Expression parseAndAndExpression()
   {
+    alias parseOrExpression parseNext;
     auto begin = token;
-    alias parseOrExpression parseNext;
     auto e = parseNext();
     while (token.type == T.AndLogical)
     {
@@ -3174,8 +3177,8 @@
 
   Expression parseOrExpression()
   {
+    alias parseXorExpression parseNext;
     auto begin = token;
-    alias parseXorExpression parseNext;
     auto e = parseNext();
     while (token.type == T.OrBinary)
     {
@@ -3189,8 +3192,8 @@
 
   Expression parseXorExpression()
   {
+    alias parseAndExpression parseNext;
     auto begin = token;
-    alias parseAndExpression parseNext;
     auto e = parseNext();
     while (token.type == T.Xor)
     {
@@ -3204,8 +3207,8 @@
 
   Expression parseAndExpression()
   {
+    alias parseCmpExpression parseNext;
     auto begin = token;
-    alias parseCmpExpression parseNext;
     auto e = parseNext();
     while (token.type == T.AndBinary)
     {
@@ -3219,6 +3222,7 @@
 
   Expression parseCmpExpression()
   {
+    alias parseShiftExpression parseNext;
     auto begin = token;
     auto e = parseShiftExpression();
 
@@ -3227,7 +3231,7 @@
     {
     case T.Equal, T.NotEqual:
       nT();
-      e = new EqualExpression(e, parseShiftExpression(), operator);
+      e = new EqualExpression(e, parseNext(), operator);
       break;
     case T.Not:
       if (peekNext() != T.Is)
@@ -3236,17 +3240,17 @@
       // fall through
     case T.Is:
       nT();
-      e = new IdentityExpression(e, parseShiftExpression(), operator);
+      e = new IdentityExpression(e, parseNext(), operator);
       break;
     case T.LessEqual, T.Less, T.GreaterEqual, T.Greater,
          T.Unordered, T.UorE, T.UorG, T.UorGorE,
          T.UorL, T.UorLorE, T.LorEorG, T.LorG:
       nT();
-      e = new RelExpression(e, parseShiftExpression(), operator);
+      e = new RelExpression(e, parseNext(), operator);
       break;
     case T.In:
       nT();
-      e = new InExpression(e, parseShiftExpression(), operator);
+      e = new InExpression(e, parseNext(), operator);
       break;
     default:
       return e;
@@ -3257,16 +3261,17 @@
 
   Expression parseShiftExpression()
   {
+    alias parseAddExpression parseNext;
     auto begin = token;
-    auto e = parseAddExpression();
+    auto e = parseNext();
     while (1)
     {
       auto operator = token;
       switch (operator.type)
       {
-      case T.LShift:  nT(); e = new LShiftExpression(e, parseAddExpression(), operator); break;
-      case T.RShift:  nT(); e = new RShiftExpression(e, parseAddExpression(), operator); break;
-      case T.URShift: nT(); e = new URShiftExpression(e, parseAddExpression(), operator); break;
+      case T.LShift:  nT(); e = new LShiftExpression(e, parseNext(), operator); break;
+      case T.RShift:  nT(); e = new RShiftExpression(e, parseNext(), operator); break;
+      case T.URShift: nT(); e = new URShiftExpression(e, parseNext(), operator); break;
       default:
         return e;
       }
@@ -3277,16 +3282,17 @@
 
   Expression parseAddExpression()
   {
+    alias parseMulExpression parseNext;
     auto begin = token;
-    auto e = parseMulExpression();
+    auto e = parseNext();
     while (1)
     {
       auto operator = token;
       switch (operator.type)
       {
-      case T.Plus:  nT(); e = new PlusExpression(e, parseMulExpression(), operator); break;
-      case T.Minus: nT(); e = new MinusExpression(e, parseMulExpression(), operator); break;
-      case T.Tilde: nT(); e = new CatExpression(e, parseMulExpression(), operator); break;
+      case T.Plus:  nT(); e = new PlusExpression(e, parseNext(), operator); break;
+      case T.Minus: nT(); e = new MinusExpression(e, parseNext(), operator); break;
+      case T.Tilde: nT(); e = new CatExpression(e, parseNext(), operator); break;
       default:
         return e;
       }
@@ -3334,7 +3340,7 @@
         e = new PostDecrExpression(e);
         break;
       case T.LParen:
-        e = new CallExpression(e, parseArguments(T.RParen));
+        e = new CallExpression(e, parseArguments());
         goto Lset;
       case T.LBracket:
         // parse Slice- and IndexExpression
@@ -3354,12 +3360,13 @@
           require(T.RBracket);
           goto Lset;
         }
-        else if (token.type == T.Comma)
+
+        if (token.type == T.Comma)
         {
-           es ~= parseArguments(T.RBracket);
+           nT();
+           es ~= parseExpressionList();
         }
-        else
-          require(T.RBracket);
+        require(T.RBracket);
 
         e = new IndexExpression(e, es);
         goto Lset;
@@ -3506,8 +3513,8 @@
       nT();
       break;
     case T.CharLiteral, T.WCharLiteral, T.DCharLiteral:
+      e = new CharExpression(token);
       nT();
-      e = new CharExpression();
       break;
     case T.String:
       Token*[] stringLiterals;
@@ -3527,10 +3534,12 @@
         e = parseAssignExpression();
         if (token.type == T.Colon)
           goto LparseAssocArray;
-        else if (token.type == T.Comma)
-          values = [e] ~ parseArguments(T.RBracket);
-        else
-          require(T.RBracket);
+        if (token.type == T.Comma)
+        {
+          nT();
+          values = [e] ~ parseExpressionList();
+        }
+        require(T.RBracket);
       }
       else
         nT();
@@ -3732,7 +3741,7 @@
     Expression[] ctorArguments;
 
     if (token.type == T.LParen)
-      newArguments = parseArguments(T.RParen);
+      newArguments = parseArguments();
 
     // NewAnonClassExpression:
     //         new (ArgumentList)opt class (ArgumentList)opt SuperClassopt InterfaceClassesopt ClassBody
@@ -3740,7 +3749,7 @@
     {
       nT();
       if (token.type == T.LParen)
-        ctorArguments = parseArguments(T.RParen);
+        ctorArguments = parseArguments();
 
       BaseClass[] bases = token.type != T.LBrace ? parseBaseClasses(false) : null ;
 
@@ -3755,7 +3764,7 @@
     auto type = parseType();
 
     if (token.type == T.LParen)
-      ctorArguments = parseArguments(T.RParen);
+      ctorArguments = parseArguments();
 
     return set(new NewExpression(/*e, */newArguments, type, ctorArguments), begin);
   }
@@ -4003,28 +4012,38 @@
     return t;
   }
 
-  Expression[] parseArguments(TOK terminator)
+  /++
+    Parse a list of AssignExpressions.
+    ExpressionList:
+      AssignExpression
+      AssignExpression , ExpressionList
+  +/
+  Expression[] parseExpressionList()
   {
-    assert(token.type == T.LParen || token.type == T.LBracket || token.type == T.Comma);
-    assert(terminator == T.RParen || terminator == T.RBracket);
-    Expression[] args;
-
-    nT();
-    if (token.type == terminator)
+    Expression[] expressions;
+    while (1)
     {
+      expressions ~= parseAssignExpression();
+      if (token.type != T.Comma)
+        break;
       nT();
-      return null;
     }
-
-    goto LenterLoop;
-    do
-    {
-      nT();
-    LenterLoop:
-      args ~= parseAssignExpression();
-    } while (token.type == T.Comma)
-
-    require(terminator);
+    return expressions;
+  }
+
+  /++
+    Arguments:
+      ( )
+      ( ExpressionList )
+  +/
+  Expression[] parseArguments()
+  {
+    assert(token.type == T.LParen);
+    nT();
+    Expression[] args;
+    if (token.type != TOK.RParen)
+      args = parseExpressionList();
+    require(TOK.RParen);
     return args;
   }
 
--- a/trunk/src/dil/Scope.d	Fri Nov 30 20:17:29 2007 +0100
+++ b/trunk/src/dil/Scope.d	Sat Dec 01 18:22:56 2007 +0100
@@ -4,11 +4,13 @@
 +/
 module dil.Scope;
 import dil.Symbol;
+import dil.Information;
 import common;
 
 class Scope
 {
   Scope parent; /// The surrounding scope.
+  InformationManager infoMan; /// Collects errors reported during the semantic phase.
 
   this()
   {
@@ -19,7 +21,7 @@
   +/
   Symbol find(char[] ident)
   {
-
+    return null;
   }
 
   /++