some function decl stuff
[official-gcc.git] / gcc / python / py-stmt.c
blob4afe967b1d6ab9342883f48ecad12f61a7ffebc5
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 = gpy_fold_primitive (sym);
200 else if( sym->type == SYMBOL_REFERENCE )
202 gcc_assert( sym->op_a_t == TYPE_STRING );
203 tree decl = gpy_ctx_lookup_decl (context, sym->op_a.string);
204 if( decl )
206 retval = VEC_alloc(tree,gc,0);
207 debug("tree reference <%s>!\n", sym->op_a.string);
208 VEC_safe_push (tree,gc,retval,decl);
210 else
212 error("undeclared symbol reference <%s>!\n",
213 sym->op_a.string );
216 else if (sym->type == OP_CALL_GOTO)
218 gcc_assert (sym->op_a.string);
219 tree decl = gpy_ctx_lookup_decl (context, sym->op_a.string);
221 if (decl)
223 //gcc_assert (TREE_TYPE(decl) == FUNCTION_DECL);
224 //retval = gpy_fold_call (decl);
226 else
227 error ("undefined symbol name <%s>!\n", sym->op_a.string);
229 else
231 gpy_symbol_obj *opa = NULL, *opb = NULL;
232 VEC(tree,gc) *res = NULL;
234 debug ("expression evalution <0x%x>!\n", sym->type);
236 opa = sym->op_a.symbol_table;
237 opb = sym->op_b.symbol_table;
239 debug ("opa->type = <0x%x>, opb->type = <0x%x>!\n",
240 opa->type, opb->type);
242 switch (sym->type)
244 case OP_ASSIGN_EVAL:
245 res = gpy_process_assign (&opa, &opb, context);
246 break;
248 case OP_BIN_ADDITION:
249 res = gpy_process_bin_expression (&opa, &opb, sym->type,
250 context);
251 break;
253 /* .......... */
255 default:
256 fatal_error ("invalid expression evaluation symbol type <0x%x>!\n",
257 sym->type);
258 break;
260 if( res ) { retval = res; }
261 else { fatal_error("error evaluating expression!\n"); }
264 return retval;
267 VEC(tree,gc) * gpy_process_functor (const gpy_symbol_obj * const functor,
268 const char * base_ident,
269 VEC(gpy_ctx_t,gc) * context)
271 VEC(tree,gc) * retval_vec = VEC_alloc (tree,gc,0);
273 tree params = NULL_TREE;
275 chainon( params, tree_cons (NULL_TREE, gpy_object_type_ptr_ptr, NULL_TREE) );
276 chainon( params, tree_cons (NULL_TREE, void_type_node, NULL_TREE) );
278 gpy_symbol_obj * o = functor->op_a.symbol_table;
279 tree fntype = build_function_type(void_type_node, void_list_node);
280 tree retval = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
281 get_identifier( functor->identifier ),
282 fntype);
284 tree declare_vars = NULL_TREE;
285 tree bind = NULL_TREE;
286 tree block = alloc_stmt_list ();
287 tree resdecl = NULL_TREE;
288 tree restype = TREE_TYPE (retval);
290 int idx = 0;
291 gpy_context_branch *co = NULL;
292 gpy_ident it = NULL;
294 if (base_ident)
296 size_t len = strlen (functor->identifier) + strlen( base_ident );
297 size_t idx = 0, idy = 0;
298 char * buffer = (char *) xmalloc( (sizeof(char) * len)+2 );
299 for( ; idx<strlen( base_ident ); ++idx )
301 buffer[ idy ] = base_ident[ idx ];
302 idy++;
304 buffer[ idy ] = '.'; idy++;
305 for (idx=0; idx<strlen(functor->identifier); ++idx)
307 buffer[ idy ] = functor->identifier[ idx ];
308 idy++;
310 buffer[idy] = '\0';
311 debug("buffer = <%s>!\n", buffer );
312 SET_DECL_ASSEMBLER_NAME( retval, get_identifier( buffer ) );
313 free( buffer );
315 else
316 SET_DECL_ASSEMBLER_NAME( retval, get_identifier(functor->identifier) );
318 tree check = gpy_ctx_lookup_decl (context, functor->identifier);
319 if (check)
321 error("name <%s> is already defined, dynamic re-defintion not implemented yet!\n",
322 functor->identifier);
323 VEC_safe_push (tree,gc,retval_vec,error_mark_node);
325 else
327 TREE_PUBLIC(retval) = 1;
328 TREE_STATIC(retval) = 1;
330 resdecl = build_decl (BUILTINS_LOCATION, RESULT_DECL, NULL_TREE,
331 restype);
332 DECL_CONTEXT(resdecl) = retval;
333 DECL_RESULT(retval) = resdecl;
335 DECL_INITIAL(retval) = block;
337 /* push a new context for local symbols */
338 co = (gpy_context_branch *)
339 xmalloc( sizeof(gpy_context_branch) );
340 gpy_init_ctx_branch( &co );
341 VEC_safe_push( gpy_ctx_t, gc, context, co );
343 while( o )
345 /* looping over the gpy_symbol_obj block of function statements
346 and getting the respective tree's and creating the GENERIC block
348 VEC(tree,gc) * x = gpy_get_tree( o,context );
349 int itx = 0; tree xt;
350 for( ; VEC_iterate(tree,x,itx,xt); ++itx )
352 gcc_assert( xt );
353 append_to_statement_list( xt, &block );
355 o = o->next;
358 for( ; VEC_iterate( gpy_ident,co->decl_t, idx, it ); ++idx )
360 /* get all block var_decls */
361 tree x = gpy_ctx_lookup_decl( context, it->ident);
362 gcc_assert( TREE_CODE( x ) == VAR_DECL );
363 debug("got var decl <%p>:<%s> within func <%s>!\n", (void*)x,
364 it->ident, functor->identifier );
365 TREE_CHAIN( x ) = declare_vars;
366 declare_vars = x;
369 if( declare_vars != NULL_TREE )
371 tree bl = make_node(BLOCK);
372 BLOCK_SUPERCONTEXT(bl) = retval;
373 DECL_INITIAL(retval) = bl;
374 BLOCK_VARS(bl) = declare_vars;
375 TREE_USED(bl) = 1;
376 bind = build3(BIND_EXPR, void_type_node, BLOCK_VARS(bl),
377 NULL_TREE, bl);
378 TREE_SIDE_EFFECTS(bind) = 1;
380 BIND_EXPR_BODY(bind) = block;
381 block = bind;
382 DECL_SAVED_TREE(retval) = block;
384 VEC_pop (gpy_ctx_t, gpy_ctx_table);
386 gimplify_function_tree (retval);
388 cgraph_add_new_function (retval, false);
389 cgraph_finalize_function (retval, true);
391 VEC_safe_push( tree,gc,retval_vec,retval );
393 gpy_ctx_t x = VEC_index (gpy_ctx_t, context, 0);
394 if (!gpy_ctx_push_decl (retval, functor->identifier, x))
395 fatal_error("error pushing decl <%s>!\n", functor->identifier );
398 return retval_vec;
401 VEC(tree,gc) * gpy_process_print (gpy_symbol_obj *sym,
402 VEC(gpy_ctx_t,gc) * context)
404 VEC(tree,gc) * retval = NULL;
405 gcc_assert( sym->op_a_t == TYPE_SYMBOL );
406 gpy_symbol_obj * argument_list = sym->op_a.symbol_table;
408 if( argument_list )
410 int len = 0;
411 gpy_symbol_obj * t = argument_list;
412 while( t )
414 len++;
415 t=t->next;
418 int idx, idy = 0; t = argument_list;
419 tree * args = XNEWVEC( tree,len );
420 for( idx=0; idx<len; ++idx )
422 VEC(tree,gc) * x = gpy_get_tree( t, context );
423 gcc_assert( VEC_length(tree,x) == 1 );
424 args[ idy ] = VEC_index(tree,x,0);
425 idy++;
426 t = t->next;
429 VEC_safe_push( tree,gc,retval,gpy_builtin_get_print_call( len, args ) );
431 else
432 error("print call without any arguments!\n");
434 return retval;
437 VEC(tree,gc) * gpy_process_class( gpy_symbol_obj * const sym,
438 VEC(gpy_ctx_t,gc) * context )
440 VEC(tree,gc) * retval = NULL;
441 return retval;
444 VEC(tree,gc) * gpy_get_tree( gpy_symbol_obj * sym,
445 VEC(gpy_ctx_t,gc) * context )
447 VEC(tree,gc) * retval = NULL;
449 debug( "processing decl of type <0x%X> object <%p>\n",
450 sym->type, (void*) sym );
452 if( sym->exp == OP_EXPRESS )
454 sym = gpy_process_AST_Align( &sym );
455 retval = gpy_process_expression( sym, context );
457 else
459 switch( sym->type )
461 case STRUCTURE_OBJECT_DEF:
463 VEC(gpy_ctx_t,gc) * class_ctx = VEC_alloc(gpy_ctx_t,gc,0);
464 retval = gpy_process_class( sym, class_ctx );
466 break;
468 case STRUCTURE_FUNCTION_DEF:
470 VEC(gpy_ctx_t,gc) * func_ctx = VEC_alloc(gpy_ctx_t,gc,0);
471 retval = gpy_process_functor( sym, NULL, func_ctx );
473 break;
475 case KEY_PRINT:
476 retval = gpy_process_print( sym, context );
477 break;
479 default:
480 fatal_error("unhandled symbol type <0x%x>\n", sym->type );
481 break;
485 return retval;
488 tree gpy_main_method_decl( VEC(tree,gc) * block, gpy_context_branch * co )
490 tree retval = NULL_TREE; int idx;
492 tree main_fn_type = build_function_type_list( integer_type_node, NULL_TREE );
493 tree main_fn_decl = build_decl( BUILTINS_LOCATION, FUNCTION_DECL,
494 get_identifier("main"), main_fn_type );
496 DECL_CONTEXT(main_fn_decl) = NULL_TREE;
497 TREE_STATIC(main_fn_decl) = true;
498 TREE_PUBLIC(main_fn_decl) = true;
499 DECL_ARGUMENTS(main_fn_decl) = NULL_TREE;
501 /* Define the return type (represented by RESULT_DECL) for the main functin */
502 tree main_ret = build_decl( BUILTINS_LOCATION, RESULT_DECL,
503 NULL_TREE, TREE_TYPE(main_fn_type) );
504 DECL_CONTEXT(main_ret) = main_fn_decl;
505 DECL_ARTIFICIAL(main_ret) = true;
506 DECL_IGNORED_P(main_ret) = true;
508 DECL_RESULT(main_fn_decl) = main_ret;
510 tree main_art_block = build_block(NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
511 DECL_INITIAL(main_fn_decl) = main_art_block;
513 tree declare_vars = NULL_TREE;
514 tree main_stmts = alloc_stmt_list( );
516 append_to_statement_list( gpy_builtin_get_init_call( ), &main_stmts );
518 tree it = NULL_TREE;
519 for( idx = 0; VEC_iterate(tree,block,idx,it); ++idx )
521 gcc_assert( it );
522 append_to_statement_list( it, &main_stmts );
525 int block_decl_len = 0; gpy_ident vit = NULL;
526 for( idx = 0; VEC_iterate( gpy_ident,co->decl_t, idx, vit ); ++idx )
528 /* get all block var_decls */
529 tree x = gpy_ctx_lookup_decl( gpy_ctx_table, vit->ident);
530 gcc_assert( TREE_CODE( x ) == VAR_DECL );
531 debug("got var decl <%p>:<%s> within func <%s>!\n", (void*)x,
532 vit->ident, "main" );
533 TREE_CHAIN( x ) = declare_vars;
534 declare_vars = x;
535 block_decl_len++;
538 if( block_decl_len > 0 )
540 tree * block_decl_vec = XNEWVEC( tree, block_decl_len );
541 int idy = 0;
543 for( idx = 0; VEC_iterate( gpy_ident,co->decl_t, idx, vit ); ++idx )
545 tree x = gpy_ctx_lookup_decl( gpy_ctx_table, vit->ident);
546 gcc_assert( TREE_CODE( x ) == VAR_DECL );
548 block_decl_vec[ idy ] = x;
549 idy++;
551 //block_decl_vec[ idy ] = main_ret; idy++;
552 append_to_statement_list( gpy_builtin_get_finalize_block_call( block_decl_len,
553 block_decl_vec ),
554 &main_stmts );
556 else
558 declare_vars = main_ret;
561 append_to_statement_list( gpy_builtin_get_cleanup_final_call( ), &main_stmts );
563 tree main_set_ret = build2( MODIFY_EXPR, TREE_TYPE(main_ret),
564 main_ret, build_int_cst(integer_type_node, 0));
565 tree main_ret_expr = build1( RETURN_EXPR, void_type_node, main_set_ret );
566 append_to_statement_list( main_ret_expr, &main_stmts );
568 tree bind = NULL_TREE;
569 if( declare_vars != NULL_TREE )
571 tree bl = make_node(BLOCK);
572 BLOCK_SUPERCONTEXT(bl) = main_fn_decl;
573 DECL_INITIAL(main_fn_decl) = bl;
574 BLOCK_VARS(bl) = declare_vars;
575 TREE_USED(bl) = 1;
576 bind = build3( BIND_EXPR, void_type_node, BLOCK_VARS(bl),
577 NULL_TREE, bl );
578 TREE_SIDE_EFFECTS(bind) = 1;
580 BIND_EXPR_BODY(bind) = main_stmts;
581 main_stmts = bind;
582 DECL_SAVED_TREE(main_fn_decl) = main_stmts;
584 gimplify_function_tree( main_fn_decl );
585 cgraph_finalize_function( main_fn_decl, false );
587 retval = main_fn_decl;
589 return retval;
592 void gpy_write_globals (void)
594 gpy_context_branch *co = NULL;
595 gpy_symbol_obj * it = NULL;
596 VEC(tree,gc) * main_stmts_vec = VEC_alloc(tree,gc,0);
598 /* push a new context for local symbols */
599 co = (gpy_context_branch *)
600 xmalloc( sizeof(gpy_context_branch) );
601 gpy_init_ctx_branch( &co );
602 VEC_safe_push( gpy_ctx_t, gc, gpy_ctx_table, co );
604 int idx;
605 for( idx= 0; VEC_iterate(gpy_sym,gpy_decls,idx,it); ++idx )
607 VEC(tree,gc) * x = gpy_get_tree( it, gpy_ctx_table );
608 gcc_assert( x ); int itx = 0; tree xt;
609 for( ; VEC_iterate(tree,x,itx,xt); ++itx )
611 if( TREE_CODE(xt) == FUNCTION_DECL )
613 VEC_safe_push (tree,gc,global_decls,xt);
615 else if( TREE_CODE(xt) == VAR_DECL )
617 VEC_safe_push (tree,gc,global_decls,xt);
619 else
621 VEC_safe_push (tree,gc,main_stmts_vec,xt);
626 /* Add in the main method decl! */
627 VEC_safe_push( tree,gc,global_decls,gpy_main_method_decl( main_stmts_vec,co ) );
629 VEC_pop( gpy_ctx_t, gpy_ctx_table );
631 tree itx = NULL_TREE; int idy = 0;
632 int global_vec_len = VEC_length (tree, global_decls);
633 tree * global_vec = XNEWVEC (tree, global_vec_len);
635 FILE *tu_stream = dump_begin (TDI_tu, NULL);
636 for( idx=0; VEC_iterate(tree,global_decls,idx,itx); ++idx )
638 debug_tree (itx);
640 if (tu_stream)
641 dump_node(itx, 0, tu_stream);
643 global_vec[ idy ] = itx;
644 idy++;
646 if (tu_stream)
647 dump_end(TDI_tu, tu_stream);
649 debug("Finished processing!\n\n");
651 debug("global_vec len = <%i>!\n", global_vec_len);
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");