Skip to content
Extraits de code Groupes Projets
Vérifiée Valider 66fe5e7b rédigé par Kubat's avatar Kubat
Parcourir les fichiers

WIP: Parsing of expressions in progress

parent 7b07dfec
Aucune branche associée trouvée
Aucune étiquette associée trouvée
1 requête de fusion!25Draft: New Vivy module spec
......@@ -44,8 +44,14 @@ IrExpression::toString() const noexcept
assert(false && "Unreachable");
}
bool
IrExpression::isInfixOperator() const noexcept
{
return (type() == Type::CompOp) || (type() == Type::ArithmeticOp) || (type() == Type::LogicOp);
}
void
IrExpression::parse(std::vector<Token> *tokens)
IrExpression::parse(std::vector<Token> *argTokens)
{
#include "Parser/IrExpression.hh"
}
......
......@@ -6,6 +6,10 @@
namespace Vivy::Script
{
#define VIVY_IR_EXPRESSION(clazz) \
VIVY_IR_ELEMENT(clazz) \
friend class IrExpression;
class IrExpression : public IrElement {
VIVY_IR_ELEMENT(IrExpression)
......@@ -27,11 +31,12 @@ public:
void parse(std::vector<Token> *);
Type type() const noexcept;
bool isInfixOperator() const noexcept;
virtual IrType *innerType() const noexcept;
};
class IrEConstExpr : public IrExpression {
VIVY_IR_ELEMENT(IrEConstExpr)
VIVY_IR_EXPRESSION(IrEConstExpr)
IrEConstExpr(const Token &);
......@@ -56,7 +61,7 @@ public:
};
class IrECall : public IrExpression {
VIVY_IR_ELEMENT(IrECall)
VIVY_IR_EXPRESSION(IrECall)
IrFunction *callPtr = nullptr;
std::vector<IrExpression *> inArgs;
......@@ -69,7 +74,7 @@ public:
};
class IrECompOp : public IrExpression {
VIVY_IR_ELEMENT(IrECompOp)
VIVY_IR_EXPRESSION(IrECompOp)
public:
enum class OpType { LT, GT, LE, GE, EQ, NEQ };
......@@ -88,7 +93,7 @@ public:
};
class IrEArithmeticOp : public IrExpression {
VIVY_IR_ELEMENT(IrEArithmeticOp)
VIVY_IR_EXPRESSION(IrEArithmeticOp)
public:
enum class OpType { Add, Sub, Mul, Div, Mod };
......@@ -107,7 +112,7 @@ public:
};
class IrELogicOp : public IrExpression {
VIVY_IR_ELEMENT(IrELogicOp)
VIVY_IR_EXPRESSION(IrELogicOp)
public:
enum class OpType { And, Or, Xor };
......@@ -126,7 +131,7 @@ public:
};
class IrEVariableRef : public IrExpression {
VIVY_IR_ELEMENT(IrEVariableRef)
VIVY_IR_EXPRESSION(IrEVariableRef)
IrVariable *const referencedVariable;
std::vector<IrExpression *> indicies;
......
/* In: std::vector<Token>* tokens */
auto throwUnexpectedToken = [](const Token &tok) {
throw std::runtime_error("Unexpected token in location " + tok.location().toString() + ": " +
tok.toString());
};
auto updateExprWithConstExpr = [](IrExpression *&current, Token tok) -> void {
IrExpression *newLeft = IrElement::create<IrEConstExpr>(current, tok);
/* (... `op` <- currentExpression) newLeft -> currentExpression */
if (current != 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::ConstExpr:
case Type::Call:
case Type::VariableRef: throw std::runtime_error("Invalid expression");
}
}
/* newLeft -> currentExpression */
else
current = newLeft;
};
volatile ssize_t expressionScopeLevel = 0;
/*
** a + b + c + d + e ==> (e + (d + (c + (b + a))))
** first : simple
** find op, parse the next token
** parse tokens => new expr, take current, add to left
*/
auto parseNextExpression = [&expressionScopeLevel, updateExprWithConstExpr](
std::vector<Token> *tokens, auto &itSelf) -> IrExpression * {
const ssize_t expressionScopeLevelAtLaunchTime = expressionScopeLevel;
IrExpression *currentExpression = nullptr;
while (tokenListIsNotEmpty(tokens) &&
(expressionScopeLevelAtLaunchTime < expressionScopeLevel)) {
const std::optional<Token> maybeFirstToken = tokenListPeek(tokens);
if (!maybeFirstToken.has_value())
return nullptr;
const Token firstToken = getInnerTokenOpt(maybeFirstToken);
switch (firstToken.valueType()) {
case Token::Type::QNAME: {
// Function Call or Variable Ref
throw std::logic_error("QNAME not handled (call or var)");
break;
}
case Token::Type::COLORLIT:
case Token::Type::INTEGER:
case Token::Type::FLOATING:
case Token::Type::STRINGLIT: {
updateExprWithConstExpr(currentExpression, firstToken);
break;
}
case Token::Type::SIMPLE: {
if (firstToken.isSimple(TOKEN_TRUE) || firstToken.isSimple(TOKEN_FALSE)) {
updateExprWithConstExpr(currentExpression, firstToken);
}
else {
// operation -> new current, add old into right
}
break;
}
}
}
return currentExpression;
};
parseNextExpression(argTokens, parseNextExpression);
throw std::logic_error("Parser/IrExpression: Not implemented");
......@@ -28,6 +28,7 @@ auto parseNextInstruction = [&instructionScopeLevel](
auto &itSelf /* The lambda itself, for recursion */
) {
if (tokenListIsEmpty(tokens)) {
throw std::runtime_error("Implement void instruction");
/* Create a `return void` instruction */
}
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter