From 66fcd19348efb2e16a21124c4465f4b911d87ded Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 20 Mar 2015 09:26:22 +0800 Subject: Lifetime bounds, pattern fragments, nested modules --- src/ast/ast.cpp | 7 ++++--- src/ast/ast.hpp | 14 +++++++++----- src/macros.cpp | 5 +++++ src/macros.hpp | 1 + src/parse/expr.cpp | 9 +++++++++ src/parse/root.cpp | 34 ++++++++++++++++++---------------- src/parse/tokentree.hpp | 1 + 7 files changed, 47 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 37cb17b6..42052c5e 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -674,14 +674,15 @@ SERIALISE_TYPE(TypeParam::, "AST_TypeParam", { ::std::ostream& operator<<(::std::ostream& os, const GenericBound& x) { os << x.m_type << ": "; - if( x.m_lifetime != "" ) - return os << "'" << x.m_lifetime; + if( x.m_lifetime_bound != "" ) + return os << "'" << x.m_lifetime_bound; else return os << x.m_trait; } SERIALISE_TYPE_S(GenericBound, { + s.item(m_lifetime_test); s.item(m_type); - s.item(m_lifetime); + s.item(m_lifetime_bound); s.item(m_trait); }) diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 8274f22f..6ef0d85a 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -58,18 +58,22 @@ public: class GenericBound: public Serialisable { + ::std::string m_lifetime_test; // if "", use m_type TypeRef m_type; - ::std::string m_lifetime; - + ::std::string m_lifetime_bound; // if "", use m_trait bool m_optional; AST::Path m_trait; public: GenericBound() {} + GenericBound(::std::string test, ::std::string bound): + m_lifetime_test( ::std::move(test) ), + m_lifetime_bound( ::std::move(bound) ) + { } GenericBound(TypeRef type, ::std::string lifetime): m_type( ::std::move(type) ), - m_lifetime(lifetime) + m_lifetime_bound( ::std::move(lifetime) ) { } GenericBound(TypeRef type, AST::Path trait, bool optional=false): m_type( ::std::move(type) ), @@ -77,8 +81,8 @@ public: m_trait( ::std::move(trait) ) { } - bool is_trait() const { return m_lifetime == ""; } - const ::std::string& lifetime() const { return m_lifetime; } + bool is_trait() const { return m_lifetime_bound == ""; } + const ::std::string& lifetime() const { return m_lifetime_bound; } const TypeRef& test() const { return m_type; } const AST::Path& bound() const { return m_trait; } diff --git a/src/macros.cpp b/src/macros.cpp index 841758f1..1dd4f16b 100644 --- a/src/macros.cpp +++ b/src/macros.cpp @@ -227,6 +227,9 @@ void Macro_HandlePattern(TTStream& lex, const MacroPatEnt& pat, unsigned int lay lex.putback(tok); val = Parse_TT(lex, false); if(0) + case MacroPatEnt::PAT_PAT: + val = Parse_TT_Pattern(lex); + if(0) case MacroPatEnt::PAT_TYPE: val = Parse_TT_Type(lex); if(0) @@ -631,6 +634,7 @@ void operator%(Serialiser& s, MacroPatEnt::Type c) { #define _(v) case MacroPatEnt::v: s << #v; return _(PAT_TOKEN); _(PAT_TT); + _(PAT_PAT); _(PAT_TYPE); _(PAT_EXPR); _(PAT_LOOP); @@ -649,6 +653,7 @@ void operator%(::Deserialiser& s, MacroPatEnt::Type& c) { if(0) ; _(PAT_TOKEN); _(PAT_TT); + _(PAT_PAT); _(PAT_TYPE); _(PAT_EXPR); _(PAT_LOOP); diff --git a/src/macros.hpp b/src/macros.hpp index df16a4c5..05c337b0 100644 --- a/src/macros.hpp +++ b/src/macros.hpp @@ -63,6 +63,7 @@ struct MacroPatEnt: enum Type { PAT_TOKEN, PAT_TT, + PAT_PAT, PAT_IDENT, PAT_PATH, PAT_TYPE, diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 7f600385..8a3490d3 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -1407,6 +1407,15 @@ TokenTree Parse_TT_Expr(TokenStream& lex) return wlex.get_output(); } +TokenTree Parse_TT_Pattern(TokenStream& lex) +{ + TRACE_FUNCTION; + TTLexer wlex(lex); + + Parse_Pattern(wlex); + + return wlex.get_output(); +} TokenTree Parse_TT_Stmt(TokenStream& lex) { throw ParseError::Todo("Parse_TT_Stmt"); diff --git a/src/parse/root.cpp b/src/parse/root.cpp index f1e1acf9..7f2ed359 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -408,16 +408,19 @@ AST::TypeParams Parse_TypeParams(TokenStream& lex) { if( is_lifetime ) { - throw ParseError::Todo(lex, "lifetime param conditions"); + do { + GET_CHECK_TOK(tok, lex, TOK_LIFETIME); + ret.add_bound( AST::GenericBound( param_name, tok.str() ) ); + } while( GET_TOK(tok, lex) == TOK_PLUS ); } else { Parse_TypeBound(lex, ret, TypeRef(TypeRef::TagArg(), param_name)); + GET_TOK(tok, lex); } - GET_TOK(tok, lex); } - if( tok.type() == TOK_EQUAL ) + if( !is_lifetime && tok.type() == TOK_EQUAL ) { ret.params().back().setDefault( Parse_Type(lex) ); GET_TOK(tok, lex); @@ -1254,6 +1257,8 @@ void Parse_Use(TokenStream& lex, ::std::function ; else if( type == "tt" ) ret.push_back( MacroPatEnt(name, MacroPatEnt::PAT_TT) ); + else if( type == "pat" ) + ret.push_back( MacroPatEnt(name, MacroPatEnt::PAT_PAT) ); else if( type == "ident" ) ret.push_back( MacroPatEnt(name, MacroPatEnt::PAT_IDENT) ); else if( type == "path" ) @@ -1468,17 +1473,9 @@ void Parse_ModRoot_Items(TokenStream& lex, AST::Crate& crate, AST::Module& mod, switch(GET_TOK(tok, lex)) { case TOK_BRACE_CLOSE: - if( !nested_module ) { - DEBUG("Brace close in file root"); - throw ParseError::Unexpected(lex, tok); - } - return ; case TOK_EOF: - if( nested_module ) { - DEBUG("EOF in nested module"); - throw ParseError::Unexpected(lex, tok); - } - return ; + lex.putback(tok); + return; default: lex.putback(tok); break; @@ -1683,9 +1680,11 @@ void Parse_ModRoot_Items(TokenStream& lex, AST::Crate& crate, AST::Module& mod, DEBUG("Sub module '"<