diff --git a/frontend/cmd/compile.c b/frontend/cmd/compile.c index 6563bd6..4a836dd 100644 --- a/frontend/cmd/compile.c +++ b/frontend/cmd/compile.c @@ -84,7 +84,9 @@ static int compile_file(const char *path, const b_arglist *args) if (!lex_only && r == 0) { struct ivy_ast_node *root = ivy_parser_root_node(parser); - ivy_ast_node_print(root); + struct ivy_ast_node_iterator it = {0}; + ivy_ast_node_iterate(root, &it, print_ast_node); + // ivy_ast_node_print(root); } if (lex) { diff --git a/frontend/debug.c b/frontend/debug.c index d0e099a..62cfabb 100644 --- a/frontend/debug.c +++ b/frontend/debug.c @@ -1,6 +1,7 @@ #include -#include #include +#include +#include #include extern void print_lex_token(struct ivy_token *tok) @@ -128,3 +129,210 @@ extern void print_asm_lex_token(struct ivy_asm_token *tok) b_puts("[reset]\n"); } + +extern enum ivy_status print_ast_node( + struct ivy_ast_node *node, struct ivy_ast_node_iterator *it) +{ + for (unsigned int i = 0; i < node->n_it.it_depth; i++) { + b_puts(" "); + } + + switch (node->n_type) { + case IVY_AST_UNIT: + case IVY_AST_CLASS: + case IVY_AST_MSGH: + case IVY_AST_UNIT_PACKAGE: + case IVY_AST_UNIT_IMPORT: + b_puts("[magenta]"); + break; + case IVY_AST_OP: + b_puts("[blue]"); + break; + case IVY_AST_MSG: + b_puts("[red]"); + break; + case IVY_AST_INT: + case IVY_AST_DOUBLE: + b_puts("[yellow]"); + break; + case IVY_AST_BLOCK: + b_puts("[red]"); + break; + case IVY_AST_IDENT: + case IVY_AST_SELECTOR: + b_puts("[cyan]"); + break; + case IVY_AST_STRING: + case IVY_AST_FSTRING: + b_puts("[green]"); + break; + default: + break; + } + + b_puts(ivy_ast_node_type_to_string(node->n_type)); + + switch (node->n_type) { + case IVY_AST_INT: { + struct ivy_ast_int_node *v = (struct ivy_ast_int_node *)node; + b_printf(" (%llu)", v->n_value->t_int); + break; + } + case IVY_AST_DOUBLE: { + struct ivy_ast_double_node *v = (struct ivy_ast_double_node *)node; + b_printf(" (%.2lf)", v->n_value->t_double); + break; + } + case IVY_AST_IDENT: { + struct ivy_ast_ident_node *v = (struct ivy_ast_ident_node *)node; + b_printf(" (%s)", v->n_content->t_str); + break; + } + case IVY_AST_SELECTOR: { + struct ivy_ast_selector_node *v + = (struct ivy_ast_selector_node *)node; + b_printf(" [["); + + switch (v->n_recipient) { + case IVY_SELECTOR_RECIPIENT_CLASS: + b_putc('+'); + break; + case IVY_SELECTOR_RECIPIENT_OBJECT: + b_putc('-'); + break; + default: + /* this will occur if the selector is being used to send + a message at runtime, rather than as part of a + message handler definition. */ + break; + } + + if (v->n_msg_name) { + b_printf("%s", v->n_msg_name->t_str); + } + + if (v->n_msg_name && !b_queue_empty(&v->n_arg_labels)) { + b_putc('('); + } + + b_queue_iterator label_it = {0}; + b_queue_iterator name_it = {0}; + + b_queue_iterator_begin(&v->n_arg_labels, &label_it); + b_queue_iterator_begin(&v->n_arg_names, &name_it); + + bool name_present = false; + int i = 0; + while (b_queue_iterator_is_valid(&label_it)) { + if (i > 0 && name_present) { + fputc(' ', stdout); + } + + struct ivy_token *label = b_unbox( + struct ivy_token, label_it.entry, t_entry); + struct ivy_token *name = b_unbox( + struct ivy_token, name_it.entry, t_entry); + + if (label) { + b_printf("%s:", label->t_str); + } + + if (name) { + b_printf("%s", name->t_str); + } + + name_present = (name != NULL); + + i++; + b_queue_iterator_next(&label_it); + b_queue_iterator_next(&name_it); + } + + if (v->n_msg_name && !b_queue_empty(&v->n_arg_labels)) { + b_putc(')'); + } + + b_puts("]"); + break; + } + case IVY_AST_OP: { + struct ivy_ast_op_node *v = (struct ivy_ast_op_node *)node; + b_printf(" (%s)", ivy_operator_id_to_string(v->n_op->op_id)); + break; + } + case IVY_AST_CLASS: { + struct ivy_ast_class_node *v = (struct ivy_ast_class_node *)node; + b_printf(" (%s)", v->n_ident->t_str); + break; + } + case IVY_AST_UNIT_PACKAGE: { + struct ivy_ast_unit_package_node *v + = (struct ivy_ast_unit_package_node *)node; + b_printf(" ("); + b_queue_iterator it = {0}; + int i = 0; + b_queue_foreach (&it, &v->n_ident) { + struct ivy_token *tok + = b_unbox(struct ivy_token, it.entry, t_entry); + + if (i > 0) { + b_printf("."); + } + + b_printf("%s", tok->t_str); + i++; + } + b_printf(")"); + break; + } + case IVY_AST_UNIT_IMPORT: { + struct ivy_ast_unit_import_node *v + = (struct ivy_ast_unit_import_node *)node; + b_printf(" ("); + b_queue_iterator it = {0}; + int i = 0; + b_queue_foreach (&it, &v->n_ident) { + struct ivy_token *tok + = b_unbox(struct ivy_token, it.entry, t_entry); + + if (i > 0) { + b_printf("."); + } + + b_printf("%s", tok->t_str); + i++; + } + b_printf(")"); + break; + } + default: + break; + } +#if 0 + switch (tok->t_type) { + case IVY_TOK_IDENT: + case IVY_TOK_LABEL: + case IVY_TOK_STRING: + case IVY_TOK_ATOM: + printf("(%s)", tok->t_str); + break; + case IVY_TOK_SYMBOL: + printf("(%s)", ivy_symbol_to_string(tok->t_symbol)); + break; + case IVY_TOK_KEYWORD: + printf("(%s)", ivy_keyword_to_string(tok->t_keyword)); + break; + case IVY_TOK_INT: + printf("(%llu)", tok->t_int); + break; + case IVY_TOK_DOUBLE: + printf("(%lf)", tok->t_double); + break; + default: + break; + } +#endif + + b_puts("[reset]\n"); + return IVY_OK; +} diff --git a/frontend/debug.h b/frontend/debug.h index a08271c..6884742 100644 --- a/frontend/debug.h +++ b/frontend/debug.h @@ -1,10 +1,18 @@ #ifndef DEBUG_H_ #define DEBUG_H_ +#include + struct ivy_token; struct ivy_asm_token; +struct ivy_ast_node; +struct ivy_ast_node_iterator; + extern void print_lex_token(struct ivy_token *tok); extern void print_asm_lex_token(struct ivy_asm_token *tok); +extern enum ivy_status print_ast_node( + struct ivy_ast_node *node, struct ivy_ast_node_iterator *it); + #endif