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; \
}
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* info_codegen = "codegen";
@ -66,32 +61,24 @@ write_bc_header(FILE* restrict output_stream, uint32_t text_len, uint32_t rodata
}
bool
u6a_write_prefix(const char* prefix_string) {
if (dump_mnemonics) {
u6a_write_prefix(const struct u6a_codegen_options* options, const char* prefix_string) {
if (options->dump_mnemonics) {
return true;
}
if (prefix_string == NULL) {
return true;
}
uint32_t write_length = strlen(prefix_string);
if (UNLIKELY(write_length != fwrite(prefix_string, sizeof(char), write_length, output_stream))) {
u6a_err_write_failed(err_codegen, write_length, file_name);
if (UNLIKELY(write_length != fwrite(prefix_string, sizeof(char), write_length, options->output_stream))) {
u6a_err_write_failed(err_codegen, write_length, options->file_name);
return false;
}
u6a_info_verbose(info_codegen, "prefix string written, %" PRIu32 " chars total", write_length);
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
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));
if (UNLIKELY(bc_buffer == NULL)) {
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 {
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_stack_top = stack_top;
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;
if (UNLIKELY(dump_mnemonics)) {
if (UNLIKELY(!u6a_dump_mnemonics(output_stream, text_buffer, text_len))) {
if (UNLIKELY(options->dump_mnemonics)) {
if (UNLIKELY(!u6a_dump_mnemonics(options->output_stream, text_buffer, text_len))) {
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;
}
} 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);
goto codegen_failed;
}
WRITE_SECION(text_buffer, sizeof(struct u6a_vm_ins), text_len, output_stream);
WRITE_SECION(rodata_buffer, sizeof(char), rodata_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, options->output_stream);
}
free(bc_buffer);
free(stack);
@ -222,7 +209,7 @@ u6a_codegen(struct u6a_ast_node* ast_arr, uint32_t ast_len) {
return true;
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(stack);
return false;

View File

@ -26,13 +26,17 @@
#include <stdbool.h>
#include <stdio.h>
void
u6a_codegen_init(FILE* output_stream, const char* file_name, bool optimize_const, bool dump_mnemonics);
struct u6a_codegen_options {
FILE* output_stream;
char* file_name;
bool optimize_const;
bool dump_mnemonics;
};
bool
u6a_write_prefix(const char* prefix_string);
u6a_write_prefix(const struct u6a_codegen_options* options, const char* prefix_string);
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

View File

@ -33,13 +33,10 @@
#define EC_ERR_CODEGEN 4
struct arg_options {
struct u6a_codegen_options codegen;
FILE* input_file;
char* input_file_name;
FILE* output_file;
char* output_file_prefix;
char* output_file_name;
bool optimize_const;
bool dump_mnemonics;
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) {
fclose(options->input_file);
}
const bool not_using_stdout = options->output_file != stdout;
if (options->output_file && not_using_stdout) {
fclose(options->output_file);
const bool not_using_stdout = options->codegen.output_stream != stdout;
if (options->codegen.output_stream && not_using_stdout) {
fclose(options->codegen.output_stream);
}
if (delete_output_file && not_using_stdout && options->output_file_name) {
remove(options->output_file_name);
if (delete_output_file && not_using_stdout && options->codegen.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' },
{ 0, 0, 0, 0 }
};
options->optimize_const = false;
options->codegen.optimize_const = false;
bool syntax_only = false;
bool verbose = false;
char optimize_level = '1';
@ -82,10 +79,10 @@ process_options(struct arg_options* options, int argc, char** argv) {
}
switch (result) {
case 'o':
if (UNLIKELY(options->output_file_name)) {
if (UNLIKELY(options->codegen.file_name)) {
break;
}
options->output_file_name = optarg;
options->codegen.file_name = optarg;
break;
case 'O':
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";
break;
case 'S':
options->dump_mnemonics = true;
options->codegen.dump_mnemonics = true;
break;
case 'v':
verbose = true;
@ -145,11 +142,11 @@ process_options(struct arg_options* options, int argc, char** argv) {
}
// Output file
if (syntax_only) {
if (UNLIKELY(options->output_file_name)) {
options->output_file_name = NULL;
if (UNLIKELY(options->codegen.file_name)) {
options->codegen.file_name = NULL;
}
} else {
if (options->output_file_name == NULL) {
if (options->codegen.file_name == NULL) {
if (options->input_file == stdin) {
goto write_to_stdout;
} 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);
return false;
}
options->output_file_name = malloc((file_name_size + 9) * sizeof(char));
strcpy(options->output_file_name, options->input_file_name);
strcpy(options->output_file_name + file_name_size, options->dump_mnemonics ? ".bc.dump\0" : ".bc\0");
options->codegen.file_name = malloc((file_name_size + 9) * sizeof(char));
strcpy(options->codegen.file_name, options->input_file_name);
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:
if (verbose) {
u6a_err_custom(err_toplevel, "cannot write to STDOUT on verbose mode");
return false;
}
options->output_file = stdout;
options->output_file_name = "STDOUT";
options->codegen.output_stream = stdout;
options->codegen.file_name = "STDOUT";
}
if (options->output_file == NULL) {
options->output_file = fopen(options->output_file_name, "w");
if (options->output_file == NULL) {
u6a_err_cannot_open_file(err_toplevel, options->output_file_name);
if (options->codegen.output_stream == NULL) {
options->codegen.output_stream = fopen(options->codegen.file_name, "w");
if (options->codegen.output_stream == NULL) {
u6a_err_cannot_open_file(err_toplevel, options->codegen.file_name);
return false;
}
}
}
if (optimize_level > '0') {
options->optimize_const = true;
options->codegen.optimize_const = true;
}
u6a_logging_verbose(verbose);
return true;
@ -209,16 +207,15 @@ main(int argc, char** argv) {
exit_code = EC_ERR_PARSE;
goto terminate;
}
if (UNLIKELY(options.output_file == NULL)) {
if (UNLIKELY(options.codegen.output_stream == NULL)) {
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.output_file_name);
if (UNLIKELY(!u6a_write_prefix(options.output_file_prefix))) {
u6a_info_verbose(info_toplevel, "writing to %s", options.codegen.file_name);
if (UNLIKELY(!u6a_write_prefix(&options.codegen, options.output_file_prefix))) {
exit_code = EC_ERR_CODEGEN;
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;
goto terminate;
}