aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2015-11-26 15:36:59 -0500
committerFranklin Wei <git@fwei.tk>2015-11-26 15:36:59 -0500
commit4ac525349f7997aaf090edae932c14972c77d385 (patch)
treeb9ea3037365778077122770f9378eea80ea12c0c
parentf9bd70a047c357d7f4ebfadbfe34c30becb380db (diff)
downloadducky-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.c22
-rw-r--r--target/unix/main.c39
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;
}