compiler/libec2: Improved Specifiers support
authorJerome St-Louis <jerome@ecere.com>
Sun, 7 Jul 2013 03:29:06 +0000 (23:29 -0400)
committerJerome St-Louis <jerome@ecere.com>
Mon, 21 Nov 2016 14:19:00 +0000 (09:19 -0500)
compiler/libec2/rdParser.epj
compiler/libec2/src/externals.ec
compiler/libec2/src/lexing.ec
compiler/libec2/src/specifiers.ec
compiler/libec2/src/statements.ec
compiler/libec2/test.ec

index 5e9000e..82bbabb 100644 (file)
       }
    ],
    "Files" : [
-      "parser.ec"
+      "parser.ec",
+      {
+         "FileName" : "test.ec",
+         "Options" : {
+            "ExcludeFromBuild" : true
+         }
+      }
    ],
    "ResourcesPath" : "",
    "Resources" : [
index e8c055b..e7c595f 100644 (file)
@@ -23,12 +23,10 @@ public:
    {
       if(specifiers)
       {
-         for(s : specifiers)
-            s.print();
-         Print(" ");
+         specifiers.print();
+         if(declarators) Print(" ");
       }
-      if(declarators)
-         declarators.print();
+      if(declarators) declarators.print();
       Print(";");
    }
 }
index 9fc7a2f..2bed41c 100644 (file)
@@ -15,6 +15,26 @@ public enum TokenType
 
    property char { }
 
