Merged arrays into Charj mainline.
[charm.git] / src / langs / charj / src / charj / translator / CharjSemantics.g
index 50810c78ef4962a155aaaf814020cc25103fa28d..c9ff0cbcf12115af89258e96232bb34d5a713fde 100644 (file)
@@ -28,6 +28,8 @@ package charj.translator;
     MethodSymbol currentMethod = null;
     LocalScope currentLocalScope = null;
     Translator translator;
+    List<CharjAST> imports = new ArrayList<CharjAST>();
+    AstModifier astmod = new AstModifier();
 
     /**
      *  Test a list of CharjAST nodes to see if any of them has the given token
@@ -62,6 +64,10 @@ package charj.translator;
             }
         }
     }
+
+    public void addImport(CharjAST importNode) {
+        imports.add(importNode);
+    }
 }
 
 
@@ -81,22 +87,22 @@ scope ScopeStack; // default scope
     symtab = _symtab;
     $ScopeStack::current = symtab.getDefaultPkg();
 }
-    // TODO: go back to allowing multiple type definitions per file, check that
-    // there is exactly one public type and return that one.
     :   ^(CHARJ_SOURCE 
         (packageDeclaration)? 
-        (importDeclarations) 
-        (typeDeclaration[$importDeclarations.packageNames]))
-        { $cs = $typeDeclaration.sym; }
+        (importDeclaration
+        | typeDeclaration { $cs = $typeDeclaration.sym; }
+        | readonlyDeclaration)*)
     ;
 
 // note: no new scope here--this replaces the default scope
 packageDeclaration
 @init { 
     List<String> names = null; 
+    String packageName = "";
 }
-    :   ^('package' qualifiedIdentifier)  {
-            String packageName = $qualifiedIdentifier.text;
+    :   ^(PACKAGE ((ids+=IDENT) { packageName += "." + $IDENT.text; })+)
+        {
+            packageName = packageName.substring(1);
             PackageScope ps = symtab.resolvePackage(packageName);
             if (ps == null) {
                 ps = symtab.definePackage(packageName);
@@ -104,49 +110,74 @@ packageDeclaration
             }
             currentPackage = ps;
             $ScopeStack::current = ps;
-            $qualifiedIdentifier.start.symbol = ps;
         }
     ;
     
-importDeclarations returns [List<CharjAST> packageNames]
-@init {
-       packageNames = new ArrayList<CharjAST>();
-}
-    :   (^('import' qualifiedIdentifier './*'?)
-               { packageNames.add($qualifiedIdentifier.start); })*
+importDeclaration
+    :   ^(IMPORT qualifiedIdentifier '.*'?)
+        { addImport($qualifiedIdentifier.start); }
     ;
 
+readonlyDeclaration
+    :   ^(READONLY localVariableDeclaration)
+    ;
 
-typeDeclaration[List<CharjAST> imports] returns [ClassSymbol sym]
+typeDeclaration returns [ClassSymbol sym]
 scope ScopeStack; // top-level type scope
-    :   ^('template' i1=IDENT* typeDeclaration[$imports])
+    :   ^(TYPE classType IDENT
+            (^('extends' parent=type))? (^('implements' type+))?
+            {
+                Scope outerScope = $ScopeStack[-1]::current;
+                $sym = new ClassSymbol(symtab, $IDENT.text, outerScope.resolveType($parent.text), outerScope);
+                outerScope.define($sym.name, $sym);
+                currentClass = $sym;
+                $sym.definition = $typeDeclaration.start;
+                $sym.definitionTokenStream = input.getTokenStream();
+                $IDENT.symbol = $sym;
+                $ScopeStack::current = $sym;
+                String classTypeName = $classType.text;
+                if (classTypeName.equals("class")) {
+                } else if (classTypeName.equals("chare")) {
+                    currentClass.isChare = true;
+                } else if (classTypeName.equals("group")) {
+                    currentClass.isChare = true;
+                } else if (classTypeName.equals("nodegroup")) {
+                    currentClass.isChare = true;
+                } else if (classTypeName.equals("chare_array")) {
+                    currentClass.isChare = true;
+                } else if (classTypeName.equals("mainchare")) {
+                    currentClass.isChare = true;
+                    currentClass.isMainChare = true;
+                } else System.out.println("Error: type " + classTypeName + " not recognized.");
+                importPackages($sym, imports);
+            }
+            classScopeDeclaration*)
+            {
+                //System.out.println("Members for type " + $sym.name + ":");
+                //for (Map.Entry<String, Symbol> entry : $sym.members.entrySet()) {
+                //    System.out.println(entry.getKey());
+                //}
+            }
+    |   ^('template' i1=IDENT* typeDeclaration)
         {
             // JL: Need to fill the templateArgs in ClassSymbol, and push this down
             // to the class subtree
         }
-    |   ^('class' i2=IDENT (^('extends' type))? (^('implements' type+))? 
-        {
-            Scope outerScope = $ScopeStack[-1]::current;
-            $sym = new ClassSymbol(symtab, $i2.text, null, outerScope);
-            outerScope.define($sym.name, $sym);
-            currentClass = $sym;
-            $sym.definition = $typeDeclaration.start;
-            $sym.definitionTokenStream = input.getTokenStream();
-            $i2.symbol = $sym;
-            $ScopeStack::current = $sym;
-            importPackages($sym, $imports);
-        }
-            classScopeDeclaration*)
     |   ^('interface' IDENT (^('extends' type+))?  interfaceScopeDeclaration*)
     |   ^('enum' IDENT (^('implements' type+))? enumConstant+ classScopeDeclaration*)
-    |   ^(chareType IDENT (^('extends' type))? (^('implements' type+))? classScopeDeclaration*)
-    |   ^('chare_array' ARRAY_DIMENSION IDENT (^('extends' type))? (^('implements' type+))? classScopeDeclaration*)
+    ;
+
+classType
+    :   CLASS
+    |   chareType
     ;
 
 chareType
-    :   'chare'
-    |   'group'
-    |   'nodegroup'
+    :   CHARE
+    |   GROUP
+    |   NODEGROUP
+    |   MAINCHARE
+    |   ^(CHARE_ARRAY ARRAY_DIMENSION)
     ;
 
 enumConstant
@@ -154,26 +185,51 @@ enumConstant
     ;
     
 classScopeDeclaration
+scope ScopeStack;
     :   ^(FUNCTION_METHOD_DECL m=modifierList? g=genericTypeParameterList? 
             ty=type IDENT f=formalParameterList a=arrayDeclaratorList? 
             b=block?)
-    |   ^(VOID_METHOD_DECL m=modifierList? g=genericTypeParameterList? IDENT 
-            f=formalParameterList b=block?)
-    |   ^(PRIMITIVE_VAR_DECLARATION modifierList? simpleType variableDeclaratorList[false])
-    |   ^(OBJECT_VAR_DECLARATION modifierList? objectType variableDeclaratorList[false])
+        {
+            ClassSymbol returnType = currentClass.resolveType($ty.text);
+            MethodSymbol sym = new MethodSymbol(symtab, $IDENT.text, currentClass, returnType);
+            currentMethod = sym;
+            sym.definition = $classScopeDeclaration.start;
+            sym.definitionTokenStream = input.getTokenStream();
+            currentClass.define($IDENT.text, sym);
+            $FUNCTION_METHOD_DECL.symbol = sym;
+        }
+    |   ^(PRIMITIVE_VAR_DECLARATION modifierList? simpleType
+            ^(VAR_DECLARATOR_LIST field[$simpleType.type, false]+))
+    |   ^(OBJECT_VAR_DECLARATION modifierList? objectType
+            ^(VAR_DECLARATOR_LIST field[$objectType.type, false]+))
+        {
+            ClassSymbol type = $objectType.type;
+            if (type != null && type.isChare) currentClass.addExtern(type.getName());
+        }
     |   ^(CONSTRUCTOR_DECL m=modifierList? g=genericTypeParameterList? IDENT f=formalParameterList 
             b=block)
         {
-               if (currentClass != null) {
+            if (astmod.isMigrationCtor($CONSTRUCTOR_DECL)) currentClass.migrationCtor = $CONSTRUCTOR_DECL;
+            if (currentClass != null) {
                 currentClass.constructor = $classScopeDeclaration.start;
-            } 
+            }
         }
     ;
+
+field [ClassSymbol type, boolean localdef]
+    :   ^(VAR_DECLARATOR variableDeclaratorId[localdef] variableInitializer?)
+    {
+            VariableSymbol sym = new VariableSymbol(symtab, $variableDeclaratorId.ident, $type);
+            sym.definition = $field.start;
+            sym.definitionTokenStream = input.getTokenStream();
+            $VAR_DECLARATOR.symbol = sym;
+            currentClass.define($variableDeclaratorId.ident, sym);
+    }
+    ;
     
 interfaceScopeDeclaration
     :   ^(FUNCTION_METHOD_DECL modifierList? genericTypeParameterList? 
             type IDENT formalParameterList arrayDeclaratorList?)
-    |   ^(VOID_METHOD_DECL modifierList? genericTypeParameterList? IDENT formalParameterList)
         // Interface constant declarations have been switched to variable
         // declarations by Charj.g; the parser has already checked that
         // there's an obligatory initializer.
@@ -189,12 +245,14 @@ variableDeclarator[boolean localdef]
     :   ^(VAR_DECLARATOR variableDeclaratorId[localdef] variableInitializer?)
     ;
     
-variableDeclaratorId[boolean localdef]
-    :   ^(IDENT domainExpression? 
+variableDeclaratorId[boolean localdef] returns [String ident]
+    :   ^(IDENT domainExpression?
         { 
             if (currentClass != null && !localdef) {
                 currentClass.initializers.add($variableDeclaratorId.start);
             }
+
+            $ident = $IDENT.text;
         } )
     ;
 
@@ -219,7 +277,7 @@ domainExpression
 
 variableInitializer
     :   arrayInitializer
-    |   newExpression
+    |   expression
     ;
 
 arrayDeclaratorList
@@ -243,59 +301,105 @@ bound
     ;
 
 modifierList
-    :   ^(MODIFIER_LIST modifier+)
+    :   ^(MODIFIER_LIST accessModifierList? localModifierList? charjModifierList? otherModifierList?)
     ;
 
 modifier
-    :   'public'
-    |   'protected'
-    |   'private'
-    |   'entry'
-    |   'abstract'
-    |   'native'
+    :   accessModifier
     |   localModifier
+    |   charjModifier
+    |   otherModifier
     ;
 
 localModifierList
     :   ^(LOCAL_MODIFIER_LIST localModifier+)
     ;
 
+accessModifierList
+    :   ^(ACCESS_MODIFIER_LIST accessModifier+)
+    ;
+
+charjModifierList
+    :   ^(CHARJ_MODIFIER_LIST charjModifier+)
+    ;
+
+otherModifierList
+    :   ^(OTHER_MODIFIER_LIST otherModifier+)
+    ;
+    
 localModifier
-    :   'final'
-    |   'static'
-    |   'volatile'
+    :   FINAL
+    |   STATIC
+    |   VOLATILE
+    ;
+
+accessModifier
+    :   PUBLIC
+    |   PROTECTED
+    |   PRIVATE
+    ;
+
+charjModifier
+    :   ENTRY
+    ;
+
+otherModifier
+    :   ABSTRACT
+    |   NATIVE
     ;
 
 type
     :   simpleType
-    |   objectType 
+    |   objectType
+    |   VOID
     ;
 
-simpleType
-    :   ^(TYPE primitiveType domainExpression?)
+simpleType returns [ClassSymbol type]
+    :   ^(SIMPLE_TYPE primitiveType arrayDeclaratorList?)
+        {
+            $type = symtab.resolveBuiltinType($primitiveType.text);
+        }
     ;
     
-objectType
-    :   ^(TYPE qualifiedTypeIdent domainExpression?)
+objectType returns [ClassSymbol type]
+    :   ^(OBJECT_TYPE qualifiedTypeIdent arrayDeclaratorList?)
+    |   ^(REFERENCE_TYPE qualifiedTypeIdent arrayDeclaratorList?)
+    |   ^(PROXY_TYPE qualifiedTypeIdent arrayDeclaratorList?)
+    |   ^(POINTER_TYPE qualifiedTypeIdent arrayDeclaratorList?)
+        {
+            $type = $qualifiedTypeIdent.type;
+        }
     ;
 
-qualifiedTypeIdent
-    :   ^(QUALIFIED_TYPE_IDENT typeIdent+) 
+qualifiedTypeIdent returns [ClassSymbol type]
+@init {
+String name = "";
+}
+    :   ^(QUALIFIED_TYPE_IDENT (typeIdent {name += $typeIdent.name;})+) 
+        {
+            $type = null;
+            /*System.out.println("trying to resolve type " + name + " in type " + currentClass);*/
+            if (currentClass != null) $type = currentClass.resolveType(name);
+            /*System.out.println("got " + $type);*/
+            if ($type == null) $type = symtab.resolveBuiltinType(name);
+            $QUALIFIED_TYPE_IDENT.symbol = $type;
+        }
     ;
 
