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
,
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
;
377 gpy_symbol_obj
* t
= argument_list
;
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);
395 VEC_safe_push( tree
,gc
,retval
,gpy_builtin_get_print_call( len
, args
) );
398 error("print call without any arguments!\n");
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
;
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
);
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
);
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
);
442 retval
= gpy_process_print( sym
, context
);
446 fatal_error("unhandled symbol type <0x%x>\n", sym
->type
);
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
);
485 for( idx
= 0; VEC_iterate(tree
,block
,idx
,it
); ++idx
)
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
;
504 if( block_decl_len
> 0 )
506 tree
* block_decl_vec
= XNEWVEC( tree
, block_decl_len
);
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
;
517 //block_decl_vec[ idy ] = main_ret; idy++;
518 append_to_statement_list( gpy_builtin_get_finalize_block_call( block_decl_len
,
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
;
542 bind
= build3( BIND_EXPR
, void_type_node
, BLOCK_VARS(bl
),
544 TREE_SIDE_EFFECTS(bind
) = 1;
546 BIND_EXPR_BODY(bind
) = main_stmts
;
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
;
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
);
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
);
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
)
602 dump_node(itx
, 0, tu_stream
);
604 global_vec
[ idy
] = itx
;
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");