diff --git a/src/ast.c b/src/ast.c new file mode 100644 index 00000000..ce38f442 --- /dev/null +++ b/src/ast.c @@ -0,0 +1,10 @@ +#include "ast.h" +#include + +const char* ast_info(enum AstTag tag) { + static const char* const tag_info[] = { + "IDENTIFIER", + }; + assert(sizeof(tag_info)/sizeof(char*) == AST_TAG_ENUM_END); + return tag_info[tag]; +} diff --git a/src/ast.h b/src/ast.h index 424a2620..454617ac 100644 --- a/src/ast.h +++ b/src/ast.h @@ -2,7 +2,10 @@ #define KMC_C90_COMPILER_AST_H enum AstTag { - AST_IDENTIFIER + AST_IDENTIFIER, + AST_TAG_ENUM_END }; +const char* ast_info(enum AstTag tag); + #endif /* KMC_C90_COMPILER_AST_H */ diff --git a/src/sexpr.c b/src/sexpr.c index 7a695cba..e89020a9 100644 --- a/src/sexpr.c +++ b/src/sexpr.c @@ -66,3 +66,42 @@ enum AstTag sexpr_get_ast(SexprRef sexpr) { assert(sexpr_is_ast(sexpr)); return sexpr->data.ast; } + +static void indent(FILE* stream, int depth) { + int i = 0; + for (; i < depth; ++i) { + fprintf(stream, " "); + } +} +static void sexpr_print_impl(FILE* stream, SexprRef sexpr, int depth) { + if (sexpr_is_pair(sexpr)) { + if (sexpr_is_atom(car(sexpr))) { + sexpr_print_impl(stream, car(sexpr), depth); + } else { + fprintf(stream, "("); + sexpr_print_impl(stream, car(sexpr), depth + 1); + fprintf(stream, ")"); + } + if (sexpr_is_atom(cdr(sexpr))) { + fprintf(stream, " . "); + sexpr_print_impl(stream, cdr(sexpr), depth + 3); + } else if (sexpr_is_pair(cdr(sexpr))) { + fprintf(stream, "\n"); + indent(stream, depth); + sexpr_print_impl(stream, cdr(sexpr), depth); + } + } else if (sexpr_is_symbol(sexpr)) { + fprintf(stream, "%s", string_data(sexpr_get_symbol(sexpr))); + } else if (sexpr_is_ast(sexpr)) { + fprintf(stream, "%s", ast_info(sexpr_get_ast(sexpr))); + } +} +void sexpr_print(FILE* stream, SexprRef sexpr) { + if (sexpr_is_atom(sexpr)) { + sexpr_print_impl(stream, sexpr, 0); + } else { + fprintf(stream, "("); + sexpr_print_impl(stream, sexpr, 1); + fprintf(stream, ")\n"); + } +} diff --git a/src/sexpr.h b/src/sexpr.h index 0261cbf4..b9d23ed4 100644 --- a/src/sexpr.h +++ b/src/sexpr.h @@ -1,6 +1,7 @@ #ifndef KMC_C90_COMPILER_SEXPR_H #define KMC_C90_COMPILER_SEXPR_H +#include #include "ast.h" #include "stdstring.h" #include "utility.h" @@ -43,4 +44,6 @@ StringRef sexpr_get_symbol(SexprRef sexpr); SexprRef sexpr_make_ast(enum AstTag ast); enum AstTag sexpr_get_ast(SexprRef sexpr); +void sexpr_print(FILE* stream, SexprRef sexpr); + #endif /* KMC_C90_COMPILER_SEXPR_H */ diff --git a/tests/lexer_test/Makefile b/tests/lexer_test/Makefile index f570ae61..b64fc1d8 100644 --- a/tests/lexer_test/Makefile +++ b/tests/lexer_test/Makefile @@ -9,7 +9,7 @@ include $(TOP_DIR)/Makefile.common include $(GTEST_DIR)/Makefile.common include $(TESTS_DIR)/Makefile.common -LEX_SRCS := lex.yy.c utility.c parser.tab.c allocator.c memory_pool.c stdstring.c sexpr.c sexpr_pool.c +LEX_SRCS := lex.yy.c utility.c parser.tab.c allocator.c memory_pool.c stdstring.c sexpr.c sexpr_pool.c ast.c LEX_OBJS := $(LEX_SRCS:%.c=$(SRC_DIR)/%.o) TARGET := lexer_test.out