Example #1
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);
}
Example #2
0
int ctr_sort_cmp(const void * a, const void * b) {
	ctr_argument* arg1 = CTR_CREATE_ARGUMENT();
	ctr_argument* arg2 = CTR_CREATE_ARGUMENT();
	ctr_object* result;
	ctr_object* numResult;
	arg1->next = arg2;
	arg1->object = *((ctr_object**) a);
	arg2->object = *((ctr_object**) b);
	result = ctr_block_run(temp_sorter, arg1, temp_sorter);
	numResult = ctr_internal_cast2number(result);
	return (int) numResult->value.nvalue;
}
Example #3
0
/**
 * ifFalse
 *
 * Executes a block of code if the value of the boolean
 * object is True.
 *
 * Usage:
 * (some expression) ifFalse: {\ ... }.
 *
 */
ctr_object* ctr_bool_ifFalse(ctr_object* myself, ctr_argument* argumentList) {
	if (!myself->value.bvalue) {
		ctr_object* codeBlock = argumentList->object;
		ctr_argument* arguments = CTR_CREATE_ARGUMENT();
		arguments->object = myself;
		return ctr_block_run(codeBlock, arguments, codeBlock);
	}
	if (CtrStdError == CtrStdNil) CtrStdError = NULL; /* consume break */
	return myself;
}
Example #4
0
/**
 * CTRMessageSend
 *
 * Sends a message to a receiver object.
 */
ctr_object* ctr_send_message(ctr_object* receiverObject, char* message, long vlen, ctr_argument* argumentList) {
	char toParent = 0;
	ctr_object* me;
	ctr_object* methodObject;
	ctr_object* searchObject;
	ctr_argument* argCounter;
	ctr_argument* mesgArgument;
	ctr_object* result;
	ctr_object* (*funct)(ctr_object* receiverObject, ctr_argument* argumentList);
	int argCount;
	if (CtrStdError != NULL) return NULL; /* Error mode, ignore subsequent messages until resolved. */
	methodObject = NULL;
	searchObject = receiverObject;
	if (vlen > 1 && message[0] == '`') {
		me = ctr_internal_object_find_property(ctr_contexts[ctr_context_id], ctr_build_string_from_cstring("me\0"), 0);
		if (searchObject == me) {
			toParent = 1;
			message = message + 1;
			vlen--;
		}
	}
	while(!methodObject) {
		methodObject = ctr_internal_object_find_property(searchObject, ctr_build_string(message, vlen), 1);
		if (methodObject && toParent) { toParent = 0; methodObject = NULL; }
		if (methodObject) break;
		if (!searchObject->link) break;
		searchObject = searchObject->link;
	}
	if (!methodObject) {
		argCounter = argumentList;
		argCount = 0;
		while(argCounter->next && argCount < 4) {
			argCounter = argCounter->next;
			argCount ++;
		}
		mesgArgument = CTR_CREATE_ARGUMENT();
		mesgArgument->object = ctr_build_string(message, vlen);
		mesgArgument->next = argumentList;
		if (argCount == 0 || argCount > 2) {
			return ctr_send_message(receiverObject, "respondTo:", 10,  mesgArgument);
		} else if (argCount == 1) {
			return ctr_send_message(receiverObject, "respondTo:with:", 15,  mesgArgument);
		} else if (argCount == 2) {
			return ctr_send_message(receiverObject, "respondTo:with:and:", 19,  mesgArgument);
		}
	}
	if (methodObject->info.type == CTR_OBJECT_TYPE_OTNATFUNC) {
		funct = methodObject->value.fvalue;
		result = funct(receiverObject, argumentList);
	}
	if (methodObject->info.type == CTR_OBJECT_TYPE_OTBLOCK) {
		result = ctr_block_run(methodObject, argumentList, receiverObject);
	}	
	return result;
}
Example #5
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;
}
Example #6
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;
}
Example #7
0
/**
 * [Map] each: [Block]
 *
 * Iterates over the map, passing key-value pairs to the specified block.
 */
ctr_object* ctr_map_each(ctr_object* myself, ctr_argument* argumentList) {
	ctr_object* block = argumentList->object;
	ctr_mapitem* m;
	if (block->info.type != CTR_OBJECT_TYPE_OTBLOCK) {
		CtrStdError = ctr_build_string_from_cstring("Expected Block.\0");
	}
	block->info.sticky = 1;
	m = myself->properties->head;
	while(m && !CtrStdError) {
		ctr_argument* arguments = CTR_CREATE_ARGUMENT();
		ctr_argument* argument2 = CTR_CREATE_ARGUMENT();
		arguments->object = m->key;
		argument2->object = m->value;
		arguments->next = argument2;
		ctr_block_run(block, arguments, myself);
		if (CtrStdError == CtrStdContinue) CtrStdError = NULL;
		m = m->next;
	}
	if (CtrStdError == CtrStdBreak) CtrStdError = NULL;
	block->info.mark = 0;
	block->info.sticky = 0;
	return myself;
}
Example #8
0
/**
 * [Array] + [Array]
 *
 * Returns a new array, containing elements of itself and the other
 * array.
 */
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_CREATE_ARGUMENT();
		ctr_argument* elnumArg = CTR_CREATE_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);
	}
	if (otherArray->info.type == CTR_OBJECT_TYPE_OTARRAY) {
		for(i = otherArray->value.avalue->tail; i<otherArray->value.avalue->head; i++) {
			ctr_argument* pushArg = CTR_CREATE_ARGUMENT();
			ctr_argument* elnumArg = CTR_CREATE_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);
		}
	}
	return newArray;
}
Example #9
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));
}
Example #10
0
/**
 * BlockRun
 *
 * Runs a block of code.
 */
