From 59f99059bb68ce0e54cb448ebfcb71f4c619da12 Mon Sep 17 00:00:00 2001 From: laentropia Date: Tue, 12 May 2026 18:15:36 -0600 Subject: [PATCH] refactor: changes and additions ot parser --- include/lexer.h | 10 +++++++--- include/parser.h | 6 ++++-- src/evaluator.c | 4 +++- src/lexer.c | 6 ++++++ src/parser.c | 42 +++++++++++++++++++++++++++++++++++++----- 5 files changed, 57 insertions(+), 11 deletions(-) diff --git a/include/lexer.h b/include/lexer.h index 430b0a4..5081605 100644 --- a/include/lexer.h +++ b/include/lexer.h @@ -10,6 +10,7 @@ typedef enum { NODE_INTEGER, NODE_BINARY_OP, + NODE_UNARY_OP, } ASTNodeType; // For classify operators @@ -17,7 +18,8 @@ typedef enum { OP_ADD, OP_SUB, OP_MUL, - OP_DIV + OP_DIV, + OP_POW, } Operator; typedef enum { @@ -26,8 +28,6 @@ typedef enum { LEXER_FAILED_NUMBER_CONVERSION, LEXER_NOT_RECOGNIZED_SYMBOL, LEXER_EMPTY_INPUT, - LEXER_NULL_ARG, - LEXER_WRONG_SYNTAX, LEXER_BUF_OVERFLOW, } LexerErr; @@ -41,6 +41,10 @@ typedef struct ASTNode { struct ASTNode *right; Operator op; } binary; + struct { + struct ASTNode *val; + Operator op; + } unary; } data; } ASTNode; diff --git a/include/parser.h b/include/parser.h index 158b348..0c8f080 100644 --- a/include/parser.h +++ b/include/parser.h @@ -32,8 +32,10 @@ typedef struct { ASTNode *nud(ArraySlice *slice); ASTNode *led(ArraySlice *slice, size_t right_precedence); -uint8_t node_lbp(ASTNode node); -uint8_t node_rbp(ASTNode node); +uint8_t prefix_lbp(ASTNode node); +uint8_t prefix_rbp(ASTNode node); +uint8_t infix_lbp(ASTNode node); +uint8_t infix_rbp(ASTNode node); ParseResult parse(TokenizeResult tokens); ASTNode *parse_expr(ArraySlice *slice, Arena *arena, uint8_t min_bp); diff --git a/src/evaluator.c b/src/evaluator.c index 36d9fb1..551f779 100644 --- a/src/evaluator.c +++ b/src/evaluator.c @@ -3,6 +3,7 @@ #include "lexer.h" #include "parser.h" #include +#include int64_t evaluate_tree(ASTNode *tree) { @@ -20,7 +21,8 @@ int64_t evaluate_tree(ASTNode *tree) { return evaluate_tree(left) * evaluate_tree(right); case OP_DIV: return evaluate_tree(left) / evaluate_tree(right); - + case OP_POW: + return pow(evaluate_tree(left), evaluate_tree(right)); } } diff --git a/src/lexer.c b/src/lexer.c index f139394..201a187 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -131,6 +131,7 @@ bool isoperator(int c) { case '-': case '/': case '*': + case '^': return true; default: return false; @@ -151,6 +152,9 @@ Operator char_to_operator(int c) { case '/': return OP_DIV; break; + case '^': + return OP_POW; + break; default: // I mean shouldn't be used, we assume return -1; } @@ -166,5 +170,7 @@ char operator_to_char(Operator op) { return '*'; case OP_DIV: return '/'; + case OP_POW: + return '^'; } } diff --git a/src/parser.c b/src/parser.c index a3efae0..fc4c142 100644 --- a/src/parser.c +++ b/src/parser.c @@ -6,7 +6,21 @@ #include #include -uint8_t node_lbp(ASTNode node) { +uint8_t prefix_rbp(ASTNode node) { + if (node.type == NODE_INTEGER) { + return 0; + } + + switch (node.data.unary.op) { + case OP_SUB: + case OP_ADD: + return 5; + default: + return -1; + } +} + +uint8_t infix_lbp(ASTNode node) { if (node.type == NODE_INTEGER) { return 0; } @@ -19,12 +33,14 @@ uint8_t node_lbp(ASTNode node) { case OP_DIV: case OP_MUL: return 20; + case OP_POW: + return 31; default: return 0; } } -uint8_t node_rbp(ASTNode node) { +uint8_t infix_rbp(ASTNode node) { if (node.type == NODE_INTEGER) { return 0; } @@ -37,6 +53,8 @@ uint8_t node_rbp(ASTNode node) { case OP_DIV: case OP_MUL: return 21; + case OP_POW: + return 30; default: return 0; } @@ -53,12 +71,14 @@ ParseResult parse(TokenizeResult tokens) { } ASTNode *parse_expr(ArraySlice *slice, Arena *arena, uint8_t min_bp) { + // First: Consume a first number arena_ensure_capacity( arena, sizeof(ASTNode), alignof(ASTNode) - ); + ); // shouldn't fail but if it does then what a shame + // Get pointer in the arena ASTNode *left_side = arena_unwrap_pointer( arena_alloc( arena, @@ -67,22 +87,33 @@ ASTNode *parse_expr(ArraySlice *slice, Arena *arena, uint8_t min_bp) { ) ); + // Should check if is Integer or number arrayslice_next(slice, left_side); while (true) { + // Second: Get next one and checn bp if (!arrayslice_is_valid(slice)) { break; } ASTNode operator; + // Here should chekc if is operator not some bs + // Third, get operator and binding powers arrayslice_peek(slice, &operator); - uint8_t rbp = node_rbp(operator); - uint8_t lbp = node_lbp(operator); + uint8_t rbp = infix_rbp(operator); + uint8_t lbp = infix_lbp(operator); + // If lbp is LESS then stop recursion, + // we found the next smaller binding power + // or the one with more precedence if (lbp < min_bp) { break; } + + // If NOT, then we continue wtching ahead + // for the next one but taking our current + // concern that is rbp of the current operator arrayslice_next(slice, NULL); ASTNode *right_side = parse_expr(slice, arena, rbp); @@ -106,6 +137,7 @@ ASTNode *parse_expr(ArraySlice *slice, Arena *arena, uint8_t min_bp) { } + // Final: return left side return left_side; }