RPA Toolkit
work on loopy rules compiler - 2 (added rpa_compiler_inlinerule_begin/rpa_compiler_in...
authorMartin Stoilov <martin@rpasearch.com>
Fri, 15 Apr 2011 05:58:25 +0000 (22:58 -0700)
committerMartin Stoilov <martin@rpasearch.com>
Fri, 15 Apr 2011 05:58:25 +0000 (22:58 -0700)
datapatterns/directloop.rpa
datapatterns/indirectloop.rpa
rpa2/rpacompiler.c
rpa2/rpacompiler.h
rpa2/rpadbex.c
rpa2/rpaparser.c
rpa2/rpavm.c
rvm/rvmcpu.c
rvm/rvmcpu.h

index 2f3f050..1bf0a28 100644 (file)
@@ -3,5 +3,5 @@
 lb     ::= '('
 rb     ::= ')'
 term    ::= [0-9]+ | '(' <:exp:> ')'
-exp     ::= <:exp:> '+' <:term:> | <:term:>
+exp     ::= <:exp:> '+' <:term:> | <:exp:> '-' <:term:> | <:exp:> '*' <:term:> | <:exp:> '/' <:term:> | <:term:>
 
index 2f92876..efe9333 100644 (file)
@@ -1,8 +1,8 @@
 #!emitall
 sign   ::= '+'
 term   ::= [0-9]+ | '(' <:exp:> ')'
-expop  ::= (<:exp:> <:sign:> <:term:>) | <term>
-exp    ::= ((<:expop:>))
+opdiv  ::= <:exp:> '/' <:term:>
+expop  ::= (<:exp:> <:sign:> <:term:>) | (<:exp:> '*' <:term:>) | <:exp:> '-' <:term:> | <:opdiv:>
+exp    ::= ((<:expop:>)) | <term>
 
-ifexp  ::= 'if' ' '* <exp>
 
index ae57ead..7126c19 100644 (file)
@@ -408,20 +408,10 @@ rint rpa_compiler_loop_begin(rpa_compiler_t *co, const rchar *name, ruint namesi
        exp.againidx = rpa_codegen_invalid_add_numlabel_s(co->cg, "__again", exp.start);
        exp.dataidx = rpa_compiler_addblob(co, exp.start, ruleuid, flags, name, namesize);
 
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_RID, DA, XX, exp.start));
-       rvm_codegen_addins(co->cg, rvm_asm(RPA_LOOPDETECT, R_RID, R_TOP, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R0, DA, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_BLES, DA, XX, XX, 6));   /* No loop detected, go ahead and execute the rule */
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_BGRE, DA, XX, XX, 3));   /* There is a loop, add its size to R_TOP and return */
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOVS, R0, DA, XX, -1));  /* There is a loop but its size is 0, return -1 */
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_ADD, R_TOP, R_TOP, R0, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_CLR, R_LOO, XX, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_CLR, R_LPP, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_CLR, R3, XX, XX, 0));
        exp.loopidx = rpa_codegen_add_numlabel_s(co->cg, "__loop", exp.start);
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(R_REC)|BIT(R_RID)|BIT(R_LPP)|BIT(R_LOO)|BIT(R_TOP)|BIT(FP)|BIT(LR)));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, FP, SP, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(R_REC)|BIT(R_LOO)|BIT(R_TOP)|BIT(LR)));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_LOO, R3, XX, 0));
        rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BLOB, exp.dataidx, rvm_asm(RPA_EMITSTART, DA, R_TOP, XX, 0));
 
        r_array_add(co->expressions, &exp);
