view string.c @ 75:0083b2f7b3c7

Partially working implementation of List. Modified build scripts to allow use of other compilers. Fixed some bugs involving method implementations on different types returning different numbers of outputs. Added Fold to the 'builtins' in the comipler.
author Mike Pavone <pavone@retrodev.com>
date Tue, 06 Jul 2010 07:52:59 -0400
parents 3cc5e4a42344
children
line wrap: on
line source

#include "datum.h"
#include "structs.h"
#include "interp.h"
#include <string.h>
#include <stdlib.h>


int vis_inttostring(datum ** inputlist, queue_entry * worker_entry)
{
	int i,j,val;
	char temp_buf[12];
	datum * output;
	char * out_buf;
	//sprintf(temp_buf, "%d", inputlist[0]->c.integers.num_a);
	val = (inputlist[0]->c.integers.num_a >= 0 ? inputlist[0]->c.integers.num_a : 0-inputlist[0]->c.integers.num_a);
	i = 0;
	if(!val)
		temp_buf[i++] = '0';

	while(val > 0)
	{
		temp_buf[i] = (val % 10) + '0';
		val /= 10;
		++i;
	}
	if(inputlist[0]->c.integers.num_a < 0)
	{
		temp_buf[i] = '-';
		++i;
	}
	release_ref(inputlist[0]);
	inputlist[0] = new_datum(BUILTIN_TYPE_STRING, 1, i+1, worker_entry->instance->def->program);
	out_buf = inputlist[0]->c.generic.data;
	out_buf[i] = '\0';
	j = 0;
	--i;
	while(i >= 0)
	{
		out_buf[j] = temp_buf[i];
		++j;
		--i;
	}
	//strcpy(inputlist[0]->c.generic.data, temp_buf);
	return 0;
	
}

#ifndef SEGA
int vis_realtostring(datum ** inputlist, queue_entry * worker_entry)
{
	char temp_buf[512];//Is this enough?
	datum * output;
	sprintf(temp_buf, "%f", inputlist[0]->c.real);
	release_ref(inputlist[0]);
	inputlist[0] = new_datum(BUILTIN_TYPE_STRING, 1, strlen(temp_buf)+1, worker_entry->instance->def->program);
	strcpy(inputlist[0]->c.generic.data, temp_buf);
	return 0;
	
}
#endif

int vis_stringequal(datum ** inputlist, queue_entry * worker_entry)
{
	int result = strcmp(inputlist[0]->c.generic.data, inputlist[1]->c.generic.data);
	release_ref(inputlist[0]);
	release_ref(inputlist[1]);
	inputlist[0] = new_datum(BUILTIN_TYPE_YESNO, 2, 0, worker_entry->instance->def->program);
	datum_set_yesno(inputlist[0], (result == 0 ? 1 : 0));
	return 0;
}

int vis_append(datum ** inputlist, queue_entry * worker_entry)
{
	datum * output;
	int temp_size = inputlist[0]->c.generic.len;
	DEBUGPUTS("Begin vis_append\n");
	
	DEBUGPRINTF("Left: %s(%d)\n", inputlist[0]->c.generic.data, inputlist[0]->c.generic.len);
	DEBUGPRINTF("Right: %s(%d)\n", inputlist[1]->c.generic.data, inputlist[1]->c.generic.len);
	output = new_datum(BUILTIN_TYPE_STRING, 1, temp_size+inputlist[1]->c.generic.len-1, worker_entry->instance->def->program);
	memcpy(output->c.generic.data, inputlist[0]->c.generic.data, temp_size-1);
	memcpy(((char *)output->c.generic.data)+temp_size-1, inputlist[1]->c.generic.data, inputlist[1]->c.generic.len-1);
	((char *)output->c.generic.data)[temp_size + inputlist[1]->c.generic.len-2]='\0';
	DEBUGPRINTF("Appended string: %s(%d)\n", output->c.generic.data, output->c.generic.len);
	release_ref(inputlist[0]);
	release_ref(inputlist[1]);
	inputlist[0] = output;
	DEBUGPUTS("End vis_append\n");
	
	return 0;
}

