RPA Toolkit
work on the RPA2 expression compiler
authorMartin Stoilov <martin@rpasearch.com>
Mon, 28 Feb 2011 00:52:16 +0000 (16:52 -0800)
committerMartin Stoilov <martin@rpasearch.com>
Mon, 28 Feb 2011 00:52:16 +0000 (16:52 -0800)
rpa2/rpacompiler.c
rpa2/rpacompiler.h
rvm/rvmcodegen.c
rvm/rvmcodegen.h
testrpa2/build/linux/testrpa2.mk
testrpa2/rpacompiler-rule.c

index 102ab04..9ead57b 100644 (file)
@@ -74,7 +74,7 @@ rpa_compiler_t *rpa_compiler_create()
        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);
@@ -88,6 +88,7 @@ void rpa_compiler_destroy(rpa_compiler_t *co)
        if (co) {
                rvm_codegen_destroy(co->cg);
                rvm_scope_destroy(co->scope);
+               r_object_destroy((robject_t*)co->expressions);
        }
        r_free(co);
 }
@@ -95,15 +96,17 @@ void rpa_compiler_destroy(rpa_compiler_t *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;
 }
 
@@ -116,17 +119,50 @@ rint rpa_compiler_rule_begin_s(rpa_compiler_t *co, const rchar *name)
 
 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;
 }
 
index 4c6ddfa..2831ebc 100644 (file)
@@ -10,15 +10,19 @@ extern "C" {
 #endif
 
 typedef struct rpa_ruledef_s {
+       rulong branch;
+       rulong start;
        rlong labelidx;
        rlong emitidx;
        rlong endidx;
-       rchar end[64];
 } rpa_ruledef_t;
 
+
+#define RPA_COMPILER_CURRENTEXP(__co__) ((rpa_ruledef_t*)r_array_lastslot((__co__)->expressions))
+
 typedef struct rpa_compiler_s {
        rvm_codegen_t *cg;
-       rpa_ruledef_t current;
+       rarray_t *expressions;
        rboolean optimized;
        rvm_scope_t *scope;
        rulong fpoff;
@@ -31,6 +35,9 @@ 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_exp_begin(rpa_compiler_t *co);
+rint rpa_compiler_exp_end(rpa_compiler_t *co, ruint qflag);
+
 
 #ifdef __cplusplus
 }
index bce0afe..d4e3400 100644 (file)
@@ -59,6 +59,16 @@ ruint rvm_codegen_addins(rvm_codegen_t *cg, rvm_asmins_t ins)
 }
 
 
+rlong rvm_codegen_redefinelabel(rvm_codegen_t *cg, rlong index)
+{
+       rvm_codelabel_t *label = rvm_codemap_label(cg->codemap, index);
+
+       if (!label)
+               return -1;
+       return rvm_codemap_addoffset(cg->codemap, label->name->str, label->name->size, rvm_codemap_lookup_s(cg->codemap, ".code"), RVM_CODE2BYTE_OFFSET(rvm_codegen_getcodesize(cg)));
+}
+
+
 rlong rvm_codegen_addlabel(rvm_codegen_t *cg, const rchar* name, ruint namesize)
 {
        return rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookup_s(cg->codemap, ".code"), RVM_CODE2BYTE_OFFSET(rvm_codegen_getcodesize(cg)));
index 2cff991..1a3c61a 100644 (file)
@@ -45,6 +45,7 @@ rulong rvm_codegen_getcodesize(rvm_codegen_t *cg);
 void rvm_codegen_setcodesize(rvm_codegen_t *cg, ruint size);
 void rvm_codegen_clear(rvm_codegen_t *cg);
 rint rvm_codegen_relocate(rvm_codegen_t *cg, rvm_codelabel_t **err);
+rlong rvm_codegen_redefinelabel(rvm_codegen_t *cg, rlong index);
 rlong rvm_codegen_addlabel(rvm_codegen_t *cg, const rchar* name, ruint namesize);
 rlong rvm_codegen_addlabel_s(rvm_codegen_t *cg, const rchar* name);
 rlong rvm_codegen_adddata(rvm_codegen_t *cg, const rchar *name, ruint namesize, rconstpointer data, rsize_t size);
index 18842e7..d7c6e8e 100644 (file)
@@ -11,10 +11,10 @@ LIBS += -L$(RPA2_SRCDIR)/build/$(OS)/$(ARCHDIR)/out
 LIBS += -lrpa2 -lrvm -lrlib -lpthread -lm --static
 
 
-TESTS  += $(OUTDIR)/rpavm-test
 TESTS  += $(OUTDIR)/rpavm-matchchr
 TESTS  += $(OUTDIR)/rpavm-mnode
 TESTS  += $(OUTDIR)/rpacompiler-rule
+TESTS  += $(OUTDIR)/rpacompiler-exp
 
 all : $(OUTDIR) $(TESTS)
 
index 4ffc4b1..b95e7cc 100644 (file)
@@ -17,11 +17,11 @@ void code_rpa_matchabc(rpa_compiler_t *co, rpastat_t *stat)
 {
        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);
 }
 
@@ -30,11 +30,11 @@ void code_rpa_matchxyz(rpa_compiler_t *co, rpastat_t *stat)
 {
        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);
 }