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