+   property bool isSpecifier
+   {
+      get
+      {
+         return isQualifier || this == CHAR || this == SHORT || this == INT || this == UINT || this == INT64 || this == LONG || this == SIGNED ||
+                this == UNSIGNED || this == FLOAT || this == DOUBLE || this == VOID ||
+                this == VALIST || this == THISCLASS || this == TYPED_OBJECT || this == ANY_OBJECT ||
+                this == TYPEDEF || this == STRUCT || this == UNION || this == ENUM ||
+                this == TYPEOF || this == SUBCLASS;
+      }
+   }
+
+   property bool isQualifier
+   {
+      get
+      {
+         return this == EXTERN || this == STATIC || this == AUTO || this == REGISTER || this == CONST || this == VOLATILE;
+      }
+   }
+
    property bool isUnaryOperator
    {
       get
@@ -42,15 +62,33 @@ public enum TokenType
          switch(this)
          {
             case VOID: Print("void"); break;
-            case CHAR:  Print("char");  break;
-            case SHORT:  Print("short");  break;
-            case INT:  Print("int");  break;
-            case LONG:  Print("long");  break;
-            case INT64:  Print("int64");  break;
-            case UNSIGNED:  Print("unsigned");  break;
-            case SIGNED:  Print("signed");  break;
-            case FLOAT:  Print("float");  break;
-            case DOUBLE:  Print("double");  break;
+            case CHAR: Print("char"); break;
+            case SHORT: Print("short"); break;
+            case INT: Print("int"); break;
+            case LONG: Print("long"); break;
+            case INT64: Print("int64"); break;
+            case UNSIGNED: Print("unsigned"); break;
+            case SIGNED: Print("signed"); break;
+            case FLOAT: Print("float"); break;
+            case DOUBLE: Print("double"); break;
+            case TYPEDEF: Print("typedef"); break;
+            case EXTERN: Print("extern"); break;
+            case STATIC: Print("static"); break;
+            case AUTO: Print("auto"); break;
+            case REGISTER: Print("register"); break;
+            case UINT: Print("uint"); break;
+            case CONST: Print("const"); break;
+            case VOLATILE: Print("volatile"); break;
+            case VALIST: Print("va_list"); break;
+            case THISCLASS: Print("thisclass"); break;
+            case TYPED_OBJECT: Print("typed_Object"); break;
+            case ANY_OBJECT: Print("any_object"); break;
+            case STRUCT: Print("struct"); break;
+            case UNION: Print("union"); break;
+            case ENUM: Print("enum"); break;
+
+            case TYPEOF: Print("typeof"); break;
+            case SUBCLASS: Print("subclass"); break;
 
             case INC_OP: Print("++"); break;
             case DEC_OP: Print("--"); break;
index 14e4a96..edb91c4 100644 (file)
@@ -30,6 +30,11 @@ public:
 
 public class SpecsList : ASTList<ASTSpecifier>
 {
+   void printSep()
+   {
+      Print(" ");
+   }
+
    SpecsList ::parse()
    {
       SpecsList specs = null;
@@ -37,12 +42,13 @@ public class SpecsList : ASTList<ASTSpecifier>
       while(true)
       {
          peekToken();
-         if(nextToken.type == INT || nextToken.type == CHAR || nextToken.type == VOID)
+         if(nextToken.type.isSpecifier)
          {
             readToken();
             if(!specs) specs = { };
             specs.Add(SpecBase { specifier = token.type });
-            gotSpec = true;
+            if(!token.type.isQualifier)
+               gotSpec = true;
          }
          else if(nextToken.type == IDENTIFIER)
          {
index 054d894..a49911f 100644 (file)
@@ -24,11 +24,12 @@ public class ASTStmtOrDecl : ASTNode
 {
    ASTStmtOrDecl ::parse()
    {
-      SpecsList specs;
-      InitDeclList decls;
+      SpecsList specs = null;
+      InitDeclList decls = null;
+      bool isType = false;
 
       peekToken();
-      if(nextToken.type == INT || nextToken.type == CHAR || nextToken.type == VOID)
+      if(nextToken.type.isSpecifier || (nextToken.type == IDENTIFIER && isType))
       {
          specs = SpecsList::parse();
          decls = InitDeclList::parse();
@@ -36,17 +37,25 @@ public class ASTStmtOrDecl : ASTNode
       }
       else if(nextToken.type == IDENTIFIER)
       {
+         ASTStatement stmt;
          int a = pushAmbiguity();
-         specs = SpecsList::parse();
-         decls = InitDeclList::parse();
-         if(specs && decls)
+         stmt = ASTStatement::parse();
+         if(stmt)
          {
             clearAmbiguity();
-            return ASTDeclaration::parse(specs, decls);
+            return stmt;
          }
          popAmbiguity(a);
+         specs = SpecsList::parse();
+         if(specs)
+            decls = InitDeclList::parse();
+         if(specs && decls)
+            return ASTDeclaration::parse(specs, decls);
+         else
+            return null;
       }
-      return ASTStatement::parse();
+      else
+         return ASTStatement::parse();
    }
 }
 
@@ -107,7 +116,12 @@ public class StmtExpression : ASTStatement
          StmtExpression stmt { expressions = exp };
          if(peekToken().type == ';')
             readToken();
-         return stmt;      
+         else
+         {
+            if(ambiguous)
+               delete stmt;
+         }
+         return stmt;
       }
       return null;
    }
@@ -169,6 +183,7 @@ public class StmtCompound : ASTStatement
       StmtCompound stmt { };
       if(peekToken().type == '{')
       {
+         bool inDecls = true;
          readToken();
          while(true)
          {
@@ -186,13 +201,19 @@ public class StmtCompound : ASTStatement
                {
                   if(eClass_IsDerived(sod._class, class(ASTDeclaration)))
                   {
+                     ASTDeclaration decl = (ASTDeclaration)sod;
                      if(!stmt.declarations) stmt.declarations = { };
-                     stmt.declarations.Add((ASTDeclaration)sod);
+                     if(inDecls)
+                        stmt.declarations.Add(decl);
+                     else
+                        stmt.statements.Add(StmtDecl { decl = decl });
                   }
                   else
                   {
+                     ASTStatement s = (ASTStatement)sod;
                      if(!stmt.statements) stmt.statements = { };
-                     stmt.statements.Add((ASTStatement)sod);
+                     stmt.statements.Add(s);
+                     inDecls = false;
                   }
                }
                else
@@ -569,5 +590,10 @@ public class StmtForEach : ASTStatement
 
 public class StmtDecl : ASTStatement
 {
-   Declaration decl;
+   ASTDeclaration decl;
+
+   void print()
+   {
+      if(decl) decl.print();
+   }
 }
index 7db260e..ae90d9a 100644 (file)
@@ -9,7 +9,7 @@ int SomeFunction(int * p)
       { 0, 0, 1, 0 }
    };
    int c, d, e = 4;
-   String name = "Foo";
+   const String name = "Foo";
    b * a;
 
    b = ((a + 3) * a) - (3.1415 * 180 / a);