237 lines
8.8 KiB
C
Raw Normal View History

2025-12-02 06:54:32 +01:00
#define _POSIX_C_SOURCE 200809L
#include "parser.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
RavaASTNode_t* rava_ast_node_create(RavaASTNodeType_e type, int line, int column) {
RavaASTNode_t *node = calloc(1, sizeof(RavaASTNode_t));
node->type = type;
node->line = line;
node->column = column;
node->parent = NULL;
node->children = NULL;
node->children_count = 0;
node->children_capacity = 0;
return node;
}
void rava_ast_node_destroy(RavaASTNode_t *node) {
if (!node) return;
for (size_t i = 0; i < node->children_count; i++) {
rava_ast_node_destroy(node->children[i]);
}
free(node->children);
switch (node->type) {
case RAVA_AST_IDENTIFIER_EXPR:
free(node->data.identifier.name);
break;
case RAVA_AST_CLASS_DECL:
free(node->data.class_decl.name);
free(node->data.class_decl.modifiers);
rava_ast_node_destroy(node->data.class_decl.type);
break;
case RAVA_AST_METHOD_DECL:
free(node->data.method_decl.name);
free(node->data.method_decl.modifiers);
rava_ast_node_destroy(node->data.method_decl.return_type);
break;
case RAVA_AST_VAR_DECL:
free(node->data.var_decl.name);
rava_ast_node_destroy(node->data.var_decl.type);
rava_ast_node_destroy(node->data.var_decl.initializer);
break;
case RAVA_AST_TYPE:
free(node->data.type.type_name);
break;
case RAVA_AST_MEMBER_ACCESS_EXPR:
free(node->data.member_access.member);
rava_ast_node_destroy(node->data.member_access.object);
break;
case RAVA_AST_CALL_EXPR:
rava_ast_node_destroy(node->data.call.callee);
for (size_t i = 0; i < node->data.call.arguments_count; i++) {
rava_ast_node_destroy(node->data.call.arguments[i]);
}
free(node->data.call.arguments);
break;
case RAVA_AST_NEW_EXPR:
rava_ast_node_destroy(node->data.new_expr.type);
for (size_t i = 0; i < node->data.new_expr.arguments_count; i++) {
rava_ast_node_destroy(node->data.new_expr.arguments[i]);
}
free(node->data.new_expr.arguments);
break;
case RAVA_AST_LITERAL_EXPR:
if (node->data.literal.literal_type == RAVA_TOKEN_LITERAL_STRING) {
free(node->data.literal.value.string_value);
}
break;
default:
break;
}
free(node);
}
void rava_ast_node_add_child(RavaASTNode_t *parent, RavaASTNode_t *child) {
if (!parent || !child) return;
if (parent->children_count >= parent->children_capacity) {
size_t new_capacity = parent->children_capacity == 0 ? 4 : parent->children_capacity * 2;
parent->children = realloc(parent->children, sizeof(RavaASTNode_t*) * new_capacity);
parent->children_capacity = new_capacity;
}
parent->children[parent->children_count++] = child;
child->parent = parent;
}
RavaParser_t* rava_parser_create(RavaLexer_t *lexer) {
RavaParser_t *parser = malloc(sizeof(RavaParser_t));
parser->lexer = lexer;
parser->current_token = rava_lexer_next_token(lexer);
parser->peek_token = rava_lexer_next_token(lexer);
parser->error_message = NULL;
parser->had_error = false;
return parser;
}
void rava_parser_destroy(RavaParser_t *parser) {
if (!parser) return;
rava_token_destroy(parser->current_token);
rava_token_destroy(parser->peek_token);
free(parser->error_message);
free(parser);
}
void _rava_parser_advance(RavaParser_t *parser) {
rava_token_destroy(parser->current_token);
parser->current_token = parser->peek_token;
parser->peek_token = rava_lexer_next_token(parser->lexer);
}
bool _rava_parser_check(RavaParser_t *parser, RavaTokenType_e type) {
return parser->current_token->type == type;
}
bool _rava_parser_match(RavaParser_t *parser, RavaTokenType_e type) {
if (_rava_parser_check(parser, type)) {
_rava_parser_advance(parser);
return true;
}
return false;
}
bool _rava_parser_expect(RavaParser_t *parser, RavaTokenType_e type, const char *message) {
if (_rava_parser_check(parser, type)) {
_rava_parser_advance(parser);
return true;
}
parser->had_error = true;
if (parser->error_message) free(parser->error_message);
parser->error_message = malloc(256);
snprintf(parser->error_message, 256, "%s at line %d, column %d",
message, parser->current_token->line, parser->current_token->column);
return false;
}
extern RavaASTNode_t* _rava_parser_parse_type(RavaParser_t *parser);
extern RavaASTNode_t* _rava_parser_parse_expression(RavaParser_t *parser);
extern RavaASTNode_t* _rava_parser_parse_statement(RavaParser_t *parser);
extern RavaASTNode_t* _rava_parser_parse_block(RavaParser_t *parser);
static RavaModifier_e _rava_token_to_modifier(RavaTokenType_e type) {
switch (type) {
case RAVA_TOKEN_KEYWORD_PUBLIC: return RAVA_MODIFIER_PUBLIC;
case RAVA_TOKEN_KEYWORD_PRIVATE: return RAVA_MODIFIER_PRIVATE;
case RAVA_TOKEN_KEYWORD_PROTECTED: return RAVA_MODIFIER_PROTECTED;
case RAVA_TOKEN_KEYWORD_STATIC: return RAVA_MODIFIER_STATIC;
case RAVA_TOKEN_KEYWORD_FINAL: return RAVA_MODIFIER_FINAL;
case RAVA_TOKEN_KEYWORD_ABSTRACT: return RAVA_MODIFIER_ABSTRACT;
case RAVA_TOKEN_KEYWORD_NATIVE: return RAVA_MODIFIER_NATIVE;
case RAVA_TOKEN_KEYWORD_SYNCHRONIZED: return RAVA_MODIFIER_SYNCHRONIZED;
case RAVA_TOKEN_KEYWORD_TRANSIENT: return RAVA_MODIFIER_TRANSIENT;
case RAVA_TOKEN_KEYWORD_VOLATILE: return RAVA_MODIFIER_VOLATILE;
case RAVA_TOKEN_KEYWORD_STRICTFP: return RAVA_MODIFIER_STRICTFP;
default: return RAVA_MODIFIER_PUBLIC;
}
}
static bool _rava_is_modifier(RavaTokenType_e type) {
return type == RAVA_TOKEN_KEYWORD_PUBLIC ||
type == RAVA_TOKEN_KEYWORD_PRIVATE ||
type == RAVA_TOKEN_KEYWORD_PROTECTED ||
type == RAVA_TOKEN_KEYWORD_STATIC ||
type == RAVA_TOKEN_KEYWORD_FINAL ||
type == RAVA_TOKEN_KEYWORD_ABSTRACT ||
type == RAVA_TOKEN_KEYWORD_NATIVE ||
type == RAVA_TOKEN_KEYWORD_SYNCHRONIZED ||
type == RAVA_TOKEN_KEYWORD_TRANSIENT ||
type == RAVA_TOKEN_KEYWORD_VOLATILE ||
type == RAVA_TOKEN_KEYWORD_STRICTFP;
}
void _rava_parser_parse_modifiers(RavaParser_t *parser, RavaModifier_e **modifiers, size_t *count) {
size_t capacity = 4;
*modifiers = malloc(sizeof(RavaModifier_e) * capacity);
*count = 0;
while (_rava_is_modifier(parser->current_token->type)) {
if (*count >= capacity) {
capacity *= 2;
*modifiers = realloc(*modifiers, sizeof(RavaModifier_e) * capacity);
}
(*modifiers)[(*count)++] = _rava_token_to_modifier(parser->current_token->type);
_rava_parser_advance(parser);
}
}
RavaASTNode_t* _rava_parser_parse_type(RavaParser_t *parser) {
RavaASTNode_t *type_node = rava_ast_node_create(RAVA_AST_TYPE,
parser->current_token->line,
parser->current_token->column);
if (_rava_parser_check(parser, RAVA_TOKEN_IDENTIFIER) ||
_rava_parser_check(parser, RAVA_TOKEN_KEYWORD_INT) ||
_rava_parser_check(parser, RAVA_TOKEN_KEYWORD_BOOLEAN) ||
_rava_parser_check(parser, RAVA_TOKEN_KEYWORD_CHAR) ||
_rava_parser_check(parser, RAVA_TOKEN_KEYWORD_BYTE) ||
_rava_parser_check(parser, RAVA_TOKEN_KEYWORD_SHORT) ||
_rava_parser_check(parser, RAVA_TOKEN_KEYWORD_LONG) ||
_rava_parser_check(parser, RAVA_TOKEN_KEYWORD_FLOAT) ||
_rava_parser_check(parser, RAVA_TOKEN_KEYWORD_DOUBLE) ||
_rava_parser_check(parser, RAVA_TOKEN_KEYWORD_VOID)) {
type_node->data.type.type_name = strdup(parser->current_token->lexeme);
type_node->data.type.is_array = false;
type_node->data.type.array_dimensions = 0;
_rava_parser_advance(parser);
while (_rava_parser_check(parser, RAVA_TOKEN_LBRACKET)) {
if (parser->peek_token && parser->peek_token->type == RAVA_TOKEN_RBRACKET) {
_rava_parser_advance(parser);
_rava_parser_advance(parser);
type_node->data.type.is_array = true;
type_node->data.type.array_dimensions++;
} else {
break;
}
}
} else {
parser->had_error = true;
if (parser->error_message) free(parser->error_message);
parser->error_message = strdup("Expected type name");
rava_ast_node_destroy(type_node);
return NULL;
}
return type_node;
}
RavaASTNode_t* rava_parser_parse(RavaParser_t *parser);