diff --git a/ExprPrimaryNodes.py b/ExprPrimaryNodes.py index ab85e8ec09e68f2bc65715fd07c5a0824d77d695..3fa30e00ba8a56132a6a602a21866fc79eaca7ca 100644 --- a/ExprPrimaryNodes.py +++ b/ExprPrimaryNodes.py @@ -366,21 +366,30 @@ class AssignNode(ASTNode): # cast: castExpr LPAREN castType RPAREN unaryNotPlusMinus class CastNode(ASTNode): # always list all fields in the init method to show the class structure - def __init__(self, parseTree, typeName): + def __init__(self, parseTree, typeName, left = None, right = None): self.parseTree = parseTree - self.left = parseTree.children[1] # cast: (left)right - self.right = makeNodeFromExpr(parseTree.children[3], typeName) # expr self.env = None self.children = [] self.typeName = typeName # the type (class/interface) this node belongs under - if self.left.name == 'expr': - self.left = makeNodeFromExpr(self.left, typeName) - else: #primitiveType or ArrayType - self.left = TypeNode(self.left, typeName) - # since a type might be mis-parsed as a name - if self.left.__class__.__name__ == 'NameNode': - self.left = TypeNode(self.parseTree.children[1], typeName) + if left is None or right is None: + self.left = parseTree.children[1] # cast: (left)right + self.right = makeNodeFromExpr(parseTree.children[3], typeName) # expr + + if self.left.name == 'expr': + self.left = makeNodeFromExpr(self.left, typeName) + else: #primitiveType or ArrayType + self.left = TypeNode(self.left, typeName) + # since a type might be mis-parsed as a name + if self.left.__class__.__name__ == 'NameNode': + self.left = TypeNode(self.parseTree.children[1], typeName) + + else: + # manually induce left and right + # for converting string concatenation to a method call + # see ExprPrimaryNodes:ExprNode on string concat + self.left = left + self.right = right self.children.append(self.left) self.children.append(self.right) @@ -622,23 +631,42 @@ class ExprNode(ASTNode): valueOfNameNode = NameNode(self.parseTree, True, self.typeName, "String.valueOf") valueOfNameNode.env = self.env + # store these as they could change in step 2 + leftValueOf = self.left + rightValueOf = self.right + + # 2. cast to Object if it is not safe to call String.valueOf + safeTypes = ['java.lang.String', 'char', 'int', 'short', 'byte', 'boolean', 'java.lang.Object', 'String'] + + if self.left.myType.name not in safeTypes or self.right.myType.name not in safeTypes: + + # CastNode + # - left = TypeNode + # - myType = TypeStruct + # - name = 'java.lang.Object' + # - typePointer = call link() ! + # - right = value of thing being casted + + # create object TypeNode + objectCastType = TypeNode('VOID', self.typeName) + objectCastType.myType = TypeStruct('java.lang.Object', None) + objectCastType.myType.link(self.env) + + if self.left.myType.name not in safeTypes: + leftValueOf = CastNode(self.parseTree, self.typeName, objectCastType, self.left) + + if self.right.myType.name not in safeTypes: + rightValueOf = CastNode(self.parseTree, self.typeName, objectCastType, self.right) + + # 3. call String.valueOf on the variable that needs to be converted if self.left.myType.name != 'java.lang.String': - # 2. Make ArgsNode - leftArg = ArgsNode(self.parseTree, self.typeName, [self.left]) - # 3. Put it all together + leftArg = ArgsNode(self.parseTree, self.typeName, [leftValueOf]) concatLeft = MethodInvNode(self.parseTree, self.typeName, valueOfNameNode, leftArg) if self.right.myType.name != 'java.lang.String': - # 2. Make ArgsNode - rightArg = ArgsNode(self.parseTree, self.typeName, [self.right]) - # 3. Put it all together + rightArg = ArgsNode(self.parseTree, self.typeName, [rightValueOf]) concatRight = MethodInvNode(self.parseTree, self.typeName, valueOfNameNode, rightArg) - # 4. Check type to be safe - # concatLeft.checkType() - # concatRight.checkType() - - # methodInvoc primary PERIOD ID LPAREN args RPAREN # MethodInvNode # primary = self.left @@ -732,8 +760,10 @@ class ExprNode(ASTNode): self.code += self.left.code if self.op == '&&': + # if left result == false, break out self.code += p("cmp", "eax", "0") elif self.op == '||': + # if left result == true, break out self.code += p("cmp", "eax", "1") self.code += p("je", endLabel, "", " breaking out of " + self.op) @@ -758,7 +788,7 @@ class ExprNode(ASTNode): self.code += p(endLabel + ":", "") return - # String Add TODO + # String Add if (self.left.myType.name =='java.lang.String' or self.right.myType.name =='java.lang.String') and self.op == '+': # ( String.valueOf(right) ).concat( left ) if not hasattr(self.concatMethodInv, "code"):