bool persist_collect_(V original, HashMap *hm) { int type = getType(original); HashMap *hmv; Bucket *b; int i; if (type == T_SCOPE || type == T_FUNC || type == T_CFUNC) { return false; } if (get_hashmap(hm, original) != NULL) { return true; } set_hashmap(hm, original, intToV(-pair_ordinal(original)-1)); switch(type) { case T_STR: case T_IDENT: case T_NUM: case T_FRAC: break; case T_LIST: for (i = 0; i < toStack(original)->used; i++) { if (!persist_collect_(toStack(original)->nodes[i], hm)) { return false; } } break; case T_DICT: hmv = toHashMap(original); if (hmv->map != NULL) { for (i = 0; i < hmv->size; i++) { b = hmv->map[i]; while(b != NULL) { if (!persist_collect_(b->key, hm) ||!persist_collect_(b->value, hm)) { return false; } b = b->next; } } } break; case T_PAIR: if (!persist_collect_(toFirst(original), hm) || !persist_collect_(toSecond(original), hm)) return false; break; } return true; }
ZObject3d* ZStroke2dArray::toObject3d() const { ZStack *stack = toStack(); ZObject3d *obj = NULL; if (stack != NULL) { obj = new ZObject3d; obj->loadStack(stack); } return obj; }
Error chars(Stack* S, Stack* scope_arr) { require(1); V source = popS(); if (getType(source) != T_STR) { clear_ref(source); return TypeError; } utf8 chrs = toNewString(source)->text; utf8index index = 0; V list = new_list(); Stack *st = toStack(list); size_t size = toNewString(source)->size; size_t i; for (i = 0; i < size; i++) { push(st, unichar_to_value(decode_codepoint(chrs, &index))); } pushS(list); return Nothing; }
bool read_literals(char *oldpos, size_t size, Header* h) { int i, j; int n = 0; char type; uint32_t str_length; uint32_t ref; char *startpos = oldpos + h->size * 4; char *curpos = startpos; while (!eofreached) { type = *curpos++; if (eofreached) { break; } n++; switch (type) { case TYPE_NUM: curpos += 8; break; case TYPE_NUM | TYPE_SHORT: curpos += 3; break; case TYPE_STR: case TYPE_IDENT: memcpy(&str_length, curpos, 4); curpos += 4 + ntohl(str_length); break; case TYPE_STR | TYPE_SHORT: case TYPE_IDENT | TYPE_SHORT: str_length = (unsigned char)*curpos++; curpos += str_length; break; case TYPE_PAIR: curpos += 6; break; case TYPE_FRAC: curpos += 16; break; case TYPE_FRAC | TYPE_SHORT: curpos += 2; break; case TYPE_LIST: memcpy(&str_length, curpos, 4); curpos += 4 + 3 * ntohl(str_length); break; case TYPE_DICT: memcpy(&str_length, curpos, 4); curpos += 4 + 6 * ntohl(str_length); break; } } V* arr = calloc(n, sizeof(V)); V t; curpos = startpos; for (i = 0; i < n; i++) { type = *curpos++; if (type == TYPE_NUM) { union double_or_uint64_t d; memcpy(&d, curpos, 8); curpos += 8; d.i = ntohll(d.i); t = double_to_value(d.d); } else if (type == (TYPE_NUM | TYPE_SHORT)) { ref = 0; memcpy(((char*)&ref) + 1, curpos, 3); ref = ntohl(ref); curpos += 3; t = int_to_value(ref); } else if (type == TYPE_STR) { memcpy(&str_length, curpos, 4); curpos += 4; str_length = ntohl(str_length); if (!valid_utf8(str_length, curpos)) { set_error_msg("wrong encoding for string literal, should be UTF-8"); return false; } t = str_to_string(str_length, curpos); curpos += str_length; } else if (type == TYPE_IDENT) { memcpy(&str_length, curpos, 4); curpos += 4; str_length = ntohl(str_length); char data[str_length + 1]; memcpy(&data, curpos, str_length); data[str_length] = '\0'; t = lookup_ident(str_length, data); curpos += str_length; } else if (type == (TYPE_STR | TYPE_SHORT)) { str_length = (unsigned char)*curpos++; if (!valid_utf8(str_length, curpos)) { set_error_msg("wrong encoding for string literal, should be UTF-8"); return false; } t = str_to_string(str_length, curpos); curpos += str_length; } else if (type == (TYPE_IDENT | TYPE_SHORT)) { str_length = *curpos++; char data[str_length + 1]; memcpy(&data, curpos, str_length); data[str_length] = '\0'; t = lookup_ident(str_length, data); curpos += str_length; } else if (type == TYPE_PAIR) { ref = 0; memcpy(((char*)&ref) + 1, curpos, 3); ref = ntohl(ref); if (ref >= i) { set_error_msg("illegal pair detected"); return false; } V v1 = arr[ref]; ref = 0; memcpy(((char*)&ref) + 1, curpos + 3, 3); ref = ntohl(ref); if (ref >= i) { set_error_msg("illegal pair detected"); return false; } V v2 = arr[ref]; t = new_pair(v1, v2); curpos += 6; } else if (type == TYPE_FRAC) { int64_t numer; int64_t denom; memcpy(&numer, curpos, 8); numer = ntohll(numer); memcpy(&denom, curpos + 8, 8); denom = ntohll(denom); t = new_frac(numer, denom); curpos += 16; } else if (type == (TYPE_FRAC | TYPE_SHORT)) { int8_t numer; uint8_t denom; numer = *curpos++; denom = *curpos++; t = new_frac(numer, denom); } else if (type == TYPE_LIST) { memcpy(&str_length, curpos, 4); str_length = ntohl(str_length); t = new_list(); curpos += 4; if (str_length > 0) { uint32_t size = 64; while (size < str_length) size <<= 1; toStack(t)->size = size; toStack(t)->used = str_length; toStack(t)->nodes = calloc(size, sizeof(V)); for (j = 0; j < str_length; j++) { ref = 0; memcpy(((char*)&ref) + 1, curpos, 3); ref = ntohl(ref); toStack(t)->nodes[j] = intToV((uint64_t)ref); curpos += 3; } } } else if (type == TYPE_DICT) { memcpy(&str_length, curpos, 4); curpos += 4; str_length = ntohl(str_length); t = new_dict(); if (str_length > 0) { uint32_t size = 16; while (size < str_length) size <<= 1; toHashMap(t)->size = size; toHashMap(t)->used = str_length; toHashMap(t)->map = (Bucket**)curpos; } curpos += 6 * str_length; } else { set_error_msg("Unknown literal type."); return false; } arr[i] = t; } for (i = 0; i < n; i++) { t = arr[i]; switch(getType(t)) { case TYPE_LIST: for (j = 0; j < toStack(t)->used; j++) { toStack(t)->nodes[j] = arr[toInt(toStack(t)->nodes[j])]; } break; case TYPE_DICT: if (toHashMap(t)->map) { curpos = ((char*)toHashMap(t)->map); toHashMap(t)->map = NULL; str_length = toHashMap(t)->used; //worst abuse of variable name ever Y/Y? toHashMap(t)->used = 0; for (j = 0; j < str_length; j++) { ref = 0; memcpy(((char*)&ref) + 1, curpos, 3); ref = ntohl(ref); V key = arr[ref]; ref = 0; memcpy(((char*)&ref) + 1, curpos + 3, 3); ref = ntohl(ref); V value = arr[ref]; set_hashmap(toHashMap(t), key, value); curpos += 6; } } break; } } h->n_literals = n; h->literals = arr; return true; }
void write_object(FILE *file, V obj, HashMap *hm) { int t = getType(obj); union double_or_uint64_t num; ITreeNode *id = NULL; NewString *s = NULL; Stack *st; HashMap *hmv; int8_t n8; uint8_t l8; int32_t n32; uint32_t l32; int64_t n64; uint64_t l64; int i; Bucket *b; char type = t; switch (t) { case T_NUM: if (canBeSmallInt(obj)) type |= TYPE_SHORT; break; case T_IDENT: id = toIdent(obj); if (id->length < 256) type |= TYPE_SHORT; break; case T_STR: s = toNewString(obj); if (s->size < 256) type |= TYPE_SHORT; break; case T_FRAC: if (toNumerator(obj) < 128 && toNumerator(obj) >= -128 && toDenominator(obj) < 256) type |= TYPE_SHORT; break; } fwrite(&type, 1, 1, file); switch (t) { case T_IDENT: if (type & TYPE_SHORT) { l8 = id->length; fwrite(&l8, 1, 1, file); } else { l32 = id->length; l32 = htonl(l32); fwrite(&l32, 4, 1, file); } fwrite(&id->data, id->length, 1, file); break; case T_STR: if (type & TYPE_SHORT) { l8 = s->size; fwrite(&l8, 1, 1, file); } else { l32 = s->size; l32 = htonl(l32); fwrite(&l32, 4, 1, file); } fwrite(s->text, s->size, 1, file); break; case T_NUM: if (type & TYPE_SHORT) { n32 = toInt(obj); n32 = htonl(n32); fwrite(((char*)&n32) + 1, 3, 1, file); } else { num.d = toNumber(obj); num.i = htonll(num.i); fwrite(&num, 8, 1, file); } break; case T_FRAC: if (type & TYPE_SHORT) { n8 = toNumerator(obj); fwrite(&n8, 1, 1, file); l8 = toDenominator(obj); fwrite(&l8, 1, 1, file); } else { n64 = toNumerator(obj); n64 = htonl(n64); fwrite(&n64, 8, 1, file); l64 = toDenominator(obj); l64 = htonl(l64); fwrite(&l64, 8, 1, file); } break; case T_PAIR: write_ref(file, toFirst(obj), hm); write_ref(file, toSecond(obj), hm); break; case T_LIST: st = toStack(obj); l32 = st->used; l32 = htonl(l32); fwrite(&l32, 4, 1, file); for (i = 0; i < st->used; i++) { write_ref(file, st->nodes[i], hm); } break; case T_DICT: hmv = toHashMap(obj); l32 = hmv->used; l32 = htonl(l32); fwrite(&l32, 4, 1, file); if (hmv->map != NULL) { for (i = 0; i < hmv->size; i++) { b = hmv->map[i]; while(b != NULL) { write_ref(file, b->key, hm); write_ref(file, b->value, hm); b = b->next; } } } break; } }