/** * [List] + [List] * * Returns a new list, containing elements of itself and the other * list. * * In other languages: * Dutch: [Reeks] + [Reeks] | Geeft de reeks die bestaat uit de samenvoeging van gegeven reeksen. */ ctr_object* ctr_array_add(ctr_object* myself, ctr_argument* argumentList) { ctr_object* otherArray = argumentList->object; ctr_object* newArray = ctr_array_new(CtrStdArray, NULL); int i; for(i = myself->value.avalue->tail; i<myself->value.avalue->head; i++) { ctr_argument* pushArg = (ctr_argument*) ctr_heap_allocate( sizeof( ctr_argument ) ); ctr_argument* elnumArg = (ctr_argument*) ctr_heap_allocate( sizeof( ctr_argument ) ); ctr_object* elnum = ctr_build_number_from_float((ctr_number) i); elnumArg->object = elnum; pushArg->object = ctr_array_get(myself, elnumArg); ctr_array_push(newArray, pushArg); ctr_heap_free( elnumArg ); ctr_heap_free( pushArg ); } if (otherArray->info.type == CTR_OBJECT_TYPE_OTARRAY) { for(i = otherArray->value.avalue->tail; i<otherArray->value.avalue->head; i++) { ctr_argument* pushArg = (ctr_argument*) ctr_heap_allocate( sizeof( ctr_argument ) ); ctr_argument* elnumArg = (ctr_argument*) ctr_heap_allocate( sizeof( ctr_argument ) ); ctr_object* elnum = ctr_build_number_from_float((ctr_number) i); elnumArg->object = elnum; pushArg->object = ctr_array_get(otherArray, elnumArg); ctr_array_push(newArray, pushArg); ctr_heap_free( elnumArg ); ctr_heap_free( pushArg ); } } return newArray; }
/** * @internal * * Returns an array from the request, either for GET, POST or COOKIE. */ ctr_object* ctr_request_array(ctr_object* myself, ctr_argument* argumentList, CGI_varlist* varlist) { ctr_object* cgiVarObject; ctr_object* list; char* cgiVar; const CGI_value* value; char* val; ctr_argument* arg; int i = 0; list = ctr_array_new(CtrStdArray, NULL); cgiVarObject = ctr_internal_cast2string(argumentList->object); cgiVar = ctr_heap_allocate_cstring( cgiVarObject ); value = CGI_lookup_all(varlist, (const char*)cgiVar); ctr_heap_free( cgiVar ); if (value == NULL) { return list; } for (i = 0; value[i] != 0; i++) { arg = (ctr_argument*) ctr_heap_allocate( sizeof( ctr_argument ) ); val = (char*) value[i]; arg->object = ctr_build_string_from_cstring(val); ctr_array_push(list, arg); ctr_heap_free( arg ); } return list; }
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; } }
/** * [List] copy * * Copies the list. The list object will answer this message by * returning a shallow copy of itself. This means that the values in the * newly returned list can be replaced or deleted without affecting * the original one. However, modifying the values in the list will * still cause their counterparts in the original list to be modified * as well. * In the example we replace the first item (1) in b with 999. * The first element in a will still be 1 though because we have created * copy b by sending the message 'copy' to a and assiging the result * to b. * * Usage: * * ☞ a := List ← 1 ; 2 ; 3. * ☞ b := a copy. * b put: 999 at: 1. * * In other languages: * Dutch: [Reeks] kopieer | Maakt een kopie van de reeks. */ ctr_object* ctr_array_copy(ctr_object* myself, ctr_argument* argumentList) { ctr_size i = 0; ctr_object* copy = ctr_array_new( CtrStdArray, argumentList ); ctr_argument* arg = 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); arg->object = ctr_array_get( myself, index ); ctr_array_push( copy, arg ); } ctr_heap_free( arg ); ctr_heap_free( index ); return copy; }
/** * [Map] values * * Returns an array containing all the keys in the map. * The order of the keys is undefined. Use the sort message * to enforce a specific order. * * Usage: * * ☞ city := List ← 'London' ; 'Paris' ; 'Berlin'. * ☞ temperature := List ← '15' ; '16' ; '15'. * * ☞ weather := temperature by: city. * temperatures := weather values sort: { * :a :b ↲ (a compare: b). * }. * * In other languages: * Dutch: [Lijst] waarden | Geeft alle waarden uit de lijst als een reeks. */ ctr_object* ctr_map_values(ctr_object* myself, ctr_argument* argumentList) { ctr_object* list; ctr_mapitem* m; ctr_argument* element; list = ctr_array_new( CtrStdArray, argumentList ); m = myself->properties->head; element = ctr_heap_allocate( sizeof( ctr_argument ) ); while( m ) { element->object = m->value; ctr_array_push( list, element ); m = m->next; } ctr_heap_free( element ); return list; }
/** * [Array] from: [Begin] to: [End] * * Copies part of an array indicated by from and to and * returns a new array consisting of a copy of this region. */ ctr_object* ctr_array_from_to(ctr_object* myself, ctr_argument* argumentList) { ctr_argument* pushArg; ctr_argument* elnumArg; ctr_object* elnum; ctr_object* startElement = ctr_internal_cast2number(argumentList->object); ctr_object* count = ctr_internal_cast2number(argumentList->next->object); int start = (int) startElement->value.nvalue; int len = (int) count->value.nvalue; int i = 0; ctr_object* newArray = ctr_array_new(CtrStdArray, NULL); for(i = start; i < start + len; i++) { pushArg = CTR_CREATE_ARGUMENT(); elnumArg = CTR_CREATE_ARGUMENT(); elnum = ctr_build_number_from_float((ctr_number) i); elnumArg->object = elnum; pushArg->object = ctr_array_get(myself, elnumArg); ctr_array_push(newArray, pushArg); } return newArray; }
/** * [List] replace: [Number] length: [Number] with: [List]. * * Returns a copy of the list with the specified elements replaced. * The first argument indicates the start index to begin the replacement. * Here, 0 means the beginning of the list. * The second argument (length) * must indicate the number of elements to delete in the copy, counting * from the starting point. Finally, one has to provide the replacement * list as the third argument. * If the replacement list is empty, the specified elements will only be * removed from the copy. * If the replacement is not an array an error will be thrown. * * Usage: * * ☞ buy := cakes * replace: 1 * length: 2 * with: ( List ← 'cinnamon' ; 'pineapple' ). * * In other languages: * Dutch: [Reeks] vervang: [Getal] lengte: [Getal] door: [Reeks] * Vervangt een deel van de reeks door een andere reeks. */ ctr_object* ctr_array_splice(ctr_object* myself, ctr_argument* argumentList) { ctr_object* newArray = ctr_array_new(CtrStdArray, NULL); ctr_object* start = ctr_internal_cast2number(argumentList->object); ctr_object* deleteCount = ctr_internal_cast2number(argumentList->next->object); ctr_object* replacement = argumentList->next->next->object; ctr_object* remainder; ctr_argument* sliceFromArg; ctr_argument* sliceLengthArg; ctr_argument* replacementArg; ctr_argument* remainderArg; ctr_size n; if ( replacement->info.type != CTR_OBJECT_TYPE_OTARRAY ) { CtrStdFlow = ctr_error_text( CTR_ERR_EXP_ARR ); return myself; } n = ( start->value.nvalue + deleteCount->value.nvalue ); sliceFromArg = (ctr_argument*) ctr_heap_allocate( sizeof( ctr_argument ) ); sliceLengthArg = (ctr_argument*) ctr_heap_allocate( sizeof( ctr_argument ) ); replacementArg = (ctr_argument*) ctr_heap_allocate( sizeof( ctr_argument ) ); remainderArg = (ctr_argument*) ctr_heap_allocate( sizeof( ctr_argument ) ); sliceFromArg->object = ctr_build_number_from_float(0); sliceLengthArg->object = start; sliceFromArg->next = sliceLengthArg; newArray = ctr_array_from_length( myself, sliceFromArg ); replacementArg->object = replacement; newArray = ctr_array_add(newArray, replacementArg); sliceFromArg->object = ctr_build_number_from_float( n ); if ( n < (myself->value.avalue->head - myself->value.avalue->tail) ) { sliceLengthArg->object = ctr_build_number_from_float( (myself->value.avalue->head - myself->value.avalue->tail) - n ); sliceFromArg->next = sliceLengthArg; remainder = ctr_array_from_length( myself, sliceFromArg ); remainderArg->object = remainder; newArray = ctr_array_add( newArray, remainderArg ); } ctr_heap_free( sliceFromArg ); ctr_heap_free( sliceLengthArg ); ctr_heap_free( replacementArg ); ctr_heap_free( remainderArg ); return newArray; }
/** * [List] from: [Begin] length: [End] * * Copies part of an array indicated by from and to and * returns a new array consisting of a copy of this region. * * In other languages: * Dutch: [Reeks] van: [Getal] lengte: [Getal] | Geeft subreeks. */ ctr_object* ctr_array_from_length(ctr_object* myself, ctr_argument* argumentList) { ctr_argument* pushArg; ctr_argument* elnumArg; ctr_object* elnum; ctr_object* startElement = ctr_internal_cast2number(argumentList->object); ctr_object* count = ctr_internal_cast2number(argumentList->next->object); int start = (int) startElement->value.nvalue; int len = (int) count->value.nvalue; int i = 0; ctr_object* newArray = ctr_array_new(CtrStdArray, NULL); for(i = start; i < start + len; i++) { pushArg = (ctr_argument*) ctr_heap_allocate( sizeof( ctr_argument ) ); elnumArg = (ctr_argument*) ctr_heap_allocate( sizeof( ctr_argument ) ); elnum = ctr_build_number_from_float((ctr_number) i); elnumArg->object = elnum; pushArg->object = ctr_array_get(myself, elnumArg); ctr_array_push(newArray, pushArg); ctr_heap_free( elnumArg ); ctr_heap_free( pushArg ); } return newArray; }
/** * StringSplit * * Converts a string to an array by splitting the string using * the specified delimiter (also a string). */ ctr_object* ctr_string_split(ctr_object* myself, ctr_argument* argumentList) { char* str = myself->value.svalue->value; long len = myself->value.svalue->vlen; ctr_object* delimObject = ctr_internal_cast2string(argumentList->object); char* dstr = delimObject->value.svalue->value; long dlen = delimObject->value.svalue->vlen; ctr_argument* arg; char* elem; ctr_object* arr = ctr_array_new(CtrStdArray, NULL); long i; long j = 0; char* buffer = malloc(sizeof(char)*len); for(i=0; i<len; i++) { buffer[j] = str[i]; j++; if (ctr_internal_memmem(buffer, j, dstr, dlen, 0)!=NULL) { elem = malloc(sizeof(char)*(j-dlen)); memcpy(elem,buffer,j-dlen); arg = malloc(sizeof(ctr_argument)); arg->object = ctr_build_string(elem, j-dlen); ctr_array_push(arr, arg); free(arg); j=0; } } if (j>0) { elem = malloc(sizeof(char)*j); memcpy(elem,buffer,j); arg = malloc(sizeof(ctr_argument)); arg->object = ctr_build_string(elem, j); ctr_array_push(arr, arg); free(arg); } free(buffer); return arr; }
/** * [List] ← [Element1] ; [Element2] ; ... * * Creates a new instance of a list and initializes this * array with a first element, useful for literal-like List * notations. In the example we create a new list consisting * of the numbers 1, 2 and 3. * * Usage: * * a := List ← 1 ; 2 ; 3. * * In other languages: * Dutch: [Reeks] ← [Element1] ; [Element2] ; ... | De pijl maakt een nieuwe reeks en voegt het eerste * element direct toe, opvolgende elementen kunnen worden gescheiden door puntkomma's (;), hiermee * voegt men telkens een nieuw element toe aan de reeks. */ ctr_object* ctr_array_new_and_push(ctr_object* myclass, ctr_argument* argumentList) { ctr_object* s = ctr_array_new(myclass, NULL); return ctr_array_push(s, argumentList); }
/** * WorldInitialize * * Populate the World of Citrine. */ void ctr_initialize_world() { int i; srand((unsigned)time(NULL)); for(i=0; i<16; i++) { CtrHashKey[i] = (rand() % 255); } ctr_first_object = NULL; CtrStdWorld = ctr_internal_create_object(CTR_OBJECT_TYPE_OTOBJECT); ctr_contexts[0] = CtrStdWorld; /* Object */ CtrStdObject = ctr_internal_create_object(CTR_OBJECT_TYPE_OTOBJECT); ctr_internal_create_func(CtrStdObject, ctr_build_string("new", 3), &ctr_object_make); ctr_internal_create_func(CtrStdObject, ctr_build_string("equals:", 7), &ctr_object_equals); ctr_internal_create_func(CtrStdObject, ctr_build_string("=",1), &ctr_object_equals); ctr_internal_create_func(CtrStdObject, ctr_build_string("on:do:", 6), &ctr_object_on_do); ctr_internal_create_func(CtrStdObject, ctr_build_string("respondTo:", 10), &ctr_object_respond); ctr_internal_create_func(CtrStdObject, ctr_build_string("respondTo:with:", 15), &ctr_object_respond); ctr_internal_create_func(CtrStdObject, ctr_build_string("respondTo:with:and:", 19), &ctr_object_respond); ctr_internal_create_func(CtrStdObject, ctr_build_string("type", 4), &ctr_object_type); ctr_internal_create_func(CtrStdObject, ctr_build_string("new", 3), &ctr_object_make); ctr_internal_create_func(CtrStdObject, ctr_build_string("isNil", 5), &ctr_object_is_nil); ctr_internal_create_func(CtrStdObject, ctr_build_string("myself", 6), &ctr_object_myself); ctr_internal_object_add_property(CtrStdWorld, ctr_build_string("Object", 6), CtrStdObject, 0); CtrStdObject->link = NULL; /* Nil */ CtrStdNil = ctr_internal_create_object(CTR_OBJECT_TYPE_OTNIL); ctr_internal_object_add_property(CtrStdWorld, ctr_build_string("Nil", 3), CtrStdNil, 0); ctr_internal_create_func(CtrStdNil, ctr_build_string("isNil", 5), &ctr_nil_is_nil); CtrStdNil->link = CtrStdObject; /* Boolean */ CtrStdBool = ctr_internal_create_object(CTR_OBJECT_TYPE_OTBOOL); ctr_internal_create_func(CtrStdBool, ctr_build_string("ifTrue:", 7), &ctr_bool_iftrue); ctr_internal_create_func(CtrStdBool, ctr_build_string("ifFalse:", 8), &ctr_bool_ifFalse); ctr_internal_create_func(CtrStdBool, ctr_build_string("break", 5), &ctr_bool_break); ctr_internal_create_func(CtrStdBool, ctr_build_string("continue", 8), &ctr_bool_continue); ctr_internal_create_func(CtrStdBool, ctr_build_string("else:", 5), &ctr_bool_ifFalse); ctr_internal_create_func(CtrStdBool, ctr_build_string("not", 3), &ctr_bool_not); ctr_internal_create_func(CtrStdBool, ctr_build_string("∧", 3), &ctr_bool_and); ctr_internal_create_func(CtrStdBool, ctr_build_string("nor:", 4), &ctr_bool_nor); ctr_internal_create_func(CtrStdBool, ctr_build_string("∨", 3), &ctr_bool_or); ctr_internal_create_func(CtrStdBool, ctr_build_string("xor:", 4), &ctr_bool_xor); ctr_internal_create_func(CtrStdBool, ctr_build_string("=",1),&ctr_bool_eq); ctr_internal_create_func(CtrStdBool, ctr_build_string("≠",3),&ctr_bool_neq); ctr_internal_create_func(CtrStdBool, ctr_build_string("toNumber", 8), &ctr_bool_to_number); ctr_internal_create_func(CtrStdBool, ctr_build_string("toString", 8), &ctr_bool_to_string); ctr_internal_create_func(CtrStdBool, ctr_build_string("flip", 4), &ctr_bool_flip); ctr_internal_create_func(CtrStdBool, ctr_build_string("either:or:", 10), &ctr_bool_either_or); ctr_internal_object_add_property(CtrStdWorld, ctr_build_string("Boolean", 7), CtrStdBool, 0); CtrStdBool->link = CtrStdObject; /* Number */ CtrStdNumber = ctr_internal_create_object(CTR_OBJECT_TYPE_OTNUMBER); ctr_internal_create_func(CtrStdNumber, ctr_build_string("to:by:do:", 9), &ctr_number_to_by_do); ctr_internal_create_func(CtrStdNumber, ctr_build_string("+", 1), &ctr_number_add); ctr_internal_create_func(CtrStdNumber, ctr_build_string("inc:",4), &ctr_number_inc); ctr_internal_create_func(CtrStdNumber, ctr_build_string("-",1), &ctr_number_minus); ctr_internal_create_func(CtrStdNumber, ctr_build_string("dec:",4), &ctr_number_dec); ctr_internal_create_func(CtrStdNumber, ctr_build_string("*",1),&ctr_number_multiply); ctr_internal_create_func(CtrStdNumber, ctr_build_string("times:",6),&ctr_number_times); ctr_internal_create_func(CtrStdNumber, ctr_build_string("mul:",4),&ctr_number_mul); ctr_internal_create_func(CtrStdNumber, ctr_build_string("/",1), &ctr_number_divide); ctr_internal_create_func(CtrStdNumber, ctr_build_string("div:",4),&ctr_number_div); ctr_internal_create_func(CtrStdNumber, ctr_build_string(">",1),&ctr_number_higherThan); ctr_internal_create_func(CtrStdNumber, ctr_build_string("≥",3),&ctr_number_higherEqThan); ctr_internal_create_func(CtrStdNumber, ctr_build_string("<",1),&ctr_number_lowerThan); ctr_internal_create_func(CtrStdNumber, ctr_build_string("≤",3),&ctr_number_lowerEqThan); ctr_internal_create_func(CtrStdNumber, ctr_build_string("=",1),&ctr_number_eq); ctr_internal_create_func(CtrStdNumber, ctr_build_string("≠",3),&ctr_number_neq); ctr_internal_create_func(CtrStdNumber, ctr_build_string("%",1),&ctr_number_modulo); ctr_internal_create_func(CtrStdNumber, ctr_build_string("factorial",9),&ctr_number_factorial); ctr_internal_create_func(CtrStdNumber, ctr_build_string("floor",5),&ctr_number_floor); ctr_internal_create_func(CtrStdNumber, ctr_build_string("ceil",4),&ctr_number_ceil); ctr_internal_create_func(CtrStdNumber, ctr_build_string("round",5),&ctr_number_round); ctr_internal_create_func(CtrStdNumber, ctr_build_string("abs",3),&ctr_number_abs); ctr_internal_create_func(CtrStdNumber, ctr_build_string("sin",3),&ctr_number_sin); ctr_internal_create_func(CtrStdNumber, ctr_build_string("cos",3),&ctr_number_cos); ctr_internal_create_func(CtrStdNumber, ctr_build_string("exp",3),&ctr_number_exp); ctr_internal_create_func(CtrStdNumber, ctr_build_string("sqrt",4),&ctr_number_sqrt); ctr_internal_create_func(CtrStdNumber, ctr_build_string("tan",3),&ctr_number_tan); ctr_internal_create_func(CtrStdNumber, ctr_build_string("atan",4),&ctr_number_atan); ctr_internal_create_func(CtrStdNumber, ctr_build_string("log",3),&ctr_number_log); ctr_internal_create_func(CtrStdNumber, ctr_build_string("pow:",4),&ctr_number_pow); ctr_internal_create_func(CtrStdNumber, ctr_build_string("min:",4),&ctr_number_min); ctr_internal_create_func(CtrStdNumber, ctr_build_string("max:",4),&ctr_number_max); ctr_internal_create_func(CtrStdNumber, ctr_build_string("odd",3),&ctr_number_odd); ctr_internal_create_func(CtrStdNumber, ctr_build_string("even",4),&ctr_number_even); ctr_internal_create_func(CtrStdNumber, ctr_build_string("toString", 8), &ctr_number_to_string); ctr_internal_create_func(CtrStdNumber, ctr_build_string("toBoolean", 9), &ctr_number_to_boolean); ctr_internal_create_func(CtrStdNumber, ctr_build_string("between:and:",12),&ctr_number_between); ctr_internal_object_add_property(CtrStdWorld, ctr_build_string("Number", 6), CtrStdNumber, 0); CtrStdNumber->link = CtrStdObject; /* String */ CtrStdString = ctr_internal_create_object(CTR_OBJECT_TYPE_OTSTRING); ctr_internal_create_func(CtrStdString, ctr_build_string("bytes", 5), &ctr_string_bytes); ctr_internal_create_func(CtrStdString, ctr_build_string("length", 6), &ctr_string_length); ctr_internal_create_func(CtrStdString, ctr_build_string("from:to:", 8), &ctr_string_fromto); ctr_internal_create_func(CtrStdString, ctr_build_string("from:length:", 12), &ctr_string_from_length); ctr_internal_create_func(CtrStdString, ctr_build_string("+", 1), &ctr_string_concat); ctr_internal_create_func(CtrStdString, ctr_build_string("=", 1), &ctr_string_eq); ctr_internal_create_func(CtrStdString, ctr_build_string("≠", 3), &ctr_string_neq); ctr_internal_create_func(CtrStdString, ctr_build_string("trim", 4), &ctr_string_trim); ctr_internal_create_func(CtrStdString, ctr_build_string("ltrim", 5), &ctr_string_ltrim); ctr_internal_create_func(CtrStdString, ctr_build_string("rtrim", 5), &ctr_string_rtrim); ctr_internal_create_func(CtrStdString, ctr_build_string("htmlEscape", 10), &ctr_string_html_escape); ctr_internal_create_func(CtrStdString, ctr_build_string("at:", 3), &ctr_string_at); ctr_internal_create_func(CtrStdString, ctr_build_string("byteAt:", 7), &ctr_string_byte_at); ctr_internal_create_func(CtrStdString, ctr_build_string("indexOf:", 8), &ctr_string_index_of); ctr_internal_create_func(CtrStdString, ctr_build_string("lastIndexOf:", 12), &ctr_string_last_index_of); ctr_internal_create_func(CtrStdString, ctr_build_string("replace:with:", 13), &ctr_string_replace_with); ctr_internal_create_func(CtrStdString, ctr_build_string("split:", 6), &ctr_string_split); ctr_internal_create_func(CtrStdString, ctr_build_string("up", 2), &ctr_string_to_upper); ctr_internal_create_func(CtrStdString, ctr_build_string("low", 3), &ctr_string_to_lower); ctr_internal_create_func(CtrStdString, ctr_build_string("skip:", 5), &ctr_string_skip); ctr_internal_create_func(CtrStdString, ctr_build_string("toNumber", 8), &ctr_string_to_number); ctr_internal_create_func(CtrStdString, ctr_build_string("toBoolean", 9), &ctr_string_to_boolean); ctr_internal_object_add_property(CtrStdWorld, ctr_build_string("String", 6), CtrStdString, 0); CtrStdString->link = CtrStdObject; /* Block */ CtrStdBlock = ctr_internal_create_object(CTR_OBJECT_TYPE_OTBLOCK); ctr_internal_create_func(CtrStdBlock, ctr_build_string("run", 3), &ctr_block_runIt); ctr_internal_create_func(CtrStdBlock, ctr_build_string("*", 1), &ctr_block_times); ctr_internal_create_func(CtrStdBlock, ctr_build_string("applyTo:", 8), &ctr_block_runIt); ctr_internal_create_func(CtrStdBlock, ctr_build_string("applyTo:and:", 12), &ctr_block_runIt); ctr_internal_create_func(CtrStdBlock, ctr_build_string("applyTo:and:and:", 16), &ctr_block_runIt); ctr_internal_create_func(CtrStdBlock, ctr_build_string("set:value:", 10), &ctr_block_set); ctr_internal_create_func(CtrStdBlock, ctr_build_string("error:", 6), &ctr_block_error); ctr_internal_create_func(CtrStdBlock, ctr_build_string("catch:", 6), &ctr_block_catch); ctr_internal_create_func(CtrStdBlock, ctr_build_string("whileTrue:", 10), &ctr_block_while_true); ctr_internal_create_func(CtrStdBlock, ctr_build_string("whileFalse:", 11), &ctr_block_while_false); ctr_internal_object_add_property(CtrStdWorld, ctr_build_string("CodeBlock", 9), CtrStdBlock, 0); CtrStdBlock->link = CtrStdObject; /* Array */ CtrStdArray = ctr_array_new(CtrStdObject, NULL); ctr_internal_create_func(CtrStdArray, ctr_build_string("new", 3), &ctr_array_new); ctr_internal_create_func(CtrStdArray, ctr_build_string("←", 3), &ctr_array_new_and_push); ctr_internal_create_func(CtrStdArray, ctr_build_string("push:", 5), &ctr_array_push); ctr_internal_create_func(CtrStdArray, ctr_build_string(";", 1), &ctr_array_push); ctr_internal_create_func(CtrStdArray, ctr_build_string("unshift:", 8), &ctr_array_unshift); ctr_internal_create_func(CtrStdArray, ctr_build_string("shift", 5), &ctr_array_shift); ctr_internal_create_func(CtrStdArray, ctr_build_string("count", 5), &ctr_array_count); ctr_internal_create_func(CtrStdArray, ctr_build_string("join:", 5), &ctr_array_join); ctr_internal_create_func(CtrStdArray, ctr_build_string("pop", 3), &ctr_array_pop); ctr_internal_create_func(CtrStdArray, ctr_build_string("at:", 3), &ctr_array_get); ctr_internal_create_func(CtrStdArray, ctr_build_string("@", 1), &ctr_array_get); ctr_internal_create_func(CtrStdArray, ctr_build_string("sort:", 5), &ctr_array_sort); ctr_internal_create_func(CtrStdArray, ctr_build_string("put:at:", 7), &ctr_array_put); ctr_internal_create_func(CtrStdArray, ctr_build_string("from:length:", 12), &ctr_array_from_to); ctr_internal_create_func(CtrStdArray, ctr_build_string("+", 1), &ctr_array_add); ctr_internal_create_func(CtrStdArray, ctr_build_string("map:", 4), &ctr_array_map); ctr_internal_create_func(CtrStdArray, ctr_build_string("each:", 5), &ctr_array_map); ctr_internal_object_add_property(CtrStdWorld, ctr_build_string("Array", 5), CtrStdArray, 0); CtrStdArray->link = CtrStdObject; /* Map */ CtrStdMap = ctr_internal_create_object(CTR_OBJECT_TYPE_OTOBJECT); ctr_internal_create_func(CtrStdMap, ctr_build_string("new", 3), &ctr_map_new); ctr_internal_create_func(CtrStdMap, ctr_build_string("put:at:", 7), &ctr_map_put); ctr_internal_create_func(CtrStdMap, ctr_build_string("at:", 3), &ctr_map_get); ctr_internal_create_func(CtrStdMap, ctr_build_string("@", 1), &ctr_map_get); ctr_internal_create_func(CtrStdMap, ctr_build_string("count", 5), &ctr_map_count); ctr_internal_create_func(CtrStdMap, ctr_build_string("each:", 5), &ctr_map_each); ctr_internal_create_func(CtrStdMap, ctr_build_string("map:", 4), &ctr_map_each); ctr_internal_object_add_property(CtrStdWorld, ctr_build_string("Map", 3), CtrStdMap, 0); CtrStdMap->link = CtrStdObject; /* Console */ CtrStdConsole = ctr_internal_create_object(CTR_OBJECT_TYPE_OTOBJECT); ctr_internal_create_func(CtrStdConsole, ctr_build_string("write:", 6), &ctr_console_write); ctr_internal_create_func(CtrStdConsole, ctr_build_string(">", 1), &ctr_console_write); ctr_internal_create_func(CtrStdConsole, ctr_build_string("brk", 3), &ctr_console_brk); ctr_internal_object_add_property(CtrStdWorld, ctr_build_string("Pen", 3), CtrStdConsole, 0); ctr_internal_object_add_property(CtrStdWorld, ctr_build_string("?", 1), CtrStdConsole, 0); CtrStdConsole->link = CtrStdObject; /* File */ CtrStdFile = ctr_internal_create_object(CTR_OBJECT_TYPE_OTOBJECT); ctr_internal_create_func(CtrStdFile, ctr_build_string("new:", 4), &ctr_file_new); ctr_internal_create_func(CtrStdFile, ctr_build_string("path", 4), &ctr_file_path); ctr_internal_create_func(CtrStdFile, ctr_build_string("read", 4), &ctr_file_read); ctr_internal_create_func(CtrStdFile, ctr_build_string("write:", 6), &ctr_file_write); ctr_internal_create_func(CtrStdFile, ctr_build_string("append:", 7), &ctr_file_append); ctr_internal_create_func(CtrStdFile, ctr_build_string("exists", 6), &ctr_file_exists); ctr_internal_create_func(CtrStdFile, ctr_build_string("size", 4), &ctr_file_size); ctr_internal_create_func(CtrStdFile, ctr_build_string("delete", 6), &ctr_file_delete); ctr_internal_create_func(CtrStdFile, ctr_build_string("include", 7), &ctr_file_include); ctr_internal_create_func(CtrStdFile, ctr_build_string("go", 2), &ctr_file_include_ast); ctr_internal_object_add_property(CtrStdWorld, ctr_build_string("File", 4), CtrStdFile, 0); CtrStdFile->link = CtrStdObject; /* Command */ CtrStdCommand = ctr_internal_create_object(CTR_OBJECT_TYPE_OTOBJECT); ctr_internal_create_func(CtrStdCommand, ctr_build_string("argument:", 9), &ctr_command_argument); ctr_internal_create_func(CtrStdCommand, ctr_build_string("argCount", 8), &ctr_command_num_of_args); ctr_internal_create_func(CtrStdCommand, ctr_build_string("env:", 4), &ctr_command_get_env); ctr_internal_create_func(CtrStdCommand, ctr_build_string("env:val:", 8), &ctr_command_set_env); ctr_internal_create_func(CtrStdCommand, ctr_build_string("??", 2), &ctr_command_question); ctr_internal_create_func(CtrStdCommand, ctr_build_string("exit", 4), &ctr_command_exit); ctr_internal_object_add_property(CtrStdWorld, ctr_build_string("Command", 7), CtrStdCommand, 0); CtrStdCommand->link = CtrStdObject; /* Clock */ CtrStdClock = ctr_internal_create_object(CTR_OBJECT_TYPE_OTOBJECT); ctr_internal_create_func(CtrStdClock, ctr_build_string("wait:", 5), &ctr_clock_wait); ctr_internal_create_func(CtrStdClock, ctr_build_string("time", 4), &ctr_clock_time); ctr_internal_object_add_property(CtrStdWorld, ctr_build_string("Clock", 5), CtrStdClock, 0); CtrStdClock->link = CtrStdObject; /* Dice */ CtrStdDice = ctr_internal_create_object(CTR_OBJECT_TYPE_OTOBJECT); ctr_internal_create_func(CtrStdDice, ctr_build_string("roll", 4), &ctr_dice_throw); ctr_internal_create_func(CtrStdDice, ctr_build_string("rollWithSides:", 14), &ctr_dice_sides); ctr_internal_object_add_property(CtrStdWorld, ctr_build_string("Dice", 4), CtrStdDice, 0); CtrStdDice->link = CtrStdObject; /* Shell */ CtrStdShell = ctr_internal_create_object(CTR_OBJECT_TYPE_OTOBJECT); ctr_internal_create_func(CtrStdShell, ctr_build_string("call:", 5), &ctr_shell_call); ctr_internal_object_add_property(CtrStdWorld, ctr_build_string("Shell", 5), CtrStdShell, 0); CtrStdShell->link = CtrStdObject; /* Broom */ CtrStdGC = ctr_internal_create_object(CTR_OBJECT_TYPE_OTOBJECT); ctr_internal_create_func(CtrStdGC, ctr_build_string("sweep", 5), &ctr_gc_collect); ctr_internal_create_func(CtrStdGC, ctr_build_string("dust", 4), &ctr_gc_dust); ctr_internal_create_func(CtrStdGC, ctr_build_string("objectCount", 11), &ctr_gc_object_count); ctr_internal_object_add_property(CtrStdWorld, ctr_build_string("Broom", 5), CtrStdGC, 0); CtrStdGC->link = CtrStdObject; /* Other objects */ CtrStdBreak = ctr_internal_create_object(CTR_OBJECT_TYPE_OTOBJECT); CtrStdContinue = ctr_internal_create_object(CTR_OBJECT_TYPE_OTOBJECT); }