Template declaration, semantics still need some work
authorJonathan Lifflander <jliffl2@illinois.edu>
Mon, 19 Apr 2010 15:31:56 +0000 (10:31 -0500)
committerJonathan Lifflander <jliffl2@illinois.edu>
Mon, 19 Apr 2010 15:31:56 +0000 (10:31 -0500)
src/langs/charj/src/charj/translator/Charj.g
src/langs/charj/src/charj/translator/Charj.g~ [new file with mode: 0644]
src/langs/charj/src/charj/translator/Charj.stg
src/langs/charj/src/charj/translator/Charj.stg~ [new file with mode: 0644]
src/langs/charj/src/charj/translator/CharjEmitter.g
src/langs/charj/src/charj/translator/CharjEmitter.g~ [new file with mode: 0644]
src/langs/charj/src/charj/translator/CharjSemantics.g
src/langs/charj/src/charj/translator/CharjSemantics.g~ [new file with mode: 0644]
src/langs/charj/tests/unit/Template.cj [new file with mode: 0644]

index 1ccfbaa09820f927607eeaaebbc66a951980fe62..9b6cb96cf94c3fd10547911ad706c690e36ae0ed 100644 (file)
@@ -144,9 +144,13 @@ typeDeclaration
     |   chareArrayDefinition
     ;
 
+templateList
+    : 'class'! IDENT (','! 'class'! IDENT)*
+    ;
+
 templateDeclaration
-    : 'template' '<' 'class' IDENT '>' classDefinition
-        -> ^('template' 'class' IDENT classDefinition)
+    : 'template' '<' templateList '>' classDefinition
+        -> ^('template' templateList classDefinition)
     ;
 
 classDefinition
