diff options
| author | Franklin Wei <git@fwei.tk> | 2015-11-26 15:36:59 -0500 |
|---|---|---|
| committer | Franklin Wei <git@fwei.tk> | 2015-11-26 15:36:59 -0500 |
| commit | 4ac525349f7997aaf090edae932c14972c77d385 (patch) | |
| tree | b9ea3037365778077122770f9378eea80ea12c0c | |
| parent | f9bd70a047c357d7f4ebfadbfe34c30becb380db (diff) | |
| download | ducky-4ac525349f7997aaf090edae932c14972c77d385.zip ducky-4ac525349f7997aaf090edae932c14972c77d385.tar.gz ducky-4ac525349f7997aaf090edae932c14972c77d385.tar.bz2 ducky-4ac525349f7997aaf090edae932c14972c77d385.tar.xz | |
support one-command compilation, replace jump table with switch statement
| -rw-r--r-- | src/emitc.c | 22 | ||||
| -rw-r--r-- | target/unix/main.c | 39 |
2 files changed, 56 insertions, 5 deletions
diff --git a/src/emitc.c b/src/emitc.c index 94d8210..c205a91 100644 --- a/src/emitc.c +++ b/src/emitc.c @@ -506,7 +506,9 @@ static void inc_line_pointer(void) { ++current_line; - write_src_noindent("label_%d:\n", current_line); + --indent_depth; + write_src("case %d:\n", current_line); + ++indent_depth; write_src("vars[0].val = %d;\n\n", current_line); } @@ -901,17 +903,17 @@ void write_stub_code(int num_lines) write_src("return a2<0 ? 0 : (a2==0?1:a1*eval_exp(a1, a2-1));\n"); write_src("}\n"); - write_src("#define JUMP(LINE) do{imm_t x = LINE; if(1 <= x && x <= %d) goto *jump_table[x]; else ERROR(\"jump target out of range\");}while(0);\n\n", num_lines); + write_src("#define JUMP(LINE) {imm_t x = LINE; if(1 <= x && x <= %d) { vars[0].val = x; break; } else ERROR(\"jump target out of range\");}\n\n", num_lines); write_src("#define PUSH(VAL) do { imm_t x = VAL; if(stack_pointer < STACK_SZ) stack[stack_pointer++] = x; else ERROR(\"stack overflow\");}while(0);\n\n"); - write_src("#define POP() (stack[--stack_pointer])\n"); + write_src("#define POP() (stack[--stack_pointer])\n\n"); write_src("int main()\n"); write_src("{\n"); write_src("register imm_t stack_pointer = 0, callstack_pointer = 0;\n"); write_src("(void) stack_pointer; (void) callstack_pointer;\n"); write_src("(void) eval_exp;\n"); - /* prefetch some high-use variables */ +#if 0 write_src("/* this uses labels as values, a GCC extension */\n"); write_src("const void *jump_table[%d] = {\n", num_lines + 1); @@ -923,6 +925,15 @@ void write_stub_code(int num_lines) } write_src("};\n"); write_src_noindent("\n"); +#endif + write_src("for(;;)\n"); + write_src("{\n"); + write_src("switch(vars[0].val)\n"); + write_src("{\n"); + --indent_depth; + write_src("case 0:\n"); + ++indent_depth; + write_src("/* init code */\n"); } int ducky_to_c(int fd, int out) @@ -957,6 +968,9 @@ int ducky_to_c(int fd, int out) else ERROR("invalid instruction %d", instr); } + write_src("return 0;\n"); + write_src("}\n"); + write_src("}\n"); write_src("}"); return 0; } diff --git a/target/unix/main.c b/target/unix/main.c index d7f49bf..e5dc4a3 100644 --- a/target/unix/main.c +++ b/target/unix/main.c @@ -12,6 +12,12 @@ char *progname; void arg_error(void) { printf("Usage: %s [-aceit] FILE\n", progname); + printf(" -a: compile to machine code\n"); + printf(" -c: compile to bytecode\n"); + printf(" -e: execute bytecode (not needed)\n"); + printf(" -i: interpret directly (default action)\n"); + printf(" -t: transcompile to C\n"); + printf("Default action is to interpret or execute bytecode.\n"); exit(EXIT_FAILURE); } @@ -24,7 +30,9 @@ int main(int argc, char *argv[]) { for(int i = 1; i < argc; ++i) { - if(!strcmp(argv[i], "-c")) + if(!strcmp(argv[i], "-a")) + action = EVERYTHING; + else if(!strcmp(argv[i], "-c")) action = COMPILE; else if(!strcmp(argv[i], "-i")) action = INTERP; @@ -79,6 +87,35 @@ int main(int argc, char *argv[]) return 1; } break; + case EVERYTHING: + { + char bytecode[L_tmpnam]; + tmpnam(bytecode); + out_fd = open(bytecode, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if(ducky_compile(fd, false, out_fd)) + { + printf("Compiler error.\n"); + return 1; + } + + close(fd); + close(out_fd); + + char c_code[L_tmpnam]; + tmpnam(c_code); + fd = open(bytecode, O_RDONLY); + out_fd = open(c_code, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if(ducky_to_c(fd, out_fd)) + { + printf("Transcompiler error.\n"); + return 1; + } + close(fd); + close(out_fd); + char cmd[256]; + snprintf(cmd, sizeof(cmd), "cc -O3 -lm -x c %s", c_code); + system(cmd); + } default: break; } |