From abebdb595ac69f99b2a78928a8eb25aba865479d Mon Sep 17 00:00:00 2001 From: Max Wash Date: Tue, 15 Apr 2025 11:00:48 +0100 Subject: [PATCH] frontend: add IR generation to compile command --- frontend/cmd/compile.c | 67 ++++++++++++++++++++++++++++++++++++++++-- frontend/cmd/repl.c | 2 ++ frontend/debug.c | 1 + 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/frontend/cmd/compile.c b/frontend/cmd/compile.c index 7fec06d..ea91116 100644 --- a/frontend/cmd/compile.c +++ b/frontend/cmd/compile.c @@ -6,15 +6,27 @@ #include #include #include +#include #include +#include +#include #include enum { ARG_SOURCE_FILE = 200, OPT_SHOW_LEX_TOKENS, OPT_SHOW_AST_NODES, + OPT_SHOW_IR, }; +static enum ivy_status node_codegen( + struct ivy_ast_node *node, enum ivy_ast_iteration_type iteration_type, + struct ivy_ast_node_iterator *it, void *arg) +{ + struct ivy_codegen *gen = arg; + return ivy_codegen_push_node(gen, node, iteration_type); +} + static int compile_file(const char *path, const b_arglist *args) { bool show_lex = b_arglist_get_count( @@ -23,6 +35,8 @@ static int compile_file(const char *path, const b_arglist *args) bool show_ast = b_arglist_get_count( args, OPT_SHOW_AST_NODES, B_COMMAND_INVALID_ID) > 0; + bool show_ir + = b_arglist_get_count(args, OPT_SHOW_IR, B_COMMAND_INVALID_ID) > 0; FILE *fp = fopen(path, "r"); if (!fp) { @@ -52,6 +66,17 @@ static int compile_file(const char *path, const b_arglist *args) return -1; } + struct ivy_codegen *codegen; + status = ivy_codegen_create(&codegen); + + if (status != IVY_OK) { + b_err("failed to initialise Ivy code generator"); + ivy_parser_destroy(parser); + ivy_lexer_destroy(lex); + ivy_file_close(src); + return -1; + } + while (true) { struct ivy_token *tok = ivy_lexer_read(lex); status = ivy_lexer_get_status(lex); @@ -90,14 +115,41 @@ static int compile_file(const char *path, const b_arglist *args) ivy_ast_node_iterate(root, &it, print_ast_node, NULL); } - if (lex) { - ivy_lexer_destroy(lex); + ivy_lexer_destroy(lex); + + if (r != 0) { + ivy_parser_destroy(parser); + return r; } - if (parser) { + if (!show_ir) { ivy_parser_destroy(parser); + return 0; } + ivy_codegen_start_module(codegen); + + struct ivy_ast_node *node = NULL; + while ((node = ivy_parser_dequeue_node(parser))) { + struct ivy_ast_node_iterator it = {0}; + ivy_ast_node_iterate(node, &it, node_codegen, codegen); + ivy_ast_node_destroy(node); + } + + struct mie_module *mod = NULL; + ivy_codegen_end_module(codegen, &mod); + + struct mie_ir_converter *convert + = mie_ir_converter_create(MIE_IR_MEM, MIE_IR_TEXT); + mie_ir_converter_set_src_value(convert, MIE_VALUE(mod)); + mie_ir_converter_set_dest_file(convert, stdout); + mie_ir_converter_process(convert); + + mie_ir_converter_destroy(convert); + ivy_codegen_destroy(codegen); + + ivy_parser_destroy(parser); + return r; } @@ -148,6 +200,15 @@ B_COMMAND(CMD_COMPILE, CMD_ROOT) "input files."); } + B_COMMAND_OPTION(OPT_SHOW_IR) + { + B_OPTION_LONG_NAME("show-ir"); + B_OPTION_SHORT_NAME('i'); + B_OPTION_DESC( + "print the Mie IR generated from the " + "input files."); + } + B_COMMAND_ARG(ARG_SOURCE_FILE) { B_ARG_NAME("source file"); diff --git a/frontend/cmd/repl.c b/frontend/cmd/repl.c index 2e61f22..5e5d13a 100644 --- a/frontend/cmd/repl.c +++ b/frontend/cmd/repl.c @@ -150,6 +150,7 @@ static enum ivy_status repl_create(struct repl **out) int repl(const b_command *cmd, const b_arglist *args, const b_array *_) { +#if 0 b_printf( "[bold,bright_red]error[[E0384][reset,bold,white]: cannot " "assign twice to immutable variable `i`[reset]\n"); @@ -169,6 +170,7 @@ int repl(const b_command *cmd, const b_arglist *args, const b_array *_) b_printf( "[bold,bright_blue] |[bold,bright_red] ^^^^^^ cannot " "assign twice to immutable variable[reset]\n"); +#endif struct repl *repl = NULL; enum ivy_status status = repl_create(&repl); diff --git a/frontend/debug.c b/frontend/debug.c index 5004c6a..8e9bf6a 100644 --- a/frontend/debug.c +++ b/frontend/debug.c @@ -164,6 +164,7 @@ extern enum ivy_status print_ast_node( case IVY_AST_FOR_LOOP: case IVY_AST_TRY: case IVY_AST_RETURN: + case IVY_AST_VAR: b_puts("[magenta]"); break; case IVY_AST_OP: