コード例 #1
0
    def visitMethod_decl(self, ctx: DecafParser.Method_declContext):
        line_num = ctx.start.line
        method_name = ctx.ID(0).getText()
        method_type = ctx.return_type().getText()
        method_params = []

        for i in range(len(ctx.data_type())):
            param_type = ctx.data_type(i).getText()
            param_name = ctx.ID(i + 1).getText()
            param_symbol = VarSymbol(id=param_name, type=param_type, line=line_num, size=8, mem=STACK)
            method_params.append(param_symbol)

        method_symbol = MethodSymbol(method_name,
                                     method_type,
                                     line_num,
                                     method_params)
        self.st.addSymbol(method_symbol)

        self.body += method_name + ':\n'
        if method_name == 'main':
            self.body += 'movq %rsp, %rbp\n'

        self.st.enterScope()
        for i in range(len(method_params)):
            self.st.addSymbol(method_params[i])
            self.body += 'movq ' + param_registers[i] + ',' + str(method_params[i].getAddr()) + '(%rsp)\n'

        self.visitChildren(ctx)
        self.body += 'ret\n'
        self.st.exitScope()
コード例 #2
0
    def visitMethod_decl(self, ctx: DecafParser.Method_declContext):
        #1. get method return type
        method_type = ctx.return_type().getText()
        #2. get method name
        method_name = ctx.ID(0).getText()
        #3. get list of method parameter types and names
        param_types = []
        param_names = []
        for i in range(len(ctx.data_type())):
            param_types.append(ctx.data_type(i).getText())
            param_names.append(ctx.ID(i + 1).getText())
        #4. create a new method symbol
        method_symbol = SymbolTable.MethodSymbol(method_name, method_type,
                                                 ctx.start.line, param_types)
        #5. add method symbol to current scope
        self.st.addSymbol(method_symbol)
        #6. enter the method scope
        self.st.enterScope()
        #7. add method symbol to method scope (method names hsould exist in two scopes)

        #8. add the method parameters as individual symbols
        for i in range(len(param_types)):
            self.st.addSymbol(
                SymbolTable.VarSymbol(param_names[i], param_types[i],
                                      ctx.start.line))
        #9. visit child nodes (all sub trees and nodes)
        result = self.visitChildren(ctx)
        #10. exis the method scope (after visiting all sub-trees!)
        self.st.exitScope()
        return result
コード例 #3
0
    def visitMethod_decl(self, ctx:DecafParser.Method_declContext):
        method_name = ctx.ID(0).getText()
        return_type = ctx.TYPE(0)
        line_number = ctx.start.line

        # Checks if the method has already been declared.
        if self.st.probe(method_name) != None:
            print('[Error]: The method ' + method_name + ' on line: ' + line_number + 'was already declared!')
        else:
            self.body += method_name
            self.body += ':\n'

        params = []

        # Loops through paramaters and creates a var symbol for them and appends them to a list.
        if len(params) > 1:
            for param in range(len(ctx.ID())):
                param_name = ctx.ID(param).getText()
                params.append(param_name)
                var_symbol = self.st.probe(param_name)
                if var_symbol == None:
                    var_symbol = VarSymbol(id=param_name, type='int', line=ctx.start.line, size=8, mem=self.st.stack_pointer)
                    self.st.addSymbol(var_symbol)
                    var_addr = var_symbol.getAddr()
                    self.body += '\tmovq %rax, -' + str(var_addr[0]) + '(%rsp)\n'

            params.pop(0)

        method_symbol = MethodSymbol(id=method_name, type=return_type, line=line_number, params=params)
        self.st.addSymbol(method_symbol)

        visit = self.visitChildren(ctx)
        return visit
コード例 #4
0
 def visitMethod_decl(self, ctx: DecafParser.Method_declContext):
     method_name = ctx.ID()[0].getText()
     method_return_type = ctx.return_type().getText()
     line_num = ctx.start.line
     method_params = []
     for x in ctx.data_type():
         method_params.append(x.getText())  # get data type as a string
     method_symbol = MethodSymbol(
         id=method_name,
         type=method_return_type,
         line=line_num,
         params=method_params)  # create a method symbol with ctx values
     self.st.addSymbol(
         method_symbol
     )  # push method symbol with params list to global scope
     return self.visitChildren(ctx)
