10 #include "rjsobject.h"
14 #include "rvmcodegen.h"
15 #include "rvmcodemap.h"
17 #include "rvmoperator.h"
22 typedef struct rastcompiler_s {
29 void r_astcompiler_loadrules(rastcompiler_t *aco);
32 static int debuginfo = 0;
33 static int parseinfo = 0;
34 static int verboseinfo = 0;
35 static int compileonly = 0;
38 void codegen_unmap_file(rstr_t *buf)
41 munmap(buf->str, buf->size);
47 rstr_t *codegen_map_file(const char *filename)
54 int fd = open(filename, O_RDONLY);
58 if (fstat(fd, &st) < 0) {
62 buffer = (char*)mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
63 if (buffer == (void*)-1) {
67 str = (rstr_t *)r_malloc(sizeof(*str));
70 r_memset(str, 0, sizeof(*str));
72 str->size = st.st_size;
77 munmap(buffer, st.st_size);
83 rastcompiler_t *r_astcompiler_create()
87 aco = r_malloc(sizeof(*aco));
88 r_memset(aco, 0, sizeof(*aco));
89 aco->gc = r_gc_create();
90 aco->root = r_astnode_create();
91 r_gc_add(aco->gc, (robject_t*)aco->root);
96 void r_astcompiler_destroy(rastcompiler_t *aco)
99 r_object_destroy((robject_t*)aco->gc);
105 void r_astnode_dump(rastnode_t *node, ruint level)
110 for (i = 0; i < level; i++)
111 fprintf(stdout, " ");
112 nodename = (rastval_t*)r_harray_get(node->props, r_harray_lookup_s(node->props, "name"));
114 if (node->val.type == R_ASTVAL_ARRAY) {
116 fprintf(stdout, "%s: ", nodename->v.str->s.str);
117 fwrite(node->src.ptr, sizeof(char), node->src.size, stdout);
118 fprintf(stdout, "\n");
121 for (i = 0; i < r_carray_length(node->val.v.arr); i++) {
122 rastval_t *val = (rastval_t *)r_carray_slot(node->val.v.arr, i);
123 r_astnode_dump(val->v.node, level + 1);
128 fprintf(stdout, "%s: ", nodename->v.str->s.str);
130 fwrite(node->src.ptr, sizeof(char), node->src.size, stdout);
131 fprintf(stdout, "\n");
137 void r_astnode_propery_set_string(rastnode_t *node, const char *key, rstring_t *str)
140 R_ASTVAL_SET_STRING(&val, str);
141 r_harray_add_s(node->props, key, &val);
144 void r_astcompiler_dumptree(rastcompiler_t *aco)
146 r_astnode_dump(aco->root, 0);
150 int r_astcompiler_dumpnotification(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
152 rastcompiler_t *aco = (rastcompiler_t *)userdata;
154 if (reason & RPA_REASON_START)
155 fprintf(stdout, "START ");
156 if (reason & RPA_REASON_MATCHED)
157 fprintf(stdout, "MATCHED ");
158 if (reason & RPA_REASON_END)
159 fprintf(stdout, "END ");
160 fprintf(stdout, "%s: ", name);
161 fprintf(stdout, "\n");
166 int r_astcompiler_notify(rpa_stat_handle stat, const char *name, void *userdata, const char *input, unsigned int size, unsigned int reason)
168 rastcompiler_t *aco = (rastcompiler_t *)userdata;
171 r_astcompiler_dumpnotification(stat, name, userdata, input, size, reason);
173 if (reason & RPA_REASON_START) {
174 rastnode_t *node = r_astnode_create();
175 r_gc_add(aco->gc, (robject_t*)node);
176 node->parent = aco->root;
178 } else if (reason & RPA_REASON_MATCHED) {
179 rastnode_t *node = aco->root;
180 rstring_t *nodename = r_string_create_from_ansistr(name);
181 r_gc_add(aco->gc, (robject_t*)nodename);
182 r_astnode_propery_set_string(node, "name", nodename);
183 aco->root = node->parent;
184 r_astnode_addchild(aco->root, node);
185 node->src.ptr = (rpointer)input;
186 node->src.size = size;
188 aco->root = aco->root->parent;
195 int main(int argc, char *argv[])
198 rstr_t *script = NULL, *unmapscript = NULL;
199 rastcompiler_t *aco = r_astcompiler_create();
200 aco->dbex = rpa_dbex_create();
203 for (i = 1; i < argc; i++) {
204 if (r_strcmp(argv[i], "-L") == 0) {
205 } else if (r_strcmp(argv[i], "-d") == 0) {
207 } else if (r_strcmp(argv[i], "-p") == 0) {
209 } else if (r_strcmp(argv[i], "-P") == 0) {
212 } else if (r_strcmp(argv[i], "-c") == 0) {
214 } else if (r_strcmp(argv[i], "-o") == 0) {
216 } else if (r_strcmp(argv[i], "-m") == 0) {
221 r_astcompiler_loadrules(aco);
223 for (i = 1; i < argc; i++) {
224 if (r_strcmp(argv[i], "-e") == 0) {
226 rstr_t script = { argv[i], r_strlen(argv[i]) };
227 res = rpa_dbex_parse(aco->dbex, rpa_dbex_default_pattern(aco->dbex), script.str, script.str, script.str + script.size);
235 for (i = 1; i < argc; i++) {
236 if (r_strcmp(argv[i], "-f") == 0) {
239 script = codegen_map_file(argv[i]);
241 res = rpa_dbex_parse(aco->dbex, rpa_dbex_default_pattern(aco->dbex), script->str, script->str, script->str + script->size);
242 unmapscript = script;
254 r_astcompiler_dumptree(aco);
259 codegen_unmap_file(unmapscript);
260 rpa_dbex_destroy(aco->dbex);
261 r_astcompiler_destroy(aco);
264 r_printf("Max alloc mem: %ld\n", r_debug_get_maxmem());
265 r_printf("Leaked mem: %ld\n", r_debug_get_allocmem());
272 extern char _binary_____________tests_astecma262_rpa_start[];
273 extern char _binary_____________tests_astecma262_rpa_end[];
274 extern unsigned long *_binary_____________tests_astecma262_rpa_size;
276 void r_astcompiler_loadrules(rastcompiler_t *aco)
279 int inputsize = _binary_____________tests_astecma262_rpa_end - _binary_____________tests_astecma262_rpa_start;
280 const char *buffer = _binary_____________tests_astecma262_rpa_start;
281 const char *pattern = buffer;
283 rpa_dbex_open(aco->dbex);
284 rpa_dbex_add_callback_exact(aco->dbex, "Identifier", RPA_REASON_ALL, r_astcompiler_notify, aco);
288 rpa_dbex_add_callback_exact(aco->dbex, "BitwiseANDOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
289 rpa_dbex_add_callback_exact(aco->dbex, "BitwiseXOROp", RPA_REASON_ALL, r_astcompiler_notify, aco);
290 rpa_dbex_add_callback_exact(aco->dbex, "BitwiseOROp", RPA_REASON_ALL, r_astcompiler_notify, aco);
291 rpa_dbex_add_callback_exact(aco->dbex, "AdditiveExpressionOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
292 rpa_dbex_add_callback_exact(aco->dbex, "MultiplicativeExpressionOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
294 // rpa_dbex_add_callback_exact(aco->dbex, "AdditiveExpression", RPA_REASON_ALL, r_astcompiler_notify, aco);
295 // rpa_dbex_add_callback_exact(aco->dbex, "MultiplicativeExpression", RPA_REASON_ALL, r_astcompiler_notify, aco);
298 rpa_dbex_add_callback_exact(aco->dbex, "ShiftExpressionOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
299 rpa_dbex_add_callback_exact(aco->dbex, "EqualityExpressionOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
300 rpa_dbex_add_callback_exact(aco->dbex, "RelationalExpressionOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
301 rpa_dbex_add_callback_exact(aco->dbex, "LogicalOROp", RPA_REASON_ALL, r_astcompiler_notify, aco);
302 rpa_dbex_add_callback_exact(aco->dbex, "LogicalANDOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
304 rpa_dbex_add_callback_exact(aco->dbex, "AssignmentOperator", RPA_REASON_ALL, r_astcompiler_notify, aco);
305 rpa_dbex_add_callback_exact(aco->dbex, "EqualityOperator", RPA_REASON_ALL, r_astcompiler_notify, aco);
306 rpa_dbex_add_callback_exact(aco->dbex, "RelationalOperator", RPA_REASON_ALL, r_astcompiler_notify, aco);
307 rpa_dbex_add_callback_exact(aco->dbex, "AdditiveOperator", RPA_REASON_ALL, r_astcompiler_notify, aco);
308 rpa_dbex_add_callback_exact(aco->dbex, "MultiplicativeOperator", RPA_REASON_ALL, r_astcompiler_notify, aco);
309 rpa_dbex_add_callback_exact(aco->dbex, "ShiftOperator", RPA_REASON_ALL, r_astcompiler_notify, aco);
310 rpa_dbex_add_callback_exact(aco->dbex, "BitwiseANDOperator", RPA_REASON_ALL, r_astcompiler_notify, aco);
311 rpa_dbex_add_callback_exact(aco->dbex, "BitwiseXOROperator", RPA_REASON_ALL, r_astcompiler_notify, aco);
312 rpa_dbex_add_callback_exact(aco->dbex, "BitwiseOROperator", RPA_REASON_ALL, r_astcompiler_notify, aco);
313 rpa_dbex_add_callback_exact(aco->dbex, "LogicalANDOperator", RPA_REASON_ALL, r_astcompiler_notify, aco);
314 rpa_dbex_add_callback_exact(aco->dbex, "LogicalOROperator", RPA_REASON_ALL, r_astcompiler_notify, aco);
315 rpa_dbex_add_callback_exact(aco->dbex, "LogicalNotOperator", RPA_REASON_ALL, r_astcompiler_notify, aco);
316 rpa_dbex_add_callback_exact(aco->dbex, "BitwiseNotOperator", RPA_REASON_ALL, r_astcompiler_notify, aco);
317 rpa_dbex_add_callback_exact(aco->dbex, "UnaryOperatorOpcode", RPA_REASON_ALL, r_astcompiler_notify, aco);
318 rpa_dbex_add_callback_exact(aco->dbex, "PrintOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
321 rpa_dbex_add_callback_exact(aco->dbex, "PostfixOperator", RPA_REASON_ALL, r_astcompiler_notify, aco);
322 rpa_dbex_add_callback_exact(aco->dbex, "PostfixExpressionOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
323 rpa_dbex_add_callback_exact(aco->dbex, "PrefixExpressionOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
326 rpa_dbex_add_callback_exact(aco->dbex, "UnaryExpressionOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
327 rpa_dbex_add_callback_exact(aco->dbex, "LogicalNotExpressionOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
328 rpa_dbex_add_callback_exact(aco->dbex, "BitwiseNotExpressionOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
330 rpa_dbex_add_callback_exact(aco->dbex, "DecimalIntegerLiteral", RPA_REASON_ALL, r_astcompiler_notify, aco);
331 rpa_dbex_add_callback_exact(aco->dbex, "DecimalNonIntegerLiteral", RPA_REASON_ALL, r_astcompiler_notify, aco);
332 rpa_dbex_add_callback_exact(aco->dbex, "BlockBegin", RPA_REASON_ALL, r_astcompiler_notify, aco);
333 rpa_dbex_add_callback_exact(aco->dbex, "BlockEnd", RPA_REASON_ALL, r_astcompiler_notify, aco);
335 rpa_dbex_add_callback_exact(aco->dbex, "DoKeyword", RPA_REASON_ALL, r_astcompiler_notify, aco);
336 rpa_dbex_add_callback_exact(aco->dbex, "IterationDo", RPA_REASON_ALL, r_astcompiler_notify, aco);
338 rpa_dbex_add_callback_exact(aco->dbex, "sqstring", RPA_REASON_ALL, r_astcompiler_notify, aco);
339 rpa_dbex_add_callback_exact(aco->dbex, "dqstring", RPA_REASON_ALL, r_astcompiler_notify, aco);
340 rpa_dbex_add_callback_exact(aco->dbex, "DoubleStringCharacters", RPA_REASON_ALL, r_astcompiler_notify, aco);
341 rpa_dbex_add_callback_exact(aco->dbex, "SingleStringCharacters", RPA_REASON_ALL, r_astcompiler_notify, aco);
342 rpa_dbex_add_callback_exact(aco->dbex, "Program", RPA_REASON_ALL, r_astcompiler_notify, aco);
343 rpa_dbex_add_callback_exact(aco->dbex, "Initialiser", RPA_REASON_ALL, r_astcompiler_notify, aco);
344 rpa_dbex_add_callback_exact(aco->dbex, "AssignmentExpressionOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
346 rpa_dbex_add_callback_exact(aco->dbex, "VariableAllocate", RPA_REASON_ALL, r_astcompiler_notify, aco);
347 rpa_dbex_add_callback_exact(aco->dbex, "VariableAllocateAndInit", RPA_REASON_ALL, r_astcompiler_notify, aco);
349 rpa_dbex_add_callback_exact(aco->dbex, "ReturnOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
351 // rpa_dbex_add_callback_exact(aco->dbex, "SwiId", RPA_REASON_ALL, r_astcompiler_notify, aco);
352 // rpa_dbex_add_callback_exact(aco->dbex, "SwiIdExist", RPA_REASON_ALL, r_astcompiler_notify, aco);
354 rpa_dbex_add_callback_exact(aco->dbex, "PostfixExpressionValOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
355 rpa_dbex_add_callback_exact(aco->dbex, "LeftHandSideExpressionPush", RPA_REASON_ALL, r_astcompiler_notify, aco);
359 rpa_dbex_add_callback_exact(aco->dbex, "ThisOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
360 rpa_dbex_add_callback_exact(aco->dbex, "IdentifierOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
361 rpa_dbex_add_callback_exact(aco->dbex, "MemberIdentifierNameOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
362 rpa_dbex_add_callback_exact(aco->dbex, "MemberExpressionBaseOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
363 rpa_dbex_add_callback_exact(aco->dbex, "MemberExpressionIndexOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
364 rpa_dbex_add_callback_exact(aco->dbex, "MemberExpressionNameOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
365 rpa_dbex_add_callback_exact(aco->dbex, "CallExpressionNameOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
366 rpa_dbex_add_callback_exact(aco->dbex, "CallExpressionBaseOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
367 rpa_dbex_add_callback_exact(aco->dbex, "CallExpressionIndexOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
368 rpa_dbex_add_callback_exact(aco->dbex, "AddressLeftHandSideExpression", RPA_REASON_ALL, r_astcompiler_notify, aco);
373 rpa_dbex_add_callback_exact(aco->dbex, "ConditionalExpression", RPA_REASON_ALL, r_astcompiler_notify, aco);
374 rpa_dbex_add_callback_exact(aco->dbex, "NewArrayExpressionOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
375 rpa_dbex_add_callback_exact(aco->dbex, "compile_error", RPA_REASON_ALL, r_astcompiler_notify, aco);
377 rpa_dbex_add_callback_exact(aco->dbex, "ArgumentsOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
378 rpa_dbex_add_callback_exact(aco->dbex, "BracketExpressionOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
379 rpa_dbex_add_callback_exact(aco->dbex, "ValLeftHandSideExpression", RPA_REASON_ALL, r_astcompiler_notify, aco);
381 rpa_dbex_add_callback_exact(aco->dbex, "FunctionNameLookupAlloc", RPA_REASON_ALL, r_astcompiler_notify, aco);
382 rpa_dbex_add_callback_exact(aco->dbex, "FunctionName", RPA_REASON_ALL, r_astcompiler_notify, aco);
383 rpa_dbex_add_callback_exact(aco->dbex, "FunctionDeclaration", RPA_REASON_ALL, r_astcompiler_notify, aco);
384 rpa_dbex_add_callback_exact(aco->dbex, "FunctionParameter", RPA_REASON_ALL, r_astcompiler_notify, aco);
385 rpa_dbex_add_callback_exact(aco->dbex, "FunctionCallParameter", RPA_REASON_ALL, r_astcompiler_notify, aco);
386 rpa_dbex_add_callback_exact(aco->dbex, "FunctionCallName", RPA_REASON_ALL, r_astcompiler_notify, aco);
387 rpa_dbex_add_callback_exact(aco->dbex, "CallExpressionOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
388 rpa_dbex_add_callback_exact(aco->dbex, "NewKeyword", RPA_REASON_ALL, r_astcompiler_notify, aco);
390 rpa_dbex_add_callback_exact(aco->dbex, "NewExpressionCallName", RPA_REASON_ALL, r_astcompiler_notify, aco);
391 rpa_dbex_add_callback_exact(aco->dbex, "NewExpressionCallOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
394 rpa_dbex_add_callback_exact(aco->dbex, "IfConditionOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
395 rpa_dbex_add_callback_exact(aco->dbex, "IfOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
396 rpa_dbex_add_callback_exact(aco->dbex, "ElseOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
397 rpa_dbex_add_callback_exact(aco->dbex, "IfElseOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
399 rpa_dbex_add_callback_exact(aco->dbex, "WhileConditionOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
400 rpa_dbex_add_callback_exact(aco->dbex, "IterationWhileOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
402 rpa_dbex_add_callback_exact(aco->dbex, "QuestionMarkOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
403 rpa_dbex_add_callback_exact(aco->dbex, "AssignmentExpressionIfTrueOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
404 rpa_dbex_add_callback_exact(aco->dbex, "AssignmentExpressionIfFalseOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
406 rpa_dbex_add_callback_exact(aco->dbex, "ForKeyword", RPA_REASON_ALL, r_astcompiler_notify, aco);
407 rpa_dbex_add_callback_exact(aco->dbex, "ForExpressionInitOp", RPA_REASON_END, r_astcompiler_notify, aco);
408 rpa_dbex_add_callback_exact(aco->dbex, "ForExpressionCompareOp", RPA_REASON_END, r_astcompiler_notify, aco);
409 rpa_dbex_add_callback_exact(aco->dbex, "ForExpressionIncrementOp", RPA_REASON_END, r_astcompiler_notify, aco);
410 rpa_dbex_add_callback_exact(aco->dbex, "IterationForOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
411 rpa_dbex_add_callback_exact(aco->dbex, "BreakOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
412 rpa_dbex_add_callback_exact(aco->dbex, "ContinueOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
414 rpa_dbex_add_callback_exact(aco->dbex, "SwitchExpressionOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
415 rpa_dbex_add_callback_exact(aco->dbex, "SwitchStatementOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
416 rpa_dbex_add_callback_exact(aco->dbex, "CaseExpressionOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
417 rpa_dbex_add_callback_exact(aco->dbex, "CaseClauseOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
418 rpa_dbex_add_callback_exact(aco->dbex, "DefaultKeywordOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
419 rpa_dbex_add_callback_exact(aco->dbex, "DefaultClauseOp", RPA_REASON_ALL, r_astcompiler_notify, aco);
423 // rpa_dbex_add_callback(aco->dbex, ".*", RPA_REASON_ALL, r_astcompiler_notify, aco);
425 while ((ret = rpa_dbex_load(aco->dbex, pattern, inputsize)) > 0) {
430 for (line = 1; pattern >= buffer; --pattern) {
431 if (*pattern == '\n')
434 fprintf(stdout, "Line: %d, RPA LOAD ERROR: %s\n", line, (rpa_dbex_get_error(aco->dbex) == RPA_E_SYNTAX_ERROR) ? "Syntax Error." : "Pattern Loading failed.");
439 rpa_dbex_close(aco->dbex);