refactor code

This commit is contained in:
CismonX 2020-06-08 02:32:48 +08:00
parent eb6a710522
commit b551b5fb8a
No known key found for this signature in database
GPG Key ID: 315D6652268C5007
3 changed files with 50 additions and 62 deletions

View File

@ -35,11 +35,6 @@
goto codegen_failed; \ goto codegen_failed; \
} }
static FILE* output_stream;
static const char* file_name;
static bool optimize_const;
static bool dump_mnemonics;
static const char* err_codegen = "codegen error"; static const char* err_codegen = "codegen error";
static const char* info_codegen = "codegen"; static const char* info_codegen = "codegen";
@ -66,32 +61,24 @@ write_bc_header(FILE* restrict output_stream, uint32_t text_len, uint32_t rodata
} }
bool bool
u6a_write_prefix(const char* prefix_string) { u6a_write_prefix(const struct u6a_codegen_options* options, const char* prefix_string) {
if (dump_mnemonics) { if (options->dump_mnemonics) {
return true; return true;
} }
if (prefix_string == NULL) { if (prefix_string == NULL) {
return true; return true;
} }
uint32_t write_length = strlen(prefix_string); uint32_t write_length = strlen(prefix_string);
if (UNLIKELY(write_length != fwrite(prefix_string, sizeof(char), write_length, output_stream))) { if (UNLIKELY(write_length != fwrite(prefix_string, sizeof(char), write_length, options->output_stream))) {
u6a_err_write_failed(err_codegen, write_length, file_name); u6a_err_write_failed(err_codegen, write_length, options->file_name);
return false; return false;
} }
u6a_info_verbose(info_codegen, "prefix string written, %" PRIu32 " chars total", write_length); u6a_info_verbose(info_codegen, "prefix string written, %" PRIu32 " chars total", write_length);
return true; return true;
} }
void
u6a_codegen_init(FILE* output_stream_, const char* file_name_, bool optimize_const_, bool dump_mnemonics_) {
output_stream = output_stream_;
file_name = file_name_;
optimize_const = optimize_const_;
dump_mnemonics = dump_mnemonics_;
}
bool bool
u6a_codegen(struct u6a_ast_node* ast_arr, uint32_t ast_len) { u6a_codegen(const struct u6a_codegen_options* options, struct u6a_ast_node* ast_arr, uint32_t ast_len) {
void* bc_buffer = calloc(ast_len, sizeof(struct u6a_vm_ins) + sizeof(char)); void* bc_buffer = calloc(ast_len, sizeof(struct u6a_vm_ins) + sizeof(char));
if (UNLIKELY(bc_buffer == NULL)) { if (UNLIKELY(bc_buffer == NULL)) {
u6a_err_bad_alloc(err_codegen, ast_len * (sizeof(struct u6a_vm_ins) + sizeof(char))); u6a_err_bad_alloc(err_codegen, ast_len * (sizeof(struct u6a_vm_ins) + sizeof(char)));
@ -139,7 +126,7 @@ u6a_codegen(struct u6a_ast_node* ast_arr, uint32_t ast_len) {
}; };
} }
} else { } else {
if (optimize_const && U6A_AN_FN(lchild) == u6a_tf_out) { if (options->optimize_const && U6A_AN_FN(lchild) == u6a_tf_out) {
uint32_t old_rodata_len = rodata_len; uint32_t old_rodata_len = rodata_len;
uint32_t old_stack_top = stack_top; uint32_t old_stack_top = stack_top;
rodata_buffer[rodata_len++] = U6A_AN_CH(lchild); rodata_buffer[rodata_len++] = U6A_AN_CH(lchild);
@ -201,20 +188,20 @@ u6a_codegen(struct u6a_ast_node* ast_arr, uint32_t ast_len) {
} }
} }
uint32_t write_len = 0; uint32_t write_len = 0;
if (UNLIKELY(dump_mnemonics)) { if (UNLIKELY(options->dump_mnemonics)) {
if (UNLIKELY(!u6a_dump_mnemonics(output_stream, text_buffer, text_len))) { if (UNLIKELY(!u6a_dump_mnemonics(options->output_stream, text_buffer, text_len))) {
goto codegen_failed; goto codegen_failed;
} }
if (UNLIKELY(!u6a_dump_data(output_stream, rodata_buffer, rodata_len))) { if (UNLIKELY(!u6a_dump_data(options->output_stream, rodata_buffer, rodata_len))) {
goto codegen_failed; goto codegen_failed;
} }
} else { } else {
if (UNLIKELY(!write_bc_header(output_stream, text_len, rodata_len))) { if (UNLIKELY(!write_bc_header(options->output_stream, text_len, rodata_len))) {
write_len = sizeof(struct u6a_bc_header); write_len = sizeof(struct u6a_bc_header);
goto codegen_failed; goto codegen_failed;
} }
WRITE_SECION(text_buffer, sizeof(struct u6a_vm_ins), text_len, output_stream); WRITE_SECION(text_buffer, sizeof(struct u6a_vm_ins), text_len, options->output_stream);
WRITE_SECION(rodata_buffer, sizeof(char), rodata_len, output_stream); WRITE_SECION(rodata_buffer, sizeof(char), rodata_len, options->output_stream);
} }
free(bc_buffer); free(bc_buffer);
free(stack); free(stack);
@ -222,7 +209,7 @@ u6a_codegen(struct u6a_ast_node* ast_arr, uint32_t ast_len) {
return true; return true;
codegen_failed: codegen_failed:
u6a_err_write_failed(err_codegen, write_len, file_name); u6a_err_write_failed(err_codegen, write_len, options->file_name);
free(bc_buffer); free(bc_buffer);
free(stack); free(stack);
return false; return false;

View File

@ -26,13 +26,17 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
void struct u6a_codegen_options {
u6a_codegen_init(FILE* output_stream, const char* file_name, bool optimize_const, bool dump_mnemonics); FILE* output_stream;
char* file_name;
bool optimize_const;
bool dump_mnemonics;
};
bool bool
u6a_write_prefix(const char* prefix_string); u6a_write_prefix(const struct u6a_codegen_options* options, const char* prefix_string);
bool bool
u6a_codegen(struct u6a_ast_node* ast_arr, uint32_t ast_len); u6a_codegen(const struct u6a_codegen_options* options, struct u6a_ast_node* ast_arr, uint32_t ast_len);
#endif #endif

View File

@ -33,13 +33,10 @@
#define EC_ERR_CODEGEN 4 #define EC_ERR_CODEGEN 4
struct arg_options { struct arg_options {
struct u6a_codegen_options codegen;
FILE* input_file; FILE* input_file;
char* input_file_name; char* input_file_name;
FILE* output_file;
char* output_file_prefix; char* output_file_prefix;
char* output_file_name;
bool optimize_const;
bool dump_mnemonics;
bool print_only; bool print_only;
}; };
@ -51,12 +48,12 @@ arg_options_destroy(struct arg_options* options, bool delete_output_file) {
if (options->input_file && options->input_file != stdin) { if (options->input_file && options->input_file != stdin) {
fclose(options->input_file); fclose(options->input_file);
} }
const bool not_using_stdout = options->output_file != stdout; const bool not_using_stdout = options->codegen.output_stream != stdout;
if (options->output_file && not_using_stdout) { if (options->codegen.output_stream && not_using_stdout) {
fclose(options->output_file); fclose(options->codegen.output_stream);
} }
if (delete_output_file && not_using_stdout && options->output_file_name) { if (delete_output_file && not_using_stdout && options->codegen.file_name) {
remove(options->output_file_name); remove(options->codegen.file_name);
} }
} }
@ -71,7 +68,7 @@ process_options(struct arg_options* options, int argc, char** argv) {
{ "version", no_argument, NULL, 'V' }, { "version", no_argument, NULL, 'V' },
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
options->optimize_const = false; options->codegen.optimize_const = false;
bool syntax_only = false; bool syntax_only = false;
bool verbose = false; bool verbose = false;
char optimize_level = '1'; char optimize_level = '1';
@ -82,10 +79,10 @@ process_options(struct arg_options* options, int argc, char** argv) {
} }
switch (result) { switch (result) {
case 'o': case 'o':
if (UNLIKELY(options->output_file_name)) { if (UNLIKELY(options->codegen.file_name)) {
break; break;
} }
options->output_file_name = optarg; options->codegen.file_name = optarg;
break; break;
case 'O': case 'O':
optimize_level = optarg ? optarg[0] : '1'; optimize_level = optarg ? optarg[0] : '1';
@ -96,7 +93,7 @@ process_options(struct arg_options* options, int argc, char** argv) {
options->output_file_prefix = optarg ? optarg : "#!/usr/bin/env u6a\n"; options->output_file_prefix = optarg ? optarg : "#!/usr/bin/env u6a\n";
break; break;
case 'S': case 'S':
options->dump_mnemonics = true; options->codegen.dump_mnemonics = true;
break; break;
case 'v': case 'v':
verbose = true; verbose = true;
@ -145,11 +142,11 @@ process_options(struct arg_options* options, int argc, char** argv) {
} }
// Output file // Output file
if (syntax_only) { if (syntax_only) {
if (UNLIKELY(options->output_file_name)) { if (UNLIKELY(options->codegen.file_name)) {
options->output_file_name = NULL; options->codegen.file_name = NULL;
} }
} else { } else {
if (options->output_file_name == NULL) { if (options->codegen.file_name == NULL) {
if (options->input_file == stdin) { if (options->input_file == stdin) {
goto write_to_stdout; goto write_to_stdout;
} else { } else {
@ -157,29 +154,30 @@ process_options(struct arg_options* options, int argc, char** argv) {
u6a_err_path_too_long(err_toplevel, PATH_MAX - 1, file_name_size + 8); u6a_err_path_too_long(err_toplevel, PATH_MAX - 1, file_name_size + 8);
return false; return false;
} }
options->output_file_name = malloc((file_name_size + 9) * sizeof(char)); options->codegen.file_name = malloc((file_name_size + 9) * sizeof(char));
strcpy(options->output_file_name, options->input_file_name); strcpy(options->codegen.file_name, options->input_file_name);
strcpy(options->output_file_name + file_name_size, options->dump_mnemonics ? ".bc.dump\0" : ".bc\0"); strcpy(options->codegen.file_name + file_name_size,
options->codegen.dump_mnemonics ? ".bc.dump\0" : ".bc\0");
} }
} else if (strlen(options->output_file_name) == 1 && options->output_file_name[0] == '-') { } else if (strlen(options->codegen.file_name) == 1 && options->codegen.file_name[0] == '-') {
write_to_stdout: write_to_stdout:
if (verbose) { if (verbose) {
u6a_err_custom(err_toplevel, "cannot write to STDOUT on verbose mode"); u6a_err_custom(err_toplevel, "cannot write to STDOUT on verbose mode");
return false; return false;
} }
options->output_file = stdout; options->codegen.output_stream = stdout;
options->output_file_name = "STDOUT"; options->codegen.file_name = "STDOUT";
} }
if (options->output_file == NULL) { if (options->codegen.output_stream == NULL) {
options->output_file = fopen(options->output_file_name, "w"); options->codegen.output_stream = fopen(options->codegen.file_name, "w");
if (options->output_file == NULL) { if (options->codegen.output_stream == NULL) {
u6a_err_cannot_open_file(err_toplevel, options->output_file_name); u6a_err_cannot_open_file(err_toplevel, options->codegen.file_name);
return false; return false;
} }
} }
} }
if (optimize_level > '0') { if (optimize_level > '0') {
options->optimize_const = true; options->codegen.optimize_const = true;
} }
u6a_logging_verbose(verbose); u6a_logging_verbose(verbose);
return true; return true;
@ -209,16 +207,15 @@ main(int argc, char** argv) {
exit_code = EC_ERR_PARSE; exit_code = EC_ERR_PARSE;
goto terminate; goto terminate;
} }
if (UNLIKELY(options.output_file == NULL)) { if (UNLIKELY(options.codegen.output_stream == NULL)) {
goto terminate; goto terminate;
} }
u6a_codegen_init(options.output_file, options.output_file_name, options.optimize_const, options.dump_mnemonics); u6a_info_verbose(info_toplevel, "writing to %s", options.codegen.file_name);
u6a_info_verbose(info_toplevel, "writing to %s", options.output_file_name); if (UNLIKELY(!u6a_write_prefix(&options.codegen, options.output_file_prefix))) {
if (UNLIKELY(!u6a_write_prefix(options.output_file_prefix))) {
exit_code = EC_ERR_CODEGEN; exit_code = EC_ERR_CODEGEN;
goto terminate; goto terminate;
} }
if (UNLIKELY(!u6a_codegen(ast_arr, token_len + 2))) { if (UNLIKELY(!u6a_codegen(&options.codegen, ast_arr, token_len + 2))) {
exit_code = EC_ERR_CODEGEN; exit_code = EC_ERR_CODEGEN;
goto terminate; goto terminate;
} }