| @@ -23,17 +23,47 @@ void step_through(struct l2_vm *vm) { | |||
| } | |||
| } | |||
| int main(int argc, char **argv) { | |||
| if (argc != 1 && argc != 2) { | |||
| fprintf(stderr, "Usage: %s [file]\n", argv[0]); | |||
| return 1; | |||
| } | |||
| static void usage(const char *argv0) { | |||
| printf("Usage: %s [options] [input|-]\n", argv0); | |||
| printf("\n"); | |||
| printf("Options:\n"); | |||
| printf(" --help: Print this help text\n"); | |||
| printf(" --bytecode: Print the generated bytecode, don't execute\n"); | |||
| printf(" --step: Step through the program\n"); | |||
| } | |||
| FILE *inf; | |||
| if (argc == 1 || (argc == 2 && strcmp(argv[1], "-") == 0)) { | |||
| inf = stdin; | |||
| } else { | |||
| inf = fopen(argv[1], "r"); | |||
| int main(int argc, char **argv) { | |||
| int do_print_bytecode = 0; | |||
| int do_step = 0; | |||
| int was_inf_set = 0; | |||
| FILE *inf = stdin; | |||
| int dashes = 0; | |||
| for (int i = 1; i < argc; ++i) { | |||
| if (!dashes && strcmp(argv[i], "--help") == 0) { | |||
| usage(argv[0]); | |||
| return 0; | |||
| } else if (!dashes && strcmp(argv[i], "--bytecode") == 0) { | |||
| do_print_bytecode = 1; | |||
| } else if (!dashes && strcmp(argv[i], "--step") == 0) { | |||
| do_step = 1; | |||
| } else if (strcmp(argv[i], "--") == 0) { | |||
| dashes = 1; | |||
| } else if (strcmp(argv[i], "-") == 0) { | |||
| inf = stdin; | |||
| } else if (!was_inf_set) { | |||
| inf = fopen(argv[i], "r"); | |||
| was_inf_set = 1; | |||
| if (inf == NULL) { | |||
| perror(argv[i]); | |||
| return 1; | |||
| } | |||
| } else { | |||
| printf("Unexpected argument: %s\n", argv[i]); | |||
| usage(argv[0]); | |||
| return 1; | |||
| } | |||
| } | |||
| // Init lexer with its input reader | |||
| @@ -61,24 +91,21 @@ int main(int argc, char **argv) { | |||
| l2_gen_free(&gen); | |||
| fclose(inf); | |||
| printf("Generated bytecode:\n"); | |||
| l2_vm_print_bytecode((l2_word *)w.mem, w.len / sizeof(l2_word)); | |||
| printf("\n"); | |||
| if (do_print_bytecode) { | |||
| l2_vm_print_bytecode((l2_word *)w.mem, w.len / sizeof(l2_word)); | |||
| free(w.mem); | |||
| return 0; | |||
| } | |||
| struct l2_vm vm; | |||
| l2_vm_init(&vm, (void *)w.mem, w.len / sizeof(l2_word)); | |||
| l2_vm_run(&vm); | |||
| free(w.mem); | |||
| printf("State before GC:\n"); | |||
| l2_vm_print_state(&vm); | |||
| printf("\n"); | |||
| while (l2_vm_gc(&vm)); | |||
| printf("\nState after GC:\n"); | |||
| l2_vm_print_state(&vm); | |||
| if (do_step) { | |||
| step_through(&vm); | |||
| } else { | |||
| l2_vm_run(&vm); | |||
| } | |||
| l2_vm_free(&vm); | |||
| free(w.mem); | |||
| } | |||