RPA Toolkit
changed the callback parameters and added look ahead/back while parsing
[rpatk.git] / tests / rpagen-test.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <sys/types.h>
6 #include <fcntl.h>
7 #include <unistd.h>
8 #include <sys/mman.h>
9 #include "rmem.h"
10 #include "rvmcpu.h"
11 #include "rpadbex.h"
12 #include "rpaerror.h"
13 #include "rvmcodegen.h"
14 #include "rvmcodemap.h"
15 #include "rvmscope.h"
16 #include "rvmoperator.h"
17
18 #define DEBUGPRINT 1
19 static int debuginfo = 0;
20 static int parseinfo = 0;
21 static int verboseinfo = 0;
22 static int compileonly = 0;
23
24 typedef struct rvm_vardeclaration_s {
25         const rchar *varname;
26         ruint varnamesiz;
27         const rchar *val;
28         ruint valsiz;
29 } rvm_vardeclaration_t;
30
31
32 typedef struct rvm_fundecl_s {
33         const rchar *funname;
34         rword funnamesiz;
35         rword params;
36         rword codestart;
37         rword codesize;
38 } rvm_fundecl_t;
39
40
41 typedef struct rvm_funcall_s {
42         const rchar *funname;
43         rword funnamesiz;
44         rword params;
45 } rvm_funcall_t;
46
47
48 typedef enum {
49         RVM_CODESPAN_NONE = 0,
50         RVM_CODESPAN_LOOP,
51 } rvm_codespantype_t;
52
53 typedef struct rvm_codespan_s {
54         rvm_codespantype_t type;
55         rword codestart;
56         rword codesize;
57         rword l1;
58         rword l2;
59         rword l3;
60         rword l4;
61 } rvm_codespan_t;
62
63
64 typedef struct rvm_costat_s rvm_costat_t;
65
66 struct rvm_costat_s {
67         ruint binaryop;
68         ruint level;
69         ruint dirty;
70         ruint funcalls;
71         rvm_costat_t *root;
72 };
73
74 typedef struct rvm_compiler_s {
75         rpa_dbex_handle dbex;
76         rvm_codegen_t *cg;
77         rvm_scope_t *scope;
78         rarray_t *fp;
79         rarray_t *funcall;
80         rarray_t *fundecl;
81         rarray_t *opcodes;
82         rarray_t *codespan;
83         rarray_t *loops;
84         rarray_t *varmap;
85         rarray_t *stat;
86         rvmcpu_t *cpu;
87         rboolean optimized;
88 } rvm_compiler_t;
89
90
91
92 #define RVM_SAVEDREGS_FIRST 4
93 #define RVM_SAVEDREGS_MAX (RLST - (RLST - TP) - RVM_SAVEDREGS_FIRST - 1)
94
95
96 void rpagen_load_rules(rpa_dbex_handle dbex, rvm_compiler_t *co);
97
98 rvm_costat_t *rvm_costat_current(rvm_compiler_t *co)
99 {
100         return (rvm_costat_t *)r_array_lastslot(co->stat);
101 }
102
103
104 ruint rvm_costat_getdebth(rvm_compiler_t *co)
105 {
106         return r_array_length(co->stat);
107 }
108
109 ruint rvm_costat_getlevel(rvm_compiler_t *co)
110 {
111         if (!rvm_costat_current(co))
112                 return 0;
113         return rvm_costat_current(co)->level;
114 }
115
116
117 void rvm_costat_inclevel(rvm_compiler_t *co)
118 {
119         rvm_costat_current(co)->level += 1;
120         if (rvm_costat_current(co)->level > rvm_costat_current(co)->root->dirty)
121                 rvm_costat_current(co)->root->dirty = rvm_costat_current(co)->level;
122 }
123
124 void rvm_costat_declevel(rvm_compiler_t *co)
125 {
126         rvm_costat_current(co)->level -= 1;
127 }
128
129
130 ruint rvm_costat_getbinaryop(rvm_compiler_t *co)
131 {
132         if (!rvm_costat_current(co))
133                 return 0;
134         return rvm_costat_current(co)->binaryop;
135 }
136
137
138 void rvm_costat_incbinaryop(rvm_compiler_t *co)
139 {
140         rvm_costat_current(co)->binaryop += 1;
141 }
142
143
144 void rvm_costat_decbinaryop(rvm_compiler_t *co)
145 {
146         rvm_costat_current(co)->binaryop -= 1;
147 }
148
149 ruint rvm_costat_getdirty(rvm_compiler_t *co)
150 {
151         if (!rvm_costat_current(co))
152                 return 0;
153         return rvm_costat_current(co)->root->dirty;
154 }
155
156
157 void rvm_costat_push(rvm_compiler_t *co)
158 {
159         rvm_costat_t stat = *rvm_costat_current(co);
160         stat.binaryop = 0;
161         r_array_add(co->stat, &stat);
162 }
163
164
165 void rvm_costat_pushroot(rvm_compiler_t *co)
166 {
167         rvm_costat_t stat;
168         r_memset(&stat, 0, sizeof(stat));
169         r_array_add(co->stat, &stat);
170         rvm_costat_current(co)->root = rvm_costat_current(co);
171 }
172
173 void rvm_costat_pop(rvm_compiler_t *co)
174 {
175         r_array_removelast(co->stat);
176 }
177
178
179
180 rvm_compiler_t *rvm_compiler_create(rpa_dbex_handle dbex)
181 {
182         rvm_compiler_t *co;
183
184         co = r_malloc(sizeof(*co));
185         r_memset(co, 0, sizeof(*co));
186         co->cg = rvm_codegen_create();
187         co->scope = rvm_scope_create();
188         co->opcodes = r_array_create(sizeof(ruint));
189         co->fp = r_array_create(sizeof(rword));
190         co->funcall = r_array_create(sizeof(rvm_funcall_t));
191         co->stat = r_array_create(sizeof(rvm_costat_t));
192         co->fundecl = r_array_create(sizeof(rvm_fundecl_t));
193         co->codespan = r_array_create(sizeof(rvm_codespan_t));
194         co->loops = r_array_create(sizeof(rvm_codespan_t*));
195         co->varmap = r_array_create(sizeof(rvm_varmap_t*));
196         r_array_push(co->fp, 0, rword);
197         co->dbex = dbex;
198         return co;
199 }
200
201
202 void rvm_compiler_destroy(rvm_compiler_t *co)
203 {
204         if (co) {
205                 rvm_codegen_destroy(co->cg);
206                 rvm_scope_destroy(co->scope);
207                 r_object_destroy((robject_t*) co->opcodes);
208                 r_object_destroy((robject_t*) co->stat);
209                 r_object_destroy((robject_t*) co->fp);
210                 r_object_destroy((robject_t*) co->funcall);
211                 r_object_destroy((robject_t*) co->fundecl);
212                 r_object_destroy((robject_t*) co->codespan);
213                 r_object_destroy((robject_t*) co->varmap);
214                 r_object_destroy((robject_t*) co->loops);
215                 r_free(co);
216         }
217 }
218
219
220 static void test_swi_none(rvmcpu_t *cpu, rvm_asmins_t *ins)
221 {
222 }
223
224
225 static void rvm_swi_negative(rvmcpu_t *cpu, rvm_asmins_t *ins)
226 {
227         rvmreg_t *res = RVM_CPUREG_PTR(cpu, ins->op1);
228         rvmreg_t *arg = RVM_CPUREG_PTR(cpu, ins->op2);
229         rvmreg_t zero;
230
231         RVM_REG_CLEAR(&zero);
232         rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_SUB, cpu, res, &zero, arg);
233 }
234
235
236 static void rvm_swi_eadd(rvmcpu_t *cpu, rvm_asmins_t *ins)
237 {
238         rvmreg_t *res = RVM_CPUREG_PTR(cpu, R0);
239         rvmreg_t *arg1 = (rvmreg_t *)RVM_STACK_ADDR(cpu->stack, RVM_CPUREG_GETU(cpu, FP) + 1);
240         rvmreg_t *arg2 = (rvmreg_t *)RVM_STACK_ADDR(cpu->stack, RVM_CPUREG_GETU(cpu, FP) + 2);
241
242         rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_ADD, cpu, res, arg1, arg2);
243 }
244
245
246 static void rvm_swi_object(rvmcpu_t *cpu, rvm_asmins_t *ins)
247 {
248         rvmreg_t *res = RVM_CPUREG_PTR(cpu, R0);
249         rharray_t *a = r_harray_create_rvmreg();
250         rvm_reg_setharray(res, (robject_t*)a);
251 }
252
253
254 static rvm_switable_t switable[] = {
255                 {"none", test_swi_none},
256                 {"RVM_SWI_NEG", rvm_swi_negative},
257                 {"Object", rvm_swi_object},
258                 {"rvm_swi_eadd", rvm_swi_eadd},
259                 {NULL, NULL},
260 };
261
262
263 static void rvm_js_print(rvmcpu_t *cpu, rvm_asmins_t *ins)
264 {
265         rvmreg_t *r = (rvmreg_t *)RVM_STACK_ADDR(cpu->stack, RVM_CPUREG_GETU(cpu, FP) + 1);
266
267         if (rvm_reg_gettype(r) == RVM_DTYPE_UNSIGNED)
268                 r_printf("%lu\n", RVM_REG_GETU(r));
269         else if (rvm_reg_gettype(r) == RVM_DTYPE_NAN)
270                 r_printf("NaN\n");
271         else if (rvm_reg_gettype(r) == RVM_DTYPE_UNDEF)
272                 r_printf("undefined\n");
273         else if (rvm_reg_gettype(r) == RVM_DTYPE_BOOLEAN)
274                 r_printf("%s\n", RVM_REG_GETU(r) ? "true" : "false");
275         else if (rvm_reg_gettype(r) == RVM_DTYPE_POINTER)
276                 r_printf("%p\n", RVM_REG_GETP(r));
277         else if (rvm_reg_gettype(r) == RVM_DTYPE_LONG)
278                 r_printf("%ld\n", RVM_REG_GETL(r));
279         else if (rvm_reg_gettype(r) == RVM_DTYPE_DOUBLE)
280                 r_printf("%f\n", RVM_REG_GETD(r));
281         else if (rvm_reg_gettype(r) == RVM_DTYPE_STRING)
282                 r_printf("%s\n", ((rstring_t*) RVM_REG_GETP(r))->s.str);
283         else if (rvm_reg_gettype(r) == RVM_DTYPE_JSOBJECT)
284                 r_printf("(object) %p\n",RVM_REG_GETP(r));
285         else if (rvm_reg_gettype(r) == RVM_DTYPE_HARRAY)
286                 r_printf("(hashed array) %p\n",RVM_REG_GETP(r));
287         else if (rvm_reg_gettype(r) == RVM_DTYPE_SWIID)
288                 r_printf("(function) %p\n",RVM_REG_GETP(r));
289         else
290                 r_printf("%p\n", RVM_REG_GETP(r));
291 }
292
293 static rvm_switable_t switable_js[] = {
294                 {"print", rvm_js_print},
295                 {NULL, NULL},
296 };
297
298 inline int codegen_print_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
299 {
300         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
301         const rpa_recordpeek_t *rec = rpa_stat_record_lookahead(stat, 1);
302
303
304         if (parseinfo) {
305                 if (reason & RPA_REASON_START)
306                         fprintf(stdout, "START ");
307                 if (reason & RPA_REASON_MATCHED)
308                         fprintf(stdout, "MATCHED ");
309                 if (reason & RPA_REASON_END)
310                         fprintf(stdout, "END ");
311                 fprintf(stdout, "%s: ", name);
312                 if (!(reason & RPA_REASON_START))
313                                 fwrite(input, sizeof(char), size, stdout);
314                 if (rec)
315                         fprintf(stdout, "(next name: %s)", rec->name);
316                 fprintf(stdout, " (debth: %d, level: %d, binaryop: %d, dirty: %d)", rvm_costat_getdebth(co), rvm_costat_getlevel(co), rvm_costat_getbinaryop(co), rvm_costat_getdirty(co));
317                 fprintf(stdout, "\n");
318                 fflush(stdout);
319         }
320
321         return size;
322 }
323
324
325 void codegen_dump_code(rvm_asmins_t *code, rulong size)
326 {
327         if (parseinfo)
328                 rvm_asm_dump(code, size);
329 }
330
331
332 int codegen_opcode_unary_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
333 {
334         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
335
336         if (r_stringncmp("-", input, size))
337                 r_array_push(co->opcodes, RVM_OPSWI(rvm_cpu_getswi_s(co->cpu, "RVM_SWI_NEG")), ruint);
338         else if (r_stringncmp("+", input, size))
339                 r_array_push(co->opcodes, RVM_NOP, ruint);
340         else if (r_stringncmp("!", input, size))
341                 r_array_push(co->opcodes, RVM_ELNOT, ruint);
342         else if (r_stringncmp("~", input, size))
343                 r_array_push(co->opcodes, RVM_ENOT, ruint);
344         else if (r_stringncmp("delete", input, size))
345                 r_array_push(co->opcodes, RVM_NOP, ruint);
346         else if (r_stringncmp("void", input, size))
347                 r_array_push(co->opcodes, RVM_NOP, ruint);
348         else if (r_stringncmp("typeof", input, size))
349                 r_array_push(co->opcodes, RVM_NOP, ruint);
350         else
351                 r_array_push(co->opcodes, RVM_ABORT, ruint);
352
353         codegen_print_callback(stat, name, userdata, input, size, reason);
354         return size;
355 }
356
357
358 int codegen_opcode_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
359 {
360         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
361
362         if (r_stringncmp("++", input,  size))
363                 r_array_push(co->opcodes, RVM_EADD, ruint);
364         else if (r_stringncmp("+", input,  size))
365                 r_array_push(co->opcodes, RVM_EADD, ruint);
366         else if (r_stringncmp("+=", input,  size))
367                 r_array_push(co->opcodes, RVM_EADD, ruint);
368         else if (r_stringncmp("--", input,  size))
369                 r_array_push(co->opcodes, RVM_ESUB, ruint);
370         else if (r_stringncmp("-", input,  size))
371                 r_array_push(co->opcodes, RVM_ESUB, ruint);
372         else if (r_stringncmp("-=", input,  size))
373                 r_array_push(co->opcodes, RVM_ESUB, ruint);
374         else if (r_stringncmp("*", input,  size))
375                 r_array_push(co->opcodes, RVM_EMUL, ruint);
376         else if (r_stringncmp("*=", input,  size))
377                 r_array_push(co->opcodes, RVM_EMUL, ruint);
378         else if (r_stringncmp("/", input,  size))
379                 r_array_push(co->opcodes, RVM_EDIV, ruint);
380         else if (r_stringncmp("/=", input,  size))
381                 r_array_push(co->opcodes, RVM_EDIV, ruint);
382         else if (r_stringncmp("%", input,  size))
383                 r_array_push(co->opcodes, RVM_EMOD, ruint);
384         else if (r_stringncmp("%=", input,  size))
385                 r_array_push(co->opcodes, RVM_EMOD, ruint);
386         else if (r_stringncmp("&&", input,  size))
387                 r_array_push(co->opcodes, RVM_ELAND, ruint);
388         else if (r_stringncmp("||", input,  size))
389                 r_array_push(co->opcodes, RVM_ELOR, ruint);
390         else if (r_stringncmp("&", input,  size))
391                 r_array_push(co->opcodes, RVM_EAND, ruint);
392         else if (r_stringncmp("&=", input,  size))
393                 r_array_push(co->opcodes, RVM_EAND, ruint);
394         else if (r_stringncmp("|", input,  size))
395                 r_array_push(co->opcodes, RVM_EORR, ruint);
396         else if (r_stringncmp("|=", input,  size))
397                 r_array_push(co->opcodes, RVM_EORR, ruint);
398         else if (r_stringncmp("^", input,  size))
399                 r_array_push(co->opcodes, RVM_EXOR, ruint);
400         else if (r_stringncmp("^=", input,  size))
401                 r_array_push(co->opcodes, RVM_EXOR, ruint);
402         else if (r_stringncmp(">>", input,  size))
403                 r_array_push(co->opcodes, RVM_ELSR, ruint);
404         else if (r_stringncmp(">>=", input,  size))
405                 r_array_push(co->opcodes, RVM_ELSR, ruint);
406         else if (r_stringncmp("<<", input,  size))
407                 r_array_push(co->opcodes, RVM_ELSL, ruint);
408         else if (r_stringncmp("<<=", input,  size))
409                 r_array_push(co->opcodes, RVM_ELSL, ruint);
410         else if (r_stringncmp(">>>", input,  size))
411                 r_array_push(co->opcodes, RVM_ELSRU, ruint);
412         else if (r_stringncmp(">>>=", input,  size))
413                 r_array_push(co->opcodes, RVM_ELSRU, ruint);
414         else if (r_stringncmp("<=", input,  size))
415                 r_array_push(co->opcodes, RVM_ELESSEQ, ruint);
416         else if (r_stringncmp(">=", input,  size))
417                 r_array_push(co->opcodes, RVM_EGREATEQ, ruint);
418         else if (r_stringncmp("<", input,  size))
419                 r_array_push(co->opcodes, RVM_ELESS, ruint);
420         else if (r_stringncmp(">", input,  size))
421                 r_array_push(co->opcodes, RVM_EGREAT, ruint);
422         else if (r_stringncmp("===", input,  size))
423                 r_array_push(co->opcodes, RVM_EEQ, ruint);
424         else if (r_stringncmp("==", input,  size))
425                 r_array_push(co->opcodes, RVM_EEQ, ruint);
426         else if (r_stringncmp("!==", input,  size))
427                 r_array_push(co->opcodes, RVM_ENOTEQ, ruint);
428         else if (r_stringncmp("!=", input,  size))
429                 r_array_push(co->opcodes, RVM_ENOTEQ, ruint);
430         else if (r_stringncmp("!", input,  size))
431                 r_array_push(co->opcodes, RVM_ELNOT, ruint);
432         else if (r_stringncmp("~", input,  size))
433                 r_array_push(co->opcodes, RVM_ENOT, ruint);
434         else if (r_stringncmp("=", input,  size))
435                 r_array_push(co->opcodes, RVM_NOP, ruint);
436         else
437                 r_array_push(co->opcodes, RVM_ABORT, ruint);
438
439         codegen_print_callback(stat, name, userdata, input, size, reason);
440         return size;
441 }
442
443
444 int codegen_binary_asmop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
445 {
446         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
447         rulong off = rvm_codegen_getcodesize(co->cg);
448
449         if (reason & RPA_REASON_START) {
450                 rvm_costat_inclevel(co);
451                 rvm_costat_incbinaryop(co);
452         } else if (reason & RPA_REASON_MATCHED) {
453                 ruint op1;
454                 ruint opcode = r_array_pop(co->opcodes, ruint);
455
456                 if (rvm_costat_getlevel(co) < RVM_SAVEDREGS_MAX) {
457                         op1 = rvm_costat_getlevel(co) + RVM_SAVEDREGS_FIRST - 1;
458                 } else {
459                         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
460                         op1 = R1;
461                 }
462                 rvm_codegen_addins(co->cg, rvm_asm(opcode, R0, op1, R0, 0));
463                 rvm_costat_declevel(co);
464                 rvm_costat_decbinaryop(co);
465         } else if (reason & RPA_REASON_END) {
466                 rvm_costat_declevel(co);
467                 rvm_costat_decbinaryop(co);
468         }
469
470         codegen_print_callback(stat, name, userdata, input, size, reason);
471         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
472
473         return size;
474 }
475
476
477 int codegen_valop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
478 {
479         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
480         rulong off = rvm_codegen_getcodesize(co->cg);
481         rvm_asmins_t *last = rvm_codegen_getcode(co->cg, off - 1);
482
483         if ((reason & RPA_REASON_START) && rvm_costat_getbinaryop(co)) {
484                 if (rvm_costat_getlevel(co) < RVM_SAVEDREGS_MAX) {
485                         if (co->optimized && last->op1 == R0 && (last->opcode == RVM_MOV || last->opcode == RVM_LDRR ||
486                                         last->opcode == RVM_LDS || (last->opcode >= RVM_EADD && last->opcode <= RVM_ELESSEQ))) {
487                                 last->op1 = rvm_costat_getlevel(co) + RVM_SAVEDREGS_FIRST - 1;
488                                 off -= 1;
489                         } else {
490                                 rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, rvm_costat_getlevel(co) + RVM_SAVEDREGS_FIRST - 1, R0, XX, 0));
491                         }
492                 } else {
493                         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
494                 }
495         }
496
497
498         if (reason & RPA_REASON_MATCHED) {
499
500         }
501
502         codegen_print_callback(stat, name, userdata, input, size, reason);
503         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
504
505         return size;
506 }
507
508
509 int codegen_conditionalexp_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
510 {
511         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
512         rulong off = rvm_codegen_getcodesize(co->cg);
513
514         codegen_print_callback(stat, name, userdata, input, size, reason);
515         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
516
517         return size;
518 }
519
520
521 int codegen_unary_asmop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
522 {
523         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
524         rulong off = rvm_codegen_getcodesize(co->cg);
525         ruint op1 = rvm_costat_getlevel(co) ? RVM_SAVEDREGS_FIRST - 1 + rvm_costat_getlevel(co) : R0;
526
527         if (reason & RPA_REASON_START) {
528         }
529
530         if (reason & RPA_REASON_MATCHED) {
531                 ruint opcode = r_array_pop(co->opcodes, ruint);
532                 rvm_codegen_addins(co->cg, rvm_asm(opcode, op1, op1, XX, 0));
533         }
534
535         if (reason & RPA_REASON_END) {
536         }
537
538         codegen_print_callback(stat, name, userdata, input, size, reason);
539         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
540         return size;
541 }
542
543
544 int codegen_costate_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
545 {
546         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
547         rulong off = rvm_codegen_getcodesize(co->cg);
548
549         if (reason & RPA_REASON_START) {
550                 rvm_costat_push(co);
551         }
552
553         if (reason & RPA_REASON_END) {
554                 rvm_costat_pop(co);
555         }
556
557         codegen_print_callback(stat, name, userdata, input, size, reason);
558         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
559         return size;
560 }
561
562
563 int codegen_push_r0_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
564 {
565         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
566         rulong off = rvm_codegen_getcodesize(co->cg);
567
568         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
569
570         codegen_print_callback(stat, name, userdata, input, size, reason);
571         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
572
573         return size;
574 }
575
576
577 int codegen_integer_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
578 {
579         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
580         rulong off = rvm_codegen_getcodesize(co->cg);
581
582         rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R0, DA, XX, r_strtol(input, NULL, 10)));
583
584         codegen_print_callback(stat, name, userdata, input, size, reason);
585         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
586
587         return size;
588 }
589
590
591 int codegen_printop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
592 {
593         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
594         rulong off = rvm_codegen_getcodesize(co->cg);
595
596         rvm_codegen_addins(co->cg, rvm_asmd(RVM_PRN, R0, DA, XX, 0));
597
598         codegen_print_callback(stat, name, userdata, input, size, reason);
599         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
600
601         return size;
602 }
603
604
605 int codegen_double_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
606 {
607         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
608         rulong off = rvm_codegen_getcodesize(co->cg);
609
610         rvm_codegen_addins(co->cg, rvm_asmd(RVM_MOV, R0, DA, XX, r_strtod(input, NULL)));
611
612         codegen_print_callback(stat, name, userdata, input, size, reason);
613         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
614
615         return size;
616 }
617
618
619 int codegen_string_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
620 {
621         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
622         rulong off = rvm_codegen_getcodesize(co->cg);
623
624         rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R1, DA, XX, (void*)input));
625         rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R2, DA, XX, size));
626         rvm_codegen_addins(co->cg, rvm_asm(RVM_ALLOCSTR, R0, R1, R2, 0));
627
628         codegen_print_callback(stat, name, userdata, input, size, reason);
629         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
630
631         return size;
632 }
633
634
635 int codegen_program_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
636 {
637         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
638         ruint off;
639
640         if (reason & RPA_REASON_START) {
641                 off = rvm_codegen_getcodesize(co->cg);
642                 rvm_costat_pushroot(co);
643                 rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
644                 rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
645         } else {
646                 rvm_codegen_replaceins(co->cg, 0, rvm_asm(RVM_MOV, FP, SP, XX, 0));
647                 rvm_codegen_replaceins(co->cg, 1, rvm_asm(RVM_ADD, SP, SP, DA, r_array_pop(co->fp, rword)));
648                 off = rvm_codegen_getcodesize(co->cg);
649                 if (debuginfo)
650                         rvm_codegen_addins(co->cg, rvm_asm(RVM_PRN, R0, XX, XX, 0));
651                 rvm_codegen_addins(co->cg, rvm_asm(RVM_EXT, XX, XX, XX, 0));
652         }
653
654
655         codegen_print_callback(stat, name, userdata, input, size, reason);
656         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
657
658         if (reason & RPA_REASON_END) {
659                 rvm_costat_pop(co);
660         }
661         return size;
662 }
663
664
665 int codegen_opinit_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
666 {
667         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
668         rulong off = rvm_codegen_getcodesize(co->cg);
669
670         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
671         rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
672
673         codegen_print_callback(stat, name, userdata, input, size, reason);
674         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
675
676         return size;
677 }
678
679
680 int codegen_opassign_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
681 {
682         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
683         rulong off = rvm_codegen_getcodesize(co->cg);
684         ruint opcode = r_array_pop(co->opcodes, ruint);
685
686         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
687         if (opcode != RVM_NOP) {
688                 rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R2, R1, XX, 0));
689                 rvm_codegen_addins(co->cg, rvm_asm(opcode, R0, R2, R0, 0));
690         }
691         rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
692
693         codegen_print_callback(stat, name, userdata, input, size, reason);
694         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
695
696         return size;
697 }
698
699
700 int codegen_oppostfix_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
701 {
702         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
703         rulong off = rvm_codegen_getcodesize(co->cg);
704         ruint opcode = r_array_pop(co->opcodes, ruint);
705
706         rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, R0, XX, 0));
707         rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R0, R1, XX, 0));
708         rvm_codegen_addins(co->cg, rvm_asm(opcode, R2, R0, DA, 1));
709         rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R2, R1, XX, 0));
710
711
712         codegen_print_callback(stat, name, userdata, input, size, reason);
713         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
714
715         return size;
716 }
717
718
719 int codegen_opprefix_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
720 {
721         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
722         rulong off = rvm_codegen_getcodesize(co->cg);
723         ruint opcode = r_array_pop(co->opcodes, ruint);
724
725         rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, R0, XX, 0));
726         rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R0, R1, XX, 0));
727         rvm_codegen_addins(co->cg, rvm_asm(opcode, R0, R0, DA, 1));
728         rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
729
730         codegen_print_callback(stat, name, userdata, input, size, reason);
731         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
732
733         return size;
734 }
735
736
737 int codegen_ptr_deref_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
738 {
739         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
740         rulong off = rvm_codegen_getcodesize(co->cg);
741
742         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));    // Address
743         rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R0, R1, XX, 0));   // Load the value from offset
744         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));   // Push it on the stack
745
746         codegen_print_callback(stat, name, userdata, input, size, reason);
747         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
748
749         return size;
750 }
751
752
753 int codegen_arrayelementvalue_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
754 {
755         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
756         rulong off = rvm_codegen_getcodesize(co->cg);
757
758         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));    // Array
759         rvm_codegen_addins(co->cg, rvm_asm(RVM_LDOBJN, R0, R1, R0, 0)); // Load the value from array offset
760
761         codegen_print_callback(stat, name, userdata, input, size, reason);
762         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
763
764         return size;
765 }
766
767
768 int codegen_memberexpressionbase_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
769 {
770         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
771         rulong off = rvm_codegen_getcodesize(co->cg);
772
773         rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R0, R0, XX, 0));   // Array Address
774         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));   // Array -> On Stack
775
776         codegen_print_callback(stat, name, userdata, input, size, reason);
777         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
778
779         return size;
780 }
781
782
783 int codegen_n_arrayelementaddress_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
784 {
785         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
786         rulong off = rvm_codegen_getcodesize(co->cg);
787
788         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));    // Supposedly Array Address
789         rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDROBJN, R0, R1, R0, 0));       // Get the address of the element at offset R0
790
791         codegen_print_callback(stat, name, userdata, input, size, reason);
792         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
793
794         return size;
795 }
796
797
798 int codegen_h_arrayelementaddress_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
799 {
800         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
801         rulong off = rvm_codegen_getcodesize(co->cg);
802
803 //      rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));    // Supposedly Array Address
804         rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDROBJH, R0, R1, R0, 0));       // Get the address of the element at offset R0
805
806         codegen_print_callback(stat, name, userdata, input, size, reason);
807         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
808
809         return size;
810 }
811
812
813 int codegen_h_arraynamelookupadd_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
814 {
815         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
816         rulong off = rvm_codegen_getcodesize(co->cg);
817
818         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));    // Supposedly Array or Array Address
819         rvm_codegen_addins(co->cg, rvm_asm(RVM_TYPE, R0, R1, XX, 0));
820         rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R0, DA, XX, RVM_DTYPE_POINTER));
821         rvm_codegen_addins(co->cg, rvm_asm(RVM_BNEQ, DA, XX, XX, 2));
822         rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R1, R1, XX, 0));
823         rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, size));
824         rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R2, DA, XX, (void*)input));
825         rvm_codegen_addins(co->cg, rvm_asm(RVM_OBJLKUPADD, R0, R1, R2, 0));     // Get the address of the element at offset R0
826
827         codegen_print_callback(stat, name, userdata, input, size, reason);
828         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
829
830         return size;
831 }
832
833
834 int codegen_h_arraynamelookup_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
835 {
836         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
837         rulong off = rvm_codegen_getcodesize(co->cg);
838
839         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));    // Supposedly Array Address
840         rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, size));
841         rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R2, DA, XX, (void*)input));
842         rvm_codegen_addins(co->cg, rvm_asm(RVM_OBJLKUP, R0, R1, R2, 0));        // Get the address of the element at offset R0
843
844         codegen_print_callback(stat, name, userdata, input, size, reason);
845         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
846
847         return size;
848 }
849
850
851 int codegen_h_arrayelementvalue_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
852 {
853         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
854         rulong off = rvm_codegen_getcodesize(co->cg);
855
856 //      rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));    // Supposedly Array Address
857         rvm_codegen_addins(co->cg, rvm_asm(RVM_LDOBJH, R0, R1, R0, 0)); // Get the address of the element at offset R0
858
859         codegen_print_callback(stat, name, userdata, input, size, reason);
860         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
861
862         return size;
863 }
864
865
866 int codegen_swiidexist_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
867 {
868         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
869         rint swi = rvm_cpu_getswi(co->cpu, input, size);
870
871         if (swi < 0)
872                 return 0;
873
874
875         return size;
876 }
877
878
879 int codegen_swiid_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
880 {
881         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
882         rulong off = rvm_codegen_getcodesize(co->cg);
883         rint swi = rvm_cpu_getswi(co->cpu, input, size);
884
885         if (swi < 0)
886                 return 0;
887
888         rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, swi));
889         rvm_codegen_addins(co->cg, rvm_asm(RVM_SETTYPE, R0, DA, XX, RVM_DTYPE_SWIID));
890
891         codegen_print_callback(stat, name, userdata, input, size, reason);
892         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
893
894         return size;
895 }
896
897
898 int codegen_opidentifier_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
899 {
900         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
901         rulong off = rvm_codegen_getcodesize(co->cg);
902         rvm_varmap_t *v = rvm_scope_lookup(co->scope, input, size);
903
904         if (v) {
905                 if (v->datatype == VARMAP_DATATYPE_OFFSET) {
906                         rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRS, R0, FP, DA, v->data.offset));
907                 } else {
908                         rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R0, DA, XX, v->data.ptr));
909                 }
910                 codegen_print_callback(stat, name, userdata, input, size, reason);
911                 codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
912
913                 return size;
914         }
915
916         fprintf(stdout, "ERROR: undefined variable: ");
917         fwrite(input, sizeof(char), size, stdout);
918         fprintf(stdout, "\n");
919         rpa_dbex_abort(co->dbex);
920         return 0;
921 }
922
923
924 int codegen_validentifierop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
925 {
926         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
927         rulong off = rvm_codegen_getcodesize(co->cg);
928         rvm_varmap_t *v = rvm_scope_lookup(co->scope, input, size);
929
930         if (v) {
931                 if (v->datatype == VARMAP_DATATYPE_OFFSET) {
932                         rvm_codegen_addins(co->cg, rvm_asm(RVM_LDS, R0, FP, DA, v->data.offset));
933                 } else {
934                         rvm_codegen_addins(co->cg, rvm_asmp(RVM_LDRR, R0, DA, XX, v->data.ptr));
935                 }
936                 codegen_print_callback(stat, name, userdata, input, size, reason);
937                 codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
938
939                 return size;
940         }
941
942         fprintf(stdout, "ERROR: undefined variable: ");
943         fwrite(input, sizeof(char), size, stdout);
944         fprintf(stdout, "\n");
945         rpa_dbex_abort(co->dbex);
946         return 0;
947 }
948
949
950 int codegen_varalloc_to_ptr_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
951 {
952         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
953         rulong off = rvm_codegen_getcodesize(co->cg);
954         rvm_varmap_t *v = rvm_scope_tiplookup(co->scope, input, size);
955         if (v) {
956                 fprintf(stdout, "ERROR: variable already defined: ");
957                 fwrite(input, sizeof(char), size, stdout);
958                 fprintf(stdout, "\n");
959                 rpa_dbex_abort(co->dbex);
960                 return 0;
961         }
962
963         if (rvm_scope_count(co->scope)) {
964                 r_array_inclast(co->fp, rword);
965                 rvm_scope_addoffset(co->scope, input, size, r_array_last(co->fp, rword));
966         } else {
967                 rvm_scope_addpointer(co->scope, input, size, r_carray_slot_expand(co->cpu->data, r_carray_length(co->cpu->data)));
968                 r_carray_inclength(co->cpu->data);
969         }
970         v = rvm_scope_tiplookup(co->scope, input, size);
971
972         if (v->datatype == VARMAP_DATATYPE_OFFSET) {
973                 rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRS, R0, FP, DA, v->data.offset));
974         } else {
975                 rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R0, DA, XX, v->data.ptr));
976         }
977         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
978
979         codegen_print_callback(stat, name, userdata, input, size, reason);
980         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
981
982         return size;
983 }
984
985
986 int codegen_varalloc_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
987 {
988         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
989         rulong off = rvm_codegen_getcodesize(co->cg);
990         rvm_varmap_t *v = rvm_scope_tiplookup(co->scope, input, size);
991         if (v) {
992                 fprintf(stdout, "ERROR: variable already defined: ");
993                 fwrite(input, sizeof(char), size, stdout);
994                 fprintf(stdout, "\n");
995                 rpa_dbex_abort(co->dbex);
996                 return 0;
997         }
998
999         if (rvm_scope_count(co->scope)) {
1000                 r_array_inclast(co->fp, rword);
1001                 rvm_scope_addoffset(co->scope, input, size, r_array_last(co->fp, rword));
1002         } else {
1003                 rvm_scope_addpointer(co->scope, input, size, r_carray_slot_expand(co->cpu->data, r_carray_length(co->cpu->data)));
1004                 r_carray_inclength(co->cpu->data);
1005         }
1006
1007         v = rvm_scope_tiplookup(co->scope, input, size);
1008         if (v->datatype == VARMAP_DATATYPE_OFFSET) {
1009                 rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRS, R1, FP, DA, v->data.offset));
1010         } else {
1011                 rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R1, DA, XX, v->data.ptr));
1012         }
1013         rvm_codegen_addins(co->cg, rvm_asm(RVM_CLRR, R1, XX, XX, 0));
1014
1015         codegen_print_callback(stat, name, userdata, input, size, reason);
1016         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1017
1018         return size;
1019 }
1020
1021
1022 int codegen_newarraysize_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1023 {
1024         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1025         rulong off = rvm_codegen_getcodesize(co->cg);
1026
1027         rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, R0, XX, 0));
1028         rvm_codegen_addins(co->cg, rvm_asm(RVM_ALLOCOBJ, R0, R1, XX, 0));
1029
1030         codegen_print_callback(stat, name, userdata, input, size, reason);
1031         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1032
1033         return size;
1034 }
1035
1036
1037 int codegen_newarraynosize_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1038 {
1039         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1040         rulong off = rvm_codegen_getcodesize(co->cg);
1041
1042         rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, DA, XX, 0));
1043         rvm_codegen_addins(co->cg, rvm_asm(RVM_ALLOCOBJ, R0, R1, XX, 0));
1044
1045         codegen_print_callback(stat, name, userdata, input, size, reason);
1046         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1047
1048         return size;
1049 }
1050
1051
1052 int codegen_scopepush_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1053 {
1054         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1055         rulong off = rvm_codegen_getcodesize(co->cg);
1056
1057         rvm_scope_push(co->scope);
1058         codegen_print_callback(stat, name, userdata, input, size, reason);
1059         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1060
1061         return size;
1062 }
1063
1064
1065 int codegen_scopepop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1066 {
1067         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1068         rulong off = rvm_codegen_getcodesize(co->cg);
1069
1070         rvm_scope_pop(co->scope);
1071         codegen_print_callback(stat, name, userdata, input, size, reason);
1072         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1073
1074         return size;
1075 }
1076
1077
1078 int codegen_compile_error_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1079 {
1080         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1081         fprintf(stdout, "COMPILE ERROR pos: %ld\n", (long) (input - rpa_stat_input_start(stat)));
1082         rpa_dbex_abort(co->dbex);
1083         return 0;
1084 }
1085
1086
1087 int codegen_funcallparameter_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1088 {
1089         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1090         rulong off = rvm_codegen_getcodesize(co->cg);
1091         rvm_funcall_t *funcall = (rvm_funcall_t *)r_array_slot(co->funcall, r_array_length(co->funcall) - 1);
1092
1093         funcall->params += 1;
1094         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
1095         codegen_print_callback(stat, name, userdata, input, size, reason);
1096         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1097
1098         return size;
1099 }
1100
1101
1102 int codegen_funcallname_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1103 {
1104         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1105         rulong off = rvm_codegen_getcodesize(co->cg);
1106         rvm_funcall_t funcall = {input, size, 0};
1107
1108         r_array_add(co->funcall, &funcall);
1109
1110
1111         /*
1112          * R0 holds the label of the called function, we save on the stack
1113          * and FP will point there. After the call we save the LR at that spot
1114          * as we don't need the RO anymore.
1115          */
1116 //      rvm_codegen_addins(co->cg, rvm_asm(RVM_TYPE, R1, R0, XX, 0));
1117 //      rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R1, DA, XX, RVM_DTYPE_POINTER));
1118 //      rvm_codegen_addins(co->cg, rvm_asm(RVM_BNEQ, DA, XX, XX, 2));
1119 //      rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R0, R0, XX, 0));
1120
1121         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(TP)|BIT(FP)|BIT(SP)));
1122         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
1123
1124         codegen_print_callback(stat, name, userdata, input, size, reason);
1125         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1126
1127         return size;
1128 }
1129
1130
1131 int codegen_funcallexpression_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1132 {
1133         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1134         rulong off = rvm_codegen_getcodesize(co->cg);
1135         rvm_funcall_t *funcall = r_array_empty(co->funcall) ? NULL : (rvm_funcall_t *) r_array_slot(co->funcall, r_array_length(co->funcall) - 1);
1136
1137         rvm_codegen_addins(co->cg, rvm_asm(RVM_SUB, FP, SP, DA, funcall->params));
1138         rvm_codegen_addins(co->cg, rvm_asm(RVM_LDS, R1, FP, XX, 0));
1139         rvm_codegen_addins(co->cg, rvm_asm(RVM_STS, LR, FP, XX, 0));
1140         rvm_codegen_addins(co->cg, rvm_asm(RVM_CALL, R1, DA, XX, -rvm_codegen_getcodesize(co->cg)));
1141         rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, SP, FP, XX, 0));
1142         rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BITS(TP,LR)));
1143
1144         r_array_removelast(co->funcall);
1145         codegen_print_callback(stat, name, userdata, input, size, reason);
1146         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1147
1148         return size;
1149 }
1150
1151
1152 int codegen_fundeclparameter_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1153 {
1154         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1155         rulong off = rvm_codegen_getcodesize(co->cg);
1156         rvm_fundecl_t *fundecl = (rvm_fundecl_t *)r_array_lastslot(co->fundecl);
1157         rvm_varmap_t *v = rvm_scope_tiplookup(co->scope, input, size);
1158         if (v) {
1159                 fprintf(stdout, "ERROR: variable already defined: ");
1160                 fwrite(input, sizeof(char), size, stdout);
1161                 fprintf(stdout, "\n");
1162                 rpa_dbex_abort(co->dbex);
1163                 return 0;
1164         }
1165
1166         fundecl->params += 1;
1167         r_array_inclast(co->fp, rword);
1168         rvm_scope_addoffset(co->scope, input, size, r_array_last(co->fp, rword));
1169         codegen_print_callback(stat, name, userdata, input, size, reason);
1170         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1171
1172         return size;
1173 }
1174
1175
1176 int codegen_fundeclname_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1177 {
1178         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1179         rulong off;
1180         rvm_fundecl_t fundecl = {input, size, 0, 0};
1181         rint ret;
1182
1183         ret = codegen_varalloc_callback(stat, name, userdata, input, size, reason);
1184         if (ret == 0)
1185                 return ret;
1186
1187         off = rvm_codegen_getcodesize(co->cg);
1188         fundecl.codestart = off;
1189
1190         rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, 0));    /* Will be re-written later */
1191         rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, DA, R0, XX, 0));   /* Will be re-written later */
1192         rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, 0));              /* Will be re-written later */
1193         rvm_codegen_addins(co->cg, rvm_asm(RVM_ADD, SP, FP, DA, 0));    /* Will be re-written later */
1194         rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xffffffff));
1195 //      rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xffffffff));
1196
1197         r_array_push(co->fp, 0, rword);
1198         r_array_add(co->fundecl, &fundecl);
1199         rvm_scope_push(co->scope);
1200         rvm_costat_pushroot(co);
1201
1202         codegen_print_callback(stat, name, userdata, input, size, reason);
1203         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1204         return size;
1205 }
1206
1207
1208
1209 int codegen_fundeclsignature_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1210 {
1211         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1212         rulong off = rvm_codegen_getcodesize(co->cg);
1213
1214 //      rvm_codemap_add(cg->codemap, fundecl->funname, fundecl->funnamesiz, rvm_codegen_getcodesize(co->cg));
1215
1216         codegen_print_callback(stat, name, userdata, input, size, reason);
1217         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1218
1219         return size;
1220 }
1221
1222
1223 int codegen_fundecl_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1224 {
1225         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1226         rulong off = rvm_codegen_getcodesize(co->cg);
1227         rvm_fundecl_t *fundecl = (rvm_fundecl_t *)r_array_lastslot(co->fundecl);
1228         rvm_varmap_t *fname;
1229         rword fp = r_array_pop(co->fp, rword);
1230         rvm_scope_pop(co->scope);
1231         fname = rvm_scope_tiplookup(co->scope, fundecl->funname, fundecl->funnamesiz);
1232
1233         /*
1234          * Function end, we first define the function end
1235          */
1236         if (rvm_costat_getdirty(co))
1237                 rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BITS(RVM_SAVEDREGS_FIRST, RVM_SAVEDREGS_FIRST+ rvm_costat_getdirty(co) - 1)));
1238         rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
1239
1240         /*
1241          * the number of arguments passed is = SP - FP
1242          */
1243         fundecl->codesize = rvm_codegen_getcodesize(co->cg) - fundecl->codestart;
1244         if (fname->datatype == VARMAP_DATATYPE_OFFSET) {
1245                 rvm_codegen_replaceins(co->cg, fundecl->codestart + 0, rvm_asm(RVM_ADDRS, R0, FP, DA, fname->data.offset));
1246         } else {
1247                 rvm_codegen_replaceins(co->cg, fundecl->codestart + 0, rvm_asmp(RVM_MOV, R0, DA, XX, fname->data.ptr));
1248         }
1249         rvm_codegen_replaceins(co->cg, fundecl->codestart + 1, rvm_asm(RVM_STRR, DA, R0, XX, fundecl->codestart + 3));
1250         rvm_codegen_replaceins(co->cg, fundecl->codestart + 2, rvm_asm(RVM_B, DA, XX, XX, fundecl->codesize - 2));
1251         rvm_codegen_replaceins(co->cg, fundecl->codestart + 3, rvm_asm(RVM_ADD, SP, FP, DA, fp));
1252         if (rvm_costat_getdirty(co))
1253                 rvm_codegen_replaceins(co->cg, fundecl->codestart + 4, rvm_asm(RVM_PUSHM, DA, XX, XX, BITS(RVM_SAVEDREGS_FIRST, RVM_SAVEDREGS_FIRST + rvm_costat_getdirty(co) - 1)));
1254
1255         fundecl->codesize = rvm_codegen_getcodesize(co->cg) - fundecl->codestart;
1256         fundecl->params = r_array_last(co->fp, rword);
1257
1258         r_array_removelast(co->fundecl);
1259         rvm_costat_pop(co);
1260         codegen_print_callback(stat, name, userdata, input, size, reason);
1261         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1262
1263         return size;
1264 }
1265
1266
1267 int codegen_opreturn_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1268 {
1269         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1270         rulong off = rvm_codegen_getcodesize(co->cg);
1271
1272         if (rvm_costat_getdirty(co))
1273                 rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BITS(RVM_SAVEDREGS_FIRST, RVM_SAVEDREGS_FIRST + rvm_costat_getdirty(co) - 1)));
1274         rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
1275
1276         codegen_print_callback(stat, name, userdata, input, size, reason);
1277         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1278
1279         return size;
1280 }
1281
1282
1283 int codegen_ifconditionop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1284 {
1285         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1286         rulong off = rvm_codegen_getcodesize(co->cg);
1287         rvm_codespan_t cs = {RVM_CODESPAN_NONE, 0, 0, 0, 0, 0, 0};
1288
1289         cs.codestart = rvm_codegen_getcodesize(co->cg);
1290         r_array_add(co->codespan, &cs);
1291
1292         rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R0, DA, XX, 0));
1293         rvm_codegen_addins(co->cg, rvm_asm(RVM_BEQ, DA, XX, XX, -1));   //This has to be redefined when we know the size of the code block
1294
1295         codegen_print_callback(stat, name, userdata, input, size, reason);
1296         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1297
1298         return size;
1299 }
1300
1301
1302 int codegen_ifop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1303 {
1304         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1305         rulong off = rvm_codegen_getcodesize(co->cg);
1306         rvm_codespan_t cs = r_array_pop(co->codespan, rvm_codespan_t);
1307
1308         cs.codesize = rvm_codegen_getcodesize(co->cg) - cs.codestart;
1309         rvm_codegen_replaceins(co->cg, cs.codestart + 1, rvm_asm(RVM_BEQ, DA, XX, XX, cs.codesize - 1));        //This has to be redefined when we know the size of the code block
1310
1311         codegen_print_callback(stat, name, userdata, input, size, reason);
1312         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1313
1314         return size;
1315 }
1316
1317
1318 int codegen_elseop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1319 {
1320         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1321         rulong off = rvm_codegen_getcodesize(co->cg);
1322         rvm_codespan_t cs = r_array_pop(co->codespan, rvm_codespan_t);
1323
1324         rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, - 1));            // Branch to the end of the else block, has to be redefined
1325         cs.codesize = rvm_codegen_getcodesize(co->cg) - cs.codestart;
1326         rvm_codegen_replaceins(co->cg, cs.codestart + 1, rvm_asm(RVM_BEQ, DA, XX, XX, cs.codesize - 1));        // Branch to the begining of the else block
1327
1328         /* Reuse the cs to define the *else* codespan */
1329         cs.codestart = rvm_codegen_getcodesize(co->cg);
1330         cs.codesize = 0;
1331         r_array_add(co->codespan, &cs);
1332
1333         codegen_print_callback(stat, name, userdata, input, size, reason);
1334         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1335
1336         return size;
1337 }
1338
1339
1340 int codegen_ifelseop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1341 {
1342         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1343         rulong off = rvm_codegen_getcodesize(co->cg);
1344         rvm_codespan_t cs = r_array_pop(co->codespan, rvm_codespan_t);
1345
1346         cs.codesize = rvm_codegen_getcodesize(co->cg) - cs.codestart;
1347         rvm_codegen_replaceins(co->cg, cs.codestart - 1, rvm_asm(RVM_B, DA, XX, XX, cs.codesize));      //Branch to the end of the else block, now we know the size
1348
1349         codegen_print_callback(stat, name, userdata, input, size, reason);
1350         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1351
1352         return size;
1353 }
1354
1355
1356 int codegen_dokeyword_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1357 {
1358         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1359         rulong off = rvm_codegen_getcodesize(co->cg);
1360         rvm_codespan_t cs = {RVM_CODESPAN_NONE, 0, 0, 0, 0, 0, 0};
1361
1362         cs.codestart = rvm_codegen_getcodesize(co->cg);
1363         r_array_add(co->codespan, &cs);
1364
1365         codegen_print_callback(stat, name, userdata, input, size, reason);
1366         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1367         return size;
1368 }
1369
1370
1371 int codegen_iterationdo_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1372 {
1373         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1374         rulong off = rvm_codegen_getcodesize(co->cg);
1375         rvm_codespan_t cs = r_array_pop(co->codespan, rvm_codespan_t);
1376         rvm_asmins_t *last = rvm_codegen_getcode(co->cg, off - 1);
1377
1378         if (last->op1 == R0 && last->opcode >= RVM_EADD && last->opcode <= RVM_ELESSEQ) {
1379                 /*
1380                  * Nothing to do, the status register will be updated.
1381                  */
1382         } else {
1383                 rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R0, DA, XX, 0));
1384         }
1385
1386         cs.codesize = rvm_codegen_getcodesize(co->cg) - cs.codestart;
1387         rvm_codegen_addins(co->cg, rvm_asm(RVM_BNEQ, DA, XX, XX, -cs.codesize));
1388         rvm_codemap_poploopblock(co->cg->codemap);
1389
1390         codegen_print_callback(stat, name, userdata, input, size, reason);
1391         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1392         return size;
1393 }
1394
1395
1396 int codegen_whileconditionop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1397 {
1398         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1399         rulong off = rvm_codegen_getcodesize(co->cg);
1400         rvm_codespan_t *cs = (rvm_codespan_t*)r_array_lastslot(co->codespan);
1401
1402         rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R0, DA, XX, 0));
1403         cs->l1 = rvm_codegen_getcodesize(co->cg);
1404         rvm_codegen_addins(co->cg, rvm_asm(RVM_BEQ, DA, XX, XX, -1));   //This has to be redefined when we know the size of the code block
1405
1406         codegen_print_callback(stat, name, userdata, input, size, reason);
1407         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1408
1409         return size;
1410 }
1411
1412
1413 int codegen_iterationwhileop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1414 {
1415         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1416         rulong off = rvm_codegen_getcodesize(co->cg);
1417
1418         if (reason & RPA_REASON_START) {
1419                 rvm_codespan_t cs = {RVM_CODESPAN_NONE, 0, 0, 0, 0, 0, 0};
1420
1421                 cs.codestart = rvm_codegen_getcodesize(co->cg);
1422                 r_array_add(co->codespan, &cs);
1423         } else if (reason & RPA_REASON_MATCHED) {
1424                 rvm_codespan_t cs = r_array_pop(co->codespan, rvm_codespan_t);
1425
1426                 cs.codesize = rvm_codegen_getcodesize(co->cg) + 1 - cs.codestart;
1427                 rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, -(cs.codesize - 1)));
1428 //              rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, DA, XX, XX, 0xaaaaa));
1429
1430                 rvm_codegen_replaceins(co->cg, cs.l1, rvm_asm(RVM_BEQ, DA, XX, XX, cs.codesize - (cs.l1 - cs.codestart)));      // Re-writing the instruction
1431         } else if (reason & RPA_REASON_END) {
1432                 rvm_codespan_t cs = r_array_pop(co->codespan, rvm_codespan_t);
1433                 cs.codesize = rvm_codegen_getcodesize(co->cg) - cs.codestart;
1434         }
1435
1436         codegen_print_callback(stat, name, userdata, input, size, reason);
1437         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1438
1439         return size;
1440 }
1441
1442
1443 int codegen_questionmarkop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1444 {
1445         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1446         rulong off = rvm_codegen_getcodesize(co->cg);
1447         rvm_codespan_t cs = {RVM_CODESPAN_NONE, 0, 0, 0, 0, 0, 0};
1448
1449         cs.codestart = rvm_codegen_getcodesize(co->cg);
1450         rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R0, DA, XX, 0));
1451         cs.l1 = rvm_codegen_getcodesize(co->cg);
1452         rvm_codegen_addins(co->cg, rvm_asm(RVM_BEQ, DA, XX, XX, 0)); // This will be re-written
1453         r_array_add(co->codespan, &cs);
1454
1455         codegen_print_callback(stat, name, userdata, input, size, reason);
1456         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1457
1458         return size;
1459 }
1460
1461
1462 int codegen_iftrueop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1463 {
1464         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1465         rulong off = rvm_codegen_getcodesize(co->cg);
1466         rvm_codespan_t *cs = (rvm_codespan_t*) r_array_lastslot(co->codespan);
1467
1468         cs->l2 = rvm_codegen_getcodesize(co->cg);
1469         rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, 0)); // This will be re-written
1470         rvm_codegen_replaceins(co->cg, cs->l1, rvm_asm(RVM_BEQ, DA, XX, XX, rvm_codegen_getcodesize(co->cg) - cs->l1)); // Re-writing the instruction
1471
1472         codegen_print_callback(stat, name, userdata, input, size, reason);
1473         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1474
1475         return size;
1476 }
1477
1478
1479 int codegen_iffalseop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1480 {
1481         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1482         rulong off = rvm_codegen_getcodesize(co->cg);
1483         rvm_codespan_t cs = r_array_pop(co->codespan, rvm_codespan_t);
1484
1485         rvm_codegen_replaceins(co->cg, cs.l2, rvm_asm(RVM_B, DA, XX, XX, rvm_codegen_getcodesize(co->cg) - cs.l2));     // Re-writing the instruction
1486
1487         codegen_print_callback(stat, name, userdata, input, size, reason);
1488         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1489
1490         return size;
1491 }
1492
1493
1494 int codegen_breakkeyword_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1495 {
1496         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1497         rulong off = rvm_codegen_getcodesize(co->cg);
1498         rvm_codespan_t *cs = (rvm_codespan_t *)r_array_last(co->loops, rvm_codespan_t*);
1499
1500         if (cs->type != RVM_CODESPAN_LOOP) {
1501                 return 0;
1502         }
1503
1504         rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, -(rvm_codegen_getcodesize(co->cg) - cs->l2)));
1505
1506
1507         codegen_print_callback(stat, name, userdata, input, size, reason);
1508         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1509         return size;
1510 }
1511
1512
1513 int codegen_continuekeyword_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1514 {
1515         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1516         rulong off = rvm_codegen_getcodesize(co->cg);
1517         rvm_codespan_t *cs = (rvm_codespan_t *)r_array_last(co->loops, rvm_codespan_t*);
1518
1519         if (cs->type != RVM_CODESPAN_LOOP) {
1520                 return 0;
1521         }
1522
1523         rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, -(rvm_codegen_getcodesize(co->cg) - cs->l3)));
1524
1525
1526         codegen_print_callback(stat, name, userdata, input, size, reason);
1527         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1528         return size;
1529 }
1530
1531
1532 int codegen_forkeyword_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1533 {
1534         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1535         rulong off = rvm_codegen_getcodesize(co->cg);
1536         rvm_codespan_t cs = {RVM_CODESPAN_LOOP, 0, 0, 0, 0, 0, 0};
1537
1538         cs.codestart = rvm_codegen_getcodesize(co->cg);
1539         r_array_add(co->codespan, &cs);
1540         rvm_scope_push(co->scope);
1541         r_array_push(co->loops, r_array_lastslot(co->codespan), rvm_codespan_t*);
1542
1543         codegen_print_callback(stat, name, userdata, input, size, reason);
1544         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1545         return size;
1546 }
1547
1548
1549 int codegen_forinitop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1550 {
1551         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1552         rulong off = rvm_codegen_getcodesize(co->cg);
1553         rvm_codespan_t *cs = (rvm_codespan_t *)r_array_lastslot(co->codespan);
1554
1555
1556         cs->l1 = rvm_codegen_getcodesize(co->cg);
1557         rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, 1)); // This will be re-written, when we know the start point of the comparison expression
1558         cs->l2 = rvm_codegen_getcodesize(co->cg);
1559         rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, 1)); // Break point, This will be re-written.
1560         cs->l3 = rvm_codegen_getcodesize(co->cg);
1561
1562         codegen_print_callback(stat, name, userdata, input, size, reason);
1563         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1564         return size;
1565 }
1566
1567 /*
1568  * The code generated for the increment expression will appear before the comparison expression
1569  * due to the trick we did in the BNF schema. That will make the implementation of the for ( ; ; ) loops
1570  * a lot more easier and the generated code having less branch instructions
1571  */
1572 int codegen_forincrementop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1573 {
1574         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1575         rulong off = rvm_codegen_getcodesize(co->cg);
1576         rvm_codespan_t *cs = (rvm_codespan_t *)r_array_lastslot(co->codespan);
1577
1578         rvm_codegen_replaceins(co->cg, cs->l1, rvm_asm(RVM_B, DA, XX, XX, rvm_codegen_getcodesize(co->cg) - cs->l1));   // Re-writing the instruction
1579
1580         codegen_print_callback(stat, name, userdata, input, size, reason);
1581         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1582         return size;
1583 }
1584
1585
1586 int codegen_forcompareop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1587 {
1588         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1589         rulong off = rvm_codegen_getcodesize(co->cg);
1590         rvm_codespan_t *cs = (rvm_codespan_t *)r_array_lastslot(co->codespan);
1591
1592         rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R0, DA, XX, 0));
1593         cs->l4 = rvm_codegen_getcodesize(co->cg);
1594         rvm_codegen_addins(co->cg, rvm_asm(RVM_BEQ, DA, XX, XX, 0)); // This will be re-written when we know the size of the code inside the loop.
1595         /*
1596          * The beginning loop starts here, right after the RVM_BEQ instruction.
1597          */
1598
1599         codegen_print_callback(stat, name, userdata, input, size, reason);
1600         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1601         return size;
1602 }
1603
1604
1605 int codegen_iterationforop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1606 {
1607         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1608         rulong off = rvm_codegen_getcodesize(co->cg);
1609         rvm_codespan_t cs = r_array_pop(co->codespan, rvm_codespan_t);
1610
1611         rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, -(rvm_codegen_getcodesize(co->cg) - (cs.l3))));
1612         cs.codesize = rvm_codegen_getcodesize(co->cg) - cs.codestart;
1613         rvm_codegen_replaceins(co->cg, cs.l4, rvm_asm(RVM_BEQ, DA, XX, XX, cs.codesize - (cs.l4 - cs.codestart)));
1614         rvm_codegen_replaceins(co->cg, cs.l2, rvm_asm(RVM_B, DA, XX, XX, cs.codesize - (cs.l2 - cs.codestart)));        // Re-writing the instruction
1615
1616         rvm_scope_pop(co->scope);
1617         r_array_removelast(co->loops);
1618
1619         codegen_print_callback(stat, name, userdata, input, size, reason);
1620         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1621         return size;
1622 }
1623
1624
1625 int codegen_newexpressionop_callback(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
1626 {
1627         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1628         rulong off = rvm_codegen_getcodesize(co->cg);
1629
1630         if (reason & RPA_REASON_START) {
1631
1632         } else  if (reason & RPA_REASON_MATCHED) {
1633
1634         }
1635
1636
1637         rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
1638
1639
1640         codegen_print_callback(stat, name, userdata, input, size, reason);
1641         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1642         return size;
1643 }
1644
1645
1646 void codegen_unmap_file(rstr_t *buf)
1647 {
1648         if (buf) {
1649                 munmap(buf->str, buf->size);
1650                 r_free(buf);
1651         }
1652 }
1653
1654
1655 rstr_t *codegen_map_file(const char *filename)
1656 {
1657         struct stat st;
1658         rstr_t *str;
1659         char *buffer;
1660
1661
1662         int fd = open(filename, O_RDONLY);
1663         if (fd < 0) {
1664                 return (void*)0;
1665         }
1666         if (fstat(fd, &st) < 0) {
1667                 close(fd);
1668                 return (void*)0;
1669         }
1670         buffer = (char*)mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
1671         if (buffer == (void*)-1) {
1672                 close(fd);
1673                 return (void*)0;
1674         }
1675         str = (rstr_t *)r_malloc(sizeof(*str));
1676         if (!str)
1677                 goto error;
1678         r_memset(str, 0, sizeof(*str));
1679         str->str = buffer;
1680         str->size = st.st_size;
1681         close(fd);
1682         return str;
1683
1684 error:
1685         munmap(buffer, st.st_size);
1686         close(fd);
1687         return str;
1688 }
1689
1690
1691 int main(int argc, char *argv[])
1692 {
1693         int res, i;
1694         rstr_t *script = NULL, *unmapscript = NULL;
1695         rvmcpu_t *cpu;
1696         ruint ntable;
1697         rpa_dbex_handle dbex = rpa_dbex_create();
1698         rvm_compiler_t *co = rvm_compiler_create(dbex);
1699
1700         cpu = rvm_cpu_create_default();
1701         ntable = rvm_cpu_addswitable(cpu, switable);
1702         rvm_cpu_addswitable(cpu, switable_js);
1703         co->cpu = cpu;
1704
1705         rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
1706         rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
1707         rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
1708         rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
1709
1710         for (i = 1; i < argc; i++) {
1711                 if (r_strcmp(argv[i], "-L") == 0) {
1712                 } else if (r_strcmp(argv[i], "-d") == 0) {
1713                         debuginfo = 1;
1714                 } else if (r_strcmp(argv[i], "-p") == 0) {
1715                         parseinfo = 1;
1716                 } else if (r_strcmp(argv[i], "-P") == 0) {
1717                         parseinfo = 1;
1718                         verboseinfo = 1;
1719                 } else if (r_strcmp(argv[i], "-c") == 0) {
1720                         compileonly = 1;
1721                 } else if (r_strcmp(argv[i], "-o") == 0) {
1722                         co->optimized = 1;
1723                 } else if (r_strcmp(argv[i], "-m") == 0) {
1724
1725                 }
1726         }
1727
1728         rpagen_load_rules(dbex, co);
1729
1730         for (i = 1; i < argc; i++) {
1731                 if (r_strcmp(argv[i], "-e") == 0) {
1732                         if (++i < argc) {
1733                                 rstr_t script = { argv[i], r_strlen(argv[i]) };
1734                                 res = rpa_dbex_parse(dbex, rpa_dbex_default_pattern(dbex), script.str, script.str, script.str + script.size);
1735                                 if (res <= 0)
1736                                         rvm_codegen_clear(co->cg);
1737                         }
1738                         goto exec;
1739                 }
1740         }
1741
1742         for (i = 1; i < argc; i++) {
1743                 if (r_strcmp(argv[i], "-f") == 0) {
1744
1745                         if (++i < argc) {
1746                                 script = codegen_map_file(argv[i]);
1747                                 if (script) {
1748                                         res = rpa_dbex_parse(dbex, rpa_dbex_default_pattern(dbex), script->str, script->str, script->str + script->size);
1749                                         unmapscript = script;
1750                                 }
1751
1752                         }
1753                         goto exec;
1754                 }
1755         }
1756
1757
1758 exec:
1759         rvm_relocate(rvm_codegen_getcode(co->cg, 0), rvm_codegen_getcodesize(co->cg));
1760
1761         if (debuginfo) {
1762                 fprintf(stdout, "\nGenerated Code:\n");
1763                 rvm_asm_dump(rvm_codegen_getcode(co->cg, 0), rvm_codegen_getcodesize(co->cg));
1764                 if (rvm_codegen_getcodesize(co->cg)) {
1765                         if (!compileonly) {
1766                                 fprintf(stdout, "\nExecution:\n");
1767                                 rvm_cpu_exec_debug(cpu, rvm_codegen_getcode(co->cg, 0), 0);
1768                         }
1769                 }
1770         } else {
1771                 if (!compileonly)
1772                         rvm_cpu_exec(cpu, rvm_codegen_getcode(co->cg, 0), 0);
1773         }
1774
1775         if (unmapscript)
1776                 codegen_unmap_file(unmapscript);
1777         rpa_dbex_destroy(dbex);
1778         rvm_cpu_destroy(cpu);
1779         rvm_compiler_destroy(co);
1780
1781         if (debuginfo) {
1782                 r_printf("Max alloc mem: %ld\n", r_debug_get_maxmem());
1783                 r_printf("Leaked mem: %ld\n", r_debug_get_allocmem());
1784         }
1785         return 0;
1786 }
1787
1788
1789 #define EOL "\n"
1790
1791
1792 extern char _binary_____________tests_ecma262_rpa_start[];
1793 extern char _binary_____________tests_ecma262_rpa_end[];
1794 extern unsigned long *_binary_____________tests_ecma262_rpa_size;
1795
1796 void rpagen_load_rules(rpa_dbex_handle dbex, rvm_compiler_t *co)
1797 {
1798         int ret, line;
1799         int inputsize = _binary_____________tests_ecma262_rpa_end - _binary_____________tests_ecma262_rpa_start;
1800         const char *buffer = _binary_____________tests_ecma262_rpa_start;
1801         const char *pattern = buffer;
1802
1803         rpa_dbex_open(dbex);
1804
1805         rpa_dbex_add_callback_exact(dbex, "BitwiseANDOp", RPA_REASON_ALL, codegen_binary_asmop_callback, co);
1806         rpa_dbex_add_callback_exact(dbex, "BitwiseXOROp", RPA_REASON_ALL, codegen_binary_asmop_callback, co);
1807         rpa_dbex_add_callback_exact(dbex, "BitwiseOROp", RPA_REASON_ALL, codegen_binary_asmop_callback, co);
1808         rpa_dbex_add_callback_exact(dbex, "AdditiveExpressionOp", RPA_REASON_ALL, codegen_binary_asmop_callback, co);
1809
1810         rpa_dbex_add_callback_exact(dbex, "MultiplicativeExpressionOp", RPA_REASON_ALL, codegen_binary_asmop_callback, co);
1811         rpa_dbex_add_callback_exact(dbex, "ShiftExpressionOp", RPA_REASON_ALL, codegen_binary_asmop_callback, co);
1812         rpa_dbex_add_callback_exact(dbex, "EqualityExpressionOp", RPA_REASON_ALL, codegen_binary_asmop_callback, co);
1813         rpa_dbex_add_callback_exact(dbex, "RelationalExpressionOp", RPA_REASON_ALL, codegen_binary_asmop_callback, co);
1814         rpa_dbex_add_callback_exact(dbex, "LogicalOROp", RPA_REASON_ALL, codegen_binary_asmop_callback, co);
1815         rpa_dbex_add_callback_exact(dbex, "LogicalANDOp", RPA_REASON_ALL, codegen_binary_asmop_callback, co);
1816
1817         rpa_dbex_add_callback_exact(dbex, "AssignmentOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1818         rpa_dbex_add_callback_exact(dbex, "EqualityOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1819         rpa_dbex_add_callback_exact(dbex, "RelationalOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1820         rpa_dbex_add_callback_exact(dbex, "AdditiveOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1821         rpa_dbex_add_callback_exact(dbex, "MultiplicativeOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1822         rpa_dbex_add_callback_exact(dbex, "ShiftOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1823         rpa_dbex_add_callback_exact(dbex, "BitwiseANDOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1824         rpa_dbex_add_callback_exact(dbex, "BitwiseXOROperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1825         rpa_dbex_add_callback_exact(dbex, "BitwiseOROperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1826         rpa_dbex_add_callback_exact(dbex, "LogicalANDOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1827         rpa_dbex_add_callback_exact(dbex, "LogicalOROperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1828         rpa_dbex_add_callback_exact(dbex, "LogicalNotOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1829         rpa_dbex_add_callback_exact(dbex, "BitwiseNotOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1830         rpa_dbex_add_callback_exact(dbex, "UnaryOperatorOpcode", RPA_REASON_MATCHED, codegen_opcode_unary_callback, co);
1831         rpa_dbex_add_callback_exact(dbex, "PrintOp", RPA_REASON_MATCHED, codegen_printop_callback, co);
1832
1833
1834         rpa_dbex_add_callback_exact(dbex, "PostfixOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1835         rpa_dbex_add_callback_exact(dbex, "PostfixExpressionOp", RPA_REASON_MATCHED, codegen_oppostfix_callback, co);
1836         rpa_dbex_add_callback_exact(dbex, "PrefixExpressionOp", RPA_REASON_MATCHED, codegen_opprefix_callback, co);
1837
1838
1839         rpa_dbex_add_callback_exact(dbex, "UnaryExpressionOp", RPA_REASON_ALL, codegen_unary_asmop_callback, co);
1840         rpa_dbex_add_callback_exact(dbex, "LogicalNotExpressionOp", RPA_REASON_ALL, codegen_unary_asmop_callback, co);
1841         rpa_dbex_add_callback_exact(dbex, "BitwiseNotExpressionOp", RPA_REASON_ALL, codegen_unary_asmop_callback, co);
1842
1843         rpa_dbex_add_callback_exact(dbex, "DecimalIntegerLiteral", RPA_REASON_MATCHED, codegen_integer_callback, co);
1844         rpa_dbex_add_callback_exact(dbex, "DecimalNonIntegerLiteral", RPA_REASON_MATCHED, codegen_double_callback, co);
1845         rpa_dbex_add_callback_exact(dbex, "BlockBegin", RPA_REASON_MATCHED, codegen_scopepush_callback, co);
1846         rpa_dbex_add_callback_exact(dbex, "BlockEnd", RPA_REASON_MATCHED, codegen_scopepop_callback, co);
1847
1848         rpa_dbex_add_callback_exact(dbex, "DoKeyword", RPA_REASON_MATCHED, codegen_dokeyword_callback, co);
1849         rpa_dbex_add_callback_exact(dbex, "IterationDo", RPA_REASON_MATCHED, codegen_iterationdo_callback, co);
1850
1851         rpa_dbex_add_callback_exact(dbex, "sqstring", RPA_REASON_MATCHED, codegen_string_callback, co);
1852         rpa_dbex_add_callback_exact(dbex, "dqstring", RPA_REASON_MATCHED, codegen_string_callback, co);
1853         rpa_dbex_add_callback_exact(dbex, "DoubleStringCharacters", RPA_REASON_MATCHED, codegen_string_callback, co);
1854         rpa_dbex_add_callback_exact(dbex, "SingleStringCharacters", RPA_REASON_MATCHED, codegen_string_callback, co);
1855         rpa_dbex_add_callback_exact(dbex, "Program", RPA_REASON_START|RPA_REASON_MATCHED, codegen_program_callback, co);
1856         rpa_dbex_add_callback_exact(dbex, "Initialiser", RPA_REASON_MATCHED, codegen_opinit_callback, co);
1857         rpa_dbex_add_callback_exact(dbex, "AssignmentExpressionOp", RPA_REASON_MATCHED, codegen_opassign_callback, co);
1858
1859         rpa_dbex_add_callback_exact(dbex, "VariableAllocate", RPA_REASON_MATCHED, codegen_varalloc_callback, co);
1860         rpa_dbex_add_callback_exact(dbex, "VariableAllocateAndInit", RPA_REASON_MATCHED, codegen_varalloc_to_ptr_callback, co);
1861
1862         rpa_dbex_add_callback_exact(dbex, "ReturnOp", RPA_REASON_MATCHED, codegen_opreturn_callback, co);
1863
1864         rpa_dbex_add_callback_exact(dbex, "SwiId", RPA_REASON_MATCHED, codegen_swiid_callback, co);
1865         rpa_dbex_add_callback_exact(dbex, "SwiIdExist", RPA_REASON_MATCHED, codegen_swiidexist_callback, co);
1866
1867         rpa_dbex_add_callback_exact(dbex, "IdentifierOp", RPA_REASON_MATCHED, codegen_opidentifier_callback, co);
1868         rpa_dbex_add_callback_exact(dbex, "ValIdentifierOp", RPA_REASON_MATCHED, codegen_validentifierop_callback, co);
1869         rpa_dbex_add_callback_exact(dbex, "PostfixExpressionValOp", RPA_REASON_ALL, codegen_valop_callback, co);
1870
1871         rpa_dbex_add_callback_exact(dbex, "LeftHandSideExpressionPush", RPA_REASON_MATCHED, codegen_push_r0_callback, co);
1872
1873         rpa_dbex_add_callback_exact(dbex, "MemberExpressionBaseOp", RPA_REASON_MATCHED, codegen_memberexpressionbase_callback, co);
1874         rpa_dbex_add_callback_exact(dbex, "MemberExpressionIndexOp", RPA_REASON_MATCHED, codegen_n_arrayelementaddress_callback, co);
1875
1876         rpa_dbex_add_callback_exact(dbex, "MemberExpressionNameOp", RPA_REASON_MATCHED, codegen_h_arrayelementaddress_callback, co);
1877         rpa_dbex_add_callback_exact(dbex, "CallExpressionNameOp", RPA_REASON_MATCHED, codegen_h_arrayelementaddress_callback, co);
1878         rpa_dbex_add_callback_exact(dbex, "MemberIdentifierNameOp", RPA_REASON_MATCHED, codegen_h_arraynamelookupadd_callback, co);
1879         rpa_dbex_add_callback_exact(dbex, "MemberIdentifierNameLookupOp", RPA_REASON_MATCHED, codegen_h_arraynamelookup_callback, co);
1880         rpa_dbex_add_callback_exact(dbex, "ValMemberExpressionNameOp", RPA_REASON_MATCHED, codegen_h_arrayelementvalue_callback, co);
1881         rpa_dbex_add_callback_exact(dbex, "ValCallExpressionNameOp", RPA_REASON_MATCHED, codegen_h_arrayelementvalue_callback, co);
1882
1883
1884         rpa_dbex_add_callback_exact(dbex, "ValMemberExpressionBaseOp", RPA_REASON_MATCHED, codegen_push_r0_callback, co);
1885         rpa_dbex_add_callback_exact(dbex, "ValMemberExpressionIndexOp", RPA_REASON_MATCHED, codegen_arrayelementvalue_callback, co);
1886
1887         rpa_dbex_add_callback_exact(dbex, "CallExpressionBaseOp", RPA_REASON_MATCHED, codegen_push_r0_callback, co);
1888         rpa_dbex_add_callback_exact(dbex, "CallExpressionIndexOp", RPA_REASON_MATCHED, codegen_n_arrayelementaddress_callback, co);
1889
1890
1891         rpa_dbex_add_callback_exact(dbex, "ValCallExpressionBaseOp", RPA_REASON_MATCHED, codegen_push_r0_callback, co);
1892         rpa_dbex_add_callback_exact(dbex, "ValCallExpressionIndexOp", RPA_REASON_MATCHED, codegen_arrayelementvalue_callback, co);
1893
1894         rpa_dbex_add_callback_exact(dbex, "ConditionalExpression", RPA_REASON_MATCHED, codegen_conditionalexp_callback, co);
1895
1896         rpa_dbex_add_callback_exact(dbex, "NewArraySize", RPA_REASON_MATCHED, codegen_newarraysize_callback, co);
1897         rpa_dbex_add_callback_exact(dbex, "NewArrayNoSize", RPA_REASON_MATCHED, codegen_newarraynosize_callback, co);
1898         rpa_dbex_add_callback_exact(dbex, "compile_error", RPA_REASON_MATCHED, codegen_compile_error_callback, co);
1899
1900         rpa_dbex_add_callback_exact(dbex, "ArgumentsOp", RPA_REASON_ALL, codegen_costate_callback, co);
1901         rpa_dbex_add_callback_exact(dbex, "BracketExpressionOp", RPA_REASON_ALL, codegen_costate_callback, co);
1902         rpa_dbex_add_callback_exact(dbex, "ValLeftHandSideExpression", RPA_REASON_ALL, codegen_costate_callback, co);
1903
1904
1905         rpa_dbex_add_callback_exact(dbex, "FunctionName", RPA_REASON_MATCHED, codegen_fundeclname_callback, co);
1906         rpa_dbex_add_callback_exact(dbex, "FunctionDefinition", RPA_REASON_MATCHED, codegen_fundeclsignature_callback, co);
1907         rpa_dbex_add_callback_exact(dbex, "FunctionDeclaration", RPA_REASON_MATCHED, codegen_fundecl_callback, co);
1908         rpa_dbex_add_callback_exact(dbex, "FunctionParameter", RPA_REASON_MATCHED, codegen_fundeclparameter_callback, co);
1909         rpa_dbex_add_callback_exact(dbex, "FunctionCallParameter", RPA_REASON_MATCHED, codegen_funcallparameter_callback, co);
1910         rpa_dbex_add_callback_exact(dbex, "FunctionCallName", RPA_REASON_MATCHED, codegen_funcallname_callback, co);
1911         rpa_dbex_add_callback_exact(dbex, "CallExpressionOp", RPA_REASON_MATCHED, codegen_funcallexpression_callback, co);
1912
1913         rpa_dbex_add_callback_exact(dbex, "ValFunctionCallName", RPA_REASON_MATCHED, codegen_funcallname_callback, co);
1914         rpa_dbex_add_callback_exact(dbex, "ValCallExpressionOp", RPA_REASON_MATCHED, codegen_funcallexpression_callback, co);
1915
1916
1917         rpa_dbex_add_callback_exact(dbex, "IfConditionOp", RPA_REASON_MATCHED, codegen_ifconditionop_callback, co);
1918         rpa_dbex_add_callback_exact(dbex, "IfOp", RPA_REASON_MATCHED, codegen_ifop_callback, co);
1919         rpa_dbex_add_callback_exact(dbex, "ElseOp", RPA_REASON_MATCHED, codegen_elseop_callback, co);
1920         rpa_dbex_add_callback_exact(dbex, "IfElseOp", RPA_REASON_MATCHED, codegen_ifelseop_callback, co);
1921
1922         rpa_dbex_add_callback_exact(dbex, "WhileConditionOp", RPA_REASON_MATCHED, codegen_whileconditionop_callback, co);
1923         rpa_dbex_add_callback_exact(dbex, "IterationWhileOp", RPA_REASON_ALL, codegen_iterationwhileop_callback, co);
1924
1925         rpa_dbex_add_callback_exact(dbex, "QuestionMarkOp", RPA_REASON_MATCHED, codegen_questionmarkop_callback, co);
1926         rpa_dbex_add_callback_exact(dbex, "AssignmentExpressionIfTrueOp", RPA_REASON_MATCHED, codegen_iftrueop_callback, co);
1927         rpa_dbex_add_callback_exact(dbex, "AssignmentExpressionIfFalseOp", RPA_REASON_MATCHED, codegen_iffalseop_callback, co);
1928
1929         rpa_dbex_add_callback_exact(dbex, "ForKeyword", RPA_REASON_MATCHED, codegen_forkeyword_callback, co);
1930         rpa_dbex_add_callback_exact(dbex, "ForExpressionInitOp", RPA_REASON_END, codegen_forinitop_callback, co);
1931         rpa_dbex_add_callback_exact(dbex, "ForExpressionCompareOp", RPA_REASON_END, codegen_forcompareop_callback, co);
1932         rpa_dbex_add_callback_exact(dbex, "ForExpressionIncrementOp", RPA_REASON_END, codegen_forincrementop_callback, co);
1933         rpa_dbex_add_callback_exact(dbex, "IterationForOp", RPA_REASON_MATCHED, codegen_iterationforop_callback, co);
1934         rpa_dbex_add_callback_exact(dbex, "BreakOp", RPA_REASON_MATCHED, codegen_breakkeyword_callback, co);
1935         rpa_dbex_add_callback_exact(dbex, "ContinueOp", RPA_REASON_MATCHED, codegen_continuekeyword_callback, co);
1936
1937         rpa_dbex_add_callback_exact(dbex, "NewExpressionOp", RPA_REASON_ALL, codegen_newexpressionop_callback, co);
1938
1939         if (verboseinfo)
1940                 rpa_dbex_add_callback(dbex, ".*", RPA_REASON_MATCHED, codegen_print_callback, co);
1941
1942         while ((ret = rpa_dbex_load(dbex, pattern, inputsize)) > 0) {
1943                 inputsize -= ret;
1944                 pattern += ret;
1945         }
1946         if (ret < 0) {
1947                 for (line = 1; pattern >= buffer; --pattern) {
1948                         if (*pattern == '\n')
1949                                 line += 1;
1950                 }
1951                 fprintf(stdout, "Line: %d, RPA LOAD ERROR: %s\n", line, (rpa_dbex_get_error(dbex) == RPA_E_SYNTAX_ERROR) ? "Syntax Error." : "Pattern Loading failed.");
1952                 goto error;
1953         }
1954
1955 error:
1956         rpa_dbex_close(dbex);
1957 }