diff --git a/.gitignore b/.gitignore index 9cdb480..09e5b39 100644 --- a/.gitignore +++ b/.gitignore @@ -177,3 +177,4 @@ m4/ltversion.m4 m4/lt~obsolete.m4 Makefile +*.svg diff --git a/src/main.c b/src/main.c index f9c4407..a6b18a7 100644 --- a/src/main.c +++ b/src/main.c @@ -76,6 +76,14 @@ int main(int argc, char **argv) // Retrieve and build first AST struct ast *command_ast = get_ast(ctx); + if (options.pretty_print) + { + ast_print_dot(command_ast); + } + + // Call the executor with the AST + return_code = execution(command_ast); + // Main parse-execute loop while (command_ast != NULL && command_ast->type != AST_END) { diff --git a/src/parser/parser.c b/src/parser/parser.c index 862c025..dbe3f72 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -51,4 +51,4 @@ struct ast *get_ast_str(char *command) { (void)command; return NULL; -} +} \ No newline at end of file diff --git a/src/utils/ast/ast.c b/src/utils/ast/ast.c index c4bece9..4cfdf69 100644 --- a/src/utils/ast/ast.c +++ b/src/utils/ast/ast.c @@ -1,6 +1,89 @@ +#define _POSIX_C_SOURCE 12344 + #include "ast.h" #include +#include +#include + +static void ast_print_dot_recursive(struct ast *node, FILE *out) +{ + if (!node) + return; + + switch (node->type) + { + case AST_IF: { + struct ast_if *if_data = ast_get_if(node); + fprintf(out, " node%p [label=\"IF\"];\n", (void *)node); + + if (if_data->condition) + { + fprintf(out, " node%p -> node%p;\n", (void *)node, + (void *)if_data->condition); + fprintf(out, + " node%p [fillcolor=\"lightyellow\", style=\"filled\"];\n", + (void *)if_data->condition); + ast_print_dot_recursive(if_data->condition, out); + + if (if_data->then_clause) + { + fprintf(out, " node%p -> node%p [label=\"true\"];\n", + (void *)if_data->condition, + (void *)if_data->then_clause); + ast_print_dot_recursive(if_data->then_clause, out); + } + + if (if_data->else_clause) + { + fprintf(out, " node%p -> node%p [label=\"false\"];\n", + (void *)if_data->condition, + (void *)if_data->else_clause); + ast_print_dot_recursive(if_data->else_clause, out); + } + } + break; + } + case AST_CMD: { + struct ast_command *command_data = ast_get_command(node); + fprintf(out, " node%p [label=\"", (void *)node); + struct list *l = command_data->command; + while (l) + { + fprintf(out, "%s", (char *)l->data); + if (l->next) + fprintf(out, " "); + l = l->next; + } + fprintf(out, "\"];\n"); + break; + } + case AST_END: + fprintf(out, " node%p [label=\"END\"];\n", (void *)node); + break; + default: + break; + } +} + +void ast_print_dot(struct ast *ast) +{ + if (!ast) + return; + + FILE *dot_pipe = popen("dot -Tsvg -o ast.svg", "w"); + if (!dot_pipe) + { + return; + } + + fprintf(dot_pipe, "digraph AST {\n"); + ast_print_dot_recursive(ast, dot_pipe); + fprintf(dot_pipe, "}\n"); + pclose(dot_pipe); + + system("open ast.svg"); +} void ast_free(struct ast **node) { diff --git a/src/utils/ast/ast.h b/src/utils/ast/ast.h index 187f748..a98d88b 100644 --- a/src/utils/ast/ast.h +++ b/src/utils/ast/ast.h @@ -10,4 +10,9 @@ #include "ast_redir.h" #include "ast_void.h" +/** + * Prints the Graphviz DOT representation of the given AST to stdout. + */ +void ast_print_dot(struct ast *ast); + #endif /* ! AST_H */