summaryrefslogtreecommitdiff
path: root/src/expand/asm.cpp
blob: f2412da59fc98a4a53eed57634d4be9962db884e (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
116
117
118
119
120
121
/*
 * MRustC - Rust Compiler
 * - By John Hodge (Mutabah/thePowersGang)
 *
 * expand/asm.cpp
 * - asm! macro
 */
#include <common.hpp>
#include <synext_macro.hpp>
#include <parse/tokentree.hpp>

class CAsmExpander:
    public ExpandProcMacro
{
    bool    expand_early() const override { return true; }
    
    ::std::unique_ptr<TokenStream> expand(const Span& sp, const ::AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override
    {
        // TODO: Convert this into an AST node
        return box$( TTStreamO(TokenTree()) );
        
        #if 0
        Token   tok;
        auto lex = TTStream(tt);
        if( ident != "" )
            ERROR(sp, E0000, "format_args! doesn't take an ident");
        
        auto n = Parse_ExprVal(lex);
        auto format_string = dynamic_cast<AST::ExprNode_String&>(*n).m_value;
        
        ::std::map< ::std::string, unsigned int>   named_args_index;
        ::std::vector<TokenTree>    named_args;
        ::std::vector<TokenTree>    free_args;
        
        // - Parse the arguments
        while( GET_TOK(tok, lex) == TOK_COMMA )
        {
            // - Named parameters
            if( lex.lookahead(0) == TOK_IDENT && lex.lookahead(1) == TOK_EQUAL )
            {
                GET_CHECK_TOK(tok, lex, TOK_IDENT);
                auto name = mv$(tok.str());
                
                GET_CHECK_TOK(tok, lex, TOK_EQUAL);
                
                auto expr_tt = Parse_TT_Expr(lex);
                
                auto ins_rv = named_args_index.insert( ::std::make_pair(mv$(name), named_args.size()) );
                if( ins_rv.second == false ) {
                    ERROR(sp, E0000, "Duplicate definition of named argument `" << ins_rv.first->first << "`");
                }
                named_args.push_back( mv$(expr_tt) );
            }
            // - Free parameters
            else
            {
                auto expr_tt = Parse_TT_Expr(lex);
                free_args.push_back( mv$(expr_tt) );
            }
        }
        
        // - Parse the format string
        ::std::vector< FmtFrag> fragments;
        ::std::string   tail;
        ::std::tie( fragments, tail ) = parse_format_string(sp, format_string,  named_args_index, free_args.size());
        
        // TODO: Properly expand format_args! (requires mangling to fit ::core::fmt::rt::v1)
        // - For now, just emits the text with no corresponding format fragments
        
        ::std::vector<TokenTree> toks;
        {
            switch(crate.m_load_std)
            {
            case ::AST::Crate::LOAD_NONE:
                break;
            case ::AST::Crate::LOAD_CORE:
                toks.push_back( TokenTree(TOK_DOUBLE_COLON) );
                toks.push_back( Token(TOK_STRING, "core") );
                break;
            case ::AST::Crate::LOAD_STD:
                toks.push_back( TokenTree(TOK_DOUBLE_COLON) );
                toks.push_back( Token(TOK_IDENT, "std") );
                break;
            }
            
            // ::fmt::Arguments::new_v1
            toks.push_back( TokenTree(TOK_DOUBLE_COLON) );
            toks.push_back( Token(TOK_IDENT, "fmt") );
            toks.push_back( TokenTree(TOK_DOUBLE_COLON) );
            toks.push_back( Token(TOK_IDENT, "Arguments") );
            toks.push_back( TokenTree(TOK_DOUBLE_COLON) );
            toks.push_back( Token(TOK_IDENT, "new_v1") );
            // (
            toks.push_back( TokenTree(TOK_PAREN_OPEN) );
            {
                toks.push_back( TokenTree(TOK_AMP) );
                // Raw string fragments
                toks.push_back( TokenTree(TOK_SQUARE_OPEN) );
                for(const auto& frag : fragments ) {
                    toks.push_back( Token(TOK_STRING, frag.leading_text) );
                    toks.push_back( TokenTree(TOK_COMMA) );
                }
                toks.push_back( TokenTree(TOK_SQUARE_CLOSE) );
                toks.push_back( TokenTree(TOK_COMMA) );
                
                // TODO: Fragments to format
                // - The format stored by mrustc doesn't quite work with how rustc (and fmt::rt::v1) works
                toks.push_back( TokenTree(TOK_AMP) );
                toks.push_back( TokenTree(TOK_SQUARE_OPEN) );
                toks.push_back( TokenTree(TOK_SQUARE_CLOSE) );
            }
            // )
            toks.push_back( TokenTree(TOK_PAREN_CLOSE) );
        }
        
        return box$( TTStreamO(TokenTree(mv$(toks))) );
        #endif
    }
};

STATIC_MACRO("asm", CAsmExpander);