summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-03-19 12:35:08 +0800
committerJohn Hodge <tpg@mutabah.net>2016-03-19 12:35:08 +0800
commitd9ddf019fe73c78213cddac02c700b6ebf782de4 (patch)
treeea8120e3fae11cbb8b0e66607e3680205bdb7046
parent485dfcb3fe4ddfeb7c0342ec288807fde3ef9504 (diff)
downloadmrust-d9ddf019fe73c78213cddac02c700b6ebf782de4.tar.gz
Expand - Handle impl and trait
-rw-r--r--src/ast/ast.hpp3
-rw-r--r--src/expand/mod.cpp105
-rw-r--r--src/parse/common.hpp1
-rw-r--r--src/parse/root.cpp2
4 files changed, 104 insertions, 7 deletions
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp
index 3dc45305..886766ff 100644
--- a/src/ast/ast.hpp
+++ b/src/ast/ast.hpp
@@ -398,10 +398,11 @@ class Impl:
//NamedList<TypeRef> m_types;
//NamedList<Function> m_functions;
//NamedList<Static> m_statics;
- ::std::vector<MacroInvocation> m_macro_invocations;
::std::vector< ::std::pair< ::std::vector<TypeRef>, Impl > > m_concrete_impls;
public:
+ ::std::vector<MacroInvocation> m_macro_invocations;
+
Impl() {}
Impl(Impl&&) /*noexcept*/ = default;
Impl(MetaItems attrs, GenericParams params, TypeRef impl_type, Path trait_type):
diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp
index f1bea16c..f1a9891a 100644
--- a/src/expand/mod.cpp
+++ b/src/expand/mod.cpp
@@ -542,7 +542,36 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo
}
),
(Trait,
- // TODO: Trait definition
+ for(auto& ti : e.e.items())
+ {
+ auto attrs = mv$(ti.data.attrs);
+ Expand_Attrs(attrs, stage_pre(is_early), crate, AST::Path(), mod, ti.data);
+
+ TU_MATCH_DEF(AST::Item, (ti.data), (e),
+ (
+ throw ::std::runtime_error("BUG: Unknown item type in impl block");
+ ),
+ (None, ),
+ (Function,
+ for(auto& arg : e.e.args()) {
+ Expand_Pattern(is_early, crate, modstack, mod, arg.first);
+ Expand_Type(is_early, crate, modstack, mod, arg.second);
+ }
+ Expand_Type(is_early, crate, modstack, mod, e.e.rettype());
+ Expand_Expr(is_early, crate, modstack, e.e.code());
+ ),
+ (Static,
+ Expand_Expr(is_early, crate, modstack, e.e.value());
+ ),
+ (Type,
+ Expand_Type(is_early, crate, modstack, mod, e.e.type());
+ )
+ )
+
+ Expand_Attrs(attrs, stage_post(is_early), crate, AST::Path(), mod, ti.data);
+ if( ti.data.attrs.m_items.size() == 0 )
+ ti.data.attrs = mv$(attrs);
+ }
),
(Type,
Expand_Type(is_early, crate, modstack, mod, e.e.type());
@@ -567,10 +596,78 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo
}
DEBUG("Impls");
- for( auto& i : mod.impls() )
+ for( auto& impl : mod.impls() )
{
- DEBUG("- " << i);
- // TODO: Expand impls
+ DEBUG("- " << impl);
+ Expand_Type(is_early, crate, modstack, mod, impl.def().type());
+ //Expand_Type(is_early, crate, modstack, mod, impl.def().trait());
+
+ // - Macro invocation
+ for(unsigned int i = 0; i < impl.m_macro_invocations.size(); i ++ )
+ {
+ auto& mi = impl.m_macro_invocations[i];
+ DEBUG("> Macro invoke '"<<mi.name()<<"'");
+ if( mi.name() != "" )
+ {
+ // 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, crate, modstack, mod, mi_owned);
+
+ if( ! ttl.get() )
+ {
+ // - Return ownership to the list
+ mod.macro_invs()[i] = mv$(mi_owned);
+ }
+ else
+ {
+ // Re-parse tt
+ assert(ttl.get());
+ while( ttl->lookahead(0) != TOK_EOF )
+ {
+ Parse_Impl_Item(*ttl, impl);
+ }
+ // - Any new macro invocations ends up at the end of the list and handled
+ }
+ }
+ }
+
+ DEBUG("> Items");
+ for( auto& i : impl.items() )
+ {
+ DEBUG(" - " << i.name << " :: " << i.data.attrs);
+ // TODO: Make a path from the impl definition? Requires having the impl def resolved to be correct
+ // - Does it? the namespace is essentially the same
+ //::AST::Path path = modpath + i.name;
+
+ auto attrs = mv$(i.data.attrs);
+ Expand_Attrs(attrs, stage_pre(is_early), crate, AST::Path(), mod, i.data);
+
+ TU_MATCH_DEF(AST::Item, (i.data), (e),
+ (
+ throw ::std::runtime_error("BUG: Unknown item type in impl block");
+ ),
+ (None, ),
+ (Function,
+ for(auto& arg : e.e.args()) {
+ Expand_Pattern(is_early, crate, modstack, mod, arg.first);
+ Expand_Type(is_early, crate, modstack, mod, arg.second);
+ }
+ Expand_Type(is_early, crate, modstack, mod, e.e.rettype());
+ Expand_Expr(is_early, crate, modstack, e.e.code());
+ ),
+ (Static,
+ Expand_Expr(is_early, crate, modstack, e.e.value());
+ ),
+ (Type,
+ Expand_Type(is_early, crate, modstack, mod, e.e.type());
+ )
+ )
+
+ Expand_Attrs(attrs, stage_post(is_early), crate, AST::Path(), mod, i.data);
+ if( i.data.attrs.m_items.size() == 0 )
+ i.data.attrs = mv$(attrs);
+ }
}
for( const auto& mi: mod.macro_imports_res() )
diff --git a/src/parse/common.hpp b/src/parse/common.hpp
index 4581f365..b1927512 100644
--- a/src/parse/common.hpp
+++ b/src/parse/common.hpp
@@ -45,6 +45,7 @@ extern AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable);
extern MacroRules Parse_MacroRules(TokenStream& lex);
+extern void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl);
extern void Parse_Mod_Item(TokenStream& lex, bool file_controls_dir, const ::std::string& file_path, AST::Module& mod, bool is_public, AST::MetaItems meta_items);
extern void Parse_ModRoot_Items(TokenStream& lex, AST::Module& mod, bool file_controls_dir, const ::std::string& path);
diff --git a/src/parse/root.cpp b/src/parse/root.cpp
index 8f1a041d..fd90ed5d 100644
--- a/src/parse/root.cpp
+++ b/src/parse/root.cpp
@@ -825,8 +825,6 @@ AST::MetaItem Parse_MetaItem(TokenStream& lex)
}
}
-void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl);
-
void Parse_Impl(TokenStream& lex, AST::Module& mod, AST::MetaItems attrs, bool is_unsafe=false)
{
TRACE_FUNCTION;