RPA Toolkit
Fixed SYNTAX_ERROR reporting. Added a few string operations (SWI).
authorMartin Stoilov <martin@rpasearch.com>
Thu, 26 May 2011 04:38:41 +0000 (21:38 -0700)
committerMartin Stoilov <martin@rpasearch.com>
Thu, 26 May 2011 04:38:41 +0000 (21:38 -0700)
rjs/rjs.c
rjs/rjs.h
rjs/rjscompiler.c
rjs/rjscompiler.h
rjs/rjserror.h
rjs/rjsexec.c
rjs/rjsparser.h

index e528912..b434f69 100644 (file)
--- a/rjs/rjs.c
+++ b/rjs/rjs.c
@@ -32,6 +32,7 @@ rjs_engine_t *rjs_engine_create()
        jse->co = rjs_compiler_create(jse->cpu);
        jse->cgs = r_array_create(sizeof(rvm_codegen_t*));
        jse->errors = r_array_create(sizeof(rjs_error_t));
+       jse->cpu->userdata1 = jse;
        rvm_cpu_addswitable(jse->cpu, "rjsswitable", rjsswitable);
        if (!jse->pa || !jse->cpu || !jse->co || !jse->cgs)
                goto error;
@@ -71,15 +72,17 @@ rint rjs_engine_open(rjs_engine_t *jse)
 }
 
 
-static rint rjs_engine_parse(rjs_engine_t *jse, const rchar *script, rsize_t size, rarray_t *records)
+rint rjs_engine_addswitable(rjs_engine_t *jse, const rchar *tabname, rvm_switable_t *switalbe)
+{
+       return rvm_cpu_addswitable(jse->cpu, tabname, switalbe);
+}
+
+
+static rint rjs_engine_parse(rjs_engine_t *jse, const rchar *script, rsize_t size, rarray_t *records, rjs_error_t *error)
 {
        rlong res = 0;
-       rjs_error_t error;
 
-       r_memset(&error, 0, sizeof(error));
-       res = rjs_parser_exec(jse->pa, script, size, records, &error);
-       if (res < 0)
-               r_array_add(jse->errors, &error);
+       res = rjs_parser_exec(jse->pa, script, size, records, error);
        return res;
 }
 
