RPA Toolkit
Added break, continue implementation to RJS.
authorMartin Stoilov <martin@rpasearch.com>
Wed, 11 May 2011 06:19:25 +0000 (23:19 -0700)
committerMartin Stoilov <martin@rpasearch.com>
Wed, 11 May 2011 06:19:25 +0000 (23:19 -0700)
rjs/ecma262.rpa
rjs/rjs.c
rjs/rjscompiler.c
rjs/rjscompiler.h
rjs/rjsuids.h
rpa2/rparecord.c
rvm/rvmcpu.c
rvm/rvmcpu.h

index 9448b9e..258c7d7 100644 (file)
@@ -1,43 +1,39 @@
 #!emitall
 #!emitnone
 
-#!emit AdditiveOperator
-#!emit AssignmentExpression
-#!emit AssignmentOperator
-#!emit BitwiseANDOperator
-#!emit BitwiseNotExpressionOp
-#!emit BitwiseNotOperator
-#!emit BitwiseOROperator
-#!emit BitwiseXOROperator
+
 #!emit DoKeyword
-#!emit EqualityOperator
 #!emit FunctionCallName
 #!emit IterationDo
-#!emit LogicalANDOperator
 #!emit LogicalNotExpressionOp
-#!emit LogicalNotOperator
-#!emit LogicalOROperator
-#!emit MultiplicativeOperator
 #!emit PostfixExpressionOp
-#!emit PostfixOperator
-#!emit PostfixOperator
 #!emit PrefixExpressionOp
-#!emit PrefixOperator
-#!emit PrefixOperator
-#!emit RelationalOperator
-#!emit ShiftOperator
-#!emit UnaryExpressionOp
-#!emit UnaryOperator
 #!emit dqstring
 #!emit sqstring
 
-#!emitid Program                                               UID_PROGRAM                                             1
-#!emitid This                                                  UID_THIS                                                        2
-#!emitid Expression                                            UID_EXPRESSION                                          3
-#!emitid LeftHandSideExpression                        UID_LEFTHANDSIDEEXPRESSION                      4
-#!emitid LeftHandSideExpressionAddr            UID_LEFTHANDSIDEEXPRESSIONADDR          5
-#!emitid DecimalIntegerLiteral                 UID_DECIMALINTEGERLITERAL                       6
-#!emitid DecimalNonIntegerLiteral              UID_DECIMALNONINTEGERLITERAL            7
+#!emitid UnaryOperator                                 UID_UNARYOPERATOR                                       1
+#!emitid AdditiveOperator                              UID_BINARYOPERATOR                                      2
+#!emitid AdditiveOperator                              UID_ADDITIVEOPERATOR                            2
+#!emitid MultiplicativeOperator                        UID_MULTIPLICATIVEOPERATOR                      2
+#!emitid AssignmentOperator                            UID_ASSIGNMENTOPERATOR                          2
+#!emitid BitwiseANDOperator                            UID_BITWISEANDOPERATOR                          2
+#!emitid BitwiseNotExpressionOp                        UID_BITWISENOTEXPRESSIONOP                      2
+#!emitid BitwiseNotOperator                            UID_BITWISENOTOPERATOR                          2
+#!emitid BitwiseOROperator                             UID_BITWISEOROPERATOR                           2
+#!emitid BitwiseXOROperator                            UID_BITWISEXOROPERATOR                          2
+#!emitid LogicalNotOperator                            UID_LOGICALNOTOPERATOR                          2
+#!emitid LogicalOROperator                             UID_LOGICALOROPERATOR                           2
+#!emitid LogicalANDOperator                            UID_LOGICALANDOPERATOR                          2
+#!emitid RelationalOperator                            UID_RELATIONALOPERATOR                          2
+#!emitid PostfixOperator                               UID_POSTFIXOPERATOR                                     2
+#!emitid PrefixOperator                                        UID_PREFIXOPERATOR                                      2
+#!emitid ShiftOperator                                 UID_SHIFTOPERATOR                                       2
+#!emitid EqualityOperator                              UID_EQUALITYOPERATOR                            2
+#!emitid Program                                               UID_PROGRAM                                             3
+#!emitid This                                                  UID_THIS                                                        4
+#!emitid Expression                                            UID_EXPRESSION                                          5
+#!emitid LeftHandSideExpression                        UID_LEFTHANDSIDEEXPRESSION                      6
+#!emitid LeftHandSideExpressionAddr            UID_LEFTHANDSIDEEXPRESSIONADDR          7
 #!emitid AdditiveExpressionOp                  UID_ADDITIVEEXPRESSIONOP                        8
 #!emitid MultiplicativeExpressionOp            UID_MULTIPLICATIVEEXPRESSIONOP          9
 #!emitid BitwiseANDOp                                  UID_BITWISEANDOP                                        10
 #!emitid PrefixExpressionOp                            UID_PREFIXEXPRESSIONOP                          48
 #!emitid NewExpressionCall                             UID_NEWEXPRESSIONCALL                           49
 #!emitid FunctionExpression                            UID_FUNCTIONEXPRESSION                          50
