diff options
author | John Hodge <tpg@mutabah.net> | 2016-05-02 12:51:05 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-05-02 12:51:05 +0800 |
commit | 809ac4b7f439a6f5b0fe97d3215ad79e510f4c10 (patch) | |
tree | 8cf11a34fd0c92d9a2a3e0aea3e2ade1a1df1d49 /src | |
parent | a87c8d9ce4b789ba26146f2f574937558687789a (diff) | |
download | mrust-809ac4b7f439a6f5b0fe97d3215ad79e510f4c10.tar.gz |
AST - Make trait in UFCS paths be an optional Path
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/path.cpp | 35 | ||||
-rw-r--r-- | src/ast/path.hpp | 16 | ||||
-rw-r--r-- | src/main.cpp | 2 | ||||
-rw-r--r-- | src/parse/expr.cpp | 17 | ||||
-rw-r--r-- | src/parse/paths.cpp | 24 | ||||
-rw-r--r-- | src/parse/root.cpp | 2 | ||||
-rw-r--r-- | src/resolve/absolute.cpp | 25 |
7 files changed, 80 insertions, 41 deletions
diff --git a/src/ast/path.cpp b/src/ast/path.cpp index 5b1ba2f8..484ac7b7 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -58,14 +58,6 @@ PathNode::PathNode(::std::string name, ::std::vector<TypeRef> args): m_params(args) { } -const ::std::string& PathNode::name() const -{ - return m_name; -} -const ::std::vector<TypeRef>& PathNode::args() const -{ - return m_params; -} Ordering PathNode::ord(const PathNode& x) const { Ordering rv; @@ -109,7 +101,11 @@ typename ::std::vector<Named<T> >::const_iterator find_named(const ::std::vector } // --- AST::Path -AST::Path::Path(TagUfcs, TypeRef type, TypeRef trait, ::std::vector<AST::PathNode> nodes): +AST::Path::Path(TagUfcs, TypeRef type, ::std::vector<AST::PathNode> nodes): + m_class( AST::Path::Class::make_UFCS({box$(type), nullptr, nodes}) ) +{ +} +AST::Path::Path(TagUfcs, TypeRef type, Path trait, ::std::vector<AST::PathNode> nodes): m_class( AST::Path::Class::make_UFCS({box$(type), box$(trait), nodes}) ) { } @@ -136,7 +132,10 @@ AST::Path::Path(const Path& x): m_class = Class::make_Absolute({nodes: ent.nodes}); ), (UFCS, - m_class = Class::make_UFCS({ box$(TypeRef(*ent.type)), box$(TypeRef(*ent.trait)), ent.nodes }); + if( ent.trait ) + m_class = Class::make_UFCS({ box$(TypeRef(*ent.type)), ::std::unique_ptr<Path>(new Path(*ent.trait)), ent.nodes }); + else + m_class = Class::make_UFCS({ box$(TypeRef(*ent.type)), nullptr, ent.nodes }); ) ) @@ -505,8 +504,15 @@ void Path::print_pretty(::std::ostream& os, bool is_type_context) const ), (UFCS, //os << "/*ufcs*/"; - if( ! ent.trait->m_data.is_None() ) { - os << "<" << *ent.type << " as " << *ent.trait << ">"; + if( ent.trait ) { + os << "<" << *ent.type << " as "; + if( ent.trait->m_class.is_Invalid() ) { + os << "_"; + } + else { + os << *ent.trait; + } + os << ">"; } else { os << "<" << *ent.type << ">"; @@ -546,6 +552,11 @@ void operator%(::Deserialiser& s, Path::Class::Tag& c) { c = Path::Class::tag_from_str(n); } #define _D(VAR, ...) case Class::TAG_##VAR: { m_class = Class::make_null_##VAR(); auto& ent = m_class.as_##VAR(); (void)&ent; __VA_ARGS__ } break; +::std::unique_ptr<Path> Path::from_deserialiser(Deserialiser& s) { + Path p; + s.item(p); + return ::std::unique_ptr<Path>( new Path( mv$(p) ) ); +} SERIALISE_TYPE(Path::, "AST_Path", { s % m_class.tag(); TU_MATCH(Path::Class, (m_class), (ent), diff --git a/src/ast/path.hpp b/src/ast/path.hpp index 3b2b9969..462ab946 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -91,9 +91,9 @@ class PathNode: public: PathNode() {} PathNode(::std::string name, ::std::vector<TypeRef> args = {}); - const ::std::string& name() const; - ::std::vector<TypeRef>& args() { return m_params; } - const ::std::vector<TypeRef>& args() const; + const ::std::string& name() const { return m_name; } + ::std::vector<TypeRef>& args() { return m_params; } + const ::std::vector<TypeRef>& args() const { return m_params; } Ordering ord(const PathNode& x) const; void print_pretty(::std::ostream& os, bool is_type_context) const; @@ -127,8 +127,8 @@ public: ::std::vector<PathNode> nodes; } ), (UFCS, struct { // Type-relative - ::std::unique_ptr<TypeRef> type; - ::std::unique_ptr<TypeRef> trait; + ::std::unique_ptr<TypeRef> type; // always non-null + ::std::unique_ptr<Path> trait; // nullptr = inherent, Invalid = unknown trait ::std::vector<PathNode> nodes; } ) ); @@ -166,9 +166,8 @@ public: // UFCS struct TagUfcs {}; - // TODO: Replace with "Path(TagUfcs, TypeRef, Path, PathNode)" and "Path(TagUfcs, TypeRef, PathNode)" - // - Making Class::UFCS.trait be a nullable Path pointer - Path(TagUfcs, TypeRef type, TypeRef trait, ::std::vector<PathNode> nodes={}); + Path(TagUfcs, TypeRef type, ::std::vector<PathNode> nodes={}); + Path(TagUfcs, TypeRef type, Path trait, ::std::vector<PathNode> nodes={}); // VARIABLE struct TagLocal {}; @@ -324,6 +323,7 @@ public: bool operator!=(const Path& x) const { return ord(x) != OrdEqual; } bool operator<(const Path& x) const { return ord(x) != OrdLess; } + static ::std::unique_ptr<Path> from_deserialiser(Deserialiser& s); SERIALISABLE_PROTOTYPES(); void print_pretty(::std::ostream& os, bool is_type_context) const; friend ::std::ostream& operator<<(::std::ostream& os, const Path& path); diff --git a/src/main.cpp b/src/main.cpp index 07e25f0f..2030a663 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -122,7 +122,7 @@ int main(int argc, char *argv[]) //Resolve_UfcsPaths(crate);
// OLD resolve code, kinda bad
- ResolvePaths(crate);
+ //ResolvePaths(crate);
});
// XXX: Dump crate before typecheck
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 407afbf3..3c12941d 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -964,16 +964,19 @@ ExprNodeP Parse_ExprVal(TokenStream& lex) lex.putback(tok);
case TOK_LT: {
TypeRef ty = Parse_Type(lex);
- TypeRef trait;// = TypeRef(TypeRef::TagInvalid());
if( GET_TOK(tok, lex) == TOK_RWORD_AS ) {
- trait = Parse_Type(lex);
+ auto trait = Parse_Path(lex, PATH_GENERIC_TYPE);
+ GET_CHECK_TOK(tok, lex, TOK_GT);
+ GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON);
+ path = AST::Path(AST::Path::TagUfcs(), ty, trait, Parse_PathNodes(lex, PATH_GENERIC_EXPR));
}
- else
+ else {
lex.putback(tok);
- GET_CHECK_TOK(tok, lex, TOK_GT);
- // TODO: Terminating the "path" here is sometimes valid
- GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON);
- path = AST::Path(AST::Path::TagUfcs(), ty, trait, Parse_PathNodes(lex, PATH_GENERIC_EXPR));
+ GET_CHECK_TOK(tok, lex, TOK_GT);
+ // TODO: Terminating the "path" here is sometimes valid
+ GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON);
+ path = AST::Path(AST::Path::TagUfcs(), ty, Parse_PathNodes(lex, PATH_GENERIC_EXPR));
+ }
}
if(0)
case TOK_RWORD_SELF:
diff --git a/src/parse/paths.cpp b/src/parse/paths.cpp index 1e0ddac1..2e463060 100644 --- a/src/parse/paths.cpp +++ b/src/parse/paths.cpp @@ -38,16 +38,26 @@ AST::Path Parse_Path(TokenStream& lex, eParsePathGenericMode generic_mode) lex.putback( Token(TOK_LT) ); case TOK_LT: { TypeRef ty = Parse_Type(lex); - TypeRef trait; if( GET_TOK(tok, lex) == TOK_RWORD_AS ) { - trait = Parse_Type(lex); + ::AST::Path trait; + if( GET_TOK(tok, lex) == TOK_DOUBLE_COLON ) { + trait = Parse_Path(lex, false, PATH_GENERIC_TYPE); + } + else { + lex.putback(tok); + trait = Parse_Path(lex, true, PATH_GENERIC_TYPE); + } + GET_CHECK_TOK(tok, lex, TOK_GT); + GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON); + return AST::Path(AST::Path::TagUfcs(), ty, trait, Parse_PathNodes(lex, generic_mode)); } - else + else { lex.putback(tok); - GET_CHECK_TOK(tok, lex, TOK_GT); - // TODO: Terminating the "path" here is sometimes valid? - GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON); - return AST::Path(AST::Path::TagUfcs(), ty, trait, Parse_PathNodes(lex, generic_mode)); + GET_CHECK_TOK(tok, lex, TOK_GT); + // TODO: Terminating the "path" here is sometimes valid? + GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON); + return AST::Path(AST::Path::TagUfcs(), ty, Parse_PathNodes(lex, generic_mode)); + } } default: lex.putback(tok); diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 4dc8f999..df149a5b 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -618,7 +618,7 @@ AST::Trait Parse_TraitDef(TokenStream& lex, AST::Module& mod, const AST::MetaIte if( GET_TOK(tok, lex) == TOK_COLON )
{
// Bounded associated type
- TypeRef a_type = TypeRef( Span(), AST::Path(AST::Path::TagUfcs(), TypeRef(TypeRef::TagArg(), "Self"), TypeRef(Span()), {AST::PathNode(name)}) );
+ TypeRef a_type = TypeRef( Span(), AST::Path(AST::Path::TagUfcs(), TypeRef(TypeRef::TagArg(), "Self"), AST::Path(), {AST::PathNode(name)}) );
//TypeRef a_type = TypeRef(TypeRef::TagAssoc(), TypeRef(TypeRef::TagArg(), "Self"), TypeRef(), name);
Parse_TypeBound(lex, params, a_type);
GET_TOK(tok, lex);
diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index 7d11c85e..b3df1a0e 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -227,7 +227,7 @@ struct Context -void Resolve_Absolute_Path(const Context& context, const Span& sp, bool is_type, ::AST::Path& path); +void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, bool is_type, ::AST::Path& path); void Resolve_Absolute_Type(Context& context, TypeRef& type); void Resolve_Absolute_Expr(Context& context, ::AST::Expr& expr); void Resolve_Absolute_Expr(Context& context, ::AST::ExprNode& node); @@ -235,9 +235,20 @@ void Resolve_Absolute_Pattern(Context& context, bool allow_refutable, ::AST::Pat void Resolve_Absolute_Mod(const ::AST::Crate& crate, ::AST::Module& mod); -void Resolve_Absolute_Path(const Context& context, const Span& sp, bool is_type, ::AST::Path& path) +void Resolve_Absolute_PathNodes(/*const*/ Context& context, const Span& sp, bool is_type, ::std::vector< ::AST::PathNode >& nodes) +{ + for(auto& node : nodes) + { + for(auto& arg : node.args()) + { + Resolve_Absolute_Type(context, arg); + } + } +} +void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, bool is_type, ::AST::Path& path) { DEBUG("is_type = " << is_type << ", path = " << path); + TU_MATCH(::AST::Path::Class, (path.m_class), (e), (Invalid, BUG(sp, "Encountered invalid path"); @@ -287,8 +298,12 @@ void Resolve_Absolute_Path(const Context& context, const Span& sp, bool is_type, // Nothing to do (TODO: Bind?) ), (UFCS, - Resolve_Absolute_Type(context, e.type); - TODO(sp, "Resolve_Absolute_Path - UFCS"); + Resolve_Absolute_Type(context, *e.type); + if( e.trait ) { + Resolve_Absolute_Path(context, Span(), true, *e.trait); + } + + Resolve_Absolute_PathNodes(context, Span(), is_type, e.nodes); ) ) } @@ -463,7 +478,7 @@ void Resolve_Absolute_Generic(Context& context, ::AST::GenericParams& params) } // Locals shouldn't be possible, as they'd end up as MaybeBind. Will assert the path class. -void Resolve_Absolute_PatternValue(const Context& context, ::AST::Pattern::Value& val) +void Resolve_Absolute_PatternValue(/*const*/ Context& context, ::AST::Pattern::Value& val) { TU_MATCH(::AST::Pattern::Value, (val), (e), (Invalid, ), |