From 8f99dc3ddcd87ea0ed3457aaa4b4c302e715bf05 Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Tue, 22 Feb 2022 21:24:49 +0100
Subject: [PATCH] SCRIPT: Add an IrScope that will reference things accessible
 in the current scope

The IrExpression instances hold a pointer to their parent scope.

The IrRoot holds a global scope. In the future instruction blocks,
functions and jobs will hold a scope.
---
 src/Lib/Script/Ast/IrElement.hh    |  3 +++
 src/Lib/Script/Ast/IrExpression.cc |  1 +
 src/Lib/Script/Ast/IrExpression.hh |  6 +++---
 src/Lib/Script/Ast/IrRoot.cc       |  5 +++++
 src/Lib/Script/Ast/IrRoot.hh       |  5 ++++-
 src/Lib/Script/Ast/IrScope.cc      | 17 +++++++++++++++
 src/Lib/Script/Ast/IrScope.hh      | 33 ++++++++++++++++++++++++++++++
 7 files changed, 66 insertions(+), 4 deletions(-)
 create mode 100644 src/Lib/Script/Ast/IrScope.cc
 create mode 100644 src/Lib/Script/Ast/IrScope.hh

diff --git a/src/Lib/Script/Ast/IrElement.hh b/src/Lib/Script/Ast/IrElement.hh
index 53dcd663..77d353c2 100644
--- a/src/Lib/Script/Ast/IrElement.hh
+++ b/src/Lib/Script/Ast/IrElement.hh
@@ -14,6 +14,7 @@ namespace Vivy::Script
 
 /* Structural And Declarative Objects */
 class IrRoot;      // A root, with all the needed modules, etc
+class IrScope;     // A thing to store everything that is in the scope
 class IrModule;    // A module (single vvs file)
 class IrAttribute; // Attribute placed on the module, function, etc
 class IrImport;    // An import statement