-
+#!emitid UnaryExpressionOp                             UID_UNARYEXPRESSIONOP                           51
+#!emitid DecimalIntegerLiteral                 UID_DECIMALINTEGERLITERAL                       52
+#!emitid DecimalNonIntegerLiteral              UID_DECIMALNONINTEGERLITERAL            53
+#!emitid BreakStatement                                        UID_BREAKSTATEMENT                                      54
+#!emitid ContinueStatement                             UID_CONTINUESTATEMENT                           55
 
 
 # 6 Source Text
@@ -208,14 +208,10 @@ MemberExpression                          ::= <MemberExpressionIndexOp>  |
                                                                        <FunctionExpression> |
                                                                        <PrimaryExpression>
                                                                        
-                                                                       
 NewKeyword                                             ::= 'new' - 'new' <IdentifierPart>
-NewArrayExpression                             ::= <S>? 'new' <S> ( 'Array' | 'Object') <S>? <Arguments>?
-NewExpressionCall                              ::= 'new' <S>? <MemberExpression> <S>? <Arguments>?
-
+NewExpressionCall                              ::= <NewKeyword> <S>? <MemberExpression> <S>? <Arguments>?
 
-NewExpression                                  ::= <NewArrayExpression> |
-                                                                       <NewExpressionCall> |
+NewExpression                                  ::= <NewExpressionCall> |
                                                                        <MemberExpression>
 
 # NewExpression                                        ::= <NewKeyword> <S>? <NewExpression> |
index b40dd5d..0889d72 100644 (file)
--- a/rjs/rjs.c
+++ b/rjs/rjs.c
@@ -4,9 +4,12 @@
 
 static void rjs_engine_print(rvmcpu_t *cpu, rvm_asmins_t *ins);
 static void rjs_engine_dbgprint(rvmcpu_t *cpu, rvm_asmins_t *ins);
+static void rjs_engine_object(rvmcpu_t *cpu, rvm_asmins_t *ins);
 static rvm_switable_t rjsswitable[] = {
                {"print", rjs_engine_print},
                {"dbgprint", rjs_engine_dbgprint},
+               {"Object", rjs_engine_object},
+               {"Array", rjs_engine_object},
                {NULL, NULL},
 };
 
@@ -190,3 +193,9 @@ static void rjs_engine_dbgprint(rvmcpu_t *cpu, rvm_asmins_t *ins)
        else
                r_printf("%p\n", RVM_REG_GETP(r));
 }
+
+
+static void rjs_engine_object(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+
+}
index 16e78b6..c08f5e4 100644 (file)
@@ -40,6 +40,29 @@ static const rchar *rjs_compiler_record2str(rjs_compiler_t *co, rarray_t *record
 }
 
 
+static rlong rjs_compiler_record_parentuid(rjs_compiler_t *co, rarray_t *records, rlong rec)
+{
+       rlong parent = rpa_recordtree_parent(records, rec, RPA_RECORD_START);
+
+       if (parent < 0)
+               return -1;
+       return rpa_record_getruleuid(records, parent);
+}
+
+
+static rlong rjs_compiler_record_lastofkind(rjs_compiler_t *co, rarray_t *records, rlong rec)
+{
+       rlong uid = rpa_record_getruleuid(records, rec);
+       rlong i;
+
+       for (i = rpa_recordtree_next(records, rec, RPA_RECORD_START) ; i >= 0; i = rpa_recordtree_next(records, i, RPA_RECORD_START)) {
+               if (rpa_record_getruleuid(records, i) == uid)
+                       return 0;
+       }
+       return 1;
+}
+
+
 static rlong rjs_compiler_record2identifer(rjs_compiler_t *co, rarray_t *records, rlong rec)
 {
        rvm_varmap_t *v = NULL;
@@ -192,6 +215,22 @@ rlong rjs_compiler_record2opcode(rparecord_t *prec)
 }
 
 
