RPA Toolkit
work on RPA2 CLASS, NOT, MINUS expressions
authorMartin Stoilov <martin@rpasearch.com>
Mon, 28 Feb 2011 07:14:47 +0000 (23:14 -0800)
committerMartin Stoilov <martin@rpasearch.com>
Mon, 28 Feb 2011 07:14:47 +0000 (23:14 -0800)
13 files changed:
rpa2/rpacompiler.c
rpa2/rpacompiler.h
rpa2/rpavm.c
rpa2/rpavm.h
testrpa2/build/linux/testrpa2.mk
testrpa2/rpacompiler-altexp.c
testrpa2/rpacompiler-class.c [new file with mode: 0644]
testrpa2/rpacompiler-exp.c
testrpa2/rpacompiler-minusexp.c [new file with mode: 0644]
testrpa2/rpacompiler-notexp.c [new file with mode: 0644]
testrpa2/rpavm-matchrng.c [new file with mode: 0644]
testrpa2/rpavm-mnode.c
tests/regex-test.c

index 40f8c23..4e009c8 100644 (file)
@@ -218,7 +218,7 @@ rint rpa_compiler_altexp_end(rpa_compiler_t *co, ruint qflag)
 }
 
 
-rint rpa_compiler_altbranch_begin(rpa_compiler_t *co)
+rint rpa_compiler_branch_begin(rpa_compiler_t *co)
 {
        rpa_ruledef_t exp;
        rchar endlabel[64];
@@ -234,7 +234,7 @@ rint rpa_compiler_altbranch_begin(rpa_compiler_t *co)
 }
 
 
-rint rpa_compiler_altbranch_end(rpa_compiler_t *co, ruint qflag)
+rint rpa_compiler_branch_end(rpa_compiler_t *co, ruint qflag)
 {
        rpa_ruledef_t exp = r_array_pop(co->expressions, rpa_ruledef_t);
 
@@ -260,3 +260,90 @@ rint rpa_compiler_altbranch_end(rpa_compiler_t *co, ruint qflag)
 
        return 0;
 }
+
+
+rint rpa_compiler_class_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_class_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(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));
+       rvm_codegen_redefinelabel(co->cg, exp.endidx);
+       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_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
+
+       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(RVM_MOV, R_WHT, DA, XX, 0));
+       if (qflag == RPA_MATCH_OPTIONAL) {
+               rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_BRANCH, "rpacompiler_mnode_opt", rvm_asm(RVM_BL, DA, XX, XX, 0));
+       } else if (qflag == RPA_MATCH_MULTIPLE) {
+               rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_BRANCH, "rpacompiler_mnode_mul", rvm_asm(RVM_BL, DA, XX, XX, 0));
+       } else if (qflag == RPA_MATCH_MULTIOPT) {
+               rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_BRANCH, "rpacompiler_mnode_mop", rvm_asm(RVM_BL, DA, XX, XX, 0));
+       } else {
+               rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_BRANCH, "rpacompiler_mnode_nan", rvm_asm(RVM_BL, DA, XX, XX, 0));
+       }
+       return 0;
+}
+
+
+rint rpa_compiler_notexp_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_notexp_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(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_CMP, R0, DA, XX, 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(RPA_MATCHSPCHR_NAN, DA, XX, XX, '.'));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
+
+       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(RVM_MOV, R_WHT, DA, XX, 0));
+       if (qflag == RPA_MATCH_OPTIONAL) {
+               rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_BRANCH, "rpacompiler_mnode_opt", rvm_asm(RVM_BL, DA, XX, XX, 0));
+       } else if (qflag == RPA_MATCH_MULTIPLE) {
+               rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_BRANCH, "rpacompiler_mnode_mul", rvm_asm(RVM_BL, DA, XX, XX, 0));
+       } else if (qflag == RPA_MATCH_MULTIOPT) {
+               rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_BRANCH, "rpacompiler_mnode_mop", rvm_asm(RVM_BL, DA, XX, XX, 0));
+       } else {
+               rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_BRANCH, "rpacompiler_mnode_nan", rvm_asm(RVM_BL, DA, XX, XX, 0));
+       }
+       return 0;
+}
index 93014d6..cae68c2 100644 (file)
@@ -37,11 +37,18 @@ rint rpa_compiler_rule_end(rpa_compiler_t *co);
 rint rpa_compiler_exp_begin(rpa_compiler_t *co);
 rint rpa_compiler_exp_end(rpa_compiler_t *co, ruint qflag);
 
-rint rpa_compiler_altbranch_begin(rpa_compiler_t *co);
-rint rpa_compiler_altbranch_end(rpa_compiler_t *co, ruint qflag);
 rint rpa_compiler_altexp_begin(rpa_compiler_t *co);
 rint rpa_compiler_altexp_end(rpa_compiler_t *co, ruint qflag);
 
+rint rpa_compiler_branch_begin(rpa_compiler_t *co);
+rint rpa_compiler_branch_end(rpa_compiler_t *co, ruint qflag);
+
+rint rpa_compiler_class_begin(rpa_compiler_t *co);
+rint rpa_compiler_class_end(rpa_compiler_t *co, ruint qflag);
+
+rint rpa_compiler_notexp_begin(rpa_compiler_t *co);
+rint rpa_compiler_notexp_end(rpa_compiler_t *co, ruint qflag);
+
 
 #ifdef __cplusplus
 }
index 2d17348..42e0a27 100644 (file)
@@ -9,7 +9,7 @@ static void rpavm_swi_shift(rvmcpu_t *cpu, rvm_asmins_t *ins)
        rlong tp = RVM_CPUREG_GETL(cpu, R_TOP);
        rpainput_t * ptp = &stat->instack[tp];
 
