IO_METHOD(IoSeq, between) { /*doc Sequence between(aSequence, anotherSequence) Returns a new Sequence containing the bytes between the occurance of aSequence and anotherSequence in the receiver. */ long start = 0; long end = 0; IoSeq *fromSeq, *toSeq; fromSeq = (IoSeq *)IoMessage_locals_valueArgAt_(m, locals, 0); if (ISSEQ(fromSeq)) { start = UArray_find_from_(DATA(self), DATA(fromSeq), 0) + IoSeq_rawSize(fromSeq); if (start == -1) { start = 0; } } else if (ISNIL(fromSeq)) { start = 0; } else { IoState_error_(IOSTATE, m, "Nil or Sequence argument required for arg 0, not a %s", IoObject_name((IoObject *)fromSeq)); } toSeq = (IoSeq *)IoMessage_locals_valueArgAt_(m, locals, 1); if (ISSEQ(toSeq)) { end = UArray_find_from_(DATA(self), DATA(toSeq), start); if (end == -1) start = UArray_size(DATA(self)); } else if (ISNIL(toSeq)) { end = UArray_size(DATA(self)); } else { IoState_error_(IOSTATE, m, "Nil or Sequence argument required for arg 1, not a %s", IoObject_name((IoObject *)toSeq)); } { UArray *ba = UArray_slice(DATA(self), start, end); IoSeq *result = IoSeq_newWithUArray_copy_(IOSTATE, ba, 0); return result; } }
IO_METHOD(IoSeq, replaceMap) { /*doc Sequence replaceMap(aMap) In the receiver, the keys of aMap replaced with its values. Returns self. */ IoMap *map = IoMessage_locals_mapArgAt_(m, locals, 0); UArray *ba = DATA(self); IO_ASSERT_NOT_SYMBOL(self); PHASH_FOREACH(IoMap_rawHash(map), k, v, { IoSymbol *subSeq = k; IoSymbol *otherSeq = v; if (ISSEQ(otherSeq)) { UArray_replace_with_(ba, DATA(subSeq), DATA(otherSeq)); } else { IoState_error_(IOSTATE, m, "argument 0 to method '%s' must be a Map with Sequence values, not '%s'", CSTRING(IoMessage_name(m)), IoObject_name(otherSeq)); } } );
void IoCoroutine_rawReturnToParent(IoCoroutine *self) { IoCoroutine *parent = IoCoroutine_rawParentCoroutine(self); if (parent && ISCOROUTINE(parent)) { IoCoroutine_rawResume(parent); } else { if (self == IOSTATE->mainCoroutine) { printf("IoCoroutine error: attempt to return from main coro\n"); exit(-1); } } if (!ISNIL(IoCoroutine_rawException(self))) { IoCoroutine_rawPrintBackTrace(self); } printf("IoCoroutine error: unable to auto abort coro %p by resuming parent coro %s_%p\n", (void *)self, IoObject_name(parent), (void *)parent); exit(-1); }
IoObject *IoDBI_with(IoDBI *self, IoObject *locals, IoMessage *m) { //doc DBI with(driverName) Get a new connection with the given driver. IoObject *name = IoMessage_locals_valueArgAt_(m, locals, 0); if (!ISSYMBOL(name)) { IoState_error_(IOSTATE, m, "argument 0 to method '%s' must be a Symbol, not a '%s'\n", CSTRING(IoMessage_name(m)), IoObject_name(name)); return IONIL(self); } if (DATA(self)->didInit != 1) { IoDBI_init(self, locals, m); } dbi_conn c = dbi_conn_new(CSTRING(name)); if (c == NULL) { IoState_error_(IOSTATE, m, "libdbi error during dbi_conn_new\n"); return IONIL(self); } return IoDBIConn_new(IOSTATE, c); }
IoObject *IoDBI_initWithDriversPath(IoDBI *self, IoObject *locals, IoMessage *m) { /*doc DBI initWithDriversPath Initialize the DBI environment with the specified libdbi driver path. */ IoObject *dir = IoMessage_locals_valueArgAt_(m, locals, 0); if (ISSYMBOL(dir)) { DATA(self)->driverCount = dbi_initialize(CSTRING(dir)); } else { IoState_error_(IOSTATE, m, "argument 0 to method '%s' must be a Symbol, not a '%s'\n", CSTRING(IoMessage_name(m)), IoObject_name(dir)); } if (DATA(self)->driverCount == -1) { IoState_error_(IOSTATE, m, "*** IoDBI error during dbi_initialize\n"); } else { DATA(self)->didInit = 1; } return IONUMBER(DATA(self)->driverCount); }
void IoMessage_assertArgCount_receiver_(IoMessage *self, int n, IoObject *receiver) { if (List_size(DATA(self)->args) < n) { IoState_error_(IOSTATE, self, "[%s %s] requires %i arguments\n", IoObject_name(receiver), CSTRING(DATA(self)->name), n); } }
void IoMessage_locals_numberArgAt_errorForType_(IoMessage *self, IoObject *locals, int n, const char *typeName) { IoObject *v = IoMessage_locals_valueArgAt_(self, locals, n); IoState_error_(IOSTATE, self, "argument %i to method '%s' must be a %s, not a '%s'", n, CSTRING(DATA(self)->name), typeName, IoObject_name(v)); }
IO_METHOD(IoSeq, findSeqs) { /*doc Sequence findSeqs(listOfSequences, optionalStartIndex) Returns an object with two slots - an \"index\" slot which contains the first occurrence of any of the sequences in listOfSequences found in the receiver after the startIndex, and a \"match\" slot, which contains a reference to the matching sequence from listOfSequences. If no startIndex is specified, the search starts at index 0. nil is returned if no occurences are found. */ IoList *others = IoMessage_locals_listArgAt_(m, locals, 0); List *delims = IoList_rawList(others); long f = 0; long firstIndex = -1; size_t match = 0; if (IoMessage_argCount(m) > 1) { f = IoMessage_locals_longArgAt_(m, locals, 1); } { size_t index; LIST_FOREACH(delims, i, s, if (!ISSEQ((IoSeq *)s)) { IoState_error_(IOSTATE, m, "requires Sequences as arguments, not %ss", IoObject_name((IoSeq *)s)); } index = UArray_find_from_(DATA(self), DATA(((IoSeq *)s)), f); if(index != -1 && (firstIndex == -1 || index < firstIndex)) { firstIndex = (long)index; match = i; } ); }
void IoState_registerProtoWithFunc_(IoState *self, IoObject *proto, IoStateProtoFunc *func) { if (PHash_at_(self->primitives, (void *)func)) { IoState_fatalError_(self, "IoState_registerProtoWithFunc_() Error: attempt to add the same proto twice"); } IoState_retain_(self, proto); PHash_at_put_(self->primitives, (void *)func, proto); //printf("registered %s\n", IoObject_name(proto)); } IoObject *IoState_protoWithName_(IoState *self, const char *name) { PHASH_FOREACH(self->primitives, key, proto, if (!strcmp(IoObject_name(proto), name)) { return proto; }); return NULL; } List *IoState_tagList(IoState *self) // caller must io_free returned List { List *tags = List_new(); PHASH_FOREACH(self->primitives, k, proto, List_append_(tags, IoObject_tag((IoObject *)proto))); return tags; } void IoState_done(IoState *self) { // this should only be called from the main coro from outside of Io List *tags = IoState_tagList(self); // need to get the tags before we io_free the protos
IO_METHOD(IoSeq, between) { /*doc Sequence betweenSeq(aSequence, anotherSequence) Returns a new Sequence containing the bytes between the occurrence of aSequence and anotherSequence in the receiver. If aSequence is empty, this method is equivalent to beforeSeq(anotherSequence). If anotherSequence is nil, this method is equivalent to afterSeq(aSequence). nil is returned if no match is found. */ long start = 0; long end = 0; IoSeq *fromSeq, *toSeq; fromSeq = (IoSeq *)IoMessage_locals_valueArgAt_(m, locals, 0); if (ISSEQ(fromSeq)) { if (IoSeq_rawSize(fromSeq) == 0) { start = 0; } else { start = UArray_find_from_(DATA(self), DATA(fromSeq), 0); if (start == -1) { //start = 0; return IONIL(self); } start += IoSeq_rawSize(fromSeq); } } else if (ISNIL(fromSeq)) { start = 0; } else { IoState_error_(IOSTATE, m, "Nil or Sequence argument required for arg 0, not a %s", IoObject_name((IoObject *)fromSeq)); } toSeq = (IoSeq *)IoMessage_locals_valueArgAt_(m, locals, 1); if (ISSEQ(toSeq)) { end = UArray_find_from_(DATA(self), DATA(toSeq), start); //if (end == -1) start = UArray_size(DATA(self)); if (end == -1) return IONIL(self); } else if (ISNIL(toSeq)) { end = UArray_size(DATA(self)); } else { IoState_error_(IOSTATE, m, "Nil or Sequence argument required for arg 1, not a %s", IoObject_name((IoObject *)toSeq)); } { UArray *ba = UArray_slice(DATA(self), start, end); IoSeq *result = IoSeq_newWithUArray_copy_(IOSTATE, ba, 0); return result; } }