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 :)
This commit is contained in:
2026-05-12 20:04:41 -06:00
parent 7f390a8c6b
commit 56c80fa071
3 changed files with 73 additions and 35 deletions

View File

@@ -11,6 +11,7 @@ typedef enum {
NODE_INTEGER, NODE_INTEGER,
NODE_BINARY_OP, NODE_BINARY_OP,
NODE_UNARY_OP, NODE_UNARY_OP,
NODE_PARENTHESIS,
} ASTNodeType; } ASTNodeType;
// For classify operators // For classify operators
@@ -21,6 +22,8 @@ typedef enum {
OP_DIV, OP_DIV,
OP_POW, OP_POW,
OP_FACTORIAL, OP_FACTORIAL,
OP_START_PAR,
OP_END_PAR,
} Operator; } Operator;
typedef enum { typedef enum {
@@ -46,6 +49,10 @@ typedef struct ASTNode {
struct ASTNode *val; struct ASTNode *val;
Operator op; Operator op;
} unary; } unary;
struct {
struct ASTNode *val;
Operator op;
} parenthesis;
} data; } data;
} ASTNode; } ASTNode;

View File

@@ -132,6 +132,9 @@ bool isoperator(int c) {
case '/': case '/':
case '*': case '*':
case '^': case '^':
case '!':
case '(':
case ')':
return true; return true;
default: default:
return false; return false;
@@ -158,6 +161,12 @@ Operator char_to_operator(int c) {
case '!': case '!':
return OP_FACTORIAL; return OP_FACTORIAL;
break; break;
case '(':
return OP_START_PAR;
break;
case ')':
return OP_END_PAR;
break;
default: // I mean shouldn't be used, we assume default: // I mean shouldn't be used, we assume
return -1; return -1;
} }
@@ -177,6 +186,10 @@ char operator_to_char(Operator op) {
return '^'; return '^';
case OP_FACTORIAL: case OP_FACTORIAL:
return '!'; return '!';
case OP_START_PAR:
return '(';
case OP_END_PAR:
return ')';
default: default:
return EOF; return EOF;
} }

View File

@@ -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 // if is unary then take prefix bp and continue
// to the right, no need to allocate left side // to the right, no need to allocate left side
// because we just did and right 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); ASTNode *righ_side = parse_expr(slice, arena, rbp);
left_side->data.unary.val = righ_side; left_side->data.unary.val = righ_side;
return left_side;
} }
// Should check if is Integer or number
arrayslice_next(slice, left_side);
while (true) { while (true) {
// Second: Get next one and checn bp // 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; new_node->data.unary.val = left_side;
left_side = new_node; left_side = new_node;
continue;
} }
// check if it has infix or not, if not then error
uint8_t rbp = infix_rbp(operator); uint8_t rbp = infix_rbp(operator);
uint8_t lbp = infix_lbp(operator); uint8_t lbp = infix_lbp(operator);
// If lbp is LESS then stop recursion, if (rbp != 255 && lbp != 255) {
// we found the next smaller binding power
// or the one with more precedence // If lbp is LESS then stop recursion,
if (lbp < min_bp) { // we found the next smaller binding power
break; // or the one with more precedence
} if (lbp < min_bp) {
break;
}
// If NOT, then we continue wtching ahead // If NOT, then we continue wtching ahead
// for the next one but taking our current // for the next one but taking our current
// concern that is rbp of the current operator // concern that is rbp of the current operator
arrayslice_next(slice, NULL); arrayslice_next(slice, NULL);
ASTNode *right_side = parse_expr(slice, arena, rbp); ASTNode *right_side = parse_expr(slice, arena, rbp);
arena_ensure_capacity( arena_ensure_capacity(
arena,
sizeof(ASTNode),
alignof(ASTNode));
ASTNode *new_node = arena_unwrap_pointer(
arena_alloc(
arena, arena,
sizeof(ASTNode), sizeof(ASTNode),
alignof(ASTNode) alignof(ASTNode));
) ASTNode *new_node = arena_unwrap_pointer(
); arena_alloc(
*new_node = operator; arena,
sizeof(ASTNode),
alignof(ASTNode)
)
);
*new_node = operator;
new_node->data.binary.left = left_side; new_node->data.binary.left = left_side;
new_node->data.binary.right = right_side; new_node->data.binary.right = right_side;
left_side = new_node; left_side = new_node;
continue;
}
break;
} }
// Final: return left side // Final: return left side
return left_side; return left_side;
} }