-typeIdent
+typeIdent returns [String name]
     :   ^(IDENT templateInstantiation?)
+        { $name = $IDENT.text; }
     ;
 
 primitiveType
-    :   'boolean'     { $start.symbol = new Symbol(symtab, "bool_primitive", symtab.resolveBuiltinType("bool")); }
-    |   'char'        { $start.symbol = new Symbol(symtab, "char_primitive", symtab.resolveBuiltinType("char")); }
-    |   'byte'        { $start.symbol = new Symbol(symtab, "byte_primitive", symtab.resolveBuiltinType("char")); }
-    |   'short'       { $start.symbol = new Symbol(symtab, "short_primitive", symtab.resolveBuiltinType("short")); }
-    |   'int'         { $start.symbol = new Symbol(symtab, "int_primitive", symtab.resolveBuiltinType("int")); }
-    |   'long'        { $start.symbol = new Symbol(symtab, "long_primitive", symtab.resolveBuiltinType("long")); }
-    |   'float'       { $start.symbol = new Symbol(symtab, "float_primitive", symtab.resolveBuiltinType("float")); }
-    |   'double'      { $start.symbol = new Symbol(symtab, "double_primitive", symtab.resolveBuiltinType("double")); }
+    :   BOOLEAN     { $start.symbol = new Symbol(symtab, "bool_primitive", symtab.resolveBuiltinType("bool")); }
+    |   CHAR        { $start.symbol = new Symbol(symtab, "char_primitive", symtab.resolveBuiltinType("char")); }
+    |   BYTE        { $start.symbol = new Symbol(symtab, "byte_primitive", symtab.resolveBuiltinType("char")); }
+    |   SHORT       { $start.symbol = new Symbol(symtab, "short_primitive", symtab.resolveBuiltinType("short")); }
+    |   INT         { $start.symbol = new Symbol(symtab, "int_primitive", symtab.resolveBuiltinType("int")); }
+    |   LONG        { $start.symbol = new Symbol(symtab, "long_primitive", symtab.resolveBuiltinType("long")); }
+    |   FLOAT       { $start.symbol = new Symbol(symtab, "float_primitive", symtab.resolveBuiltinType("float")); }
+    |   DOUBLE      { $start.symbol = new Symbol(symtab, "double_primitive", symtab.resolveBuiltinType("double")); }
     ;
 
 genericTypeArgumentList