-       if (ptp->eof)
+       if (tp >= 0 && ptp->eof)
                return;
        ptp++;
        tp++;
@@ -173,28 +173,73 @@ static void rpavm_swi_matchspchr_mop(rvmcpu_t *cpu, rvm_asmins_t *ins)
 }
 
 
+static void rpavm_matchrng_do(rvmcpu_t *cpu, rvm_asmins_t *ins, rword flags)
+{
+       rpastat_t *stat = (rpastat_t *)cpu->userdata1;
+       rpair_t pr = RVM_CPUREG_GETPAIR(cpu, ins->op1);
+       rword matched = 0;
+
+       if (flags == RPA_MATCH_OPTIONAL) {
+               if (!stat->instack[RVM_CPUREG_GETL(cpu, R_TOP)].eof &&
+                       (stat->instack[RVM_CPUREG_GETL(cpu, R_TOP)].wc >= pr.p1 && stat->instack[RVM_CPUREG_GETL(cpu, R_TOP)].wc <= pr.p2)) {
+                       rpavm_swi_shift(cpu, ins);
+                       matched = 1;
+               }
+               cpu->status = matched ? 0 : RVM_STATUS_Z;
+               RVM_CPUREG_SETU(cpu, R0, matched);
+       } else if (flags == RPA_MATCH_MULTIPLE) {
+               while (!stat->instack[RVM_CPUREG_GETL(cpu, R_TOP)].eof &&
+                               (stat->instack[RVM_CPUREG_GETL(cpu, R_TOP)].wc >= pr.p1 && stat->instack[RVM_CPUREG_GETL(cpu, R_TOP)].wc <= pr.p2)) {
+                       rpavm_swi_shift(cpu, ins);
+                       matched += 1;
+               }
+               cpu->status = matched ? 0 : RVM_STATUS_N;
+               RVM_CPUREG_SETU(cpu, R0, matched ? matched : (rword)-1);
+       } else if (flags == RPA_MATCH_MULTIOPT) {
+               while (!stat->instack[RVM_CPUREG_GETL(cpu, R_TOP)].eof &&
+                               (stat->instack[RVM_CPUREG_GETL(cpu, R_TOP)].wc >= pr.p1 && stat->instack[RVM_CPUREG_GETL(cpu, R_TOP)].wc <= pr.p2)) {
+                       rpavm_swi_shift(cpu, ins);
+                       matched += 1;
+               }
+               cpu->status = matched ? 0 : RVM_STATUS_Z;
+               RVM_CPUREG_SETU(cpu, R0, matched );
+       } else {
+               if (!stat->instack[RVM_CPUREG_GETL(cpu, R_TOP)].eof &&
+                       (stat->instack[RVM_CPUREG_GETL(cpu, R_TOP)].wc >= pr.p1 && stat->instack[RVM_CPUREG_GETL(cpu, R_TOP)].wc <= pr.p2)) {
+                       rpavm_swi_shift(cpu, ins);
+                       matched = 1;
+               }
+               cpu->status = matched ? 0 : RVM_STATUS_N;
+               RVM_CPUREG_SETU(cpu, R0, matched ? matched : (rword)-1);
+       }
+}
 
 
-static void rpavm_swi_matchany_nan(rvmcpu_t *cpu, rvm_asmins_t *ins)
+static void rpavm_swi_matchrng_nan(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rpastat_t *stat = (rpastat_t *)cpu->userdata1;
+       rpavm_matchrng_do(cpu, ins, RPA_MATCH_NONE);
+}
+
 
-       RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, (!stat->instack[RVM_CPUREG_GETL(cpu, R_TOP)].eof) ? 0 : 1);
-       if (!(cpu->status & RVM_STATUS_N))
-               rpavm_swi_shift(cpu, ins);
+static void rpavm_swi_matchrng_opt(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rpavm_matchrng_do(cpu, ins, RPA_MATCH_OPTIONAL);
 }
 
 
-static void rpavm_swi_matcheol_nan(rvmcpu_t *cpu, rvm_asmins_t *ins)
+static void rpavm_swi_matchrng_mul(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rpastat_t *stat = (rpastat_t *)cpu->userdata1;
+       rpavm_matchrng_do(cpu, ins, RPA_MATCH_MULTIPLE);
+}
+
 
-       RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, (!stat->instack[RVM_CPUREG_GETL(cpu, R_TOP)].eof && r_strchr("\r\n", stat->instack[RVM_CPUREG_GETL(cpu, R_TOP)].wc)) ? 0 : 1);
-       if (!(cpu->status & RVM_STATUS_N))
-               rpavm_swi_shift(cpu, ins);
+static void rpavm_swi_matchrng_mop(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rpavm_matchrng_do(cpu, ins, RPA_MATCH_MULTIOPT);
 }
 
 
+
 static void rpavm_swi_emitstart(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
        rpastat_t *stat = (rpastat_t *)cpu->userdata1;
@@ -207,6 +252,7 @@ static void rpavm_swi_emitstart(rvmcpu_t *cpu, rvm_asmins_t *ins)
        rec = (rparecord_t *)r_array_slot(stat->records, index);
        rec->rule = name.str;
        rec->top = tp;
+       stat->instack[RVM_CPUREG_GETL(cpu, R_TOP)].rp = (rint32)index;
        rec->type = RPA_RECORD_START;
 //     r_printf("START: %s(%ld)\n", name.str, (rulong)tp);
 }
@@ -225,6 +271,7 @@ static void rpavm_swi_emitend(rvmcpu_t *cpu, rvm_asmins_t *ins)
        rec = (rparecord_t *)r_array_slot(stat->records, index);
        rec->rule = name.str;
        rec->top = tp;
+       stat->instack[RVM_CPUREG_GETL(cpu, R_TOP)].rp = (rint32)index;
        rec->size = tplen;
        rec->type = RPA_RECORD_START;
 
@@ -253,6 +300,10 @@ static rvm_switable_t rpavm_swi_table[] = {
                {"RPA_MATCHCHR_OPT", rpavm_swi_matchchr_opt},
                {"RPA_MATCHCHR_MUL", rpavm_swi_matchchr_mul},
                {"RPA_MATCHCHR_MOP", rpavm_swi_matchchr_mop},
+               {"RPA_MATCHRNG_NAN", rpavm_swi_matchrng_nan},
+               {"RPA_MATCHRNG_OPT", rpavm_swi_matchrng_opt},
+               {"RPA_MATCHRNG_MUL", rpavm_swi_matchrng_mul},
+               {"RPA_MATCHRNG_MOP", rpavm_swi_matchrng_mop},
                {"RPA_MATCHSPCHR_NAN", rpavm_swi_matchspchr_nan},
                {"RPA_MATCHSPCHR_OPT", rpavm_swi_matchspchr_opt},
                {"RPA_MATCHSPCHR_MUL", rpavm_swi_matchspchr_mul},
@@ -260,8 +311,6 @@ static rvm_switable_t rpavm_swi_table[] = {
                {"RPA_SHIFT", rpavm_swi_shift},
                {"RPA_EMITSTART", rpavm_swi_emitstart},
                {"RPA_EMITEND", rpavm_swi_emitend},
-               {"RPA_MATCHANY_NAN", rpavm_swi_matchany_nan},
-               {"RPA_MATCHEOL_NAN", rpavm_swi_matcheol_nan},
                {"RPA_BXLWHT", rpavm_swi_bxlwht},
                {NULL, NULL},
 };
index 4053af0..2fe5e96 100644 (file)
@@ -30,16 +30,21 @@ extern "C" {
 #define RPA_MATCHCHR_OPT       RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 1))
 #define RPA_MATCHCHR_MUL       RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 2))
 #define RPA_MATCHCHR_MOP       RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 3))
-#define RPA_MATCHSPCHR_NAN     RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 4))
-#define RPA_MATCHSPCHR_OPT     RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 5))
-#define RPA_MATCHSPCHR_MUL     RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 6))
-#define RPA_MATCHSPCHR_MOP     RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 7))
-#define RPA_SHIFT                      RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 8))
-#define RPA_EMITSTART          RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 9))
-#define RPA_EMITEND                    RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 10))
-#define RPA_MATCHANY_NAN       RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 11))
-#define RPA_MATCHEOL_NAN       RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 12))
-#define RPA_BXLWHT                     RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 13))
+
+#define RPA_MATCHRNG_NAN       RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 4))
+#define RPA_MATCHRNG_OPT       RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 5))
+#define RPA_MATCHRNG_MUL       RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 6))
+#define RPA_MATCHRNG_MOP       RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 7))
+
+#define RPA_MATCHSPCHR_NAN     RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 8))
+#define RPA_MATCHSPCHR_OPT     RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 9))
+#define RPA_MATCHSPCHR_MUL     RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 10))
+#define RPA_MATCHSPCHR_MOP     RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 11))
+
+#define RPA_SHIFT                      RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 12))
+#define RPA_EMITSTART          RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 13))
+#define RPA_EMITEND                    RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 14))
+#define RPA_BXLWHT                     RVM_OPSWI(RVM_SWI_ID(RPAVM_SWI_TABLEID, 15))
 
 
 typedef struct rparecord_s {
@@ -55,6 +60,7 @@ typedef struct rparecord_s {
 typedef struct rpainput_s {
        const rchar *input;
        ruint32 wc;
+       rint32 rp;
        ruchar eof;
 } rpainput_t;
 
index 8ff870a..aa63e9d 100644 (file)
@@ -12,10 +12,15 @@ LIBS += -lrpa2 -lrvm -lrlib -lpthread -lm --static
 
 
 TESTS  += $(OUTDIR)/rpavm-matchchr
+TESTS  += $(OUTDIR)/rpavm-matchrng
 TESTS  += $(OUTDIR)/rpavm-mnode
 TESTS  += $(OUTDIR)/rpacompiler-rule
 TESTS  += $(OUTDIR)/rpacompiler-exp
+TESTS  += $(OUTDIR)/rpacompiler-notexp
+TESTS  += $(OUTDIR)/rpacompiler-class
 TESTS  += $(OUTDIR)/rpacompiler-altexp
+TESTS  += $(OUTDIR)/rpacompiler-minusexp
+
 
 all : $(OUTDIR) $(TESTS)
 
index 1ea71d8..be66b73 100644 (file)
@@ -17,46 +17,54 @@ void code_rpa_matchaltexp(rpa_compiler_t *co, rpastat_t *stat)
 {
        rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
        rpa_compiler_altexp_begin(co);
-       rpa_compiler_altbranch_begin(co);
+       rpa_compiler_branch_begin(co);
        rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'd'));
        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, 'e'));
        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, 'f'));
        rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
-       rpa_compiler_altbranch_end(co, RPA_MATCH_NONE);
-       rpa_compiler_altbranch_begin(co);
+       rpa_compiler_branch_end(co, RPA_MATCH_NONE);
+       rpa_compiler_branch_begin(co);
        rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'a'));
        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, 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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
