Ejemplo n.º 1
0
/**
 * [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;
}
Ejemplo n.º 2
0
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;
        }
    }
Ejemplo n.º 3
0
/**
 * StringLastIndexOf
 *
 * Returns the index (character number, not the byte!) of the
 * needle in the haystack.
 * 
 * Usage:
 * 'find the needle' lastIndexOf: 'needle'. #9
 */
ctr_object* ctr_string_last_index_of(ctr_object* myself, ctr_argument* argumentList) {
	ctr_object* sub = ctr_internal_cast2string(argumentList->object);
	long hlen = myself->value.svalue->vlen;
	long nlen = sub->value.svalue->vlen;
	ctr_size uchar_index;
	ctr_size byte_index;
	char* p = ctr_internal_memmem(myself->value.svalue->value, hlen, sub->value.svalue->value, nlen, 1);
	if (p == NULL) return ctr_build_number_from_float((float)-1);
	byte_index = (ctr_size) ( (uintptr_t) p - (uintptr_t) (myself->value.svalue->value) );
	uchar_index = ctr_getutf8len(myself->value.svalue->value, byte_index);
	return ctr_build_number_from_float((float) uchar_index);
}
Ejemplo n.º 4
0
/**
 * InternalNumberCast
 *
 * Casts an object to a number object.
 */
ctr_object* ctr_internal_cast2number(ctr_object* o) {
	if (o->info.type == CTR_OBJECT_TYPE_OTNUMBER) return o;
	if (o->info.type == CTR_OBJECT_TYPE_OTSTRING) {
		return ctr_build_number_from_string(o->value.svalue->value, o->value.svalue->vlen);
	}
	return ctr_build_number_from_float((ctr_number)0);
}
Ejemplo n.º 5
0
/**
 * [List] map: [Block].
 *
 * Iterates over the array. Passing each element as a key-value pair to the
 * specified block.
 * The map message will pass the following arguments to the block, the key,
 * the value and a reference to the array itself. The last argument might seem
 * redundant but allows for a more functional programming style. Instead of map,
 * you can also use each:.
 *
 * Usage:
 *
 * files map: showName.
 * files map: {
 *   :key :filename :files
 *   ✎ write: filename.
 * }.
 *
 * files each: {
 *   :key :filename :files
 *   ✎ write: filename.
 * }.
 *
 * In other languages:
 * Dutch: [Reeks] lijst: [Codeblok] | Maakt van een reeks
 */
ctr_object* ctr_array_map(ctr_object* myself, ctr_argument* argumentList) {
	ctr_object* block = argumentList->object;
	int i = 0;
	if (block->info.type != CTR_OBJECT_TYPE_OTBLOCK) {
		CtrStdFlow = ctr_build_string_from_cstring( CTR_ERR_EXP_BLK );
		CtrStdFlow->info.sticky = 1;
	}
	for(i = myself->value.avalue->tail; i < myself->value.avalue->head; i++) {
		ctr_argument* arguments = (ctr_argument*) ctr_heap_allocate( sizeof( ctr_argument ) );
		ctr_argument* argument2 = (ctr_argument*) ctr_heap_allocate( sizeof( ctr_argument ) );
		ctr_argument* argument3 = (ctr_argument*) ctr_heap_allocate( sizeof( ctr_argument ) );
		arguments->object = ctr_build_number_from_float((double) i);
		argument2->object = *(myself->value.avalue->elements + i);
		argument3->object = myself;
		arguments->next = argument2;
		argument2->next = argument3;
		/* keep receiver in block object otherwise, GC will destroy it */
		ctr_gc_internal_pin(block);
		ctr_gc_internal_pin(myself);
		ctr_gc_internal_pin(argument2->object);
		ctr_block_run(block, arguments, myself);
		ctr_heap_free( arguments );
		ctr_heap_free( argument2 );
		ctr_heap_free( argument3 );
		if (CtrStdFlow == CtrStdContinue) CtrStdFlow = NULL;
		if (CtrStdFlow) break;
	}
	if (CtrStdFlow == CtrStdBreak) CtrStdFlow = NULL; /* consume break */
	return myself;
}
Ejemplo n.º 6
0
/**
 * Factorial
 *
 * Calculates the factorial of a number.
 */
