summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2015-03-20 09:26:22 +0800
committerJohn Hodge <tpg@mutabah.net>2015-03-20 09:26:22 +0800
commit66fcd19348efb2e16a21124c4465f4b911d87ded (patch)
tree3d8f4e8749247da4dafbb090e089c964e418ba30
parente34c31e1090fe83b70dc98b8d16bbbbc29c33517 (diff)
downloadmrust-66fcd19348efb2e16a21124c4465f4b911d87ded.tar.gz
Lifetime bounds, pattern fragments, nested modules
-rw-r--r--src/ast/ast.cpp7
-rw-r--r--src/ast/ast.hpp14
-rw-r--r--src/macros.cpp5
-rw-r--r--src/macros.hpp1
-rw-r--r--src/parse/expr.cpp9
-rw-r--r--src/parse/root.cpp34
-rw-r--r--src/parse/tokentree.hpp1
7 files changed, 47 insertions, 24 deletions
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<void(AST::Path, ::std::string)>
;
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 '"<<name<<"'");
switch( GET_TOK(tok, lex) )
{
- case TOK_BRACE_OPEN:
- Parse_ModRoot(lex, crate, submod, &modstack, "-");
- break;
+ case TOK_BRACE_OPEN: {
+ ::std::string subpath = ( path.back() != '/' ? "-" : path + name + "/" );
+ Parse_ModRoot(lex, crate, submod, &modstack, subpath);
+ GET_CHECK_TOK(tok, lex, TOK_BRACE_CLOSE);
+ break; }
case TOK_SEMICOLON:
DEBUG("Mod = " << name << ", curpath = " << path);
if( path == "-" || path == "!" ) {
@@ -1707,6 +1706,7 @@ void Parse_ModRoot_Items(TokenStream& lex, AST::Crate& crate, AST::Module& mod,
::std::string newdir( newpath_dir.begin(), newpath_dir.begin() + newpath_dir.find_last_of('/') );
Lexer sub_lex(newpath_dir);
Parse_ModRoot(sub_lex, crate, submod, &modstack, newdir);
+ GET_CHECK_TOK(tok, sub_lex, TOK_EOF);
}
}
else
@@ -1724,12 +1724,14 @@ void Parse_ModRoot_Items(TokenStream& lex, AST::Crate& crate, AST::Module& mod,
// Load from dir
Lexer sub_lex(newpath_dir + "mod.rs");
Parse_ModRoot(sub_lex, crate, submod, &modstack, newpath_dir);
+ GET_CHECK_TOK(tok, sub_lex, TOK_EOF);
}
else if( ifs_file.is_open() )
{
// Load from file
Lexer sub_lex(newpath_file);
Parse_ModRoot(sub_lex, crate, submod, &modstack, newpath_file);
+ GET_CHECK_TOK(tok, sub_lex, TOK_EOF);
}
else
{
diff --git a/src/parse/tokentree.hpp b/src/parse/tokentree.hpp
index 2eb967ac..34418340 100644
--- a/src/parse/tokentree.hpp
+++ b/src/parse/tokentree.hpp
@@ -59,6 +59,7 @@ protected:
// unwrapped = Exclude the enclosing brackets (used by macro parse code)
extern TokenTree Parse_TT(TokenStream& lex, bool unwrapped);
+extern TokenTree Parse_TT_Pattern(TokenStream& lex);
extern TokenTree Parse_TT_Expr(TokenStream& lex);
extern TokenTree Parse_TT_Type(TokenStream& lex);
extern TokenTree Parse_TT_Stmt(TokenStream& lex);