コード例 #5
0
    def visitMethod_decl(self, ctx: DecafParser.Method_declContext):
        #Makes method have its own scope
        #self.st.enterScope()
        line_num = ctx.start.line
        method_name = ctx.ID().getText()
        method_args = []

        main_check = self.st.probe('main')
        method_symbol = self.st.probe(method_name)

        if ctx.data_type() != None:
            data_type = ctx.data_type().getText()
        else:
            data_type = "void"

        if method_name == "main" and len(ctx.method_arg()) > 0:
            # 3
            print('Error on line', line_num,
                  ', method \'main\' cannot have any parameters')

        if main_check != None:
            # 3
            print('Warning detected function ' + method_name +
                  ' declared after main, this will not be executed')

        # Adds space to method arguments
        for m in ctx.method_arg():
            method_args.append(m.data_type().getText() + ' ' +
                               m.ID().getText())
            # var_symbol = VarSymbol(id=m.ID().getText(),
            #                          type=m.data_type().getText(),
            #                          line=line_num,
            #                          size=8,
            #                          mem=STACK)
            #
            # self.st.addSymbol(var_symbol)

        method_symbol = MethodSymbol(id=method_name,
                                     type=data_type,
                                     line=line_num,
                                     params=method_args)

        self.st.addSymbol(method_symbol)

        self.visitChildren(ctx)

        statements = ctx.block().statement()

        # 7 and 8
        for s in statements:
            var_type = self.visit(s.expr(0))
            #print(ctx.data_literal().bool_literal())

            if s.RETURN() != None:
                if ctx.VOID() != None:
                    print('Error on line ' + str(line_num) +
                          ', method should not have a return statement')
コード例 #6
0
ファイル: decaf-codegen.py プロジェクト: cole-mansfield/Decaf
    def visitMethod_decl(self, ctx:DecafParser.Method_declContext):
        data_type = ""
        line_num = ctx.start.line
        method_name = ctx.ID().getText()
        method_args = ctx.method_arg()
        method_params = []
        
        if ctx.data_type() != None:
            data_type = ctx.data_type().getText()
        else:
            data_type = "void"

        for i in method_args:
            arg_type = i.data_type().getText()
            method_arg = VarSymbol(id=i.ID().getText(), type=arg_type, line=line_num, size=8, mem=STACK)
            method_params.append(method_arg)

        method_symbol = MethodSymbol(id=method_name,
                                         type=data_type,
                                         line=line_num,
                                         params=method_params)
        
        self.body += method_name + ':\n'
        
        if method_name == 'main':
            self.body += 'movq %rsp, %rbp\n'
            
        self.st.enterScope()
        for i in range(len(method_params)):
            self.st.addSymbol(method_params[i])
            #Saving each method parameter onto a location on the stack(Memory)
            self.body += 'movq ' + param_registers[i] + ',' + str(method_params[i].getAddr()) + '(%rsp)\n'
        
        self.visitChildren(ctx)
        self.body += 'ret\n'
        self.st.exitScope()
コード例 #7
0
    def visitMethod_decl(self, ctx: DecafParser.Method_declContext):       
        # add the method_decl params to the symbol table one by one
        i = 1
        paramvalues = []
        if ctx.ID() and ctx.data_type(1):
            while i < len(ctx.ID()):  
                val = ctx.ID(i).getText()
                t = ctx.data_type(1).getText()
                i += 1     
                paramvalues.append(val)
                
                var_symbol = SymbolTable.VarSymbol(
                id=val,
                type=t,
                line=ctx.start.line,
                size=8,
                mem=SymbolTable.STACK
            )
            self.st.addSymbol(var_symbol)             
        
        if ctx.ID() and ctx.data_type():
            #add the method_decl and its type to the symbol table, with also the list of params 
            return_type = ctx.data_type(0).getText()
            method_name = ctx.ID(0).getText()
            line_number = ctx.start.line
                
            #sets values to be inserted into the symbol table
            method_symbol = SymbolTable.MethodSymbol(
                id=method_name,
                type=return_type,
                line=line_number,
                params = paramvalues
            )
            
            #add var symbol to the stack, you need to add method symbol to global scope and method symbol include param types, enter new scope,    
            #then loop through the param list and add to stack so theyre added to the symbol table

            #adds the above method to the symbol table for later use!            
            self.st.addSymbol(method_symbol)  
     
            #Rule 3 check if main has params, which it should not, we also check that method currently being checked is main, otherwise they are allowed to have params
            if len(self.st.lookup(method_name).params) > 0 and method_name == 'main':
                print("[Rule 3] error found parameters in main declaration on line", ctx.start.line)
        # enter the scope for the method scope
        self.st.enterScope()          
        #add params to table one by one
        self.visitChildren(ctx)

        #Rule 7 void method check if contains return in body! as the method we're checking should not have a return since it is VOID
        if ctx.VOID():
            if ctx.block().getText().find('return') != -1:
                print('[Rule 7] found void method, but return found on line', ctx.start.line , 'for method:', method_name)
                #catch the method_name if this method is type void
                self.voidMethods.append(method_name)
      
        self.st.exitScope()
