summaryrefslogtreecommitdiff
path: root/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/parser.c b/parser.c
new file mode 100644
index 0000000..764858d
--- /dev/null
+++ b/parser.c
@@ -0,0 +1,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;
+}