-       rpa_compiler_altbranch_end(co, RPA_MATCH_NONE);
+       rpa_compiler_branch_end(co, RPA_MATCH_NONE);
        rpa_compiler_altexp_end(co, RPA_MATCH_NONE);
        VMTEST_REG(co->cg, 0, 3, "RPA_MATCH_NONE 'abc|def'");
        VMTEST_STATUS(co->cg, 0, "RPA_MATCH_NONE STATUS");
 
        rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
        rpa_compiler_altexp_begin(co);
-       rpa_compiler_altbranch_begin(co);
+       rpa_compiler_branch_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'g'));
+       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, 'h'));
+       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, 'i'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+       rpa_compiler_branch_end(co, RPA_MATCH_NONE);
+       rpa_compiler_branch_begin(co);
        rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'd'));
        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, 'e'));
        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, 'f'));
        rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
-       rpa_compiler_altbranch_end(co, RPA_MATCH_NONE);
-       rpa_compiler_altbranch_begin(co);
+       rpa_compiler_branch_end(co, RPA_MATCH_NONE);
+       rpa_compiler_branch_begin(co);
        rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'a'));
        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, 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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
-       rpa_compiler_altbranch_end(co, RPA_MATCH_NONE);
+       rpa_compiler_branch_end(co, RPA_MATCH_NONE);
        rpa_compiler_altexp_end(co, RPA_MATCH_MULTIPLE);
-       VMTEST_REG(co->cg, 0, 15, "RPA_MATCH_MULTIPLE 'abc|def'");
+       VMTEST_REG(co->cg, 0, 12, "RPA_MATCH_MULTIPLE 'ghi|def|abc'");
        VMTEST_STATUS(co->cg, 0, "RPA_MATCH_MULTIPLE STATUS");
 
 }
@@ -68,13 +76,13 @@ int main(int argc, char *argv[])
        rpa_compiler_t *co;
        rpastat_t *stat;
        ruint mainoff;
-       char teststr[] = "abcabcabcabcabc";
+       char teststr[] = "abcdefghiabc";
 
        co = rpa_compiler_create();
        stat = rpa_stat_create(4096);
        rvm_cpu_addswitable(stat->cpu, common_calltable);
 
-       rpa_stat_init(stat, teststr, teststr, teststr+15);
+       rpa_stat_init(stat, teststr, teststr, teststr+12);
 
        mainoff = rvm_codegen_addins(co->cg, rvm_asml(RVM_NOP, XX, XX, XX, -1));
        rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R_TOP, DA, XX, -1));
