def do_function_execution(self, ctx): """ Name: do_function_execution Description: Generates quadruples for user defined function calls. Parameters: ctx: Holds the context of the execution_function_name rule. Returns: The name of the function and its returned direction. Important methods where its called: execution_function_name: To execute a user definied function. """ (function_name, grps) = get_execution_data(self, ctx) func = gl.functions[function_name] (new_function_name, groups) = prepare_arguments(self, grps, function_name) memory.add_quadruple(Operator.ERA, func.virtual_directon, None, None) parameters = gl.functions[function_name].parameters for group in groups: for key, parameter in parameters.items(): if parameter.pos == group.pos and parameter.param == group.param: if parameter.type == 'LIST': (_, _, size_dir) = parameter.array_info memory.add_quadruple(Operator.PARAMARR, group.virtual_direction, size_dir, parameter.virtual_direction) else: memory.add_quadruple(Operator.PARAM, group.virtual_direction, None, parameter.virtual_direction) memory.add_quadruple(Operator.GOSUB, func.code_direction, None, None) new_dir = gl.get_last_data() gl.add_memory(None) memory.add_quadruple(Operator.ASSIGN, func.return_direction, None, new_dir) return (new_function_name, new_dir)
def create_function(self, ctx, function_name, parameters, initial_virtual_direction, literal, return_direction): """ Name: create_function Description: Creates the information for the function with its corresponding quadruples. Parameters: ctx: Holds the context of the definition_function rule. function_name: The name of the function to create. parameters: The information of the parameters of the function. initial_virtual_direction: The virtual direction to access after Start Proc. literal: Information about the return literal. return_direction: The global direction used for the return. Returns: NA Important methods where its called: definition_function: To create the quadruples of the function. """ # Ensure the new function is not already defined check_defined_function(function_name) code_virtual_direction = memory.get_last_code() + 1 # Add the function to the functions table gl.functions[function_name] = Function(function_name, literal.type, {}, parameters, False, initial_virtual_direction, code_virtual_direction, return_direction, literal.array_info) memory.add_quadruple(Operator.PARAMEND, None, None, None) self.function(ctx.function()) gl.current_scope = global_function memory.add_quadruple(Operator.ENDPROC, None, None, None) memory.local_segment.clear()
def definition_function(self, ctx): """ Name: definition_function Description: Compiles the definition of a user defined function. Parameters: ctx: Holds the context of the definition rule. Returns: NA Important methods where its called: definition: To define a new user defined function. """ memory.add_quadruple(Operator.STARTPROC, None, None, None) initial_virtual_direction = memory.get_last_code() literal = self.extended_literal(ctx.extended_literal()) return_direction = memory.get_last_global() if literal.type == 'LIST': (size, _, _) = literal.array_info literal.virtual_direction = return_direction literal.constant_direction = memory.get_last_constant() memory.add_constant(return_direction, 'NUMBER') for _ in range(0, size): gl.add_memory(None) else: memory.global_data.append(None) memory.add_quadruple(Operator.ASSIGN, literal.virtual_direction, None, return_direction) (function_name, parameters) = self.definition_function_name( ctx.definition_function_name()) # Change scope inside of the new function gl.current_scope = function_name parameters = definition_function_parameters(self, ctx, parameters) create_function(self, ctx, function_name, parameters, initial_virtual_direction, literal, return_direction)
def enterProgram(self, ctx): """ Name: enterProgram Description: Walks through the generated tree strcuture from the first rule until the last one. Parameters: ctx: Holds the context of the root node. Returns: NA Important methods where its called: NA """ self.function_code(ctx.function_code()) memory.add_quadruple(Operator.EOF, None, None, None)
def return_statement(self, ctx): """ Name: return_statement Description: Compiles the return statement. Parameters: ctx: Holds the context of the return_statement rule. Returns: NA Important methods where its called: instruction: To execute a return statement for the current scope. """ return_literal = self.basic_literal(ctx.basic_literal()) current_function = gl.get_current_function() memory.add_quadruple(Operator.RETURN, return_literal.virtual_direction, None, current_function.return_direction) check_return_type(current_function, return_literal)
def array_access(self, ctx): """ Name: array_access Description: Compiles an access to an array/matrix. Parameters: ctx: Holds the context of the array_access rule. Returns: Name of the array and its virtual direction in memory. Important methods where its called: create_literal: For the definition of literals. definition: To assign a value in the array index. """ variable_name = self.identification(ctx.identification()) items = self.array_access2(ctx.array_access2()) check_variable_exits(variable_name) variable = gl.get_variable(variable_name) registry = None if variable != None: (size, i, _) = variable.array_info if len(items) > len(i): raise ValueError("The dimensions of array '" + variable_name + "' do not match.") previous_aux = None current_aux = None for (index, x) in enumerate(i): dir = items[index].virtual_direction current_aux = dir memory.add_quadruple(Operator.VER, dir, 0, x["size"] - 1) if index < len(i) - 1: current_aux = gl.get_last_data() memory.add_quadruple(Operator.MULTIPLY, dir, x["m"], current_aux) gl.add_memory(None) if index >= 1: memory.add_quadruple(Operator.SUM, previous_aux, current_aux, gl.get_last_data()) current_aux = gl.get_last_data() gl.add_memory(None) previous_aux = current_aux memory.add_quadruple(Operator.SUM, current_aux, variable.constant_direction, gl.get_last_data()) registry = gl.get_last_data() gl.add_memory(None) return (variable_name, '(' + str(registry) + ')')