RPA Toolkit
daf325c13e4ca7e95b862148d57cc4a488ea8605
[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 struct rvm_codespan_s {
49         rword codestart;
50         rword codesize;
51 } rvm_codespan_t;
52
53
54 typedef struct rvm_compiler_s {
55         rpa_dbex_handle dbex;
56         rvm_codegen_t *cg;
57         rvm_scope_t *scope;
58         rarray_t *fp;
59         rarray_t *funcall;
60         rarray_t *fundecl;
61         rarray_t *opcodes;
62         rarray_t *codespan;
63         rvmcpu_t *cpu;
64         rboolean optimized;
65 } rvm_compiler_t;
66
67 void rpagen_load_rules(rpa_dbex_handle dbex, rvm_compiler_t *co);
68
69
70 rvm_compiler_t *rvm_compiler_create(rpa_dbex_handle dbex)
71 {
72         rvm_compiler_t *co;
73
74         co = r_malloc(sizeof(*co));
75         r_memset(co, 0, sizeof(*co));
76         co->cg = rvm_codegen_create();
77         co->scope = rvm_scope_create();
78         co->opcodes = r_array_create(sizeof(ruint));
79         co->fp = r_array_create(sizeof(rword));
80         co->funcall = r_array_create(sizeof(rvm_funcall_t));
81         co->fundecl = r_array_create(sizeof(rvm_fundecl_t));
82         co->codespan = r_array_create(sizeof(rvm_codespan_t));
83         r_array_push(co->fp, 0, rword);
84         co->dbex = dbex;
85         return co;
86 }
87
88
89 void rvm_compiler_destroy(rvm_compiler_t *co)
90 {
91         if (co) {
92                 rvm_codegen_destroy(co->cg);
93                 rvm_scope_destroy(co->scope);
94                 r_object_destroy((robject_t*) co->opcodes);
95                 r_object_destroy((robject_t*) co->fp);
96                 r_object_destroy((robject_t*) co->funcall);
97                 r_object_destroy((robject_t*) co->fundecl);
98                 r_object_destroy((robject_t*) co->codespan);
99                 r_free(co);
100         }
101 }
102
103
104 static void test_swi_none(rvmcpu_t *cpu, rvm_asmins_t *ins)
105 {
106 }
107
108
109 static void rvm_swi_negative(rvmcpu_t *cpu, rvm_asmins_t *ins)
110 {
111         rvmreg_t *res = RVM_CPUREG_PTR(cpu, ins->op1);
112         rvmreg_t *arg = RVM_CPUREG_PTR(cpu, ins->op2);
113         rvmreg_t zero;
114
115         RVM_REG_CLEAR(&zero);
116         rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_SUB, cpu, res, &zero, arg);
117 }
118
119
120 static void rvm_swi_eadd(rvmcpu_t *cpu, rvm_asmins_t *ins)
121 {
122         rvmreg_t *res = RVM_CPUREG_PTR(cpu, R0);
123         rvmreg_t *arg1 = (rvmreg_t *)r_carray_slot(cpu->stack, RVM_CPUREG_GETU(cpu, FP) + 1);
124         rvmreg_t *arg2 = (rvmreg_t *)r_carray_slot(cpu->stack, RVM_CPUREG_GETU(cpu, FP) + 2);
125
126         rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_ADD, cpu, res, arg1, arg2);
127 }
128
129 static void rvm_swi_eless(rvmcpu_t *cpu, rvm_asmins_t *ins)
130 {
131         rvmreg_t *res = RVM_SPOFF_ADDR(cpu, 1);
132         rvmreg_t *arg2 = RVM_SPOFF_ADDR(cpu, 0);
133
134         rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LESS, cpu, res, res, arg2);
135         RVM_CPUREG_SETU(cpu, SP, RVM_CPUREG_GETU(cpu, SP) - 1);
136 }
137
138
139 static void rvm_swi_bnonzero(rvmcpu_t *cpu, rvm_asmins_t *ins)
140 {
141         rvmreg_t *arg = RVM_SPOFF_ADDR(cpu, 0);
142
143         if (RVM_REG_GETU(arg))
144                 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
145         RVM_CPUREG_SETU(cpu, SP, RVM_CPUREG_GETU(cpu, SP) - 1);
146 }
147
148
149 static void rvm_swi_identifiervalue(rvmcpu_t *cpu, rvm_asmins_t *ins)
150 {
151         RVM_CPUREG_SET(cpu, ins->op1, *r_carray_rvmregslot(cpu->stack, RVM_CPUREG_GETU(cpu, ins->op2) + RVM_CPUREG_GETU(cpu, ins->op3)));
152 }
153
154
155 static rvm_switable_t switable[] = {
156                 {"none", test_swi_none},
157                 {"RVM_SWI_NEG", rvm_swi_negative},
158                 {"rvm_swi_eadd", rvm_swi_eadd},
159                 {"rvm_swi_eless", rvm_swi_eless},
160                 {"rvm_swi_bnonzero", rvm_swi_bnonzero},
161                 {"rvm_swi_identifiervalue", rvm_swi_identifiervalue},
162                 {NULL, NULL},
163 };
164
165
166 static void rvm_js_print(rvmcpu_t *cpu, rvm_asmins_t *ins)
167 {
168         rvmreg_t *r = (rvmreg_t *)r_carray_slot(cpu->stack, RVM_CPUREG_GETU(cpu, FP) + 1);
169
170         if (rvm_reg_gettype(r) == RVM_DTYPE_UNSIGNED)
171                 r_printf("%lu\n", RVM_REG_GETU(r));
172         else if (rvm_reg_gettype(r) == RVM_DTYPE_BOOLEAN)
173                 r_printf("%s\n", RVM_REG_GETU(r) ? "true" : "false");
174         else if (rvm_reg_gettype(r) == RVM_DTYPE_POINTER)
175                 r_printf("%p\n", RVM_REG_GETP(r));
176         else if (rvm_reg_gettype(r) == RVM_DTYPE_LONG)
177                 r_printf("%ld\n", RVM_REG_GETL(r));
178         else if (rvm_reg_gettype(r) == RVM_DTYPE_DOUBLE)
179                 r_printf("%f\n", RVM_REG_GETD(r));
180         else if (rvm_reg_gettype(r) == RVM_DTYPE_STRING)
181                 r_printf("%s\n", ((rstring_t*) RVM_REG_GETP(r))->s.str);
182         else if (rvm_reg_gettype(r) == RVM_DTYPE_ARRAY)
183                 r_printf("(array) %p\n",RVM_REG_GETP(r));
184         else if (rvm_reg_gettype(r) == RVM_DTYPE_SWIID)
185                 r_printf("(function) %p\n",RVM_REG_GETP(r));
186         else
187                 r_printf("%p\n", RVM_REG_GETP(r));
188 }
189
190 static rvm_switable_t switable_js[] = {
191                 {"print", rvm_js_print},
192                 {NULL, NULL},
193 };
194
195 inline int codegen_print_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
196 {
197         if (parseinfo) {
198                 fprintf(stdout, "%s: ", name);
199                 fwrite(input, sizeof(char), size, stdout);
200                 fprintf(stdout, "\n");
201                 fflush(stdout);
202         }
203
204         return size;
205 }
206
207
208 void codegen_dump_code(rvm_asmins_t *code, rulong size)
209 {
210         if (parseinfo)
211                 rvm_asm_dump(code, size);
212 }
213
214
215 int codegen_opcode_unary_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
216 {
217         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
218
219         if (r_stringncmp("-", input, size))
220                 r_array_push(co->opcodes, RVM_OPSWI(rvm_cpu_getswi_s(co->cpu, "RVM_SWI_NEG")), ruint);
221         else
222                 r_array_push(co->opcodes, RVM_ABORT, ruint);
223
224         codegen_print_callback(name, userdata, input, size, reason, start, end);
225         return size;
226 }
227
228
229 int codegen_opcode_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
230 {
231         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
232
233         if (r_stringncmp("+", input,  size))
234                 r_array_push(co->opcodes, RVM_EADD, ruint);
235         else if (r_stringncmp("-", input,  size))
236                 r_array_push(co->opcodes, RVM_ESUB, ruint);
237         else if (r_stringncmp("*", input,  size))
238                 r_array_push(co->opcodes, RVM_EMUL, ruint);
239         else if (r_stringncmp("/", input,  size))
240                 r_array_push(co->opcodes, RVM_EDIV, ruint);
241         else if (r_stringncmp("%", input,  size))
242                 r_array_push(co->opcodes, RVM_EMOD, ruint);
243         else if (r_stringncmp("&&", input,  size))
244                 r_array_push(co->opcodes, RVM_ELAND, ruint);
245         else if (r_stringncmp("||", input,  size))
246                 r_array_push(co->opcodes, RVM_ELOR, ruint);
247         else if (r_stringncmp("&", input,  size))
248                 r_array_push(co->opcodes, RVM_EAND, ruint);
249         else if (r_stringncmp("|", input,  size))
250                 r_array_push(co->opcodes, RVM_EORR, ruint);
251         else if (r_stringncmp("^", input,  size))
252                 r_array_push(co->opcodes, RVM_EXOR, ruint);
253         else if (r_stringncmp(">>", input,  size))
254                 r_array_push(co->opcodes, RVM_ELSR, ruint);
255         else if (r_stringncmp("<<", input,  size))
256                 r_array_push(co->opcodes, RVM_ELSL, ruint);
257         else if (r_stringncmp(">>>", input,  size))
258                 r_array_push(co->opcodes, RVM_ELSRU, ruint);
259         else if (r_stringncmp("<=", input,  size))
260                 r_array_push(co->opcodes, RVM_ELESSEQ, ruint);
261         else if (r_stringncmp(">=", input,  size))
262                 r_array_push(co->opcodes, RVM_EGREATEQ, ruint);
263         else if (r_stringncmp("<", input,  size))
264                 r_array_push(co->opcodes, RVM_ELESS, ruint);
265         else if (r_stringncmp(">", input,  size))
266                 r_array_push(co->opcodes, RVM_EGREAT, ruint);
267         else if (r_stringncmp("===", input,  size))
268                 r_array_push(co->opcodes, RVM_EEQ, ruint);
269         else if (r_stringncmp("==", input,  size))
270                 r_array_push(co->opcodes, RVM_EEQ, ruint);
271         else if (r_stringncmp("!==", input,  size))
272                 r_array_push(co->opcodes, RVM_ENOTEQ, ruint);
273         else if (r_stringncmp("!=", input,  size))
274                 r_array_push(co->opcodes, RVM_ENOTEQ, ruint);
275         else if (r_stringncmp("!", input,  size))
276                 r_array_push(co->opcodes, RVM_ELNOT, ruint);
277         else if (r_stringncmp("~", input,  size))
278                 r_array_push(co->opcodes, RVM_ENOT, ruint);
279         else
280                 r_array_push(co->opcodes, RVM_ABORT, ruint);
281
282         codegen_print_callback(name, userdata, input, size, reason, start, end);
283         return size;
284 }
285
286
287 int codegen_binary_asmop_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
288 {
289         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
290         rulong off = rvm_codegen_getcodesize(co->cg);
291         ruint opcode = r_array_pop(co->opcodes, ruint);
292
293         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
294         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R0, XX, XX, 0));
295         rvm_codegen_addins(co->cg, rvm_asm(opcode, R0, R0, R1, 0));
296         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
297
298         codegen_print_callback(name, userdata, input, size, reason, start, end);
299         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
300
301         return size;
302 }
303
304
305 int codegen_unary_asmop_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
306 {
307         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
308         rulong off = rvm_codegen_getcodesize(co->cg);
309         ruint opcode = r_array_pop(co->opcodes, ruint);
310
311         if (co->optimized) {
312                 rvm_asmins_t * last = rvm_codegen_getcode(co->cg, off - 1);
313                 if (last->opcode == RVM_PUSH && last->op1 == R0) {
314                         rvm_codegen_setcodesize(co->cg, off - 1);
315                         off = rvm_codegen_getcodesize(co->cg);
316                 } else {
317                         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R0, XX, XX, 0));
318                 }
319
320         } else {
321                 rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R0, XX, XX, 0));
322         }
323         rvm_codegen_addins(co->cg, rvm_asm(opcode, R0, R0, XX, 0));
324         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
325
326         codegen_print_callback(name, userdata, input, size, reason, start, end);
327         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
328
329         return size;
330 }
331
332
333 int codegen_postfixexpression_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
334 {
335         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
336         rulong off = rvm_codegen_getcodesize(co->cg);
337
338         rvm_codegen_addins(co->cg, rvm_asm(RVM_TYPE, R1, R0, XX, 0));
339         rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R1, DA, XX, RVM_DTYPE_POINTER));
340         rvm_codegen_addins(co->cg, rvm_asm(RVM_BNEQ, DA, XX, XX, 2));
341         rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R0, R0, XX, 0));
342         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
343
344         codegen_print_callback(name, userdata, input, size, reason, start, end);
345         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
346
347         return size;
348 }
349
350
351 int codegen_push_r0_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
352 {
353         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
354         rulong off = rvm_codegen_getcodesize(co->cg);
355
356         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
357
358         codegen_print_callback(name, userdata, input, size, reason, start, end);
359         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
360
361         return size;
362 }
363
364
365 int codegen_push_r1_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
366 {
367         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
368         rulong off = rvm_codegen_getcodesize(co->cg);
369
370         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R1, XX, XX, 0));
371         codegen_print_callback(name, userdata, input, size, reason, start, end);
372         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
373
374         return size;
375 }
376
377
378 int codegen_pop_r0_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
379 {
380         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
381         rulong off = rvm_codegen_getcodesize(co->cg);
382
383         if (co->optimized) {
384                 rvm_asmins_t * last = rvm_codegen_getcode(co->cg, off - 1);
385                 if (last->opcode == RVM_PUSH && last->op1 == R0) {
386                         rvm_codegen_setcodesize(co->cg, off - 1);
387                         off = rvm_codegen_getcodesize(co->cg);
388                 } else {
389                         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R0, XX, XX, 0));
390                 }
391
392         } else {
393                 rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R0, XX, XX, 0));
394         }
395
396         codegen_print_callback(name, userdata, input, size, reason, start, end);
397         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
398
399         return size;
400 }
401
402
403 int codegen_integer_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
404 {
405         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
406         rulong off = rvm_codegen_getcodesize(co->cg);
407
408         rvm_codegen_addins(co->cg, rvm_asml(RVM_MOV, R0, DA, XX, r_strtol(input, NULL, 10)));
409
410         codegen_print_callback(name, userdata, input, size, reason, start, end);
411         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
412
413         return size;
414 }
415
416
417 int codegen_double_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
418 {
419         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
420         rulong off = rvm_codegen_getcodesize(co->cg);
421
422         rvm_codegen_addins(co->cg, rvm_asmd(RVM_MOV, R0, DA, XX, r_strtod(input, NULL)));
423
424         codegen_print_callback(name, userdata, input, size, reason, start, end);
425         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
426
427         return size;
428 }
429
430
431 int codegen_string_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
432 {
433         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
434         rulong off = rvm_codegen_getcodesize(co->cg);
435
436         rvm_codegen_addins(co->cg, rvm_asmp(RVM_MOV, R1, DA, XX, (void*)input));
437         rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R2, DA, XX, size));
438         rvm_codegen_addins(co->cg, rvm_asm(RVM_ALLOCSTR, R0, R1, R2, 0));
439
440         codegen_print_callback(name, userdata, input, size, reason, start, end);
441         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
442
443         return size;
444 }
445
446
447 int codegen_programinit_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
448 {
449         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
450         ruint off;
451
452         off = rvm_codegen_getcodesize(co->cg);
453
454         codegen_print_callback(name, userdata, input, size, reason, start, end);
455         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
456
457         return size;
458 }
459
460
461 int codegen_program_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
462 {
463         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
464         ruint off;
465
466         rvm_codegen_replaceins(co->cg, 0, rvm_asm(RVM_MOV, FP, SP, XX, 0));
467         rvm_codegen_replaceins(co->cg, 1, rvm_asm(RVM_ADD, SP, SP, DA, r_array_pop(co->fp, rword)));
468
469         off = rvm_codegen_getcodesize(co->cg);
470         if (debuginfo)
471                 rvm_codegen_addins(co->cg, rvm_asm(RVM_PRN, R0, XX, XX, 0));
472         rvm_codegen_addins(co->cg, rvm_asm(RVM_EXT, XX, XX, XX, 0));
473
474         codegen_print_callback(name, userdata, input, size, reason, start, end);
475         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
476
477         return size;
478 }
479
480
481 int codegen_opassign_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
482 {
483         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
484         rulong off = rvm_codegen_getcodesize(co->cg);
485
486         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
487         rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
488
489         codegen_print_callback(name, userdata, input, size, reason, start, end);
490         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
491
492         return size;
493 }
494
495
496 int codegen_postfixinc_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
497 {
498         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
499         rulong off = rvm_codegen_getcodesize(co->cg);
500
501         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
502         rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R0, R1, XX, 0));
503         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
504         rvm_codegen_addins(co->cg, rvm_asm(RVM_EADD, R0, R0, DA, 1));
505         rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
506
507         codegen_print_callback(name, userdata, input, size, reason, start, end);
508         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
509
510         return size;
511 }
512
513
514 int codegen_postfixdec_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
515 {
516         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
517         rulong off = rvm_codegen_getcodesize(co->cg);
518
519         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
520         rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R0, R1, XX, 0));
521         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
522         rvm_codegen_addins(co->cg, rvm_asm(RVM_ESUB, R0, R0, DA, 1));
523         rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
524
525         codegen_print_callback(name, userdata, input, size, reason, start, end);
526         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
527
528         return size;
529 }
530
531
532 int codegen_prefixinc_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
533 {
534         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
535         rulong off = rvm_codegen_getcodesize(co->cg);
536
537         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
538         rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R0, R1, XX, 0));
539         rvm_codegen_addins(co->cg, rvm_asm(RVM_EADD, R0, R0, DA, 1));
540         rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
541         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
542
543         codegen_print_callback(name, userdata, input, size, reason, start, end);
544         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
545
546         return size;
547 }
548
549
550 int codegen_prefixdec_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
551 {
552         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
553         rulong off = rvm_codegen_getcodesize(co->cg);
554
555         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
556         rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R0, R1, XX, 0));
557         rvm_codegen_addins(co->cg, rvm_asm(RVM_ESUB, R0, R0, DA, 1));
558         rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
559         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
560
561         codegen_print_callback(name, userdata, input, size, reason, start, end);
562         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
563
564         return size;
565 }
566
567
568 int codegen_ptr_deref_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
569 {
570         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
571         rulong off = rvm_codegen_getcodesize(co->cg);
572
573         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));    // Address
574         rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R0, R1, XX, 0));   // Load the value from offset
575         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));   // Push it on the stack
576
577         codegen_print_callback(name, userdata, input, size, reason, start, end);
578         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
579
580         return size;
581 }
582
583
584 int codegen_arrayelementvalue_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
585 {
586         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
587         rulong off = rvm_codegen_getcodesize(co->cg);
588
589         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));    // Array
590         rvm_codegen_addins(co->cg, rvm_asm(RVM_ELDA, R0, R1, R0, 0));   // Load the value from array offset
591
592         codegen_print_callback(name, userdata, input, size, reason, start, end);
593         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
594
595         return size;
596 }
597
598
599 int codegen_memberexpressionbase_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
600 {
601         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
602         rulong off = rvm_codegen_getcodesize(co->cg);
603
604         rvm_codegen_addins(co->cg, rvm_asm(RVM_TYPE, R1, R0, XX, 0));
605         rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R1, DA, XX, RVM_DTYPE_POINTER));
606         rvm_codegen_addins(co->cg, rvm_asm(RVM_BNEQ, DA, XX, XX, 2));
607         rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R0, R0, XX, 0));   // Array Address
608         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));   // Array -> On Stack
609
610         codegen_print_callback(name, userdata, input, size, reason, start, end);
611         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
612
613         return size;
614 }
615
616
617 int codegen_arrayelementaddress_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
618 {
619         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
620         rulong off = rvm_codegen_getcodesize(co->cg);
621
622         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));    // Supposedly Array Address
623         rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRA, R0, R1, R0, 0));  // Get the address of the element at offset R0
624
625         codegen_print_callback(name, userdata, input, size, reason, start, end);
626         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
627
628         return size;
629 }
630
631
632
633 int codegen_offset_to_ptr_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
634 {
635         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
636         rulong off = rvm_codegen_getcodesize(co->cg);
637
638         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R2, XX, XX, 0));    // Offset
639         rvm_codegen_addins(co->cg, rvm_asm(RVM_CAST, R2, R2, DA, RVM_DTYPE_UNSIGNED));  // cast to unsigned
640         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));    // Array
641         rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRA, R0, R1, R2, 0));  // Pointer to element at offset
642         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));   // Push it on the stack
643
644         codegen_print_callback(name, userdata, input, size, reason, start, end);
645         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
646
647         return size;
648 }
649
650
651 int codegen_identifiervalue_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
652 {
653         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
654         rulong off = rvm_codegen_getcodesize(co->cg);
655         rvm_varmap_t *v = rvm_scope_lookup(co->scope, input, size);
656
657         if (!v) {
658                 fprintf(stdout, "ERROR: undefined variable: ");
659                 fwrite(input, sizeof(char), size, stdout);
660                 fprintf(stdout, "\n");
661                 rpa_dbex_abort(co->dbex);
662                 return 0;
663         }
664
665         if (v->datatype == VARMAP_DATATYPE_FPOFFSET) {
666                 rvm_codegen_addins(co->cg, rvm_asm(RVM_ELDS, R0, FP, DA, v->data.offset));
667         } else {
668                 rvm_codegen_addins(co->cg, rvm_asm(RVM_ELDS, R0, DA, XX, v->data.offset));
669         }
670
671         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));   // Push it on the stack
672
673         codegen_print_callback(name, userdata, input, size, reason, start, end);
674         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
675
676         return size;
677 }
678
679
680 int codegen_swiidexist_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
681 {
682         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
683         rint swi = rvm_cpu_getswi(co->cpu, input, size);
684
685         if (swi < 0)
686                 return 0;
687
688
689         return size;
690 }
691
692
693 int codegen_swiid_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
694 {
695         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
696         rulong off = rvm_codegen_getcodesize(co->cg);
697         rint swi = rvm_cpu_getswi(co->cpu, input, size);
698
699         if (swi < 0)
700                 return 0;
701
702         rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, swi));
703         rvm_codegen_addins(co->cg, rvm_asm(RVM_SETTYPE, R0, DA, XX, RVM_DTYPE_SWIID));
704
705         codegen_print_callback(name, userdata, input, size, reason, start, end);
706         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
707
708         return size;
709 }
710
711
712 int codegen_opidentifier_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
713 {
714         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
715         rulong off = rvm_codegen_getcodesize(co->cg);
716         rvm_varmap_t *v = rvm_scope_lookup(co->scope, input, size);
717
718         if (v) {
719                 if (v->datatype == VARMAP_DATATYPE_FPOFFSET) {
720                         rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRS, R0, FP, DA, v->data.offset));
721                 } else {
722                         rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRS, R0, DA, XX, v->data.offset));
723                 }
724                 codegen_print_callback(name, userdata, input, size, reason, start, end);
725                 codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
726
727                 return size;
728         }
729
730         fprintf(stdout, "ERROR: undefined variable: ");
731         fwrite(input, sizeof(char), size, stdout);
732         fprintf(stdout, "\n");
733         rpa_dbex_abort(co->dbex);
734         return 0;
735
736 }
737
738
739 int codegen_varalloc_to_ptr_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
740 {
741         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
742         rulong off = rvm_codegen_getcodesize(co->cg);
743         rvm_varmap_t *v = rvm_scope_tiplookup(co->scope, input, size);
744         if (v) {
745                 fprintf(stdout, "ERROR: variable already defined: ");
746                 fwrite(input, sizeof(char), size, stdout);
747                 fprintf(stdout, "\n");
748                 rpa_dbex_abort(co->dbex);
749                 return 0;
750         }
751
752         r_array_push(co->fp, r_array_pop(co->fp, rword) + 1, rword);
753         rvm_scope_addoffset(co->scope, input, size, r_array_last(co->fp, rword));
754         v = rvm_scope_tiplookup(co->scope, input, size);
755
756         if (v->datatype == VARMAP_DATATYPE_FPOFFSET) {
757                 rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRS, R0, FP, DA, v->data.offset));
758         } else {
759                 rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDRS, R0, DA, XX, v->data.offset));
760         }
761
762         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
763         codegen_print_callback(name, userdata, input, size, reason, start, end);
764         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
765
766         return size;
767 }
768
769
770 int codegen_varalloc_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
771 {
772         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
773         rulong off = rvm_codegen_getcodesize(co->cg);
774         rvm_varmap_t *v = rvm_scope_tiplookup(co->scope, input, size);
775         if (v) {
776                 fprintf(stdout, "ERROR: variable already defined: ");
777                 fwrite(input, sizeof(char), size, stdout);
778                 fprintf(stdout, "\n");
779                 rpa_dbex_abort(co->dbex);
780                 return 0;
781         }
782
783         r_array_push(co->fp, r_array_pop(co->fp, rword) + 1, rword);
784         rvm_scope_addoffset(co->scope, input, size, r_array_last(co->fp, rword));
785
786         codegen_print_callback(name, userdata, input, size, reason, start, end);
787         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
788
789         return size;
790 }
791
792
793
794
795 int codegen_newarraysize_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
796 {
797         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
798         rulong off = rvm_codegen_getcodesize(co->cg);
799
800         rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, R0, XX, 0));
801         rvm_codegen_addins(co->cg, rvm_asm(RVM_ALLOCARR, R0, R1, XX, 0));
802 //      rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
803
804         codegen_print_callback(name, userdata, input, size, reason, start, end);
805         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
806
807         return size;
808 }
809
810
811 int codegen_newarraynosize_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
812 {
813         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
814         rulong off = rvm_codegen_getcodesize(co->cg);
815
816         rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, DA, XX, 0));
817         rvm_codegen_addins(co->cg, rvm_asm(RVM_ALLOCARR, R0, R1, XX, 0));
818 //      rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
819
820         codegen_print_callback(name, userdata, input, size, reason, start, end);
821         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
822
823         return size;
824 }
825
826
827 int codegen_scopepush_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
828 {
829         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
830         rulong off = rvm_codegen_getcodesize(co->cg);
831
832         rvm_scope_push(co->scope);
833         codegen_print_callback(name, userdata, input, size, reason, start, end);
834         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
835
836         return size;
837 }
838
839
840 int codegen_scopepop_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
841 {
842         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
843         rulong off = rvm_codegen_getcodesize(co->cg);
844
845         rvm_scope_pop(co->scope);
846         codegen_print_callback(name, userdata, input, size, reason, start, end);
847         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
848
849         return size;
850 }
851
852
853 int codegen_compile_error_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
854 {
855         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
856         fprintf(stdout, "COMPILE ERROR pos: %ld\n", (long) (input - start));
857         rpa_dbex_abort(co->dbex);
858         return 0;
859 }
860
861
862 int codegen_funcallparameter_callback(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         rulong off = rvm_codegen_getcodesize(co->cg);
866         rvm_funcall_t *funcall = (rvm_funcall_t *)r_array_slot(co->funcall, r_array_length(co->funcall) - 1);
867
868         funcall->params += 1;
869         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
870         codegen_print_callback(name, userdata, input, size, reason, start, end);
871         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
872
873         return size;
874 }
875
876
877 int codegen_funcallexpression_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
878 {
879         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
880         rulong off = rvm_codegen_getcodesize(co->cg);
881         rvm_funcall_t *funcall = r_array_empty(co->funcall) ? NULL : (rvm_funcall_t *) r_array_slot(co->funcall, r_array_length(co->funcall) - 1);
882
883
884         rvm_codegen_addins(co->cg, rvm_asm(RVM_SUB, FP, SP, DA, funcall->params));
885         rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, DA, XX, funcall->params));
886         rvm_codegen_addins(co->cg, rvm_asm(RVM_STS, R1, FP, DA, -3));
887         rvm_codegen_addins(co->cg, rvm_asm(RVM_LDS, R0, FP, DA, 0));
888         rvm_codegen_addins(co->cg, rvm_asm(RVM_TYPE, R1, R0, XX, 0));
889         rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R1, DA, XX, RVM_DTYPE_SWIID));
890         rvm_codegen_addins(co->cg, rvm_asm(RVM_BNEQ, DA, XX, XX, 5));
891         rvm_codegen_addins(co->cg, rvm_asm(RVM_SWIID, R0, XX, XX, 0));
892         rvm_codegen_addins(co->cg, rvm_asm(RVM_SUB, SP, FP, DA, 1));
893         rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(FP)|BIT(SP)));
894         rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, 2));
895         rvm_codegen_addins(co->cg, rvm_asm(RVM_BL, R0, DA, XX, -rvm_codegen_getcodesize(co->cg)));
896
897         r_array_remove(co->funcall);
898         codegen_print_callback(name, userdata, input, size, reason, start, end);
899         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
900
901         return size;
902 }
903
904
905 int codegen_funcallname_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
906 {
907         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
908         rulong off = rvm_codegen_getcodesize(co->cg);
909         rvm_funcall_t funcall = {input, size, 0};
910
911         r_array_add(co->funcall, &funcall);
912
913
914         /*
915          * R0 holds the label of the called function, we save on the stack
916          * and FP will point there. After the call we save the LR at that spot
917          * as we don't need the RO anymore.
918          */
919         rvm_codegen_addins(co->cg, rvm_asm(RVM_TYPE, R1, R0, XX, 0));
920         rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R1, DA, XX, RVM_DTYPE_POINTER));
921         rvm_codegen_addins(co->cg, rvm_asm(RVM_BNEQ, DA, XX, XX, 2));
922         rvm_codegen_addins(co->cg, rvm_asm(RVM_LDRR, R0, R0, XX, 0));
923
924         /*
925          * R1 is just a place holder, we will write the number of args passed
926          * later when we find out the number
927          */
928         rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R1, DA, XX, 0));
929         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(R1)|BIT(FP)|BIT(SP)));
930         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
931
932         codegen_print_callback(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
939 int codegen_fundeclparameter_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
940 {
941         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
942         rulong off = rvm_codegen_getcodesize(co->cg);
943         rvm_fundecl_t *fundecl = (rvm_fundecl_t *)r_array_lastslot(co->fundecl);
944         rvm_varmap_t *v = rvm_scope_tiplookup(co->scope, input, size);
945         if (v) {
946                 fprintf(stdout, "ERROR: variable already defined: ");
947                 fwrite(input, sizeof(char), size, stdout);
948                 fprintf(stdout, "\n");
949                 rpa_dbex_abort(co->dbex);
950                 return 0;
951         }
952
953         fundecl->params += 1;
954         r_array_push(co->fp, r_array_pop(co->fp, rword) + 1, rword);
955         rvm_scope_addoffset(co->scope, input, size, r_array_last(co->fp, rword));
956         codegen_print_callback(name, userdata, input, size, reason, start, end);
957         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
958
959         return size;
960 }
961
962
963 int codegen_fundeclname_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
964 {
965         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
966         rulong off = rvm_codegen_getcodesize(co->cg);
967         rvm_fundecl_t fundecl = {input, size, 0, off, 0};
968         rint ret;
969
970         ret = codegen_varalloc_callback(name, userdata, input, size, reason, start, end);
971         if (ret == 0)
972                 return ret;
973
974         rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xffffffff));
975         rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xffffffff));
976         rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xffffffff));
977         rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xffffffff));
978         rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xffffffff));
979         rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xffffffff));
980
981         r_array_push(co->fp, 0, rword);
982         r_array_add(co->fundecl, &fundecl);
983         rvm_scope_push(co->scope);
984
985         codegen_print_callback(name, userdata, input, size, reason, start, end);
986         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
987         return size;
988 }
989
990
991
992 int codegen_fundeclsignature_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
993 {
994         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
995         rulong off = rvm_codegen_getcodesize(co->cg);
996
997 //      rvm_codemap_add(cg->codemap, fundecl->funname, fundecl->funnamesiz, rvm_codegen_getcodesize(co->cg));
998
999         codegen_print_callback(name, userdata, input, size, reason, start, end);
1000         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1001
1002         return size;
1003 }
1004
1005
1006 int codegen_fundecl_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
1007 {
1008         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1009         rulong off = rvm_codegen_getcodesize(co->cg);
1010         rvm_fundecl_t *fundecl = (rvm_fundecl_t *)r_array_lastslot(co->fundecl);
1011         rvm_varmap_t *fname;
1012         rword fp = r_array_pop(co->fp, rword);
1013         rvm_scope_pop(co->scope);
1014         fname = rvm_scope_tiplookup(co->scope, fundecl->funname, fundecl->funnamesiz);
1015
1016         /*
1017          * Function end, we first define the function end
1018          */
1019         rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xeeeeeeee));
1020         rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, SP, FP, XX, 0));
1021         rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(PC)));
1022         rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xeeeeeeee));
1023
1024         fundecl->codesize = rvm_codegen_getcodesize(co->cg) - fundecl->codestart;
1025
1026
1027         if (fname->datatype == VARMAP_DATATYPE_FPOFFSET) {
1028                 rvm_codegen_replaceins(co->cg, fundecl->codestart + 0, rvm_asm(RVM_ADDRS, R0, FP, DA, fname->data.offset));
1029         } else {
1030                 rvm_codegen_replaceins(co->cg, fundecl->codestart + 0, rvm_asm(RVM_ADDRS, R0, DA, XX, fname->data.offset));
1031         }
1032         rvm_codegen_replaceins(co->cg, fundecl->codestart + 1, rvm_asm(RVM_STRR, DA, R0, XX, fundecl->codestart + 3));
1033         rvm_codegen_replaceins(co->cg, fundecl->codestart + 2, rvm_asm(RVM_B, DA, XX, XX, fundecl->codesize - 2));
1034         rvm_codegen_replaceins(co->cg, fundecl->codestart + 3, rvm_asm(RVM_STS, LR, FP, DA, 0));
1035         rvm_codegen_replaceins(co->cg, fundecl->codestart + 4, rvm_asm(RVM_ADD, SP, FP, DA, fp));
1036
1037         fundecl->codesize = rvm_codegen_getcodesize(co->cg) - fundecl->codestart;
1038         fundecl->params = r_array_last(co->fp, rword);
1039
1040         r_array_remove(co->fundecl);
1041         codegen_print_callback(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_opreturn_callback(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_codegen_addins(co->cg, rvm_asm(RVM_MOV, SP, FP, XX, 0));
1054         rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(PC)));
1055
1056         codegen_print_callback(name, userdata, input, size, reason, start, end);
1057         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1058
1059         return size;
1060 }
1061
1062
1063 int codegen_ifconditionop_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
1064 {
1065         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1066         rulong off = rvm_codegen_getcodesize(co->cg);
1067         rvm_codespan_t cs = {0, 0};
1068
1069         cs.codestart = rvm_codegen_getcodesize(co->cg);
1070         r_array_add(co->codespan, &cs);
1071
1072         rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R0, DA, XX, 0));
1073         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
1074
1075         codegen_print_callback(name, userdata, input, size, reason, start, end);
1076         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1077
1078         return size;
1079 }
1080
1081
1082 int codegen_ifop_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
1083 {
1084         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1085         rulong off = rvm_codegen_getcodesize(co->cg);
1086         rvm_codespan_t cs = r_array_pop(co->codespan, rvm_codespan_t);
1087
1088         cs.codesize = rvm_codegen_getcodesize(co->cg) - cs.codestart;
1089         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
1090
1091         codegen_print_callback(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_elseop_callback(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_codespan_t cs = r_array_pop(co->codespan, rvm_codespan_t);
1103
1104         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
1105         cs.codesize = rvm_codegen_getcodesize(co->cg) - cs.codestart;
1106         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
1107
1108         /* Reuse the cs to define the *else* codespan */
1109         cs.codestart = rvm_codegen_getcodesize(co->cg);
1110         cs.codesize = 0;
1111         r_array_add(co->codespan, &cs);
1112
1113         codegen_print_callback(name, userdata, input, size, reason, start, end);
1114         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1115
1116         return size;
1117 }
1118
1119
1120 int codegen_ifelseop_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
1121 {
1122         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1123         rulong off = rvm_codegen_getcodesize(co->cg);
1124         rvm_codespan_t cs = r_array_pop(co->codespan, rvm_codespan_t);
1125
1126         cs.codesize = rvm_codegen_getcodesize(co->cg) - cs.codestart;
1127         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
1128
1129         codegen_print_callback(name, userdata, input, size, reason, start, end);
1130         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1131
1132         return size;
1133 }
1134
1135
1136 int codegen_dokeyword_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
1137 {
1138         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1139         rulong off = rvm_codegen_getcodesize(co->cg);
1140         rvm_codespan_t cs = {0, 0};
1141
1142         cs.codestart = rvm_codegen_getcodesize(co->cg);
1143         r_array_add(co->codespan, &cs);
1144
1145         codegen_print_callback(name, userdata, input, size, reason, start, end);
1146         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1147         return size;
1148 }
1149
1150
1151 int codegen_iterationdo_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
1152 {
1153         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
1154         rulong off = rvm_codegen_getcodesize(co->cg);
1155         rvm_codespan_t cs = r_array_pop(co->codespan, rvm_codespan_t);
1156
1157
1158         rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R0, DA, XX, 0));
1159         cs.codesize = rvm_codegen_getcodesize(co->cg) - cs.codestart;
1160         rvm_codegen_addins(co->cg, rvm_asm(RVM_BNEQ, DA, XX, XX, -cs.codesize));
1161         rvm_codemap_poploopblock(co->cg->codemap);
1162
1163         codegen_print_callback(name, userdata, input, size, reason, start, end);
1164         codegen_dump_code(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
1165         return size;
1166 }
1167
1168
1169
1170 void codegen_unmap_file(rstr_t *buf)
1171 {
1172         if (buf) {
1173                 munmap(buf->str, buf->size);
1174                 r_free(buf);
1175         }
1176 }
1177
1178
1179 rstr_t *codegen_map_file(const char *filename)
1180 {
1181         struct stat st;
1182         rstr_t *str;
1183         char *buffer;
1184
1185
1186         int fd = open(filename, O_RDONLY);
1187         if (fd < 0) {
1188                 return (void*)0;
1189         }
1190         if (fstat(fd, &st) < 0) {
1191                 close(fd);
1192                 return (void*)0;
1193         }
1194         buffer = (char*)mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
1195         if (buffer == (void*)-1) {
1196                 close(fd);
1197                 return (void*)0;
1198         }
1199         str = (rstr_t *)r_malloc(sizeof(*str));
1200         if (!str)
1201                 goto error;
1202         r_memset(str, 0, sizeof(*str));
1203         str->str = buffer;
1204         str->size = st.st_size;
1205         close(fd);
1206         return str;
1207
1208 error:
1209         munmap(buffer, st.st_size);
1210         close(fd);
1211         return str;
1212 }
1213
1214
1215 int main(int argc, char *argv[])
1216 {
1217         int res, i;
1218         rvmcpu_t *cpu;
1219         ruint ntable;
1220         rpa_dbex_handle dbex = rpa_dbex_create();
1221         rvm_compiler_t *co = rvm_compiler_create(dbex);
1222
1223         cpu = rvm_cpu_create();
1224         ntable = rvm_cpu_addswitable(cpu, switable);
1225         rvm_cpu_addswitable(cpu, switable_js);
1226         co->cpu = cpu;
1227
1228         rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
1229         rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
1230         rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
1231         rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
1232
1233         for (i = 1; i < argc; i++) {
1234                 if (r_strcmp(argv[i], "-L") == 0) {
1235                 } else if (r_strcmp(argv[i], "-d") == 0) {
1236                         debuginfo = 1;
1237                 } else if (r_strcmp(argv[i], "-p") == 0) {
1238                         parseinfo = 1;
1239                 } else if (r_strcmp(argv[i], "-P") == 0) {
1240                         parseinfo = 1;
1241                         verboseinfo = 1;
1242                 } else if (r_strcmp(argv[i], "-c") == 0) {
1243                         compileonly = 1;
1244                 } else if (r_strcmp(argv[i], "-o") == 0) {
1245                         co->optimized = 1;
1246                 } else if (r_strcmp(argv[i], "-m") == 0) {
1247
1248                 }
1249         }
1250
1251         rpagen_load_rules(dbex, co);
1252
1253         for (i = 1; i < argc; i++) {
1254                 if (r_strcmp(argv[i], "-e") == 0) {
1255                         if (++i < argc) {
1256                                 rstr_t script = { argv[i], r_strlen(argv[i]) };
1257                                 res = rpa_dbex_parse(dbex, rpa_dbex_default_pattern(dbex), script.str, script.str, script.str + script.size);
1258                                 if (res <= 0)
1259                                         rvm_codegen_clear(co->cg);
1260                         }
1261                         goto exec;
1262                 }
1263         }
1264
1265         for (i = 1; i < argc; i++) {
1266                 if (r_strcmp(argv[i], "-f") == 0) {
1267                         rstr_t *script = NULL;
1268                         if (++i < argc) {
1269                                 script = codegen_map_file(argv[i]);
1270                                 if (script) {
1271                                         res = rpa_dbex_parse(dbex, rpa_dbex_default_pattern(dbex), script->str, script->str, script->str + script->size);
1272                                         codegen_unmap_file(script);
1273                                 }
1274
1275                         }
1276                         goto exec;
1277                 }
1278         }
1279
1280
1281 exec:
1282         rvm_relocate(rvm_codegen_getcode(co->cg, 0), rvm_codegen_getcodesize(co->cg));
1283
1284         if (debuginfo) {
1285                 fprintf(stdout, "\nGenerated Code:\n");
1286                 rvm_asm_dump(rvm_codegen_getcode(co->cg, 0), rvm_codegen_getcodesize(co->cg));
1287                 if (rvm_codegen_getcodesize(co->cg)) {
1288                         if (!compileonly) {
1289                                 fprintf(stdout, "\nExecution:\n");
1290                                 rvm_cpu_exec_debug(cpu, rvm_codegen_getcode(co->cg, 0), 0);
1291                         }
1292                 }
1293         } else {
1294                 if (!compileonly)
1295                         rvm_cpu_exec(cpu, rvm_codegen_getcode(co->cg, 0), 0);
1296         }
1297
1298
1299         rpa_dbex_destroy(dbex);
1300         rvm_cpu_destroy(cpu);
1301         rvm_compiler_destroy(co);
1302
1303         if (debuginfo) {
1304                 r_printf("Max alloc mem: %ld\n", r_debug_get_maxmem());
1305                 r_printf("Leaked mem: %ld\n", r_debug_get_allocmem());
1306         }
1307         return 0;
1308 }
1309
1310
1311 #define EOL "\n"
1312
1313
1314 extern char _binary_____________tests_ecma262_rpa_start[];
1315 extern char _binary_____________tests_ecma262_rpa_end[];
1316 extern unsigned long *_binary_____________tests_ecma262_rpa_size;
1317
1318 void rpagen_load_rules(rpa_dbex_handle dbex, rvm_compiler_t *co)
1319 {
1320         int ret, line;
1321         int inputsize = _binary_____________tests_ecma262_rpa_end - _binary_____________tests_ecma262_rpa_start;
1322         const char *buffer = _binary_____________tests_ecma262_rpa_start;
1323         const char *pattern = buffer;
1324
1325         rpa_dbex_open(dbex);
1326
1327         rpa_dbex_add_callback_exact(dbex, "BitwiseANDOp", RPA_REASON_MATCHED, codegen_binary_asmop_callback, co);
1328         rpa_dbex_add_callback_exact(dbex, "BitwiseXOROp", RPA_REASON_MATCHED, codegen_binary_asmop_callback, co);
1329         rpa_dbex_add_callback_exact(dbex, "BitwiseOROp", RPA_REASON_MATCHED, codegen_binary_asmop_callback, co);
1330         rpa_dbex_add_callback_exact(dbex, "AdditiveExpressionOp", RPA_REASON_MATCHED, codegen_binary_asmop_callback, co);
1331         rpa_dbex_add_callback_exact(dbex, "MultiplicativeExpressionOp", RPA_REASON_MATCHED, codegen_binary_asmop_callback, co);
1332         rpa_dbex_add_callback_exact(dbex, "ShiftExpressionOp", RPA_REASON_MATCHED, codegen_binary_asmop_callback, co);
1333         rpa_dbex_add_callback_exact(dbex, "EqualityExpressionOp", RPA_REASON_MATCHED, codegen_binary_asmop_callback, co);
1334         rpa_dbex_add_callback_exact(dbex, "RelationalExpressionOp", RPA_REASON_MATCHED, codegen_binary_asmop_callback, co);
1335         rpa_dbex_add_callback_exact(dbex, "LogicalOROp", RPA_REASON_MATCHED, codegen_binary_asmop_callback, co);
1336         rpa_dbex_add_callback_exact(dbex, "LogicalANDOp", RPA_REASON_MATCHED, codegen_binary_asmop_callback, co);
1337
1338         rpa_dbex_add_callback_exact(dbex, "EqualityOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1339         rpa_dbex_add_callback_exact(dbex, "RelationalOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1340         rpa_dbex_add_callback_exact(dbex, "AdditiveOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1341         rpa_dbex_add_callback_exact(dbex, "MultiplicativeOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1342         rpa_dbex_add_callback_exact(dbex, "ShiftOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1343         rpa_dbex_add_callback_exact(dbex, "BitwiseANDOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1344         rpa_dbex_add_callback_exact(dbex, "BitwiseXOROperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1345         rpa_dbex_add_callback_exact(dbex, "BitwiseOROperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1346         rpa_dbex_add_callback_exact(dbex, "LogicalANDOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1347         rpa_dbex_add_callback_exact(dbex, "LogicalOROperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1348         rpa_dbex_add_callback_exact(dbex, "UnaryOperator", RPA_REASON_MATCHED, codegen_opcode_unary_callback, co);
1349         rpa_dbex_add_callback_exact(dbex, "LogicalNotOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1350         rpa_dbex_add_callback_exact(dbex, "BitwiseNotOperator", RPA_REASON_MATCHED, codegen_opcode_callback, co);
1351
1352
1353         rpa_dbex_add_callback_exact(dbex, "UnaryExpressionOp", RPA_REASON_MATCHED, codegen_unary_asmop_callback, co);
1354         rpa_dbex_add_callback_exact(dbex, "LogicalNotExpressionOp", RPA_REASON_MATCHED, codegen_unary_asmop_callback, co);
1355         rpa_dbex_add_callback_exact(dbex, "BitwiseNotExpressionOp", RPA_REASON_MATCHED, codegen_unary_asmop_callback, co);
1356
1357         rpa_dbex_add_callback_exact(dbex, "DecimalIntegerLiteral", RPA_REASON_MATCHED, codegen_integer_callback, co);
1358         rpa_dbex_add_callback_exact(dbex, "DecimalNonIntegerLiteral", RPA_REASON_MATCHED, codegen_double_callback, co);
1359         rpa_dbex_add_callback_exact(dbex, "BlockBegin", RPA_REASON_MATCHED, codegen_scopepush_callback, co);
1360         rpa_dbex_add_callback_exact(dbex, "BlockEnd", RPA_REASON_MATCHED, codegen_scopepop_callback, co);
1361         rpa_dbex_add_callback_exact(dbex, "PostfixExpressionInc", RPA_REASON_MATCHED, codegen_postfixinc_callback, co);
1362         rpa_dbex_add_callback_exact(dbex, "PostfixExpressionDec", RPA_REASON_MATCHED, codegen_postfixdec_callback, co);
1363         rpa_dbex_add_callback_exact(dbex, "PrefixExpressionInc", RPA_REASON_MATCHED, codegen_prefixinc_callback, co);
1364         rpa_dbex_add_callback_exact(dbex, "PrefixExpressionDec", RPA_REASON_MATCHED, codegen_prefixdec_callback, co);
1365
1366         rpa_dbex_add_callback_exact(dbex, "DoKeyword", RPA_REASON_MATCHED, codegen_dokeyword_callback, co);
1367         rpa_dbex_add_callback_exact(dbex, "IterationDo", RPA_REASON_MATCHED, codegen_iterationdo_callback, co);
1368
1369
1370
1371         rpa_dbex_add_callback_exact(dbex, "sqstring", RPA_REASON_MATCHED, codegen_string_callback, co);
1372         rpa_dbex_add_callback_exact(dbex, "dqstring", RPA_REASON_MATCHED, codegen_string_callback, co);
1373         rpa_dbex_add_callback_exact(dbex, "DoubleStringCharacters", RPA_REASON_MATCHED, codegen_string_callback, co);
1374         rpa_dbex_add_callback_exact(dbex, "SingleStringCharacters", RPA_REASON_MATCHED, codegen_string_callback, co);
1375         rpa_dbex_add_callback_exact(dbex, "ProgramInit", RPA_REASON_MATCHED, codegen_programinit_callback, co);
1376         rpa_dbex_add_callback_exact(dbex, "Program", RPA_REASON_MATCHED, codegen_program_callback, co);
1377         rpa_dbex_add_callback_exact(dbex, "Initialiser", RPA_REASON_MATCHED, codegen_opassign_callback, co);
1378         rpa_dbex_add_callback_exact(dbex, "AssignmentEq", RPA_REASON_MATCHED, codegen_opassign_callback, co);
1379         rpa_dbex_add_callback_exact(dbex, "AssignmentExpressionOp", RPA_REASON_MATCHED, codegen_opassign_callback, co);
1380
1381         rpa_dbex_add_callback_exact(dbex, "VariableAllocate", RPA_REASON_MATCHED, codegen_varalloc_callback, co);
1382         rpa_dbex_add_callback_exact(dbex, "VariableAllocateAndInit", RPA_REASON_MATCHED, codegen_varalloc_to_ptr_callback, co);
1383
1384         rpa_dbex_add_callback_exact(dbex, "ReturnOp", RPA_REASON_MATCHED, codegen_opreturn_callback, co);
1385
1386         rpa_dbex_add_callback_exact(dbex, "SwiId", RPA_REASON_MATCHED, codegen_swiid_callback, co);
1387         rpa_dbex_add_callback_exact(dbex, "SwiIdExist", RPA_REASON_MATCHED, codegen_swiidexist_callback, co);
1388
1389         rpa_dbex_add_callback_exact(dbex, "IdentifierOp", RPA_REASON_MATCHED, codegen_opidentifier_callback, co);
1390         rpa_dbex_add_callback_exact(dbex, "PostfixExpression", RPA_REASON_MATCHED, codegen_postfixexpression_callback, co);
1391
1392
1393         rpa_dbex_add_callback_exact(dbex, "LeftHandSideExpressionPush", RPA_REASON_MATCHED, codegen_push_r0_callback, co);
1394         rpa_dbex_add_callback_exact(dbex, "LiteralPushOp", RPA_REASON_MATCHED, codegen_push_r0_callback, co);
1395
1396
1397         rpa_dbex_add_callback_exact(dbex, "MemberExpressionIndexBaseOp", RPA_REASON_MATCHED, codegen_memberexpressionbase_callback, co);
1398         rpa_dbex_add_callback_exact(dbex, "MemberExpressionIndexOp", RPA_REASON_MATCHED, codegen_arrayelementaddress_callback, co);
1399
1400         rpa_dbex_add_callback_exact(dbex, "CallExpressionIndexBaseOp", RPA_REASON_MATCHED, codegen_memberexpressionbase_callback, co);
1401         rpa_dbex_add_callback_exact(dbex, "CallExpressionIndexOp", RPA_REASON_MATCHED, codegen_arrayelementaddress_callback, co);
1402
1403         rpa_dbex_add_callback_exact(dbex, "ConditionalExpression", RPA_REASON_MATCHED, codegen_pop_r0_callback, co);
1404         rpa_dbex_add_callback_exact(dbex, "LeftHandSideExpressionDeref", RPA_REASON_MATCHED, codegen_ptr_deref_callback, co);
1405         rpa_dbex_add_callback_exact(dbex, "IdentifierValueOp", RPA_REASON_MATCHED, codegen_identifiervalue_callback, co);
1406
1407
1408         rpa_dbex_add_callback_exact(dbex, "array_member_val", RPA_REASON_MATCHED, codegen_ptr_deref_callback, co);
1409         rpa_dbex_add_callback_exact(dbex, "AssignmetRightHandSide", RPA_REASON_MATCHED, codegen_pop_r0_callback, co);
1410         rpa_dbex_add_callback_exact(dbex, "pop_r0", RPA_REASON_MATCHED, codegen_pop_r0_callback, co);
1411         rpa_dbex_add_callback_exact(dbex, "ValueOfExpression", RPA_REASON_MATCHED, codegen_pop_r0_callback, co);
1412
1413         rpa_dbex_add_callback_exact(dbex, "ArrayElementValue", RPA_REASON_MATCHED, codegen_arrayelementvalue_callback, co);
1414         rpa_dbex_add_callback_exact(dbex, "ArrayElementAddress", RPA_REASON_MATCHED, codegen_arrayelementaddress_callback, co);
1415         rpa_dbex_add_callback_exact(dbex, "NewArraySize", RPA_REASON_MATCHED, codegen_newarraysize_callback, co);
1416         rpa_dbex_add_callback_exact(dbex, "NewArrayNoSize", RPA_REASON_MATCHED, codegen_newarraynosize_callback, co);
1417         rpa_dbex_add_callback_exact(dbex, "compile_error", RPA_REASON_MATCHED, codegen_compile_error_callback, co);
1418
1419         rpa_dbex_add_callback_exact(dbex, "FunctionName", RPA_REASON_MATCHED, codegen_fundeclname_callback, co);
1420         rpa_dbex_add_callback_exact(dbex, "FunctionDefinition", RPA_REASON_MATCHED, codegen_fundeclsignature_callback, co);
1421         rpa_dbex_add_callback_exact(dbex, "FunctionDeclaration", RPA_REASON_MATCHED, codegen_fundecl_callback, co);
1422         rpa_dbex_add_callback_exact(dbex, "FunctionParameter", RPA_REASON_MATCHED, codegen_fundeclparameter_callback, co);
1423         rpa_dbex_add_callback_exact(dbex, "FunctionCallParameter", RPA_REASON_MATCHED, codegen_funcallparameter_callback, co);
1424         rpa_dbex_add_callback_exact(dbex, "FunctionCallName", RPA_REASON_MATCHED, codegen_funcallname_callback, co);
1425         rpa_dbex_add_callback_exact(dbex, "CallExpressionOp", RPA_REASON_MATCHED, codegen_funcallexpression_callback, co);
1426         rpa_dbex_add_callback_exact(dbex, "IfConditionOp", RPA_REASON_MATCHED, codegen_ifconditionop_callback, co);
1427         rpa_dbex_add_callback_exact(dbex, "IfOp", RPA_REASON_MATCHED, codegen_ifop_callback, co);
1428         rpa_dbex_add_callback_exact(dbex, "ElseOp", RPA_REASON_MATCHED, codegen_elseop_callback, co);
1429         rpa_dbex_add_callback_exact(dbex, "IfElseOp", RPA_REASON_MATCHED, codegen_ifelseop_callback, co);
1430
1431
1432         if (verboseinfo)
1433                 rpa_dbex_add_callback(dbex, ".*", RPA_REASON_MATCHED, codegen_print_callback, co);
1434
1435         while ((ret = rpa_dbex_load(dbex, pattern, inputsize)) > 0) {
1436                 inputsize -= ret;
1437                 pattern += ret;
1438         }
1439         if (ret < 0) {
1440                 for (line = 1; pattern >= buffer; --pattern) {
1441                         if (*pattern == '\n')
1442                                 line += 1;
1443                 }
1444                 fprintf(stdout, "Line: %d, RPA LOAD ERROR: %s\n", line, (rpa_dbex_get_error(dbex) == RPA_E_SYNTAX_ERROR) ? "Syntax Error." : "Pattern Loading failed.");
1445                 goto error;
1446         }
1447
1448 error:
1449         rpa_dbex_close(dbex);
1450 }