compiler/libec2: Support for instantiations
authorJerome St-Louis <jerome@ecere.com>
Mon, 15 Jul 2013 08:30:58 +0000 (04:30 -0400)
committerJerome St-Louis <jerome@ecere.com>
Mon, 21 Nov 2016 14:19:02 +0000 (09:19 -0500)
compiler/libec2/src/classes.ec
compiler/libec2/src/declarators.ec
compiler/libec2/src/expressions.ec
compiler/libec2/src/externals.ec
compiler/libec2/test.ec

index 4fe8b2b..8875bd9 100644 (file)
@@ -15,22 +15,31 @@ public:
    ASTMemberInit ::parse()
    {
       ASTMemberInit init { };
-      while(true)
+      if(peekToken().type == IDENTIFIER)
       {
-         ASTIdentifier id = ASTIdentifier::parse();
-         if(id)
+         int a = pushAmbiguity();
+         while(true)
          {
-            if(!init.identifiers) init.identifiers = { };
-            init.identifiers.Add(id);
-            if(peekToken().type != '.')
-               break;
+            ASTIdentifier id = ASTIdentifier::parse();
+            if(id)
+            {
+               if(!init.identifiers) init.identifiers = { };
+               init.identifiers.Add(id);
+               if(peekToken().type != '.')
+                  break;
+               else
+                  readToken();
+            }
          }
+         if(peekToken().type == '=')
+         {
+            clearAmbiguity();
+            readToken();
+         }
+         else
+            popAmbiguity(a);
       }
-      if(peekToken().type == '=')
-      {
-         readToken();
-         init.initializer = ASTInitializer::parse();
-      }
+      init.initializer = InitExp::parse();
       return init;
    }
 
@@ -45,9 +54,10 @@ public:
             if(identifiers.GetNext(it.pointer))
                Print(".");
          }
+         Print(" = ");
       }
-      Print(" = ");
-      if(initializer) initializer.print();
+      if(initializer)
+         initializer.print();
    }
 };
 
@@ -101,6 +111,7 @@ public:
       SpecsList specs = null;
       InitDeclList decls = null;
       int a = -1;
+      ASTDeclarator decl;
 
       peekToken();
       if(nextToken.type == '}')
@@ -112,8 +123,12 @@ public:
       specs = SpecsList::parse();
       decls = InitDeclList::parse();
       peekToken();