@@ -88,9 +91,11 @@ rint rjs_engine_compile(rjs_engine_t *jse, const rchar *script, rsize_t size)
 {
        rvm_codegen_t *topcg = NULL;
        rarray_t *records = rpa_records_create();
+       rjs_error_t error;
        jse->co->debug = jse->debugcompile;
 
-       if (rjs_engine_parse(jse, script, size, records) < 0) {
+       r_memset(&error, 0, sizeof(error));
+       if (rjs_engine_parse(jse, script, size, records, &error) < 0) {
 
                goto err;
        }
@@ -103,7 +108,7 @@ rint rjs_engine_compile(rjs_engine_t *jse, const rchar *script, rsize_t size)
                rvm_codegen_clear(topcg);
        }
        topcg->userdata = 0;
-       if (rjs_compiler_compile(jse->co, records, topcg) < 0) {
+       if (rjs_compiler_compile(jse->co, script, size, records, topcg, &error) < 0) {
                topcg->userdata = 0;
                goto err;
        }
@@ -112,6 +117,7 @@ rint rjs_engine_compile(rjs_engine_t *jse, const rchar *script, rsize_t size)
        return 0;
 
 err:
+       r_array_add(jse->errors, &error);
        rpa_records_destroy(records);
        return -1;
 }
@@ -119,8 +125,10 @@ err:
 
 rint rjs_engine_dumpast(rjs_engine_t *jse, const rchar *script, rsize_t size)
 {
+       rjs_error_t error;
        rarray_t *records = rpa_records_create();
-       if (rjs_engine_parse(jse, script, size, records) < 0) {
+
+       if (rjs_engine_parse(jse, script, size, records, &error) < 0) {
 
 
                return -1;
@@ -252,3 +260,18 @@ static void rjs_engine_object(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
 
 }
+
+
+void rjs_engine_abort(rjs_engine_t *jse, rjs_error_t *error)
+{
+       if (error) {
+               r_array_add(jse->errors, error);
+       }
+       rvm_cpu_abort(jse->cpu);
+}
+
+
+rjs_engine_t *rjs_engine_get(rvmcpu_t *cpu)
+{
+       return (rjs_engine_t *)cpu->userdata1;
+}
index 3630edc..2090c84 100644 (file)
--- a/rjs/rjs.h
+++ b/rjs/rjs.h
@@ -28,6 +28,8 @@ typedef struct rjs_engine_s {
 #define RJS_VERSION_MINOR 51
 #define RJS_VERSION_MICRO 1
 #define RJS_VERSION_STRING "0.51.1"
+#define RJS_SWI_PARAM(__cpu__, __n__) RVM_STACK_ADDR((__cpu__)->stack, RVM_CPUREG_GETU(__cpu__, FP) + (__n__))
+#define RJS_SWI_PARAMS(__cpu__) (RVM_CPUREG_GETU((__cpu__), SP) - RVM_CPUREG_GETU((__cpu__), FP))
 
 const rchar *rjs_version();
 
@@ -38,10 +40,12 @@ rint rjs_engine_compile(rjs_engine_t *jse, const rchar *script, rsize_t size);
 rint rjs_engine_compile_s(rjs_engine_t *jse, const rchar *script);
 rint rjs_engine_close(rjs_engine_t *jse);
 rint rjs_engine_run(rjs_engine_t *jse);
+rint rjs_engine_addswitable(rjs_engine_t *jse, const rchar *tabname, rvm_switable_t *switalbe);
 rint rjs_engine_dumpast(rjs_engine_t *jse, const rchar *script, rsize_t size);
 rvmreg_t *rjs_engine_exec(rjs_engine_t *jse, const rchar *script, rsize_t size);
 rvmreg_t *rjs_engine_exec_s(rjs_engine_t *jse, const rchar *script);
-
+void rjs_engine_abort(rjs_engine_t *jse, rjs_error_t *error);
+rjs_engine_t *rjs_engine_get(rvmcpu_t *cpu);
 
 #ifdef __cplusplus
 }
index 85d48ee..0d518f0 100644 (file)
@@ -1,5 +1,7 @@
 #include "rmem.h"
 #include "rjscompiler.h"
+#include "rjsparser.h"
+
 
 rint rjs_compiler_playreversechildrecords(rjs_compiler_t *co, rarray_t *records, rlong rec);
 static rint rjs_compiler_playrecord(rjs_compiler_t *co, rarray_t *records, rlong rec);
@@ -24,11 +26,16 @@ void rjs_compiler_debugtail(rjs_compiler_t *co, rarray_t *records, rlong rec)
 }
 
 
-void rjs_compiler_adderror(rjs_compiler_t *co, rlong code, const rchar *script)
+void rjs_compiler_adderror(rjs_compiler_t *co, rlong code, rparecord_t *prec)
 {
-       /*
-        * Not used for now. I should probably get rid of this altogether.
-        */
+       co->error->type = RJS_ERRORTYPE_SYNTAX;
+       co->error->error = code;
+       co->error->script = co->script;
+       co->error->offset = prec->input - co->script;
+       co->error->size = prec->inputsiz;
+       co->error->line = rjs_parser_offset2line(co->script, co->error->offset);
+       co->error->lineoffset = rjs_parser_offset2lineoffset(co->script, co->error->offset);
+
 }
 
 
@@ -368,8 +375,8 @@ rint rjs_compiler_rh_identifier(rjs_compiler_t *co, rarray_t *records, rlong rec
                        goto end;
                }
 
-               rjs_compiler_adderror(co, RJS_ERROR_UNDEFINED, prec->input);
-               return 0;
+               rjs_compiler_adderror(co, RJS_ERROR_UNDEFINED, prec);
+               return -1;
        }
 
        if (rjs_compiler_record_parentuid(co, records, rec) == UID_LEFTHANDSIDEEXPRESSIONADDR && rpa_recordtree_next(records, rec, RPA_RECORD_START) == -1) {
@@ -750,8 +757,8 @@ rint rjs_compiler_rh_functionparameter(rjs_compiler_t *co, rarray_t *records, rl
         */
        ctx = rjs_compiler_getctx(co, RJS_COCTX_FUNCTION);
        if (!ctx) {
-               rjs_compiler_adderror(co, RJS_ERROR_NOTAFUNCTION, prec->input);
-               return 0;
+               rjs_compiler_adderror(co, RJS_ERROR_NOTAFUNCTION, prec);
+               return -1;
        }
        R_ASSERT(ctx);
        functx = (rjs_coctx_function_t *)ctx;
@@ -831,8 +838,8 @@ rint rjs_compiler_rh_argument(rjs_compiler_t *co, rarray_t *records, rlong rec)
        prec = (rparecord_t *)r_array_slot(records, rec);
        rjs_compiler_debughead(co, records, rec);
        if (!ctx) {
-               rjs_compiler_adderror(co, RJS_ERROR_NOTAFUNCTIONCALL, prec->input);
-               return 0;
+               rjs_compiler_adderror(co, RJS_ERROR_NOTAFUNCTIONCALL, prec);
+               return -1;
        }
        R_ASSERT(ctx);
        rjs_compiler_debugtail(co, records, rec);
@@ -858,8 +865,8 @@ rint rjs_compiler_rh_arguments(rjs_compiler_t *co, rarray_t *records, rlong rec)
        prec = (rparecord_t *)r_array_slot(records, rec);
        rjs_compiler_debughead(co, records, rec);
        if (!ctx) {
-               rjs_compiler_adderror(co, RJS_ERROR_NOTAFUNCTIONCALL, prec->input);
-               return 0;
+               rjs_compiler_adderror(co, RJS_ERROR_NOTAFUNCTIONCALL, prec);
+               return -1;
        }
        R_ASSERT(ctx);
        rjs_compiler_debugtail(co, records, rec);
@@ -938,8 +945,8 @@ rint rjs_compiler_rh_ifconditionop(rjs_compiler_t *co, rarray_t *records, rlong
        prec = (rparecord_t *)r_array_slot(records, rec);
        rjs_compiler_debughead(co, records, rec);
        if (!ctx) {
-               rjs_compiler_adderror(co, RJS_ERROR_NOTAIFSTATEMENT, prec->input);
-               return 0;
+               rjs_compiler_adderror(co, RJS_ERROR_NOTAIFSTATEMENT, prec);
+               return -1;
        }
        R_ASSERT(ctx);
        rjs_compiler_debugtail(co, records, rec);
@@ -962,8 +969,8 @@ rint rjs_compiler_rh_iftruestatement(rjs_compiler_t *co, rarray_t *records, rlon
        prec = (rparecord_t *)r_array_slot(records, rec);
        rjs_compiler_debughead(co, records, rec);
        if (!ctx) {
-               rjs_compiler_adderror(co, RJS_ERROR_NOTAIFSTATEMENT, prec->input);
-               return 0;
+               rjs_compiler_adderror(co, RJS_ERROR_NOTAIFSTATEMENT, prec);
+               return -1;
        }
        R_ASSERT(ctx);
        rjs_compiler_debugtail(co, records, rec);
@@ -988,8 +995,8 @@ rint rjs_compiler_rh_iffalsestatement(rjs_compiler_t *co, rarray_t *records, rlo
        prec = (rparecord_t *)r_array_slot(records, rec);
        rjs_compiler_debughead(co, records, rec);
        if (!ctx) {
-               rjs_compiler_adderror(co, RJS_ERROR_NOTAIFSTATEMENT, prec->input);
-               return 0;
+               rjs_compiler_adderror(co, RJS_ERROR_NOTAIFSTATEMENT, prec);
+               return -1;
        }
        R_ASSERT(ctx);
        rvm_codegen_redefinelabel_default(co->cg, ctx->falseidx);
@@ -1169,8 +1176,8 @@ rint rjs_compiler_rh_dowhileexpressioncompare(rjs_compiler_t *co, rarray_t *reco
        prec = (rparecord_t *)r_array_slot(records, rec);
        rjs_compiler_debughead(co, records, rec);
        if (!ctx) {
-               rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec->input);
-               return 0;
+               rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec);
+               return -1;
        }
        R_ASSERT(ctx);
        rvm_codegen_redefinelabel_default(co->cg, ctx->continueidx);
@@ -1196,8 +1203,8 @@ rint rjs_compiler_rh_forexpressioncompare(rjs_compiler_t *co, rarray_t *records,
        prec = (rparecord_t *)r_array_slot(records, rec);
        rjs_compiler_debughead(co, records, rec);
        if (!ctx) {
-               rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec->input);
-               return 0;
+               rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec);
+               return -1;
        }
        R_ASSERT(ctx);
        rjs_compiler_debugtail(co, records, rec);
@@ -1222,8 +1229,8 @@ rint rjs_compiler_rh_forexpressionincrement(rjs_compiler_t *co, rarray_t *record
        prec = (rparecord_t *)r_array_slot(records, rec);
        rjs_compiler_debughead(co, records, rec);
        if (!ctx) {
-               rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec->input);
-               return 0;
+               rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec);
+               return -1;
        }
        R_ASSERT(ctx);
        rjs_compiler_debugtail(co, records, rec);
@@ -1434,8 +1441,8 @@ rint rjs_compiler_rh_continue(rjs_compiler_t *co, rarray_t *records, rlong rec)
        prec = (rparecord_t *)r_array_slot(records, rec);
        rjs_compiler_debughead(co, records, rec);
        if (!ctx) {
-               rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec->input);
-               return 0;
+               rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec);
+               return -1;
        }
        R_ASSERT(ctx);
        iterctx = (rjs_coctx_iteration_t *)ctx;
@@ -1464,8 +1471,8 @@ rint rjs_compiler_rh_break(rjs_compiler_t *co, rarray_t *records, rlong rec)
        prec = (rparecord_t *)r_array_slot(records, rec);
        rjs_compiler_debughead(co, records, rec);
        if (!ctx) {
-               rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec->input);
-               return 0;
+               rjs_compiler_adderror(co, RJS_ERROR_NOTALOOP, prec);
+               return -1;
        }
        R_ASSERT(ctx);
        iterctx = (rjs_coctx_iteration_t *)ctx;
@@ -1496,7 +1503,7 @@ rint rjs_compiler_rh_syntaxerror(rjs_compiler_t *co, rarray_t *records, rlong re
        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_adderror(co, RJS_ERROR_SYNTAX, prec->input);
+       rjs_compiler_adderror(co, RJS_ERROR_SYNTAX, prec);
        rjs_compiler_debugtail(co, records, rec);
        return 0;
 }
@@ -1658,7 +1665,7 @@ static rint rjs_compiler_playrecord(rjs_compiler_t *co, rarray_t *records, rlong
 }
 
 
-rint rjs_compiler_compile(rjs_compiler_t *co, rarray_t *records, rvm_codegen_t *cg)
+rint rjs_compiler_compile(rjs_compiler_t *co, const rchar *script, rsize_t scriptsize, rarray_t *records, rvm_codegen_t *cg, rjs_error_t *error)
 {
        rlong i;
        rvm_codelabel_t *labelerr;
@@ -1670,6 +1677,9 @@ rint rjs_compiler_compile(rjs_compiler_t *co, rarray_t *records, rvm_codegen_t *
                return -1;
        }
        co->cg = cg;
+       co->error = error;
+       co->script = script;
+       co->scriptsize = scriptsize;
 
        for (i = 0; i >= 0; i = rpa_recordtree_next(records, i, RPA_RECORD_START)) {
                if (rjs_compiler_playrecord(co, records, i) < 0)
index 1524d61..95c8e90 100644 (file)
@@ -87,8 +87,11 @@ struct rjs_compiler_s {
        rvmcpu_t *cpu;
        rvm_codegen_t *cg;
        rvm_scope_t *scope;
+       rjs_error_t *error;
        rarray_t *coctx;
        rchar *temp;
+       const rchar *script;
+       rsize_t scriptsize;
        rlong headoff;
        rlong opcode;
        rulong debug:1;
@@ -98,7 +101,7 @@ struct rjs_compiler_s {
 
 rjs_compiler_t *rjs_compiler_create(rvmcpu_t *cpu);
 void rjs_compiler_destroy(rjs_compiler_t *co);
-rint rjs_compiler_compile(rjs_compiler_t *co, rarray_t *records, rvm_codegen_t *cg);
+rint rjs_compiler_compile(rjs_compiler_t *co, const rchar *script, rsize_t scriptsize, rarray_t *records, rvm_codegen_t *cg, rjs_error_t *error);
 rjs_coctx_t *rjs_compiler_getctx(rjs_compiler_t *co, rulong type);
 
 #ifdef __cplusplus
index c08db31..d8d1371 100644 (file)
@@ -20,8 +20,10 @@ typedef struct rjs_error_s {
        rlong type;
        rlong error;
        rlong offset;
+       rlong size;
        rlong line;
        rlong lineoffset;
+       const rchar *script;
 } rjs_error_t;
 
 
index faf4c17..a9957bd 100644 (file)
@@ -40,6 +40,152 @@ static rchar *errormsg[] = {
        "Unknown",
 };
 
+
+static void rjs_exec_ltrim(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       const rchar *ptr, *list;
+       rsize_t size;
+       rvmreg_t *r = NULL, *l = NULL;
+       rstring_t *src, *dest;
+
+       if (RJS_SWI_PARAMS(cpu) == 0) {
+               rjs_engine_abort(rjs_engine_get(cpu), NULL);
+               return;
+       }
+       r = (rvmreg_t *) RJS_SWI_PARAM(cpu, 1);
+       if (RJS_SWI_PARAMS(cpu) > 1) {
+               l = (rvmreg_t *) RJS_SWI_PARAM(cpu, 2);
+               if (rvm_reg_gettype(l) != RVM_DTYPE_STRING) {
+                       rjs_engine_abort(rjs_engine_get(cpu), NULL);
+                       return;
+               }
+       }
+       if (rvm_reg_gettype(r) != RVM_DTYPE_STRING) {
+               rjs_engine_abort(rjs_engine_get(cpu), NULL);
+               return;
+       }
+
+       if (l)
+               list = ((rstring_t *)RVM_REG_GETP(l))->s.str;
+       else
+               list = " \t\n\r\0";
+       src = (rstring_t *)RVM_REG_GETP(r);
+       ptr = src->s.str;
+       size = src->s.size;
+       while (size > 0) {
+               if (!r_strchr(list, *ptr))
+                       break;
+               size--;
+               ptr++;
+       }
+       dest = r_string_create_strsize(ptr, size);
+       rvm_gc_add(cpu->gc, (robject_t*)dest);
+       rvm_reg_setstring(RVM_CPUREG_PTR(cpu, R0), dest);
+}
+
+
+static void rjs_exec_rtrim(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       const rchar *ptr, *list;
+       rsize_t size;
+       rvmreg_t *r = NULL, *l = NULL;
+       rstring_t *src, *dest;
+
+       if (RJS_SWI_PARAMS(cpu) == 0) {
+               rjs_engine_abort(rjs_engine_get(cpu), NULL);
+               return;
+       }
+       r = (rvmreg_t *) RJS_SWI_PARAM(cpu, 1);
+       if (RJS_SWI_PARAMS(cpu) > 1) {
+               l = (rvmreg_t *) RJS_SWI_PARAM(cpu, 2);
+               if (rvm_reg_gettype(l) != RVM_DTYPE_STRING) {
+                       rjs_engine_abort(rjs_engine_get(cpu), NULL);
+                       return;
+               }
+       }
+       if (rvm_reg_gettype(r) != RVM_DTYPE_STRING) {
+               rjs_engine_abort(rjs_engine_get(cpu), NULL);
+               return;
+       }
+
+       if (l)
+               list = ((rstring_t *)RVM_REG_GETP(l))->s.str;
+       else
+               list = " \t\n\r\0";
+       src = (rstring_t *)RVM_REG_GETP(r);
+       size = src->s.size;
+       ptr = src->s.str + size - 1;
+       while (size > 0) {
+               if (!r_strchr(list, *ptr))
+                       break;
+               size--;
+               ptr--;
+       }
+       dest = r_string_create_strsize(src->s.str, size);
+       rvm_gc_add(cpu->gc, (robject_t*)dest);
+       rvm_reg_setstring(RVM_CPUREG_PTR(cpu, R0), dest);
+}
+
+
+static void rjs_exec_trim(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       const rchar *start, *ptr, *list;
+       rsize_t size;
+       rvmreg_t *r = NULL, *l = NULL;
+       rstring_t *src, *dest;
+
+       if (RJS_SWI_PARAMS(cpu) == 0) {
+               rjs_engine_abort(rjs_engine_get(cpu), NULL);
+               return;
+       }
+       r = (rvmreg_t *) RJS_SWI_PARAM(cpu, 1);
+       if (RJS_SWI_PARAMS(cpu) > 1) {
+               l = (rvmreg_t *) RJS_SWI_PARAM(cpu, 2);
+               if (rvm_reg_gettype(l) != RVM_DTYPE_STRING) {
+                       rjs_engine_abort(rjs_engine_get(cpu), NULL);
+                       return;
+               }
+       }
+       if (rvm_reg_gettype(r) != RVM_DTYPE_STRING) {
+               rjs_engine_abort(rjs_engine_get(cpu), NULL);
+               return;
+       }
+
+       if (l)
+               list = ((rstring_t *)RVM_REG_GETP(l))->s.str;
+       else
+               list = " \t\n\r\0";
+       src = (rstring_t *)RVM_REG_GETP(r);
+       ptr = src->s.str;
+       size = src->s.size;
+       while (size > 0) {
+               if (!r_strchr(list, *ptr))
+                       break;
+               size--;
+               ptr++;
+       }
+       start = ptr;
+       ptr = start + size - 1;
+       while (size > 0) {
+               if (!r_strchr(list, *ptr))
+                       break;
+               size--;
+               ptr--;
+       }
+       dest = r_string_create_strsize(start, size);
+       rvm_gc_add(cpu->gc, (robject_t*)dest);
+       rvm_reg_setstring(RVM_CPUREG_PTR(cpu, R0), dest);
+}
+
+
+static rvm_switable_t swistring[] = {
+               {"ltrim", rjs_exec_ltrim},
+               {"rtrim", rjs_exec_rtrim},
+               {"trim", rjs_exec_trim},
+               {NULL, NULL},
+};
+
+
 void rjs_unmap_file(rstr_t *buf)
 {
        if (buf) {
@@ -135,7 +281,11 @@ void rjs_display_errors(rjs_engine_t *jse, rstr_t *script)
                err = (rjs_error_t *)r_array_slot(jse->errors, i);
                fprintf(stdout, "Line: %ld (%ld, %ld), Error Code: %ld, ", (rlong)err->line, err->offset, err->lineoffset, err->error);
                fprintf(stdout, "%s: ", errormsg[err->error]);
-               fwrite(script->str + err->lineoffset, sizeof(rchar), err->offset - err->lineoffset, stdout);
+               if (err->size) {
+                       fwrite(script->str + err->offset, sizeof(rchar), err->size, stdout);
+               } else {
+                       fwrite(script->str + err->lineoffset, sizeof(rchar), err->offset - err->lineoffset, stdout);
+               }
                fprintf(stdout, "\n");
        }
 }
@@ -151,6 +301,9 @@ int main(int argc, char *argv[])
        jse = rjs_engine_create();
        if (!jse)
                return 1;
+       if (rjs_engine_addswitable(jse, "string", swistring) < 0) {
+               return 2;
+       }
        for (i = 1; i < argc; i++) {
                if (r_strcmp(argv[i], "-L") == 0) {
 
index d52bf36..af3ccca 100644 (file)
@@ -22,6 +22,8 @@ typedef struct rjs_parser_s {
 rjs_parser_t *rjs_parser_create();
 void rjs_parser_destroy(rjs_parser_t *parser);
 rlong rjs_parser_exec(rjs_parser_t *parser, const rchar *script, rsize_t size, rarray_t *ast, rjs_error_t *error);
+rlong rjs_parser_offset2line(const rchar *script, rlong offset);
+rlong rjs_parser_offset2lineoffset(const rchar *script, rlong offset);
 
 
 #ifdef __cplusplus