/* It works like: * 1 - boot smop, * 2 - init a new object, and set the methods * 3 - get a stack * 4 - call method 1 * 5 - lower the refcount (should init destruction) * 6 - call method 2 * 7 - call stack loop */ int main(int argc, char** argv) { printf("1..6\n"); smop_init(); SMOP__Object* obj = smop_lowlevel_alloc(sizeof(SMOP__ResponderInterface)); if (!obj) { printf("not "); } printf("ok 1 - object allocated successfully.\n"); SMOP__ResponderInterface* ri = (SMOP__ResponderInterface*)obj; ri->MESSAGE = custom_MESSAGE; ri->REFERENCE = smop_lowlevel_refcnt_inc; ri->RELEASE = smop_lowlevel_refcnt_dec; SMOP__Object* intrp = SMOP_DISPATCH(SMOP__INTPTR__InterpreterInstance, SMOP_RI(SMOP__INTPTR__InterpreterInstance), SMOP__ID__new, SMOP__NATIVE__capture_create(SMOP__INTPTR__InterpreterInstance, SMOP__INTPTR__InterpreterInstance, NULL, NULL)); if (!intrp) { printf("not "); } printf("ok 2 - got new interp successfully %p.\n",intrp); SMOP_DISPATCH(intrp, ri, SMOP__ID__new, NULL); /* At this point, the destruction code for the object will be put in * the stack. That's why we still can call the second method just * below that. The object will only be invalidated when the stack * loop is called. */ SMOP_RELEASE(intrp, obj); SMOP_DISPATCH(intrp, ri, SMOP__ID__invocant, NULL); SMOP_DISPATCH(intrp, SMOP_RI(intrp), SMOP__ID__loop, SMOP__NATIVE__capture_create(intrp, SMOP_REFERENCE(intrp,intrp), NULL, NULL)); SMOP_RELEASE(SMOP__INTPTR__InterpreterInstance, intrp); printf("ok 6 - finished succesfully.\n"); smop_destr(); return 0; }
void smop_util_hash_destr(SMOP__Object* interpreter,smop_util_hash* hash) { int i; for (i=0;i < hash->size;i++) { smop_util_hash_bucket* bucket = hash->content[i]; while (bucket) { SMOP_RELEASE(interpreter,bucket->value); SMOP_RELEASE(interpreter,bucket->key); smop_util_hash_bucket* next = bucket->next; free(bucket); bucket = next; } } free(hash->content); free(hash); }
static SMOP__Object* smop_s1p_endofiterator_message(SMOP__Object* interpreter, SMOP__ResponderInterface* self, SMOP__Object* identifier, SMOP__Object* capture) { ___CONST_IDENTIFIER_ONLY___; SMOP__Object* ret = SMOP__NATIVE__bool_false; if (identifier == SMOP__ID__new) { ret = SMOP__S1P__EndOfIterator; } else if (identifier == SMOP__ID__defined) { ret = SMOP__NATIVE__bool_false; } else if (identifier == SMOP__ID__postcircumfix_square) { ret = SMOP__NATIVE__bool_false; } else if (identifier == SMOP__ID__Iterator) { ret = SMOP__S1P__EndOfIterator; } else if (identifier == SMOP__ID__List) { ret = SMOP__S1P__EndOfIterator; } else if (identifier == SMOP__ID__elems) { ret = SMOP__NATIVE__int_create(0); } else if (identifier == SMOP__ID__DESTROYALL) { } else { ___UNKNOWN_METHOD___ } SMOP_RELEASE(interpreter,capture); return ret; }
/* In this test, we're going to define a object that is its own * responder interface, and that have three methods (one of them being * DESTROYALL). Each one will print to the standard output the "ok" * message in the expected order. */ static SMOP__Object* custom_MESSAGE(SMOP__Object* stack, SMOP__ResponderInterface* self, SMOP__Object* identifier, SMOP__Object* capture) { if ((int)identifier == SMOP__ID__new) { printf("ok 3 - method 1 should be called early.\n"); } else if ((int)identifier == SMOP__ID__invocant) { printf("ok 4 - method 2 should be called immediatly afterwards.\n"); } else if (identifier == SMOP__ID__DESTROYALL) { printf("ok 5 - DESTROYALL should be the last one called.\n"); } else { printf("not ok - Unknown identifier given %p.\n", identifier); } if (capture) SMOP_RELEASE(stack, capture); return NULL; }
void smop_util_hash_set(SMOP__Object* interpreter,smop_util_hash* hash,SMOP__Object* key,SMOP__Object* value) { int hash_value = 0; smop_util_hash_bucket* bucket = hash->content[hash_value % hash->size]; while (bucket) { if (bucket->key == key) { SMOP_RELEASE(interpreter,bucket->value); bucket->value = value; return; } bucket = bucket->next; } smop_util_hash_bucket* new_bucket = (smop_util_hash_bucket*) malloc(sizeof(smop_util_hash_bucket)); new_bucket->next = hash->content[hash_value % hash->size]; new_bucket->key = key; new_bucket->value = value; hash->content[hash_value % hash->size] = new_bucket; }
int main(int argc, char** argv) { printf("1..2\n"); smop_init(); // For starts, there will be some functions to // wrap the dispatch, after the list is built, // we can start to use the dispatcher itself SMOP__Object* myint = SMOP__NATIVE__int_create(1234); if (!myint) printf("not "); printf("ok 1 - create works...\n"); if (SMOP__NATIVE__int_fetch(myint) != 1234) printf("not "); printf("ok 2 - fetch works...\n"); SMOP_RELEASE(SMOP__INTPTR__InterpreterInstance, myint); smop_destr(); return 0; }
static SMOP__Object* custom_message(SMOP__Object* interpreter, SMOP__ResponderInterface* self, SMOP__Object* identifier, SMOP__Object* capture) { static int counter=0; SMOP__Object* ret = SMOP__NATIVE__bool_false; if (identifier == SMOP__NATIVE__idconst_createn("eval",4)) { counter++; if (counter == 1) { printf("ok 2 # eval called\n"); ret = SMOP__NATIVE__bool_true; } else if (counter == 2) { printf("ok 3 # eval called second time\n"); } else { printf("not ok 3 # eval called third time\n"); } } else { printf("not ok # wrong method called\n"); } SMOP_RELEASE(interpreter,capture); return ret; }