summaryrefslogtreecommitdiff
path: root/parser.c
blob: 764858d33a4a5fb9f3ee9c7bfc6c26aa5fd288b3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include "parser.h"
#include "lexer.h"

#include <stdio.h>
#include <stdlib.h>

#define STBDS_SIZE_T_BITS           ((sizeof (size_t)) * 8)

#define STBDS_ROTATE_LEFT(val, n)   (((val) << (n)) | ((val) >> (STBDS_SIZE_T_BITS - (n))))
#define STBDS_ROTATE_RIGHT(val, n)  (((val) >> (n)) | ((val) << (STBDS_SIZE_T_BITS - (n))))

#define STBDS_SIPHASH_C_ROUNDS 1
#define STBDS_SIPHASH_D_ROUNDS 1

static size_t hash_bytes(void *p, size_t len, size_t seed)
{
	unsigned char *d = (unsigned char *) p;
	size_t i,j;
	size_t v0,v1,v2,v3, data;

	v0 = ((((size_t) 0x736f6d65 << 16) << 16) + 0x70736575) ^  seed;
	v1 = ((((size_t) 0x646f7261 << 16) << 16) + 0x6e646f6d) ^ ~seed;
	v2 = ((((size_t) 0x6c796765 << 16) << 16) + 0x6e657261) ^  seed;
	v3 = ((((size_t) 0x74656462 << 16) << 16) + 0x79746573) ^ ~seed;

#ifdef STBDS_TEST_SIPHASH_2_4
	v0 ^= 0x0706050403020100ull ^  seed;
	v1 ^= 0x0f0e0d0c0b0a0908ull ^ ~seed;
	v2 ^= 0x0706050403020100ull ^  seed;
	v3 ^= 0x0f0e0d0c0b0a0908ull ^ ~seed;
#endif

#define STBDS_SIPROUND() \
	do {                   \
		v0 += v1; v1 = STBDS_ROTATE_LEFT(v1, 13);  v1 ^= v0; v0 = STBDS_ROTATE_LEFT(v0,STBDS_SIZE_T_BITS/2); \
		v2 += v3; v3 = STBDS_ROTATE_LEFT(v3, 16);  v3 ^= v2;                                                 \
		v2 += v1; v1 = STBDS_ROTATE_LEFT(v1, 17);  v1 ^= v2; v2 = STBDS_ROTATE_LEFT(v2,STBDS_SIZE_T_BITS/2); \
		v0 += v3; v3 = STBDS_ROTATE_LEFT(v3, 21);  v3 ^= v0;                                                 \
	} while (0)

	for (i=0; i+sizeof(size_t) <= len; i += sizeof(size_t), d += sizeof(size_t)) {
	data = d[0] | (d[1] << 8) | (d[2] << 16) | (d[3] << 24);
	data |= (size_t) (d[4] | (d[5] << 8) | (d[6] << 16) | (d[7] << 24)) << 16 << 16; // discarded if size_t == 4

	v3 ^= data;
	for (j=0; j < STBDS_SIPHASH_C_ROUNDS; ++j)
	STBDS_SIPROUND();
	v0 ^= data;
	}
	data = len << (STBDS_SIZE_T_BITS-8);
	switch (len - i) {
		case 7: data |= ((size_t) d[6] << 24) << 24; // fall through
		case 6: data |= ((size_t) d[5] << 20) << 20; // fall through
		case 5: data |= ((size_t) d[4] << 16) << 16; // fall through
		case 4: data |= (d[3] << 24); // fall through
		case 3: data |= (d[2] << 16); // fall through
		case 2: data |= (d[1] << 8); // fall through
		case 1: data |= d[0]; // fall through
		case 0: break;
	}
	v3 ^= data;
	for (j=0; j < STBDS_SIPHASH_C_ROUNDS; ++j)
	STBDS_SIPROUND();
	v0 ^= data;
	v2 ^= 0xff;
	for (j=0; j < STBDS_SIPHASH_D_ROUNDS; ++j)
	STBDS_SIPROUND();

	return v1^v2^v3;
}

void add_child(node *n, node *child)
{
	if (n->children_length + 1 >= n->children_size) {
		n->children_size += (n->children_size / 2) + n->children_size;
		n->children = realloc(n->children, n->children_size * sizeof(node));
	}

	n->children[n->children_length++] = child;
}

node *ir_parse(token *tokens)
{
	(void)tokens;
	node *start = calloc(1, sizeof(node));
	start->type = NODE_START;
	start->id = hash_bytes((void *)start, sizeof(node), 0xcafebabe);

	return NULL;
}