@@ -439,25 +429,15 @@ rint rpa_compiler_loop_end(rpa_compiler_t *co)
 {
        rpa_ruledef_t exp = r_array_pop(co->expressions, rpa_ruledef_t);
 
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_SUB, R2, FP, DA, 3));                                                                                            //          |
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(R1)|BIT(R_RID)|BIT(R_LPP)|BIT(R_LOO)|BIT(R_OTP)|BIT(FP)|BIT(LR)));
-       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BLOB, exp.dataidx, rvm_asm(RPA_PRNINFO, DA, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R3, R_LOO, XX, 0));         // Save LOO to R3 before restoring the old one
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(R1)|BIT(R_LOO)|BIT(R_OTP)|BIT(LR)));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_SUBS, R0, R_TOP, R_OTP, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_BEQ, DA, XX, XX, 15));   // R_TOP is the same    --------------------------------
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, exp.failidx, rvm_asm(RVM_BEQ, DA, XX, XX, 0));  // ------------- R_TOP is the same
        rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BLOB, exp.dataidx, rvm_asm(RPA_EMITEND, DA, R_OTP, R0, 0));     //          |
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R_LOO, DA, XX, 0));                                                                                         //          |
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_BEQ, DA, XX, XX, 11));                                                                                           //          |
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_LOO, R0, XX, 0));                                                                                         //          |
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R3, R0, XX, 0));                                                                                            //          |
        rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_TOP, R_OTP, XX, 0));                                                                                      //          |
        rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, exp.loopidx, rvm_asm(RVM_B, DA, XX, XX, 0));            //          |
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));                                                                                            //          |
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));                                                                                            //          |
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));                                                                                            //          |
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));                                                                                            //          |
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));                                                                                            //          |
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));                                                                                            //          |
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));                                                                                            //          |
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));                                                         //          |
+       rvm_codegen_redefinelabel(co->cg, exp.failidx);                                                                                 //          |
        rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_REC, R1, XX, 0));                 //        <-------------------------------------
        rvm_codegen_addins(co->cg, rvm_asm(RVM_MOVS, R0, DA, XX, -1));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
@@ -466,16 +446,14 @@ rint rpa_compiler_loop_end(rpa_compiler_t *co)
         *  END FAILED:
         */
        rvm_codegen_redefinelabel(co->cg, exp.endidx);
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(R_REC)|BIT(R_RID)|BIT(R_LPP)|BIT(R_LOO)|BIT(R_TOP)|BIT(FP)|BIT(LR)));
-       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BLOB, exp.dataidx, rvm_asm(RPA_PRNINFO, DA, XX, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOVS, R0, R_LOO, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R3, R_LOO, XX, 0));         // Save LOO to R3 before restoring the old one
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(R_REC)|BIT(R_LOO)|BIT(R_TOP)|BIT(LR)));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOVS, R0, R3, XX, 0));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_BGRE, DA, XX, XX, 3));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_MOVS, R0, DA, XX, -1));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_ADD, R_TOP, R_TOP, R_LOO, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_ADD, R_TOP, R_TOP, R3, 0));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
-
-
        return 0;
 }
 
@@ -535,6 +513,65 @@ rint rpa_compiler_rule_end(rpa_compiler_t *co)
 }
 
 
+rint rpa_compiler_inlinerule_begin(rpa_compiler_t *co, const rchar *name, ruint namesize, ruint flags)
+{
+       rpa_ruledef_t exp;
+       rlong ruleuid = RPA_RECORD_INVALID_UID;
+       rulong ruleflags = 0;
+       rpa_rulepref_t *rulepref = rpa_compiler_rulepref_lookup(co, name, namesize);
+
+       if (rulepref) {
+               ruleflags = rulepref->flags;
+               ruleuid = rulepref->ruleuid;
+       }
+
+       r_memset(&exp, 0, sizeof(exp));
+       exp.branch = rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, 0));
+       exp.start = rvm_codegen_getcodesize(co->cg);
+       exp.startidx = rvm_codegen_addlabel(co->cg, name, namesize);
+       exp.endidx = rpa_codegen_invalid_add_numlabel_s(co->cg, "__end", exp.start);
+       exp.dataidx = rpa_compiler_addblob(co, exp.start, ruleuid, ruleflags, name, namesize);
+
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_CHECKCACHE, DA, R_TOP, XX, exp.start));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_BXGRE, LR, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(R_REC)|BIT(R_TOP)|BIT(LR)));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BLOB, exp.dataidx, rvm_asm(RPA_EMITSTART, DA, R_TOP, XX, 0));
+       r_array_add(co->expressions, &exp);
+       return 0;
+}
+
+
+rint rpa_compiler_inlinerule_begin_s(rpa_compiler_t *co, const rchar *name, ruint flags)
+{
+       return rpa_compiler_inlinerule_begin(co, name, r_strlen(name), flags);
+}
+
+
+rint rpa_compiler_inlinerule_end(rpa_compiler_t *co)
+{
+       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(R2)|BIT(LR)));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_SUBS, R0, R_TOP, R2, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_BEQ, DA, XX, XX, 5));
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BLOB, exp.dataidx, rvm_asm(RPA_EMITEND, DA, R2, R0, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RPA_GETNEXTREC, R2, R1, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asml(RPA_SETCACHE, DA, R0, R2, exp.start));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_REC, R1, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOVS, 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(R_REC)|BIT(R_TOP)|BIT(LR)));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOVS, R0, DA, XX, -1));
+       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));
+       rpa_compiler_index_reference(co, exp.startidx, (exp.flags & RPA_MATCH_MASK));
+
+       return 0;
+}
+
+
 rint rpa_compiler_exp_begin(rpa_compiler_t *co, ruint flags)
 {
        rpa_ruledef_t exp;
@@ -643,8 +680,6 @@ rint rpa_compiler_nonloopybranch_begin(rpa_compiler_t *co, ruint flags)
        exp.start = rvm_codegen_getcodesize(co->cg);
        exp.startidx = rpa_codegen_add_numlabel_s(co->cg, "__begin", exp.start);
        exp.endidx = rpa_codegen_invalid_add_numlabel_s(co->cg, "__end", exp.start);
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_LDS, R_LOO, FP, DA, -3));
-//     rvm_codegen_addins(co->cg, rvm_asm(RPA_CURLOOP, R_LOO, XX, XX, 0));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(R_REC)|BIT(R_TOP)|BIT(LR)));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R_LOO, DA, XX, 0));
        rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, exp.endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));
