41 //#include "../../util/symtable.hh" |
41 //#include "../../util/symtable.hh" |
42 |
42 |
43 |
43 |
44 |
44 |
45 |
45 |
46 |
46 class generate_c_array_initialization_c: public generate_c_typedecl_c { |
47 |
47 |
48 |
48 public: |
49 |
49 typedef enum { |
|
50 none_am, |
|
51 dimensioncount_am, |
|
52 initializationvalue_am, |
|
53 arrayassignment_am, |
|
54 varlistparse_am |
|
55 } arrayinitialization_mode_t; |
|
56 |
|
57 arrayinitialization_mode_t current_mode; |
|
58 |
|
59 symbol_c* array_default_value; |
|
60 |
|
61 private: |
|
62 int dimension_number, current_dimension, array_size; |
|
63 |
|
64 public: |
|
65 generate_c_array_initialization_c(stage4out_c *s4o_ptr): generate_c_typedecl_c(s4o_ptr) {} |
|
66 ~generate_c_array_initialization_c(void) {} |
|
67 |
|
68 void init_array(symbol_c *var1_list, symbol_c *array_specification, symbol_c *array_initialization) { |
|
69 int i; |
|
70 |
|
71 dimension_number = 0; |
|
72 current_dimension = 0; |
|
73 array_size = 1; |
|
74 array_default_value = NULL; |
|
75 |
|
76 current_mode = dimensioncount_am; |
|
77 array_specification->accept(*this); |
|
78 |
|
79 current_mode = initializationvalue_am; |
|
80 s4o.print("\n"); |
|
81 s4o.print(s4o.indent_spaces + "{\n"); |
|
82 s4o.indent_right(); |
|
83 s4o.print(s4o.indent_spaces + "int index["); |
|
84 print_integer(dimension_number); |
|
85 s4o.print("];\n"); |
|
86 s4o.print(s4o.indent_spaces); |
|
87 array_specification->accept(*this); |
|
88 s4o.print(" temp = "); |
|
89 array_initialization->accept(*this); |
|
90 s4o.print(";\n"); |
|
91 |
|
92 current_mode = arrayassignment_am; |
|
93 array_specification->accept(*this); |
|
94 |
|
95 current_mode = varlistparse_am; |
|
96 var1_list->accept(*this); |
|
97 |
|
98 current_mode = arrayassignment_am; |
|
99 for (i = 0; i < dimension_number; i++) { |
|
100 s4o.indent_left(); |
|
101 s4o.print(s4o.indent_spaces + "}\n"); |
|
102 } |
|
103 s4o.indent_left(); |
|
104 s4o.print(s4o.indent_spaces + "}"); |
|
105 } |
|
106 |
|
107 void *visit(identifier_c *type_name) { |
|
108 symbol_c *type_decl; |
|
109 switch (current_mode) { |
|
110 case dimensioncount_am: |
|
111 case arrayassignment_am: |
|
112 /* look up the type declaration... */ |
|
113 type_decl = type_symtable.find_value(type_name); |
|
114 if (type_decl == type_symtable.end_value()) |
|
115 /* Type declaration not found!! */ |
|
116 ERROR; |
|
117 type_decl->accept(*this); |
|
118 break; |
|
119 default: |
|
120 print_token(type_name); |
|
121 break; |
|
122 } |
|
123 return NULL; |
|
124 } |
|
125 |
|
126 void *visit(var1_list_c *symbol) { |
|
127 int i, j; |
|
128 |
|
129 for (i = 0; i < symbol->n; i++) { |
|
130 s4o.print(s4o.indent_spaces); |
|
131 print_variable_prefix(); |
|
132 symbol->elements[i]->accept(*this); |
|
133 for (j = 0; j < dimension_number; j++) { |
|
134 s4o.print("[index["); |
|
135 print_integer(j); |
|
136 s4o.print("]]"); |
|
137 } |
|
138 s4o.print(" = temp"); |
|
139 for (j = 0; j < dimension_number; j++) { |
|
140 s4o.print("[index["); |
|
141 print_integer(j); |
|
142 s4o.print("]]"); |
|
143 } |
|
144 s4o.print(";\n"); |
|
145 } |
|
146 return NULL; |
|
147 } |
|
148 |
|
149 /********************************/ |
|
150 /* B 1.3.3 - Derived data types */ |
|
151 /********************************/ |
|
152 |
|
153 /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */ |
|
154 void *visit(array_specification_c *symbol) { |
|
155 switch (current_mode) { |
|
156 case dimensioncount_am: |
|
157 symbol->array_subrange_list->accept(*this); |
|
158 array_default_value = (symbol_c *)symbol->non_generic_type_name->accept(*type_initial_value_c::instance());; |
|
159 break; |
|
160 default: |
|
161 symbol->array_subrange_list->accept(*this); |
|
162 break; |
|
163 } |
|
164 return NULL; |
|
165 } |
|
166 |
|
167 /* signed_integer DOTDOT signed_integer */ |
|
168 //SYM_REF2(subrange_c, lower_limit, upper_limit) |
|
169 void *visit(subrange_c *symbol) { |
|
170 switch (current_mode) { |
|
171 case dimensioncount_am: |
|
172 dimension_number++; |
|
173 array_size *= extract_integer(symbol->upper_limit) - extract_integer(symbol->lower_limit) + 1; |
|
174 break; |
|
175 case arrayassignment_am: |
|
176 s4o.print(s4o.indent_spaces + "for (index["); |
|
177 print_integer(current_dimension); |
|
178 s4o.print("] = 0; index["); |
|
179 print_integer(current_dimension); |
|
180 s4o.print("] <= "); |
|
181 print_integer(extract_integer(symbol->upper_limit) - extract_integer(symbol->lower_limit)); |
|
182 s4o.print("; index["); |
|
183 print_integer(current_dimension); |
|
184 s4o.print("]++) {\n"); |
|
185 s4o.indent_right(); |
|
186 current_dimension++; |
|
187 break; |
|
188 default: |
|
189 break; |
|
190 } |
|
191 return NULL; |
|
192 } |
|
193 |
|
194 /* helper symbol for array_initialization */ |
|
195 /* array_initial_elements_list ',' array_initial_elements */ |
|
196 void *visit(array_initial_elements_list_c *symbol) { |
|
197 switch (current_mode) { |
|
198 case initializationvalue_am: |
|
199 int i; |
|
200 |
|
201 s4o.print("{"); |
|
202 for (i = 0; i < symbol->n; i++) { |
|
203 if (i > 0) |
|
204 s4o.print(", "); |
|
205 symbol->elements[i]->accept(*this); |
|
206 array_size--; |
|
207 } |
|
208 if (array_size > 0) { |
|
209 if (symbol->n > 0) |
|
210 s4o.print(", "); |
|
211 for (i = 0; i < array_size; i++) { |
|
212 if (i > 0) |
|
213 s4o.print(", "); |
|
214 array_default_value->accept(*this); |
|
215 } |
|
216 } |
|
217 s4o.print("}"); |
|
218 break; |
|
219 default: |
|
220 break; |
|
221 } |
|
222 return NULL; |
|
223 } |
|
224 |
|
225 /* integer '(' [array_initial_element] ')' */ |
|
226 /* array_initial_element may be NULL ! */ |
|
227 void *visit(array_initial_elements_c *symbol) { |
|
228 int initial_element_number; |
|
229 |
|
230 switch (current_mode) { |
|
231 case initializationvalue_am: |
|
232 initial_element_number = extract_integer(symbol->integer); |
|
233 |
|
234 for (int i = 0; i < initial_element_number; i++) { |
|
235 if (i > 0) |
|
236 s4o.print(", "); |
|
237 if (symbol->array_initial_element != NULL) |
|
238 symbol->array_initial_element->accept(*this); |
|
239 else if (array_default_value != NULL) |
|
240 array_default_value->accept(*this); |
|
241 } |
|
242 if (initial_element_number > 1) |
|
243 array_size -= initial_element_number - 1; |
|
244 break; |
|
245 default: |
|
246 break; |
|
247 } |
|
248 return NULL; |
|
249 } |
|
250 |
|
251 }; |
50 |
252 |
51 /***********************************************************************/ |
253 /***********************************************************************/ |
52 /***********************************************************************/ |
254 /***********************************************************************/ |
53 /***********************************************************************/ |
255 /***********************************************************************/ |
54 /***********************************************************************/ |
256 /***********************************************************************/ |
351 |
555 |
352 |
556 |
353 public: |
557 public: |
354 generate_c_vardecl_c(stage4out_c *s4o_ptr, varformat_t varformat, unsigned int vartype) |
558 generate_c_vardecl_c(stage4out_c *s4o_ptr, varformat_t varformat, unsigned int vartype) |
355 : generate_c_typedecl_c(s4o_ptr) { |
559 : generate_c_typedecl_c(s4o_ptr) { |
|
560 generate_c_array_initialization = new generate_c_array_initialization_c(s4o_ptr); |
356 wanted_varformat = varformat; |
561 wanted_varformat = varformat; |
357 wanted_vartype = vartype; |
562 wanted_vartype = vartype; |
358 current_vartype = none_vt; |
563 current_vartype = none_vt; |
359 current_var_type_symbol = NULL; |
564 current_var_type_symbol = NULL; |
360 current_var_init_symbol = NULL; |
565 current_var_init_symbol = NULL; |
361 globalnamespace = NULL; |
566 globalnamespace = NULL; |
362 nv = NULL; |
567 nv = NULL; |
363 } |
568 } |
364 |
569 |
365 ~generate_c_vardecl_c(void) {} |
570 ~generate_c_vardecl_c(void) { |
|
571 delete generate_c_array_initialization; |
|
572 } |
366 |
573 |
367 |
574 |
368 void print(symbol_c *symbol, symbol_c *scope = NULL, const char *variable_prefix = NULL) { |
575 void print(symbol_c *symbol, symbol_c *scope = NULL, const char *variable_prefix = NULL) { |
369 this->set_variable_prefix(variable_prefix); |
576 this->set_variable_prefix(variable_prefix); |
|
577 this->generate_c_array_initialization->set_variable_prefix(variable_prefix); |
370 if (globalinit_vf == wanted_varformat) |
578 if (globalinit_vf == wanted_varformat) |
371 globalnamespace = scope; |
579 globalnamespace = scope; |
372 |
580 |
373 finterface_var_count = 0; |
581 finterface_var_count = 0; |
374 |
582 |
512 // TO DO ... |
720 // TO DO ... |
513 s4o.print("R_EDGE"); |
721 s4o.print("R_EDGE"); |
514 return NULL; |
722 return NULL; |
515 } |
723 } |
516 |
724 |
517 |
725 /* var1_list ':' array_spec_init */ |
518 #if 0 |
726 // SYM_REF2(array_var_init_decl_c, var1_list, array_spec_init) |
519 /* var1_list ':' array_spec_init */ |
727 void *visit(array_var_init_decl_c *symbol) { |
520 SYM_REF2(array_var_init_decl_c, var1_list, array_spec_init) |
728 TRACE("array_var_init_decl_c"); |
521 #endif |
729 /* Please read the comments inside the var1_init_decl_c |
|
730 * visitor, as they apply here too. |
|
731 */ |
|
732 |
|
733 /* Start off by setting the current_var_type_symbol and |
|
734 * current_var_init_symbol private variables... |
|
735 */ |
|
736 update_type_init(symbol->array_spec_init); |
|
737 |
|
738 /* now to produce the c equivalent... */ |
|
739 if (wanted_varformat == constructorinit_vf) |
|
740 generate_c_array_initialization->init_array(symbol->var1_list, this->current_var_type_symbol, this->current_var_init_symbol); |
|
741 else |
|
742 symbol->var1_list->accept(*this); |
|
743 |
|
744 /* Values no longer in scope, and therefore no longer used. |
|
745 * Make an effort to keep them set to NULL when not in use |
|
746 * in order to catch bugs as soon as possible... |
|
747 */ |
|
748 void_type_init(); |
|
749 |
|
750 return NULL; |
|
751 } |
522 |
752 |
523 /* var1_list ':' initialized_structure */ |
753 /* var1_list ':' initialized_structure */ |
524 // SYM_REF2(structured_var_init_decl_c, var1_list, initialized_structure) |
754 // SYM_REF2(structured_var_init_decl_c, var1_list, initialized_structure) |
525 void *visit(structured_var_init_decl_c *symbol) { |
755 void *visit(structured_var_init_decl_c *symbol) { |
526 TRACE("structured_var_init_decl_c"); |
756 TRACE("structured_var_init_decl_c"); |