+rlong rjs_compiler_record2unaryopcode(rparecord_t *prec)
+{
+       const rchar *input = prec->input;
+       rsize_t size = prec->inputsiz;
+
+       if (r_stringncmp("+", input,  size))
+               return RVM_NOP;
+       else if (r_stringncmp("-", input,  size))
+               return RVM_ENEG;
+       else if (r_stringncmp("~", input,  size))
+               return RVM_ENOT;
+
+       return -1;
+}
+
+
 rint rjs_compiler_rh_program(rjs_compiler_t *co, rarray_t *records, rlong rec)
 {
        rjs_coctx_global_t ctx;
@@ -294,8 +333,7 @@ rint rjs_compiler_rh_initializer(rjs_compiler_t *co, rarray_t *records, rlong re
 rint rjs_compiler_rh_identifier(rjs_compiler_t *co, rarray_t *records, rlong rec)
 {
        rvm_varmap_t *v;
-       rlong parrec;
-       rparecord_t *prec, *pparrec;
+       rparecord_t *prec;
        rlong swiid = -1;
        prec = (rparecord_t *)r_array_slot(records, rec);
        rjs_compiler_debughead(co, records, rec);
@@ -322,12 +360,7 @@ rint rjs_compiler_rh_identifier(rjs_compiler_t *co, rarray_t *records, rlong rec
                return -1;
        }
 
-       if ((parrec = rpa_recordtree_parent(records, rec, RPA_RECORD_END)) < 0) {
-
-               return -1;
-       }
-       pparrec = (rparecord_t *)r_array_slot(records, parrec);
-       if (rpa_recordtree_next(records, rec, RPA_RECORD_START) < 0 && pparrec->ruleuid == UID_LEFTHANDSIDEEXPRESSIONADDR) {
+       if (rjs_compiler_record_parentuid(co, records, rec) == UID_LEFTHANDSIDEEXPRESSIONADDR && rpa_recordtree_next(records, rec, RPA_RECORD_START) == -1) {
                /*
                 * If this is the last child of UID_LEFTHANDSIDEEXPRESSIONADDR
                 */
@@ -464,62 +497,93 @@ rint rjs_compiler_rh_stringcharacters(rjs_compiler_t *co, rarray_t *records, rlo
 }
 
 
-rint rjs_compiler_rh_expressionop(rjs_compiler_t *co, rarray_t *records, rlong rec)
+rint rjs_compiler_rh_binaryexpressionop(rjs_compiler_t *co, rarray_t *records, rlong rec)
 {
        rparecord_t *prec;
-       rlong opcode = 0;
-       rlong opcoderec = -1;
+       rjs_coctx_operation_t ctx;
+
+       r_memset(&ctx, 0, sizeof(ctx));
+       ctx.base.type = RJS_COCTX_OPERATION;
+       r_array_push(co->coctx, &ctx, rjs_coctx_t*);
 
        prec = (rparecord_t *)r_array_slot(records, rec);
        rjs_compiler_debughead(co, records, rec);
        rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
        rjs_compiler_debugtail(co, records, rec);
-
-       if ((opcoderec = rpa_recordtree_firstchild(records, rec, RPA_RECORD_END)) < 0)
-               return -1;
-       opcode = rjs_compiler_record2opcode((rparecord_t *)r_array_slot(records, opcoderec));
-
        if (rjs_compiler_playchildrecords(co, records, rec) < 0)
-               return -1;
-
+               goto error;
        rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
        prec = (rparecord_t *)r_array_slot(records, rec);
        rjs_compiler_debughead(co, records, rec);
        rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
-       rvm_codegen_addins(co->cg, rvm_asm(opcode, R0, R1, R0, 0));
+       rvm_codegen_addins(co->cg, rvm_asm(ctx.opcode, R0, R1, R0, 0));
        rjs_compiler_debugtail(co, records, rec);
+       r_array_removelast(co->coctx);
        return 0;
+
+error:
+       r_array_removelast(co->coctx);
+       return -1;
 }
 
 
-rint rjs_compiler_rh_assignmentexpressionop(rjs_compiler_t *co, rarray_t *records, rlong rec)
+rint rjs_compiler_rh_unaryexpressionop(rjs_compiler_t *co, rarray_t *records, rlong rec)
 {
        rparecord_t *prec;
-       rlong opcode = 0;
-       rlong opcoderec = -1;
+       rjs_coctx_operation_t ctx;
+
+       r_memset(&ctx, 0, sizeof(ctx));
+       ctx.base.type = RJS_COCTX_OPERATION;
+       r_array_push(co->coctx, &ctx, rjs_coctx_t*);
 
        prec = (rparecord_t *)r_array_slot(records, rec);
        rjs_compiler_debughead(co, records, rec);
        rjs_compiler_debugtail(co, records, rec);
+       if (rjs_compiler_playchildrecords(co, records, rec) < 0)
+               goto error;
+       rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
+       prec = (rparecord_t *)r_array_slot(records, rec);
+       rjs_compiler_debughead(co, records, rec);
+       rvm_codegen_addins(co->cg, rvm_asm(ctx.opcode, R0, R0, XX, 0));
+       rjs_compiler_debugtail(co, records, rec);
+       r_array_removelast(co->coctx);
+       return 0;
 
-       if ((opcoderec = rpa_recordtree_next(records, rpa_recordtree_firstchild(records, rec, RPA_RECORD_END), RPA_RECORD_END)) < 0)
-               return -1;
-       opcode = rjs_compiler_record2opcode((rparecord_t *)r_array_slot(records, opcoderec));
+error:
+       r_array_removelast(co->coctx);
+       return -1;
+}
 
-       if (rjs_compiler_playchildrecords(co, records, rec) < 0)
-               return -1;
 
+rint rjs_compiler_rh_assignmentexpressionop(rjs_compiler_t *co, rarray_t *records, rlong rec)
+{
+       rparecord_t *prec;
+       rjs_coctx_operation_t ctx;
+
+       r_memset(&ctx, 0, sizeof(ctx));
+       ctx.base.type = RJS_COCTX_OPERATION;
+       r_array_push(co->coctx, &ctx, rjs_coctx_t*);
+
+       prec = (rparecord_t *)r_array_slot(records, rec);
+       rjs_compiler_debughead(co, records, rec);
+       rjs_compiler_debugtail(co, records, rec);
+       if (rjs_compiler_playchildrecords(co, records, rec) < 0)
+               goto error;
        rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
        prec = (rparecord_t *)r_array_slot(records, rec);
        rjs_compiler_debughead(co, records, rec);
        rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
-       if (opcode != RVM_NOP) {
+       if (ctx.opcode != RVM_NOP) {
                rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R2, R1, XX, 0));
-               rvm_codegen_addins(co->cg, rvm_asm(opcode, R0, R2, R0, 0));
+               rvm_codegen_addins(co->cg, rvm_asm(ctx.opcode, R0, R2, R0, 0));
        }
        rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
        rjs_compiler_debugtail(co, records, rec);
+       r_array_removelast(co->coctx);
        return 0;
+error:
+       r_array_removelast(co->coctx);
+       return -1;
 }
 
 
@@ -529,10 +593,8 @@ rint rjs_compiler_rh_newarrayexpression(rjs_compiler_t *co, rarray_t *records, r
        prec = (rparecord_t *)r_array_slot(records, rec);
        rjs_compiler_debughead(co, records, rec);
        rjs_compiler_debugtail(co, records, rec);
-
        if (rjs_compiler_playchildrecords(co, records, rec) < 0)
                return -1;
-
        rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
        prec = (rparecord_t *)r_array_slot(records, rec);
        rjs_compiler_debughead(co, records, rec);
@@ -545,36 +607,24 @@ rint rjs_compiler_rh_newarrayexpression(rjs_compiler_t *co, rarray_t *records, r
 rint rjs_compiler_rh_memberexpressiondotop(rjs_compiler_t *co, rarray_t *records, rlong rec)
 {
        rjs_coctx_t *ctx = rjs_compiler_gettopctx(co);
-       rparecord_t *prec, *pidentnamerec;
+       rparecord_t *prec;
+
        prec = (rparecord_t *)r_array_slot(records, rec);
        rjs_compiler_debughead(co, records, rec);
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, R0, XX, 0));    // Supposedly an Array
        rjs_compiler_debugtail(co, records, rec);
-
        if (rjs_compiler_playchildrecords(co, records, rec) < 0)
                return -1;
-       if (ctx && ctx->type == RJS_COCTX_FUNCTIONCALL) {
+       if (ctx && ctx->type == RJS_COCTX_FUNCTIONCALL)
                ((rjs_coctx_functioncall_t *)ctx)->setthis = 1;
-       }
-
        rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
        prec = (rparecord_t *)r_array_slot(records, rec);
        rjs_compiler_debughead(co, records, rec);
-       if (rpa_record_getruleuid(records, rpa_recordtree_firstchild(records, rec, RPA_RECORD_START)) != UID_IDENTIFIERNAME)
-               return -1;
-       pidentnamerec = (rparecord_t *)r_array_slot(records, rpa_recordtree_firstchild(records, rec, RPA_RECORD_START));
-
-       if (rpa_record_getruleuid(records, rpa_recordtree_parent(records, rec, RPA_RECORD_START)) == UID_LEFTHANDSIDEEXPRESSIONADDR &&
-               rpa_recordtree_next(records, rec, RPA_RECORD_START) == -1) {
-               rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, R0, XX, 0));    // Supposedly an Array
-               rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, pidentnamerec->inputsiz));
-               rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R2, DA, XX, (void*)pidentnamerec->input));
+       if (rjs_compiler_record_parentuid(co, records, rec) == UID_LEFTHANDSIDEEXPRESSIONADDR && rjs_compiler_record_lastofkind(co, records, rec)) {
                rvm_codegen_addins(co->cg, rvm_asm(RVM_OBJLKUPADD, R0, R1, R2, 0));     // Get the offset of the element at offset R0
                rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDROBJH, R0, R1, R0, 0));       // Get the address of the element at offset R0
 
        } else {
-               rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, R0, XX, 0));    // Supposedly an Array
-               rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, pidentnamerec->inputsiz));
-               rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R2, DA, XX, (void*)pidentnamerec->input));
                rvm_codegen_addins(co->cg, rvm_asm(RVM_OBJLKUP, R0, R1, R2, 0));        // Get the offset of the element at offset R0
                rvm_codegen_addins(co->cg, rvm_asm(RVM_LDOBJH, R0, R1, R0, 0)); // Get the value of the element at offset R0
        }
