diff options
author | John Hodge <tpg@mutabah.net> | 2016-03-19 12:35:08 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-03-19 12:35:08 +0800 |
commit | d9ddf019fe73c78213cddac02c700b6ebf782de4 (patch) | |
tree | ea8120e3fae11cbb8b0e66607e3680205bdb7046 /src | |
parent | 485dfcb3fe4ddfeb7c0342ec288807fde3ef9504 (diff) | |
download | mrust-d9ddf019fe73c78213cddac02c700b6ebf782de4.tar.gz |
Expand - Handle impl and trait
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/ast.hpp | 3 | ||||
-rw-r--r-- | src/expand/mod.cpp | 105 | ||||
-rw-r--r-- | src/parse/common.hpp | 1 | ||||
-rw-r--r-- | src/parse/root.cpp | 2 |
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;
|