@@ -660,7 +695,7 @@ rint rpa_compiler_nonloopybranch_end(rpa_compiler_t *co)
 
        rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(R0)|BIT(R1)|BIT(LR)));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_SUBS, R0, R_TOP, R1, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, R_LOO, XX, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R_LOO, R0, 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_REC)|BIT(R_TOP)|BIT(LR)));
index 7ab8928..b024ef4 100644 (file)
@@ -64,6 +64,10 @@ rint rpa_compiler_rule_begin(rpa_compiler_t *co, const rchar *name, ruint namesi
 rint rpa_compiler_rule_begin_s(rpa_compiler_t *co, const rchar *name);
 rint rpa_compiler_rule_end(rpa_compiler_t *co);
 
+rint rpa_compiler_inlinerule_begin(rpa_compiler_t *co, const rchar *name, ruint namesize, ruint flags);
+rint rpa_compiler_inlinerule_begin_s(rpa_compiler_t *co, const rchar *name, ruint flags);
+rint rpa_compiler_inlinerule_end(rpa_compiler_t *co);
+
 rint rpa_compiler_exp_begin(rpa_compiler_t *co, ruint flags);
 rint rpa_compiler_exp_end(rpa_compiler_t *co);
 
index 4c581c7..19930af 100644 (file)
@@ -30,11 +30,15 @@ struct rpadbex_s {
        rpa_dbex_recordhandler *handlers;
        ruint error;
        rvm_codelabel_t *labelerr;
+       rlong crule;
 };
 
 static rparecord_t *rpa_dbex_rulerecord(rpadbex_t *dbex, rparule_t rid);
 static rparecord_t *rpa_dbex_record(rpadbex_t *dbex, rlong rec);
 static rint rpa_dbex_rulename(rpadbex_t *dbex, rlong rec, const rchar **name, rsize_t *namesize);
+static rint rpa_parseinfo_loopdetect(rpadbex_t *dbex, rlong parent, rlong loopto);
+static rlong rpa_dbex_play_recordhandler(rpadbex_t *dbex, rlong rec);
+static rlong rpa_dbex_play_recordhandlers(rpadbex_t *dbex, rlong rec, rlong nrecs);
 
 
 static rlong rpa_dbex_getmatchchr(rulong matchtype)
@@ -168,25 +172,26 @@ static rint rpa_dbex_rh_namedrule(rpadbex_t *dbex, rlong rec)
 
                        return -1;
                }
-
+               dbex->crule = rec;
                rvm_codegen_addins(dbex->co->cg, rvm_asm(RPA_EMITHEAD, XX, XX, XX, 0));
                rvm_codegen_addins(dbex->co->cg, rvm_asm(RPA_SHIFT, XX, XX, XX, 0));
                rvm_codegen_addins(dbex->co->cg, rvm_asm(RVM_BL, DA, XX, XX, 3));
                rvm_codegen_addins(dbex->co->cg, rvm_asm(RPA_EMITTAIL, XX, XX, XX, 0));
                rvm_codegen_addins(dbex->co->cg, rvm_asm(RVM_EXT, XX, XX, XX, 0));
 