@@ -107,6 +108,7 @@ concept IrElementParsable = std::is_base_of<IrElement, T>::value && requires(T i
 class IrElement {
     IrElement *parentElement       = nullptr;
     IrAttribute *elementAttributes = nullptr;
+    IrRoot *parentRoot             = nullptr;
     std::vector<IrElement *> childElements;
 
 protected:
@@ -125,6 +127,7 @@ public:
 
     virtual const IrElement *parent() const noexcept;
     virtual IrElement *parent() noexcept;
+    IrRoot *irRoot() const noexcept;
 
     void setParent(IrElement *p) noexcept;
     void setAttribute(IrAttribute *a) noexcept;
diff --git a/src/Lib/Script/Ast/IrExpression.cc b/src/Lib/Script/Ast/IrExpression.cc
index 8aa191c4..60f991b8 100644
--- a/src/Lib/Script/Ast/IrExpression.cc
+++ b/src/Lib/Script/Ast/IrExpression.cc
@@ -1,4 +1,5 @@
 #include "IrExpression.hh"
+#include "IrScope.hh"
 #include "IrFunction.hh"
 #include "IrElement.hh"
 #include "IrVariable.hh"
diff --git a/src/Lib/Script/Ast/IrExpression.hh b/src/Lib/Script/Ast/IrExpression.hh
index c2ff6f9d..4295eff6 100644
--- a/src/Lib/Script/Ast/IrExpression.hh
+++ b/src/Lib/Script/Ast/IrExpression.hh
@@ -18,7 +18,8 @@ public:
 
 private:
     Type selfType;
-    IrType *selfInnerType = nullptr;
+    IrType *selfInnerType    = nullptr;
+    IrScope *selfParentScope = nullptr;
 
     /*
     ** Helper for the parser, create a binary expression, insert the last expression at
@@ -57,6 +58,7 @@ protected:
 
 public:
     std::string toString() const noexcept override;
+    IrScope *parentScope() const noexcept;
     void parse(std::vector<Token> *);
 
     Type type() const noexcept;
@@ -169,9 +171,7 @@ class IrEVariableRef : public IrExpression {
     std::vector<IrExpression *> indicies;
 
     IrEVariableRef(IrVariable *) noexcept;
-
     IrEVariableRef(IrVariable *, std::vector<IrExpression *> &&);
-
     template <typename... Args> IrEVariableRef(IrVariable *var, Args &&...indicieArgs)
         : IrEVariableRef(var, std::vector<IrExpression *>{ indicieArgs... })
     {
diff --git a/src/Lib/Script/Ast/IrRoot.cc b/src/Lib/Script/Ast/IrRoot.cc
index 9cd352ae..708c2690 100644
--- a/src/Lib/Script/Ast/IrRoot.cc
+++ b/src/Lib/Script/Ast/IrRoot.cc
@@ -30,6 +30,11 @@ findInVector(const std::vector<T *> &vector, ::Vivy::Script::StrV itemName) noex
 
 namespace Vivy::Script
 {
+IrRoot::IrRoot() noexcept
+    : IrElement(this)
+{
+}
+
 const IrRoot *
 IrRoot::parent() const noexcept
 {
diff --git a/src/Lib/Script/Ast/IrRoot.hh b/src/Lib/Script/Ast/IrRoot.hh
index 1c4d5d87..01209b85 100644
--- a/src/Lib/Script/Ast/IrRoot.hh
+++ b/src/Lib/Script/Ast/IrRoot.hh
@@ -9,12 +9,15 @@ class IrRoot final : public IrElement {
     VIVY_IR_ELEMENT(IrRoot)
     std::vector<IrModule *> modules;
     IrModule *mainVivyModule = nullptr;
-    IrRoot() noexcept        = default;
+    IrScope *globalScope     = nullptr;
+    IrRoot() noexcept;
 
 public:
     const IrRoot *parent() const noexcept override;
     IrRoot *parent() noexcept override;
 
+    IrScope *scope() noexcept;
+
     std::string toString() const noexcept override;
     void parse(std::vector<Token> *tokens);
 
diff --git a/src/Lib/Script/Ast/IrScope.cc b/src/Lib/Script/Ast/IrScope.cc
new file mode 100644
index 00000000..ef053614
--- /dev/null
+++ b/src/Lib/Script/Ast/IrScope.cc
@@ -0,0 +1,17 @@
+#include "IrScope.hh"
+#include "IrRoot.hh"
+
+namespace Vivy::Script
+{
+bool
+IrScope::isGlobal() const noexcept
+{
+    return irRoot()->scope() == this;
+}
+
+bool
+IrScope::isLocal() const noexcept
+{
+    return !isGlobal();
+}
+}
diff --git a/src/Lib/Script/Ast/IrScope.hh b/src/Lib/Script/Ast/IrScope.hh
new file mode 100644
index 00000000..91ebb366
--- /dev/null
+++ b/src/Lib/Script/Ast/IrScope.hh
@@ -0,0 +1,33 @@
+#pragma once
+
+#include "IrElement.hh"
+
+namespace Vivy::Script
+{
+class IrScope final : public IrElement {
+    VIVY_IR_ELEMENT(IrScope)
+
+    IrScope *parentScope;
+    std::vector<IrFunction *> inScopeFunctions;
+    std::vector<IrVariable *> inScopeVariables;
+
+    IrScope(IrElement *parent);
+
+public:
+    std::string toString() const noexcept override;
+
+    bool isGlobal() const noexcept;
+    bool isLocal() const noexcept;
+
+    IrFunction *getFunctionByName(StrV) const noexcept;
+    IrFunction *getFunctionByName(const char *) const noexcept;
+    IrFunction *getFunctionByName(const std::string &) const noexcept;
+
+    IrVariable *getVariableByName(StrV) const noexcept;
+    IrVariable *getVariableByName(const char *) const noexcept;
+    IrVariable *getVariableByName(const std::string &) const noexcept;
+
+    void addFunction(IrFunction *);
+    void addVariable(IrVariable *);
+};
+}
-- 
GitLab