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
= 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
);
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
);
212 error("undeclared symbol reference <%s>!\n",
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
);
223 //gcc_assert (TREE_TYPE(decl) == FUNCTION_DECL);
224 //retval = gpy_fold_call (decl);
227 error ("undefined symbol name <%s>!\n", sym
->op_a
.string
);
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
);
245 res
= gpy_process_assign (&opa
, &opb
, context
);
248 case OP_BIN_ADDITION
:
249 res
= gpy_process_bin_expression (&opa
, &opb
, sym
->type
,
256 fatal_error ("invalid expression evaluation symbol type <0x%x>!\n",
260 if( res
) { retval
= res
; }
261 else { fatal_error("error evaluating expression!\n"); }
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
),
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
);
291 gpy_context_branch
*co
= NULL
;
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
];
304 buffer
[ idy
] = '.'; idy
++;
305 for (idx
=0; idx
<strlen(functor
->identifier
); ++idx
)
307 buffer
[ idy
] = functor
->identifier
[ idx
];
311 debug("buffer = <%s>!\n", buffer
);
312 SET_DECL_ASSEMBLER_NAME( retval
, get_identifier( buffer
) );
316 SET_DECL_ASSEMBLER_NAME( retval
, get_identifier(functor
->identifier
) );
318 tree check
= gpy_ctx_lookup_decl (context
, functor
->identifier
);
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
);
327 TREE_PUBLIC(retval
) = 1;
328 TREE_STATIC(retval
) = 1;
330 resdecl
= build_decl (BUILTINS_LOCATION
, RESULT_DECL
, NULL_TREE
,
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
);
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
)
353 append_to_statement_list( xt
, &block
);
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
;
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
;
376 bind
= build3(BIND_EXPR
, void_type_node
, BLOCK_VARS(bl
),
378 TREE_SIDE_EFFECTS(bind
) = 1;
380 BIND_EXPR_BODY(bind
) = block
;
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
);
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
;
411 gpy_symbol_obj
* t
= argument_list
;
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);
429 VEC_safe_push( tree
,gc
,retval
,gpy_builtin_get_print_call( len
, args
) );
432 error("print call without any arguments!\n");
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
;
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
);
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
);
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
);
476 retval
= gpy_process_print( sym
, context
);
480 fatal_error("unhandled symbol type <0x%x>\n", sym
->type
);
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
);
519 for( idx
= 0; VEC_iterate(tree
,block
,idx
,it
); ++idx
)
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
;
538 if( block_decl_len
> 0 )
540 tree
* block_decl_vec
= XNEWVEC( tree
, block_decl_len
);
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
;
551 //block_decl_vec[ idy ] = main_ret; idy++;
552 append_to_statement_list( gpy_builtin_get_finalize_block_call( block_decl_len
,
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
;
576 bind
= build3( BIND_EXPR
, void_type_node
, BLOCK_VARS(bl
),
578 TREE_SIDE_EFFECTS(bind
) = 1;
580 BIND_EXPR_BODY(bind
) = main_stmts
;
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
;
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
);
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
);
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
)
641 dump_node(itx
, 0, tu_stream
);
643 global_vec
[ idy
] = itx
;
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");