regen makefiles stubs and cleanup runtime lib more
[official-gcc.git] / libgpython / runtime / py-runtime.c
blob301bcc387c14a950c586227b21c513149b3fb20d
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 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdbool.h>
25 #include <stdarg.h>
27 #include <gpython/gpython.h>
28 #include <gpython/objects.h>
29 #include <gpython/vectors.h>
30 #include <gpython/garbage.h>
32 gpy_vector_t * gpy_primitives;
33 gpy_vector_t * gpy_namespace_vec;
35 /* Used for stack-traces ... */
36 gpy_vector_t * gpy_call_stack;
38 void gpy_rr_init_primitives( void )
40 gpy_primitives = (gpy_vector_t *)
41 gpy_malloc( sizeof(gpy_vector_t) );
42 gpy_vec_init( gpy_primitives );
44 gpy_obj_integer_mod_init( gpy_primitives );
47 void gpy_dump_current_stack_trace (void)
49 return;
52 void gpy_rr_init_runtime( void )
54 /*
55 Setup runtime namespace Init builtin's
57 gpy_rr_init_primitives( );
59 gpy_namespace_vec = (gpy_vector_t*)
60 gpy_malloc( sizeof(gpy_vector_t) );
61 gpy_vec_init( gpy_namespace_vec );
63 gpy_call_stack = (gpy_vector_t*)
64 gpy_malloc(sizeof(gpy_vector_t));
65 gpy_vec_init( gpy_call_stack );
67 gpy_context_t * head = (gpy_context_t *)
68 gpy_malloc( sizeof(gpy_context_t) );
70 head->symbols = (gpy_vector_t*)
71 gpy_malloc( sizeof(gpy_vector_t) );
72 gpy_vec_init( head->symbols );
74 gpy_vec_push( gpy_namespace_vec, head );
77 void gpy_rr_cleanup_final( void )
79 gpy_rr_pop_context( );
81 if( gpy_namespace_vec->length > 0 )
82 error( "<%i> un-free'd conexts!\n", gpy_namespace_vec->length );
84 gpy_vec_free( gpy_namespace_vec );
85 gpy_vec_free( gpy_primitives );
86 gpy_vec_free( gpy_call_stack );
89 gpy_object_t * gpy_rr_fold_integer( int x )
91 gpy_object_t * retval = NULL_OBJECT;
93 gpy_object_state_t * o = NULL_OBJ_STATE;
94 Gpy_Object_State_Init_Ctx( o, gpy_namespace_vec );
96 gpy_object_t ** args = (gpy_object_t **)
97 gpy_calloc(2, sizeof(gpy_object_t*));
99 gpy_literal_t i;
100 i.type = TYPE_INTEGER;
101 i.literal.integer = x;
103 gpy_object_t a1 = { .T = TYPE_OBJECT_LIT, .o.literal = &i };
104 gpy_object_t a2 = { .T = TYPE_NULL, .o.literal = NULL };
106 args[0] = &a1;
107 args[1] = &a2;
109 gpy_type_obj_def_t * Int_def = (gpy_type_obj_def_t *)
110 gpy_primitives->vector[ 0 ];
111 gpy_assert( Int_def );
113 retval = Int_def->init_hook (args);
114 gpy_free(args);
116 debug("initilized integer object <%p> to <%i>!\n",
117 (void*)retval, x );
119 gpy_assert (retval->T == TYPE_OBJECT_STATE);
120 Gpy_Incr_Ref (retval->o.object_state);
122 return retval;
126 * int fd: we could use bit masks to represent:
127 * stdout/stderr ...
129 void gpy_rr_eval_print( int fd, int count, ... )
131 va_list vl; int idx;
132 va_start( vl,count );
134 /* gpy_object_t is a typedef of gpy_object_state_t *
135 to keep stdarg.h happy
137 gpy_object_t * it = NULL;
138 for( idx = 0; idx<count; ++idx )
140 it = va_arg( vl, gpy_object_t* );
141 gpy_assert(it->T == TYPE_OBJECT_STATE);
142 struct gpy_type_obj_def_t * definition = it->o.object_state->definition;
144 switch( fd )
146 case 1:
147 (*definition).print_hook( it, stdout, false );
148 break;
150 case 2:
151 (*definition).print_hook( it, stderr, false );
152 break;
154 default:
155 fatal("invalid print file-descriptor <%i>!\n", fd );
156 break;
160 fprintf( stdout, "\n" );
161 va_end(vl);
164 inline
165 void gpy_rr_incr_ref_count( gpy_object_state_t * x )
167 gpy_assert( x );
168 debug("incrementing ref count on <%p>:<%i> to <%i>!\n",
169 (void*) x, x->ref_count, (x->ref_count + 1) );
170 x->ref_count++;
173 inline
174 void gpy_rr_decr_ref_count( gpy_object_state_t * x )
176 gpy_assert( x );
177 debug("decrementing ref count on <%p>:<%i> to <%i>!\n",
178 (void*) x, x->ref_count, (x->ref_count - 1) );
179 x->ref_count--;
182 void gpy_rr_push_context( void )
184 gpy_context_t * ctx = (gpy_context_t *)
185 gpy_malloc( sizeof(gpy_context_t) );
186 ctx->symbols = (gpy_vector_t*)
187 gpy_malloc( sizeof(gpy_vector_t) );
188 gpy_vec_init( ctx->symbols );
190 gpy_vec_push( gpy_namespace_vec, ctx );
193 void gpy_rr_pop_context( void )
195 gpy_context_t * head = Gpy_Namespace_Head;
196 void ** vec = head->symbols->vector;
198 unsigned int idx = 0;
199 for( ; idx<(head->symbols->length); ++idx )
201 gpy_object_state_t * i = (gpy_object_state_t *) vec[ idx ];
202 Gpy_Decr_Ref( i );
205 gpy_garbage_invoke_sweep( gpy_namespace_vec );
207 /* Loop over for stragglers like returns which need pushed up a
208 context soo they can still be garbage collected....
210 straggler is something which will have a (ref_count > 0) after
211 this set of decreasing references...
214 gpy_context_t * popd = gpy_vec_pop( gpy_namespace_vec );
215 gpy_vec_free( popd->symbols );
216 gpy_free( popd );
219 void gpy_rr_finalize_block_decls( int n, ... )
221 va_list vl; int idx;
222 va_start( vl,n );
224 /* gpy_object_t is a typedef of gpy_object_state_t *
225 to keep stdarg.h happy
227 gpy_object_t * it = NULL;
228 for( idx = 0; idx<n; ++idx )
230 it = va_arg( vl, gpy_object_t* );
231 gpy_assert(it->T == TYPE_OBJECT_STATE);
232 /* no assert this macro auto inserts an assert */
233 Gpy_Decr_Ref( it->o.object_state );
235 va_end(vl);
238 gpy_object_t * gpy_rr_fold_call(struct gpy_callable_def_t * callables,
239 const char * ident, int n_args, ... )
241 return NULL;
244 gpy_object_t *
245 gpy_rr_eval_dot_operator( gpy_object_t * x, gpy_object_t * y )
247 return NULL;
250 gpy_object_t *
251 gpy_rr_eval_expression (gpy_object_t * x1, gpy_object_t * y1,
252 gpy_opcode_t op)
254 char * op_str = NULL;
255 gpy_object_t * retval = NULL;
257 gpy_assert(x1->T == TYPE_OBJECT_STATE);
258 gpy_assert(y1->T == TYPE_OBJECT_STATE);
259 gpy_object_state_t * x = x1->o.object_state;
260 gpy_object_state_t * y = y1->o.object_state;
262 struct gpy_type_obj_def_t * def = x->definition;
263 struct gpy_number_prot_t * binops = (*def).binary_protocol;
264 struct gpy_number_prot_t binops_l = (*binops);
266 if( binops_l.init )
268 binary_op o = NULL;
269 switch( op )
271 case OP_BIN_ADDITION:
272 o = binops_l.n_add;
273 op_str = "+ ";
274 break;
276 default:
277 fatal("unhandled binary operation <%x>!\n", op );
278 break;
281 #ifdef DEBUG
282 x->definition->print_hook( x1, stdout, false );
283 fprintf(stdout, "%s", op_str );
284 y->definition->print_hook( y1, stdout, true );
285 #endif
287 retval = o(x1,y1);
289 #ifdef DEBUG
290 if( retval )
292 fprintf(stdout, "evaluated to: ");
293 retval->o.object_state->definition->print_hook (retval, stdout, false);
294 fprintf(stdout, "!\n");
296 #endif
298 else
300 fatal("object type <%s> has no binary protocol!\n",
301 x->obj_t_ident );
304 return retval;