ctr_object* ctr_number_factorial(ctr_object* myself, ctr_argument* argumentList) {
	ctr_number t = myself->value.nvalue;
	int i;
	ctr_number a = 1;
	for(i = (int) t; i > 0; i--) {
		a = a * i;
	}
	return ctr_build_number_from_float(a);
}
Ejemplo n.º 7
0
/**
 * [Array] sum
 *
 * Takes the sum of an array. This message will calculate the
 * sum of the numerical elements in the array.
 *
 * Usage:
 *
 * a := Array <- 1 ; 2 ; 3.
 * s := a sum. #6
 *
 * In the example above, the sum of array will be stored in s and
 * it's value will be 6. 
 */
ctr_object* ctr_array_sum(ctr_object* myself, ctr_argument* argumentList) {
	double sum = 0;
	ctr_object* el;
	size_t i = 0;
	for(i = 0; i < myself->value.avalue->head; i++) {
		el = *(myself->value.avalue->elements + i);
		sum += ctr_internal_cast2number(el)->value.nvalue;
	}
	return ctr_build_number_from_float(sum);
}
Ejemplo n.º 8
0
/**
 * [Shell] call: [String]
 *
 * Performs a Shell operation. The Shell object uses a fluid API, so you can
 * mix shell code with programming logic. For instance to list the contents
 * of a directory use:
 *
 * Shell ls
 *
 * This will output the contents of the current working directly, you
 * can also pass keyword messages like so:
 *
 * Shell echo: 'Hello from the Shell!'.
 *
 * The example above will output the specified message to the console.
 * Every message you send will be turned into a string and dispatched to
 * the 'call:' message.
 */
ctr_object* ctr_shell_call(ctr_object* myself, ctr_argument* argumentList) {
	ctr_object* arg = ctr_internal_cast2string(argumentList->object);
	long vlen = arg->value.svalue->vlen;
	char* comString = malloc(vlen + 1);
	int r;
	memcpy(comString, arg->value.svalue->value, vlen);
	memcpy(comString+vlen,"\0",1);
	r = system(comString);
	return ctr_build_number_from_float( (ctr_number) r );
}
Ejemplo n.º 9
0
/**
 * StringByteAt
 *
 * Returns the byte at the specified position (in bytes).
 *
 * Usage:
 * ('abc' byteAt: 1). #98
 */
ctr_object* ctr_string_byte_at(ctr_object* myself, ctr_argument* argumentList) {
	char x;
	ctr_object* fromPos = ctr_internal_cast2number(argumentList->object);
	long a = (fromPos->value.nvalue);
	long len = myself->value.svalue->vlen;
	if (a > len) return CtrStdNil;
	if (a < 0) return CtrStdNil;
	x = (char) *(myself->value.svalue->value + a);
	return ctr_build_number_from_float((double)x);
}
Ejemplo n.º 10
0
ctr_object* ctr_number_modulo(ctr_object* myself, ctr_argument* argumentList) {
	ctr_object* otherNum = ctr_internal_cast2number(argumentList->object);
ctr_number a = myself->value.nvalue;
ctr_number b = otherNum->value.nvalue;
	if (b == 0) {
		CtrStdError = ctr_build_string_from_cstring("Division by zero.");
		return myself;
	}
	return ctr_build_number_from_float(fmod(a,b));
}
Ejemplo n.º 11
0
/**
 * Percolator new
 * 
 * Creates a new instance of the percolator object.
 * 
 * Usage:
 * 
 * myPercolator := Percolator new.
 * cupOfCoffee  := myPercolator coffee: 1 water: 2, brew.
 * 
 */
