101 |
101 |
102 |
102 |
103 |
103 |
104 |
104 |
105 |
105 |
106 /* Verify if the datatypes of all prev_il_instructions are valid and equal! */ |
106 /* Verify if the datatypes of all symbols in the vector are valid and equal! */ |
107 static bool are_all_datatypes_of_prev_il_instructions_datatypes_equal(il_instruction_c *symbol) { |
107 static bool are_all_datatypes_equal(std::vector <symbol_c *> &symbol_vect) { |
108 if (NULL == symbol) ERROR; |
108 if (symbol_vect.size() <= 0) return false; |
109 bool res; |
109 |
110 |
110 bool res = get_datatype_info_c::is_type_valid(symbol_vect[0]->datatype); |
111 if (symbol->prev_il_instruction.size() > 0) |
111 for (unsigned int i = 1; i < symbol_vect.size(); i++) |
112 res = get_datatype_info_c::is_type_valid(symbol->prev_il_instruction[0]->datatype); |
112 res &= get_datatype_info_c::is_type_equal(symbol_vect[i-1]->datatype, symbol_vect[i]->datatype); |
113 |
|
114 for (unsigned int i = 1; i < symbol->prev_il_instruction.size(); i++) |
|
115 res &= get_datatype_info_c::is_type_equal(symbol->prev_il_instruction[i-1]->datatype, symbol->prev_il_instruction[i]->datatype); |
|
116 |
|
117 return res; |
113 return res; |
118 } |
114 } |
119 |
115 |
120 |
116 |
121 |
117 |
316 * which will not work for an implicit FB call! |
312 * which will not work for an implicit FB call! |
317 */ |
313 */ |
318 STAGE3_ERROR(0, il_operator, il_operand, "FB called by '%s' operator does not have a parameter named '%s'", param_name, param_name); |
314 STAGE3_ERROR(0, il_operator, il_operand, "FB called by '%s' operator does not have a parameter named '%s'", param_name, param_name); |
319 return NULL; |
315 return NULL; |
320 } |
316 } |
321 if (!are_all_datatypes_of_prev_il_instructions_datatypes_equal(fake_prev_il_instruction)) { |
317 if (!are_all_datatypes_equal(fake_prev_il_instruction->prev_il_instruction)) { |
322 STAGE3_ERROR(0, il_operator, il_operand, "Data type incompatibility between parameter '%s' and value being passed.", param_name); |
318 STAGE3_ERROR(0, il_operator, il_operand, "Data type incompatibility between parameter '%s' and value being passed.", param_name); |
323 return NULL; |
319 return NULL; |
324 } |
320 } |
325 |
321 |
326 |
322 |
760 * Instead of creating two 'global' (within the class) variables, we create a single il_instruction_c variable (fake_prev_il_instruction), |
756 * Instead of creating two 'global' (within the class) variables, we create a single il_instruction_c variable (fake_prev_il_instruction), |
761 * and shove that data into this single variable. |
757 * and shove that data into this single variable. |
762 */ |
758 */ |
763 tmp_prev_il_instruction.prev_il_instruction = symbol->prev_il_instruction; |
759 tmp_prev_il_instruction.prev_il_instruction = symbol->prev_il_instruction; |
764 intersect_prev_candidate_datatype_lists(&tmp_prev_il_instruction); |
760 intersect_prev_candidate_datatype_lists(&tmp_prev_il_instruction); |
765 if (are_all_datatypes_of_prev_il_instructions_datatypes_equal(symbol)) |
761 if (are_all_datatypes_equal(symbol->prev_il_instruction)) |
766 if (symbol->prev_il_instruction.size() > 0) |
762 if (symbol->prev_il_instruction.size() > 0) |
767 tmp_prev_il_instruction.datatype = (symbol->prev_il_instruction[0])->datatype; |
763 tmp_prev_il_instruction.datatype = (symbol->prev_il_instruction[0])->datatype; |
768 |
764 |
769 /* Tell the il_instruction the datatype that it must generate - this was chosen by the next il_instruction (remember: we are iterating backwards!) */ |
765 /* Tell the il_instruction the datatype that it must generate - this was chosen by the next il_instruction (remember: we are iterating backwards!) */ |
770 fake_prev_il_instruction = &tmp_prev_il_instruction; |
766 fake_prev_il_instruction = &tmp_prev_il_instruction; |
833 |
829 |
834 |
830 |
835 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */ |
831 /* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */ |
836 // SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list); |
832 // SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list); |
837 void *print_datatypes_error_c::visit(il_expression_c *symbol) { |
833 void *print_datatypes_error_c::visit(il_expression_c *symbol) { |
|
834 /* Stage2 will insert an artificial (and equivalent) LD <il_operand> to the simple_instr_list if necessary. We can therefore ignore the 'il_operand' entry! */ |
|
835 |
838 /* first give the parenthesised IL list a chance to print errors */ |
836 /* first give the parenthesised IL list a chance to print errors */ |
839 il_instruction_c *save_fake_prev_il_instruction = fake_prev_il_instruction; |
837 il_instruction_c *save_fake_prev_il_instruction = fake_prev_il_instruction; |
840 symbol->simple_instr_list->accept(*this); |
838 symbol->simple_instr_list->accept(*this); |
841 fake_prev_il_instruction = save_fake_prev_il_instruction; |
839 fake_prev_il_instruction = save_fake_prev_il_instruction; |
842 |
840 |
900 // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;) |
898 // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;) |
901 void *print_datatypes_error_c::visit(il_simple_instruction_c *symbol) { |
899 void *print_datatypes_error_c::visit(il_simple_instruction_c *symbol) { |
902 if (symbol->prev_il_instruction.size() > 1) ERROR; /* There should be no labeled insructions inside an IL expression! */ |
900 if (symbol->prev_il_instruction.size() > 1) ERROR; /* There should be no labeled insructions inside an IL expression! */ |
903 |
901 |
904 il_instruction_c tmp_prev_il_instruction(NULL, NULL); |
902 il_instruction_c tmp_prev_il_instruction(NULL, NULL); |
|
903 #if 0 |
905 /* the print error algorithm will need access to the intersected candidate_datatype lists of all prev_il_instructions, as well as the |
904 /* the print error algorithm will need access to the intersected candidate_datatype lists of all prev_il_instructions, as well as the |
906 * list of the prev_il_instructions. |
905 * list of the prev_il_instructions. |
907 * Instead of creating two 'global' (within the class) variables, we create a single il_instruction_c variable (fake_prev_il_instruction), |
906 * Instead of creating two 'global' (within the class) variables, we create a single il_instruction_c variable (fake_prev_il_instruction), |
908 * and shove that data into this single variable. |
907 * and shove that data into this single variable. |
909 */ |
908 */ |
910 if (symbol->prev_il_instruction.size() > 0) |
909 if (symbol->prev_il_instruction.size() > 0) |
911 tmp_prev_il_instruction.candidate_datatypes = symbol->prev_il_instruction[0]->candidate_datatypes; |
910 tmp_prev_il_instruction.candidate_datatypes = symbol->prev_il_instruction[0]->candidate_datatypes; |
912 tmp_prev_il_instruction.prev_il_instruction = symbol->prev_il_instruction; |
911 tmp_prev_il_instruction.prev_il_instruction = symbol->prev_il_instruction; |
|
912 #endif |
|
913 |
|
914 /* the print error algorithm will need access to the intersected candidate_datatype lists of all prev_il_instructions, as well as the |
|
915 * list of the prev_il_instructions. |
|
916 * Instead of creating two 'global' (within the class) variables, we create a single il_instruction_c variable (fake_prev_il_instruction), |
|
917 * and shove that data into this single variable. |
|
918 */ |
|
919 tmp_prev_il_instruction.prev_il_instruction = symbol->prev_il_instruction; |
|
920 intersect_prev_candidate_datatype_lists(&tmp_prev_il_instruction); |
|
921 if (are_all_datatypes_equal(symbol->prev_il_instruction)) |
|
922 if (symbol->prev_il_instruction.size() > 0) |
|
923 tmp_prev_il_instruction.datatype = (symbol->prev_il_instruction[0])->datatype; |
|
924 |
913 |
925 |
914 /* copy the candidate_datatypes list */ |
926 /* copy the candidate_datatypes list */ |
915 fake_prev_il_instruction = &tmp_prev_il_instruction; |
927 fake_prev_il_instruction = &tmp_prev_il_instruction; |
916 symbol->il_simple_instruction->accept(*this); |
928 symbol->il_simple_instruction->accept(*this); |
917 fake_prev_il_instruction = NULL; |
929 fake_prev_il_instruction = NULL; |