/* This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ #include "config.h" #include "system.h" #include "ansidecl.h" #include "coretypes.h" #include "tm.h" #include "opts.h" #include "tree.h" #include "tree-iterator.h" #include "tree-pass.h" #include "gimple.h" #include "toplev.h" #include "debug.h" #include "options.h" #include "flags.h" #include "convert.h" #include "diagnostic-core.h" #include "langhooks.h" #include "langhooks-def.h" #include "target.h" #include "cgraph.h" #include #include #include "vec.h" #include "hashtab.h" #include "gpython.h" #include "py-dot.h" #include "py-vec.h" #include "py-tree.h" static VEC(gpydot,gc) * gpy_decls; typedef VEC(gpydot,gc) * (*DOT_stmt_pass__)(VEC(gpydot,gc) *); static DOT_stmt_pass__ gpy_stmt_pass_mngr[] = { NULL /* sentinal */ }; /* Pushes each decl from the parser onto the current translation unit */ void gpy_stmt_process_decl (gpy_dot_tree_t * const dot) { /* Push the declaration! */ VEC_safe_push (gpydot, gc, gpy_decls, dot); debug ("decl <%p> was pushed!\n", (void*)dot); } /** * Fairly Confusing Function to read. * * example: * >>> x = y = z = 2 + 2 + 2; * * --- Currently Yacc parses that expression into this Tree, which is just side effect of the way we generate the gpy_dot_tree's the much higher level IR which we bring down to GENERIC: + / \ + 2 / = / \ x = / \ y = / \ z 2 -- Is converted into the procedure: 1. z = 2 + 2 + 2; 2. y = z; 3. x = y; -- Tree structure as so: = / \ x = / \ y = / \ z + / \ + 2 / \ 2 2 **/ gpy_dot_tree_t * gpy_stmt_process_AST_Align (gpy_dot_tree_t ** d_dot) { gpy_dot_tree_t * retval = NULL_DOT; gpy_dot_tree_t * nn = NULL_DOT; gpy_dot_tree_t * dot = *d_dot; if (DOT_CHAIN(dot)) { nn = DOT_CHAIN(dot); DOT_CHAIN(dot) = NULL_DOT; } retval = (*d_dot); if (DOT_TYPE(retval) != D_MODIFY_EXPR) { gpy_dot_tree_t *o = retval; gpy_dot_tree_t *h = NULL_DOT; while (o != NULL_DOT) { if ((DOT_TYPE(o) != D_IDENTIFIER) || (DOT_TYPE(o) != D_PRIMITIVE)) { if (DOT_lhs_T(o) == D_TD_DOT) { if (DOT_TYPE(DOT_lhs_TT(o)) == D_MODIFY_EXPR) { h = o; break; } else { o = DOT_lhs_TT(o); } } else break; } else break; } if (h) { gpy_dot_tree_t *head = DOT_lhs_TT(h); if (DOT_TYPE(DOT_rhs_TT(head)) == D_MODIFY_EXPR) { gpy_dot_tree_t *t = head, *m = NULL_DOT; while (t) { if ((DOT_TYPE(t) != D_IDENTIFIER) || (DOT_TYPE(t) != D_PRIMITIVE)) { if (DOT_TYPE(DOT_rhs_TT(t)) != D_MODIFY_EXPR) { m = t; break; } else { t = t->opb.t; } } else break; } if( m ) { DOT_lhs_TT(h) = DOT_rhs_TT(m); DOT_rhs_TT(m) = retval; } else fatal_error ("error processing the expression AST!\n"); } else { DOT_lhs_TT(h) = DOT_rhs_TT(head); DOT_rhs_TT(head) = retval; } retval = head; } } if (nn) DOT_CHAIN(retval) = nn; (*d_dot) = retval; return retval; } /** * Things are quite complicated from here on and will change frequently * We need to do a 1st pass over the code to generate our module. Example: x = 1 y = 2 def foo (): return x + y print foo () we need to generate out RECORD_TYPE with FIELDS x,y then pass again to generate the rest of the code as our first pass will let us generate our TYPE so we know how to access each variable in each context on the 2nd pass. struct main.main { gpy_object_t *x , *y; } gpy_object_t * main.foo (struct main.main * self, gpy_object_t ** __args) { T.1 = gpy_rr_bin_op (OP_ADDITION, self->x, self->y); return T.1; } void main.init (struct main.main *self) { self->x = fold_int (1); self->y = fold_int (2); T.2 = fold_call (&main.foo, 1, self) gpy_rr_print_stmt (1, T.2) } int main (int argc, char *argv[]) { int retval; init_runtime (); struct main.main P; main.init (&P); cleanup_runtime (); retval = 0; return retval; } **/ void gpy_stmt_write_globals (void) { int idx = 0; VEC(gpydot,gc) * dot_decls = gpy_decls; while (gpy_stmt_pass_mngr[idx] != NULL) { DOT_stmt_pass__ x = gpy_stmt_pass_mngr[idx]; dot_decls = x(dot_decls); idx++; } VEC(tree,gc) * module_types = gpy_stmt_pass_generate_types (dot_decls); VEC(tree,gc) * dot2gen_trees = gpy_stmt_pass_lower (module_types, gpy_decls); VEC(tree,gc) * globals = dot2gen_trees; int global_vec_len = VEC_length (tree, globals); tree * global_vec = XNEWVEC (tree, global_vec_len); tree itx = NULL_TREE; int idy = 0; FILE *tu_stream = dump_begin (TDI_tu, NULL); for (idx=0; VEC_iterate (tree,globals,idx,itx); ++idx) { debug_tree (itx); if (tu_stream) dump_node (itx, 0, tu_stream); global_vec [idy] = itx; idy++; } if (tu_stream) dump_end(TDI_tu, tu_stream); debug("Finished processing!\n\n"); debug("global_vec len = <%i>!\n", global_vec_len); wrapup_global_declarations (global_vec, global_vec_len); check_global_declarations (global_vec, global_vec_len); emit_debug_global_declarations (global_vec, global_vec_len); cgraph_finalize_compilation_unit (); debug("finished passing to middle-end!\n\n"); }