def p_srf_action(p): '''srf_action : ''' my_program.return_flag = True # Gets the return operand and the function been called operand = my_program.operand_stack.pop() operand_type = my_program.type_stack.pop() function = my_program.function_directory.get_function( my_program.current_scope) function_type = function['return_type'] function_return_address = function['return_address'] # Checks if the types match if function_type != operand_type: print("Return type of function {0} doesn't match function return type". format(my_program.current_scope)) sys.exit() # Creates the returns quadruples and sets the adress they will return quadruple = Quadruple(my_program.quadruple_number, 'RETURN', operand, None, function_return_address) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1 # Creates the GOTO quadruple and stores them in a stack for multiple returns quadruple = Quadruple(my_program.quadruple_number, 'GOTO', None, None, None) my_program.return_list.append(my_program.quadruple_number) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1
def p_pfc_end_fill(p): '''pfc_end_fill : ''' # Creates the END_FILL quadruple quadruple = Quadruple(my_program.quadruple_number, 'END_FILL', None, None, None) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1
def p_pfc_begin_fill(p): '''pfc_begin_fill : ''' # Creates the BEGIN_FILL quadruple quadruple = Quadruple(my_program.quadruple_number, 'BEGIN_FILL', None, None, None) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1
def p_pfc_pen_down(p): '''pfc_pen_down : ''' # Creates the PEN_DOWN quadruple quadruple = Quadruple(my_program.quadruple_number, 'PEN_DOWN', None, None, None) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1
def p_pfc_pen_up(p): '''pfc_pen_up : ''' # Creates the PEN_UP quadruple quadruple = Quadruple(my_program.quadruple_number, 'PEN_UP', None, None, None) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1
def p_pfc_create_turtle(p): '''pfc_create_turtle : ''' # Creates the CREATE_TURTLE quadruple quadruple = Quadruple(my_program.quadruple_number, 'CREATE_TURTLE', None, None, None) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1
def p_pfc_reset(p): '''pfc_reset : ''' # Creates the RESET quadruple quadruple = Quadruple(my_program.quadruple_number, 'RESET', None, None, None) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1
def p_soa_action(p): '''soa_action : ''' # Gets the operator operator = my_program.operator_stack.pop() if operator == '=': # Gets the operands and its types right_operand = my_program.operand_stack.pop() right_type = my_program.type_stack.pop() left_operand = my_program.operand_stack.pop() left_type = my_program.type_stack.pop() # Gets the type of the result result_type = my_program.semantic_cube.get_semantic_type( left_type, right_type, operator) if result_type != 'error': # Creates the quadruple quadruple = Quadruple(my_program.quadruple_number, operator, right_operand, None, left_operand) # Adds the quadruple to its list and increments the counter my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1 else: print('Operation type mismatch at {0}'.format(p.lexer.lineno)) sys.exit()
def p_pfc_finish_drawing(p): '''pfc_finish_drawing : ''' # Creates the FINISH_DRAWING quadruple quadruple = Quadruple(my_program.quadruple_number, 'FINISH_DRAWING', None, None, None) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1
def p_enp_action(p): '''enp_action : ''' function_type = p[-7] # Checks if the functions and procedures have the correct return semantics if function_type == 'void' and my_program.return_flag: print('Function {0} of type {1} should not have return statement.'. format(my_program.current_scope, function_type)) sys.exit() elif function_type != 'void' and not my_program.return_flag: print('Function {0} of type {1} should have return statement.'.format( my_program.current_scope, function_type)) sys.exit() else: # Creates the end of function quadruple quadruple = Quadruple(my_program.quadruple_number, 'ENDPROC', None, None, None) my_program.quadruple_list.append(quadruple) # Fills the returns quadruples if exist if my_program.return_flag: while my_program.return_list: quadruple_number_to_fill = my_program.return_list.pop() my_program.quadruple_list[quadruple_number_to_fill - 1].fill_quadruple_jump( my_program.quadruple_number) my_program.quadruple_number += 1 my_program.return_flag = False # Reset the temporal memory my_program.current_scope = my_program.global_scope my_program.memory.reset_temporal_memory()
def p_cwr_action(p): '''cwr_action : ''' operand = my_program.operand_stack.pop() quadruple = Quadruple(my_program.quadruple_number, 'PRINT', operand, None, None) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1
def p_pfc_fill_color(p): '''pfc_fill_color : ''' # Gets the color (string constant) from the operand stack operand = my_program.operand_stack.pop() # Creates the PEN_COLOR quadruple quadruple = Quadruple(my_program.quadruple_number, 'FILL_COLOR', operand, None, None) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1
def p_pfc_move_left(p): '''pfc_move_left : ''' # Gets the distance number (exp) from the operand stack operand = my_program.operand_stack.pop() # Creates the MOVE_LEFT quadruple quadruple = Quadruple(my_program.quadruple_number, 'MOVE_LEFT', operand, None, None) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1
def p_pfc_set_speed(p): '''pfc_set_speed : ''' # Gets the speed number operand = my_program.operand_stack.pop() # Creates the SET_SPEED quadruple quadruple = Quadruple(my_program.quadruple_number, 'SET_SPEED', operand, None, None) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1
def p_pfc_draw_circle(p): '''pfc_draw_circle : ''' # Gets the length of the radius of the circle (exp) from the operand stack operand = my_program.operand_stack.pop() # Creates the DRAW_CIRCLE quadruple quadruple = Quadruple(my_program.quadruple_number, 'DRAW_CIRCLE', operand, None, None) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1
def p_pfc_draw_triangle(p): '''pfc_draw_triangle : ''' # Gets the length of the sides of the triangle (exp) from the operand stack operand = my_program.operand_stack.pop() # Creates the DRAW_TRIANGLE quadruple quadruple = Quadruple(my_program.quadruple_number, 'DRAW_TRIANGLE', operand, None, None) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1
def p_pfc_turn_left(p): '''pfc_turn_left : ''' # Gets the degrees number (exp) from the operand stack operand = my_program.operand_stack.pop() # Creates the TURN_LEFT quadruple quadruple = Quadruple(my_program.quadruple_number, 'TURN_LEFT', operand, None, None) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1
def p_pfc_pen_width(p): '''pfc_pen_width : ''' # Gets the width size number (exp) from the operand stack operand = my_program.operand_stack.pop() # Creates the PEN_WIDTH quadruple quadruple = Quadruple(my_program.quadruple_number, 'PEN_WIDTH', operand, None, None) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1
def p_pfc_set_position(p): '''pfc_set_position : ''' # Gets the position on X axis y_axis = my_program.operand_stack.pop() # Gets the position on Y axis x_axis = my_program.operand_stack.pop() # Creates the SET_POSITION quadruple quadruple = Quadruple(my_program.quadruple_number, 'SET_POSITION', x_axis, y_axis, None) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1
def p_pfc_draw_rectangle(p): '''pfc_draw_rectangle : ''' # Gets the length of the left and right sides of the rectangle (exp) from the operand stack height = my_program.operand_stack.pop() # Gets the length of the upper and bottom sides of the rectangle (exp) from the operand stack width = my_program.operand_stack.pop() # Creates the DRAW_RECTANGLE quadruple quadruple = Quadruple(my_program.quadruple_number, 'DRAW_RECTANGLE', width, height, None) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1
def p_cdv_action(p): '''cdv_action : ''' index_address = my_program.operand_stack.pop() index_type = my_program.type_stack.pop() # Returns the last dimensioned variable called dimensioned_variable = my_program.dimensioned_varible_stack.pop() # Verifies the type of the index if index_type != 'int': print("Array indexes should be of type int") sys.exit() else: # Verifies the boundaries quadruple = Quadruple(my_program.quadruple_number, 'VERF_INDEX', index_address, dimensioned_variable['lower_limit'], dimensioned_variable['upper_limit']) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1 # The base address of the dimensioned variable must be stored in new # address, this makes possible the adding of the base address number and # not its content base_address_proxy = my_program.memory.request_global_address( 'int', dimensioned_variable['memory_adress']) index_address_result = my_program.memory.request_global_address('int') # Adds the base address number with the result of the index quadruple = Quadruple(my_program.quadruple_number, '+', base_address_proxy, index_address, index_address_result) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1 # Stores the index address result int a dictionary to difference it # from a regular address result_proxy = {'index_address': index_address_result} my_program.operand_stack.append(result_proxy) my_program.type_stack.append(dimensioned_variable['type'])
def p_swl_action(p): '''swl_action : ''' # Gets the number of the GotoF quadruple and where the while starts quadruple_number_to_fill = my_program.jump_list.pop() quadruple_number_to_return = my_program.jump_list.pop() while_quadruple = Quadruple(my_program.quadruple_number, 'GOTO', None, None, quadruple_number_to_return) my_program.quadruple_list.append(while_quadruple) my_program.quadruple_number += 1 conditional_quadruple = my_program.quadruple_list[quadruple_number_to_fill] # Fills the pending GoToF quadruple with the number of the next quadruple conditional_quadruple.fill_quadruple_jump(my_program.quadruple_number)
def p_crq_action(p): '''crq_action : ''' message_address = my_program.operand_stack.pop() my_program.type_stack.pop() # Gets the type of the variable where the input will be stored and request # a temporal address to resolve its assignment variable_type = my_program.type_stack[-1] input_address = my_program.memory.request_temporal_address(variable_type) my_program.operand_stack.append(input_address) my_program.type_stack.append(variable_type) quadruple = Quadruple(my_program.quadruple_number, 'READ', variable_type, message_address, input_address) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1
def p_sfc_action(p): '''sfc_action : ''' # If there are more parameters than arguments if not my_program.temporal_arguments_types: # Retrieves the function and is quadruple number function = p[-7] function_quadruple_number = my_program.function_directory.get_function_quadruple_number( function) # Creates its call quadruple quadruple = Quadruple(my_program.quadruple_number, 'GOSUB', function, None, function_quadruple_number) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1 else: print('Argument number mismatch at {0} line '.format(p.lexer.lineno)) sys.exit()
def create_conditional_quadruple(p): """Creates the quadruple when an if or a while is reached""" type_result = my_program.type_stack.pop() # It makes no action when the result's type is not a boolean if type_result != 'bool': print('Operation type mismatch in line {0}'.format(p.lexer.lineno)) sys.exit() else: # Creates the GotoF quadruple result = my_program.operand_stack.pop() quadruple = Quadruple(my_program.quadruple_number, 'GOTOF', result, None, None) my_program.quadruple_list.append(quadruple) # Stores the number of the GotoF quaduple in order to be filled later my_program.jump_list.append(my_program.quadruple_number - 1) my_program.quadruple_number += 1
def p_cel_action(p): '''cel_action : ''' # Creates the GoTo quadruple quadruple = Quadruple(my_program.quadruple_number, 'GOTO', None, None, None) my_program.quadruple_list.append(quadruple) # Gets the number of the GotoF quadruple to be filled quadruple_number_to_fill = my_program.jump_list.pop() quadruple = my_program.quadruple_list[quadruple_number_to_fill] # Stores the actual quadruple_number GoTo in the jump list my_program.jump_list.append(my_program.quadruple_number - 1) my_program.quadruple_number += 1 # Fills the pending GoToF quadruple with the number of the next quadruple # after GoTo was created quadruple.fill_quadruple_jump(my_program.quadruple_number)
def p_cra_action(p): '''cra_action : ''' function = p[-3] # Checks if the function exists if my_program.function_directory.has_function(function): # Creates its quadruple action quadruple = Quadruple(my_program.quadruple_number, 'ERA', function, None, None) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1 # Retrieves the parameters of the function parameters = my_program.function_directory.get_function_parameters( function) my_program.temporal_arguments_types = list(parameters['types']) else: print("The function " + function + " you are trying to call doesn't exists") sys.exit()
def p_sar_action(p): '''sar_action : ''' # If there are more arguments than parameters if my_program.temporal_arguments_types: # Gets the argument and its type from the stacks argument = my_program.operand_stack.pop() argument_type = my_program.type_stack.pop() parameter_type = my_program.temporal_arguments_types.pop(0) # Creates the quadruple for the parameter if argument_type == parameter_type: quadruple = Quadruple(my_program.quadruple_number, 'PARAMETER', argument, None, None) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1 else: print('Argument type mismatch at {0} line '.format(p.lexer.lineno)) sys.exit() else: print('Agument number mismatch at {0} line '.format(p.lexer.lineno)) sys.exit()
def solve_operation(p): """Solve an operation from the stacks""" # Gets the operands and its types right_operand = my_program.operand_stack.pop() right_type = my_program.type_stack.pop() left_operand = my_program.operand_stack.pop() left_type = my_program.type_stack.pop() # Gets the operator operator = my_program.operator_stack.pop() # Gets the type of the result result_type = my_program.semantic_cube.get_semantic_type( left_type, right_type, operator) if result_type != 'error': #my_program.temporal_variable_counter += 1 #temporal_variable = "t" + str(my_program.temporal_variable_counter) # Gets an address of the temporal memory temporal_variable_address = my_program.memory.request_temporal_address( result_type) my_program.function_directory.add_temporal_to_function( my_program.current_scope, result_type) # Creates the quadruple quadruple = Quadruple(my_program.quadruple_number, operator, left_operand, right_operand, temporal_variable_address) # Adds the quadruple to its list and the results to the stacks my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1 my_program.operand_stack.append(temporal_variable_address) my_program.type_stack.append(result_type) else: print('Operation type mismatch at {0}'.format(p.lexer.lineno)) sys.exit()
def p_arf_action(p): '''arf_action : ''' function_called = p[-8] function = my_program.function_directory.get_function(function_called) function_return = function['return_address'] function_type = function['return_type'] #my_program.temporal_variable_counter += 1 # Requests a temporal variable to store the result of the function temporal_variable_address = my_program.memory.request_temporal_address( function_type) my_program.function_directory.add_temporal_to_function( my_program.current_scope, function_type) # Assignates the result to a new temporal variable and adds it to the # operand stack quadruple = Quadruple(my_program.quadruple_number, '=', function_return, None, temporal_variable_address) my_program.quadruple_list.append(quadruple) my_program.quadruple_number += 1 my_program.operand_stack.append(temporal_variable_address) my_program.type_stack.append(function_type)