int vis_yesnotostring(datum ** inputlist, queue_entry * worker_entry)
{
	int result = inputlist[0]->c.integers.num_a;
	release_ref(inputlist[0]);
	if(result)
	{
		inputlist[0] = new_datum(BUILTIN_TYPE_STRING, 1, 4, worker_entry->instance->def->program);
		strcpy(inputlist[0]->c.generic.data, "Yes");
	}
	else
	{
		inputlist[0] = new_datum(BUILTIN_TYPE_STRING, 1, 3, worker_entry->instance->def->program);
		strcpy(inputlist[0]->c.generic.data, "No");
	}
	return 0;
}

int vis_greaterstring(datum ** inputlist, queue_entry * worker_entry)
{
	int result;
	if(strcmp(inputlist[0]->c.generic.data, inputlist[1]->c.generic.data) > 0)
		result = 1;
	else
		result = 0;
	release_ref(inputlist[0]);
	release_ref(inputlist[1]);
	inputlist[0] = new_datum(BUILTIN_TYPE_YESNO, 2, 0, worker_entry->instance->def->program);
	datum_set_yesno(inputlist[0], result);
	return 0;
}

int vis_lesserstring(datum ** inputlist, queue_entry * worker_entry)
{
	int result;
	if(strcmp(inputlist[0]->c.generic.data, inputlist[1]->c.generic.data) < 0)
		result = 1;
	else
		result = 0;
	release_ref(inputlist[0]);
	release_ref(inputlist[1]);
	inputlist[0] = new_datum(BUILTIN_TYPE_YESNO, 2, 0, worker_entry->instance->def->program);
	datum_set_yesno(inputlist[0], result);
	return 0;
}

datum * make_string(const char * string, int len, program * prog)
{
	datum * output;
	if(len < 0)
		len = strlen(string);
	output = new_datum(BUILTIN_TYPE_STRING, 1, len+1, prog);
	if(string)
		memcpy(output->c.generic.data, string, len);
	((char *)output->c.generic.data)[len] = '\0';
	return output;
}

int vis_string_split(datum ** inputlist, queue_entry * worker_entry)
{
	int i, start=0, len = inputlist[0]->c.generic.len-1;
	char * string = inputlist[0]->c.generic.data;
	char * delim = inputlist[1]->c.generic.data;
	int delimlen = inputlist[1]->c.generic.len-1;
	int search_offset = 0;
	datum * params[2];
	params[0] = create_list(worker_entry->instance->def->program);
	DEBUGPRINTF("Split@String: delim(%s) string(%s)\n", delim, string);
	for(i = 0; i < len; ++i)
	{
		if(string[i] == delim[search_offset])
		{
			if(search_offset == (delimlen-1))
			{
				params[1] = make_string(string + start, i-start-(delimlen-1), worker_entry->instance->def->program);
				DEBUGPRINTF("Appending %s(%d) to list\n", params[1]->c.generic.data, params[1]->c.generic.len);
				vis_list_append(params, worker_entry);
				start = i+1;
				search_offset = 0;
			}
			else
				++search_offset;
		}
		else if(search_offset > 0)
		{
			i = (i-search_offset+1);
			search_offset = 0;
		}
	}
	if(len)
	{
		params[1] = make_string(string + start, i-start, worker_entry->instance->def->program);
		vis_list_append(params, worker_entry);
	}
	DEBUGPUTS("End Split@String\n");
	
	release_ref(inputlist[0]);
	release_ref(inputlist[1]);
	inputlist[0] = params[0];
	return 0;
}