diff --git a/testrpa2/rpacompiler-class.c b/testrpa2/rpacompiler-class.c
new file mode 100644 (file)
index 0000000..93e329c
--- /dev/null
@@ -0,0 +1,163 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include "rmem.h"
+#include "rpacompiler.h"
+#include "rpastat.h"
+#include "common.h"
+
+
+
+void code_rpa_matchclass(rpa_compiler_t *co, rpastat_t *stat)
+{
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rpa_compiler_class_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'a'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, 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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, 'c', 'd'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rpa_compiler_class_end(co, RPA_MATCH_NONE);
+       VMTEST_REG(co->cg, 0, 1, "RPA_MATCH_NONE '[abc-d]'");
+       VMTEST_STATUS(co->cg, 0, "RPA_MATCH_NONE STATUS");
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rpa_compiler_class_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'p'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'q'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, 'x', 'z'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rpa_compiler_class_end(co, RPA_MATCH_NONE);
+       VMTEST_REG(co->cg, 0, -1, "RPA_MATCH_NONE '[pqx-z]'");
+       VMTEST_STATUS(co->cg, RVM_STATUS_N, "RPA_MATCH_NONE STATUS");
+
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rpa_compiler_class_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'a'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, 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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, 'c', 'd'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rpa_compiler_class_end(co, RPA_MATCH_OPTIONAL);
+       VMTEST_REG(co->cg, 0, 1, "RPA_MATCH_OPTIONAL '[abc-d]'");
+       VMTEST_STATUS(co->cg, 0, "RPA_MATCH_OPTIONAL STATUS");
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rpa_compiler_class_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'p'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'q'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, 'x', 'z'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rpa_compiler_class_end(co, RPA_MATCH_OPTIONAL);
+       VMTEST_REG(co->cg, 0, 0, "RPA_MATCH_OPTIONAL '[pqx-z]'");
+       VMTEST_STATUS(co->cg, RVM_STATUS_Z, "RPA_MATCH_OPTIONAL STATUS");
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rpa_compiler_class_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'a'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, 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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, 'c', 'd'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rpa_compiler_class_end(co, RPA_MATCH_MULTIPLE);
+       VMTEST_REG(co->cg, 0, 12, "RPA_MATCH_MULTIPLE '[abc-d]'");
+       VMTEST_STATUS(co->cg, 0, "RPA_MATCH_MULTIPLE STATUS");
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rpa_compiler_class_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'p'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'q'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, 'x', 'z'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rpa_compiler_class_end(co, RPA_MATCH_MULTIPLE);
+       VMTEST_REG(co->cg, 0, -1, "RPA_MATCH_MULTIPLE '[pqx-z]'");
+       VMTEST_STATUS(co->cg, RVM_STATUS_N, "RPA_MATCH_MULTIPLE STATUS");
+
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rpa_compiler_class_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'a'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, 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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, 'c', 'd'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rpa_compiler_class_end(co, RPA_MATCH_MULTIOPT);
+       VMTEST_REG(co->cg, 0, 12, "RPA_MATCH_MULTIOPT '[abc-d]'");
+       VMTEST_STATUS(co->cg, 0, "RPA_MATCH_MULTIOPT STATUS");
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rpa_compiler_class_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'p'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'q'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, 'x', 'z'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rpa_compiler_class_end(co, RPA_MATCH_MULTIOPT);
+       VMTEST_REG(co->cg, 0, 0, "RPA_MATCH_MULTIOPT '[pqx-z]'");
+       VMTEST_STATUS(co->cg, RVM_STATUS_Z, "RPA_MATCH_MULTIOPT STATUS");
+
+}
+
+
+int main(int argc, char *argv[])
+{
+       rvm_codelabel_t *err;
+       rpa_compiler_t *co;
+       rpastat_t *stat;
+       ruint mainoff;
+       char teststr[] = "abcabcabcabc";
+
+       co = rpa_compiler_create();
+       stat = rpa_stat_create(4096);
+       rvm_cpu_addswitable(stat->cpu, common_calltable);
+
+       rpa_stat_init(stat, teststr, teststr, teststr+12);
+
+       mainoff = rvm_codegen_addins(co->cg, rvm_asml(RVM_NOP, XX, XX, XX, -1));
+       rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R_TOP, DA, XX, -1));
+       rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, FP, DA, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, SP, DA, XX, 0));
+
+       rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_JUMP, "rpacompiler_mnode_nan", rvm_asm(RVM_MOV, R_MNODE_NAN, DA, XX, 0));
+       rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_JUMP, "rpacompiler_mnode_mul", rvm_asm(RVM_MOV, R_MNODE_MUL, DA, XX, 0));
+       rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_JUMP, "rpacompiler_mnode_opt", rvm_asm(RVM_MOV, R_MNODE_OPT, DA, XX, 0));
+       rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_JUMP, "rpacompiler_mnode_mop", rvm_asm(RVM_MOV, R_MNODE_MOP, DA, XX, 0));
+
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_SHIFT, XX, XX, XX, 0));
+       code_rpa_matchclass(co, stat);
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xabc));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_EXT, XX, XX, XX, 0));
+
+       if (rvm_codegen_relocate(co->cg, &err) < 0) {
+               r_printf("Unresolved symbol: %s\n", err->name->str);
+               goto end;
+       }
+
+       rvm_cpu_exec(stat->cpu, rvm_codegen_getcode(co->cg, 0), mainoff);
+
+end:
+       rpa_stat_destroy(stat);
+       rpa_compiler_destroy(co);
+
+
+       r_printf("Max alloc mem: %ld\n", r_debug_get_maxmem());
+       r_printf("Leaked mem: %ld\n", r_debug_get_allocmem());
+       return 0;
+}
index 5e992f7..8fc7eb6 100644 (file)
@@ -21,10 +21,16 @@ void code_rpa_matchexp(rpa_compiler_t *co, rpastat_t *stat)
        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, 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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+       rpa_compiler_class_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'a'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, 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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, 'c', 'd'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rpa_compiler_class_end(co, RPA_MATCH_NONE);
        rpa_compiler_exp_end(co, RPA_MATCH_NONE);
-       VMTEST_REG(co->cg, 0, 3, "RPA_MATCH_NONE 'abc'");
+       VMTEST_REG(co->cg, 0, 3, "RPA_MATCH_NONE 'ab[abc-d]'");
        VMTEST_STATUS(co->cg, 0, "RPA_MATCH_NONE STATUS");
 
        rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
@@ -42,14 +48,20 @@ void code_rpa_matchexp(rpa_compiler_t *co, rpastat_t *stat)
 
        rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
        rpa_compiler_exp_begin(co);
+       rpa_compiler_class_begin(co);
        rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'a'));
-       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->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_BGRE, 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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, 'c', 'd'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rpa_compiler_class_end(co, RPA_MATCH_NONE);
        rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'b'));
        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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
        rpa_compiler_exp_end(co, RPA_MATCH_OPTIONAL);
-       VMTEST_REG(co->cg, 0, 3, "RPA_MATCH_OPTIONAL 'abc'");
+       VMTEST_REG(co->cg, 0, 3, "RPA_MATCH_OPTIONAL '[abc-d]bc'");
        VMTEST_STATUS(co->cg, 0, "RPA_MATCH_OPTIONAL STATUS");
 
 
@@ -70,12 +82,18 @@ void code_rpa_matchexp(rpa_compiler_t *co, rpastat_t *stat)
        rpa_compiler_exp_begin(co);
        rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'a'));
        rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+       rpa_compiler_class_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'a'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, 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, RPA_COMPILER_CURRENTEXP(co)->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_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, 'c', 'd'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rpa_compiler_class_end(co, RPA_MATCH_NONE);
        rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'c'));
        rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
        rpa_compiler_exp_end(co, RPA_MATCH_MULTIOPT);
-       VMTEST_REG(co->cg, 0, 12, "RPA_MATCH_MULTIOPT 'abc'");
+       VMTEST_REG(co->cg, 0, 12, "RPA_MATCH_MULTIOPT 'a[abc-d]c'");
        VMTEST_STATUS(co->cg, 0, "RPA_MATCH_MULTIOPT STATUS");
 
 
