diff options
author | John Hodge <tpg@mutabah.net> | 2016-03-11 23:10:54 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-03-11 23:10:54 +0800 |
commit | 990102479e927dd175b2e3ae7aa4c5c1a977d5d1 (patch) | |
tree | e587bdc3c218f784b42e1f20ceaae13575ec8ba2 | |
parent | 76a037ed785148fb271135b5c17c06fd5d036f94 (diff) | |
download | mrust-990102479e927dd175b2e3ae7aa4c5c1a977d5d1.tar.gz |
Expand - Macros expansion improved
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | src/expand/cfg.cpp | 8 | ||||
-rw-r--r-- | src/expand/concat.cpp | 50 | ||||
-rw-r--r-- | src/expand/file_line.cpp | 30 | ||||
-rw-r--r-- | src/expand/format_args.cpp | 2 | ||||
-rw-r--r-- | src/expand/macro_rules.cpp | 5 | ||||
-rw-r--r-- | src/expand/mod.cpp | 317 | ||||
-rw-r--r-- | src/expand/stringify.cpp | 28 | ||||
-rw-r--r-- | src/include/synext.hpp | 7 | ||||
-rw-r--r-- | src/synexts/derive.cpp | 2 |
10 files changed, 285 insertions, 165 deletions
@@ -30,6 +30,7 @@ OBJ += ast/provided_module.o OBJ += parse/parseerror.o parse/lex.o OBJ += parse/root.o parse/paths.o parse/types.o parse/expr.o parse/pattern.o parse/macro_rules.o OBJ += expand/mod.o expand/macro_rules.o expand/cfg.o expand/format_args.o +OBJ += expand/concat.o expand/stringify.o expand/file_line.o OBJ += dump_as_rust.o OBJ += convert/ast_iterate.o #OBJ += convert/decorators.o diff --git a/src/expand/cfg.cpp b/src/expand/cfg.cpp index 3def0150..c77ada2a 100644 --- a/src/expand/cfg.cpp +++ b/src/expand/cfg.cpp @@ -72,7 +72,7 @@ class CCfgExpander: { bool expand_early() const override { return true; } - ::std::unique_ptr<TokenStream> expand(Span sp, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr<TokenStream> expand(Span sp, const ::AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override { if( ident != "" ) { ERROR(sp, E0000, "cfg! doesn't take an identifier"); @@ -98,7 +98,7 @@ class CCfgHandler: AttrStage stage() const override { return AttrStage::EarlyPre; } - void handle(const AST::MetaItem& mi, AST::Crate& crate, AST::MacroInvocation& mac) const override { + void handle(const AST::MetaItem& mi, ::AST::Crate& crate, AST::MacroInvocation& mac) const override { if( check_cfg(mac.span(), mi) ) { // Leave as is } @@ -106,7 +106,7 @@ class CCfgHandler: mac.clear(); } } - void handle(const AST::MetaItem& mi, AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item&i) const override { + void handle(const AST::MetaItem& mi, ::AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item&i) const override { if( check_cfg(Span(), mi) ) { // Leave } @@ -114,7 +114,7 @@ class CCfgHandler: i = AST::Item::make_None({}); } } - void handle(const AST::MetaItem& mi, ::std::unique_ptr<AST::ExprNode>& expr) const override { + void handle(const AST::MetaItem& mi, ::AST::Crate& crate, ::std::unique_ptr<AST::ExprNode>& expr) const override { if( check_cfg(Span(expr->get_pos()), mi) ) { // Leave } diff --git a/src/expand/concat.cpp b/src/expand/concat.cpp new file mode 100644 index 00000000..c7da73a1 --- /dev/null +++ b/src/expand/concat.cpp @@ -0,0 +1,50 @@ +/* + */ +#include <synext.hpp> +#include "../parse/common.hpp" +#include "../parse/parseerror.hpp" +#include "../parse/tokentree.hpp" +#include "../parse/lex.hpp" + +class CConcatExpander: + public ExpandProcMacro +{ + bool expand_early() const override { return true; } + + ::std::unique_ptr<TokenStream> expand(Span sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + { + Token tok; + + auto lex = TTStream(tt); + if( ident != "" ) + ERROR(sp, E0000, "format_args! doesn't take an ident"); + + ::std::string rv; + do { + auto v = Parse_Expr0(lex); + DEBUG("concat - v=" << *v); + Expand_Expr(true , *const_cast<AST::Crate*>(&crate), LList<const AST::Module*>(nullptr, &mod), v); + Expand_Expr(false, *const_cast<AST::Crate*>(&crate), LList<const AST::Module*>(nullptr, &mod), v); + DEBUG("concat[pe] - v=" << *v); + if( auto* vp = dynamic_cast<AST::ExprNode_String*>(v.get()) ) + { + rv += vp->m_value; + } + else if( auto* vp = dynamic_cast<AST::ExprNode_Integer*>(v.get()) ) + { + rv += FMT(vp->m_value); + } + else + { + ERROR(sp, E0000, "Unexpected expression type"); + } + } while( GET_TOK(tok, lex) == TOK_COMMA ); + if( tok.type() != TOK_EOF ) + throw ParseError::Unexpected(lex, tok, {TOK_COMMA, TOK_EOF}); + + return box$( TTStreamO(TokenTree(Token(TOK_STRING, mv$(rv)))) ); + } +}; + +STATIC_MACRO("concat", CConcatExpander); + diff --git a/src/expand/file_line.cpp b/src/expand/file_line.cpp new file mode 100644 index 00000000..a4117d70 --- /dev/null +++ b/src/expand/file_line.cpp @@ -0,0 +1,30 @@ +/* + */ +#include <synext.hpp> +#include "../parse/common.hpp" + +class CExpanderFile: + public ExpandProcMacro +{ + bool expand_early() const override { return true; } + + ::std::unique_ptr<TokenStream> expand(Span sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + { + return box$( TTStreamO(TokenTree(Token(TOK_STRING, sp.filename))) ); + } +}; + +class CExpanderLine: + public ExpandProcMacro +{ + bool expand_early() const override { return true; } + + ::std::unique_ptr<TokenStream> expand(Span sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + { + return box$( TTStreamO(TokenTree(Token((uint64_t)sp.start_line, CORETYPE_I32))) ); + } +}; + +STATIC_MACRO("file", CExpanderFile); +STATIC_MACRO("line", CExpanderLine); + diff --git a/src/expand/format_args.cpp b/src/expand/format_args.cpp index 0c809601..d12096a7 100644 --- a/src/expand/format_args.cpp +++ b/src/expand/format_args.cpp @@ -11,7 +11,7 @@ class CFormatArgsExpander: { bool expand_early() const override { return true; } - ::std::unique_ptr<TokenStream> expand(Span sp, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr<TokenStream> expand(Span sp, const ::AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override { Token tok; diff --git a/src/expand/macro_rules.cpp b/src/expand/macro_rules.cpp index fac987ff..bd9348e5 100644 --- a/src/expand/macro_rules.cpp +++ b/src/expand/macro_rules.cpp @@ -10,14 +10,13 @@ class CMacroRulesExpander: { bool expand_early() const override { return true; } - ::std::unique_ptr<TokenStream> expand(Span sp, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr<TokenStream> expand(Span sp, const ::AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override { if( ident == "" ) ERROR(sp, E0000, "macro_rules! requires an identifier" ); TTStream lex(tt); auto mac = Parse_MacroRules(lex); - // TODO: Place into current module using `ident` as the name mod.add_macro( false, ident, mac ); return box$( TTStreamO(TokenTree()) ); @@ -29,7 +28,7 @@ class CMacroUseHandler: { AttrStage stage() const override { return AttrStage::EarlyPost; } - void handle(const AST::MetaItem& mi, AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item& i) const override + void handle(const AST::MetaItem& mi, ::AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item& i) const override { TRACE_FUNCTION_F("path=" << path); if( !i.is_Module() ) diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index dd966545..b7aa6518 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -63,7 +63,7 @@ void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate& } ::std::unique_ptr<TokenStream> Expand_Macro( - bool is_early, LList<const AST::Module*> modstack, ::AST::Module& mod, + bool is_early, const ::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST::Module& mod, Span mi_span, const ::std::string& name, const ::std::string& input_ident, const TokenTree& input_tt ) { @@ -71,7 +71,7 @@ void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate& { if( name == m.first && m.second->expand_early() == is_early ) { - auto e = m.second->expand(mi_span, input_ident, input_tt, mod); + auto e = m.second->expand(mi_span, crate, input_ident, input_tt, mod); return e; } } @@ -115,68 +115,72 @@ void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate& // Leave valid and return an empty expression return ::std::unique_ptr<TokenStream>(); } - -void Expand_Expr(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST::Path item_path, AST::Expr& node) +struct CExpandExpr: + public ::AST::NodeVisitor { - struct CExpandExpr: - public ::AST::NodeVisitor + bool is_early; + ::AST::Crate& crate; + LList<const AST::Module*> modstack; + ::std::unique_ptr<::AST::ExprNode> replacement; + + CExpandExpr(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> ms): + is_early(is_early), + crate(crate), + modstack(ms) { - bool is_early; - ::AST::Crate& crate; - LList<const AST::Module*> modstack; - ::std::unique_ptr<::AST::ExprNode> replacement; - - CExpandExpr(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> ms): - is_early(is_early), - crate(crate), - modstack(ms) + } + + void visit(::std::unique_ptr<AST::ExprNode>& cnode) { + if(cnode.get()) + Expand_Attrs(cnode->attrs(), stage_pre(is_early), [&](const auto& d, const auto& a){ d.handle(a, this->crate, cnode); }); + if(cnode.get()) { - } - - void visit(::std::unique_ptr<AST::ExprNode>& cnode) { - if(cnode.get()) - Expand_Attrs(cnode->attrs(), stage_pre(is_early), [&](const auto& d, const auto& a){ d.handle(a, cnode); }); - if(cnode.get()) + cnode->visit(*this); + if( auto* n_mac = dynamic_cast<AST::ExprNode_Macro*>(cnode.get()) ) { - cnode->visit(*this); - if( this->replacement.get() ) { - cnode = mv$(this->replacement); - } + if( n_mac->m_name == "" ) + cnode.reset(); } - - if(cnode.get()) - Expand_Attrs(cnode->attrs(), stage_post(is_early), [&](const auto& d, const auto& a){ d.handle(a, cnode); }); - } - void visit_nodelete(const ::AST::ExprNode& parent, ::std::unique_ptr<AST::ExprNode>& cnode) { - if( cnode.get() != nullptr ) - { - this->visit(cnode); - if(cnode.get() == nullptr) - ERROR(parent.get_pos(), E0000, "#[cfg] not allowed in this position"); + if( this->replacement.get() ) { + cnode = mv$(this->replacement); } } - void visit_vector(::std::vector< ::std::unique_ptr<AST::ExprNode> >& cnodes) { - for( auto& child : cnodes ) { - this->visit(child); + + if(cnode.get()) + Expand_Attrs(cnode->attrs(), stage_post(is_early), [&](const auto& d, const auto& a){ d.handle(a, this->crate, cnode); }); + } + void visit_nodelete(const ::AST::ExprNode& parent, ::std::unique_ptr<AST::ExprNode>& cnode) { + if( cnode.get() != nullptr ) + { + this->visit(cnode); + if(cnode.get() == nullptr) + ERROR(parent.get_pos(), E0000, "#[cfg] not allowed in this position"); + } + } + void visit_vector(::std::vector< ::std::unique_ptr<AST::ExprNode> >& cnodes) { + for( auto& child : cnodes ) { + this->visit(child); + } + // Delete null children + for( auto it = cnodes.begin(); it != cnodes.end(); ) { + if( it->get() == nullptr ) { + it = cnodes.erase( it ); } - // Delete null children - for( auto it = cnodes.begin(); it != cnodes.end(); ) { - if( it->get() == nullptr ) { - it = cnodes.erase( it ); - } - else { - ++ it; - } + else { + ++ it; } } - - void visit(::AST::ExprNode_Macro& node) override { - auto ttl = Expand_Macro( - is_early, modstack, *(::AST::Module*)(modstack.m_item), - Span(node.get_pos()), - node.m_name, node.m_ident, node.m_tokens - ); - if( ttl.get() != nullptr && ttl->lookahead(0) != TOK_EOF ) + } + + void visit(::AST::ExprNode_Macro& node) override { + auto ttl = Expand_Macro( + is_early, crate, modstack, *(::AST::Module*)(modstack.m_item), + Span(node.get_pos()), + node.m_name, node.m_ident, node.m_tokens + ); + if( ttl.get() != nullptr ) + { + if( ttl->lookahead(0) != TOK_EOF ) { // Reparse as expression / item auto newexpr = Parse_Expr0(*ttl); @@ -185,101 +189,112 @@ void Expand_Expr(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> m // And schedule it to replace the previous replacement = mv$(newexpr); } - } - - void visit(::AST::ExprNode_Block& node) override { - // TODO! Use a proper path here - if( node.m_inner_mod ) { - Expand_Mod(is_early, crate, modstack, AST::Path(), *node.m_inner_mod); + else + { + node.m_name = ""; } - this->visit_vector(node.m_nodes); - } - void visit(::AST::ExprNode_Flow& node) override { - this->visit_nodelete(node, node.m_value); - } - void visit(::AST::ExprNode_LetBinding& node) override { - // TODO: Pattern and type - this->visit_nodelete(node, node.m_value); - } - void visit(::AST::ExprNode_Assign& node) override { - this->visit_nodelete(node, node.m_slot); - this->visit_nodelete(node, node.m_value); - } - void visit(::AST::ExprNode_CallPath& node) override { - // TODO: path? - this->visit_vector(node.m_args); - } - void visit(::AST::ExprNode_CallMethod& node) override { - this->visit_nodelete(node, node.m_val); - this->visit_vector(node.m_args); - } - void visit(::AST::ExprNode_CallObject& node) override { - this->visit_nodelete(node, node.m_val); - this->visit_vector(node.m_args); - } - void visit(::AST::ExprNode_Loop& node) override { - this->visit_nodelete(node, node.m_cond); - this->visit_nodelete(node, node.m_code); - } - void visit(::AST::ExprNode_Match& node) override { - this->visit_nodelete(node, node.m_val); - // TODO: Arms - } - void visit(::AST::ExprNode_If& node) override { - this->visit_nodelete(node, node.m_cond); - this->visit_nodelete(node, node.m_true); - this->visit_nodelete(node, node.m_false); // TODO: Can the false branch be `#[cfg]`d off? - } - void visit(::AST::ExprNode_IfLet& node) override { - // TODO: Pattern - this->visit_nodelete(node, node.m_value); - this->visit_nodelete(node, node.m_true); - this->visit_nodelete(node, node.m_false); // TODO: Can the false branch be `#[cfg]`d off? - } - void visit(::AST::ExprNode_Integer& node) override { } - void visit(::AST::ExprNode_Float& node) override { } - void visit(::AST::ExprNode_Bool& node) override { } - void visit(::AST::ExprNode_String& node) override { } - void visit(::AST::ExprNode_Closure& node) override { - // TODO: Arg patterns and types - // TODO: Return type - this->visit_nodelete(node, node.m_code); - } - void visit(::AST::ExprNode_StructLiteral& node) override { - this->visit_nodelete(node, node.m_base_value); - // TODO: Values (with #[cfg] support) - } - void visit(::AST::ExprNode_Array& node) override { - this->visit_nodelete(node, node.m_size); - this->visit_vector(node.m_values); - } - void visit(::AST::ExprNode_Tuple& node) override { - this->visit_vector(node.m_values); - } - void visit(::AST::ExprNode_NamedValue& node) override { } - void visit(::AST::ExprNode_Field& node) override { - this->visit_nodelete(node, node.m_obj); } - void visit(::AST::ExprNode_Index& node) override { - this->visit_nodelete(node, node.m_obj); - this->visit_nodelete(node, node.m_idx); - } - void visit(::AST::ExprNode_Deref& node) override { - this->visit_nodelete(node, node.m_value); - } - void visit(::AST::ExprNode_Cast& node) override { - this->visit_nodelete(node, node.m_value); - // TODO: Type - } - void visit(::AST::ExprNode_BinOp& node) override { - this->visit_nodelete(node, node.m_left); - this->visit_nodelete(node, node.m_right); - } - void visit(::AST::ExprNode_UniOp& node) override { - this->visit_nodelete(node, node.m_value); + } + + void visit(::AST::ExprNode_Block& node) override { + // TODO! Use a proper path here + if( node.m_inner_mod ) { + Expand_Mod(is_early, crate, modstack, AST::Path(), *node.m_inner_mod); } - }; + this->visit_vector(node.m_nodes); + } + void visit(::AST::ExprNode_Flow& node) override { + this->visit_nodelete(node, node.m_value); + } + void visit(::AST::ExprNode_LetBinding& node) override { + // TODO: Pattern and type + this->visit_nodelete(node, node.m_value); + } + void visit(::AST::ExprNode_Assign& node) override { + this->visit_nodelete(node, node.m_slot); + this->visit_nodelete(node, node.m_value); + } + void visit(::AST::ExprNode_CallPath& node) override { + // TODO: path? + this->visit_vector(node.m_args); + } + void visit(::AST::ExprNode_CallMethod& node) override { + this->visit_nodelete(node, node.m_val); + this->visit_vector(node.m_args); + } + void visit(::AST::ExprNode_CallObject& node) override { + this->visit_nodelete(node, node.m_val); + this->visit_vector(node.m_args); + } + void visit(::AST::ExprNode_Loop& node) override { + this->visit_nodelete(node, node.m_cond); + this->visit_nodelete(node, node.m_code); + } + void visit(::AST::ExprNode_Match& node) override { + this->visit_nodelete(node, node.m_val); + // TODO: Arms + } + void visit(::AST::ExprNode_If& node) override { + this->visit_nodelete(node, node.m_cond); + this->visit_nodelete(node, node.m_true); + this->visit_nodelete(node, node.m_false); // TODO: Can the false branch be `#[cfg]`d off? + } + void visit(::AST::ExprNode_IfLet& node) override { + // TODO: Pattern + this->visit_nodelete(node, node.m_value); + this->visit_nodelete(node, node.m_true); + this->visit_nodelete(node, node.m_false); // TODO: Can the false branch be `#[cfg]`d off? + } + void visit(::AST::ExprNode_Integer& node) override { } + void visit(::AST::ExprNode_Float& node) override { } + void visit(::AST::ExprNode_Bool& node) override { } + void visit(::AST::ExprNode_String& node) override { } + void visit(::AST::ExprNode_Closure& node) override { + // TODO: Arg patterns and types + // TODO: Return type + this->visit_nodelete(node, node.m_code); + } + void visit(::AST::ExprNode_StructLiteral& node) override { + this->visit_nodelete(node, node.m_base_value); + // TODO: Values (with #[cfg] support) + } + void visit(::AST::ExprNode_Array& node) override { + this->visit_nodelete(node, node.m_size); + this->visit_vector(node.m_values); + } + void visit(::AST::ExprNode_Tuple& node) override { + this->visit_vector(node.m_values); + } + void visit(::AST::ExprNode_NamedValue& node) override { } + void visit(::AST::ExprNode_Field& node) override { + this->visit_nodelete(node, node.m_obj); + } + void visit(::AST::ExprNode_Index& node) override { + this->visit_nodelete(node, node.m_obj); + this->visit_nodelete(node, node.m_idx); + } + void visit(::AST::ExprNode_Deref& node) override { + this->visit_nodelete(node, node.m_value); + } + void visit(::AST::ExprNode_Cast& node) override { + this->visit_nodelete(node, node.m_value); + // TODO: Type + } + void visit(::AST::ExprNode_BinOp& node) override { + this->visit_nodelete(node, node.m_left); + this->visit_nodelete(node, node.m_right); + } + void visit(::AST::ExprNode_UniOp& node) override { + this->visit_nodelete(node, node.m_value); + } +}; +void Expand_Expr(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> modstack, ::std::unique_ptr<AST::ExprNode>& node) { + auto visitor = CExpandExpr(is_early, crate, modstack); + visitor.visit(node); +} +void Expand_Expr(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST::Path item_path, AST::Expr& node) +{ auto visitor = CExpandExpr(is_early, crate, modstack); node.visit_nodes(visitor); } @@ -305,7 +320,8 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo // Move out of the module to avoid invalidation if a new macro invocation is added auto mi_owned = mv$(mi); - auto ttl = Expand_Macro(is_early, modstack, mod, mi_owned.span(), mi_owned.name(), mi_owned.input_ident(), mi_owned.input_tt()); + auto ttl = Expand_Macro(is_early, crate, modstack, mod, + mi_owned.span(), mi_owned.name(), mi_owned.input_ident(), mi_owned.input_tt()); if( ! ttl.get() ) { @@ -385,14 +401,7 @@ void Expand(::AST::Crate& crate) auto modstack = LList<const ::AST::Module*>(nullptr, &crate.m_root_module); // 1. Crate attributes - for( auto& a : crate.m_attrs.m_items ) - { - for( auto& d : g_decorators ) { - if( d.first == a.name() && d.second->stage() == AttrStage::EarlyPre ) { - d.second->handle(a, crate); - } - } - } + Expand_Attrs(crate.m_attrs, AttrStage::EarlyPre, [&](const auto& d, const auto& a){ d.handle(a, crate); }); // 2. Module attributes for( auto& a : crate.m_attrs.m_items ) diff --git a/src/expand/stringify.cpp b/src/expand/stringify.cpp new file mode 100644 index 00000000..e4abb99b --- /dev/null +++ b/src/expand/stringify.cpp @@ -0,0 +1,28 @@ +/* + */ +#include <synext.hpp> +#include "../parse/common.hpp" + +class CExpander: + public ExpandProcMacro +{ + bool expand_early() const override { return true; } + + ::std::unique_ptr<TokenStream> expand(Span sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + { + Token tok; + ::std::string rv; + + auto lex = TTStream(tt); + while( GET_TOK(tok, lex) != TOK_EOF ) + { + rv += tok.to_str(); + rv += " "; + } + + return box$( TTStreamO(TokenTree(Token(TOK_STRING, mv$(rv)))) ); + } +}; + +STATIC_MACRO("stringify", CExpander); + diff --git a/src/include/synext.hpp b/src/include/synext.hpp index 3ab594a5..aa72e985 100644 --- a/src/include/synext.hpp +++ b/src/include/synext.hpp @@ -44,7 +44,7 @@ public: virtual void handle(const AST::MetaItem& mi, AST::Crate& crate) const {} virtual void handle(const AST::MetaItem& mi, AST::Crate& crate, AST::MacroInvocation& mac) const {} virtual void handle(const AST::MetaItem& mi, AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item&i) const {} - virtual void handle(const AST::MetaItem& mi, ::std::unique_ptr<AST::ExprNode>& expr) const {}; + virtual void handle(const AST::MetaItem& mi, AST::Crate& crate, ::std::unique_ptr<AST::ExprNode>& expr) const {}; }; enum class MacroPosition @@ -61,7 +61,7 @@ class ExpandProcMacro public: virtual bool expand_early() const = 0; - virtual ::std::unique_ptr<TokenStream> expand(Span sp, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) = 0; + virtual ::std::unique_ptr<TokenStream> expand(Span sp, const AST::Crate& crate, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) = 0; }; #define STATIC_DECORATOR(ident, _handler_class) \ @@ -80,5 +80,8 @@ public: extern void Register_Synext_Decorator(::std::string name, ::std::unique_ptr<ExpandDecorator> handler); extern void Register_Synext_Macro(::std::string name, ::std::unique_ptr<ExpandProcMacro> handler); + +extern void Expand_Expr(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> modstack, ::std::unique_ptr<AST::ExprNode>& node); + #endif diff --git a/src/synexts/derive.cpp b/src/synexts/derive.cpp index 5849e280..e4c10f4e 100644 --- a/src/synexts/derive.cpp +++ b/src/synexts/derive.cpp @@ -149,7 +149,7 @@ class Decorator_Derive: { public: AttrStage stage() const override { return AttrStage::LatePost; } - void handle(const AST::MetaItem& attr, AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item& i) const override + void handle(const AST::MetaItem& attr, ::AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item& i) const override { TU_MATCH_DEF(::AST::Item, (i), (e), ( |