-      if(nextToken.type == '{' || (decls && decls[0] && decls[0].declarator && decls[0].declarator._class == class(DeclFunction)))
+      decl = GetFuncDecl(decls && decls[0] ? decls[0].declarator : null);
+      if(decl)
+      {
+         if(a > -1) clearAmbiguity();
          return ClassDefFunction::parse(specs, decls);
+      }
       else if((specs || decls) && (nextToken.type != '.' && nextToken.type != '='))
       {
          if(a > -1) clearAmbiguity();
index 29a69fd..a1d47ae 100644 (file)
@@ -29,6 +29,7 @@ public class ASTDeclarator : ASTNode
 {
 public:
    DeclaratorType type;
+   ASTDeclarator declarator;
    // Symbol symbol;
 
    ASTDeclarator ::parse()
@@ -101,7 +102,6 @@ public class TypeNameList : ASTList<ASTTypeName>
 public class DeclFunction : ASTDeclarator
 {
 public:
-   ASTDeclarator declarator;
    TypeNameList parameters;
 
    void print()
@@ -140,8 +140,6 @@ public class DeclIdentifier : ASTDeclarator
 
 public class DeclBrackets : ASTDeclarator
 {
-   ASTDeclarator declarator;
-
    void print()
    {
       Print("(");
@@ -165,7 +163,6 @@ public class DeclBrackets : ASTDeclarator
 
 public class DeclArray : ASTDeclarator
 {
-   ASTDeclarator declarator;
    ASTExpression exp;
    // ASTSpecifier enumClass;
 
@@ -189,7 +186,6 @@ public class DeclArray : ASTDeclarator
 
 public class DeclPointer : ASTDeclarator
 {
-   ASTDeclarator declarator;
    ASTPointer pointer;
 
    void print()
@@ -206,7 +202,6 @@ public class DeclPointer : ASTDeclarator
 
 public class DeclStruct : ASTDeclarator
 {
-   ASTDeclarator declarator;
    ASTExpression exp;
    ASTExpression posExp;
    ASTAttrib attrib;
@@ -236,7 +231,7 @@ public class ASTInitializer : ASTNode
          return init;
       }
       else
-         return InitExp { exp = ASTExpression::parse() };
+         return InitExp::parse();
    }
 };
 
@@ -249,6 +244,11 @@ public class InitExp : ASTInitializer
       if(exp)
          exp.print();
    }
+
+   InitExp ::parse()
+   {
+      return InitExp { exp = ASTExpression::parse() };
+   }
 };
 
 public class InitList : ASTInitializer
index 5973da0..78bb36c 100644 (file)
@@ -193,9 +193,20 @@ simple_primary_expression:
    if(peekToken().type == CONSTANT)
       return ExpConstant::parse();
    else if(nextToken.type == IDENTIFIER)
-      return ExpIdentifier::parse();
+   {
+      ExpIdentifier exp = ExpIdentifier::parse();
+      if(peekToken().type == '{')
+      {
+         SpecsList specs { };
+         specs.Add(SpecName { name = exp.identifier.string });
+         return ExpInstance::parse(specs, null);
+      }
+      return exp;
+   }
    else if(nextToken.type == STRING_LITERAL)
       return ExpString::parse();
+   else if(nextToken.type == '{')
+      return ExpInstance::parse(null, null);
    else
       return null;
 }
@@ -519,6 +530,16 @@ public class ExpCast : ASTExpression
 public class ExpInstance : ASTExpression
 {
    ASTInstantiation instance;
+
+   ExpInstance ::parse(SpecsList specs, InitDeclList decls)
+   {
+      return { instance = ASTInstantiation::parse(specs, decls) };
+   }
+
+   void print()
+   {
+      if(instance) instance.print();
+   }
 }
 /*
 public class ExpSizeOf : ASTExpression
@@ -589,16 +610,72 @@ public class ExpAlignOf : ASTExpression
 };
 */
 
-public class InstanceInit : ASTNode { }
+public class InstanceInit : ASTNode
+{
+   InstanceInit ::parse()
+   {
+      int a = pushAmbiguity();
+      SpecsList specs = SpecsList::parse();
+      InitDeclList decls = InitDeclList::parse();
+
+      peekToken();
+      if(nextToken.type == '{' || (specs && decls))
+      {
+         clearAmbiguity();
+         return InstInitFunction::parse(specs, decls);
+      }
+      else if(nextToken.type != '}')
+      {
+         popAmbiguity(a);
+         return InstInitMember::parse();
+      }
+      return null;
+   }
+}
 
 public class InstInitMember : InstanceInit
 {
    MemberInitList members;
+
+   InstInitMember ::parse()
+   {
+      MemberInitList list = MemberInitList::parse();
+
+      return { members = list };
+   }
+
+   void print()
+   {
+      if(members) members.print();
+   }
 }
 
 public class InstInitFunction : InstanceInit
 {
    ASTClassFunction function;
+
+   InstInitFunction ::parse(SpecsList specs, InitDeclList decls)
+   {
+      return { function = ASTClassFunction::parse(specs, decls) };
+   }
+
+   void print()
+   {
+      if(function) function.print();
+   }
+}
+
+public class InstInitList : ASTList<InstanceInit>
+{
+   InstInitList ::parse()
+   {
+      return (InstInitList)ASTList::parse(class(InstInitList), InstanceInit::parse, 0);
+   }
+
+   void print()
+   {
+      ASTList::print();
+   }
 }
 
 public class ASTInstantiation : ASTNode
@@ -606,11 +683,95 @@ public class ASTInstantiation : ASTNode
 public:
    ASTSpecifier _class;
    ASTExpression exp;
-   List<InstanceInit> members;
+
+   InstInitList members;
    Symbol symbol;
    bool fullSet;
    bool isConstant;
    byte * data;
    Location nameLoc, insideLoc;
    bool built;
+
+   ASTInstantiation ::parse(SpecsList specs, InitDeclList decls)
+   {
+      ASTInstantiation inst { };
+      if(specs && specs[0])
+         inst._class = specs[0];
+
+      if(decls && decls[0] && decls[0].declarator && decls[0].declarator._class == class(DeclIdentifier))
+         inst.exp = ExpIdentifier { identifier = ((DeclIdentifier)decls[0].declarator).identifier };
+
+      readToken();
+      inst.members = InstInitList::parse();
+      if(peekToken().type == '}')
+         readToken();
+      return inst;
+   }
+
+   void print()
+   {
+      bool multiLine = false;
+      if(members)
+      {
+         for(m : members; m._class == class(InstInitFunction))
+         {
+            multiLine = true;
+            break;
+         }
+      }
+
+      if(_class) { _class.print(); if(!multiLine || exp) Print(" "); }
+      if(exp) { exp.print(); if(!multiLine) Print(" "); }
+      if(multiLine)
+      {
+         PrintLn("");
+         printIndent();
+      }
+      Print("{");
+      if(multiLine)
+      {
+         PrintLn("");
+         indent++;
+      }
+      if(members && members[0])
+      {
+         if(multiLine)
+         {
+            Iterator<InstanceInit> it { members };
+            while(it.Next())
+            {
+               InstanceInit init = it.data;
+               Link nextLink = (Link)members.GetNext(it.pointer);
+               if(init._class != class(InstInitFunction))
+                  printIndent();
+               init.print();
+               if(init._class == class(InstInitMember))
+                  Print(";");
+               if(nextLink)
+               {
+                  InstanceInit next = nextLink ? (InstanceInit)nextLink.data : null;
+                  PrintLn("");
+                  if(next._class == class(InstInitFunction))
+                     PrintLn("");
+               }
+               else if(init._class != class(InstInitFunction))
+                  PrintLn("");
+            }
+         }
+         else
+         {
+            Print(" ");
+            members.print();
+            Print(" ");
+         }
+      }
+      else
+         Print(" ");
+      if(multiLine)
+      {
+         indent--;
+         printIndent();
+      }
+      Print("}");
+   }
 };
index e2e9819..381de8d 100644 (file)
@@ -10,7 +10,10 @@ public:
 
    ASTDeclaration ::parse(SpecsList specs, InitDeclList decls)
    {
-      if(peekToken().type == ';')
+      peekToken();
+      if(nextToken.type == '{')
+         return DeclarationInstance::parse(specs, decls);
+      else if(nextToken.type == ';')
          readToken();
       return DeclarationInit { specifiers = specs, declarators = decls };
    }
@@ -37,6 +40,27 @@ public:
 public class DeclarationInstance : ASTDeclaration
 {
    ASTInstantiation inst;
+
+   DeclarationInstance ::parse(SpecsList specs, InitDeclList decls)
+   {
+      ASTInstantiation inst = ASTInstantiation::parse(specs, decls);
+      if(peekToken().type == ';')
+         readToken();
+      if(inst)
+      {
+         return { inst = inst };
+      }
+      return null;
+   }
+
+   void print()
+   {
+      if(inst)
+      {
+         inst.print();
+         Print(";");
+      }
+   }
 }
 
 public class DeclarationDefine : ASTDeclaration
@@ -94,13 +118,23 @@ public:
    */
 };
 