ctr_object* ctr_percolator_new(ctr_object* myself, ctr_argument* argumentList) {
	
	ctr_object* percolatorInstance = ctr_internal_create_object(CTR_OBJECT_TYPE_OTOBJECT);
	percolatorInstance->link = myself;
	ctr_internal_object_set_property(
		percolatorInstance, 
		ctr_build_string_from_cstring( "coffee" ),
		ctr_build_number_from_float(0),
		CTR_CATEGORY_PRIVATE_PROPERTY
	);
	ctr_internal_object_set_property(
		percolatorInstance, 
		ctr_build_string_from_cstring( "water" ),
		ctr_build_number_from_float(0),
		CTR_CATEGORY_PRIVATE_PROPERTY
	);
	
	return percolatorInstance;	
}
Ejemplo n.º 12
0
ctr_object* ctr_number_multiply(ctr_object* myself, ctr_argument* argumentList) {
	ctr_object* otherNum;
	ctr_number a;
	ctr_number b;
	CTR_MIRROR_CALL(CTR_OBJECT_TYPE_OTBLOCK, ctr_block_times, mirror1);
	otherNum = ctr_internal_cast2number(argumentList->object);
	a = myself->value.nvalue;
	b = otherNum->value.nvalue;
	return ctr_build_number_from_float(a*b);
}
Ejemplo n.º 13
0
ctr_object* ctr_string_skip(ctr_object* myself, ctr_argument* argumentList) {
	ctr_argument* argument1;
	ctr_argument* argument2;
	if (myself->value.svalue->vlen < argumentList->object->value.nvalue) return ctr_build_string("",0);
	argument1 = CTR_CREATE_ARGUMENT();
	argument2 = CTR_CREATE_ARGUMENT();
	argument1->object = argumentList->object;
	argument1->next = argument2;
	argument2->object = ctr_build_number_from_float(myself->value.svalue->vlen - argumentList->object->value.nvalue);
	return ctr_string_from_length(myself, argument1);
}
Ejemplo n.º 14
0
/**
 * [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;
}
Ejemplo n.º 15
0
/**
 * [File] writeBytes: [String].
 *
 * Takes a string and writes the bytes in the string to the file
 * object. Returns the number of bytes actually written.
 *
 * Usage:
 *
 * f := File new: '/path/to/file.txt'.
 * f open: 'r+'.
 * n := f writeBytes: 'Hello World'.
 * f close.
 *
 * The example above writes 'Hello World' to the specified file as bytes.
 * The number of bytes written is returned in variable n.
 */
ctr_object* ctr_file_write_bytes(ctr_object* myself, ctr_argument* argumentList) {
	int bytes, written;
	ctr_object* string2write;
	char* buffer;
	if (myself->value.rvalue == NULL) return myself;
	if (myself->value.rvalue->type != 1) return myself;
	string2write = ctr_internal_cast2string(argumentList->object);
	buffer = ctr_heap_allocate_cstring( string2write );
	bytes = string2write->value.svalue->vlen;
	written = fwrite(buffer, sizeof(char), (int)bytes, (FILE*)myself->value.rvalue->ptr);
	ctr_heap_free( buffer );
	return ctr_build_number_from_float((double_t) written);
}
Ejemplo n.º 16
0
/**
 * [File] size
 *
 * Returns the size of the file.
 */
ctr_object* ctr_file_size(ctr_object* myself, ctr_argument* argumentList) {
	ctr_object* path = ctr_internal_object_find_property(myself, ctr_build_string("path",4), 0);
	ctr_size vlen;
	char* pathString;
	FILE* f;
	int prev, sz;
	if (path == NULL) return ctr_build_number_from_float(0);
	vlen = path->value.svalue->vlen;
	pathString = malloc(vlen + 1);
	memcpy(pathString, path->value.svalue->value, vlen);
	memcpy(pathString+vlen,"\0",1);
	f = fopen(pathString, "r");
	if (f == NULL) return ctr_build_number_from_float(0);
	prev = ftell(f);
    fseek(f, 0L, SEEK_END);
    sz=ftell(f);
    fseek(f,prev,SEEK_SET);
    if (f) {
		fclose(f);
	}
    return ctr_build_number_from_float( (ctr_number) sz );
}
Ejemplo n.º 17
0
/**
 * [List] maximum
 *
 * Returns the maximum value in a list.
 * In the example this will yield the number 16.
 *
 * Usage:
 *
 * a := List ← 8 ; 4 ; 2 ; 16.
 * m := a maximum.
 *
 * In other languages:
 * Dutch: [Reeks] maximum | Geeft de hoogste waarde uit de reeks terug.
 *
 */
