summaryrefslogtreecommitdiff
path: root/src/expand/mod.cpp
blob: 6598af4eb5e95597cd4974f5a995c985871b3ab9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
 */
#include <ast/ast.hpp>
#include <ast/crate.hpp>
#include <main_bindings.hpp>
#include <synext.hpp>
#include <map>

::std::map< ::std::string, ::std::unique_ptr<ExpandDecorator> >  g_decorators;
::std::map< ::std::string, ::std::unique_ptr<ExpandProcMacro> >  g_macros;

void init() __attribute__((constructor(101)));
void init()
{
}

void Register_Synext_Decorator(::std::string name, ::std::unique_ptr<ExpandDecorator> handler) {
    g_decorators[name] = mv$(handler);
}

void Expand_Decorators_Mod(::AST::Crate& crate, bool is_before_macros, ::AST::Path modpath, ::AST::Module& mod)
{
    for( auto& i : mod.items() )
    {
        ::AST::Path path = modpath + i.name;
        for( auto& a : i.data.attrs.m_items )
        {
            for( auto& d : g_decorators ) {
                if( d.first == a.name() && d.second->expand_before_macros() == is_before_macros ) {
                    d.second->handle(a, crate, path, mod, i.data);
                }
            }
        }
        
        TU_MATCH(::AST::Item, (i.data), (e),
        (None,
            // Skip, nothing
            ),
        (Module,
            Expand_Decorators_Mod(crate, is_before_macros, path, e.e);
            ),
        (Crate,
            // Skip, no recursion
            ),
        
        (Struct,
            // TODO: Struct items
            ),
        (Enum,
            ),
        (Trait,
            ),
        (Type,
            // TODO: Do type aliases require recursion?
            ),
        
        (Function,
            // TODO:
            ),
        (Static,
            // TODO: 
            )
        )
    }
}
void Expand_Decorators(::AST::Crate& crate, bool is_before_macros)
{
    // 1. Crate attributes
    for( auto& a : crate.m_attrs.m_items )
    {
        for( auto& d : g_decorators ) {
            if( d.first == a.name() && d.second->expand_before_macros() == is_before_macros ) {
                d.second->handle(a, crate);
            }
        }
    }
    
    // 2. Module attributes
    for( auto& a : crate.m_attrs.m_items )
    {
        for( auto& d : g_decorators ) {
            if( d.first == a.name() && d.second->expand_before_macros() == is_before_macros ) {
                //d.second->handle(a, crate, ::AST::Path(), crate.m_root_module, crate.m_root_module);
            }
        }
    }
    
    // 3. Module tree
    Expand_Decorators_Mod(crate, is_before_macros, ::AST::Path(), crate.m_root_module);
}

/// Expand decorators that apply before macros are expanded
/// - E.g. #[cfg] #![no_std] ...
void Expand_Decorators_Pre(::AST::Crate& crate)
{
    Expand_Decorators(crate, true);
}

/// Expand macros
void Expand_Macros(::AST::Crate& crate)
{
}

/// Expand decorators that apply _after_ macros
/// - E.g. #[derive]
void Expand_Decorators_Post(::AST::Crate& crate)
{
    Expand_Decorators(crate, false);
}

/// Expand syntax sugar (e.g. for loops)
void Expand_Sugar(::AST::Crate& crate)
{
}