summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-09-28 10:35:32 +0800
committerJohn Hodge <tpg@mutabah.net>2016-09-28 10:35:32 +0800
commite7bae8f3f2188c6b04e4f4d62e898275f072a6e3 (patch)
treed3bb27250ec99c65389da6a0852bf4fe3e2395c0
parent9ba41a54e44ae2f107a8646364353b06a7776bb5 (diff)
downloadmrust-e7bae8f3f2188c6b04e4f4d62e898275f072a6e3.tar.gz
AST - Make anon modules `shared_ptr`s to handle case where a block is depeted
-rw-r--r--src/ast/ast.cpp18
-rw-r--r--src/ast/ast.hpp22
-rw-r--r--src/ast/expr.cpp6
-rw-r--r--src/ast/expr.hpp4
-rw-r--r--src/expand/mod.cpp23
-rw-r--r--src/parse/common.hpp2
-rw-r--r--src/parse/expr.cpp6
-rw-r--r--src/parse/root.cpp1
-rw-r--r--src/resolve/absolute.cpp3
-rw-r--r--src/resolve/index.cpp8
-rw-r--r--src/resolve/use.cpp3
11 files changed, 51 insertions, 45 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp
index efac6520..0ec36f82 100644
--- a/src/ast/ast.cpp
+++ b/src/ast/ast.cpp
@@ -258,10 +258,11 @@ ExternBlock ExternBlock::clone() const
TODO(Span(), "Clone an extern block");
}
-::std::unique_ptr<AST::Module> Module::add_anon() {
- auto rv = box$( Module(m_my_path + FMT("#" << m_anon_modules.size())) );
+::std::shared_ptr<AST::Module> Module::add_anon() {
+ auto rv = ::std::shared_ptr<AST::Module>( new Module(m_my_path + FMT("#" << m_anon_modules.size())) );
+ DEBUG("New anon " << rv->m_my_path);
- m_anon_modules.push_back( rv.get() );
+ m_anon_modules.push_back( rv );
return rv;
}
@@ -292,17 +293,6 @@ void Module::add_macro(bool is_exported, ::std::string name, MacroRulesPtr macro
m_macros.push_back( Named<MacroRulesPtr>( mv$(name), mv$(macro), is_exported ) );
}
-void Module::prescan()
-{
- //TRACE_FUNCTION;
- //DEBUG("- '"<<m_name<<"'");
- //
- //for( auto& sm_p : m_submods )
- //{
- // sm_p.first.prescan();
- //}
-}
-
Item Item::clone() const
{
TU_MATCHA( (*this), (e),
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp
index 2554ed58..d06f0531 100644
--- a/src/ast/ast.hpp
+++ b/src/ast/ast.hpp
@@ -490,7 +490,7 @@ class Module
// --- Runtime caches and state ---
- ::std::vector<Module*> m_anon_modules;
+ ::std::vector< ::std::shared_ptr<Module> > m_anon_modules;
::std::vector< NamedNS<const MacroRules*> > m_macro_import_res; // Vec of imported macros (not serialised)
::std::vector< Named<MacroRulesPtr> > m_macros;
@@ -511,7 +511,8 @@ public:
bool is_import; // Set if this item has a path that isn't `mod->path() + name`
::AST::Path path;
};
- // TODO: Add "namespace" list (separate to types)
+
+ // TODO: Document difference between namespace and Type
::std::unordered_map< ::std::string, IndexEnt > m_namespace_items;
::std::unordered_map< ::std::string, IndexEnt > m_type_items;
::std::unordered_map< ::std::string, IndexEnt > m_value_items;
@@ -527,11 +528,8 @@ public:
return m_my_path.nodes().back().name()[0] == '#';
}
- // Called when module is loaded from a serialised format
- void prescan();
-
/// Create an anon module (for use inside expressions)
- ::std::unique_ptr<AST::Module> add_anon();
+ ::std::shared_ptr<AST::Module> add_anon();
void add_item(Named<Item> item);
void add_item(bool is_pub, ::std::string name, Item it, MetaItems attrs);
@@ -552,14 +550,6 @@ public:
- unsigned int add_anon_module(Module* mod_ptr) {
- auto it = ::std::find(m_anon_modules.begin(), m_anon_modules.end(), mod_ptr);
- if( it != m_anon_modules.end() )
- return it - m_anon_modules.begin();
- m_anon_modules.push_back(mod_ptr);
- return m_anon_modules.size()-1;
- }
-
const ::AST::Path& path() const { return m_my_path; }
::std::vector<Named<Item>>& items() { return m_items; }
@@ -571,8 +561,8 @@ public:
::std::vector<ImplDef>& neg_impls() { return m_neg_impls; }
const ::std::vector<ImplDef>& neg_impls() const { return m_neg_impls; }
- ::std::vector<Module*>& anon_mods() { return m_anon_modules; }
- const ::std::vector<Module*>& anon_mods() const { return m_anon_modules; }
+ ::std::vector< ::std::shared_ptr<Module> >& anon_mods() { return m_anon_modules; }
+ const ::std::vector< ::std::shared_ptr<Module> >& anon_mods() const { return m_anon_modules; }
::std::vector<MacroInvocation>& macro_invs() { return m_macro_invocations; }
diff --git a/src/ast/expr.cpp b/src/ast/expr.cpp
index c2b2889f..5c9afa5d 100644
--- a/src/ast/expr.cpp
+++ b/src/ast/expr.cpp
@@ -374,14 +374,14 @@ NODE(ExprNode_UniOp, {
#define NV(type, actions)\
- void NodeVisitorDef::visit(type& node) { DEBUG("DEF - "#type); actions }
+ void NodeVisitorDef::visit(type& node) { /*DEBUG("DEF - "#type);*/ actions }
// void NodeVisitorDef::visit(const type& node) { DEBUG("DEF - "#type" (const)"); actions }
NV(ExprNode_Block, {
- INDENT();
+ //INDENT();
for( auto& child : node.m_nodes )
visit(child);
- UNINDENT();
+ //UNINDENT();
})
NV(ExprNode_Macro,
{
diff --git a/src/ast/expr.hpp b/src/ast/expr.hpp
index 00c1154b..3f2151dd 100644
--- a/src/ast/expr.hpp
+++ b/src/ast/expr.hpp
@@ -54,7 +54,7 @@ struct ExprNode_Block:
{
bool m_is_unsafe;
bool m_yields_final_value;
- ::std::unique_ptr<AST::Module> m_local_mod;
+ ::std::shared_ptr<AST::Module> m_local_mod;
::std::vector<ExprNodeP> m_nodes;
ExprNode_Block(::std::vector<ExprNodeP> nodes={}):
@@ -63,7 +63,7 @@ struct ExprNode_Block:
m_local_mod(),
m_nodes( mv$(nodes) )
{}
- ExprNode_Block(bool is_unsafe, bool yields_final_value, ::std::vector<ExprNodeP> nodes, ::std::unique_ptr<AST::Module> local_mod):
+ ExprNode_Block(bool is_unsafe, bool yields_final_value, ::std::vector<ExprNodeP> nodes, ::std::shared_ptr<AST::Module> local_mod):
m_is_unsafe(is_unsafe),
m_yields_final_value(yields_final_value),
m_local_mod( move(local_mod) ),
diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp
index 4b60bab2..12360f42 100644
--- a/src/expand/mod.cpp
+++ b/src/expand/mod.cpp
@@ -300,7 +300,7 @@ struct CExpandExpr:
SET_MODULE( (*ttl), mod );
// Reparse as expression / item
bool add_silence_if_end = false;
- ::std::unique_ptr< AST::Module> tmp_local_mod;
+ ::std::shared_ptr< AST::Module> tmp_local_mod;
auto& local_mod_ptr = (this->current_block ? this->current_block->m_local_mod : tmp_local_mod);
auto newexpr = Parse_ExprBlockLine_WithItems(*ttl, local_mod_ptr, add_silence_if_end);
if( newexpr )
@@ -942,6 +942,26 @@ void Expand_Mod(::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST::
for( const auto& mi: mod.macro_imports_res() )
DEBUG("- Imports '" << mi.name << "'");
}
+void Expand_Mod_IndexAnon(::AST::Crate& crate, ::AST::Module& mod)
+{
+ TRACE_FUNCTION_F("mod=" << mod.path());
+
+ for(auto& i : mod.items())
+ {
+ DEBUG("- " << i.data.tag_str() << " '" << i.name << "'");
+ TU_IFLET(::AST::Item, (i.data), Module, e,
+ Expand_Mod_IndexAnon(crate, e);
+ )
+ }
+
+ for( auto& mp : mod.anon_mods() )
+ {
+ if( mp.unique() ) {
+ DEBUG("- " << mp->path() << " dropped due to node destruction");
+ mp.reset();
+ }
+ }
+}
void Expand(::AST::Crate& crate)
{
auto modstack = LList<const ::AST::Module*>(nullptr, &crate.m_root_module);
@@ -987,6 +1007,7 @@ void Expand(::AST::Crate& crate)
Expand_Mod(crate, modstack, ::AST::Path("",{}), crate.m_root_module);
// Post-process
+ Expand_Mod_IndexAnon(crate, crate.m_root_module);
#if 0
for( auto& a : crate.m_attrs.m_items )
{
diff --git a/src/parse/common.hpp b/src/parse/common.hpp
index c883c493..54f9eb16 100644
--- a/src/parse/common.hpp
+++ b/src/parse/common.hpp
@@ -56,7 +56,7 @@ extern AST::ExprNodeP Parse_Expr0(TokenStream& lex);
extern AST::ExprNodeP Parse_ExprVal(TokenStream& lex);
extern AST::ExprNodeP Parse_ExprBlockNode(TokenStream& lex, bool is_unsafe=false);
extern AST::ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *add_silence);
-extern AST::ExprNodeP Parse_ExprBlockLine_WithItems(TokenStream& lex, ::std::unique_ptr<AST::Module>& local_mod, bool& add_silence_if_end);
+extern AST::ExprNodeP Parse_ExprBlockLine_WithItems(TokenStream& lex, ::std::shared_ptr<AST::Module>& local_mod, bool& add_silence_if_end);
extern AST::ExprNodeP Parse_Stmt(TokenStream& lex);
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp
index 774d7acc..a01bc26b 100644
--- a/src/parse/expr.cpp
+++ b/src/parse/expr.cpp
@@ -24,7 +24,7 @@ static inline ExprNodeP mk_exprnodep(const TokenStream& lex, AST::ExprNode* en){
#define NEWNODE(type, ...) mk_exprnodep(lex, new type(__VA_ARGS__))
//ExprNodeP Parse_ExprBlockNode(TokenStream& lex, bool is_unsafe=false); // common.hpp
-//ExprNodeP Parse_ExprBlockLine_WithItems(TokenStream& lex, ::std::unique_ptr<AST::Module>& local_mod, bool& add_silence_if_end);
+//ExprNodeP Parse_ExprBlockLine_WithItems(TokenStream& lex, ::std::shared_ptr<AST::Module>& local_mod, bool& add_silence_if_end);
//ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *add_silence);
ExprNodeP Parse_ExprBlockLine_Stmt(TokenStream& lex, bool *add_silence);
//ExprNodeP Parse_Stmt(TokenStream& lex); // common.hpp
@@ -55,7 +55,7 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex, bool is_unsafe/*=false*/)
bool yields_final_value = true;
::std::vector<ExprNodeP> nodes;
- ::std::unique_ptr<AST::Module> local_mod;
+ ::std::shared_ptr<AST::Module> local_mod;
GET_CHECK_TOK(tok, lex, TOK_BRACE_OPEN);
@@ -97,7 +97,7 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex, bool is_unsafe/*=false*/)
/// Parse a single line in a block, handling items added to the local module
///
/// - If an item was parsed, this returns an empty ExprNodeP
-ExprNodeP Parse_ExprBlockLine_WithItems(TokenStream& lex, ::std::unique_ptr<AST::Module>& local_mod, bool& add_silence_if_end)
+ExprNodeP Parse_ExprBlockLine_WithItems(TokenStream& lex, ::std::shared_ptr<AST::Module>& local_mod, bool& add_silence_if_end)
{
Token tok;
diff --git a/src/parse/root.cpp b/src/parse/root.cpp
index ff792788..2e776332 100644
--- a/src/parse/root.cpp
+++ b/src/parse/root.cpp
@@ -1657,7 +1657,6 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::UseStmt, ::std::strin
default:
throw ParseError::Generic("Expected { or ; after module name");
}
- submod.prescan();
item_name = mv$(name);
item_data = ::AST::Item( mv$(submod) );
break; }
diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp
index c2e77678..ce9abd0a 100644
--- a/src/resolve/absolute.cpp
+++ b/src/resolve/absolute.cpp
@@ -994,7 +994,8 @@ void Resolve_Absolute_Path_BindAbsolute(Context& context, const Span& sp, Contex
ss >> c;
ss >> idx;
assert( idx < mod->anon_mods().size() );
- mod = mod->anon_mods()[idx];
+ assert( mod->anon_mods()[idx] );
+ mod = mod->anon_mods()[idx].get();
}
else
{
diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp
index 754b6eea..f712bd46 100644
--- a/src/resolve/index.cpp
+++ b/src/resolve/index.cpp
@@ -245,7 +245,9 @@ void Resolve_Index_Module_Base(const AST::Crate& crate, AST::Module& mod)
}
for(auto& mp : mod.anon_mods())
{
- Resolve_Index_Module_Base(crate, *mp);
+ if( mp ) {
+ Resolve_Index_Module_Base(crate, *mp);
+ }
}
}
@@ -459,7 +461,9 @@ void Resolve_Index_Module_Wildcard(AST::Crate& crate, AST::Module& mod, bool han
}
for(auto& mp : mod.anon_mods())
{
- Resolve_Index_Module_Wildcard(crate, *mp, handle_pub);
+ if( mp ) {
+ Resolve_Index_Module_Wildcard(crate, *mp, handle_pub);
+ }
}
}
diff --git a/src/resolve/use.cpp b/src/resolve/use.cpp
index 44d50516..c2079bdd 100644
--- a/src/resolve/use.cpp
+++ b/src/resolve/use.cpp
@@ -256,7 +256,8 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path
if( idx >= mod.anon_mods().size() ) {
BUG(span, "Invalid anon path segment '" << des_item_name << "'");
}
- return ::AST::PathBinding::make_Module({mod.anon_mods()[idx]});
+ assert( mod.anon_mods()[idx] );
+ return ::AST::PathBinding::make_Module({&*mod.anon_mods()[idx]});
}
// Seach for the name defined in the module.