summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge (sonata) <tpg@mutabah.net>2015-01-17 16:19:27 +0800
committerJohn Hodge (sonata) <tpg@mutabah.net>2015-01-17 16:19:27 +0800
commit553112fcbf7175e9ea751a2aedc4c0d336d95593 (patch)
treeb8fb70cf33bcc88ac21abcb7e7a50d9a956d755d
parente4e710eb0b752981b61af1f09884d4ec12f6ddc1 (diff)
downloadmrust-553112fcbf7175e9ea751a2aedc4c0d336d95593.tar.gz
Clean up hanlding of generic params
-rw-r--r--samples/std.rs5
-rw-r--r--src/ast/ast.cpp120
-rw-r--r--src/ast/ast.hpp67
-rw-r--r--src/ast/path.cpp3
-rw-r--r--src/convert/resolve.cpp8
-rw-r--r--src/parse/root.cpp23
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();