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
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()