+class ASTImport : ASTNode
+{
+   String importString;
+
+   void print()
+   {
+      Print("import ");
+      PrintLn(importString);
+   }
+}
+
 /*
    union
    {
       ASTFunctionDefinition function;
       SpecClass _class;
       ASTDeclaration declaration;
-      String importString;
       ASTIdentifier id;
       DBTableDef table;
    };
@@ -114,21 +148,66 @@ class External
 }
 */
 
+public ASTDeclarator GetFuncDecl(ASTDeclarator decl)
+{
+   ASTDeclarator funcDecl = null;
+   while(decl && decl._class != class(DeclIdentifier))
+   {
+      if(decl._class == class(DeclFunction))
+         funcDecl = decl;
+      decl = decl.declarator;
+   }
+   return funcDecl;
+}
+
 public class AST : ASTList<ASTNode>
 {
    ASTNode ::ParseExternalDeclaration()
    {
-      SpecsList specs = SpecsList::parse();
-      InitDeclList decls = InitDeclList::parse();
+      SpecsList specs = null; 
+      InitDeclList decls = null;
 
-      if(peekToken().type == '{')
-         return ASTFunctionDefinition::parse(specs, decls);
-      else if(specs || decls)
-         return ASTDeclaration::parse(specs, decls);
+      peekToken();
+      if(nextToken.type == IMPORT)
+      {
+         ASTImport astImport { };
+         readToken();
+         peekToken();
+         if(nextToken.type == STATIC)
+         {
+            readToken();
+         }
+         else if(nextToken.type == IDENTIFIER)
+         {
+            readToken();
+         }
+         peekToken();
+         if(nextToken.type == STRING_LITERAL)
+         {
+            readToken();
+            astImport.importString = CopyString(token.text);
+         }
+         return astImport;
+      }
       else
       {
-         readToken(); // Error
-         return null;
+         specs = SpecsList::parse();
+         decls = InitDeclList::parse();
+         if(nextToken.type == '{')
+         {
+            ASTDeclarator funcDecl = GetFuncDecl((decls && decls[0]) ? decls[0].declarator : null);
+            if(funcDecl)
+               return ASTFunctionDefinition::parse(specs, decls);
+            else
+               return ASTDeclaration::parse(specs, decls);
+         }
+         else if(specs || decls)
+            return ASTDeclaration::parse(specs, decls);
+         else
+         {
+            readToken(); // Error
+            return null;
+         }
       }
    }
 public:
index 03cc65e..3fa074a 100644 (file)
@@ -1,7 +1,37 @@
+import "ecere"
+
 class Form1 : Window
 {
-   void OnCreate(
+   Button button1
+   {
+      caption = "Click Here", foreground = red;
+   };
+
+   bool OnCreate(
+
+   void OnCreate()
+   {
+      MessageBox mb { contents = "Hello, world!!" };
+      mb.Modal();
+      MessageBox { contents = "Hello, world!!", anchor.bottom = 20 }.Modal();
+      MessageBox mb;
+      mb = { };
+   }
+   Button button1
+   {
+      caption = "Click Here";
+      foreground = red;
+
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         MessageBox { contents = "Hello, world!!" }.Modal();
+         return true;
+      }
+   };
+
 
+   int a = 10;
+   anchor.right = 10;
    caption = "Form1";
    background = formColor;
    borderStyle = sizable;
@@ -9,7 +39,9 @@ class Form1 : Window
    hasMinimize = true;
    hasClose = true;
    clientSize = { 632, 438 };
-}
+};
+
+Form1 form1 { caption = "My Form" };
 
 struct InventoryItem
 {
@@ -28,8 +60,6 @@ int a;
 
 typedef int bla;
 
-// import "ecere"
-
 int SomeFunction(int * p)
 {
    int b[3][4] =