45 #ifndef _ABSYNTAX_HH |
45 #ifndef _ABSYNTAX_HH |
46 #define _ABSYNTAX_HH |
46 #define _ABSYNTAX_HH |
47 |
47 |
48 |
48 |
49 #include <stdio.h> // required for NULL |
49 #include <stdio.h> // required for NULL |
|
50 #include <vector> |
|
51 #include <string> |
|
52 #include <stdint.h> // required for uint64_t, etc... |
|
53 #include "../main.hh" // required for uint8_t, real_64_t, ..., and the macros INT8_MAX, REAL32_MAX, ... */ |
|
54 |
|
55 |
|
56 |
50 |
57 |
51 /* Forward declaration of the visitor interface |
58 /* Forward declaration of the visitor interface |
52 * dclared in the visitor.hh file |
59 * declared in the visitor.hh file |
53 * We cannot include the visitor.hh file, as it will |
60 * We cannot include the visitor.hh file, as it will |
54 * include this same file first, as it too requires references |
61 * include this same file first, as it too requires references |
55 * to the abstract syntax classes defined here. |
62 * to the abstract syntax classes defined here. |
56 */ |
63 */ |
57 class visitor_c; // forward declaration |
64 class visitor_c; // forward declaration |
59 |
66 |
60 class symbol_c; // forward declaration |
67 class symbol_c; // forward declaration |
61 |
68 |
62 |
69 |
63 |
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 |
64 /* The base class of all symbols */ |
79 /* The base class of all symbols */ |
65 class symbol_c { |
80 class symbol_c { |
66 |
81 |
67 public: |
82 public: |
68 /* |
83 /* |
69 * Line number for the purposes of error checking |
84 * Line number for the purposes of error checking. |
|
85 * Annotated (inserted) by stage1_2 |
70 */ |
86 */ |
71 int first_line; |
87 int first_line; |
72 int first_column; |
88 int first_column; |
73 const char *first_file; /* filename referenced by first line/column */ |
89 const char *first_file; /* filename referenced by first line/column */ |
74 long int first_order; /* relative order in which it is read by lexcial analyser */ |
90 long int first_order; /* relative order in which it is read by lexcial analyser */ |
75 int last_line; |
91 int last_line; |
76 int last_column; |
92 int last_column; |
77 const char *last_file; /* filename referenced by last line/column */ |
93 const char *last_file; /* filename referenced by last line/column */ |
78 long int last_order; /* relative order in which it is read by lexcial analyser */ |
94 long int last_order; /* relative order in which it is read by lexcial analyser */ |
|
95 |
|
96 |
|
97 /* |
|
98 * Annotations produced during stage 3 |
|
99 */ |
|
100 /*** Data type analysis ***/ |
|
101 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 */ |
|
102 /* Data type of the expression/literal/etc. Filled in stage3 by narrow_candidate_datatypes_c |
|
103 * If set to NULL, it means it has not yet been evaluated. |
|
104 * If it points to an object of type invalid_type_name_c, it means it is invalid. |
|
105 * Otherwise, it points to an object of the apropriate data type (e.g. int_type_name_c, bool_type_name_c, ...) |
|
106 */ |
|
107 symbol_c *datatype; |
|
108 |
|
109 /*** constant folding ***/ |
|
110 /* During stage 3 (semantic analysis/checking) we will be doing constant folding. |
|
111 * That algorithm will anotate the abstract syntax tree with the result of operations |
|
112 * on literals (i.e. 44 + 55 will store the result 99). |
|
113 * Since the same source code (e.g. 1 + 0) may actually be a BOOL or an ANY_INT, |
|
114 * or an ANY_BIT, we need to handle all possibilities, and determine the result of the |
|
115 * operation assuming each type. |
|
116 * For this reason, we have one entry for each possible type, with some expressions |
|
117 * having more than one entry filled in! |
|
118 */ |
|
119 typedef enum { cs_undefined, /* not defined/not yet evaluated --> const_value is not valid! */ |
|
120 cs_non_const, /* we have deternmined that expression is not a const value --> const_value is not valid! */ |
|
121 cs_const_value, /* const value is valid */ |
|
122 cs_overflow /* result produced overflow or underflow --> const_value is not valid! */ |
|
123 } const_status_t; |
|
124 |
|
125 typedef struct {const_status_t status; real64_t value; } const_value_real64_t; |
|
126 typedef struct {const_status_t status; int64_t value; } const_value_int64_t; |
|
127 typedef struct {const_status_t status; uint64_t value; } const_value_uint64_t; |
|
128 typedef struct {const_status_t status; bool value; } const_value_bool_t; |
|
129 |
|
130 typedef struct { |
|
131 const_value_real64_t _real64; /* status is initialised to UNDEFINED */ |
|
132 const_value_int64_t _int64; /* status is initialised to UNDEFINED */ |
|
133 const_value_uint64_t _uint64; /* status is initialised to UNDEFINED */ |
|
134 const_value_bool_t _bool; /* status is initialised to UNDEFINED */ |
|
135 } const_value_t; |
|
136 const_value_t const_value; |
|
137 |
79 |
138 |
80 public: |
139 public: |
81 /* default constructor */ |
140 /* default constructor */ |
82 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 */ |
141 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 */ |
83 int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0 /* order in which it is read by lexcial analyser */ |
142 int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0 /* order in which it is read by lexcial analyser */ |
123 virtual void add_element(symbol_c *elem); |
182 virtual void add_element(symbol_c *elem); |
124 /* insert a new element before position pos. */ |
183 /* insert a new element before position pos. */ |
125 /* To insert into the begining of list, call with pos=0 */ |
184 /* To insert into the begining of list, call with pos=0 */ |
126 /* To insert into the end of list, call with pos=list->n */ |
185 /* To insert into the end of list, call with pos=list->n */ |
127 virtual void insert_element(symbol_c *elem, int pos = 0); |
186 virtual void insert_element(symbol_c *elem, int pos = 0); |
128 }; |
187 /* remove element at position pos. */ |
129 |
188 virtual void remove_element(int pos = 0); |
130 |
189 }; |
131 |
190 |
132 |
191 |
133 #define SYM_LIST(class_name_c, ...) \ |
192 |
|
193 |
|
194 #define SYM_LIST(class_name_c, ...) \ |
134 class class_name_c: public list_c { \ |
195 class class_name_c: public list_c { \ |
135 public: \ |
196 public: \ |
136 __VA_ARGS__ \ |
197 __VA_ARGS__ \ |
137 public: \ |
198 public: \ |
138 class_name_c( \ |
199 class_name_c( \ |
143 int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0); \ |
204 int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0); \ |
144 virtual void *accept(visitor_c &visitor); \ |
205 virtual void *accept(visitor_c &visitor); \ |
145 }; |
206 }; |
146 |
207 |
147 |
208 |
148 #define SYM_TOKEN(class_name_c, ...) \ |
209 #define SYM_TOKEN(class_name_c, ...) \ |
149 class class_name_c: public token_c { \ |
210 class class_name_c: public token_c { \ |
150 public: \ |
211 public: \ |
151 __VA_ARGS__ \ |
212 __VA_ARGS__ \ |
152 public: \ |
213 public: \ |
153 class_name_c(const char *value, \ |
214 class_name_c(const char *value, \ |
231 int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0); \ |
292 int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0); \ |
232 virtual void *accept(visitor_c &visitor); \ |
293 virtual void *accept(visitor_c &visitor); \ |
233 }; |
294 }; |
234 |
295 |
235 |
296 |
236 #define SYM_REF5(class_name_c, ref1, ref2, ref3, ref4, ref5, ...) \ |
297 #define SYM_REF5(class_name_c, ref1, ref2, ref3, ref4, ref5, ...) \ |
237 class class_name_c: public symbol_c { \ |
298 class class_name_c: public symbol_c { \ |
238 public: \ |
299 public: \ |
239 symbol_c *ref1; \ |
300 symbol_c *ref1; \ |
240 symbol_c *ref2; \ |
301 symbol_c *ref2; \ |
241 symbol_c *ref3; \ |
302 symbol_c *ref3; \ |