Charj : a helper method is called as the first statement of each
authorMinas Charalambides <charala1@illinois.edu>
Sun, 6 Jun 2010 00:43:43 +0000 (19:43 -0500)
committerMinas Charalambides <charala1@illinois.edu>
Sun, 6 Jun 2010 00:46:34 +0000 (19:46 -0500)
            constructor, initializing any fields that are declared
            and initialized in the class scope. The latter is not
            allowed in C++, so we have to split member initialization
            from their respective declarations.

src/langs/charj/src/charj/translator/AstModifier.java
src/langs/charj/src/charj/translator/Charj.stg
src/langs/charj/src/charj/translator/CharjASTModifier.g
src/langs/charj/src/charj/translator/CharjEmitter.g

index f409cd85e69e0c66524f5efc344ccac94c72fad3..4633bf85763a90da459e9dfcdf0367f165d0ac7c 100644 (file)
@@ -10,11 +10,13 @@ class AstModifier
     private CharjAST pupNode;
     private CharjAST initNode;
     private CharjAST migrationCtor;
+    private CharjAST constructorHelper;
 
     AstModifier()
     {
         createPupNode();
         createInitNode();
+        createCtorHelperNode();
     }
 
     protected CharjAST getPupRoutineNode()
@@ -27,10 +29,27 @@ class AstModifier
         return initNode;
     }
 
+    protected CharjAST getCtorHelperNode()
+    {
+        return constructorHelper;
+    }
+
     private CharjAST createNode(int type, String text)
     {
         return new CharjAST(new CommonToken(type, text));
-    }    
+    }   
+
+    private void createCtorHelperNode()
+    {
+        constructorHelper = createNode(CharjParser.FUNCTION_METHOD_DECL, "FUNCTION_METHOD_DECL");
+        constructorHelper.addChild(createNode(CharjParser.MODIFIER_LIST, "MODIFIER_LIST"));
+        constructorHelper.getChild(0).addChild(createNode(CharjParser.ACCESS_MODIFIER_LIST, "ACCESS_MODIFIER_LIST"));
+        constructorHelper.getChild(0).getChild(0).addChild(createNode(CharjParser.PROTECTED, "protected"));
+        constructorHelper.addChild(createNode(CharjParser.VOID, "void"));
+        constructorHelper.addChild(createNode(CharjParser.IDENT, "constructorHelper"));
+        constructorHelper.addChild(createNode(CharjParser.FORMAL_PARAM_LIST, "FORMAL_PARAM_LIST"));
+        constructorHelper.addChild(createNode(CharjParser.BLOCK, "BLOCK"));
+    }
     
     private void createInitNode()
     {
@@ -263,7 +282,38 @@ class AstModifier
         declNode.insertChild(0, modlist);
     }
 
-    protected void dealWithInit(CharjAST vardecl) {} // TODO
+    protected void insertHelperRoutineCall(CharjAST ctordecl)
+    {
+        CharjAST expr = createNode(CharjParser.EXPR, "EXPR");
+        expr.addChild(createNode(CharjParser.METHOD_CALL, "METHOD_CALL"));
+        expr.getChild(0).addChild(createNode(CharjParser.IDENT, "constructorHelper"));
+        expr.getChild(0).addChild(createNode(CharjParser.ARGUMENT_LIST, "ARGUMENT_LIST"));
+
+        ctordecl.getChild(3).insertChild(0, expr);   
+    }
+
+    protected void dealWithInit(CharjAST vardecl)
+    {
+        if(vardecl.getChildCount() > 1) // has an initialization expression
+        {
+            boolean localScope = false;
+            for(CharjAST temp = vardecl; temp != null; temp = temp.getParent())
+                if(temp.getType() == CharjParser.FUNCTION_METHOD_DECL || temp.getType() == CharjParser.CONSTRUCTOR_DECL)
+                {
+                    localScope = true;
+                    break;
+                }
+            if(!localScope)
+            {
+                // add current variable initialization to constructorHelper
+                CharjAST expr = createNode(CharjParser.EXPR, "EXPR");
+                expr.addChild(createNode(CharjParser.ASSIGNMENT, "="));
+                expr.getChild(0).addChild(vardecl.getChild(0).dupNode());
+                expr.getChild(0).addChild(vardecl.getChild(1).getChild(0).dupTree());
+                constructorHelper.getChild(4).addChild(expr);
+            }
+        }
+    }
 
     private boolean hasMigrationCtor = false;
     private CharjAST defaultCtor;
