refactor-lexer #11
@@ -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;
|
||||||
|
|
||||||
|
|||||||
13
src/lexer.c
13
src/lexer.c
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
78
src/parser.c
78
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
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user