ctr_object* ctr_json_create_object(json_t* root, ctr_object* gt) { switch(json_typeof(root)) { case JSON_OBJECT: { ctr_object* sub = ctr_internal_create_object(CTR_OBJECT_TYPE_OTOBJECT); ctr_set_link_all(sub, gt); // size_t size; const char *key; json_t *value; ctr_argument* argl = ctr_heap_allocate(sizeof(*argl)); argl->next = ctr_heap_allocate(sizeof(*argl)); // size = json_object_size(root); json_object_foreach(root, key, value) { char* k = (char*)key; ctr_object* ko = ctr_build_string_from_cstring(k); ctr_object* vo = ctr_json_create_object(value, gt); argl->object = vo; argl->next->object = ko; sub = ctr_map_put(sub, argl); } ctr_heap_free(argl->next); ctr_heap_free(argl); return sub; } case JSON_ARRAY: { ctr_object* arr = ctr_array_new(CtrStdArray, NULL); ctr_argument* arg = ctr_heap_allocate(sizeof(ctr_argument)); size_t i; size_t size = json_array_size(root); for (i = 0; i < size; i++) { arg->object = ctr_json_create_object(json_array_get(root, i), gt); ctr_array_push(arr, arg); } ctr_heap_free(arg); return arr; } case JSON_STRING: { ctr_object* str = ctr_build_string((char*)json_string_value(root), json_string_length(root)); return str; } case JSON_INTEGER: { return ctr_build_number_from_float(json_integer_value(root)); } case JSON_REAL: { return ctr_build_number_from_float(json_real_value(root)); } case JSON_FALSE: { return ctr_build_bool(0); } case JSON_TRUE: { return ctr_build_bool(1); } case JSON_NULL: { return ctr_build_nil(); } default: { CtrStdFlow = ctr_build_string_from_cstring("Unrecognized JSON type"); return CtrStdNil; } }
/** * [Map] [Key]: [Value] * * You can fill the map object with key-value pairs by sending any * binary or keyword message that is not part if its standard behaviour. * Likewise you can retrieve any value from the map by sending the corresponding key * as a unary message. This allows for a very natural looking notation to create * and modify map objects. * * Usage: * * ☞ menu := Map new * Margherita: 11.90, * Hawaii: 12.99, * QuattroFormaggi: 13.00. * * ✎ write: ( menu ? 'Hawaii' ), brk. * ✎ write: ( menu Margherita ), brk. * * In other languages: * * Dutch: [Lijst] [Object]: [Object] * Snelle en leesbare notatie om objecten toe te voegen aan een lijst. * Elk bericht dat niet wordt herkend wordt door de lijst als een * sleutel beschouwd, het opvolgende object zal op de plek worden * gezet in de lijst die door de sleutel wordt aangegeven. Dus om een * menukaart te vullen kan men zeggen: * * ☞ menu := Lijst nieuw. * menu pannekoek: 10. (hier kopppelen we pannekoek aan 10) * * Om nu op te vragen hoeveel een pannekoek kost schrijven we: * ☞ prijs := menu pannekoek. */ ctr_object* ctr_map_key_value(ctr_object* myself, ctr_argument* argumentList) { ctr_object* newKey; ctr_object* key = ctr_internal_cast2string(argumentList->object); newKey = key; if (key->value.svalue->vlen>1) { newKey = ctr_build_string(key->value.svalue->value,key->value.svalue->vlen-1); } argumentList->object = argumentList->next->object; argumentList->next->object = newKey; return ctr_map_put( myself, argumentList ); }
/** * [List] by: [List]. * * Combines the first list with the second one, thus creating * a map. The keys of the newly generated map will be provided by the * first list while the values are extracted from the second one. * In the example we derive a temperature map from a pair of lists * (cities and temperatures). * * Usage: * * ☞ city := List ← 'London' ; 'Paris' ; 'Berlin'. * ☞ temperature := List ← '15' ; '16' ; '15'. * ☞ weather := temperature by: city. * * In other languages: * Dutch: [Reeks] per: [Reeks] * Maakt een Lijst door elementen uit de eerste reeks te koppelen * aan de elementen op dezelfde plek uit de tweede reeks. */ ctr_object* ctr_array_combine(ctr_object* myself, ctr_argument* argumentList) { ctr_size i; ctr_object* map = ctr_map_new( CtrStdMap, argumentList ); if (argumentList->object->info.type != CTR_OBJECT_TYPE_OTARRAY) { return map; } ctr_argument* key = ctr_heap_allocate( sizeof( ctr_argument ) ); ctr_argument* value = ctr_heap_allocate( sizeof( ctr_argument ) ); ctr_argument* index = ctr_heap_allocate( sizeof( ctr_argument ) ); for(i = myself->value.avalue->tail; i<myself->value.avalue->head; i++) { index->object = ctr_build_number_from_float((ctr_number) i); key->object = ctr_array_get( myself, index ); value->object = ctr_array_get( argumentList->object, index ); key->next = value; ctr_send_message( map, CTR_DICT_PUT_AT, strlen(CTR_DICT_PUT_AT), key); ctr_map_put( map, key ); } ctr_heap_free(key); ctr_heap_free(value); ctr_heap_free(index); return map; }