From 6e534485601cef265bea4a4aa637452315e2bcee Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Fri, 14 Nov 2014 22:30:55 -0500 Subject: [PATCH] refactored to minimze amount of code in main.c --- source/sclpl/log.c | 18 +++ source/sclpl/log.h | 14 +++ source/sclpl/main.c | 296 +++----------------------------------------- source/sclpl/ops.c | 122 ++++++++++++++++++ source/sclpl/ops.h | 20 +++ source/sclpl/sys.c | 84 +++++++++++++ source/sclpl/sys.h | 28 +++++ source/sclpl/tree.c | 36 ++++++ source/sclpl/tree.h | 1 + 9 files changed, 342 insertions(+), 277 deletions(-) create mode 100644 source/sclpl/log.c create mode 100644 source/sclpl/log.h create mode 100644 source/sclpl/ops.c create mode 100644 source/sclpl/ops.h create mode 100644 source/sclpl/sys.c create mode 100644 source/sclpl/sys.h diff --git a/source/sclpl/log.c b/source/sclpl/log.c new file mode 100644 index 0000000..ae0e384 --- /dev/null +++ b/source/sclpl/log.c @@ -0,0 +1,18 @@ +/** + @file log.c + @brief See header for details + $Revision$ + $HeadURL$ + */ +#include "log.h" +#include + +void log_error(const char msg[], ...) { + va_list args; + va_start(args, msg); + fprintf(stderr, "Error: "); + vfprintf(stderr, msg, args); + va_end(args); + fputs("\n",stderr); +} + diff --git a/source/sclpl/log.h b/source/sclpl/log.h new file mode 100644 index 0000000..90c4637 --- /dev/null +++ b/source/sclpl/log.h @@ -0,0 +1,14 @@ +/** + @file log.h + @brief TODO: Describe this file + $Revision$ + $HeadURL$ + */ +#ifndef LOG_H +#define LOG_H + +#include + +void log_error(const char msg[], ...); + +#endif /* LOG_H */ diff --git a/source/sclpl/main.c b/source/sclpl/main.c index 95d01ae..44f458b 100644 --- a/source/sclpl/main.c +++ b/source/sclpl/main.c @@ -9,6 +9,10 @@ #include "lexer.h" #include "pprint.h" #include "codegen.h" +#include "sys.h" +#include "log.h" +#include "ops.h" +#include "tree.h" /* Command Line Options *****************************************************************************/ @@ -34,53 +38,6 @@ void print_usage(void) { exit(1); } -void error_msg(const char msg[], ...) { - va_list args; - va_start(args, msg); - fprintf(stderr, "Error: "); - vfprintf(stderr, msg, args); - va_end(args); - fputs("\n",stderr); -} - -/* Tree Rewriting - *****************************************************************************/ -bool is_punctuation(lex_tok_t* p_tok) { - bool ret = false; - switch(p_tok->type) { - case T_END: - case T_LBRACE: - case T_RBRACE: - case T_LBRACK: - case T_RBRACK: - case T_LPAR: - case T_RPAR: - case T_COMMA: - ret = true; - default: - break; - } - return ret; -} - -tree_t* convert_to_ast(tree_t* p_tree) { - tree_t* p_newtree = NULL; - if (p_tree->tag == ATOM) { - if (!is_punctuation(p_tree->ptr.tok)) - p_newtree = mem_retain(p_tree); - } else { - vec_t* p_vec = p_tree->ptr.vec; - vec_t* p_newvec = vec_new(0); - p_newtree = tree_new(TREE, p_newvec); - for(size_t idx = 0; idx < vec_size(p_vec); idx++) { - tree_t* p_item = convert_to_ast(vec_at(p_vec,idx)); - if (NULL != p_item) - vec_push_back(p_newvec, p_item); - } - } - return p_newtree; -} - /* Options Helpers *****************************************************************************/ bool file_exists(const char* name) { @@ -100,7 +57,7 @@ list_t* input_files(void) { while (NULL != files[0]) { if (!file_exists(files[0])) { mem_release(infiles); - error_msg("no such file or directory: %s", files[0]); + log_error("no such file or directory: %s", files[0]); exit(1); } list_push_front(infiles, str_new(files[0])); @@ -110,224 +67,18 @@ list_t* input_files(void) { return infiles; } -/* Command Building - *****************************************************************************/ -char Object_Cmd[] = "cc -c -o %s %s"; -char Program_Cmd[] = "cc -o %s %s"; -char StaticLib_Cmd[] = "ar rcs %s %s"; -char SharedLib_Cmd[] = "cc -shared %s"; - -/* Utility Functions - *****************************************************************************/ -str_t* get_bin_dir(void) { - str_t* bindir = NULL; - str_t* slash = str_new("/"); - str_t* progname = str_new(opts_prog_name()); - size_t index = str_rfind(progname, slash); - str_t* path = (index == SIZE_MAX) ? NULL : str_substr(progname, 0, index+1); - str_t* prog = (index == SIZE_MAX) ? str_new(str_cstr(progname)) : str_substr(progname, index+1, str_size(progname)); - if (NULL != path) { - bindir = mem_retain(path); - } else { - error_msg("Could not locate the bin directory"); - exit(1); - // str_t* pathvar = str_new(getenv("PATH")); - // str_t* sep = str_new(":"); - // vec_t* paths = str_split(pathvar, sep); - // for (size_t idx = 0u; idx < vec_size(paths); idx++) { - // str_t* currpath = (str_t*)vec_at(paths, idx); - // str_t* binpath = str_concat(str_concat(currpath, slash), prog); - // if (file_exists(str_cstr(binpath))) { - // bindir = binpath; - // mem_release(currpath); - // break; - // } - // mem_release(currpath); - // mem_release(binpath); - // } - // mem_release(sep); - // mem_release(pathvar); - // mem_release(paths); - } - mem_release(slash); - mem_release(progname); - mem_release(path); - mem_release(prog); - return bindir; -} - -str_t* get_inc_dir(void) { - str_t* bindir = get_bin_dir(); - str_t* pathmod = str_new("../include/"); - str_t* incdir = str_concat(bindir, pathmod); - mem_release(bindir); - mem_release(pathmod); - return incdir; -} - -typedef enum { - TOKFILE, - ASTFILE, - CSOURCE, - OBJECT, - PROGRAM, - STATICLIB, - SHAREDLIB -} file_type_t; - -str_t* get_extension(file_type_t ftype) { - str_t* ext = NULL; - switch (ftype) { - case TOKFILE: ext = str_new(".tok"); break; - case ASTFILE: ext = str_new(".ast"); break; - case CSOURCE: ext = str_new(".c"); break; - case OBJECT: ext = str_new(".o"); break; - case PROGRAM: ext = str_new(""); break; - case STATICLIB: ext = str_new(".a"); break; - case SHAREDLIB: ext = str_new(".lib"); break; - default: ext = str_new(""); break; - } - return ext; -} - -str_t* get_filename(file_type_t ftype, str_t* infile) { - str_t* ext_ind = str_new("."); - size_t index = str_rfind(infile, ext_ind); - str_t* rawname = str_substr(infile, 0, index); - str_t* ext = get_extension(ftype); - str_t* fname = str_concat(rawname, ext); - mem_release(ext_ind); - mem_release(rawname); - mem_release(ext); - return fname; -} - -vec_t* parse_file(str_t* in) { - bool failed = false; - FILE* input = (NULL == in) ? stdin : fopen(str_cstr(in), "r"); - parser_t* p_parser = parser_new(NULL, input); - vec_t* p_vec = vec_new(0); - while(!parser_eof(p_parser)) { - tree_t* p_tree = grammar_toplevel(p_parser); - if (NULL != p_tree) { - tree_t* p_ast = convert_to_ast(p_tree); - mem_release(p_tree); - vec_push_back(p_vec, p_ast); - } else { - parser_resume(p_parser); - failed = true; - } - } - mem_release(p_parser); - if (failed) mem_release(p_vec); - return ((failed) ? NULL : p_vec); -} - -vec_t* program_deps(vec_t* program) { - vec_t* deps = vec_new(0); - (void)program; - return deps; -} - -str_t* token_file(str_t* in) { - str_t* ofname = NULL; - FILE* input = (NULL == in) ? stdin : fopen(str_cstr(in), "r"); - FILE* output; - if (NULL == in) { - output = stdout; - } else { - ofname = get_filename(TOKFILE, in); - output = fopen(str_cstr(ofname), "w"); - } - - lexer_t* p_lexer = lexer_new(NULL, input); - lex_tok_t* token; - while(NULL != (token = lexer_read(p_lexer))) { - pprint_token(output, token, true); - mem_release(token); - } - mem_release(p_lexer); - - return ofname; -} - -str_t* syntax_file(str_t* in) { - str_t* ofname = NULL; - FILE* output; - if (NULL == in) { - output = stdout; - } else { - ofname = get_filename(ASTFILE, in); - output = fopen(str_cstr(ofname), "w"); - } - vec_t* program = parse_file(in); - if (NULL != program) { - for (size_t idx = 0; idx < vec_size(program); idx++) { - pprint_tree(output, (tree_t*)vec_at(program, idx), 0); - } - mem_release(program); - fclose(output); - } else { - fclose(output); - if (NULL != ofname) - remove(str_cstr(ofname)); - mem_release(ofname); - ofname = NULL; - } - return ofname; -} - -str_t* translate_file(str_t* in) { - str_t* ofname = NULL; - FILE* output; - if (NULL == in) { - output = stdout; - } else { - ofname = get_filename(CSOURCE, in); - output = fopen(str_cstr(ofname), "w"); - } - vec_t* program = parse_file(in); - codegen_csource(output, program); - fclose(output); - mem_release(program); - return ofname; -} - -str_t* compile_file(str_t* in) { - str_t* ofname = get_filename(OBJECT, in); - vec_t* parts = vec_new(5, str_new("cc -c -o"), mem_retain(ofname), str_new("-I"), get_inc_dir(), mem_retain(in)); - str_t* command = str_join(" ", parts); - if (opts_is_set(NULL, "verbose")) - puts(str_cstr(command)); - if (0 != system(str_cstr(command))) { - remove(str_cstr(ofname)); - mem_swap((void**)&ofname, NULL); - } - remove(str_cstr(in)); - mem_release(parts); - mem_release(command); - return ofname; -} - -#if 0 -str_t* link_files(list_t* in) { - str_t* ofname = get_filename(get_output_type(), in); - return ofname; -} -#endif - /* Driver Modes *****************************************************************************/ static int emit_tokens(void) { list_t* files = input_files(); size_t nfiles = list_size(files); if (0 == nfiles) { - (void)token_file(NULL); + (void)ops_token_file(NULL); } else if (1 == nfiles) { str_t* fname = list_front(files)->contents; - mem_release( token_file(fname) ); + mem_release( ops_token_file(fname) ); } else { - error_msg("too many files provided for target mode 'tokens'"); + log_error("too many files provided for target mode 'tokens'"); } mem_release(files); return 0; @@ -338,12 +89,12 @@ static int emit_tree(void) { list_t* files = input_files(); size_t nfiles = list_size(files); if (0 == nfiles) { - (void)syntax_file(NULL); + (void)ops_syntax_file(NULL); } else if (1 == nfiles) { str_t* fname = list_front(files)->contents; - mem_release( syntax_file(fname) ); + mem_release( ops_syntax_file(fname) ); } else { - error_msg("too many files provided for target mode 'ast'"); + log_error("too many files provided for target mode 'ast'"); } mem_release(files); @@ -355,12 +106,12 @@ static int emit_csource(void) { list_t* files = input_files(); size_t nfiles = list_size(files); if (0 == nfiles) { - (void)translate_file(NULL); + (void)ops_translate_file(NULL); } else if (1 == nfiles) { str_t* fname = list_front(files)->contents; - mem_release( translate_file(fname) ); + mem_release( ops_translate_file(fname) ); } else { - error_msg("too many files provided for target mode 'csource'"); + log_error("too many files provided for target mode 'csource'"); } mem_release(files); return ret; @@ -371,7 +122,7 @@ static int exec_repl(void) { while(!parser_eof(p_parser)) { tree_t* p_tree = grammar_toplevel(p_parser); if (NULL != p_tree) { - tree_t* p_ast = convert_to_ast(p_tree); + tree_t* p_ast = tree_convert(p_tree); pprint_tree(stdout, p_ast, 0); mem_release(p_tree); mem_release(p_ast); @@ -388,15 +139,15 @@ static int emit_object(void) { list_t* files = input_files(); size_t nfiles = list_size(files); if (0 == nfiles) { - error_msg("too few files provided for target mode 'object'"); + log_error("too few files provided for target mode 'object'"); } else if (1 == nfiles) { str_t* fname = list_front(files)->contents; - str_t* csrc = translate_file(fname); - str_t* obj = compile_file(csrc); + str_t* csrc = ops_translate_file(fname); + str_t* obj = ops_compile_file(csrc); mem_release(csrc); mem_release(obj); } else { - error_msg("too many files provided for target mode 'object'"); + log_error("too many files provided for target mode 'object'"); } mem_release(files); return 0; @@ -425,15 +176,6 @@ static int emit_program(void) { int main(int argc, char **argv) { opts_parse( Options_Config, argc, argv ); - //str_t* bindir = get_bin_dir(); - //str_t* incdir = get_inc_dir(); - //printf("Bin Dir: %s\n", str_cstr(bindir)); - //printf("Inc Dir: %s\n", str_cstr(incdir)); - //mem_release(bindir); - //mem_release(incdir); - //puts("done"); - //exit(1); - if (!opts_is_set(NULL,"mode")) { print_usage(); } else if(opts_equal(NULL, "mode", "repl")) { diff --git a/source/sclpl/ops.c b/source/sclpl/ops.c new file mode 100644 index 0000000..dc2770f --- /dev/null +++ b/source/sclpl/ops.c @@ -0,0 +1,122 @@ +/** + @file opts.c + @brief See header for details + $Revision$ + $HeadURL$ + */ +#include "opts.h" +#include "parser.h" +#include "str.h" +#include "sys.h" +#include "tree.h" +#include "grammar.h" +#include "pprint.h" +#include "codegen.h" + +vec_t* ops_parse_file(str_t* in) { + bool failed = false; + FILE* input = (NULL == in) ? stdin : fopen(str_cstr(in), "r"); + parser_t* p_parser = parser_new(NULL, input); + vec_t* p_vec = vec_new(0); + while(!parser_eof(p_parser)) { + tree_t* p_tree = grammar_toplevel(p_parser); + if (NULL != p_tree) { + tree_t* p_ast = tree_convert(p_tree); + mem_release(p_tree); + vec_push_back(p_vec, p_ast); + } else { + parser_resume(p_parser); + failed = true; + } + } + mem_release(p_parser); + if (failed) mem_release(p_vec); + return ((failed) ? NULL : p_vec); +} + +vec_t* ops_deps_file(vec_t* program) { + vec_t* deps = vec_new(0); + (void)program; + return deps; +} + +str_t* ops_token_file(str_t* in) { + str_t* ofname = NULL; + FILE* input = (NULL == in) ? stdin : fopen(str_cstr(in), "r"); + FILE* output; + if (NULL == in) { + output = stdout; + } else { + ofname = sys_filename(TOKFILE, in); + output = fopen(str_cstr(ofname), "w"); + } + + lexer_t* p_lexer = lexer_new(NULL, input); + lex_tok_t* token; + while(NULL != (token = lexer_read(p_lexer))) { + pprint_token(output, token, true); + mem_release(token); + } + mem_release(p_lexer); + + return ofname; +} + +str_t* ops_syntax_file(str_t* in) { + str_t* ofname = NULL; + FILE* output; + if (NULL == in) { + output = stdout; + } else { + ofname = sys_filename(ASTFILE, in); + output = fopen(str_cstr(ofname), "w"); + } + vec_t* program = ops_parse_file(in); + if (NULL != program) { + for (size_t idx = 0; idx < vec_size(program); idx++) { + pprint_tree(output, (tree_t*)vec_at(program, idx), 0); + } + mem_release(program); + fclose(output); + } else { + fclose(output); + if (NULL != ofname) + remove(str_cstr(ofname)); + mem_release(ofname); + ofname = NULL; + } + return ofname; +} + +str_t* ops_translate_file(str_t* in) { + str_t* ofname = NULL; + FILE* output; + if (NULL == in) { + output = stdout; + } else { + ofname = sys_filename(CSOURCE, in); + output = fopen(str_cstr(ofname), "w"); + } + vec_t* program = ops_parse_file(in); + codegen_csource(output, program); + fclose(output); + mem_release(program); + return ofname; +} + +str_t* ops_compile_file(str_t* in) { + str_t* ofname = sys_filename(OBJECT, in); + vec_t* parts = vec_new(5, str_new("cc -c -o"), mem_retain(ofname), str_new("-I"), sys_inc_dir(), mem_retain(in)); + str_t* command = str_join(" ", parts); + if (opts_is_set(NULL, "verbose")) + puts(str_cstr(command)); + if (0 != system(str_cstr(command))) { + remove(str_cstr(ofname)); + mem_swap((void**)&ofname, NULL); + } + remove(str_cstr(in)); + mem_release(parts); + mem_release(command); + return ofname; +} + diff --git a/source/sclpl/ops.h b/source/sclpl/ops.h new file mode 100644 index 0000000..fd52b17 --- /dev/null +++ b/source/sclpl/ops.h @@ -0,0 +1,20 @@ +/** + @file ops.h + @brief TODO: Describe this file + $Revision$ + $HeadURL$ + */ +#ifndef OPS_H +#define OPS_H + +#include "str.h" +#include "vec.h" + +vec_t* ops_parse_file(str_t* in); +vec_t* ops_deps_file(vec_t* program); +str_t* ops_token_file(str_t* in); +str_t* ops_syntax_file(str_t* in); +str_t* ops_translate_file(str_t* in); +str_t* ops_compile_file(str_t* in); + +#endif /* OPS_H */ diff --git a/source/sclpl/sys.c b/source/sclpl/sys.c new file mode 100644 index 0000000..06301e1 --- /dev/null +++ b/source/sclpl/sys.c @@ -0,0 +1,84 @@ +/** + @file sys.c + @brief See header for details + $Revision$ + $HeadURL$ + */ +#include +#include "sys.h" +#include "opts.h" +#include "log.h" + +str_t* sys_bin_dir(void) { + str_t* bindir = NULL; + str_t* slash = str_new("/"); + str_t* progname = str_new(opts_prog_name()); + size_t index = str_rfind(progname, slash); + str_t* path = (index == SIZE_MAX) ? NULL : str_substr(progname, 0, index+1); + str_t* prog = (index == SIZE_MAX) ? str_new(str_cstr(progname)) : str_substr(progname, index+1, str_size(progname)); + if (NULL != path) { + bindir = mem_retain(path); + } else { + log_error("Could not locate the bin directory"); + exit(1); + // str_t* pathvar = str_new(getenv("PATH")); + // str_t* sep = str_new(":"); + // vec_t* paths = str_split(pathvar, sep); + // for (size_t idx = 0u; idx < vec_size(paths); idx++) { + // str_t* currpath = (str_t*)vec_at(paths, idx); + // str_t* binpath = str_concat(str_concat(currpath, slash), prog); + // if (file_exists(str_cstr(binpath))) { + // bindir = binpath; + // mem_release(currpath); + // break; + // } + // mem_release(currpath); + // mem_release(binpath); + // } + // mem_release(sep); + // mem_release(pathvar); + // mem_release(paths); + } + mem_release(slash); + mem_release(progname); + mem_release(path); + mem_release(prog); + return bindir; +} + +str_t* sys_inc_dir(void) { + str_t* bindir = sys_bin_dir(); + str_t* pathmod = str_new("../include/"); + str_t* incdir = str_concat(bindir, pathmod); + mem_release(bindir); + mem_release(pathmod); + return incdir; +} + +str_t* sys_extension(file_type_t ftype) { + str_t* ext = NULL; + switch (ftype) { + case TOKFILE: ext = str_new(".tok"); break; + case ASTFILE: ext = str_new(".ast"); break; + case CSOURCE: ext = str_new(".c"); break; + case OBJECT: ext = str_new(".o"); break; + case PROGRAM: ext = str_new(""); break; + case STATICLIB: ext = str_new(".a"); break; + case SHAREDLIB: ext = str_new(".lib"); break; + default: ext = str_new(""); break; + } + return ext; +} + +str_t* sys_filename(file_type_t ftype, str_t* infile) { + str_t* ext_ind = str_new("."); + size_t index = str_rfind(infile, ext_ind); + str_t* rawname = str_substr(infile, 0, index); + str_t* ext = sys_extension(ftype); + str_t* fname = str_concat(rawname, ext); + mem_release(ext_ind); + mem_release(rawname); + mem_release(ext); + return fname; +} + diff --git a/source/sclpl/sys.h b/source/sclpl/sys.h new file mode 100644 index 0000000..f386bec --- /dev/null +++ b/source/sclpl/sys.h @@ -0,0 +1,28 @@ +/** + @file sys.h + @brief TODO: Describe this file + $Revision$ + $HeadURL$ + */ +#ifndef SYS_H +#define SYS_H + +#include "str.h" + +str_t* sys_bin_dir(void); +str_t* sys_inc_dir(void); + +typedef enum { + TOKFILE, + ASTFILE, + CSOURCE, + OBJECT, + PROGRAM, + STATICLIB, + SHAREDLIB +} file_type_t; + +str_t* sys_extension(file_type_t ftype); +str_t* sys_filename(file_type_t ftype, str_t* infile); + +#endif /* SYS_H */ diff --git a/source/sclpl/tree.c b/source/sclpl/tree.c index a7c9fbe..63e1f9a 100644 --- a/source/sclpl/tree.c +++ b/source/sclpl/tree.c @@ -13,6 +13,42 @@ static void tree_free(void* p_obj) { } } +static bool is_punctuation(lex_tok_t* p_tok) { + bool ret = false; + switch(p_tok->type) { + case T_END: + case T_LBRACE: + case T_RBRACE: + case T_LBRACK: + case T_RBRACK: + case T_LPAR: + case T_RPAR: + case T_COMMA: + ret = true; + default: + break; + } + return ret; +} + +tree_t* tree_convert(tree_t* p_tree) { + tree_t* p_newtree = NULL; + if (p_tree->tag == ATOM) { + if (!is_punctuation(p_tree->ptr.tok)) + p_newtree = mem_retain(p_tree); + } else { + vec_t* p_vec = p_tree->ptr.vec; + vec_t* p_newvec = vec_new(0); + p_newtree = tree_new(TREE, p_newvec); + for(size_t idx = 0; idx < vec_size(p_vec); idx++) { + tree_t* p_item = tree_convert(vec_at(p_vec,idx)); + if (NULL != p_item) + vec_push_back(p_newvec, p_item); + } + } + return p_newtree; +} + tree_t* tree_new(tree_tag_t tag, void* p_obj) { tree_t* p_tree = (tree_t*)mem_allocate(sizeof(tree_t), &tree_free); p_tree->tag = tag; diff --git a/source/sclpl/tree.h b/source/sclpl/tree.h index 8f727b3..e3374b0 100644 --- a/source/sclpl/tree.h +++ b/source/sclpl/tree.h @@ -20,6 +20,7 @@ typedef struct { } ptr; } tree_t; +tree_t* tree_convert(tree_t* p_tree); tree_t* tree_new(tree_tag_t tag, void* p_obj); tree_t* tree_get_child(tree_t* p_tree, size_t idx); void* tree_get_val(tree_t* p_tree); -- 2.52.0