]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
Broke out parse tree structure and related functions into it's own module
authorMichael D. Lowis <mike@mdlowis.com>
Wed, 29 Oct 2014 20:45:39 +0000 (16:45 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Wed, 29 Oct 2014 20:45:39 +0000 (16:45 -0400)
source/sclpl/codegen.c
source/sclpl/main.c
source/sclpl/parser.c
source/sclpl/parser.h
source/sclpl/tree.c [new file with mode: 0644]
source/sclpl/tree.h [new file with mode: 0644]

index dbc66cff48ffdf1fd59039cac0b29129e16def2d..76e741f1e90eb198288185d874921195491f6d72 100644 (file)
@@ -2,50 +2,8 @@
 #include "codegen.h"
 #include "pprint.h"
 
-static tree_t* get_child(tree_t* p_tree, size_t idx) {
-    tree_t* child = NULL;
-    if (p_tree->tag == TREE) {
-        vec_t* vec = p_tree->ptr.vec;
-        if (idx < vec_size(vec))
-            child = vec_at(vec, idx);
-    }
-    return child;
-}
-
-static void* get_val(tree_t* p_tree) {
-    void* ret = NULL;
-    if (p_tree->tag == ATOM) {
-        ret = p_tree->ptr.tok->value;
-    }
-    return ret;
-}
-
-static void* get_child_val(tree_t* p_tree, size_t idx) {
-    void* ret = NULL;
-    tree_t* child = get_child(p_tree,idx);
-    if (child != NULL) {
-        ret = get_val(child);
-    }
-    return ret;
-}
-
-static bool is_formtype(tree_t* p_tree, const char* val) {
-    bool ret = false;
-    tree_t* child = get_child(p_tree, 0);
-    if ((NULL != child) && (child->tag == ATOM)) {
-        lex_tok_t* token = child->ptr.tok;
-        if ((token->type == T_ID) &&
-            (0 == strcmp(val, (char*)token->value))) {
-            ret = true;
-        }
-    }
-    return ret;
-}
-
-/*****************************************************************************/
-
 static void lift_funcs(vec_t* fnlst, tree_t* tree) {
-    if (is_formtype(tree, "fn"))
+    if (tree_is_formtype(tree, "fn"))
         vec_push_back(fnlst, mem_retain(tree));
 
     if (tree->tag == TREE) {
@@ -60,7 +18,7 @@ static vec_t* find_fn_literals(vec_t* prgrm) {
     vec_t* fnlst = vec_new(0);
     for (size_t idx = 0; idx < vec_size(prgrm); idx++) {
         tree_t* tree = (tree_t*)vec_at(prgrm, idx);
-        if (!is_formtype(tree, "require")) {
+        if (!tree_is_formtype(tree, "require")) {
             lift_funcs(fnlst, tree);
         }
     }
@@ -118,9 +76,9 @@ static void emit_header(FILE* file) {
 
 static void emit_fn_signature(FILE* file, char* name, tree_t* fnval) {
     fprintf(file, "_Value %s(", name);
-    vec_t* params = get_child(fnval, 1)->ptr.vec;
+    vec_t* params = tree_get_child(fnval, 1)->ptr.vec;
     for (size_t i = 0; i < vec_size(params); i++) {
-        fprintf(file, "_Value %s", (char*)get_val((tree_t*)vec_at(params,i)));
+        fprintf(file, "_Value %s", (char*)tree_get_val((tree_t*)vec_at(params,i)));
         if (i+1 < vec_size(params))
             fprintf(file, ", ");
     }
@@ -130,8 +88,8 @@ static void emit_fn_signature(FILE* file, char* name, tree_t* fnval) {
 static void emit_def_placeholders(FILE* file, vec_t* prgrm) {
     for (size_t idx = 0; idx < vec_size(prgrm); idx++) {
         tree_t* p_tree = (tree_t*)vec_at(prgrm, idx);
-        if (is_formtype(p_tree, "def")) {
-            fprintf(file, "_Value %s;\n", (char*)get_child_val(p_tree,1));
+        if (tree_is_formtype(p_tree, "def")) {
+            fprintf(file, "_Value %s;\n", (char*)tree_get_child_val(p_tree,1));
         }
     }
     fputs("\n", file);
@@ -149,34 +107,34 @@ static void emit_expression(FILE* file, vec_t* fnlst, tree_t* p_tree, int depth)
             case T_ID:     fprintf(file, "%s",          ((char*)tok->value));                   break;
             default:                                                                            break;
         }
-    } else if (is_formtype(p_tree, "if")) {
+    } else if (tree_is_formtype(p_tree, "if")) {
         fprintf(file, "IF (");
-        emit_expression(file, fnlst, get_child(p_tree, 1), depth);
+        emit_expression(file, fnlst, tree_get_child(p_tree, 1), depth);
         fprintf(file, ")\n");
         print_indent(file, depth+1);
-        emit_expression(file, fnlst, get_child(p_tree, 2), depth+1);
+        emit_expression(file, fnlst, tree_get_child(p_tree, 2), depth+1);
         fprintf(file, "\n");
         print_indent(file, depth);
         fprintf(file, "ELSE\n");
         print_indent(file, depth+1);
         if (vec_size(p_tree->ptr.vec) > 3) {
-            emit_expression(file, fnlst, get_child(p_tree, 4), depth+1);
+            emit_expression(file, fnlst, tree_get_child(p_tree, 4), depth+1);
         } else {
             fprintf(file, "__nil");
         }
 
-    } else if (is_formtype(p_tree, "fn")) {
+    } else if (tree_is_formtype(p_tree, "fn")) {
         fprintf(file, "__func(&fn%d)", (int)get_fn_id(fnlst, p_tree));
     } else {
         vec_t* vec   = p_tree->ptr.vec;
         int nargs = vec_size(vec)-1;
         /* Determine the calling convention based on number of args */
         if (0 == nargs)
-            fprintf(file, "__call0(%s", (char*)get_val(vec_at(vec,0)));
+            fprintf(file, "__call0(%s", (char*)tree_get_val(vec_at(vec,0)));
         else if (nargs < 16)
-            fprintf(file, "__calln(%s, %d, ", (char*)get_val(vec_at(vec,0)), (int)nargs);
+            fprintf(file, "__calln(%s, %d, ", (char*)tree_get_val(vec_at(vec,0)), (int)nargs);
         else
-            fprintf(file, "__calln(%s, n, ", (char*)get_val(vec_at(vec,0)));
+            fprintf(file, "__calln(%s, n, ", (char*)tree_get_val(vec_at(vec,0)));
         /* Print out the arguments */
         for (size_t idx = 1; idx < vec_size(vec); idx++) {
             emit_expression(file, fnlst, (tree_t*)vec_at(vec,idx), depth);
@@ -223,12 +181,12 @@ static void emit_toplevel(FILE* file, vec_t* fnlst, vec_t* prgrm) {
     fputs("void toplevel(void) {\n", file);
     for (size_t idx = 0; idx < vec_size(prgrm); idx++) {
         tree_t* p_tree = (tree_t*)vec_at(prgrm, idx);
-        if (is_formtype(p_tree, "require")) {
-            fprintf(file, "    extern void %s_toplevel(void);\n", (char*)get_child_val(p_tree,1));
-            fprintf(file, "    %s_toplevel();\n", (char*)get_child_val(p_tree,1));
-        } else if (is_formtype(p_tree, "def")) {
-            fprintf(file, "    %s = ", (char*)get_child_val(p_tree,1));
-            emit_expression(file, fnlst, get_child(p_tree, 2), 0);
+        if (tree_is_formtype(p_tree, "require")) {
+            fprintf(file, "    extern void %s_toplevel(void);\n", (char*)tree_get_child_val(p_tree,1));
+            fprintf(file, "    %s_toplevel();\n", (char*)tree_get_child_val(p_tree,1));
+        } else if (tree_is_formtype(p_tree, "def")) {
+            fprintf(file, "    %s = ", (char*)tree_get_child_val(p_tree,1));
+            emit_expression(file, fnlst, tree_get_child(p_tree, 2), 0);
             fprintf(file, ";\n");
         } else {
             fprintf(file, "    (void)(");
index 885e3dceafd3f3b8c0e41678a35ff73ed7f32344..7afc1fd2160ed458d9742cc44c0b1b1ac45fb91e 100644 (file)
@@ -100,7 +100,7 @@ tree_t* convert_to_ast(tree_t* 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);
+        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)
index 5202b934600e853c8f82e20c94c09b4582403da8..3d088303a15a3b2377b7ac8ba019a24c454861c2 100644 (file)
@@ -29,20 +29,6 @@ parser_t* parser_new(char* p_prompt, FILE* input)
     return p_parser;
 }
 
-static void parser_tree_free(void* p_obj) {
-    tree_t* p_tree = ((tree_t*)p_obj);
-    if (NULL != p_tree->ptr.tok) {
-        mem_release(p_tree->ptr.tok);
-    }
-}
-
-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;
-    return p_tree;
-}
-
 void parser_fetch(parser_t* p_parser)
 {
     p_parser->p_tok = lexer_read(p_parser->p_lexer);
@@ -80,7 +66,7 @@ bool parser_accept(parser_t* p_parser, lex_tok_type_t type)
 {
     bool ret = false;
     if (parser_peek(p_parser)->type == type) {
-        vec_push_back(p_parser->p_tok_buf, parser_tree_new(ATOM, p_parser->p_tok));
+        vec_push_back(p_parser->p_tok_buf, tree_new(ATOM, p_parser->p_tok));
         p_parser->p_tok = NULL;
         ret = true;
     }
@@ -91,7 +77,7 @@ bool parser_accept_str(parser_t* p_parser, lex_tok_type_t type, const char* p_te
 {
     bool ret = false;
     if ((parser_peek(p_parser)->type == type) && (0 == strcmp((char*)(p_parser->p_tok->value), p_text))) {
-        vec_push_back(p_parser->p_tok_buf, parser_tree_new(ATOM, p_parser->p_tok));
+        vec_push_back(p_parser->p_tok_buf, tree_new(ATOM, p_parser->p_tok));
         p_parser->p_tok = NULL;
         ret = true;
     }
@@ -134,7 +120,7 @@ void parser_reduce(parser_t* p_parser, size_t mark)
         vec_push_back(p_form, p_tree);
     }
     vec_erase(p_buf, mark, vec_size(p_buf)-1);
-    vec_push_back(p_buf, parser_tree_new(TREE, p_form));
+    vec_push_back(p_buf, tree_new(TREE, p_form));
 }
 
 tree_t* parser_get_tree(parser_t* p_parser) {
@@ -143,7 +129,7 @@ tree_t* parser_get_tree(parser_t* p_parser) {
         p_tree = mem_retain(vec_at(p_parser->p_tok_buf, 0));
         vec_clear(p_parser->p_tok_buf);
     } else {
-        p_tree = parser_tree_new(TREE, p_parser->p_tok_buf);
+        p_tree = tree_new(TREE, p_parser->p_tok_buf);
         p_parser->p_tok_buf = vec_new(0);
     }
     return p_tree;
@@ -151,7 +137,7 @@ tree_t* parser_get_tree(parser_t* p_parser) {
 
 void parser_insert(parser_t* p_parser, lex_tok_type_t type, void* value) {
     lex_tok_t* p_tok = lex_tok_new(type, value);
-    tree_t*   p_tree = parser_tree_new(ATOM, p_tok);
+    tree_t*   p_tree = tree_new(ATOM, p_tok);
     vec_push_back(p_parser->p_tok_buf, p_tree);
 }
 
index cc6d15cd918c873683f2436c996fda520cd9af8e..980e7f57a2f490c5d6a414ca20c8400d928fe331 100644 (file)
 #include "lexer.h"
 #include "vec.h"
 #include "exn.h"
+#include "tree.h"
 
 DECLARE_EXCEPTION(ParseException);
 
-typedef enum { ATOM, TREE } tree_tag_t;
-
-typedef struct {
-    tree_tag_t tag;
-    union {
-        lex_tok_t* tok;
-        vec_t* vec;
-    } ptr;
-} tree_t;
-
 typedef struct {
     lexer_t* p_lexer;
     lex_tok_t* p_tok;
@@ -31,8 +22,6 @@ 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);
diff --git a/source/sclpl/tree.c b/source/sclpl/tree.c
new file mode 100644 (file)
index 0000000..a7c9fbe
--- /dev/null
@@ -0,0 +1,62 @@
+/**
+  @file tree.c
+  @brief See header for details
+  $Revision$
+  $HeadURL$
+  */
+#include "tree.h"
+
+static void tree_free(void* p_obj) {
+    tree_t* p_tree = ((tree_t*)p_obj);
+    if (NULL != p_tree->ptr.tok) {
+        mem_release(p_tree->ptr.tok);
+    }
+}
+
+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;
+    p_tree->ptr.tok = (lex_tok_t*)p_obj;
+    return p_tree;
+}
+
+tree_t* tree_get_child(tree_t* p_tree, size_t idx) {
+    tree_t* child = NULL;
+    if (p_tree->tag == TREE) {
+        vec_t* vec = p_tree->ptr.vec;
+        if (idx < vec_size(vec))
+            child = vec_at(vec, idx);
+    }
+    return child;
+}
+
+void* tree_get_val(tree_t* p_tree) {
+    void* ret = NULL;
+    if (p_tree->tag == ATOM) {
+        ret = p_tree->ptr.tok->value;
+    }
+    return ret;
+}
+
+void* tree_get_child_val(tree_t* p_tree, size_t idx) {
+    void* ret = NULL;
+    tree_t* child = tree_get_child(p_tree,idx);
+    if (child != NULL) {
+        ret = tree_get_val(child);
+    }
+    return ret;
+}
+
+bool tree_is_formtype(tree_t* p_tree, const char* val) {
+    bool ret = false;
+    tree_t* child = tree_get_child(p_tree, 0);
+    if ((NULL != child) && (child->tag == ATOM)) {
+        lex_tok_t* token = child->ptr.tok;
+        if ((token->type == T_ID) &&
+            (0 == strcmp(val, (char*)token->value))) {
+            ret = true;
+        }
+    }
+    return ret;
+}
+
diff --git a/source/sclpl/tree.h b/source/sclpl/tree.h
new file mode 100644 (file)
index 0000000..8f727b3
--- /dev/null
@@ -0,0 +1,29 @@
+/**
+  @file tree.h
+  @brief Module containing definition and common operations on parse trees.
+  $Revision$
+  $HeadURL$
+  */
+#ifndef TREE_H
+#define TREE_H
+
+#include "vec.h"
+#include "lexer.h"
+
+typedef enum { ATOM, TREE } tree_tag_t;
+
+typedef struct {
+    tree_tag_t tag;
+    union {
+        lex_tok_t* tok;
+        vec_t* vec;
+    } ptr;
+} tree_t;
+
+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);
+void* tree_get_child_val(tree_t* p_tree, size_t idx);
+bool tree_is_formtype(tree_t* p_tree, const char* val);
+
+#endif /* TREE_H */