diff --git a/src/Lib/Script/Ast/IrElement.cc b/src/Lib/Script/Ast/IrElement.cc
index 94dfb5f3926f6721b80335acd2597b8690cc0fd6..155957c2a3c3179802c082221ccf1d41a732309b 100644
--- a/src/Lib/Script/Ast/IrElement.cc
+++ b/src/Lib/Script/Ast/IrElement.cc
@@ -6,6 +6,13 @@ namespace Vivy::Script
 {
 IrElement::IrElement(IrElement *p) noexcept { setParent(p); }
 
+void
+IrElement::throwUnexpectedToken(const Token &tok) const
+{
+    throw std::runtime_error("Unexpected token in location " + tok.location().toString() + ": " +
+                             tok.toString());
+}
+
 IrElement::~IrElement() noexcept
 {
     std::erase_if(childElements, [this](IrElement *child) noexcept -> bool {
diff --git a/src/Lib/Script/Ast/IrElement.hh b/src/Lib/Script/Ast/IrElement.hh
index 00503dcf7aec2fab5638ad7d6c28fd27b8ff3ec2..4e0e13fce1b3628d6487a86bd6500aa793454d2d 100644
--- a/src/Lib/Script/Ast/IrElement.hh
+++ b/src/Lib/Script/Ast/IrElement.hh
@@ -116,6 +116,8 @@ protected:
     void detachElementFromParent() noexcept;
     void addChild(IrElement *) noexcept;
 
+    void throwUnexpectedToken(const Token &tok) const;
+
 public:
     virtual ~IrElement() noexcept;
 
diff --git a/src/Lib/Script/Ast/IrExpression.cc b/src/Lib/Script/Ast/IrExpression.cc
index a2b1faf01cf8fd87ccc0a52c112cedbd840ae6bc..8aa191c4d718408d07abe7bcae57aacf01ac8b00 100644
--- a/src/Lib/Script/Ast/IrExpression.cc
+++ b/src/Lib/Script/Ast/IrExpression.cc
@@ -242,8 +242,20 @@ IrECall::args() const noexcept
 }
 }
 
+/*
+** IrECompOp
+*/
+
 namespace Vivy::Script
 {
+IrECompOp::IrECompOp(OpType type, IrExpression *&&leftA, IrExpression *&&rightA) noexcept
+    : IrExpression(nullptr, Type::ArithmeticOp)
+    , selfOpType(type)
+    , left(leftA)
+    , right(rightA)
+{
+}
+
 std::string
 IrECompOp::toString() const noexcept
 {
@@ -251,8 +263,21 @@ IrECompOp::toString() const noexcept
 }
 }
 
+/*
+** IrEArithmeticOp
+*/
+
 namespace Vivy::Script
 {
+IrEArithmeticOp::IrEArithmeticOp(OpType type, IrExpression *&&leftA,
+                                 IrExpression *&&rightA) noexcept
+    : IrExpression(nullptr, Type::ArithmeticOp)
+    , selfOpType(type)
+    , left(leftA)
+    , right(rightA)
+{
+}
+
 std::string
 IrEArithmeticOp::toString() const noexcept
 {
@@ -260,8 +285,20 @@ IrEArithmeticOp::toString() const noexcept
 }
 }
 
+/*
+** IrELogicOp
+*/
+
 namespace Vivy::Script
 {
+IrELogicOp::IrELogicOp(OpType type, IrExpression *&&leftA, IrExpression *&&rightA) noexcept
+    : IrExpression(nullptr, Type::LogicOp)
+    , selfOpType(type)
+    , left(leftA)
+    , right(rightA)
+{
+}
+
 std::string
 IrELogicOp::toString() const noexcept
 {
@@ -269,6 +306,10 @@ IrELogicOp::toString() const noexcept
 }
 }
 
+/*
+** Free functions
+*/
+
 namespace Vivy::Script
 {
 std::string
@@ -307,6 +348,10 @@ toString(IrECompOp::OpType op) noexcept
 }
 }
 
+/*
+** Binary expressions' type from tokens
+*/
+
 namespace Vivy::Script
 {
 IrELogicOp::OpType
diff --git a/src/Lib/Script/Ast/IrExpression.hh b/src/Lib/Script/Ast/IrExpression.hh
index 36458dd7c61aaf9c2becb251e665dce26e17e02d..c2ff6f9d72f0d69215d15645fc4f7e06d7e55bf1 100644
--- a/src/Lib/Script/Ast/IrExpression.hh
+++ b/src/Lib/Script/Ast/IrExpression.hh
@@ -20,6 +20,35 @@ private:
     Type selfType;
     IrType *selfInnerType = nullptr;
 
+    /*
+    ** Helper for the parser, create a binary expression, insert the last expression at
+    ** the right and update the current expression pointer.
+    */
+
+    template <typename IrT> IrExpression *createOpElement(IrExpression *&current, Token tok)
+    {
+        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   */
+                                   ));
+    }
+
+    /*
+    ** Helper for the parser, update the left expression of a binary expression or throw
+    ** an error if there was already somthing.
+    */
+
+    template <typename IrT> void updateLeft(IrExpression *current, IrExpression *newLeft, Token tok)
+    {
+        IrT *typpedCurrent = dynamic_cast<IrT *>(current);
+        if (typpedCurrent->left != nullptr)
+            throw std::runtime_error("Unexpected token in expression parsing: " + tok.toString());
+        typpedCurrent->left = newLeft;
+        newLeft->setParent(current);
+    }
+
 protected:
     IrExpression(IrElement *p, Type) noexcept;
 
