Changeset f47f887


Ignore:
Timestamp:
May 9, 2019, 2:31:15 PM (2 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
arm-eh, cleanup-dtors, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr
Children:
2bb4a01
Parents:
ee7a29f
Message:

First draft of Pass.hpp and some updates to node.hpp

Location:
src/AST
Files:
3 added
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Node.hpp

    ree7a29f rf47f887  
    44
    55namespace ast {
     6class Node {
     7public:
     8        virtual ~Node() = default;
    69
    7         class Node {
    8         public:
    9                 virtual ~Node() = default;
     10        enum class ref_type {
     11                strong,
     12                weak
     13        };
    1014
    11                 enum class ref_type {
    12                         strong,
    13                         weak
    14                 };
     15        inline void increment(ref_type ref) const {
     16                switch (ref) {
     17                        case ref_type::strong: strong_ref++; break;
     18                        case ref_type::weak  : weak_ref  ++; break;
     19                }
     20        }
    1521
    16                 void increment(ref_type ref) {
    17                         switch (ref)                    {
    18                                 case ref_type::strong: strong_ref++; break;
    19                                 case ref_type::weak  : weak_ref  ++; break;
    20                         }
     22        inline void decrement(ref_type ref) const {
     23                switch (ref) {
     24                        case ref_type::strong: strong_ref--; break;
     25                        case ref_type::weak  : weak_ref  --; break;
    2126                }
    2227
    23                 void decrement(ref_type ref) {
    24                         switch (ref)                    {
    25                                 case ref_type::strong: strong_ref--; break;
    26                                 case ref_type::weak  : weak_ref  --; break;
    27                         }
    28 
    29                         if(!strong_ref && !weak_ref) {
    30                                 delete this;
    31                         }
     28                if(!strong_ref && !weak_ref) {
     29                        delete this;
    3230                }
    33 
    34                 template<typename node_t>
    35                 friend auto mutate(const node_t * node);
    36 
    37         private:
    38                 size_t strong_ref = 0;
    39                 size_t weak_ref = 0;
    40         };
    41 
    42         // Mutate a node, non-member function to avoid static type
    43         // problems and be able to use auto return
    44         template<typename node_t>
    45         auto mutate(const node_t * node) {
    46                 assertf(
    47                         node->strong_count >= 1,
    48                         "Error: attempting to mutate a node that appears to have been linked"
    49                 );
    50                 if (node->strong_count == 1) {
    51                         return const_cast<node_t *>(node);
    52                 }
    53 
    54                 assertf(
    55                         node->weak_count == 0,
    56                         "Error: mutating node with weak references to it will invalided some references"
    57                 );
    58                 return node->clone();
    5931        }
    6032
    61         // All accept routines should look as follows :
    62         // virtual void accept( Visitor &v ) override {
    63         //      return v.visit(this);
    64         // }
    65         // Using the following wrapper to handle the node type
    66         template< typename node_t >
    67         auto visit_this( visitor & v, node_t * node ) {
    68                 ptr<node_t> p;
    69                 p.node = node;
    70                 auto r = v.visit(p);
    71                 p.node = nullptr;
    72                 return r;
     33        template<typename node_t>
     34        friend auto mutate(const node_t * node);
     35
     36private:
     37        mutable size_t strong_ref = 0;
     38        mutable size_t weak_ref = 0;
     39};
     40
     41// Mutate a node, non-member function to avoid static type
     42// problems and be able to use auto return
     43template<typename node_t>
     44auto mutate(const node_t * node) {
     45        assertf(
     46                node->strong_count >= 1,
     47                "Error: attempting to mutate a node that appears to have been linked"
     48        );
     49        if (node->strong_count == 1) {
     50                return const_cast<node_t *>(node);
    7351        }
    7452
    75         // Base class for the smart pointer types
    76         // should never really be used.
    77         template< typename node_t, enum Node::ref_type ref_t>
    78         class ptr_base {
    79         public:
    80                 ptr_base() : node(nullptr) {}
    81                 ptr_base( node_t * n ) : node(n) { if( !node ) node->increment(ref_t); }
    82                 ~ptr_base() { if( node ) node->decrement(ref_t); }
     53        assertf(
     54                node->weak_count == 0,
     55                "Error: mutating node with weak references to it will invalided some references"
     56        );
     57        return node->clone();
     58}
    8359
    84                 template< enum  Node::ref_type o_ref_t >
    85                 ptr_base( const ptr_base<node_t, o_ref_t> & o ) : node(o.node) {
    86                         if( !node ) return;
    87                         node->increment(ref_t);
    88                 }
     60// Base class for the smart pointer types
     61// should never really be used.
     62template< typename node_t, enum Node::ref_type ref_t>
     63class ptr_base {
     64public:
     65        ptr_base() : node(nullptr) {}
     66        ptr_base( node_t * n ) : node(n) { if( !node ) node->increment(ref_t); }
     67        ~ptr_base() { if( node ) node->decrement(ref_t); }
    8968
    90                 template< enum  Node::ref_type o_ref_t >
    91                 ptr_base( ptr_base<node_t, o_ref_t> && o ) : node(o.node) {
    92                         if( node ) node->increment(ref_t);
    93                         if( node ) node->decrement(o_ref_t);
    94                 }
     69        template< enum  Node::ref_type o_ref_t >
     70        ptr_base( const ptr_base<node_t, o_ref_t> & o ) : node(o.node) {
     71                if( !node ) return;
     72                node->increment(ref_t);
     73        }
    9574
    96                 template< enum  Node::ref_type o_ref_t >
    97                 ptr_base & operator=( const ptr_base<node_t, o_ref_t> & o ) {
    98                         assign(o.node);
    99                         return *this;
    100                 }
     75        template< enum  Node::ref_type o_ref_t >
     76        ptr_base( ptr_base<node_t, o_ref_t> && o ) : node(o.node) {
     77                if( node ) node->increment(ref_t);
     78                if( node ) node->decrement(o_ref_t);
     79        }
    10180
    102                 template< enum  Node::ref_type o_ref_t >
    103                 ptr_base & operator=( ptr_base<node_t, o_ref_t> && o ) {
    104                         if(o.node == node) return *this;
    105                         assign(o.node);
    106                         if( node ) node->decrement(o_ref_t);
    107                         return *this;
    108                 }
     81        template< enum  Node::ref_type o_ref_t >
     82        ptr_base & operator=( const ptr_base<node_t, o_ref_t> & o ) {
     83                assign(o.node);
     84                return *this;
     85        }
    10986
    110                 const node_t * get() const { return  node; }
    111                 const node_t * operator->() const { return  node; }
    112                 const node_t & operator* () const { return *node; }
    113                 operator bool() const { return node; }
     87        template< enum  Node::ref_type o_ref_t >
     88        ptr_base & operator=( ptr_base<node_t, o_ref_t> && o ) {
     89                if(o.node == node) return *this;
     90                assign(o.node);
     91                if( node ) node->decrement(o_ref_t);
     92                return *this;
     93        }
    11494
    115         private:
    116                 void assign(node_t * other ) {
    117                         if( other ) other->increment(ref_t);
    118                         if( node  ) node ->decrement(ref_t);
    119                         node = other;
    120                 }
     95        const node_t * get() const { return  node; }
     96        const node_t * operator->() const { return  node; }
     97        const node_t & operator* () const { return *node; }
     98        explicit operator bool() const { return node; }
     99        operator const node_t * const() const { return node; }
    121100
    122         protected:
    123                 node_t * node;
    124         };
     101        using ptr = const node_t *;
    125102
    126         template< typename node_t >
    127         using ptr = ptr_base< node_t, Node::ref_type::strong >;
     103private:
     104        void assign(node_t * other ) {
     105                if( other ) other->increment(ref_t);
     106                if( node  ) node ->decrement(ref_t);
     107                node = other;
     108        }
    128109
    129         template< typename node_t >
    130         using readonly = ptr_base< node_t, Node::ref_type::weak >;
     110protected:
     111        node_t * node;
     112};
     113
     114template< typename node_t >
     115using ptr = ptr_base< node_t, Node::ref_type::strong >;
     116
     117template< typename node_t >
     118using readonly = ptr_base< node_t, Node::ref_type::weak >;
    131119}
Note: See TracChangeset for help on using the changeset viewer.