/* This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include gpy_vector_t * gpy_primitives; gpy_vector_t * gpy_namespace_vec; /* Used for stack-traces ... */ gpy_vector_t * gpy_call_stack; void gpy_rr_init_primitives (void) { gpy_primitives = (gpy_vector_t *) gpy_malloc( sizeof(gpy_vector_t) ); gpy_vec_init( gpy_primitives ); gpy_obj_integer_mod_init( gpy_primitives ); } void gpy_dump_current_stack_trace (void) { return; } void gpy_rr_register_callable (gpy_std_callable call, int nargs, char * ident) { gpy_object_t * c = NULL_OBJECT; gpy_callable_t * call_ = (gpy_callable_t *) gpy_malloc (sizeof(gpy_callable_t)); call_->ident = ident; call_->n = nargs; call_->call = call; c = (gpy_object_t *) gpy_malloc (sizeof(gpy_object_t)); c->T = TYPE_CALLABLE; c->o.call = call_; gpy_hashval_t h = gpy_dd_hash_string (ident); gpy_hash_entry_t * f = gpy_rr_lookup_decl (h, gpy_namespace_vec); if (f) { gpy_object_t * prev = f->data; gpy_free (prev); // fix later f->data = c; } else { void ** r = gpy_dd_hash_insert (h, c, Gpy_Vec_Head (gpy_namespace_vec, gpy_hash_tab_t *)); if (r) fatal ("error registering decl <%s>!\n", ident); } } void gpy_rr_register_decl (char * ident) { gpy_hashval_t h = gpy_dd_hash_string (ident); gpy_hash_entry_t * f = gpy_rr_lookup_decl (h, gpy_namespace_vec); if (!f) { gpy_object_t * o = (gpy_object_t *) gpy_malloc (sizeof (gpy_object_t)); o->T = TYPE_NULL; o->o.object_state = NULL; void ** r = gpy_dd_hash_insert (h, o, Gpy_Vec_Head (gpy_namespace_vec, gpy_hash_tab_t *)); if (r) fatal ("error registering decl <%s>!\n", ident); } } void gpy_rr_set_decl_val (char *ident, gpy_object_t *o) { gpy_hashval_t h = gpy_dd_hash_string (ident); gpy_hash_entry_t * f = gpy_rr_lookup_decl (h, gpy_namespace_vec); if (f) { gpy_object_t * prev = f->data; gpy_rr_decr_ref_count (prev); f->data = o; } else { void ** r = gpy_dd_hash_insert (h, o, Gpy_Vec_Head (gpy_namespace_vec, gpy_hash_tab_t *)); if (r) fatal ("error registering decl <%s>!\n", ident); } } void gpy_rr_init_runtime (void) { /* Setup runtime namespace Init builtin's */ gpy_rr_init_primitives (); gpy_namespace_vec = (gpy_vector_t*) gpy_malloc( sizeof(gpy_vector_t) ); gpy_vec_init( gpy_namespace_vec ); gpy_call_stack = (gpy_vector_t*) gpy_malloc(sizeof(gpy_vector_t)); gpy_vec_init( gpy_call_stack ); gpy_hash_tab_t * head = (gpy_hash_tab_t *) gpy_malloc (sizeof(gpy_hash_tab_t)); gpy_dd_hash_init_table (&head); gpy_vec_push( gpy_namespace_vec, head ); } void gpy_rr_cleanup_final( void ) { gpy_rr_pop_context (); if( gpy_namespace_vec->length > 0 ) error( "<%i> un-free'd conexts!\n", gpy_namespace_vec->length ); gpy_vec_free (gpy_namespace_vec); gpy_vec_free (gpy_primitives); gpy_vec_free (gpy_call_stack); } gpy_object_t * gpy_rr_fold_integer (int x) { gpy_object_t * retval = NULL_OBJECT; gpy_object_t ** args = (gpy_object_t **) gpy_calloc(2, sizeof(gpy_object_t*)); gpy_literal_t i; i.type = TYPE_INTEGER; i.literal.integer = x; gpy_object_t a1 = { .T = TYPE_OBJECT_LIT, .o.literal = &i }; gpy_object_t a2 = { .T = TYPE_NULL, .o.literal = NULL }; args[0] = &a1; args[1] = &a2; gpy_typedef_t * Int_def = (gpy_typedef_t *) gpy_primitives->vector[ 0 ]; gpy_assert (Int_def); retval = Int_def->init_hook (Int_def, args); gpy_free(args); debug("initilized integer object <%p> to <%i>!\n", (void*)retval, x ); gpy_assert (retval->T == TYPE_OBJECT_STATE); return retval; } /** * int fd: we could use bit masks to represent: * stdout/stderr ... **/ void gpy_rr_eval_print (int fd, int count, ...) { va_list vl; int idx; va_start (vl,count); gpy_object_t * it = NULL; for( idx = 0; idxT == TYPE_OBJECT_STATE); struct gpy_typedef_t * definition = it->o.object_state->definition; switch( fd ) { case 1: (*definition).print_hook( it, stdout, false ); break; case 2: (*definition).print_hook( it, stderr, false ); break; default: fatal("invalid print file-descriptor <%i>!\n", fd ); break; } } fprintf( stdout, "\n" ); va_end(vl); } inline void gpy_rr_incr_ref_count (gpy_object_t * x1) { gpy_assert( x1->T == TYPE_OBJECT_STATE ); gpy_object_state_t * x = x1->o.object_state; debug("incrementing ref count on <%p>:<%i> to <%i>!\n", (void*) x, x->ref_count, (x->ref_count + 1) ); x->ref_count++; } inline void gpy_rr_decr_ref_count (gpy_object_t * x1) { gpy_assert( x1->T == TYPE_OBJECT_STATE ); gpy_object_state_t * x = x1->o.object_state; debug("decrementing ref count on <%p>:<%i> to <%i>!\n", (void*) x, x->ref_count, (x->ref_count - 1) ); x->ref_count--; } void gpy_rr_push_context (void) { gpy_hash_tab_t * head = (gpy_hash_tab_t *) gpy_malloc (sizeof(gpy_hash_tab_t)); gpy_dd_hash_init_table (&head); gpy_vec_push (gpy_namespace_vec, head); } void gpy_rr_pop_context (void) { gpy_hash_tab_t * head = Gpy_Vec_Head (gpy_namespace_vec, gpy_hash_tab_t *); gpy_hash_entry_t * array = head->array; unsigned int idx = 0; for( ; idx<(head->length); ++idx ) { gpy_hash_entry_t i = array[idx]; if (i.data) { gpy_object_t * o = i.data; gpy_rr_decr_ref_count (o); } } gpy_garbage_invoke_sweep (gpy_namespace_vec); /* Loop over for stragglers like returns which need pushed up a context soo they can still be garbage collected.... -- straggler is something which will have a (ref_count > 0) after this set of decreasing references... */ //.... gpy_hash_tab_t * popd = gpy_vec_pop (gpy_namespace_vec); gpy_free (popd); } void gpy_rr_finalize_block_decls (int n, ...) { va_list vl; int idx; va_start (vl,n); /* gpy_object_t is a typedef of gpy_object_state_t * to keep stdarg.h happy */ gpy_object_t * it = NULL; for (idx = 0; idxT == TYPE_OBJECT_STATE); gpy_rr_decr_ref_count (it); } va_end (vl); } gpy_object_t * gpy_rr_fold_call (gpy_callable_t * callables, const char * ident, int n, ...) { gpy_object_t * retval = NULL; return retval; } gpy_object_t * gpy_rr_eval_dot_operator (gpy_object_t * x, gpy_object_t * y) { return NULL; } gpy_object_t * gpy_rr_eval_expression (gpy_object_t * x1, gpy_object_t * y1, gpy_opcode_t op) { char * op_str = NULL; gpy_object_t * retval = NULL; gpy_assert(x1->T == TYPE_OBJECT_STATE); gpy_assert(y1->T == TYPE_OBJECT_STATE); gpy_object_state_t * x = x1->o.object_state; gpy_object_state_t * y = y1->o.object_state; struct gpy_typedef_t * def = x1->o.object_state->definition; struct gpy_number_prot_t * binops = (*def).binary_protocol; struct gpy_number_prot_t binops_l = (*binops); debug ("Eval expression!\n"); if( binops_l.init ) { binary_op o = NULL; switch( op ) { case OP_BIN_ADDITION: o = binops_l.n_add; op_str = "+ "; break; default: fatal("unhandled binary operation <%x>!\n", op ); break; } #ifdef DEBUG x->definition->print_hook( x1, stdout, false ); fprintf(stdout, "%s", op_str ); y->definition->print_hook( y1, stdout, true ); #endif retval = o(x1,y1); #ifdef DEBUG if( retval ) { fprintf(stdout, "evaluated to: "); retval->o.object_state->definition->print_hook (retval, stdout, false); fprintf(stdout, "!\n"); } #endif } else { fatal("object type <%s> has no binary protocol!\n", x->obj_t_ident ); } return retval; }