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