]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
Added command line options to driver
authorMichael D. Lowis <mike@mdlowis.com>
Mon, 6 Oct 2014 19:03:53 +0000 (15:03 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Mon, 6 Oct 2014 19:03:53 +0000 (15:03 -0400)
Rakefile
modules/libopts
source/sclpl/grammar.c
source/sclpl/main.c
source/sclpl/parser.c
source/sclpl/parser.h

index 01a8efa1e9f0605ba2316f17132872d293fde8c1..8562ab326b0e85a413264b90f28b0722ad2fa810 100644 (file)
--- 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
 
 #------------------------------------------------------------------------------
index 9266387d534a8ca397824e07e62e390ca1dbb236..86210d19fd6028f4954c4278dbef620734a896e1 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 9266387d534a8ca397824e07e62e390ca1dbb236
+Subproject commit 86210d19fd6028f4954c4278dbef620734a896e1
index 8a4a33c2a5022d7ac84dfb52c377f2fd790b1654..5dd497a020de375a4871ae9fd599d5e97b334011 100644 (file)
@@ -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:
index 0e032a7dc3e01769991bdb16bb5fe4dc75cd69b6..10a77ffece6fd87b98d9bc5dffe4533b6e108f66 100644 (file)
@@ -1,20 +1,26 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <stddef.h>
 #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("<token(%s)>\n", lexer_tok_type_str(p_tok));
+        printf("<tok %s>\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("<tok %s>\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;
+}
index 57362a8786dbd0e8a1499a8b71cacf786a8c2806..87dac055c52ac79d56435654ec39bc78058aae7d 100644 (file)
@@ -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;
index 0ab71fce2c328fe407607f8bf80a462c1bb96a36..2dc1624ed1c93b49b6b5006bb4e2a28f25da2543 100644 (file)
@@ -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);