コード例 #8
0
    def visitMethod_decl(self, ctx: DecafParser.Method_declContext):

        self.params
        param_types = []
        ctx.method_param_type()
        #line used for debugging
        #print(ctx.method_param_type(0).getText())
        method_name = ctx.id(0).getText()
        return_type = ctx.method_type().getText()
        line_number = ctx.start.line

        for i in range(len(ctx.method_param_type())):
            param_types.append(ctx.method_param_type(i).getText())

        for i in range(len(ctx.method_Param_names())):
            self.params.append(ctx.method_Param_names(i).getText())

        #line used for debugging
        #print(ctx.method_Param_names(0).getText())

        for i in range(len(param_types)):
            if self.params == []:
                method_params = VarSymbol(id=self.params[i],
                                          type=param_types[i],
                                          line=line_number,
                                          size=8,
                                          mem=SymbolTable.STACK)
                self.st.addSymbol(method_params)
            else:
                method_params = VarSymbol(id=self.params[i],
                                          type=param_types[i],
                                          line=line_number,
                                          size=8,
                                          mem=SymbolTable.STACK)
                self.st.addSymbol(method_params)

                method_symbol = MethodSymbol(id=method_name,
                                             type=return_type,
                                             line=line_number,
                                             params=ctx.method_Param_names())
                self.st.addSymbol(method_symbol)
        if self.st.lookup(method_name) != None:
            for i in range(len(self.st.lookup(method_name).params)):

                method_params = VarSymbol(
                    id=ctx.method_Param_names(i).getText(),
                    type=ctx.method_param_type(i).getText(),
                    line=line_number,
                    size=8,
                    mem=SymbolTable.STACK)
                self.st.addSymbol(method_params)
        """don't add main to code more than once"""
        if "main" in method_name:
            pass
        else:
            self.body += method_name + ":" + "\n"
        """get the statment in the return statment"""
        returnStatment = ctx.block().statement()
        if returnStatment != None:
            for item in returnStatment:
                if "if" in item.getText():
                    pass
                elif "return" in item.getText():
                    if self.st.lookup(item.expr(0)) == None:
                        """if return of method is void then throw and error"""
                        if return_type == "void":
                            print("method on line:", line_number,
                                  "should not return anything")
                        elif return_type == "int":
                            """try to int the expr, if that fails throw an error"""
                            try:
                                int(item.expr(0).getText())
                            except:
                                print(
                                    "ERROR: wrong return type found for method on line:",
                                    line_number)
                        elif self.st.lookup(
                                item.expr(0).getText()).type != return_type:
                            print(
                                "ERROR: type of retrun statement does not match method return type, line number:",
                                line_number)
                        else:
                            Addr = self.st.lookup(
                                item.expr(0).getText()).getAddr()

                            self.st.stack_pointer[-1] += 8
                            self.body += 'movq %rax, ' + str(
                                -self.st.stack_pointer[-1]) + '(%rsp)\n'

                            self.body += "movq " + str(
                                Addr) + " (%rbp), " + " %rax" + "\n" ""

        if return_type == "int" and returnStatment == []:
            print("ERROR: method missing return statement", line_number)
        if return_type == "boolean" and returnStatment == []:
            print("ERROR: method missing return statement", line_number)
        return self.visitChildren(ctx)