From ad6c4a80ce2d1bd3f4ebf40c7c9a912c0def48a6 Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Thu, 10 Feb 2022 23:29:55 +0100
Subject: [PATCH] PARSER: IrOption is Ok modulo type and expression parsing

---
 src/Lib/Script/Ast/IrElement.cc    |  5 +----
 src/Lib/Script/Ast/IrExpression.cc | 12 ++++++++++++
 src/Lib/Script/Ast/IrExpression.hh |  5 +++++
 src/Lib/Script/Ast/IrOption.cc     | 22 ++++++++++++++++------
 src/Lib/Script/Ast/IrType.cc       |  5 +++++
 src/Lib/Script/Ast/IrType.hh       |  2 ++
 6 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/src/Lib/Script/Ast/IrElement.cc b/src/Lib/Script/Ast/IrElement.cc
index 3793c8c1..94dfb5f3 100644
--- a/src/Lib/Script/Ast/IrElement.cc
+++ b/src/Lib/Script/Ast/IrElement.cc
@@ -4,10 +4,7 @@
 
 namespace Vivy::Script
 {
-IrElement::IrElement(IrElement *p) noexcept
-    : parentElement(p != nullptr ? p : this)
-{
-}
+IrElement::IrElement(IrElement *p) noexcept { setParent(p); }
 
 IrElement::~IrElement() noexcept
 {
diff --git a/src/Lib/Script/Ast/IrExpression.cc b/src/Lib/Script/Ast/IrExpression.cc
index b47559e6..1d519fb1 100644
--- a/src/Lib/Script/Ast/IrExpression.cc
+++ b/src/Lib/Script/Ast/IrExpression.cc
@@ -7,6 +7,12 @@
 
 namespace Vivy::Script
 {
+IrExpression::IrExpression(IrElement *p, Type type) noexcept
+    : IrElement(p)
+    , selfType(type)
+{
+}
+
 std::string
 IrExpression::toString() const noexcept
 {
@@ -58,6 +64,12 @@ IrEVariableRef::parse(std::vector<Token> *)
 
 namespace Vivy::Script
 {
+IrEConstExpr::IrEConstExpr(const Token &singleElement)
+    : IrExpression(nullptr, Type::ConstExpr)
+{
+    throw std::logic_error("IrEConstExpr " + singleElement.toString());
+}
+
 std::string
 IrEConstExpr::toString() const noexcept
 {
diff --git a/src/Lib/Script/Ast/IrExpression.hh b/src/Lib/Script/Ast/IrExpression.hh
index 5b49cb58..9261515b 100644
--- a/src/Lib/Script/Ast/IrExpression.hh
+++ b/src/Lib/Script/Ast/IrExpression.hh
@@ -14,6 +14,9 @@ private:
     Type selfType;
     IrType *selfInnerType = nullptr;
 
+protected:
+    IrExpression(IrElement *p, Type) noexcept;
+
 public:
     std::string toString() const noexcept override;
     void parse(std::vector<Token> *) override;
@@ -25,6 +28,8 @@ public:
 class IrEConstExpr : public IrExpression {
     VIVY_IR_ELEMENT(IrEConstExpr)
 
+    IrEConstExpr(const Token &);
+
 public:
     std::string toString() const noexcept override;
     void parse(std::vector<Token> *) override;
diff --git a/src/Lib/Script/Ast/IrOption.cc b/src/Lib/Script/Ast/IrOption.cc
index 78aec697..5d4dfcaa 100644
--- a/src/Lib/Script/Ast/IrOption.cc
+++ b/src/Lib/Script/Ast/IrOption.cc
@@ -1,4 +1,6 @@
 #include "IrOption.hh"
+#include "IrExpression.hh"
+#include "IrType.hh"
 #include "Lib/Script/FrontEnd/Lexer.hh"
 
 namespace Vivy::Script
@@ -89,6 +91,8 @@ IrOption::match(const std::vector<IrOption *> &others) const noexcept
 void
 IrOption::parse(std::vector<Token> *tokens)
 {
+    IrModule *sourceModule = parent();
+
     const Token firstDeclToken = getInnerTokenOpt(tokenListPop(tokens));
     firstDeclToken.assertTypeSimple(TOKEN_OPTION);
 
@@ -112,13 +116,19 @@ IrOption::parse(std::vector<Token> *tokens)
         getInnerTokenOpt(tokenListPop(tokens)).assertTypeSimple(TOKEN_ASSIGN);
         const Token defaultValueToken = getInnerTokenOpt(tokenListPop(tokens));
 
-        std::cerr << "Found option: " << shapeName.toStdString() << "."
-                  << fieldNameToken.asQName().toStdString() << " : "
-                  << typeNameToken.asSimple().toStdString() << " = " << defaultValueToken.toString()
-                  << ";\n";
+        IrEConstExpr *defaultValue = IrElement::create<IrEConstExpr>(this, defaultValueToken);
+        IrType *optionType         = IrElement::create<IrTPrimitive>(this, typeNameToken);
+
+        const ShapeElement::Content content = {
+            .fieldName    = fieldNameToken.asQName(),
+            .type         = optionType,
+            .defaultValue = defaultValue,
+        };
+
+        addShape(sourceModule, content);
 
-        const Token continuationToken = getInnerTokenOpt(tokenListPop(tokens));
-        if (continuationToken.isSimple(TOKEN_COMMA))
+        if (const Token continuationToken = getInnerTokenOpt(tokenListPop(tokens));
+            continuationToken.isSimple(TOKEN_COMMA))
             continue;
         else if (continuationToken.isSimple(TOKEN_CURLY_BRACKET_RIGHT))
             break;
diff --git a/src/Lib/Script/Ast/IrType.cc b/src/Lib/Script/Ast/IrType.cc
index 71138e37..009a1f0e 100644
--- a/src/Lib/Script/Ast/IrType.cc
+++ b/src/Lib/Script/Ast/IrType.cc
@@ -78,6 +78,11 @@ IrTOption::parse(std::vector<Token> *)
 
 namespace Vivy::Script
 {
+IrTPrimitive::IrTPrimitive(const Token &name)
+{
+    throw std::logic_error("IrTPrimitive " + name.toString());
+}
+
 IrType::Type
 IrTPrimitive::type() const noexcept
 {
diff --git a/src/Lib/Script/Ast/IrType.hh b/src/Lib/Script/Ast/IrType.hh
index ef0da35d..d74b6025 100644
--- a/src/Lib/Script/Ast/IrType.hh
+++ b/src/Lib/Script/Ast/IrType.hh
@@ -53,6 +53,8 @@ class IrTPrimitive : public IrType {
     PrimitiveType selfInnerType;
     unsigned int selfArraySize;
 
+    IrTPrimitive(const Token &);
+
 public:
     Type type() const noexcept override;
     PrimitiveType innerType() const noexcept;
-- 
GitLab