void h_seq_snoc(HParsedToken *xs, const HParsedToken *x) { assert(xs != NULL); assert(xs->token_type == TT_SEQUENCE); h_carray_append(xs->seq, (HParsedToken *)x); }
void h_seq_append(HParsedToken *xs, const HParsedToken *ys) { assert(xs != NULL); assert(xs->token_type == TT_SEQUENCE); assert(ys != NULL); assert(ys->token_type == TT_SEQUENCE); for(size_t i=0; i<ys->seq->used; i++) h_carray_append(xs->seq, ys->seq->elements[i]); }
static void act_flatten_(HCountedArray *seq, const HParsedToken *tok) { if(tok == NULL) { return; } else if(tok->token_type == TT_SEQUENCE) { size_t i; for(i=0; i<tok->seq->used; i++) act_flatten_(seq, tok->seq->elements[i]); } else { h_carray_append(seq, (HParsedToken *)tok); } }
static HParseResult* parse_sequence(void *env, HParseState *state) { HSequence *s = (HSequence*)env; HCountedArray *seq = h_carray_new_sized(state->arena, (s->len > 0) ? s->len : 4); for (size_t i=0; i<s->len; ++i) { HParseResult *tmp = h_do_parse(s->p_array[i], state); // if the interim parse fails, the whole thing fails if (NULL == tmp) { return NULL; } else { if (tmp->ast) h_carray_append(seq, (void*)tmp->ast); } } HParsedToken *tok = a_new(HParsedToken, 1); tok->token_type = TT_SEQUENCE; tok->seq = seq; return make_result(state->arena, tok); }
static HParsedToken *reshape_sequence(const HParseResult *p) { assert(p->ast); assert(p->ast->token_type == TT_SEQUENCE); HCountedArray *seq = h_carray_new(p->arena); // drop all elements that are NULL for(size_t i=0; i<p->ast->seq->used; i++) { if(p->ast->seq->elements[i] != NULL) h_carray_append(seq, p->ast->seq->elements[i]); } HParsedToken *res = a_new_(p->arena, HParsedToken, 1); res->token_type = TT_SEQUENCE; res->seq = seq; res->index = p->ast->index; res->bit_offset = p->ast->bit_offset; return res; }
static HParseResult *parse_many(void* env, HParseState *state) { HRepeat *env_ = (HRepeat*) env; HCountedArray *seq = h_carray_new_sized(state->arena, (env_->count > 0 ? env_->count : 4)); size_t count = 0; HInputStream bak; while (env_->min_p || env_->count > count) { bak = state->input_stream; if (count > 0) { HParseResult *sep = h_do_parse(env_->sep, state); if (!sep) goto err0; } HParseResult *elem = h_do_parse(env_->p, state); if (!elem) goto err0; if (elem->ast) h_carray_append(seq, (void*)elem->ast); count++; } if (count < env_->count) goto err; succ: ; // necessary for the label to be here... HParsedToken *res = a_new(HParsedToken, 1); res->token_type = TT_SEQUENCE; res->seq = seq; return make_result(state, res); err0: if (count >= env_->count) { state->input_stream = bak; goto succ; } err: state->input_stream = bak; return NULL; }