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)
Exemple #2
0
    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)
Exemple #5
0
    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)
    def visitMethod_call(self, ctx: DecafParser.Method_callContext):

        line_number = ctx.start.line
        param_names = ctx.expr()
        if "callout" in ctx.getText():
            callout_argument = ctx.callout_arg(0).getText()
            print(callout_argument)
            self.body += 'mov	edx, len \n'  #message length
            self.body += 'mov	ecx, msg \n'  #message to to be written
            self.body += 'mov	ebx, 1 \n'  #file descriptor
            self.body += 'mov	eax, 4 \n'  #system call number (system write)
            self.body += 'int	0x80 \n'  #call the kernel
            self.body += 'mov	eax, 1 \n'  #system call number (system exit)
            self.body += 'int	0x80 \n'  #call kernel again
            self.body += 'section .data \n'

            self.body += 'msg  db ' + callout_argument + ', 0x0' + '\n'  #string to be printed
            self.body += 'len equ $-msg \n'  #ength of string

        else:
            method_params = self.st.lookup(ctx.id().getText()).params
            """
            if the length of the paramertor lists in the method call and 
            the original method decal are not the same throw an error
            """
            if len(method_params) != len(param_names):
                print("ERROR: " + "method " + ctx.id().getText() + " epecting",
                      len(method_params), "input params but got",
                      len(param_names), "on line", line_number)
            else:
                for i in range(len(param_names)):
                    """
                    if any of the method params in the 
                    original method decal is a boolean
                    check if the types of the oringal params 
                    and the types of the called params match
                    """
                    if self.st.lookup(
                            method_params[i].getText()).type == "boolean":
                        for i in range(len(ctx.expr())):
                            if self.st.lookup(
                                    param_names[i].getText()) != None:
                                if self.st.lookup(param_names[i].getText(
                                )).type != self.st.lookup(
                                        method_params[i].getText()).type:
                                    print(
                                        "ERROR: wrong paramertor type found for method call on line:",
                                        line_number)
                        try:
                            int(param_names[i].getText())
                            print(
                                "ERROR: parametor type cannot be boolean for method call",
                                "int", "on line:", line_number)
                        except:
                            pass
        """
        check if a varible inside of method call exists
        """
        if param_names != None:
            for name in param_names:
                if name.literal() == None:
                    pass
                else:
                    if name.literal().bool_literal() or name.literal(
                    ).int_litereal():
                        pass
                    else:
                        self.params.append(name.getText())
                        var_symbol = self.st.lookup(name.getText())
                        if var_symbol != None:
                            pass
                        else:
                            print(
                                "ERROR:",
                                "varible referanced but never assinged " +
                                " '" + name.getText() + "' " + "on line",
                                line_number)
        return self.params
        # Visit a parse tree produced by DecafParser#block."""
        return self.visitChildren(ctx)