ctr_object* ctr_array_max(ctr_object* myself, ctr_argument* argumentList) {
	double max = 0;
	double v = 0;
	ctr_object* el;
	size_t i = 0;
	for(i = 0; i < myself->value.avalue->head; i++) {
		el = *(myself->value.avalue->elements + i);
		v = ctr_internal_cast2number(el)->value.nvalue;
		if (i == 0 || max < v) {
			max = v;
		}
	}
	return ctr_build_number_from_float(max);
}
Ejemplo n.º 18
0
/**
 * [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;
}
Ejemplo n.º 19
0
/**
 * [List] find: [Object].
 *
 * Checks whether the specified object occurs in the list
 * and returns the index number if so.
 * If not, the index number -1 will be returned. Note that the comparison
 * will be performed by converting both values to strings.
 *
 * In other languages:
 * Dutch: [Reeks] vind: [Object]
 * Geeft de positie van het object terug of -1 als niet gevonden.
 */
ctr_object* ctr_array_index_of( ctr_object* myself, ctr_argument* argumentList ) {
	int64_t found = -1, i = 0;
	ctr_object* needle = ctr_internal_cast2string(argumentList->object);
	ctr_object* element;
	for(i = myself->value.avalue->tail; i < myself->value.avalue->head; i++) {
		element = ctr_internal_cast2string( (ctr_object*) *(myself->value.avalue->elements + i) );
		if (
		element->value.svalue->vlen == needle->value.svalue->vlen &&
		strncmp(element->value.svalue->value,needle->value.svalue->value,needle->value.svalue->vlen)==0) {
			found = i;
			break;
		}
	}
	return ctr_build_number_from_float(found);
}
Ejemplo n.º 20
0
ctr_object* ctr_number_add(ctr_object* myself, ctr_argument* argumentList) {
	ctr_argument* newArg;
	ctr_object* otherNum = argumentList->object;
	ctr_number a;
	ctr_number b;
	ctr_object* strObject;
	if (otherNum->info.type == CTR_OBJECT_TYPE_OTSTRING) {
		strObject = ctr_internal_create_object(CTR_OBJECT_TYPE_OTSTRING);
		strObject = ctr_internal_cast2string(myself);
		newArg = CTR_CREATE_ARGUMENT();
		newArg->object = otherNum;
		return ctr_string_concat(strObject, newArg);
	}
	a = myself->value.nvalue;
	b = otherNum->value.nvalue;
	return ctr_build_number_from_float((a+b));
}
Ejemplo n.º 21
0
/**
 * [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;
}
Ejemplo n.º 22
0
/**
 * BlockTimes
 *
 * Runs the specified code block N times.
 *
 * Usage:
 * { ... } * 7.
 */
ctr_object* ctr_block_times(ctr_object* myself, ctr_argument* argumentList) {
	ctr_object* indexNumber;
	ctr_object* block = myself;
	ctr_argument* arguments;
	int t;
	int i;
	if (block->info.type != CTR_OBJECT_TYPE_OTBLOCK) { printf("Expected code block."); exit(1); }
	block->info.sticky = 1;
	t = ctr_internal_cast2number(argumentList->object)->value.nvalue;
	for(i=0; i<t; i++) {
		indexNumber = ctr_build_number_from_float((ctr_number) i);
		arguments = CTR_CREATE_ARGUMENT();
		arguments->object = indexNumber;
		ctr_block_run(block, arguments, block);
		if (CtrStdError) break;
	}
	if (CtrStdError == CtrStdNil) CtrStdError = NULL; /* consume break */
	block->info.mark = 0;
	block->info.sticky = 0;
	return myself;
}
Ejemplo n.º 23
0
/**
 * [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;
}
Ejemplo n.º 24
0
/**
 * [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;
}
Ejemplo n.º 25
0
/**
 * [Array] map: [Block].
 *
 * Iterates over the array. Passing each element as a key-value pair to the
 * specified block.
 * 
 * Usage:
 *
 * files map: showName.
 * files map: { key filename | Pen write: filename, brk. }.
 */
