diff --git a/object.c b/object.c index 8f28bdf..7bd448c 100644 --- a/object.c +++ b/object.c @@ -141,8 +141,8 @@ struct Map { struct Pair *elements; // even are keys, odd are values [ key val key val key val ] size_t capacity; union { - size_t size; // free Maps will be reset to 0 size on allocation - oop pool; // free list of Map objects + size_t size; // free Maps will be reset to 0 size on allocation + oop pool; // free list of Map objects }; }; @@ -197,7 +197,7 @@ oop _checkType(oop ptr, type_t type, char *file, int line) { assert(ptr); if (getType(ptr) != type) { - fprintf(stderr, "\n%s:%i: expected %i got %i\n", file, line, type, ptr->type); + fprintf(stderr, "\n%s:%i: expected %i got %i\n", file, line, type, getType(ptr)); } assert(getType(ptr) == type); return ptr; @@ -237,7 +237,7 @@ int isIntegerValue(int_t value) oop makeInteger(int_t value) { #if (USE_TAG) - if (isIntegerValue(value)) return (oop)(((intptr_t)value << 1) | 1); //TODO + if (isIntegerValue(value)) return (oop)(((intptr_t)value << 1) | 1); #endif oop newInt = malloc(sizeof(struct Integer)); newInt->type = Integer; @@ -267,11 +267,47 @@ oop makeString(char *value) return newString; } +// value will be used directly +oop makeStringFrom(char *value, size_t l) +{ + oop newString = malloc(sizeof(struct String)); + newString->type = String; + newString->String.value = value; + newString->String.size = l; + return newString; +} + +oop makeStringFromChar(char c, int repeat) +{ + char *str= malloc(sizeof(char) * (repeat + 1)); + for (int i=0; i len) return NULL; + if (stop < 0 || stop > len) return NULL; + if (start > stop) return NULL; + + size_t cpylen = stop - start; + char *slice= memcheck(malloc(sizeof(char) * (cpylen + 1))); + memcpy(slice, get(str, String, value) + start, cpylen); + slice[cpylen]= '\0'; + return makeStringFrom(slice, cpylen); +} + oop string_concat(oop str1, oop str2) { size_t len = string_size(str1) + string_size(str2); @@ -279,11 +315,7 @@ oop string_concat(oop str1, oop str2) memcpy(concat, get(str1, String, value), string_size(str1)); memcpy(concat + string_size(str1), get(str2, String, value), string_size(str2)); concat[len]= '\0'; - oop newString = malloc(sizeof(struct String)); - newString->type = String; - newString->String.value = concat; - newString->String.size = len; - return newString; + return makeStringFrom(concat, len); } oop string_mul(oop str, oop factor) @@ -295,11 +327,7 @@ oop string_mul(oop str, oop factor) memcpy(concat + (i * string_size(str)), get(str, String, value), string_size(str)); } concat[len]= '\0'; - oop newString = malloc(sizeof(struct String)); - newString->type = String; - newString->String.value = concat; - newString->String.size = len; - return newString; + return makeStringFrom(concat, len); } oop makeSymbol(char *name) @@ -311,6 +339,25 @@ oop makeSymbol(char *name) return newSymb; } +oop makeSymbolFrom(char *name) +{ + oop newSymbol= malloc(sizeof(struct Symbol)); + newSymbol->type= Symbol; + newSymbol->Symbol.name= name; + newSymbol->Symbol.prototype= 0; + return newSymbol; +} + +oop makeSymbolFromChar(char c, int repeat) +{ + char *str= malloc(sizeof(char) * (repeat + 1)); + for (int i=0; iMap.flags); + oop newMap = malloc(sizeof(struct Map)); assert(0 == newMap->Map.flags); newMap->type = Map; return newMap; } +oop makeMapCapacity(size_t capa) +{ + oop map= makeMap(); + set(map, Map, elements, malloc(sizeof(struct Pair) * capa)); + set(map, Map, capacity, capa); + return map; +} + size_t map_size(oop map) { assert(is(Map, map)); @@ -345,6 +400,14 @@ bool map_hasIntegerKey(oop map, size_t index) return index == getInteger(key); } +bool map_isArray(oop map) +{ + assert(is(Map, map)); + size_t size= map_size(map); + if (size == 0) return true; + return map_hasIntegerKey(map, 0) && map_hasIntegerKey(map, size-1); +} + int oopcmp(oop a, oop b) { type_t ta = getType(a), tb = getType(b); @@ -433,7 +496,7 @@ oop map_insert(oop map, oop key, oop value, size_t pos) // check capacity and expand if needed if (map_size(map) >= get(map, Map, capacity)) { size_t newCapacity = get(map, Map, capacity) * MAP_GROW_SIZE; - if (newCapacity < MAP_MIN_SIZE) newCapacity= MAP_MIN_SIZE; + if (newCapacity < MAP_MIN_SIZE) newCapacity= MAP_MIN_SIZE; set(map, Map, elements, realloc(get(map, Map, elements), sizeof(struct Pair) * newCapacity)); set(map, Map, capacity, newCapacity); } @@ -482,6 +545,25 @@ oop map_append(oop map, oop value) return map_set(map, makeInteger(map_size(map)), value); } +oop makeArrayFromElement(oop elem, int repeat) +{ + oop array= makeMapCapacity(repeat); + for(int i=0; i < repeat; ++i) { + map_append(array, elem); + } + return array; +} + +oop makeArrayFromString(char *str) +{ + size_t len= strlen(str); + oop array= makeMapCapacity(len); + for(int i=0; i < len; ++i) { + map_append(array, makeInteger(str[i])); + } + return array; +} + bool isHidden(oop obj) { if (is(Symbol, obj)) { char *s = get(obj, Symbol, name); @@ -526,6 +608,36 @@ oop map_values(oop map) return values; } +oop map_allValues(oop map) +{ + assert(is(Map, map)); + oop values = makeMap(); + for (size_t i = 0; i < get(map, Map, size); i++) { + map_append(values, get(map, Map, elements)[i].value); + } + return values; +} + +oop map_slice(oop map, ssize_t start, ssize_t stop) { + assert(is(Map, map)); + size_t len = map_size(map); + if (start < 0) start= start + len; + if (stop < 0) stop= stop + len; + if (start < 0 || start > len) return NULL; + if (stop < 0 || stop > len) return NULL; + if (start > stop) return NULL; + + oop slice= makeMap(); + if (start < stop) { + if (!map_hasIntegerKey(map, start )) return NULL; + if (!map_hasIntegerKey(map, stop - 1)) return NULL; + for (size_t i= start; i < stop; ++i) { + map_append(slice, get(map, Map, elements)[i].value); + } + } + return slice; +} + DECLARE_BUFFER(oop, OopStack); OopStack printing = BUFFER_INITIALISER;