diff --git a/src/langs/charj/src/charj/translator/Charj.g~ b/src/langs/charj/src/charj/translator/Charj.g~
new file mode 100644 (file)
index 0000000..4db1134
--- /dev/null
@@ -0,0 +1,853 @@
+/**
+ * ANTLR (v3) grammar for the Charj Language
+ *
+ * The other .g files are tree parsers that can read and modify an AST 
+ * using the output of this grammar.
+ */
+
+
+grammar Charj;
+
+options {
+    backtrack = true; 
+    memoize = true;
+    output = AST;
+    ASTLabelType = CharjAST;
+}
+
+tokens {
+    ENTRY                   = 'entry'           ;
+
+    // C++ keywords that aren't used in charj. 
+    // We don't use these ourselves, but they're still reserved
+    ASM                     = 'asm'             ;
+    AUTO                    = 'auto'            ;
+    BOOL                    = 'bool'            ;
+    CONST_CAST              = 'const_cast'      ;
+    DYNAMIC_CAST            = 'dynamic_cast'    ;
+    EXPLICIT                = 'explicit'        ;
+    EXPORT                  = 'export'          ;
+    EXTERN                  = 'extern'          ;
+    FRIEND                  = 'friend'          ;
+    GOTO                    = 'goto'            ;
+    INLINE                  = 'inline'          ;
+    MUTABLE                 = 'mutable'         ;
+    NAMESPACE               = 'namespace'       ;
+    OPERATOR                = 'operator'        ;
+    REGISTER                = 'register'        ;
+    REINTERPRET_CAST        = 'reinterpret_cast';
+    SIGNED                  = 'signed'          ;
+    SIZEOF                  = 'sizeof'          ;
+    STATIC_CAST             = 'static_cast'     ;
+    STRUCT                  = 'struct'          ;
+    TEMPLATE                = 'template'        ;
+    TYPEDEF                 = 'typedef'         ;
+    TYPEID                  = 'typeid'          ;
+    TYPENAME                = 'typename'        ;
+    UNION                   = 'union'           ;
+    UNSIGNED                = 'unsigned'        ;
+    USING                   = 'using'           ;
+    VIRTUAL                 = 'virtual'         ;
+    WCHAR_T                 = 'wchar_t'         ;
+    
+    // tokens for imaginary nodes
+    ARGUMENT_LIST;
+    ARRAY_DECLARATOR;
+    ARRAY_DECLARATOR_LIST;
+    ARRAY_ELEMENT_ACCESS;
+    ARRAY_INITIALIZER;
+    BLOCK;
+    CAST_EXPR;
+    CATCH_CLAUSE_LIST;
+    CLASS_CONSTRUCTOR_CALL;
+    CLASS_INSTANCE_INITIALIZER;
+    CLASS_STATIC_INITIALIZER;
+    CLASS_TOP_LEVEL_SCOPE;
+    CONSTRUCTOR_DECL;
+    ENUM_TOP_LEVEL_SCOPE;
+    EXPR;
+    EXTENDS_BOUND_LIST;
+    EXTENDS_CLAUSE;
+    FOR_EACH;
+    FORMAL_PARAM_LIST;
+    FORMAL_PARAM_STD_DECL;
+    FORMAL_PARAM_VARARG_DECL;
+    FUNCTION_METHOD_DECL;
+    GENERIC_TYPE_ARG_LIST;
+    GENERIC_TYPE_PARAM_LIST;
+    INTERFACE_TOP_LEVEL_SCOPE;
+    IMPLEMENTS_CLAUSE;
+    LABELED_STATEMENT;
+    LOCAL_MODIFIER_LIST;
+    CHARJ_SOURCE;
+    METHOD_CALL;
+    MODIFIER_LIST;
+    PAREN_EXPR;
+    POST_DEC;
+    POST_INC;
+    PRE_DEC;
+    PRE_INC;
+    QUALIFIED_TYPE_IDENT;
+    STATIC_ARRAY_CREATOR;
+    SUPER_CONSTRUCTOR_CALL;
+    THIS_CONSTRUCTOR_CALL;
+    TYPE;
+    UNARY_MINUS;
+    UNARY_PLUS;
+    PRIMITIVE_VAR_DECLARATION;
+    OBJECT_VAR_DECLARATION;
+    VAR_DECLARATOR;
+    VAR_DECLARATOR_LIST;
+    VOID_METHOD_DECL;
+}
+
+@header {
+package charj.translator;
+}
+
+@members {
+}
+
+@lexer::header {
+package charj.translator; 
+}
+
+@lexer::members {
+}
+
+// Starting point for parsing a Charj file.
+charjSource
+    :   compilationUnit
+        ->  ^(CHARJ_SOURCE compilationUnit)
+    ;
+
+compilationUnit
+    :   packageDeclaration? 
+        importDeclaration* 
+        typeDeclaration
+    ;
+
+packageDeclaration
+    :   'package'^ qualifiedIdentifier ';'!  
+    ;
+
+importDeclaration
+    :   'import'^ qualifiedIdentifier '.*'? ';'!
+    ;
+
+typeDeclaration
+    :   classDefinition
+    |   interfaceDefinition
+    |   enumDefinition
+    |   chareDefinition
+    |   chareArrayDefinition
+    ;
+
+classDefinition
+    :   'public'? 'class' IDENT ('extends' type)? ('implements' typeList)? '{'
+            classScopeDeclaration*
+        '}' ';'?
+        -> ^('class' IDENT ^('extends' type)? ^('implements' typeList)? classScopeDeclaration*)
+    ;
+
+chareType
+    :   'chare'
+    |   'group'
+    |   'nodegroup'
+    ;
+
+chareDefinition
+    :   'public'? chareType IDENT ('extends' type)? ('implements' typeList)? '{'
+            classScopeDeclaration*
+        '}' ';'?
+        -> ^(chareType IDENT ^('extends' type)? ^('implements' typeList)? classScopeDeclaration*)
+    ;
+
+chareArrayDefinition
+    :   'public'? 'chare_array' '[' ARRAY_DIMENSION ']' IDENT ('extends' type)? ('implements' typeList)? '{'
+            classScopeDeclaration*
+        '}' ';'?
+        -> ^('chare_array' ARRAY_DIMENSION IDENT ^('extends' type)? ^('implements' typeList)? classScopeDeclaration*)
+    ;
+
+interfaceDefinition
+    :   'interface' IDENT ('extends' typeList)?  '{'
+            interfaceScopeDeclaration*
+        '}' ';'?
+        -> ^('interface' IDENT ^('extends' typeList)? interfaceScopeDeclaration*)
+    ;
+
+enumDefinition
+    :   'enum' IDENT ('implements' typeList)? '{'
+            enumConstants ','? ';' classScopeDeclaration*
+        '}' ';'?
+        -> ^('enum' IDENT ^('implements' typeList)? enumConstants classScopeDeclaration*)
+    ;
+
+enumConstants
+    :   enumConstant (','! enumConstant)*
+    ;
+
+enumConstant
+    :   IDENT^ arguments?
+    ;
+
+typeList
+    :   type (','! type)*
+    ;
+
+classScopeDeclaration
+    :   modifierList?
+        (   genericTypeParameterList?
+            (   type IDENT formalParameterList arrayDeclaratorList? (block | ';')
+                ->  ^(FUNCTION_METHOD_DECL modifierList? genericTypeParameterList? type IDENT
+                    formalParameterList arrayDeclaratorList? block?)
+            |   'void' IDENT formalParameterList (block | ';')
+                ->  ^(VOID_METHOD_DECL modifierList? genericTypeParameterList? IDENT formalParameterList block?)
+            |   ident=IDENT formalParameterList block
+                ->  ^(CONSTRUCTOR_DECL[$ident, "CONSTRUCTOR_DECL"] modifierList? genericTypeParameterList? IDENT
+                        formalParameterList block)
+            )
+        |   simpleType classFieldDeclaratorList ';'
+            ->  ^(PRIMITIVE_VAR_DECLARATION modifierList? simpleType classFieldDeclaratorList)
+        |   objectType classFieldDeclaratorList ';'
+            ->  ^(OBJECT_VAR_DECLARATION modifierList? objectType classFieldDeclaratorList)
+        )
+    ;
+
+interfaceScopeDeclaration
+    :   modifierList?
+        (   genericTypeParameterList?
+            (   type IDENT formalParameterList arrayDeclaratorList? ';'
+                ->  ^(FUNCTION_METHOD_DECL modifierList? genericTypeParameterList?
+                        type IDENT formalParameterList arrayDeclaratorList?)
+            |   'void' IDENT formalParameterList ';'
+                ->  ^(VOID_METHOD_DECL modifierList? genericTypeParameterList? IDENT formalParameterList)
+            )
+        |   simpleType interfaceFieldDeclaratorList ';'
+            ->  ^(PRIMITIVE_VAR_DECLARATION modifierList? simpleType interfaceFieldDeclaratorList)
+        |   objectType interfaceFieldDeclaratorList ';'
+            ->  ^(OBJECT_VAR_DECLARATION modifierList? objectType interfaceFieldDeclaratorList)        
+        )
+    ;
+
+classFieldDeclaratorList
+    :   classFieldDeclarator (',' classFieldDeclarator)*
+        ->  ^(VAR_DECLARATOR_LIST classFieldDeclarator+)
+    ;
+
+classFieldDeclarator
+    :   variableDeclaratorId ('=' variableInitializer)?
+        ->  ^(VAR_DECLARATOR variableDeclaratorId variableInitializer?)
+    ;
+
+interfaceFieldDeclaratorList
+    :   interfaceFieldDeclarator (',' interfaceFieldDeclarator)*
+        ->  ^(VAR_DECLARATOR_LIST interfaceFieldDeclarator+)
+    ;
+
+interfaceFieldDeclarator
+    :   variableDeclaratorId '=' variableInitializer
+        ->  ^(VAR_DECLARATOR variableDeclaratorId variableInitializer)
+    ;
+
+
+variableDeclaratorId
+    :   IDENT^ arrayDeclaratorList?
+    ;
+
+variableInitializer
+    :   arrayInitializer
+    |   expression
+    ;
+
+arrayDeclarator
+    :   '[' ']'
+        ->  ARRAY_DECLARATOR
+    ;
+
+arrayDeclaratorList
+    :   arrayDeclarator+
+        ->  ^(ARRAY_DECLARATOR_LIST arrayDeclarator+)   
+    ;
+
+arrayInitializer
+    :   lc='{' (variableInitializer (',' variableInitializer)* ','?)? '}'
+        ->  ^(ARRAY_INITIALIZER[$lc, "ARRAY_INITIALIZER"] variableInitializer*)
+    ;
+
+genericTypeParameterList
+    :   lt='<' genericTypeParameter (',' genericTypeParameter)* genericTypeListClosing
+        ->  ^(GENERIC_TYPE_PARAM_LIST[$lt, "GENERIC_TYPE_PARAM_LIST"] genericTypeParameter+)
+    ;
+
+// This hack is fairly dirty - we just bite off some angle brackets and don't
+// actually match up opening and closing brackets.
+genericTypeListClosing  
+    :   '>'
+    |   '>>'
+    |   '>>>'
+    |
+    ;
+
+genericTypeParameter
+    :   IDENT bound?
+        ->  ^(IDENT bound?)
+    ;
+
+bound
+    :   e='extends' type ('&' type)*
+        ->  ^(EXTENDS_BOUND_LIST[$e, "EXTENDS_BOUND_LIST"] type+)
+    ;
+
+modifierList
+    :   modifier+
+        ->  ^(MODIFIER_LIST modifier+)
+    ;
+
+modifier
+    :   'public'
+    |   'protected'
+    |   'entry'
+    |   'private'
+    |   'abstract'
+    |   'native'
+    |   localModifier
+    ;
+
+localModifierList
+    :   localModifier+
+        -> ^(LOCAL_MODIFIER_LIST localModifier+)
+    ;
+
+localModifier
+    :   'final'
+    |   'static'
+    |   'volatile'
+    ;
+
+type
+    :   simpleType
+    |   objectType
+    ;
+
+simpleType
+    :   primitiveType arrayDeclaratorList?
+        ->  ^(TYPE primitiveType arrayDeclaratorList?)  
+    ;
+
+objectType
+    :   qualifiedTypeIdent arrayDeclaratorList?
+        ->  ^(TYPE qualifiedTypeIdent arrayDeclaratorList?)
+    ;
+
+qualifiedTypeIdent
+    :   typeIdent ('.' typeIdent)*
+        ->  ^(QUALIFIED_TYPE_IDENT typeIdent+) 
+    ;
+
+typeIdent
+    :   IDENT^ genericTypeArgumentList?
+    ;
+
+primitiveType
+    :   'boolean'
+    |   'char'
+    |   'byte'
+    |   'short'
+    |   'int'
+    |   'long'
+    |   'float'
+    |   'double'
+    ;
+
+genericTypeArgumentList
+    :   lt='<' genericTypeArgument (',' genericTypeArgument)* genericTypeListClosing
+        ->  ^(GENERIC_TYPE_ARG_LIST[$lt, "GENERIC_TYPE_ARG_LIST"] genericTypeArgument+)
+    ;
+
+genericTypeArgument
+    :   type
+    |   '?'
+    ;
+
+qualifiedIdentList
+    :   qualifiedIdentifier (','! qualifiedIdentifier)*
+    ;
+
+formalParameterList
+    :   lp='('
+        (   // Contains at least one standard argument declaration and optionally a variable argument declaration.
+            formalParameterStandardDecl (',' formalParameterStandardDecl)* (',' formalParameterVarArgDecl)? 
+            ->  ^(FORMAL_PARAM_LIST[$lp, "FORMAL_PARAM_LIST"] formalParameterStandardDecl+ formalParameterVarArgDecl?) 
+            // Contains a variable argument declaration only.
+        |   formalParameterVarArgDecl
+            ->  ^(FORMAL_PARAM_LIST[$lp, "FORMAL_PARAM_LIST"] formalParameterVarArgDecl) 
+            // Contains nothing.
+        |   ->  ^(FORMAL_PARAM_LIST[$lp, "FORMAL_PARAM_LIST"]) 
+        )
+        ')'
+    ;
+
+formalParameterStandardDecl
+    :   localModifierList? type variableDeclaratorId
+        ->  ^(FORMAL_PARAM_STD_DECL localModifierList? type variableDeclaratorId)
+    ;
+
+formalParameterVarArgDecl
+    :   localModifierList? type '...' variableDeclaratorId
+        ->  ^(FORMAL_PARAM_VARARG_DECL localModifierList? type variableDeclaratorId)
+    ;
+
+qualifiedIdentifier
+    :   (   IDENT
+            ->  IDENT
+        )
+        (   '.' ident=IDENT
+            ->  ^('.' $qualifiedIdentifier $ident)
+        )*
+    ;
+
+block
+    :   lc='{' blockStatement* '}'
+        ->  ^(BLOCK[$lc, "BLOCK"] blockStatement*)
+    ;
+
+blockStatement
+    :   localVariableDeclaration ';'!
+    |   statement
+    ;
+
+localVariableDeclaration
+    :   localModifierList? simpleType classFieldDeclaratorList
+        ->  ^(PRIMITIVE_VAR_DECLARATION localModifierList? simpleType classFieldDeclaratorList)
+    |   localModifierList? objectType classFieldDeclaratorList
+        ->  ^(OBJECT_VAR_DECLARATION localModifierList? objectType classFieldDeclaratorList)
+    ;
+        
+statement
+    :   block
+    |   'assert' expr1=expression 
+        (   ':' expr2=expression ';'
+            ->  ^('assert' $expr1 $expr2)
+        |   ';'
+            ->  ^('assert' $expr1)
+        )
+    |   'if' parenthesizedExpression ifStat=statement 
+        (   'else' elseStat=statement
+            ->  ^('if' parenthesizedExpression $ifStat $elseStat)
+        |
+            ->  ^('if' parenthesizedExpression $ifStat)
+        )   
+    |   f='for' '('
+        (   forInit? ';' expression? ';' expressionList? ')' statement
+            -> ^($f forInit expression? expressionList statement)
+        |   localModifierList? type IDENT ':' expression ')' statement
+            -> ^(FOR_EACH[$f, "FOR_EACH"] localModifierList? type IDENT expression statement)
+        )
+    |   'while' parenthesizedExpression statement
+        ->  ^('while' parenthesizedExpression statement)
+    |   'do' statement 'while' parenthesizedExpression ';'
+        ->  ^('do' statement parenthesizedExpression)
+    |   'switch' parenthesizedExpression '{' switchCaseLabel* '}'
+        ->  ^('switch' parenthesizedExpression switchCaseLabel*)
+    |   'return' expression? ';'
+        ->  ^('return' expression?)
+    |   'throw' expression ';'
+        ->  ^('throw' expression)
+    |   'break' IDENT? ';'
+        ->  ^('break' IDENT?)
+    |   'continue' IDENT? ';'
+        ->  ^('continue' IDENT?)
+    |   IDENT ':' statement
+        ->  ^(LABELED_STATEMENT IDENT statement)
+    |   'embed' STRING_LITERAL EMBED_BLOCK
+        ->  ^('embed' STRING_LITERAL EMBED_BLOCK)
+    |   expression ';'!
+    |   ';' // Preserve empty statements.
+    ;           
+        
+
+switchCaseLabel
+    :   'case'^ expression ':'! blockStatement*
+    |   'default'^ ':'! blockStatement*
+    ;
+    
+forInit
+    :   localVariableDeclaration
+    |   expressionList
+    ;
+    
+// EXPRESSIONS
+
+parenthesizedExpression
+    :   lp='(' expression ')'
+        ->  ^(PAREN_EXPR[$lp, "PAREN_EXPR"] expression)
+    ;
+    
+expressionList
+    :   expression (','! expression)*
+    ;
+
+expression
+    :   assignmentExpression
+        ->  ^(EXPR assignmentExpression)
+    ;
+
+assignmentExpression
+    :   conditionalExpression 
+        (   (   '='^
+            |   '+='^
+            |   '-='^
+            |   '*='^
+            |   '/='^
+            |   '&='^
+            |   '|='^
+            |   '^='^
+            |   '%='^
+            |   '<<='^
+            |   '>>='^
+            |   '>>>='^
+        ) 
+        assignmentExpression)?
+    ;
+    
+conditionalExpression
+    :   logicalOrExpression ('?'^ assignmentExpression ':'! conditionalExpression)?
+    ;
+
+logicalOrExpression
+    :   logicalAndExpression ('||'^ logicalAndExpression)*
+    ;
+
+logicalAndExpression
+    :   inclusiveOrExpression ('&&'^ inclusiveOrExpression)*
+    ;
+
+inclusiveOrExpression
+    :   exclusiveOrExpression ('|'^ exclusiveOrExpression)*
+    ;
+
+exclusiveOrExpression
+    :   andExpression ('^'^ andExpression)*
+    ;
+
+andExpression
+    :   equalityExpression ('&'^ equalityExpression)*
+    ;
+
+equalityExpression
+    :   instanceOfExpression 
+        (   (   '=='^
+            |   '!='^
+            ) 
+            instanceOfExpression
+        )*
+    ;
+
+instanceOfExpression
+    :   relationalExpression ('instanceof'^ type)?
+    ;
+
+relationalExpression
+    :   shiftExpression 
+        (   (   '<='^
+            |   '>='^
+            |   '<'^
+            |   '>'^
+            )
+            shiftExpression
+        )*
+    ;
+    
+shiftExpression
+    :   additiveExpression
+        (   (   '>>>'^
+            |   '>>'^
+            |   '<<'^
+            )
+            additiveExpression
+        )*
+    ;
+
+additiveExpression
+    :   multiplicativeExpression
+        (   (   '+'^
+            |   '-'^
+            )
+            multiplicativeExpression
+        )*
+    ;
+
+multiplicativeExpression
+    :   unaryExpression 
+        (   (   '*'^
+            |   '/'^
+            |   '%'^
+            )
+            unaryExpression
+        )*
+    ;
+    
+unaryExpression
+    :   op='+' unaryExpression
+        ->  ^(UNARY_PLUS[$op, "UNARY_PLUS"] unaryExpression)
+    |   op='-' unaryExpression
+        ->  ^(UNARY_MINUS[$op, "UNARY_MINUS"] unaryExpression)
+    |   op='++' postfixedExpression
+        ->  ^(PRE_INC[$op, "PRE_INC"] postfixedExpression)
+    |   op='--' postfixedExpression
+        ->  ^(PRE_DEC[$op, "PRE_DEC"] postfixedExpression)
+    |   unaryExpressionNotPlusMinus
+    ;
+
+unaryExpressionNotPlusMinus
+    :   '!' unaryExpression
+        ->  ^('!' unaryExpression)
+    |   '~' unaryExpression
+        ->  ^('~' unaryExpression)
+    |   lp='(' type ')' unaryExpression
+        ->  ^(CAST_EXPR[$lp, "CAST_EXPR"] type unaryExpression)
+    |   postfixedExpression
+    ;
+    
+postfixedExpression
+        // At first resolve the primary expression ...
+    :   (   primaryExpression
+            ->  primaryExpression
+        )
+        // ... and than the optional things that may follow a primary
+        // expression 0 or more times.
+        (   outerDot='.'                 
+            // Note: generic type arguments are only valid for method calls,
+            // i.e. if there is an argument list
+            (   (   genericTypeArgumentList?  
+                    IDENT
+                    ->  ^($outerDot $postfixedExpression IDENT)
+                ) 
+                (   arguments
+                    ->  ^(METHOD_CALL $postfixedExpression genericTypeArgumentList? arguments)
+                )?
+            |   'this'
+                ->  ^($outerDot $postfixedExpression 'this')
+            |   s='super' arguments
+                ->  ^(SUPER_CONSTRUCTOR_CALL[$s, "SUPER_CONSTRUCTOR_CALL"] $postfixedExpression arguments)
+            |   (   'super' innerDot='.' IDENT
+                    ->  ^($innerDot ^($outerDot $postfixedExpression 'super') IDENT)
+                )
+                (   arguments
+                    ->  ^(METHOD_CALL $postfixedExpression arguments)
+                )?
+            )
+        |   '[' expression ']'
+            ->  ^(ARRAY_ELEMENT_ACCESS $postfixedExpression expression)
+        )*
+        // At the end there may follow a post increment/decrement.
+        (   op='++'-> ^(POST_INC[$op, "POST_INC"] $postfixedExpression)
+        |   op='--'-> ^(POST_DEC[$op, "POST_DEC"] $postfixedExpression)
+        )?
+    ;    
+    
+primaryExpression
+    :   parenthesizedExpression
+    |   literal
+    |   newExpression
+    |   qualifiedIdentExpression
+    |   genericTypeArgumentList 
+        (   s='super'
+            (   arguments
+                ->  ^(SUPER_CONSTRUCTOR_CALL[$s, "SUPER_CONSTRUCTOR_CALL"] genericTypeArgumentList arguments)
+            |   IDENT arguments
+                ->  ^(METHOD_CALL ^('.' 'super' IDENT) genericTypeArgumentList arguments)
+            )
+        |   IDENT arguments
+            ->  ^(METHOD_CALL IDENT genericTypeArgumentList arguments)
+        |   t='this' arguments
+            ->  ^(THIS_CONSTRUCTOR_CALL[$t, "THIS_CONSTRUCTOR_CALL"] genericTypeArgumentList arguments)
+        )
+    |   (   'this'
+            ->  'this'
+        )
+        (   arguments
+            ->  ^(THIS_CONSTRUCTOR_CALL[$t, "THIS_CONSTRUCTOR_CALL"] arguments)
+        )?
+    |   s='super' arguments
+        ->  ^(SUPER_CONSTRUCTOR_CALL[$s, "SUPER_CONSTRUCTOR_CALL"] arguments)
+    |   (   'super' '.' IDENT
+        )
+        (   arguments
+            ->  ^(METHOD_CALL ^('.' 'super' IDENT) arguments)
+        |   ->  ^('.' 'super' IDENT)
+        )
+    ;
+    
+qualifiedIdentExpression
+        // The qualified identifier itself is the starting point for this rule.
+    :   (   qualifiedIdentifier
+            ->  qualifiedIdentifier
+        )
+        // And now comes the stuff that may follow the qualified identifier.
+        (   arguments
+            ->  ^(METHOD_CALL qualifiedIdentifier arguments)
+        |   outerDot='.'
+            (   genericTypeArgumentList 
+                (   s='super' arguments
+                    ->  ^(SUPER_CONSTRUCTOR_CALL[$s, "SUPER_CONSTRUCTOR_CALL"]
+                            qualifiedIdentifier genericTypeArgumentList arguments)
+                |   'super' innerDot='.' IDENT arguments
+                    ->  ^(METHOD_CALL ^($innerDot ^($outerDot qualifiedIdentifier 'super') IDENT)
+                            genericTypeArgumentList arguments)
+                |   IDENT arguments
+                    ->  ^(METHOD_CALL ^($outerDot qualifiedIdentifier IDENT) genericTypeArgumentList arguments)
+                )
+            |   'this'
+                ->  ^($outerDot qualifiedIdentifier 'this')
+            |   s='super' arguments
+                ->  ^(SUPER_CONSTRUCTOR_CALL[$s, "SUPER_CONSTRUCTOR_CALL"] qualifiedIdentifier arguments)
+            )
+        )?
+    ;
+
+newExpression
+    :   n='new'
+        (   primitiveType newArrayConstruction          // new static array of primitive type elements
+            ->  ^(STATIC_ARRAY_CREATOR[$n, "STATIC_ARRAY_CREATOR"] primitiveType newArrayConstruction)
+        |   genericTypeArgumentList? qualifiedTypeIdent
+                newArrayConstruction                // new static array of object type reference elements
+            ->  ^(STATIC_ARRAY_CREATOR[$n, "STATIC_ARRAY_CREATOR"] genericTypeArgumentList? qualifiedTypeIdent newArrayConstruction)
+        )
+    ;
+    
+newArrayConstruction
+    :   arrayDeclaratorList arrayInitializer
+    |   '['! expression ']'! ('['! expression ']'!)* arrayDeclaratorList?
+    ;
+
+arguments
+    :   lp='(' expressionList? ')'
+        ->  ^(ARGUMENT_LIST[$lp, "ARGUMENT_LIST"] expressionList?)
+    ;
+
+literal 
+    :   HEX_LITERAL
+    |   OCTAL_LITERAL
+    |   DECIMAL_LITERAL
+    |   FLOATING_POINT_LITERAL
+    |   CHARACTER_LITERAL
+    |   STRING_LITERAL
+    |   'true'
+    |   'false'
+    |   'null'
+    ;
+
+// LEXER
+
+HEX_LITERAL : '0' ('x'|'X') HEX_DIGIT+ INTEGER_TYPE_SUFFIX? ;
+
+DECIMAL_LITERAL : ('0' | '1'..'9' '0'..'9'*) INTEGER_TYPE_SUFFIX? ;
+
+OCTAL_LITERAL : '0' ('0'..'7')+ INTEGER_TYPE_SUFFIX? ;
+
+//fragment
+ARRAY_DIMENSION :  '1'..'6' ('d'|'D') ;
+
+fragment
+HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;
+
+fragment
+INTEGER_TYPE_SUFFIX : ('l'|'L') ;
+
+FLOATING_POINT_LITERAL
+    :   ('0'..'9')+ 
+        (
+            '.' ('0'..'9')* EXPONENT? FLOAT_TYPE_SUFFIX?
+        |   EXPONENT FLOAT_TYPE_SUFFIX?
+        |   FLOAT_TYPE_SUFFIX
+        )
+    |   '.' ('0'..'9')+ EXPONENT? FLOAT_TYPE_SUFFIX?
+    ;
+
+fragment
+EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;
+
+fragment
+FLOAT_TYPE_SUFFIX : ('f'|'F'|'d'|'D') ;
+
+CHARACTER_LITERAL
+    :   '\'' ( ESCAPE_SEQUENCE | ~('\''|'\\') ) '\''
+    ;
+
+STRING_LITERAL
+    :  '"' ( ESCAPE_SEQUENCE | ~('\\'|'"') )* '"'
+    ;
+
+fragment
+ESCAPE_SEQUENCE
+    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
+    |   UNICODE_ESCAPE
+    |   OCTAL_ESCAPE
+    ;
+
+fragment
+OCTAL_ESCAPE
+    :   '\\' ('0'..'3') ('0'..'7') ('0'..'7')
+    |   '\\' ('0'..'7') ('0'..'7')
+    |   '\\' ('0'..'7')
+    ;
+
+fragment
+UNICODE_ESCAPE
+    :   '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
+    ;
+
+IDENT
+    :   CHARJ_ID_START (CHARJ_ID_PART)*
+    ;
+
+fragment
+CHARJ_ID_START
+    :  '\u0024'
+    |  '\u0041'..'\u005a'
+    |  '\u005f'
+    |  '\u0061'..'\u007a'
+    |  '\u00c0'..'\u00d6'
+    |  '\u00d8'..'\u00f6'
+    |  '\u00f8'..'\u00ff'
+    |  '\u0100'..'\u1fff'
+    |  '\u3040'..'\u318f'
+    |  '\u3300'..'\u337f'
+    |  '\u3400'..'\u3d2d'
+    |  '\u4e00'..'\u9fff'
+    |  '\uf900'..'\ufaff'
+    ;
+
+fragment
+CHARJ_ID_PART
+    :  CHARJ_ID_START
+    |  '\u0030'..'\u0039'
+    ;
+
+WS  :  (' '|'\r'|'\t'|'\u000C'|'\n') 
+    {   
+        $channel = HIDDEN;
+    }
+    ;
+
+fragment
+EMBED_BLOCK
+    :   '{' ( options {greedy=false;} : EMBED_BLOCK | . )* '}'
+    ;
+
+COMMENT
+    :   '/*' ( options {greedy=false;} : . )* '*/'
+    {   
+        $channel = HIDDEN;
+    }
+    ;
+
+LINE_COMMENT
+    : '//' ~('\n'|'\r')* '\r'? '\n'
+    {   
+        $channel = HIDDEN;
+    }
+    ;
index 66ea745ac60a6a904dde5484f16bec6ae52176e2..9c8b4a96ac1fcb74ae3a3d7fea4d063099aa7ba3 100644 (file)
@@ -82,21 +82,28 @@ interfaceExtends(ts) ::=
 
 classDeclaration_h(ident, ext, csds) ::=
 <<