ctr_object* ctr_array_map(ctr_object* myself, ctr_argument* argumentList) {
	ctr_object* block = argumentList->object;
	int i = 0;
	if (block->info.type != CTR_OBJECT_TYPE_OTBLOCK) {
		CtrStdError = ctr_build_string_from_cstring("Expected Block.\0");
	}
	block->info.sticky = 1;
	for(i = 0; i < myself->value.avalue->head; i++) {
		ctr_argument* arguments = CTR_CREATE_ARGUMENT();
		ctr_argument* argument2 = CTR_CREATE_ARGUMENT();
		arguments->object = ctr_build_number_from_float((double) i);
		argument2->object = *(myself->value.avalue->elements + i);
		arguments->next = argument2;
		ctr_block_run(block, arguments, myself);
		if (CtrStdError == CtrStdContinue) CtrStdError = NULL;
		if (CtrStdError) break;
	}
	if (CtrStdError == CtrStdBreak) CtrStdError = NULL; /* consume break */
	block->info.mark = 0;
	block->info.sticky = 0;
	return myself;
}
Ejemplo n.º 26
0
ctr_object* ctr_number_to_by_do(ctr_object* myself, ctr_argument* argumentList) {
	double startValue = myself->value.nvalue;
	double endValue   = ctr_internal_cast2number(argumentList->object)->value.nvalue;
	double incValue   = ctr_internal_cast2number(argumentList->next->object)->value.nvalue;
	double curValue   = startValue;
	ctr_object* codeBlock = argumentList->next->next->object;
	ctr_argument* arguments;
	int forward = 0;
	if (startValue == endValue) return myself;
	forward = (startValue < endValue);
	if (codeBlock->info.type != CTR_OBJECT_TYPE_OTBLOCK) {
		CtrStdError = ctr_build_string_from_cstring("Expected block.\0");
		return myself;
	}
	while(((forward && curValue <= endValue) || (!forward && curValue >= endValue)) && !CtrStdError) {
		arguments = CTR_CREATE_ARGUMENT();
		arguments->object = ctr_build_number_from_float(curValue);
		ctr_block_run(codeBlock, arguments, codeBlock);
		curValue += incValue;
	}
	if (CtrStdError == CtrStdNil) CtrStdError = NULL; /* consume break */
	return myself;
}
Ejemplo n.º 27
0
/**
 * StringLength
 *
 * Returns the length of the string in symbols.
 * This message is UTF-8 unicode aware. A 4 byte character will be counted as ONE.
 */
ctr_object* ctr_string_length(ctr_object* myself, ctr_argument* argumentList) {
	ctr_size n = ctr_getutf8len(myself->value.svalue->value, (ctr_size) myself->value.svalue->vlen);
	return ctr_build_number_from_float((ctr_number) n);
}
Ejemplo n.º 28
0
/**
 * StringBytes
 *
 * Returns the number of bytes in a string.
 */
ctr_object* ctr_string_bytes(ctr_object* myself, ctr_argument* argumentList) {
	return ctr_build_number_from_float((float)myself->value.svalue->vlen);
}
Ejemplo n.º 29
0
/**
 * BooleanToNumber
 *
 * Wrapper for cast function.
 * Returns 0 if boolean is False and 1 otherwise.
 */
ctr_object* ctr_bool_to_number(ctr_object* myself, ctr_argument* argumentList) {
	return ctr_build_number_from_float( (ctr_number) myself->value.bvalue );
}
Ejemplo n.º 30
0
ctr_object* ctr_number_log(ctr_object* myself, ctr_argument* argumentList) {
	return ctr_build_number_from_float(log(myself->value.nvalue));
}