Permalink
Cannot retrieve contributors at this time
Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign up
Fetching contributors…
| #include <stdio.h> | |
| #include <string.h> | |
| #include "../../analyse/data/kludge.h" | |
| #include "../../data/dict.h" | |
| #include "data/instructions.h" | |
| #include "data/runtime_data.h" | |
| #include "pancake.h" | |
| /* run instructions in fresh pancake runtime | |
| * | |
| * returns 1 on success | |
| * returns 0 on failure | |
| */ | |
| static unsigned int ic_backend_pancake_run(struct ic_backend_pancake_instructions *instructions, struct ic_opts *opts); | |
| /* run instructions in fresh pancake runtime | |
| * | |
| * returns 1 on success | |
| * returns 0 on failure | |
| */ | |
| static unsigned int ic_backend_pancake_run(struct ic_backend_pancake_instructions *instructions, struct ic_opts *opts) { | |
| struct ic_backend_pancake_runtime_data *runtime_data = 0; | |
| if (!instructions) { | |
| puts("ic_backend_pancake_run: instructions was null"); | |
| return 0; | |
| } | |
| if (!opts) { | |
| puts("ic_backend_pancake_run: opts was null"); | |
| return 0; | |
| } | |
| runtime_data = ic_backend_pancake_runtime_data_new(instructions); | |
| if (!runtime_data) { | |
| puts("ic_backend_pancake_run: call to ic_backend_pancake_runtime_data_new failed"); | |
| return 0; | |
| } | |
| if (!ic_backend_pancake_interpret(runtime_data)) { | |
| puts("ic_backend_pancake_run: call to ic_backend_pancake_interpret failed"); | |
| return 0; | |
| } | |
| if (opts->debug) { | |
| puts("\npancake value_stack after execution finished:"); | |
| puts("----------------"); | |
| if (!ic_backend_pancake_value_stack_print(stdout, runtime_data->value_stack)) { | |
| puts("ic_backend_pancake_run: call to ic_backend_pancake_value_stack_print failed"); | |
| return 0; | |
| } | |
| puts("----------------\n"); | |
| } | |
| if (!ic_backend_pancake_runtime_data_destroy(runtime_data, 1)) { | |
| puts("ic_backend_pancake_run: call to ic_backend_pancake_runtime_data_destroy failed"); | |
| return 0; | |
| } | |
| return 1; | |
| } | |
| /* pancake - stack based interpreter backend | |
| * | |
| * returns 1 on success | |
| * returns 0 on failure | |
| */ | |
| unsigned int ic_backend_pancake(struct ic_kludge *kludge, struct ic_opts *opts) { | |
| struct ic_backend_pancake_instructions *instructions = 0; | |
| FILE *out_fh = 0; | |
| /* do we need to close the fh or not */ | |
| unsigned int close_fh = 0; | |
| if (!kludge) { | |
| puts("ic_backend_pancake: kludge was null"); | |
| return 0; | |
| } | |
| if (!opts) { | |
| puts("ic_backend_pancake: opts was null"); | |
| return 0; | |
| } | |
| instructions = ic_backend_pancake_compile(kludge); | |
| if (!instructions) { | |
| puts("ic_backend_pancake: call to ic_backend_pancake_compile failed"); | |
| return 0; | |
| } | |
| if (opts->debug) { | |
| /* print instructions */ | |
| puts("Pancake bytecode:"); | |
| puts("=========================="); | |
| if (!ic_backend_pancake_instructions_print(stdout, instructions)) { | |
| puts("ic_backend_pancake: call to ic_backend_pancake_instructions_print failed"); | |
| return 0; | |
| } | |
| puts("=========================="); | |
| puts(""); | |
| puts("Pancake interpreter output"); | |
| puts("=========================="); | |
| } | |
| /* if out_filename is specified then output pancake bytecode */ | |
| if (opts->out_filename) { | |
| if (0 == strcmp("-", opts->out_filename)) { | |
| out_fh = stdout; | |
| } else { | |
| out_fh = fopen(opts->out_filename, "w"); | |
| close_fh = 1; | |
| if (NULL == out_fh) { | |
| puts("ic_backend_pancake: call to fopen failed"); | |
| return 0; | |
| } | |
| } | |
| if (!out_fh) { | |
| printf("ic_backend_pancake: call to fopen failed for file '%s'\n", opts->out_filename); | |
| return 0; | |
| } | |
| if (!ic_backend_pancake_instructions_print(out_fh, instructions)) { | |
| puts("ic_backend_pancake: call to ic_backend_pancake_instructions_print failed"); | |
| return 0; | |
| } | |
| if (close_fh) { | |
| fclose(out_fh); | |
| } | |
| } | |
| if (!ic_backend_pancake_run(instructions, opts)) { | |
| puts("ic_backend_pancake: call to ic_backend_pancake_run failed"); | |
| return 0; | |
| } | |
| return 1; | |
| } | |
| /* load bytecode from file (opts->in_bytecode_filename) and then interpret it | |
| * in a fresh pancake runtime | |
| * | |
| * returns 1 on success | |
| * returns 0 on failure | |
| */ | |
| unsigned int ic_backend_pancake_run_bytecode_from_file(struct ic_opts *opts) { | |
| struct ic_backend_pancake_instructions *instructions = 0; | |
| FILE *in_fh = 0; | |
| /* boolean as to whether or not we should close in_fh when we are finished */ | |
| unsigned int close_fh = 0; | |
| if (!opts->in_bytecode_filename) { | |
| puts("ic_backend_pancake_run_bytecode: in_bytecode_filename not specified"); | |
| return 0; | |
| } | |
| if (0 == strcmp("-", opts->in_bytecode_filename)) { | |
| in_fh = stdin; | |
| } else { | |
| in_fh = fopen(opts->in_bytecode_filename, "r"); | |
| close_fh = 1; | |
| if (NULL == in_fh) { | |
| puts("ic_backend_pancake_run_bytecode: call to fopen failed"); | |
| return 0; | |
| } | |
| } | |
| instructions = ic_backend_pancake_instructions_load(in_fh); | |
| if (!instructions) { | |
| puts("main: call to ic_backend_pancake_instructions_load failed"); | |
| return 0; | |
| } | |
| if (close_fh) { | |
| fclose(in_fh); | |
| } | |
| if (!ic_backend_pancake_run(instructions, opts)) { | |
| puts("ic_backend_pancake: call to ic_backend_pancake_run failed"); | |
| return 0; | |
| } | |
| return 1; | |
| } |