@@ -593,12 +643,10 @@ rint rjs_compiler_rh_memberexpressionindexop(rjs_compiler_t *co, rarray_t *recor
 
        if (rjs_compiler_playchildrecords(co, records, rec) < 0)
                return -1;
-
        rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
        prec = (rparecord_t *)r_array_slot(records, rec);
        rjs_compiler_debughead(co, records, rec);
-       if (rpa_record_getruleuid(records, rpa_recordtree_parent(records, rec, RPA_RECORD_START)) == UID_LEFTHANDSIDEEXPRESSIONADDR &&
-               rpa_recordtree_next(records, rec, RPA_RECORD_START) == -1) {
+       if (rjs_compiler_record_parentuid(co, records, rec) == UID_LEFTHANDSIDEEXPRESSIONADDR && rjs_compiler_record_lastofkind(co, records, rec)) {
                rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));    // Supposedly an Array
                rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDROBJN, R0, R1, R0, 0));       // Get the address of the element at offset R0
 
@@ -926,6 +974,7 @@ rint rjs_compiler_rh_iterationfor(rjs_compiler_t *co, rarray_t *records, rlong r
        ctx.base.type = RJS_COCTX_ITERATION;
        ctx.start = rvm_codegen_getcodesize(co->cg);
        ctx.iterationidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__iteration", ctx.start);
+       ctx.continueidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__continue", ctx.start);
        ctx.endidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__end", ctx.start);
        r_array_push(co->coctx, &ctx, rjs_coctx_t*);
        rvm_scope_push(co->scope);
@@ -959,6 +1008,7 @@ rint rjs_compiler_rh_iterationfor(rjs_compiler_t *co, rarray_t *records, rlong r
                }
        }
 
