From aa5ef0e6641203242d2e427445fcf21051768261 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Wed, 24 Dec 2025 22:01:16 +1100 Subject: [PATCH] Operator precedence I think --- src/parser.cpp | 108 ++++++++++++++++++++++++++++++++++++++++++++----- src/parser.h | 6 ++- 2 files changed, 104 insertions(+), 10 deletions(-) diff --git a/src/parser.cpp b/src/parser.cpp index a7a6abe..fe3c0aa 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -743,6 +743,94 @@ namespace Solstice { return SolNodeType::Identifier; } + int Parser::getPrecedence(std::string token) { + if (token == "*" || token == "/") return 2; + if (token == "+" || token == "-") return 1; + return 0; + } + + SolNode Parser::parsePrimary() { + auto tokenopt = consume(); + if (!tokenopt) { + std::cout << "Unexpected end of input\n"; + exit(1); + } + std::string token = tokenopt.value(); + SolNodeType type = getNodeType(token); + + if (type == SolNodeType::Value) { + SolNode node(SolNodeType::Value); + switch (getDataType(token)) { + case SolDataType::Int: node.setValue((int64_t) std::stoll(token)); break; + case SolDataType::Double: node.setValue(std::stod(token)); break; + case SolDataType::String: node.setValue(token.substr(1, token.size() - 2)); break; + case SolDataType::Char: node.setValue(token[1]); break; + case SolDataType::Bool: node.setValue(token == "true"); break; + default: break; + } + return node; + } + + if (type == SolNodeType::Identifier) { + SolNode idNode(SolNodeType::Identifier); + idNode.outputId = token; + if (peek().value_or("") == "(") { + consume(); // ( + SolNode fnCallNode(SolNodeType::FunctionCall); + fnCallNode.addNode(idNode); + + std::vector tokens; + size_t brackets = 1; + while (auto t = consume()) { + if (t.value() == "(") brackets++; + if (t.value() == ")") brackets--; + if (brackets == 0) break; + tokens.push_back(t.value()); + } + auto args = Parser(tokens).parse(); + for(auto& child : args.children) fnCallNode.addNode(child); + return fnCallNode; + } + return idNode; + } + + if (type == SolNodeType::BracketStart) { + std::vector tokens; + size_t brackets = 1; + while (auto t = consume()) { + if (t.value() == "(") brackets++; + if (t.value() == ")") brackets--; + if (brackets == 0) break; + tokens.push_back(t.value()); + } + auto inner = Parser(tokens).parse(); + if (inner.children.size() > 0) return inner.children[0]; + return SolNode(SolNodeType::None); + } + + std::cout << "Unexpected token in expression: " << token << "\n"; + exit(1); + } + + SolNode Parser::parseExpression(int minPrec) { + SolNode lhs = parsePrimary(); + while(true) { + auto opOpt = peek(); + if (!opOpt) break; + std::string op = opOpt.value(); + int prec = getPrecedence(op); + if (prec < minPrec) break; + + consume(); + SolNode rhs = parseExpression(prec + 1); + SolNode newNode(getNodeType(op)); + newNode.addNode(lhs); + newNode.addNode(rhs); + lhs = newNode; + } + return lhs; + } + SolNode Parser::parse() { current = 0; size = tokensToParse.size(); @@ -790,17 +878,19 @@ namespace Solstice { case SolNodeType::Multiply: case SolNodeType::Divide: { - SolNode addNode(getNodeType(token)); - addNode.addNode(rootNode.children.back()); - rootNode.children.pop_back(); - auto tokenopt = consume(); - if (tokenopt) { - addNode.addNode(parseOneToken(tokenopt)); - } else { - std::cout << "FEED ME MORE TOKENS\n"; + SolNode opNode(getNodeType(token)); + if (rootNode.children.empty()) { + std::cout << "Expected operand before operator\n"; exit(1); } - rootNode.addNode(addNode); + opNode.addNode(rootNode.children.back()); + rootNode.children.pop_back(); + + // Parse RHS with higher precedence + SolNode rhs = parseExpression(getPrecedence(token) + 1); + opNode.addNode(rhs); + + rootNode.addNode(opNode); break; } case SolNodeType::Equal: diff --git a/src/parser.h b/src/parser.h index 453683c..41f91e7 100644 --- a/src/parser.h +++ b/src/parser.h @@ -109,7 +109,7 @@ namespace Solstice { size_t current; size_t size; - std::optional peek(int ahead = 1); + std::optional peek(int ahead = 0); std::optional consume(); bool isInt(std::string in); bool isDouble(std::string in); @@ -118,6 +118,10 @@ namespace Solstice { bool isBool(std::string in); SolDataType getDataType(std::string in); SolNodeType getNodeType(std::string in); + + SolNode parsePrimary(); + SolNode parseExpression(int minPrec); + int getPrecedence(std::string token); public: Parser(std::vector in);