diff --git a/common.mk b/common.mk index 1d83db70c79322b6ee532ccec1ca667f72d7594f..ca79430455d18fd0103d1a47d64e0aee61fc9008 100644 --- a/common.mk +++ b/common.mk @@ -1,4 +1,4 @@ -CFLAGS := $(shell pkg-config --cflags glib-2.0) +CFLAGS := $(shell pkg-config --cflags glib-2.0) -std=c99 LDFLAGS := $(shell pkg-config --libs glib-2.0) CC := gcc diff --git a/src/Makefile b/src/Makefile index fcfda82804a7197a27ab45d6980f6b67060e26b3..69a3e2ef4ded249f6d2249fa22cba241dfea40c1 100644 --- a/src/Makefile +++ b/src/Makefile @@ -9,6 +9,7 @@ all: libhammer.a test_suite test_suite: test_suite.o libhammer.a $(CC) -o $@ $^ $(LDFLAGS) -libhammer.a: bitreader.o +libhammer.a: bitreader.o hammer.o bitreader.o: test_suite.h +hammer.o: hammer.h \ No newline at end of file diff --git a/src/hammer.c b/src/hammer.c index 44144f3cb4c81725b732430d735b59cc4a80329c..260bd3971c7fc39b0684fac00e2599d9d5930d3c 100644 --- a/src/hammer.c +++ b/src/hammer.c @@ -17,18 +17,18 @@ #include "hammer.h" #include <string.h> - +/* TODO(thequux): rewrite to follow new parse_state_t layout parse_state_t* from(parse_state_t *ps, const size_t index) { parse_state_t p = { ps->input, ps->index + index, ps->length - index, ps->cache }; parse_state_t *ret = g_new(parse_state_t, 1); *ret = p; return ret; } - +*/ const uint8_t* substring(const parse_state_t *ps, const size_t start, const size_t end) { - if (end > start && (ps->index + end) < ps->length) { + if (end > start && (ps->input_stream.index + end) < ps->input_stream.length) { gpointer ret = g_malloc(end - start); - memcpy(ret, ps->input, end - start); + memcpy(ret, ps->input_stream.input, end - start); return (const uint8_t*)ret; } else { return NULL; @@ -37,46 +37,79 @@ const uint8_t* substring(const parse_state_t *ps, const size_t start, const size const GVariant* at(parse_state_t *ps, const size_t index) { GVariant *ret = NULL; - if (index + ps->index < ps->length) - ret = g_variant_new_byte((ps->input)[index + ps->index]); + if (index + ps->input_stream.index < ps->input_stream.length) + ret = g_variant_new_byte((ps->input_stream.input)[index + ps->input_stream.index]); return g_variant_new_maybe(G_VARIANT_TYPE_BYTE, ret); } const gchar* to_string(parse_state_t *ps) { - return g_strescape((const gchar*)(ps->input), NULL); + return g_strescape((const gchar*)(ps->input_stream.input), NULL); } -const parse_result_t* get_cached(parse_state_t *ps, const size_t pid); /* { - gpointer p = g_hash_table_lookup(ps->cache, &pid); - if (NULL != p) +uint8_t djbhash(size_t index, char bit_offset) { + unsigned int hash = 5381; + for (uint8_t i = 0; i < sizeof(size_t); ++i) { + hash = hash * 33 + (index & 0xFF); + index >>= 8; + } + hash = hash * 33 + bit_offset; + return hash; } - */ -int put_cached(parse_state_t *ps, const size_t pid, parse_result_t *cached); -parser_t* token(const uint8_t *s) { return NULL; } -parser_t* ch(const uint8_t c) { return NULL; } -parser_t* range(const uint8_t lower, const uint8_t upper) { return NULL; } -parser_t* whitespace(parser_t* p) { return NULL; } -//parser_t* action(parser_t* p, /* fptr to action on AST */) { return NULL; } -parser_t* join_action(parser_t* p, const uint8_t *sep) { return NULL; } -parser_t* left_faction_action(parser_t* p) { return NULL; } -parser_t* negate(parser_t* p) { return NULL; } -parser_t* end_p() { return NULL; } -parser_t* nothing_p() { return NULL; } -parser_t* sequence(parser_t* p_array[]) { return NULL; } -parser_t* choice(parser_t* p_array[]) { return NULL; } -parser_t* butnot(parser_t* p1, parser_t* p2) { return NULL; } -parser_t* difference(parser_t* p1, parser_t* p2) { return NULL; } -parser_t* xor(parser_t* p1, parser_t* p2) { return NULL; } -parser_t* repeat0(parser_t* p) { return NULL; } -parser_t* repeat1(parser_t* p) { return NULL; } -parser_t* repeat_n(parser_t* p, const size_t n) { return NULL; } -parser_t* optional(parser_t* p) { return NULL; } -parser_t* expect(parser_t* p) { return NULL; } -parser_t* chain(parser_t* p1, parser_t* p2, parser_t* p3) { return NULL; } -parser_t* chainl(parser_t* p1, parser_t* p2) { return NULL; } -parser_t* list(parser_t* p1, parser_t* p2) { return NULL; } -parser_t* epsilon_p() { return NULL; } -//parser_t* semantic(/* fptr to nullary function? */) { return NULL; } -parser_t* and(parser_t* p) { return NULL; } -parser_t* not(parser_t* p) { return NULL; } +parse_result_t* get_cached(parse_state_t *ps, const parser_t *p) { + gpointer t = g_hash_table_lookup(ps->cache, p); + if (NULL != t) { + parse_result_t* ret = g_hash_table_lookup(t, GUINT_TO_POINTER(djbhash(ps->input_stream.index, + ps->input_stream.length))); + if (NULL != ret) { + return ret; + } else { + // TODO(mlp): need a return value for "this parser was in the cache but nothing was at this location" + return NULL; + } + } else { + // TODO(mlp): need a return value for "this parser wasn't in the cache" + return NULL; + } +} + +int put_cached(parse_state_t *ps, const parser_t *p, parse_result_t *cached) { + gpointer t = g_hash_table_lookup(ps->cache, p); + if (NULL != t) { + g_hash_table_insert(t, GUINT_TO_POINTER(djbhash(ps->input_stream.index, ps->input_stream.length)), (gpointer)cached); + } else { + GHashTable *t = g_hash_table_new(g_direct_hash, g_direct_equal); + g_hash_table_insert(t, GUINT_TO_POINTER(djbhash(ps->input_stream.index, ps->input_stream.length)), (gpointer)cached); + g_hash_table_insert(ps->cache, (parser_t*)p, t); + } +} + +const parser_t* token(const uint8_t *s) { return NULL; } +const parser_t* ch(const uint8_t c) { return NULL; } +const parser_t* range(const uint8_t lower, const uint8_t upper) { return NULL; } +const parser_t* whitespace(const parser_t* p) { return NULL; } +//const parser_t* action(const parser_t* p, /* fptr to action on AST */) { return NULL; } +const parser_t* join_action(const parser_t* p, const uint8_t *sep) { return NULL; } +const parser_t* left_faction_action(const parser_t* p) { return NULL; } +const parser_t* negate(const parser_t* p) { return NULL; } +const parser_t* end_p() { return NULL; } +const parser_t* nothing_p() { return NULL; } +const parser_t* sequence(const parser_t* p_array[]) { return NULL; } +const parser_t* choice(const parser_t* p_array[]) { return NULL; } +const parser_t* butnot(const parser_t* p1, const parser_t* p2) { return NULL; } +const parser_t* difference(const parser_t* p1, const parser_t* p2) { return NULL; } +const parser_t* xor(const parser_t* p1, const parser_t* p2) { return NULL; } +const parser_t* repeat0(const parser_t* p) { return NULL; } +const parser_t* repeat1(const parser_t* p) { return NULL; } +const parser_t* repeat_n(const parser_t* p, const size_t n) { return NULL; } +const parser_t* optional(const parser_t* p) { return NULL; } +const parser_t* expect(const parser_t* p) { return NULL; } +const parser_t* chain(const parser_t* p1, const parser_t* p2, const parser_t* p3) { return NULL; } +const parser_t* chainl(const parser_t* p1, const parser_t* p2) { return NULL; } +const parser_t* list(const parser_t* p1, const parser_t* p2) { return NULL; } +const parser_t* epsilon_p() { return NULL; } +//const parser_t* semantic(/* fptr to nullary function? */) { return NULL; } +const parser_t* and(const parser_t* p) { return NULL; } +const parser_t* not(const parser_t* p) { return NULL; } + +parse_result_t* parse(const parser_t* parser, const uint8_t* input) { return NULL; } diff --git a/src/hammer.h b/src/hammer.h index 99b4578c11dcd13bba70b0933e0b87e95a8ec8ab..1a06ffd920d9b9c62c2767a90d77db33adc394cc 100644 --- a/src/hammer.h +++ b/src/hammer.h @@ -65,34 +65,34 @@ typedef struct parser { void* env; } parser_t; -parse_result_t* parse(parser_t* parser, const uint8_t* input); +parse_result_t* parse(const parser_t* parser, const uint8_t* input); -parser_t* token(const uint8_t *s); -parser_t* ch(const uint8_t c); -parser_t* range(const uint8_t lower, const uint8_t upper); -parser_t* whitespace(parser_t* p); -//parser_t* action(parser_t* p, /* fptr to action on AST */); -parser_t* join_action(parser_t* p, const uint8_t *sep); -parser_t* left_faction_action(parser_t* p); -parser_t* negate(parser_t* p); -parser_t* end_p(); -parser_t* nothing_p(); -parser_t* sequence(parser_t* p_array[]); -parser_t* choice(parser_t* p_array[]); -parser_t* butnot(parser_t* p1, parser_t* p2); -parser_t* difference(parser_t* p1, parser_t* p2); -parser_t* xor(parser_t* p1, parser_t* p2); -parser_t* repeat0(parser_t* p); -parser_t* repeat1(parser_t* p); -parser_t* repeat_n(parser_t* p, const size_t n); -parser_t* optional(parser_t* p); -parser_t* expect(parser_t* p); -parser_t* chain(parser_t* p1, parser_t* p2, parser_t* p3); -parser_t* chainl(parser_t* p1, parser_t* p2); -parser_t* list(parser_t* p1, parser_t* p2); -parser_t* epsilon_p(); -//parser_t* semantic(/* fptr to nullary function? */); -parser_t* and(parser_t* p); -parser_t* not(parser_t* p); +const parser_t* token(const uint8_t *s); +const parser_t* ch(const uint8_t c); +const parser_t* range(const uint8_t lower, const uint8_t upper); +const parser_t* whitespace(const parser_t* p); +//const parser_t* action(const parser_t* p, /* fptr to action on AST */); +const parser_t* join_action(const parser_t* p, const uint8_t *sep); +const parser_t* left_faction_action(const parser_t* p); +const parser_t* negate(const parser_t* p); +const parser_t* end_p(); +const parser_t* nothing_p(); +const parser_t* sequence(const parser_t* p_array[]); +const parser_t* choice(const parser_t* p_array[]); +const parser_t* butnot(const parser_t* p1, const parser_t* p2); +const parser_t* difference(const parser_t* p1, const parser_t* p2); +const parser_t* xor(const parser_t* p1, const parser_t* p2); +const parser_t* repeat0(const parser_t* p); +const parser_t* repeat1(const parser_t* p); +const parser_t* repeat_n(const parser_t* p, const size_t n); +const parser_t* optional(const parser_t* p); +const parser_t* expect(const parser_t* p); +const parser_t* chain(const parser_t* p1, const parser_t* p2, const parser_t* p3); +const parser_t* chainl(const parser_t* p1, const parser_t* p2); +const parser_t* list(const parser_t* p1, const parser_t* p2); +const parser_t* epsilon_p(); +//const parser_t* semantic(/* fptr to nullary function? */); +const parser_t* and(const parser_t* p); +const parser_t* not(const parser_t* p); #endif // #ifndef HAMMER_HAMMER__H