197 /* B.1 - Common elements */ |
197 /* B.1 - Common elements */ |
198 /*************************/ |
198 /*************************/ |
199 /*******************************************/ |
199 /*******************************************/ |
200 /* B 1.1 - Letters, digits and identifiers */ |
200 /* B 1.1 - Letters, digits and identifiers */ |
201 /*******************************************/ |
201 /*******************************************/ |
202 void *visit(identifier_c *symbol) {return (void *)symbol->value;}; |
202 void *visit( identifier_c *symbol) {return (void *)symbol->value;}; |
|
203 void *visit(derived_datatype_identifier_c *symbol) {return (void *)symbol->value;}; |
203 |
204 |
204 /***********************************/ |
205 /***********************************/ |
205 /* B 1.3.1 - Elementary Data Types */ |
206 /* B 1.3.1 - Elementary Data Types */ |
206 /***********************************/ |
207 /***********************************/ |
207 void *visit(time_type_name_c *symbol) {return (void *)"TIME"; }; |
208 void *visit(time_type_name_c *symbol) {return (void *)"TIME"; }; |
245 void *visit(safeword_type_name_c *symbol) {return (void *)"SAFEWORD"; }; |
246 void *visit(safeword_type_name_c *symbol) {return (void *)"SAFEWORD"; }; |
246 void *visit(safelword_type_name_c *symbol) {return (void *)"SAFELWORD"; }; |
247 void *visit(safelword_type_name_c *symbol) {return (void *)"SAFELWORD"; }; |
247 void *visit(safedword_type_name_c *symbol) {return (void *)"SAFEDWORD"; }; |
248 void *visit(safedword_type_name_c *symbol) {return (void *)"SAFEDWORD"; }; |
248 void *visit(safestring_type_name_c *symbol) {return (void *)"SAFESTRING"; }; |
249 void *visit(safestring_type_name_c *symbol) {return (void *)"SAFESTRING"; }; |
249 void *visit(safewstring_type_name_c *symbol) {return (void *)"SAFEWSTRING"; }; |
250 void *visit(safewstring_type_name_c *symbol) {return (void *)"SAFEWSTRING"; }; |
|
251 |
|
252 /********************************/ |
|
253 /* B.1.3.2 - Generic data types */ |
|
254 /********************************/ |
|
255 void *visit(generic_type_any_c *symbol) {return (void *)"ANY"; }; |
250 |
256 |
251 /********************************/ |
257 /********************************/ |
252 /* B 1.3.3 - Derived data types */ |
258 /* B 1.3.3 - Derived data types */ |
253 /********************************/ |
259 /********************************/ |
254 /* simple_type_name ':' simple_spec_init */ |
260 /* simple_type_name ':' simple_spec_init */ |
415 |
421 |
416 symbol_c *get_datatype_info_c::get_struct_field_type_id(symbol_c *struct_datatype, symbol_c *struct_fieldname) { |
422 symbol_c *get_datatype_info_c::get_struct_field_type_id(symbol_c *struct_datatype, symbol_c *struct_fieldname) { |
417 return get_struct_info_c::get_field_type_id(struct_datatype, struct_fieldname); |
423 return get_struct_info_c::get_field_type_id(struct_datatype, struct_fieldname); |
418 } |
424 } |
419 |
425 |
|
426 |
|
427 |
420 symbol_c *get_datatype_info_c::get_array_storedtype_id(symbol_c *type_symbol) { |
428 symbol_c *get_datatype_info_c::get_array_storedtype_id(symbol_c *type_symbol) { |
421 // returns the datatype of the variables stored in the array |
429 // returns the datatype of the variables stored in the array |
422 symbol_c *basetype = search_base_type_c::get_basetype_decl(type_symbol); |
430 array_specification_c *symbol = NULL; |
423 array_specification_c *symbol = dynamic_cast<array_specification_c *>(basetype); |
431 if (NULL == symbol) symbol = dynamic_cast<array_specification_c *>(type_symbol); |
424 |
432 if (NULL == symbol) symbol = dynamic_cast<array_specification_c *>(search_base_type_c::get_basetype_decl(type_symbol)); |
425 if (NULL != symbol) |
433 if (NULL != symbol) |
426 return symbol->non_generic_type_name; |
434 return symbol->non_generic_type_name; |
427 return NULL; // this is not an array! |
435 return NULL; // this is not an array! |
428 } |
436 } |
429 |
437 |
430 |
438 |
|
439 |
|
440 |
431 /* Returns true if both datatypes are equivalent (not necessarily equal!). |
441 /* Returns true if both datatypes are equivalent (not necessarily equal!). |
432 * WARNING: May return true even though the datatypes are not the same/identicial!!! |
442 * WARNING: May return true even though the datatypes are not the same/identicial!!! |
433 * This occurs when at least one of the datatypes is of a generic |
443 * This occurs when at least one of the datatypes is of a generic |
434 * datatype (or a REF_TO a generic datatype). |
444 * datatype (or a REF_TO a generic datatype). |
435 * (Generic dataypes: ANY, ANY_INT, ANY_NUM, ...) |
445 * (Generic dataypes: ANY, ANY_INT, ANY_NUM, ...) |
437 * NOTE: Currently stage1_2 only allows the use of the ANY keyword when in conjuntion with |
447 * NOTE: Currently stage1_2 only allows the use of the ANY keyword when in conjuntion with |
438 * the REF_TO keyword (i.e. REF_TO ANY), so when handling non REF_TO datatypes, |
448 * the REF_TO keyword (i.e. REF_TO ANY), so when handling non REF_TO datatypes, |
439 * this function will currently only return true if the dataypes are identicial. |
449 * this function will currently only return true if the dataypes are identicial. |
440 */ |
450 */ |
441 |
451 |
442 /* NOTE: Currently the datatype model used by matiec considers any implicitly defined datatype |
452 /* NOTE: matiec supports a strict and a relaxed data type model. Which datatype model to use is chosen |
|
453 * as a command line option. |
|
454 * |
|
455 * |
|
456 * The Strict Datatype Model |
|
457 * ========================= |
|
458 * The strict datatype model used by matiec considers any implicitly defined datatype |
443 * (e.g. an array datatype defined in the variable declaration itself, instead of inside a TYPE ... END_TYPE |
459 * (e.g. an array datatype defined in the variable declaration itself, instead of inside a TYPE ... END_TYPE |
444 * construct) to be different (i.e. not the same datatype, and therefore not compatible) to any other |
460 * construct) to be different (i.e. not the same datatype, and therefore not compatible) to any other |
445 * datatype, including with datatypes declared identically to the implicit datatype. |
461 * datatype, including with datatypes declared identically to the implicit datatype. |
446 * e.g. |
462 * e.g. |
447 * TYPE my_array_t: ARRAY [1..3] OF INT; END_TYPE; |
463 * TYPE my_array_t: ARRAY [1..3] OF INT; END_TYPE; |
457 * There are 2 exceptions to the above rule: |
473 * There are 2 exceptions to the above rule: |
458 * (1) Datatypes that are directly derived from other datatypes. |
474 * (1) Datatypes that are directly derived from other datatypes. |
459 * (this rule is specified in the standard, so we follow it!) |
475 * (this rule is specified in the standard, so we follow it!) |
460 * (2) REF_TO datatypes that reference the same datatype |
476 * (2) REF_TO datatypes that reference the same datatype |
461 * (I dont think the standard says anything about this!) |
477 * (I dont think the standard says anything about this!) |
|
478 * (This rule should actually be part of the relaxed datatype model, but for now we |
|
479 * will leave it in the strict datatype model) |
462 * |
480 * |
463 * TYPE |
481 * TYPE |
464 * my_array_1_t: ARRAY [1..3] OF INT; |
482 * my_array_1_t: ARRAY [1..3] OF INT; |
465 * my_array_2_t: ARRAY [1..3] OF INT; |
483 * my_array_2_t: ARRAY [1..3] OF INT; |
466 * my_array_3_t: my_array_1_t; |
484 * my_array_3_t: my_array_1_t; |
509 * |
527 * |
510 * Rule/exception (2) goes against the datatype model used for all other datatypes. |
528 * Rule/exception (2) goes against the datatype model used for all other datatypes. |
511 * This rule was adopted as without it, the datatype of the value returned by the REF() |
529 * This rule was adopted as without it, the datatype of the value returned by the REF() |
512 * operator would be considered distinct to all other datatypes, and therefore the |
530 * operator would be considered distinct to all other datatypes, and therefore the |
513 * REF() operator would be essentially useless. |
531 * REF() operator would be essentially useless. |
|
532 * |
|
533 * |
|
534 * The Relaxed Datatype Model |
|
535 * ========================== |
|
536 * In the relaxed datatype model, the same rules as the strict datatype model are followed, with the |
|
537 * exception of implicitly defined array datatypes, which are now considered equal if they define |
|
538 * identical datatypes. |
|
539 * This means that in the following example |
|
540 * TYPE |
|
541 * array_t: ARRAY [1..3] OF INT; |
|
542 * END_TYPE; |
|
543 * VAR |
|
544 * array_var1: array_t; |
|
545 * array_var2: ARRAY [1..3] OF INT; |
|
546 * array_var3: ARRAY [1..3] OF INT; |
|
547 * END_VAR |
|
548 * |
|
549 * all three variables (array_var1, array_var2, and array_var3) are considered as being of the |
|
550 * same datatype. |
|
551 * |
|
552 * Note that the strict datatype model currently actually uses a relaxed datatype model for |
|
553 * REF_TO datatypes, so in both the relaxed and strict datatype models matiec currently uses a |
|
554 * relaxed datatype equivalince for REF_TO datatypes. |
514 */ |
555 */ |
515 bool get_datatype_info_c::is_type_equal(symbol_c *first_type, symbol_c *second_type) { |
556 bool get_datatype_info_c::is_type_equal(symbol_c *first_type, symbol_c *second_type) { |
516 if (!is_type_valid( first_type)) {return false;} |
557 if (!is_type_valid( first_type)) {return false;} |
517 if (!is_type_valid(second_type)) {return false;} |
558 if (!is_type_valid(second_type)) {return false;} |
518 |
559 |
520 /* For the moment, we only support the ANY generic datatype! */ |
561 /* For the moment, we only support the ANY generic datatype! */ |
521 if ((is_ANY_generic_type( first_type)) || |
562 if ((is_ANY_generic_type( first_type)) || |
522 (is_ANY_generic_type(second_type))) {return true;} |
563 (is_ANY_generic_type(second_type))) {return true;} |
523 |
564 |
524 /* ANY_ELEMENTARY */ |
565 /* ANY_ELEMENTARY */ |
525 if ((is_ANY_ELEMENTARY(first_type)) && |
566 if ((is_ANY_ELEMENTARY_compatible(first_type)) && |
526 (typeid(*first_type) == typeid(*second_type))) {return true;} |
567 (typeid(*first_type) == typeid(*second_type))) {return true;} |
527 |
568 if ( is_ANY_ELEMENTARY_compatible(first_type) |
528 /* ANY_DERIVED */ |
569 || is_ANY_ELEMENTARY_compatible(second_type)) {return false;} |
|
570 |
|
571 /* ANY_DERIVED */ |
|
572 // from now on, we are sure both datatypes are derived... |
529 if (is_ref_to(first_type) && is_ref_to(second_type)) { |
573 if (is_ref_to(first_type) && is_ref_to(second_type)) { |
530 return is_type_equal(search_base_type_c::get_basetype_decl(get_ref_to(first_type )), |
574 return is_type_equal(search_base_type_c::get_basetype_decl(get_ref_to(first_type )), |
531 search_base_type_c::get_basetype_decl(get_ref_to(second_type))); |
575 search_base_type_c::get_basetype_decl(get_ref_to(second_type))); |
532 } |
576 } |
533 return (first_type == second_type); |
577 |
534 } |
578 // check for same datatype |
|
579 if (first_type == second_type) {return true;} |
|
580 |
|
581 // remaining type equivalence rules are not applied in the strict datatype model |
|
582 //if (!option...relaxed_datatypemodel) |
|
583 //return false; |
|
584 |
|
585 // check for array equivalence usig the relaxed datatype model |
|
586 if (is_arraytype_equal_relaxed(first_type, second_type)) {return true;} |
|
587 |
|
588 return false; |
|
589 } |
|
590 |
|
591 |
|
592 |
|
593 /* A local helper function that transforms strings conatining signed_integers into a normalized |
|
594 * form, so they can be compared for equality. |
|
595 * examples: |
|
596 * 82 -> 82 |
|
597 * 8_2 -> 82 |
|
598 * +82 -> 82 |
|
599 * 082 -> 82 |
|
600 * +082 -> 82 |
|
601 * -82 -> -82 |
|
602 * -8_2 -> -82 |
|
603 * -082 -> -82 |
|
604 */ |
|
605 #include <string.h> /* required for strlen() */ |
|
606 static std::string normalize_integer(symbol_c *symbol) { |
|
607 integer_c *token = dynamic_cast<integer_c *>(symbol); |
|
608 if (NULL == token) ERROR; |
|
609 |
|
610 std::string str = ""; |
|
611 bool leading_zero = true; |
|
612 unsigned int offset = 0; |
|
613 |
|
614 // handle any possible leading '-' or '+' |
|
615 if (token->value[0] == '-') { |
|
616 // '-' -> retained |
|
617 str += token->value[0]; |
|
618 offset++; |
|
619 } else if (token->value[0] == '+') |
|
620 // '+' -> skip, so '+8' and '8' will both result in '8' |
|
621 offset++; |
|
622 |
|
623 for (unsigned int i = offset; i < strlen(token->value); i++) { |
|
624 if (leading_zero && (token->value[i] != '0')) |
|
625 leading_zero = false; |
|
626 if (!leading_zero && token->value[i] != '_') |
|
627 str += token->value[i]; |
|
628 } |
|
629 return str; |
|
630 } |
|
631 |
|
632 |
|
633 /* A helper method to get_datatype_info_c::is_type_equal() |
|
634 * Assuming the relaxed datatype model, determine whether the two array datatypes are equal/equivalent |
|
635 */ |
|
636 bool get_datatype_info_c::is_arraytype_equal_relaxed(symbol_c *first_type, symbol_c *second_type) { |
|
637 symbol_c *basetype_1 = search_base_type_c::get_basetype_decl( first_type); |
|
638 symbol_c *basetype_2 = search_base_type_c::get_basetype_decl(second_type); |
|
639 array_specification_c *array_1 = dynamic_cast<array_specification_c *>(basetype_1); |
|
640 array_specification_c *array_2 = dynamic_cast<array_specification_c *>(basetype_2); |
|
641 |
|
642 // are they both array datatypes? |
|
643 if ((NULL == array_1) || (NULL == array_2)) |
|
644 return false; |
|
645 |
|
646 // number of subranges |
|
647 array_subrange_list_c *subrange_list_1 = dynamic_cast<array_subrange_list_c *>(array_1->array_subrange_list); |
|
648 array_subrange_list_c *subrange_list_2 = dynamic_cast<array_subrange_list_c *>(array_2->array_subrange_list); |
|
649 if ((NULL == subrange_list_1) || (NULL == subrange_list_2)) ERROR; |
|
650 if (subrange_list_1->n != subrange_list_2->n) |
|
651 return false; |
|
652 |
|
653 // comparison of each subrange start and end elements |
|
654 for (int i = 0; i < subrange_list_1->n; i++) { |
|
655 subrange_c *subrange_1 = dynamic_cast<subrange_c *>(subrange_list_1->elements[i]); |
|
656 subrange_c *subrange_2 = dynamic_cast<subrange_c *>(subrange_list_2->elements[i]); |
|
657 if ((NULL == subrange_1) || (NULL == subrange_2)) ERROR; |
|
658 #if 0 |
|
659 /* An alternative method of checking whether the subranges have the same values, using the result of the constant folding agorithm. |
|
660 * This method has the drawback that it inserts a dependency on having to run the constant folding algorithm before |
|
661 * the get_datatype_info_c::is_type_equal() method is called. |
|
662 * The probably slower alternative of comparing the strings themselves is therefor used. |
|
663 */ |
|
664 if (!constant_folding_c::is_equal_cvalue(subrange_1->lower_limit, subrange_2->lower_limit)) return false; |
|
665 if (!constant_folding_c::is_equal_cvalue(subrange_1->upper_limit, subrange_2->upper_limit)) return false; |
|
666 #endif |
|
667 if (normalize_integer(subrange_1->lower_limit) != normalize_integer(subrange_2->lower_limit)) return false; |
|
668 if (normalize_integer(subrange_1->upper_limit) != normalize_integer(subrange_2->upper_limit)) return false; |
|
669 } |
|
670 |
|
671 return is_type_equal(search_base_type_c::get_basetype_decl(array_1->non_generic_type_name), |
|
672 search_base_type_c::get_basetype_decl(array_2->non_generic_type_name)); |
|
673 } |
|
674 |
|
675 |
|
676 |
535 |
677 |
536 |
678 |
537 bool get_datatype_info_c::is_type_valid(symbol_c *type) { |
679 bool get_datatype_info_c::is_type_valid(symbol_c *type) { |
538 if (NULL == type) {return false;} |
680 if (NULL == type) {return false;} |
539 if (typeid(*type) == typeid(invalid_type_name_c)) {return false;} |
681 if (typeid(*type) == typeid(invalid_type_name_c)) {return false;} |