#include "parser.h" #include "lexer.h" #include "utils.h" #include #include #include ParsedExpr* parsed_expr_alloc(const ParsedExpr source) { ParsedExpr* destination = malloc(sizeof(ParsedExpr)); *destination = source; return destination; } void parsed_expr_free(ParsedExpr* expr) { switch (expr->type) { case ParsedExprTypeError: free(expr->error.message); break; case ParsedExprTypeId: free(expr->id.value); break; case ParsedExprTypeInt: break; default: TODO(); } free(expr); } ParsedExpr* parsed_error_expr(Position position, const char* message) { return parsed_expr_alloc((ParsedExpr) { .type = ParsedExprTypeError, .error = { .position = position, .message = alloc_cstring(message), }, }); } void parser_create(Parser* parser, const char* text, Lexer* lexer) { *parser = (Parser) { .text = text, .lexer = lexer, .current = lexer_next(lexer), }; } ParsedExpr* parser_parse_expression(Parser* parser) { return parser_parse_operand(parser); } ParsedExpr* parser_parse_operand(Parser* parser) { Token current_token = parser_current(parser); if (parser_current_is(parser, TokenTypeId)) { AllocatedString string = alloc_token_string(parser_current(parser), parser->text); return parsed_expr_alloc((ParsedExpr) { .type = ParsedExprTypeId, .id = { .value = string.value, .length = string.length, }, }); } else if (parser_current_is(parser, TokenTypeInt)) { char string_value[24] = { 0 }; strncpy( string_value, &parser->text[current_token.position.index], current_token.length ); int64_t value = strtoll(string_value, NULL, 10); return parsed_expr_alloc((ParsedExpr) { .type = ParsedExprTypeInt, .int_value = value, }); } else { parser_step(parser); return parsed_expr_alloc((ParsedExpr) { .type = ParsedExprTypeError, .error = { .position = current_token.position, .message = alloc_cstring("expected value"), }, }); } } bool parser_current_is(const Parser* parser, TokenType type) { return !parser_done(parser) && parser_current(parser).type == type; } bool parser_done(const Parser* parser) { return parser->current.type == TokenTypeEof; } Token parser_current(const Parser* parser) { return parser->current; } void parser_step(Parser* parser) { parser->current = lexer_next(parser->lexer); } AllocatedString alloc_token_string(Token token, const char* text) { return alloc_string(&text[token.position.index], token.length); }