GCCPY:
[official-gcc.git] / gcc / python / dot-pass-generic.cc
blobd5f29b08b9291c5d534957a66a024e8f83ea9c03
1 /* This file is part of GCC.
3 GCC is free software; you can redistribute it and/or modify it under
4 the terms of the GNU General Public License as published by the Free
5 Software Foundation; either version 3, or (at your option) any later
6 version.
8 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
9 WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 for more details.
13 You should have received a copy of the GNU General Public License
14 along with GCC; see the file COPYING3. If not see
15 <http://www.gnu.org/licenses/>. */
17 #include "gpython.h"
19 /* DEFINES */
20 #define DOT_CURRENT_CONTEXT(x_) \
21 VEC_index (dot_contextEntry_t, x_, VEC_length (x_) - 1)
22 /* ... ... ... */
24 static tree moduleInit = NULL_TREE;
26 /* PROTOTYPES... */
27 static tree dot_pass_genFndecl_Basic (tree, tree);
29 static tree dot_pass_getModuleType (const char *, gpy_hash_tab_t *);
30 static void dot_pass_setupContext (tree, dot_contextTable_t, vec<tree,va_gc> *, tree *);
31 static void dot_pass_generic_TU (gpy_hash_tab_t *, vec<gpydot,va_gc> *, vec<tree,va_gc> *);
33 static tree dot_pass_genFindAddr (const char *, const char *, vec<tree,va_gc> *);
34 static void dot_pass_genWalkClass (tree *, tree, tree, vec<tree,va_gc> *);
35 static void dot_pass_setupClassFieldContext (tree, tree, dot_contextEntry_t);
37 static tree dot_pass_lookupDecl (dot_contextTable_t, const char *);
38 static int dot_pass_pushDecl (tree, const char *, dot_contextEntry_t);
40 static tree dot_pass_genFunction (gpy_dot_tree_t *, dot_contextTable_t, const char *);
41 static vec<tree,va_gc> * dot_pass_genClass (gpy_dot_tree_t *, dot_contextTable_t, tree, const char *);
43 static tree dot_pass_genScalar (gpy_dot_tree_t *, tree *);
44 static tree dot_pass_genEnclosure (gpy_dot_tree_t *, tree *, dot_contextTable_t);
45 static void dot_pass_genCBlock (gpy_dot_tree_t *, tree *, dot_contextTable_t, tree, tree);
47 static tree dot_pass_lowerExpr (gpy_dot_tree_t *, dot_contextTable_t, tree *);
48 static void dot_pass_genPrintStmt (gpy_dot_tree_t * , tree *, dot_contextTable_t);
49 static void dot_pass_genReturnStmt (gpy_dot_tree_t * , tree *, dot_contextTable_t);
50 static tree dot_pass_genModifyExpr (gpy_dot_tree_t *, tree *, dot_contextTable_t);
51 static tree dot_pass_genBinExpr (gpy_dot_tree_t *, tree *, dot_contextTable_t);
53 static void dot_pass_genConditional (gpy_dot_tree_t *, tree *, dot_contextTable_t);
54 static void dot_pass_genWhile (gpy_dot_tree_t *, tree *, dot_contextTable_t);
55 static void dot_pass_genFor (gpy_dot_tree_t *, tree *, dot_contextTable_t);
56 static void dot_pass_genImport (gpy_dot_tree_t *, tree *, dot_contextTable_t);
57 static void dot_pass_genSuite (gpy_dot_tree_t * , tree *, dot_contextTable_t);
58 /* ... ... ... */
60 static
61 tree dot_pass_genFndecl_Basic (tree ident, tree fntype)
63 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, ident, fntype);
65 TREE_STATIC (fndecl) = 0;
66 TREE_USED (fndecl) = 1;
67 DECL_ARTIFICIAL (fndecl) = 1;
68 TREE_PUBLIC (fndecl) = 1;
70 tree argslist = NULL_TREE;
71 DECL_ARGUMENTS (fndecl) = argslist;
72 /* Define the return type (represented by RESULT_DECL) for the main functin */
73 tree resdecl = build_decl (BUILTINS_LOCATION, RESULT_DECL,
74 NULL_TREE, TREE_TYPE (fntype));
75 DECL_CONTEXT (resdecl) = fndecl;
76 DECL_ARTIFICIAL (resdecl) = true;
77 DECL_IGNORED_P (resdecl) = true;
78 DECL_RESULT (fndecl) = resdecl;
80 if (DECL_STRUCT_FUNCTION(fndecl) == NULL)
81 push_struct_function(fndecl);
82 else
83 push_cfun(DECL_STRUCT_FUNCTION(fndecl));
85 return fndecl;
88 static
89 tree dot_pass_getModuleType (const char * s,
90 gpy_hash_tab_t * modules)
92 tree retval = error_mark_node;
94 gpy_hashval_t h = gpy_dd_hash_string (s);
95 gpy_hash_entry_t * e = gpy_dd_hash_lookup_table (modules, h);
96 if (e)
98 if (e->data)
99 retval = (tree) e->data;
101 return retval;
104 static
105 void dot_pass_setupClassFieldContext (tree type, tree self,
106 dot_contextEntry_t context)
108 tree field = NULL_TREE;
109 for (field = TYPE_FIELDS (type); field != NULL_TREE;
110 field = DECL_CHAIN (field))
112 const char * ident = IDENTIFIER_POINTER (DECL_NAME (field));
113 tree ref = build3 (COMPONENT_REF, TREE_TYPE (field),
114 build_fold_indirect_ref (self),
115 field, NULL_TREE);
116 gcc_assert (dot_pass_pushDecl (ref, ident, context));
120 static
121 tree dot_pass_genFindAddr (const char * id,
122 const char * parent_ident,
123 vec<tree,va_gc> * decls)
125 tree retval = null_pointer_node;
126 tree ident = dot_pass_concat_identifier (parent_ident, id);
127 const char * search = IDENTIFIER_POINTER (ident);
129 int idx;
130 tree decl = NULL_TREE;
131 for (idx = 0; decls->iterate (idx, &decl); ++idx)
133 tree decl_name = DECL_NAME (decl);
134 if (!strcmp (search, IDENTIFIER_POINTER (decl_name)))
136 retval = decl;
137 break;
140 return retval;
143 static
144 void dot_pass_genWalkClass (tree * block, tree type,
145 tree decl,
146 vec<tree,va_gc> * ldecls)
148 const char * type_name = IDENTIFIER_POINTER (TYPE_NAME (type));
149 vec<tree,va_gc> * attribs;
150 vec_alloc (attribs, 0);
152 tree field = NULL_TREE;
153 int offset = 0;
154 for (field = TYPE_FIELDS (type); field != NULL_TREE;
155 field = DECL_CHAIN (field))
157 const char * ident = IDENTIFIER_POINTER (DECL_NAME (field));
158 tree element_size = TYPE_SIZE_UNIT (TREE_TYPE (field));
159 tree offs = fold_build2_loc (UNKNOWN_LOCATION, MULT_EXPR, sizetype,
160 build_int_cst (sizetype, offset),
161 element_size);
162 tree str = gpy_dot_type_const_string_tree (ident);
163 tree fnaddr = dot_pass_genFindAddr (ident, type_name, ldecls);
165 tree fnaddr_tmp = build_decl (UNKNOWN_LOCATION, VAR_DECL,
166 create_tmp_var_name ("FNAD"),
167 ptr_type_node);
168 tree arguments = NULL_TREE;
169 int n = 0;
170 if (fnaddr != null_pointer_node)
172 gcc_assert (TREE_CODE (fnaddr) == FUNCTION_DECL);
173 arguments = DECL_ARGUMENTS (fnaddr);
174 tree args;
175 for (args = arguments; args != NULL_TREE;
176 args = DECL_CHAIN (args))
177 n++;
178 append_to_statement_list (build2 (MODIFY_EXPR, ptr_type_node,
179 fnaddr_tmp,
180 build_fold_addr_expr (fnaddr)),
181 block);
183 else
184 append_to_statement_list (build2 (MODIFY_EXPR, ptr_type_node,
185 fnaddr_tmp,
186 build_int_cst (ptr_type_node, 0)),
187 block);
189 tree nargs = build_int_cst (integer_type_node, n);
190 tree atdecl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
191 create_tmp_var_name ("AT"),
192 gpy_attrib_type_ptr);
193 tree a = GPY_RR_fold_attrib (build_fold_addr_expr (str),
194 fnaddr_tmp,
195 offs, nargs);
196 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
197 atdecl, a),
198 block);
199 vec_safe_push (attribs, atdecl);
200 offset++;
202 vec<tree,va_gc> * args;
203 vec_alloc (args, 0);
204 vec_safe_push (args, build_int_cst (integer_type_node,
205 attribs->length ()));
206 GPY_VEC_stmts_append (tree, args, attribs);
208 tree attribs_decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
209 create_tmp_var_name ("AL"),
210 gpy_attrib_type_ptr_ptr);
211 append_to_statement_list (build2 (MODIFY_EXPR, gpy_attrib_type_ptr_ptr,
212 attribs_decl,
213 GPY_RR_fold_attrib_list (args)),
214 block);
215 tree class_str = gpy_dot_type_const_string_tree (type_name);
216 tree fold_class = GPY_RR_fold_class_decl (attribs_decl, TYPE_SIZE_UNIT (type),
217 build_fold_addr_expr (class_str));
219 switch (TREE_CODE (decl))
221 case POINTER_PLUS_EXPR:
223 tree fold = build_decl (UNKNOWN_LOCATION, VAR_DECL,
224 create_tmp_var_name ("__MOD_DECL_ACC"),
225 gpy_object_type_ptr_ptr);
226 append_to_statement_list (build2 (MODIFY_EXPR,
227 gpy_object_type_ptr_ptr,
228 fold, decl),
229 block);
231 tree class_tmp = build_decl (UNKNOWN_LOCATION, VAR_DECL,
232 create_tmp_var_name ("ATFC"),
233 gpy_object_type_ptr);
234 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
235 class_tmp, fold_class),
236 block);
237 tree refer = build_fold_indirect_ref (fold);
238 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
239 refer,
240 class_tmp),
241 block);
243 break;
245 default:
246 fatal_error ("Error seting up class decl!\n");
247 break;
251 static
252 tree dot_pass_foldCIDS (int len, char ** cids)
254 tree fntype = build_function_type_list (ptr_type_node,
255 integer_type_node,
256 va_list_type_node,
257 NULL_TREE);
258 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
259 get_identifier ("gpy_rr_modAttribList"),
260 fntype);
261 tree restype = TREE_TYPE (fndecl);
262 tree resdecl = build_decl (BUILTINS_LOCATION, RESULT_DECL, NULL_TREE,
263 restype);
264 DECL_CONTEXT (resdecl) = fndecl;
265 DECL_RESULT (fndecl) = resdecl;
266 DECL_EXTERNAL (fndecl) = 1;
267 TREE_PUBLIC (fndecl) = 1;
269 int i;
270 vec<tree,va_gc> *args;
271 vec_alloc (args, 0);
273 vec_safe_push (args, build_int_cst (integer_type_node, len));
274 for (i = 0; i < len; ++i)
276 char * id = cids [i];
277 tree tid = gpy_dot_type_const_string_tree (id);
278 vec_safe_push (args, build_fold_addr_expr (tid));
280 return build_call_expr_loc_vec (BUILTINS_LOCATION, fndecl, args);
283 static
284 void dot_pass_setupContext (tree module,
285 dot_contextTable_t context,
286 vec<tree,va_gc> * generic,
287 tree * block)
289 dot_contextEntry_t globls = VEC_index (dot_contextEntry_t, context, 0);
290 dot_contextEntry_t globls_symbols = VEC_index (dot_contextEntry_t, context, 1);
292 tree stack_pointer = build_decl (BUILTINS_LOCATION, VAR_DECL,
293 get_identifier (GPY_RR_stack_ptr),
294 gpy_object_type_ptr_ptr);
295 TREE_PUBLIC (stack_pointer) = 1;
296 TREE_USED (stack_pointer) = 1;
297 DECL_EXTERNAL (stack_pointer) = 1;
299 DECL_INITIAL (stack_pointer) = build_int_cst (integer_type_node, 0);
300 rest_of_decl_compilation (stack_pointer, 1, 0);
302 gpy_dd_hash_insert (gpy_dd_hash_string (GPY_RR_stack_ptr), stack_pointer, globls);
303 vec_safe_push (generic, stack_pointer);
305 int offset = 0, field_count = 0;
306 tree field;
307 for (field = TYPE_FIELDS (module); field != NULL_TREE;
308 field = DECL_CHAIN (field))
309 field_count++;
311 char ** cids = (char **) xcalloc (field_count, sizeof (char *));
312 memset (cids, 0, sizeof (char *)*field_count);
314 int i = 0;
315 for (field = TYPE_FIELDS (module); field != NULL_TREE;
316 field = DECL_CHAIN (field))
318 gcc_assert (TREE_CODE (field) == FIELD_DECL);
319 const char * ident = IDENTIFIER_POINTER (DECL_NAME (field));
321 cids [i] = xstrdup (ident);
322 i++;
325 tree fcids = dot_pass_foldCIDS (field_count, cids);
326 tree fcids_decl = build_decl (BUILTINS_LOCATION, VAR_DECL,
327 create_tmp_var_name ("FCIDS"),
328 ptr_type_node);
329 append_to_statement_list (build2 (MODIFY_EXPR, ptr_type_node,
330 fcids_decl, fcids),
331 block);
332 tree str = gpy_dot_type_const_string_tree (GPY_current_module_name);
333 tree stack_extendCall = GPY_RR_extendRRStack (build_int_cst (integer_type_node,
334 field_count),
335 build_fold_addr_expr (str),
336 fcids_decl);
338 tree stack_offset = build_decl (BUILTINS_LOCATION, VAR_DECL,
339 create_tmp_var_name ("__MODULE_STK_OFFS"),
340 sizetype);
341 TREE_STATIC (stack_offset) = 1;
342 TREE_PUBLIC (stack_offset) = 0;
343 TREE_USED (stack_offset) = 1;
344 DECL_INITIAL (stack_offset) = build_int_cst (integer_type_node, 0);
345 rest_of_decl_compilation (stack_offset, 1, 0);
347 append_to_statement_list (build2 (MODIFY_EXPR, integer_type_node,
348 stack_offset, stack_extendCall),
349 block);
351 offset = 0;
352 field_count = 0;
353 for (field = TYPE_FIELDS (module); field != NULL_TREE;
354 field = DECL_CHAIN (field))
356 gcc_assert (TREE_CODE (field) == FIELD_DECL);
357 const char * ident = IDENTIFIER_POINTER (DECL_NAME (field));
359 tree element_size = TYPE_SIZE_UNIT (TREE_TYPE (field));
361 tree offs1 = build2 (MULT_EXPR, sizetype,
362 build_int_cst (sizetype, offset),
363 element_size);
364 tree offs2 = build2 (MULT_EXPR, sizetype,
365 stack_offset,
366 element_size);
368 tree offs = build2 (PLUS_EXPR, sizetype,
369 offs1, offs2);
370 tree addr = build2 (POINTER_PLUS_EXPR,
371 TREE_TYPE (stack_pointer),
372 stack_pointer, offs);
374 gcc_assert (dot_pass_pushDecl (addr, ident, globls_symbols));
375 offset++;
376 field_count++;
379 // the module_init shizzle!
380 moduleInit = build_decl (BUILTINS_LOCATION, VAR_DECL,
381 get_identifier ("__MOD_INIT_CHK"),
382 boolean_type_node);
383 TREE_STATIC (moduleInit) = 1;
384 TREE_PUBLIC (moduleInit) = 0;
385 TREE_USED (moduleInit) = 1;
386 DECL_INITIAL(moduleInit) = boolean_false_node;
387 rest_of_decl_compilation (moduleInit, 1, 0);
390 static
391 int dot_pass_pushDecl (tree decl, const char * ident,
392 dot_contextEntry_t context)
394 int retval = 1;
395 gpy_hashval_t h = gpy_dd_hash_string (ident);
396 void ** slot = gpy_dd_hash_insert (h, decl, context);
397 if (slot)
399 error ("error pushing decl <%s>!\n", ident);
400 retval = 0;
402 return retval;
405 static
406 tree dot_pass_lookupDecl (dot_contextTable_t context,
407 const char * identifier)
409 tree retval = error_mark_node;
410 gpy_hashval_t h = gpy_dd_hash_string (identifier);
411 int length = VEC_length (context);
413 int i;
414 for (i = length - 1; i >= 0; --i)
416 dot_contextEntry_t ctx = VEC_index (dot_contextEntry_t, context, i);
417 gpy_hash_entry_t * o = NULL;
418 o = gpy_dd_hash_lookup_table (ctx, h);
420 if (o)
421 if (o->data)
423 retval = (tree) o->data;
424 break;
427 return retval;
430 static
431 tree dot_pass_genScalar (gpy_dot_tree_t * decl, tree * block)
433 tree retval = error_mark_node;
435 gcc_assert (DOT_TYPE (decl) == D_PRIMITIVE);
436 gcc_assert (DOT_lhs_T (decl) == D_TD_COM);
438 switch (DOT_lhs_TC (decl)->T)
440 case D_T_INTEGER:
442 retval = build_decl (UNKNOWN_LOCATION, VAR_DECL,
443 create_tmp_var_name ("PI"),
444 gpy_object_type_ptr);
445 tree fold_call = GPY_RR_fold_integer (build_int_cst (integer_type_node,
446 DOT_lhs_TC (decl)->o.integer));
447 append_to_statement_list (build2 (MODIFY_EXPR,
448 gpy_object_type_ptr,
449 retval, fold_call),
450 block);
452 break;
454 case D_T_STRING:
456 retval = build_decl (UNKNOWN_LOCATION, VAR_DECL,
457 create_tmp_var_name ("PI"),
458 gpy_object_type_ptr);
459 tree fstr = gpy_dot_type_const_string_tree (DOT_lhs_TC (decl)->o.string);
460 tree fold_call = GPY_RR_fold_string (build_fold_addr_expr (fstr));
461 append_to_statement_list (build2 (MODIFY_EXPR,
462 gpy_object_type_ptr,
463 retval, fold_call),
464 block);
466 break;
468 default:
469 error ("invalid scalar type!\n");
470 break;
473 return retval;
476 static
477 tree dot_pass_genEnclosure (gpy_dot_tree_t * decl,
478 tree * block,
479 dot_contextTable_t context)
481 tree retval = error_mark_node;
482 gcc_assert (DOT_TYPE (decl) == D_T_LIST);
484 gpy_dot_tree_t * node;
485 size_t length = 0;
486 for (node = DOT_lhs_TT (decl); node != NULL_DOT;
487 node = DOT_CHAIN (node))
488 length++;
490 vec<tree,va_gc> * elms;
491 vec_alloc (elms, 0);
492 vec_safe_push (elms, build_int_cst (integer_type_node, length));
493 for (node = DOT_lhs_TT (decl); node != NULL_DOT;
494 node = DOT_CHAIN (node))
496 tree tmp = dot_pass_lowerExpr (node, context, block);
497 vec_safe_push (elms, tmp);
499 retval = build_decl (UNKNOWN_LOCATION, VAR_DECL,
500 create_tmp_var_name ("PL"),
501 gpy_object_type_ptr);
502 tree fold_call = GPY_RR_fold_encList (elms);
503 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
504 retval, fold_call),
505 block);
506 return retval;
509 static
510 void dot_pass_genSuite (gpy_dot_tree_t * decl,
511 tree * block,
512 dot_contextTable_t context)
514 gpy_hash_tab_t suite;
515 gpy_dd_hash_init_table (&suite);
517 gpy_vec_push (context, &suite);
519 gpy_dot_tree_t * node;
520 for (node = decl; node != NULL_DOT;
521 node = DOT_CHAIN (node))
523 if (DOT_T_FIELD (node) == D_D_EXPR)
525 dot_pass_lowerExpr (node, context, block);
526 continue;
528 switch (DOT_TYPE (node))
530 case D_PRINT_STMT:
531 dot_pass_genPrintStmt (node, block, context);
532 break;
534 case D_KEY_RETURN:
535 dot_pass_genReturnStmt (node, block, context);
536 break;
538 case D_STRUCT_CONDITIONAL:
539 dot_pass_genConditional (node, block, context);
540 break;
542 case D_STRUCT_WHILE:
543 dot_pass_genWhile (node, block, context);
544 break;
546 case D_STRUCT_FOR:
547 dot_pass_genFor (node, block, context);
548 break;
550 default:
551 error ("unhandled syntax within suite");
552 break;
556 gpy_vec_pop (context);
559 static
560 void dot_pass_genCBlock (gpy_dot_tree_t * decl,
561 tree * block,
562 dot_contextTable_t context,
563 tree cval, tree endif)
565 gpy_dot_tree_t * suite = NULL_DOT;
566 tree ifcval = error_mark_node;
567 if (DOT_TYPE (decl) == D_STRUCT_IF
568 || DOT_TYPE (decl) == D_STRUCT_ELIF)
570 gpy_dot_tree_t * expr = DOT_lhs_TT (decl);
571 tree val = dot_pass_lowerExpr (expr, context, block);
572 tree lval = val;
573 if (TREE_TYPE (lval) == gpy_object_type_ptr_ptr)
575 lval = build_decl (UNKNOWN_LOCATION, VAR_DECL,
576 create_tmp_var_name ("CDRD"),
577 gpy_object_type_ptr);
578 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
579 lval, build_fold_indirect_ref (val)),
580 block);
582 tree fold = build_decl (UNKNOWN_LOCATION, VAR_DECL,
583 create_tmp_var_name ("COND"),
584 boolean_type_node);
585 append_to_statement_list (build2 (MODIFY_EXPR, boolean_type_node,
586 fold, GPY_RR_eval_boolean (lval)),
587 block);
588 ifcval = fold;
589 suite = DOT_rhs_TT (decl);
591 else
593 gcc_assert (DOT_TYPE (decl) == D_STRUCT_ELSE);
594 suite = DOT_lhs_TT (decl);
597 tree label_decl = build_decl (UNKNOWN_LOCATION, LABEL_DECL,
598 create_tmp_var_name ("LBIF"),
599 void_type_node);
600 tree label_expr = fold_build1_loc (UNKNOWN_LOCATION, LABEL_EXPR,
601 void_type_node, label_decl);
603 tree label_exit_decl = build_decl (UNKNOWN_LOCATION, LABEL_DECL,
604 create_tmp_var_name ("LBFI"),
605 void_type_node);
606 tree label_exit_expr = fold_build1_loc (UNKNOWN_LOCATION, LABEL_EXPR,
607 void_type_node, label_exit_decl);
609 DECL_CONTEXT (label_decl) = current_function_decl;
610 DECL_CONTEXT (label_exit_decl) = current_function_decl;
612 tree condition;
613 tree evalto;
614 if (ifcval != error_mark_node)
616 condition = ifcval;
617 evalto = boolean_true_node;
619 else
621 condition = cval;
622 evalto = boolean_false_node;
624 tree conditional = fold_build2_loc (UNKNOWN_LOCATION, EQ_EXPR,
625 boolean_type_node,
626 condition, evalto);
628 tree cond = build3_loc (UNKNOWN_LOCATION, COND_EXPR, void_type_node,
629 conditional,
630 build1 (GOTO_EXPR, void_type_node, label_decl),
631 build1 (GOTO_EXPR, void_type_node, label_exit_decl));
633 append_to_statement_list (cond, block);
634 append_to_statement_list (label_expr, block);
636 dot_pass_genSuite (suite, block, context);
638 append_to_statement_list (build2 (MODIFY_EXPR, boolean_type_node,
639 cval, boolean_true_node),
640 block);
641 append_to_statement_list (build1 (GOTO_EXPR, void_type_node, endif),
642 block);
643 append_to_statement_list (label_exit_expr, block);
647 static
648 void dot_pass_genImport (gpy_dot_tree_t * decl,
649 tree * block,
650 dot_contextTable_t context)
652 const char * import = DOT_IDENTIFIER_POINTER (DOT_lhs_TT (decl));
653 tree lookup = dot_pass_lookupDecl (context, import);
654 gcc_assert (lookup != error_mark_node);
656 struct gpy_dataExport * exp = gpy_readExportData (import);
657 if (exp == NULL)
658 error ("No export data for module <%s>\n", import);
659 else
661 if (GPY_OPT_gen_main && exp->main)
662 error ("Module %s already has main!\n", import);
664 // ... setup runtime to call module entry...
665 tree decl = lookup;
666 tree ident = get_identifier (exp->entry);
668 tree fntype = build_function_type_list (void_type_node, NULL_TREE);
669 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
670 ident, fntype);
671 tree restype = TREE_TYPE (fndecl);
672 tree resdecl = build_decl (BUILTINS_LOCATION, RESULT_DECL, NULL_TREE,
673 restype);
674 DECL_CONTEXT (resdecl) = fndecl;
675 DECL_RESULT (fndecl) = resdecl;
676 DECL_EXTERNAL (fndecl) = 1;
677 TREE_PUBLIC (fndecl) = 1;
678 append_to_statement_list (build_call_expr (fndecl, 0), block);
680 tree tstr = gpy_dot_type_const_string_tree (import);
681 tree imp = GPY_RR_foldImport (decl, build_fold_addr_expr (tstr));
682 append_to_statement_list (imp, block);
686 static
687 void dot_pass_genFor (gpy_dot_tree_t * decl,
688 tree * block,
689 dot_contextTable_t context)
691 debug ("Trying to compile the for loop!\n");
693 /* gpy_dot_tree_t * it = DOT_FIELD (decl);
694 gpy_dot_tree_t * in = DOT_lhs_TT (decl);
695 gpy_dot_tree_t * suite = DOT_rhs (decl);*/
697 fatal_error ("For loops/iterators not implemented yet!\n");
701 static
702 void dot_pass_genWhile (gpy_dot_tree_t * decl,
703 tree * block,
704 dot_contextTable_t context)
706 tree label_decl = build_decl (UNKNOWN_LOCATION, LABEL_DECL,
707 create_tmp_var_name ("WHLIF"),
708 void_type_node);
709 tree label_expr = fold_build1_loc (UNKNOWN_LOCATION, LABEL_EXPR,
710 void_type_node, label_decl);
712 tree label_exit_decl = build_decl (UNKNOWN_LOCATION, LABEL_DECL,
713 create_tmp_var_name ("WHLFI"),
714 void_type_node);
715 tree label_exit_expr = fold_build1_loc (UNKNOWN_LOCATION, LABEL_EXPR,
716 void_type_node, label_exit_decl);
718 DECL_CONTEXT (label_decl) = current_function_decl;
719 DECL_CONTEXT (label_exit_decl) = current_function_decl;
721 append_to_statement_list (label_expr, block);
723 gpy_dot_tree_t * expr = DOT_lhs_TT (decl);
724 tree val = dot_pass_lowerExpr (expr, context, block);
725 tree lval = val;
726 if (TREE_TYPE (lval) == gpy_object_type_ptr_ptr)
728 lval = build_decl (UNKNOWN_LOCATION, VAR_DECL,
729 create_tmp_var_name ("CDRD"),
730 gpy_object_type_ptr);
731 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
732 lval, build_fold_indirect_ref (val)),
733 block);
735 tree fold = build_decl (UNKNOWN_LOCATION, VAR_DECL,
736 create_tmp_var_name ("COND"),
737 boolean_type_node);
740 append_to_statement_list (build2 (MODIFY_EXPR, boolean_type_node,
741 fold, GPY_RR_eval_boolean (lval)),
742 block);
744 gpy_dot_tree_t * suite = DOT_rhs_TT (decl);
746 tree conditional = fold_build2_loc (UNKNOWN_LOCATION, EQ_EXPR,
747 boolean_type_node,
748 fold, boolean_true_node);
749 tree cond = build3_loc (UNKNOWN_LOCATION, COND_EXPR, void_type_node,
750 conditional,
751 NULL_TREE,
752 build1 (GOTO_EXPR, void_type_node, label_exit_decl));
754 append_to_statement_list (cond, block);
755 dot_pass_genSuite (suite, block, context);
756 append_to_statement_list (build1 (GOTO_EXPR, void_type_node, label_decl),
757 block);
758 append_to_statement_list (label_exit_expr, block);
761 static
762 void dot_pass_genConditional (gpy_dot_tree_t * decl,
763 tree * block,
764 dot_contextTable_t context)
766 tree cval = build_decl (UNKNOWN_LOCATION, VAR_DECL,
767 create_tmp_var_name ("CELSE"),
768 boolean_type_node);
769 DECL_INITIAL (cval) = boolean_false_node;
770 append_to_statement_list (cval, block);
773 Make each conditional block exit out of the whole thing properly
775 tree endif_label_decl = build_decl (UNKNOWN_LOCATION, LABEL_DECL,
776 create_tmp_var_name ("ENDIF"),
777 void_type_node);
778 tree endif_label_expr = fold_build1_loc (UNKNOWN_LOCATION, LABEL_EXPR,
779 void_type_node, endif_label_decl);
780 DECL_CONTEXT (endif_label_decl) = current_function_decl;
782 gpy_dot_tree_t * ifblock = DOT_FIELD (decl);
783 gpy_dot_tree_t * elifchain = DOT_lhs_TT (decl);
784 gpy_dot_tree_t * elseblock = DOT_rhs_TT (decl);
786 dot_pass_genCBlock (ifblock, block, context, cval, endif_label_decl);
788 gpy_dot_tree_t * elifnode;
789 for (elifnode = elifchain; elifnode != NULL_DOT;
790 elifnode = DOT_CHAIN (elifnode))
791 dot_pass_genCBlock (elifnode, block, context, cval, endif_label_decl);
793 if (elseblock)
794 dot_pass_genCBlock (elseblock, block, context, cval, endif_label_decl);
796 append_to_statement_list (endif_label_expr, block);
799 static
800 tree dot_pass_genModifyExpr (gpy_dot_tree_t * decl,
801 tree * block,
802 dot_contextTable_t context)
804 tree retval = error_mark_node;
805 gpy_dot_tree_t * lhs = DOT_lhs_TT (decl);
806 gpy_dot_tree_t * rhs = DOT_rhs_TT (decl);
809 We dont handle full target lists yet
810 all targets are in the lhs tree.
812 To implment a target list such as:
813 x,y,z = 1
815 The lhs should be a DOT_CHAIN of identifiers!
816 So we just iterate over them and deal with it as such!
819 switch (DOT_TYPE (lhs))
821 case D_IDENTIFIER:
823 tree addr = dot_pass_lookupDecl (context,
824 DOT_IDENTIFIER_POINTER (lhs));
825 /* means id isn't previously declared and we can just make it locally. */
826 if (addr == error_mark_node)
828 dot_contextEntry_t current_context = DOT_CURRENT_CONTEXT (context);
829 addr = build_decl (UNKNOWN_LOCATION, VAR_DECL,
830 get_identifier (DOT_IDENTIFIER_POINTER (lhs)),
831 gpy_object_type_ptr);
832 gcc_assert (dot_pass_pushDecl (addr, DOT_IDENTIFIER_POINTER (lhs), current_context));
834 tree addr_rhs_tree = dot_pass_lowerExpr (rhs, context, block);
836 switch (TREE_CODE (addr))
838 case POINTER_PLUS_EXPR:
840 tree fold = build_decl (UNKNOWN_LOCATION, VAR_DECL,
841 create_tmp_var_name ("__MOD_DECL_ACC"),
842 gpy_object_type_ptr_ptr);
843 append_to_statement_list (build2 (MODIFY_EXPR,
844 gpy_object_type_ptr_ptr,
845 fold, addr),
846 block);
848 tree refer = build_fold_indirect_ref (fold);
849 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
850 refer,
851 addr_rhs_tree),
852 block);
853 retval = refer;
855 break;
857 case PARM_DECL:
858 case COMPONENT_REF:
859 case VAR_DECL:
861 if (TREE_TYPE (addr) == gpy_object_type_ptr_ptr)
863 /* *T.x = addr */
864 tree refer = build_fold_indirect_ref (addr);
865 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
866 refer,
867 addr_rhs_tree),
868 block);
869 retval = refer;
871 else
873 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
874 addr,
875 addr_rhs_tree),
876 block);
877 retval = addr;
880 break;
882 default:
883 error ("unhandled shizzle!\n");
884 break;
887 break;
889 case D_ATTRIB_REF:
891 tree addr_rhs_tree = dot_pass_lowerExpr (rhs, context, block);
892 tree addr_lhs_tree = dot_pass_lowerExpr (lhs, context, block);
894 gcc_assert (TREE_TYPE (addr_lhs_tree) == gpy_object_type_ptr_ptr);
895 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr_ptr,
896 build_fold_indirect_ref (addr_lhs_tree),
897 addr_rhs_tree),
898 block);
899 retval = addr_lhs_tree;
901 break;
903 case D_SLICE:
905 tree addr_rhs_tree = dot_pass_lowerExpr (rhs, context, block);
906 gcc_assert (TREE_TYPE (addr_rhs_tree) == gpy_object_type_ptr);
908 tree ident = dot_pass_lowerExpr (DOT_lhs_TT (lhs), context, block);
909 tree slice = dot_pass_lowerExpr (DOT_rhs_TT (lhs), context, block);
911 tree sla = GPY_RR_makeRefSlice (ident, slice);
912 gcc_assert (TREE_TYPE (sla) == gpy_object_type_ptr_ptr);
914 tree tmp = build_decl (UNKNOWN_LOCATION, VAR_DECL,
915 create_tmp_var_name ("MSLA"),
916 gpy_object_type_ptr_ptr);
917 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr_ptr,
918 tmp, sla),
919 block);
920 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr_ptr,
921 build_fold_indirect_ref (tmp), addr_rhs_tree),
922 block);
923 retval = tmp;
925 break;
927 default:
928 error ("unhandled target or target list in modify expression\n");
929 break;
932 return retval;
935 static
936 tree dot_pass_cleanRef (tree decl, tree * block)
938 tree retval = decl;
939 if (TREE_TYPE (decl) == gpy_object_type_ptr_ptr)
941 tree fold = build_decl (UNKNOWN_LOCATION, VAR_DECL,
942 create_tmp_var_name ("CLRF"),
943 gpy_object_type_ptr);
944 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
945 fold, build_fold_indirect_ref (decl)),
946 block);
947 retval = fold;
949 return retval;
952 static
953 tree dot_pass_genBinExpr (gpy_dot_tree_t * decl, tree * block,
954 dot_contextTable_t context)
956 tree retval = error_mark_node;
957 gcc_assert (DOT_T_FIELD (decl) == D_D_EXPR);
959 gpy_dot_tree_t * lhs = DOT_lhs_TT (decl);
960 gpy_dot_tree_t * rhs = DOT_rhs_TT (decl);
961 tree lhs_eval = dot_pass_lowerExpr (lhs, context, block);
962 tree rhs_eval = dot_pass_lowerExpr (rhs, context, block);
964 lhs_eval = dot_pass_cleanRef (lhs_eval, block);
965 rhs_eval = dot_pass_cleanRef (rhs_eval, block);
967 tree op = error_mark_node;
968 switch (DOT_TYPE (decl))
970 // @see libgpython/runtime/gpy-module-stack.c::gpy_rr_eval_expression
971 case D_ADD_EXPR:
972 op = GPY_RR_eval_expression (lhs_eval, rhs_eval,
973 build_int_cst (integer_type_node, 1));
974 break;
976 case D_MINUS_EXPR:
977 op = GPY_RR_eval_expression (lhs_eval, rhs_eval,
978 build_int_cst (integer_type_node, 2));
979 break;
981 case D_MULT_EXPR:
982 op = GPY_RR_eval_expression (lhs_eval, rhs_eval,
983 build_int_cst (integer_type_node, 4));
984 break;
986 case D_LESS_EXPR:
987 op = GPY_RR_eval_expression (lhs_eval, rhs_eval,
988 build_int_cst (integer_type_node, 6));
989 break;
991 case D_GREATER_EXPR:
992 op = GPY_RR_eval_expression (lhs_eval, rhs_eval,
993 build_int_cst (integer_type_node, 8));
994 break;
996 case D_EQ_EQ_EXPR:
997 op = GPY_RR_eval_expression (lhs_eval, rhs_eval,
998 build_int_cst (integer_type_node, 10));
999 break;
1001 case D_NOT_EQ_EXPR:
1002 op = GPY_RR_eval_expression (lhs_eval, rhs_eval,
1003 build_int_cst (integer_type_node, 11));
1004 break;
1006 default:
1007 error ("unhandled binary operation type!\n");
1008 break;
1010 gcc_assert (op != error_mark_node);
1012 tree retaddr = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1013 create_tmp_var_name ("T"),
1014 gpy_object_type_ptr);
1015 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
1016 retaddr, op),
1017 block);
1018 retval = retaddr;
1019 return retval;
1022 static
1023 void dot_pass_genReturnStmt (gpy_dot_tree_t * decl, tree * block,
1024 dot_contextTable_t context)
1026 /* Remember we have have return x or we can simply just have a return */
1027 if (DOT_lhs_TT (decl))
1029 tree lexpr = dot_pass_lowerExpr (DOT_lhs_TT (decl), context, block);
1030 tree tmp = lexpr;
1031 if (TREE_TYPE (tmp) == gpy_object_type_ptr_ptr)
1033 tmp = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1034 create_tmp_var_name ("ATAR"),
1035 gpy_object_type_ptr);
1036 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
1037 tmp,
1038 build_fold_indirect_ref (lexpr)),
1039 block);
1041 append_to_statement_list (GPY_RR_eval_return (tmp), block);
1043 append_to_statement_list (fold_build1_loc (UNKNOWN_LOCATION, RETURN_EXPR,
1044 void_type_node, NULL_TREE),
1045 block);
1048 static
1049 void dot_pass_genPrintStmt (gpy_dot_tree_t * decl, tree * block,
1050 dot_contextTable_t context)
1052 gpy_dot_tree_t * arguments = decl->opa.t;
1054 vec<tree,va_gc> * callvec_tmp;
1055 vec_alloc (callvec_tmp, 0);
1057 gpy_dot_tree_t * it = NULL;
1058 for (it = arguments; it != NULL; it = DOT_CHAIN (it))
1060 tree lexpr = dot_pass_lowerExpr (it, context, block);
1061 tree tmp = lexpr;
1062 if (TREE_TYPE (lexpr) == gpy_object_type_ptr_ptr)
1064 /* lets fold */
1065 tmp = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1066 create_tmp_var_name ("ATAR"),
1067 gpy_object_type_ptr);
1068 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
1069 tmp,
1070 build_fold_indirect_ref (lexpr)),
1071 block);
1073 vec_safe_push (callvec_tmp, tmp);
1075 vec<tree,va_gc> * callvec;
1076 vec_alloc (callvec, 0);
1077 vec_safe_push (callvec, build_int_cst (integer_type_node, 1));
1078 vec_safe_push (callvec, build_int_cst (integer_type_node, callvec_tmp->length ()));
1080 GPY_VEC_stmts_append (tree, callvec, callvec_tmp);
1081 append_to_statement_list (GPY_RR_eval_print (callvec), block);
1084 static
1085 tree dot_pass_lowerExpr (gpy_dot_tree_t * dot,
1086 dot_contextTable_t context,
1087 tree * block)
1089 tree retval = error_mark_node;
1090 switch (DOT_TYPE (dot))
1092 case D_PRIMITIVE:
1093 retval = dot_pass_genScalar (dot, block);
1094 break;
1096 case D_T_LIST:
1097 retval = dot_pass_genEnclosure (dot, block, context);
1098 break;
1100 case D_SLICE:
1102 tree ident = dot_pass_lowerExpr (DOT_lhs_TT (dot), context, block);
1103 tree slice = dot_pass_lowerExpr (DOT_rhs_TT (dot), context, block);
1105 tree sla = GPY_RR_makeSlice (ident, slice);
1106 tree tmp = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1107 create_tmp_var_name ("SLA"),
1108 gpy_object_type_ptr);
1109 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
1110 tmp, sla),
1111 block);
1112 retval = tmp;
1114 break;
1116 case D_IDENTIFIER:
1118 tree lookup = dot_pass_lookupDecl (context,
1119 DOT_IDENTIFIER_POINTER (dot));
1121 //debug ("IDENT lExpr lookup %s!\n", DOT_IDENTIFIER_POINTER (dot));
1122 //gcc_assert (lookup != error_mark_node);
1123 if (lookup == error_mark_node)
1124 fatal_error ("Identifier <%s> was not found in this scope\n",
1125 DOT_IDENTIFIER_POINTER (dot));
1127 switch (TREE_CODE (lookup))
1129 case VAR_DECL:
1130 case PARM_DECL:
1131 case COMPONENT_REF:
1132 retval = lookup;
1133 break;
1135 default:
1137 tree tmp = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1138 create_tmp_var_name ("VA"),
1139 gpy_object_type_ptr_ptr);
1140 append_to_statement_list (build2 (MODIFY_EXPR,
1141 gpy_object_type_ptr_ptr,
1142 tmp, lookup),
1143 block);
1144 tree atmp = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1145 create_tmp_var_name ("VP"),
1146 gpy_object_type_ptr);
1147 append_to_statement_list (build2 (MODIFY_EXPR,
1148 gpy_object_type_ptr,
1149 atmp, build_fold_indirect_ref (tmp)),
1150 block);
1151 retval = atmp;
1153 break;
1156 break;
1158 case D_ATTRIB_REF:
1160 tree addr_1 = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1161 create_tmp_var_name ("ATRD"),
1162 gpy_object_type_ptr_ptr);
1163 gpy_dot_tree_t * xlhs = DOT_lhs_TT (dot);
1164 gpy_dot_tree_t * xrhs = DOT_rhs_TT (dot);
1166 gcc_assert (DOT_TYPE (xrhs) == D_IDENTIFIER);
1167 tree lhs_tree = dot_pass_lowerExpr (xlhs, context, block);
1168 const char * attrib_ident = DOT_IDENTIFIER_POINTER (xrhs);
1170 tree str = gpy_dot_type_const_string_tree (attrib_ident);
1171 tree lhs_tree_fold = lhs_tree;
1172 if (TREE_TYPE (lhs_tree) == gpy_object_type_ptr_ptr)
1174 lhs_tree_fold = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1175 create_tmp_var_name ("ATRDF"),
1176 gpy_object_type_ptr);
1177 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
1178 lhs_tree_fold,
1179 build_fold_indirect_ref (lhs_tree)),
1180 block);
1182 tree attrib_ref = build2 (MODIFY_EXPR, gpy_object_type_ptr_ptr, addr_1,
1183 GPY_RR_fold_attrib_ref (lhs_tree_fold,
1184 build_fold_addr_expr (str))
1186 append_to_statement_list (attrib_ref, block);
1187 retval = addr_1;
1189 break;
1191 case D_CALL_EXPR:
1193 gpy_dot_tree_t * callid = DOT_lhs_TT (dot);
1195 tree lcall_decl = dot_pass_lowerExpr (callid, context, block);
1196 tree call_decl = lcall_decl;
1197 if (TREE_TYPE (lcall_decl) == gpy_object_type_ptr_ptr)
1199 /* lets fold */
1200 call_decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1201 create_tmp_var_name ("ATAR"),
1202 gpy_object_type_ptr);
1203 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
1204 call_decl,
1205 build_fold_indirect_ref (lcall_decl)),
1206 block);
1209 gpy_dot_tree_t * argslist;
1210 vec<tree,va_gc> * argsvec = NULL;
1211 if (DOT_TYPE (callid) == D_ATTRIB_REF)
1213 tree basetree = dot_pass_lowerExpr (DOT_lhs_TT (callid),
1214 context, block);
1215 tree basetree_fold = basetree;
1216 if (TREE_TYPE (basetree) == gpy_object_type_ptr_ptr)
1218 basetree_fold = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1219 create_tmp_var_name ("ATRDF"),
1220 gpy_object_type_ptr);
1221 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
1222 basetree_fold,
1223 build_fold_indirect_ref (basetree)),
1224 block);
1226 vec_safe_push (argsvec, basetree_fold);
1228 else
1230 // we push in a null entry...
1231 tree nullp = build_int_cst (ptr_type_node, 0);
1232 vec_safe_push (argsvec, nullp);
1235 for (argslist = DOT_rhs_TT (dot); argslist != NULL_DOT;
1236 argslist = DOT_CHAIN (argslist))
1238 tree lexpr = dot_pass_lowerExpr (argslist, context, block);
1239 tree argument = lexpr;
1240 if (TREE_TYPE (argument) == gpy_object_type_ptr_ptr)
1242 argument = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1243 create_tmp_var_name ("ATRDF"),
1244 gpy_object_type_ptr);
1245 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
1246 argument,
1247 build_fold_indirect_ref (lexpr)),
1248 block);
1250 vec_safe_push (argsvec, argument);
1252 vec<tree,va_gc> * args = NULL;
1253 vec_alloc (args, 0);
1254 vec_safe_push (args, call_decl);
1256 int tmp = 0;
1257 if (argsvec)
1259 tmp = argsvec->length ();
1260 vec_safe_push (args, build_int_cst (integer_type_node, tmp));
1261 GPY_VEC_stmts_append (tree, args, argsvec);
1263 else
1264 vec_safe_push (args, build_int_cst (integer_type_node, tmp));
1266 tree retaddr = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1267 create_tmp_var_name ("RET"),
1268 gpy_object_type_ptr);
1269 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
1270 retaddr,
1271 GPY_RR_fold_call (args)),
1272 block);
1273 retval = retaddr;
1275 break;
1277 default:
1279 switch (DOT_TYPE (dot))
1281 case D_MODIFY_EXPR:
1282 retval = dot_pass_genModifyExpr (dot, block, context);
1283 break;
1285 case D_ADD_EXPR:
1286 case D_MINUS_EXPR:
1287 case D_MULT_EXPR:
1288 case D_DIVD_EXPR:
1289 case D_LESS_EXPR:
1290 case D_GREATER_EXPR:
1291 case D_EQ_EQ_EXPR:
1292 case D_NOT_EQ_EXPR:
1293 /* TODO remember to add the rest of the bin ops */
1294 retval = dot_pass_genBinExpr (dot, block, context);
1295 break;
1297 default:
1298 error ("unhandled operation type!\n");
1299 break;
1302 break;
1304 return retval;
1307 static
1308 vec<tree,va_gc> * dot_pass_genClass (gpy_dot_tree_t * dot,
1309 dot_contextTable_t context,
1310 tree class_type,
1311 const char * pid)
1313 vec<tree,va_gc> * lowered_decls;
1314 vec_alloc (lowered_decls, 0);
1316 tree class_type_ptr = build_pointer_type (class_type);
1317 tree fntype = build_function_type_list (void_type_node,
1318 class_type_ptr,
1319 NULL_TREE);
1320 tree ident = dot_pass_concat_identifier (GPY_current_module_name,
1321 DOT_IDENTIFIER_POINTER (DOT_FIELD (dot)));
1322 ident = dot_pass_concat_identifier (IDENTIFIER_POINTER (ident),
1323 "__field_init__");
1324 tree fndecl = dot_pass_genFndecl_Basic (ident, fntype);
1325 current_function_decl = fndecl;
1327 tree arglist = NULL_TREE;
1328 tree self_parm_decl = build_decl (BUILTINS_LOCATION, PARM_DECL,
1329 get_identifier ("__object_state__"),
1330 class_type_ptr);
1331 DECL_CONTEXT (self_parm_decl) = fndecl;
1332 DECL_ARG_TYPE (self_parm_decl) = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
1333 TREE_READONLY (self_parm_decl) = 1;
1334 arglist = chainon (arglist, self_parm_decl);
1335 TREE_USED (self_parm_decl) = 1;
1336 DECL_ARGUMENTS (fndecl) = arglist;
1338 gpy_hash_tab_t field_type_namespace;
1339 gpy_dd_hash_init_table (&field_type_namespace);
1340 dot_pass_setupClassFieldContext (class_type, self_parm_decl, &field_type_namespace);
1342 gpy_vec_push (context, &field_type_namespace);
1344 tree block = alloc_stmt_list ();
1345 gpy_dot_tree_t * node;
1346 for (node = DOT_lhs_TT (dot); node != NULL_DOT;
1347 node = DOT_CHAIN (node))
1349 if (DOT_T_FIELD (node) == D_D_EXPR)
1351 dot_pass_lowerExpr (node, context, &block);
1352 continue;
1354 switch (DOT_TYPE (node))
1356 case D_PRINT_STMT:
1357 dot_pass_genPrintStmt (node, &block, context);
1358 break;
1360 case D_KEY_RETURN:
1361 dot_pass_genReturnStmt (node, &block, context);
1362 break;
1364 case D_STRUCT_WHILE:
1365 dot_pass_genWhile (node, &block, context);
1366 break;
1368 case D_STRUCT_METHOD:
1370 const char * modID = DOT_IDENTIFIER_POINTER (DOT_FIELD (dot));
1371 const char * npid = dot_pass_concat (pid, modID);
1372 tree attrib = dot_pass_genFunction (node, context, npid);
1373 vec_safe_push (lowered_decls, attrib);
1375 break;
1377 default:
1378 error ("unhandled syntax within class!\n");
1379 break;
1382 tree bind = NULL_TREE;
1383 tree bl = build_block (DECL_RESULT (fndecl), NULL_TREE, fndecl, NULL_TREE);
1384 DECL_INITIAL (fndecl) = bl;
1385 TREE_USED (bl) = 1;
1387 bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS(bl),
1388 NULL_TREE, bl);
1389 TREE_SIDE_EFFECTS (bind) = 1;
1390 /* Finalize the main function */
1391 BIND_EXPR_BODY (bind) = block;
1392 block = bind;
1393 DECL_SAVED_TREE (fndecl) = block;
1395 gimplify_function_tree (fndecl);
1396 cgraph_finalize_function (fndecl, false);
1398 vec_safe_push (lowered_decls, fndecl);
1399 gpy_vec_pop (context);
1400 pop_cfun ();
1402 return lowered_decls;
1405 static
1406 tree dot_pass_genFunction (gpy_dot_tree_t * dot,
1407 dot_contextTable_t context,
1408 const char * parentID)
1410 /* setup next context */
1411 gpy_hash_tab_t ctx;
1412 gpy_dd_hash_init_table (&ctx);
1413 gpy_vec_push (context, &ctx);
1415 gpy_dot_tree_t * pnode;
1416 tree params = NULL_TREE;
1417 for (pnode = DOT_lhs_TT (dot); pnode != NULL_DOT;
1418 pnode = DOT_CHAIN (pnode))
1419 chainon (params, tree_cons (NULL_TREE, gpy_object_type_ptr, NULL_TREE));
1420 chainon (params, tree_cons (NULL_TREE, void_type_node, NULL_TREE));
1422 tree fntype = build_function_type_list (void_type_node, params);
1423 tree ident = dot_pass_concat_identifier (parentID,
1424 DOT_IDENTIFIER_POINTER (DOT_FIELD (dot)));
1425 tree fndecl = dot_pass_genFndecl_Basic (ident, fntype);
1426 current_function_decl = fndecl;
1428 tree arglist = NULL_TREE;
1429 for (pnode = DOT_lhs_TT (dot); pnode != NULL_DOT;
1430 pnode = DOT_CHAIN (pnode))
1432 const char * parmid = DOT_IDENTIFIER_POINTER (pnode);
1433 tree parm_decl = build_decl (BUILTINS_LOCATION, PARM_DECL,
1434 get_identifier (parmid),
1435 gpy_object_type_ptr);
1436 DECL_CONTEXT (parm_decl) = fndecl;
1437 DECL_ARG_TYPE (parm_decl) = gpy_object_type_ptr;
1438 TREE_READONLY (parm_decl) = 1;
1439 arglist = chainon (arglist, parm_decl);
1440 TREE_USED (parm_decl) = 1;
1442 gcc_assert (dot_pass_pushDecl (parm_decl, parmid, &ctx));
1444 DECL_ARGUMENTS (fndecl) = arglist;
1446 tree block = alloc_stmt_list ();
1447 gpy_dot_tree_t * node;
1448 for (node = DOT_rhs_TT (dot); node != NULL_DOT;
1449 node = DOT_CHAIN (node))
1451 if (DOT_T_FIELD (node) == D_D_EXPR)
1453 dot_pass_lowerExpr (node, context, &block);
1454 continue;
1456 switch (DOT_TYPE (node))
1458 case D_PRINT_STMT:
1459 dot_pass_genPrintStmt (node, &block, context);
1460 break;
1462 case D_KEY_RETURN:
1463 dot_pass_genReturnStmt (node, &block, context);
1464 break;
1466 case D_STRUCT_CONDITIONAL:
1467 dot_pass_genConditional (node, &block, context);
1468 break;
1470 case D_STRUCT_WHILE:
1471 dot_pass_genWhile (node, &block, context);
1472 break;
1474 default:
1475 error ("unhandled syntax within toplevel function!\n");
1476 break;
1479 tree bind = NULL_TREE;
1480 tree bl = build_block (DECL_RESULT (fndecl), NULL_TREE, fndecl, NULL_TREE);
1481 DECL_INITIAL (fndecl) = bl;
1482 TREE_USED (bl) = 1;
1484 bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS(bl),
1485 NULL_TREE, bl);
1486 TREE_SIDE_EFFECTS (bind) = 1;
1487 /* Finalize the main function */
1488 BIND_EXPR_BODY (bind) = block;
1489 block = bind;
1490 DECL_SAVED_TREE (fndecl) = block;
1492 gimplify_function_tree (fndecl);
1493 cgraph_finalize_function (fndecl, false);
1494 pop_cfun ();
1496 gpy_vec_pop (context);
1497 return fndecl;
1500 static
1501 void dot_pass_mainInitCheck (tree * block)
1503 // if we have already initilized we should just return...
1504 tree label_decl = build_decl (UNKNOWN_LOCATION, LABEL_DECL,
1505 create_tmp_var_name ("LBIF"),
1506 void_type_node);
1507 tree label_expr = fold_build1_loc (UNKNOWN_LOCATION, LABEL_EXPR,
1508 void_type_node, label_decl);
1510 tree endif_label_decl = build_decl (UNKNOWN_LOCATION, LABEL_DECL,
1511 create_tmp_var_name ("ENDIF"),
1512 void_type_node);
1513 tree endif_label_expr = fold_build1_loc (UNKNOWN_LOCATION, LABEL_EXPR,
1514 void_type_node, endif_label_decl);
1515 DECL_CONTEXT (endif_label_decl) = current_function_decl;
1516 DECL_CONTEXT (label_decl) = current_function_decl;
1518 tree conditional = fold_build2_loc (UNKNOWN_LOCATION, EQ_EXPR,
1519 boolean_type_node,
1520 moduleInit,
1521 boolean_true_node);
1522 tree cond = build3_loc (UNKNOWN_LOCATION, COND_EXPR, void_type_node,
1523 conditional,
1524 build1 (GOTO_EXPR, void_type_node, label_decl),
1525 build1 (GOTO_EXPR, void_type_node, endif_label_decl));
1527 append_to_statement_list (cond, block);
1528 append_to_statement_list (label_expr, block);
1529 append_to_statement_list (fold_build1_loc (UNKNOWN_LOCATION, RETURN_EXPR,
1530 void_type_node, NULL_TREE),
1531 block);
1532 append_to_statement_list (endif_label_expr, block);
1533 append_to_statement_list (build2 (MODIFY_EXPR, boolean_type_node,
1534 moduleInit, boolean_true_node),
1535 block);
1538 static
1539 void dot_pass_generic_TU (gpy_hash_tab_t * types,
1540 vec<gpydot,va_gc> * decls,
1541 vec<tree,va_gc> * generic)
1543 gpy_hash_tab_t toplvl, topnxt;
1544 gpy_dd_hash_init_table (&toplvl);
1545 gpy_dd_hash_init_table (&topnxt);
1547 gpy_vector_t context;
1548 memset (&context, 0, sizeof (gpy_vector_t));
1550 gpy_vec_push (&context, &toplvl);
1551 gpy_vec_push (&context, &topnxt);
1553 tree block = alloc_stmt_list ();
1554 tree module = dot_pass_getModuleType (GPY_current_module_name, types);
1555 dot_pass_setupContext (module, &context, generic, &block);
1557 tree fntype = build_function_type_list (void_type_node, NULL_TREE);
1558 tree ident = dot_pass_concat_identifier (GPY_current_module_name,
1559 "__main_start__");
1560 tree fndecl = dot_pass_genFndecl_Basic (ident, fntype);
1561 current_function_decl = fndecl;
1562 dot_pass_mainInitCheck (&block);
1564 int i;
1565 gpy_dot_tree_t * dot = NULL_DOT;
1566 for (i = 0; decls->iterate (i, &dot); ++i)
1568 if (DOT_T_FIELD (dot) == D_D_EXPR)
1570 dot_pass_lowerExpr (dot, &context, &block);
1571 continue;
1574 switch (DOT_TYPE (dot))
1576 case D_PRINT_STMT:
1577 dot_pass_genPrintStmt (dot, &block, &context);
1578 break;
1580 case D_STRUCT_CONDITIONAL:
1581 dot_pass_genConditional (dot, &block, &context);
1582 break;
1584 case D_STRUCT_WHILE:
1585 dot_pass_genWhile (dot, &block, &context);
1586 break;
1588 case D_STRUCT_FOR:
1589 dot_pass_genFor (dot, &block, &context);
1590 break;
1592 case D_KEY_RETURN:
1593 error ("Return in toplevel context is invalid!\n");
1594 break;
1596 case D_KEY_IMPORT:
1597 dot_pass_genImport (dot, &block, &context);
1598 break;
1600 case D_STRUCT_METHOD:
1602 tree func = dot_pass_genFunction (dot, &context, GPY_current_module_name);
1603 /* assign the function to the decl */
1604 const char * funcid = DOT_IDENTIFIER_POINTER (DOT_FIELD (dot));
1605 tree funcdecl = dot_pass_lookupDecl (&context, funcid);
1606 int n = 0;
1607 gpy_dot_tree_t * pnode;
1608 for (pnode = DOT_lhs_TT (dot); pnode != NULL_DOT;
1609 pnode = DOT_CHAIN (pnode))
1610 n++;
1611 tree nargs = build_int_cst (integer_type_node, n);
1612 tree str = gpy_dot_type_const_string_tree (funcid);
1613 tree fold_functor = GPY_RR_fold_func_decl (build_fold_addr_expr (str),
1614 func, nargs);
1615 tree decl_func = build_decl (UNKNOWN_LOCATION, VAR_DECL,
1616 create_tmp_var_name ("FN"),
1617 gpy_object_type_ptr);
1618 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
1619 decl_func, fold_functor),
1620 &block);
1621 append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
1622 build_fold_indirect_ref (funcdecl),
1623 decl_func),
1624 &block);
1625 vec_safe_push (generic, func);
1627 break;
1629 case D_STRUCT_CLASS:
1631 char * classID = dot_pass_concat (GPY_current_module_name,
1632 DOT_IDENTIFIER_POINTER (DOT_FIELD (dot)));
1633 tree classType = dot_pass_getModuleType (classID, types);
1634 vec<tree,va_gc> * cdecls = dot_pass_genClass (dot, &context, classType,
1635 GPY_current_module_name);
1636 GPY_VEC_stmts_append (tree, generic, cdecls);
1637 tree class_decl_ptr = dot_pass_lookupDecl (&context,
1638 DOT_IDENTIFIER_POINTER (DOT_FIELD (dot)));
1639 dot_pass_genWalkClass (&block, classType, class_decl_ptr, cdecls);
1641 break;
1643 default:
1644 fatal_error ("unhandled tree!\n");
1645 break;
1649 tree entry_decl = NULL_TREE;
1650 if (GPY_OPT_gen_main)
1652 tree entry_fntype = gpy_unsigned_char_ptr;
1653 entry_decl = build_decl (BUILTINS_LOCATION, VAR_DECL,
1654 get_identifier (GPY_RR_entry),
1655 entry_fntype);
1656 TREE_STATIC (entry_decl) = 1;
1657 TREE_PUBLIC (entry_decl) = 1;
1658 TREE_USED (entry_decl) = 1;
1659 DECL_ARTIFICIAL (entry_decl) = 1;
1660 DECL_EXTERNAL (entry_decl) = 0;
1661 DECL_INITIAL (entry_decl) = build_fold_addr_expr (fndecl);
1662 rest_of_decl_compilation (entry_decl, 1, 0);
1665 tree bind = NULL_TREE;
1666 tree bl = build_block (DECL_RESULT (fndecl), NULL_TREE, fndecl, NULL_TREE);
1667 DECL_INITIAL (fndecl) = bl;
1668 TREE_USED (bl) = 1;
1670 bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS(bl),
1671 NULL_TREE, bl);
1672 TREE_SIDE_EFFECTS (bind) = 1;
1673 /* Finalize the main function */
1674 BIND_EXPR_BODY (bind) = block;
1675 block = bind;
1676 DECL_SAVED_TREE (fndecl) = block;
1678 gimplify_function_tree (fndecl);
1679 cgraph_finalize_function (fndecl, false);
1681 pop_cfun ();
1683 /* Here we need to write out export data to object */
1684 char * exportFile = (char *) alloca (512);
1685 const char * main_FNDECL = IDENTIFIER_POINTER (DECL_NAME (fndecl));
1686 snprintf (exportFile, 511, "%s.export.gpyx", GPY_current_module_name);
1687 gpy_writeExport (exportFile, (bool) GPY_OPT_gen_main,
1688 GPY_current_module_name, main_FNDECL);
1690 vec_safe_push (generic, fndecl);
1691 if (GPY_OPT_gen_main)
1692 vec_safe_push (generic, entry_decl);
1695 vec<tree,va_gc> * dot_pass_genericify (vec<tree,va_gc> * modules,
1696 vec<gpydot,va_gc> * decls)
1698 vec<tree,va_gc> * retval;
1699 vec_alloc (retval, 0);
1701 gpy_hash_tab_t types;
1702 gpy_dd_hash_init_table (&types);
1704 int i;
1705 tree type = NULL_TREE;
1706 for (i = 0; modules->iterate (i, &type); ++i)
1708 gpy_hashval_t h = gpy_dd_hash_string (IDENTIFIER_POINTER (TYPE_NAME(type)));
1709 void ** e = gpy_dd_hash_insert (h, type, &types);
1710 if (e)
1711 fatal_error ("module <%s> is already defined!\n",
1712 IDENTIFIER_POINTER (DECL_NAME (type)));
1714 dot_pass_generic_TU (&types, decls, retval);
1716 if (types.array)
1717 free (types.array);
1718 return retval;