added some kind of pass manager
[official-gcc.git] / gcc / python / py-stmt.c
blobc5f915ab5faecd40bb1cf79e01234030278c187f
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 "config.h"
18 #include "system.h"
19 #include "ansidecl.h"
20 #include "coretypes.h"
21 #include "tm.h"
22 #include "opts.h"
23 #include "tree.h"
24 #include "tree-iterator.h"
25 #include "tree-pass.h"
26 #include "gimple.h"
27 #include "toplev.h"
28 #include "debug.h"
29 #include "options.h"
30 #include "flags.h"
31 #include "convert.h"
32 #include "diagnostic-core.h"
33 #include "langhooks.h"
34 #include "langhooks-def.h"
35 #include "target.h"
36 #include "cgraph.h"
38 #include <gmp.h>
39 #include <mpfr.h>
41 #include "vec.h"
42 #include "hashtab.h"
44 #include "gpython.h"
45 #include "py-dot-codes.def"
46 #include "py-dot.h"
47 #include "py-vec.h"
48 #include "py-tree.h"
49 #include "py-types.h"
50 #include "py-runtime.h"
52 static VEC(gpydot,gc) * gpy_decls;
54 static gpy_symbol_obj * gpy_stmt_process_AST_Align (gpy_dot_tree_t **);
56 void gpy_stmt_process_decl (gpy_dot_tree_t * const dot)
58 /* Push the declaration! */
59 VEC_safe_push (gpydot, gc, gpy_decls, dot);
60 debug ("decl <%p> was pushed!\n", (void*)dot);
63 /**
64 * Fairly Confusing Function to read.
66 * example:
67 * >>> x = y = z = 2 + 2 + 2;
69 * --- Currently Yacc parses that expression into this Tree, which is just
70 side effect of the way we generate the gpy_dot_tree's the much higher level IR
71 which we bring down to GENERIC:
74 / \
75 + 2
78 / \
79 x =
80 / \
81 y =
82 / \
83 z 2
85 -- Is converted into the procedure:
87 1. z = 2 + 2 + 2;
88 2. y = z;
89 3. x = y;
91 -- Tree structure as so:
94 / \
95 x =
96 / \
97 y =
98 / \
99 z +
105 static
106 gpy_dot_tree_t * gpy_stmt_process_AST_Align (gpy_dot_tree_t ** dot)
108 gpy_dot_tree_t *retval = NULL_DOT;
109 gpy_dot_tree_t *nn = NULL_DOT;
110 if (DECL_CHAIN(*dot))
112 nn = DECL_CHAIN(*dot);
113 DECL_CHAIN(*dot) = NULL_DOT;
115 retval = (*dot);
117 if (DOT_TYPE(retval) != D_MODIFY_EXPR)
119 gpy_dot_tree_t *o = retval;
120 gpy_dot_tree_t *h = NULL_DOT;
122 while (o != NULL_DOT)
124 if ((DOT_TYPE(o) != D_IDENTIFIER) ||
125 (DOT_TYPE(o) != D_PRIMITIVE))
127 if (DOT_lhs_T(o) == D_TD_DOT)
129 if (DOT_TYPE(DOT_lhs_TT(o)) == D_MODIFY_EXPR)
131 h = o;
132 break;
134 else
136 o = DOT_lhs_TT(o);
139 else break;
141 else break;
143 if (h)
145 gpy_dot_tree_t *head = DOT_lhs_TT(h);
146 if (DOT_TYPE(DOT_rhs_TT(head)) == D_MODIFY_EXPR)
148 gpy_dot_tree_t *t = head, *m = NULL_DOT;
149 while (t)
151 if ((DOT_TYPE(t) != D_IDENTIFIER) ||
152 (DOT_TYPE(t) != D_PRIMITIVE))
154 if (DOT_TYPE(DOT_rhs_TT(t)) != D_MODIFY_EXPR)
156 m = t;
157 break;
159 else
161 t = t->opb.t;
164 else break;
167 if( m )
169 DOT_lhs_TT(h) = DOT_rhs_TT(m);
170 DOT_rhs_TT(m) = retval;
172 else
173 fatal_error ("error processing the expression AST!\n");
175 else
177 DOT_lhs_TT(h) = DOT_rhs_TT(head);
178 DOT_rhs_TT(head) = retval;
180 retval = head;
184 if (nn)
185 DOT_CHAIN(retval) = nn;
186 (*dot) = retval;
188 return retval;
191 VEC(tree,gc) * gpy_stmt_pass_generate_types (VEC(gpydot,gc) * decls)
193 VEC(tree,gc) * retval = VEC_alloc(tree,gc,0);
197 return retval;
201 * Things are quite complicated from here on and will change frequently
202 * We need to do a 1st pass over the code to generate our module.
204 Example:
206 x = 1
207 y = 2
208 def foo ():
209 return x + y
210 print foo ()
212 we need to generate out RECORD_TYPE with FIELDS x,y then pass again to generate
213 the rest of the code as our first pass will let us generate our TYPE so we know
214 how to access each variable in each context on the 2nd pass.
216 struct main.main {
217 gpy_object_t *x , *y;
220 gpy_object_t * main.foo (struct main.main * self, gpy_object_t ** __args)
222 T.1 = gpy_rr_bin_op (OP_ADDITION, self->x, self->y);
223 return T.1;
226 void main.init (struct main.main *self)
228 self->x = fold_int (1);
229 self->y = fold_int (2);
231 T.2 = fold_call (&main.foo, 1, self)
232 gpy_rr_print_stmt (1, T.2)
235 int main (int argc, char *argv[])
237 int retval;
239 init_runtime ();
241 struct main.main P;
242 main.init (&P);
244 cleanup_runtime ();
246 retval = 0;
247 return retval;
251 void gpy_stmt_write_globals (void)
253 VEC(tree,gc) * module_types = gpy_stmt_pass_generate_types (gpy_decls);
254 VEC(tree,gc) * dot2gen_trees = gpy_stmt_lower (module_types, gpy_decls);
256 VEC(tree,gc) * globals = dot2gen_trees;
257 int idx = 0;
258 while (gpy_stmt_pass_mngr[idx] != NULL)
260 DOT_stmt_pass x = gpy_stmt_pass_mngr[idx];
261 globals = x(module_types, globals);
262 idx++
265 int global_vec_len = VEC_length (tree, globals);
266 tree * global_vec = XNEWVEC (tree, global_vec_len);
267 tree itx = NULL_TREE;
268 int idy = 0;
270 FILE *tu_stream = dump_begin (TDI_tu, NULL);
271 for (idx=0; VEC_iterate (tree,globals,idx,itx); ++idx)
273 // debug_tree (itx);
275 if (tu_stream)
276 dump_node (itx, 0, tu_stream);
278 global_vec [idy] = itx;
279 idy++;
281 if (tu_stream)
282 dump_end(TDI_tu, tu_stream);
284 debug("Finished processing!\n\n");
286 debug("global_vec len = <%i>!\n", global_vec_len);
288 wrapup_global_declarations (global_vec, global_vec_len);
290 check_global_declarations (global_vec, global_vec_len);
291 emit_debug_global_declarations (global_vec, global_vec_len);
293 cgraph_finalize_compilation_unit ();
295 debug("finished passing to middle-end!\n\n");
298 typedef VEC(tree,gc) * (*DOT_stmt_pass__)(VEC(tree,gc) *, VEC(tree,gc) *);
299 static DOT_stmt_pass gpy_stmt_pass_mngr[] = { NULL };