r_memset(co, 0, sizeof(*co));
co->cg = rvm_codegen_create();
co->scope = rvm_scope_create();
- co->current.labelidx = -1;
+ co->expressions = r_array_create(sizeof(rpa_ruledef_t));
rpacompiler_mnode_nan(co);
rpacompiler_mnode_opt(co);
rpacompiler_mnode_mul(co);
if (co) {
rvm_codegen_destroy(co->cg);
rvm_scope_destroy(co->scope);
+ r_object_destroy((robject_t*)co->expressions);
}
r_free(co);
}
rint rpa_compiler_rule_begin(rpa_compiler_t *co, const rchar *name, ruint namesize)
{
- if (co->current.labelidx >= 0)
- return -1;
- co->current.labelidx = rvm_codegen_addlabel(co->cg, name, namesize);
- r_snprintf(co->current.end, sizeof(co->current.end) - 1, "%__end:ld", co->current.labelidx);
- co->current.end[sizeof(co->current.end) - 1] = '\0';
- co->current.endidx = rvm_codemap_invalid_add_s(co->cg->codemap, co->current.end);
- co->current.emitidx = rvm_codegen_adddata_s(co->cg, NULL, name, namesize);
- rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_STRING, co->current.emitidx, rvm_asm(RPA_EMITSTART, DA, R_TOP, XX, 0));
+ rpa_ruledef_t exp;
+ rchar endlabel[64];
+
+ r_memset(&exp, 0, sizeof(exp));
+ exp.emitidx = rvm_codegen_adddata_s(co->cg, NULL, name, namesize);
+ exp.labelidx = rvm_codegen_addlabel(co->cg, name, namesize);
+ exp.start = rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_STRING, exp.emitidx, rvm_asm(RPA_EMITSTART, DA, R_TOP, XX, 0));
rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(R_TOP)|BIT(R_WHT)|BIT(LR)));
+ r_snprintf(endlabel, sizeof(endlabel) - 1, "__end:%ld", exp.start);
+ exp.endidx = rvm_codemap_invalid_add_s(co->cg->codemap, endlabel);
+ r_array_add(co->expressions, &exp);
return 0;
}
rint rpa_compiler_rule_end(rpa_compiler_t *co)
{
- if (co->current.labelidx < 0)
- return -1;
+ rpa_ruledef_t exp = r_array_pop(co->expressions, rpa_ruledef_t);
+
+ rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(R1)|BIT(R_WHT)|BIT(LR)));
+ rvm_codegen_addins(co->cg, rvm_asm(RVM_SUBS, R0, R_TOP, R1, 0));
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_STRING, exp.emitidx, rvm_asm(RPA_EMITEND, DA, R1, R0, 0));
+ rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
+ rvm_codegen_redefinelabel(co->cg, exp.endidx);
+ rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(R_TOP)|BIT(R_WHT)|BIT(LR)));
+ rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, -1));
+ rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
+ return 0;
+}
+
+
+rint rpa_compiler_exp_begin(rpa_compiler_t *co)
+{
+ rpa_ruledef_t exp;
+ rchar endlabel[64];
+
+ exp.branch = rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, 0));
+ r_snprintf(endlabel, sizeof(endlabel) - 1, "__begin:%ld", rvm_codegen_getcodesize(co->cg));
+ exp.labelidx = rvm_codegen_addlabel_s(co->cg, endlabel);
+ exp.start = rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(R_TOP)|BIT(R_WHT)|BIT(LR)));
+ r_snprintf(endlabel, sizeof(endlabel) - 1, "__end:%ld", exp.start);
+ exp.endidx = rvm_codemap_invalid_add_s(co->cg->codemap, endlabel);
+ r_array_add(co->expressions, &exp);
+ return 0;
+}
+
+
+rint rpa_compiler_exp_end(rpa_compiler_t *co, ruint qflag)
+{
+ rpa_ruledef_t exp = r_array_pop(co->expressions, rpa_ruledef_t);
+
rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(R1)|BIT(R_WHT)|BIT(LR)));
rvm_codegen_addins(co->cg, rvm_asm(RVM_SUBS, R0, R_TOP, R1, 0));
- rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_STRING, co->current.emitidx, rvm_asm(RPA_EMITEND, DA, R1, R0, 0));
rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
- rvm_codegen_addlabel_s(co->cg, co->current.end);
+ rvm_codegen_redefinelabel(co->cg, exp.endidx);
rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(R_TOP)|BIT(R_WHT)|BIT(LR)));
rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, -1));
rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
- co->current.labelidx = -1;
+ rvm_codegen_replaceins(co->cg, exp.branch, rvm_asm(RVM_B, DA, XX, XX, rvm_codegen_getcodesize(co->cg) - exp.branch));
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_JUMP, exp.labelidx, rvm_asm(RPA_BXLWHT, R_MNODE_NAN, DA, XX, 0));
+
return 0;
}
{
rpa_compiler_rule_begin_s(co, "rpa_matchabc");
rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'a'));
- rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, co->current.endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'b'));
- rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, co->current.endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'c'));
- rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, co->current.endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
rpa_compiler_rule_end(co);
}
{
rpa_compiler_rule_begin_s(co, "rpa_matchxyz");
rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'x'));
- rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, co->current.endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'y'));
- rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, co->current.endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'z'));
- rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, co->current.endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
rpa_compiler_rule_end(co);
}