modelica_metatype listAppend(modelica_metatype lst1,modelica_metatype lst2) { int length = 0, i = 0; struct mmc_cons_struct *res = NULL; struct mmc_cons_struct *p = NULL; if (MMC_NILTEST(lst2)) /* If lst2 is empty, simply return lst1; huge performance gain for some uses of listAppend */ return lst1; length = listLength(lst1); if (length == 0) /* We need to check for empty lst1 */ return lst2; res = (struct mmc_cons_struct*)mmc_alloc_words( length * 3 /*(sizeof(struct mmc_cons_struct)/sizeof(void*))*/ ); /* Do one single big alloc. It's cheaper */ for (i=0; i<length-1; i++) { /* Write all except the last element... */ struct mmc_cons_struct *p = res+i; p->header = MMC_STRUCTHDR(2, MMC_CONS_CTOR); p->data[0] = MMC_CAR(lst1); p->data[1] = MMC_TAGPTR(res+i+1); lst1 = MMC_CDR(lst1); } /* The last element is a bit special. It points to lst2. */ p = res+length-1; p->header = MMC_STRUCTHDR(2, MMC_CONS_CTOR); p->data[0] = MMC_CAR(lst1); p->data[1] = lst2; return MMC_TAGPTR(res); }
modelica_metatype boxptr_listDelete(threadData_t *threadData, modelica_metatype lst, modelica_metatype iix) { /* TODO: If we assume the index exists we can do this in a much better way */ int ix = mmc_unbox_integer(iix); modelica_metatype *tmpArr = NULL; int i = 0; if (ix <= 0) { MMC_THROW_INTERNAL(); } tmpArr = (modelica_metatype *) mmc_alloc_words(ix-1); /* We know the size of the first part of the list */ if (tmpArr == NULL) { fprintf(stderr, "%s:%d: malloc failed", __FILE__, __LINE__); EXIT(1); } for (i=0; i<ix-1; i++) { if (listEmpty(lst)) { if (tmpArr) { GC_free(tmpArr); } MMC_THROW_INTERNAL(); } tmpArr[i] = MMC_CAR(lst); lst = MMC_CDR(lst); } if (listEmpty(lst)) { GC_free(tmpArr); MMC_THROW_INTERNAL(); } lst = MMC_CDR(lst); for (i=ix-2; i>=0; i--) { lst = mmc_mk_cons(tmpArr[i], lst); } GC_free(tmpArr); return lst; }