diff --git a/src/hammer.c b/src/hammer.c
index f66b96301a186d2e8c33e6bb90e43230dd67845e..11492c3fdfb28705f7eaad360f5d99af74068fb9 100644
--- a/src/hammer.c
+++ b/src/hammer.c
@@ -35,14 +35,43 @@ static guint djbhash(const uint8_t *buf, size_t len) {
 }
 
 // short-hand for constructing HCachedResult's
-static HCachedResult *cached_result(const HParseState *state, HParseResult *result)
-{
+static HCachedResult *cached_result(const HParseState *state, HParseResult *result) {
   HCachedResult *ret = a_new(HCachedResult, 1);
   ret->result = result;
   ret->input_stream = state->input_stream;
   return ret;
 }
 
+// Really library-internal tool to perform an uncached parse, and handle any common error-handling.
+static inline HParseResult* perform_lowlevel_parse(HParseState *state, const HParser *parser) {
+  HParseResult *tmp_res;
+  if (parser) {
+    HInputStream bak = state->input_stream;
+    tmp_res = parser->vtable->parse(parser->env, state);
+    if (tmp_res) {
+      tmp_res->arena = state->arena;
+      if (!state->input_stream.overrun) {
+	tmp_res->bit_length = ((state->input_stream.index - bak.index) << 3);
+	if (state->input_stream.endianness & BIT_BIG_ENDIAN)
+	  tmp_res->bit_length += state->input_stream.bit_offset - bak.bit_offset;
+	else
+	  tmp_res->bit_length += bak.bit_offset - state->input_stream.bit_offset;
+      } else
+	tmp_res->bit_length = 0;
+    }
+  } else
+    tmp_res = NULL;
+  if (state->input_stream.overrun)
+    return NULL; // overrun is always failure.
+#ifdef CONSISTENCY_CHECK
+  if (!tmp_res) {
+    state->input_stream = INVALID;
+    state->input_stream.input = key->input_pos.input;
+  }
+#endif
+  return tmp_res;
+}
+
 HParserCacheValue* recall(HParserCacheKey *k, HParseState *state) {
   HParserCacheValue *cached = g_hash_table_lookup(state->cache, k);
   HRecursionHead *head = g_hash_table_lookup(state->recursion_heads, k);
@@ -60,9 +89,7 @@ HParserCacheValue* recall(HParserCacheKey *k, HParseState *state) {
     if (g_slist_find(head->eval_set, k->parser)) {
       // Something is in the cache, and the key parser is in the eval set. Remove the key parser from the eval set of the head. 
       head->eval_set = g_slist_remove_all(head->eval_set, k->parser);
-      HParseResult *tmp_res = k->parser->vtable->parse(k->parser->env, state);
-      if (tmp_res)
-	tmp_res->arena = state->arena;
+      HParseResult *tmp_res = perform_lowlevel_parse(state, k->parser);
       // we know that cached has an entry here, modify it
       if (!cached)
 	cached = a_new(HParserCacheValue, 1);
@@ -106,13 +133,8 @@ HParseResult* grow(HParserCacheKey *k, HParseState *state, HRecursionHead *head)
   
   // reset the eval_set of the head of the recursion at each beginning of growth
   head->eval_set = head->involved_set;
-  HParseResult *tmp_res;
-  if (k->parser) {
-    tmp_res = k->parser->vtable->parse(k->parser->env, state);
-    if (tmp_res)
-      tmp_res->arena = state->arena;
-  } else
-    tmp_res = NULL;
+  HParseResult *tmp_res = perform_lowlevel_parse(state, k->parser);
+
   if (tmp_res) {
     if ((old_res->ast->index < tmp_res->ast->index) || 
 	(old_res->ast->index == tmp_res->ast->index && old_res->ast->bit_offset < tmp_res->ast->bit_offset)) {
@@ -173,31 +195,7 @@ HParseResult* h_do_parse(const HParser* parser, HParseState *state) {
     dummy->value_type = PC_LEFT; dummy->left = base;
     g_hash_table_replace(state->cache, key, dummy);
     // parse the input
-    HParseResult *tmp_res;
-    if (parser) {
-      HInputStream bak = state->input_stream;
-      tmp_res = parser->vtable->parse(parser->env, state);
-      if (tmp_res) {
-	tmp_res->arena = state->arena;
-	if (!state->input_stream.overrun) {
-	  tmp_res->bit_length = ((state->input_stream.index - bak.index) << 3);
-	  if (state->input_stream.endianness & BIT_BIG_ENDIAN)
-	    tmp_res->bit_length += state->input_stream.bit_offset - bak.bit_offset;
-	  else
-	    tmp_res->bit_length += bak.bit_offset - state->input_stream.bit_offset;
-	} else
-	  tmp_res->bit_length = 0;
-      }
-    } else
-      tmp_res = NULL;
-    if (state->input_stream.overrun)
-      return NULL; // overrun is always failure.
-#ifdef CONSISTENCY_CHECK
-    if (!tmp_res) {
-      state->input_stream = INVALID;
-      state->input_stream.input = key->input_pos.input;
-    }
-#endif
+    HParseResult *tmp_res = perform_lowlevel_parse(state, parser);
     // the base variable has passed equality tests with the cache
     g_queue_pop_head(state->lr_stack);
     // setupLR, used below, mutates the LR to have a head if appropriate, so we check to see if we have one