ctr_object* ctr_block_run(ctr_object* myself, ctr_argument* argList, ctr_object* my) {
	ctr_object* result;
	ctr_tnode* node = myself->value.block;
	ctr_tlistitem* codeBlockParts = node->nodes;
	ctr_tnode* codeBlockPart1 = codeBlockParts->node;
	ctr_tnode* codeBlockPart2 = codeBlockParts->next->node;
	ctr_tlistitem* parameterList = codeBlockPart1->nodes;
	ctr_tnode* parameter;
	ctr_object* a;
	ctr_open_context();
	if (parameterList && parameterList->node) {
		parameter = parameterList->node;
		while(1) {
			if (parameter && argList->object) {
				a = argList->object;
				ctr_assign_value_to_local(ctr_build_string(parameter->value, parameter->vlen), a);
			}
			if (!argList->next) break;
			argList = argList->next;
			if (!parameterList->next) break;
			parameterList = parameterList->next;
			parameter = parameterList->node;
		}
	}
	ctr_assign_value_to_local(ctr_build_string("me",2), my);
	ctr_assign_value_to_local(ctr_build_string("thisBlock",9), myself); /* otherwise running block may get gc'ed. */
	result = ctr_cwlk_run(codeBlockPart2);
	if (result == NULL) result = my;
	ctr_close_context();
	if (CtrStdError != NULL && CtrStdError != CtrStdNil) {
		ctr_object* catchBlock = malloc(sizeof(ctr_object));
		catchBlock = ctr_internal_object_find_property(myself, ctr_build_string("catch",5), 0);
		if (catchBlock != NULL) {
			ctr_argument* a = CTR_CREATE_ARGUMENT();
			a->object = CtrStdError;
			CtrStdError = NULL;
			ctr_block_run(catchBlock, a, my);
			result = myself;
		}
	}
	return result;
}
Example #11
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;
}
Example #12
0
/**
 * @internal
 *
 * Shell Object uses a fluid API.
 */
ctr_object* ctr_shell_respond_to_with(ctr_object* myself, ctr_argument* argumentList) {
	ctr_object*   commandObj;
	ctr_object*   prefix;
	ctr_object*   suffix;
	ctr_argument* newArgumentList;
	char* command;
	int len;
	prefix = ctr_internal_cast2string(argumentList->object);
	suffix = ctr_internal_cast2string(argumentList->next->object);
	len = prefix->value.svalue->vlen + suffix->value.svalue->vlen;
	if (len == 0) return myself;
	command = (char*) malloc(len); /* actually we need +1 for the space between commands, but we dont because we remove the colon : !*/
	strncpy(command, prefix->value.svalue->value, prefix->value.svalue->vlen - 1); /* remove colon, gives room for space */
	strncpy(command + (prefix->value.svalue->vlen - 1), " ", 1); /* space to separate commands */
	strncpy(command + (prefix->value.svalue->vlen), suffix->value.svalue->value, suffix->value.svalue->vlen);
	commandObj = ctr_build_string(command, len);
	newArgumentList = CTR_CREATE_ARGUMENT();
	newArgumentList->object = commandObj;
	ctr_shell_call(myself, newArgumentList);
	return myself;
}
Example #13
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;
}
Example #14
0
/**
 * [Array] put: [Element] at: [Index]
 *
 * Puts a value in the array at the specified index.
 * Array will be automatically expanded if the index is higher than
 * the maximum index of the array.
 * 
 * Usage:
 * 
 * fruits := Array new.
 * fruits put: 'apples' at: 5.
 */
ctr_object* ctr_array_put(ctr_object* myself, ctr_argument* argumentList) {
	
	ctr_object* putValue = argumentList->object;
	ctr_object* putIndex = ctr_internal_cast2number(argumentList->next->object);
	ctr_size putIndexNumber;
	ctr_size head;
	ctr_size tail;
	
	if (putIndex->value.nvalue < 0) {
		CtrStdError = ctr_build_string_from_cstring("Index out of bounds.\0");
		return myself;
	}
	
	head = (ctr_size) myself->value.avalue->head;
	tail = (ctr_size) myself->value.avalue->tail;
	putIndexNumber = (ctr_size) putIndex->value.nvalue;
	if (head <= putIndexNumber) {
		ctr_size j;
		for(j = head; j <= putIndexNumber; j++) {
			ctr_argument* argument;
			argument = CTR_CREATE_ARGUMENT();
			argument->object = CtrStdNil;
			ctr_array_push(myself, argument);
		}
		myself->value.avalue->head = putIndexNumber + 1;
	}
	if (putIndexNumber < tail) {
		ctr_size j;
		for(j = tail; j > putIndexNumber; j--) {
			*(myself->value.avalue->elements + j) = CtrStdNil;
		}
		myself->value.avalue->tail = putIndexNumber;
	}
	*(myself->value.avalue->elements + putIndexNumber) = putValue;
	return myself;
}