45 |
45 |
46 |
46 |
47 #define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order) ? (symbol1) : (symbol2)) |
47 #define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order) ? (symbol1) : (symbol2)) |
48 #define LAST_(symbol1, symbol2) (((symbol1)->last_order > (symbol2)->last_order) ? (symbol1) : (symbol2)) |
48 #define LAST_(symbol1, symbol2) (((symbol1)->last_order > (symbol2)->last_order) ? (symbol1) : (symbol2)) |
49 |
49 |
50 #define STAGE3_ERROR(symbol1, symbol2, msg) { \ |
50 #define STAGE3_ERROR(symbol1, symbol2, ...) { \ |
51 fprintf(stderr, "%s:%d-%d..%d-%d: error : %s\n", \ |
51 fprintf(stderr, "%s:%d-%d..%d-%d: error : ", \ |
52 FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column, \ |
52 FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column, \ |
53 LAST_(symbol1,symbol2) ->last_line, LAST_(symbol1,symbol2) ->last_column, \ |
53 LAST_(symbol1,symbol2) ->last_line, LAST_(symbol1,symbol2) ->last_column); \ |
54 msg); \ |
54 fprintf(stderr, __VA_ARGS__); \ |
|
55 fprintf(stderr, "\n"); \ |
55 il_error = true; \ |
56 il_error = true; \ |
56 error_found = true; \ |
57 error_found = true; \ |
57 } |
58 } |
58 |
59 |
59 |
60 |
747 } |
748 } |
748 } // if (use_il_defvar) |
749 } // if (use_il_defvar) |
749 |
750 |
750 /* Iterating through the non-formal parameters of the function call */ |
751 /* Iterating through the non-formal parameters of the function call */ |
751 while((call_param_value = fcp_iterator.next_nf()) != NULL) { |
752 while((call_param_value = fcp_iterator.next_nf()) != NULL) { |
752 /* Obtaining the type of the current parameter in the function call */ |
753 /* Obtaining the type of the value being passed in the function call */ |
753 call_param_type = base_type((symbol_c*)call_param_value->accept(*this)); |
754 call_param_type = base_type((symbol_c*)call_param_value->accept(*this)); |
754 if (call_param_type == NULL) STAGE3_ERROR(call_param_value, call_param_value, "Could not determine data type of value being passed in function/FB call.");; |
755 if (call_param_type == NULL) { |
755 |
756 STAGE3_ERROR(call_param_value, call_param_value, "Could not determine data type of value being passed in function/FB call."); |
|
757 continue; |
|
758 } |
|
759 |
756 /* Iterate to the next parameter of the function being called. |
760 /* Iterate to the next parameter of the function being called. |
757 * Get the name of that parameter, and ignore if EN or ENO. |
761 * Get the name of that parameter, and ignore if EN or ENO. |
758 */ |
762 */ |
759 do { |
763 do { |
760 param_name = fp_iterator.next(); |
764 param_name = fp_iterator.next(); |
762 if(param_name == NULL) {STAGE3_ERROR(f_call, f_call, "Too many parameters in function/FB call."); break;} |
766 if(param_name == NULL) {STAGE3_ERROR(f_call, f_call, "Too many parameters in function/FB call."); break;} |
763 } while ((strcmp(param_name->value, "EN") == 0) || (strcmp(param_name->value, "ENO") == 0)); |
767 } while ((strcmp(param_name->value, "EN") == 0) || (strcmp(param_name->value, "ENO") == 0)); |
764 |
768 |
765 if(param_name != NULL) { |
769 if(param_name != NULL) { |
766 /* Get the parameter type */ |
770 /* Get the parameter type */ |
767 param_type = fp_iterator.param_type(); |
771 param_type = base_type(fp_iterator.param_type()); |
768 /* If the declared parameter and the parameter from the function call do no have the same type */ |
772 /* If the declared parameter and the parameter from the function call do no have the same type */ |
769 if(!is_valid_assignment(param_type, call_param_type)) STAGE3_ERROR(call_param_value, call_param_value, "Type mismatch in function/FB call parameter."); |
773 if(!is_valid_assignment(param_type, call_param_type)) STAGE3_ERROR(call_param_value, call_param_value, "Type mismatch in function/FB call parameter."); |
770 } |
774 } |
771 } |
775 } |
772 } |
776 } |
773 |
777 |
774 void visit_expression_type_c::compute_input_operatores(symbol_c *symbol, const char *input_operator){ |
778 |
775 symbol_c *call_param_type; |
779 /* check semantics of FB call in the IL language using input operators */ |
|
780 /* e.g. CU, CLK, IN, PT, SR, ... */ |
|
781 void visit_expression_type_c::check_il_fbcall(symbol_c *il_operator, const char *il_operator_str) { |
|
782 symbol_c *call_param_type = il_default_variable_type; |
776 symbol_c *fb_decl = il_operand_type; |
783 symbol_c *fb_decl = il_operand_type; |
777 /* The following should never occur. The function block must be defined, |
784 /* The following should never occur. The function block must be defined, |
778 * and the FB type being called MUST be in the symtable... |
785 * and the FB type being called MUST be in the symtable... |
779 * This was all already checked at stage 2! |
786 * This was all already checked at stage 2! |
780 */ |
787 */ |
781 if (NULL == fb_decl){ |
788 if (NULL == fb_decl) ERROR; |
782 STAGE3_ERROR(symbol, symbol, "Parameter operator needs an instance of a function block operand."); |
789 if (call_param_type == NULL) ERROR; |
783 ERROR; |
790 |
784 } |
791 /* We also create an identifier_c object, so we can later use it to find the equivalent FB parameter */ |
785 |
792 /* Note however that this symbol does not have the correct location (file name and line numbers) |
786 /* Iterating through the formal parameters of the function call */ |
793 * so any error messages must use the il_operator symbol to generate the error location |
787 identifier_c call_param_name(input_operator); |
794 */ |
|
795 identifier_c call_param_name(il_operator_str); |
788 |
796 |
789 /* Obtaining the type of the value being passed in the function call */ |
797 /* Obtaining the type of the value being passed in the function call */ |
790 call_param_type = il_default_variable_type; |
|
791 if (call_param_type == NULL) { |
|
792 STAGE3_ERROR(&call_param_name, &call_param_name, "Could not determine data type of value being passed in function/FB call."); |
|
793 /* The data value being passed is possibly any enumerated type value. |
|
794 * We do not yet handle semantic verification of enumerated types. |
|
795 */ |
|
796 ERROR; |
|
797 } |
|
798 call_param_type = base_type(call_param_type); |
798 call_param_type = base_type(call_param_type); |
799 if (call_param_type == NULL) STAGE3_ERROR(&call_param_name, &call_param_name, "Could not determine data type of value being passed in function/FB call."); |
799 if (call_param_type == NULL) STAGE3_ERROR(il_operator, il_operator, "Could not determine data type of value being passed in FB call."); |
800 |
800 |
801 |
|
802 check_formal_parameter(&call_param_name, call_param_type, fb_decl); |
|
803 // return NULL; |
|
804 } |
|
805 |
|
806 void visit_expression_type_c::check_formal_parameter(symbol_c *call_param_name, symbol_c *call_param_type, symbol_c *f_decl) { |
|
807 symbol_c *param_type; |
|
808 identifier_c *param_name; |
|
809 function_param_iterator_c fp_iterator(f_decl); |
|
810 |
|
811 /* Find the corresponding parameter of the function being called */ |
801 /* Find the corresponding parameter of the function being called */ |
812 param_name = fp_iterator.search(call_param_name); |
802 function_param_iterator_c fp_iterator(fb_decl); |
813 if(param_name == NULL) { |
803 if(fp_iterator.search(&call_param_name) == NULL) { |
814 STAGE3_ERROR(call_param_name, call_param_name, "Invalid parameter in function/FB call."); |
804 STAGE3_ERROR(il_operand, il_operand, "Called FB does not have an input parameter named %s.", il_operator_str); |
815 } else { |
805 } else { |
816 /* Get the parameter type */ |
806 /* Get the parameter type */ |
817 param_type = fp_iterator.param_type(); |
807 symbol_c *param_type = base_type(fp_iterator.param_type()); |
818 /* If the declared parameter and the parameter from the function call have the same type */ |
808 /* If the declared parameter and the parameter from the function call have the same type */ |
819 if(!is_valid_assignment(param_type, call_param_type)) STAGE3_ERROR(call_param_name, call_param_name, "Type mismatch function/FB call parameter."); |
809 if(!is_valid_assignment(param_type, call_param_type)) STAGE3_ERROR(il_operator, il_operator, "Type mismatch in FB call parameter."); |
820 } |
810 } |
821 } |
811 } |
822 |
812 |
823 |
813 |
824 /* A helper function... */ |
814 /* A helper function... */ |
1346 } |
1336 } |
1347 |
1337 |
1348 |
1338 |
1349 // SYM_REF0(S1_operator_c) |
1339 // SYM_REF0(S1_operator_c) |
1350 void *visit_expression_type_c::visit(S1_operator_c *symbol){ |
1340 void *visit_expression_type_c::visit(S1_operator_c *symbol){ |
1351 compute_input_operatores(symbol, "S1"); |
1341 check_il_fbcall(symbol, "S1"); |
1352 return NULL; |
1342 return NULL; |
1353 } |
1343 } |
1354 |
1344 |
1355 // SYM_REF0(R1_operator_c) |
1345 // SYM_REF0(R1_operator_c) |
1356 void *visit_expression_type_c::visit(R1_operator_c *symbol) { |
1346 void *visit_expression_type_c::visit(R1_operator_c *symbol) { |
1357 compute_input_operatores(symbol, "R1"); |
1347 check_il_fbcall(symbol, "R1"); |
1358 return NULL; |
1348 return NULL; |
1359 } |
1349 } |
1360 |
1350 |
1361 // SYM_REF0(CLK_operator_c) |
1351 // SYM_REF0(CLK_operator_c) |
1362 void *visit_expression_type_c::visit(CLK_operator_c *symbol) { |
1352 void *visit_expression_type_c::visit(CLK_operator_c *symbol) { |
1363 compute_input_operatores(symbol, "CLK"); |
1353 check_il_fbcall(symbol, "CLK"); |
1364 return NULL; |
1354 return NULL; |
1365 } |
1355 } |
1366 |
1356 |
1367 // SYM_REF0(CU_operator_c) |
1357 // SYM_REF0(CU_operator_c) |
1368 void *visit_expression_type_c::visit(CU_operator_c *symbol) { |
1358 void *visit_expression_type_c::visit(CU_operator_c *symbol) { |
1369 compute_input_operatores(symbol, "CU"); |
1359 check_il_fbcall(symbol, "CU"); |
1370 return NULL; |
1360 return NULL; |
1371 } |
1361 } |
1372 |
1362 |
1373 // SYM_REF0(CD_operator_c) |
1363 // SYM_REF0(CD_operator_c) |
1374 void *visit_expression_type_c::visit(CD_operator_c *symbol) { |
1364 void *visit_expression_type_c::visit(CD_operator_c *symbol) { |
1375 compute_input_operatores(symbol, "CD"); |
1365 check_il_fbcall(symbol, "CD"); |
1376 return NULL; |
1366 return NULL; |
1377 } |
1367 } |
1378 |
1368 |
1379 // SYM_REF0(PV_operator_c) |
1369 // SYM_REF0(PV_operator_c) |
1380 void *visit_expression_type_c::visit(PV_operator_c *symbol) { |
1370 void *visit_expression_type_c::visit(PV_operator_c *symbol) { |
1381 compute_input_operatores(symbol, "PV"); |
1371 check_il_fbcall(symbol, "PV"); |
1382 return NULL; |
1372 return NULL; |
1383 } |
1373 } |
1384 |
1374 |
1385 // SYM_REF0(IN_operator_c) |
1375 // SYM_REF0(IN_operator_c) |
1386 void *visit_expression_type_c::visit(IN_operator_c *symbol) { |
1376 void *visit_expression_type_c::visit(IN_operator_c *symbol) { |
1387 compute_input_operatores(symbol, "IN"); |
1377 check_il_fbcall(symbol, "IN"); |
1388 return NULL; |
1378 return NULL; |
1389 } |
1379 } |
1390 |
1380 |
1391 // SYM_REF0(PT_operator_c) |
1381 // SYM_REF0(PT_operator_c) |
1392 void *visit_expression_type_c::visit(PT_operator_c *symbol) { |
1382 void *visit_expression_type_c::visit(PT_operator_c *symbol) { |
1393 compute_input_operatores(symbol, "PT"); |
1383 check_il_fbcall(symbol, "PT"); |
1394 return NULL; |
1384 return NULL; |
1395 } |
1385 } |
1396 |
1386 |
1397 //SYM_REF0(AND_operator_c) |
1387 //SYM_REF0(AND_operator_c) |
1398 void *visit_expression_type_c::visit(AND_operator_c *symbol) { |
1388 void *visit_expression_type_c::visit(AND_operator_c *symbol) { |