}
+static rlong rjs_compiler_record2identifer(rjs_compiler_t *co, rarray_t *records, rlong rec)
+{
+ rlong i;
+ rvm_varmap_t *v = NULL;
+ rjs_coctx_t *ctx = NULL;
+ rparecord_t *prec = (rparecord_t *)r_array_slot(records, rec);
+
+ /*
+ * First lets find out if we are within a function definition or
+ * this is a global variable.
+ */
+ for (i = r_array_length(co->coctx) - 1; i >= 0; i--) {
+ ctx = r_array_index(co->coctx, i, rjs_coctx_t*);
+ if (ctx->type == RJS_COCTX_FUNCTION || ctx->type == RJS_COCTX_GLOBAL)
+ break;
+ }
+ R_ASSERT(ctx);
+
+ v = rvm_scope_tiplookup(co->scope, prec->input, prec->inputsiz);
+
+ /*
+ * TBD: Temporary here
+ */
+ if (v) {
+ r_printf("ERROR: Identifier already defined: %s\n", rjs_compiler_record2str(co, records, rec));
+ return -1;
+ }
+
+ if (ctx->type == RJS_COCTX_FUNCTION) {
+ rjs_coctx_function_t *functx = (rjs_coctx_function_t *)ctx;
+ functx->allocs += 1;
+ rvm_scope_addoffset(co->scope, prec->input, prec->inputsiz, functx->allocs);
+ } else {
+ rjs_coctx_global_t *functx = (rjs_coctx_global_t *)ctx;
+ functx->allocs += 1;
+ r_carray_setlength(co->cpu->data, functx->allocs + 1);
+ rvm_scope_addpointer(co->scope, prec->input, prec->inputsiz, r_carray_slot(co->cpu->data, functx->allocs));
+ }
+ v = rvm_scope_tiplookup(co->scope, prec->input, prec->inputsiz);
+ if (v->datatype == VARMAP_DATATYPE_OFFSET) {
+ rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRS, R0, FP, DA, v->data.offset));
+ } else {
+ rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R0, DA, XX, v->data.ptr));
+ }
+
+ return 0;
+}
+
+
rlong rjs_compiler_record2opcode(rparecord_t *prec)
{
const rchar *input = prec->input;
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) {
- rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, R0, XX, 0)); // Supposedly Array Address
+ 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, prec->inputsiz));
rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R2, DA, XX, (void*)prec->input));
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 Array Address
+ 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, prec->inputsiz));
rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R2, DA, XX, (void*)prec->input));
rvm_codegen_addins(co->cg, rvm_asm(RVM_OBJLKUP, R0, R1, R2, 0)); // Get the offset of the element at offset R0
}
+rint rjs_compiler_rh_memberexpressionindexop(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_PUSH, R0, XX, XX, 0)); // Supposedly an Array
+ 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 (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_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
+
+ } else {
+ rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0)); // Supposedly an Array
+ rvm_codegen_addins(co->cg, rvm_asm(RVM_LDOBJN, R0, R1, R0, 0)); // Get the value of the element at offset R0
+ }
+ rjs_compiler_debugtail(co, records, rec);
+ return 0;
+}
+
+
+rint rjs_compiler_rh_functiondeclaration(rjs_compiler_t *co, rarray_t *records, rlong rec)
+{
+ rjs_coctx_function_t ctx;
+ rparecord_t *prec;
+ rlong start, execidx, endidx, allocsidx;
+
+ r_memset(&ctx, 0, sizeof(ctx));
+ ctx.base.type = RJS_COCTX_FUNCTION;
+
+ prec = (rparecord_t *)r_array_slot(records, rec);
+ rjs_compiler_debughead(co, records, rec);
+ start = rvm_codegen_getcodesize(co->cg);
+ endidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__funend", start);
+ execidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__funexec", start);
+ allocsidx = rvm_codegen_invalid_add_numlabel_s(co->cg, "__allocs", start);
+
+ if (rpa_record_getruleuid(records, rpa_recordtree_firstchild(records, rec, RPA_RECORD_START)) != UID_FUNCTIONNAME)
+ goto error;
+ if (rjs_compiler_record2identifer(co, records, rpa_recordtree_firstchild(records, rec, RPA_RECORD_START)) < 0)
+ goto error;
+
+ rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, R0, XX, 0));
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_JUMP, execidx, rvm_asm(RVM_MOV, R0, DA, XX, 0));
+ rvm_codegen_addins(co->cg, rvm_asm(RVM_SETTYPE, R0, DA, XX, RVM_DTYPE_FUNCTION));
+ rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, endidx, rvm_asm(RVM_B, DA, XX, XX, 0));
+ rvm_codegen_redefinelabel(co->cg, execidx);
+ rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_DEFAULT, allocsidx, rvm_asm(RVM_ADD, SP, FP, DA, 0));
+
+ rjs_compiler_debugtail(co, records, rec);
+
+ r_array_push(co->coctx, &ctx, rjs_coctx_t*);
+ rvm_scope_push(co->scope);
+ 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_redefinelabel(co->cg, endidx);
+ rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xffffffff));
+ rvm_codegen_redefinepointer(co->cg, allocsidx, (rpointer)ctx.allocs);
+ rjs_compiler_debugtail(co, records, rec);
+
+ rvm_scope_pop(co->scope);
+ r_array_removelast(co->coctx);
+ return 0;
+
+error:
+ rvm_scope_pop(co->scope);
+ r_array_removelast(co->coctx);
+ return -1;
+}
+
+
+rint rjs_compiler_rh_functionparameter(rjs_compiler_t *co, rarray_t *records, rlong rec)
+{
+ rjs_coctx_t *ctx = NULL;
+ rjs_coctx_function_t *functx = NULL;
+ rparecord_t *prec;
+ rlong i;
+ rvm_varmap_t *v;
+
+ /*
+ * First lets find out if we are within a function definition or
+ * this is a global variable.
+ */
+ for (i = r_array_length(co->coctx) - 1; i >= 0; i--) {
+ ctx = r_array_index(co->coctx, i, rjs_coctx_t*);
+ if (ctx->type == RJS_COCTX_FUNCTION)
+ break;
+ }
+ R_ASSERT(ctx);
+ functx = (rjs_coctx_function_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);
+ v = rvm_scope_tiplookup(co->scope, prec->input, prec->inputsiz);
+
+ /*
+ * TBD: Temporary here
+ */
+ if (v) {
+ r_printf("ERROR: Identifier already defined: %s\n", rjs_compiler_record2str(co, records, rec));
+ return -1;
+ }
+
+ functx->allocs += 1;
+ rvm_scope_addoffset(co->scope, prec->input, prec->inputsiz, functx->allocs);
+
+ rjs_compiler_debugtail(co, records, rec);
+ return 0;
+}
+
+
rint rjs_compiler_rh_(rjs_compiler_t *co, rarray_t *records, rlong rec)
{
rparecord_t *prec;
co->handlers[UID_ASSIGNMENTEXPRESSIONOP] = rjs_compiler_rh_assignmentexpressionop;
co->handlers[UID_NEWARRAYEXPRESSION] = rjs_compiler_rh_newarrayexpression;
co->handlers[UID_MEMBEREXPRESSIONDOTOP] = rjs_compiler_rh_memberexpressiondotop;
+ co->handlers[UID_MEMBEREXPRESSIONINDEXOP] = rjs_compiler_rh_memberexpressionindexop;
+ co->handlers[UID_FUNCTIONDECLARATION] = rjs_compiler_rh_functiondeclaration;
+ co->handlers[UID_FUNCTIONPARAMETER] = rjs_compiler_rh_functionparameter;
return co;
}
rint rjs_compiler_compile(rjs_compiler_t *co, rarray_t *records)
{
rlong i;
+ rvm_codelabel_t *labelerr;
if (!co || !records || r_array_empty(records)) {
-
+ /*
+ * TBD
+ */
return -1;
}
for (i = 0; i >= 0; i = rpa_recordtree_next(records, i, RPA_RECORD_START)) {
if (rjs_compiler_playrecord(co, records, i) < 0)
+ /*
+ * TBD
+ */
return -1;
}
+
+ if (rvm_codegen_relocate(co->cg, &labelerr) < 0) {
+ /*
+ * TBD
+ */
+ return -1;
+ }
+
return 0;
}