int vis_string_put_raw(datum ** inputlist, queue_entry * worker_entry)
{
	int old_len = inputlist[0]->c.generic.len;
	char * data;
	inputlist[0] = copy_datum(inputlist[0], old_len + inputlist[1]->c.generic.len);
	data = inputlist[0]->c.generic.data;
	memcpy(data + old_len - 1, inputlist[1]->c.generic.data, inputlist[1]->c.generic.len);
	release_ref(inputlist[1]);
	data[inputlist[0]->c.generic.len-1] = '\0';
	return 0;
}

int vis_string_get_raw(datum ** inputlist, queue_entry * worker_entry)
{
	char * data = inputlist[0]->c.generic.data;
	datum * output;
	inputlist[1] = copy_datum(inputlist[1], 0);
	memcpy(inputlist[1]->c.generic.data, data, inputlist[1]->c.generic.len);
	output = make_string(data + inputlist[1]->c.generic.len, inputlist[0]->c.generic.len - inputlist[1]->c.generic.len - 1, worker_entry->instance->def->program);
	release_ref(inputlist[0]);
	inputlist[0] = output;
	return 0;
}

int vis_string_slice(datum ** inputlist, queue_entry * worker_entry)
{
	char * string;
	int index = inputlist[1]->c.integers.num_a;
	release_ref(inputlist[1]);
	if(index < (inputlist[0]->c.generic.len-1))
	{
		inputlist[1] = new_datum_comp(inputlist[0]->company, 1, inputlist[0]->c.generic.len-index);
		memcpy(inputlist[1]->c.generic.data, (char *)(inputlist[0]->c.generic.data) + index, inputlist[0]->c.generic.len-index);
		inputlist[0] = copy_datum(inputlist[0], index+1);
		string = inputlist[0]->c.generic.data;
		string[index] = '\0';
	}
	else
	{
		inputlist[1] = new_datum_comp(inputlist[0]->company, 1, 1);
		string = inputlist[1]->c.generic.data;
		string[0] = '\0';
	}
	return 0;
}

int vis_string_reverse(datum ** inputlist, queue_entry * worker_entry)
{
	int ref_count, i,j;
	datum * output;
	char *source, *dest, tmp;
	VIS_EnterCriticalSection(inputlist[0]->lock);
		ref_count = inputlist[0]->ref_count;
	VIS_LeaveCriticalSection(inputlist[0]->lock);

	if(ref_count > 1)
		output = new_datum_comp(inputlist[0]->company, 1, inputlist[0]->c.generic.len);
	else
		output = inputlist[0];
	source = inputlist[0]->c.generic.data;
	
	if(ref_count > 1)
	{
		dest = output->c.generic.data;
		i = 0;
		for(j = output->c.generic.len-2; j >= 0; --j)
			dest[j] = source[i++];
		release_ref(inputlist[0]);
		inputlist[0] = output;
	}
	else
	{
		i = 0;
		for(j = output->c.generic.len-2; j > i; --j)
		{
			tmp = source[i];
			source[i++] = source[j];
			source[j] = tmp;
		}
	}
	return 0;
}

int vis_string_length(datum ** inputlist, queue_entry * worker_entry)
{
	int len = inputlist[0]->c.generic.len-1;
	release_ref(inputlist[0]);
	inputlist[0] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program);
	inputlist[0]->c.integers.num_a = len;
	return 0;
}

int vis_string_put_byte(datum ** inputlist, queue_entry * worker_entry)
{
	inputlist[0] = copy_datum(inputlist[0], inputlist[0]->c.generic.len + 1);
	((unsigned char *)(inputlist[0]->c.generic.data))[inputlist[0]->c.generic.len - 2] = (unsigned char)inputlist[1]->c.integers.num_a;
	((unsigned char *)(inputlist[0]->c.generic.data))[inputlist[0]->c.generic.len - 1] = '\0';
	release_ref(inputlist[1]);
	return 0;	
}

