From: Michael D. Lowis Date: Mon, 6 Oct 2014 19:03:53 +0000 (-0400) Subject: Added command line options to driver X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=09583e57f60faf03c82f217898f4f7e1c9ac4783;p=proto%2Fsclpl.git Added command line options to driver --- diff --git a/Rakefile b/Rakefile index 01a8efa..8562ab3 100644 --- a/Rakefile +++ b/Rakefile @@ -14,6 +14,7 @@ base_env = BuildEnv.new(echo: :command) do |env| env.set_toolset(:clang) env["CFLAGS"] += ['-DLEAK_DETECT_LEVEL=1', '--std=c99', '-Wall', '-Wextra'] #, '-Werror'] env["CPPPATH"] += ['modules/libopts/source'] + Dir['modules/libcds/source/**/'] + env["AR"] = 'ar' end #------------------------------------------------------------------------------ diff --git a/modules/libopts b/modules/libopts index 9266387..86210d1 160000 --- a/modules/libopts +++ b/modules/libopts @@ -1 +1 @@ -Subproject commit 9266387d534a8ca397824e07e62e390ca1dbb236 +Subproject commit 86210d19fd6028f4954c4278dbef620734a896e1 diff --git a/source/sclpl/grammar.c b/source/sclpl/grammar.c index 8a4a33c..5dd497a 100644 --- a/source/sclpl/grammar.c +++ b/source/sclpl/grammar.c @@ -70,8 +70,7 @@ void grammar_expression(parser_t* p_parser) void grammar_literal(parser_t* p_parser) { - switch (parser_peek(p_parser)->type) - { + switch (parser_peek(p_parser)->type) { case T_BOOL: case T_CHAR: case T_STRING: diff --git a/source/sclpl/main.c b/source/sclpl/main.c index 0e032a7..10a77ff 100644 --- a/source/sclpl/main.c +++ b/source/sclpl/main.c @@ -1,20 +1,26 @@ #include #include +#include #include "opts.h" #include "grammar.h" +#include "parser.h" #include "lexer.h" /* Command Line Options *****************************************************************************/ OptionConfig_T Options_Config[] = { - { SHORT, (char*)"L", (char*)"scan", 0, (char*)"Output the results of lexical analysis and quit"}, - { SHORT, (char*)"P", (char*)"parse", 0, (char*)"Output the results of parsing quit"}, - { END, (char*)NULL, (char*)NULL, 0, (char*)NULL } + { "tokens", false, "mode", "Emit the token output of lexical analysis for the given file"}, + { "ast", false, "mode", "Emit the abstract syntax tree for the given file"}, + { "repl", false, "mode", "Execute the application in a REPL"}, + { "staticlib", false, "mode", "Compile the application as a static library"}, + { "sharedlib", false, "mode", "Compile the application as a shared library"}, + { "program", false, "mode", "Compile the application as an executable"}, + { "R", true, "include", "Add a path to the list of require paths"}, + { NULL, false, NULL, NULL } }; -/* SCLPL Parser +/* Tree Printing *****************************************************************************/ - void print_indent(int depth) { for(int i = 0; i < (2 * depth); i++) printf("%c", ' '); @@ -24,9 +30,9 @@ void print_tree(tree_t* p_tree, int depth) { print_indent(depth); if (p_tree->tag == ATOM) { lex_tok_t* p_tok = p_tree->ptr.tok; - printf("\n", lexer_tok_type_str(p_tok)); + printf("\n", lexer_tok_type_str(p_tok)); } else { - puts("(tree:"); + puts("(tree"); vec_t* p_vec = p_tree->ptr.vec; for(size_t idx = 0; idx < vec_size(p_vec); idx++) { print_tree((tree_t*)vec_at(p_vec, idx), depth+1); @@ -36,30 +42,129 @@ void print_tree(tree_t* p_tree, int depth) { } } -/* TODO: +/* 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; + } + return ret; +} - * Formalize grammar for parser - * Paren for function application must be on same line as variable in REPL - * skip line on error and terminate after full program parse - * skip line and print on error but do not terminate the REPL +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 = parser_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; +} -*/ -int main(int argc, char **argv) { - Result_T* results = OPTS_ParseOptions( Options_Config, argc, argv ); +/* Driver Modes + *****************************************************************************/ +static int emit_tokens(void) { + lexer_t* p_lexer = lexer_new(NULL, stdin); + lex_tok_t* token; + while(NULL != (token = lexer_read(p_lexer))) { + printf("\n", lexer_tok_type_str(token)); + mem_release(token); + } + mem_release(p_lexer); + return 0; +} +static int emit_tree(void) { + int ret = 0; + parser_t* p_parser = parser_new(NULL, stdin); + 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); + print_tree(p_ast, 0); + mem_release(p_tree); + mem_release(p_ast); + } else { + parser_resume(p_parser); + ret = 1; + } + } + mem_release(p_parser); + return ret; +} + +static int exec_repl(void) { parser_t* p_parser = parser_new(":> ", stdin); while(!parser_eof(p_parser)) { tree_t* p_tree = grammar_toplevel(p_parser); if (NULL != p_tree) { - print_tree(p_tree, 0); + tree_t* p_ast = convert_to_ast(p_tree); + print_tree(p_ast, 0); mem_release(p_tree); + mem_release(p_ast); puts("OK."); } else { parser_resume(p_parser); } } mem_release(p_parser); + return 0; +} - (void)results; +static int emit_staticlib(void) { return 0; } + +static int emit_sharedlib(void) { + return 0; +} + +static int emit_program(void) { + return 0; +} + +/* TODO: + + * Formalize grammar for parser + * Paren for function application must be on same line as variable in REPL + * skip line on error and terminate after full program parse + * skip line and print on error but do not terminate the REPL + +*/ +int main(int argc, char **argv) { + opts_parse( Options_Config, argc, argv ); + + if (!opts_is_set(NULL,"mode") || opts_equal(NULL, "mode", "repl")) { + return exec_repl(); + } else if (opts_equal(NULL, "mode", "tokens")) { + return emit_tokens(); + } else if (opts_equal(NULL, "mode", "ast")) { + return emit_tree(); + } else if (opts_equal(NULL, "mode", "staticlib")) { + return emit_staticlib(); + } else if (opts_equal(NULL, "mode", "sharedlib")) { + return emit_sharedlib(); + } else if (opts_equal(NULL, "mode", "program")) { + return emit_program(); + } + + opts_reset(); + return 1; +} diff --git a/source/sclpl/parser.c b/source/sclpl/parser.c index 57362a8..87dac05 100644 --- a/source/sclpl/parser.c +++ b/source/sclpl/parser.c @@ -36,7 +36,7 @@ static void parser_tree_free(void* p_obj) { } } -static tree_t* parser_tree_new(tree_tag_t tag, void* p_obj) { +tree_t* parser_tree_new(tree_tag_t tag, void* p_obj) { tree_t* p_tree = (tree_t*)mem_allocate(sizeof(tree_t), &parser_tree_free); p_tree->tag = tag; p_tree->ptr.tok = (lex_tok_t*)p_obj; diff --git a/source/sclpl/parser.h b/source/sclpl/parser.h index 0ab71fc..2dc1624 100644 --- a/source/sclpl/parser.h +++ b/source/sclpl/parser.h @@ -31,6 +31,8 @@ typedef struct { parser_t* parser_new(char* p_prompt, FILE* input); +tree_t* parser_tree_new(tree_tag_t tag, void* p_obj); + void parser_fetch(parser_t* p_parser); lex_tok_t* parser_peek(parser_t* p_parser);