#include "parser.h"
#include <stdio.h>
#include <string.h>
static void _rava_print_indent(int depth) {
for (int i = 0; i < depth; i++) {
printf(" ");
}
}
static const char* _rava_ast_node_type_name(RavaASTNodeType_e type) {
switch (type) {
case RAVA_AST_COMPILATION_UNIT: return "CompilationUnit";
case RAVA_AST_CLASS_DECL: return "ClassDecl";
case RAVA_AST_METHOD_DECL: return "MethodDecl";
case RAVA_AST_FIELD_DECL: return "FieldDecl";
case RAVA_AST_CONSTRUCTOR_DECL: return "ConstructorDecl";
case RAVA_AST_VAR_DECL: return "VarDecl";
case RAVA_AST_PARAM_DECL: return "ParamDecl";
case RAVA_AST_BLOCK_STMT: return "BlockStmt";
case RAVA_AST_IF_STMT: return "IfStmt";
case RAVA_AST_WHILE_STMT: return "WhileStmt";
case RAVA_AST_FOR_STMT: return "ForStmt";
case RAVA_AST_RETURN_STMT: return "ReturnStmt";
case RAVA_AST_BREAK_STMT: return "BreakStmt";
case RAVA_AST_CONTINUE_STMT: return "ContinueStmt";
case RAVA_AST_EXPR_STMT: return "ExprStmt";
case RAVA_AST_LITERAL_EXPR: return "LiteralExpr";
case RAVA_AST_IDENTIFIER_EXPR: return "IdentifierExpr";
case RAVA_AST_BINARY_EXPR: return "BinaryExpr";
case RAVA_AST_UNARY_EXPR: return "UnaryExpr";
case RAVA_AST_ASSIGN_EXPR: return "AssignExpr";
case RAVA_AST_CALL_EXPR: return "CallExpr";
case RAVA_AST_MEMBER_ACCESS_EXPR: return "MemberAccessExpr";
case RAVA_AST_ARRAY_ACCESS_EXPR: return "ArrayAccessExpr";
case RAVA_AST_NEW_EXPR: return "NewExpr";
case RAVA_AST_TYPE: return "Type";
default: return "Unknown";
}
}
void rava_ast_print(RavaASTNode_t *node, int depth) {
if (!node) {
_rava_print_indent(depth);
printf("<null>\n");
return;
}
_rava_print_indent(depth);
printf("%s", _rava_ast_node_type_name(node->type));
switch (node->type) {
case RAVA_AST_CLASS_DECL:
printf(": %s\n", node->data.class_decl.name);
break;
case RAVA_AST_METHOD_DECL:
printf(": %s\n", node->data.method_decl.name);
break;
case RAVA_AST_FIELD_DECL:
case RAVA_AST_VAR_DECL:
case RAVA_AST_PARAM_DECL:
printf(": %s\n", node->data.var_decl.name ? node->data.var_decl.name : "<unnamed>");
break;
case RAVA_AST_IDENTIFIER_EXPR:
printf(": %s\n", node->data.identifier.name);
break;
case RAVA_AST_LITERAL_EXPR:
printf(": ");
if (node->data.literal.literal_type == RAVA_TOKEN_LITERAL_INTEGER ||
node->data.literal.literal_type == RAVA_TOKEN_LITERAL_LONG) {
printf("%lld\n", (long long)node->data.literal.value.int_value);
} else if (node->data.literal.literal_type == RAVA_TOKEN_LITERAL_FLOAT ||
node->data.literal.literal_type == RAVA_TOKEN_LITERAL_DOUBLE) {
printf("%f\n", node->data.literal.value.float_value);
} else if (node->data.literal.literal_type == RAVA_TOKEN_LITERAL_STRING) {
printf("\"%s\"\n", node->data.literal.value.string_value);
} else if (node->data.literal.literal_type == RAVA_TOKEN_LITERAL_TRUE) {
printf("true\n");
} else if (node->data.literal.literal_type == RAVA_TOKEN_LITERAL_FALSE) {
printf("false\n");
} else if (node->data.literal.literal_type == RAVA_TOKEN_LITERAL_NULL) {
printf("null\n");
} else {
printf("?\n");
}
break;
case RAVA_AST_TYPE:
printf(": %s%s\n", node->data.type.type_name,
node->data.type.is_array ? "[]" : "");
break;
case RAVA_AST_MEMBER_ACCESS_EXPR:
printf(": .%s\n", node->data.member_access.member);
break;
default:
printf("\n");
break;
}
if (node->type == RAVA_AST_BINARY_EXPR) {
_rava_print_indent(depth + 1);
printf("Left:\n");
rava_ast_print(node->data.binary.left, depth + 2);
_rava_print_indent(depth + 1);
printf("Right:\n");
rava_ast_print(node->data.binary.right, depth + 2);
} else if (node->type == RAVA_AST_UNARY_EXPR) {
_rava_print_indent(depth + 1);
printf("Operand:\n");
rava_ast_print(node->data.unary.operand, depth + 2);
} else if (node->type == RAVA_AST_ASSIGN_EXPR) {
_rava_print_indent(depth + 1);
printf("Target:\n");
rava_ast_print(node->data.assign.target, depth + 2);
_rava_print_indent(depth + 1);
printf("Value:\n");
rava_ast_print(node->data.assign.value, depth + 2);
} else if (node->type == RAVA_AST_IF_STMT) {
_rava_print_indent(depth + 1);
printf("Condition:\n");
rava_ast_print(node->data.if_stmt.condition, depth + 2);
_rava_print_indent(depth + 1);
printf("Then:\n");
rava_ast_print(node->data.if_stmt.then_stmt, depth + 2);
if (node->data.if_stmt.else_stmt) {
_rava_print_indent(depth + 1);
printf("Else:\n");
rava_ast_print(node->data.if_stmt.else_stmt, depth + 2);
}
} else if (node->type == RAVA_AST_WHILE_STMT) {
_rava_print_indent(depth + 1);
printf("Condition:\n");
rava_ast_print(node->data.while_stmt.condition, depth + 2);
_rava_print_indent(depth + 1);
printf("Body:\n");
rava_ast_print(node->data.while_stmt.body, depth + 2);
} else if (node->type == RAVA_AST_FOR_STMT) {
if (node->data.for_stmt.init) {
_rava_print_indent(depth + 1);
printf("Init:\n");
rava_ast_print(node->data.for_stmt.init, depth + 2);
}
if (node->data.for_stmt.condition) {
_rava_print_indent(depth + 1);
printf("Condition:\n");
rava_ast_print(node->data.for_stmt.condition, depth + 2);
}
if (node->data.for_stmt.update) {
_rava_print_indent(depth + 1);
printf("Update:\n");
rava_ast_print(node->data.for_stmt.update, depth + 2);
}
_rava_print_indent(depth + 1);
printf("Body:\n");
rava_ast_print(node->data.for_stmt.body, depth + 2);
} else if (node->type == RAVA_AST_RETURN_STMT) {
if (node->data.return_stmt.value) {
_rava_print_indent(depth + 1);
printf("Value:\n");
rava_ast_print(node->data.return_stmt.value, depth + 2);
}
} else if (node->type == RAVA_AST_VAR_DECL || node->type == RAVA_AST_FIELD_DECL || node->type == RAVA_AST_PARAM_DECL) {
if (node->data.var_decl.type) {
_rava_print_indent(depth + 1);
printf("Type:\n");
rava_ast_print(node->data.var_decl.type, depth + 2);
}
if (node->data.var_decl.initializer) {
_rava_print_indent(depth + 1);
printf("Initializer:\n");
rava_ast_print(node->data.var_decl.initializer, depth + 2);
}
} else if (node->type == RAVA_AST_METHOD_DECL) {
if (node->data.method_decl.return_type) {
_rava_print_indent(depth + 1);
printf("Return Type:\n");
rava_ast_print(node->data.method_decl.return_type, depth + 2);
}
} else if (node->type == RAVA_AST_CALL_EXPR) {
_rava_print_indent(depth + 1);
printf("Callee:\n");
rava_ast_print(node->data.call.callee, depth + 2);
if (node->data.call.arguments_count > 0) {
_rava_print_indent(depth + 1);
printf("Arguments:\n");
for (size_t i = 0; i < node->data.call.arguments_count; i++) {
rava_ast_print(node->data.call.arguments[i], depth + 2);
}
}
} else if (node->type == RAVA_AST_MEMBER_ACCESS_EXPR) {
_rava_print_indent(depth + 1);
printf("Object:\n");
rava_ast_print(node->data.member_access.object, depth + 2);
} else if (node->type == RAVA_AST_ARRAY_ACCESS_EXPR) {
_rava_print_indent(depth + 1);
printf("Array:\n");
rava_ast_print(node->data.array_access.array, depth + 2);
_rava_print_indent(depth + 1);
printf("Index:\n");
rava_ast_print(node->data.array_access.index, depth + 2);
} else if (node->type == RAVA_AST_NEW_EXPR) {
_rava_print_indent(depth + 1);
printf("Type:\n");
rava_ast_print(node->data.new_expr.type, depth + 2);
if (node->data.new_expr.arguments_count > 0) {
_rava_print_indent(depth + 1);
printf("Arguments:\n");
for (size_t i = 0; i < node->data.new_expr.arguments_count; i++) {
rava_ast_print(node->data.new_expr.arguments[i], depth + 2);
}
}
}
for (size_t i = 0; i < node->children_count; i++) {
rava_ast_print(node->children[i], depth + 1);
}
}