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"
23 #include "tree-iterator.h"
30 #include "diagnostic-core.h"
31 #include "langhooks.h"
32 #include "langhooks-def.h"
43 #include "opcodes.def"
45 #include "pypy-tree.h"
48 static VEC( gpy_sym
,gc
) * gpy_decls
;
49 VEC(gpy_ctx_t
,gc
) * gpy_ctx_table
;
50 VEC(tree
,gc
) * global_decls
;
52 void gpy_process_decl( gpy_symbol_obj
* sym
)
54 /* Push the declaration! */
55 VEC_safe_push( gpy_sym
, gc
, gpy_decls
, sym
);
56 debug("decl <%p> was pushed!\n", (void*)sym
);
60 * Fairly Confusing Function to read.
63 * >>> x = y = z = 2 + 2 + 2;
65 * --- Currently Yacc parses that expression into this Tree:
79 -- Is converted into the procedure:
85 -- Tree structure as so:
100 gpy_symbol_obj
* gpy_process_AST_Align( gpy_symbol_obj
** sym
)
102 gpy_symbol_obj
*nn
= NULL
;
103 gpy_symbol_obj
*retval
= NULL
;
111 if( (*sym
)->exp
== OP_EXPRESS
)
113 debug("Processing Expression AST!\n");
114 if( retval
->type
!= OP_ASSIGN_EVAL
)
116 gpy_symbol_obj
*o
= retval
;
117 gpy_symbol_obj
*h
= NULL
;
120 if( o
->op_a_t
== TYPE_SYMBOL
)
122 if( o
->op_a
.symbol_table
->type
== OP_ASSIGN_EVAL
)
129 o
= o
->op_a
.symbol_table
;
136 gpy_symbol_obj
*head
= h
->op_a
.symbol_table
;
137 if( head
->op_b
.symbol_table
->type
== OP_ASSIGN_EVAL
)
139 gpy_symbol_obj
*t
= head
, *m
= NULL
;
142 if( t
->op_b_t
== TYPE_SYMBOL
)
144 if( t
->op_b
.symbol_table
->type
!= OP_ASSIGN_EVAL
)
151 t
= t
->op_b
.symbol_table
;
158 h
->op_a
.symbol_table
= m
->op_b
.symbol_table
;
159 m
->op_b
.symbol_table
= retval
;
163 fatal_error("error processing the expression AST!\n");
168 h
->op_a
.symbol_table
= head
->op_b
.symbol_table
;
169 head
->op_b
.symbol_table
= retval
;
185 VEC(tree
,gc
) * gpy_process_expression( const gpy_symbol_obj
* const sym
,
186 VEC(gpy_ctx_t
,gc
) * context
)
188 VEC(tree
,gc
) * retval
= NULL
;
189 if( sym
->type
== SYMBOL_PRIMARY
)
191 retval
= VEC_alloc(tree
,gc
,0);
192 VEC(tree
,gc
) *primitive
= gpy_fold_primitive( sym
);
193 gcc_assert( VEC_length(tree
,primitive
) == 1 );
194 VEC_safe_push( tree
,gc
,retval
,VEC_index(tree
,primitive
,0) );
196 else if( sym
->type
== SYMBOL_REFERENCE
)
198 gcc_assert( sym
->op_a_t
== TYPE_STRING
);
199 tree decl
= gpy_ctx_lookup_decl( context
, sym
->op_a
.string
, VAR
);
202 retval
= VEC_alloc(tree
,gc
,0);
203 debug("tree reference <%s>!\n", sym
->op_a
.string
);
204 VEC_safe_push( tree
,gc
,retval
,decl
);
208 error("undeclared symbol reference <%s>!\n",
214 gpy_symbol_obj
*opa
= NULL
, *opb
= NULL
; VEC(tree
,gc
) *res
= NULL
;
215 debug("expression evalution <0x%x>!\n", sym
->type
);
217 opa
= sym
->op_a
.symbol_table
;
218 opb
= sym
->op_b
.symbol_table
;
220 debug( "opa->type = <0x%x>, opb->type = <0x%x>!\n",
221 opa
->type
, opb
->type
);
226 res
= gpy_process_assign( &opa
, &opb
, context
);
229 case OP_BIN_ADDITION
:
230 res
= gpy_process_bin_expression( &opa
, &opb
, sym
->type
, context
);
234 fatal_error( "invalid expression evaluation symbol type <0x%x>!\n",
238 if( res
) { retval
= res
; }
239 else { fatal_error("error evaluating expression!\n"); }
245 VEC(tree
,gc
) * gpy_process_functor( const gpy_symbol_obj
* const functor
,
246 const char * base_ident
,
247 VEC(gpy_ctx_t
,gc
) * context
)
249 VEC(tree
,gc
) * retval_vec
= VEC_alloc( tree
,gc
,0 );
251 gpy_symbol_obj
* o
= functor
->op_a
.symbol_table
;
252 tree fntype
= build_function_type(void_type_node
, void_list_node
);
253 tree retval
= build_decl( UNKNOWN_LOCATION
, FUNCTION_DECL
,
254 get_identifier( functor
->identifier
),
257 tree declare_vars
= NULL_TREE
;
258 tree bind
= NULL_TREE
;
259 tree block
= alloc_stmt_list( );
260 tree resdecl
= NULL_TREE
;
261 tree restype
= TREE_TYPE(retval
);
264 gpy_context_branch
*co
= NULL
;
269 size_t len
= strlen( functor
->identifier
) + strlen( base_ident
);
270 size_t idx
= 0, idy
= 0;
271 char * buffer
= (char *) xmalloc( (sizeof(char) * len
)+2 );
272 for( ; idx
<strlen( base_ident
); ++idx
)
274 buffer
[ idy
] = base_ident
[ idx
];
277 buffer
[ idy
] = '.'; idy
++;
278 for( idx
=0; idx
<strlen( functor
->identifier
); ++idx
)
280 buffer
[ idy
] = functor
->identifier
[ idx
];
284 debug("buffer = <%s>!\n", buffer
);
285 SET_DECL_ASSEMBLER_NAME( retval
, get_identifier( buffer
) );
289 SET_DECL_ASSEMBLER_NAME( retval
, get_identifier(functor
->identifier
) );
291 TREE_PUBLIC(retval
) = 1;
292 TREE_STATIC(retval
) = 1;
294 resdecl
= build_decl( UNKNOWN_LOCATION
, RESULT_DECL
, NULL_TREE
,
296 DECL_CONTEXT(resdecl
) = retval
;
297 DECL_RESULT(retval
) = resdecl
;
299 DECL_INITIAL(retval
) = block
;
301 /* push a new context for local symbols */
302 co
= (gpy_context_branch
*)
303 xmalloc( sizeof(gpy_context_branch
) );
304 gpy_init_ctx_branch( &co
);
305 VEC_safe_push( gpy_ctx_t
, gc
, context
, co
);
309 /* looping over the gpy_symbol_obj block of function statements
310 and getting the respective tree's and creating the GENERIC block
312 VEC(tree
,gc
) * x
= gpy_get_tree( o
,context
);
313 int itx
= 0; tree xt
;
314 for( ; VEC_iterate(tree
,x
,itx
,xt
); ++itx
)
317 append_to_statement_list( xt
, &block
);
322 for( ; VEC_iterate( gpy_ident
,co
->var_decl_t
, idx
, it
); ++idx
)
324 /* get all block var_decls */
325 tree x
= gpy_ctx_lookup_decl( context
, it
->ident
, VAR
);
326 gcc_assert( TREE_CODE( x
) == VAR_DECL
);
327 debug("got var decl <%p>:<%s> within func <%s>!\n", (void*)x
,
328 it
->ident
, functor
->identifier
);
329 TREE_CHAIN( x
) = declare_vars
;
333 if( declare_vars
!= NULL_TREE
)
335 tree bl
= make_node(BLOCK
);
336 BLOCK_SUPERCONTEXT(bl
) = retval
;
337 DECL_INITIAL(retval
) = bl
;
338 BLOCK_VARS(bl
) = declare_vars
;
340 bind
= build3(BIND_EXPR
, void_type_node
, BLOCK_VARS(bl
),
342 TREE_SIDE_EFFECTS(bind
) = 1;
344 BIND_EXPR_BODY(bind
) = block
;
346 DECL_SAVED_TREE(retval
) = block
;
348 VEC_pop( gpy_ctx_t
, gpy_ctx_table
);
350 gimplify_function_tree( retval
);
352 cgraph_add_new_function(retval
, false);
353 cgraph_finalize_function(retval
, true);
355 VEC_safe_push( tree
,gc
,retval_vec
,retval
);
360 VEC(tree
,gc
) * gpy_process_print( gpy_symbol_obj
*sym
, VEC(gpy_ctx_t
,gc
) * context
)
362 VEC(tree
,gc
) * retval
= NULL
;
363 gcc_assert( sym
->op_a_t
== TYPE_SYMBOL
);
364 gpy_symbol_obj
* argument_list
= sym
->op_a
.symbol_table
;
369 gpy_symbol_obj
* t
= argument_list
;
376 int idx
, idy
= 0; t
= argument_list
;
377 tree
* args
= XNEWVEC( tree
,len
);
378 for( idx
=0; idx
<len
; ++idx
)
380 VEC(tree
,gc
) * x
= gpy_get_tree( t
, context
);
381 gcc_assert( VEC_length(tree
,x
) == 1 );
382 args
[ idy
] = VEC_index(tree
,x
,0);
387 VEC_safe_push( tree
,gc
,retval
,gpy_builtin_get_print_call( len
, args
) );
390 error("print call without any arguments!\n");
395 VEC(tree
,gc
) * gpy_process_class( gpy_symbol_obj
* const sym
,
396 VEC(gpy_ctx_t
,gc
) * context
)
398 VEC(tree
,gc
) * retval
= NULL
;
402 VEC(tree
,gc
) * gpy_get_tree( gpy_symbol_obj
* sym
, VEC(gpy_ctx_t
,gc
) * context
)
404 VEC(tree
,gc
) * retval
= NULL
;
406 debug( "processing decl of type <0x%X> object <%p>\n",
407 sym
->type
, (void*) sym
);
409 if( sym
->exp
== OP_EXPRESS
)
411 sym
= gpy_process_AST_Align( &sym
);
412 retval
= gpy_process_expression( sym
, context
);
418 case STRUCTURE_OBJECT_DEF
:
419 retval
= gpy_process_class( sym
, context
);
422 case STRUCTURE_FUNCTION_DEF
:
423 retval
= gpy_process_functor( sym
, NULL
, context
);
427 retval
= gpy_process_print( sym
, context
);
431 fatal_error("unhandled symbol type <0x%x>\n", sym
->type
);
439 tree
gpy_main_method_decl( VEC(tree
,gc
) * block
, gpy_context_branch
* co
)
441 tree retval
= NULL_TREE
; int idx
;
443 tree main_fn_type
= build_function_type_list( integer_type_node
, NULL_TREE
);
444 tree main_fn_decl
= build_decl( BUILTINS_LOCATION
, FUNCTION_DECL
,
445 get_identifier("main"), main_fn_type
);
447 DECL_CONTEXT(main_fn_decl
) = NULL_TREE
;
448 TREE_STATIC(main_fn_decl
) = true;
449 TREE_PUBLIC(main_fn_decl
) = true;
450 DECL_ARGUMENTS(main_fn_decl
) = NULL_TREE
;
452 /* Define the return type (represented by RESULT_DECL) for the main functin */
453 tree main_ret
= build_decl( BUILTINS_LOCATION
, RESULT_DECL
,
454 NULL_TREE
, TREE_TYPE(main_fn_type
) );
455 DECL_CONTEXT(main_ret
) = main_fn_decl
;
456 DECL_ARTIFICIAL(main_ret
) = true;
457 DECL_IGNORED_P(main_ret
) = true;
459 DECL_RESULT(main_fn_decl
) = main_ret
;
461 tree main_art_block
= build_block(NULL_TREE
, NULL_TREE
, NULL_TREE
, NULL_TREE
);
462 DECL_INITIAL(main_fn_decl
) = main_art_block
;
464 tree declare_vars
= NULL_TREE
;
465 tree main_stmts
= alloc_stmt_list( );
467 append_to_statement_list( gpy_builtin_get_init_call( ), &main_stmts
);
470 for( idx
= 0; VEC_iterate(tree
,block
,idx
,it
); ++idx
)
473 append_to_statement_list( it
, &main_stmts
);
476 int block_decl_len
= 0; gpy_ident vit
= NULL
;
477 for( idx
= 0; VEC_iterate( gpy_ident
,co
->var_decl_t
, idx
, vit
); ++idx
)
479 /* get all block var_decls */
480 tree x
= gpy_ctx_lookup_decl( gpy_ctx_table
, vit
->ident
, VAR
);
481 gcc_assert( TREE_CODE( x
) == VAR_DECL
);
482 debug("got var decl <%p>:<%s> within func <%s>!\n", (void*)x
,
483 vit
->ident
, "main" );
484 TREE_CHAIN( x
) = declare_vars
;
489 if( block_decl_len
> 0 )
491 tree
* block_decl_vec
= XNEWVEC( tree
, block_decl_len
);
494 for( idx
= 0; VEC_iterate( gpy_ident
,co
->var_decl_t
, idx
, vit
); ++idx
)
496 tree x
= gpy_ctx_lookup_decl( gpy_ctx_table
, vit
->ident
, VAR
);
497 gcc_assert( TREE_CODE( x
) == VAR_DECL
);
499 block_decl_vec
[ idy
] = x
;
502 block_decl_vec
[ idy
] = main_ret
; idy
++;
503 append_to_statement_list( gpy_builtin_get_finalize_block_call( block_decl_len
,
509 declare_vars
= main_ret
;
512 append_to_statement_list( gpy_builtin_get_cleanup_final_call( ), &main_stmts
);
514 tree main_set_ret
= build2( MODIFY_EXPR
, TREE_TYPE(main_ret
),
515 main_ret
, build_int_cst(integer_type_node
, 0));
516 tree main_ret_expr
= build1( RETURN_EXPR
, void_type_node
, main_set_ret
);
517 append_to_statement_list( main_ret_expr
, &main_stmts
);
519 tree bind
= NULL_TREE
;
520 if( declare_vars
!= NULL_TREE
)
522 tree bl
= make_node(BLOCK
);
523 BLOCK_SUPERCONTEXT(bl
) = main_fn_decl
;
524 DECL_INITIAL(main_fn_decl
) = bl
;
525 BLOCK_VARS(bl
) = declare_vars
;
527 bind
= build3( BIND_EXPR
, void_type_node
, BLOCK_VARS(bl
),
529 TREE_SIDE_EFFECTS(bind
) = 1;
531 BIND_EXPR_BODY(bind
) = main_stmts
;
533 DECL_SAVED_TREE(main_fn_decl
) = main_stmts
;
535 gimplify_function_tree( main_fn_decl
);
536 cgraph_finalize_function( main_fn_decl
, false );
538 retval
= main_fn_decl
;
543 void gpy_write_globals( void )
545 gpy_context_branch
*co
= NULL
;
546 gpy_symbol_obj
* it
= NULL
;
547 VEC(tree
,gc
) * main_stmts_vec
= VEC_alloc(tree
,gc
,0);
549 /* push a new context for local symbols */
550 co
= (gpy_context_branch
*)
551 xmalloc( sizeof(gpy_context_branch
) );
552 gpy_init_ctx_branch( &co
);
553 VEC_safe_push( gpy_ctx_t
, gc
, gpy_ctx_table
, co
);
556 for( idx
= 0; VEC_iterate(gpy_sym
,gpy_decls
,idx
,it
); ++idx
)
558 VEC(tree
,gc
) * x
= gpy_get_tree( it
, gpy_ctx_table
);
559 int itx
= 0; tree xt
;
560 for( ; VEC_iterate(tree
,x
,itx
,xt
); ++itx
)
562 if( TREE_CODE(xt
) == FUNCTION_DECL
)
564 VEC_safe_push( tree
,gc
,global_decls
,xt
);
568 VEC_safe_push( tree
,gc
,main_stmts_vec
,xt
);
573 /* Add in the main method decl! */
574 VEC_safe_push( tree
,gc
,global_decls
,gpy_main_method_decl( main_stmts_vec
,co
) );
576 VEC_pop( gpy_ctx_t
, gpy_ctx_table
);
578 tree itx
= NULL_TREE
; int idy
= 0; int global_vec_len
= VEC_length(tree
, global_decls
);
579 tree
* global_vec
= XNEWVEC( tree
, global_vec_len
);
580 for( idx
=0; VEC_iterate(tree
,global_decls
,idx
,itx
); ++idx
)
582 global_vec
[ idy
] = itx
;
586 debug("Finished processing!\n\n");
588 wrapup_global_declarations( global_vec
, global_vec_len
);
590 check_global_declarations( global_vec
, global_vec_len
);
591 emit_debug_global_declarations( global_vec
, global_vec_len
);
593 cgraph_finalize_compilation_unit( );
595 debug("finished passing to middle-end!\n\n");