Parse logical operators

This commit is contained in:
augustin64 2023-11-24 11:01:42 +01:00
parent b7dcca2d47
commit 76770b6ecc
3 changed files with 91 additions and 32 deletions

View File

@ -104,8 +104,9 @@ enum class NodeType {
Mult, // -> Unary * Term
Div, // -> Unary / Term
Mod, // -> Unary % Term
UnaryMinus, // -> -Unary
UnaryPlus, // -> +Unary
UnaryMinus, // -> - Unary
UnaryPlus, // -> + Unary
Neg, // -> ! Unary
Assignment, // -> Identifier = Expr
LIncr, // -> ++ParIdentifier
RIncr, // -> ParIdentifier++
@ -113,7 +114,15 @@ enum class NodeType {
RDecr, // -> ParIdentifier--
If, // -> If (Expr) Instruction
IfElse, // -> If (Expr) Instruction Else Instruction
Bloc // -> { Prog }
Bloc, // -> { Prog }
Lt, // -> Sum < Comp
Gt, // -> Sum > Comp
Leq, // -> Sum <= Comp
Geq, // -> Sum >= Comp
Eq, // -> Sum == Comp
Neq, // -> Sum != Comp
Land, // -> Sum && Comp
Lor // -> Sum || Comp
};
struct InnerNode;

View File

@ -184,6 +184,9 @@ EvalResult eval(Node &ast, Memory &memory) {
return value;
}
default: {
throw RuntimeError("Not Implemented", node.pos);
}
}
}
else {

View File

@ -15,7 +15,8 @@ CodePosition null_pos = {
const char* _node_names[] = {
"Prog", "Epsilon", "AssignedDeclaration", "Declaration", "Plus", "Minus", "Mult", "Div", "Mod",
"UnaryMinus", "UnaryPlus", "Assignment", "LIncr", "RIncr", "LDecr", "RDecr", "If", "IfElse", "Bloc"
"UnaryMinus", "UnaryPlus", "Neg", "Assignment", "LIncr", "RIncr", "LDecr", "RDecr", "If", "IfElse",
"Bloc", "Lt", "Gt", "Leq", "Geq", "Eq", "Neq", "Land", "Lor"
};
void _debug_print_tree(const Node& node, int depth, const string& prefix) {
if (holds_alternative<InnerNode>(node)) {
@ -330,7 +331,52 @@ ParseReturn parse_expr(vector<Token> tokens) {
}
ParseReturn parse_comp(vector<Token> tokens) {
return parse_sum(tokens);
ParseReturn ret = parse_sum(tokens);
if (tokens.size() == 0)
return ret;
tokens = ret.tokens;
NodeType type;
switch (tokens.back().type) {
case TokenType::Equal:
type = NodeType::Eq;
break;
case TokenType::NotEqual:
type = NodeType::Neq;
break;
case TokenType::Lt:
type = NodeType::Lt;
break;
case TokenType::Gt:
type = NodeType::Gt;
break;
case TokenType::Leq:
type = NodeType::Leq;
break;
case TokenType::Geq:
type = NodeType::Geq;
break;
case TokenType::Land:
type = NodeType::Land;
break;
case TokenType::Lor:
type = NodeType::Lor;
break;
default:
return ret;
}
tokens.pop_back();
ParseReturn ret_comp = parse_comp(tokens);
InnerNode node = {
.type=type,
.children={ ret.node, ret_comp.node },
.pos=get_node_pos(ret_comp.node)
};
return {
.node=node,
.tokens=ret_comp.tokens
};
}
ParseReturn parse_sum(vector<Token> tokens) {
@ -452,13 +498,29 @@ ParseReturn parse_term(vector<Token> tokens) {
}
ParseReturn parse_unary(vector<Token> tokens) {
if (tokens.size() > 0 && tokens.back().type == TokenType::Minus) { //* Unary -> - Unary
if (tokens.size() > 0) {
NodeType type;
switch (tokens.back().type) {
case TokenType::Minus: //* Unary -> - Unary
type = NodeType::UnaryMinus;
break;
case TokenType::Plus: //* Unary -> + Unary
type = NodeType::UnaryPlus;
break;
case TokenType::Not: //* Unary -> ! Unary
type = NodeType::Neg;
break;
default:
type = NodeType::Epsilon; // No valid element found
}
if (type != NodeType::Epsilon) {
tokens.pop_back();
ParseReturn ret = parse_unary(tokens);
InnerNode node = {
.type=NodeType::UnaryMinus,
.type=type,
.children={ ret.node },
.pos=get_node_pos(ret.node)
};
@ -467,21 +529,6 @@ ParseReturn parse_unary(vector<Token> tokens) {
.tokens=ret.tokens
};
}
if (tokens.size() > 0 && tokens.back().type == TokenType::Plus) { //* Unary -> + Unary
tokens.pop_back();
ParseReturn ret = parse_unary(tokens);
InnerNode node = {
.type=NodeType::UnaryPlus,
.children={ ret.node },
.pos=get_node_pos(ret.node)
};
return {
.node=node,
.tokens=ret.tokens
};
}
//* Unary -> Val