summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2019-05-05 20:12:58 +0800
committerJohn Hodge <tpg@ucc.asn.au>2019-05-05 20:12:58 +0800
commit7a5cd835703fdfac0634b975392f915e0230c2a7 (patch)
treececda0ef233d853e9058649b49d373a8f0a5f299 /src
parent6cc802dfbd44a6f1f76cc5ae76227f1f54cf9f75 (diff)
downloadmrust-7a5cd835703fdfac0634b975392f915e0230c2a7.tar.gz
parse/expand/resolve - `macro` macros use their own module as the resolve root
Diffstat (limited to 'src')
-rw-r--r--src/ast/ast.cpp3
-rw-r--r--src/ast/ast.hpp1
-rw-r--r--src/expand/mod.cpp3
-rw-r--r--src/hir/from_ast.cpp2
-rw-r--r--src/ident.cpp5
-rw-r--r--src/include/ident.hpp20
-rw-r--r--src/macro_rules/eval.cpp1
-rw-r--r--src/macro_rules/macro_rules.hpp4
-rw-r--r--src/macro_rules/parse.cpp20
-rw-r--r--src/parse/paths.cpp1
-rw-r--r--src/parse/root.cpp43
-rw-r--r--src/resolve/absolute.cpp27
-rw-r--r--src/resolve/index.cpp4
13 files changed, 103 insertions, 31 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp
index 9893e87f..03257fc6 100644
--- a/src/ast/ast.cpp
+++ b/src/ast/ast.cpp
@@ -315,6 +315,9 @@ Item Item::clone() const
(MacroInv,
TODO(this->span, "Clone on Item::MacroInv");
),
+ (Macro,
+ TODO(this->span, "Clone on Item::Macro");
+ ),
(Use,
return AST::Item(e.clone());
),
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp
index 43a0e027..f6f97fce 100644
--- a/src/ast/ast.hpp
+++ b/src/ast/ast.hpp
@@ -607,6 +607,7 @@ TAGGED_UNION_EX(Item, (), None,
(Impl, Impl),
(NegImpl, ImplDef),
+ (Macro, MacroRulesPtr),
(Module, Module),
(Crate, struct {
::std::string name;
diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp
index fd851c89..bc51e1ff 100644
--- a/src/expand/mod.cpp
+++ b/src/expand/mod.cpp
@@ -1113,6 +1113,9 @@ void Expand_Mod(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST::
}
dat.as_MacroInv() = mv$(mi_owned);
}
+ TU_ARMA(Macro, e) {
+ mod.add_macro(i.is_pub, i.name, mv$(e));
+ }
TU_ARMA(Use, e) {
// No inner expand.
}
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp
index af6bc9cb..2393cadd 100644
--- a/src/hir/from_ast.cpp
+++ b/src/hir/from_ast.cpp
@@ -1433,6 +1433,8 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, ::HIR::Publicity
TU_MATCH(::AST::Item, (item.data), (e),
(None,
),
+ (Macro,
+ ),
(MacroInv,
// Valid.
//BUG(sp, "Stray macro invocation in " << path);
diff --git a/src/ident.cpp b/src/ident.cpp
index da029e21..63fe57ed 100644
--- a/src/ident.cpp
+++ b/src/ident.cpp
@@ -34,7 +34,10 @@ bool Ident::Hygiene::is_visible(const Hygiene& src) const
}
::std::ostream& operator<<(::std::ostream& os, const Ident::Hygiene& x) {
- os << "{" << x.contexts << "}";
+ os << "{" << x.contexts;
+ if( x.search_module )
+ os << " " << x.search_module->ents;
+ os << "}";
return os;
}
diff --git a/src/include/ident.hpp b/src/include/ident.hpp
index b9a6dec5..ec42c582 100644
--- a/src/include/ident.hpp
+++ b/src/include/ident.hpp
@@ -8,14 +8,21 @@
#pragma once
#include <vector>
#include <string>
+#include <memory>
struct Ident
{
+ struct ModPath
+ {
+ //::std::vector<RcString> ents;
+ ::std::vector<::std::string> ents;
+ };
class Hygiene
{
static unsigned g_next_scope;
::std::vector<unsigned int> contexts;
+ ::std::shared_ptr<ModPath> search_module;
Hygiene(unsigned int index):
contexts({index})
@@ -32,6 +39,7 @@ struct Ident
static Hygiene new_scope_chained(const Hygiene& parent)
{
Hygiene rv;
+ rv.search_module = parent.search_module;
rv.contexts.reserve( parent.contexts.size() + 1 );
rv.contexts.insert( rv.contexts.begin(), parent.contexts.begin(), parent.contexts.end() );
rv.contexts.push_back( ++g_next_scope );
@@ -45,12 +53,22 @@ struct Ident
return rv;
}
+ bool has_mod_path() const {
+ return this->search_module != 0;
+ }
+ const ModPath& mod_path() const {
+ return *this->search_module;
+ }
+ void set_mod_path(ModPath p) {
+ this->search_module.reset( new ModPath(::std::move(p)) );
+ }
+
Hygiene(Hygiene&& x) = default;
Hygiene(const Hygiene& x) = default;
Hygiene& operator=(Hygiene&& x) = default;
Hygiene& operator=(const Hygiene& x) = default;
- // Returns true if an ident with hygine `souce` can see an ident with this hygine
+ // Returns true if an ident with hygine `source` can see an ident with this hygine
bool is_visible(const Hygiene& source) const;
//bool operator==(const Hygiene& x) const { return scope_index == x.scope_index; }
//bool operator!=(const Hygiene& x) const { return scope_index != x.scope_index; }
diff --git a/src/macro_rules/eval.cpp b/src/macro_rules/eval.cpp
index 9caff7b8..c40eb810 100644
--- a/src/macro_rules/eval.cpp
+++ b/src/macro_rules/eval.cpp
@@ -502,6 +502,7 @@ InterpolatedFragment Macro_HandlePatternCap(TokenStream& lex, MacroPatEnt::Type
::std::unique_ptr<TokenStream> Macro_InvokeRules(const char *name, const MacroRules& rules, const Span& sp, TokenTree input, AST::Module& mod)
{
TRACE_FUNCTION_F("'" << name << "', " << input);
+ DEBUG("rules.m_hygiene = " << rules.m_hygiene);
ParameterMappings bound_tts;
unsigned int rule_index = Macro_InvokeRules_MatchPattern(sp, rules, mv$(input), mod, bound_tts);
diff --git a/src/macro_rules/macro_rules.hpp b/src/macro_rules/macro_rules.hpp
index 02b302d8..9e408fd5 100644
--- a/src/macro_rules/macro_rules.hpp
+++ b/src/macro_rules/macro_rules.hpp
@@ -181,4 +181,8 @@ public:
extern ::std::unique_ptr<TokenStream> Macro_InvokeRules(const char *name, const MacroRules& rules, const Span& sp, TokenTree input, AST::Module& mod);
extern MacroRulesPtr Parse_MacroRules(TokenStream& lex);
+extern ::std::vector<MacroPatEnt> Parse_MacroRules_Pat(TokenStream& lex, enum eTokenType open, enum eTokenType close, ::std::vector< ::std::string>& names);
+extern ::std::vector<MacroExpansionEnt> Parse_MacroRules_Cont(TokenStream& lex, enum eTokenType open, enum eTokenType close, const ::std::vector< ::std::string>& var_names, ::std::map<unsigned int,bool>* var_set_ptr=nullptr);
+extern MacroRulesArm Parse_MacroRules_MakeArm(Span pat_sp, ::std::vector<MacroPatEnt> pattern, ::std::vector<MacroExpansionEnt> contents);
+
#endif // MACROS_HPP_INCLUDED
diff --git a/src/macro_rules/parse.cpp b/src/macro_rules/parse.cpp
index 98163998..4bd8a577 100644
--- a/src/macro_rules/parse.cpp
+++ b/src/macro_rules/parse.cpp
@@ -40,6 +40,7 @@ public:
int depth = 0;
while( GET_TOK(tok, lex) != close || depth > 0 )
{
+ DEBUG("tok = " << tok);
if( tok.type() == open )
{
depth ++;
@@ -142,7 +143,7 @@ public:
TokenStream& lex,
enum eTokenType open, enum eTokenType close,
const ::std::vector< ::std::string>& var_names,
- ::std::map<unsigned int,bool>* var_set_ptr=nullptr
+ ::std::map<unsigned int,bool>* var_set_ptr/*=nullptr*/
)
{
TRACE_FUNCTION;
@@ -310,6 +311,15 @@ void enumerate_names(const ::std::vector<MacroPatEnt>& pats, ::std::vector< ::st
}
}
+MacroRulesArm Parse_MacroRules_MakeArm(Span pat_sp, ::std::vector<MacroPatEnt> pattern, ::std::vector<MacroExpansionEnt> contents)
+{
+ // - Convert the rule into an instruction stream
+ auto rule_sequence = macro_pattern_to_simple(pat_sp, pattern);
+ auto arm = MacroRulesArm( mv$(rule_sequence), mv$(contents) );
+ enumerate_names(pattern, arm.m_param_names);
+ return arm;
+}
+
/// Parse an entire macro_rules! block into a format that exec.cpp can use
MacroRulesPtr Parse_MacroRules(TokenStream& lex)
{
@@ -336,13 +346,7 @@ MacroRulesPtr Parse_MacroRules(TokenStream& lex)
// Re-parse the patterns into a unified form
for(auto& rule : rules)
{
- // TODO: Transform the pattern into a DFA or similar here (seekable instruction stream?)
-
- auto rule_sequence = macro_pattern_to_simple(rule.m_pat_span, rule.m_pattern);
- MacroRulesArm arm = MacroRulesArm( mv$(rule_sequence), mv$(rule.m_contents) );
- enumerate_names(rule.m_pattern, arm.m_param_names);
-
- rule_arms.push_back( mv$(arm) );
+ rule_arms.push_back( Parse_MacroRules_MakeArm(rule.m_pat_span, mv$(rule.m_pattern), mv$(rule.m_contents)) );
}
auto rv = new MacroRules( );
diff --git a/src/parse/paths.cpp b/src/parse/paths.cpp
index cb704f85..5c99e049 100644
--- a/src/parse/paths.cpp
+++ b/src/parse/paths.cpp
@@ -103,6 +103,7 @@ AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generi
// TODO: TOK_INTERPOLATED_IDENT?
GET_CHECK_TOK(tok, lex, TOK_IDENT);
auto hygine = lex.getHygiene();
+ DEBUG("hygine = " << hygine);
PUTBACK(tok, lex);
return AST::Path(AST::Path::TagRelative(), mv$(hygine), Parse_PathNodes(lex, generic_mode));
}
diff --git a/src/parse/root.cpp b/src/parse/root.cpp
index c055c190..b0c37a21 100644
--- a/src/parse/root.cpp
+++ b/src/parse/root.cpp
@@ -20,6 +20,7 @@
#include "lex.hpp" // New file lexer
#include <parse/interpolated_fragment.hpp>
#include <ast/expr.hpp>
+#include <macro_rules/macro_rules.hpp>
template<typename T>
Spanned<T> get_spanned(TokenStream& lex, ::std::function<T()> f) {
@@ -1931,31 +1932,31 @@ namespace {
GET_TOK(tok, lex);
throw ParseError::Unexpected(lex, tok);
}
+ DEBUG("name = " << name);
- //::std::vector< ::std::string> names;
- //auto arm_pat = Parse_MacroRules_Pat(lex, TOK_PAREN_OPEN, TOK_PAREN_CLOSE, names);
- auto args_tt = Parse_TT(lex, false);
- if( lex.lookahead(0) != TOK_BRACE_OPEN )
+ ::std::vector< ::std::string> names;
+ auto ps = lex.start_span();
+ GET_CHECK_TOK(tok, lex, TOK_PAREN_OPEN);
+ auto arm_pat = Parse_MacroRules_Pat(lex, TOK_PAREN_OPEN, TOK_PAREN_CLOSE, names);
+ auto pat_span = lex.end_span(ps);
+ GET_CHECK_TOK(tok, lex, TOK_BRACE_OPEN);
+ // TODO: Pass a flag that annotates all idents with the current module?
+ auto body = Parse_MacroRules_Cont(lex, TOK_BRACE_OPEN, TOK_BRACE_CLOSE, names);
+
+ auto mr = new MacroRules( );
+ mr->m_hygiene = lex.getHygiene();
{
- GET_TOK(tok, lex);
- throw ParseError::Unexpected(lex, tok);
+ Ident::ModPath mp;
+ for(const auto& node : mod_path.nodes())
+ {
+ mp.ents.push_back(node.name());
+ }
+ mr->m_hygiene.set_mod_path(::std::move(mp));
}
- //auto body = Parse_MacroRules_Cont(lex, TOK_BRACE_OPEN, TOK_BRACE_CLOSE, names);
- auto body_tt = Parse_TT(lex, false);
-
- // TODO: Invoke the macro_rules parsers here
- // - Could also do the same level of parsing when `macro_rules! foo {` is seen (i.e. parse macros at parse
- // time, instead of during expand).
- // - That would simplify some of the expand logic...
+ mr->m_rules.push_back(Parse_MacroRules_MakeArm(pat_span, ::std::move(arm_pat), ::std::move(body)));
- // Lazy option: create a TT
- ::std::vector<TokenTree> out;
- out.push_back(mv$(args_tt));
- out.push_back(TokenTree( Token(TOK_FATARROW) ));
- out.push_back(mv$(body_tt));
-
- item_name = "";
- item_data = ::AST::Item( AST::MacroInvocation(lex.end_span(ps), "macro_rules", name, TokenTree({}, mv$(out))) );
+ item_name = name;
+ item_data = ::AST::Item( MacroRulesPtr(mr) );
}
else
{
diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp
index 95e01d18..c2dedfcb 100644
--- a/src/resolve/absolute.cpp
+++ b/src/resolve/absolute.cpp
@@ -424,6 +424,29 @@ namespace
}
AST::Path lookup_opt(const ::std::string& name, const Ident::Hygiene& src_context, LookupMode mode) const {
DEBUG("name=" << name <<", src_context=" << src_context);
+ // NOTE: src_context may provide a module to search
+ if( src_context.has_mod_path() )
+ {
+ DEBUG(src_context.mod_path().ents);
+ const AST::Module* mod = &m_crate.root_module();
+ for(const auto& node : src_context.mod_path().ents)
+ {
+ const AST::Module* next = nullptr;
+ for(const auto& i : mod->items())
+ {
+ if( i.name == node ) {
+ next = &i.data.as_Module();
+ break;
+ }
+ }
+ assert(next);
+ mod = next;
+ }
+ ::AST::Path rv;
+ if( this->lookup_in_mod(*mod, name, mode, rv) ) {
+ return rv;
+ }
+ }
for(auto it = m_name_context.rbegin(); it != m_name_context.rend(); ++ it)
{
TU_MATCH(Ent, (*it), (e),
@@ -2012,6 +2035,7 @@ void Resolve_Absolute_ImplItems(Context& item_context, ::AST::NamedList< ::AST:
(ExternBlock, BUG(i.data.span, "Resolve_Absolute_ImplItems - " << i.data.tag_str());),
(Impl, BUG(i.data.span, "Resolve_Absolute_ImplItems - " << i.data.tag_str());),
(NegImpl, BUG(i.data.span, "Resolve_Absolute_ImplItems - " << i.data.tag_str());),
+ (Macro, BUG(i.data.span, "Resolve_Absolute_ImplItems - " << i.data.tag_str());),
(Use, BUG(i.data.span, "Resolve_Absolute_ImplItems - Use");),
(Module, BUG(i.data.span, "Resolve_Absolute_ImplItems - Module");),
(Crate , BUG(i.data.span, "Resolve_Absolute_ImplItems - Crate");),
@@ -2056,6 +2080,7 @@ void Resolve_Absolute_ImplItems(Context& item_context, ::std::vector< ::AST::Im
(Impl , BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());),
(NegImpl, BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());),
(ExternBlock, BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());),
+ (Macro , BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());),
(Use , BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());),
(Module, BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());),
(Crate , BUG(i.data->span, "Resolve_Absolute_ImplItems - " << i.data->tag_str());),
@@ -2221,6 +2246,8 @@ void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod )
),
(Use,
),
+ (Macro,
+ ),
(ExternBlock,
for(auto& i2 : e.items())
{
diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp
index f38219ef..43182faf 100644
--- a/src/resolve/index.cpp
+++ b/src/resolve/index.cpp
@@ -121,6 +121,10 @@ void Resolve_Index_Module_Base(const AST::Crate& crate, AST::Module& mod)
(NegImpl,
),
+ (Macro,
+ // TODO: Add to a macro list
+ ),
+
(Use,
// Skip for now
),