changeset 109:d0cc281cacbd

- Added methods parseClassDeclaration() and parseBaseClasses(). - Added classes BaseClass and ClassDeclaration, and enum Protection.
author aziz
date Sun, 08 Jul 2007 18:51:00 +0000
parents 469188935d56
children 2fb631daaaae
files trunk/src/Declarations.d trunk/src/Parser.d
diffstat 2 files changed, 123 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/trunk/src/Declarations.d	Sun Jul 08 15:42:03 2007 +0000
+++ b/trunk/src/Declarations.d	Sun Jul 08 18:51:00 2007 +0000
@@ -34,3 +34,36 @@
     this.values = values;
   }
 }
+
+enum Protection
+{
+  None,
+  Private   = 1,
+  Protected = 1<<1,
+  Package   = 1<<2,
+  Public    = 1<<3
+}
+
+class BaseClass
+{
+  Protection prot;
+  string ident;
+  this(Protection prot, string ident)
+  {
+    this.prot = prot;
+    this.ident = ident;
+  }
+}
+
+class ClassDeclaration : Declaration
+{
+  string className;
+  BaseClass[] bases;
+  Declaration[] decls;
+  this(string className, BaseClass[] bases, Declaration[] decls)
+  {
+    this.className = className;
+    this.bases = bases;
+    this.decls = decls;
+  }
+}
--- a/trunk/src/Parser.d	Sun Jul 08 15:42:03 2007 +0000
+++ b/trunk/src/Parser.d	Sun Jul 08 18:51:00 2007 +0000
@@ -156,10 +156,16 @@
       //goto case T.Import;
     case T.Import:
       decl = parseImportDeclaration();
+      break;
     case T.Enum:
       decl = parseEnumDeclaration();
+      break;
+    case T.Class:
+      decl = parseClassDeclaration();
+      break;
     case T.Module:
       // Error: module is optional and can only appear once at the top of the source file.
+      break;
     default:
     }
     return null;
@@ -210,6 +216,8 @@
       baseType = parseBasicType();
     }
 
+//     if (token.type == T.Semicolon && ident.length == 0)
+      // error
     if (token.type == T.LBrace)
     {
       nT();
@@ -242,6 +250,88 @@
     return new EnumDeclaration(enumName, baseType, members, values);
   }
 
+  Declaration parseClassDeclaration()
+  {
+    assert(token.type == T.Class);
+
+    string className;
+    BaseClass[] bases;
+    Declaration[] decls;
+
+    nT();
+    if (token.type == T.Identifier)
+    {
+      className = token.identifier;
+      nT();
+    }
+    else
+      errorIfNot(T.Identifier);
+
+    if (token.type == T.LParen)
+    {
+      // TODO: parse template parameters
+    }
+
+    if (token.type == T.Colon)
+      bases = parseBaseClasses();
+
+    if (token.type == T.Semicolon)
+    {
+      //if (bases.length != 0)
+        // error: bases classes are not allowed in forward declarations.
+      nT();
+    }
+    else if (token.type == T.LBrace)
+    {
+      nT();
+      decls = parseDeclarations();
+      require(T.RBrace);
+    }
+    else
+      errorIfNot(T.LBrace); // TODO: better error msg
+
+    return new ClassDeclaration(className, bases, decls);
+  }
+
+  BaseClass[] parseBaseClasses()
+  {
+    assert(token.type == T.Colon);
+
+    BaseClass[] bases;
+    Protection prot;
+
+    nT();
+
+    while (1)
+    {
+      prot = Protection.Public;
+      switch (token.type)
+      {
+      case T.Identifier: goto LisIdentifier;
+      case T.Private:   prot = Protection.Private;   break;
+      case T.Protected: prot = Protection.Protected; break;
+      case T.Package:   prot = Protection.Package;   break;
+      case T.Public:  /*prot = Protection.Public;*/  break;
+      //case T.Dot: // What about "class Foo : .Bar"?
+      default:
+        // TODO: issue error msg
+        return bases;
+      }
+      nT();
+      string ident;
+      if (token.type == T.Identifier)
+      {
+      LisIdentifier:
+        ident = token.identifier;
+        nT();
+      }
+      bases ~= new BaseClass(prot, ident);
+      if (token.type != T.Comma)
+        break;
+    }
+    return bases;
+  }
+
   /+++++++++++++++++++++++++++++
   + Expression parsing methods +
   +++++++++++++++++++++++++++++/