From a3e28c60b97fd96182727715ba15ed0cc713597a Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Sat, 3 Dec 2011 16:49:16 +0000 Subject: Correct array initialization, add testcase --- pp2cc.py | 48 +++++++++++++++--------------------------------- 1 file changed, 15 insertions(+), 33 deletions(-) (limited to 'pp2cc.py') diff --git a/pp2cc.py b/pp2cc.py index 9420de3..27c0fa1 100755 --- a/pp2cc.py +++ b/pp2cc.py @@ -955,9 +955,12 @@ class Parse(object): linked_node=linked_node) return lines def parseDecl(self, linked_node): + """Parses declarations in the global context and for local variables + (not params) + """ lines = [] in_function = linked_node.getFunctionNode() is not None - size = 0 + size = 1 linked_type = LinkedNode(linked_node.node.type, linked_node) name = linked_node.node.name if linked_type.type == "ArrayDecl": @@ -997,10 +1000,6 @@ class Parse(object): self.logger.error("Unknown declaration type '{}'".format(linked_type.type), linked_node=linked_node) - # increment size here because the array dimension calculation does not - # take the pointer into account - size += 1 - try: # global variables may be declared multiple times, local variables # are not allowed for that @@ -1012,17 +1011,6 @@ class Parse(object): except RuntimeError as errmsg: self.logger.error(errmsg, linked_node=linked_node) - # initialize pointer address of array - if linked_type.type == "ArrayDecl" and not in_function: - reg_array = self.registers.next_free() - # store the address of the first array element in the pointer - self.globalInit.append(self.asm.binary_op("LOAD", reg_array, var_reg)) - # in this particular case, it happens that the array values are - # next to the pointer to the array - self.globalInit.append(self.asm.binary_op("ADD", reg_array, 1)) - # store address of the first array element in the array pointer - self.globalInit.append(self.asm.binary_op("STOR", reg_array, "[" + - var_reg + "+" + var_disp + "]")) # if the declaration also has a definition if linked_node.node.init: # global variables needs to be marked as defined @@ -1036,7 +1024,7 @@ class Parse(object): if (linked_type.type == "ArrayDecl" and linked_init.type == "ExprList"): # next available register for storing the value - reg_value = self.registers.next_free(reg_array) + reg_value = self.registers.next_free() array_index = 0 for array_elm in linked_init.node.exprs: linked_arrelm = LinkedNode(array_elm, linked_init) @@ -1047,37 +1035,31 @@ class Parse(object): lines.append(self.asm.binary_op("LOAD", reg_value, init_val)) else: - # +1 because the first element is reserved for pointer - self.varNames[var_disp][array_index + 1] = init_val + self.varNames[var_disp][array_index] = init_val except RuntimeError as errmsg: # only functions are allowed to have non-constant # expressions if not in_function: self.logger.error(errmsg, linked_node=linked_arrelm) - lines.append(self.asm.push(reg_array)) init_val = self.parseExpression(array_elm, linked_init) # if the result register has changed, update - res_reg = self.registers.find_register(init_val, fatal=True) + reg_value = self.registers.find_register(init_val, fatal=True) lines += init_val - # swap registers if the result would be overwritten - if res_reg == reg_array: - reg_value, reg_array = reg_array, res_value - lines.append(self.asm.pull(reg_array)) - - # store the array element in the array instead of the - # pointer itself - lines.append(self.asm.binary_op("LOAD", reg_value, - init_val)) if in_function: - # save the value to the array's base address + index + assert var_reg == self.registers.BP, ("Expected an" + " array definition in a local variable") + # an array element at index array_index of variable at + # var_disp, relative to the BP. Remember that a local + # variable can be accessed with [BP-i] + rel_addr = int(var_disp) - array_index lines.append(self.asm.binary_op("STOR", reg_value, - "[" + reg_array + "+" + str(array_index) + "]")) + "[" + var_reg + "+" + str(rel_addr) + "]")) array_index += 1 # ignore elements which do not fit in the allocated space - if array_index > size: + if array_index >= size: break else: result_reg = self.registers.next_free() -- cgit v1.2.1