From c3b1855d1252a212b5867c04d4fc34e07bb85494 Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Fri, 11 Feb 2022 14:09:49 +0100
Subject: [PATCH] WIP: Continue the implementation of the IrType

---
 src/Lib/Script/Ast/IrType.cc | 83 ++++++++++++++++++++++++++++++++++--
 src/Lib/Script/Ast/IrType.hh | 29 ++++++++++---
 2 files changed, 103 insertions(+), 9 deletions(-)

diff --git a/src/Lib/Script/Ast/IrType.cc b/src/Lib/Script/Ast/IrType.cc
index fc45e61e..23e8b6df 100644
--- a/src/Lib/Script/Ast/IrType.cc
+++ b/src/Lib/Script/Ast/IrType.cc
@@ -26,6 +26,35 @@ IrType::~IrType() noexcept {}
 
 namespace Vivy::Script
 {
+IrTAss::IrTAss(const Token &name)
+{
+    setSelfInnerTypeFromToken(name);
+}
+
+IrTAss::IrTAss(const AssType type, unsigned int size) noexcept
+    : selfInnerType(type)
+    , selfArraySize(size)
+{
+}
+
+IrTAss::IrTAss(const AssType type) noexcept
+    : AssType(type, 1)
+{
+}
+
+void
+IrTAss::setSelfInnerTypeFromToken(const Token &name)
+ {
+    name.assertType(Token::Type::SIMPLE);
+    if (name.isSimple(TOKEN_LINE)) {
+        selfInnerType = IrType::AssType::Line;
+    } else if (name.isSimple(TOKEN_SYLLABE)) {
+        selfInnerType = IrType::AssType::Syllabe;
+    } else {
+        throw std::logic_error("IrTPrimitive unexpected token " + name.toString());
+    }
+ }
+
 IrType::Type
 IrTAss::type() const noexcept
 {
@@ -41,7 +70,13 @@ IrTAss::innerType() const noexcept
 unsigned int
 IrTAss::innerTypeCount() const noexcept
 {
-    return selfArraySize;
+    /* 0 is same as 1, it's not an array! */
+    const unsigned int ret = std::reduce(
+        std::execution::seq,
+        std::begin(arraySizes), std::end(arraySizes), 1,
+        [](unsigned int a, unsigned int b) noexcept -> unsigned int { return a * b; }
+    );
+    return ret <= 1 ? 1 : ret;
 }
 
 std::string
@@ -50,6 +85,28 @@ IrTAss::toString() const noexcept
     return "IrTAss";
 }
 
+bool IrTAss::isArray() const
+{
+    return selfArraySize >= 2;
+}
+
+unsigned int IrTAss::getArrayDimensions() const
+{
+    isArray() ? selfArraySize : 0;
+}
+
+unsigned int IrTAss::getArrayDimensionAt(unsigned int level) const
+{
+    return level >= selfArraySize ? 0 : arraySizes.at(level);
+}
+
+void IrTAss::assertInnerType(AssType type) const
+{
+    if (innerType() != t) {
+        throw std::runtime_error("Expected inner type " + std::to_string(static_cast<int>(t)) + " but was type " + std::to_string(static_cast<int>(innerType())));
+    }
+}
+
 void
 IrTAss::parse(std::vector<Token> *)
 {
@@ -148,11 +205,31 @@ IrTPrimitive::innerType() const noexcept
     return selfInnerType;
 }
 
+bool IrTPrimitive::isArray() const
+{
+    return selfArraySize >= 2;
+}
+
+unsigned int IrTPrimitive::getArrayDimensions() const
+{
+    isArray() ? selfArraySize : 0;
+}
+
+unsigned int IrTPrimitive::getArrayDimensionAt(unsigned int level) const
+{
+    return level >= selfArraySize ? 0 : arraySizes.at(level);
+}
+
 unsigned int
-IrTPrimitive::innerTypeCount() const noexcept
+IrTAss::innerTypeCount() const noexcept
 {
     /* 0 is same as 1, it's not an array! */
-    return selfArraySize <= 1 ? 1 : selfArraySize;
+    const unsigned int ret = std::reduce(
+        std::execution::seq,
+        std::begin(arraySizes), std::end(arraySizes), 1,
+        [](unsigned int a, unsigned int b) noexcept -> unsigned int { return a * b; }
+    );
+    return ret <= 1 ? 1 : ret;
 }
 
 std::string
diff --git a/src/Lib/Script/Ast/IrType.hh b/src/Lib/Script/Ast/IrType.hh
index f3b80941..24497e12 100644
--- a/src/Lib/Script/Ast/IrType.hh
+++ b/src/Lib/Script/Ast/IrType.hh
@@ -23,13 +23,26 @@ class IrTAss final : public IrType {
     VIVY_IR_ELEMENT(IrTAss)
 
     AssType selfType;
-    unsigned int selfArraySize = 1; /* One for no array! */
+    unsigned int selfArraySize = 1;
+    std::vector<unsigned int> arraySizes = { 1 };
+
+    IrTAss(const Token &);
+    IrTAss(const AssType) noexcept;
+    IrTAss(const AssType, unsigned int) noexcept;
+
+    void setSelfInnerTypeFromToken(const Token &name);
 
 public:
     Type type() const noexcept override;
     AssType innerType() const noexcept;
     unsigned int innerTypeCount() const noexcept;
 
+    void assertInnerType(AssType) const;
+
+    bool isArray() const;
+    unsigned int getArrayDimensions() const;
+    unsigned int getArrayDimensionAt(unsigned int level) const;
+
     std::string toString() const noexcept override;
     void parse(std::vector<Token> *) override;
 };
@@ -37,7 +50,7 @@ public:
 class IrTOption final : public IrType {
     VIVY_IR_ELEMENT(IrTOption)
 
-    IrOption *selfInnerOption;
+    IrOption *selfInnerOption = nullptr;
 
 public:
     Type type() const noexcept override;
@@ -51,7 +64,7 @@ class IrTPrimitive final : public IrType {
     VIVY_IR_ELEMENT(IrTPrimitive)
 
     PrimitiveType selfInnerType;
-    unsigned int selfArraySize;
+    unsigned int selfArraySize = 1;
     std::vector<unsigned int> arraySizes = { 1 };
 
     IrTPrimitive(const Token &);
@@ -67,24 +80,28 @@ public:
 
     void assertInnerType(PrimitiveType) const;
 
+    bool isArray() const;
+    unsigned int getArrayDimensions() const;
+    unsigned int getArrayDimensionAt(unsigned int level) const;
+
     std::string toString() const noexcept override;
     void parse(std::vector<Token> *) override;
 };
 
 [[maybe_unused]] static bool
-operator==(const ::Vivy::Script::IrTAss &a, const ::Vivy::Script::IrTAss &b)
+operator==(const ::Vivy::Script::IrTAss &a, const ::Vivy::Script::IrTAss &b) noexcept
 {
     return (a.innerType() == b.innerType()) && (a.innerTypeCount() == b.innerTypeCount());
 }
 
 [[maybe_unused]] static bool
-operator==(const ::Vivy::Script::IrTPrimitive &a, const ::Vivy::Script::IrTPrimitive &b)
+operator==(const ::Vivy::Script::IrTPrimitive &a, const ::Vivy::Script::IrTPrimitive &b) noexcept
 {
     return (a.innerType() == b.innerType()) && (a.innerTypeCount() == b.innerTypeCount());
 }
 
 [[maybe_unused]] static bool
-operator==(const ::Vivy::Script::IrType &a, const ::Vivy::Script::IrType &b)
+operator==(const ::Vivy::Script::IrType &a, const ::Vivy::Script::IrType &b) noexcept
 {
     if (a.type() != b.type())
         return false;
-- 
GitLab