Skip to content
Extraits de code Groupes Projets
Sélectionner une révision Git
  • 40641489c4e2976969c9250925b6b2ab29e5652c
  • main par défaut protégée
  • renovate/docker-28.x
3 résultats

hosts

Blame
  • IrElement.hh 6,54 Kio
    #pragma once
    
    #include <string>
    #include <vector>
    #include <memory>
    #include <type_traits>
    #include "Lib/Utils.hh"
    #include "Lib/Script/FrontEnd/Token.hh"
    #include "Lib/Script/FrontEnd/Tokens.hh"
    #include "Lib/Script/FrontEnd/Location.hh"
    
    namespace Vivy::Script
    {
    
    /* Structural And Declarative Objects */
    class IrRoot;      // A root, with all the needed modules, etc
    class IrModule;    // A module (single vvs file)
    class IrAttribute; // Attribute placed on the module, function, etc
    class IrImport;    // An import statement
    class IrOption;    // An option to pass to jobs (no global vars)
    
    /* Types */
    class IrType;
    class IrTAss;       // Ass types, SYLLABE, LINE, etc
    class IrTOption;    // An option type, need to have the same shape
    class IrTPrimitive; // Primitive types
    
    /* Jobs */
    class IrJob;
    class IrImportedJob; // An imported job
    
    /* Functions */
    class IrFunction;
    class IrImportedFunction; // A utility to hide the imported functions
    
    /* Variables */
    class IrVariable;
    class IrVPrimitive; // A simple base variable
    class IrVTable;     // A variable with fields (a struct)
    
    /* Instructions */
    class IrInstruction;
    class IrILoop;        // Any loop
    class IrIAffectation; // Variable affectation
    class IrIReturn;      // Return statement
    class IrIDeclaration; // Variable declaration
    class IrIConditional; // If/Else/Elif statements
    
    /* Expression */
    class IrExpression;
    class IrEConstExpr;    // A constant expression, known at compile time
    class IrECall;         // A function call
    class IrECompOp;       // A comparaison (!=, <=, ...)
    class IrEArithmeticOp; // Simple operations (+, *, ...)
    class IrELogicOp;      // A logic operation (and, or, ...)
    class IrEVariableRef;  // Reference to a variable, local or argument
    
    /* A signature for a callable element */
    class IrCallableSignature;
    
    /* Base class forward declaration needed for concepts */
    class IrElement;
    
    /*
    ** Base concept for an IR element class.
    */
    
    template <typename T>
    concept IrElementObject = std::is_base_of<IrElement, T>::value;
    
    template <typename... T>
    concept IrElementObjects = std::conjunction<std::is_base_of<IrElement, T>...>::value;
    
    /*
    ** IrElementConstructible object. Used to create an element from
    ** the passed arguments (`typename... Args`).
    */
    
    template <typename T, typename... Args>
    concept IrElementConstructible = IrElementObject<T> && requires(T irElem, Args &&...args)
    {
        T(std::forward<Args>(args)...);
    };
    
    /*
    ** IrElementDefaultConstructible object. Used to create an element
    ** from nothing.
    */
    
    template <typename T>
    concept IrElementDefaultConstructible =
        std::is_base_of<IrElement, T>::value && has_any_default_constructor<T>::value;
    
    /*
    ** IrElementParsable object. Used for the create with the pointer
    ** to the tokens passed. Also removes the
    ** `virtual void parse(std::vector<Token>*)` abstract method.
    */
    
    template <typename T>
    concept IrElementParsable = std::is_base_of<IrElement, T>::value && requires(T irElem)
    {
        irElem.parse(new std::vector<Token>);
    };
    
    /* Base class definition: IrElement */
    class IrElement {
        IrElement *parentElement       = nullptr;
        IrAttribute *elementAttributes = nullptr;
        std::vector<IrElement *> childElements;
    
    protected:
        IrElement() noexcept = default;
        IrElement(IrElement *p) noexcept;
    
        void detachElementFromParent() noexcept;
        void addChild(IrElement *) noexcept;
    
        void throwUnexpectedToken(const Token &tok) const;
    
    public:
        virtual ~IrElement() noexcept;
    
        virtual const IrElement *parent() const noexcept;
        virtual IrElement *parent() noexcept;
    
        void setParent(IrElement *p) noexcept;
        void setAttribute(IrAttribute *a) noexcept;
    
        virtual std::string toString() const noexcept = 0;
    
        /*
        ** Get attributes for an element!
        */
    
        std::vector<StrV> attribute(const std::string &name) const noexcept;
        std::vector<StrV> attribute(StrV name) const noexcept;
    
        /*
        ** Create an IrElement by parsing a token stream representing the file.
        ** May throw an exception because parse is not noexcept. Always return a
        ** non null pointer, will throw an exception on failure.
        **
        ** TODO: Use concepts IrElementParsable and IrElementConstructible.
        */
    
        template <typename T>
        requires IrElementParsable<T> && IrElementDefaultConstructible<T>
        static T *create(IrElement *p, std::vector<Token> *tokens)
        {
            using DeleteCall = decltype(&IrElement::destroy<T>);
            std::unique_ptr<T, DeleteCall> ret(new T, IrElement::destroy<T>);
            ret->setParent(p != nullptr ? p : ret.get());
            ret->parse(tokens);
            return ret.release();
        }
    
        template <typename T, typename... Args>
        requires IrElementConstructible<T, Args...> && IrElementParsable<T>
        static T *create(IrElement *p, std::vector<Token> *tokens, Args &&...args)
        {
            using DeleteCall = decltype(&IrElement::destroy<T>);
            std::unique_ptr<T, DeleteCall> ret(new T(std::forward<Args>(args)...),
                                               IrElement::destroy<T>);
            ret->setParent(p != nullptr ? p : ret.get());
            ret->parse(tokens);
            return ret.release();
        }
    
        template <typename T>
        requires IrElementParsable<T>
        static T *create(IrElement *p)
        {
            using DeleteCall = decltype(&IrElement::destroy<T>);
            std::unique_ptr<T, DeleteCall> ret(new T, IrElement::destroy<T>);
            ret->setParent(p != nullptr ? p : ret.get());
            return ret.release();
        }
    
        template <typename T, typename... Args>
        requires IrElementConstructible<T, Args...>
        static T *create(IrElement *p, Args &&...args)
        {
            using DeleteCall = decltype(&IrElement::destroy<T>);
            std::unique_ptr<T, DeleteCall> ret(new T(std::forward<Args>(args)...),
                                               IrElement::destroy<T>);
            ret->setParent(p != nullptr ? p : ret.get());
            return ret.release();
        }
    
        /* A safer call to delete, to also remove the children from its parent */
        template <typename T>
        requires IrElementObject<T>
        static void destroy(T *const e) noexcept
        {
            if (e != nullptr) {
                e->detachElementFromParent();
                delete e;
            }
        }
    };
    
    /*
    ** Define an IrElement sub-class. Sets the correct visibility for the
    ** constructors and add IrElement as a friend for the create static
    ** method.
    */
    
    #define VIVY_IR_ELEMENT(clazz)                                \
    protected:                                                    \
        friend class IrElement;                                   \
        template <typename... T> friend struct HasAnyConstructor; \
                                                                  \
    private:
    
    }