diff options
author | John Hodge (sonata) <tpg@mutabah.net> | 2015-01-17 16:19:27 +0800 |
---|---|---|
committer | John Hodge (sonata) <tpg@mutabah.net> | 2015-01-17 16:19:27 +0800 |
commit | 553112fcbf7175e9ea751a2aedc4c0d336d95593 (patch) | |
tree | b8fb70cf33bcc88ac21abcb7e7a50d9a956d755d | |
parent | e4e710eb0b752981b61af1f09884d4ec12f6ddc1 (diff) | |
download | mrust-553112fcbf7175e9ea751a2aedc4c0d336d95593.tar.gz |
Clean up hanlding of generic params
-rw-r--r-- | samples/std.rs | 5 | ||||
-rw-r--r-- | src/ast/ast.cpp | 120 | ||||
-rw-r--r-- | src/ast/ast.hpp | 67 | ||||
-rw-r--r-- | src/ast/path.cpp | 3 | ||||
-rw-r--r-- | src/convert/resolve.cpp | 8 | ||||
-rw-r--r-- | src/parse/root.cpp | 23 |
6 files changed, 99 insertions, 127 deletions
diff --git a/samples/std.rs b/samples/std.rs index 26039934..2900ddae 100644 --- a/samples/std.rs +++ b/samples/std.rs @@ -24,6 +24,10 @@ pub mod io { EndOfFile, } + + pub trait Reader + { + } } pub mod iter @@ -46,6 +50,7 @@ pub mod prelude pub use option::Option::{self, None, Some}; pub use result::Result::{self, Ok, Err}; pub use io::IoResult; + pub use io::Reader; pub use iter::Iterator; } } diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 4bafb357..be4c9400 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -9,8 +9,6 @@ namespace AST {
-ExternCrate ExternCrate_std();
-
SERIALISE_TYPE(MetaItem::, "AST_MetaItem", {
s << m_name;
s << m_str_val;
@@ -116,16 +114,6 @@ void Crate::load_extern_crate(::std::string name) d.item( ret.crate() );
m_extern_crates.insert( make_pair(::std::move(name), ::std::move(ret)) );
-
- //if( name == "std" )
- //{
- // // HACK! Load std using a hackjob (included within the compiler)
- // m_extern_crates.insert( make_pair( ::std::move(name), ExternCrate_std() ) );
- //}
- //else
- //{
- // throw ParseError::Todo("'extern crate' (not hackjob std)");
- //}
}
SERIALISE_TYPE(Crate::, "AST_Crate", {
s << m_load_std;
@@ -149,77 +137,6 @@ SERIALISE_TYPE(ExternCrate::, "AST_ExternCrate", { },{
})
-ExternCrate ExternCrate_std()
-{
- ExternCrate crate;
-
- Module& std_mod = crate.root_module();
-
- // === Add modules ===
- // - option
- Module option("option");
- option.add_enum(true, "Option", Enum(
- {
- TypeParam(false, "T"),
- },
- {
- StructItem("None", TypeRef()),
- StructItem("Some", TypeRef(TypeRef::TagArg(), "T")),
- }
- ));
- std_mod.add_submod(true, ::std::move(option));
- // - result
- Module result("result");
- result.add_enum(true, "Result", Enum(
- {
- TypeParam(false, "R"),
- TypeParam(false, "E"),
- },
- {
- StructItem("Ok", TypeRef(TypeRef::TagArg(), "R")),
- StructItem("Err", TypeRef(TypeRef::TagArg(), "E")),
- }
- ));
- std_mod.add_submod(true, ::std::move(result));
- // - io
- Module io("io");
- io.add_typealias(true, "IoResult", TypeAlias(
- { TypeParam(false, "T") },
- TypeRef( Path("std", {
- PathNode("result",{}),
- PathNode("Result", {TypeRef("T"),TypeRef(Path("std", {PathNode("io"), PathNode("IoError")}))})
- }) )
- ));
- std_mod.add_submod(true, ::std::move(io));
- // - iter
- {
- Module iter("iter");
- #if 0
- {
- Trait iterator;
- iterator.add_type("Item", TypeRef());
- //iterator.add_function("next", Function({}, Function::CLASS_REFMETHOD, "Option<<Self as Iterator>::Item>", {}, Expr());
- iter.add_trait(true, "Iterator", ::std::move(iterator));
- }
- #endif
- std_mod.add_submod(true, ::std::move(iter));
- }
-
- // - prelude
- Module prelude("prelude");
- // Re-exports
- #define USE(mod, name, ...) do{ Path p("std", {__VA_ARGS__}); mod.add_alias(true, ::std::move(p), name); } while(0)
- USE(prelude, "Option", PathNode("option", {}), PathNode("Option",{}) );
- USE(prelude, "Some", PathNode("option", {}), PathNode("Option",{}), PathNode("Some",{}) );
- USE(prelude, "None", PathNode("option", {}), PathNode("Option",{}), PathNode("None",{}) );
- USE(prelude, "Result", PathNode("result", {}), PathNode("Result",{}) );
- USE(prelude, "Ok", PathNode("result", {}), PathNode("Result",{}), PathNode("Ok",{}) );
- USE(prelude, "Err", PathNode("result", {}), PathNode("Result",{}), PathNode("Err",{}) );
- std_mod.add_submod(true, prelude);
-
- return crate;
-}
-
SERIALISE_TYPE(Module::, "AST_Module", {
s << m_name;
s << m_attrs;
@@ -368,14 +285,6 @@ SERIALISE_TYPE(Struct::, "AST_Struct", { s.item(m_fields);
})
-void TypeParam::addLifetimeBound(::std::string name)
-{
-
-}
-void TypeParam::addTypeBound(TypeRef type)
-{
-
-}
::std::ostream& operator<<(::std::ostream& os, const TypeParam& tp)
{
os << "TypeParam(";
@@ -385,10 +294,8 @@ void TypeParam::addTypeBound(TypeRef type) case TypeParam::TYPE: os << ""; break;
}
os << tp.m_name;
- if( tp.m_trait_bounds.size() )
- {
- os << ": [" << tp.m_trait_bounds << "]";
- }
+ os << " = ";
+ os << tp.m_default;
os << ")";
return os;
}
@@ -401,7 +308,7 @@ SERIALISE_TYPE(TypeParam::, "AST_TypeParam", { }
s << classstr;
s << m_name;
- s << m_trait_bounds;
+ s << m_default;
},{
{
::std::string n;
@@ -411,7 +318,26 @@ SERIALISE_TYPE(TypeParam::, "AST_TypeParam", { else throw ::std::runtime_error("");
}
s.item(m_name);
- s.item(m_trait_bounds);
+ s.item(m_default);
+})
+
+::std::ostream& operator<<(::std::ostream& os, const GenericBound& x)
+{
+ return os << "GenericBound(" << x.m_argname << "," << x.m_lifetime << "," << x.m_trait << ")";
+}
+SERIALISE_TYPE_S(GenericBound, {
+ s.item(m_argname);
+ s.item(m_lifetime);
+ s.item(m_trait);
+})
+
+::std::ostream& operator<<(::std::ostream& os, const TypeParams& tps)
+{
+ return os << "TypeParams({" << tps.m_params << "}, {" << tps.m_bounds << "})";
+}
+SERIALISE_TYPE_S(TypeParams, {
+ s.item(m_params);
+ s.item(m_bounds);
})
}
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 4cc8f807..af797e7b 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -31,7 +31,7 @@ class TypeParam: };
Class m_class;
::std::string m_name;
- ::std::vector<TypeRef> m_trait_bounds;
+ TypeRef m_default;
public:
TypeParam():
m_class(LIFETIME)
@@ -40,20 +40,62 @@ public: m_class( is_lifetime ? LIFETIME : TYPE ),
m_name( ::std::move(name) )
{}
- void addLifetimeBound(::std::string name);
- void addTypeBound(TypeRef type);
void setDefault(TypeRef type);
const ::std::string& name() const { return m_name; }
bool is_type() const { return m_class == TYPE; }
- //TypeRef& get_default() const { return m_
- ::std::vector<TypeRef>& get_bounds() { assert(is_type()); return m_trait_bounds; }
friend ::std::ostream& operator<<(::std::ostream& os, const TypeParam& tp);
SERIALISABLE_PROTOTYPES();
};
+class GenericBound:
+ public Serialisable
+{
+ ::std::string m_argname;
+ ::std::string m_lifetime;
+ TypeRef m_trait;
+public:
+ GenericBound() {}
+ GenericBound(::std::string argname, ::std::string lifetime):
+ m_argname(argname),
+ m_lifetime(lifetime)
+ { }
+ GenericBound(::std::string argname, TypeRef trait):
+ m_argname(argname),
+ m_trait( ::std::move(trait) )
+ { }
+
+ TypeRef& get_type() { return m_trait; }
+
+ friend ::std::ostream& operator<<(::std::ostream& os, const GenericBound& x);
+ SERIALISABLE_PROTOTYPES();
+};
+
+class TypeParams:
+ public Serialisable
+{
+ ::std::vector<TypeParam> m_params;
+ ::std::vector<GenericBound> m_bounds;
+public:
+ TypeParams() {}
+
+ size_t n_params() const { return m_params.size(); }
+ ::std::vector<TypeParam>& params() { return m_params; }
+ ::std::vector<GenericBound>& bounds() { return m_bounds; }
+
+ void add_param(TypeParam param) {
+ m_params.push_back( ::std::move(param) );
+ }
+ void add_bound(GenericBound bound) {
+ m_bounds.push_back( ::std::move(bound) );
+ }
+
+ friend ::std::ostream& operator<<(::std::ostream& os, const TypeParams& tp);
+ SERIALISABLE_PROTOTYPES();
+};
+
template <typename T>
struct Item:
public Serialisable
@@ -83,7 +125,6 @@ struct Item: template <typename T>
using ItemList = ::std::vector<Item<T> >;
-typedef ::std::vector<TypeParam> TypeParams;
typedef ::std::pair< ::std::string, TypeRef> StructItem;
class Crate;
@@ -204,7 +245,7 @@ public: class Trait:
public Serialisable
{
- ::std::vector<TypeParam> m_params;
+ TypeParams m_params;
ItemList<TypeRef> m_types;
ItemList<Function> m_functions;
public:
@@ -227,16 +268,16 @@ public: class Enum:
public Serialisable
{
- ::std::vector<TypeParam> m_params;
+ TypeParams m_params;
::std::vector<StructItem> m_variants;
public:
Enum() {}
- Enum( ::std::vector<TypeParam> params, ::std::vector<StructItem> variants ):
+ Enum( TypeParams params, ::std::vector<StructItem> variants ):
m_params( move(params) ),
m_variants( move(variants) )
{}
- const ::std::vector<TypeParam> params() const { return m_params; }
+ const TypeParams params() const { return m_params; }
const ::std::vector<StructItem> variants() const { return m_variants; }
SERIALISABLE_PROTOTYPES();
@@ -245,16 +286,16 @@ public: class Struct:
public Serialisable
{
- ::std::vector<TypeParam> m_params;
+ TypeParams m_params;
::std::vector<StructItem> m_fields;
public:
Struct() {}
- Struct( ::std::vector<TypeParam> params, ::std::vector<StructItem> fields ):
+ Struct( TypeParams params, ::std::vector<StructItem> fields ):
m_params( move(params) ),
m_fields( move(fields) )
{}
- const ::std::vector<TypeParam> params() const { return m_params; }
+ const TypeParams params() const { return m_params; }
const ::std::vector<StructItem> fields() const { return m_fields; }
SERIALISABLE_PROTOTYPES();
diff --git a/src/ast/path.cpp b/src/ast/path.cpp index acd92dd8..8f77f008 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -53,7 +53,6 @@ void Path::resolve(const Crate& root_crate) const bool is_last = (i+1 == m_nodes.size()); const bool is_sec_last = (i+2 == m_nodes.size()); const PathNode& node = m_nodes[i]; - DEBUG("mod = " << mod << ", node = " << node); // Sub-modules { @@ -261,7 +260,7 @@ void Path::bind_struct(const Struct& ent, const ::std::vector<TypeRef>& args) { if( args.size() > 0 ) { - if( args.size() != ent.params().size() ) + if( args.size() != ent.params().n_params() ) throw ParseError::Generic("Parameter count mismatch"); // TODO: Is it the role of this section of code to ensure that the passed args are valid? // - Probably not, it should instead be the type checker that does it diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp index 02b3ea78..f5e88b4f 100644 --- a/src/convert/resolve.cpp +++ b/src/convert/resolve.cpp @@ -449,12 +449,14 @@ void ResolvePaths_HandleModule(const AST::Crate& crate, const AST::Path& modpath // Params
pr.push_scope();
- for( auto& param : impl.params() )
+ for( auto& param : impl.params().params() )
{
DEBUG("Param " << param);
pr.add_local_type(param.name());
- for(auto& trait : param.get_bounds())
- pr.resolve_type(trait);
+ }
+ for( auto& bound : impl.params().bounds() )
+ {
+ pr.resolve_type(bound.get_type());
}
// Trait
pr.resolve_type( impl.trait() );
diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 024860bf..2c0acd4e 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -228,9 +228,9 @@ AST::TypeParams Parse_TypeParams(TokenStream& lex) // Oopsie!
throw ParseError::Unexpected(tok);
}
- AST::TypeParam param( is_lifetime, tok.str() );
- tok = lex.getToken();
- if( tok.type() == TOK_COLON )
+ ::std::string param_name = tok.str();
+ ret.add_param( AST::TypeParam( is_lifetime, param_name ) );
+ if( GET_TOK(tok, lex) == TOK_COLON )
{
// TODO: Conditions
if( is_lifetime )
@@ -238,18 +238,17 @@ AST::TypeParams Parse_TypeParams(TokenStream& lex) throw ParseError::Todo("lifetime param conditions");
}
- do {
- tok = lex.getToken();
- if(tok.type() == TOK_LIFETIME)
- param.addLifetimeBound(tok.str());
+ do
+ {
+ if(GET_TOK(tok, lex) == TOK_LIFETIME) {
+ ret.add_bound( AST::GenericBound(param_name, tok.str()) );
+ }
else {
lex.putback(tok);
- param.addTypeBound(Parse_Type(lex));
+ ret.add_bound( AST::GenericBound(param_name, Parse_Type(lex)) );
}
- tok = lex.getToken();
- } while(tok.type() == TOK_PLUS);
+ } while( GET_TOK(tok, lex) == TOK_PLUS );
}
- ret.push_back(param);
} while( tok.type() == TOK_COMMA );
lex.putback(tok);
return ret;
@@ -473,7 +472,7 @@ AST::Trait Parse_TraitDef(TokenStream& lex, const ::std::vector<AST::MetaItem> m // TODO: Support "for Sized?"
if(tok.type() == TOK_RWORD_WHERE)
{
- if( params.size() == 0 )
+ if( params.n_params() == 0 )
throw ParseError::Generic("Where clause with no generic params");
Parse_TypeConds(lex, params);
tok = lex.getToken();
|