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 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; }
static bool ws_ctrvm(HRVMProg *prog, void *env) { HParser *p = (HParser*)env; uint16_t start = h_rvm_get_ip(prog); uint16_t next; uint16_t ranges[2] = { 0x0d09, 0x2020, }; for (int i = 0; i < 2; i++) { next = h_rvm_insert_insn(prog, RVM_FORK, 0); h_rvm_insert_insn(prog, RVM_MATCH, ranges[i]); h_rvm_insert_insn(prog, RVM_STEP, 0); h_rvm_insert_insn(prog, RVM_GOTO, start); h_rvm_patch_arg(prog, next, h_rvm_get_ip(prog)); } return h_compile_regex(prog, p); }
static bool choice_ctrvm(HRVMProg *prog, void* env) { HSequence *s = (HSequence*)env; // NOTE(uucidl): stack allocation since this backend uses // setjmp/longjmp for error handling. STACK_VLA(uint16_t, gotos, s->len); for (size_t i=0; i<s->len; ++i) { uint16_t insn = h_rvm_insert_insn(prog, RVM_FORK, 0); if (!h_compile_regex(prog, s->p_array[i])) { return false; } gotos[i] = h_rvm_insert_insn(prog, RVM_GOTO, 65535); h_rvm_patch_arg(prog, insn, h_rvm_get_ip(prog)); } h_rvm_insert_insn(prog, RVM_MATCH, 0x00FF); // fail. uint16_t jump = h_rvm_get_ip(prog); for (size_t i=0; i<s->len; ++i) { h_rvm_patch_arg(prog, gotos[i], jump); } return true; }