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 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 defintion_parameter(self, ctx):
     """
     Name: defintion_parameter
     Description: Generates quadruples for parameters of a function with its default value.
     Parameters:
         ctx: Holds the context of the definition_function rule.
     Returns: NA
     Important methods where its called:
         get_parameters_data: To access information about a parameter.
     """
     variable_name = self.identification(ctx.identification())
     literal = self.extended_literal(ctx.extended_literal())
     new_dir = gl.get_last_data()
     gl.add_memory(None)
     if literal.type == 'LIST':
         new_dir = gl.get_last_data()
         literal.constant_direction = memory.get_last_constant()
         memory.add_constant(new_dir, 'NUMBER')
         (size, _, _) = literal.array_info
         for _ in range(0, size):
             gl.add_memory(None)
     else:
         memory.add_assign(literal.virtual_direction, new_dir)
     return (variable_name, literal, new_dir)
def create_variable(variable_name, literal):
    """
    Name: create_variable
    Description: Creates a variable in the current scope.
    Parameters:
        variable_name: The name of the variable to create.
        literal: The information of the content of the variable.
    Returns: NA
    Important methods where its called:
        definition_variable: To define an array or variable.
    """
    check_variable_type(variable_name, literal)
    variable = gl.get_variable(variable_name)
    if not variable:
        # Add variable if not already declared.
        new_dir = gl.get_last_data()
        if literal.type == 'LIST':
            (size, _, _) = literal.array_info
            literal.virtual_direction = new_dir
            literal.name = variable_name
            literal.constant_direction = memory.get_last_constant()
            memory.add_constant(new_dir, 'NUMBER')
            new_variable = literal
            for _ in range(0, size):
                gl.add_memory(None)
        else:
            gl.add_memory(None)
            new_variable = Variable(variable_name, literal.type, new_dir)
        gl.add_variable(variable_name, new_variable)
        variable = gl.get_variable(variable_name)
    else:
        if literal.type == 'LIST':
            new_dir = gl.get_last_data()
            (size, _, _) = literal.array_info
            literal.virtual_direction = new_dir
            literal.name = variable_name
            literal.constant_direction = memory.get_last_constant()
            memory.add_constant(new_dir, 'NUMBER')
            new_variable = literal
            for _ in range(0, size):
                gl.add_memory(None)
            gl.add_variable(variable_name, new_variable)
            variable = gl.get_variable(variable_name)
    if literal.type != 'LIST':
        memory.add_assign(literal.virtual_direction,
                          variable.virtual_direction)
 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) + ')')