diff --git a/src/hammer.c b/src/hammer.c
index f6cffd850b4bf8b9c556b01135e9e7691cc810d1..e10fdd8966c32b37c3dd403b430b03585465262b 100644
--- a/src/hammer.c
+++ b/src/hammer.c
@@ -22,34 +22,6 @@
 #include <stdarg.h>
 #include <ctype.h>
 
-parse_state_t* from(parse_state_t *ps, const size_t index) {
-  parse_state_t *ret = g_new(parse_state_t, 1);
-  *ret = *ps;
-  ret->input_stream.index += index;
-  return ret;
-}
-
-const uint8_t* substring(const parse_state_t *ps, const size_t start, const size_t end) {
-  if (end > start && (ps->input_stream.index + end) < ps->input_stream.length) {
-    gpointer ret = g_malloc(end - start);
-    memcpy(ret, ps->input_stream.input, end - start);
-    return (const uint8_t*)ret;
-  } else {
-    return NULL;
-  }
-}
-
-const GVariant* at(parse_state_t *ps, const size_t index) {
-  GVariant *ret = NULL;
-  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_stream.input), NULL);
-}
-
 guint djbhash(const uint8_t *buf, size_t len) {
   guint hash = 5381;
   while (len--) {
diff --git a/src/hammer.h b/src/hammer.h
index 57a0aebd762ff9335c33b4b0fe386a94b14790ff..6e1cb77a3f65ab2f6a4ab75d68432c80405b198a 100644
--- a/src/hammer.h
+++ b/src/hammer.h
@@ -70,7 +70,7 @@ typedef struct parsed_token {
     uint64_t uint;
     double dbl;
     float flt;
-    GSequence *seq;
+    GSequence *seq; // a sequence of parsed_token_t's
   };
 } parsed_token_t;
 
diff --git a/src/internal.h b/src/internal.h
index 771a0ee4a4be1c394cfeecbce4b4548433cbb84d..decd7215c4265207781984e4a7e8ac28e625a53e 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -11,6 +11,23 @@ typedef struct parser_cache_key {
   const parser_t *parser;
 } parser_cache_key_t;
 
+typedef enum parser_cache_value_type {
+  PC_BASE,
+  PC_IN_RECURSION,
+  PC_LRESULT,
+  PC_RESULT
+} parser_cache_value_type_t;
+
+typedef struct parser_cache_value {
+  parser_cache_value_type_t value_type;
+  union {
+    int base;
+    parse_result_t *in_recursion;
+    parse_result_t *lresult;
+    parse_result_t *result;
+  };
+} parser_cache_value_t;
+
 typedef unsigned int *charset;
 
 static inline charset new_charset() {