@@ -329,10 +433,10 @@ formalParameterVarargDecl
     ;
     
 // FIXME: is this rule right? Verify that this is ok, I expected something like:
-// IDENT (^('.' qualifiedIdentifier IDENT))*
+// IDENT (^(DOT qualifiedIdentifier IDENT))*
 qualifiedIdentifier
     :   IDENT
-    |   ^('.' qualifiedIdentifier IDENT)
+    |   ^(DOT qualifiedIdentifier IDENT)
     ;
     
 block
@@ -347,38 +451,52 @@ blockStatement
 localVariableDeclaration
     :   ^(PRIMITIVE_VAR_DECLARATION localModifierList? simpleType variableDeclaratorList[true])
     |   ^(OBJECT_VAR_DECLARATION localModifierList? objectType variableDeclaratorList[true])
+        {
+            ClassSymbol type = $objectType.type;
+            /*System.out.println("looked up type " + type + " for declaration " + $objectType.text);*/
+            if (type != null && type.isChare && currentClass != null) currentClass.addExtern(type.getName());
+        }
     ;
 
 statement
-    :   block
-    |   ^('assert' expression expression?)
-    |   ^('if' parenthesizedExpression statement statement?)
-    |   ^('for' forInit expression? expression* statement)
-    |   ^(FOR_EACH localModifierList? type IDENT expression statement) 
-    |   ^('while' parenthesizedExpression statement)
-    |   ^('do' statement parenthesizedExpression)
-    |   ^('switch' parenthesizedExpression switchCaseLabel*)
-    |   ^('return' expression?)
-    |   ^('throw' expression)
-    |   ^('break' IDENT?) {
+    : nonBlockStatement
+    | block
+    ;
+
+nonBlockStatement
+    :   ^(ASSERT expression expression?)
+    |   ^(IF parenthesizedExpression block block?)
+    |   ^(FOR forInit? FOR_EXPR expression? FOR_UPDATE expression* block)
+    |   ^(FOR_EACH localModifierList? type IDENT expression block) 
+    |   ^(WHILE parenthesizedExpression block)
+    |   ^(DO block parenthesizedExpression)
+    |   ^(SWITCH parenthesizedExpression switchCaseLabel*)
+    |   ^(RETURN expression?)
+    |   ^(THROW expression)
+    |   ^(BREAK IDENT?) {
             if ($IDENT != null) {
                 translator.error(this, "Labeled break not supported yet, ignoring.", $IDENT);
             }
         }
-    |   ^('continue' IDENT?) {
+    |   ^(CONTINUE IDENT?) {
             if ($IDENT != null) {
                 translator.error(this, "Labeled continue not supported yet, ignoring.", $IDENT);
             }
         }
     |   ^(LABELED_STATEMENT IDENT statement)
     |   expression
-    |   ^('embed' STRING_LITERAL EMBED_BLOCK)
+    |   ^('delete' qualifiedIdentifier)
+    |   ^(EMBED STRING_LITERAL EMBED_BLOCK)
     |   ';' // Empty statement.
+    |   ^(PRINT expression*)
+    |   ^(PRINTLN expression*)
+    |   ^(EXIT expression?)
+    |   EXITALL
     ;
         
 switchCaseLabel
-    :   ^('case' expression blockStatement*)
-    |   ^('default' blockStatement*)
+    :   ^(CASE expression blockStatement*)
+    |   ^(DEFAULT blockStatement*)
     ;
     
 forInit
@@ -397,68 +515,80 @@ expression
     ;
 
 expr
-    :   ^('=' expr expr)
-    |   ^('+=' expr expr)
-    |   ^('-=' expr expr)
-    |   ^('*=' expr expr)
-    |   ^('/=' expr expr)
-    |   ^('&=' expr expr)
-    |   ^('|=' expr expr)
-    |   ^('^=' expr expr)
-    |   ^('%=' expr expr)
+    :   ^(ASSIGNMENT expr expr)
+    |   ^(PLUS_EQUALS expr expr)
+    |   ^(MINUS_EQUALS expr expr)
+    |   ^(TIMES_EQUALS expr expr)
+    |   ^(DIVIDE_EQUALS expr expr)
+    |   ^(AND_EQUALS expr expr)
+    |   ^(OR_EQUALS expr expr)
+    |   ^(POWER_EQUALS expr expr)
+    |   ^(MOD_EQUALS expr expr)
     |   ^('>>>=' expr expr)
     |   ^('>>=' expr expr)
     |   ^('<<=' expr expr)
     |   ^('?' expr expr expr)
-    |   ^('||' expr expr)
-    |   ^('&&' expr expr)
-    |   ^('|' expr expr)
-    |   ^('^' expr expr)
-    |   ^('&' expr expr)
-    |   ^('==' expr expr)
-    |   ^('!=' expr expr)
-    |   ^('instanceof' expr type)
-    |   ^('<=' expr expr)
-    |   ^('>=' expr expr)
+    |   ^(OR expr expr)
+    |   ^(AND expr expr)
+    |   ^(BITWISE_OR expr expr)
+    |   ^(POWER expr expr)
+    |   ^(BITWISE_AND expr expr)
+    |   ^(EQUALS expr expr)
+    |   ^(NOT_EQUALS expr expr)
+    |   ^(INSTANCEOF expr type)
+    |   ^(LTE expr expr)
+    |   ^(GTE expr expr)
     |   ^('>>>' expr expr)
     |   ^('>>' expr expr)
-    |   ^('>' expr expr)
+    |   ^(GT expr expr)
     |   ^('<<' expr expr)
-    |   ^('<' expr expr)
-    |   ^('+' expr expr)
-    |   ^('-' expr expr)
-    |   ^('*' expr expr)
-    |   ^('/' expr expr)
-    |   ^('%' expr expr)
+    |   ^(LT expr expr)
+    |   ^(PLUS expr expr)
+    |   ^(MINUS expr expr)
+    |   ^(TIMES expr expr)
+    |   ^(DIVIDE expr expr)
+    |   ^(MOD expr expr)
     |   ^(UNARY_PLUS expr)
     |   ^(UNARY_MINUS expr)
     |   ^(PRE_INC expr)
     |   ^(PRE_DEC expr)
     |   ^(POST_INC expr)
     |   ^(POST_DEC expr)
-    |   ^('~' expr)
-    |   ^('!' expr)
+    |   ^(TILDE expr)
+    |   ^(NOT expr)
     |   ^(CAST_EXPR type expr)
     |   primaryExpression
     ;
     
 primaryExpression
-    :   ^(  '.' primaryExpression
+    :   ^(DOT primaryExpression
                 (   IDENT
-                |   'this'
-                |   'super'
+                |   THIS
+                |   SUPER
+                )
+        )
+    |   ^(ARROW primaryExpression
+                (   IDENT
+                |   THIS
+                |   SUPER
                 )
         )
     |   parenthesizedExpression
     |   IDENT
     |   ^(METHOD_CALL primaryExpression genericTypeArgumentList? arguments)
+    |   ^(ENTRY_METHOD_CALL primaryExpression genericTypeArgumentList? arguments)
     |   explicitConstructorCall
     |   ^(ARRAY_ELEMENT_ACCESS primaryExpression expression)
     |   literal
     |   newExpression
-    |   'this'
+    |   THIS
     |   arrayTypeDeclarator
-    |   'super'
+    |   SUPER
+    |   GETNUMPES
+    |   GETNUMNODES
+    |   GETMYPE
+    |   GETMYNODE
+    |   GETMYRANK
     ;
     
 explicitConstructorCall
@@ -477,16 +607,9 @@ newExpression
                 currentClass.initializers.add($newExpression.start);
             }
         }
+    |   ^(NEW type arguments)
     ;
 
-/*newExpression
-    :   ^(  STATIC_ARRAY_CREATOR
-            (   primitiveType newArrayConstruction
-            |   genericTypeArgumentList? qualifiedTypeIdent newArrayConstruction
-            )
-        )
-    ;*/
-
 newArrayConstruction
     :   arrayDeclaratorList arrayInitializer
     |   expression+ arrayDeclaratorList?
@@ -503,8 +626,8 @@ literal
     |   FLOATING_POINT_LITERAL
     |   CHARACTER_LITERAL
     |   STRING_LITERAL          
-    |   'true'
-    |   'false'
-    |   'null'
+    |   TRUE
+    |   FALSE
+    |   NULL 
     ;