-               if (1 || (prec->usertype & RPA_LOOP_PATH)) {
+               if ((prec->usertype & RPA_LOOP_PATH)) {
                        rpa_compiler_loop_begin(dbex->co, name, namesize);
                } else {
                        rpa_compiler_rule_begin(dbex->co, name, namesize);
                }
 
        } else if (prec->type & RPA_RECORD_END) {
-               if (1 || (prec->usertype & RPA_LOOP_PATH)) {
+               if ((prec->usertype & RPA_LOOP_PATH)) {
                        rpa_compiler_loop_end(dbex->co);
                } else {
                        rpa_compiler_rule_end(dbex->co);
                }
+               dbex->crule = -1;
 
        }
        return 0;
@@ -501,6 +506,7 @@ static rint rpa_dbex_rh_aref(rpadbex_t *dbex, rlong rec)
 {
        const rchar *name = NULL;
        rsize_t namesize;
+       rpa_ruleinfo_t *info;
        rparecord_t *prec = (rparecord_t *) r_array_slot(dbex->records, rec);
 
        if (prec->type & RPA_RECORD_START) {
@@ -509,11 +515,42 @@ static rint rpa_dbex_rh_aref(rpadbex_t *dbex, rlong rec)
                        return -1;
                }
 
-               rpa_compiler_reference(dbex->co, name, namesize, (prec->usertype & RPA_MATCH_MASK));
+               if (rpa_parseinfo_loopdetect(dbex, rec, dbex->crule)) {
+                       info = (rpa_ruleinfo_t *) r_harray_get(dbex->rules, rpa_dbex_lookup(dbex, name, namesize));
+                       if (info->startrec == dbex->crule) {
+                               rpa_compiler_exp_begin(dbex->co, (prec->usertype & RPA_MATCH_MASK));
+                               rvm_codegen_addins(dbex->co->cg, rvm_asm(RVM_CMP, R_LOO, DA, XX, 0));
+                               rvm_codegen_addins(dbex->co->cg, rvm_asm(RVM_BGRE, DA, XX, XX, 3));
+                               rvm_codegen_addins(dbex->co->cg, rvm_asm(RVM_MOVS, R0, DA, XX, -1));
+                               rvm_codegen_index_addrelocins(dbex->co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(dbex->co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+                               rvm_codegen_addins(dbex->co->cg, rvm_asm(RVM_ADD, R_TOP, R_TOP, R_LOO, 0));
+                               rvm_codegen_addins(dbex->co->cg, rvm_asm(RVM_MOVS, R0, R_LOO, XX, 0));
+                               rvm_codegen_index_addrelocins(dbex->co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(dbex->co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
+                               rpa_compiler_exp_end(dbex->co);
+                       } else {
+                               rpa_compiler_inlinerule_begin(dbex->co, name, namesize, (prec->usertype & RPA_MATCH_MASK));
+//                             r_printf("%s: currule: %ld, inlining: %ld, %ld\n", __FUNCTION__, dbex->crule, info->startrec, info->sizerecs);
+//                             rpa_dbex_play_recordhandlers(dbex, info->startrec + 3, info->sizerecs - 4);
+                       }
+               } else {
+                       rpa_compiler_reference(dbex->co, name, namesize, (prec->usertype & RPA_MATCH_MASK));
+               }
                rvm_codegen_index_addrelocins(dbex->co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(dbex->co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
 
        } else if (prec->type & RPA_RECORD_END) {
+               if (rpa_parseinfo_loopdetect(dbex, rpa_recordtree_get(dbex->records, rec, RPA_RECORD_START), dbex->crule)) {
+                       if (rpa_dbex_rulename(dbex, rec, &name, &namesize) < 0) {
+
+                               return -1;
+                       }
+
+                       info = (rpa_ruleinfo_t *) r_harray_get(dbex->rules, rpa_dbex_lookup(dbex, name, namesize));
+                       if (info->startrec == dbex->crule) {
 
+                       } else {
+                               rpa_compiler_inlinerule_end(dbex->co);
+                       }
+               }
        }
        return 0;
 }
@@ -574,7 +611,7 @@ void rpa_dbex_destroy(rpadbex_t *dbex)
 }
 
 
-static rint rpa_parseinfo_loopdetect(rpadbex_t *dbex, rlong parent, rlong loopto, rint inderction)
+static rint rpa_parseinfo_loopdetect_do(rpadbex_t *dbex, rlong parent, rlong loopto, rint inderction)
 {
        rsize_t namesiz;
        const rchar *name;
@@ -602,18 +639,23 @@ static rint rpa_parseinfo_loopdetect(rpadbex_t *dbex, rlong parent, rlong loopto
                        continue;
                if (prec->ruleuid == RPA_PRODUCTION_AREF || prec->ruleuid == RPA_PRODUCTION_CREF) {
                        rpa_ruleinfo_t *info;
-                       rstr_t *refname;
+                       if ((inderction > 0 || i != parent) && i == loopto) {
+                               /*
+                                * We found what we are looking for
+                                */
+                               ret = 1;
+                               break;
+                       }
                        if (rpa_dbex_rulename(dbex, i, &name, &namesiz) < 0)
                                R_ASSERT(0);
                        info = (rpa_ruleinfo_t *) r_harray_get(dbex->rules, rpa_dbex_lookup(dbex, name, namesiz));
                        if (!info)
                                continue;
-                       refname = r_array_index(dbex->rules->names, rpa_dbex_lookup(dbex, name, namesiz), rstr_t*);
-
-                       ret |= rpa_parseinfo_loopdetect(dbex, info->startrec, loopto, inderction + 1);
-//                     r_printf("              %s : lret = %ld, rec = %ld (%ld, %ld), refname = %s, loopto: %ld, startrec = %ld\n", __FUNCTION__, lret, i, loopto, loopto_end, refname->str, loopto, info->startrec);
+                       if ((ret = rpa_parseinfo_loopdetect_do(dbex, info->startrec, loopto, inderction + 1)) > 0)
+                               break;
                } else {
-                       ret |= rpa_parseinfo_loopdetect(dbex, i, loopto, inderction + 1);
+                       if ((ret = rpa_parseinfo_loopdetect_do(dbex, i, loopto, inderction + 1)) > 0)
+                               break;
                }
 
                if ((prec->usertype & RPA_MATCH_OPTIONAL) == 0 && (prec->ruleuid == RPA_PRODUCTION_CREF || prec->ruleuid == RPA_PRODUCTION_AREF ||
@@ -627,78 +669,34 @@ static rint rpa_parseinfo_loopdetect(rpadbex_t *dbex, rlong parent, rlong loopto
 }
 
 
-static void rpa_parseinfo_marklooppath(rpadbex_t *dbex, rlong parent)
+static rint rpa_parseinfo_loopdetect(rpadbex_t *dbex, rlong parent, rlong loopto)
 {
-       rlong i;
-
-       if (rpa_parseinfo_loopdetect(dbex, parent, parent, 0) > 0) {
-               rpa_record_setusertype(dbex->records, parent, RPA_LOOP_PATH, RVALSET_OR);
-               for (i = rpa_recordtree_firstchild(dbex->records, parent, RPA_RECORD_START); i >= 0; i = rpa_recordtree_next(dbex->records, i, RPA_RECORD_START)) {
-                       rpa_parseinfo_marklooppath(dbex, i);
-               }
+       if (parent != loopto) {
+               /*
+                * Make sure we are dealing with a loop first
+                */
+//             if (!rpa_parseinfo_loopdetect_do(dbex, parent, parent, 0))
+//                     return 0;
+//             if (!rpa_parseinfo_loopdetect_do(dbex, loopto, loopto, 0))
+//                     return 0;
+               if (!rpa_parseinfo_loopdetect_do(dbex, loopto, parent, 0))
+                       return 0;
        }
-}
-
 
+       return (rpa_parseinfo_loopdetect_do(dbex, parent, loopto, 0)) ? 1 : 0;
+}
 
 
-static rint rpa_parseinfo_checkforloop(rpadbex_t *dbex, rlong parent, rlong loopto, rint inderction)
+static void rpa_parseinfo_marklooppath(rpadbex_t *dbex, rlong parent)
 {
-       rsize_t namesiz;
-       const rchar *name;
        rlong i;
-       rint lret, ret = 0;
-       rlong parent_end = rpa_recordtree_get(dbex->records, parent, RPA_RECORD_END);
-       rlong loopto_end = rpa_recordtree_get(dbex->records, loopto, RPA_RECORD_END);
-
-       if (parent == loopto && inderction > 0)
-               return 1;
-
-       for (i = 0; i < r_array_length(dbex->recstack); i++) {
-               if (parent == r_array_index(dbex->recstack, i, rlong))
-                       return 0;
-       }
-
-       r_array_add(dbex->recstack, &parent);
-
-       for (i = rpa_recordtree_firstchild(dbex->records, parent, RPA_RECORD_START); i >= 0; i = rpa_recordtree_next(dbex->records, i, RPA_RECORD_START)) {
-               rparecord_t *prec = (rparecord_t *)r_array_slot(dbex->records, i);
-               if (prec->ruleuid == RPA_PRODUCTION_RULENAME)
-                       continue;
-               if (prec->ruleuid == RPA_PRODUCTION_AREF || prec->ruleuid == RPA_PRODUCTION_CREF) {
-                       rpa_ruleinfo_t *info;
-                       rstr_t *refname;
-                       if (rpa_dbex_rulename(dbex, i, &name, &namesiz) < 0)
-                               R_ASSERT(0);
-                       info = (rpa_ruleinfo_t *) r_harray_get(dbex->rules, rpa_dbex_lookup(dbex, name, namesiz));
-                       if (!info)
-                               continue;
-                       refname = r_array_index(dbex->rules->names, rpa_dbex_lookup(dbex, name, namesiz), rstr_t*);
-
-                       lret = rpa_parseinfo_checkforloop(dbex, info->startrec, loopto, inderction + 1);
-//                     r_printf("              %s : lret = %ld, rec = %ld (%ld, %ld), refname = %s, loopto: %ld, startrec = %ld\n", __FUNCTION__, lret, i, loopto, loopto_end, refname->str, loopto, info->startrec);
-
-                       if (i >= loopto && i <= loopto_end && lret) {
-                               rpa_record_setusertype(dbex->records, i, RPA_LOOP_PATH, RVALSET_OR);
-                       }
-                       ret |= lret;
-               } else {
-                       lret = rpa_parseinfo_checkforloop(dbex, i, loopto, inderction + 1);
-                       if (i >= loopto && i <= loopto_end && lret) {
-                               rpa_record_setusertype(dbex->records, i, RPA_LOOP_PATH, RVALSET_OR);
-                       }
-                       ret |= lret;
 
+       if (rpa_parseinfo_loopdetect(dbex, parent, parent) > 0) {
+               rpa_record_setusertype(dbex->records, parent, RPA_LOOP_PATH, RVALSET_OR);
+               for (i = rpa_recordtree_firstchild(dbex->records, parent, RPA_RECORD_START); i >= 0; i = rpa_recordtree_next(dbex->records, i, RPA_RECORD_START)) {
+                       rpa_parseinfo_marklooppath(dbex, i);
                }
-
-               if ((prec->usertype & RPA_MATCH_OPTIONAL) == 0 && (prec->ruleuid == RPA_PRODUCTION_CREF || prec->ruleuid == RPA_PRODUCTION_AREF ||
-                               prec->ruleuid == RPA_PRODUCTION_CHAR || prec->ruleuid == RPA_PRODUCTION_CLS || prec->ruleuid == RPA_PRODUCTION_SPECIALCHAR))
-                       break;
-
        }
-
-       r_array_removelast(dbex->recstack);
-       return ret;
 }
 
 
@@ -708,7 +706,7 @@ static rint rpa_parseinfo_rule_checkforloop(rpadbex_t *dbex, const char *name, r
 
        if (!info)
                return 0;
-       return rpa_parseinfo_checkforloop(dbex, info->startrec, loopto, 0);
+       return rpa_parseinfo_loopdetect(dbex, info->startrec, loopto);
 }
 
 
@@ -880,7 +878,7 @@ static rparecord_t *rpa_dbex_rulerecord(rpadbex_t *dbex, rparule_t rid)
 
 static rint rpa_dbex_rulename(rpadbex_t *dbex, rlong rec, const rchar **name, rsize_t *namesize)
 {
-       rparecord_t *pnamerec = rpa_dbex_record(dbex, rpa_recordtree_firstchild(dbex->records, rec, RPA_RECORD_END));
+       rparecord_t *pnamerec = rpa_dbex_record(dbex, rpa_recordtree_firstchild(dbex->records, rpa_recordtree_get(dbex->records, rec, RPA_RECORD_START), RPA_RECORD_END));
        if (!pnamerec || !(pnamerec->ruleuid & RPA_PRODUCTION_RULENAME))
                return -1;
        *name = pnamerec->input;
index c9d8d64..d723ced 100644 (file)
@@ -1266,10 +1266,10 @@ static void rpa_production_minexp(rpa_parser_t *pa)
        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_compiler_nonloopybranch_begin(co, RPA_MATCH_NONE);
+       rpa_compiler_branch_begin(co, RPA_MATCH_NONE);
        rpa_compiler_reference_nan_s(co, "exp");
        rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
-       rpa_compiler_nonloopybranch_end(co);
+       rpa_compiler_branch_end(co);
        rpa_compiler_altexp_end(co);
 
        rpa_compiler_rule_end(co);
@@ -1333,10 +1333,10 @@ static void rpa_production_orexp(rpa_parser_t *pa)
        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_compiler_nonloopybranch_begin(co, RPA_MATCH_NONE);
+       rpa_compiler_branch_begin(co, RPA_MATCH_NONE);
        rpa_compiler_reference_nan_s(co, "minexp");
        rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BLES, DA, XX, XX, 0));
-       rpa_compiler_nonloopybranch_end(co);
+       rpa_compiler_branch_end(co);
        rpa_compiler_altexp_end(co);
 
        rpa_compiler_rule_end(co);
index 98e9d1b..da15055 100644 (file)
@@ -334,7 +334,8 @@ static void rpavm_swi_prninfo(rvmcpu_t *cpu, rvm_asmins_t *ins)
 
        if (!(ruledata->flags & RPA_RFLAG_EMITRECORD))
                return;
-       r_printf("%s: R_TOP = %ld, R0 = %ld, R_LOO = %ld, R_LPP = %ld\n", name.str, RVM_CPUREG_GETL(cpu, R_TOP), RVM_CPUREG_GETL(cpu, R0), RVM_CPUREG_GETL(cpu, R_LOO), RVM_CPUREG_GETL(cpu, R_LPP));
+       r_printf("%s: ", name.str);
+       rvm_cpu_dumpregs(cpu, ins);
 }
 
 
index 0372542..f6825c8 100644 (file)
@@ -1222,7 +1222,7 @@ void rvm_asm_dump(rvm_asmins_t *pi, ruint count)
 }
 
 
-static void rvm_cpu_dumpregs(rvm_asmins_t *pi, rvmcpu_t *vm)
+void rvm_cpu_dumpregs(rvmcpu_t *vm, rvm_asmins_t *pi)
 {
     int ret;
        char buffer[1024];
@@ -2039,7 +2039,7 @@ rint rvm_cpu_exec_debug(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off)
                }
                ops[pi->opcode](cpu, pi);
                r_printf("%7ld :", ++line);
-               rvm_cpu_dumpregs(pi, cpu);
+               rvm_cpu_dumpregs(cpu, pi);
 skipexec:
                RVM_REG_INCIP(regpc, 1);
        } while (!cpu->abort);
index 75c68fd..5b67000 100644 (file)
@@ -344,6 +344,7 @@ rint rvm_cpu_addswitable(rvmcpu_t * cpu, const rchar *tabname, rvm_switable_t *s
 rvmreg_t *rvm_cpu_alloc_global(rvmcpu_t *cpu);
 int rvm_cpu_setreg(rvmcpu_t *cpu, rword regnum, const rvmreg_t *src);
 rvmreg_t *rvm_cpu_getreg(rvmcpu_t *cpu, rword regnum);
+void rvm_cpu_dumpregs( rvmcpu_t *cpu, rvm_asmins_t *pi);
 rvm_asmins_t rvm_asm(rword opcode, rword op1, rword op2, rword op3, rword data);
 rvm_asmins_t rvm_asma(rword opcode, rword op1, rword op2, rword op3, rchar *data, rulong size);
 rvm_asmins_t rvm_asml(rword opcode, rword op1, rword op2, rword op3, rlong data);