HParsedToken *h_seq_index_vpath(const HParsedToken *p, size_t i, va_list va) { HParsedToken *ret = h_seq_index(p, i); int j; while((j = va_arg(va, int)) >= 0) ret = h_seq_index(p, j); return ret; }
// Flatten nested sequences. Always returns a sequence. // If input element is not a sequence, returns it as a singleton sequence. const HParsedToken *h_seq_flatten(HArena *arena, const HParsedToken *p) { assert(p != NULL); HParsedToken *ret = h_make_seq(arena); switch(p->token_type) { case TT_SEQUENCE: // Flatten and append all. for(size_t i; i<p->seq->used; i++) { h_seq_append(ret, h_seq_flatten(arena, h_seq_index(p, i))); } break; default: // Make singleton sequence. h_seq_snoc(ret, p); break; } return ret; }
const HParsedToken *act_base64(const HParseResult *p) { assert(p->ast->token_type == TT_SEQUENCE); assert(p->ast->seq->used == 2); assert(p->ast->seq->elements[0]->token_type == TT_SEQUENCE); HParsedToken *res = H_MAKE_SEQ(); // concatenate base64_3 blocks HCountedArray *seq = H_FIELD_SEQ(0); for(size_t i=0; i<seq->used; i++) h_seq_append(res, seq->elements[i]); // append one trailing base64_2 or _1 block const HParsedToken *tok = h_seq_index(p->ast, 1); if(tok->token_type == TT_SEQUENCE) h_seq_append(res, tok); return res; }