summaryrefslogtreecommitdiff
path: root/src/include/synext_macro.hpp
blob: e62a61268f77dc6f503c70b7fe9e529259c6af08 (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
/*
 * MRustC - Rust Compiler
 * - By John Hodge (Mutabah/thePowersGang)
 *
 * include/synext_macro.hpp
 * - Macro-style syntax extensions ( `foo!()` )
 */
#pragma once
#ifndef _SYNEXT_MACRO_HPP_
#define _SYNEXT_MACRO_HPP_

//#include "../common.hpp"   // for mv$ and other things
#include <string>
#include <memory>
#include <span.hpp>

class TypeRef;
namespace AST {
    class Crate;
    class Module;
}
class TokenTree;
class TokenStream;



class ExpandProcMacro
{
public:
    virtual ::std::unique_ptr<TokenStream>  expand(const Span& sp, const AST::Crate& crate, const TokenTree& tt, AST::Module& mod) = 0;
    virtual ::std::unique_ptr<TokenStream>  expand_ident(const Span& sp, const AST::Crate& crate, const RcString& ident, const TokenTree& tt, AST::Module& mod) {
        ERROR(sp, E0000, "macro doesn't take an identifier");
    }
};

struct MacroDef;
extern void Register_Synext_Macro(::std::string name, ::std::unique_ptr<ExpandProcMacro> handler);
extern void Register_Synext_Macro_Static(MacroDef* def);

struct MacroDef
{
    MacroDef*   prev;
    ::std::string   name;
    ::std::unique_ptr<ExpandProcMacro>  def;
    MacroDef(::std::string name, ::std::unique_ptr<ExpandProcMacro> def) :
        prev(nullptr),
        name(::std::move(name)),
        def(::std::move(def))
    {
        Register_Synext_Macro_Static(this);
    }
};

#define STATIC_MACRO(ident, _handler_class) static MacroDef s_register_##_handler_class(ident, ::std::unique_ptr<ExpandProcMacro>(new _handler_class()));

#endif