From 20cbd79c56ecb6726ccbb9a5877f784c1402261b Mon Sep 17 00:00:00 2001 From: Kubat <mael.martin31@gmail.com> Date: Mon, 14 Feb 2022 09:46:20 +0100 Subject: [PATCH] WIP: Work a bit on the expression parsing --- src/Lib/Script/Ast/Parser/IrExpression.hh | 48 ++++++++++++++--------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/src/Lib/Script/Ast/Parser/IrExpression.hh b/src/Lib/Script/Ast/Parser/IrExpression.hh index e4caa0f4..0412c4b9 100644 --- a/src/Lib/Script/Ast/Parser/IrExpression.hh +++ b/src/Lib/Script/Ast/Parser/IrExpression.hh @@ -5,41 +5,53 @@ auto throwUnexpectedToken = [](const Token &tok) { tok.toString()); }; +auto createOpElement = []<typename IrT>(IrExpression *¤t, Token tok) -> IrT* { + return dynamic_cast<IrExpression *>(IrElement::create<IrT>( + nullptr, /* The parent, will be set later */ + IrT::getOpFromToken(tok), /* The type of operation (+,-,...) */ + std::move(nullptr), /* We leave the left empty for now */ + std::move(current) /* We add everything to the right */ + )); +}; + /* <|!!|> The left will be left empty (nullptr) */ -auto updateExprWithInfixOperator = [throwUnexpectedToken](IrExpression *¤t, - Token tok) -> void { +auto updateExprWithInfixOperator = [throwUnexpectedToken, createOpElement]( + IrExpression *¤t, Token tok) -> void +{ /* operation -> new current, add old into right */ if (current->isInfixOperator()) throwUnexpectedToken(tok); current = - (tok.isSimple(TOKEN_LIST_ARITHMETIC_OP)) - ? dynamic_cast<IrExpression *>( - IrElement::create<IrEArithmeticOp>(nullptr, IrEArithmeticOp::getOpFromToken(tok), - std::move(current), std::move(nullptr))) - : (tok.isSimple(TOKEN_LIST_LOGIC_OP)) - ? dynamic_cast<IrExpression *>(IrElement::create<IrELogicOp>( - nullptr, IrELogicOp::getOpFromToken(tok), std::move(current), std::move(nullptr))) - : (tok.isSimple(TOKEN_LIST_COMP_OP)) - ? dynamic_cast<IrExpression *>(IrElement::create<IrECompOp>( - nullptr, IrECompOp::getOpFromToken(tok), std::move(current), std::move(nullptr))) - : nullptr; + (tok.isSimple(TOKEN_LIST_ARITHMETIC_OP)) ? createOpElement<IrEArithmeticOp>(current, tok) + : (tok.isSimple(TOKEN_LIST_LOGIC_OP)) ? createOpElement<IrELogicOp>(current, tok) + : (tok.isSimple(TOKEN_LIST_COMP_OP)) ? createOpElement<IrECompOp>(current, tok) + : throw std::runtime_error("Can't create an infix operation from token " + tok.toString()); }; -auto updateExprWithConstExpr = [](IrExpression *¤t, Token tok) -> void { +auto updateLeft = []<typename IrT>(IrExpression *current, IrExpression *newLeft) -> void { + dynamic_cast<IrT *>(current)->left = newLeft; + newLeft->setParent(current); +}; + +auto updateExprWithConstExpr = [updateLeft](IrExpression *¤t, Token tok) -> void { IrExpression *newLeft = IrElement::create<IrEConstExpr>(current, tok); /* (... `op` <- currentExpression) newLeft -> currentExpression */ - if (current != nullptr) { + if (current != nullptr && current->left == nullptr) { switch (current->type()) { - case Type::CompOp: dynamic_cast<IrECompOp *>(current)->left = newLeft; return; - case Type::ArithmeticOp: dynamic_cast<IrEArithmeticOp *>(current)->left = newLeft; return; - case Type::LogicOp: dynamic_cast<IrELogicOp *>(current)->left = newLeft; return; + case Type::CompOp: updateLeft<IrECompOp>(current, newLeft); return; + case Type::ArithmeticOp: updateLeft<IrEArithmeticOp>(current, newLeft); return; + case Type::LogicOp: updateLeft<IrELogicOp>(current, newLeft); return; case Type::ConstExpr: case Type::Call: case Type::VariableRef: throw std::runtime_error("Invalid expression"); } } + /* Can be the case for `1 + 2 2` which is invalid */ + else if (current != nullptr && current->left != nullptr) + throw std::runtime_error("Unexpected token in expression parsing: " + tok.toString()); + /* newLeft -> currentExpression */ else current = newLeft; -- GitLab