+       rvm_codegen_redefinelabel(co->cg, ctx.continueidx);
        for (childrec = rpa_recordtree_firstchild(records, rec, RPA_RECORD_START); childrec >= 0; childrec = rpa_recordtree_next(records, childrec, RPA_RECORD_START)) {
                if (rpa_record_getruleuid(records, childrec) == UID_FOREXPRESSIONINCREMENT) {
                        if (rjs_compiler_playrecord(co, records, childrec) < 0)
@@ -1148,6 +1198,124 @@ rint rjs_compiler_rh_this(rjs_compiler_t *co, rarray_t *records, rlong rec)
 }
 
 
+rint rjs_compiler_rh_binaryoperator(rjs_compiler_t *co, rarray_t *records, rlong rec)
+{
+       rparecord_t *prec;
+       rjs_coctx_t *ctx = rjs_compiler_gettopctx(co);
+
+       prec = (rparecord_t *)r_array_slot(records, rec);
+       rjs_compiler_debughead(co, records, rec);
+       rjs_compiler_debugtail(co, records, rec);
+
+       if (rjs_compiler_playchildrecords(co, records, rec) < 0)
+               return -1;
+
+       rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
+       prec = (rparecord_t *)r_array_slot(records, rec);
+       rjs_compiler_debughead(co, records, rec);
+       if (ctx && ctx->type == RJS_COCTX_OPERATION)
+               ((rjs_coctx_operation_t *)ctx)->opcode = rjs_compiler_record2opcode(prec);
+       rjs_compiler_debugtail(co, records, rec);
+       return 0;
+}
+
+
+rint rjs_compiler_rh_unaryoperator(rjs_compiler_t *co, rarray_t *records, rlong rec)
+{
+       rparecord_t *prec;
+       rjs_coctx_t *ctx = rjs_compiler_gettopctx(co);
+
+       prec = (rparecord_t *)r_array_slot(records, rec);
+       rjs_compiler_debughead(co, records, rec);
+       rjs_compiler_debugtail(co, records, rec);
+
+       if (rjs_compiler_playchildrecords(co, records, rec) < 0)
+               return -1;
+
+       rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
+       prec = (rparecord_t *)r_array_slot(records, rec);
+       rjs_compiler_debughead(co, records, rec);
+       if (ctx && ctx->type == RJS_COCTX_OPERATION)
+               ((rjs_coctx_operation_t *)ctx)->opcode = rjs_compiler_record2unaryopcode(prec);
+       rjs_compiler_debugtail(co, records, rec);
+       return 0;
+}
+
+
+rint rjs_compiler_rh_identifiername(rjs_compiler_t *co, rarray_t *records, rlong rec)
+{
+       rparecord_t *prec;
+       prec = (rparecord_t *)r_array_slot(records, rec);
+       rjs_compiler_debughead(co, records, rec);
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, prec->inputsiz));
+       rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R2, DA, XX, (void*)prec->input));
+       rjs_compiler_debugtail(co, records, rec);
+
+       if (rjs_compiler_playchildrecords(co, records, rec) < 0)
+               return -1;
+
+       rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
+       prec = (rparecord_t *)r_array_slot(records, rec);
+       rjs_compiler_debughead(co, records, rec);
+       rjs_compiler_debugtail(co, records, rec);
+       return 0;
+}
+
+
+rint rjs_compiler_rh_continue(rjs_compiler_t *co, rarray_t *records, rlong rec)
+{
+       rparecord_t *prec;
+       rjs_coctx_t *ctx;
+       rjs_coctx_iteration_t *iterctx;
+
+
+       ctx = rjs_compiler_getctx(co, RJS_COCTX_ITERATION);
+       R_ASSERT(ctx);
+       iterctx = (rjs_coctx_iteration_t *)ctx;
+
+       prec = (rparecord_t *)r_array_slot(records, rec);
+       rjs_compiler_debughead(co, records, rec);
+       rjs_compiler_debugtail(co, records, rec);
+
+       if (rjs_compiler_playchildrecords(co, records, rec) < 0)
+               return -1;
+
+       rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
+       prec = (rparecord_t *)r_array_slot(records, rec);
+       rjs_compiler_debughead(co, records, rec);
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, iterctx->continueidx, rvm_asm(RVM_B, DA, XX, XX, 0));
+       rjs_compiler_debugtail(co, records, rec);
+       return 0;
+}
+
+
+rint rjs_compiler_rh_break(rjs_compiler_t *co, rarray_t *records, rlong rec)
+{
+       rparecord_t *prec;
+       rjs_coctx_t *ctx;
+       rjs_coctx_iteration_t *iterctx;
+
+
+       ctx = rjs_compiler_getctx(co, RJS_COCTX_ITERATION);
+       R_ASSERT(ctx);
+       iterctx = (rjs_coctx_iteration_t *)ctx;
+
+       prec = (rparecord_t *)r_array_slot(records, rec);
+       rjs_compiler_debughead(co, records, rec);
+       rjs_compiler_debugtail(co, records, rec);
+
+       if (rjs_compiler_playchildrecords(co, records, rec) < 0)
+               return -1;
+
+       rec = rpa_recordtree_get(records, rec, RPA_RECORD_END);
+       prec = (rparecord_t *)r_array_slot(records, rec);
+       rjs_compiler_debughead(co, records, rec);
+       rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, iterctx->endidx, rvm_asm(RVM_B, DA, XX, XX, 0));
+       rjs_compiler_debugtail(co, records, rec);
+       return 0;
+}
+
+
 rint rjs_compiler_rh_(rjs_compiler_t *co, rarray_t *records, rlong rec)
 {
        rparecord_t *prec;
@@ -1183,19 +1351,20 @@ rjs_compiler_t *rjs_compiler_create(rvmcpu_t *cpu)
        co->handlers[UID_DECIMALINTEGERLITERAL] = rjs_compiler_rh_decimalintegerliteral;
        co->handlers[UID_DECIMALNONINTEGERLITERAL] = rjs_compiler_rh_decimalnonintegerliteral;
        co->handlers[UID_STRINGCHARACTERS] = rjs_compiler_rh_stringcharacters;
-       co->handlers[UID_ADDITIVEEXPRESSIONOP] = rjs_compiler_rh_expressionop;
-       co->handlers[UID_MULTIPLICATIVEEXPRESSIONOP] = rjs_compiler_rh_expressionop;
-       co->handlers[UID_BITWISEANDOP] = rjs_compiler_rh_expressionop;
-       co->handlers[UID_BITWISEXOROP] = rjs_compiler_rh_expressionop;
-       co->handlers[UID_BITWISEOROP] = rjs_compiler_rh_expressionop;
-       co->handlers[UID_SHIFTEXPRESSIONOP] = rjs_compiler_rh_expressionop;
-       co->handlers[UID_EQUALITYEXPRESSIONOP] = rjs_compiler_rh_expressionop;
-       co->handlers[UID_RELATIONALEXPRESSIONOP] = rjs_compiler_rh_expressionop;
-       co->handlers[UID_LOGICALOROP] = rjs_compiler_rh_expressionop;
-       co->handlers[UID_LOGICALANDOP] = rjs_compiler_rh_expressionop;
+       co->handlers[UID_ADDITIVEEXPRESSIONOP] = rjs_compiler_rh_binaryexpressionop;
+       co->handlers[UID_MULTIPLICATIVEEXPRESSIONOP] = rjs_compiler_rh_binaryexpressionop;
+       co->handlers[UID_BITWISEANDOP] = rjs_compiler_rh_binaryexpressionop;
+       co->handlers[UID_BITWISEXOROP] = rjs_compiler_rh_binaryexpressionop;
+       co->handlers[UID_BITWISEOROP] = rjs_compiler_rh_binaryexpressionop;
+       co->handlers[UID_SHIFTEXPRESSIONOP] = rjs_compiler_rh_binaryexpressionop;
+       co->handlers[UID_EQUALITYEXPRESSIONOP] = rjs_compiler_rh_binaryexpressionop;
+       co->handlers[UID_RELATIONALEXPRESSIONOP] = rjs_compiler_rh_binaryexpressionop;
+       co->handlers[UID_LOGICALOROP] = rjs_compiler_rh_binaryexpressionop;
+       co->handlers[UID_LOGICALANDOP] = rjs_compiler_rh_binaryexpressionop;
        co->handlers[UID_VARIABLEALLOCATEANDINIT] = rjs_compiler_rh_varallocinit;
        co->handlers[UID_VARIABLEALLOCATE] = rjs_compiler_rh_varalloc;
        co->handlers[UID_IDENTIFIER] = rjs_compiler_rh_identifier;
+       co->handlers[UID_IDENTIFIERNAME] = rjs_compiler_rh_identifiername;
        co->handlers[UID_INITIALISER] = rjs_compiler_rh_initializer;
        co->handlers[UID_ASSIGNMENTEXPRESSIONOP] = rjs_compiler_rh_assignmentexpressionop;
        co->handlers[UID_NEWARRAYEXPRESSION] = rjs_compiler_rh_newarrayexpression;
@@ -1220,6 +1389,11 @@ rjs_compiler_t *rjs_compiler_create(rvmcpu_t *cpu)
        co->handlers[UID_PREFIXEXPRESSIONOP] = rjs_compiler_rh_prefixexpressionop;
        co->handlers[UID_THIS] = rjs_compiler_rh_this;
        co->handlers[UID_NEWEXPRESSIONCALL] = rjs_compiler_rh_newexpressioncall;
+       co->handlers[UID_UNARYEXPRESSIONOP] = rjs_compiler_rh_unaryexpressionop;
+       co->handlers[UID_BINARYOPERATOR] = rjs_compiler_rh_binaryoperator;
+       co->handlers[UID_UNARYOPERATOR] = rjs_compiler_rh_unaryoperator;
+       co->handlers[UID_BREAKSTATEMENT] = rjs_compiler_rh_break;
+       co->handlers[UID_CONTINUESTATEMENT] = rjs_compiler_rh_continue;
 
        return co;
 }
