Skip to content
Snippets Groups Projects
Commit 4f1d914a authored by Xun Yang's avatar Xun Yang
Browse files

Merge branch 'string_concat' into 'new-new-string'

String concat

See merge request !29
parents 4a8fb3c0 dc023159
No related branches found
No related tags found
3 merge requests!30New new string,!29String concat,!20Master
......@@ -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"):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment