|
#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);
|
|
}
|
|
}
|