diff --git a/testrpa2/rpacompiler-minusexp.c b/testrpa2/rpacompiler-minusexp.c
new file mode 100644 (file)
index 0000000..c9d72d2
--- /dev/null
@@ -0,0 +1,126 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include "rmem.h"
+#include "rpacompiler.h"
+#include "rpastat.h"
+#include "common.h"
+
+
+
+void code_rpa_matchminusexp(rpa_compiler_t *co, rpastat_t *stat)
+{
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rpa_compiler_exp_begin(co);
+       rpa_compiler_branch_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'd'));
+       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, 'e'));
+       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, 'f'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+       rpa_compiler_branch_end(co, RPA_MATCH_NONE);
+
+       rpa_compiler_branch_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'x'));
+       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, 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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+       rpa_compiler_branch_end(co, RPA_MATCH_NONE);
+
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'a'));
+       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, 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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+       rpa_compiler_exp_end(co, RPA_MATCH_NONE);
+       VMTEST_REG(co->cg, 0, 3, "RPA_MATCH_NONE 'abc - def - xyz'");
+       VMTEST_STATUS(co->cg, 0, "RPA_MATCH_NONE STATUS");
+
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rpa_compiler_exp_begin(co);
+       rpa_compiler_branch_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'd'));
+       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, 'e'));
+       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, 'f'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+       rpa_compiler_branch_end(co, RPA_MATCH_NONE);
+
+       rpa_compiler_branch_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'x'));
+       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, 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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+       rpa_compiler_branch_end(co, RPA_MATCH_NONE);
+
+
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'a'));
+       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, 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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+       rpa_compiler_exp_end(co, RPA_MATCH_MULTIPLE);
+       VMTEST_REG(co->cg, 0, 9, "RPA_MATCH_MULTIPLE 'abc - def - xyz'");
+       VMTEST_STATUS(co->cg, 0, "RPA_MATCH_MULTIPLE STATUS");
+}
+
+
+int main(int argc, char *argv[])
+{
+       rvm_codelabel_t *err;
+       rpa_compiler_t *co;
+       rpastat_t *stat;
+       ruint mainoff;
+       char teststr[] = "abcabcabcdefghiabc";
+
+       co = rpa_compiler_create();
+       stat = rpa_stat_create(4096);
+       rvm_cpu_addswitable(stat->cpu, common_calltable);
+
+       rpa_stat_init(stat, teststr, teststr, teststr+12);
+
+       mainoff = rvm_codegen_addins(co->cg, rvm_asml(RVM_NOP, XX, XX, XX, -1));
+       rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R_TOP, DA, XX, -1));
+       rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, FP, DA, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, SP, DA, XX, 0));
+
+       rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_JUMP, "rpacompiler_mnode_nan", rvm_asm(RVM_MOV, R_MNODE_NAN, DA, XX, 0));
+       rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_JUMP, "rpacompiler_mnode_mul", rvm_asm(RVM_MOV, R_MNODE_MUL, DA, XX, 0));
+       rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_JUMP, "rpacompiler_mnode_opt", rvm_asm(RVM_MOV, R_MNODE_OPT, DA, XX, 0));
+       rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_JUMP, "rpacompiler_mnode_mop", rvm_asm(RVM_MOV, R_MNODE_MOP, DA, XX, 0));
+
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_SHIFT, XX, XX, XX, 0));
+       code_rpa_matchminusexp(co, stat);
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xabc));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_EXT, XX, XX, XX, 0));
+
+       if (rvm_codegen_relocate(co->cg, &err) < 0) {
+               r_printf("Unresolved symbol: %s\n", err->name->str);
+               goto end;
+       }
+
+       rvm_cpu_exec(stat->cpu, rvm_codegen_getcode(co->cg, 0), mainoff);
+
+end:
+       rpa_stat_destroy(stat);
+       rpa_compiler_destroy(co);
+
+
+       r_printf("Max alloc mem: %ld\n", r_debug_get_maxmem());
+       r_printf("Leaked mem: %ld\n", r_debug_get_allocmem());
+       return 0;
+}
diff --git a/testrpa2/rpacompiler-notexp.c b/testrpa2/rpacompiler-notexp.c
new file mode 100644 (file)
index 0000000..589ad0e
--- /dev/null
@@ -0,0 +1,186 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include "rmem.h"
+#include "rpacompiler.h"
+#include "rpastat.h"
+#include "common.h"
+
+
+
+void code_rpa_matchexp(rpa_compiler_t *co, rpastat_t *stat)
+{
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rpa_compiler_notexp_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'a'));
+       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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+       rpa_compiler_class_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'a'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, 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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, 'c', 'd'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rpa_compiler_class_end(co, RPA_MATCH_NONE);
+       rpa_compiler_notexp_end(co, RPA_MATCH_NONE);
+       VMTEST_REG(co->cg, 0, 1, "RPA_MATCH_NONE '^(ab[abc-d])'");
+       VMTEST_STATUS(co->cg, 0, "RPA_MATCH_NONE STATUS");
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rpa_compiler_notexp_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'x'));
+       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, 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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+       rpa_compiler_notexp_end(co, RPA_MATCH_NONE);
+       VMTEST_REG(co->cg, 0, -1, "RPA_MATCH_NONE '^(xyz)'");
+       VMTEST_STATUS(co->cg, RVM_STATUS_N, "RPA_MATCH_NONE STATUS");
+
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rpa_compiler_notexp_begin(co);
+       rpa_compiler_class_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'a'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, 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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, 'c', 'd'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rpa_compiler_class_end(co, RPA_MATCH_NONE);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'b'));
+       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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+       rpa_compiler_notexp_end(co, RPA_MATCH_OPTIONAL);
+       VMTEST_REG(co->cg, 0, 1, "RPA_MATCH_OPTIONAL '^([abc-d]bc)'");
+       VMTEST_STATUS(co->cg, 0, "RPA_MATCH_OPTIONAL STATUS");
+
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rpa_compiler_notexp_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'x'));
+       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, 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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+       rpa_compiler_notexp_end(co, RPA_MATCH_OPTIONAL);
+       VMTEST_REG(co->cg, 0, 0, "RPA_MATCH_OPTIONAL '^(xyz)'");
+       VMTEST_STATUS(co->cg, RVM_STATUS_Z, "RPA_MATCH_OPTIONAL STATUS");
+
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rpa_compiler_notexp_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'a'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+       rpa_compiler_class_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'a'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, 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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, 'c', 'd'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
+       rpa_compiler_class_end(co, RPA_MATCH_NONE);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'c'));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+       rpa_compiler_notexp_end(co, RPA_MATCH_MULTIOPT);
+       VMTEST_REG(co->cg, 0, 12, "RPA_MATCH_MULTIOPT '^(a[abc-d]c)'");
+       VMTEST_STATUS(co->cg, 0, "RPA_MATCH_MULTIOPT STATUS");
+
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rpa_compiler_notexp_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'x'));
+       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, 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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+       rpa_compiler_notexp_end(co, RPA_MATCH_MULTIOPT);
+       VMTEST_REG(co->cg, 0, 0, "RPA_MATCH_MULTIOPT '^(xyz)'");
+       VMTEST_STATUS(co->cg, RVM_STATUS_Z, "RPA_MATCH_MULTIOPT STATUS");
+
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rpa_compiler_notexp_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'a'));
+       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, 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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+       rpa_compiler_notexp_end(co, RPA_MATCH_MULTIPLE);
+       VMTEST_REG(co->cg, 0, 12, "RPA_MATCH_MULTIPLE '^(abc)'");
+       VMTEST_STATUS(co->cg, 0, "RPA_MATCH_MULTIPLE STATUS");
+
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rpa_compiler_notexp_begin(co);
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR_NAN, DA, XX, XX, 'x'));
+       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, 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, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+       rpa_compiler_notexp_end(co, RPA_MATCH_MULTIPLE);
+       VMTEST_REG(co->cg, 0, -1, "RPA_MATCH_MULTIPLE '^(xyz)'");
+       VMTEST_STATUS(co->cg, RVM_STATUS_N, "RPA_MATCH_MULTIPLE STATUS");
+
+
+}
+
+
+int main(int argc, char *argv[])
+{
+       rvm_codelabel_t *err;
+       rpa_compiler_t *co;
+       rpastat_t *stat;
+       ruint mainoff;
+       char teststr[] = "xyzxyzxyzxyz";
+
+       co = rpa_compiler_create();
+       stat = rpa_stat_create(4096);
+       rvm_cpu_addswitable(stat->cpu, common_calltable);
+
+       rpa_stat_init(stat, teststr, teststr, teststr+12);
+
+       mainoff = rvm_codegen_addins(co->cg, rvm_asml(RVM_NOP, XX, XX, XX, -1));
+       rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R_TOP, DA, XX, -1));
+       rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, FP, DA, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, SP, DA, XX, 0));
+
+       rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_JUMP, "rpacompiler_mnode_nan", rvm_asm(RVM_MOV, R_MNODE_NAN, DA, XX, 0));
+       rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_JUMP, "rpacompiler_mnode_mul", rvm_asm(RVM_MOV, R_MNODE_MUL, DA, XX, 0));
+       rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_JUMP, "rpacompiler_mnode_opt", rvm_asm(RVM_MOV, R_MNODE_OPT, DA, XX, 0));
+       rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_JUMP, "rpacompiler_mnode_mop", rvm_asm(RVM_MOV, R_MNODE_MOP, DA, XX, 0));
+
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_SHIFT, XX, XX, XX, 0));
+       code_rpa_matchexp(co, stat);
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xabc));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_EXT, XX, XX, XX, 0));
+
+       if (rvm_codegen_relocate(co->cg, &err) < 0) {
+               r_printf("Unresolved symbol: %s\n", err->name->str);
+               goto end;
+       }
+
+       rvm_cpu_exec(stat->cpu, rvm_codegen_getcode(co->cg, 0), mainoff);
+
+end:
+       rpa_stat_destroy(stat);
+       rpa_compiler_destroy(co);
+
+
+       r_printf("Max alloc mem: %ld\n", r_debug_get_maxmem());
+       r_printf("Leaked mem: %ld\n", r_debug_get_allocmem());
+       return 0;
+}
diff --git a/testrpa2/rpavm-matchrng.c b/testrpa2/rpavm-matchrng.c
new file mode 100644 (file)
index 0000000..ed2dc5f
--- /dev/null
@@ -0,0 +1,96 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include "rmem.h"
+#include "rpacompiler.h"
+#include "rpastat.h"
+#include "common.h"
+
+
+void code_rpa_matchrng(rpa_compiler_t *co, rpastat_t *stat)
+{
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, 'a', 'b'));
+       VMTEST_REG(co->cg, 0, 1, "RPA_MATCHRNG_NAN 'a-b'");
+       VMTEST_STATUS(co->cg, 0, "RPA_MATCHRNG_NAN STATUS");
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_NAN, DA, XX, XX, 'c', 'd'));
+       VMTEST_REG(co->cg, 0, -1, "RPA_MATCHRNG_NAN 'c-d'");
+       VMTEST_STATUS(co->cg, RVM_STATUS_N, "RPA_MATCHRNG_NAN STATUS");
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_OPT, DA, XX, XX, 'a', 'b'));
+       VMTEST_REG(co->cg, 0, 1, "RPA_MATCHRNG_OPT 'a-b'");
+       VMTEST_STATUS(co->cg, 0, "RPA_MATCHRNG_OPT STATUS");
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_OPT, DA, XX, XX, 'c', 'd'));
+       VMTEST_REG(co->cg, 0, 0, "RPA_MATCHRNG_OPT 'c-d'");
+       VMTEST_STATUS(co->cg, RVM_STATUS_Z, "RPA_MATCHRNG_OPT STATUS");
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_MOP, DA, XX, XX, 'a', 'b'));
+       VMTEST_REG(co->cg, 0, 3, "RPA_MATCHRNG_MOP 'a-b'");
+       VMTEST_STATUS(co->cg, 0, "RPA_MATCHRNG_MOP STATUS");
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_MOP, DA, XX, XX, 'c', 'd'));
+       VMTEST_REG(co->cg, 0, 0, "RPA_MATCHRNG_MOP 'c-d'");
+       VMTEST_STATUS(co->cg, RVM_STATUS_Z, "RPA_MATCHRNG_MOP STATUS");
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_MUL, DA, XX, XX, 'a', 'b'));
+       VMTEST_REG(co->cg, 0, 3, "RPA_MATCHRNG_MUL 'a-b'");
+       VMTEST_STATUS(co->cg, 0, "RPA_MATCHRNG_MUL STATUS");
+
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm2(RPA_MATCHRNG_MUL, DA, XX, XX, 'c', 'd'));
+       VMTEST_REG(co->cg, 0, -1, "RPA_MATCHRNG_MUL 'c-d'");
+       VMTEST_STATUS(co->cg, RVM_STATUS_N, "RPA_MATCHRNG_MUL STATUS");
+}
+
+
+int main(int argc, char *argv[])
+{
+       rpa_compiler_t *co;
+       rpastat_t *stat;
+       ruint mainoff;
+       char teststr[] = "abaaa";
+
+       co = rpa_compiler_create();
+       stat = rpa_stat_create(4096);
+       rvm_cpu_addswitable(stat->cpu, common_calltable);
+
+       rpa_stat_init(stat, teststr, teststr, teststr+3);
+
+       mainoff = rvm_codegen_addins(co->cg, rvm_asml(RVM_NOP, XX, XX, XX, -1));
+       rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R_TOP, DA, XX, -1));
+       rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, FP, DA, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, SP, DA, XX, 0));
+
+       rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_JUMP, "rpacompiler_mnode_nan", rvm_asm(RVM_MOV, R_MNODE_NAN, DA, XX, 0));
+       rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_JUMP, "rpacompiler_mnode_mul", rvm_asm(RVM_MOV, R_MNODE_MUL, DA, XX, 0));
+       rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_JUMP, "rpacompiler_mnode_opt", rvm_asm(RVM_MOV, R_MNODE_OPT, DA, XX, 0));
+       rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_JUMP, "rpacompiler_mnode_mop", rvm_asm(RVM_MOV, R_MNODE_MOP, DA, XX, 0));
+
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_SHIFT, XX, XX, XX, 0));
+       code_rpa_matchrng(co, stat);
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xabc));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_EXT, XX, XX, XX, 0));
+
+       rvm_cpu_exec(stat->cpu, rvm_codegen_getcode(co->cg, 0), mainoff);
+
+       rpa_stat_destroy(stat);
+       rpa_compiler_destroy(co);
+
+
+       r_printf("Max alloc mem: %ld\n", r_debug_get_maxmem());
+       r_printf("Leaked mem: %ld\n", r_debug_get_allocmem());
+       return 0;
+}
index b3749ff..0b6dd8c 100644 (file)
@@ -84,6 +84,7 @@ void code_rpa_matchmnode(rpa_compiler_t *co, rpastat_t *stat)
        VMTEST_REG(co->cg, 0, -1, "RPA_MNODE_NAN 'xyz'");
        VMTEST_STATUS(co->cg, RVM_STATUS_N, "RPA_MNODE_NAN STATUS");
 
