Example #1
0
Error ends_with(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 (needle_s->size > haystack_s->size ||
	    memcmp(haystack_s->text + haystack_s->size - needle_s->size,
	           needle_s->text, needle_s->size))
	{
		pushS(add_ref(v_false));
	}
	else
	{
		pushS(add_ref(v_true));
	}
	clear_ref(needle);
	clear_ref(haystack);
	return Nothing;
}
Example #2
0
Error concat_list(Stack *S, Stack *scope_arr) /* concat [ "a" "b" "c" ] */
{
	NewString *s1;
	int i;
	require(1);
	V v1 = popS();
	if (getType(v1) == T_LIST)
	{
		int newlength = 0;
		int u = toStack(v1)->used;
		V *n = toStack(v1)->nodes;
		for (i = u - 1; i >= 0; i--)
		{
			if (getType(n[i]) != T_STR)
			{
				clear_ref(v1);
				return TypeError;
			}
			newlength += toNewString(n[i])->size;
		}

		char *new = malloc(newlength + 1);
		char *currpoint = new;

		for (i = u - 1; i >= 0; i--)
		{
			s1 = toNewString(n[i]);
			memcpy(currpoint, s1->text, s1->size);
			currpoint += s1->size;
		}
		*currpoint = '\0';
		pushS(str_to_string(newlength, new));
		clear_ref(v1);
		return Nothing;
	}
Example #3
0
File: file.c Project: gvx/deja
V load_file(V file_name, V global)
{
	if (file_name == NULL || getType(file_name) != T_STR)
	{
		clear_ref(file_name);
		return NULL;
	}
	FILE* f = fopen(toNewString(file_name)->text, "rb");
	if (f == NULL)
	{
		clear_ref(file_name);
		return NULL;
	}
	fseek(f, 0, SEEK_END);
	size_t length = ftell(f);
	rewind(f);
	char *data = malloc(length * sizeof(char));
	size_t read = fread(data, sizeof(char), length, f);
	assert (read == length);
	V new_file = load_memfile(data, length, file_name, global);
	free(data);
	fclose(f);
	clear_ref(file_name);
	return new_file;
}
Example #4
0
File: persist.c Project: gvx/deja
char *make_persist_path(V fname)
{
    NewString *s = toNewString(fname);
    char *pathbase = getenv("XDG_DATA_HOME");
    size_t plen;
    char *home = NULL;
    if (pathbase == NULL)
    {
        home = getenv("HOME");
        plen = strlen(home) + strlen("/.local/share");
        pathbase = malloc(plen + 1);
        sprintf(pathbase, "%s/.local/share", home);
    }
    else
    {
        plen = strlen(pathbase);
    }
    char *data = malloc(plen + strlen("/deja/persist/") + s->size + 3 + 1);
    sprintf(data, "%s/deja/persist/%*s.vu", pathbase, (int)s->size, s->text);
    if (home)
    {   // if home is not NULL, that means we allocated pathbase
        free(pathbase);
    }
    makedirs(data);
    return data;
}
Example #5
0
V unichar_to_value(unichar c)
{
	utf8 adr = NULL;
	V r = empty_string_to_value(codepoint_length(c), &adr);
	toNewString(r)->length = 1;
	encode_codepoint(c, adr);
	return r;
}
Example #6
0
uint32_t need_hash(V string)
{
	NewString *s = toNewString(string);
	if (s->hash == 0)
	{
		s->hash = new_string_hash(s->size, s->text);
	}
	return s->hash;
}
Example #7
0
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;
}
Example #8
0
Error concat(Stack *S, Stack *scope_arr) /* concat( "a" "b" "c" ) */
{
	NewString *s1;
	int i;
	require(1);
	V v1 = popS();
	int newlength = 0;
	for (i = S->used - 1; i >= 0; i--)
	{
		int t = getType(S->nodes[i]);
		if (t == T_IDENT && S->nodes[i] == get_ident(")"))
		{
			break;
		}
		else if (t != T_STR)
		{
			clear_ref(v1);
			return TypeError;
		}
		newlength += toNewString(S->nodes[i])->size;
	}

	char *new = malloc(newlength + 1);
	char *currpoint = new;

	for (i = S->used - 1; i >= 0; i--)
	{
		if (getType(S->nodes[i]) == T_IDENT && S->nodes[i] == get_ident(")"))
		{
			clear_ref(popS());
			break;
		}
		s1 = toNewString(S->nodes[i]);
		memcpy(currpoint, s1->text, s1->size);
		currpoint += s1->size;
		clear_ref(popS());
	}
	*currpoint = '\0';
	pushS(str_to_string(newlength, new));
	clear_ref(v1);
	return Nothing;
}
Example #9
0
V a_to_string(char* str)
{
	size_t size = strlen(str);
	V t = make_new_value(T_STR, true, sizeof(NewString) + size);
	NewString *s = toNewString(t);
	s->size = size;
	s->hash = 0;
	s->length = -1;
	memcpy(s->text, str, size + 1);
	return t;
}
Example #10
0
V empty_string_to_value(size_t max, utf8 *adr)
{
	V t = make_new_value(T_STR, true, sizeof(NewString) + max);
	NewString *s = toNewString(t);
	s->size = max;
	s->hash = 0;
	s->length = -1;
	s->text[max] = '\0';
	*adr = s->text;
	return t;
}
Example #11
0
V str_to_string(size_t max, char *str)
{
	V t = make_new_value(T_STR, true, sizeof(NewString) + max);
	NewString *s = toNewString(t);
	s->size = max;
	s->hash = 0;
	s->length = -1;
	memcpy(s->text, str, max);
	s->text[max] = '\0';
	return t;
}
Example #12
0
Error chars(Stack* S, Stack* scope_arr)
{
	require(1);
	V source = popS();
	if (getType(source) != T_STR)
	{
		clear_ref(source);
		return TypeError;
	}
	utf8 chrs = toNewString(source)->text;
	utf8index index = 0;
	V list = new_list();
	Stack *st = toStack(list);
	size_t size = toNewString(source)->size;
	size_t i;
	for (i = 0; i < size; i++)
	{
		push(st, unichar_to_value(decode_codepoint(chrs, &index)));
	}
	pushS(list);
	return Nothing;
}
Example #13
0
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;
}
Example #14
0
Error contains(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))
	{
		pushS(add_ref(v_false));
	}
	else
	{
		uint32_t i;
		utf8index index = 0;
		for (i = 0; i <= string_length(haystack_s) - string_length(needle_s); i++)
		{
			if (!memcmp(haystack_s->text + index, needle_s->text, needle_s->size))
			{
				pushS(add_ref(v_true));
				clear_ref(needle);
				clear_ref(haystack);
				return Nothing;
			}
			index = nextchar(haystack_s->text, index);
		}
		pushS(add_ref(v_false));
	}
	clear_ref(needle);
	clear_ref(haystack);
	return Nothing;
}
Example #15
0
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;
}
Example #16
0
File: persist.c Project: gvx/deja
void write_object(FILE *file, V obj, HashMap *hm)
{
    int t = getType(obj);
    union double_or_uint64_t num;
    ITreeNode *id = NULL;
    NewString *s = NULL;
    Stack *st;
    HashMap *hmv;
    int8_t n8;
    uint8_t l8;
    int32_t n32;
    uint32_t l32;
    int64_t n64;
    uint64_t l64;
    int i;
    Bucket *b;

    char type = t;

    switch (t)
    {
    case T_NUM:
        if (canBeSmallInt(obj))
            type |= TYPE_SHORT;
        break;
    case T_IDENT:
        id = toIdent(obj);
        if (id->length < 256)
            type |= TYPE_SHORT;
        break;
    case T_STR:
        s = toNewString(obj);
        if (s->size < 256)
            type |= TYPE_SHORT;
        break;
    case T_FRAC:
        if (toNumerator(obj) < 128 && toNumerator(obj) >= -128 &&
                toDenominator(obj) < 256)
            type |= TYPE_SHORT;
        break;
    }

    fwrite(&type, 1, 1, file);

    switch (t)
    {
    case T_IDENT:
        if (type & TYPE_SHORT)
        {
            l8 = id->length;
            fwrite(&l8, 1, 1, file);
        }
        else
        {
            l32 = id->length;
            l32 = htonl(l32);
            fwrite(&l32, 4, 1, file);
        }
        fwrite(&id->data, id->length, 1, file);
        break;
    case T_STR:
        if (type & TYPE_SHORT)
        {
            l8 = s->size;
            fwrite(&l8, 1, 1, file);
        }
        else
        {
            l32 = s->size;
            l32 = htonl(l32);
            fwrite(&l32, 4, 1, file);
        }
        fwrite(s->text, s->size, 1, file);
        break;
    case T_NUM:
        if (type & TYPE_SHORT)
        {
            n32 = toInt(obj);
            n32 = htonl(n32);
            fwrite(((char*)&n32) + 1, 3, 1, file);
        }
        else
        {
            num.d = toNumber(obj);
            num.i = htonll(num.i);
            fwrite(&num, 8, 1, file);
        }
        break;
    case T_FRAC:
        if (type & TYPE_SHORT)
        {
            n8 = toNumerator(obj);
            fwrite(&n8, 1, 1, file);
            l8 = toDenominator(obj);
            fwrite(&l8, 1, 1, file);
        }
        else
        {
            n64 = toNumerator(obj);
            n64 = htonl(n64);
            fwrite(&n64, 8, 1, file);
            l64 = toDenominator(obj);
            l64 = htonl(l64);
            fwrite(&l64, 8, 1, file);
        }
        break;
    case T_PAIR:
        write_ref(file, toFirst(obj), hm);
        write_ref(file, toSecond(obj), hm);
        break;
    case T_LIST:
        st = toStack(obj);
        l32 = st->used;
        l32 = htonl(l32);
        fwrite(&l32, 4, 1, file);
        for (i = 0; i < st->used; i++)
        {
            write_ref(file, st->nodes[i], hm);
        }
        break;
    case T_DICT:
        hmv = toHashMap(obj);
        l32 = hmv->used;
        l32 = htonl(l32);
        fwrite(&l32, 4, 1, file);
        if (hmv->map != NULL)
        {
            for (i = 0; i < hmv->size; i++)
            {
                b = hmv->map[i];
                while(b != NULL)
                {
                    write_ref(file, b->key, hm);
                    write_ref(file, b->value, hm);
                    b = b->next;
                }
            }
        }
        break;
    }
}
Example #17
0
File: persist.c Project: gvx/deja
bool valid_persist_name(V fname)
{
    NewString *s = toNewString(fname);
    return memchr(s->text, '/', s->size) == NULL;
}