author | mjsousa |
Sun, 14 Dec 2014 18:40:20 +0000 | |
changeset 963 | e3d4dca7520b |
parent 945 | 477393b00f95 |
child 964 | 5f4dfe6670da |
permissions | -rw-r--r-- |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
1 |
/* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
2 |
* matiec - a compiler for the programming languages defined in IEC 61131-3 |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
3 |
* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
4 |
* Copyright (C) 2003-2011 Mario de Sousa (msousa@fe.up.pt) |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
5 |
* Copyright (C) 2012 Manuele Conti (conti.ma@alice.it) |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
6 |
* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
7 |
* This program is free software: you can redistribute it and/or modify |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
8 |
* it under the terms of the GNU General Public License as published by |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
9 |
* the Free Software Foundation, either version 3 of the License, or |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
10 |
* (at your option) any later version. |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
11 |
* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
12 |
* This program is distributed in the hope that it will be useful, |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
13 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
14 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
15 |
* GNU General Public License for more details. |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
16 |
* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
17 |
* You should have received a copy of the GNU General Public License |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
18 |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
19 |
* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
20 |
* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
21 |
* This code is made available on the understanding that it will not be |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
22 |
* used in safety-critical situations without a full and competent review. |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
23 |
*/ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
24 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
25 |
/* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
26 |
* An IEC 61131-3 compiler. |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
27 |
* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
28 |
* Based on the |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
29 |
* FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
30 |
* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
31 |
*/ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
32 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
33 |
|
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
34 |
|
640 | 35 |
/* TODO: |
36 |
* - Add support for comparison (= and !=) of enumeration literals! |
|
37 |
* We will need to add another const_value entry to the symbol_c, containing the |
|
38 |
* possible enumeration value of the enum constant! |
|
39 |
* Doing this will allow us to more easily implement a constant_propagation_c later on! |
|
40 |
* |
|
41 |
* - Add support for comparison (= and !=) of the exact same variable |
|
42 |
* (e.g. if (int_v = int_v) then ...) |
|
43 |
*/ |
|
44 |
||
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
45 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
46 |
|
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
47 |
/* Do constant folding... |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
48 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
49 |
* I.e., Determine the value of all expressions in which only constant values (i.e. literals) are used. |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
50 |
* The (constant) result of each operation is stored (annotated) in the respective operation symbol |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
51 |
* (e.g.: add_expression_c) in the abstract syntax tree, |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
52 |
* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
53 |
* For example: |
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
54 |
* 2 + 3 -> the constant value '5' is stored in the add_expression_c symbol. |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
55 |
* 22.2 - 5.0 -> the constant value '17.2' is stored in the add_expression_c symbol. |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
56 |
* etc... |
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
57 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
58 |
* |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
59 |
* NOTE 1 |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
60 |
* Some operations and constants can have multiple data types. For example, |
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
61 |
* 1 AND 0 |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
62 |
* may be either a BOOL, BYTE, WORD or LWORD. |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
63 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
64 |
* The same happens with |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
65 |
* 1 + 2 |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
66 |
* which may be signed (e.g. INT) or unsigned (UINT) |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
67 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
68 |
* For the above reason, instead of storing a single constant value, we actually store 4: |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
69 |
* - bool |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
70 |
* - uint64 |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
71 |
* - int64 |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
72 |
* - real64 |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
73 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
74 |
* Additionally, since the result of an operation may result in an overflow, we actually |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
75 |
* store the result inside a struct (defined in absyntax.hh) |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
76 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
77 |
* ** During stage 3 (semantic analysis/checking) we will be doing constant folding. |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
78 |
* * That algorithm will anotate the abstract syntax tree with the result of operations |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
79 |
* * on literals (i.e. 44 + 55 will store the result 99). |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
80 |
* * Since the same source code (e.g. 1 + 0) may actually be a BOOL or an ANY_INT, |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
81 |
* * or an ANY_BIT, we need to handle all possibilities, and determine the result of the |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
82 |
* * operation assuming each type. |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
83 |
* * For this reason, we have one entry for each possible type, with some expressions |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
84 |
* * having more than one entry filled in! |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
85 |
* ** |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
86 |
* typedef enum { cs_undefined, // not defined --> const_value is not valid! |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
87 |
* cs_const_value, // const value is valid |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
88 |
* cs_overflow // result produced overflow or underflow --> const_value is not valid! |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
89 |
* } const_status_t; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
90 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
91 |
* typedef struct { |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
92 |
* const_status_t status; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
93 |
* real64_t value; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
94 |
* } const_value_real64_t; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
95 |
* const_value_real64_t *const_value_real64; // when NULL --> UNDEFINED |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
96 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
97 |
* typedef struct { |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
98 |
* const_status_t status; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
99 |
* int64_t value; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
100 |
* } const_value_int64_t; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
101 |
* const_value_int64_t *const_value_int64; // when NULL --> UNDEFINED |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
102 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
103 |
* typedef struct { |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
104 |
* const_status_t status; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
105 |
* uint64_t value; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
106 |
* } const_value_uint64_t; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
107 |
* const_value_uint64_t *const_value_uint64; // when NULL --> UNDEFINED |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
108 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
109 |
* typedef struct { |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
110 |
* const_status_t status; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
111 |
* bool value; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
112 |
* } const_value_bool_t; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
113 |
* const_value_bool_t *const_value_bool; // when NULL --> UNDEFINED |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
114 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
115 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
116 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
117 |
* NOTE 2 |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
118 |
* This file does not print out any error messages! |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
119 |
* We cannot really print out error messages when we find an overflow. Since each operation |
781
577547327f67
Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents:
780
diff
changeset
|
120 |
* (symbol in the abstract syntax tree for that operation) will have up to 4 constant results, |
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
121 |
* it may happen that some of them overflow, while other do not. |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
122 |
* We must wait for data type checking to determine the exact data type of each expression |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
123 |
* before we can decide whether or not we should print out an overflow error message. |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
124 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
125 |
* For this reason, this visitor merely annotates the abstract syntax tree, and leaves the |
781
577547327f67
Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents:
780
diff
changeset
|
126 |
* actually printing of errors for the print_datatype_errors_c class! |
577547327f67
Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents:
780
diff
changeset
|
127 |
* |
577547327f67
Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents:
780
diff
changeset
|
128 |
* NOTE 3 |
577547327f67
Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents:
780
diff
changeset
|
129 |
* Constant Folding class is extended with a implementation constant propagation algorithm |
577547327f67
Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents:
780
diff
changeset
|
130 |
* by Mario de Sousa. |
577547327f67
Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents:
780
diff
changeset
|
131 |
* Main idea is not to implement a general constant propagation algorithm but to reinterpret it |
577547327f67
Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents:
780
diff
changeset
|
132 |
* for visitor classes. |
577547327f67
Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents:
780
diff
changeset
|
133 |
* We declared a hash map, it contains a variables list linked with current constant values. |
577547327f67
Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents:
780
diff
changeset
|
134 |
* During expression evaluation we can retrieve a constant value to symbolic variables getting it from the map. |
577547327f67
Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents:
780
diff
changeset
|
135 |
* Also at join source points we use a meet semilattice rules to merge current values between a block |
577547327f67
Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents:
780
diff
changeset
|
136 |
* and adjacent block. |
577547327f67
Add note about How Constant Folding class is extended with a implementation constant propagation algorithm
Manuele Conti <conti.ma@alice.it>
parents:
780
diff
changeset
|
137 |
* |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
138 |
*/ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
139 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
140 |
#include "constant_folding.hh" |
565
8acbddf75333
Fix a few bugs of previous commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
564
diff
changeset
|
141 |
#include <stdlib.h> /* required for malloc() */ |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
142 |
|
596
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
143 |
#include <string.h> /* required for strlen() */ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
144 |
// #include <stdlib.h> /* required for atoi() */ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
145 |
#include <errno.h> /* required for errno */ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
146 |
|
607
be9ba3531afb
cleaning up code. Changing HUGE_VAL to INFINITY.
Mario de Sousa <msousa@fe.up.pt>
parents:
604
diff
changeset
|
147 |
#include "../main.hh" // required for uint8_t, real_64_t, ..., and the macros NAN, INFINITY, INT8_MAX, REAL32_MAX, ... */ |
579
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
148 |
|
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
149 |
|
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
150 |
|
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
151 |
|
568
5f79478142d7
make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents:
567
diff
changeset
|
152 |
|
5f79478142d7
make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents:
567
diff
changeset
|
153 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
154 |
#define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order) ? (symbol1) : (symbol2)) |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
155 |
#define LAST_(symbol1, symbol2) (((symbol1)->last_order > (symbol2)->last_order) ? (symbol1) : (symbol2)) |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
156 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
157 |
#define STAGE3_ERROR(error_level, symbol1, symbol2, ...) { \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
158 |
if (current_display_error_level >= error_level) { \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
159 |
fprintf(stderr, "%s:%d-%d..%d-%d: error: ", \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
160 |
FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
161 |
LAST_(symbol1,symbol2) ->last_line, LAST_(symbol1,symbol2) ->last_column);\ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
162 |
fprintf(stderr, __VA_ARGS__); \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
163 |
fprintf(stderr, "\n"); \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
164 |
error_count++; \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
165 |
} \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
166 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
167 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
168 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
169 |
#define STAGE3_WARNING(symbol1, symbol2, ...) { \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
170 |
fprintf(stderr, "%s:%d-%d..%d-%d: warning: ", \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
171 |
FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
172 |
LAST_(symbol1,symbol2) ->last_line, LAST_(symbol1,symbol2) ->last_column);\ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
173 |
fprintf(stderr, __VA_ARGS__); \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
174 |
fprintf(stderr, "\n"); \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
175 |
warning_found = true; \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
176 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
177 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
178 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
179 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
180 |
|
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
181 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
182 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
183 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
184 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
185 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
186 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
187 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
188 |
|
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
189 |
#define SET_CVALUE(dtype, symbol, new_value) {((symbol)->const_value._##dtype.value) = new_value; ((symbol)->const_value._##dtype.status) = symbol_c::cs_const_value;} |
612 | 190 |
#define GET_CVALUE(dtype, symbol) ((symbol)->const_value._##dtype.value) |
191 |
#define SET_OVFLOW(dtype, symbol) ((symbol)->const_value._##dtype.status) = symbol_c::cs_overflow |
|
192 |
#define SET_NONCONST(dtype, symbol) ((symbol)->const_value._##dtype.status) = symbol_c::cs_non_const |
|
193 |
||
194 |
#define VALID_CVALUE(dtype, symbol) (symbol_c::cs_const_value == (symbol)->const_value._##dtype.status) |
|
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
195 |
#define IS_OVFLOW(dtype, symbol) (symbol_c::cs_overflow == (symbol)->const_value._##dtype.status) |
648
5ca2aabb8bcb
More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents:
643
diff
changeset
|
196 |
#define IS_NONCONST(dtype, symbol) (symbol_c::cs_non_const == (symbol)->const_value._##dtype.status) |
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
197 |
#define ISZERO_CVALUE(dtype, symbol) ((VALID_CVALUE(dtype, symbol)) && (GET_CVALUE(dtype, symbol) == 0)) |
575 | 198 |
|
612 | 199 |
#define ISEQUAL_CVALUE(dtype, symbol1, symbol2) \ |
200 |
(VALID_CVALUE(dtype, symbol1) && VALID_CVALUE(dtype, symbol2) && (GET_CVALUE(dtype, symbol1) == GET_CVALUE(dtype, symbol2))) |
|
201 |
||
648
5ca2aabb8bcb
More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents:
643
diff
changeset
|
202 |
#define DO_BINARY_OPER(oper_type, operation, res_type, operand1, operand2) { \ |
5ca2aabb8bcb
More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents:
643
diff
changeset
|
203 |
if (VALID_CVALUE(oper_type, operand1) && VALID_CVALUE(oper_type, operand2)) \ |
5ca2aabb8bcb
More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents:
643
diff
changeset
|
204 |
{SET_CVALUE(res_type, symbol, GET_CVALUE(oper_type, operand1) operation GET_CVALUE(oper_type, operand2));}\ |
5ca2aabb8bcb
More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents:
643
diff
changeset
|
205 |
else if (IS_OVFLOW (oper_type, operand1) || IS_OVFLOW (oper_type, operand2)) \ |
5ca2aabb8bcb
More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents:
643
diff
changeset
|
206 |
{SET_OVFLOW(res_type, symbol);} /* does it really make sense to set OVFLOW when restype is boolean?? */ \ |
5ca2aabb8bcb
More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents:
643
diff
changeset
|
207 |
else if (IS_NONCONST (oper_type, operand1) || IS_NONCONST (oper_type, operand2)) \ |
5ca2aabb8bcb
More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents:
643
diff
changeset
|
208 |
{SET_NONCONST(res_type, symbol);} \ |
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
209 |
} |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
210 |
|
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
211 |
#define DO_UNARY_OPER(dtype, operation, operand) { \ |
648
5ca2aabb8bcb
More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents:
643
diff
changeset
|
212 |
if (VALID_CVALUE(dtype, operand)) \ |
5ca2aabb8bcb
More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents:
643
diff
changeset
|
213 |
{SET_CVALUE(dtype, symbol, operation GET_CVALUE(dtype, operand));} \ |
5ca2aabb8bcb
More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents:
643
diff
changeset
|
214 |
else if (IS_OVFLOW (dtype, operand)) \ |
5ca2aabb8bcb
More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents:
643
diff
changeset
|
215 |
{SET_OVFLOW(dtype, symbol);} \ |
5ca2aabb8bcb
More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents:
643
diff
changeset
|
216 |
else if (IS_NONCONST (dtype, operand)) \ |
5ca2aabb8bcb
More precise handling of const value status.
Mario de Sousa <msousa@fe.up.pt>
parents:
643
diff
changeset
|
217 |
{SET_NONCONST(dtype, symbol);} \ |
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
218 |
} |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
219 |
|
776
96a1199d0739
Fix comment about meet semilattice rules.
Manuele Conti <conti.ma@alice.it>
parents:
774
diff
changeset
|
220 |
/* Constant Propagation: Rules for Meet from "Cooper K., Torczon L. - Engineering a Compiler, Second Edition - 2011" |
96a1199d0739
Fix comment about meet semilattice rules.
Manuele Conti <conti.ma@alice.it>
parents:
774
diff
changeset
|
221 |
* at 9.3 Static Single-Assignment Form page 517 |
96a1199d0739
Fix comment about meet semilattice rules.
Manuele Conti <conti.ma@alice.it>
parents:
774
diff
changeset
|
222 |
* - any * undefined = any |
96a1199d0739
Fix comment about meet semilattice rules.
Manuele Conti <conti.ma@alice.it>
parents:
774
diff
changeset
|
223 |
* - any * non_const = non_const |
96a1199d0739
Fix comment about meet semilattice rules.
Manuele Conti <conti.ma@alice.it>
parents:
774
diff
changeset
|
224 |
* - constant * constant = constant (if equal) |
96a1199d0739
Fix comment about meet semilattice rules.
Manuele Conti <conti.ma@alice.it>
parents:
774
diff
changeset
|
225 |
* - constant * constant = non_const (if not equal) |
774
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
226 |
*/ |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
227 |
#define COMPUTE_MEET_SEMILATTICE(dtype, c1, c2, resValue) {\ |
776
96a1199d0739
Fix comment about meet semilattice rules.
Manuele Conti <conti.ma@alice.it>
parents:
774
diff
changeset
|
228 |
if (( c1._##dtype.value != c2._##dtype.value && c2._##dtype.status == symbol_c::cs_const_value &&\ |
96a1199d0739
Fix comment about meet semilattice rules.
Manuele Conti <conti.ma@alice.it>
parents:
774
diff
changeset
|
229 |
c1._##dtype.status == symbol_c::cs_const_value) ||\ |
774
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
230 |
( c1._##dtype.status == symbol_c::cs_non_const && c2._##dtype.status == symbol_c::cs_const_value ) ||\ |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
231 |
( c2._##dtype.status == symbol_c::cs_non_const && c1._##dtype.status == symbol_c::cs_const_value )) {\ |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
232 |
resValue._##dtype.status = symbol_c::cs_non_const;\ |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
233 |
} else {\ |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
234 |
resValue._##dtype.status = symbol_c::cs_const_value;\ |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
235 |
resValue._##dtype.value = c1._##dtype.value;\ |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
236 |
}\ |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
237 |
} |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
238 |
|
788
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
239 |
typedef std::map <std::string, symbol_c::const_value_t> map_values_t; |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
240 |
|
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
241 |
static map_values_t values; |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
242 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
243 |
|
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
244 |
|
596
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
245 |
/***********************************************************************/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
246 |
/***********************************************************************/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
247 |
/***********************************************************************/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
248 |
/*** convert string to numerical value ***/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
249 |
/***********************************************************************/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
250 |
/***********************************************************************/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
251 |
/***********************************************************************/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
252 |
|
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
253 |
|
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
254 |
|
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
255 |
/* To allow the compiler to be portable, we cannot assume that int64_t is mapped onto long long int, |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
256 |
* so we cannot call strtoll() and strtoull() in extract_int64() and extract_uint64(). |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
257 |
* |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
258 |
* So, we create our own strtouint64() and strtoint64() functions. |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
259 |
* (We actually call them matiec_strtoint64() so they will not clash with any function |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
260 |
* that may be added to the standard library in the future). |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
261 |
* We actually create several of each, and let the compiler choose which is the correct one, |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
262 |
* by having it resolve the call to the overloaded function. For the C++ compiler to be able |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
263 |
* to resolve this ambiguity, we need to add a dummy parameter to each function! |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
264 |
* |
640 | 265 |
* TODO: support platforms (where the compiler will run) in which int64_t is mapped onto int !! |
266 |
* Is this really needed? |
|
267 |
* Currently, when trying to compile matiec on sych a platform, the C++ compiler will not |
|
268 |
* find any apropriate matiec_strtoint64() to call, so matiec will not be able to be compiled. |
|
269 |
* If you need this, you are welcome to fix it yourself... |
|
596
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
270 |
*/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
271 |
static int64_t matiec_strtoint64 ( long int *dummy, const char *nptr, char **endptr, int base) {return strtol (nptr, endptr, base);} |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
272 |
static int64_t matiec_strtoint64 ( long long int *dummy, const char *nptr, char **endptr, int base) {return strtoll (nptr, endptr, base);} |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
273 |
|
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
274 |
static uint64_t matiec_strtouint64(unsigned long int *dummy, const char *nptr, char **endptr, int base) {return strtoul (nptr, endptr, base);} |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
275 |
static uint64_t matiec_strtouint64(unsigned long long int *dummy, const char *nptr, char **endptr, int base) {return strtoull(nptr, endptr, base);} |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
276 |
|
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
277 |
|
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
278 |
/* extract the value of an integer from an integer_c object !! */ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
279 |
/* NOTE: it must ignore underscores! */ |
601
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
280 |
/* NOTE: To follow the basic structure used throughout the compiler's code, we should really be |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
281 |
* writing this as a visitor_c (and do away with the dynamic casts!), but since we only have 3 distinct |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
282 |
* symbol class types to handle, it is probably easier to read if we write it as a standard function... |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
283 |
*/ |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
284 |
int64_t extract_int64_value(symbol_c *sym, bool *overflow) { |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
285 |
int64_t ret; |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
286 |
std::string str = ""; |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
287 |
char *endptr; |
735
0304ff59fd7f
Fix some important clang++ warnings.
Manuele Conti <conti.ma@alice.it>
parents:
690
diff
changeset
|
288 |
const char *value = NULL; |
601
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
289 |
int base; |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
290 |
integer_c *integer; |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
291 |
hex_integer_c *hex_integer; |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
292 |
octal_integer_c *octal_integer; |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
293 |
binary_integer_c *binary_integer; |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
294 |
|
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
295 |
if ((integer = dynamic_cast<integer_c *>(sym)) != NULL) {value = integer ->value + 0; base = 10;} |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
296 |
else if ((hex_integer = dynamic_cast<hex_integer_c *>(sym)) != NULL) {value = hex_integer ->value + 3; base = 16;} |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
297 |
else if ((octal_integer = dynamic_cast<octal_integer_c *>(sym)) != NULL) {value = octal_integer ->value + 2; base = 8;} |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
298 |
else if ((binary_integer = dynamic_cast<binary_integer_c *>(sym)) != NULL) {value = binary_integer->value + 2; base = 2;} |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
299 |
else ERROR; |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
300 |
|
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
301 |
for(unsigned int i = 0; i < strlen(value); i++) |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
302 |
if (value[i] != '_') str += value[i]; |
596
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
303 |
|
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
304 |
errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly! |
600
f5d4e9f91513
determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
596
diff
changeset
|
305 |
ret = matiec_strtoint64((int64_t *)NULL, str.c_str(), &endptr, base); |
596
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
306 |
if (overflow != NULL) |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
307 |
*overflow = (errno == ERANGE); |
600
f5d4e9f91513
determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
596
diff
changeset
|
308 |
if (((errno != 0) && (errno != ERANGE)) || (*endptr != '\0')) |
596
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
309 |
ERROR; |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
310 |
|
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
311 |
return ret; |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
312 |
} |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
313 |
|
601
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
314 |
|
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
315 |
|
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
316 |
uint64_t extract_uint64_value(symbol_c *sym, bool *overflow) { |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
317 |
uint64_t ret; |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
318 |
std::string str = ""; |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
319 |
char *endptr; |
735
0304ff59fd7f
Fix some important clang++ warnings.
Manuele Conti <conti.ma@alice.it>
parents:
690
diff
changeset
|
320 |
const char *value = NULL; |
601
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
321 |
int base; |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
322 |
integer_c *integer; |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
323 |
hex_integer_c *hex_integer; |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
324 |
octal_integer_c *octal_integer; |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
325 |
binary_integer_c *binary_integer; |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
326 |
|
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
327 |
if ((integer = dynamic_cast<integer_c *>(sym)) != NULL) {value = integer ->value + 0; base = 10;} |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
328 |
else if ((hex_integer = dynamic_cast<hex_integer_c *>(sym)) != NULL) {value = hex_integer ->value + 3; base = 16;} |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
329 |
else if ((octal_integer = dynamic_cast<octal_integer_c *>(sym)) != NULL) {value = octal_integer ->value + 2; base = 8;} |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
330 |
else if ((binary_integer = dynamic_cast<binary_integer_c *>(sym)) != NULL) {value = binary_integer->value + 2; base = 2;} |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
331 |
else ERROR; |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
332 |
|
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
333 |
for(unsigned int i = 0; i < strlen(value); i++) |
683ae5444237
fix parsing of non base 10 constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
600
diff
changeset
|
334 |
if (value[i] != '_') str += value[i]; |
596
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
335 |
|
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
336 |
errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly! |
600
f5d4e9f91513
determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
596
diff
changeset
|
337 |
ret = matiec_strtouint64((uint64_t *)NULL, str.c_str(), &endptr, base); |
596
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
338 |
if (overflow != NULL) |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
339 |
*overflow = (errno == ERANGE); |
600
f5d4e9f91513
determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
596
diff
changeset
|
340 |
if (((errno != 0) && (errno != ERANGE)) || (*endptr != '\0')) |
596
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
341 |
ERROR; |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
342 |
|
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
343 |
return ret; |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
344 |
} |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
345 |
|
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
346 |
|
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
347 |
|
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
348 |
/* extract the value of a real from an real_c object !! */ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
349 |
/* NOTE: it must ignore underscores! */ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
350 |
/* From iec_bison.yy |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
351 |
* real: |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
352 |
* real_token {$$ = new real_c($1, locloc(@$));} |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
353 |
* | fixed_point_token {$$ = new real_c($1, locloc(@$));} |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
354 |
* |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
355 |
* From iec_flex.ll |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
356 |
* {real} {yylval.ID=strdup(yytext); return real_token;} |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
357 |
* {fixed_point} {yylval.ID=strdup(yytext); return fixed_point_token;} |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
358 |
* |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
359 |
* real {integer}\.{integer}{exponent} |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
360 |
* fixed_point {integer}\.{integer} |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
361 |
* exponent [Ee]([+-]?){integer} |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
362 |
* integer {digit}((_?{digit})*) |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
363 |
*/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
364 |
real64_t extract_real_value(symbol_c *sym, bool *overflow) { |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
365 |
std::string str = ""; |
600
f5d4e9f91513
determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
596
diff
changeset
|
366 |
real_c *real_sym; |
633
73b56dc69e61
Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents:
621
diff
changeset
|
367 |
fixed_point_c *fixed_point_sym; |
600
f5d4e9f91513
determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
596
diff
changeset
|
368 |
char *endptr; |
596
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
369 |
real64_t ret; |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
370 |
|
633
73b56dc69e61
Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents:
621
diff
changeset
|
371 |
if ((real_sym = dynamic_cast<real_c *>(sym)) != NULL) { |
73b56dc69e61
Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents:
621
diff
changeset
|
372 |
for(unsigned int i = 0; i < strlen(real_sym->value); i++) |
73b56dc69e61
Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents:
621
diff
changeset
|
373 |
if (real_sym->value[i] != '_') str += real_sym->value[i]; |
73b56dc69e61
Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents:
621
diff
changeset
|
374 |
} |
73b56dc69e61
Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents:
621
diff
changeset
|
375 |
else if ((fixed_point_sym = dynamic_cast<fixed_point_c *>(sym)) != NULL) { |
73b56dc69e61
Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents:
621
diff
changeset
|
376 |
for(unsigned int i = 0; i < strlen(fixed_point_sym->value); i++) |
73b56dc69e61
Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents:
621
diff
changeset
|
377 |
if (fixed_point_sym->value[i] != '_') str += fixed_point_sym->value[i]; |
73b56dc69e61
Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents:
621
diff
changeset
|
378 |
} |
73b56dc69e61
Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents:
621
diff
changeset
|
379 |
else ERROR; |
596
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
380 |
|
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
381 |
errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly! |
890
499486ece119
Fix compilation error on platforms where real64_t is mapped onto 'long double'
mjsousa
parents:
792
diff
changeset
|
382 |
#if (real64_tX == float) |
600
f5d4e9f91513
determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
596
diff
changeset
|
383 |
ret = strtof(str.c_str(), &endptr); |
890
499486ece119
Fix compilation error on platforms where real64_t is mapped onto 'long double'
mjsousa
parents:
792
diff
changeset
|
384 |
#elif (real64_tX == double) |
600
f5d4e9f91513
determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
596
diff
changeset
|
385 |
ret = strtod(str.c_str(), &endptr); |
890
499486ece119
Fix compilation error on platforms where real64_t is mapped onto 'long double'
mjsousa
parents:
792
diff
changeset
|
386 |
#elif (real64_tX == long_double) |
600
f5d4e9f91513
determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
596
diff
changeset
|
387 |
ret = strtold(str.c_str(), &endptr); |
596
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
388 |
#else |
890
499486ece119
Fix compilation error on platforms where real64_t is mapped onto 'long double'
mjsousa
parents:
792
diff
changeset
|
389 |
#error Could not determine which data type is being used for real64_t (defined in main.hh). Aborting! |
596
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
390 |
#endif |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
391 |
if (overflow != NULL) |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
392 |
*overflow = (errno == ERANGE); |
600
f5d4e9f91513
determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
596
diff
changeset
|
393 |
if (((errno != 0) && (errno != ERANGE)) || (*endptr != '\0')) |
596
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
394 |
ERROR; |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
395 |
|
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
396 |
return ret; |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
397 |
} |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
398 |
|
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
399 |
|
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
400 |
|
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
401 |
|
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
402 |
|
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
403 |
/***********************************************************************/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
404 |
/***********************************************************************/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
405 |
/***********************************************************************/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
406 |
/*** Functions to check for overflow situation ***/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
407 |
/***********************************************************************/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
408 |
/***********************************************************************/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
409 |
/***********************************************************************/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
410 |
|
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
411 |
|
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
412 |
/* NOTE: |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
413 |
* Most of the conditions to detect overflows on signed and unsigned integer operations were adapted from |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
414 |
* https://www.securecoding.cert.org/confluence/display/seccode/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow?showComments=false |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
415 |
* https://www.securecoding.cert.org/confluence/display/seccode/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
416 |
*/ |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
417 |
|
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
418 |
/* NOTE: If at all possible, all overflow tests are done by pre-condition tests, i.e. tests that |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
419 |
* can be run _before_ the operation is executed, and therefore without accessing the result! |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
420 |
* |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
421 |
* The exception is for real/floating point values, that simply test if the result is NaN (not a number). |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
422 |
*/ |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
423 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
424 |
/* res = a + b */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
425 |
static void CHECK_OVERFLOW_uint64_SUM(symbol_c *res, symbol_c *a, symbol_c *b) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
426 |
if (!VALID_CVALUE(uint64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
427 |
return; |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
428 |
/* Test by post-condition: If sum is smaller than either operand => overflow! */ |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
429 |
// if (GET_CVALUE(uint64, res) < GET_CVALUE(uint64, a)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
430 |
/* Test by pre-condition: If (UINT64_MAX - a) < b => overflow! */ |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
431 |
if ((UINT64_MAX - GET_CVALUE(uint64, a)) < GET_CVALUE(uint64, b)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
432 |
SET_OVFLOW(uint64, res); |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
433 |
} |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
434 |
|
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
435 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
436 |
/* res = a - b */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
437 |
static void CHECK_OVERFLOW_uint64_SUB(symbol_c *res, symbol_c *a, symbol_c *b) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
438 |
if (!VALID_CVALUE(uint64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
439 |
return; |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
440 |
/* Test by post-condition: If diference is larger than a => overflow! */ |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
441 |
// if (GET_CVALUE(uint64, res) > GET_CVALUE(uint64, a)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
442 |
/* Test by pre-condition: if b > a => overflow! */ |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
443 |
if (GET_CVALUE(uint64, b) > GET_CVALUE(uint64, a)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
444 |
SET_OVFLOW(uint64, res); |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
445 |
} |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
446 |
|
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
447 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
448 |
/* res = a * b */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
449 |
static void CHECK_OVERFLOW_uint64_MUL(symbol_c *res, symbol_c *a, symbol_c *b) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
450 |
if (!VALID_CVALUE(uint64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
451 |
return; |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
452 |
/* Test by pre-condition: If (UINT64_MAX / a) < b => overflow! */ |
786 | 453 |
if (0 == GET_CVALUE(uint64, a)) |
454 |
return; // multiplying by 0 will always result in 0, a valid result! |
|
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
455 |
if ((UINT64_MAX / GET_CVALUE(uint64, a)) < GET_CVALUE(uint64, b)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
456 |
SET_OVFLOW(uint64, res); |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
457 |
} |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
458 |
|
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
459 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
460 |
/* res = a / b */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
461 |
static void CHECK_OVERFLOW_uint64_DIV(symbol_c *res, symbol_c *a, symbol_c *b) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
462 |
if (!VALID_CVALUE(uint64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
463 |
return; |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
464 |
if (GET_CVALUE(uint64, b) == 0) /* division by zero! */ |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
465 |
SET_OVFLOW(uint64, res); |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
466 |
} |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
467 |
|
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
468 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
469 |
/* res = a MOD b */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
470 |
static void CHECK_OVERFLOW_uint64_MOD(symbol_c *res, symbol_c *a, symbol_c *b) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
471 |
if (!VALID_CVALUE(uint64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
472 |
return; |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
473 |
/* no overflow condition exists, including division by zero, which IEC 61131-3 considers legal for MOD operation! */ |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
474 |
if (false) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
475 |
SET_OVFLOW(uint64, res); |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
476 |
} |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
477 |
|
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
478 |
|
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
479 |
/* res = - a */ |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
480 |
static void CHECK_OVERFLOW_uint64_NEG(symbol_c *res, symbol_c *a) { |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
481 |
/* The only legal operation is res = -0, everything else is an overflow! */ |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
482 |
if (VALID_CVALUE(uint64, a) && (GET_CVALUE(uint64, a) != 0)) |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
483 |
SET_OVFLOW(uint64, res); |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
484 |
} |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
485 |
|
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
486 |
|
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
487 |
|
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
488 |
|
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
489 |
|
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
490 |
|
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
491 |
/* res = a + b */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
492 |
static void CHECK_OVERFLOW_int64_SUM(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
493 |
if (!VALID_CVALUE(int64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
494 |
return; |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
495 |
int64_t a = GET_CVALUE(int64, a_ptr); |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
496 |
int64_t b = GET_CVALUE(int64, b_ptr); |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
497 |
/* The following test is valid no matter what representation is being used (e.g. two's complement, etc...) */ |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
498 |
if (((b > 0) && (a > (INT64_MAX - b))) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
499 |
|| ((b < 0) && (a < (INT64_MIN - b)))) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
500 |
SET_OVFLOW(int64, res); |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
501 |
} |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
502 |
|
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
503 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
504 |
/* res = a - b */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
505 |
static void CHECK_OVERFLOW_int64_SUB(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
506 |
if (!VALID_CVALUE(int64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
507 |
return; |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
508 |
int64_t a = GET_CVALUE(int64, a_ptr); |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
509 |
int64_t b = GET_CVALUE(int64, b_ptr); |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
510 |
/* The following test is valid no matter what representation is being used (e.g. two's complement, etc...) */ |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
511 |
if (((b > 0) && (a < (INT64_MIN + b))) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
512 |
|| ((b < 0) && (a > (INT64_MAX + b)))) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
513 |
SET_OVFLOW(int64, res); |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
514 |
} |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
515 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
516 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
517 |
/* res = a * b */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
518 |
static void CHECK_OVERFLOW_int64_MUL(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
519 |
if (!VALID_CVALUE(int64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
520 |
return; |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
521 |
int64_t a = GET_CVALUE(int64, a_ptr); |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
522 |
int64_t b = GET_CVALUE(int64, b_ptr); |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
523 |
if ( ( (a > 0) && (b > 0) && (a > (INT64_MAX / b))) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
524 |
|| ( (a > 0) && !(b > 0) && (b < (INT64_MIN / a))) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
525 |
|| (!(a > 0) && (b > 0) && (a < (INT64_MIN / b))) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
526 |
|| (!(a > 0) && !(b > 0) && (a != 0) && (b < (INT64_MAX / a)))) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
527 |
SET_OVFLOW(int64, res); |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
528 |
} |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
529 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
530 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
531 |
/* res = a / b */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
532 |
static void CHECK_OVERFLOW_int64_DIV(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
533 |
if (!VALID_CVALUE(int64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
534 |
return; |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
535 |
int64_t a = GET_CVALUE(int64, a_ptr); |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
536 |
int64_t b = GET_CVALUE(int64, b_ptr); |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
537 |
if ((b == 0) || ((a == INT64_MIN) && (b == -1))) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
538 |
SET_OVFLOW(int64, res); |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
539 |
} |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
540 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
541 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
542 |
/* res = a MOD b */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
543 |
static void CHECK_OVERFLOW_int64_MOD(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
544 |
if (!VALID_CVALUE(int64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
545 |
return; |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
546 |
int64_t a = GET_CVALUE(int64, a_ptr); |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
547 |
int64_t b = GET_CVALUE(int64, b_ptr); |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
548 |
/* IEC 61131-3 standard says IN1 MOD IN2 must be equivalent to |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
549 |
* IF (IN2 = 0) THEN OUT:=0 ; ELSE OUT:=IN1 - (IN1/IN2)*IN2 ; END_IF |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
550 |
* |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
551 |
* Note that, when IN1 = INT64_MIN, and IN2 = -1, an overflow occurs in the division, |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
552 |
* so although the MOD operation should be OK, acording to the above definition, we actually have an overflow!! |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
553 |
* |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
554 |
* On the other hand, division by 0 is OK!! |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
555 |
*/ |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
556 |
if ((a == INT64_MIN) && (b == -1)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
557 |
SET_OVFLOW(int64, res); |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
558 |
} |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
559 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
560 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
561 |
/* res = - a */ |
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
562 |
static void CHECK_OVERFLOW_int64_NEG(symbol_c *res, symbol_c *a) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
563 |
if (!VALID_CVALUE(int64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
564 |
return; |
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
565 |
if (GET_CVALUE(int64, a) == INT64_MIN) |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
566 |
SET_OVFLOW(int64, res); |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
567 |
} |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
568 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
569 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
570 |
|
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
571 |
|
579
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
572 |
static void CHECK_OVERFLOW_real64(symbol_c *res_ptr) { |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
573 |
if (!VALID_CVALUE(real64, res_ptr)) |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
574 |
return; |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
575 |
real64_t res = GET_CVALUE(real64, res_ptr); |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
576 |
/* NaN => underflow, overflow, number is a higher precision format, is a complex number (IEEE standard) */ |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
577 |
/* The IEC 61131-3 clearly states in section '2.5.1.5.2 Numerical functions': |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
578 |
* "It is an error if the result of evaluation of one of these [numerical] functions exceeds the range of values |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
579 |
* specified for the data type of the function output, or if division by zero is attempted." |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
580 |
* For this reason, any operation that has as a result a positive or negative inifinity, is also an error! |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
581 |
*/ |
607
be9ba3531afb
cleaning up code. Changing HUGE_VAL to INFINITY.
Mario de Sousa <msousa@fe.up.pt>
parents:
604
diff
changeset
|
582 |
if ((isnan(res)) || (res == INFINITY) || (res == -INFINITY)) |
579
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
583 |
SET_OVFLOW(real64, res_ptr); |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
584 |
} |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
585 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
586 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
587 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
588 |
|
612 | 589 |
/***********************************************************************/ |
590 |
/***********************************************************************/ |
|
591 |
/***********************************************************************/ |
|
592 |
/*** Functions to execute operations on the const values ***/ |
|
593 |
/***********************************************************************/ |
|
594 |
/***********************************************************************/ |
|
595 |
/***********************************************************************/ |
|
596 |
||
597 |
/* static void *handle_cmp(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2, OPERATION) */ |
|
598 |
#define handle_cmp(symbol, oper1, oper2, operation) { \ |
|
599 |
if ((NULL == oper1) || (NULL == oper2)) return NULL; \ |
|
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
600 |
DO_BINARY_OPER( bool, operation, bool, oper1, oper2); \ |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
601 |
DO_BINARY_OPER(uint64, operation, bool, oper1, oper2); \ |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
602 |
DO_BINARY_OPER( int64, operation, bool, oper1, oper2); \ |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
603 |
DO_BINARY_OPER(real64, operation, bool, oper1, oper2); \ |
612 | 604 |
return NULL; \ |
605 |
} |
|
606 |
||
607 |
||
608 |
/* NOTE: the MOVE standard function is equivalent to the ':=' in ST syntax */ |
|
609 |
static void *handle_move(symbol_c *to, symbol_c *from) { |
|
610 |
if (NULL == from) return NULL; |
|
611 |
to->const_value = from->const_value; |
|
612 |
return NULL; |
|
613 |
} |
|
614 |
||
615 |
||
616 |
/* unary negation (multiply by -1) */ |
|
617 |
static void *handle_neg(symbol_c *symbol, symbol_c *oper) { |
|
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
618 |
if (NULL == oper) return NULL; |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
619 |
/* NOTE: The oper may never be an integer/real literal, '-1' and '-2.2' are stored as an neg_integer_c/neg_real_c instead. |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
620 |
* Because of this, we MUST NOT handle the INT_MIN special situation that is handled in neg_integer_c visitor! |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
621 |
* |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
622 |
* VAR v1, v2, v3 : UINT; END_VAR; |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
623 |
* v1 = 9223372036854775808 ; (* |INT64_MIN| == -INT64_MIN *) <------ LEGAL |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
624 |
* v2 = -(-v1); <------ ILLEGAL (since it -v1 is overflow!) |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
625 |
* v2 = -(-9223372036854775808 ); <------ MUST also be ILLEGAL |
640 | 626 |
*/ |
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
627 |
DO_UNARY_OPER(uint64, -, oper); CHECK_OVERFLOW_uint64_NEG(symbol, oper); /* handle the uint_v := -0 situation! */ |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
628 |
DO_UNARY_OPER( int64, -, oper); CHECK_OVERFLOW_int64_NEG (symbol, oper); |
612 | 629 |
DO_UNARY_OPER(real64, -, oper); CHECK_OVERFLOW_real64(symbol); |
630 |
return NULL; |
|
631 |
} |
|
632 |
||
633 |
||
634 |
/* unary boolean negation (NOT) */ |
|
635 |
static void *handle_not(symbol_c *symbol, symbol_c *oper) { |
|
636 |
if (NULL == oper) return NULL; |
|
637 |
DO_UNARY_OPER( bool, !, oper); |
|
638 |
DO_UNARY_OPER(uint64, ~, oper); |
|
639 |
return NULL; |
|
640 |
} |
|
641 |
||
642 |
||
643 |
static void *handle_or (symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) { |
|
644 |
if ((NULL == oper1) || (NULL == oper2)) return NULL; |
|
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
645 |
DO_BINARY_OPER( bool, ||, bool , oper1, oper2); |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
646 |
DO_BINARY_OPER(uint64, | , uint64, oper1, oper2); |
612 | 647 |
return NULL; |
648 |
} |
|
649 |
||
650 |
||
651 |
static void *handle_xor(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) { |
|
652 |
if ((NULL == oper1) || (NULL == oper2)) return NULL; |
|
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
653 |
DO_BINARY_OPER( bool, ^, bool , oper1, oper2); |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
654 |
DO_BINARY_OPER(uint64, ^, uint64, oper1, oper2); |
612 | 655 |
return NULL; |
656 |
} |
|
657 |
||
658 |
||
659 |
static void *handle_and(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) { |
|
660 |
if ((NULL == oper1) || (NULL == oper2)) return NULL; |
|
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
661 |
DO_BINARY_OPER( bool, &&, bool, oper1, oper2); |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
662 |
DO_BINARY_OPER(uint64, & , uint64, oper1, oper2); |
612 | 663 |
return NULL; |
664 |
} |
|
665 |
||
666 |
||
667 |
static void *handle_add(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) { |
|
668 |
if ((NULL == oper1) || (NULL == oper2)) return NULL; |
|
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
669 |
DO_BINARY_OPER(uint64, +, uint64, oper1, oper2); CHECK_OVERFLOW_uint64_SUM(symbol, oper1, oper2); |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
670 |
DO_BINARY_OPER( int64, +, int64, oper1, oper2); CHECK_OVERFLOW_int64_SUM (symbol, oper1, oper2); |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
671 |
DO_BINARY_OPER(real64, +, real64, oper1, oper2); CHECK_OVERFLOW_real64 (symbol); |
612 | 672 |
return NULL; |
673 |
} |
|
674 |
||
675 |
||
676 |
static void *handle_sub(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) { |
|
677 |
if ((NULL == oper1) || (NULL == oper2)) return NULL; |
|
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
678 |
DO_BINARY_OPER(uint64, -, uint64, oper1, oper2); CHECK_OVERFLOW_uint64_SUB(symbol, oper1, oper2); |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
679 |
DO_BINARY_OPER( int64, -, int64, oper1, oper2); CHECK_OVERFLOW_int64_SUB (symbol, oper1, oper2); |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
680 |
DO_BINARY_OPER(real64, -, real64, oper1, oper2); CHECK_OVERFLOW_real64 (symbol); |
612 | 681 |
return NULL; |
682 |
} |
|
683 |
||
684 |
||
685 |
static void *handle_mul(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) { |
|
686 |
if ((NULL == oper1) || (NULL == oper2)) return NULL; |
|
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
687 |
DO_BINARY_OPER(uint64, *, uint64, oper1, oper2); CHECK_OVERFLOW_uint64_MUL(symbol, oper1, oper2); |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
688 |
DO_BINARY_OPER( int64, *, int64, oper1, oper2); CHECK_OVERFLOW_int64_MUL (symbol, oper1, oper2); |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
689 |
DO_BINARY_OPER(real64, *, real64, oper1, oper2); CHECK_OVERFLOW_real64 (symbol); |
612 | 690 |
return NULL; |
691 |
} |
|
692 |
||
693 |
||
694 |
static void *handle_div(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) { |
|
695 |
if ((NULL == oper1) || (NULL == oper2)) return NULL; |
|
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
696 |
if (ISZERO_CVALUE(uint64, oper2)) {SET_OVFLOW(uint64, symbol);} else {DO_BINARY_OPER(uint64, /, uint64, oper1, oper2); CHECK_OVERFLOW_uint64_DIV(symbol, oper1, oper2);}; |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
697 |
if (ISZERO_CVALUE( int64, oper2)) {SET_OVFLOW( int64, symbol);} else {DO_BINARY_OPER( int64, /, int64, oper1, oper2); CHECK_OVERFLOW_int64_DIV (symbol, oper1, oper2);}; |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
698 |
if (ISZERO_CVALUE(real64, oper2)) {SET_OVFLOW(real64, symbol);} else {DO_BINARY_OPER(real64, /, real64, oper1, oper2); CHECK_OVERFLOW_real64(symbol);}; |
612 | 699 |
return NULL; |
700 |
} |
|
701 |
||
702 |
||
703 |
static void *handle_mod(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) { |
|
704 |
if ((NULL == oper1) || (NULL == oper2)) return NULL; |
|
705 |
/* IEC 61131-3 standard says IN1 MOD IN2 must be equivalent to |
|
706 |
* IF (IN2 = 0) THEN OUT:=0 ; ELSE OUT:=IN1 - (IN1/IN2)*IN2 ; END_IF |
|
707 |
* |
|
708 |
* Note that, when IN1 = INT64_MIN, and IN2 = -1, an overflow occurs in the division, |
|
709 |
* so although the MOD operation should be OK, acording to the above definition, we actually have an overflow!! |
|
710 |
*/ |
|
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
711 |
if (ISZERO_CVALUE(uint64, oper2)) {SET_CVALUE(uint64, symbol, 0);} else {DO_BINARY_OPER(uint64, %, uint64, oper1, oper2); CHECK_OVERFLOW_uint64_MOD(symbol, oper1, oper2);}; |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
712 |
if (ISZERO_CVALUE( int64, oper2)) {SET_CVALUE( int64, symbol, 0);} else {DO_BINARY_OPER( int64, %, int64, oper1, oper2); CHECK_OVERFLOW_int64_MOD (symbol, oper1, oper2);}; |
612 | 713 |
return NULL; |
714 |
} |
|
715 |
||
716 |
||
717 |
static void *handle_pow(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) { |
|
718 |
/* NOTE: If the const_value in symbol->r_exp is within the limits of both int64 and uint64, then we do both operations. |
|
719 |
* That is OK, as the result should be identicial (we do create an unnecessary CVALUE variable, but who cares?). |
|
720 |
* If only one is valid, then that is the oper we will do! |
|
721 |
*/ |
|
722 |
if (VALID_CVALUE(real64, oper1) && VALID_CVALUE( int64, oper2)) |
|
723 |
SET_CVALUE(real64, symbol, pow(GET_CVALUE(real64, oper1), GET_CVALUE( int64, oper2))); |
|
724 |
if (VALID_CVALUE(real64, oper1) && VALID_CVALUE(uint64, oper2)) |
|
725 |
SET_CVALUE(real64, symbol, pow(GET_CVALUE(real64, oper1), GET_CVALUE(uint64, oper2))); |
|
726 |
CHECK_OVERFLOW_real64(symbol); |
|
727 |
return NULL; |
|
728 |
} |
|
729 |
||
788
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
730 |
static map_values_t inner_left_join_values(map_values_t m1, map_values_t m2) { |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
731 |
map_values_t::const_iterator itr; |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
732 |
map_values_t ret; |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
733 |
|
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
734 |
itr = m1.begin(); |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
735 |
for ( ; itr != m1.end(); ++itr) { |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
736 |
std::string name = itr->first; |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
737 |
symbol_c::const_value_t value; |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
738 |
|
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
739 |
if (m2.count(name) > 0) { |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
740 |
symbol_c::const_value_t c1 = itr->second; |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
741 |
symbol_c::const_value_t c2 = m2[name]; |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
742 |
COMPUTE_MEET_SEMILATTICE (real64, c1, c2, value); |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
743 |
COMPUTE_MEET_SEMILATTICE (uint64, c1, c2, value); |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
744 |
COMPUTE_MEET_SEMILATTICE ( int64, c1, c2, value); |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
745 |
COMPUTE_MEET_SEMILATTICE ( bool, c1, c2, value); |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
746 |
} else |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
747 |
value = m1[name]; |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
748 |
ret[name] = value; |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
749 |
} |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
750 |
|
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
751 |
return ret; |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
752 |
} |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
753 |
|
612 | 754 |
/***********************************************************************/ |
755 |
/***********************************************************************/ |
|
756 |
/***********************************************************************/ |
|
757 |
/*** Helper functions for handling IL instruction lists. ***/ |
|
758 |
/***********************************************************************/ |
|
759 |
/***********************************************************************/ |
|
760 |
/***********************************************************************/ |
|
761 |
||
762 |
||
763 |
/* If the cvalues of all the prev_il_intructions have the same VALID value, then set the local cvalue to that value, otherwise, set it to NONCONST! */ |
|
764 |
#define intersect_prev_CVALUE_(dtype, symbol) { \ |
|
765 |
symbol->const_value._##dtype = symbol->prev_il_instruction[0]->const_value._##dtype; \ |
|
766 |
for (unsigned int i = 1; i < symbol->prev_il_instruction.size(); i++) { \ |
|
767 |
if (!ISEQUAL_CVALUE(dtype, symbol, symbol->prev_il_instruction[i])) \ |
|
768 |
{SET_NONCONST(dtype, symbol); break;} \ |
|
769 |
} \ |
|
770 |
} |
|
771 |
||
772 |
static void intersect_prev_cvalues(il_instruction_c *symbol) { |
|
773 |
if (symbol->prev_il_instruction.empty()) |
|
774 |
return; |
|
775 |
intersect_prev_CVALUE_(real64, symbol); |
|
776 |
intersect_prev_CVALUE_(uint64, symbol); |
|
777 |
intersect_prev_CVALUE_( int64, symbol); |
|
778 |
intersect_prev_CVALUE_( bool, symbol); |
|
779 |
} |
|
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
780 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
781 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
782 |
|
596
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
783 |
/***********************************************************************/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
784 |
/***********************************************************************/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
785 |
/***********************************************************************/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
786 |
/*** The constant_folding_c ***/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
787 |
/***********************************************************************/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
788 |
/***********************************************************************/ |
4efb11e44065
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
Mario de Sousa <msousa@fe.up.pt>
parents:
592
diff
changeset
|
789 |
/***********************************************************************/ |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
790 |
|
945
477393b00f95
Add support for relaxed datatype model for array datatypes.
mjsousa
parents:
890
diff
changeset
|
791 |
#if 0 |
477393b00f95
Add support for relaxed datatype model for array datatypes.
mjsousa
parents:
890
diff
changeset
|
792 |
// not currently needed, so comment it out!... |
477393b00f95
Add support for relaxed datatype model for array datatypes.
mjsousa
parents:
890
diff
changeset
|
793 |
// returns true if both symbols have the same value in all the cvalues |
477393b00f95
Add support for relaxed datatype model for array datatypes.
mjsousa
parents:
890
diff
changeset
|
794 |
bool constant_folding_c::is_equal_cvalue(symbol_c *symbol_1, symbol_c *symbol_2) { |
477393b00f95
Add support for relaxed datatype model for array datatypes.
mjsousa
parents:
890
diff
changeset
|
795 |
if (VALID_CVALUE (real64, symbol_1) != VALID_CVALUE (real64, symbol_2)) return false; |
477393b00f95
Add support for relaxed datatype model for array datatypes.
mjsousa
parents:
890
diff
changeset
|
796 |
if (VALID_CVALUE (uint64, symbol_1) != VALID_CVALUE (uint64, symbol_2)) return false; |
477393b00f95
Add support for relaxed datatype model for array datatypes.
mjsousa
parents:
890
diff
changeset
|
797 |
if (VALID_CVALUE ( int64, symbol_1) != VALID_CVALUE ( int64, symbol_2)) return false; |
477393b00f95
Add support for relaxed datatype model for array datatypes.
mjsousa
parents:
890
diff
changeset
|
798 |
if (VALID_CVALUE ( bool, symbol_1) != VALID_CVALUE ( bool, symbol_2)) return false; |
477393b00f95
Add support for relaxed datatype model for array datatypes.
mjsousa
parents:
890
diff
changeset
|
799 |
if (VALID_CVALUE (real64, symbol_1) && !ISEQUAL_CVALUE(real64, symbol_1, symbol_2)) return false; |
477393b00f95
Add support for relaxed datatype model for array datatypes.
mjsousa
parents:
890
diff
changeset
|
800 |
if (VALID_CVALUE (uint64, symbol_1) && !ISEQUAL_CVALUE(uint64, symbol_1, symbol_2)) return false; |
477393b00f95
Add support for relaxed datatype model for array datatypes.
mjsousa
parents:
890
diff
changeset
|
801 |
if (VALID_CVALUE ( int64, symbol_1) && !ISEQUAL_CVALUE( int64, symbol_1, symbol_2)) return false; |
477393b00f95
Add support for relaxed datatype model for array datatypes.
mjsousa
parents:
890
diff
changeset
|
802 |
if (VALID_CVALUE ( bool, symbol_1) && !ISEQUAL_CVALUE( bool, symbol_1, symbol_2)) return false; |
477393b00f95
Add support for relaxed datatype model for array datatypes.
mjsousa
parents:
890
diff
changeset
|
803 |
return true; |
477393b00f95
Add support for relaxed datatype model for array datatypes.
mjsousa
parents:
890
diff
changeset
|
804 |
} |
477393b00f95
Add support for relaxed datatype model for array datatypes.
mjsousa
parents:
890
diff
changeset
|
805 |
#endif |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
806 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
807 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
808 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
809 |
constant_folding_c::constant_folding_c(symbol_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
810 |
error_count = 0; |
568
5f79478142d7
make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents:
567
diff
changeset
|
811 |
warning_found = false; |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
812 |
current_display_error_level = 0; |
661
f537c3315f83
Minor changes needed to build with pedantic flag.
Manuele Conti <conti.ma@alice.it>
parents:
648
diff
changeset
|
813 |
il_operand = NULL; |
f537c3315f83
Minor changes needed to build with pedantic flag.
Manuele Conti <conti.ma@alice.it>
parents:
648
diff
changeset
|
814 |
search_varfb_instance_type = NULL; |
f537c3315f83
Minor changes needed to build with pedantic flag.
Manuele Conti <conti.ma@alice.it>
parents:
648
diff
changeset
|
815 |
prev_il_instruction = NULL; |
568
5f79478142d7
make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents:
567
diff
changeset
|
816 |
|
5f79478142d7
make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents:
567
diff
changeset
|
817 |
/* check whether the platform on which the compiler is being run implements IEC 559 floating point data types. */ |
5f79478142d7
make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents:
567
diff
changeset
|
818 |
symbol_c null_symbol; |
5f79478142d7
make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents:
567
diff
changeset
|
819 |
if (! (std::numeric_limits<real64_t>::is_iec559) ) |
579
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
820 |
STAGE3_WARNING(&null_symbol, &null_symbol, "The platform running the compiler does not implement IEC 60559 floating point numbers. " |
568
5f79478142d7
make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents:
567
diff
changeset
|
821 |
"Any error and/or warning messages related to overflow/underflow of the result of operations on REAL/LREAL literals " |
579
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
822 |
"(i.e. constant folding) may themselves be erroneous, although are most probably correct." |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
823 |
"However, more likely is the possible existance of overflow/underflow errors that are not detected."); |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
824 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
825 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
826 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
827 |
constant_folding_c::~constant_folding_c(void) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
828 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
829 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
830 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
831 |
int constant_folding_c::get_error_count() { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
832 |
return error_count; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
833 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
834 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
835 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
836 |
/*********************/ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
837 |
/* B 1.2 - Constants */ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
838 |
/*********************/ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
839 |
/******************************/ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
840 |
/* B 1.2.1 - Numeric Literals */ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
841 |
/******************************/ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
842 |
void *constant_folding_c::visit(real_c *symbol) { |
576
8368ec909825
Fix extract_real (thanks Manuele), and add check for overflow.
Mario de Sousa <msousa@fe.up.pt>
parents:
575
diff
changeset
|
843 |
bool overflow; |
612 | 844 |
SET_CVALUE(real64, symbol, extract_real_value(symbol, &overflow)); |
576
8368ec909825
Fix extract_real (thanks Manuele), and add check for overflow.
Mario de Sousa <msousa@fe.up.pt>
parents:
575
diff
changeset
|
845 |
if (overflow) SET_OVFLOW(real64, symbol); |
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
846 |
return NULL; |
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
847 |
} |
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
848 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
849 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
850 |
void *constant_folding_c::visit(integer_c *symbol) { |
587
1ecf916cc397
Fix extract_integer_value.
Manuele Conti <conti.ma@alice.it>
parents:
579
diff
changeset
|
851 |
bool overflow; |
612 | 852 |
SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow)); |
588
3d72d09bd40f
Add missing set overflow flag.
Manuele Conti <conti.ma@alice.it>
parents:
587
diff
changeset
|
853 |
if (overflow) SET_OVFLOW(int64, symbol); |
612 | 854 |
SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow)); |
588
3d72d09bd40f
Add missing set overflow flag.
Manuele Conti <conti.ma@alice.it>
parents:
587
diff
changeset
|
855 |
if (overflow) SET_OVFLOW(uint64, symbol); |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
856 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
857 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
858 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
859 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
860 |
void *constant_folding_c::visit(neg_real_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
861 |
symbol->exp->accept(*this); |
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
862 |
DO_UNARY_OPER(real64, -, symbol->exp); CHECK_OVERFLOW_real64(symbol); |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
863 |
if (IS_OVFLOW(real64, symbol->exp)) SET_OVFLOW(real64, symbol); |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
864 |
return NULL; |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
865 |
} |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
866 |
|
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
867 |
|
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
868 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
869 |
/* | '-' integer {$$ = new neg_integer_c($2, locloc(@$));} */ |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
870 |
void *constant_folding_c::visit(neg_integer_c *symbol) { |
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
871 |
symbol->exp->accept(*this); |
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
872 |
/* Note that due to syntax restrictions, the value of symbol->exp will always be positive. |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
873 |
* However, the following code does not depend on that restriction. |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
874 |
*/ |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
875 |
/* The remainder of the code (for example, data type checking) considers the neg_integer_c as a leaf of the |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
876 |
* abstract syntax tree, and therefore simply ignores the values of neg_integer_c->exp. |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
877 |
* For this reason only, and in only this situation, we must guarantee that any 'overflow' situation in |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
878 |
* the cvalue of neg_integer_c->exp is also reflected back to this neg_integer_c symbol. |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
879 |
* For the rest of the code we do NOT do this, as it would gurantee that a single overflow deep inside |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
880 |
* an expression would imply that the expression itself would also be set to 'overflow' condition. |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
881 |
* This in turn would then have the compiler produce a whole load of error messages where they are not wanted! |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
882 |
*/ |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
883 |
DO_UNARY_OPER(uint64, -, symbol->exp); CHECK_OVERFLOW_uint64_NEG(symbol, symbol->exp); /* handle the uintv := -0 situation */ |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
884 |
if (IS_OVFLOW(uint64, symbol->exp)) SET_OVFLOW(uint64, symbol); |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
885 |
DO_UNARY_OPER( int64, -, symbol->exp); CHECK_OVERFLOW_int64_NEG (symbol, symbol->exp); |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
886 |
if (IS_OVFLOW( int64, symbol->exp)) SET_OVFLOW( int64, symbol); |
590
649667749171
Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents:
588
diff
changeset
|
887 |
/* NOTE 1: INT64_MIN = -(INT64_MAX + 1) ---> assuming two's complement representation!!! |
649667749171
Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents:
588
diff
changeset
|
888 |
* NOTE 2: if the user happens to want INT_MIN, that value will first be parsed as a positive integer, before being negated here. |
649667749171
Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents:
588
diff
changeset
|
889 |
* However, the positive value cannot be stored inside an int64! So, in this case, we will get the value from the uint64 cvalue. |
643
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
890 |
* |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
891 |
* This same situation is usually considered an overflow (check handle_neg() function). However, here we have a special |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
892 |
* situation. If we do not allow this, then the user would never the able to use the following code: |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
893 |
* VAR v : LINT; END_VAR |
1cc0e1ca2aad
Fix constant folding: now handles INT_MIN and neg_integer_c correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
640
diff
changeset
|
894 |
* v := -9223372036854775809 ; (* - |INT64_MIN| == INT64_MIN *) |
590
649667749171
Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents:
588
diff
changeset
|
895 |
*/ |
649667749171
Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents:
588
diff
changeset
|
896 |
// if (INT64_MIN == -INT64_MAX - 1) // We do not really need to check that the platform uses two's complement |
621
e3616f6b6959
Remove remaining signed/unsigned comparison error messages when compiling.
Mario de Sousa <msousa@fe.up.pt>
parents:
612
diff
changeset
|
897 |
if (VALID_CVALUE(uint64, symbol->exp) && (GET_CVALUE(uint64, symbol->exp) == (uint64_t)INT64_MAX+1)) { |
590
649667749171
Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents:
588
diff
changeset
|
898 |
SET_CVALUE(int64, symbol, INT64_MIN); |
649667749171
Add support for -INT64_MIN values in literals.
Mario de Sousa <msousa@fe.up.pt>
parents:
588
diff
changeset
|
899 |
} |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
900 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
901 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
902 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
903 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
904 |
void *constant_folding_c::visit(binary_integer_c *symbol) { |
600
f5d4e9f91513
determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
596
diff
changeset
|
905 |
bool overflow; |
612 | 906 |
SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow)); |
600
f5d4e9f91513
determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
596
diff
changeset
|
907 |
if (overflow) SET_OVFLOW(int64, symbol); |
612 | 908 |
SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow)); |
600
f5d4e9f91513
determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
596
diff
changeset
|
909 |
if (overflow) SET_OVFLOW(uint64, symbol); |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
910 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
911 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
912 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
913 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
914 |
void *constant_folding_c::visit(octal_integer_c *symbol) { |
600
f5d4e9f91513
determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
596
diff
changeset
|
915 |
bool overflow; |
612 | 916 |
SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow)); |
600
f5d4e9f91513
determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
596
diff
changeset
|
917 |
if (overflow) SET_OVFLOW(int64, symbol); |
612 | 918 |
SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow)); |
600
f5d4e9f91513
determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
596
diff
changeset
|
919 |
if (overflow) SET_OVFLOW(uint64, symbol); |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
920 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
921 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
922 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
923 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
924 |
void *constant_folding_c::visit(hex_integer_c *symbol) { |
600
f5d4e9f91513
determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
596
diff
changeset
|
925 |
bool overflow; |
612 | 926 |
SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow)); |
600
f5d4e9f91513
determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
596
diff
changeset
|
927 |
if (overflow) SET_OVFLOW(int64, symbol); |
612 | 928 |
SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow)); |
600
f5d4e9f91513
determine const value of hex, octal and bin literals correctly.
Mario de Sousa <msousa@fe.up.pt>
parents:
596
diff
changeset
|
929 |
if (overflow) SET_OVFLOW(uint64, symbol); |
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
930 |
return NULL; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
931 |
} |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
932 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
933 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
934 |
/* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
935 |
integer_literal: |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
936 |
integer_type_name '#' signed_integer {$$ = new integer_literal_c($1, $3, locloc(@$));} |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
937 |
| integer_type_name '#' binary_integer {$$ = new integer_literal_c($1, $3, locloc(@$));} |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
938 |
| integer_type_name '#' octal_integer {$$ = new integer_literal_c($1, $3, locloc(@$));} |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
939 |
| integer_type_name '#' hex_integer {$$ = new integer_literal_c($1, $3, locloc(@$));} |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
940 |
*/ |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
941 |
// SYM_REF2(integer_literal_c, type, value) |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
942 |
void *constant_folding_c::visit(integer_literal_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
943 |
symbol->value->accept(*this); |
575 | 944 |
DO_UNARY_OPER( int64, /* none */, symbol->value); |
945 |
DO_UNARY_OPER(uint64, /* none */, symbol->value); |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
946 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
947 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
948 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
949 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
950 |
void *constant_folding_c::visit(real_literal_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
951 |
symbol->value->accept(*this); |
575 | 952 |
DO_UNARY_OPER(real64, /* none */, symbol->value); |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
953 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
954 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
955 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
956 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
957 |
void *constant_folding_c::visit(bit_string_literal_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
958 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
959 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
960 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
961 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
962 |
void *constant_folding_c::visit(boolean_literal_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
963 |
symbol->value->accept(*this); |
575 | 964 |
DO_UNARY_OPER(bool, /* none */, symbol->value); |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
965 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
966 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
967 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
968 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
969 |
void *constant_folding_c::visit(boolean_true_c *symbol) { |
612 | 970 |
SET_CVALUE(bool, symbol, true); |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
971 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
972 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
973 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
974 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
975 |
void *constant_folding_c::visit(boolean_false_c *symbol) { |
612 | 976 |
SET_CVALUE(bool, symbol, false); |
977 |
return NULL; |
|
978 |
} |
|
979 |
||
633
73b56dc69e61
Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents:
621
diff
changeset
|
980 |
/************************/ |
73b56dc69e61
Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents:
621
diff
changeset
|
981 |
/* B 1.2.3.1 - Duration */ |
73b56dc69e61
Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents:
621
diff
changeset
|
982 |
/********* **************/ |
73b56dc69e61
Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents:
621
diff
changeset
|
983 |
void *constant_folding_c::visit(fixed_point_c *symbol) { |
73b56dc69e61
Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents:
621
diff
changeset
|
984 |
bool overflow; |
73b56dc69e61
Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents:
621
diff
changeset
|
985 |
SET_CVALUE(real64, symbol, extract_real_value(symbol, &overflow)); |
73b56dc69e61
Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents:
621
diff
changeset
|
986 |
if (overflow) SET_OVFLOW(real64, symbol); |
73b56dc69e61
Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents:
621
diff
changeset
|
987 |
return NULL; |
73b56dc69e61
Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents:
621
diff
changeset
|
988 |
} |
612 | 989 |
|
774
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
990 |
/*********************/ |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
991 |
/* B 1.4 - Variables */ |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
992 |
/*********************/ |
792
78083edf93d5
disable not yet complete constant propagation algorithm (currently brocken and producing incorrect results),
Mario de Sousa <msousa@fe.up.pt>
parents:
791
diff
changeset
|
993 |
#if DO_CONSTANT_PROPAGATION__ |
774
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
994 |
void *constant_folding_c::visit(symbolic_variable_c *symbol) { |
963
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
995 |
std::string varName = get_var_name_c::get_name(symbol->var_name)->value; |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
996 |
if (values.count(varName) > 0) |
774
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
997 |
symbol->const_value = values[varName]; |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
998 |
return NULL; |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
999 |
} |
792
78083edf93d5
disable not yet complete constant propagation algorithm (currently brocken and producing incorrect results),
Mario de Sousa <msousa@fe.up.pt>
parents:
791
diff
changeset
|
1000 |
#endif // DO_CONSTANT_PROPAGATION__ |
774
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1001 |
|
963
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1002 |
void *constant_folding_c::visit(symbolic_constant_c *symbol) { |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1003 |
std::string varName = get_var_name_c::get_name(symbol->var_name)->value; |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1004 |
if (values.count(varName) > 0) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1005 |
symbol->const_value = values[varName]; |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1006 |
return NULL; |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1007 |
} |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1008 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1009 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1010 |
/******************************************/ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1011 |
/* B 1.4.3 - Declaration & Initialisation */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1012 |
/******************************************/ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1013 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1014 |
/* Do the constant folding for VAR_EXTERNAL and VAR_GLOBAL pairs. |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1015 |
* This function is called from the declaration_check_c, since it has easy access to the extern<->global pairing information |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1016 |
* needed for this function to work. |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1017 |
*/ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1018 |
int constant_folding_c::handle_var_extern_global_pair(symbol_c *extern_var_name, symbol_c *extern_var_decl, symbol_c *global_var_name, symbol_c *global_var_decl) { |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1019 |
// the minimum infor we must get to make sense |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1020 |
if (NULL == global_var_decl) ERROR; |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1021 |
if (NULL == extern_var_name) ERROR; |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1022 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1023 |
symbol_c *init_value = type_initial_value_c::get(global_var_decl); |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1024 |
if (NULL == init_value) return 0; // this is probably a FB datatype, for which no initial value exists! Do nothing and return. |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1025 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1026 |
// Do constant folding of the initial value! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1027 |
// This is required since this function may be called before we do the iterative constant folding of the complete library! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1028 |
init_value->accept(*this); |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1029 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1030 |
if (NULL != extern_var_name) extern_var_name->const_value = init_value->const_value; |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1031 |
if (NULL != extern_var_decl) extern_var_decl->const_value = init_value->const_value; // Note that each external variable declaration has its own datatype specification, so we can set this symbol's const_value too! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1032 |
// we could leave the constant folding of the global variable itself for later, when we iteratively visit the whole library, but there is nor harm in doing it now! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1033 |
if (NULL != global_var_name) global_var_name->const_value = init_value->const_value; |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1034 |
if (NULL != global_var_decl) global_var_decl->const_value = init_value->const_value; // Note that each external variable declaration has its own datatype specification, so we can set this symbol's const_value too! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1035 |
return 0; |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1036 |
} |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1037 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1038 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1039 |
void *constant_folding_c::handle_var_list_decl(symbol_c *var_list, symbol_c *type_decl) { |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1040 |
symbol_c *init_value = type_initial_value_c::get(type_decl); |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1041 |
if (NULL == init_value) return NULL; // this is probably a FB datatype, for which no initial value exists! Do nothing and return. |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1042 |
init_value->accept(*this); // Do constant folding of the initial value! (we will probably be doing this multiple times for the same init value, but this is safe as the cvalue is idem-potent) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1043 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1044 |
list_c *list = dynamic_cast<list_c *>(var_list); |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1045 |
if (NULL == list) ERROR; |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1046 |
for (int i = 0; i < list->n; i++) { |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1047 |
token_c *var_name = dynamic_cast<token_c *>(list->elements[i]); |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1048 |
if (NULL == var_name) { |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1049 |
if (NULL != dynamic_cast<extensible_input_parameter_c *>(list->elements[i])) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1050 |
continue; // this is an extensible standard function. Ignore this variable, and continue! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1051 |
debug_c::print(list->elements[i]); |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1052 |
ERROR; |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1053 |
} |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1054 |
std::string varName = var_name->value; |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1055 |
values[varName] = init_value->const_value; |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1056 |
list->elements[i]->const_value = init_value->const_value; |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1057 |
} |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1058 |
return NULL; |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1059 |
} |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1060 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1061 |
/* | var1_list ',' variable_name */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1062 |
//SYM_LIST(var1_list_c) // Not needed! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1063 |
//SYM_REF0(constant_option_c) // Not needed! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1064 |
//SYM_REF0(retain_option_c) // Not needed! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1065 |
//SYM_REF0(non_retain_option_c) // Not needed! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1066 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1067 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1068 |
/* spec_init is one of the following... |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1069 |
* simple_spec_init_c * |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1070 |
* subrange_spec_init_c * |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1071 |
* enumerated_spec_init_c * |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1072 |
*/ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1073 |
// SYM_REF2(var1_init_decl_c, var1_list, spec_init) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1074 |
void *constant_folding_c::visit(var1_init_decl_c *symbol) {return handle_var_list_decl(symbol->var1_list, symbol->spec_init);} |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1075 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1076 |
/* | [var1_list ','] variable_name integer '..' */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1077 |
/* NOTE: This is an extension to the standard!!! */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1078 |
//SYM_REF2(extensible_input_parameter_c, var_name, first_index) // Not needed! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1079 |
/* var1_list ':' array_spec_init */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1080 |
//SYM_REF2(array_var_init_decl_c, var1_list, array_spec_init) // We do not yet handle arrays! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1081 |
/* var1_list ':' initialized_structure */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1082 |
//SYM_REF2(structured_var_init_decl_c, var1_list, initialized_structure) // We do not yet handle structures! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1083 |
/* fb_name_list ':' function_block_type_name ASSIGN structure_initialization */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1084 |
//SYM_REF2(fb_name_decl_c, fb_name_list, fb_spec_init) // We do not yet handle FBs! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1085 |
/* fb_name_list ',' fb_name */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1086 |
//SYM_LIST(fb_name_list_c) // Not needed! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1087 |
/* VAR_INPUT [option] input_declaration_list END_VAR */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1088 |
/* option -> the RETAIN/NON_RETAIN/<NULL> directive... */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1089 |
//SYM_REF3(input_declarations_c, option, input_declaration_list, method) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1090 |
void *constant_folding_c::visit(input_declarations_c *symbol) {return NULL;} // Input variables can take any initial value, so we can not set the const_value annotation! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1091 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1092 |
/* helper symbol for input_declarations */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1093 |
//SYM_LIST(input_declaration_list_c) // Not needed! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1094 |
/* VAR_OUTPUT [RETAIN | NON_RETAIN] var_init_decl_list END_VAR */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1095 |
/* option -> may be NULL ! */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1096 |
//SYM_REF3(output_declarations_c, option, var_init_decl_list, method) // Not needed since we inherit from iterator_visitor_c! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1097 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1098 |
/* VAR_IN_OUT var_declaration_list END_VAR */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1099 |
//SYM_REF1(input_output_declarations_c, var_declaration_list) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1100 |
void *constant_folding_c::visit(input_output_declarations_c *symbol) {return NULL;} // Input variables can take any initial value, so we can not set the const_value annotation! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1101 |
/* helper symbol for input_output_declarations */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1102 |
/* var_declaration_list var_declaration ';' */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1103 |
//SYM_LIST(var_declaration_list_c) // Not needed since we inherit from iterator_visitor_c! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1104 |
/* var1_list ':' array_specification */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1105 |
//SYM_REF2(array_var_declaration_c, var1_list, array_specification) // We do not yet handle arrays! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1106 |
/* var1_list ':' structure_type_name */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1107 |
//SYM_REF2(structured_var_declaration_c, var1_list, structure_type_name) // We do not yet handle structures! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1108 |
/* VAR [CONSTANT] var_init_decl_list END_VAR */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1109 |
/* option -> may be NULL ! */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1110 |
//SYM_REF2(var_declarations_c, option, var_init_decl_list) // Not needed: we inherit from iterator_c |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1111 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1112 |
/* VAR RETAIN var_init_decl_list END_VAR */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1113 |
//SYM_REF1(retentive_var_declarations_c, var_init_decl_list) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1114 |
void *constant_folding_c::visit(retentive_var_declarations_c *symbol) {return NULL;} // Retentive variables can take any initial value, so we can not set the const_value annotation! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1115 |
/* VAR [CONSTANT|RETAIN|NON_RETAIN] located_var_decl_list END_VAR */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1116 |
/* option -> may be NULL ! */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1117 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1118 |
#if 0 |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1119 |
// TODO |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1120 |
SYM_REF2(located_var_declarations_c, option, located_var_decl_list) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1121 |
/* helper symbol for located_var_declarations */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1122 |
/* located_var_decl_list located_var_decl ';' */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1123 |
SYM_LIST(located_var_decl_list_c) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1124 |
/* [variable_name] location ':' located_var_spec_init */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1125 |
/* variable_name -> may be NULL ! */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1126 |
SYM_REF3(located_var_decl_c, variable_name, location, located_var_spec_init) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1127 |
#endif |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1128 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1129 |
/*| VAR_EXTERNAL [CONSTANT] external_declaration_list END_VAR */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1130 |
/* option -> may be NULL ! */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1131 |
// SYM_REF2(external_var_declarations_c, option, external_declaration_list) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1132 |
// void *constant_folding_c::visit(external_var_declarations_c *symbol) {} // Not needed: we inherit from iterator_c |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1133 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1134 |
/* helper symbol for external_var_declarations */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1135 |
/*| external_declaration_list external_declaration';' */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1136 |
// SYM_LIST(external_declaration_list_c) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1137 |
// void *constant_folding_c::visit(external_declaration_list_c *symbol) {} // Not needed: we inherit from iterator_c |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1138 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1139 |
/* global_var_name ':' (simple_specification|subrange_specification|enumerated_specification|array_specification|prev_declared_structure_type_name|function_block_type_name */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1140 |
//SYM_REF2(external_declaration_c, global_var_name, specification) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1141 |
void *constant_folding_c::visit(external_declaration_c *symbol) { |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1142 |
// Note that specification->const_value will have been set by handle_var_extern_global_pair, which is called from declaration_check_c |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1143 |
symbol->global_var_name->const_value = symbol->specification->const_value; |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1144 |
std::string varName = get_var_name_c::get_name(symbol->global_var_name)->value; |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1145 |
values[varName] = symbol->specification->const_value; |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1146 |
return NULL; |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1147 |
} |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1148 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1149 |
/* Visitors related to GLOBAL variables are not really needed, |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1150 |
* as they are already handled by handle_var_extern_global_pair, which is called from declaration_check_c |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1151 |
* |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1152 |
* This is done like this because we need to know the pairing of external<->global variables to get the cvalue |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1153 |
* from the global variable. Since the external<->global pairing information is available in the declaration_check_c, |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1154 |
* we have that class call the constant_folding_c::handle_var_extern_global_pair(), which will actually do the |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1155 |
* constant folding of the global and the external variable declarations! |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1156 |
*/ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1157 |
/*| VAR_GLOBAL [CONSTANT|RETAIN] global_var_decl_list END_VAR */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1158 |
/* option -> may be NULL ! */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1159 |
// SYM_REF2(global_var_declarations_c, option, global_var_decl_list) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1160 |
/* helper symbol for global_var_declarations */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1161 |
/*| global_var_decl_list global_var_decl ';' */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1162 |
// SYM_LIST(global_var_decl_list_c) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1163 |
/*| global_var_spec ':' [located_var_spec_init|function_block_type_name] */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1164 |
/* type_specification ->may be NULL ! */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1165 |
//SYM_REF2(global_var_decl_c, global_var_spec, type_specification) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1166 |
/*| global_var_name location */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1167 |
//SYM_REF2(global_var_spec_c, global_var_name, location) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1168 |
/* AT direct_variable */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1169 |
//SYM_REF1(location_c, direct_variable) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1170 |
/*| global_var_list ',' global_var_name */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1171 |
//SYM_LIST(global_var_list_c) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1172 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1173 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1174 |
#if 0 |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1175 |
// TODO |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1176 |
/* var1_list ':' single_byte_string_spec */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1177 |
SYM_REF2(single_byte_string_var_declaration_c, var1_list, single_byte_string_spec) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1178 |
/* STRING ['[' integer ']'] [ASSIGN single_byte_character_string] */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1179 |
/* integer ->may be NULL ! */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1180 |
/* single_byte_character_string ->may be NULL ! */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1181 |
SYM_REF2(single_byte_string_spec_c, string_spec, single_byte_character_string) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1182 |
/* STRING ['[' integer ']'] */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1183 |
/* integer ->may be NULL ! */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1184 |
SYM_REF2(single_byte_limited_len_string_spec_c, string_type_name, character_string_len) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1185 |
/* WSTRING ['[' integer ']'] */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1186 |
/* integer ->may be NULL ! */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1187 |
SYM_REF2(double_byte_limited_len_string_spec_c, string_type_name, character_string_len) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1188 |
/* var1_list ':' double_byte_string_spec */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1189 |
SYM_REF2(double_byte_string_var_declaration_c, var1_list, double_byte_string_spec) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1190 |
/* WSTRING ['[' integer ']'] [ASSIGN double_byte_character_string] */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1191 |
/* integer ->may be NULL ! */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1192 |
/* double_byte_character_string ->may be NULL ! */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1193 |
SYM_REF2(double_byte_string_spec_c, string_spec, double_byte_character_string) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1194 |
/*| VAR [RETAIN|NON_RETAIN] incompl_located_var_decl_list END_VAR */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1195 |
/* option ->may be NULL ! */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1196 |
SYM_REF2(incompl_located_var_declarations_c, option, incompl_located_var_decl_list) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1197 |
/* helper symbol for incompl_located_var_declarations */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1198 |
/*| incompl_located_var_decl_list incompl_located_var_decl ';' */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1199 |
SYM_LIST(incompl_located_var_decl_list_c) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1200 |
/* variable_name incompl_location ':' var_spec */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1201 |
SYM_REF3(incompl_located_var_decl_c, variable_name, incompl_location, var_spec) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1202 |
/* AT incompl_location_token */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1203 |
SYM_TOKEN(incompl_location_c) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1204 |
/* intermediate helper symbol for: |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1205 |
* - non_retentive_var_decls |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1206 |
* - output_declarations |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1207 |
*/ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1208 |
SYM_LIST(var_init_decl_list_c) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1209 |
#endif |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1210 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1211 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1212 |
/***********************/ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1213 |
/* B 1.5.1 - Functions */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1214 |
/***********************/ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1215 |
/* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1216 |
//SYM_REF4(function_declaration_c, derived_function_name, type_name, var_declarations_list, function_body, enumvalue_symtable_t enumvalue_symtable;) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1217 |
void *constant_folding_c::visit(function_declaration_c *symbol) { |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1218 |
values.clear(); /* Clear global map */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1219 |
/* Add initial value of all declared variables into Values map. */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1220 |
symbol->var_declarations_list->accept(*this); |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1221 |
symbol->function_body->accept(*this); |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1222 |
return NULL; |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1223 |
} |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1224 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1225 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1226 |
/*****************************/ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1227 |
/* B 1.5.2 - Function Blocks */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1228 |
/*****************************/ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1229 |
/* FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1230 |
/* enumvalue_symtable is filled in by enum_declaration_check_c, during stage3 semantic verification, with a list of all enumerated constants declared inside this POU */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1231 |
//SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body, enumvalue_symtable_t enumvalue_symtable;) |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1232 |
void *constant_folding_c::visit(function_block_declaration_c *symbol) { |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1233 |
values.clear(); /* Clear global map */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1234 |
/* Add initial value of all declared variables into Values map. */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1235 |
symbol->var_declarations->accept(*this); |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1236 |
symbol->fblock_body->accept(*this); |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1237 |
return NULL; |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1238 |
} |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1239 |
|
788
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1240 |
|
774
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1241 |
/**********************/ |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1242 |
/* B 1.5.3 - Programs */ |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1243 |
/**********************/ |
963
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1244 |
/* PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1245 |
//SYM_REF3(program_declaration_c, program_type_name, var_declarations, function_block_body, enumvalue_symtable_t enumvalue_symtable;) |
774
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1246 |
void *constant_folding_c::visit(program_declaration_c *symbol) { |
963
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1247 |
values.clear(); /* Clear global map */ |
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1248 |
/* Add initial value of all declared variables into Values map. */ |
787
6e2671e0f1a8
Fix constant_folding missing call. [Bug found by Mario.]
Manuele Conti <conti.ma@alice.it>
parents:
783
diff
changeset
|
1249 |
symbol->var_declarations->accept(*this); |
774
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1250 |
symbol->function_block_body->accept(*this); |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1251 |
return NULL; |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1252 |
} |
612 | 1253 |
|
1254 |
||
1255 |
/****************************************/ |
|
1256 |
/* B.2 - Language IL (Instruction List) */ |
|
1257 |
/****************************************/ |
|
1258 |
/***********************************/ |
|
1259 |
/* B 2.1 Instructions and Operands */ |
|
1260 |
/***********************************/ |
|
1261 |
/* Not needed, since we inherit from iterator_visitor_c */ |
|
1262 |
/*| instruction_list il_instruction */ |
|
1263 |
// SYM_LIST(instruction_list_c) |
|
1264 |
// void *constant_folding_c::visit(instruction_list_c *symbol) {} |
|
1265 |
||
1266 |
/* | label ':' [il_incomplete_instruction] eol_list */ |
|
1267 |
// SYM_REF2(il_instruction_c, label, il_instruction) |
|
1268 |
// void *visit(instruction_list_c *symbol); |
|
1269 |
void *constant_folding_c::visit(il_instruction_c *symbol) { |
|
1270 |
if (NULL == symbol->il_instruction) { |
|
1271 |
/* This empty/null il_instruction does not change the value of the current/default IL variable. |
|
1272 |
* So it inherits the candidate_datatypes from it's previous IL instructions! |
|
1273 |
*/ |
|
1274 |
intersect_prev_cvalues(symbol); |
|
1275 |
} else { |
|
1276 |
il_instruction_c fake_prev_il_instruction = *symbol; |
|
1277 |
intersect_prev_cvalues(&fake_prev_il_instruction); |
|
1278 |
||
1279 |
if (symbol->prev_il_instruction.size() == 0) prev_il_instruction = NULL; |
|
1280 |
else prev_il_instruction = &fake_prev_il_instruction; |
|
1281 |
symbol->il_instruction->accept(*this); |
|
1282 |
prev_il_instruction = NULL; |
|
1283 |
||
1284 |
/* This object has (inherits) the same cvalues as the il_instruction */ |
|
1285 |
symbol->const_value = symbol->il_instruction->const_value; |
|
1286 |
} |
|
1287 |
||
1288 |
return NULL; |
|
1289 |
} |
|
1290 |
||
1291 |
||
1292 |
void *constant_folding_c::visit(il_simple_operation_c *symbol) { |
|
1293 |
/* determine the cvalue of the operand */ |
|
1294 |
if (NULL != symbol->il_operand) { |
|
1295 |
symbol->il_operand->accept(*this); |
|
1296 |
} |
|
1297 |
/* determine the cvalue resulting from executing the il_operator... */ |
|
1298 |
il_operand = symbol->il_operand; |
|
1299 |
symbol->il_simple_operator->accept(*this); |
|
1300 |
il_operand = NULL; |
|
1301 |
/* This object has (inherits) the same cvalues as the il_instruction */ |
|
1302 |
symbol->const_value = symbol->il_simple_operator->const_value; |
|
1303 |
return NULL; |
|
1304 |
} |
|
1305 |
||
1306 |
||
1307 |
/* TODO: handle function invocations... */ |
|
1308 |
/* | function_name [il_operand_list] */ |
|
1309 |
/* NOTE: The parameters 'called_function_declaration' and 'extensible_param_count' are used to pass data between the stage 3 and stage 4. */ |
|
1310 |
// SYM_REF2(il_function_call_c, function_name, il_operand_list, symbol_c *called_function_declaration; int extensible_param_count;) |
|
1311 |
// void *constant_folding_c::visit(il_function_call_c *symbol) {} |
|
1312 |
||
1313 |
||
1314 |
/* | il_expr_operator '(' [il_operand] eol_list [simple_instr_list] ')' */ |
|
1315 |
// SYM_REF3(il_expression_c, il_expr_operator, il_operand, simple_instr_list); |
|
1316 |
void *constant_folding_c::visit(il_expression_c *symbol) { |
|
1317 |
symbol_c *prev_il_instruction_backup = prev_il_instruction; |
|
1318 |
||
690
6156ee2b4e32
Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents:
667
diff
changeset
|
1319 |
/* 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! */ |
6156ee2b4e32
Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents:
667
diff
changeset
|
1320 |
// if (NULL != symbol->il_operand) |
6156ee2b4e32
Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents:
667
diff
changeset
|
1321 |
// symbol->il_operand->accept(*this); |
612 | 1322 |
|
1323 |
if(symbol->simple_instr_list != NULL) |
|
1324 |
symbol->simple_instr_list->accept(*this); |
|
1325 |
||
1326 |
/* Now do the operation, */ |
|
1327 |
il_operand = symbol->simple_instr_list; |
|
1328 |
prev_il_instruction = prev_il_instruction_backup; |
|
1329 |
symbol->il_expr_operator->accept(*this); |
|
1330 |
il_operand = NULL; |
|
1331 |
||
1332 |
/* This object has (inherits) the same cvalues as the il_instruction */ |
|
1333 |
symbol->const_value = symbol->il_expr_operator->const_value; |
|
690
6156ee2b4e32
Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents:
667
diff
changeset
|
1334 |
|
6156ee2b4e32
Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents:
667
diff
changeset
|
1335 |
/* Since stage2 will insert an artificial (and equivalent) LD <il_operand> to the simple_instr_list when an 'il_operand' exists, we know |
6156ee2b4e32
Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents:
667
diff
changeset
|
1336 |
* that if (symbol->il_operand != NULL), then the first IL instruction in the simple_instr_list will be the equivalent and artificial |
6156ee2b4e32
Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents:
667
diff
changeset
|
1337 |
* 'LD <il_operand>' IL instruction. |
6156ee2b4e32
Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents:
667
diff
changeset
|
1338 |
* Just to be cosistent, we will copy the constant info back into the il_operand, even though this should not be necessary! |
6156ee2b4e32
Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents:
667
diff
changeset
|
1339 |
*/ |
6156ee2b4e32
Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents:
667
diff
changeset
|
1340 |
if ((NULL != symbol->il_operand) && ((NULL == symbol->simple_instr_list) || (0 == ((list_c *)symbol->simple_instr_list)->n))) ERROR; // stage2 is not behaving as we expect it to! |
6156ee2b4e32
Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents:
667
diff
changeset
|
1341 |
if (NULL != symbol->il_operand) |
6156ee2b4e32
Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents:
667
diff
changeset
|
1342 |
symbol->il_operand->const_value = ((list_c *)symbol->simple_instr_list)->elements[0]->const_value; |
6156ee2b4e32
Correctly generate C code for IL expressions, i.e. IL instructions inside parenthesis.
Mario de Sousa <msousa@fe.up.pt>
parents:
667
diff
changeset
|
1343 |
|
612 | 1344 |
return NULL; |
1345 |
} |
|
1346 |
||
1347 |
||
1348 |
||
1349 |
void *constant_folding_c::visit(il_jump_operation_c *symbol) { |
|
1350 |
/* recursive call to fill const values... */ |
|
1351 |
il_operand = NULL; |
|
1352 |
symbol->il_jump_operator->accept(*this); |
|
1353 |
il_operand = NULL; |
|
1354 |
/* This object has (inherits) the same cvalues as the il_jump_operator */ |
|
1355 |
symbol->const_value = symbol->il_jump_operator->const_value; |
|
1356 |
return NULL; |
|
1357 |
} |
|
1358 |
||
1359 |
||
1360 |
||
1361 |
/* FB calls leave the value in the accumulator unchanged */ |
|
1362 |
/* il_call_operator prev_declared_fb_name |
|
1363 |
* | il_call_operator prev_declared_fb_name '(' ')' |
|
1364 |
* | il_call_operator prev_declared_fb_name '(' eol_list ')' |
|
1365 |
* | il_call_operator prev_declared_fb_name '(' il_operand_list ')' |
|
1366 |
* | il_call_operator prev_declared_fb_name '(' eol_list il_param_list ')' |
|
1367 |
*/ |
|
1368 |
/* NOTE: The parameter 'called_fb_declaration'is used to pass data between stage 3 and stage4 (although currently it is not used in stage 4 */ |
|
1369 |
// SYM_REF4(il_fb_call_c, il_call_operator, fb_name, il_operand_list, il_param_list, symbol_c *called_fb_declaration) |
|
1370 |
void *constant_folding_c::visit(il_fb_call_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1371 |
||
1372 |
||
1373 |
/* TODO: handle function invocations... */ |
|
1374 |
/* | function_name '(' eol_list [il_param_list] ')' */ |
|
1375 |
/* NOTE: The parameter 'called_function_declaration' is used to pass data between the stage 3 and stage 4. */ |
|
1376 |
// SYM_REF2(il_formal_funct_call_c, function_name, il_param_list, symbol_c *called_function_declaration; int extensible_param_count;) |
|
1377 |
// void *constant_folding_c::visit(il_formal_funct_call_c *symbol) {return NULL;} |
|
1378 |
||
1379 |
||
1380 |
||
1381 |
/* Not needed, since we inherit from iterator_visitor_c */ |
|
1382 |
// void *constant_folding_c::visit(il_operand_list_c *symbol); |
|
1383 |
||
1384 |
||
1385 |
||
1386 |
/* | simple_instr_list il_simple_instruction */ |
|
1387 |
/* This object is referenced by il_expression_c objects */ |
|
1388 |
void *constant_folding_c::visit(simple_instr_list_c *symbol) { |
|
1389 |
if (symbol->n <= 0) |
|
1390 |
return NULL; /* List is empty! Nothing to do. */ |
|
1391 |
||
1392 |
for(int i = 0; i < symbol->n; i++) |
|
1393 |
symbol->elements[i]->accept(*this); |
|
1394 |
||
1395 |
/* This object has (inherits) the same cvalues as the il_jump_operator */ |
|
1396 |
symbol->const_value = symbol->elements[symbol->n-1]->const_value; |
|
1397 |
return NULL; |
|
1398 |
} |
|
1399 |
||
1400 |
||
1401 |
||
1402 |
// SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;) |
|
1403 |
void *constant_folding_c::visit(il_simple_instruction_c *symbol) { |
|
1404 |
if (symbol->prev_il_instruction.size() > 1) ERROR; /* There should be no labeled insructions inside an IL expression! */ |
|
1405 |
if (symbol->prev_il_instruction.size() == 0) prev_il_instruction = NULL; |
|
1406 |
else prev_il_instruction = symbol->prev_il_instruction[0]; |
|
1407 |
symbol->il_simple_instruction->accept(*this); |
|
1408 |
prev_il_instruction = NULL; |
|
1409 |
||
1410 |
/* This object has (inherits) the same cvalues as the il_jump_operator */ |
|
1411 |
symbol->const_value = symbol->il_simple_instruction->const_value; |
|
1412 |
return NULL; |
|
1413 |
} |
|
1414 |
||
1415 |
||
1416 |
/* |
|
1417 |
void *visit(il_param_list_c *symbol); |
|
1418 |
void *visit(il_param_assignment_c *symbol); |
|
1419 |
void *visit(il_param_out_assignment_c *symbol); |
|
1420 |
*/ |
|
1421 |
||
1422 |
||
1423 |
/*******************/ |
|
1424 |
/* B 2.2 Operators */ |
|
1425 |
/*******************/ |
|
1426 |
void *constant_folding_c::visit( LD_operator_c *symbol) {return handle_move(symbol, il_operand);} |
|
1427 |
void *constant_folding_c::visit( LDN_operator_c *symbol) {return handle_not (symbol, il_operand);} |
|
1428 |
||
1429 |
/* NOTE: we are implementing a constant folding algorithm, not a constant propagation algorithm. |
|
1430 |
* For the constant propagation algorithm, the correct implementation of ST(N)_operator_c would be... |
|
1431 |
*/ |
|
1432 |
//void *constant_folding_c::visit( ST_operator_c *symbol) {return handle_move(il_operand, symbol);} |
|
1433 |
//void *constant_folding_c::visit( STN_operator_c *symbol) {return handle_not (il_operand, symbol);} |
|
1434 |
void *constant_folding_c::visit( ST_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1435 |
void *constant_folding_c::visit( STN_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1436 |
||
1437 |
/* NOTE: the standard allows syntax in which the NOT operator is followed by an optional <il_operand> |
|
1438 |
* NOT [<il_operand>] |
|
1439 |
* However, it does not define the semantic of the NOT operation when the <il_operand> is specified. |
|
1440 |
* We therefore consider it an error if an il_operand is specified! This error will be caught elsewhere! |
|
1441 |
*/ |
|
1442 |
void *constant_folding_c::visit( NOT_operator_c *symbol) {return handle_not(symbol, prev_il_instruction);} |
|
1443 |
||
1444 |
/* NOTE: Since we are only implementing a constant folding algorithm, and not a constant propagation algorithm, |
|
1445 |
* the following IL instructions do not change/set the value of the il_operand! |
|
1446 |
*/ |
|
1447 |
void *constant_folding_c::visit( S_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1448 |
void *constant_folding_c::visit( R_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1449 |
||
1450 |
/* FB calls leave the value in the accumulator unchanged */ |
|
1451 |
void *constant_folding_c::visit( S1_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1452 |
void *constant_folding_c::visit( R1_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1453 |
void *constant_folding_c::visit( CLK_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1454 |
void *constant_folding_c::visit( CU_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1455 |
void *constant_folding_c::visit( CD_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1456 |
void *constant_folding_c::visit( PV_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1457 |
void *constant_folding_c::visit( IN_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1458 |
void *constant_folding_c::visit( PT_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1459 |
||
1460 |
void *constant_folding_c::visit( AND_operator_c *symbol) {return handle_and (symbol, prev_il_instruction, il_operand);} |
|
1461 |
void *constant_folding_c::visit( OR_operator_c *symbol) {return handle_or (symbol, prev_il_instruction, il_operand);} |
|
1462 |
void *constant_folding_c::visit( XOR_operator_c *symbol) {return handle_xor (symbol, prev_il_instruction, il_operand);} |
|
1463 |
void *constant_folding_c::visit( ANDN_operator_c *symbol) { handle_and (symbol, prev_il_instruction, il_operand); return handle_not(symbol, symbol);} |
|
1464 |
void *constant_folding_c::visit( ORN_operator_c *symbol) { handle_or (symbol, prev_il_instruction, il_operand); return handle_not(symbol, symbol);} |
|
1465 |
void *constant_folding_c::visit( XORN_operator_c *symbol) { handle_xor (symbol, prev_il_instruction, il_operand); return handle_not(symbol, symbol);} |
|
1466 |
||
1467 |
void *constant_folding_c::visit( ADD_operator_c *symbol) {return handle_add (symbol, prev_il_instruction, il_operand);} |
|
1468 |
void *constant_folding_c::visit( SUB_operator_c *symbol) {return handle_sub (symbol, prev_il_instruction, il_operand);} |
|
1469 |
void *constant_folding_c::visit( MUL_operator_c *symbol) {return handle_mul (symbol, prev_il_instruction, il_operand);} |
|
1470 |
void *constant_folding_c::visit( DIV_operator_c *symbol) {return handle_div (symbol, prev_il_instruction, il_operand);} |
|
1471 |
void *constant_folding_c::visit( MOD_operator_c *symbol) {return handle_mod (symbol, prev_il_instruction, il_operand);} |
|
1472 |
||
1473 |
void *constant_folding_c::visit( GT_operator_c *symbol) { handle_cmp (symbol, prev_il_instruction, il_operand, > );} |
|
1474 |
void *constant_folding_c::visit( GE_operator_c *symbol) { handle_cmp (symbol, prev_il_instruction, il_operand, >=);} |
|
1475 |
void *constant_folding_c::visit( EQ_operator_c *symbol) { handle_cmp (symbol, prev_il_instruction, il_operand, ==);} |
|
1476 |
void *constant_folding_c::visit( LT_operator_c *symbol) { handle_cmp (symbol, prev_il_instruction, il_operand, < );} |
|
1477 |
void *constant_folding_c::visit( LE_operator_c *symbol) { handle_cmp (symbol, prev_il_instruction, il_operand, <=);} |
|
1478 |
void *constant_folding_c::visit( NE_operator_c *symbol) { handle_cmp (symbol, prev_il_instruction, il_operand, !=);} |
|
1479 |
||
1480 |
void *constant_folding_c::visit( CAL_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1481 |
void *constant_folding_c::visit( RET_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1482 |
void *constant_folding_c::visit( JMP_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1483 |
void *constant_folding_c::visit( CALC_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1484 |
void *constant_folding_c::visit(CALCN_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1485 |
void *constant_folding_c::visit( RETC_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1486 |
void *constant_folding_c::visit(RETCN_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1487 |
void *constant_folding_c::visit( JMPC_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1488 |
void *constant_folding_c::visit(JMPCN_operator_c *symbol) {return handle_move(symbol, prev_il_instruction);} |
|
1489 |
||
1490 |
||
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
1491 |
|
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
1492 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
1493 |
/***************************************/ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
1494 |
/* B.3 - Language ST (Structured Text) */ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
1495 |
/***************************************/ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
1496 |
/***********************/ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
1497 |
/* B 3.1 - Expressions */ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
1498 |
/***********************/ |
612 | 1499 |
void *constant_folding_c::visit( or_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_or (symbol, symbol->l_exp, symbol->r_exp);} |
1500 |
void *constant_folding_c::visit( xor_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_xor(symbol, symbol->l_exp, symbol->r_exp);} |
|
1501 |
void *constant_folding_c::visit( and_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_and(symbol, symbol->l_exp, symbol->r_exp);} |
|
1502 |
||
1503 |
void *constant_folding_c::visit( equ_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); handle_cmp (symbol, symbol->l_exp, symbol->r_exp, ==);} |
|
1504 |
void *constant_folding_c::visit(notequ_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); handle_cmp (symbol, symbol->l_exp, symbol->r_exp, !=);} |
|
1505 |
void *constant_folding_c::visit( lt_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); handle_cmp (symbol, symbol->l_exp, symbol->r_exp, < );} |
|
1506 |
void *constant_folding_c::visit( gt_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); handle_cmp (symbol, symbol->l_exp, symbol->r_exp, > );} |
|
1507 |
void *constant_folding_c::visit( le_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); handle_cmp (symbol, symbol->l_exp, symbol->r_exp, <=);} |
|
1508 |
void *constant_folding_c::visit( ge_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); handle_cmp (symbol, symbol->l_exp, symbol->r_exp, >=);} |
|
1509 |
||
1510 |
void *constant_folding_c::visit( add_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_add(symbol, symbol->l_exp, symbol->r_exp);} |
|
1511 |
void *constant_folding_c::visit( sub_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_sub(symbol, symbol->l_exp, symbol->r_exp);} |
|
1512 |
void *constant_folding_c::visit( mul_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_mul(symbol, symbol->l_exp, symbol->r_exp);} |
|
1513 |
void *constant_folding_c::visit( div_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_div(symbol, symbol->l_exp, symbol->r_exp);} |
|
1514 |
void *constant_folding_c::visit( mod_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_mod(symbol, symbol->l_exp, symbol->r_exp);} |
|
1515 |
void *constant_folding_c::visit( power_expression_c *symbol) {symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); return handle_pow(symbol, symbol->l_exp, symbol->r_exp);} |
|
1516 |
||
1517 |
void *constant_folding_c::visit( neg_expression_c *symbol) {symbol-> exp->accept(*this); return handle_neg(symbol, symbol->exp);} |
|
1518 |
void *constant_folding_c::visit( not_expression_c *symbol) {symbol-> exp->accept(*this); return handle_not(symbol, symbol->exp);} |
|
1519 |
||
1520 |
/* TODO: handle function invocations... */ |
|
633
73b56dc69e61
Fix bug with task interval using fixed_point value for duration items
Laurent Bessard
parents:
621
diff
changeset
|
1521 |
// void *fill_candidate_datatypes_c::visit(function_invocation_c *symbol) {} |
774
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1522 |
|
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1523 |
|
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1524 |
|
792
78083edf93d5
disable not yet complete constant propagation algorithm (currently brocken and producing incorrect results),
Mario de Sousa <msousa@fe.up.pt>
parents:
791
diff
changeset
|
1525 |
#if DO_CONSTANT_PROPAGATION__ |
774
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1526 |
/*********************************/ |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1527 |
/* B 3.2.1 Assignment Statements */ |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1528 |
/*********************************/ |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1529 |
void *constant_folding_c::visit(assignment_statement_c *symbol) { |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1530 |
std::string varName; |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1531 |
|
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1532 |
symbol->r_exp->accept(*this); |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1533 |
symbol->l_exp->const_value = symbol->r_exp->const_value; |
783
3bd2704d9ba9
Remove redundant class for get variable name.
Manuele Conti <conti.ma@alice.it>
parents:
782
diff
changeset
|
1534 |
varName = get_var_name_c::get_name(symbol->l_exp)->value; |
774
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1535 |
values[varName] = symbol->l_exp->const_value; |
780
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1536 |
|
774
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1537 |
return NULL; |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1538 |
} |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1539 |
|
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1540 |
/********************************/ |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1541 |
/* B 3.2.3 Selection Statements */ |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1542 |
/********************************/ |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1543 |
void *constant_folding_c::visit(if_statement_c *symbol) { |
788
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1544 |
map_values_t values_incoming; |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1545 |
map_values_t values_statement_result; |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1546 |
map_values_t values_elsestatement_result; |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1547 |
map_values_t::iterator itr; |
780
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1548 |
|
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1549 |
/* Optimize dead code */ |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1550 |
symbol->expression->accept(*this); |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1551 |
if (VALID_CVALUE(bool, symbol->expression) && GET_CVALUE(bool, symbol->expression) == false) |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1552 |
return NULL; |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1553 |
|
774
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1554 |
values_incoming = values; /* save incoming status */ |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1555 |
symbol->statement_list->accept(*this); |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1556 |
values_statement_result = values; |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1557 |
if (NULL != symbol->else_statement_list) { |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1558 |
values = values_incoming; |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1559 |
symbol->else_statement_list->accept(*this); |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1560 |
values_elsestatement_result = values; |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1561 |
} else |
979af2009d88
Start to implement constant propagation algorithm.
Manuele Conti <conti.ma@alice.it>
parents:
735
diff
changeset
|
1562 |
values_elsestatement_result = values_incoming; |
788
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1563 |
values = inner_left_join_values(values_statement_result, values_elsestatement_result); |
780
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1564 |
|
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1565 |
return NULL; |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1566 |
} |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1567 |
|
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1568 |
/********************************/ |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1569 |
/* B 3.2.4 Iteration Statements */ |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1570 |
/********************************/ |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1571 |
void *constant_folding_c::visit(for_statement_c *symbol) { |
788
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1572 |
map_values_t values_incoming; |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1573 |
map_values_t values_statement_result; |
782
c8cd69801b7e
Fix constant propagation alg. in for statement like Mario suggestion.
Manuele Conti <conti.ma@alice.it>
parents:
781
diff
changeset
|
1574 |
std::string varName; |
780
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1575 |
|
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1576 |
values_incoming = values; /* save incoming status */ |
782
c8cd69801b7e
Fix constant propagation alg. in for statement like Mario suggestion.
Manuele Conti <conti.ma@alice.it>
parents:
781
diff
changeset
|
1577 |
symbol->beg_expression->accept(*this); |
c8cd69801b7e
Fix constant propagation alg. in for statement like Mario suggestion.
Manuele Conti <conti.ma@alice.it>
parents:
781
diff
changeset
|
1578 |
symbol->end_expression->accept(*this); |
783
3bd2704d9ba9
Remove redundant class for get variable name.
Manuele Conti <conti.ma@alice.it>
parents:
782
diff
changeset
|
1579 |
varName = get_var_name_c::get_name(symbol->control_variable)->value; |
788
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1580 |
values[varName]._int64.status = symbol_c::cs_non_const; |
782
c8cd69801b7e
Fix constant propagation alg. in for statement like Mario suggestion.
Manuele Conti <conti.ma@alice.it>
parents:
781
diff
changeset
|
1581 |
|
c8cd69801b7e
Fix constant propagation alg. in for statement like Mario suggestion.
Manuele Conti <conti.ma@alice.it>
parents:
781
diff
changeset
|
1582 |
/* Optimize dead code */ |
788
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1583 |
if (NULL != symbol->by_expression) { |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1584 |
symbol->by_expression->accept(*this); |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1585 |
if (VALID_CVALUE(int64, symbol->by_expression ) && GET_CVALUE(int64, symbol->by_expression ) > 0 && |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1586 |
VALID_CVALUE(int64, symbol->beg_expression) && VALID_CVALUE(int64, symbol->end_expression) && |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1587 |
GET_CVALUE(int64, symbol->beg_expression) > GET_CVALUE(int64, symbol->end_expression)) |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1588 |
return NULL; |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1589 |
|
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1590 |
if (VALID_CVALUE(int64, symbol->by_expression ) && GET_CVALUE(int64, symbol->by_expression ) < 0 && |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1591 |
VALID_CVALUE(int64, symbol->beg_expression) && VALID_CVALUE(int64, symbol->end_expression) && |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1592 |
GET_CVALUE(int64, symbol->beg_expression) < GET_CVALUE(int64, symbol->end_expression)) |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1593 |
return NULL; |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1594 |
|
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1595 |
} else { |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1596 |
if (VALID_CVALUE(int64, symbol->beg_expression) && VALID_CVALUE(int64, symbol->end_expression) && |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1597 |
GET_CVALUE(int64, symbol->beg_expression) > GET_CVALUE(int64, symbol->end_expression)) |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1598 |
return NULL; |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1599 |
|
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1600 |
} |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1601 |
|
782
c8cd69801b7e
Fix constant propagation alg. in for statement like Mario suggestion.
Manuele Conti <conti.ma@alice.it>
parents:
781
diff
changeset
|
1602 |
|
780
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1603 |
symbol->statement_list->accept(*this); |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1604 |
values_statement_result = values; |
788
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1605 |
values = inner_left_join_values(values_statement_result, values_incoming); |
780
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1606 |
|
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1607 |
return NULL; |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1608 |
} |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1609 |
|
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1610 |
void *constant_folding_c::visit(while_statement_c *symbol) { |
788
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1611 |
map_values_t values_incoming; |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1612 |
map_values_t values_statement_result; |
780
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1613 |
|
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1614 |
/* Optimize dead code */ |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1615 |
symbol->expression->accept(*this); |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1616 |
if (VALID_CVALUE(bool, symbol->expression) && GET_CVALUE(bool, symbol->expression) == false) |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1617 |
return NULL; |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1618 |
|
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1619 |
values_incoming = values; /* save incoming status */ |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1620 |
symbol->statement_list->accept(*this); |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1621 |
values_statement_result = values; |
788
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1622 |
values = inner_left_join_values(values_statement_result, values_incoming); |
780
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1623 |
|
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1624 |
return NULL; |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1625 |
} |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1626 |
|
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1627 |
void *constant_folding_c::visit(repeat_statement_c *symbol) { |
788
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1628 |
map_values_t values_incoming; |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1629 |
map_values_t values_statement_result; |
780
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1630 |
|
790
a722594dcd64
Fix constant propagation for repeat_statement_c class.
Manuele Conti <conti.ma@alice.it>
parents:
789
diff
changeset
|
1631 |
values_incoming = values; /* save incoming status */ |
a722594dcd64
Fix constant propagation for repeat_statement_c class.
Manuele Conti <conti.ma@alice.it>
parents:
789
diff
changeset
|
1632 |
symbol->statement_list->accept(*this); |
a722594dcd64
Fix constant propagation for repeat_statement_c class.
Manuele Conti <conti.ma@alice.it>
parents:
789
diff
changeset
|
1633 |
|
780
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1634 |
/* Optimize dead code */ |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1635 |
symbol->expression->accept(*this); |
790
a722594dcd64
Fix constant propagation for repeat_statement_c class.
Manuele Conti <conti.ma@alice.it>
parents:
789
diff
changeset
|
1636 |
if (VALID_CVALUE(bool, symbol->expression) && GET_CVALUE(bool, symbol->expression) == true) |
780
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1637 |
return NULL; |
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1638 |
|
9fbdf8a7430e
Add constant propagation algorithm for loop cycles.
Manuele Conti <conti.ma@alice.it>
parents:
776
diff
changeset
|
1639 |
values_statement_result = values; |
788
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1640 |
values = inner_left_join_values(values_statement_result, values_incoming); |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1641 |
|
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1642 |
return NULL; |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1643 |
} |
aa56031e5cb3
Implement Mario's suggestions:
Manuele Conti <conti.ma@alice.it>
parents:
787
diff
changeset
|
1644 |
|
792
78083edf93d5
disable not yet complete constant propagation algorithm (currently brocken and producing incorrect results),
Mario de Sousa <msousa@fe.up.pt>
parents:
791
diff
changeset
|
1645 |
#endif // DO_CONSTANT_PROPAGATION__ |
78083edf93d5
disable not yet complete constant propagation algorithm (currently brocken and producing incorrect results),
Mario de Sousa <msousa@fe.up.pt>
parents:
791
diff
changeset
|
1646 |
|
78083edf93d5
disable not yet complete constant propagation algorithm (currently brocken and producing incorrect results),
Mario de Sousa <msousa@fe.up.pt>
parents:
791
diff
changeset
|
1647 |
|
963
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1648 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1649 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1650 |
|
e3d4dca7520b
Do constant folding of variable's initial value (allows correct C code generation with variables in the subrange of an array declaration: ARRAY [1..max] of INT).
mjsousa
parents:
945
diff
changeset
|
1651 |