precedence stuff yay!

This commit is contained in:
2026-08-01 18:01:59 +10:00
parent 7df9f25119
commit 1866585af1
2 changed files with 55 additions and 10 deletions

View File

@@ -127,12 +127,13 @@ namespace Solstice {
Node Parser::parseExpr(TT type) {
auto left = getPreviousNode(output);
if (!left.has_value()) {
throw std::runtime_error("Expecting expression on left of '+'");
throw std::runtime_error("Expecting expression on left of expression");
}
Precedence leftPrec = getNodePrecedence(*left);
Precedence precedence = getTokenPrecedence(Token(type));
auto right = parseOneNode(precedence);
if (!right.has_value()) {
throw std::runtime_error("Expecting expression on right of '+'");
throw std::runtime_error("Expecting expression on right of expression");
}
NodeType nodeType;
@@ -142,7 +143,19 @@ namespace Solstice {
nodeType = tokToNodeType[type];
}
return Node(nodeType, {*left, *right});
if (leftPrec >= precedence) {
// enclose the left node inside this node
return Node(nodeType, {*left, *right});
} else {
// steal the right child of the left node and use it as our left value,
// then enclose ourself inside the left node
auto newLeft = left->children[1];
Node us{nodeType, {newLeft, *right}};
left->children[1] = us;
return *left;
}
}
Node Parser::parseLiteral() {
@@ -171,10 +184,36 @@ namespace Solstice {
return Node(*id);
}
Precedence Parser::getNodePrecedence(const Node& node) {
switch (node.type) {
case NodeType::Root:
return Precedence::Root;
case NodeType::Literal:
case NodeType::Identifier:
return Precedence::Identifier;
case NodeType::FunctionBind:
case NodeType::Bind:
case NodeType::Set:
return Precedence::Set;
case NodeType::Lambda:
case NodeType::FunctionCall:
return Precedence::Identifier;
case NodeType::Add:
case NodeType::Subtract:
return Precedence::Add;
case NodeType::Multiply:
case NodeType::Divide:
return Precedence::Multiply;
case NodeType::Equal:
case NodeType::NotEqual:
case NodeType::GreaterThan:
case NodeType::LesserThan:
return Precedence::Compare;
}
}
Precedence Parser::getTokenPrecedence(const Token& token) {
static size_t braceCount = 0;
static size_t bracketCount = 0;
static size_t spikyBracketCount = 0;
switch (token.type) {
case TT::OpenCurly: {
braceCount++;
@@ -244,7 +283,7 @@ namespace Solstice {
if (!next.has_value()) {
return {};
}
if (getTokenPrecedence(*next) >= precedence) {
if (getTokenPrecedence(*next) <= precedence) {
return {};
}
consume();