precedence stuff yay!
This commit is contained in:
@@ -127,12 +127,13 @@ namespace Solstice {
|
|||||||
Node Parser::parseExpr(TT type) {
|
Node Parser::parseExpr(TT type) {
|
||||||
auto left = getPreviousNode(output);
|
auto left = getPreviousNode(output);
|
||||||
if (!left.has_value()) {
|
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));
|
Precedence precedence = getTokenPrecedence(Token(type));
|
||||||
auto right = parseOneNode(precedence);
|
auto right = parseOneNode(precedence);
|
||||||
if (!right.has_value()) {
|
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;
|
NodeType nodeType;
|
||||||
@@ -142,7 +143,19 @@ namespace Solstice {
|
|||||||
nodeType = tokToNodeType[type];
|
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() {
|
Node Parser::parseLiteral() {
|
||||||
@@ -171,10 +184,36 @@ namespace Solstice {
|
|||||||
return Node(*id);
|
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) {
|
Precedence Parser::getTokenPrecedence(const Token& token) {
|
||||||
static size_t braceCount = 0;
|
|
||||||
static size_t bracketCount = 0;
|
|
||||||
static size_t spikyBracketCount = 0;
|
|
||||||
switch (token.type) {
|
switch (token.type) {
|
||||||
case TT::OpenCurly: {
|
case TT::OpenCurly: {
|
||||||
braceCount++;
|
braceCount++;
|
||||||
@@ -244,7 +283,7 @@ namespace Solstice {
|
|||||||
if (!next.has_value()) {
|
if (!next.has_value()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
if (getTokenPrecedence(*next) >= precedence) {
|
if (getTokenPrecedence(*next) <= precedence) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
consume();
|
consume();
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ namespace Solstice {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum class Precedence {
|
enum class Precedence {
|
||||||
|
Root,
|
||||||
NewLine,
|
NewLine,
|
||||||
Identifier,
|
|
||||||
If,
|
If,
|
||||||
While,
|
While,
|
||||||
Compare,
|
Compare,
|
||||||
@@ -26,9 +26,10 @@ namespace Solstice {
|
|||||||
FunctionCall,
|
FunctionCall,
|
||||||
Add,
|
Add,
|
||||||
Multiply,
|
Multiply,
|
||||||
|
Identifier,
|
||||||
Other,
|
Other,
|
||||||
Root
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
extern std::unordered_map<TokenType, NodeType> tokToNodeType;
|
extern std::unordered_map<TokenType, NodeType> tokToNodeType;
|
||||||
|
|
||||||
@@ -57,6 +58,10 @@ namespace Solstice {
|
|||||||
|
|
||||||
size_t current = 0;
|
size_t current = 0;
|
||||||
|
|
||||||
|
size_t braceCount = 0;
|
||||||
|
size_t bracketCount = 0;
|
||||||
|
size_t spikyBracketCount = 0;
|
||||||
|
|
||||||
std::optional<Token> peek(int64_t ahead = 0);
|
std::optional<Token> peek(int64_t ahead = 0);
|
||||||
std::optional<Token> consume();
|
std::optional<Token> consume();
|
||||||
|
|
||||||
@@ -86,7 +91,8 @@ namespace Solstice {
|
|||||||
Node parseLiteral();
|
Node parseLiteral();
|
||||||
Node parseIdentifier();
|
Node parseIdentifier();
|
||||||
|
|
||||||
static Precedence getTokenPrecedence(const Token& token);
|
Precedence getTokenPrecedence(const Token& token);
|
||||||
|
Precedence getNodePrecedence(const Node& node);
|
||||||
|
|
||||||
// Returns false when finished
|
// Returns false when finished
|
||||||
std::optional<Node> parseOneNode(Precedence precedence = Precedence::Other);
|
std::optional<Node> parseOneNode(Precedence precedence = Precedence::Other);
|
||||||
|
|||||||
Reference in New Issue
Block a user