starting to output the global callable table decls
[official-gcc.git] / gcc / python / py-stmt.c
blob7328c5ca9fec1bc05ac2b49cc3fd1a8606036f55
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 gpy_symbol_obj * gpy_process_AST_Align( gpy_symbol_obj ** );
54 static VEC( gpy_sym,gc ) * gpy_decls;
55 VEC(gpy_ctx_t,gc) * gpy_ctx_table;
56 VEC(tree,gc) * global_decls;
57 VEC(tree,gc) * gpy_toplev_fncs;
59 void gpy_process_decl( gpy_symbol_obj * sym )
61 /* Push the declaration! */
62 VEC_safe_push( gpy_sym, gc, gpy_decls, sym );
63 debug("decl <%p> was pushed!\n", (void*)sym );
66 /**
67 * Fairly Confusing Function to read.
69 * example:
70 * >>> x = y = z = 2 + 2 + 2;
72 * --- Currently Yacc parses that expression into this Tree:
75 / \
76 + 2
79 / \
80 x =
81 / \
82 y =
83 / \
84 z 2
86 -- Is converted into the procedure:
88 1. z = 2 + 2 + 2;
89 2. y = z;
90 3. x = y;
92 -- Tree structure as so:
95 / \
96 x =
97 / \
98 y =
99 / \
106 static
107 gpy_symbol_obj * gpy_process_AST_Align( gpy_symbol_obj ** sym )
109 gpy_symbol_obj *nn = NULL;
110 gpy_symbol_obj *retval = NULL;
111 if( (*sym)->next )
113 nn = (*sym)->next;
114 (*sym)->next = NULL;
116 retval = (*sym);
118 if( (*sym)->exp == OP_EXPRESS )
120 debug("Processing Expression AST!\n");
121 if( retval->type != OP_ASSIGN_EVAL )
123 gpy_symbol_obj *o= retval;
124 gpy_symbol_obj *h= NULL;
125 while( o )
127 if( o->op_a_t == TYPE_SYMBOL )
129 if( o->op_a.symbol_table->type == OP_ASSIGN_EVAL )
131 h = o;
132 break;
134 else
136 o = o->op_a.symbol_table;
139 else break;
141 if( h )
143 gpy_symbol_obj *head = h->op_a.symbol_table;
144 if( head->op_b.symbol_table->type == OP_ASSIGN_EVAL )
146 gpy_symbol_obj *t = head, *m = NULL;
147 while( t )
149 if( t->op_b_t == TYPE_SYMBOL )
151 if( t->op_b.symbol_table->type != OP_ASSIGN_EVAL )
153 m = t;
154 break;
156 else
158 t = t->op_b.symbol_table;
161 else break;
163 if( m )
165 h->op_a.symbol_table = m->op_b.symbol_table;
166 m->op_b.symbol_table = retval;
168 else
170 fatal_error("error processing the expression AST!\n");
173 else
175 h->op_a.symbol_table = head->op_b.symbol_table;
176 head->op_b.symbol_table = retval;
178 retval = head;
183 if( nn )
185 retval->next = nn;
187 (*sym) = retval;
189 return retval;
192 VEC(tree,gc) * gpy_process_expression( const gpy_symbol_obj * const sym,
193 VEC(gpy_ctx_t,gc) * context )
195 VEC(tree,gc) * retval = NULL;
196 if( sym->type == SYMBOL_PRIMARY )
198 retval = VEC_alloc(tree,gc,0);
199 VEC(tree,gc) *primitive = gpy_fold_primitive( sym );
200 gcc_assert( VEC_length(tree,primitive) == 1 );
201 VEC_safe_push( tree,gc,retval,VEC_index(tree,primitive,0) );
203 else if( sym->type == SYMBOL_REFERENCE )
205 gcc_assert( sym->op_a_t == TYPE_STRING );
206 tree decl = gpy_ctx_lookup_decl( context, sym->op_a.string, VAR );
207 if( decl )
209 retval = VEC_alloc(tree,gc,0);
210 debug("tree reference <%s>!\n", sym->op_a.string);
211 VEC_safe_push( tree,gc,retval,decl );
213 else
215 error("undeclared symbol reference <%s>!\n",
216 sym->op_a.string );
219 else
221 gpy_symbol_obj *opa= NULL, *opb= NULL; VEC(tree,gc) *res = NULL;
222 debug("expression evalution <0x%x>!\n", sym->type );
224 opa= sym->op_a.symbol_table;
225 opb= sym->op_b.symbol_table;
227 debug( "opa->type = <0x%x>, opb->type = <0x%x>!\n",
228 opa->type, opb->type );
230 switch( sym->type )
232 case OP_ASSIGN_EVAL:
233 res = gpy_process_assign( &opa, &opb, context );
234 break;
236 case OP_BIN_ADDITION:
237 res = gpy_process_bin_expression( &opa, &opb, sym->type, context );
238 break;
240 default:
241 fatal_error( "invalid expression evaluation symbol type <0x%x>!\n",
242 sym->type );
243 break;
245 if( res ) { retval = res; }
246 else { fatal_error("error evaluating expression!\n"); }
249 return retval;
252 VEC(tree,gc) * gpy_process_functor( const gpy_symbol_obj * const functor,
253 const char * base_ident,
254 VEC(gpy_ctx_t,gc) * context )
256 VEC(tree,gc) * retval_vec = VEC_alloc( tree,gc,0 );
258 gpy_symbol_obj * o = functor->op_a.symbol_table;
259 tree fntype = build_function_type(void_type_node, void_list_node);
260 tree retval = build_decl( UNKNOWN_LOCATION, FUNCTION_DECL,
261 get_identifier( functor->identifier ),
262 fntype );
264 tree declare_vars = NULL_TREE;
265 tree bind = NULL_TREE;
266 tree block = alloc_stmt_list( );
267 tree resdecl = NULL_TREE;
268 tree restype = TREE_TYPE(retval);
270 int idx = 0;
271 gpy_context_branch *co = NULL;
272 gpy_ident it = NULL;
274 if( base_ident )
276 size_t len = strlen( functor->identifier ) + strlen( base_ident );
277 size_t idx = 0, idy = 0;
278 char * buffer = (char *) xmalloc( (sizeof(char) * len)+2 );
279 for( ; idx<strlen( base_ident ); ++idx )
281 buffer[ idy ] = base_ident[ idx ];
282 idy++;
284 buffer[ idy ] = '.'; idy++;
285 for( idx=0; idx<strlen( functor->identifier ); ++idx )
287 buffer[ idy ] = functor->identifier[ idx ];
288 idy++;
290 buffer[idy] = '\0';
291 debug("buffer = <%s>!\n", buffer );
292 SET_DECL_ASSEMBLER_NAME( retval, get_identifier( buffer ) );
293 free( buffer );
295 else
296 SET_DECL_ASSEMBLER_NAME( retval, get_identifier(functor->identifier) );
298 TREE_PUBLIC(retval) = 1;
299 TREE_STATIC(retval) = 1;
301 resdecl = build_decl( UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE,
302 restype );
303 DECL_CONTEXT(resdecl) = retval;
304 DECL_RESULT(retval) = resdecl;
306 DECL_INITIAL(retval) = block;
308 /* push a new context for local symbols */
309 co = (gpy_context_branch *)
310 xmalloc( sizeof(gpy_context_branch) );
311 gpy_init_ctx_branch( &co );
312 VEC_safe_push( gpy_ctx_t, gc, context, co );
314 while( o )
316 /* looping over the gpy_symbol_obj block of function statements
317 and getting the respective tree's and creating the GENERIC block
319 VEC(tree,gc) * x = gpy_get_tree( o,context );
320 int itx = 0; tree xt;
321 for( ; VEC_iterate(tree,x,itx,xt); ++itx )
323 gcc_assert( xt );
324 append_to_statement_list( xt, &block );
326 o = o->next;
329 for( ; VEC_iterate( gpy_ident,co->var_decl_t, idx, it ); ++idx )
331 /* get all block var_decls */
332 tree x = gpy_ctx_lookup_decl( context, it->ident, VAR );
333 gcc_assert( TREE_CODE( x ) == VAR_DECL );
334 debug("got var decl <%p>:<%s> within func <%s>!\n", (void*)x,
335 it->ident, functor->identifier );
336 TREE_CHAIN( x ) = declare_vars;
337 declare_vars = x;
340 if( declare_vars != NULL_TREE )
342 tree bl = make_node(BLOCK);
343 BLOCK_SUPERCONTEXT(bl) = retval;
344 DECL_INITIAL(retval) = bl;
345 BLOCK_VARS(bl) = declare_vars;
346 TREE_USED(bl) = 1;
347 bind = build3(BIND_EXPR, void_type_node, BLOCK_VARS(bl),
348 NULL_TREE, bl);
349 TREE_SIDE_EFFECTS(bind) = 1;
351 BIND_EXPR_BODY(bind) = block;
352 block = bind;
353 DECL_SAVED_TREE(retval) = block;
355 VEC_pop( gpy_ctx_t, gpy_ctx_table );
357 gimplify_function_tree( retval );
359 cgraph_add_new_function(retval, false);
360 cgraph_finalize_function(retval, true);
362 VEC_safe_push( tree,gc,retval_vec,retval );
364 return retval_vec;
367 VEC(tree,gc) * gpy_process_print( gpy_symbol_obj *sym, VEC(gpy_ctx_t,gc) * context )
369 VEC(tree,gc) * retval = NULL;
370 gcc_assert( sym->op_a_t == TYPE_SYMBOL );
371 gpy_symbol_obj * argument_list = sym->op_a.symbol_table;
373 if( argument_list )
375 int len = 0;
376 gpy_symbol_obj * t = argument_list;
377 while( t )
379 len++;
380 t=t->next;
383 int idx, idy = 0; t = argument_list;
384 tree * args = XNEWVEC( tree,len );
385 for( idx=0; idx<len; ++idx )
387 VEC(tree,gc) * x = gpy_get_tree( t, context );
388 gcc_assert( VEC_length(tree,x) == 1 );
389 args[ idy ] = VEC_index(tree,x,0);
390 idy++;
391 t = t->next;
394 VEC_safe_push( tree,gc,retval,gpy_builtin_get_print_call( len, args ) );
396 else
397 error("print call without any arguments!\n");
399 return retval;
402 VEC(tree,gc) * gpy_process_class( gpy_symbol_obj * const sym,
403 VEC(gpy_ctx_t,gc) * context )
405 VEC(tree,gc) * retval = NULL;
406 return retval;
409 VEC(tree,gc) * gpy_get_tree( gpy_symbol_obj * sym, VEC(gpy_ctx_t,gc) * context )
411 VEC(tree,gc) * retval = NULL;
413 debug( "processing decl of type <0x%X> object <%p>\n",
414 sym->type, (void*) sym );
416 if( sym->exp == OP_EXPRESS )
418 sym = gpy_process_AST_Align( &sym );
419 retval = gpy_process_expression( sym, context );
421 else
423 switch( sym->type )
425 case STRUCTURE_OBJECT_DEF:
427 VEC(gpy_ctx_t,gc) * class_ctx = VEC_alloc(gpy_ctx_t,gc,0);
428 retval = gpy_process_class( sym, class_ctx );
430 break;
432 case STRUCTURE_FUNCTION_DEF:
434 VEC(gpy_ctx_t,gc) * func_ctx = VEC_alloc(gpy_ctx_t,gc,0);
435 retval = gpy_process_functor( sym, NULL, func_ctx );
437 break;
439 case KEY_PRINT:
440 retval = gpy_process_print( sym, context );
441 break;
443 default:
444 fatal_error("unhandled symbol type <0x%x>\n", sym->type );
445 break;
449 return retval;
452 tree gpy_main_method_decl( VEC(tree,gc) * block, gpy_context_branch * co )
454 tree retval = NULL_TREE; int idx;
456 tree main_fn_type = build_function_type_list( integer_type_node, NULL_TREE );
457 tree main_fn_decl = build_decl( BUILTINS_LOCATION, FUNCTION_DECL,
458 get_identifier("main"), main_fn_type );
460 DECL_CONTEXT(main_fn_decl) = NULL_TREE;
461 TREE_STATIC(main_fn_decl) = true;
462 TREE_PUBLIC(main_fn_decl) = true;
463 DECL_ARGUMENTS(main_fn_decl) = NULL_TREE;
465 /* Define the return type (represented by RESULT_DECL) for the main functin */
466 tree main_ret = build_decl( BUILTINS_LOCATION, RESULT_DECL,
467 NULL_TREE, TREE_TYPE(main_fn_type) );
468 DECL_CONTEXT(main_ret) = main_fn_decl;
469 DECL_ARTIFICIAL(main_ret) = true;
470 DECL_IGNORED_P(main_ret) = true;
472 DECL_RESULT(main_fn_decl) = main_ret;
474 tree main_art_block = build_block(NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
475 DECL_INITIAL(main_fn_decl) = main_art_block;
477 tree declare_vars = NULL_TREE;
478 tree main_stmts = alloc_stmt_list( );
480 append_to_statement_list( gpy_builtin_get_init_call( ), &main_stmts );
482 tree it = NULL_TREE;
483 for( idx = 0; VEC_iterate(tree,block,idx,it); ++idx )
485 gcc_assert( it );
486 append_to_statement_list( it, &main_stmts );
489 int block_decl_len = 0; gpy_ident vit = NULL;
490 for( idx = 0; VEC_iterate( gpy_ident,co->var_decl_t, idx, vit ); ++idx )
492 /* get all block var_decls */
493 tree x = gpy_ctx_lookup_decl( gpy_ctx_table, vit->ident, VAR );
494 gcc_assert( TREE_CODE( x ) == VAR_DECL );
495 debug("got var decl <%p>:<%s> within func <%s>!\n", (void*)x,
496 vit->ident, "main" );
497 TREE_CHAIN( x ) = declare_vars;
498 declare_vars = x;
499 block_decl_len++;
502 if( block_decl_len > 0 )
504 tree * block_decl_vec = XNEWVEC( tree, block_decl_len );
505 int idy = 0;
507 for( idx = 0; VEC_iterate( gpy_ident,co->var_decl_t, idx, vit ); ++idx )
509 tree x = gpy_ctx_lookup_decl( gpy_ctx_table, vit->ident, VAR );
510 gcc_assert( TREE_CODE( x ) == VAR_DECL );
512 block_decl_vec[ idy ] = x;
513 idy++;
515 //block_decl_vec[ idy ] = main_ret; idy++;
516 append_to_statement_list( gpy_builtin_get_finalize_block_call( block_decl_len,
517 block_decl_vec ),
518 &main_stmts );
520 else
522 declare_vars = main_ret;
525 append_to_statement_list( gpy_builtin_get_cleanup_final_call( ), &main_stmts );
527 tree main_set_ret = build2( MODIFY_EXPR, TREE_TYPE(main_ret),
528 main_ret, build_int_cst(integer_type_node, 0));
529 tree main_ret_expr = build1( RETURN_EXPR, void_type_node, main_set_ret );
530 append_to_statement_list( main_ret_expr, &main_stmts );
532 tree bind = NULL_TREE;
533 if( declare_vars != NULL_TREE )
535 tree bl = make_node(BLOCK);
536 BLOCK_SUPERCONTEXT(bl) = main_fn_decl;
537 DECL_INITIAL(main_fn_decl) = bl;
538 BLOCK_VARS(bl) = declare_vars;
539 TREE_USED(bl) = 1;
540 bind = build3( BIND_EXPR, void_type_node, BLOCK_VARS(bl),
541 NULL_TREE, bl );
542 TREE_SIDE_EFFECTS(bind) = 1;
544 BIND_EXPR_BODY(bind) = main_stmts;
545 main_stmts = bind;
546 DECL_SAVED_TREE(main_fn_decl) = main_stmts;
548 gimplify_function_tree( main_fn_decl );
549 cgraph_finalize_function( main_fn_decl, false );
551 retval = main_fn_decl;
553 return retval;
556 void gpy_write_globals( void )
558 gpy_context_branch *co = NULL;
559 gpy_symbol_obj * it = NULL;
560 VEC(tree,gc) * main_stmts_vec = VEC_alloc(tree,gc,0);
562 /* push a new context for local symbols */
563 co = (gpy_context_branch *)
564 xmalloc( sizeof(gpy_context_branch) );
565 gpy_init_ctx_branch( &co );
566 VEC_safe_push( gpy_ctx_t, gc, gpy_ctx_table, co );
568 int idx;
569 for( idx= 0; VEC_iterate(gpy_sym,gpy_decls,idx,it); ++idx )
571 VEC(tree,gc) * x = gpy_get_tree( it, gpy_ctx_table );
572 gcc_assert( x ); int itx = 0; tree xt;
573 for( ; VEC_iterate(tree,x,itx,xt); ++itx )
575 if( TREE_CODE(xt) == FUNCTION_DECL )
577 VEC_safe_push( tree,gc,global_decls,xt );
579 else if( TREE_CODE(xt) == VAR_DECL )
581 VEC_safe_push( tree,gc,global_decls,xt );
583 else
585 VEC_safe_push( tree,gc,main_stmts_vec,xt );
590 /* Need to generate table of gpy_callable_def_t[] and gpy_type_obj_def_t[] */
591 int table_len = 1;
593 VEC(constructor_elt,gc) *array_data = NULL;
595 CONSTRUCTOR_APPEND_ELT( array_data, NULL_TREE,
596 gpy_init_callable_record("NULL", 0, false, NULL_TREE) );
598 tree array_type = build_array_type( gpy_get_callable_record_type(),
599 build_index_type( build_int_cst(integer_type_node,table_len) ));
601 tree array = build_constructor(array_type, array_data);
602 tree table_decl = build_decl(BUILTINS_LOCATION,VAR_DECL,
603 get_identifier("__gpy_module_main_callables"),
604 array_type);
606 DECL_ARTIFICIAL (table_decl) = 1;
607 TREE_STATIC (table_decl) = 1;
608 TREE_PUBLIC (table_decl) = 1;
609 TREE_USED (table_decl) = 1;
610 // DECL_INITIAL (table_decl) = array;
612 tree test = build_decl( UNKNOWN_LOCATION, VAR_DECL,
613 get_identifier("test"),
614 integer_type_node);
616 DECL_ARTIFICIAL (test) = 1;
617 TREE_STATIC (test) = 1;
618 TREE_PUBLIC(test) = 1;
619 TREE_USED (test) = 1;
620 DECL_INITIAL (test) = build_int_cst(integer_type_node, 12345 );
622 rest_of_decl_compilation (test, 1, 0);
623 rest_of_decl_compilation (table_decl, 1, 0);
625 /* Add in the main method decl! */
626 VEC_safe_push( tree,gc,global_decls,gpy_main_method_decl( main_stmts_vec,co ) );
628 VEC_safe_push( tree,gc,global_decls,table_decl );
629 VEC_safe_push( tree,gc,global_decls,test );
631 debug_tree( table_decl );
633 VEC_pop( gpy_ctx_t, gpy_ctx_table );
635 tree itx = NULL_TREE; int idy = 0;
636 int global_vec_len = VEC_length(tree, global_decls);
637 tree * global_vec = XNEWVEC( tree, global_vec_len );
639 FILE *tu_stream = dump_begin (TDI_tu, NULL);
640 for( idx=0; VEC_iterate(tree,global_decls,idx,itx); ++idx )
642 if (tu_stream)
643 dump_node(itx, 0, tu_stream);
645 global_vec[ idy ] = itx;
646 idy++;
648 if (tu_stream)
649 dump_end(TDI_tu, tu_stream);
651 debug("Finished processing!\n\n");
653 wrapup_global_declarations( global_vec, global_vec_len );
655 check_global_declarations( global_vec, global_vec_len );
656 emit_debug_global_declarations( global_vec, global_vec_len );
658 cgraph_finalize_compilation_unit( );
660 debug("finished passing to middle-end!\n\n");