index 3f819cd..727e91d 100644 (file)
@@ -22,6 +22,7 @@ extern "C" {
 #define RJS_COCTX_FUNCTIONCALL (1 << 3)
 #define RJS_COCTX_IFSTATEMENT (1 << 4)
 #define RJS_COCTX_ITERATION (1 << 5)
+#define RJS_COCTX_OPERATION (1 << 5)
 
 typedef struct rjs_coctx_s {
        rulong type;
@@ -40,6 +41,12 @@ typedef struct rjs_coctx_function_s {
 } rjs_coctx_function_t;
 
 
+typedef struct rjs_coctx_operation_s {
+       rjs_coctx_t base;
+       rlong opcode;
+} rjs_coctx_operation_t;
+
+
 typedef struct rjs_coctx_functioncall_s {
        rjs_coctx_t base;
        rsize_t arguments;
@@ -60,6 +67,7 @@ typedef struct rjs_coctx_iteration_s {
        rjs_coctx_t base;
        rlong start;
        rlong iterationidx;
+       rlong continueidx;
        rlong endidx;
 } rjs_coctx_iteration_t;
 
index 32e3444..a2e24f3 100644 (file)
@@ -1,10 +1,26 @@
-#define UID_PROGRAM 1
-#define UID_THIS 2
-#define UID_EXPRESSION 3
-#define UID_LEFTHANDSIDEEXPRESSION 4
-#define UID_LEFTHANDSIDEEXPRESSIONADDR 5
-#define UID_DECIMALINTEGERLITERAL 6
-#define UID_DECIMALNONINTEGERLITERAL 7
+#define UID_UNARYOPERATOR 1
+#define UID_BINARYOPERATOR 2
+#define UID_ADDITIVEOPERATOR 2
+#define UID_MULTIPLICATIVEOPERATOR 2
+#define UID_ASSIGNMENTOPERATOR 2
+#define UID_BITWISEANDOPERATOR 2
+#define UID_BITWISENOTEXPRESSIONOP 2
+#define UID_BITWISENOTOPERATOR 2
+#define UID_BITWISEOROPERATOR 2
+#define UID_BITWISEXOROPERATOR 2
+#define UID_LOGICALNOTOPERATOR 2
+#define UID_LOGICALOROPERATOR 2
+#define UID_LOGICALANDOPERATOR 2
+#define UID_RELATIONALOPERATOR 2
+#define UID_POSTFIXOPERATOR 2
+#define UID_PREFIXOPERATOR 2
+#define UID_SHIFTOPERATOR 2
+#define UID_EQUALITYOPERATOR 2
+#define UID_PROGRAM 3
+#define UID_THIS 4
+#define UID_EXPRESSION 5
+#define UID_LEFTHANDSIDEEXPRESSION 6
+#define UID_LEFTHANDSIDEEXPRESSIONADDR 7
 #define UID_ADDITIVEEXPRESSIONOP 8
 #define UID_MULTIPLICATIVEEXPRESSIONOP 9
 #define UID_BITWISEANDOP 10
@@ -49,3 +65,8 @@
 #define UID_PREFIXEXPRESSIONOP 48
 #define UID_NEWEXPRESSIONCALL 49
 #define UID_FUNCTIONEXPRESSION 50
+#define UID_UNARYEXPRESSIONOP 51
+#define UID_DECIMALINTEGERLITERAL 52
+#define UID_DECIMALNONINTEGERLITERAL 53
+#define UID_BREAKSTATEMENT 54
+#define UID_CONTINUESTATEMENT 55
index 8bcffcc..5664d84 100644 (file)
@@ -376,8 +376,7 @@ void rpa_record_dump(rarray_t *records, rlong rec)
        prev = rpa_recordtree_prev(records, rec, RPA_RECORD_START);
        parent = rpa_recordtree_parent(records, rec, RPA_RECORD_START);
 
-//     n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, "%5d  ( %7ld, %4d ) : ", rec, prec->ruleid, (ruint32)prec->ruleuid);
-       n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, "%5ld, n:%5ld (s: %5ld, e: %5ld, p: %5ld) ( %4d, 0x%03x ) : ", rec, prec->next, start, end, parent, prec->ruleuid, prec->usertype);
+       n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, "%5ld: [ s: %5ld, e: %5ld, p: %5ld ] ( %4d, 0x%03x ) : ", rec, start, end, parent, prec->ruleuid, prec->usertype);
        if (prec->type & RPA_RECORD_START)
                n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, "START ");
        if (prec->type & RPA_RECORD_END)
