RPA Toolkit
adding rvm_compiler_t to the rpagen test
[rpatk.git] / tests / rpagen-test.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "rmem.h"
4 #include "rvmcpu.h"
5 #include "rpadbex.h"
6 #include "rvmcodegen.h"
7 #include "rvmcodemap.h"
8 #include "rvmscope.h"
9
10
11 typedef struct rvm_compiler_s {
12         rvm_codegen_t *cg;
13         rvm_scope_t *scope;
14         ruint fpoff;
15 } rvm_compiler_t;
16
17
18 rvm_compiler_t *rvm_compiler_create()
19 {
20         rvm_compiler_t *co;
21
22         co = r_malloc(sizeof(*co));
23         r_memset(co, 0, sizeof(*co));
24         co->cg = rvm_codegen_create();
25         co->scope = rvm_scope_create();
26         return co;
27 }
28
29
30 void rvm_compiler_destroy(rvm_compiler_t *co)
31 {
32         if (co) {
33                 rvm_codegen_destroy(co->cg);
34                 rvm_scope_destroy(co->scope);
35                 r_free(co);
36         }
37 }
38
39
40 static void test_swi_none(rvmcpu_t *cpu, rvm_asmins_t *ins)
41 {
42 }
43
44 static rvm_switable_t switable[] = {
45                 {"none", test_swi_none},
46                 {NULL, NULL},
47 };
48
49 #define DEBUGPRINT 1
50 int codegen_print_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
51 {
52 #ifdef DEBUGPRINT
53         fprintf(stdout, "%s: ", name);
54         fwrite(input, sizeof(char), size, stdout);
55         fprintf(stdout, "\n");
56 #endif
57         return size;
58 }
59
60
61 int codegen_mulop_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
62 {
63         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
64         ruint off = rvm_codegen_getcodesize(co->cg);
65
66         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R2, XX, XX, 0));
67         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
68         rvm_codegen_addins(co->cg, rvm_asm(RVM_EMUL, R0, R1, R2, 0));
69         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
70
71         codegen_print_callback(name, userdata, input, size, reason, start, end);
72         rvm_asm_dump(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
73
74         return size;
75 }
76
77
78 int codegen_divop_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
79 {
80         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
81         ruint off = rvm_codegen_getcodesize(co->cg);
82
83         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R2, XX, XX, 0));
84         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
85         rvm_codegen_addins(co->cg, rvm_asm(RVM_EDIV, R0, R1, R2, 0));
86         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
87
88         codegen_print_callback(name, userdata, input, size, reason, start, end);
89         rvm_asm_dump(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
90
91         return size;
92
93 }
94
95
96 int codegen_subop_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
97 {
98         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
99         ruint off = rvm_codegen_getcodesize(co->cg);
100
101         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R2, XX, XX, 0));
102         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
103         rvm_codegen_addins(co->cg, rvm_asm(RVM_ESUB, R0, R1, R2, 0));
104         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
105
106         codegen_print_callback(name, userdata, input, size, reason, start, end);
107         rvm_asm_dump(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
108
109         return size;
110 }
111
112
113 int codegen_addop_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
114 {
115         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
116         ruint off = rvm_codegen_getcodesize(co->cg);
117
118         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R2, XX, XX, 0));
119         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
120         rvm_codegen_addins(co->cg, rvm_asm(RVM_EADD, R0, R1, R2, 0));
121         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
122
123         codegen_print_callback(name, userdata, input, size, reason, start, end);
124         rvm_asm_dump(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
125
126         return size;
127 }
128
129
130 int codegen_integer_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
131 {
132         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
133         ruint off = rvm_codegen_getcodesize(co->cg);
134
135         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, DA, XX, XX, r_strtol(input, NULL, 10)));
136
137         codegen_print_callback(name, userdata, input, size, reason, start, end);
138         rvm_asm_dump(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
139
140         return size;
141 }
142
143
144 int codegen_double_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
145 {
146         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
147         ruint off = rvm_codegen_getcodesize(co->cg);
148
149         rvm_codegen_addins(co->cg, rvm_asmd(RVM_PUSH, DA, XX, XX, r_strtod(input, NULL)));
150
151         codegen_print_callback(name, userdata, input, size, reason, start, end);
152         rvm_asm_dump(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
153
154         return size;
155 }
156
157
158 int codegen_numexpr_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
159 {
160         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
161         ruint off = rvm_codegen_getcodesize(co->cg);
162
163         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R0, XX, XX, 0));
164         rvm_codegen_addins(co->cg, rvm_asm(RVM_PRN, R0, XX, XX, 0));
165         rvm_codegen_addins(co->cg, rvm_asm(RVM_EXT, XX, XX, XX, 0));
166
167         codegen_print_callback(name, userdata, input, size, reason, start, end);
168         rvm_asm_dump(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
169         return size;
170 }
171
172
173 int codegen_assignment_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
174 {
175         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
176         ruint off = rvm_codegen_getcodesize(co->cg);
177
178         codegen_print_callback(name, userdata, input, size, reason, start, end);
179         rvm_asm_dump(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
180
181         return size;
182 }
183
184
185 int codegen_varname_callback(const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason, const char *start, const char *end)
186 {
187         rvm_compiler_t *co = (rvm_compiler_t *)userdata;
188         ruint off = rvm_codegen_getcodesize(co->cg);
189
190         codegen_print_callback(name, userdata, input, size, reason, start, end);
191         rvm_asm_dump(rvm_codegen_getcode(co->cg, off), rvm_codegen_getcodesize(co->cg) - off);
192
193         return size;
194 }
195
196 int main(int argc, char *argv[])
197 {
198         int res;
199         rvmcpu_t *cpu;
200         ruint ntable;
201         rvm_compiler_t *co = rvm_compiler_create();
202         rpa_dbex_handle dbex;
203
204         dbex = rpa_dbex_create();
205         rpa_dbex_add_callback(dbex, "mulop", RPA_REASON_MATCHED, codegen_mulop_callback, co);
206         rpa_dbex_add_callback(dbex, "divop", RPA_REASON_MATCHED, codegen_divop_callback, co);
207         rpa_dbex_add_callback(dbex, "addop", RPA_REASON_MATCHED, codegen_addop_callback, co);
208         rpa_dbex_add_callback(dbex, "subop", RPA_REASON_MATCHED, codegen_subop_callback, co);
209         rpa_dbex_add_callback(dbex, "integer", RPA_REASON_MATCHED, codegen_integer_callback, co);
210         rpa_dbex_add_callback(dbex, "double", RPA_REASON_MATCHED, codegen_double_callback, co);
211         rpa_dbex_add_callback(dbex, "numexpr", RPA_REASON_MATCHED, codegen_numexpr_callback, co);
212         rpa_dbex_add_callback(dbex, "assignment", RPA_REASON_MATCHED, codegen_assignment_callback, co);
213         rpa_dbex_add_callback(dbex, "varname", RPA_REASON_MATCHED, codegen_varname_callback, co);
214
215
216         rpa_dbex_open(dbex);
217         rpa_dbex_load_string(dbex, "S                   ::= [#x20]+");
218         rpa_dbex_load_string(dbex, "digit               ::= [0-9]");
219         rpa_dbex_load_string(dbex, "eoe                 ::= (';' | [#xD] | [#xA])+");
220         rpa_dbex_load_string(dbex, "varname             ::= [a-zA-z][a-zA-z0-9]*");
221         rpa_dbex_load_string(dbex, "assignment  ::= <:S:>? <:varname:> <:S:>? '=' <:S:>? (<:double:> | <:integer:>) <:S:>? <:eoe:>");
222         rpa_dbex_load_string(dbex, "integer             ::= <:digit:>+");
223         rpa_dbex_load_string(dbex, "double              ::= <:digit:>+ '.' <:digit:>+ | '.' <:digit:>+");
224         rpa_dbex_load_string(dbex, "term                ::= <:double:> | <:integer:> | '('<:S:>? <:expr:> <:S:>? ')'");
225         rpa_dbex_load_string(dbex, "mulop               ::= <:mulex:> <:S:>? '*' <:S:>? <:term:>");
226         rpa_dbex_load_string(dbex, "divop               ::= <:mulex:> <:S:>? '/' <:S:>? <:term:>");
227         rpa_dbex_load_string(dbex, "mulex               ::= <:mulop:> | <:divop:> | <:term:>");
228         rpa_dbex_load_string(dbex, "addop               ::= <:expr:> <:S:>? '+' <:S:>? <:mulex:>");
229         rpa_dbex_load_string(dbex, "subop               ::= <:expr:> <:S:>? '-' <:S:>? <:mulex:>");
230         rpa_dbex_load_string(dbex, "expr        ::= <:addop:> | <:subop:> | <:mulex:>");
231         rpa_dbex_load_string(dbex, "numexpr             ::= <:expr:>");
232         rpa_dbex_load_string(dbex, "exec                ::= <:assignment:>* <:S:>? <:numexpr:>");
233         rpa_dbex_close(dbex);
234         if (argc > 1) {
235                 res = rpa_dbex_parse(dbex, rpa_dbex_default_pattern(dbex), argv[1], argv[1], argv[1] + r_strlen(argv[1]));
236         }
237         rpa_dbex_destroy(dbex);
238         rvm_relocate(rvm_codegen_getcode(co->cg, 0), rvm_codegen_getcodesize(co->cg));
239 //      rvm_asm_dump(rvm_codegen_getcode(co->cg, 0), rvm_codegen_getcodesize(co->cg));
240
241
242         cpu = rvm_cpu_create();
243         ntable = rvmcpu_switable_add(cpu, switable);
244         if (rvm_codegen_getcodesize(co->cg))
245                 rvm_cpu_exec_debug(cpu, rvm_codegen_getcode(co->cg, 0), 0);
246         rvm_cpu_destroy(cpu);
247         rvm_compiler_destroy(co);
248         fprintf(stdout, "Max alloc mem: %ld\n", r_debug_get_maxmem());
249         fprintf(stdout, "Leaked mem: %ld\n", r_debug_get_allocmem());
250
251         return 0;
252 }