refactor-lexer #11

Merged
laentropia merged 6 commits from refactor-lexer into main 2026-05-12 20:08:39 -06:00
5 changed files with 57 additions and 11 deletions
Showing only changes of commit 59f99059bb - Show all commits

View File

@@ -10,6 +10,7 @@
typedef enum { typedef enum {
NODE_INTEGER, NODE_INTEGER,
NODE_BINARY_OP, NODE_BINARY_OP,
NODE_UNARY_OP,
} ASTNodeType; } ASTNodeType;
// For classify operators // For classify operators
@@ -17,7 +18,8 @@ typedef enum {
OP_ADD, OP_ADD,
OP_SUB, OP_SUB,
OP_MUL, OP_MUL,
OP_DIV OP_DIV,
OP_POW,
} Operator; } Operator;
typedef enum { typedef enum {
@@ -26,8 +28,6 @@ typedef enum {
LEXER_FAILED_NUMBER_CONVERSION, LEXER_FAILED_NUMBER_CONVERSION,
LEXER_NOT_RECOGNIZED_SYMBOL, LEXER_NOT_RECOGNIZED_SYMBOL,
LEXER_EMPTY_INPUT, LEXER_EMPTY_INPUT,
LEXER_NULL_ARG,
LEXER_WRONG_SYNTAX,
LEXER_BUF_OVERFLOW, LEXER_BUF_OVERFLOW,
} LexerErr; } LexerErr;
@@ -41,6 +41,10 @@ typedef struct ASTNode {
struct ASTNode *right; struct ASTNode *right;
Operator op; Operator op;
} binary; } binary;
struct {
struct ASTNode *val;
Operator op;
} unary;
} data; } data;
} ASTNode; } ASTNode;

View File

@@ -32,8 +32,10 @@ typedef struct {
ASTNode *nud(ArraySlice *slice); ASTNode *nud(ArraySlice *slice);
ASTNode *led(ArraySlice *slice, size_t right_precedence); ASTNode *led(ArraySlice *slice, size_t right_precedence);
uint8_t node_lbp(ASTNode node); uint8_t prefix_lbp(ASTNode node);
uint8_t node_rbp(ASTNode node); uint8_t prefix_rbp(ASTNode node);
uint8_t infix_lbp(ASTNode node);
uint8_t infix_rbp(ASTNode node);
ParseResult parse(TokenizeResult tokens); ParseResult parse(TokenizeResult tokens);
ASTNode *parse_expr(ArraySlice *slice, Arena *arena, uint8_t min_bp); ASTNode *parse_expr(ArraySlice *slice, Arena *arena, uint8_t min_bp);

View File

@@ -3,6 +3,7 @@
#include "lexer.h" #include "lexer.h"
#include "parser.h" #include "parser.h"
#include <stdint.h> #include <stdint.h>
#include <math.h>
int64_t evaluate_tree(ASTNode *tree) { int64_t evaluate_tree(ASTNode *tree) {
@@ -20,7 +21,8 @@ int64_t evaluate_tree(ASTNode *tree) {
return evaluate_tree(left) * evaluate_tree(right); return evaluate_tree(left) * evaluate_tree(right);
case OP_DIV: case OP_DIV:
return evaluate_tree(left) / evaluate_tree(right); return evaluate_tree(left) / evaluate_tree(right);
case OP_POW:
return pow(evaluate_tree(left), evaluate_tree(right));
} }
} }

View File

@@ -131,6 +131,7 @@ bool isoperator(int c) {
case '-': case '-':
case '/': case '/':
case '*': case '*':
case '^':
return true; return true;
default: default:
return false; return false;
@@ -151,6 +152,9 @@ Operator char_to_operator(int c) {
case '/': case '/':
return OP_DIV; return OP_DIV;
break; break;
case '^':
return OP_POW;
break;
default: // I mean shouldn't be used, we assume default: // I mean shouldn't be used, we assume
return -1; return -1;
} }
@@ -166,5 +170,7 @@ char operator_to_char(Operator op) {
return '*'; return '*';
case OP_DIV: case OP_DIV:
return '/'; return '/';
case OP_POW:
return '^';
} }
} }

View File

@@ -6,7 +6,21 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
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) { if (node.type == NODE_INTEGER) {
return 0; return 0;
} }
@@ -19,12 +33,14 @@ uint8_t node_lbp(ASTNode node) {
case OP_DIV: case OP_DIV:
case OP_MUL: case OP_MUL:
return 20; return 20;
case OP_POW:
return 31;
default: default:
return 0; return 0;
} }
} }
uint8_t node_rbp(ASTNode node) { uint8_t infix_rbp(ASTNode node) {
if (node.type == NODE_INTEGER) { if (node.type == NODE_INTEGER) {
return 0; return 0;
} }
@@ -37,6 +53,8 @@ uint8_t node_rbp(ASTNode node) {
case OP_DIV: case OP_DIV:
case OP_MUL: case OP_MUL:
return 21; return 21;
case OP_POW:
return 30;
default: default:
return 0; return 0;
} }
@@ -53,12 +71,14 @@ ParseResult parse(TokenizeResult tokens) {
} }
ASTNode *parse_expr(ArraySlice *slice, Arena *arena, uint8_t min_bp) { ASTNode *parse_expr(ArraySlice *slice, Arena *arena, uint8_t min_bp) {
// First: Consume a first number
arena_ensure_capacity( arena_ensure_capacity(
arena, arena,
sizeof(ASTNode), sizeof(ASTNode),
alignof(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( ASTNode *left_side = arena_unwrap_pointer(
arena_alloc( arena_alloc(
arena, 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); arrayslice_next(slice, left_side);
while (true) { while (true) {
// Second: Get next one and checn bp
if (!arrayslice_is_valid(slice)) { if (!arrayslice_is_valid(slice)) {
break; break;
} }
ASTNode operator; ASTNode operator;
// Here should chekc if is operator not some bs
// Third, get operator and binding powers
arrayslice_peek(slice, &operator); arrayslice_peek(slice, &operator);
uint8_t rbp = node_rbp(operator); uint8_t rbp = infix_rbp(operator);
uint8_t lbp = node_lbp(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) { if (lbp < min_bp) {
break; 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); arrayslice_next(slice, NULL);
ASTNode *right_side = parse_expr(slice, arena, rbp); 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; return left_side;
} }