diff --git a/src/Lib/Script/Ast/Parser/IrExpression.hh b/src/Lib/Script/Ast/Parser/IrExpression.hh
index 8713a3021628da8a991c70a4ca70ea0399fcb74b..953f2592e209bdb8fa25de7f7fd98768d014edf8 100644
--- a/src/Lib/Script/Ast/Parser/IrExpression.hh
+++ b/src/Lib/Script/Ast/Parser/IrExpression.hh
@@ -5,47 +5,31 @@ auto throwUnexpectedToken = [](const Token &tok) {
                              tok.toString());
 };
 
-auto createOpElement = []<typename IrT>(IrExpression *&current, 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, createOpElement](
-    IrExpression *&current, Token tok) -> void
-{
+auto updateExprWithInfixOperator = [this, throwUnexpectedToken](IrExpression *&current,
+                                                                Token tok) -> void {
     /* operation -> new current, add old into right */
     if (current->isInfixOperator())
         throwUnexpectedToken(tok);
 
-    current =
-        (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 updateLeft = []<typename IrT>(IrExpression *current, IrExpression *newLeft) -> void {
-    IrT *typpedCurrent = dynamic_cast<IrT *>(current);
-    if (typpedCurrent->left != nullptr)
-        throw std::runtime_error("Unexpected token in expression parsing: " + tok.toString());
-    typpedCurrent->left = newLeft;
-    newLeft->setParent(current);
+    current = (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 = [updateLeft](IrExpression *&current, Token tok) -> void {
+auto updateExprWithConstExpr = [this](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: return <IrECompOp>(current, newLeft);
-        case Type::ArithmeticOp: return updateLeft<IrEArithmeticOp>(current, newLeft);
-        case Type::LogicOp: return updateLeft<IrELogicOp>(current, newLeft);
+        case Type::CompOp: return updateLeft<IrECompOp>(current, newLeft, tok);
+        case Type::ArithmeticOp: return updateLeft<IrEArithmeticOp>(current, newLeft, tok);
+        case Type::LogicOp: return updateLeft<IrELogicOp>(current, newLeft, tok);
         case Type::ConstExpr:
         case Type::Call:
         case Type::VariableRef: throw std::runtime_error("Invalid expression");