From 56c80fa071b52f17fac4cabae4bd2bc973a44f95 Mon Sep 17 00:00:00 2001 From: laentropia Date: Tue, 12 May 2026 20:04:41 -0600 Subject: [PATCH] addition: Managing of parenthesis Its a fucking mess, i was writting straight bullshit but it conceptually should work, just need to refactor the shit out of it to make it way more clean than it actually is and also later fix the fucking evaluator like damn it sucks ASSS now (not that much really is nice but obviously doesn't work, i like my code a lot :) --- include/lexer.h | 7 ++++ src/lexer.c | 13 ++++++++ src/parser.c | 88 +++++++++++++++++++++++++++++-------------------- 3 files changed, 73 insertions(+), 35 deletions(-) diff --git a/include/lexer.h b/include/lexer.h index 387c77c..4af0f9d 100644 --- a/include/lexer.h +++ b/include/lexer.h @@ -11,6 +11,7 @@ typedef enum { NODE_INTEGER, NODE_BINARY_OP, NODE_UNARY_OP, + NODE_PARENTHESIS, } ASTNodeType; // For classify operators @@ -21,6 +22,8 @@ typedef enum { OP_DIV, OP_POW, OP_FACTORIAL, + OP_START_PAR, + OP_END_PAR, } Operator; typedef enum { @@ -46,6 +49,10 @@ typedef struct ASTNode { struct ASTNode *val; Operator op; } unary; + struct { + struct ASTNode *val; + Operator op; + } parenthesis; } data; } ASTNode; diff --git a/src/lexer.c b/src/lexer.c index 4696fe7..2115cc4 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -132,6 +132,9 @@ bool isoperator(int c) { case '/': case '*': case '^': + case '!': + case '(': + case ')': return true; default: return false; @@ -158,6 +161,12 @@ Operator char_to_operator(int c) { case '!': return OP_FACTORIAL; break; + case '(': + return OP_START_PAR; + break; + case ')': + return OP_END_PAR; + break; default: // I mean shouldn't be used, we assume return -1; } @@ -177,6 +186,10 @@ char operator_to_char(Operator op) { return '^'; case OP_FACTORIAL: return '!'; + case OP_START_PAR: + return '('; + case OP_END_PAR: + return ')'; default: return EOF; } diff --git a/src/parser.c b/src/parser.c index 101c995..2a09988 100644 --- a/src/parser.c +++ b/src/parser.c @@ -101,6 +101,20 @@ ASTNode *parse_expr(ArraySlice *slice, Arena *arena, uint8_t min_bp) { ) ); + arrayslice_next(slice, left_side); + + if (left_side->type == NODE_PARENTHESIS && + left_side->data.parenthesis.op == OP_START_PAR) { + left_side = parse_expr(slice, arena, 0); + // HERE CHEKC LATER if slice.next != ')' + ASTNode *end_par; + arrayslice_next(slice, &end_par); + if (end_par->type != NODE_PARENTHESIS || + end_par->data.parenthesis.op != OP_END_PAR) { + // todo + } + return left_side; + } // if is unary then take prefix bp and continue // to the right, no need to allocate left side // because we just did and right side @@ -110,10 +124,7 @@ ASTNode *parse_expr(ArraySlice *slice, Arena *arena, uint8_t min_bp) { ASTNode *righ_side = parse_expr(slice, arena, rbp); left_side->data.unary.val = righ_side; - return left_side; } - // Should check if is Integer or number - arrayslice_next(slice, left_side); while (true) { // Second: Get next one and checn bp @@ -153,47 +164,54 @@ ASTNode *parse_expr(ArraySlice *slice, Arena *arena, uint8_t min_bp) { new_node->data.unary.val = left_side; left_side = new_node; + continue; } + + // check if it has infix or not, if not then error 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 (rbp != 255 && lbp != 255) { + + // 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); + + arena_ensure_capacity( + arena, + sizeof(ASTNode), + alignof(ASTNode)); + ASTNode *new_node = arena_unwrap_pointer( + arena_alloc( + arena, + sizeof(ASTNode), + alignof(ASTNode) + ) + ); + *new_node = operator; + + new_node->data.binary.left = left_side; + new_node->data.binary.right = right_side; + + left_side = new_node; + + continue; } - - // 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); - - arena_ensure_capacity( - arena, - sizeof(ASTNode), - alignof(ASTNode)); - ASTNode *new_node = arena_unwrap_pointer( - arena_alloc( - arena, - sizeof(ASTNode), - alignof(ASTNode) - ) - ); - *new_node = operator; - - new_node->data.binary.left = left_side; - new_node->data.binary.right = right_side; - - left_side = new_node; + break; } // Final: return left side return left_side; } - - -