stage3/print_datatypes_error.cc
changeset 459 01f6664bf8c5
parent 458 587884880be6
child 470 d2cd05c5e01a
equal deleted inserted replaced
458:587884880be6 459:01f6664bf8c5
    90 
    90 
    91 int print_datatypes_error_c::get_error_found() {
    91 int print_datatypes_error_c::get_error_found() {
    92 	return error_found;
    92 	return error_found;
    93 }
    93 }
    94 
    94 
       
    95 
       
    96 
       
    97 
       
    98 
       
    99 /* Verify if the datatypes of all prev_il_instructions are valid and equal!  */
       
   100 static bool are_all_datatypes_of_prev_il_instructions_datatypes_equal(il_instruction_c *symbol) {
       
   101 	if (NULL == symbol) ERROR;
       
   102 	bool res;
       
   103 	
       
   104 	if (symbol->prev_il_instruction.size() > 0)
       
   105 		res = is_type_valid(symbol->prev_il_instruction[0]->datatype);
       
   106 
       
   107 	for (unsigned int i = 1; i < symbol->prev_il_instruction.size(); i++)
       
   108 		res &= is_type_equal(symbol->prev_il_instruction[i-1]->datatype, symbol->prev_il_instruction[i]->datatype);
       
   109 	
       
   110 	return res;
       
   111 }
       
   112 
       
   113 
       
   114 
       
   115 
    95 /* a helper function... */
   116 /* a helper function... */
    96 symbol_c *print_datatypes_error_c::base_type(symbol_c *symbol) {
   117 symbol_c *print_datatypes_error_c::base_type(symbol_c *symbol) {
    97 	/* NOTE: symbol == NULL is valid. It will occur when, for e.g., an undefined/undeclared symbolic_variable is used
   118 	/* NOTE: symbol == NULL is valid. It will occur when, for e.g., an undefined/undeclared symbolic_variable is used
    98 	 *       in the code.
   119 	 *       in the code.
    99 	 */
   120 	 */
   237 	if (NULL == called_fb_declaration) {
   258 	if (NULL == called_fb_declaration) {
   238 		STAGE3_ERROR(0, il_operator, il_operand, "Invalid FB call: operand is not a FB instance.");
   259 		STAGE3_ERROR(0, il_operator, il_operand, "Invalid FB call: operand is not a FB instance.");
   239 		return;
   260 		return;
   240 	}
   261 	}
   241 
   262 
   242 	if (NULL == prev_il_instruction) {
   263 	if (fake_prev_il_instruction->prev_il_instruction.empty()) {
   243 		STAGE3_ERROR(0, il_operator, il_operand, "FB invocation operator '%s' must be preceded by a 'LD' (or equivalent) operator.", param_name);	
   264 		STAGE3_ERROR(0, il_operator, il_operand, "FB invocation operator '%s' must be preceded by a 'LD' (or equivalent) operator.", param_name);	
   244 		return;
   265 		return;
   245 	}
   266 	}
   246 
   267 
   247 	/* Find the corresponding parameter in function declaration */
   268 	/* Find the corresponding parameter in function declaration */
   255 		*        which will not work for an implicit FB call!
   276 		*        which will not work for an implicit FB call!
   256 		*/
   277 		*/
   257 		STAGE3_ERROR(0, il_operator, il_operand, "FB called by '%s' operator does not have a parameter named '%s'", param_name, param_name);	
   278 		STAGE3_ERROR(0, il_operator, il_operand, "FB called by '%s' operator does not have a parameter named '%s'", param_name, param_name);	
   258 		return;
   279 		return;
   259 	}
   280 	}
   260 	if (NULL == prev_il_instruction->datatype) {
   281 	if (!are_all_datatypes_of_prev_il_instructions_datatypes_equal(fake_prev_il_instruction)) {
   261 		STAGE3_ERROR(0, il_operator, il_operand, "Data type incompatibility between parameter '%s' and value being passed.", param_name);
   282 		STAGE3_ERROR(0, il_operator, il_operand, "Data type incompatibility between parameter '%s' and value being passed.", param_name);
   262 		return;
   283 		return;
   263 	}
   284 	}
   264 	
   285 	
   265 
   286 
   616 
   637 
   617 /* | label ':' [il_incomplete_instruction] eol_list */
   638 /* | label ':' [il_incomplete_instruction] eol_list */
   618 // SYM_REF2(il_instruction_c, label, il_instruction)
   639 // SYM_REF2(il_instruction_c, label, il_instruction)
   619 void *print_datatypes_error_c::visit(il_instruction_c *symbol) {
   640 void *print_datatypes_error_c::visit(il_instruction_c *symbol) {
   620 	if (NULL != symbol->il_instruction) {
   641 	if (NULL != symbol->il_instruction) {
   621 		if (symbol->prev_il_instruction.size() > 1) ERROR; /* This assertion is only valid for now. Remove it once flow_control_analysis_c is complete */
   642 // #if 0
   622 		if (symbol->prev_il_instruction.size() == 0)  prev_il_instruction = NULL;
   643 		il_instruction_c tmp_prev_il_instruction(NULL, NULL);
   623 		else                                          prev_il_instruction = symbol->prev_il_instruction[0];
   644 		/* the narrow algorithm will need access to the intersected candidate_datatype lists of all prev_il_instructions, as well as the 
   624 
   645 		 * list of the prev_il_instructions.
       
   646 		 * Instead of creating two 'global' (within the class) variables, we create a single il_instruction_c variable (fake_prev_il_instruction),
       
   647 		 * and shove that data into this single variable.
       
   648 		 */
       
   649 		tmp_prev_il_instruction.prev_il_instruction = symbol->prev_il_instruction;
       
   650 		intersect_prev_candidate_datatype_lists(&tmp_prev_il_instruction);
       
   651 		if (are_all_datatypes_of_prev_il_instructions_datatypes_equal(symbol))
       
   652 			if (symbol->prev_il_instruction.size() > 0)
       
   653 				tmp_prev_il_instruction.datatype = (symbol->prev_il_instruction[0])->datatype;
       
   654 		/* Tell the il_instruction the datatype that it must generate - this was chosen by the next il_instruction (remember: we are iterating backwards!) */
       
   655 		fake_prev_il_instruction = &tmp_prev_il_instruction;
   625 		symbol->il_instruction->accept(*this);
   656 		symbol->il_instruction->accept(*this);
   626 		prev_il_instruction = NULL;
   657 		fake_prev_il_instruction = NULL;
       
   658 // #endif
       
   659 // 		if (symbol->prev_il_instruction.size() > 1) ERROR; /* only valid for now! */
       
   660 // 		if (symbol->prev_il_instruction.size() == 0)  prev_il_instruction = NULL;
       
   661 // 		else                                          prev_il_instruction = symbol->prev_il_instruction[0];
       
   662 
       
   663 // 		symbol->il_instruction->accept(*this);
       
   664 // 		prev_il_instruction = NULL;
   627 	}
   665 	}
   628 
   666 
   629 	return NULL;
   667 	return NULL;
   630 }
   668 }
   631 
   669 
   655 	 * This change will also be undone later in print_datatypes_error_c.
   693 	 * This change will also be undone later in print_datatypes_error_c.
   656 	 */
   694 	 */
   657 	if (NULL == symbol->il_operand_list)  symbol->il_operand_list = new il_operand_list_c;
   695 	if (NULL == symbol->il_operand_list)  symbol->il_operand_list = new il_operand_list_c;
   658 	if (NULL == symbol->il_operand_list)  ERROR;
   696 	if (NULL == symbol->il_operand_list)  ERROR;
   659 
   697 
   660 	((list_c *)symbol->il_operand_list)->insert_element(prev_il_instruction, 0);
   698 	((list_c *)symbol->il_operand_list)->insert_element(fake_prev_il_instruction, 0);
   661 
   699 
   662 	generic_function_call_t fcall_param = {
   700 	generic_function_call_t fcall_param = {
   663 		/* fcall_param.function_name               = */ symbol->function_name,
   701 		/* fcall_param.function_name               = */ symbol->function_name,
   664 		/* fcall_param.nonformal_operand_list      = */ symbol->il_operand_list,
   702 		/* fcall_param.nonformal_operand_list      = */ symbol->il_operand_list,
   665 		/* fcall_param.formal_operand_list         = */ NULL,
   703 		/* fcall_param.formal_operand_list         = */ NULL,
   669 		/* fcall_param.extensible_param_count      = */ symbol->extensible_param_count
   707 		/* fcall_param.extensible_param_count      = */ symbol->extensible_param_count
   670 	};
   708 	};
   671 
   709 
   672 /* TODO: check what error message (if any) the compiler will give out if this function invocation
   710 /* TODO: check what error message (if any) the compiler will give out if this function invocation
   673  * is not preceded by a LD operator (or another equivalent operator or list of operators).
   711  * is not preceded by a LD operator (or another equivalent operator or list of operators).
   674  * I.e. if it is preceded by an operator or operator list that will set the 'current value'.
       
   675  * I.e. if the prev_il_operand == NULL;
       
   676  */
   712  */
   677 	handle_function_invocation(symbol, fcall_param);
   713 	handle_function_invocation(symbol, fcall_param);
   678 	
   714 	
   679 	/* The first parameter of a non formal function call in IL will be the 'current value' (i.e. the prev_il_instruction)
   715 	/* We now undo those changes to the abstract syntax tree made above! */
   680 	 * In order to be able to handle this without coding special cases, we simply prepend that symbol
       
   681 	 * to the il_operand_list. This was done in fill_candidate_datatypes_c.
       
   682 	 * We now undo those changes!
       
   683 	 */  
       
   684 	((list_c *)symbol->il_operand_list)->remove_element(0);
   716 	((list_c *)symbol->il_operand_list)->remove_element(0);
   685 	if (((list_c *)symbol->il_operand_list)->n == 0) {
   717 	if (((list_c *)symbol->il_operand_list)->n == 0) {
   686 		/* if the list becomes empty, then that means that it did not exist before we made these changes, so we delete it! */
   718 		/* if the list becomes empty, then that means that it did not exist before we made these changes, so we delete it! */
   687 		delete 	symbol->il_operand_list;
   719 		delete 	symbol->il_operand_list;
   688 		symbol->il_operand_list = NULL;
   720 		symbol->il_operand_list = NULL;
   694 
   726 
   695 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
   727 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */
   696 // SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list);
   728 // SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list);
   697 void *print_datatypes_error_c::visit(il_expression_c *symbol) {
   729 void *print_datatypes_error_c::visit(il_expression_c *symbol) {
   698   /* first give the parenthesised IL list a chance to print errors */
   730   /* first give the parenthesised IL list a chance to print errors */
   699   symbol_c *save_prev_il_instruction = prev_il_instruction;
   731   il_instruction_c *save_fake_prev_il_instruction = fake_prev_il_instruction;
   700   symbol->simple_instr_list->accept(*this);
   732   symbol->simple_instr_list->accept(*this);
   701   prev_il_instruction = save_prev_il_instruction;
   733   fake_prev_il_instruction = save_fake_prev_il_instruction;
   702 
   734 
   703   /* Now handle the operation (il_expr_operator) that will use the result coming from the parenthesised IL list (i.e. simple_instr_list) */
   735   /* Now handle the operation (il_expr_operator) that will use the result coming from the parenthesised IL list (i.e. simple_instr_list) */
   704   il_operand = symbol->simple_instr_list; /* This is not a bug! The parenthesised expression will be used as the operator! */
   736   il_operand = symbol->simple_instr_list; /* This is not a bug! The parenthesised expression will be used as the operator! */
   705   symbol->il_expr_operator->accept(*this);
   737   symbol->il_expr_operator->accept(*this);
   706 
   738 
   757 //     void *visit(il_operand_list_c *symbol);
   789 //     void *visit(il_operand_list_c *symbol);
   758 //     void *visit(simple_instr_list_c *symbol);
   790 //     void *visit(simple_instr_list_c *symbol);
   759 
   791 
   760 // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
   792 // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
   761 void *print_datatypes_error_c::visit(il_simple_instruction_c *symbol)	{
   793 void *print_datatypes_error_c::visit(il_simple_instruction_c *symbol)	{
   762   if (symbol->prev_il_instruction.size() > 1) ERROR; /* This assertion is only valid for now. Remove it once flow_control_analysis_c is complete */
   794   if (symbol->prev_il_instruction.size() > 1) ERROR; /* There should be no labeled insructions inside an IL expression! */
   763   if (symbol->prev_il_instruction.size() == 0)  prev_il_instruction = NULL;
   795     
   764   else                                          prev_il_instruction = symbol->prev_il_instruction[0];
   796   il_instruction_c tmp_prev_il_instruction(NULL, NULL);
   765 
   797   /* the print error algorithm will need access to the intersected candidate_datatype lists of all prev_il_instructions, as well as the 
       
   798    * list of the prev_il_instructions.
       
   799    * Instead of creating two 'global' (within the class) variables, we create a single il_instruction_c variable (fake_prev_il_instruction),
       
   800    * and shove that data into this single variable.
       
   801    */
       
   802   if (symbol->prev_il_instruction.size() > 0)
       
   803     tmp_prev_il_instruction.candidate_datatypes = symbol->prev_il_instruction[0]->candidate_datatypes;
       
   804   tmp_prev_il_instruction.prev_il_instruction = symbol->prev_il_instruction;
       
   805   
       
   806    /* copy the candidate_datatypes list */
       
   807   fake_prev_il_instruction = &tmp_prev_il_instruction;
   766   symbol->il_simple_instruction->accept(*this);
   808   symbol->il_simple_instruction->accept(*this);
   767   prev_il_instruction = NULL;
   809   fake_prev_il_instruction = NULL;
   768   return NULL;
   810   return NULL;
       
   811   
       
   812   
       
   813 //   if (symbol->prev_il_instruction.size() == 0)  prev_il_instruction = NULL;
       
   814 //   else                                          prev_il_instruction = symbol->prev_il_instruction[0];
       
   815 
       
   816 //   symbol->il_simple_instruction->accept(*this);
       
   817 //   prev_il_instruction = NULL;
       
   818 //   return NULL;
   769 }
   819 }
   770 
   820 
   771 
   821 
   772 //     void *visit(il_param_list_c *symbol);
   822 //     void *visit(il_param_list_c *symbol);
   773 //     void *visit(il_param_assignment_c *symbol);
   823 //     void *visit(il_param_assignment_c *symbol);