@@ -347,6 +397,8 @@ class AstModifier
             defaultCtor.addChild(createNode(CharjParser.FORMAL_PARAM_LIST, "FORMAL_PARAM_LIST"));
             defaultCtor.addChild(createNode(CharjParser.BLOCK, "BLOCK"));
 
+            insertHelperRoutineCall(defaultCtor);
+
             if(typenode.getChild(0).getType() == CharjParser.MAINCHARE)
             {
                 // fill CkMsgArg* argument
index 5f455170ef8b1cf223730b3aaf2ba19a2fec4b77..324f8775cf1dd3db75e55b95194fbe7c68f96977 100644 (file)
@@ -296,11 +296,20 @@ var_decl_list(var_decls) ::=
 >>
 
 
-var_decl(id, initializer) ::=
+var_decl_cc(id, initializer) ::=
 <<
 <id><if(initializer)> = <initializer><endif>
 >>
 
+var_decl_h(id, initializer) ::=
+<<
+<id>
+>>
+
+var_decl_ci(id, initializer) ::=
+<<
+<id><if(initializer)> = <initializer><endif>
+>>
 
 var_decl_id(id, array_decl_list) ::=
 <<
index 61f62f7a5f1e6e481f798d5bba3602e87b449c6b..2dbdf6aae4301b616122a222bbe0d3e1c974de2a 100644 (file)
@@ -72,6 +72,7 @@ typeDeclaration returns [ClassSymbol sym]
         {
             $TYPE.tree.addChild(astmod.getPupRoutineNode());
             $TYPE.tree.addChild(astmod.getInitRoutineNode());
+            $TYPE.tree.addChild(astmod.getCtorHelperNode());
             astmod.ensureDefaultCtor($TYPE.tree);
             if (array_type) astmod.ensureMigrationCtor($TYPE.tree);
         }
@@ -115,10 +116,12 @@ classScopeDeclaration
     |   ^(CONSTRUCTOR_DECL m=modifierList? g=genericTypeParameterList? IDENT f=formalParameterList 
             b=block)
         {
-            astmod.checkForDefaultCtor($CONSTRUCTOR_DECL, $CONSTRUCTOR_DECL.tree);
-            astmod.checkForMigrationCtor($CONSTRUCTOR_DECL);
             if($m.tree == null)
                 astmod.fillPrivateModifier($CONSTRUCTOR_DECL.tree);
+
+            astmod.insertHelperRoutineCall($CONSTRUCTOR_DECL.tree);
+            astmod.checkForDefaultCtor($CONSTRUCTOR_DECL, $CONSTRUCTOR_DECL.tree);
+            astmod.checkForMigrationCtor($CONSTRUCTOR_DECL);
         }
     ;
     
@@ -139,7 +142,7 @@ variableDeclaratorList
 variableDeclarator
     :   ^(VAR_DECLARATOR variableDeclaratorId variableInitializer?)
         {
-            astmod.dealWithInit($VAR_DECLARATOR.tree);
+            astmod.dealWithInit($VAR_DECLARATOR);
         }
     ;
     
index 2fa9d3666f433eb031f5048844500a4e723a5fab..322c643784ba5f6f570ada9d8598cfb78c00d2da 100644 (file)
@@ -291,8 +291,11 @@ variableDeclaratorList
 
 variableDeclarator
     :   ^(VAR_DECLARATOR id=variableDeclaratorId initializer=variableInitializer?)
-        -> var_decl(id={$id.st}, initializer={$initializer.st})
-    ;
+        -> {emitCC()}? var_decl_cc(id={$id.st}, initializer={$initializer.st})
+        -> {emitH()}?  var_decl_h(id={$id.st}, initializer={$initializer.st})
+        -> {emitCI()}? var_decl_ci(id={$id.st}, initializer={$initializer.st})
+        ->
+    ; 
     
 variableDeclaratorId
     :   ^(IDENT adl=arrayDeclaratorList?)