50 #include <vector> |
50 #include <vector> |
51 #include <string> |
51 #include <string> |
52 #include <stdint.h> // required for uint64_t, etc... |
52 #include <stdint.h> // required for uint64_t, etc... |
53 |
53 |
54 |
54 |
55 |
55 /* Determine, for the current platform, which data type (float, double or long double) uses 64 bits. */ |
56 /* NOTE: we cant use sizeof() in pre-processor directives, so we do it another way... */ |
56 /* NOTE: we cant use sizeof() in pre-processor directives, so we do it another way... */ |
57 #include <float.h> |
57 #include <float.h> |
58 #if (LDBL_MANT_DIG == 53) /* NOTE: 64 bit IEC559 real has 53 bits for mantissa! */ |
58 #if (LDBL_MANT_DIG == 53) /* NOTE: 64 bit IEC559 real has 53 bits for mantissa! */ |
59 #define long_double long double |
59 #define long_double long double |
60 #define real64_t long_double /* so we can later use #if (real64_t == long_double) directives in the code! */ |
60 #define real64_t long_double /* so we can later use #if (real64_t == long_double) directives in the code! */ |
77 |
77 |
78 |
78 |
79 class symbol_c; // forward declaration |
79 class symbol_c; // forward declaration |
80 |
80 |
81 |
81 |
|
82 |
|
83 |
|
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
82 /* The base class of all symbols */ |
91 /* The base class of all symbols */ |
83 class symbol_c { |
92 class symbol_c { |
84 |
93 |
85 public: |
94 public: |
86 /* |
95 /* |
87 * Line number for the purposes of error checking |
96 * Line number for the purposes of error checking. |
|
97 * Annotated (inserted) by stage1_2 |
88 */ |
98 */ |
89 int first_line; |
99 int first_line; |
90 int first_column; |
100 int first_column; |
91 const char *first_file; /* filename referenced by first line/column */ |
101 const char *first_file; /* filename referenced by first line/column */ |
92 long int first_order; /* relative order in which it is read by lexcial analyser */ |
102 long int first_order; /* relative order in which it is read by lexcial analyser */ |
93 int last_line; |
103 int last_line; |
94 int last_column; |
104 int last_column; |
95 const char *last_file; /* filename referenced by last line/column */ |
105 const char *last_file; /* filename referenced by last line/column */ |
96 long int last_order; /* relative order in which it is read by lexcial analyser */ |
106 long int last_order; /* relative order in which it is read by lexcial analyser */ |
|
107 |
|
108 |
|
109 /* |
|
110 * Annotations produced during stage 3 |
|
111 */ |
|
112 /*** Data type analysis ***/ |
97 std::vector <symbol_c *> candidate_datatypes; /* All possible data types the expression/literal/etc. may take. Filled in stage3 by fill_candidate_datatypes_c class */ |
113 std::vector <symbol_c *> candidate_datatypes; /* All possible data types the expression/literal/etc. may take. Filled in stage3 by fill_candidate_datatypes_c class */ |
98 /* Data type of the expression/literal/etc. Filled in stage3 by narrow_candidate_datatypes_c |
114 /* Data type of the expression/literal/etc. Filled in stage3 by narrow_candidate_datatypes_c |
99 * If set to NULL, it means it has not yet been evaluated. |
115 * If set to NULL, it means it has not yet been evaluated. |
100 * If it points to an object of type invalid_type_name_c, it means it is invalid. |
116 * If it points to an object of type invalid_type_name_c, it means it is invalid. |
101 * Otherwise, it points to an object of the apropriate data type (e.g. int_type_name_c, bool_type_name_c, ...) |
117 * Otherwise, it points to an object of the apropriate data type (e.g. int_type_name_c, bool_type_name_c, ...) |
102 */ |
118 */ |
103 symbol_c *datatype; |
119 symbol_c *datatype; |
104 |
120 |
105 real64_t *const_value_real; |
121 /*** constant folding ***/ |
106 int64_t *const_value_integer; |
122 /* During stage 3 (semantic analysis/checking) we will be doing constant folding. |
107 uint64_t *const_value_uinteger; |
123 * That algorithm will anotate the abstract syntax tree with the result of operations |
108 bool *const_value_bool; |
124 * on literals (i.e. 44 + 55 will store the result 99). |
|
125 * Since the same source code (e.g. 1 + 0) may actually be a BOOL or an ANY_INT, |
|
126 * or an ANY_BIT, we need to handle all possibilities, and determine the result of the |
|
127 * operation assuming each type. |
|
128 * For this reason, we have one entry for each possible type, with some expressions |
|
129 * having more than one entry filled in! |
|
130 */ |
|
131 typedef enum { cs_undefined, /* not defined --> const_value is not valid! */ |
|
132 cs_const_value, /* const value is valid */ |
|
133 cs_overflow /* result produced overflow or underflow --> const_value is not valid! */ |
|
134 } const_status_t; |
|
135 |
|
136 typedef struct { |
|
137 const_status_t status; |
|
138 real64_t value; |
|
139 } const_value_real64_t; |
|
140 const_value_real64_t *const_value_real64; /* when NULL --> UNDEFINED */ |
|
141 |
|
142 typedef struct { |
|
143 const_status_t status; |
|
144 int64_t value; |
|
145 } const_value_int64_t; |
|
146 const_value_int64_t *const_value_int64; /* when NULL --> UNDEFINED */ |
|
147 |
|
148 typedef struct { |
|
149 const_status_t status; |
|
150 uint64_t value; |
|
151 } const_value_uint64_t; |
|
152 const_value_uint64_t *const_value_uint64; /* when NULL --> UNDEFINED */ |
|
153 |
|
154 typedef struct { |
|
155 const_status_t status; |
|
156 bool value; |
|
157 } const_value_bool_t; |
|
158 const_value_bool_t *const_value_bool; /* when NULL --> UNDEFINED */ |
109 |
159 |
110 |
160 |
111 public: |
161 public: |
112 /* default constructor */ |
162 /* default constructor */ |
113 symbol_c(int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0, /* order in which it is read by lexcial analyser */ |
163 symbol_c(int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0, /* order in which it is read by lexcial analyser */ |