예제 #1
0
파일: strings.c 프로젝트: ghosthamlet/deja
Error count(Stack* S, Stack* scope_arr)
{
	require(2);
	V haystack = popS();
	V needle = popS();
	if (getType(haystack) != T_STR || getType(needle) != T_STR)
	{
		clear_ref(haystack);
		clear_ref(needle);
		return TypeError;
	}
	size_t haystack_len = toNewString(haystack)->size;
	size_t needle_len = toNewString(needle)->size;
	if (needle_len == 0)
	{
		pushS(int_to_value(string_length(toNewString(haystack)) + 1));
		clear_ref(haystack);
		clear_ref(needle);
		return Nothing;
	}

	utf8 haystack_c = toNewString(haystack)->text;
	utf8 needle_c = toNewString(needle)->text;
	utf8index ix;
	int count = 0;
	for (ix = 0; ix < haystack_len - needle_len + 1; )
	{
		if (!memcmp(haystack_c + ix, needle_c, needle_len))
		{
			count++;
			ix += needle_len;
		}
		else
		{
			ix = nextchar(haystack_c, ix);
		}
	}

	pushS(int_to_value(count));
	clear_ref(haystack);
	clear_ref(needle);
	return Nothing;
}
예제 #2
0
파일: strings.c 프로젝트: ghosthamlet/deja
Error find(Stack* S, Stack* scope_arr)
{
	require(2);
	V haystack = popS();
	V needle = popS();
	if (getType(needle) != T_STR || getType(haystack) != T_STR)
	{
		clear_ref(needle);
		clear_ref(haystack);
		return TypeError;
	}
	NewString *needle_s = toNewString(needle);
	NewString *haystack_s = toNewString(haystack);
	if (string_length(needle_s) <= string_length(haystack_s))
	{
		size_t haystack_len = haystack_s->size;
		size_t needle_len = needle_s->size;
		utf8 haystack_c = haystack_s->text;
		utf8 needle_c = needle_s->text;
		utf8index ix;
		int i = 0;
		for (ix = 0; ix < haystack_len - needle_len + 1; ix = nextchar(haystack_c, ix))
		{
			if (!memcmp(haystack_c + ix, needle_c, needle_len))
			{
				pushS(int_to_value(i));
				clear_ref(needle);
				clear_ref(haystack);
				return Nothing;
			}
			i++;
		}
	}
	pushS(int_to_value(-1));
	clear_ref(needle);
	clear_ref(haystack);
	return Nothing;
}
예제 #3
0
파일: strings.c 프로젝트: ghosthamlet/deja
Error ord(Stack* S, Stack* scope_arr)
{
	require(1);
	V v = popS();
	if (getType(v) != T_STR)
	{
		clear_ref(v);
		return TypeError;
	}
	NewString *s = toNewString(v);
	if (s->size == 0)
	{
		clear_ref(v);
		return ValueError;
	}
	utf8index n = 0;
	pushS(int_to_value(decode_codepoint(s->text, &n)));
	clear_ref(v);
	return Nothing;
}
예제 #4
0
파일: blob.c 프로젝트: gvx/deja
Error getbyte_blob_(Stack *S, Stack *scope_arr)
{
	require(2);
	V blob = popS();
	V index = popS();
	Error e = Nothing;
	if (getType(blob) != T_BLOB || getType(index) != T_NUM)
	{
		e = TypeError;
		goto cleanup;
	}
	int byte = getbyte_blob(blob, toNumber(index));
	if (byte < 0)
	{
		set_error_msg("Index out of range");
		e = ValueError;
		goto cleanup;
	}
	pushS(int_to_value(byte));
	cleanup:
	clear_ref(blob);
	clear_ref(index);
	return e;
}
예제 #5
0
파일: literals.c 프로젝트: gvx/deja
bool read_literals(char *oldpos, size_t size, Header* h)
{
	int i, j;
	int n = 0;
	char type;
	uint32_t str_length;
	uint32_t ref;
	char *startpos = oldpos + h->size * 4;
	char *curpos = startpos;
	while (!eofreached)
	{
		type = *curpos++;
		if (eofreached)
		{
			break;
		}
		n++;
		switch (type)
		{
			case TYPE_NUM:
				curpos += 8;
				break;
			case TYPE_NUM | TYPE_SHORT:
				curpos += 3;
				break;
			case TYPE_STR:
			case TYPE_IDENT:
				memcpy(&str_length, curpos, 4);
				curpos += 4 + ntohl(str_length);
				break;
			case TYPE_STR | TYPE_SHORT:
			case TYPE_IDENT | TYPE_SHORT:
				str_length = (unsigned char)*curpos++;
				curpos += str_length;
				break;
			case TYPE_PAIR:
				curpos += 6;
				break;
			case TYPE_FRAC:
				curpos += 16;
				break;
			case TYPE_FRAC | TYPE_SHORT:
				curpos += 2;
				break;
			case TYPE_LIST:
				memcpy(&str_length, curpos, 4);
				curpos += 4 + 3 * ntohl(str_length);
				break;
			case TYPE_DICT:
				memcpy(&str_length, curpos, 4);
				curpos += 4 + 6 * ntohl(str_length);
				break;
		}
	}
	V* arr = calloc(n, sizeof(V));
	V t;
	curpos = startpos;
	for (i = 0; i < n; i++)
	{
		type = *curpos++;
		if (type == TYPE_NUM)
		{
			union double_or_uint64_t d;
			memcpy(&d, curpos, 8);
			curpos += 8;
			d.i = ntohll(d.i);
			t = double_to_value(d.d);
		}
		else if (type == (TYPE_NUM | TYPE_SHORT))
		{
			ref = 0;
			memcpy(((char*)&ref) + 1, curpos, 3);
			ref = ntohl(ref);
			curpos += 3;
			t = int_to_value(ref);
		}
		else if (type == TYPE_STR)
		{
			memcpy(&str_length, curpos, 4);
			curpos += 4;
			str_length = ntohl(str_length);
			if (!valid_utf8(str_length, curpos))
			{
				set_error_msg("wrong encoding for string literal, should be UTF-8");
				return false;
			}
			t = str_to_string(str_length, curpos);
			curpos += str_length;
		}
		else if (type == TYPE_IDENT)
		{
			memcpy(&str_length, curpos, 4);
			curpos += 4;
			str_length = ntohl(str_length);
			char data[str_length + 1];
			memcpy(&data, curpos, str_length);
			data[str_length] = '\0';
			t = lookup_ident(str_length, data);
			curpos += str_length;
		}
		else if (type == (TYPE_STR | TYPE_SHORT))
		{
			str_length = (unsigned char)*curpos++;
			if (!valid_utf8(str_length, curpos))
			{
				set_error_msg("wrong encoding for string literal, should be UTF-8");
				return false;
			}
			t = str_to_string(str_length, curpos);
			curpos += str_length;
		}
		else if (type == (TYPE_IDENT | TYPE_SHORT))
		{
			str_length = *curpos++;
			char data[str_length + 1];
			memcpy(&data, curpos, str_length);
			data[str_length] = '\0';
			t = lookup_ident(str_length, data);
			curpos += str_length;
		}
		else if (type == TYPE_PAIR)
		{
			ref = 0;
			memcpy(((char*)&ref) + 1, curpos, 3);
			ref = ntohl(ref);
			if (ref >= i)
			{
				set_error_msg("illegal pair detected");
				return false;
			}
			V v1 = arr[ref];

			ref = 0;
			memcpy(((char*)&ref) + 1, curpos + 3, 3);
			ref = ntohl(ref);
			if (ref >= i)
			{
				set_error_msg("illegal pair detected");
				return false;
			}
			V v2 = arr[ref];

			t = new_pair(v1, v2);
			curpos += 6;
		}
		else if (type == TYPE_FRAC)
		{
			int64_t numer;
			int64_t denom;
			memcpy(&numer, curpos, 8);
			numer = ntohll(numer);
			memcpy(&denom, curpos + 8, 8);
			denom = ntohll(denom);
			t = new_frac(numer, denom);
			curpos += 16;
		}
		else if (type == (TYPE_FRAC | TYPE_SHORT))
		{
			int8_t numer;
			uint8_t denom;
			numer = *curpos++;
			denom = *curpos++;
			t = new_frac(numer, denom);
		}
		else if (type == TYPE_LIST)
		{
			memcpy(&str_length, curpos, 4);
			str_length = ntohl(str_length);
			t = new_list();
			curpos += 4;
			if (str_length > 0)
			{
				uint32_t size = 64;
				while (size < str_length) size <<= 1;
				toStack(t)->size = size;
				toStack(t)->used = str_length;
				toStack(t)->nodes = calloc(size, sizeof(V));
				for (j = 0; j < str_length; j++)
				{
					ref = 0;
					memcpy(((char*)&ref) + 1, curpos, 3);
					ref = ntohl(ref);
					toStack(t)->nodes[j] = intToV((uint64_t)ref);
					curpos += 3;
				}
			}
		}
		else if (type == TYPE_DICT)
		{
			memcpy(&str_length, curpos, 4);
			curpos += 4;
			str_length = ntohl(str_length);
			t = new_dict();
			if (str_length > 0)
			{
				uint32_t size = 16;
				while (size < str_length) size <<= 1;
				toHashMap(t)->size = size;
				toHashMap(t)->used = str_length;
				toHashMap(t)->map = (Bucket**)curpos;
			}
			curpos += 6 * str_length;
		}
		else
		{
			set_error_msg("Unknown literal type.");
			return false;
		}
		arr[i] = t;
	}

	for (i = 0; i < n; i++)
	{
		t = arr[i];
		switch(getType(t))
		{
			case TYPE_LIST:
				for (j = 0; j < toStack(t)->used; j++)
				{
					toStack(t)->nodes[j] = arr[toInt(toStack(t)->nodes[j])];
				}
				break;
			case TYPE_DICT:
				if (toHashMap(t)->map)
				{
					curpos = ((char*)toHashMap(t)->map);

					toHashMap(t)->map = NULL;
					str_length = toHashMap(t)->used; //worst abuse of variable name ever Y/Y?
					toHashMap(t)->used = 0;
					for (j = 0; j < str_length; j++)
					{
						ref = 0;
						memcpy(((char*)&ref) + 1, curpos, 3);
						ref = ntohl(ref);
						V key = arr[ref];

						ref = 0;
						memcpy(((char*)&ref) + 1, curpos + 3, 3);
						ref = ntohl(ref);
						V value = arr[ref];

						set_hashmap(toHashMap(t), key, value);

						curpos += 6;
					}
				}
				break;
		}
	}

	h->n_literals = n;
	h->literals = arr;
	return true;
}