index e728e98..1b2b794 100644 (file)
@@ -122,6 +122,7 @@ static const char *stropcalls[] = {
        "RVM_TYPE",             /* Type: op1 = typeof(op2) */
        "RVM_SETTYPE",  /* Type: op1.type = op2 */
        "RVM_EMOV",
+       "RVM_ENEG",
        "RVM_EADD",
        "RVM_ESUB",
        "RVM_EMUL",
@@ -1303,6 +1304,17 @@ static void rvm_op_esub(rvmcpu_t *cpu, rvm_asmins_t *ins)
 }
 
 
+static void rvm_op_eneg(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rvmreg_t zero;
+
+       rvm_reg_setunsigned(&zero, 0);
+       rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_SUB, cpu, RVM_CPUREG_PTR(cpu, ins->op1), &zero, arg2);
+}
+
+
+
 static void rvm_op_emul(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
        rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
@@ -1850,6 +1862,7 @@ static rvm_cpu_op ops[] = {
        rvm_op_type,            // RVM_TYPE
        rvm_op_settype,         // RVM_SETTYPE
        rvm_op_emov,            // RVM_EMOV
+       rvm_op_eneg,            // RVM_ENEG
        rvm_op_eadd,            // RVM_EADD
        rvm_op_esub,            // RVM_ESUB
        rvm_op_emul,            // RVM_EMUL
index 4c8a364..24947c7 100644 (file)
@@ -125,6 +125,7 @@ enum {
        RVM_TYPE,               /* Type: op1 = typeof(op2) */
        RVM_SETTYPE,    /* Type: op1.type = op2 */
        RVM_EMOV,
+       RVM_ENEG,               /* Negative: op1 = -op2, Update the status register */
        RVM_EADD,               /* Add: op1 = op2 + op3, update the status register */
        RVM_ESUB,               /* Subtract: op1 = op2 - op3, update the status register */
        RVM_EMUL,               /* Multiply: op1 = op2 * op3, update the status register */