def add_function(self, name, return_type=None): if name in self.functions(): raise SemanticError( 'Function with identifier: "{}" already exists!'.format(name)) self.__functions[name] = FunctionTable(name, return_type) self.__last_saved_func = self.__functions[name]
def p_check_params(p): ''' check-params :''' c_function = symbol_table.get_scope().current_function if (not c_function.verify_params()): raise SemanticError( 'Incorrect number of parameters for function with id: "{}"'.format( c_function.name))
def add_variable(self, name, var_type=None): if name in self.vars(): raise SemanticError( 'Variable with identifier: "{}" already exists!'.format(name)) self.__variables[name] = VariableTable(name, var_type) self.__last_saved_var = self.__variables[name]
def add_player(self, player_name, location=None): if player_name in self.players(): raise SemanticError( "Player with identifier: '{}' already exists!".format( player_name)) self.__players[player_name] = PlayerTable(player_name, location)
def p_push_var(p): ''' push_var :''' tvar = symbol_table.get_scope().get_var(p[-1]) if (tvar): exp_handler.push_operand(tvar.address, tvar.var_type) id_tracker.last_used_id = tvar.name() else: raise SemanticError('No variable with id: "{}"'.format(p[-1]))
def p_assign_array_literal(p): ''' assign_array_literal :''' var = symbol_table.get_scope().get_last_saved_var() if var.is_array: if var.current_index < var.dimension_list[0]: result, result_type = exp_handler.pop_operand() quad = Quadruple("=", result, None, var.address + var.current_index) quad_stack.push_quad(quad) var.add_to_index() else: raise SemanticError('Dimension for array ({}) is incorrect'.format( var.name())) else: raise SemanticError( "{} is not an array, you can't assign an array literal unless it's an array" .format(var.name()))
def p_save_arr_param_type(p): ''' save_arr_param_type :''' var_t = symbol_table.get_scope().get_last_saved_var() arr_size = p[-4] if arr_size <= 0: raise SemanticError( "INVALID ARRAY SIZE: Can't set an array size less than 1.") var_t.dimension_list = [arr_size, None] save_param_func_table(param_type=p[-1], is_array=True, size=arr_size)
def p_speak_function(p): ''' speak_function :''' tplayer = symbol_table.get_scope().get_player(p[-4]) result, result_type = exp_handler.pop_operand() if (tplayer): quad = Quadruple(p[-6], tplayer.player_name, None, result) quad_stack.push_quad(quad) else: raise SemanticError('No player with id: "{}"'.format(p[-4]))
def get_next_param(self): if self.__param_counter >= len(self.__params): raise SemanticError( 'Trying to access param ({}), but function only has ({}) params!' .format(self.__param_counter + 1, len(self.__params))) param = (self.__params[self.__param_counter], self.__param_counter, self.__param_type_counter[self.__param_counter]) self.__param_counter += 1 return param
def p_gen_size(p): ''' gen_size :''' func = symbol_table.get_scope().get_function(p[-3]) if (func): symbol_table.get_scope().current_function = func quad = Quadruple("ERA", None, None, func.name) quad_stack.push_quad(quad) func.reset_param_counter() else: raise SemanticError('No function with id: "{}"'.format(p[-3]))
def p_special_function(p): '''special_function :''' tplayer = symbol_table.get_scope().get_player(p[-2]) if (tplayer): temp_address = Avail.get_instance().next('bool') exp_handler.push_operand(temp_address, 'bool') quad = Quadruple(p[-4], tplayer.player_name, None, temp_address) quad_stack.push_quad(quad) else: raise SemanticError('No player with id: "{}"'.format(p[-2]))
def p_loop_false(p): ''' loop-false :''' exp_handler = ExpressionHandler.get_instance() var, var_type = exp_handler.pop_operand() if (var_type != 'bool'): raise SemanticError( "Result of the expression is not of type 'bool'. Found '{}' instead." .format(var_type)) jump_quad = Quadruple("GOTOF", var, None, PendingJump()) quad_stack.push_quad(jump_quad) jumps_stack.push_quad(jump_quad)
def p_flip(p): ''' flip :''' sign = 'ABS' if p[-2] == '+' else 'NEGATIVE' number = exp_handler.pop_operand() if number[1] == 'int': result = Avail.get_instance().next('int') quad = Quadruple(sign, number[0], None, result) quad_stack.push_quad(quad) exp_handler.push_operand(result, 'int') else: raise SemanticError( "Can't use a change of sign for {}, just for int type".format( number[1]))
def p_save_return_value(p): ''' save_return_value :''' function = symbol_table.get_scope().parent().get_last_saved_func().name var_table = symbol_table.get_scope().get_var(function) result, result_type = exp_handler.pop_operand() if var_table.var_type == result_type: quad = Quadruple("RETURN", var_table.address, None, result) quad_stack.push_quad(quad) exp_handler.push_operand(var_table.address, var_table.var_type) else: raise SemanticError( 'Return type for function "{}" expected "{}" and got "{}"'.format( function, var_table.var_type, result_type))
def attempt_create_quadruple(operands: List[str]): current_operator = exp_handler.peek_operator() if current_operator in operands: left_op, right_op, operator = exp_handler.pop_binary_exp() result_type = ResultingType.get_type(operator, left_op[1], right_op[1]) if result_type != ERROR_CODE: result = avail.next(result_type) quad = Quadruple(operator, left_op[0], right_op[0], result) quad_stack.push_quad(quad) exp_handler.push_operand(result, result_type) else: raise SemanticError( "TYPE MISMATCH: Invalid operation, can not [{}] {} [{}]". format(left_op[1], current_operator, right_op[1]))
def attempt_assignment_quadruple(var_id): var_table = symbol_table.get_scope().get_var(var_id) result, result_type = exp_handler.pop_operand() if var_table.var_type == result_type: if var_table.is_array: arr_address, var_type = exp_handler.pop_operand() quad = Quadruple("=", result, None, arr_address) quad_stack.push_quad(quad) else: quad = Quadruple("=", result, None, var_table.address) quad_stack.push_quad(quad) else: raise SemanticError("TYPE MISMATCH: can't assign: {} to: {}".format( result_type, var_table.var_type))
def attempt_create_quadruple_unary(operands: List[str]): current_operator = exp_handler.peek_operator() if current_operator in operands: operand, operator = exp_handler.pop_unary_exp() result_type = ResultingType.get_type_unary(operator, operand[1]) if result_type != ERROR_CODE: result = avail.next(result_type) quad = Quadruple(operator, operand[0], None, result) quad_stack.push_quad(quad) exp_handler.push_operand(result, result_type) else: raise SemanticError( "TYPE MISMATCH: {} is not compatible with {}".format( operator, operand[1]))
def p_save_array_index_exp(p): ''' save_array_index_exp :''' last_accessed_id = symbol_table.get_scope().last_accessed_id if last_accessed_id: var_table = symbol_table.get_scope().get_var(last_accessed_id) quad = Quadruple('VERIFY_DIM', exp_handler.peek_operand()[0], None, var_table.size - 1) quad_stack.push_quad(quad) next_address = address_handler.get_next_address( POINTERS, var_table.var_type, 1) quad = Quadruple('ADDRESS_SUM', var_table.address, exp_handler.pop_operand()[0], next_address) quad_stack.push_quad(quad) exp_handler.push_operand(next_address, var_table.var_type) exp_handler.pop_parenthesis() else: raise SemanticError("The variable trying to access is not an array.")
def attempt_pass_parameter(): c_function = symbol_table.get_scope().current_function c_param = c_function.get_next_param() arg, arg_type = exp_handler.pop_operand() if (c_param[0] == arg_type): regular_param = True if id_tracker.last_used_id is not None: var_table = symbol_table.get_scope().get_var( id_tracker.last_used_id) regular_param &= not var_table.is_array offset = c_param[2] if regular_param: quad = Quadruple("PARAMETER", arg, offset, arg_type) else: quad = Quadruple("ARRAY_PARAMETER", arg, (offset, var_table.size), arg_type) quad_stack.push_quad(quad) else: raise SemanticError( 'TYPE MISMATCH: Incorrect type in parameters for function with id: "{}"' .format(c_function.name))
def p_verify_assignment(p): ''' verify_assignment :''' if not Helper.get_instance().is_in_assignment: raise SemanticError( 'Trying to use an array literal outside an array assignment or inside an indexed array.' )