static bool action_ctrvm(HRVMProg *prog, void* env) { HParseAction *a = (HParseAction*)env; h_rvm_insert_insn(prog, RVM_PUSH, 0); if (!h_compile_regex(prog, a->p)) return false; h_rvm_insert_insn(prog, RVM_ACTION, h_rvm_create_action(prog, h_svm_action_action, a)); return true; }
static bool opt_ctrvm(HRVMProg *prog, void* env) { h_rvm_insert_insn(prog, RVM_PUSH, 0); uint16_t insn = h_rvm_insert_insn(prog, RVM_FORK, 0); HParser *p = (HParser*) env; if (!h_compile_regex(prog, p)) return false; h_rvm_patch_arg(prog, insn, h_rvm_get_ip(prog)); h_rvm_insert_insn(prog, RVM_ACTION, h_rvm_create_action(prog, h_svm_action_optional, NULL)); return true; }
static bool sequence_ctrvm(HRVMProg *prog, void *env) { HSequence *s = (HSequence*)env; h_rvm_insert_insn(prog, RVM_PUSH, 0); for (size_t i=0; i<s->len; ++i) { if (!s->p_array[i]->vtable->compile_to_rvm(prog, s->p_array[i]->env)) return false; } h_rvm_insert_insn(prog, RVM_ACTION, h_rvm_create_action(prog, h_svm_action_make_sequence, NULL)); return true; }
static bool is_ctrvm(HRVMProg *prog, void* env) { HIgnoreSeq *seq = (HIgnoreSeq*)env; for (size_t i=0; i<seq->len; ++i) { h_rvm_insert_insn(prog, RVM_PUSH, 0); if (!h_compile_regex(prog, seq->parsers[i])) return false; } h_rvm_insert_insn(prog, RVM_ACTION, h_rvm_create_action(prog, h_svm_action_ignoreseq, env)); return true; }
// FUTURE: this is horribly inefficient static bool cs_ctrvm(HRVMProg *prog, void *env) { HCharset cs = (HCharset)env; h_rvm_insert_insn(prog, RVM_PUSH, 0); uint16_t start = h_rvm_get_ip(prog); uint8_t range_start = 0; bool collecting = false; for (size_t i=0; i<257; ++i) { // Position 256 is only there so that every included character has // a non-included character after it. if (i < 256 && charset_isset(cs, i)) { if (!collecting) { collecting = true; range_start = i; } } else { if (collecting) { collecting = false; uint16_t insn = h_rvm_insert_insn(prog, RVM_FORK, 0); h_rvm_insert_insn(prog, RVM_MATCH, range_start | (i-1) << 8); h_rvm_insert_insn(prog, RVM_GOTO, 0); h_rvm_patch_arg(prog, insn, h_rvm_get_ip(prog)); } } } h_rvm_insert_insn(prog, RVM_MATCH, 0x00FF); uint16_t jump = h_rvm_insert_insn(prog, RVM_STEP, 0); for (size_t i=start; i<jump; ++i) { if (RVM_GOTO == prog->insns[i].op) h_rvm_patch_arg(prog, i, jump); } h_rvm_insert_insn(prog, RVM_CAPTURE, 0); h_rvm_insert_insn(prog, RVM_ACTION, h_rvm_create_action(prog, h_svm_action_ch, env)); return true; }