int vis_string_get_dstring(datum ** inputlist, queue_entry * worker_entry)
{
	datum ** delimlist;
	int num_delims;
	int i,len,delimlen;
	char *current;
	BOOL match=FALSE;
	datum * temp;
	if(inputlist[1]->company->type_id == BUILTIN_TYPE_LIST)
	{
		delimlist = ((list_data *)inputlist[1]->c.generic.data)->entries;
		num_delims = ((list_data *)inputlist[1]->c.generic.data)->num_entries;
		//TODO: check to make sure that all of the list entries are strings
	}
	else if(inputlist[1]->company->type_id == BUILTIN_TYPE_STRING) 
	{
		delimlist = inputlist+1;
		num_delims = 1;
	}
	else
	{
		ERRORPUTS("Second argument to Get DString@String must be either a String or a List");
		print_stack_trace(worker_entry->instance);
		release_ref(inputlist[0]);
		release_ref(inputlist[1]);
		return -1;
	}
	current = inputlist[0]->c.generic.data;
	len = inputlist[0]->c.generic.len - 1;
	while(len && !match)
	{
		for(i = 0; i < num_delims; ++i)
		{
			delimlen = delimlist[i]->c.generic.len-1;
			if(len >= delimlen && !memcmp(current, delimlist[i]->c.generic.data, delimlen))
			{
				match = TRUE;
				//deal with the fact that we're going to adjust current and len even though we're done
				--current;
				++len;
				break;
			}
		}
		++current;
		--len;
	}
	if(match)
	{
		inputlist[2] = add_ref(delimlist[i]);
		release_ref(inputlist[1]);
		inputlist[1] = make_string(inputlist[0]->c.generic.data, current - ((char *)inputlist[0]->c.generic.data), worker_entry->instance->def->program);
		delimlen = inputlist[2]->c.generic.len-1;
		temp = make_string(current+delimlen, len-delimlen, worker_entry->instance->def->program);
		release_ref(inputlist[0]);
		inputlist[0] = temp;
		inputlist[3] = NULL;
	}
	else
	{
		release_ref(inputlist[1]);
		inputlist[1] = inputlist[0];
		inputlist[0] = NULL;
		inputlist[2] = NULL;
		inputlist[3] = new_datum(BUILTIN_TYPE_YESNO, 2, 0, worker_entry->instance->def->program);
		inputlist[3]->c.integers.num_a = 0;
	}
	return 0;
}

int vis_string_lefttrim(datum ** params, queue_entry * entry)
{
	BOOL isatrimchar;
	int i,j;
	char *string,*trim_chars;
	string = params[0]->c.generic.data;
	trim_chars = params[1]->c.generic.data;
	isatrimchar = TRUE;
	for(i = 0; i < params[0]->c.generic.len-1; ++i)
	{
		isatrimchar = FALSE;
		for(j = 0; j < params[1]->c.generic.len-1; ++j)
			if(string[i] == trim_chars[j])
			{
				isatrimchar = TRUE;
				break;
			}
		if(!isatrimchar)
			break;
	}
	release_ref(params[1]);
	params[1] = params[0];
	params[0] = make_string(string+i, params[1]->c.generic.len-1-i, entry->instance->def->program);
	release_ref(params[1]);
	return 0;
}

int vis_string_righttrim(datum ** params, queue_entry * entry)
{
	BOOL isatrimchar;
	int i,j;
	char *string,*trim_chars;
	string = params[0]->c.generic.data;
	trim_chars = params[1]->c.generic.data;
	isatrimchar = TRUE;
	for(i = params[0]->c.generic.len-2; i >= 0 ; --i)
	{
		isatrimchar = FALSE;
		for(j = 0; j < params[1]->c.generic.len-1; ++j)
			if(string[i] == trim_chars[j])
			{
				isatrimchar = TRUE;
				break;
			}
		if(!isatrimchar)
			break;
	}
	release_ref(params[1]);
	params[1] = params[0];
	params[0] = make_string(string, i+1, entry->instance->def->program);
	release_ref(params[1]);
	return 0;
}