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
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
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/>. */
20 #include "coretypes.h"
24 #include "tree-iterator.h"
25 #include "tree-pass.h"
32 #include "diagnostic-core.h"
33 #include "langhooks.h"
34 #include "langhooks-def.h"
45 #include "py-dot-codes.def"
50 #include "py-runtime.h"
52 static VEC(gpy_sym
,gc
) * gpy_decls
;
54 static gpy_symbol_obj
* gpy_stmt_process_AST_Align (gpy_symbol_obj
**);
56 static tree
gpy_stmt_pass_1 (VEC(gpy_sym
,gc
) * const);
57 static VEC(tree
,gc
) * gpy_stmt_pass_2 (VEC(gpy_sym
,gc
) * const, tree
);
59 static tree
gpy_stmt_create_module_type (VEC(tree
,gc
) * const, const char *);
61 static tree
gpy_stmt_create_main_fndecl (tree
, tree
);
62 static tree
gpy_stmt_create_module_initilizer (VEC(tree
,gc
) *, VEC(tree
,gc
) *,
65 void gpy_stmt_process_decl (gpy_symbol_obj
* const sym
)
67 /* Push the declaration! */
68 VEC_safe_push( gpy_sym
, gc
, gpy_decls
, sym
);
69 debug("decl <%p> was pushed!\n", (void*)sym
);
73 * Fairly Confusing Function to read.
76 * >>> x = y = z = 2 + 2 + 2;
78 * --- Currently Yacc parses that expression into this Tree:
92 -- Is converted into the procedure:
98 -- Tree structure as so:
113 gpy_symbol_obj
* gpy_stmt_process_AST_Align (gpy_symbol_obj
** sym
)
115 gpy_symbol_obj
*nn
= NULL
;
116 gpy_symbol_obj
*retval
= NULL
;
124 if( (*sym
)->exp
== OP_EXPRESS
)
126 debug("Processing Expression AST!\n");
127 if( retval
->type
!= OP_ASSIGN_EVAL
)
129 gpy_symbol_obj
*o
= retval
;
130 gpy_symbol_obj
*h
= NULL
;
133 if( o
->op_a_t
== TYPE_SYMBOL
)
135 if( o
->op_a
.symbol_table
->type
== OP_ASSIGN_EVAL
)
142 o
= o
->op_a
.symbol_table
;
149 gpy_symbol_obj
*head
= h
->op_a
.symbol_table
;
150 if( head
->op_b
.symbol_table
->type
== OP_ASSIGN_EVAL
)
152 gpy_symbol_obj
*t
= head
, *m
= NULL
;
155 if( t
->op_b_t
== TYPE_SYMBOL
)
157 if( t
->op_b
.symbol_table
->type
!= OP_ASSIGN_EVAL
)
164 t
= t
->op_b
.symbol_table
;
171 h
->op_a
.symbol_table
= m
->op_b
.symbol_table
;
172 m
->op_b
.symbol_table
= retval
;
176 fatal_error("error processing the expression AST!\n");
181 h
->op_a
.symbol_table
= head
->op_b
.symbol_table
;
182 head
->op_b
.symbol_table
= retval
;
198 tree
gpy_stmt_process_functor (gpy_symbol_obj
* const functor
, const char * prefix
,
199 tree module
, VEC(gpy_ctx_t
,gc
) * context
)
201 tree fntype
= build_function_type_list (gpy_object_type_ptr
, build_pointer_type (module
),
202 gpy_object_type_ptr_ptr
, NULL_TREE
);
203 tree fndecl
= build_decl (functor
->loc
, FUNCTION_DECL
,
204 get_identifier (functor
->identifier
), fntype
);
205 DECL_EXTERNAL (fndecl
) = 0;
206 TREE_PUBLIC (fndecl
) = 1;
207 TREE_STATIC (fndecl
) = 1;
209 tree declare_vars
= NULL_TREE
;
210 tree bind
= NULL_TREE
;
211 tree block
= alloc_stmt_list ();
213 tree result_decl
= build_decl (input_location
,
214 RESULT_DECL
, NULL_TREE
, integer_type_node
);
215 DECL_ARTIFICIAL (result_decl
) = 1;
216 DECL_IGNORED_P (result_decl
) = 1;
217 DECL_CONTEXT (result_decl
) = fndecl
;
218 DECL_RESULT (fndecl
) = result_decl
;
220 tree arglist
= NULL_TREE
;
221 tree typelist
= TYPE_ARG_TYPES (TREE_TYPE (fndecl
));
223 tree tmp
= TREE_VALUE (typelist
);
224 tree self
= build_decl (functor
->loc
, PARM_DECL
, get_identifier ("self"), tmp
);
225 DECL_CONTEXT (self
) = fndecl
;
226 DECL_ARG_TYPE (self
) = TREE_VALUE (typelist
);
227 TREE_READONLY (self
) = 1;
228 arglist
= chainon (arglist
, self
);
230 typelist
= TREE_CHAIN (typelist
);
231 tmp
= TREE_VALUE (typelist
);
232 tree __args__
= build_decl (functor
->loc
, PARM_DECL
, get_identifier ("__args__"), tmp
);
233 DECL_CONTEXT (__args__
) = fndecl
;
234 DECL_ARG_TYPE (__args__
) = TREE_VALUE (typelist
);
235 TREE_READONLY (__args__
) = 1;
236 arglist
= chainon (arglist
, __args__
);
238 TREE_USED (__args__
) = 1;
239 TREE_USED (self
) = 1;
241 DECL_ARGUMENTS (fndecl
) = arglist
;
243 gpy_symbol_obj
* o
= functor
->op_a
.symbol_table
;
248 /* looping over the gpy_symbol_obj block of function statements
249 and getting the respective tree's and creating the GENERIC block
251 VEC(tree
,gc
) * x
= gpy_stmt_get_tree_2 (o
, module
, context
);
253 for(idx
= 0; VEC_iterate(tree
,x
,idx
,xt
); ++idx
)
256 append_to_statement_list (xt
, &block
);
261 gpy_hash_tab_t
* ctx
= VEC_index (gpy_ctx_t
, context
,
262 VEC_length (gpy_ctx_t
,context
)-1);
263 int size
= ctx
->size
;
264 gpy_hash_entry_t
*array
= ctx
->array
;
266 for (idx
= 0; idx
<size
; ++idx
)
270 tree x
= (tree
) array
[idx
].data
;
271 gcc_assert (TREE_CODE(x
) == VAR_DECL
);
272 debug("got decl <%p>:<%s> within func <%s>!\n", (void*)x
,
273 IDENTIFIER_POINTER (DECL_NAME(x
)), functor
->identifier
);
274 TREE_CHAIN( x
) = declare_vars
;
279 tree bl
= make_node(BLOCK
);
280 BLOCK_SUPERCONTEXT(bl
) = fndecl
;
281 DECL_INITIAL(fndecl
) = bl
;
282 BLOCK_VARS(bl
) = declare_vars
;
284 bind
= build3(BIND_EXPR
, void_type_node
, BLOCK_VARS(bl
),
286 TREE_SIDE_EFFECTS(bind
) = 1;
288 BIND_EXPR_BODY(bind
) = block
;
290 DECL_SAVED_TREE(fndecl
) = block
;
292 gimplify_function_tree (fndecl
);
294 // cgraph_add_new_function (fndecl, false);
295 // cgraph_finalize_function (fndecl, true);
301 VEC(tree
,gc
) * gpy_stmt_get_tree_1 (gpy_symbol_obj
* sym
,
302 VEC(gpy_ctx_t
,gc
) * context
)
304 VEC(tree
,gc
) * retval
= NULL
;
306 debug ("processing decl of type <0x%X> object <%p>\n",
307 sym
->type
, (void*) sym
);
309 if( sym
->exp
== OP_EXPRESS
)
311 sym
= gpy_stmt_process_AST_Align (&sym
);
312 retval
= gpy_stmt_process_expression (sym
, context
);
318 case STRUCTURE_FUNCTION_DEF
:
325 fatal_error("unhandled symbol type <0x%x>\n", sym
->type
);
333 VEC(tree
,gc
) * gpy_stmt_get_tree_2 (gpy_symbol_obj
* sym
,
334 VEC(gpy_ctx_t
,gc
) * context
)
336 VEC(tree
,gc
) * retval
= NULL
;
338 debug ("processing decl of type <0x%X> object <%p>\n",
339 sym
->type
, (void*) sym
);
341 if( sym
->exp
== OP_EXPRESS
)
343 sym
= gpy_stmt_process_AST_Align (&sym
);
344 retval
= gpy_stmt_process_expression (sym
, context
);
352 retval
= gpy_stmt_process_print (sym
, context
);
357 fatal_error("unhandled symbol type <0x%x>\n", sym
->type
);
365 tree
gpy_stmt_create_main_fndecl (tree module
, tree init_fndecl
)
370 tree
gpy_stmt_create_module_initilizer (VEC(tree
,gc
) * stmts
,
371 VEC(tree
,gc
) * var_decls
,
377 tree
gpy_stmt_create_module_type (VEC(tree
,gc
) * const fields
,
380 tree module
= make_node (RECORD_TYPE
);
382 tree itx
= NULL_TREE
, field
= NULL_TREE
, last_field
= NULL_TREE
;
384 for (idx
= 0; VEC_iterate(tree
,fields
,idx
,itx
); ++idx
)
386 gcc_assert (TREE_CODE(itx
) == VAR_DECL
);
387 tree name
= DECL_NAME(itx
);
388 field
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, name
,
389 gpy_object_type_ptr
);
390 DECL_CONTEXT(field
) = module
;
392 DECL_CHAIN(last_field
) = field
;
394 TYPE_FIELDS(module
) = field
;
398 layout_type (module
);
400 finish_builtin_struct (module
, ident
, field
, NULL_TREE
);
401 TYPE_NAME (module
) = get_identifier (ident
);
406 tree
gpy_stmt_pass_1 (VEC(gpy_sym
,gc
) * const decls
)
408 VEC (gpy_ctx_t
, gc
) * context
= VEC_alloc (gpy_ctx_t
,gc
,0);
410 gpy_dd_hash_init_table (&ctx
);
411 VEC_safe_push (gpy_ctx_t
, gc
, context
, ctx
);
414 gpy_symbol_obj
* it
= NULL
;
415 tree retval
= NULL_TREE
, itx
= NULL_TREE
;
417 for (idx
= 0; VEC_iterate (gpy_sym
,decls
,idx
,it
); ++idx
)
419 VEC(tree
,gc
) * x
= gpy_stmt_get_tree_1 (it
,context
);
423 // all we care about is this toplevel context which
424 // should now be populated with VAR_DECL's we can
425 // create our module out of.
427 VEC(tree
,gc
) * global_var_decls
= VEC_alloc (tree
,gc
,0);
429 gpy_hash_tab_t
* hctx
= VEC_index (gpy_ctx_t
, context
,
430 VEC_length (gpy_ctx_t
,context
)-1);
431 int size
= hctx
->size
;
432 gpy_hash_entry_t
*array
= hctx
->array
;
433 for (idx
= 0; idx
< size
; ++idx
)
437 tree x
= (tree
) array
[idx
].data
;
439 if (TREE_CODE (x
) == VAR_DECL
)
441 debug("got decl <%p>:<%s>!\n", (void*)x
,
442 IDENTIFIER_POINTER (DECL_NAME(x
)));
443 VEC_safe_push (tree
, gc
, global_var_decls
, x
);
448 retval
= gpy_stmt_create_module_type (global_var_decls
, "main.main");
453 VEC(tree
,gc
) * gpy_stmt_pass_2 (VEC(gpy_sym
,gc
) * const decls
,
456 VEC(tree
,gc
) * retval
= VEC_alloc (tree
,gc
,0);
457 if (module
== error_mark_node
)
460 VEC_safe_push (tree
, gc
, retval
, error_mark_node
);
464 VEC (gpy_ctx_t
, gc
) * context
= VEC_alloc (gpy_ctx_t
,gc
,0);
467 gpy_symbol_obj
* it
= NULL
;
468 tree itx
= NULL_TREE
;
470 tree fntype
= build_function_type_list (void_type_node
, build_pointer_type (module
),
472 tree fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
473 get_identifier ("main.main.init"), fntype
);
474 DECL_EXTERNAL (fndecl
) = 0;
475 TREE_PUBLIC (fndecl
) = 1;
476 TREE_STATIC (fndecl
) = 1;
478 tree declare_vars
= NULL_TREE
;
479 tree bind
= NULL_TREE
;
480 tree block
= alloc_stmt_list ();
482 tree result_decl
= build_decl (input_location
,
483 RESULT_DECL
, NULL_TREE
, integer_type_node
);
484 DECL_ARTIFICIAL (result_decl
) = 1;
485 DECL_IGNORED_P (result_decl
) = 1;
486 DECL_CONTEXT (result_decl
) = fndecl
;
487 DECL_RESULT (fndecl
) = result_decl
;
489 tree arglist
= NULL_TREE
;
490 tree typelist
= TYPE_ARG_TYPES (TREE_TYPE (fndecl
));
492 tree tmp
= TREE_VALUE (typelist
);
493 tree self
= build_decl (functor
->loc
, PARM_DECL
, get_identifier ("self"), tmp
);
494 DECL_CONTEXT (self
) = fndecl
;
495 DECL_ARG_TYPE (self
) = TREE_VALUE (typelist
);
496 TREE_READONLY (self
) = 1;
497 arglist
= chainon (arglist
, self
);
499 TREE_USED (__args__
) = 1;
500 TREE_USED (self
) = 1;
502 DECL_ARGUMENTS (fndecl
) = arglist
;
505 gpy_dd_hash_init_table (&ctx
);
506 tree field
= TYPE_FIELDS (module
);
509 gcc_assert (gpy_ctx_push_decl (build3(COMPONENT_REF
, TREE_TYPE(field
),
510 self
, field
, NULL_TREE
),
511 IDENTIFIER_POINTER (DECL_NAME (field
)),
514 field
= DECL_CHAIN (field
);
516 VEC_safe_push (gpy_ctx_t
, gc
, context
, ctx
);
518 for (idx
= 0; VEC_iterate (gpy_sym
,decls
,idx
,it
); ++idx
)
522 case STRUCTURE_FUNCTION_DEF
:
527 VEC(tree
,gc
) * xt
= gpy_stmt_get_tree_2 (it
,context
);
528 for (idy
= 0; VEC_iterate (tree
,xt
,idy
,itx
); ++idy
)
531 gcc_assert (itx
!= error_mark_node
);
532 append_to_statement_list (itx
, &block
);
539 int size
= ctx
->size
;
540 gpy_hash_entry_t
*array
= ctx
->array
;
542 for (idx
= 0; idx
<size
; ++idx
)
546 tree x
= (tree
) array
[idx
].data
;
547 if (TREE_CODE(x
) == VAR_DECL
)
549 debug("got decl <%p>:<%s> within func <%s>!\n", (void*)x
,
550 IDENTIFIER_POINTER (DECL_NAME(x
)), functor
->identifier
);
551 TREE_CHAIN( x
) = declare_vars
;
557 tree bl
= make_node(BLOCK
);
558 BLOCK_SUPERCONTEXT(bl
) = fndecl
;
559 DECL_INITIAL(fndecl
) = bl
;
560 BLOCK_VARS(bl
) = declare_vars
;
562 bind
= build3(BIND_EXPR
, void_type_node
, BLOCK_VARS(bl
),
564 TREE_SIDE_EFFECTS(bind
) = 1;
566 BIND_EXPR_BODY(bind
) = block
;
568 DECL_SAVED_TREE(fndecl
) = block
;
570 gimplify_function_tree (fndecl
);
572 cgraph_add_new_function (fndecl
, false);
573 cgraph_finalize_function (fndecl
, true);
575 VEC_pop (gpy_ctx_t
, context
);
576 gpy_dd_hash_init_table (&ctx
);
578 for (idx
= 0; VEC_iterate (gpy_sym
,decls
,idx
,it
); ++idx
)
582 case STRUCTURE_FUNCTION_DEF
:
598 * Things are quite complicated from here on and will change frequently
599 * We need to do a 1st pass over the code to generate our module.
609 we need to generate out RECORD_TYPE with FIELDS x,y then pass again to generate
610 the rest of the code as our first pass will let us generate our TYPE so we know
611 how to access each variable in each context on the 2nd pass.
614 gpy_object_t *x , *y;
617 gpy_object_t * main.foo (struct main.main * self, gpy_object_t ** __args)
619 T.1 = gpy_rr_bin_op (OP_ADDITION, self->x, self->y);
623 void main.init (struct main.main *self)
625 self->x = fold_int (1);
626 self->y = fold_int (2);
628 T.2 = fold_call (&main.foo, 1, self)
629 gpy_rr_print_stmt (1, T.2)
632 int main (int argc, char *argv[])
648 void gpy_stmt_write_globals (void)
650 tree main_module
= gpy_stmt_pass_1 (gpy_decls
);
651 VEC(tree
,gc
) * globals_decls_vec
= gpy_stmt_pass_2 (gpy_decls
,main_module
);
653 int idx
, idy
, global_vec_len
= VEC_length (tree
, globals_decls_vec
);
654 tree itx
= NULL_TREE
;
655 tree
* global_vec
= XNEWVEC (tree
, global_vec_len
);
656 FILE *tu_stream
= dump_begin (TDI_tu
, NULL
);
659 for (idx
= 0; VEC_iterate(tree
, globals_decls_vec
, idx
, itx
); ++idx
)
664 dump_node(itx
, 0, tu_stream
);
666 global_vec
[idy
] = itx
;
670 dump_end(TDI_tu
, tu_stream
);
672 debug("Finished processing!\n\n");
673 debug("global_vec len = <%i>!\n", global_vec_len
);
675 wrapup_global_declarations (global_vec
, global_vec_len
);
676 check_global_declarations (global_vec
, global_vec_len
);
677 emit_debug_global_declarations (global_vec
, global_vec_len
);
678 cgraph_finalize_compilation_unit ();
680 debug("finished passing to middle-end!\n\n");