cvs commit: mod_parrot apache.ops apache.pmc
[email protected] 3 Sep 2002 16:02:51 -0000
Newsgroups
perl.cvs.mod_parrot
Message-ID
<[email protected] >
cvsuser 02/09/03 09:02:51
Modified: . apache.ops apache.pmc
Log:
The PMC structures have changed quite a bit in the last month
This brings apache.ops up to date to use the PMC key rather than the old
fashioned KEY struct (this is much cleaner)
It also make apache.pmc compile again by pruning dead vtable methods,
and adding all the new ones.
Revision Changes Path
1.4 +3 -9 mod_parrot/apache.ops
Index: apache.ops
===================================================================
RCS file: /cvs/public/mod_parrot/apache.ops,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -w -r1.3 -r1.4
--- apache.ops 29 May 2002 17:28:47 -0000 1.3
+++ apache.ops 3 Sep 2002 16:02:51 -0000 1.4
@@ -1,25 +1,19 @@
VERSION = PARROT_VERSION;
op ap_print (in PMC, in STR) {
- KEY *key = key_new(interpreter);
- key->atom.type = enum_key_string;
- key->atom.val.string_val = string_make(interpreter,"print",5,NULL,0,NULL);
+ PMC *key = key_new_string(interpreter, string_make(interpreter,"print",5,NULL,0,NULL));
($1->vtable->set_string_keyed)(interpreter, $1, key, $2);
goto NEXT();
}
op get_args (out STR, in PMC) {
- KEY *key = key_new(interpreter);
- key->atom.type = enum_key_string;
- key->atom.val.string_val = string_make(interpreter,"get",3,NULL,0,NULL);
+ PMC *key = key_new_string(interpreter, string_make(interpreter,"get",3,NULL,0,NULL));
$1 = ($2->vtable->get_string_keyed)(interpreter, $2, key);
goto NEXT();
}
op get_remoteip (out STR, in PMC) {
- KEY *key = key_new(interpreter);
- key->atom.type = enum_key_string;
- key->atom.val.string_val = string_make(interpreter,"remote_ip",9,NULL,0,NULL);
+ PMC *key = key_new_string(interpreter, string_make(interpreter,"remote_ip",9,NULL,0,NULL));
$1 = ($2->vtable->get_string_keyed)(interpreter, $2, key);
goto NEXT();
}
1.4 +1824 -125 mod_parrot/apache.pmc
Index: apache.pmc
===================================================================
RCS file: /cvs/public/mod_parrot/apache.pmc,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -w -r1.3 -r1.4
--- apache.pmc 21 Jun 2002 01:05:16 -0000 1.3
+++ apache.pmc 3 Sep 2002 16:02:51 -0000 1.4
@@ -1,8 +1,9 @@
/* apache.pmc
- * CVS Info
- * $Id: apache.pmc,v 1.3 2002/06/21 01:05:16 falcone Exp $
+ * Copyright: (When this is determined...it will go here)
+ * CVS Info $Id: apache.pmc,v 1.4 2002/09/03 16:02:51 falcone Exp $
* Overview:
- * Access to the Apache r object
+ * These are the vtable functions for the ApachePMC class
+ * Provides access to Apache's r object
* Data Structure and Algorithms:
* History:
* Notes:
@@ -20,7 +21,7 @@
char* modparrot_getargs(void) { return NULL; }
char* modparrot_get_remoteip(void) { return NULL; }
-static STRING* get_args(Interp* interpreter, KEY * key) {
+static STRING* get_args(Interp* interpreter, PMC * key) {
char* args;
args = modparrot_getargs();
@@ -30,7 +31,7 @@
return string_make(interpreter,NULL,0,NULL,0,NULL);
}
-static STRING* get_remoteip(Interp* interpreter, KEY * key) {
+static STRING* get_remoteip(Interp* interpreter, PMC * key) {
char* remote_ip;
remote_ip = modparrot_get_remoteip();
@@ -40,125 +41,1823 @@
return string_make(interpreter,NULL,0,NULL,0,NULL);
}
-pmclass Apache {
+#define INT2KEY(i,k) ((k) ? key_new_integer((i), *(k)) : NULL)
+
+pmclass Apache noinit {
+
+ void init () {
+ }
+
+ void init_pmc (PMC* value) {
+ DYNSELF.init();
+ }
+
+ void morph (INTVAL type) {
+ }
+
+ /* The end of used parameter is passed into the mark_used function of
+ * the garbage collector.
+ */
+ PMC* mark (PMC* end_of_used_list) {
+ PANIC("custom_mark flag set but no custom mark routine defined");
+ return NULL;
+ }
+
+ void destroy () {
+ }
INTVAL type () {
- return enum_class_Apache;
+ return SELF->vtable->base_type;
}
- STRING* name () {
- return whoami;
+ INTVAL type_keyed (PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return 0;
}
- void init () {
- SELF->data=NULL;
+ INTVAL type_keyed_int (INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.type_keyed(r_key);
}
- INTVAL move_to (void * destination) {
+ UINTVAL subtype (INTVAL type) {
return 0;
}
- INTVAL real_size () {
+ UINTVAL subtype_keyed (PMC* key, INTVAL type) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
return 0;
}
- void destroy () {
+ UINTVAL subtype_keyed_int (INTVAL* key, INTVAL type) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.subtype_keyed(r_key, type);
+ }
+
+ STRING* name () {
+ return NULL;
+ }
+
+ STRING* name_keyed (PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return NULL;
+ }
+
+ STRING* name_keyed_int (INTVAL *key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.name_keyed(r_key);
+ }
+
+ PMC* clone () {
+ PMC* dest;
+ dest = pmc_new(INTERP, SELF->vtable->base_type);
+ memcpy(&dest->cache, &SELF->cache, sizeof(UnionVal));
+ dest->data = SELF->data;
+ return dest;
+ }
+
+ PMC* clone_keyed (PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return NULL;
+ }
+
+ PMC* clone_keyed_int (INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.clone_keyed(r_key);
+ }
+
+ PMC* find_method(STRING* method_name) {
+ return NULL;
+ }
+
+ PMC* find_method_keyed(PMC* key, STRING* method_name) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return NULL;
+ }
+
+ PMC* find_method_keyed_int(INTVAL *key, STRING* method_name) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.find_method_keyed(r_key, method_name);
}
INTVAL get_integer () {
- return (INTVAL)SELF->data;
+ return SELF->cache.int_val;
+ }
+
+ INTVAL get_integer_keyed (PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return 0;
+ }
+
+ INTVAL get_integer_keyed_int (INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.get_integer_keyed(r_key);
}
FLOATVAL get_number () {
- return (FLOATVAL)(INTVAL)SELF->data;
+ return SELF->cache.num_val;
+ }
+
+ FLOATVAL get_number_keyed (PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return 0.0;
+ }
+
+ FLOATVAL get_number_keyed_int (INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.get_number_keyed(r_key);
+ }
+
+ BIGNUM* get_bignum () {
+ return (BIGNUM*)SELF->cache.struct_val;
+ }
+
+ BIGNUM* get_bignum_keyed (PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return NULL;
+ }
+
+ BIGNUM* get_bignum_keyed_int (INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.get_bignum_keyed(r_key);
}
STRING* get_string () {
- STRING* ret;
- char *target=mem_sys_allocate(64);
+ STRING*s = string_copy(INTERP, SELF->cache.struct_val);
+ return s;
+ }
+
+ STRING* get_string_keyed (PMC* key) {
+ STRING* action = key->vtable->get_string(INTERP, key);
- /* XXX Dangerous if you have a 196-bit system or above
- (and if you do, you have too comfortable a life and
- deserve to be tormented by coredumps). */
- sprintf(target, "Apache=0x%p", SELF->data);
- ret=string_make(interpreter, target, strlen(target), 0, 0, 0);
+ /* should store these STRINGS premade for speed */
+ if (string_compare(INTERP,action,string_make(INTERP,"get",3,NULL,0,NULL)) == 0)
+ return get_args(INTERP,key);
+ else if (string_compare(INTERP,action,string_make(INTERP,"remote_ip",9,NULL,0,NULL)) == 0)
+ return get_remoteip(INTERP,key);
+ else
+ return string_make(INTERP,NULL,0,NULL,0,NULL);
+ }
- mem_sys_free(target);
- return ret;
+ STRING* get_string_keyed_int (INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.get_string_keyed(r_key);
}
INTVAL get_bool () {
- return (INTVAL)(SELF->data != NULL);
+ /* Everything has to be 0 */
+ if ( DYNSELF.get_integer() == 0
+ && DYNSELF.get_number() == 0.0
+ && string_bool(DYNSELF.get_string()) == 0
+ )
+ {
+ return 0;
+ }
+ return 1;
}
- void* get_value () {
- return SELF->data;
+ INTVAL get_bool_keyed (PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return 0;
+ }
+
+ INTVAL get_bool_keyed_int (INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.get_bool_keyed(r_key);
+ }
+
+ INTVAL elements () {
+ /* XXX maybe this should be one */
+ return 0;
+ }
+
+ INTVAL elements_keyed (PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return 0;
+ }
+
+ INTVAL elements_keyed_int (INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.elements_keyed(r_key);
+ }
+
+ PMC* get_pmc () {
+ return SELF;
+ }
+
+ PMC* get_pmc_keyed (PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return NULL;
+ }
+
+ PMC* get_pmc_keyed_int (INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.get_pmc_keyed(r_key);
}
INTVAL is_same (PMC* pmc2) {
- return (INTVAL)(SELF->vtable == pmc2->vtable && SELF->data == pmc2->data);
+ /* I think this should cover this correctly, is_same implies that
+ same B<data> used by each, but as meaning of data is a little
+ vtable reliant, I include that test as well */
+ return (INTVAL)(SELF->vtable == pmc2->vtable && &SELF->cache == &pmc2->cache);
+ }
+
+ INTVAL is_same_keyed (PMC* key, PMC* value, PMC* value_key) {
+ if (key == NULL) {
+ /* pmc2_key must not be null, else why did you call me? */
+ return SELF->vtable->is_same(INTERP, SELF, value->vtable->get_pmc_keyed(INTERP, value, value_key));
+ }
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return 0;
+ }
+
+ INTVAL is_same_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ return DYNSELF.is_same_keyed(r_key, value, r_value_key);
}
+ /* The set methods merely make the appropriate part of the cache
+ be what it should be, more complex behaviour is left as an
+ exercise for the inheriting class. */
+
void set_integer (PMC * value) {
- APACHE_ERROR;
+ SELF->cache.int_val = value->vtable->get_integer(INTERP, value);
}
void set_integer_native (INTVAL value) {
- APACHE_ERROR;
+ SELF->cache.int_val = value;
}
void set_integer_same (PMC * value) {
- APACHE_ERROR;
+ SELF->cache.int_val = value->vtable->get_integer(INTERP, value);
+ }
+
+ void set_integer_keyed (PMC* key, INTVAL value) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void set_integer_keyed_int (INTVAL* key, INTVAL value) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ SELF->vtable->set_integer_keyed(INTERP, SELF, r_key, value);
}
void set_number (PMC * value) {
- APACHE_ERROR;
+ SELF->cache.num_val = value->vtable->get_number(INTERP, value);
}
void set_number_native (FLOATVAL value) {
- APACHE_ERROR;
+ SELF->cache.num_val = value;
}
void set_number_same (PMC * value) {
- APACHE_ERROR;
+ SELF->cache.num_val = value->vtable->get_number(INTERP, value);
+ }
+
+ void set_number_keyed (PMC* key, FLOATVAL value) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void set_number_keyed_int (INTVAL* key, FLOATVAL value) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ SELF->vtable->set_number_keyed(INTERP, SELF, r_key, value);
+ }
+
+ void set_bignum (PMC* value) {
+ SELF->cache.struct_val = (DPOINTER*)value->vtable->get_bignum(INTERP, value);
+ }
+
+ void set_bignum_native (BIGNUM* value) {
+ SELF->cache.struct_val = (DPOINTER*)value;
+ }
+
+ void set_bignum_same (PMC* value) {
+ SELF->cache.struct_val = (DPOINTER*)value->vtable->get_bignum(INTERP, value);
+ }
+
+ void set_bignum_keyed (PMC* key, BIGNUM* value) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void set_bignum_keyed_int (INTVAL* key, BIGNUM* value) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ SELF->vtable->set_bignum_keyed(INTERP, SELF, r_key, value);
}
void set_string (PMC * value) {
- APACHE_ERROR;
+ SELF->cache.struct_val = value->vtable->get_string(INTERP, value);
}
void set_string_native (STRING * value) {
- APACHE_ERROR;
+ SELF->cache.struct_val = string_copy(INTERP, value);
}
- void set_string_unicode (STRING * value) {
- APACHE_ERROR;
+ void set_string_same (PMC* value) {
+ SELF->cache.struct_val = value->vtable->get_string(INTERP, value);
}
- void set_string_other (STRING * value) {
- APACHE_ERROR;
+ void set_string_keyed (PMC* key, STRING* string) {
+ modparrot_printf("%s\n", string_to_cstring(INTERP,string));
}
- void set_string_same (PMC * value) {
- APACHE_ERROR;
+ void set_string_keyed_int (INTVAL* key, STRING* string) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ SELF->vtable->set_string_keyed(INTERP, SELF, r_key, string);
}
- STRING* get_string_keyed (KEY * key) {
- STRING* action = (&(key->atom))->val.string_val;
+ void set_pmc (PMC* value) {
+ SELF->cache.struct_val = value->vtable->get_pmc(INTERP, value);
+ }
- /* should store these STRINGS premade for speed */
- if (string_compare(INTERP,action,string_make(INTERP,"get",3,NULL,0,NULL)) == 0)
- return get_args(INTERP,key);
- else if (string_compare(INTERP,action,string_make(INTERP,"remote_ip",9,NULL,0,NULL)) == 0)
- return get_remoteip(INTERP,key);
+ void set_pmc_keyed (PMC* key, PMC* value, PMC* value_key) {
+ /* Either key or value must NOT be NULL */
+ if (key == NULL)
+ SELF->vtable->set_pmc(INTERP, SELF, value->vtable->get_pmc_keyed(INTERP, value, value_key));
else
- return string_make(INTERP,NULL,0,NULL,0,NULL);
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void set_pmc_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ DYNSELF.set_pmc_keyed(r_key, value, r_value_key);
+ }
+
+ void set_same (PMC* value) {
+ SELF->cache = value->cache;
+ }
+
+ void set_same_keyed (PMC* dest_key, PMC* src, PMC* src_key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void set_same_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ DYNSELF.set_same_keyed(r_key, value, r_value_key);
+ }
+
+ INTVAL pop_integer() {
+ internal_exception(OUT_OF_BOUNDS, "Pop on something that's not an aggregate!\n");
+ return 0;
+ }
+
+ INTVAL pop_integer_keyed(PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return 0;
+ }
+
+ INTVAL pop_integer_keyed_int(INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.pop_integer_keyed(r_key);
+ }
+
+ FLOATVAL pop_float() {
+ internal_exception(OUT_OF_BOUNDS, "Pop on something that's not an aggregate!\n");
+ return 0.0;
+ }
+
+ FLOATVAL pop_float_keyed(PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return 0.0;
+ }
+
+ FLOATVAL pop_float_keyed_int(INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.pop_float_keyed(r_key);
+ }
+
+ BIGNUM* pop_bignum() {
+ internal_exception(OUT_OF_BOUNDS, "Pop on something that's not an aggregate!\n");
+ return NULL;
+ }
+
+ BIGNUM* pop_bignum_keyed(PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return NULL;
+ }
+
+ BIGNUM* pop_bignum_keyed_int(INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.pop_bignum_keyed(r_key);
+ }
+
+ STRING* pop_string() {
+ internal_exception(OUT_OF_BOUNDS, "Pop on something that's not an aggregate!\n");
+ return NULL;
+ }
+
+ STRING* pop_string_keyed(PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return NULL;
+ }
+
+ STRING* pop_string_keyed_int(INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.pop_string_keyed(r_key);
+ }
+
+ PMC* pop_pmc() {
+ internal_exception(OUT_OF_BOUNDS, "Pop on something that's not an aggregate!\n");
+ return NULL;
+ }
+
+ PMC* pop_pmc_keyed(PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return NULL;
+ }
+
+ PMC* pop_pmc_keyed_int(INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.pop_pmc_keyed(r_key);
+ }
+
+ void push_integer (INTVAL value) {
+ internal_exception(OUT_OF_BOUNDS, "Push on something that's not an aggregate!\n");
+ }
+
+ void push_integer_keyed (PMC* key, INTVAL value) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void push_integer_keyed_int (INTVAL* key, INTVAL value) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ DYNSELF.push_integer_keyed(r_key, value);
+ }
+
+ void push_float (FLOATVAL value) {
+ internal_exception(OUT_OF_BOUNDS, "Push on something that's not an aggregate!\n");
+ }
+
+ void push_float_keyed (PMC* key, FLOATVAL value) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void push_float_keyed_int (INTVAL* key, FLOATVAL value) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ DYNSELF.push_float_keyed(r_key, value);
+ }
+
+ void push_bignum (BIGNUM* value) {
+ internal_exception(OUT_OF_BOUNDS, "Push on something that's not an aggregate!\n");
+ }
+
+ void push_bignum_keyed (PMC* key, BIGNUM* value) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void push_bignum_keyed_int (INTVAL* key, BIGNUM* value) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ DYNSELF.push_bignum_keyed(r_key, value);
+ }
+
+ void push_string (STRING* value) {
+ internal_exception(OUT_OF_BOUNDS, "Push on something that's not an aggregate!\n");
+ }
+
+ void push_string_keyed (PMC* key, STRING* value) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void push_string_keyed_int (INTVAL* key, STRING* value) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ DYNSELF.push_string_keyed(r_key, value);
+ }
+
+ void push_pmc (PMC* value) {
+ internal_exception(OUT_OF_BOUNDS, "Push on something that's not an aggregate!\n");
+ }
+
+ void push_pmc_keyed (PMC* key, PMC* value, PMC* value_key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void push_pmc_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ DYNSELF.push_pmc_keyed(r_key, value, r_value_key);
+ }
+
+ INTVAL shift_integer() {
+ internal_exception(OUT_OF_BOUNDS, "Shift on something that's not an aggregate!\n");
+ return 0;
+ }
+
+ INTVAL shift_integer_keyed(PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return 0;
+ }
+
+ INTVAL shift_integer_keyed_int(INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.shift_integer_keyed(r_key);
+ }
+
+ FLOATVAL shift_float() {
+ internal_exception(OUT_OF_BOUNDS, "Shift on something that's not an aggregate!\n");
+ return 0.0;
+ }
+
+ FLOATVAL shift_float_keyed(PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return 0.0;
+ }
+
+ FLOATVAL shift_float_keyed_int(INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.shift_float_keyed(r_key);
+ }
+
+ BIGNUM* shift_bignum() {
+ internal_exception(OUT_OF_BOUNDS, "Shift on something that's not an aggregate!\n");
+ return NULL;
+ }
+
+ BIGNUM* shift_bignum_keyed(PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return NULL;
+ }
+
+ BIGNUM* shift_bignum_keyed_int(INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.shift_bignum_keyed(r_key);
+ }
+
+ STRING* shift_string() {
+ internal_exception(OUT_OF_BOUNDS, "Shift on something that's not an aggregate!\n");
+ return NULL;
+ }
+
+ STRING* shift_string_keyed(PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return NULL;
+ }
+
+ STRING* shift_string_keyed_int(INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.shift_string_keyed(r_key);
+ }
+
+ PMC* shift_pmc() {
+ internal_exception(OUT_OF_BOUNDS, "Shift on something that's not an aggregate!\n");
+ return NULL;
+ }
+
+ PMC* shift_pmc_keyed(PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return NULL;
+ }
+
+ PMC* shift_pmc_keyed_int(INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.shift_pmc_keyed(r_key);
+ }
+
+ void unshift_integer (INTVAL value) {
+ internal_exception(OUT_OF_BOUNDS, "Unshift on something that's not an aggregate!\n");
+ }
+
+ void unshift_integer_keyed (PMC* key, INTVAL value) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void unshift_integer_keyed_int (INTVAL* key, INTVAL value) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ DYNSELF.unshift_integer_keyed(r_key, value);
+ }
+
+ void unshift_float (FLOATVAL value) {
+ internal_exception(OUT_OF_BOUNDS, "Unshift on something that's not an aggregate!\n");
+ }
+
+ void unshift_float_keyed (PMC* key, FLOATVAL value) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void unshift_float_keyed_int (INTVAL* key, FLOATVAL value) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ DYNSELF.unshift_float_keyed(r_key, value);
+ }
+
+ void unshift_bignum (BIGNUM* value) {
+ internal_exception(OUT_OF_BOUNDS, "Unshift on something that's not an aggregate!\n");
+ }
+
+ void unshift_bignum_keyed (PMC* key, BIGNUM* value) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void unshift_bignum_keyed_int (INTVAL* key, BIGNUM* value) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ DYNSELF.unshift_bignum_keyed(r_key, value);
+ }
+
+ void unshift_string (STRING* value) {
+ internal_exception(OUT_OF_BOUNDS, "Unshift on something that's not an aggregate!\n");
+ }
+
+ void unshift_string_keyed (PMC* key, STRING* value) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void unshift_string_keyed_int (INTVAL* key, STRING* value) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ DYNSELF.unshift_string_keyed(r_key, value);
+ }
+
+ void unshift_pmc (PMC* value) {
+ internal_exception(OUT_OF_BOUNDS, "Unshift on something that's not an aggregate!\n");
+ }
+
+ void unshift_pmc_keyed (PMC* key, PMC* value, PMC* value_key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void unshift_pmc_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ DYNSELF.unshift_pmc_keyed(r_key, value, r_value_key);
+ }
+
+ void add (PMC* value, PMC* dest) {
+ /* XXX: overflow detection, bignum promotion? */
+
+ FLOATVAL result;
+
+ result = DYNSELF.get_number()
+ + value->vtable->get_number(INTERP, value);
+
+ dest->vtable->set_number_native(INTERP, dest, result);
}
- void set_string_keyed (KEY * key, STRING * value) {
- modparrot_printf("%s\n", string_to_cstring(INTERP,value));
+ void add_int (INTVAL value, PMC* dest) {
+ /* dest = SELF + value */
+ /* XXX: overflow detection, bignum promotion? */
+
+ FLOATVAL result;
+
+ result = DYNSELF.get_number()
+ + value;
+
+ dest->vtable->set_number_native(INTERP, dest, result);
}
- void set_value (void * value) {
+ void add_bignum (BIGNUM* value, PMC* dest) {
+ /* XXX: bignum magic */
+ }
+
+ void add_float (FLOATVAL value, PMC* dest) {
+ /* dest = SELF + value */
+ /* XXX: overflow detection, bignum promotion? */
+
+ FLOATVAL result;
+
+ result = DYNSELF.get_number()
+ + value;
+
+ dest->vtable->set_number_native(INTERP, dest, result);
+ }
+
+ void add_same (PMC* value, PMC* dest) {
+ /* XXX: overflow detection, bignum promotion? */
+
+ FLOATVAL result;
+
+ result = DYNSELF.get_number()
+ + value->vtable->get_number(INTERP, value);
+
+ dest->vtable->set_number_native(INTERP, dest, result);
+ }
+
+ void add_keyed (PMC* key, PMC* value, PMC* value_key,
+ PMC* dest, PMC* dest_key) {
+
+ /* At least one key MUST NOT be NULL */
+
+ if (key == NULL) {
+ FLOATVAL result;
+
+ result = DYNSELF.get_number() + (
+ value_key == NULL ?
+ value->vtable->get_number(INTERP, value) :
+ value->vtable->get_number_keyed(INTERP, value, value_key)
+ );
+
+ if (dest_key == NULL)
+ dest->vtable->set_number_native(INTERP, dest, result);
+ else
+ dest->vtable->set_number_keyed(INTERP, dest, dest_key, result);
+ }
+ else
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void add_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ PMC* r_dest_key = INT2KEY(INTERP, dest_key);
+
+ DYNSELF.add_keyed(r_key, value, r_value_key, dest, r_dest_key);
+ }
+
+ void subtract (PMC* value, PMC* dest) {
+ /* XXX: overflow detection, bignum promotion? */
+
+ FLOATVAL result;
+
+ result = DYNSELF.get_number()
+ - value->vtable->get_number(INTERP, value);
+
+ dest->vtable->set_number_native(INTERP, dest, result);
+ }
+
+ void subtract_int (INTVAL value, PMC* dest) {
+ /* dest = SELF - value */
+ /* XXX: overflow detection, bignum promotion? */
+
+ FLOATVAL result;
+
+ result = DYNSELF.get_number()
+ - value;
+
+ dest->vtable->set_number_native(INTERP, dest, result);
+ }
+
+ void subtract_bignum (BIGNUM* value, PMC* dest) {
+ /* XXX: bignum magic */
+ }
+
+ void subtract_float (FLOATVAL value, PMC* dest) {
+ /* dest = SELF - value */
+ /* XXX: overflow detection, bignum promotion? */
+
+ FLOATVAL result;
+
+ result = DYNSELF.get_number()
+ - value;
+
+ dest->vtable->set_number_native(INTERP, dest, result);
+ }
+
+ void subtract_same (PMC* value, PMC* dest) {
+ /* XXX: overflow detection, bignum promotion? */
+
+ FLOATVAL result;
+
+ result = DYNSELF.get_number()
+ - value->vtable->get_number(INTERP, value);
+
+ dest->vtable->set_number_native(INTERP, dest, result);
+ }
+
+ void subtract_keyed (PMC* key, PMC* value, PMC* value_key,
+ PMC* dest, PMC* dest_key) {
+
+ /* At least one key MUST NOT be NULL */
+
+ if (key == NULL) {
+ FLOATVAL result;
+
+ result = DYNSELF.get_number() - (
+ value_key == NULL ?
+ value->vtable->get_number(INTERP, value) :
+ value->vtable->get_number_keyed(INTERP, value, value_key)
+ );
+
+ if (dest_key == NULL)
+ dest->vtable->set_number_native(INTERP, dest, result);
+ else
+ dest->vtable->set_number_keyed(INTERP, dest, dest_key, result);
+ }
+ else
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void subtract_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ PMC* r_dest_key = INT2KEY(INTERP, dest_key);
+
+ DYNSELF.subtract_keyed(r_key, value, r_value_key, dest, r_dest_key);
+ }
+
+ void multiply (PMC* value, PMC* dest) {
+ /* XXX: overflow detection, bignum promotion? */
+
+ FLOATVAL result;
+
+ result = DYNSELF.get_number()
+ * value->vtable->get_number(INTERP, value);
+
+ dest->vtable->set_number_native(INTERP, dest, result);
+ }
+
+ void multiply_int (INTVAL value, PMC* dest) {
+ /* XXX: overflow detection, bignum promotion? */
+
+ FLOATVAL result;
+
+ result = DYNSELF.get_number()
+ * value;
+
+ dest->vtable->set_number_native(INTERP, dest, result);
+ }
+
+ void multiply_bignum (BIGNUM* value, PMC* dest) {
+ /* XXX: bignum magic */
+ }
+
+ void multiply_float (FLOATVAL value, PMC* dest) {
+ /* XXX: overflow detection, bignum promotion? */
+
+ FLOATVAL result;
+
+ result = DYNSELF.get_number()
+ * value;
+
+ dest->vtable->set_number_native(INTERP, dest, result);
+ }
+
+ void multiply_same (PMC* value, PMC* dest) {
+ /* XXX: overflow detection, bignum promotion? */
+
+ FLOATVAL result;
+
+ result = DYNSELF.get_number()
+ * value->vtable->get_number(INTERP, value);
+
+ dest->vtable->set_number_native(INTERP, dest, result);
+ }
+
+ void multiply_keyed (PMC* key, PMC* value, PMC* value_key,
+ PMC* dest, PMC* dest_key) {
+
+ /* At least one key MUST NOT be NULL */
+
+ if (key == NULL) {
+ FLOATVAL result;
+
+ result = DYNSELF.get_number() * (
+ value_key == NULL ?
+ value->vtable->get_number(INTERP, value) :
+ value->vtable->get_number_keyed(INTERP, value, value_key)
+ );
+
+ if (dest_key == NULL)
+ dest->vtable->set_number_native(INTERP, dest, result);
+ else
+ dest->vtable->set_number_keyed(INTERP, dest, dest_key, result);
+ }
+ else
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void multiply_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ PMC* r_dest_key = INT2KEY(INTERP, dest_key);
+
+ DYNSELF.multiply_keyed(r_key, value, r_value_key, dest, r_dest_key);
+ }
+
+ void divide (PMC* value, PMC* dest) {
+ /* XXX: overflow detection, bignum promotion? */
+
+ FLOATVAL result;
+
+ result = DYNSELF.get_number()
+ / value->vtable->get_number(INTERP, value);
+
+ dest->vtable->set_number_native(INTERP, dest, result);
+ }
+
+ void divide_int (INTVAL value, PMC* dest) {
+ /* dest = SELF / value */
+
+ /* XXX: overflow detection, bignum promotion? */
+
+ FLOATVAL result;
+
+ result = DYNSELF.get_number()
+ / value;
+
+ dest->vtable->set_number_native(INTERP, dest, result);
+ }
+
+ void divide_bignum (BIGNUM* value, PMC* dest) {
+ /* XXX: bignum magic */
+ }
+
+ void divide_float (FLOATVAL value, PMC* dest) {
+ /* dest = SELF / value */
+
+ /* XXX: overflow detection, bignum promotion? */
+
+ FLOATVAL result;
+
+ result = DYNSELF.get_number()
+ / value;
+
+ dest->vtable->set_number_native(INTERP, dest, result);
+ }
+
+ void divide_same (PMC* value, PMC* dest) {
+ /* XXX: overflow detection, bignum promotion? */
+
+ FLOATVAL result;
+
+ result = DYNSELF.get_number()
+ / value->vtable->get_number(INTERP, value);
+
+ dest->vtable->set_number_native(INTERP, dest, result);
+ }
+
+ void divide_keyed (PMC* key, PMC* value, PMC* value_key,
+ PMC* dest, PMC* dest_key) {
+
+ /* At least one key MUST NOT be NULL */
+
+ if (key == NULL) {
+ FLOATVAL result;
+
+ result = DYNSELF.get_number() / (
+ value_key == NULL ?
+ value->vtable->get_number(INTERP, value) :
+ value->vtable->get_number_keyed(INTERP, value, value_key)
+ );
+
+ if (dest_key == NULL)
+ dest->vtable->set_number_native(INTERP, dest, result);
+ else
+ dest->vtable->set_number_keyed(INTERP, dest, dest_key, result);
+ }
+ else
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void divide_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ PMC* r_dest_key = INT2KEY(INTERP, dest_key);
+
+ DYNSELF.divide_keyed(r_key, value, r_value_key, dest, r_dest_key);
+ }
+
+ void modulus (PMC* value, PMC* dest) {
+ /* This does perl-like modulus */
+
+ INTVAL result;
+
+ result = DYNSELF.get_integer()
+ % value->vtable->get_integer(INTERP, value);
+
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ }
+
+ void modulus_int (INTVAL value, PMC* dest) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer()
+ % value;
+
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ }
+
+ void modulus_bignum (BIGNUM* value, PMC* dest) {
+ /* XXX: Can't sleep, clown'll eat me */
+ }
+
+ void modulus_float (FLOATVAL value, PMC* dest) {
+ /* XXX: makes all arguments integers...*/
+ INTVAL result;
+
+ result = DYNSELF.get_integer()
+ % (INTVAL)value;
+
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ }
+
+ void modulus_same (PMC* value, PMC* dest) {
+ /* This does perl-like modulus */
+ INTVAL result;
+
+ result = DYNSELF.get_integer()
+ % value->vtable->get_integer(INTERP, value);
+
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ }
+
+ void modulus_keyed (PMC* key, PMC* value, PMC* value_key,
+ PMC* dest, PMC* dest_key) {
+
+ /* At least one key MUST NOT be NULL */
+
+ if (key == NULL) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer() % (
+ value_key == NULL ?
+ value->vtable->get_integer(INTERP, value) :
+ value->vtable->get_integer_keyed(INTERP, value, value_key)
+ );
+
+ if (dest_key == NULL)
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ else
+ dest->vtable->set_integer_keyed(INTERP, dest, dest_key, result);
+ }
+ else
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void modulus_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ PMC* r_dest_key = INT2KEY(INTERP, dest_key);
+
+ DYNSELF.modulus_keyed(r_key, value, r_value_key, dest, r_dest_key);
+ }
+
+ void neg (PMC* dest) {
+ dest->vtable->set_integer_native(INTERP, dest, -DYNSELF.get_integer());
+ }
+
+ void neg_keyed (PMC* key, PMC* dest, PMC* dest_key) {
+ if (key == NULL)
+ dest->vtable->set_integer_keyed(INTERP, dest,
+ dest_key, -DYNSELF.get_integer());
+ else
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void neg_keyed_int (INTVAL* key, PMC* dest, INTVAL* dest_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_dest_key = INT2KEY(INTERP, dest_key);
+ DYNSELF.neg_keyed(r_key, dest, r_dest_key);
+ }
+
+ void bitwise_or (PMC* value, PMC* dest) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer()
+ | value->vtable->get_integer(INTERP, value);
+
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ }
+
+ void bitwise_or_int (INTVAL value, PMC* dest) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer()
+ | value;
+
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ }
+
+ void bitwise_or_same (PMC* value, PMC* dest) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer()
+ | value->vtable->get_integer(INTERP, value);
+
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ }
+
+ void bitwise_or_keyed (PMC* key, PMC* value, PMC* value_key,
+ PMC* dest, PMC* dest_key) {
+
+ /* At least one key MUST NOT be NULL */
+
+ if (key == NULL) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer() | (
+ value_key == NULL ?
+ value->vtable->get_integer(INTERP, value) :
+ value->vtable->get_integer_keyed(INTERP, value, value_key)
+ );
+
+ if (dest_key == NULL)
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ else
+ dest->vtable->set_integer_keyed(INTERP, dest, dest_key, result);
+ }
+ else
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void bitwise_or_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ PMC* r_dest_key = INT2KEY(INTERP, dest_key);
+
+ DYNSELF.bitwise_or_keyed(r_key, value, r_value_key, dest, r_dest_key);
+ }
+
+ void bitwise_and (PMC* value, PMC* dest) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer()
+ & value->vtable->get_integer(INTERP, value);
+
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ }
+
+ void bitwise_and_int (INTVAL value, PMC* dest) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer()
+ & value;
+
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ }
+
+ void bitwise_and_same (PMC* value, PMC* dest) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer()
+ & value->vtable->get_integer(INTERP, value);
+
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ }
+
+ void bitwise_and_keyed (PMC* key, PMC* value, PMC* value_key,
+ PMC* dest, PMC* dest_key) {
+
+ /* At least one key MUST NOT be NULL */
+
+ if (key == NULL) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer() & (
+ value_key == NULL ?
+ value->vtable->get_integer(INTERP, value) :
+ value->vtable->get_integer_keyed(INTERP, value, value_key)
+ );
+
+ if (dest_key == NULL)
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ else
+ dest->vtable->set_integer_keyed(INTERP, dest, dest_key, result);
+ }
+ else
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void bitwise_and_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ PMC* r_dest_key = INT2KEY(INTERP, dest_key);
+
+ DYNSELF.bitwise_and_keyed(r_key, value, r_value_key, dest, r_dest_key);
+ }
+
+ void bitwise_xor (PMC* value, PMC* dest) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer()
+ ^ value->vtable->get_integer(INTERP, value);
+
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ }
+
+ void bitwise_xor_int (INTVAL value, PMC* dest) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer()
+ ^ value;
+
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ }
+
+ void bitwise_xor_same (PMC* value, PMC* dest) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer()
+ ^ value->vtable->get_integer(INTERP, value);
+
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ }
+
+ void bitwise_xor_keyed (PMC* key, PMC* value, PMC* value_key,
+ PMC* dest, PMC* dest_key) {
+
+ /* At least one key MUST NOT be NULL */
+
+ if (key == NULL) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer() ^ (
+ value_key == NULL ?
+ value->vtable->get_integer(INTERP, value) :
+ value->vtable->get_integer_keyed(INTERP, value, value_key)
+ );
+
+ if (dest_key == NULL)
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ else
+ dest->vtable->set_integer_keyed(INTERP, dest, dest_key, result);
+ }
+ else
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void bitwise_xor_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ PMC* r_dest_key = INT2KEY(INTERP, dest_key);
+
+ DYNSELF.bitwise_xor_keyed(r_key, value, r_value_key, dest, r_dest_key);
+ }
+
+ void bitwise_not (PMC* dest) {
+ dest->vtable->set_integer_native(INTERP, dest, ~DYNSELF.get_integer());
+ }
+
+ void bitwise_not_keyed (PMC* key, PMC* dest, PMC* dest_key) {
+ if (key == NULL)
+ dest->vtable->set_integer_keyed(INTERP, dest,
+ dest_key, ~DYNSELF.get_integer());
+ else
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void bitwise_not_keyed_int (INTVAL* key, PMC* dest, INTVAL* dest_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_dest_key = INT2KEY(INTERP, dest_key);
+ DYNSELF.bitwise_not_keyed(r_key, dest, r_dest_key);
+ }
+
+ void bitwise_shr (PMC* value, PMC* dest) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer()
+ >> value->vtable->get_integer(INTERP, value);
+
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ }
+
+ void bitwise_shr_int (INTVAL value, PMC* dest) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer()
+ >> value;
+
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ }
+
+ void bitwise_shr_same (PMC* value, PMC* dest) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer()
+ >> value->vtable->get_integer(INTERP, value);
+
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ }
+
+ void bitwise_shr_keyed (PMC* key, PMC* value, PMC* value_key,
+ PMC* dest, PMC* dest_key) {
+
+ /* At least one key MUST NOT be NULL */
+
+ if (key == NULL) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer() >> (
+ value_key == NULL ?
+ value->vtable->get_integer(INTERP, value) :
+ value->vtable->get_integer_keyed(INTERP, value, value_key)
+ );
+
+ if (dest_key == NULL)
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ else
+ dest->vtable->set_integer_keyed(INTERP, dest, dest_key, result);
+ }
+ else
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void bitwise_shr_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ PMC* r_dest_key = INT2KEY(INTERP, dest_key);
+
+ DYNSELF.bitwise_shr_keyed(r_key, value, r_value_key, dest, r_dest_key);
+ }
+
+ void bitwise_shl (PMC* value, PMC* dest) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer()
+ << value->vtable->get_integer(INTERP, value);
+
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ }
+
+ void bitwise_shl_int (INTVAL value, PMC* dest) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer()
+ << value;
+
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ }
+
+ void bitwise_shl_same (PMC* value, PMC* dest) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer()
+ << value->vtable->get_integer(INTERP, value);
+
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ }
+
+ void bitwise_shl_keyed (PMC* key, PMC* value, PMC* value_key,
+ PMC* dest, PMC* dest_key) {
+
+ /* At least one key MUST NOT be NULL */
+
+ if (key == NULL) {
+ INTVAL result;
+
+ result = DYNSELF.get_integer() << (
+ value_key == NULL ?
+ value->vtable->get_integer(INTERP, value) :
+ value->vtable->get_integer_keyed(INTERP, value, value_key)
+ );
+
+ if (dest_key == NULL)
+ dest->vtable->set_integer_native(INTERP, dest, result);
+ else
+ dest->vtable->set_integer_keyed(INTERP, dest, dest_key, result);
+ }
+ else
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void bitwise_shl_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ PMC* r_dest_key = INT2KEY(INTERP, dest_key);
+
+ DYNSELF.bitwise_shl_keyed(r_key, value, r_value_key, dest, r_dest_key);
+ }
+
+ void concatenate (PMC* value, PMC* dest) {
+ STRING* s = string_concat(INTERP,
+ DYNSELF.get_string(),
+ value->vtable->get_string(INTERP, value), 0);
+
+ dest->vtable->set_string_native(INTERP, dest, s);
+ }
+
+ void concatenate_native (STRING* value, PMC* dest) {
+ /* dest = SELF (concat) value */
+ STRING* s = string_concat(INTERP,
+ DYNSELF.get_string(),
+ value, 0);
+
+ dest->vtable->set_string_native(INTERP, dest, s);
+ }
+
+ void concatenate_same (PMC* value, PMC* dest) {
+ STRING* s = string_concat(INTERP,
+ DYNSELF.get_string(),
+ value->vtable->get_string(INTERP, value), 0);
+
+ dest->vtable->set_string_native(INTERP, dest, s);
+ }
+
+ void concatenate_keyed (PMC* key, PMC* value, PMC* value_key,
+ PMC* dest, PMC* dest_key) {
+
+ /* At least one key MUST NOT be NULL */
+
+ if (key == NULL) {
+
+ STRING* result;
+
+ if (value_key == NULL)
+ result = string_concat(INTERP,
+ DYNSELF.get_string(),
+ value->vtable->get_string(INTERP, value), 0);
+ else
+ result = string_concat(INTERP,
+ DYNSELF.get_string(),
+ value->vtable->get_string_keyed(INTERP, value, value_key), 0);
+
+ if (dest_key == NULL)
+ dest->vtable->set_string_native(INTERP, dest, result);
+ else
+ dest->vtable->set_string_keyed(INTERP, dest, dest_key, result);
+ }
+ else
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void concatenate_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ PMC* r_dest_key = INT2KEY(INTERP, dest_key);
+
+ DYNSELF.concatenate_keyed(r_key, value, r_value_key, dest, r_dest_key);
+ }
+
+ INTVAL is_equal (PMC* value) {
+ /* I think we need to check everything, do the easiest first... */
+ if (DYNSELF.get_integer()
+ == value->vtable->get_integer(INTERP, value)
+ && DYNSELF.get_number()
+ == value->vtable->get_number(INTERP, value)
+ && 0 == string_compare(INTERP,
+ DYNSELF.get_string(),
+ value->vtable->get_string(INTERP, value))
+ )
+ {
+ return 1;
+ }
+ return 0;
+ }
+
+ INTVAL is_equal_keyed (PMC* key, PMC* value, PMC* value_key) {
+ if (key == NULL) {
+ if (DYNSELF.get_integer()
+ == value->vtable->get_integer_keyed(INTERP, value, value_key)
+ && DYNSELF.get_number()
+ == value->vtable->get_number_keyed(INTERP, value, value_key)
+ && 0 == string_compare(INTERP,
+ DYNSELF.get_string(),
+ value->vtable->get_string_keyed(INTERP, value, value_key))
+ )
+ {
+ return 1;
+ }
+ return 0;
+ }
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return 0;
+ }
+
+ INTVAL is_equal_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ return DYNSELF.is_equal_keyed(r_key, value, r_value_key);
+ }
+
+ INTVAL cmp (PMC* value) {
+ /* XXX: What does this mean for this class? */
+ return 0;
+ }
+
+ INTVAL cmp_keyed (PMC* key, PMC* value, PMC* value_key) {
+ if (key == NULL)
+ /* XXX: What does this mean for this class? */
+ return 0;
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return 0;
+ }
+
+ INTVAL cmp_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ return DYNSELF.cmp_keyed(r_key, value, r_value_key);
+ }
+
+ INTVAL cmp_num (PMC* value) {
+ /* XXX - Floating-point precision errors possible? */
+ FLOATVAL diff = value->vtable->get_number(INTERP, value) -
+ DYNSELF.get_number();
+
+ return diff == 0.0 ? 0 : diff < 0.0 ? -1 : 1;
+ }
+
+ INTVAL cmp_num_keyed (PMC* key, PMC* value, PMC* value_key) {
+ if (key == NULL) {
+ /* XXX - Floating-point precision errors possible? */
+ FLOATVAL diff = value->vtable->get_number_keyed(INTERP, value, value_key) -
+ DYNSELF.get_number();
+
+ return diff == 0.0 ? 0 : diff < 0.0 ? -1 : 1;
+ }
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return 0;
+ }
+
+ INTVAL cmp_num_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ return DYNSELF.cmp_num_keyed(r_key, value, r_value_key);
+ }
+
+ INTVAL cmp_string (PMC* value) {
+ return string_compare(INTERP, DYNSELF.get_string(),
+ value->vtable->get_string(INTERP, value));
+ }
+
+ INTVAL cmp_string_keyed (PMC* key, PMC* value, PMC* value_key) {
+ if (key == NULL)
+ return string_compare(INTERP, DYNSELF.get_string(),
+ value->vtable->get_string_keyed(INTERP, value, value_key));
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return 0;
+ }
+
+ INTVAL cmp_string_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ return DYNSELF.cmp_string_keyed(r_key, value, r_value_key);
+ }
+
+ void logical_or (PMC* value, PMC* dest) {
+ if (DYNSELF.get_bool()) {
+ dest->vtable->set_pmc(INTERP, dest, SELF);
+ }
+ else {
+ dest->vtable->set_pmc(INTERP, dest, value);
+ }
+ }
+
+ void logical_or_keyed (PMC* key, PMC* value, PMC* value_key, PMC* dest, PMC* dest_key) {
+ if (key == NULL) {
+ if (DYNSELF.get_bool()) {
+ if (dest_key != NULL)
+ dest->vtable->set_pmc_keyed(INTERP, dest, dest_key, SELF, NULL);
+ else
+ dest->vtable->set_pmc(INTERP, dest, SELF);
+ }
+ else
+ /* Either value_key or dest_key is not NULL */
+ dest->vtable->set_pmc_keyed(INTERP, dest, dest_key, value, value_key);
+ }
+ else
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void logical_or_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ PMC* r_dest_key = INT2KEY(INTERP, dest_key);
+
+ DYNSELF.logical_or_keyed(r_key, value, r_value_key, dest, r_dest_key);
+ }
+
+ void logical_and (PMC* value, PMC* dest) {
+ if (DYNSELF.get_bool()) {
+ dest->vtable->set_pmc(INTERP, dest, value);
+ }
+ else {
+ dest->vtable->set_pmc(INTERP, dest, SELF);
+ }
+ }
+
+ void logical_and_keyed (PMC* key, PMC* value, PMC* value_key, PMC* dest, PMC* dest_key) {
+ if (key == NULL) {
+ if (DYNSELF.get_bool())
+ /* Either value_key or dest_key is not NULL */
+ dest->vtable->set_pmc_keyed(INTERP, dest, dest_key, value, value_key);
+ else {
+ if (dest_key != NULL)
+ dest->vtable->set_pmc_keyed(INTERP, dest, dest_key, SELF, NULL);
+ else
+ dest->vtable->set_pmc(INTERP, dest, SELF);
+ }
+ }
+ else
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void logical_and_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ PMC* r_dest_key = INT2KEY(INTERP, dest_key);
+
+ DYNSELF.logical_and_keyed(r_key, value, r_value_key, dest, r_dest_key);
+ }
+
+ void logical_xor (PMC* value, PMC* dest) {
+
+ INTVAL my_bool, value_bool;
+
+ my_bool = DYNSELF.get_bool();
+ value_bool = value->vtable->get_bool(INTERP, value);
+
+ if (my_bool && ! value_bool) {
+ dest->vtable->set_pmc(INTERP, dest, SELF);
+ }
+ else if (value_bool && ! my_bool) {
+ dest->vtable->set_pmc(INTERP, dest, value);
+ }
+ else {
+ /* XXX - Need a better way to set FALSE */
+ dest->vtable->set_integer_native(INTERP, dest, 0);
+ }
+ }
+
+ void logical_xor_keyed (PMC* key, PMC* value, PMC* value_key, PMC* dest, PMC* dest_key) {
+
+ if (key == NULL) {
+
+ INTVAL my_bool, value_bool;
+
+ my_bool = DYNSELF.get_bool();
+
+ if (value_key == NULL)
+ value_bool = value->vtable->get_bool(INTERP, value);
+ else
+ value_bool = value->vtable->get_bool_keyed(INTERP, value, value_key);
+
+ if (my_bool && ! value_bool) {
+ if (dest_key == NULL)
+ dest->vtable->set_pmc(INTERP, dest, SELF);
+ else
+ dest->vtable->set_pmc_keyed(INTERP, dest, dest_key, SELF, NULL);
+ }
+ else if (value_bool && ! my_bool) {
+ /* Either dest_key or value_key must be non-NULL */
+ dest->vtable->set_pmc_keyed(INTERP, dest, dest_key, value, value_key);
+ }
+ else {
+ /* XXX - Need a better way to set FALSE */
+ if (dest_key == NULL)
+ dest->vtable->set_integer_native(INTERP, dest, 0);
+ else
+ dest->vtable->set_integer_keyed(INTERP, dest, dest_key, 0);
+ }
+ }
+ else
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+
+ void logical_xor_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ PMC* r_dest_key = INT2KEY(INTERP, dest_key);
+
+ DYNSELF.logical_xor_keyed(r_key, value, r_value_key, dest, r_dest_key);
+ }
+
+ void logical_not (PMC* dest) {
+ /* XXX - Need a better way to set boolean state */
+ dest->vtable->set_integer_native(INTERP, dest,
+ ! DYNSELF.get_bool());
+ }
+
+ void logical_not_keyed (PMC* key, PMC* dest, PMC* dest_key) {
+ /* XXX - Need a better way to set boolean state */
+ if (key == NULL)
+ dest->vtable->set_integer_keyed(INTERP, dest,
+ dest_key, ! DYNSELF.get_bool());
+ else
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void logical_not_keyed_int (INTVAL* key, PMC* dest, INTVAL* dest_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_dest_key = INT2KEY(INTERP, dest_key);
+ DYNSELF.logical_not_keyed(r_key, dest, r_dest_key);
+ }
+
+ void repeat (PMC* value, PMC* dest) {
+ dest->vtable->set_string_native(INTERP, dest,
+ string_repeat(INTERP, SELF->vtable->get_string(INTERP,SELF),
+ (UINTVAL)value->vtable->get_integer(INTERP, value), NULL) );
+ }
+
+ void repeat_keyed (PMC* key, PMC* value, PMC* value_key, PMC* dest, PMC* dest_key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void repeat_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest, INTVAL* dest_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_value_key = INT2KEY(INTERP, value_key);
+ PMC* r_dest_key = INT2KEY(INTERP, dest_key);
+
+ DYNSELF.repeat_keyed(r_key, value, r_value_key, dest, r_dest_key);
+ }
+
+ void repeat_int (INTVAL value, PMC* dest) {
+ SELF->vtable->set_string_native(INTERP, dest,
+ string_repeat(INTERP, SELF->vtable->get_string(INTERP,SELF),
+ (UINTVAL)value, NULL) );
+ }
+
+ void repeat_int_keyed (PMC* key, INTVAL value, PMC* dest, PMC* dest_key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void repeat_int_keyed_int (INTVAL* key, INTVAL value, PMC* dest, INTVAL* dest_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_dest_key = INT2KEY(INTERP, dest_key);
+ DYNSELF.repeat_int_keyed(r_key, value, dest, r_dest_key);
+ }
+
+ void increment () {
+ SELF->cache.int_val = DYNSELF.get_integer() + 1;
+ }
+
+ void increment_keyed (PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void increment_keyed_int (INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ DYNSELF.increment_keyed(r_key);
+ }
+
+ void decrement () {
+ SELF->cache.int_val = DYNSELF.get_integer() - 1;
+ }
+
+ void decrement_keyed (PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void decrement_keyed_int (INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ DYNSELF.decrement_keyed(r_key);
+ }
+
+ INTVAL exists_keyed (PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return 0;
+ }
+
+ INTVAL exists_keyed_int (INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.exists_keyed(r_key);
+ }
+
+ INTVAL defined () {
+ return 1;
+ }
+
+ INTVAL defined_keyed (PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return 0;
+ }
+
+ INTVAL defined_keyed_int (INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.defined_keyed(r_key);
+ }
+
+ void delete_keyed(PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void delete_keyed_int(INTVAL* key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ DYNSELF.delete_keyed(r_key);
+ }
+
+ PMC* nextkey_keyed (PMC* key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return NULL;
+ }
+
+ PMC* nextkey_keyed_int (INTVAL* key) {
+ /* XXX - Something's not right with this method */
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.nextkey_keyed(r_key);
+ }
+
+ void substr(INTVAL offset, INTVAL length, PMC* dest) {
+ }
+
+ void substr_keyed(PMC* key, INTVAL offset, INTVAL length, PMC* dest, PMC* dest_key) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ }
+
+ void substr_keyed_int(INTVAL* key, INTVAL offset, INTVAL length, PMC* dest, INTVAL* dest_key) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ PMC* r_dest_key = INT2KEY(INTERP, dest_key);
+ DYNSELF.substr_keyed(r_key, offset, length, dest, r_dest_key);
+ }
+
+ STRING* substr_str(INTVAL offset, INTVAL length) {
+ return string_substr(INTERP, SELF->vtable->get_string(INTERP,SELF),
+ offset, length, NULL);
+ }
+
+ STRING* substr_str_keyed(PMC* key, INTVAL offset, INTVAL length) {
+ internal_exception(OUT_OF_BOUNDS, "Subscript on something that's not an aggregate!\n");
+ return NULL;
+ }
+
+ STRING* substr_str_keyed_int (INTVAL* key, INTVAL offset, INTVAL length) {
+ PMC* r_key = INT2KEY(INTERP, key);
+ return DYNSELF.substr_str_keyed(r_key, offset, length);
+ }
+
+ void* invoke (void* next) {
+ /*
+ * FIXME: should be an exception instead:
+ * "Invoking something that can not be invoked" ??
+ */
+
+ /* move on to the next op */
+ return next;
}
}