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 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
);
67 * Fairly Confusing Function to read.
70 * >>> x = y = z = 2 + 2 + 2;
72 * --- Currently Yacc parses that expression into this Tree:
86 -- Is converted into the procedure:
92 -- Tree structure as so:
107 gpy_symbol_obj
* gpy_process_AST_Align( gpy_symbol_obj
** sym
)
109 gpy_symbol_obj
*nn
= NULL
;
110 gpy_symbol_obj
*retval
= NULL
;
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
;
127 if( o
->op_a_t
== TYPE_SYMBOL
)
129 if( o
->op_a
.symbol_table
->type
== OP_ASSIGN_EVAL
)
136 o
= o
->op_a
.symbol_table
;
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
;
149 if( t
->op_b_t
== TYPE_SYMBOL
)
151 if( t
->op_b
.symbol_table
->type
!= OP_ASSIGN_EVAL
)
158 t
= t
->op_b
.symbol_table
;
165 h
->op_a
.symbol_table
= m
->op_b
.symbol_table
;
166 m
->op_b
.symbol_table
= retval
;
170 fatal_error("error processing the expression AST!\n");
175 h
->op_a
.symbol_table
= head
->op_b
.symbol_table
;
176 head
->op_b
.symbol_table
= 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
);
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
);
215 error("undeclared symbol reference <%s>!\n",
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
);
233 res
= gpy_process_assign( &opa
, &opb
, context
);
236 case OP_BIN_ADDITION
:
237 res
= gpy_process_bin_expression( &opa
, &opb
, sym
->type
, context
);
241 fatal_error( "invalid expression evaluation symbol type <0x%x>!\n",
245 if( res
) { retval
= res
; }
246 else { fatal_error("error evaluating expression!\n"); }
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
),
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
);
271 gpy_context_branch
*co
= NULL
;
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
];
284 buffer
[ idy
] = '.'; idy
++;
285 for( idx
=0; idx
<strlen( functor
->identifier
); ++idx
)
287 buffer
[ idy
] = functor
->identifier
[ idx
];
291 debug("buffer = <%s>!\n", buffer
);
292 SET_DECL_ASSEMBLER_NAME( retval
, get_identifier( buffer
) );
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
,
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
);
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
)
324 append_to_statement_list( xt
, &block
);
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
;
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
;
347 bind
= build3(BIND_EXPR
, void_type_node
, BLOCK_VARS(bl
),
349 TREE_SIDE_EFFECTS(bind
) = 1;
351 BIND_EXPR_BODY(bind
) = block
;
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
);
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
;
376 gpy_symbol_obj
* t
= argument_list
;
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);
394 VEC_safe_push( tree
,gc
,retval
,gpy_builtin_get_print_call( len
, args
) );
397 error("print call without any arguments!\n");
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
;
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
);
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
);
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
);
440 retval
= gpy_process_print( sym
, context
);
444 fatal_error("unhandled symbol type <0x%x>\n", sym
->type
);
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
);
483 for( idx
= 0; VEC_iterate(tree
,block
,idx
,it
); ++idx
)
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
;
502 if( block_decl_len
> 0 )
504 tree
* block_decl_vec
= XNEWVEC( tree
, block_decl_len
);
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
;
515 //block_decl_vec[ idy ] = main_ret; idy++;
516 append_to_statement_list( gpy_builtin_get_finalize_block_call( block_decl_len
,
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
;
540 bind
= build3( BIND_EXPR
, void_type_node
, BLOCK_VARS(bl
),
542 TREE_SIDE_EFFECTS(bind
) = 1;
544 BIND_EXPR_BODY(bind
) = main_stmts
;
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
;
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
);
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
);
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[] */
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"),
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"),
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
)
643 dump_node(itx
, 0, tu_stream
);
645 global_vec
[ idy
] = itx
;
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");