summaryrefslogtreecommitdiff
path: root/src/parse
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2018-05-20 22:01:59 +0800
committerJohn Hodge <tpg@mutabah.net>2018-05-20 22:01:59 +0800
commitde9ecd7a2d70359b34e77ded57e5aa9284345ac5 (patch)
tree29ab42c6c06960720bd67f0b8ebaec807ad0284e /src/parse
parent134be5198993096ab5216b6d52a8937430c733b0 (diff)
downloadmrust-de9ecd7a2d70359b34e77ded57e5aa9284345ac5.tar.gz
AST - Refactor lifetime/HRB handling
Diffstat (limited to 'src/parse')
-rw-r--r--src/parse/common.hpp2
-rw-r--r--src/parse/paths.cpp4
-rw-r--r--src/parse/root.cpp52
-rw-r--r--src/parse/tokenstream.cpp4
-rw-r--r--src/parse/types.cpp77
5 files changed, 85 insertions, 54 deletions
diff --git a/src/parse/common.hpp b/src/parse/common.hpp
index 1ca86128..49499c86 100644
--- a/src/parse/common.hpp
+++ b/src/parse/common.hpp
@@ -40,7 +40,7 @@ extern ::std::vector<AST::PathNode> Parse_PathNodes(TokenStream& lex, eParsePath
extern AST::PathParams Parse_Path_GenericList(TokenStream& lex);
-extern ::std::vector< ::std::string> Parse_HRB(TokenStream& lex);
+extern AST::HigherRankedBounds Parse_HRB(TokenStream& lex);
extern AST::AttributeList Parse_ItemAttrs(TokenStream& lex);
extern void Parse_ParentAttrs(TokenStream& lex, AST::AttributeList& out);
extern AST::Attribute Parse_MetaItem(TokenStream& lex);
diff --git a/src/parse/paths.cpp b/src/parse/paths.cpp
index 59b6b939..d103840e 100644
--- a/src/parse/paths.cpp
+++ b/src/parse/paths.cpp
@@ -203,7 +203,7 @@ AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generi
Token tok;
::std::vector<TypeRef> types;
- ::std::vector< ::std::string> lifetimes;
+ ::std::vector<AST::LifetimeRef> lifetimes;
::std::vector< ::std::pair< ::std::string, TypeRef > > assoc_bounds;
do {
@@ -214,7 +214,7 @@ AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generi
switch(GET_TOK(tok, lex))
{
case TOK_LIFETIME:
- lifetimes.push_back( tok.str() );
+ lifetimes.push_back(AST::LifetimeRef(/*lex.point_span(),*/ lex.get_ident(mv$(tok)) ));
break;
case TOK_IDENT:
if( LOOK_AHEAD(lex) == TOK_EQUAL )
diff --git a/src/parse/root.cpp b/src/parse/root.cpp
index 35da3a76..2b027bf9 100644
--- a/src/parse/root.cpp
+++ b/src/parse/root.cpp
@@ -119,12 +119,12 @@ bool Parse_Publicity(TokenStream& lex, bool allow_restricted=true)
}
}
-::std::vector< ::std::string> Parse_HRB(TokenStream& lex)
+::AST::HigherRankedBounds Parse_HRB(TokenStream& lex)
{
TRACE_FUNCTION;
Token tok;
- ::std::vector< ::std::string> lifetimes;
+ ::AST::HigherRankedBounds rv;
GET_CHECK_TOK(tok, lex, TOK_LT);
do {
auto attrs = Parse_ItemAttrs(lex);
@@ -133,17 +133,25 @@ bool Parse_Publicity(TokenStream& lex, bool allow_restricted=true)
switch(GET_TOK(tok, lex))
{
case TOK_LIFETIME:
- lifetimes.push_back(tok.str());
+ rv.m_lifetimes.push_back(::AST::LifetimeParam(lex.point_span(), ::std::move(attrs), Ident(lex.getHygiene(), tok.str())));
break;
default:
throw ParseError::Unexpected(lex, tok, Token(TOK_LIFETIME));
}
} while( GET_TOK(tok, lex) == TOK_COMMA );
CHECK_TOK(tok, TOK_GT);
- return lifetimes;
+ return rv;
+}
+
+namespace {
+ AST::LifetimeRef get_LifetimeRef(TokenStream& lex, Token tok)
+ {
+ CHECK_TOK(tok, TOK_LIFETIME);
+ return AST::LifetimeRef(/*lex.point_span(), */Ident(lex.getHygiene(), mv$(tok.str())));
+ }
}
/// Parse type parameters in a definition
-void Parse_TypeBound(TokenStream& lex, AST::GenericParams& ret, TypeRef checked_type, ::std::vector< ::std::string> lifetimes = {})
+void Parse_TypeBound(TokenStream& lex, AST::GenericParams& ret, TypeRef checked_type, AST::HigherRankedBounds outer_hrbs = {})
{
TRACE_FUNCTION;
Token tok;
@@ -156,10 +164,9 @@ void Parse_TypeBound(TokenStream& lex, AST::GenericParams& ret, TypeRef checked_
// return;
//}
- ::std::vector< ::std::string> hrls;
if(GET_TOK(tok, lex) == TOK_LIFETIME) {
ret.add_bound(AST::GenericBound::make_TypeLifetime( {
- checked_type.clone(), tok.str()
+ checked_type.clone(), get_LifetimeRef(lex, mv$(tok))
} ));
}
else if( tok.type() == TOK_QMARK ) {
@@ -168,17 +175,17 @@ void Parse_TypeBound(TokenStream& lex, AST::GenericParams& ret, TypeRef checked_
} ));
}
else {
+ ::AST::HigherRankedBounds inner_hrls;
if( tok.type() == TOK_RWORD_FOR )
{
- hrls = Parse_HRB(lex);
+ inner_hrls = Parse_HRB(lex);
}
else {
PUTBACK(tok, lex);
}
- (void)hrls; // TODO: HRLs
ret.add_bound( AST::GenericBound::make_IsTrait({
- checked_type.clone(), mv$(lifetimes), Parse_Path(lex, PATH_GENERIC_TYPE)
+ mv$(outer_hrbs), checked_type.clone(), mv$(inner_hrls), Parse_Path(lex, PATH_GENERIC_TYPE)
}) );
}
} while( GET_TOK(tok, lex) == TOK_PLUS );
@@ -199,14 +206,12 @@ AST::GenericParams Parse_GenericParams(TokenStream& lex)
PUTBACK(tok, lex);
auto attrs = Parse_ItemAttrs(lex);
- (void)attrs; // TODO: Attributes on generic params
GET_TOK(tok, lex);
if( tok.type() == TOK_IDENT )
{
- // TODO: Hygine
::std::string param_name = mv$(tok.str());
- ret.add_ty_param( AST::TypeParam( param_name ) );
+ ret.add_ty_param( AST::TypeParam( lex.point_span(), ::std::move(attrs), param_name ) );
auto param_ty = TypeRef(lex.point_span(), param_name);
if( GET_TOK(tok, lex) == TOK_COLON )
@@ -223,14 +228,14 @@ AST::GenericParams Parse_GenericParams(TokenStream& lex)
}
else if( tok.type() == TOK_LIFETIME )
{
- // TODO: Should lifetimes have hygine?
- ::std::string param_name = tok.str();
- ret.add_lft_param( param_name );
+ auto param_name = tok.str();
+ auto ref = get_LifetimeRef(lex, mv$(tok));
+ ret.add_lft_param(::AST::LifetimeParam(lex.point_span(), ::std::move(attrs), Ident(lex.getHygiene(), param_name) ));
if( GET_TOK(tok, lex) == TOK_COLON )
{
do {
GET_CHECK_TOK(tok, lex, TOK_LIFETIME);
- ret.add_bound(AST::GenericBound::make_Lifetime( {param_name, tok.str()} ));
+ ret.add_bound(AST::GenericBound::make_Lifetime({ AST::LifetimeRef(ref), get_LifetimeRef(lex, mv$(tok)) }));
} while( GET_TOK(tok, lex) == TOK_PLUS );
}
}
@@ -258,11 +263,11 @@ void Parse_WhereClause(TokenStream& lex, AST::GenericParams& params)
if( tok.type() == TOK_LIFETIME )
{
- auto lhs = mv$(tok.str());
+ auto lhs = get_LifetimeRef(lex, mv$(tok));
GET_CHECK_TOK(tok, lex, TOK_COLON);
do {
GET_CHECK_TOK(tok, lex, TOK_LIFETIME);
- auto rhs = mv$(tok.str());
+ auto rhs = get_LifetimeRef(lex, mv$(tok));
params.add_bound( AST::GenericBound::make_Lifetime({lhs, rhs}) );
} while( GET_TOK(tok, lex) == TOK_PLUS );
PUTBACK(tok, lex);
@@ -270,11 +275,11 @@ void Parse_WhereClause(TokenStream& lex, AST::GenericParams& params)
// Higher-ranked types/lifetimes
else if( tok.type() == TOK_RWORD_FOR )
{
- ::std::vector< ::std::string> lifetimes = Parse_HRB(lex);
+ auto hrbs = Parse_HRB(lex);
TypeRef type = Parse_Type(lex);
GET_CHECK_TOK(tok, lex, TOK_COLON);
- Parse_TypeBound(lex,params, mv$(type), mv$(lifetimes));
+ Parse_TypeBound(lex,params, mv$(type), mv$(hrbs));
}
else
{
@@ -355,9 +360,9 @@ AST::Function Parse_FunctionDef(TokenStream& lex, ::std::string abi, bool allow_
if( lex.lookahead(ofs) == TOK_RWORD_SELF || (lex.lookahead(ofs) == TOK_RWORD_MUT && lex.lookahead(ofs+1) == TOK_RWORD_SELF) )
{
auto ps = lex.start_span();
- ::std::string lifetime;
+ AST::LifetimeRef lifetime;
if( GET_TOK(tok, lex) == TOK_LIFETIME ) {
- lifetime = tok.str();
+ lifetime = get_LifetimeRef(lex, mv$(tok));
GET_TOK(tok, lex);
}
auto ty_sp = lex.end_span(ps);
@@ -622,6 +627,7 @@ AST::Trait Parse_TraitDef(TokenStream& lex, const AST::AttributeList& meta_items
do {
if( GET_TOK(tok, lex) == TOK_LIFETIME ) {
// TODO: Need a better way of indiciating 'static than just an invalid path
+ // TODO: Ensure that it's 'static
supertraits.push_back( make_spanned( Span(tok.get_pos()), AST::Path() ) );
}
else if( tok.type() == TOK_BRACE_OPEN ) {
diff --git a/src/parse/tokenstream.cpp b/src/parse/tokenstream.cpp
index 625f12db..611df2ff 100644
--- a/src/parse/tokenstream.cpp
+++ b/src/parse/tokenstream.cpp
@@ -140,6 +140,10 @@ Ident TokenStream::get_ident(Token tok) const
if(tok.type() == TOK_IDENT) {
return Ident(getHygiene(), tok.str());
}
+ else if(tok.type() == TOK_LIFETIME) {
+ // TODO: Maybe only when it's explicitly asked for?
+ return Ident(getHygiene(), tok.str());
+ }
else if( tok.type() == TOK_INTERPOLATED_IDENT ) {
TODO(getPosition(), "get_ident from TOK_INTERPOLATED_IDENT");
}
diff --git a/src/parse/types.cpp b/src/parse/types.cpp
index 26785cf7..b0b43426 100644
--- a/src/parse/types.cpp
+++ b/src/parse/types.cpp
@@ -13,8 +13,8 @@
// === PROTOTYPES ===
//TypeRef Parse_Type(TokenStream& lex, bool allow_trait_list);
TypeRef Parse_Type_Int(TokenStream& lex, bool allow_trait_list);
-TypeRef Parse_Type_Fn(TokenStream& lex, ::std::vector<::std::string> hrls = {});
-TypeRef Parse_Type_Path(TokenStream& lex, ::std::vector<::std::string> hrls, bool allow_trait_list);
+TypeRef Parse_Type_Fn(TokenStream& lex, AST::HigherRankedBounds hrbs = {});
+TypeRef Parse_Type_Path(TokenStream& lex, AST::HigherRankedBounds hrbs, bool allow_trait_list);
TypeRef Parse_Type_ErasedType(TokenStream& lex, bool allow_trait_list);
// === CODE ===
@@ -196,7 +196,7 @@ TypeRef Parse_Type_Int(TokenStream& lex, bool allow_trait_list)
throw ParseError::BugCheck("Reached end of Parse_Type");
}
-TypeRef Parse_Type_Fn(TokenStream& lex, ::std::vector<::std::string> hrls)
+TypeRef Parse_Type_Fn(TokenStream& lex, ::AST::HigherRankedBounds hrbs)
{
auto ps = lex.start_span();
// TODO: HRLs
@@ -262,36 +262,52 @@ TypeRef Parse_Type_Fn(TokenStream& lex, ::std::vector<::std::string> hrls)
return TypeRef(TypeRef::TagFunction(), lex.end_span(ps), is_unsafe, mv$(abi), mv$(args), is_variadic, mv$(ret_type));
}
-TypeRef Parse_Type_Path(TokenStream& lex, ::std::vector<::std::string> hrls, bool allow_trait_list)
+TypeRef Parse_Type_Path(TokenStream& lex, ::AST::HigherRankedBounds hrbs, bool allow_trait_list)
{
Token tok;
auto ps = lex.start_span();
- if( ! allow_trait_list )
+ if( hrbs.empty() && !allow_trait_list )
{
return TypeRef(TypeRef::TagPath(), lex.end_span(ps), Parse_Path(lex, PATH_GENERIC_TYPE));
}
else
{
- ::std::vector<AST::Path> traits;
- ::std::vector< ::std::string> lifetimes;
- do {
- if( LOOK_AHEAD(lex) == TOK_LIFETIME ) {
- GET_TOK(tok, lex);
- lifetimes.push_back( tok.str() );
+ ::std::vector<Type_TraitPath> traits;
+ ::std::vector<AST::LifetimeRef> lifetimes;
+
+ traits.push_back(Type_TraitPath { mv$(hrbs), Parse_Path(lex, PATH_GENERIC_TYPE) });
+
+ if( allow_trait_list )
+ {
+ while( GET_TOK(tok, lex) == TOK_PLUS )
+ {
+ if( LOOK_AHEAD(lex) == TOK_LIFETIME ) {
+ GET_TOK(tok, lex);
+ lifetimes.push_back(AST::LifetimeRef( /*lex.point_span(),*/ lex.get_ident(mv$(tok)) ));
+ }
+ else
+ {
+ if( lex.lookahead(0) == TOK_RWORD_FOR )
+ {
+ hrbs = Parse_HRB(lex);
+ }
+ traits.push_back({ mv$(hrbs), Parse_Path(lex, PATH_GENERIC_TYPE) });
+ }
}
- else
- traits.push_back( Parse_Path(lex, PATH_GENERIC_TYPE) );
- } while( GET_TOK(tok, lex) == TOK_PLUS );
- PUTBACK(tok, lex);
- if( hrls.size() > 0 || traits.size() > 1 || lifetimes.size() > 0 ) {
- if( lifetimes.size() )
- DEBUG("TODO: Lifetime bounds on trait objects");
- return TypeRef(lex.end_span(ps), mv$(hrls), ::std::move(traits));
+ PUTBACK(tok, lex);
}
- else {
- return TypeRef(TypeRef::TagPath(), lex.end_span(ps), mv$(traits.at(0)));
+
+ if( !traits[0].hrbs.empty() || traits.size() > 1 || lifetimes.size() > 0 )
+ {
+ if( lifetimes.empty())
+ lifetimes.push_back(AST::LifetimeRef());
+ return TypeRef(lex.end_span(ps), mv$(traits), mv$(lifetimes));
+ }
+ else
+ {
+ return TypeRef(TypeRef::TagPath(), lex.end_span(ps), mv$(traits.at(0).path));
}
}
}
@@ -300,20 +316,25 @@ TypeRef Parse_Type_ErasedType(TokenStream& lex, bool allow_trait_list)
Token tok;
auto ps = lex.start_span();
- ::std::vector<AST::Path> traits;
- ::std::vector< ::std::string> lifetimes;
+ ::std::vector<Type_TraitPath> traits;
+ ::std::vector<AST::LifetimeRef> lifetimes;
do {
if( LOOK_AHEAD(lex) == TOK_LIFETIME ) {
GET_TOK(tok, lex);
- lifetimes.push_back( tok.str() );
+ lifetimes.push_back(AST::LifetimeRef( /*lex.point_span(),*/ lex.get_ident(mv$(tok)) ));
}
else
- traits.push_back( Parse_Path(lex, PATH_GENERIC_TYPE) );
+ {
+ AST::HigherRankedBounds hrbs;
+ if( lex.lookahead(0) == TOK_RWORD_FOR )
+ {
+ hrbs = Parse_HRB(lex);
+ }
+ traits.push_back({ mv$(hrbs), Parse_Path(lex, PATH_GENERIC_TYPE) });
+ }
} while( GET_TOK(tok, lex) == TOK_PLUS );
PUTBACK(tok, lex);
- if( lifetimes.size() )
- DEBUG("TODO: Lifetime bounds on erased types");
- return TypeRef(lex.end_span(ps), TypeData::make_ErasedType({ {}, mv$(traits) }));
+ return TypeRef(lex.end_span(ps), TypeData::make_ErasedType({ mv$(traits), mv$(lifetimes) }));
}