-<if(debug)>/* \<typeDeclaration> */<endif>
-
-#include "<ident>.decl.h"
 /* superclass: <ext> */
 class <ident>: public CBase_<ident> {
     <csds; separator="\n">
 };
-<if(debug)>/* \</typeDeclaration> */<endif>
+>>
 
+classWrapper_h(ident, ext, csds, class1) ::=
+<<
+<if(debug)>/* \<typeDeclaration> */<endif>
+
+#include "<ident>.decl.h"
+
+<classDeclaration_h(ident=ident, ext=ext, csds=csds)>
+
+<if(debug)>/* \</typeDeclaration> */<endif>
 >>
 
-templateDeclaration_h(ident, class1) ::=
+templateDeclaration_h(tident, ident, ext, csds) ::=
 <<
-template \<class <ident>\>
-<class1>
+#include "<ident>.decl.h"
+template \<class <tident; separator=", class ">\>
+<classDeclaration_h(ident=ident, ext=ext, csds=csds)>
 >>
 
 classDeclaration_cc(ident, ext, csds) ::=
diff --git a/src/langs/charj/src/charj/translator/Charj.stg~ b/src/langs/charj/src/charj/translator/Charj.stg~
new file mode 100644 (file)
index 0000000..66ea745
--- /dev/null
@@ -0,0 +1,398 @@
+group Charj;
+
+charjSource_ci(pd, ids, tds, debug) ::= 
+//<pd>
+//<ids>
+<<
+<if(debug)>/* \<charjSource_ci> */<endif>
+/*
+ * packageDeclaration disabled...
+<pd>
+ * end packageDeclaration
+ */
+
+/*
+ * importDeclarations disabled...
+<ids>
+ * end importDeclarations
+ */
+
+<tds>
+<if(debug)>/* \</charjSource_ci> */<endif>
+
+>>
+
+
+charjSource_h(pd, ids, tds, cb, debug) ::= 
+<<
+<if(debug)>/* \<CHARJ_SOURCE> */<endif>
+/**************************************************************************
+ * WARNING                                                                *
+ **************************************************************************
+ * This is a machine generated header file.                               *
+ * It is not meant to be edited by hand and may be overwritten by charjc. *
+ **************************************************************************/
+
+<pd>
+<ids>
+<tds>
+<cb>
+
+<if(debug)>/* \</CHARJ_SOURCE> */<endif>
+
+>>
+
+
+charjSource_cc(pd, ids, tds, cb, debug) ::= 
+<<
+<if(debug)>/* \<CHARJ_SOURCE> */<endif>
+<ids>
+<pd>
+<tds>
+<cb>
+<if(debug)>/* \</CHARJ_SOURCE> */<endif>
+
+>>
+
+packageDeclaration_cc_h(ids) ::= 
+<<
+<if(debug)>/* \<packageDeclaration> */<endif>
+namespace <ids; separator=" { namespace "> {
+<if(debug)>/* \</packageDeclaration> */<endif>
+>>
+
+importDeclaration_cc_h(inc_id, use_id) ::= 
+<<
+<if(debug)>/* \<importDeclaration> */<endif>
+#include \<<inc_id>\>
+using <use_id>;
+<if(debug)>/* \</importDeclaration> */<endif>
+>>
+
+classExtends_ci(type) ::= "<type>"
+
+
+classExtends_cc_h(type) ::= "#include \<<type>.h\>"
+
+
+interfaceExtends(ts) ::=
+<<
+: public <ts; separator=", public ">
+>>
+
+classDeclaration_h(ident, ext, csds) ::=
+<<
+<if(debug)>/* \<typeDeclaration> */<endif>
+
+#include "<ident>.decl.h"
+/* superclass: <ext> */
+class <ident>: public CBase_<ident> {
+    <csds; separator="\n">
+};
+<if(debug)>/* \</typeDeclaration> */<endif>
+
+>>
+
+templateDeclaration_h(ident, class1) ::=
+<<
+template \<class <ident>\>
+<class1>
+>>
+
+classDeclaration_cc(ident, ext, csds) ::=
+<<
+<if(debug)>/* \<typeDeclaration> */<endif>
+
+
+#include "<ident>.decl.h"
+/* superclass: <ext> */
+class <ident>: public CBase_<ident> {
+    <csds; separator="\n">
+};
+#include "<ident>.def.h"
+<if(debug)>/* \</typeDeclaration> */<endif>
+
+>>
+
+
+charedeclaration_ci(chareType, arrayDim, ident, ext, csds) ::=
+<<
+<if(debug)>/* \<typeDeclaration> */<endif>
+module <ident> {
+<if(ext)>
+    extern module <ext>;
+    <chareType><if(arrayDim)> [<arrayDim>]<endif> <ident>: <ext> {
+<else>
+    <chareType><if(arrayDim)> [<arrayDim>]<endif> <ident> {
+<endif>
+        <csds; separator="\n">
+    }
+}
+
+<if(debug)>/* \</typeDeclaration> */<endif>
+
+>>
+
+
+funcMethodDecl_h(modl, gtpl, ty, id, fpl, adl, block) ::=
+<<
+<if(modl)><modl>: <endif><ty> <gtpl> <id><fpl> <adl>;
+>>
+
+
+funcMethodDecl_ci(modl, gtpl, ty, id, fpl, adl, block) ::=
+<<
+entry <ty> <gtpl> <id><fpl> <adl>;
+>>
+
+
+funcMethodDecl_cc(modl, gtpl, ty, id, fpl, adl, block) ::=
+<<
+<if(modl)><modl>: <endif><ty> <gtpl> <id><fpl> <adl> {
+    <block>
+}
+>>
+
+
+voidMethodDecl_ci(modl, gtpl, id, fpl, block) ::=
+<<
+entry void<gtpl> <id><fpl>;
+>>
+
+
+voidMethodDecl_h(modl, gtpl, id, fpl, block) ::=
+<<
+<if(modl)><modl>: <endif>void<gtpl> <id><fpl>;
+>>
+
+
+voidMethodDecl_cc(modl, gtpl, id, fpl, block) ::=
+<<
+<if(modl)><modl>: <endif>void<gtpl> <id><fpl> {
+    <block>
+}
+>>
+
+
+ctorDecl_ci(modl, gtpl, id, fpl, block) ::=
+<<
+entry void<gtpl> <id><fpl>;
+>>
+
+
+ctorDecl_h(modl, gtpl, id, fpl, block) ::=
+<<
+<if(modl)><modl>:<endif><gtpl> <id><fpl>;
+>>
+
+
+ctorDecl_cc(modl, gtpl, id, fpl, block) ::=
+<<
+<if(modl)><modl>:<endif><gtpl> <id><fpl> {
+    <block>
+}
+>>
+
+
+block_cc(bsl) ::=
+<<
+<bsl:{s| <s><\n>}>
+>>
+
+
+embed_cc(str, blk) ::=
+<<
+// begin embedded block: <str>
+<blk>
+// end embedded block: <str>
+>>
+
+
+class_var_decl(modl, type, declList) ::=
+<<
+<if(modl)><modl>:<else>public:<endif> <type> <declList>;
+>>
+
+
+var_decl_list(var_decls) ::=
+<<
+<var_decls; separator=", ">
+>>
+
+
+var_decl(id, initializer) ::=
+<<
+<id><if(initializer)> = <initializer><endif>
+>>
+
+
+var_decl_id(id, array_decl_list) ::=
+<<
+<id><if(array_decl_list)> <array_decl_list><endif>
+>>
+
+
+var_id_decl(id, adl) ::=
+<<
+<id><if(adl)> <adl><endif>
+>>
+
+
+mod_list(mods) ::=
+<<
+<if(mods)><mods; separator=" "><endif>
+>>
+
+
+local_mod_list(mods) ::=
+<<
+<if(mods)><mods; separator=" "><endif>
+>>
+
+local_var_decl(modList, type, declList) ::=
+<<
+<if(modList)>
+<modList> <type> <declList>;
+<else>
+<type> <declList>;
+<endif>
+>>
+
+
+type(typeID, arrDeclList) ::=
+<<
+<typeID><arrDeclList>
+>>
+
+
+typeIdent(typeID, generics) ::=
+<<
+<typeID><generics>
+>>
+
+
+generic_arg_list(types) ::=
+<<
+\<<types>\>
+>>
+
+
+formal_param_list(sdecl, vdecl) ::=
+<<
+<if(vdecl)>
+(<sdecl; separator=", ">, <vdecl>)
+<else>
+(<sdecl; separator=", ">)
+<endif>
+>>
+
+
+formal_param_decl(modList, type, declID) ::=
+<<
+<if(modList)><modList> <endif><type> <declID>
+>>
+
+
+assert(cond, msg) ::=
+<<
+<if(msg)>
+CkAssert(<cond> && <msg>);
+<else>
+CkAssert(<cond>);
+<endif>
+>>
+
+
+if(cond, then, else_) ::=
+<<
+if <cond> {
+    <then>
+}<if(else_)> else {
+    <else_>
+}<endif>
+>>
+
+
+for(initializer, cond, update, body) ::=
+<<
+for (<initializer> <cond> <update>) {
+    <body>
+}
+>>
+
+while(cond, body) ::=
+<<
+while <cond> {
+    <body>
+} 
+>>
+
+dowhile(cond, body) ::=
+<<
+do {
+    <body>
+} while <cond>;
+>>
+
+
+switch(expr, labels) ::=
+<<
+switch <expr> {
+    <labels>
+}
+>>
+
+return(val) ::=
+<<
+return<if(val)> <val><endif>;
+>>
+
+label(text, stmt) ::=
+<<
+<text>: <stmt>
+>>
+
+case(expr, block) ::=
+<<
+case <expr>: <block>
+>>
+
+for_cond(expr) ::=
+<<
+<expr>
+>>
+
+for_update(exprs) ::=
+<<
+<exprs; separator=", ">
+>>
+
+method_call(primary, generic_types, args) ::=
+<<
+<if(generic_types)>
+<primary>\<<generic_types>\>(<args>)
+<else>
+<primary>(<args>)
+<endif>
+>>
+
+
+array_construction_with_init(array_decls, initializer) ::=
+<<
+<array_decls> = {<initializer>};
+>>
+
+
+array_construction(exprs, array_decls) ::=
+<<
+[<exprs; separator="][">]<array_decls>
+>> 
+
+
+arguments(exprs) ::=
+<<
+<exprs; separator=", ">
+>>
+
+
index 6d3e5739689810136af33d6d2dac2240046aa3b7..0d29b575e60b6009c86432ff22938577501ce636 100644 (file)
@@ -136,17 +136,19 @@ importDeclaration
     ;
     
 typeDeclaration
-    :   ^('template' 'class' IDENT td=typeDeclaration)
+    :   ^('template' (i0+=IDENT*) ^('class' i1=IDENT (^('extends' su=type))? (^('implements' type+))? (csds+=classScopeDeclaration)*))
         -> {emitH()}? templateDeclaration_h(
-            ident={$IDENT.text},
-            class1={$td.st})
+            tident={$i0},
+            ident={$i1.text},
+            ext={$su.st},
+            csds={$csds})
         ->
     |   ^('class' i1=IDENT (^('extends' su=type))? (^('implements' type+))? (csds+=classScopeDeclaration)*)
         -> {emitCC()}? classDeclaration_cc(
                 ident={$i1.text}, 
                 ext={$su.st}, 
                 csds={$csds})
-        -> {emitH()}? classDeclaration_h(
+        -> {emitH()}? classWrapper_h(
                 ident={$i1.text}, 
                 ext={$su.st}, 
                 csds={$csds})
diff --git a/src/langs/charj/src/charj/translator/CharjEmitter.g~ b/src/langs/charj/src/charj/translator/CharjEmitter.g~
new file mode 100644 (file)
index 0000000..6d3e573
--- /dev/null
@@ -0,0 +1,734 @@
+/**
+ * ANTLR (v3) Tree Parser for the Charj Language
+ */
+
+tree grammar CharjEmitter;
+
+options {
+    backtrack = true; 
+    memoize = true;
+    tokenVocab = Charj;
+    ASTLabelType = CharjAST;
+    output = template;
+}
+
+
+@header {
+package charj.translator;
+}
+
+
+@members {
+    SymbolTable symtab_ = null;
+
+    PackageScope currentPackage_ = null;
+    ClassSymbol currentClass_ = null;
+    MethodSymbol currentMethod_ = null;
+    LocalScope currentLocalScope_ = null;
+
+    Translator translator_;
+    OutputMode mode_;
+
+    private boolean emitCC() { return mode_ == OutputMode.cc; }
+    private boolean emitCI() { return mode_ == OutputMode.ci; }
+    private boolean emitH() { return mode_ == OutputMode.h; }
+    private boolean debug() { return translator_.debug(); }
+
+    /**
+     *  Override ANTLR's token mismatch behavior so we throw exceptions early.
+     */
+    protected void mismatch(IntStream input, int ttype, BitSet follow)
+        throws RecognitionException {
+        throw new MismatchedTokenException(ttype, input);
+    }
+
+    /**
+     *  Override ANTLR's set mismatch behavior so we throw exceptions early.
+     */
+    public Object recoverFromMismatchedSet(IntStream input, RecognitionException e, BitSet follow)
+        throws RecognitionException {
+        throw e;
+    }
+
+    /**
+     *  Test a list of CharjAST nodes to see if any of them has the given token
+     *  type.
+     */
+    public boolean listContainsToken(List<CharjAST> list, int tokenType) {
+        if (list == null) return false;
+        for (CharjAST node : list) {
+            if (node.token.getType() == tokenType) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
+
+
+// Replace default ANTLR generated catch clauses with this action, allowing early failure.
+@rulecatch {
+    catch (RecognitionException re) {
+        reportError(re);
+        throw re;
+    }
+}
+
+
+// Starting point for parsing a Charj file.
+charjSource[SymbolTable symtab, OutputMode m]
+@init {
+    this.symtab_ = symtab;
+    this.translator_ = symtab.translator;
+    this.mode_ = m;
+    String closingBraces = "";
+}
+    :   ^(CHARJ_SOURCE (p=packageDeclaration)? 
+        (i+=importDeclaration)* 
+        (t=typeDeclaration))
+        {
+            // construct string of }'s to close namespace 
+            if ($p.st != null) {
+                String temp_p = $p.st.toString();
+                for (int idx=0; idx<temp_p.length(); ++idx) {
+                    if (temp_p.charAt(idx) == '{') {
+                        closingBraces += "} ";
+                    }
+                }
+            }
+        }
+        -> {emitCC()}? charjSource_cc(
+            pd={$p.st}, ids={$i}, tds={$t.st}, cb={closingBraces}, debug={debug()})
+        -> {emitCI()}? charjSource_ci(pd={$p.st}, ids={$i}, tds={$t.st}, debug={debug()})
+        -> {emitH()}? charjSource_h(
+            pd={$p.st}, ids={$i}, tds={$t.st}, cb={closingBraces}, debug={debug()})
+        ->
+    ;
+
+packageDeclaration
+@init { 
+    List<String> names = null; 
+}
+    :   ^('package' qualifiedIdentifier)  {
+            names =  java.util.Arrays.asList(
+                    $qualifiedIdentifier.text.split("[.]"));
+        }
+        -> {(emitCC() || emitH())}? packageDeclaration_cc_h(
+            ids={names})
+        ->
+    ;
+    
+importDeclaration
+@init {
+    String importID = null;
+}
+    :   ^('import' qualifiedIdentifier ds='.*'?)
+        {
+            importID = $qualifiedIdentifier.text;
+            if ($ds != null) {
+            }
+        }
+        {$ds == null}? // TODO: add support for importing x.*
+        -> {(emitCC() || emitH())}? importDeclaration_cc_h(
+            inc_id={importID.replace(".","/")},
+            use_id={importID.replace(".","::")})
+        ->
+    ;
+    
+typeDeclaration
+    :   ^('template' 'class' IDENT td=typeDeclaration)
+        -> {emitH()}? templateDeclaration_h(
+            ident={$IDENT.text},
+            class1={$td.st})
+        ->
+    |   ^('class' i1=IDENT (^('extends' su=type))? (^('implements' type+))? (csds+=classScopeDeclaration)*)
+        -> {emitCC()}? classDeclaration_cc(
+                ident={$i1.text}, 
+                ext={$su.st}, 
+                csds={$csds})
+        -> {emitH()}? classDeclaration_h(
+                ident={$i1.text}, 
+                ext={$su.st}, 
+                csds={$csds})
+        ->
+    |   ^('interface' IDENT (^('extends' type+))? interfaceScopeDeclaration*)
+        -> template(t={$text}) "/*INTERFACE-not implemented*/ <t>"
+    |   ^('enum' IDENT (^('implements' type+))? classScopeDeclaration*)
+        -> template(t={$text}) "/*ENUM-not implemented*/ <t>"
+    |   ^(chareType IDENT (^('extends' type))? (^('implements' type+))? classScopeDeclaration*)
+        -> {emitCC()}? classDeclaration_cc(
+                ident={$IDENT.text}, 
+                ext={$su.st}, 
+                csds={$csds})
+        -> {emitCI()}? charedeclaration_ci(
+                chareType={$chareType.st},
+                arrayDim={null},
+                ident={$IDENT.text}, 
+                ext={$su.st}, 
+                csds={$csds})
+        -> {emitH()}? classDeclaration_h(
+                ident={$IDENT.text}, 
+                ext={$su.st}, 
+                csds={$csds})
+        ->
+    |   ^('chare_array' ARRAY_DIMENSION IDENT (^('extends' type))? (^('implements' type+))? classScopeDeclaration*)
+        -> {emitCI()}? charedeclaration_ci(
+                chareType={"array"},
+                arrayDim={$ARRAY_DIMENSION.text.toUpperCase()},
+                ident={$IDENT.text}, 
+                ext={$su.st}, 
+                csds={$csds})
+        ->
+    ;
+
+chareType
+@init {
+$st = %{$start.getText()};
+}
+    :   'chare'
+    |   'group'
+    |   'nodegroup'
+    ;
+
+enumConstant
+    :   ^(IDENT arguments?)
+        -> template(t={$text}) "/*enumConstant-not implemented*/ <t>"
+    ;
+
+classScopeDeclaration
+@init { boolean entry = false; }
+    :   ^(FUNCTION_METHOD_DECL m=modifierList? g=genericTypeParameterList? 
+            ty=type IDENT f=formalParameterList a=arrayDeclaratorList? 
+            b=block?)
+        { 
+            if ($m.st != null) {
+                // determine whether this is an entry method
+                entry = listContainsToken($m.start.getChildren(), ENTRY);
+            }
+        }
+        -> {emitCC()}? funcMethodDecl_cc(
+                modl={$m.st}, 
+                gtpl={$g.st}, 
+                ty={$ty.text},
+                id={$IDENT.text}, 
+                fpl={$f.st}, 
+                adl={$a.st},
+                block={$b.st})
+        -> {emitH()}? funcMethodDecl_h(
+                modl={$m.st}, 
+                gtpl={$g.st}, 
+                ty={$ty.text},
+                id={$IDENT.text}, 
+                fpl={$f.st}, 
+                adl={$a.st},
+                block={$b.st})
+        -> {(emitCI() && entry)}? funcMethodDecl_ci(
+                modl={$m.st}, 
+                gtpl={$g.st}, 
+                ty={$ty.text},
+                id={$IDENT.text}, 
+                fpl={$f.st}, 
+                adl={$a.st},
+                block={$b.st})
+        ->
+    |   ^(VOID_METHOD_DECL m=modifierList? g=genericTypeParameterList? IDENT 
+            f=formalParameterList b=block?)
+        { 
+            // determine whether this is an entry method
+            if ($m.st != null) {
+                entry = listContainsToken($m.start.getChildren(), ENTRY);
+            }
+        }
+        -> {emitCC()}? voidMethodDecl_cc(
+                modl={$m.st}, 
+                gtpl={$g.st}, 
+                id={$IDENT.text}, 
+                fpl={$f.st}, 
+                block={$b.st})
+        -> {emitCI() && entry}? voidMethodDecl_ci(
+                modl={$m.st}, 
+                gtpl={$g.st}, 
+                id={$IDENT.text}, 
+                fpl={$f.st}, 
+                block={$b.st})
+        -> {emitH()}? voidMethodDecl_h(
+                modl={$m.st}, 
+                gtpl={$g.st}, 
+                id={$IDENT.text}, 
+                fpl={$f.st}, 
+                block={$b.st})
+        ->
+    |   ^(PRIMITIVE_VAR_DECLARATION modifierList? simpleType variableDeclaratorList)
+        -> {emitCC() || emitH()}? class_var_decl(
+            modl={$modifierList.st},
+            type={$simpleType.st},
+            declList={$variableDeclaratorList.st})
+        ->
+    |   ^(OBJECT_VAR_DECLARATION modifierList? objectType variableDeclaratorList)
+        -> {emitCC() || emitH()}? class_var_decl(
+            modl={$modifierList.st},
+            type={$objectType.st},
+            declList={$variableDeclaratorList.st})
+        ->
+    |   ^(CONSTRUCTOR_DECL m=modifierList? g=genericTypeParameterList? IDENT f=formalParameterList b=block)
+        { 
+            // determine whether this is an entry method
+            if ($m.st != null) {
+                entry = listContainsToken($m.start.getChildren(), ENTRY);
+            }
+        }
+        -> {emitCC()}? ctorDecl_cc(
+                modl={$m.st}, 
+                gtpl={$g.st}, 
+                id={$IDENT.text}, 
+                fpl={$f.st}, 
+                block={$b.st})
+        -> {emitCI() && entry}? ctorDecl_ci(
+                modl={$m.st}, 
+                gtpl={$g.st}, 
+                id={$IDENT.text}, 
+                fpl={$f.st}, 
+                block={$b.st})
+        -> {emitH()}? ctorDecl_h(
+                modl={$m.st}, 
+                gtpl={$g.st}, 
+                id={$IDENT.text}, 
+                fpl={$f.st}, 
+                block={$b.st})
+        ->
+    ;
+    
+interfaceScopeDeclaration
+    :   ^(FUNCTION_METHOD_DECL modifierList? genericTypeParameterList? type IDENT formalParameterList arrayDeclaratorList?)
+        -> template(t={$text}) "/*interfaceScopeDeclarations-not implemented */ <t>"
+    |   ^(VOID_METHOD_DECL modifierList? genericTypeParameterList? IDENT formalParameterList)
+        -> template(t={$text}) "/*interfaceScopeDeclarations-not implemented */ <t>"
+    |   ^(PRIMITIVE_VAR_DECLARATION modifierList? simpleType variableDeclaratorList)
+        -> template(t={$text}) "/*interfaceScopeDeclarations-not implemented */ <t>"
+    |   ^(OBJECT_VAR_DECLARATION modifierList? objectType variableDeclaratorList)
+        -> template(t={$text}) "/*interfaceScopeDeclarations-not implemented */ <t>"
+    ;
+
+variableDeclaratorList
+    :   ^(VAR_DECLARATOR_LIST (var_decls+=variableDeclarator)+)
+        -> var_decl_list(var_decls={$var_decls})
+    ;
+
+variableDeclarator
+    :   ^(VAR_DECLARATOR id=variableDeclaratorId initializer=variableInitializer?)
+        -> var_decl(id={$id.st}, initializer={$initializer.st})
+    ;
+    
+variableDeclaratorId
+    :   ^(IDENT adl=arrayDeclaratorList?)
+        -> var_decl_id(id={$IDENT.text}, arrayDeclList={$adl.st})
+    ;
+
+variableInitializer
+    :   arrayInitializer
+        -> {$arrayInitializer.st}
+    |   expression
+        -> {$expression.st}
+    ;
+
+arrayDeclaratorList
+    :   ^(ARRAY_DECLARATOR_LIST ARRAY_DECLARATOR*)  
+        -> template(t={$text}) "<t>"
+    ;
+    
+arrayInitializer
+    :   ^(ARRAY_INITIALIZER variableInitializer*)
+        -> template(t={$text}) "/* arrayInitializer-not implemented */ <t>"
+    ;
+
+genericTypeParameterList
+    :   ^(GENERIC_TYPE_PARAM_LIST genericTypeParameter+)
+        -> template(t={$text}) "/*GENERIC_TYPE_PARAM_LIST-not implemented*/ <t>"
+    ;
+
+genericTypeParameter
+    :   ^(IDENT bound?)
+        -> template(t={$text}) "/*genericTypeParameter-not implemented*/ <t>"
+    ;
+        
+bound
+    :   ^(EXTENDS_BOUND_LIST type+)
+        -> template(t={$text}) "/*EXTENDS_BOUND_LIST-not implemented*/ <t>"
+    ;
+
+throwsClause
+    :   ^(THROWS_CLAUSE qualifiedIdentifier+)
+        -> template(t={$text}) "/* throwsClause-not implemented */ <t>"
+    ;
+
+modifierList
+    :   ^(MODIFIER_LIST (m+=modifier)+)
+        -> mod_list(mods={$m})
+    ;
+
+modifier
+@init {
+$st = %{$start.getText()};
+}
+    :   'public'
+    |   'protected'
+    |   'private'
+    |   'entry'
+    |   'abstract'
+    |   'native'
+    |   localModifier
+        -> {$localModifier.st}
+    ;
+
+localModifierList
+    :   ^(LOCAL_MODIFIER_LIST (m+=localModifier)+)
+        -> local_mod_list(mods={$m})
+    ;
+
+localModifier
+@init {
+$st = %{$start.getText()};
+}
+    :   'final'
+    |   'static'
+    |   'volatile'
+    ;
+
+    
+type
+    :   simpleType
+        -> {$simpleType.st}
+    |   objectType 
+        -> {$objectType.st}
+    ;
+
+simpleType
+    :   ^(TYPE primitiveType arrayDeclaratorList?)
+        -> type(typeID={$primitiveType.st}, arrDeclList={$arrayDeclaratorList.st})
+    ;
+
+objectType
+    :   ^(TYPE qualifiedTypeIdent arrayDeclaratorList?)
+        -> type(typeID={$qualifiedTypeIdent.st}, arrDeclList={$arrayDeclaratorList.st})
+    ;
+
+qualifiedTypeIdent
+    :   ^(QUALIFIED_TYPE_IDENT (t+=typeIdent)+) 
+        -> template(types={$t}) "<types; separator=\".\">"
+    ;
+
+typeIdent
+    :   ^(IDENT genericTypeArgumentList?)
+        -> typeIdent(typeID={$IDENT.text}, generics={$genericTypeArgumentList.st})
+    ;
+
+primitiveType
+@init {
+$st = %{$start.getText()};
+}
+    :   'boolean'
+        -> template() "bool"
+    |   'char'
+    |   'byte'
+        -> template() "char"
+    |   'short'
+    |   'int'
+    |   'long'
+    |   'float'
+    |   'double'
+    ;
+
+genericTypeArgumentList
+    :   ^(GENERIC_TYPE_ARG_LIST (gta+=genericTypeArgument)+)
+        -> template(gtal={$gta}) "\<<gtal; separator=\", \">\>"
+    ;
+    
+genericTypeArgument
+    :   type
+        -> {$type.st}
+    |   '?'
+        -> template(t={$text}) "/* genericTypeArgument: wildcard bound types not implemented */ <t>"
+    ;
+
+formalParameterList
+    :   ^(FORMAL_PARAM_LIST (fpsd+=formalParameterStandardDecl)* fpvd=formalParameterVarargDecl?)
+        -> formal_param_list(sdecl={$fpsd}, vdecl={$fpvd.st})
+    ;
+    
+formalParameterStandardDecl
+    :   ^(FORMAL_PARAM_STD_DECL lms=localModifierList? t=type vdid=variableDeclaratorId)
+        -> formal_param_decl(modList={$lms.st}, type={$t.st}, declID={$vdid.st})
+    ;
+    
+formalParameterVarargDecl
+    :   ^(FORMAL_PARAM_VARARG_DECL localModifierList? type variableDeclaratorId)
+        -> template(t={$text}) "/*formal parameter varargs not implemented*/ <t>"
+    ;
+    
+qualifiedIdentifier
+    :   IDENT
+        -> template(t={$text}) "<t>"
+    |   ^('.' qualifiedIdentifier IDENT)
+        -> template(t={$text}) "<t>"
+    ;
+    
+block
+@init { boolean emptyBlock = true; }
+    :   ^(BLOCK (b+=blockStatement)*)
+        { emptyBlock = ($b == null || $b.size() == 0); }
+        -> {emitCC() && emptyBlock}? template(bsl={$b}) "{ }"
+        -> {emitCC()}? block_cc(bsl={$b})
+        ->
+    ;
+    
+blockStatement
+    :   localVariableDeclaration
+        -> {$localVariableDeclaration.st}
+    |   statement
+        -> {$statement.st}
+    ;
+
+
+localVariableDeclaration
+    :   ^(PRIMITIVE_VAR_DECLARATION localModifierList? simpleType variableDeclaratorList)
+        -> local_var_decl(
+            modList={null},
+            type={$simpleType.st},
+            declList={$variableDeclaratorList.st})
+    |   ^(OBJECT_VAR_DECLARATION localModifierList? objectType variableDeclaratorList)
+        -> local_var_decl(
+            modList={null},
+            type={$objectType.st},
+            declList={$variableDeclaratorList.st})
+    ;
+
+
+statement
+    :   block
+        -> {$block.st}
+    |   ^('assert' cond=expression msg=expression?)
+        -> assert(cond={$cond.st}, msg={$msg.st})
+    |   ^('if' parenthesizedExpression then=statement else_=statement?)
+        -> if(cond={$parenthesizedExpression.st}, then={$then.st}, else_={$else_.st})
+    |   ^('for' forInit cond=expression? (update+=expression)* s=statement)
+        -> for(initializer={$forInit.st}, cond={$cond.st}, update={$update}, body={$s.st})
+    |   ^(FOR_EACH localModifierList? type IDENT expression statement) 
+        -> template(t={$text}) "/* foreach not implemented */ <t>"
+    |   ^('while' pe=parenthesizedExpression s=statement)
+        -> while(cond={$pe.st}, body={$s.st})
+    |   ^('do' s=statement pe=parenthesizedExpression)
+        -> dowhile(cond={$pe.st}, block={$s.st})
+    |   ^('switch' pe=parenthesizedExpression (scls+=switchCaseLabel)*)
+        -> switch(expr={$pe.st}, labels={$scls})
+    |   ^('return' e=expression?)
+        -> return(val={$e.st})
+    |   ^('throw' expression)
+        -> template(t={$text}) "/* throw not implemented */ <t>"
+    |   ^('break' IDENT?)
+        -> template() "break;" // TODO: support labeling
+    |   ^('continue' IDENT?)
+        -> template() "continue;" // TODO: support labeling
+    |   ^(LABELED_STATEMENT i=IDENT s=statement)
+        -> label(text={$i.text}, stmt={$s.st})
+    |   expression
+        -> template(expr={$expression.st}) "<expr>;"
+    |   ^('embed' STRING_LITERAL EMBED_BLOCK)
+        ->  embed_cc(str={$STRING_LITERAL.text}, blk={$EMBED_BLOCK.text})
+    |   ';' // Empty statement.
+        -> {%{$start.getText()}}
+    ;
+        
+switchCaseLabel
+    :   ^('case' expression (b+=blockStatement)*)
+        -> case(expr={$expression.st}, block={$b})
+    |   ^('default' (b+=blockStatement)*)
+        -> template(block={$b}) "default: <block>"
+    ;
+    
+forInit
+    :   localVariableDeclaration
+        -> template(lvd={$localVariableDeclaration.st}) "<lvd>"
+    |   (ex+=expression)+
+        -> template(ex={$ex}) "<ex; separator=\", \">"
+    ;
+
+// EXPRESSIONS
+
+parenthesizedExpression
+    :   ^(PAREN_EXPR exp=expression)
+        -> template(expr={$exp.st}) "(<expr>)"
+    ;
+    
+expression
+    :   ^(EXPR expr)
+        -> {$expr.st}
+    ;
+
+expr
+    :   ^('=' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> = <e2>"
+    |   ^('+=' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> += <e2>"
+    |   ^('-=' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> -= <e2>"
+    |   ^('*=' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> *= <e2>"
+    |   ^('/=' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> /= <e2>"
+    |   ^('&=' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> &= <e2>"
+    |   ^('|=' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> |= <e2>"
+    |   ^('^=' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> ^= <e2>"
+    |   ^('%=' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> %= <e2>"
+    |   ^('>>>=' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \>\>\>= <e2>"
+    |   ^('>>=' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \>\>= <e2>"
+    |   ^('<<=' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \<\<= <e2>"
+    |   ^('?' e1=expr e2=expr e3=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}, e3={$e3.st}) "<e1> ? <e2> : <e3>"
+    |   ^('||' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> || <e2>"
+    |   ^('&&' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> && <e2>"
+    |   ^('|' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> | <e2>"
+    |   ^('^' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> ^ <e2>"
+    |   ^('&' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> & <e2>"
+    |   ^('==' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> == <e2>"
+    |   ^('!=' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> != <e2>"
+    |   ^('instanceof' expr type)
+        -> template(t={$text}) "/* instanceof not implemented */ <t>"
+    |   ^('<=' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \<= <e2>"
+    |   ^('>=' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \>= <e2>"
+    |   ^('>>>' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \>\>\> <e2>"
+    |   ^('>>' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \>\> <e2>"
+    |   ^('>' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \> <e2>"
+    |   ^('<<' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \<\< <e2>"
+    |   ^('<' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> \< <e2>"
+    |   ^('+' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> + <e2>"
+    |   ^('-' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> - <e2>"
+    |   ^('*' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> * <e2>"
+    |   ^('/' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> / <e2>"
+    |   ^('%' e1=expr e2=expr)
+        -> template(e1={$e1.st}, e2={$e2.st}) "<e1> % <e2>"
+    |   ^(UNARY_PLUS e1=expr)
+        -> template(e1={$e1.st}) "+<e1>"
+    |   ^(UNARY_MINUS e1=expr)
+        -> template(e1={$e1.st}) "-<e1>"
+    |   ^(PRE_INC e1=expr)
+        -> template(e1={$e1.st}) "++<e1>"
+    |   ^(PRE_DEC e1=expr)
+        -> template(e1={$e1.st}) "--<e1>"
+    |   ^(POST_INC e1=expr)
+        -> template(e1={$e1.st}) "<e1>++"
+    |   ^(POST_DEC e1=expr)
+        -> template(e1={$e1.st}) "<e1>--"
+    |   ^('~' e1=expr)
+        -> template(e1={$e1.st}) "~<e1>"
+    |   ^('!' e1=expr)
+        -> template(e1={$e1.st}) "!<e1>"
+    |   ^(CAST_EXPR ty=type e1=expr)
+        -> template(ty={$ty.st}, e1={$e1.st}) "(<ty>)<e1>"
+    |   primaryExpression
+        -> {$primaryExpression.st}
+    ;
+    
+primaryExpression
+    :   ^('.' prim=primaryExpression IDENT)
+        -> template(id={$IDENT}, prim={$prim.st}) "<prim>.<id>"
+    |   ^('.' prim=primaryExpression 'this')
+        -> template(prim={$prim.st}) "<prim>.this"
+    |   ^('.' prim=primaryExpression 'super')
+        -> template(prim={$prim.st}) "<prim>.super"
+    |   parenthesizedExpression
+        -> {$parenthesizedExpression.st}
+    |   IDENT
+        -> {%{$start.getText()}}
+    |   ^(METHOD_CALL pe=primaryExpression gtal=genericTypeArgumentList? args=arguments)
+        -> method_call(primary={$pe.st}, generic_types={$gtal.st}, args={$args.st})
+    |   explicitConstructorCall
+        -> {$explicitConstructorCall.st}
+    |   ^(ARRAY_ELEMENT_ACCESS pe=primaryExpression ex=expression)
+        -> template(pe={$pe.st}, ex={$ex.st}) "<pe>[<ex>]"
+    |   literal
+        -> {$literal.st}
+    |   newExpression
+        -> {$newExpression.st}
+    |   'this'
+        -> {%{$start.getText()}}
+    |   arrayTypeDeclarator
+        -> {$arrayTypeDeclarator.st}
+    |   'super'
+        -> {%{$start.getText()}}
+    ;
+    
+explicitConstructorCall
+    :   ^(THIS_CONSTRUCTOR_CALL genericTypeArgumentList? arguments)
+        -> template(t={$text}) "<t>"
+    |   ^(SUPER_CONSTRUCTOR_CALL primaryExpression? genericTypeArgumentList? arguments)
+        -> template(t={$text}) "<t>"
+    ;
+
+arrayTypeDeclarator
+    :   ^(ARRAY_DECLARATOR (arrayTypeDeclarator | qualifiedIdentifier | primitiveType))
+        -> template(t={$text}) "<t>"
+    ;
+
+newExpression
+    :   ^(  STATIC_ARRAY_CREATOR
+            (   primitiveType newArrayConstruction
+            |   genericTypeArgumentList? qualifiedTypeIdent newArrayConstruction
+            )
+        )
+        -> template(t={$text}) "<t>"
+    ;
+
+newArrayConstruction
+    :   arrayDeclaratorList arrayInitializer
+        -> array_construction_with_init(
+                array_decls={$arrayDeclaratorList.st},
+                initializer={$arrayInitializer.st})
+    |   (ex+=expression)+ adl=arrayDeclaratorList?
+        -> array_construction(exprs={$ex}, array_decls={$adl.st})
+    ;
+
+arguments
+    :   ^(ARGUMENT_LIST (ex+=expression)*)
+        -> arguments(exprs={$ex})
+    ;
+
+literal
+@init {
+$st = %{$start.getText()};
+}
+    :   HEX_LITERAL
+    |   OCTAL_LITERAL
+    |   DECIMAL_LITERAL
+    |   FLOATING_POINT_LITERAL
+    |   CHARACTER_LITERAL
+    |   STRING_LITERAL
+    |   'true'
+    |   'false'
+    |   'null'
+    ;
+
index d9dbe1c4108e93ffc53b88530bb9e6cfcd1dbc14..a08d0a07e8cfb17f06d42dd95bd5201c39cb73de 100644 (file)
@@ -119,8 +119,9 @@ importDeclarations returns [List<CharjAST> packageNames]
 
 typeDeclaration[List<CharjAST> imports] returns [ClassSymbol sym]
 scope ScopeStack; // top-level type scope
-    :   ^('template' 'class' i1=IDENT ^('class' i2=IDENT (^('extends' type))? (^('implements' type+))? classScopeDeclaration*))
+    :   ^('template' i1=IDENT* ^('class' i2=IDENT (^('extends' type))? (^('implements' type+))? classScopeDeclaration*))
         {
+            // JL: Need to fill the templateArgs in ClassSymbol
             Scope outerScope = $ScopeStack[-1]::current;
             $sym = new ClassSymbol(symtab, $i2.text, null, outerScope);
             outerScope.define($sym.name, $sym);
diff --git a/src/langs/charj/src/charj/translator/CharjSemantics.g~ b/src/langs/charj/src/charj/translator/CharjSemantics.g~
new file mode 100644 (file)
index 0000000..4220abe
--- /dev/null
@@ -0,0 +1,457 @@
+/**
+ * The semantic phase walks the tree and builds the symbol table, handles
+ * all the imports, and does the semantic checks. The resulting tree and
+ * symbol table are used by the emitter to generate the output. 
+ */
+
+tree grammar CharjSemantics;
+
+options {
+    backtrack = true; 
+    memoize = true;
+    tokenVocab = Charj;
+    ASTLabelType = CharjAST;
+}
+
+scope ScopeStack {
+    Scope current;
+}
+
+@header {
+package charj.translator;
+}
+
+@members {
+    SymbolTable symtab = null;
+    PackageScope currentPackage = null;
+    ClassSymbol currentClass = null;
+    MethodSymbol currentMethod = null;
+    LocalScope currentLocalScope = null;
+    Translator translator;
+
+    /**
+     *  Test a list of CharjAST nodes to see if any of them has the given token
+     *  type.
+     */
+    public boolean listContainsToken(List<CharjAST> list, int tokenType) {
+        if (list == null) return false;
+        for (CharjAST node : list) {
+            if (node.token.getType() == tokenType) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public void importPackages(ClassSymbol cs, List<CharjAST> imports) {
+        if (imports == null) {
+            return;
+        }
+
+        for (CharjAST pkg : imports) {
+            String pkgName = input.getTokenStream().toString(
+                    pkg.getTokenStartIndex(),
+                    pkg.getTokenStopIndex());
+            // find imported class and add to cs.imports
+            PackageScope p = cs.importPackage(pkgName);
+            if (p == null) {
+                translator.error(
+                    this, 
+                    "package " + pkgName + " not found.",
+                    pkg);
+            }
+        }
+    }
+}
+
+
+// Replace default ANTLR generated catch clauses with this action, allowing early failure.
+@rulecatch {
+    catch (RecognitionException re) {
+        reportError(re);
+        throw re;
+    }
+}
+
+
+// Starting point for parsing a Charj file.
+charjSource[SymbolTable _symtab] returns [ClassSymbol cs]
+scope ScopeStack; // default scope
+@init {
+    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; }
+    ;
+
+// note: no new scope here--this replaces the default scope
+packageDeclaration
+@init { 
+    List<String> names = null; 
+}
+    :   ^('package' qualifiedIdentifier)  {
+            String packageName = $qualifiedIdentifier.text;
+            PackageScope ps = symtab.resolvePackage(packageName);
+            if (ps == null) {
+                ps = symtab.definePackage(packageName);
+                symtab.addScope(ps);
+            }
+            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); })*
+    ;
+
+
+typeDeclaration[List<CharjAST> imports] returns [ClassSymbol sym]
+scope ScopeStack; // top-level type scope
+    :   ^('class' IDENT (^('extends' type))? (^('implements' type+))? classScopeDeclaration*)
+        {
+            Scope outerScope = $ScopeStack[-1]::current;
+            $sym = new ClassSymbol(symtab, $IDENT.text, null, outerScope);
+            outerScope.define($sym.name, $sym);
+            currentClass = $sym;
+            $sym.definition = $typeDeclaration.start;
+            $sym.definitionTokenStream = input.getTokenStream();
+            $IDENT.symbol = $sym;
+            $ScopeStack::current = $sym;
+            importPackages($sym, $imports);
+        }
+    |   ^('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*)
+    ;
+
+chareType
+    :   'chare'
+    |   'group'
+    |   'nodegroup'
+    ;
+
+enumConstant
+    :   ^(IDENT arguments?)
+    ;
+    
+classScopeDeclaration
+    :   ^(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)
+    |   ^(OBJECT_VAR_DECLARATION modifierList? objectType variableDeclaratorList)
+    |   ^(CONSTRUCTOR_DECL m=modifierList? g=genericTypeParameterList? IDENT f=formalParameterList 
+            b=block)
+    ;
+    
+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.
+    |   ^(PRIMITIVE_VAR_DECLARATION modifierList? simpleType variableDeclaratorList)
+    |   ^(OBJECT_VAR_DECLARATION modifierList? objectType variableDeclaratorList)
+    ;
+
+variableDeclaratorList
+    :   ^(VAR_DECLARATOR_LIST variableDeclarator+)
+    ;
+
+variableDeclarator
+    :   ^(VAR_DECLARATOR variableDeclaratorId variableInitializer?)
+    ;
+    
+variableDeclaratorId
+    :   ^(IDENT arrayDeclaratorList?)
+    ;
+
+variableInitializer
+    :   arrayInitializer
+    |   expression
+    ;
+
+arrayDeclaratorList
+    :   ^(ARRAY_DECLARATOR_LIST ARRAY_DECLARATOR*)  
+    ;
+    
+arrayInitializer
+    :   ^(ARRAY_INITIALIZER variableInitializer*)
+    ;
+
+genericTypeParameterList
+    :   ^(GENERIC_TYPE_PARAM_LIST genericTypeParameter+)
+    ;
+
+genericTypeParameter
+    :   ^(IDENT bound?)
+    ;
+        
+bound
+    :   ^(EXTENDS_BOUND_LIST type+)
+    ;
+
+modifierList
+    :   ^(MODIFIER_LIST modifier+)
+    ;
+
+modifier
+    :   'public'
+    |   'protected'
+    |   'private'
+    |   'entry'
+    |   'abstract'
+    |   'native'
+    |   localModifier
+    ;
+
+localModifierList
+    :   ^(LOCAL_MODIFIER_LIST localModifier+)
+    ;
+
+localModifier
+    :   'final'
+    |   'static'
+    |   'volatile'
+    ;
+
+type
+    :   simpleType
+    |   objectType 
+    ;
+
+simpleType
+    :   ^(TYPE primitiveType arrayDeclaratorList?)
+    ;
+    
+objectType
+    :   ^(TYPE qualifiedTypeIdent arrayDeclaratorList?)
+    ;
+
+qualifiedTypeIdent
+    :   ^(QUALIFIED_TYPE_IDENT typeIdent+) 
+    ;
+
+typeIdent
+    :   ^(IDENT genericTypeArgumentList?)
+    ;
+
+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")); }
+    ;
+
+genericTypeArgumentList
+    :   ^(GENERIC_TYPE_ARG_LIST genericTypeArgument+)
+    ;
+    
+genericTypeArgument
+    :   type
+    |   '?'
+    ;
+
+formalParameterList
+    :   ^(FORMAL_PARAM_LIST formalParameterStandardDecl* formalParameterVarargDecl?) 
+    ;
+    
+formalParameterStandardDecl
+    :   ^(FORMAL_PARAM_STD_DECL localModifierList? type variableDeclaratorId)
+    ;
+    
+formalParameterVarargDecl
+    :   ^(FORMAL_PARAM_VARARG_DECL localModifierList? type variableDeclaratorId)
+    ;
+    
+// FIXME: is this rule right? Verify that this is ok, I expected something like:
+// IDENT (^('.' qualifiedIdentifier IDENT))*
+qualifiedIdentifier
+    :   IDENT
+    |   ^('.' qualifiedIdentifier IDENT)
+    ;
+    
+block
+    :   ^(BLOCK (blockStatement)*)
+    ;
+    
+blockStatement
+    :   localVariableDeclaration
+    |   statement
+    ;
+    
+localVariableDeclaration
+    :   ^(PRIMITIVE_VAR_DECLARATION localModifierList? simpleType variableDeclaratorList)
+    |   ^(OBJECT_VAR_DECLARATION localModifierList? objectType variableDeclaratorList)
+    ;
+
+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?) {
+            if ($IDENT != null) {
+                translator.error(this, "Labeled break not supported yet, ignoring.", $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)
+    |   ';' // Empty statement.
+    ;
+        
+switchCaseLabel
+    :   ^('case' expression blockStatement*)
+    |   ^('default' blockStatement*)
+    ;
+    
+forInit
+    :   localVariableDeclaration 
+    |   expression+
+    ;
+    
+// EXPRESSIONS
+
+parenthesizedExpression
+    :   ^(PAREN_EXPR expression)
+    ;
+    
+expression
+    :   ^(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)
+    |   ^('<<=' 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)
+    |   ^('>>>' expr expr)
+    |   ^('>>' expr expr)
+    |   ^('>' expr expr)
+    |   ^('<<' expr expr)
+    |   ^('<' expr expr)
+    |   ^('+' expr expr)
+    |   ^('-' expr expr)
+    |   ^('*' expr expr)
+    |   ^('/' expr expr)
+    |   ^('%' expr expr)
+    |   ^(UNARY_PLUS expr)
+    |   ^(UNARY_MINUS expr)
+    |   ^(PRE_INC expr)
+    |   ^(PRE_DEC expr)
+    |   ^(POST_INC expr)
+    |   ^(POST_DEC expr)
+    |   ^('~' expr)
+    |   ^('!' expr)
+    |   ^(CAST_EXPR type expr)
+    |   primaryExpression
+    ;
+    
+primaryExpression
+    :   ^(  '.' primaryExpression
+                (   IDENT
+                |   'this'
+                |   'super'
+                )
+        )
+    |   parenthesizedExpression
+    |   IDENT
+    |   ^(METHOD_CALL primaryExpression genericTypeArgumentList? arguments)
+    |   explicitConstructorCall
+    |   ^(ARRAY_ELEMENT_ACCESS primaryExpression expression)
+    |   literal
+    |   newExpression
+    |   'this'
+    |   arrayTypeDeclarator
+    |   'super'
+    ;
+    
+explicitConstructorCall
+    :   ^(THIS_CONSTRUCTOR_CALL genericTypeArgumentList? arguments)
+    |   ^(SUPER_CONSTRUCTOR_CALL primaryExpression? genericTypeArgumentList? arguments)
+    ;
+
+arrayTypeDeclarator
+    :   ^(ARRAY_DECLARATOR (arrayTypeDeclarator | qualifiedIdentifier | primitiveType))
+    ;
+
+newExpression
+    :   ^(  STATIC_ARRAY_CREATOR
+            (   primitiveType newArrayConstruction
+            |   genericTypeArgumentList? qualifiedTypeIdent newArrayConstruction
+            )
+        )
+    ;
+
+newArrayConstruction
+    :   arrayDeclaratorList arrayInitializer
+    |   expression+ arrayDeclaratorList?
+    ;
+
+arguments
+    :   ^(ARGUMENT_LIST expression*)
+    ;
+
+literal 
+    :   HEX_LITERAL
+    |   OCTAL_LITERAL
+    |   DECIMAL_LITERAL
+    |   FLOATING_POINT_LITERAL
+    |   CHARACTER_LITERAL
+    |   STRING_LITERAL          
+    |   'true'
+    |   'false'
+    |   'null'
+    ;
+
diff --git a/src/langs/charj/tests/unit/Template.cj b/src/langs/charj/tests/unit/Template.cj
new file mode 100644 (file)
index 0000000..969314d
--- /dev/null
@@ -0,0 +1,4 @@
+template <class abc, class def>
+class T {
+
+}
\ No newline at end of file