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