fixes to strings in generic usuage
[official-gcc.git] / libgpython / runtime / py-runtime.c
blob9b811bf199f59cc7b804efb2ee0789b0796cee95
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_register_callable (gpy_std_callable call, int nargs,
53 char * ident)
55 gpy_object_t * c = NULL_OBJECT;
57 gpy_callable_t * call_ = (gpy_callable_t *)
58 gpy_malloc (sizeof(gpy_callable_t));
60 call_->ident = ident;
61 call_->n = nargs;
62 call_->call = call;
64 c = (gpy_object_t *)
65 gpy_malloc (sizeof(gpy_object_t));
66 c->T = TYPE_CALLABLE;
67 c->o.call = call_;
69 gpy_hashval_t h = gpy_dd_hash_string (ident);
71 gpy_hash_entry_t * f = gpy_rr_lookup_decl (h, gpy_namespace_vec);
72 if (f)
74 gpy_object_t * prev = f->data;
75 gpy_free (prev); // fix later
76 f->data = c;
78 else
80 void ** r = gpy_dd_hash_insert (h, c, Gpy_Vec_Head (gpy_namespace_vec,
81 gpy_hash_tab_t *));
82 if (r)
83 fatal ("error registering decl <%s>!\n", ident);
87 void gpy_rr_register_decl (char * ident)
89 gpy_hashval_t h = gpy_dd_hash_string (ident);
90 gpy_hash_entry_t * f = gpy_rr_lookup_decl (h, gpy_namespace_vec);
91 if (!f)
93 gpy_object_t * o = (gpy_object_t *)
94 gpy_malloc (sizeof (gpy_object_t));
95 o->T = TYPE_NULL;
96 o->o.object_state = NULL;
98 void ** r = gpy_dd_hash_insert (h, o, Gpy_Vec_Head (gpy_namespace_vec,
99 gpy_hash_tab_t *));
100 if (r)
101 fatal ("error registering decl <%s>!\n", ident);
105 void gpy_rr_set_decl_val (char *ident, gpy_object_t *o)
107 gpy_hashval_t h = gpy_dd_hash_string (ident);
108 gpy_hash_entry_t * f = gpy_rr_lookup_decl (h, gpy_namespace_vec);
110 if (f)
112 gpy_object_t * prev = f->data;
113 gpy_rr_decr_ref_count (prev);
114 f->data = o;
116 else
118 void ** r = gpy_dd_hash_insert (h, o, Gpy_Vec_Head (gpy_namespace_vec,
119 gpy_hash_tab_t *));
120 if (r)
121 fatal ("error registering decl <%s>!\n", ident);
125 void gpy_rr_init_runtime (void)
128 Setup runtime namespace Init builtin's
130 gpy_rr_init_primitives ();
132 gpy_namespace_vec = (gpy_vector_t*)
133 gpy_malloc( sizeof(gpy_vector_t) );
134 gpy_vec_init( gpy_namespace_vec );
136 gpy_call_stack = (gpy_vector_t*)
137 gpy_malloc(sizeof(gpy_vector_t));
138 gpy_vec_init( gpy_call_stack );
140 gpy_hash_tab_t * head = (gpy_hash_tab_t *)
141 gpy_malloc (sizeof(gpy_hash_tab_t));
142 gpy_dd_hash_init_table (&head);
143 gpy_vec_push( gpy_namespace_vec, head );
146 void gpy_rr_cleanup_final( void )
148 gpy_rr_pop_context ();
150 if( gpy_namespace_vec->length > 0 )
151 error( "<%i> un-free'd conexts!\n", gpy_namespace_vec->length );
153 gpy_vec_free (gpy_namespace_vec);
154 gpy_vec_free (gpy_primitives);
155 gpy_vec_free (gpy_call_stack);
158 gpy_object_t * gpy_rr_fold_integer (int x)
160 gpy_object_t * retval = NULL_OBJECT;
162 gpy_object_t ** args = (gpy_object_t **)
163 gpy_calloc(2, sizeof(gpy_object_t*));
165 gpy_literal_t i;
166 i.type = TYPE_INTEGER;
167 i.literal.integer = x;
169 gpy_object_t a1 = { .T = TYPE_OBJECT_LIT, .o.literal = &i };
170 gpy_object_t a2 = { .T = TYPE_NULL, .o.literal = NULL };
172 args[0] = &a1;
173 args[1] = &a2;
175 gpy_typedef_t * Int_def = (gpy_typedef_t *)
176 gpy_primitives->vector[ 0 ];
177 gpy_assert (Int_def);
179 retval = Int_def->init_hook (Int_def, args);
180 gpy_free(args);
182 debug("initilized integer object <%p> to <%i>!\n",
183 (void*)retval, x );
184 gpy_assert (retval->T == TYPE_OBJECT_STATE);
186 return retval;
190 * int fd: we could use bit masks to represent:
191 * stdout/stderr ...
193 void gpy_rr_eval_print (int fd, int count, ...)
195 va_list vl; int idx;
196 va_start (vl,count);
198 gpy_object_t * it = NULL;
199 for( idx = 0; idx<count; ++idx )
201 it = va_arg( vl, gpy_object_t* );
202 gpy_assert(it->T == TYPE_OBJECT_STATE);
203 struct gpy_typedef_t * definition = it->o.object_state->definition;
205 switch( fd )
207 case 1:
208 (*definition).print_hook( it, stdout, false );
209 break;
211 case 2:
212 (*definition).print_hook( it, stderr, false );
213 break;
215 default:
216 fatal("invalid print file-descriptor <%i>!\n", fd );
217 break;
221 fprintf( stdout, "\n" );
222 va_end(vl);
225 inline
226 void gpy_rr_incr_ref_count (gpy_object_t * x1)
228 gpy_assert( x1->T == TYPE_OBJECT_STATE );
229 gpy_object_state_t * x = x1->o.object_state;
231 debug("incrementing ref count on <%p>:<%i> to <%i>!\n",
232 (void*) x, x->ref_count, (x->ref_count + 1) );
233 x->ref_count++;
236 inline
237 void gpy_rr_decr_ref_count (gpy_object_t * x1)
239 gpy_assert( x1->T == TYPE_OBJECT_STATE );
240 gpy_object_state_t * x = x1->o.object_state;
242 debug("decrementing ref count on <%p>:<%i> to <%i>!\n",
243 (void*) x, x->ref_count, (x->ref_count - 1) );
244 x->ref_count--;
247 void gpy_rr_push_context (void)
249 gpy_hash_tab_t * head = (gpy_hash_tab_t *)
250 gpy_malloc (sizeof(gpy_hash_tab_t));
251 gpy_dd_hash_init_table (&head);
253 gpy_vec_push (gpy_namespace_vec, head);
256 void gpy_rr_pop_context (void)
258 gpy_hash_tab_t * head = Gpy_Vec_Head (gpy_namespace_vec,
259 gpy_hash_tab_t *);
260 gpy_hash_entry_t * array = head->array;
262 unsigned int idx = 0;
263 for( ; idx<(head->length); ++idx )
265 gpy_hash_entry_t i = array[idx];
266 if (i.data)
268 gpy_object_t * o = i.data;
269 gpy_rr_decr_ref_count (o);
273 gpy_garbage_invoke_sweep (gpy_namespace_vec);
275 /* Loop over for stragglers like returns which need pushed up a
276 context soo they can still be garbage collected....
278 straggler is something which will have a (ref_count > 0) after
279 this set of decreasing references...
281 //....
283 gpy_hash_tab_t * popd = gpy_vec_pop (gpy_namespace_vec);
284 gpy_free (popd);
287 void gpy_rr_finalize_block_decls (int n, ...)
289 va_list vl; int idx;
290 va_start (vl,n);
292 /* gpy_object_t is a typedef of gpy_object_state_t *
293 to keep stdarg.h happy
295 gpy_object_t * it = NULL;
296 for (idx = 0; idx<n; ++idx)
298 it = va_arg (vl, gpy_object_t *);
299 gpy_assert (it->T == TYPE_OBJECT_STATE);
300 gpy_rr_decr_ref_count (it);
302 va_end (vl);
305 gpy_object_t * gpy_rr_fold_call (gpy_callable_t * callables,
306 const char * ident,
307 int n, ...)
309 gpy_object_t * retval = NULL;
313 return retval;
316 gpy_object_t * gpy_rr_eval_dot_operator (gpy_object_t * x,
317 gpy_object_t * y)
319 return NULL;
322 gpy_object_t * gpy_rr_eval_expression (gpy_object_t * x1,
323 gpy_object_t * y1,
324 gpy_opcode_t op)
326 char * op_str = NULL;
327 gpy_object_t * retval = NULL;
329 gpy_assert(x1->T == TYPE_OBJECT_STATE);
330 gpy_assert(y1->T == TYPE_OBJECT_STATE);
331 gpy_object_state_t * x = x1->o.object_state;
332 gpy_object_state_t * y = y1->o.object_state;
334 struct gpy_typedef_t * def = x1->o.object_state->definition;
335 struct gpy_number_prot_t * binops = (*def).binary_protocol;
336 struct gpy_number_prot_t binops_l = (*binops);
338 debug ("Eval expression!\n");
340 if( binops_l.init )
342 binary_op o = NULL;
343 switch( op )
345 case OP_BIN_ADDITION:
346 o = binops_l.n_add;
347 op_str = "+ ";
348 break;
350 default:
351 fatal("unhandled binary operation <%x>!\n", op );
352 break;
355 #ifdef DEBUG
356 x->definition->print_hook( x1, stdout, false );
357 fprintf(stdout, "%s", op_str );
358 y->definition->print_hook( y1, stdout, true );
359 #endif
361 retval = o(x1,y1);
363 #ifdef DEBUG
364 if( retval )
366 fprintf(stdout, "evaluated to: ");
367 retval->o.object_state->definition->print_hook (retval, stdout, false);
368 fprintf(stdout, "!\n");
370 #endif
372 else
374 fatal("object type <%s> has no binary protocol!\n",
375 x->obj_t_ident );
378 return retval;