1 /* |
1 /* |
2 * matiec - a compiler for the programming languages defined in IEC 61131-3 |
2 * matiec - a compiler for the programming languages defined in IEC 61131-3 |
3 * |
3 * |
4 * Copyright (C) 2009-2011 Mario de Sousa (msousa@fe.up.pt) |
4 * Copyright (C) 2009-2011 Mario de Sousa (msousa@fe.up.pt) |
5 * Copyright (C) 20011-2012 Manuele Conti (manuele.conti@sirius-es.it) |
5 * Copyright (C) 2011-2012 Manuele Conti (manuele.conti@sirius-es.it) |
6 * Copyright (C) 20011-2012 Matteo Facchinetti (matteo.facchinetti@sirius-es.it) |
6 * Copyright (C) 2011-2012 Matteo Facchinetti (matteo.facchinetti@sirius-es.it) |
7 * |
7 * |
8 * This program is free software: you can redistribute it and/or modify |
8 * This program is free software: you can redistribute it and/or modify |
9 * it under the terms of the GNU General Public License as published by |
9 * it under the terms of the GNU General Public License as published by |
10 * the Free Software Foundation, either version 3 of the License, or |
10 * the Free Software Foundation, either version 3 of the License, or |
11 * (at your option) any later version. |
11 * (at your option) any later version. |
627 |
627 |
628 /* | label ':' [il_incomplete_instruction] eol_list */ |
628 /* | label ':' [il_incomplete_instruction] eol_list */ |
629 // SYM_REF2(il_instruction_c, label, il_instruction) |
629 // SYM_REF2(il_instruction_c, label, il_instruction) |
630 void *print_datatypes_error_c::visit(il_instruction_c *symbol) { |
630 void *print_datatypes_error_c::visit(il_instruction_c *symbol) { |
631 if (NULL != symbol->il_instruction) { |
631 if (NULL != symbol->il_instruction) { |
632 // #if 0 |
|
633 il_instruction_c tmp_prev_il_instruction(NULL, NULL); |
632 il_instruction_c tmp_prev_il_instruction(NULL, NULL); |
|
633 /* When handling a il function call, this fake_prev_il_instruction may be used as a standard function call parameter, so it is important that |
|
634 * it contain some valid location info so error messages make sense. |
|
635 */ |
|
636 if (symbol->prev_il_instruction.size() > 0) { |
|
637 /* since we don't want to copy all that data one variable at a time, we copy it all at once */ |
|
638 /* This has the advantage that, if we ever add some more data to the base symbol_c later on, we will not need to |
|
639 * change the following line to guarantee that the data is copied correctly! |
|
640 * However, it does have the drawback of copying more data than what we want! |
|
641 * In order to only copy the data in the base class symbol_c, we use the tmp_symbol pointer! |
|
642 * I (mario) have checked with a debugger, and it is working as intended! |
|
643 */ |
|
644 symbol_c *tmp_symbol1 = symbol->prev_il_instruction[0]; |
|
645 symbol_c *tmp_symbol2 = &tmp_prev_il_instruction; |
|
646 *tmp_symbol2 = *tmp_symbol1; |
|
647 /* we do not want to copy the datatype variable, so we reset it to NULL */ |
|
648 tmp_prev_il_instruction.datatype = NULL; |
|
649 /* We don't need to worry about the candidate_datatype list (which we don't want to copy just yet), since that will |
|
650 * be reset to the correct value when we call intersect_prev_candidate_datatype_lists() later on... |
|
651 */ |
|
652 } |
634 /* the narrow algorithm will need access to the intersected candidate_datatype lists of all prev_il_instructions, as well as the |
653 /* the narrow algorithm will need access to the intersected candidate_datatype lists of all prev_il_instructions, as well as the |
635 * list of the prev_il_instructions. |
654 * list of the prev_il_instructions. |
636 * Instead of creating two 'global' (within the class) variables, we create a single il_instruction_c variable (fake_prev_il_instruction), |
655 * Instead of creating two 'global' (within the class) variables, we create a single il_instruction_c variable (fake_prev_il_instruction), |
637 * and shove that data into this single variable. |
656 * and shove that data into this single variable. |
638 */ |
657 */ |
639 tmp_prev_il_instruction.prev_il_instruction = symbol->prev_il_instruction; |
658 tmp_prev_il_instruction.prev_il_instruction = symbol->prev_il_instruction; |
640 intersect_prev_candidate_datatype_lists(&tmp_prev_il_instruction); |
659 intersect_prev_candidate_datatype_lists(&tmp_prev_il_instruction); |
641 if (are_all_datatypes_of_prev_il_instructions_datatypes_equal(symbol)) |
660 if (are_all_datatypes_of_prev_il_instructions_datatypes_equal(symbol)) |
642 if (symbol->prev_il_instruction.size() > 0) |
661 if (symbol->prev_il_instruction.size() > 0) |
643 tmp_prev_il_instruction.datatype = (symbol->prev_il_instruction[0])->datatype; |
662 tmp_prev_il_instruction.datatype = (symbol->prev_il_instruction[0])->datatype; |
|
663 |
644 /* Tell the il_instruction the datatype that it must generate - this was chosen by the next il_instruction (remember: we are iterating backwards!) */ |
664 /* Tell the il_instruction the datatype that it must generate - this was chosen by the next il_instruction (remember: we are iterating backwards!) */ |
645 fake_prev_il_instruction = &tmp_prev_il_instruction; |
665 fake_prev_il_instruction = &tmp_prev_il_instruction; |
646 symbol->il_instruction->accept(*this); |
666 symbol->il_instruction->accept(*this); |
647 fake_prev_il_instruction = NULL; |
667 fake_prev_il_instruction = NULL; |
648 // #endif |
|
649 // if (symbol->prev_il_instruction.size() > 1) ERROR; /* only valid for now! */ |
|
650 // if (symbol->prev_il_instruction.size() == 0) prev_il_instruction = NULL; |
|
651 // else prev_il_instruction = symbol->prev_il_instruction[0]; |
|
652 |
|
653 // symbol->il_instruction->accept(*this); |
|
654 // prev_il_instruction = NULL; |
|
655 } |
668 } |
656 |
669 |
657 return NULL; |
670 return NULL; |
658 } |
671 } |
659 |
672 |