From fc9a04403eb5b694d37f77baa0de2f8e363f46f1 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 22 Mar 2015 14:46:48 +0800 Subject: Parsing "Composite" DSTs (Trait + Trait2 + Trait3) --- src/parse/root.cpp | 2 ++ src/parse/types.cpp | 28 +++++++++++++++++++++++----- src/types.hpp | 8 ++++++++ 3 files changed, 33 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/parse/root.cpp b/src/parse/root.cpp index c88b51a5..759c65ac 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -666,6 +666,8 @@ AST::Impl Parse_Impl(TokenStream& lex, bool is_unsafe/*=false*/) lex.putback(tok); impl_type = Parse_Type(lex); + // TODO: Handle the "impl Any + Send" syntax here + if( GET_TOK(tok, lex) == TOK_RWORD_FOR ) { // Implementing a trait for another type, get the target type diff --git a/src/parse/types.cpp b/src/parse/types.cpp index aa29af64..57c1bad8 100644 --- a/src/parse/types.cpp +++ b/src/parse/types.cpp @@ -65,6 +65,7 @@ TypeRef Parse_Type(TokenStream& lex) // '<' - An associated type cast case TOK_LT: { DEBUG("Associated type"); + // TODO: This should instead use the path code, not a special case in typing // ::Inner TypeRef base = Parse_Type(lex); GET_CHECK_TOK(tok, lex, TOK_RWORD_AS); @@ -86,12 +87,29 @@ TypeRef Parse_Type(TokenStream& lex) if( tok.str() == CORETYPES[i].name ) return TypeRef(TypeRef::TagPrimitive(), CORETYPES[i].type); } - lex.putback(tok); - return TypeRef(TypeRef::TagPath(), Parse_Path(lex, false, PATH_GENERIC_TYPE)); // relative path + // - Fall through to path handling // '::' - Absolute path - case TOK_DOUBLE_COLON: - // Path with generics - return TypeRef(TypeRef::TagPath(), Parse_Path(lex, true, PATH_GENERIC_TYPE)); + case TOK_DOUBLE_COLON: { + lex.putback(tok); + ::std::vector traits; + ::std::vector< ::std::string> lifetimes; + do { + if( LOOK_AHEAD(lex) == TOK_LIFETIME ) { + GET_TOK(tok, lex); + lifetimes.push_back( tok.str() ); + } + else + traits.push_back( Parse_Path(lex, PATH_GENERIC_TYPE) ); + } while( GET_TOK(tok, lex) == TOK_PLUS ); + lex.putback(tok); + if( traits.size() > 1 || lifetimes.size() > 0 ) { + if( lifetimes.size() ) + DEBUG("TODO: Lifetime bounds on trait objects"); + return TypeRef(::std::move(traits)); + } + else + return TypeRef(TypeRef::TagPath(), traits.at(0)); + } // 'super' - Parent relative path case TOK_RWORD_SUPER: GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON); diff --git a/src/types.hpp b/src/types.hpp index 9505f2cd..86733ad1 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -55,6 +55,7 @@ class TypeRef: ARRAY, GENERIC, PATH, + MULTIDST, // Multi-trait DST (e.g. Trait + Send + Sync) ASSOCIATED, }; @@ -147,6 +148,13 @@ public: TypeRef(TagPath(), ::std::move(path)) {} + TypeRef( ::std::vector traits ): + m_class(MULTIDST) + { + for( auto& t : traits ) + m_inner_types.push_back( TypeRef(::std::move(t)) ); + } + struct TagAssoc {}; TypeRef(TagAssoc, TypeRef base, TypeRef trait, ::std::string assoc_name): TypeRef(::std::move(base), ::std::move(trait), ::std::move(assoc_name)) -- cgit v1.2.3