From fc0a3757a5995c3418c591cdf5bf7d9250e923b0 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Wed, 29 Oct 2014 16:45:39 -0400 Subject: [PATCH] Broke out parse tree structure and related functions into it's own module --- source/sclpl/codegen.c | 82 +++++++++++------------------------------- source/sclpl/main.c | 2 +- source/sclpl/parser.c | 24 +++---------- source/sclpl/parser.h | 13 +------ source/sclpl/tree.c | 62 ++++++++++++++++++++++++++++++++ source/sclpl/tree.h | 29 +++++++++++++++ 6 files changed, 118 insertions(+), 94 deletions(-) create mode 100644 source/sclpl/tree.c create mode 100644 source/sclpl/tree.h diff --git a/source/sclpl/codegen.c b/source/sclpl/codegen.c index dbc66cf..76e741f 100644 --- a/source/sclpl/codegen.c +++ b/source/sclpl/codegen.c @@ -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)("); diff --git a/source/sclpl/main.c b/source/sclpl/main.c index 885e3dc..7afc1fd 100644 --- a/source/sclpl/main.c +++ b/source/sclpl/main.c @@ -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) diff --git a/source/sclpl/parser.c b/source/sclpl/parser.c index 5202b93..3d08830 100644 --- a/source/sclpl/parser.c +++ b/source/sclpl/parser.c @@ -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); } diff --git a/source/sclpl/parser.h b/source/sclpl/parser.h index cc6d15c..980e7f5 100644 --- a/source/sclpl/parser.h +++ b/source/sclpl/parser.h @@ -10,19 +10,10 @@ #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 index 0000000..a7c9fbe --- /dev/null +++ b/source/sclpl/tree.c @@ -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 index 0000000..8f727b3 --- /dev/null +++ b/source/sclpl/tree.h @@ -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 */ -- 2.52.0