def visitMethod_call(self, ctx: DecafParser.Method_callContext): if ctx.method_name(): for i in range(len(ctx.expr())): self.visit(ctx.expr(i)) self.st.stack_pointer[-1] += 8 self.body += 'movq %rax, ' + str(-self.st.stack_pointer[-1]) + '(%rsp)\n' for i in range(len(ctx.expr())): self.body += 'movq ' + str(-self.st.stack_pointer[-1]) + '(%rsp), ' + param_registers[ len(ctx.expr()) - i - 1] + '\n' self.st.stack_pointer[-1] -= 8 # adjust stack to 16-byte alignment (multiple of 8 that is not divisible by 16) stack_len = self.st.stack_pointer[-1] stack_len = stack_len + (stack_len // 8 + 1 % 2) * 8 self.body += 'subq $' + str(stack_len) + ', %rsp\n' method_name = ctx.method_name().getText() self.body += 'call ' + method_name + '\n' self.body += 'addq $' + str(stack_len) + ', %rsp\n' elif ctx.CALLOUT(): for i in range(len(ctx.callout_arg())): if ctx.callout_arg(i).STRING_LITERAL(): callout_arg = ctx.callout_arg(i).getText() label = 'str' + str(ctx.callout_arg(i).start.start) self.head += label + ': .asciz ' + callout_arg + '\n' self.st.stack_pointer[-1] += 8 self.body += 'movq $' + label + ', ' + str(-self.st.stack_pointer[-1]) + '(%rsp)\n' else: pass
def visitMethod_call(self, ctx:DecafParser.Method_callContext): if ctx.method_name(): for i in range(len(ctx.expr())): self.visit(ctx.expr(i)) self.st.stack_pointer[-1] += 8 ptr = self.st.stack_pointer[-1] self.body += 'movq %rax, ' + str(ptr) + '(%rsp)\n' for z in range(len(ctx.expr())): ptr = self.st.stack_pointer[-1] reg = param_registers[z] self.body += 'movq ' + str(ptr) + '(% rsp), ' + reg + '\n' self.st.stack_pointer[-1] -= 8 #Current pos stored in symbol table #Needs to be 16 byte aligned or we get segmentation errors stack_len = self.st.stack_pointer[-1] stack_len = stack_len + (int(stack_len/8+1) % 2) * 8 self.body += 'subq $' + str(stack_len) + ', %rsp\n' method_name = ctx.method_name().getText() self.body += 'call ' + method_name + '\n' self.body += 'addq $' + str(stack_len) + ', %rsp\n' elif ctx.CALLOUT(): pass else: self.visitChildren(ctx)
def visitMethod_call(self, ctx: DecafParser.Method_callContext): #Rule 5 find out the count of params currently found for a method_call and check if they match the len which is in the symbol table for this method if ctx.method_name() != None and ctx.expr() != None: id = ctx.method_name().getText() if self.st.lookup(id) == None or len(ctx.expr()) < len(self.st.lookup(id).params) or len(ctx.expr()) > len(self.st.lookup(id).params): count = 0 if self.st.lookup(id) != None: count = len(self.st.lookup(id).params) print('[Rule 5] error param length do not match expected for method_call', id,'lookup param count is:', count ,'found params in call_method:', len(ctx.expr())) return self.visitChildren(ctx)
def visitMethod_call(self, ctx: DecafParser.Method_callContext): line_num = ctx.start.line method_name = ctx.method_name() method_symbol = self.st.probe(method_name.getText()) # 6 # Check method is of type bool or int if method_symbol != None and method_symbol.type == 'void': # 6 print('Error on line ' + str(line_num) + ' method \'' + method_name.getText() + '\' must return a value') # 5 if method_symbol != None: # Check correct number of args if len(method_symbol.params) != len(ctx.expr()): print('Error on line ' + str(line_num) + ' method ' + method_name.getText() + ' needs ' + str(len(method_symbol.params)) + ' arguments has ' + str(len(ctx.expr()))) else: #Check correct types of args for i in range(len(method_symbol.params)): param_type = method_symbol.params[i].split(' ')[0] if (param_type == 'int' and ctx.expr(i).data_literal().int_literal() == None) or (param_type == 'boolean' and ctx.expr( i).data_literal().bool_literal() == None): print('Error on line ' + str(line_num) + ' type mismatch on method \'' + method_name.getText() + '\' parameters') self.visitChildren(ctx)
def visitMethod_call(self, ctx:DecafParser.Method_callContext): method_name = ctx.method_name() method_symbol = self.st.lookup(method_name) if not ctx.callout_arg(): if method_symbol == None: print('[Error]: Call to a function that does not exist: ' + str(method_name) + ' on line: ' + str(ctx.start.line)) else: self.body += '\tjmp '+method_name+'\n' visit = self.visitChildren(ctx) return visit
def visitMethod_call(self, ctx: DecafParser.Method_callContext): # get method call line_num = ctx.start.line method_name = ctx.method_name().getText() # lookup method call name in symbol table method_symbol = self.st.lookup(method_name) method_symbol_params = method_symbol.params if len(ctx.expr()) != len(method_symbol_params): return print( "Error you passed an incorrect combination of parameters", "on line", line_num, ", the number and types of arguments in a method call must be the same as the number and types of the formals" ) else: for i in range(max(len(method_symbol_params), len(ctx.expr()))): # check out of bound index if i >= len(method_symbol_params): print( "Error you passed an unexpected parameter", ctx.expr()[i].literal().getText(), "on line", line_num, ", the number and types of arguments in a method call must be the same as the number and types of the formals" ) else: if method_symbol_params[i] == 'int': if ctx.expr()[i].literal().int_literal() == None: print( "Error incorrect parameter data type expected", method_symbol.type, "received value", ctx.expr()[i].literal().getText(), "on line", line_num, ", the number and types of arguments in a method call must be the same as the number and types of the formals" ) elif method_symbol_params[i] == 'boolean': if ctx.expr()[i].literal().bool_literal() == None: print( "Error incorrect parameter date type expected", method_symbol.type, "received", ctx.expr()[i].literal(), "on line", line_num, ", the number and types of arguments in a method call must be the same as the number and types of the formals" ) else: print( "missing method_symbol_params with data type classification:", method_symbol_params[i], " on line number", line_num, ", the number and types of arguments in a method call must be the same as the number and types of the formals" ) return self.visitChildren(ctx)