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