Files
ivy/frontend/debug.c
Max Wash f123902215 frontend: add parameters to print_ast_node iterator function
the caller can now specify whether the nodes should be printed
in pre-order or post-order, and whether the output should be indented.
2025-04-14 12:24:56 +01:00

384 lines
7.7 KiB
C

#include "debug.h"
#include <blue/object/string.h>
#include <blue/term.h>
#include <ivy/asm/lex.h>
#include <ivy/lang/ast.h>
#include <ivy/lang/lex.h>
#include <stdio.h>
extern void print_lex_token(struct ivy_token *tok)
{
switch (tok->t_type) {
case IVY_TOK_KEYWORD:
b_puts("[magenta]");
break;
case IVY_TOK_SYMBOL:
b_puts("[blue]");
break;
case IVY_TOK_ATOM:
b_puts("[yellow]");
break;
case IVY_TOK_INT:
case IVY_TOK_DOUBLE:
b_puts("[yellow]");
break;
case IVY_TOK_LABEL:
b_puts("[red]");
break;
case IVY_TOK_IDENT:
b_puts("[cyan]");
break;
case IVY_TOK_STRING:
b_puts("[green]");
break;
case IVY_TOK_STR_START:
b_puts("[green]");
break;
case IVY_TOK_STR_END:
b_puts("[green]");
break;
case IVY_TOK_LINEFEED:
b_puts("[dark_grey]");
break;
default:
break;
}
b_puts(ivy_lex_token_type_to_string(tok->t_type));
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;
}
b_puts("[reset]\n");
}
extern void print_asm_lex_token(struct ivy_asm_token *tok)
{
switch (tok->t_type) {
case IVY_ASM_TOK_KEYWORD:
b_puts("[magenta]");
break;
case IVY_ASM_TOK_SYMBOL:
b_puts("[blue]");
break;
case IVY_ASM_TOK_INT:
case IVY_ASM_TOK_DOUBLE:
b_puts("[yellow]");
break;
case IVY_ASM_TOK_LABEL:
b_puts("[red]");
break;
case IVY_ASM_TOK_IDENT:
b_puts("[cyan]");
break;
case IVY_ASM_TOK_STRING:
b_puts("[green]");
break;
case IVY_ASM_TOK_LINEFEED:
b_puts("[dark_grey]");
break;
default:
break;
}
b_puts(ivy_asm_token_type_to_string(tok->t_type));
switch (tok->t_type) {
case IVY_ASM_TOK_IDENT:
case IVY_ASM_TOK_LABEL:
case IVY_ASM_TOK_STRING:
printf("(%s)", tok->t_str);
break;
case IVY_ASM_TOK_SYMBOL:
printf("(%s)", ivy_asm_symbol_to_string(tok->t_symbol));
break;
case IVY_ASM_TOK_KEYWORD:
printf("(%s)", ivy_asm_keyword_to_string(tok->t_keyword));
break;
case IVY_ASM_TOK_INT:
if (tok->t_int.sign) {
printf("(%lld)", tok->t_int.v);
} else {
printf("(%llu)", tok->t_int.uv);
}
break;
case IVY_ASM_TOK_DOUBLE:
printf("(%lf)", tok->t_double);
break;
default:
break;
}
b_puts("[reset]\n");
}
extern enum ivy_status print_ast_node(
struct ivy_ast_node *node, enum ivy_ast_iteration_type type,
struct ivy_ast_node_iterator *it, void *arg)
{
struct print_ast_node_args *args = arg;
if (args && args->postorder && type != IVY_AST_ITERATION_POST) {
return IVY_OK;
}
if ((!args || !args->postorder) && type != IVY_AST_ITERATION_PRE) {
return IVY_OK;
}
if (!args || (args && args->indent)) {
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:
case IVY_AST_COND_GROUP:
case IVY_AST_WHILE_LOOP:
case IVY_AST_FOR_LOOP:
case IVY_AST_TRY:
case IVY_AST_RETURN:
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:
case IVY_AST_ATOM:
case IVY_AST_TUPLE:
b_puts("[yellow]");
break;
case IVY_AST_COND:
case IVY_AST_BLOCK:
case IVY_AST_TRY_CATCH:
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;
case IVY_AST_DISCARD:
b_puts("[dark_grey]");
break;
default:
break;
}
b_string *str = b_string_create();
ivy_ast_node_to_string(node, str);
b_printf("%s", b_string_ptr(str));
b_string_release(str);
#if 0
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_STRING: {
struct ivy_ast_string_node *v = (struct ivy_ast_string_node *)node;
b_printf(" (\"%s\")", v->n_value->t_str);
break;
}
case IVY_AST_ATOM: {
struct ivy_ast_atom_node *v = (struct ivy_ast_atom_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;
}
#endif
#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;
}