+/*
        rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, DA, XX, 0));
        rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_JUMP, "rpa_matchabc", rvm_asm(RPA_BXLWHT, R_MNODE_OPT, DA, XX, 0));
        VMTEST_REG(co->cg, 0, 3, "RPA_MNODE_OPT 'abc'");
@@ -113,7 +114,7 @@ void code_rpa_matchmnode(rpa_compiler_t *co, rpastat_t *stat)
        rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_JUMP, "rpa_matchxyz", rvm_asm(RPA_BXLWHT, R_MNODE_MOP, DA, XX, 0));
        VMTEST_REG(co->cg, 0, 0, "RPA_MNODE_MOP 'xyz'");
        VMTEST_STATUS(co->cg, RVM_STATUS_Z, "RPA_MNODE_MOP STATUS");
-
+*/
 
 }
 
index e1d990e..ad7b4b1 100644 (file)
@@ -296,17 +296,6 @@ static void rpa_matchchr_mop(rvmcpu_t *cpu, rvm_asmins_t *ins)
 }
 
 
-
-static void rpa_matchrng(rvmcpu_t *cpu, rvm_asmins_t *ins)
-{
-       rpastat_t *stat = (rpastat_t *)cpu->userdata1;
-       rlong tp = RVM_CPUREG_GETL(cpu, R_TOP);
-       rpair_t op1 = RVM_CPUREG_GETPAIR(cpu, ins->op1);
-
-       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, (!stat->instack[RVM_CPUREG_GETL(cpu, R_TOP)].eof && stat->instack[tp].wc >= op1.p1 && stat->instack[tp].wc <= op1.p2) ? 1 : 0);
-}
-
-
 static void rpa_emitstart(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
        rpastat_t *stat = (rpastat_t *)cpu->userdata1;