quick commit
[official-gcc.git] / gcc / python / py-stmt.c
blob52c2c851d07edb9960aaedccad2e65e2b5ff1a66
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,
368 VEC(gpy_ctx_t,gc) * context )
370 VEC(tree,gc) * retval = NULL;
371 gcc_assert( sym->op_a_t == TYPE_SYMBOL );
372 gpy_symbol_obj * argument_list = sym->op_a.symbol_table;
374 if( argument_list )
376 int len = 0;
377 gpy_symbol_obj * t = argument_list;
378 while( t )
380 len++;
381 t=t->next;
384 int idx, idy = 0; t = argument_list;
385 tree * args = XNEWVEC( tree,len );
386 for( idx=0; idx<len; ++idx )
388 VEC(tree,gc) * x = gpy_get_tree( t, context );
389 gcc_assert( VEC_length(tree,x) == 1 );
390 args[ idy ] = VEC_index(tree,x,0);
391 idy++;
392 t = t->next;
395 VEC_safe_push( tree,gc,retval,gpy_builtin_get_print_call( len, args ) );
397 else
398 error("print call without any arguments!\n");
400 return retval;
403 VEC(tree,gc) * gpy_process_class( gpy_symbol_obj * const sym,
404 VEC(gpy_ctx_t,gc) * context )
406 VEC(tree,gc) * retval = NULL;
407 return retval;
410 VEC(tree,gc) * gpy_get_tree( gpy_symbol_obj * sym,
411 VEC(gpy_ctx_t,gc) * context )
413 VEC(tree,gc) * retval = NULL;
415 debug( "processing decl of type <0x%X> object <%p>\n",
416 sym->type, (void*) sym );
418 if( sym->exp == OP_EXPRESS )
420 sym = gpy_process_AST_Align( &sym );
421 retval = gpy_process_expression( sym, context );
423 else
425 switch( sym->type )
427 case STRUCTURE_OBJECT_DEF:
429 VEC(gpy_ctx_t,gc) * class_ctx = VEC_alloc(gpy_ctx_t,gc,0);
430 retval = gpy_process_class( sym, class_ctx );
432 break;
434 case STRUCTURE_FUNCTION_DEF:
436 VEC(gpy_ctx_t,gc) * func_ctx = VEC_alloc(gpy_ctx_t,gc,0);
437 retval = gpy_process_functor( sym, NULL, func_ctx );
439 break;
441 case KEY_PRINT:
442 retval = gpy_process_print( sym, context );
443 break;
445 default:
446 fatal_error("unhandled symbol type <0x%x>\n", sym->type );
447 break;
451 return retval;
454 tree gpy_main_method_decl( VEC(tree,gc) * block, gpy_context_branch * co )
456 tree retval = NULL_TREE; int idx;
458 tree main_fn_type = build_function_type_list( integer_type_node, NULL_TREE );
459 tree main_fn_decl = build_decl( BUILTINS_LOCATION, FUNCTION_DECL,
460 get_identifier("main"), main_fn_type );
462 DECL_CONTEXT(main_fn_decl) = NULL_TREE;
463 TREE_STATIC(main_fn_decl) = true;
464 TREE_PUBLIC(main_fn_decl) = true;
465 DECL_ARGUMENTS(main_fn_decl) = NULL_TREE;
467 /* Define the return type (represented by RESULT_DECL) for the main functin */
468 tree main_ret = build_decl( BUILTINS_LOCATION, RESULT_DECL,
469 NULL_TREE, TREE_TYPE(main_fn_type) );
470 DECL_CONTEXT(main_ret) = main_fn_decl;
471 DECL_ARTIFICIAL(main_ret) = true;
472 DECL_IGNORED_P(main_ret) = true;
474 DECL_RESULT(main_fn_decl) = main_ret;
476 tree main_art_block = build_block(NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
477 DECL_INITIAL(main_fn_decl) = main_art_block;
479 tree declare_vars = NULL_TREE;
480 tree main_stmts = alloc_stmt_list( );
482 append_to_statement_list( gpy_builtin_get_init_call( ), &main_stmts );
484 tree it = NULL_TREE;
485 for( idx = 0; VEC_iterate(tree,block,idx,it); ++idx )
487 gcc_assert( it );
488 append_to_statement_list( it, &main_stmts );
491 int block_decl_len = 0; gpy_ident vit = NULL;
492 for( idx = 0; VEC_iterate( gpy_ident,co->var_decl_t, idx, vit ); ++idx )
494 /* get all block var_decls */
495 tree x = gpy_ctx_lookup_decl( gpy_ctx_table, vit->ident, VAR );
496 gcc_assert( TREE_CODE( x ) == VAR_DECL );
497 debug("got var decl <%p>:<%s> within func <%s>!\n", (void*)x,
498 vit->ident, "main" );
499 TREE_CHAIN( x ) = declare_vars;
500 declare_vars = x;
501 block_decl_len++;
504 if( block_decl_len > 0 )
506 tree * block_decl_vec = XNEWVEC( tree, block_decl_len );
507 int idy = 0;
509 for( idx = 0; VEC_iterate( gpy_ident,co->var_decl_t, idx, vit ); ++idx )
511 tree x = gpy_ctx_lookup_decl( gpy_ctx_table, vit->ident, VAR );
512 gcc_assert( TREE_CODE( x ) == VAR_DECL );
514 block_decl_vec[ idy ] = x;
515 idy++;
517 //block_decl_vec[ idy ] = main_ret; idy++;
518 append_to_statement_list( gpy_builtin_get_finalize_block_call( block_decl_len,
519 block_decl_vec ),
520 &main_stmts );
522 else
524 declare_vars = main_ret;
527 append_to_statement_list( gpy_builtin_get_cleanup_final_call( ), &main_stmts );
529 tree main_set_ret = build2( MODIFY_EXPR, TREE_TYPE(main_ret),
530 main_ret, build_int_cst(integer_type_node, 0));
531 tree main_ret_expr = build1( RETURN_EXPR, void_type_node, main_set_ret );
532 append_to_statement_list( main_ret_expr, &main_stmts );
534 tree bind = NULL_TREE;
535 if( declare_vars != NULL_TREE )
537 tree bl = make_node(BLOCK);
538 BLOCK_SUPERCONTEXT(bl) = main_fn_decl;
539 DECL_INITIAL(main_fn_decl) = bl;
540 BLOCK_VARS(bl) = declare_vars;
541 TREE_USED(bl) = 1;
542 bind = build3( BIND_EXPR, void_type_node, BLOCK_VARS(bl),
543 NULL_TREE, bl );
544 TREE_SIDE_EFFECTS(bind) = 1;
546 BIND_EXPR_BODY(bind) = main_stmts;
547 main_stmts = bind;
548 DECL_SAVED_TREE(main_fn_decl) = main_stmts;
550 gimplify_function_tree( main_fn_decl );
551 cgraph_finalize_function( main_fn_decl, false );
553 retval = main_fn_decl;
555 return retval;
558 void gpy_write_globals (void)
560 gpy_context_branch *co = NULL;
561 gpy_symbol_obj * it = NULL;
562 VEC(tree,gc) * main_stmts_vec = VEC_alloc(tree,gc,0);
564 /* push a new context for local symbols */
565 co = (gpy_context_branch *)
566 xmalloc( sizeof(gpy_context_branch) );
567 gpy_init_ctx_branch( &co );
568 VEC_safe_push( gpy_ctx_t, gc, gpy_ctx_table, co );
570 int idx;
571 for( idx= 0; VEC_iterate(gpy_sym,gpy_decls,idx,it); ++idx )
573 VEC(tree,gc) * x = gpy_get_tree( it, gpy_ctx_table );
574 gcc_assert( x ); int itx = 0; tree xt;
575 for( ; VEC_iterate(tree,x,itx,xt); ++itx )
577 if( TREE_CODE(xt) == FUNCTION_DECL )
579 VEC_safe_push (tree,gc,global_decls,xt);
581 else if( TREE_CODE(xt) == VAR_DECL )
583 VEC_safe_push (tree,gc,global_decls,xt);
585 else
587 VEC_safe_push (tree,gc,main_stmts_vec,xt);
592 VEC_pop( gpy_ctx_t, gpy_ctx_table );
594 tree itx = NULL_TREE; int idy = 0;
595 int global_vec_len = VEC_length(tree, global_decls);
596 tree * global_vec = XNEWVEC( tree, global_vec_len );
598 FILE *tu_stream = dump_begin (TDI_tu, NULL);
599 for( idx=0; VEC_iterate(tree,global_decls,idx,itx); ++idx )
601 if (tu_stream)
602 dump_node(itx, 0, tu_stream);
604 global_vec[ idy ] = itx;
605 idy++;
607 if (tu_stream)
608 dump_end(TDI_tu, tu_stream);
610 debug("Finished processing!\n\n");
612 wrapup_global_declarations( global_vec, global_vec_len );
614 check_global_declarations( global_vec, global_vec_len );
615 emit_debug_global_declarations( global_vec, global_vec_len );
617 cgraph_finalize_compilation_unit( );
619 debug("finished passing to middle-end!\n\n");