From bcc0daa2d5091e19b2df30f8661d598b203afb0f Mon Sep 17 00:00:00 2001 From: Max Wash Date: Mon, 14 Apr 2025 12:25:49 +0100 Subject: [PATCH] frontend: update ast iterator api usage --- frontend/cmd/compile.c | 3 +- frontend/cmd/repl.c | 136 +++++++++++++++++++++++++++++------------ 2 files changed, 97 insertions(+), 42 deletions(-) diff --git a/frontend/cmd/compile.c b/frontend/cmd/compile.c index 66f7d14..7fec06d 100644 --- a/frontend/cmd/compile.c +++ b/frontend/cmd/compile.c @@ -87,8 +87,7 @@ static int compile_file(const char *path, const b_arglist *args) if (r == 0 && show_ast) { struct ivy_ast_node *root = ivy_parser_root_node(parser); struct ivy_ast_node_iterator it = {0}; - ivy_ast_node_iterate( - root, &it, IVY_AST_ITERATE_REGULAR, print_ast_node); + ivy_ast_node_iterate(root, &it, print_ast_node, NULL); } if (lex) { diff --git a/frontend/cmd/repl.c b/frontend/cmd/repl.c index 2175098..a40a1c0 100644 --- a/frontend/cmd/repl.c +++ b/frontend/cmd/repl.c @@ -5,8 +5,11 @@ #include #include #include +#include #include #include +#include +#include enum { OPT_SHOW_LEX_TOKENS = 100, @@ -15,6 +18,10 @@ enum { struct repl { bool r_show_lex, r_show_ast; + struct line_ed *r_ed; + struct ivy_lexer *r_lex; + struct ivy_parser *r_parse; + struct ivy_codegen *r_codegen; }; static void skip_line(struct ivy_lexer *lex) @@ -34,17 +41,84 @@ static void skip_line(struct ivy_lexer *lex) static int repl_eval_node(struct repl *repl, struct ivy_ast_node *node) { struct ivy_ast_node_iterator it = {0}; + struct print_ast_node_args args = { + .indent = true, + .postorder = false, + }; if (repl->r_show_ast) { - ivy_ast_node_iterate( - node, &it, IVY_AST_ITERATE_REGULAR, print_ast_node); + ivy_ast_node_iterate(node, &it, print_ast_node, &args); } - ivy_ast_node_iterate(node, &it, IVY_AST_ITERATE_POSTORDER, print_ast_node); + args.indent = false; + args.postorder = true; + ivy_ast_node_iterate(node, &it, print_ast_node, &args); return 0; } +static void repl_destroy(struct repl *repl) +{ + if (repl->r_codegen) { + ivy_codegen_destroy(repl->r_codegen); + } + + if (repl->r_parse) { + ivy_parser_destroy(repl->r_parse); + } + + if (repl->r_lex) { + ivy_lexer_destroy(repl->r_lex); + } + + if (repl->r_ed) { + line_ed_destroy(repl->r_ed); + } + + free(repl); +} + +static enum ivy_status repl_create(struct repl **out) +{ + struct repl *repl = malloc(sizeof *repl); + if (!repl) { + return IVY_ERR_NO_MEMORY; + } + + memset(repl, 0x0, sizeof *repl); + + repl->r_ed = line_ed_create(); + if (!repl->r_ed) { + repl_destroy(repl); + return IVY_ERR_NO_MEMORY; + } + + line_ed_set_flags(repl->r_ed, LINE_ED_REMOVE_CONTINUATIONS); + + enum ivy_status status = ivy_lexer_create(&repl->r_lex); + if (status != IVY_OK) { + repl_destroy(repl); + return status; + } + + ivy_lexer_set_source(repl->r_lex, &repl->r_ed->l_line_source); + + status = ivy_parser_create(&repl->r_parse); + if (status != IVY_OK) { + repl_destroy(repl); + return status; + } + + status = ivy_codegen_create(&repl->r_codegen); + if (status != IVY_OK) { + repl_destroy(repl); + return status; + } + + *out = repl; + return IVY_OK; +} + int repl(const b_command *cmd, const b_arglist *args, const b_array *_) { b_printf( @@ -67,77 +141,59 @@ int repl(const b_command *cmd, const b_arglist *args, const b_array *_) "[bold,bright_blue] |[bold,bright_red] ^^^^^^ cannot " "assign twice to immutable variable[reset]\n"); - struct repl repl = {}; - repl.r_show_lex = b_arglist_get_count( - args, OPT_SHOW_LEX_TOKENS, B_COMMAND_INVALID_ID) - > 0; - repl.r_show_ast = b_arglist_get_count( - args, OPT_SHOW_AST_NODES, B_COMMAND_INVALID_ID) - > 0; - - struct line_ed *ed = line_ed_create(); - line_ed_set_flags(ed, LINE_ED_REMOVE_CONTINUATIONS); - - struct ivy_lexer *lex; - enum ivy_status status = ivy_lexer_create(&lex); - + struct repl *repl = NULL; + enum ivy_status status = repl_create(&repl); if (status != IVY_OK) { - line_ed_destroy(ed); return -1; } - ivy_lexer_set_source(lex, &ed->l_line_source); - - struct ivy_parser *parser; - status = ivy_parser_create(&parser); - - if (status != IVY_OK) { - ivy_lexer_destroy(lex); - line_ed_destroy(ed); - return -1; - } + repl->r_show_lex = b_arglist_get_count( + args, OPT_SHOW_LEX_TOKENS, B_COMMAND_INVALID_ID) + > 0; + repl->r_show_ast = b_arglist_get_count( + args, OPT_SHOW_AST_NODES, B_COMMAND_INVALID_ID) + > 0; while (true) { - struct ivy_token *tok = ivy_lexer_read(lex); - status = ivy_lexer_get_status(lex); + struct ivy_token *tok = ivy_lexer_read(repl->r_lex); + status = ivy_lexer_get_status(repl->r_lex); if (status == IVY_ERR_EOF) { break; } if (status != IVY_OK) { b_err("lex error (%s)", - ivy_status_to_string(ivy_lexer_get_status(lex))); + ivy_status_to_string( + ivy_lexer_get_status(repl->r_lex))); continue; } - if (repl.r_show_lex) { + if (repl->r_show_lex) { print_lex_token(tok); } - status = ivy_parser_push_token(parser, tok); + status = ivy_parser_push_token(repl->r_parse, tok); if (status != IVY_OK) { b_err("parse error (%s)", ivy_status_to_string(status)); ivy_token_destroy(tok); - skip_line(lex); + skip_line(repl->r_lex); continue; } - if (ivy_lexer_tokens_available(lex)) { + if (ivy_lexer_tokens_available(repl->r_lex)) { continue; } struct ivy_ast_node *child = NULL; - while ((child = ivy_parser_dequeue_node(parser))) { - repl_eval_node(&repl, child); + while ((child = ivy_parser_dequeue_node(repl->r_parse))) { + repl_eval_node(repl, child); ivy_ast_node_destroy(child); } } - ivy_parser_destroy(parser); - ivy_lexer_destroy(lex); - line_ed_destroy(ed); + repl_destroy(repl); return 0; }