diff options
author | John Hodge <tpg@mutabah.net> | 2015-04-03 15:19:55 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2015-04-03 15:19:55 +0800 |
commit | 38c943136d2ebebceb835a8f5689d3805b3709b1 (patch) | |
tree | 68b5ea9837db05f6f55b761a4acbd6cb529a7b86 | |
parent | 8fb0812c4c43f08a51a74e96c369c4ee56616e9a (diff) | |
download | mrust-38c943136d2ebebceb835a8f5689d3805b3709b1.tar.gz |
Save #[] attrs with item, ready for post-processing derive()
-rw-r--r-- | src/ast/ast.cpp | 29 | ||||
-rw-r--r-- | src/ast/ast.hpp | 180 | ||||
-rw-r--r-- | src/ast/provided_module.cpp | 53 | ||||
-rw-r--r-- | src/common.hpp | 2 | ||||
-rw-r--r-- | src/macros.cpp | 56 | ||||
-rw-r--r-- | src/main.cpp | 5 | ||||
-rw-r--r-- | src/parse/common.hpp | 2 | ||||
-rw-r--r-- | src/parse/expr.cpp | 16 | ||||
-rw-r--r-- | src/parse/root.cpp | 94 | ||||
-rw-r--r-- | src/types.hpp | 1 |
10 files changed, 230 insertions, 208 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 7350bab8..1bd4e819 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -40,7 +40,6 @@ SERIALISE_TYPE(MetaItem::, "AST_MetaItem", { bool ImplDef::matches(::std::vector<TypeRef>& out_types, const Path& trait, const TypeRef& type) const
{
- TRACE_FUNCTION_F("m_trait=" << m_trait << ", m_type=" << m_type);
// 1. Check the type/trait counting parameters as wildcards (but flagging if one was seen)
// > If that fails, just early return
int trait_match = m_trait.equal_no_generic(trait);
@@ -188,7 +187,7 @@ SERIALISE_TYPE(Impl::, "AST_Impl", { })
Crate::Crate():
- m_root_module(""),
+ m_root_module(MetaItems(), ""),
m_load_std(true)
{
}
@@ -229,10 +228,19 @@ const Module& Crate::get_root_module(const ::std::string& name) const { throw ParseError::Generic("crate name unknown");
}
+/**
+ * \brief Checks if a type implements the provided wildcard trait
+ * \param trait Trait path
+ * \param type Type in question
+ * \note Wildcard trait = A trait for which there exists a 'impl Trait for ..' definition
+ *
+ * \return True if the trait is implemented (either exlicitly, or implicitly)
+ */
bool Crate::check_impls_wildcard(const Path& trait, const TypeRef& type)
{
::std::vector<TypeRef> _params;
DEBUG("trait="<<trait);
+
// 1. Look for a negative impl for this type
for( auto implptr : m_neg_impl_index )
{
@@ -244,6 +252,7 @@ bool Crate::check_impls_wildcard(const Path& trait, const TypeRef& type) }
}
DEBUG("No negative impl of " << trait << " for " << type);
+
// 2. Look for a positive impl for this type (i.e. an unsafe impl)
for( auto implptr : m_impl_index )
{
@@ -254,16 +263,18 @@ bool Crate::check_impls_wildcard(const Path& trait, const TypeRef& type) }
}
DEBUG("No positive impl of " << trait << " for " << type);
- // If none found, destructure the type
- // - structs need all fields to impl this trait (cache result)
- // - same for enums, tuples, arrays, pointers...
- // - traits check the Self bounds
- if( type.is_primitive() ) {
+
+ // 3. If none found, destructure the type
+ // Primitives always impl
+ if( type.is_primitive() || type.is_unit() ) {
return true;
}
- else if( type.is_unit() ) {
- return true;
+ else if( type.is_reference() ) {
+ return check_impls_wildcard(trait, type.sub_types()[0]);
}
+ // - structs need all fields to impl this trait (cache result)
+ // - same for enums, tuples, arrays, pointers...
+ // - traits check the Self bounds
else {
throw CompileError::Todo("wildcard impls - auto determine");
}
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 5cedab2f..5cf1dee2 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -114,56 +114,7 @@ public: SERIALISABLE_PROTOTYPES();
};
-template <typename T>
-struct ItemNS
-{
- ::std::string name;
- T data;
- bool is_pub;
-
- ItemNS():
- is_pub(false)
- {}
- ItemNS(ItemNS&&) = default;
- ItemNS(const ItemNS&) = default;
- ItemNS(::std::string name, T data, bool is_pub):
- name( ::std::move(name) ),
- data( ::std::move(data) ),
- is_pub( is_pub )
- {
- }
-
- //friend ::std::ostream& operator<<(::std::ostream& os, const Item& i) {
- // return os << (i.is_pub ? "pub " : " ") << i.name << ": " << i.data;
- //}
-};
-
-template <typename T>
-struct Item:
- public ItemNS<T>,
- public Serialisable
-{
- Item():
- ItemNS<T>()
- {}
- Item(Item&&) = default;
- Item(const Item&) = default;
- Item(::std::string name, T data, bool is_pub):
- ItemNS<T>( ::std::move(name), ::std::move(data), is_pub )
- {}
- SERIALISE_TYPE_A(, "Item", {
- s.item(this->name);
- s.item(this->data);
- s.item(this->is_pub);
- })
-};
-
-template <typename T>
-using ItemList = ::std::vector<Item<T> >;
-
-typedef Item<TypeRef> StructItem;
-class Crate;
-
+//
class MetaItem;
class MetaItems:
@@ -185,6 +136,10 @@ public: return get(name) != 0;
}
+ friend ::std::ostream& operator<<(::std::ostream& os, const MetaItems& x) {
+ return os << "[" << x.m_items << "]";
+ }
+
SERIALISABLE_PROTOTYPES();
};
@@ -217,17 +172,79 @@ public: bool has_sub_items() const { return m_sub_items.m_items.size() > 0; }
MetaItems& items() { return m_sub_items; }
+ friend ::std::ostream& operator<<(::std::ostream& os, const MetaItem& x) {
+ os << x.m_name;
+ if(x.m_sub_items.m_items.size())
+ os << "(" << x.m_sub_items.m_items << ")";
+ else
+ os << "=\"" << x.m_str_val << "\"";
+ return os;
+ }
+
SERIALISABLE_PROTOTYPES();
};
+
+template <typename T>
+struct ItemNS
+{
+ ::std::string name;
+ T data;
+ bool is_pub;
+
+ ItemNS():
+ is_pub(false)
+ {}
+ ItemNS(ItemNS&&) = default;
+ ItemNS(const ItemNS&) = default;
+ ItemNS(::std::string name, T data, bool is_pub):
+ name( ::std::move(name) ),
+ data( ::std::move(data) ),
+ is_pub( is_pub )
+ {
+ }
+
+ //friend ::std::ostream& operator<<(::std::ostream& os, const Item& i) {
+ // return os << (i.is_pub ? "pub " : " ") << i.name << ": " << i.data;
+ //}
+};
+
+template <typename T>
+struct Item:
+ public ItemNS<T>,
+ public Serialisable
+{
+ Item():
+ ItemNS<T>()
+ {}
+ Item(Item&&) = default;
+ Item(const Item&) = default;
+ Item(::std::string name, T data, bool is_pub):
+ ItemNS<T>( ::std::move(name), ::std::move(data), is_pub )
+ {}
+ SERIALISE_TYPE_A(, "Item", {
+ s.item(this->name);
+ s.item(this->data);
+ s.item(this->is_pub);
+ })
+};
+
+template <typename T>
+using ItemList = ::std::vector<Item<T> >;
+
+typedef Item<TypeRef> StructItem;
+class Crate;
+
class TypeAlias:
public Serialisable
{
+ MetaItems m_attrs;
TypeParams m_params;
TypeRef m_type;
public:
TypeAlias() {}
- TypeAlias(TypeParams params, TypeRef type):
+ TypeAlias(MetaItems attrs, TypeParams params, TypeRef type):
+ m_attrs( move(attrs) ),
m_params( move(params) ),
m_type( move(type) )
{}
@@ -252,6 +269,7 @@ public: MUT,
};
private:
+ MetaItems m_attrs;
Class m_class;
TypeRef m_type;
Expr m_value;
@@ -259,7 +277,8 @@ public: Static():
m_class(CONST)
{}
- Static(Class s_class, TypeRef type, Expr value):
+ Static(MetaItems attrs, Class s_class, TypeRef type, Expr value):
+ m_attrs( move(attrs) ),
m_class(s_class),
m_type( move(type) ),
m_value( move(value) )
@@ -290,6 +309,7 @@ public: typedef ::std::vector< ::std::pair<AST::Pattern,TypeRef> > Arglist;
private:
+ MetaItems m_attrs;
Class m_fcn_class;
::std::string m_lifetime;
TypeParams m_params;
@@ -302,7 +322,8 @@ public: {}
Function(const Function&) = delete;
Function(Function&&) = default;
- Function(TypeParams params, Class fcn_class, TypeRef ret_type, Arglist args):
+ Function(MetaItems attrs, TypeParams params, Class fcn_class, TypeRef ret_type, Arglist args):
+ m_attrs( move(attrs) ),
m_fcn_class(fcn_class),
m_params( move(params) ),
m_rettype( move(ret_type) ),
@@ -331,12 +352,14 @@ public: class Trait:
public Serialisable
{
+ MetaItems m_attrs;
TypeParams m_params;
ItemList<TypeRef> m_types;
ItemList<Function> m_functions;
public:
Trait() {}
- Trait(TypeParams params):
+ Trait(MetaItems attrs, TypeParams params):
+ m_attrs( move(attrs) ),
m_params(params)
{
}
@@ -362,6 +385,7 @@ public: struct EnumVariant:
public Serialisable
{
+ MetaItems m_attrs;
::std::string m_name;
::std::vector<TypeRef> m_sub_types;
int64_t m_value;
@@ -371,13 +395,15 @@ struct EnumVariant: {
}
- EnumVariant(::std::string name, int64_t value):
+ EnumVariant(MetaItems attrs, ::std::string name, int64_t value):
+ m_attrs( move(attrs) ),
m_name( ::std::move(name) ),
m_value( value )
{
}
- EnumVariant(::std::string name, ::std::vector<TypeRef> sub_types):
+ EnumVariant(MetaItems attrs, ::std::string name, ::std::vector<TypeRef> sub_types):
+ m_attrs( move(attrs) ),
m_name( ::std::move(name) ),
m_sub_types( ::std::move(sub_types) ),
m_value(0)
@@ -394,11 +420,13 @@ struct EnumVariant: class Enum:
public Serialisable
{
+ MetaItems m_attrs;
TypeParams m_params;
::std::vector<EnumVariant> m_variants;
public:
Enum() {}
- Enum( TypeParams params, ::std::vector<EnumVariant> variants ):
+ Enum( MetaItems attrs, TypeParams params, ::std::vector<EnumVariant> variants ):
+ m_attrs( move(attrs) ),
m_params( move(params) ),
m_variants( move(variants) )
{}
@@ -415,11 +443,13 @@ public: class Struct:
public Serialisable
{
+ MetaItems m_attrs;
TypeParams m_params;
::std::vector<StructItem> m_fields;
public:
Struct() {}
- Struct( TypeParams params, ::std::vector<StructItem> fields ):
+ Struct( MetaItems attrs, TypeParams params, ::std::vector<StructItem> fields ):
+ m_attrs( move(attrs) ),
m_params( move(params) ),
m_fields( move(fields) )
{}
@@ -438,12 +468,14 @@ public: class ImplDef:
public Serialisable
{
+ MetaItems m_attrs;
TypeParams m_params;
Path m_trait;
TypeRef m_type;
public:
ImplDef() {}
- ImplDef(TypeParams params, Path trait_type, TypeRef impl_type):
+ ImplDef(MetaItems attrs, TypeParams params, Path trait_type, TypeRef impl_type):
+ m_attrs( move(attrs) ),
m_params( move(params) ),
m_trait( move(trait_type) ),
m_type( move(impl_type) )
@@ -475,8 +507,8 @@ class Impl: ::std::vector< ::std::pair< ::std::vector<TypeRef>, Impl > > m_concrete_impls;
public:
Impl() {}
- Impl(TypeParams params, TypeRef impl_type, Path trait_type):
- m_def( move(params), move(trait_type), move(impl_type) )
+ Impl(MetaItems attrs, TypeParams params, TypeRef impl_type, Path trait_type):
+ m_def( move(attrs), move(params), move(trait_type), move(impl_type) )
{}
void add_function(bool is_public, ::std::string name, Function fcn) {
@@ -523,8 +555,8 @@ class Module: typedef ::std::vector< Item<MacroRules> > itemlist_macros_t;
typedef ::std::multimap< ::std::string, ::std::string > macro_imports_t;
+ MetaItems m_attrs;
::std::string m_name;
- ::std::vector<MetaItem> m_attrs;
itemlist_fcn_t m_functions;
itemlist_mod_t m_submods;
itemlist_use_t m_imports;
@@ -546,7 +578,8 @@ class Module: ::std::vector<ImplDef> m_neg_impls;
public:
Module() {}
- Module(::std::string name):
+ Module(MetaItems attrs, ::std::string name):
+ m_attrs( move(attrs) ),
m_name(name)
{
}
@@ -563,17 +596,20 @@ public: void add_typealias(bool is_public, ::std::string name, TypeAlias alias) {
m_type_aliases.push_back( Item<TypeAlias>( move(name), move(alias), is_public ) );
}
- void add_constant(bool is_public, ::std::string name, TypeRef type, Expr val) {
- m_statics.push_back( Item<Static>( move(name), Static(Static::CONST, move(type), move(val)), is_public) );
- }
- void add_global(bool is_public, bool is_mut, ::std::string name, TypeRef type, Expr val) {
- m_statics.push_back( Item<Static>( move(name), Static(is_mut ? Static::MUT : Static::STATIC, move(type), move(val)), is_public) );
+ //void add_constant(bool is_public, ::std::string name, TypeRef type, Expr val) {
+ // m_statics.push_back( Item<Static>( move(name), Static(Static::CONST, move(type), move(val)), is_public) );
+ //}
+ //void add_global(bool is_public, bool is_mut, ::std::string name, TypeRef type, Expr val) {
+ // m_statics.push_back( Item<Static>( move(name), Static(is_mut ? Static::MUT : Static::STATIC, move(type), move(val)), is_public) );
+ //}
+ void add_static(bool is_public, ::std::string name, Static item) {
+ m_statics.push_back( Item<Static>( move(name), ::std::move(item), is_public) );
}
void add_trait(bool is_public, ::std::string name, Trait trait) {
m_traits.push_back( Item<Trait>( move(name), move(trait), is_public) );
}
- void add_struct(bool is_public, ::std::string name, TypeParams params, ::std::vector<StructItem> items) {
- m_structs.push_back( Item<Struct>( move(name), Struct(move(params), move(items)), is_public) );
+ void add_struct(bool is_public, ::std::string name, Struct item) {
+ m_structs.push_back( Item<Struct>( move(name), move(item), is_public) );
}
void add_enum(bool is_public, ::std::string name, Enum inst) {
m_enums.push_back( Item<Enum>( move(name), move(inst), is_public ) );
@@ -648,7 +684,7 @@ public: };
ItemRef find_item(const ::std::string& needle, bool allow_leaves = true, bool ignore_private_wildcard = true) const;
- ::std::vector<MetaItem>& attrs() { return m_attrs; }
+ MetaItems& attrs() { return m_attrs; }
itemlist_fcn_t& functions() { return m_functions; }
itemlist_mod_t& submods() { return m_submods; }
itemlist_use_t& imports() { return m_imports; }
@@ -661,7 +697,7 @@ public: itemlist_struct_t& structs() { return m_structs; }
::std::vector<Module*>& anon_mods() { return m_anon_modules; }
- const ::std::vector<MetaItem>& attrs() const { return m_attrs; }
+ const MetaItems& attrs() const { return m_attrs; }
const itemlist_fcn_t& functions() const { return m_functions; }
const itemlist_mod_t& submods() const { return m_submods; }
const itemlist_use_t& imports() const { return m_imports; }
diff --git a/src/ast/provided_module.cpp b/src/ast/provided_module.cpp index a72869a6..f8e53bdf 100644 --- a/src/ast/provided_module.cpp +++ b/src/ast/provided_module.cpp @@ -7,35 +7,38 @@ AST::Module g_compiler_module; void AST_InitProvidedModule() { // "struct str([u8])" - g_compiler_module.add_struct(true, "str", AST::TypeParams(), ::std::vector<AST::StructItem> { - AST::StructItem("", TypeRef(TypeRef::TagUnsizedArray(), TypeRef(CORETYPE_U8)), false), - }); + g_compiler_module.add_struct(true, "str", + AST::Struct( AST::MetaItems(), AST::TypeParams(), ::std::vector<AST::StructItem> { + AST::StructItem("", TypeRef(TypeRef::TagUnsizedArray(), TypeRef(CORETYPE_U8)), false), + })); AST::Path copy_marker_path({AST::PathNode("marker"),AST::PathNode("Copy")}); - g_compiler_module.add_impl(AST::Impl(AST::TypeParams(), TypeRef(CORETYPE_U8), copy_marker_path)); - g_compiler_module.add_impl(AST::Impl(AST::TypeParams(), TypeRef(CORETYPE_U16), copy_marker_path)); - g_compiler_module.add_impl(AST::Impl(AST::TypeParams(), TypeRef(CORETYPE_U32), copy_marker_path)); - g_compiler_module.add_impl(AST::Impl(AST::TypeParams(), TypeRef(CORETYPE_U64), copy_marker_path)); - g_compiler_module.add_impl(AST::Impl(AST::TypeParams(), TypeRef(CORETYPE_UINT), copy_marker_path)); - - g_compiler_module.add_impl(AST::Impl(AST::TypeParams(), TypeRef(CORETYPE_I8), copy_marker_path)); - g_compiler_module.add_impl(AST::Impl(AST::TypeParams(), TypeRef(CORETYPE_I16), copy_marker_path)); - g_compiler_module.add_impl(AST::Impl(AST::TypeParams(), TypeRef(CORETYPE_I32), copy_marker_path)); - g_compiler_module.add_impl(AST::Impl(AST::TypeParams(), TypeRef(CORETYPE_I64), copy_marker_path)); - g_compiler_module.add_impl(AST::Impl(AST::TypeParams(), TypeRef(CORETYPE_INT), copy_marker_path)); - - g_compiler_module.add_impl(AST::Impl(AST::TypeParams(), TypeRef(CORETYPE_F32), copy_marker_path)); - g_compiler_module.add_impl(AST::Impl(AST::TypeParams(), TypeRef(CORETYPE_F64), copy_marker_path)); + #define impl(trait, type) \ + g_compiler_module.add_impl(AST::Impl(AST::MetaItems(), AST::TypeParams(), type, trait)) + impl(copy_marker_path, TypeRef(CORETYPE_U8)); + impl(copy_marker_path, TypeRef(CORETYPE_U16)); + impl(copy_marker_path, TypeRef(CORETYPE_U32)); + impl(copy_marker_path, TypeRef(CORETYPE_U64)); + impl(copy_marker_path, TypeRef(CORETYPE_UINT)); + impl(copy_marker_path, TypeRef(CORETYPE_I8)); + impl(copy_marker_path, TypeRef(CORETYPE_I16)); + impl(copy_marker_path, TypeRef(CORETYPE_I32)); + impl(copy_marker_path, TypeRef(CORETYPE_I64)); + impl(copy_marker_path, TypeRef(CORETYPE_INT)); + impl(copy_marker_path, TypeRef(CORETYPE_F32)); + impl(copy_marker_path, TypeRef(CORETYPE_F64)); // A hacky default impl of 'Sized', with a negative impl on [T] AST::Path sized_marker_path({AST::PathNode("marker"),AST::PathNode("Sized")}); - g_compiler_module.add_impl(AST::Impl(AST::TypeParams(), TypeRef(), sized_marker_path)); - AST::TypeParams tps; - tps.add_ty_param( AST::TypeParam("T") ); - g_compiler_module.add_neg_impl(AST::ImplDef( - ::std::move(tps), - sized_marker_path, - TypeRef(TypeRef::TagUnsizedArray(), TypeRef(TypeRef::TagArg(), "T")) - )); + impl(sized_marker_path, TypeRef()); + { + AST::TypeParams tps; + tps.add_ty_param( AST::TypeParam("T") ); + g_compiler_module.add_neg_impl(AST::ImplDef( + AST::MetaItems(), ::std::move(tps), + sized_marker_path, + TypeRef(TypeRef::TagUnsizedArray(), TypeRef(TypeRef::TagArg(), "T")) + )); + } } diff --git a/src/common.hpp b/src/common.hpp index 8ab37682..c3525d42 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -10,6 +10,8 @@ #include <sstream> #define FMT(ss) (dynamic_cast< ::std::stringstream&>(::std::stringstream() << ss).str()) +// XXX: Evil hack - Define 'mv$' to be ::std::move +#define mv$(x) ::std::move(x) #include "include/debug.hpp" #include "include/rustic.hpp" // slice and option diff --git a/src/macros.cpp b/src/macros.cpp index 296f6d40..a614f2fb 100644 --- a/src/macros.cpp +++ b/src/macros.cpp @@ -214,57 +214,6 @@ const LList<AST::Module*>* Macro_GetModule() void Macro_InitDefaults()
{
- #if 0
- // try!() macro
- {
- MacroRule rule;
- rule.m_pattern.push_back( MacroPatEnt("val", MacroPatEnt::PAT_EXPR) );
- // match $rule {
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_RWORD_MATCH)) );
- rule.m_contents.push_back( MacroRuleEnt("val") );
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_BRACE_OPEN)) );
- // Ok(v) => v,
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_IDENT, "Ok")) );
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_PAREN_OPEN)) );
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_IDENT, "v")) );
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_PAREN_CLOSE)) );
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_FATARROW)) );
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_IDENT, "v")) );
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_COMMA)) );
- // Err(e) => return Err(r),
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_IDENT, "Err")) );
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_PAREN_OPEN)) );
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_IDENT, "e")) );
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_PAREN_CLOSE)) );
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_FATARROW)) );
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_RWORD_RETURN)) );
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_IDENT, "Err")) );
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_PAREN_OPEN)) );
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_IDENT, "e")) );
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_PAREN_CLOSE)) );
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_COMMA)) );
- // }
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_BRACE_CLOSE)) );
- MacroRules rules;
- rules.push_back(rule);
- g_macro_registrations.insert( make_pair(::std::string("try"), rules));
- }
-
- // panic!() "macro"
- {
- MacroRule rule;
- rule.m_pattern.push_back( MacroPatEnt(Token(TOK_NULL), false, {
- MacroPatEnt("tt", MacroPatEnt::PAT_TT),
- } ) );
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_PAREN_OPEN)) );
- rule.m_contents.push_back( MacroRuleEnt(Token(TOK_PAREN_CLOSE)) );
-
-
- MacroRules rules;
- rules.push_back(rule);
- g_macro_registrations.insert( make_pair(::std::string("panic"), rules));
- }
- #endif
}
bool Macro_TryPattern(TTStream& lex, const MacroPatEnt& pat)
@@ -523,10 +472,11 @@ bool Macro_HandlePattern(TTStream& lex, const MacroPatEnt& pat, unsigned int lay for( auto ent = g_macro_module; ent; ent = ent->m_prev )
{
const AST::Module& mm = *ent->m_item;
+ DEBUG("Module '" << mm.name() << "'");
for( unsigned int i = mm.macros().size(); i --; )
{
const auto& m = mm.macros()[i];
- DEBUG("" << m.name);
+ DEBUG("- [local] " << m.name);
if( m.name == name )
{
return Macro_InvokeInt(olex, m.name.c_str(), m.data, input);
@@ -535,7 +485,7 @@ bool Macro_HandlePattern(TTStream& lex, const MacroPatEnt& pat, unsigned int lay for( const auto& mi : mm.macro_imports_res() )
{
- DEBUG("" << mi.name);
+ DEBUG("- [imp]" << mi.name);
if( mi.name == name )
{
return Macro_InvokeInt(olex, mi.name.c_str(), *mi.data, input);
diff --git a/src/main.cpp b/src/main.cpp index 299301db..d996167b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -54,6 +54,11 @@ int main(int argc, char *argv[]) {
g_cur_phase = "Parse";
AST::Crate crate = Parse_Crate(params.infile);
+
+ // Iterate all items in the AST, applying syntax extensions
+ g_cur_phase = "Syn Exts";
+ // TODO:
+
g_cur_phase = "PostParse";
crate.post_parse();
diff --git a/src/parse/common.hpp b/src/parse/common.hpp index de81feb3..3372b608 100644 --- a/src/parse/common.hpp +++ b/src/parse/common.hpp @@ -43,7 +43,7 @@ extern TypeRef Parse_Type(TokenStream& lex); extern AST::Pattern Parse_Pattern(TokenStream& lex, bool is_refutable);
extern void Parse_Use(TokenStream& lex, ::std::function<void(AST::Path, ::std::string)> fcn);
-extern void Parse_Struct(AST::Module& mod, TokenStream& lex, bool is_public, const AST::MetaItems meta_items);
+extern AST::Struct Parse_Struct(TokenStream& lex, const AST::MetaItems meta_items);
extern void Parse_Impl(TokenStream& lex, AST::Module& mod, bool is_unsafe=false);
extern void Parse_MacroRules(TokenStream& lex, AST::Module& mod, AST::MetaItems meta_items);
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 88dc2f5e..536860c6 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -52,7 +52,7 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex) ::std::vector<ExprNodeP> nodes;
- ::std::unique_ptr<AST::Module> local_mod( new AST::Module("") );
+ ::std::unique_ptr<AST::Module> local_mod( new AST::Module(AST::MetaItems(),"") );
bool keep_mod = false;
const LList<AST::Module*>* prev_modstack = Macro_GetModule();
@@ -109,7 +109,7 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex) local_mod->statics().push_back( AST::Item<AST::Static>(
::std::move(name),
- AST::Static(AST::Static::CONST, ::std::move(type), ::std::move(val)),
+ AST::Static(mv$(item_attrs), AST::Static::CONST, mv$(type), mv$(val)),
false ) );
break;
}
@@ -130,14 +130,18 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex) auto val = Parse_Expr1(lex);
GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
- local_mod->add_global(false, is_mut, ::std::move(name), ::std::move(type), ::std::move(val));
+ local_mod->add_static(false, mv$(name),
+ AST::Static(mv$(item_attrs), (is_mut ? AST::Static::MUT : AST::Static::STATIC), mv$(type), mv$(val))
+ );
break;
}
// - 'struct'
- case TOK_RWORD_STRUCT:
+ case TOK_RWORD_STRUCT: {
keep_mod = true;
- Parse_Struct(*local_mod, lex, false, item_attrs);
- break;
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ ::std::string name = tok.str();
+ local_mod->add_struct(false, mv$(name), Parse_Struct(lex, item_attrs));
+ break; }
// - 'impl'
case TOK_RWORD_IMPL:
keep_mod = true;
diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 94a21179..56f5a384 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -287,7 +287,7 @@ AST::Function Parse_FunctionDef(TokenStream& lex, ::std::string abi, AST::MetaIt lex.putback(tok);
}
- return AST::Function(::std::move(params), fcn_class, ::std::move(ret_type), ::std::move(args));
+ return AST::Function(::std::move(attrs), ::std::move(params), fcn_class, ::std::move(ret_type), ::std::move(args));
}
AST::Function Parse_FunctionDefWithCode(TokenStream& lex, ::std::string abi, AST::MetaItems attrs, bool allow_self)
@@ -300,7 +300,7 @@ AST::Function Parse_FunctionDefWithCode(TokenStream& lex, ::std::string abi, AST return ret;
}
-AST::TypeAlias Parse_TypeAlias(TokenStream& lex, const AST::MetaItems meta_items)
+AST::TypeAlias Parse_TypeAlias(TokenStream& lex, AST::MetaItems meta_items)
{
TRACE_FUNCTION;
@@ -322,17 +322,15 @@ AST::TypeAlias Parse_TypeAlias(TokenStream& lex, const AST::MetaItems meta_items TypeRef type = Parse_Type(lex);
GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
- return AST::TypeAlias( ::std::move(params), ::std::move(type) );
+ return AST::TypeAlias( ::std::move(meta_items), ::std::move(params), ::std::move(type) );
}
-void Parse_Struct(AST::Module& mod, TokenStream& lex, const bool is_public, const AST::MetaItems meta_items)
+AST::Struct Parse_Struct(TokenStream& lex, const AST::MetaItems meta_items)
{
TRACE_FUNCTION;
Token tok;
- GET_CHECK_TOK(tok, lex, TOK_IDENT);
- ::std::string name = tok.str();
tok = lex.getToken();
AST::TypeParams params;
if( tok.type() == TOK_LT )
@@ -366,12 +364,12 @@ void Parse_Struct(AST::Module& mod, TokenStream& lex, const bool is_public, cons GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
if( refs.size() == 0 )
throw ParseError::Generic(lex, "Use 'struct Name;' instead of 'struct Name();' ... ning-nong");
- mod.add_struct(is_public, ::std::move(name), ::std::move(params), ::std::move(refs));
+ return AST::Struct(::std::move(meta_items), ::std::move(params), ::std::move(refs));
}
else if(tok.type() == TOK_SEMICOLON)
{
// Unit-like struct
- mod.add_struct(is_public, name, params, ::std::vector<AST::StructItem>());
+ return AST::Struct(::std::move(meta_items), ::std::move(params), ::std::vector<AST::StructItem>());
}
else if(tok.type() == TOK_BRACE_OPEN)
{
@@ -404,7 +402,7 @@ void Parse_Struct(AST::Module& mod, TokenStream& lex, const bool is_public, cons }
if( items.size() == 0 )
throw ParseError::Generic(lex, "Use 'struct Name;' instead of 'struct Name { }' ... ning-nong");
- mod.add_struct(is_public, name, params, items);
+ return AST::Struct(::std::move(meta_items), ::std::move(params), ::std::move(items));
}
else
{
@@ -444,7 +442,7 @@ AST::Trait Parse_TraitDef(TokenStream& lex, const AST::MetaItems& meta_items) }
- AST::Trait trait(params);
+ AST::Trait trait(mv$(meta_items), mv$(params));
CHECK_TOK(tok, TOK_BRACE_OPEN);
while( GET_TOK(tok, lex) != TOK_BRACE_CLOSE )
@@ -578,7 +576,7 @@ AST::Enum Parse_EnumDef(TokenStream& lex, const AST::MetaItems meta_items) } while( GET_TOK(tok, lex) == TOK_COMMA );
CHECK_TOK(tok, TOK_PAREN_CLOSE);
GET_TOK(tok, lex);
- variants.push_back( AST::EnumVariant(::std::move(name), ::std::move(types)) );
+ variants.push_back( AST::EnumVariant(mv$(item_attrs), mv$(name), mv$(types)) );
}
else if( tok.type() == TOK_EQUAL )
{
@@ -589,12 +587,12 @@ AST::Enum Parse_EnumDef(TokenStream& lex, const AST::MetaItems meta_items) lex.putback(tok);
GET_CHECK_TOK(tok, lex, TOK_INTEGER);
int64_t val = (is_neg ? -tok.intval() : tok.intval());
- variants.push_back( AST::EnumVariant(::std::move(name), val) );
+ variants.push_back( AST::EnumVariant(mv$(item_attrs), mv$(name), val) );
GET_TOK(tok, lex);
}
else
{
- variants.push_back( AST::EnumVariant(::std::move(name), ::std::vector<TypeRef>()) );
+ variants.push_back( AST::EnumVariant(mv$(item_attrs), mv$(name), ::std::vector<TypeRef>()) );
}
if( tok.type() != TOK_COMMA )
@@ -603,7 +601,7 @@ AST::Enum Parse_EnumDef(TokenStream& lex, const AST::MetaItems meta_items) CHECK_TOK(tok, TOK_BRACE_CLOSE);
- return AST::Enum( ::std::move(params), ::std::move(variants) );
+ return AST::Enum( mv$(meta_items), mv$(params), mv$(variants) );
}
/// Parse a meta-item declaration (either #![ or #[)
@@ -670,7 +668,7 @@ void Parse_Impl(TokenStream& lex, AST::Module& mod, bool is_unsafe/*=false*/) // negative impls can't have any content
GET_CHECK_TOK(tok, lex, TOK_BRACE_CLOSE);
- mod.add_neg_impl( AST::ImplDef( ::std::move(params), ::std::move(trait_path), ::std::move(impl_type) ) );
+ mod.add_neg_impl( AST::ImplDef( AST::MetaItems(), ::std::move(params), ::std::move(trait_path), ::std::move(impl_type) ) );
return ;
}
else
@@ -713,7 +711,8 @@ void Parse_Impl(TokenStream& lex, AST::Module& mod, bool is_unsafe/*=false*/) }
GET_CHECK_TOK(tok, lex, TOK_BRACE_OPEN);
- AST::Impl impl( ::std::move(params), ::std::move(impl_type), ::std::move(trait_path) );
+ // TODO: Pass #[] attrs to impl blocks
+ AST::Impl impl( AST::MetaItems(), ::std::move(params), ::std::move(impl_type), ::std::move(trait_path) );
// A sequence of method implementations
while( GET_TOK(tok, lex) != TOK_BRACE_CLOSE )
@@ -1143,7 +1142,7 @@ MacroRule Parse_MacroRules_Var(TokenStream& lex) void Parse_MacroRules(TokenStream& lex, AST::Module& mod, AST::MetaItems meta_items)
{
- TRACE_FUNCTION;
+ TRACE_FUNCTION_F("meta_items="<<meta_items);
Token tok;
@@ -1197,25 +1196,13 @@ void Parse_ModRoot_Items(TokenStream& lex, AST::Crate& crate, AST::Module& mod, GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
}
lex.putback(tok);
+ DEBUG("meta_items = " << meta_items);
- // Module visibility
- bool is_public = false;
- if( GET_TOK(tok, lex) == TOK_RWORD_PUB )
- {
- is_public = true;
- }
- else
- {
- lex.putback(tok);
- }
-
- // The actual item!
- switch( GET_TOK(tok, lex) )
+ if( GET_TOK(tok, lex) == TOK_MACRO )
{
- case TOK_MACRO:
if( tok.str() == "macro_rules" )
{
- Parse_MacroRules(lex, mod, ::std::move(meta_items));
+ Parse_MacroRules(lex, mod, mv$(meta_items));
}
else
{
@@ -1234,7 +1221,26 @@ void Parse_ModRoot_Items(TokenStream& lex, AST::Crate& crate, AST::Module& mod, // - Silently consume ';' after the macro
if( GET_TOK(tok, lex) != TOK_SEMICOLON )
lex.putback(tok);
- break;
+ continue ;
+ }
+ else {
+ lex.putback(tok);
+ }
+
+ // Module visibility
+ bool is_public = false;
+ if( GET_TOK(tok, lex) == TOK_RWORD_PUB )
+ {
+ is_public = true;
+ }
+ else
+ {
+ lex.putback(tok);
+ }
+
+ // The actual item!
+ switch( GET_TOK(tok, lex) )
+ {
case TOK_RWORD_USE:
Parse_Use(lex, [&mod,is_public](AST::Path p, std::string s) { mod.add_alias(is_public, p, s); });
@@ -1308,7 +1314,7 @@ void Parse_ModRoot_Items(TokenStream& lex, AST::Crate& crate, AST::Module& mod, GET_CHECK_TOK(tok, lex, TOK_EQUAL);
AST::Expr val = Parse_Expr(lex, true);
GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
- mod.add_constant(is_public, name, type, val);
+ mod.add_static(is_public, name, AST::Static(::std::move(meta_items), AST::Static::CONST, type, val));
break; }
case TOK_RWORD_STATIC: {
tok = lex.getToken();
@@ -1328,7 +1334,9 @@ void Parse_ModRoot_Items(TokenStream& lex, AST::Crate& crate, AST::Module& mod, AST::Expr val = Parse_Expr(lex, true);
GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
- mod.add_global(is_public, is_mut, name, type, val);
+ mod.add_static(is_public, name,
+ AST::Static(::std::move(meta_items), (is_mut ? AST::Static::MUT : AST::Static::STATIC), type, val)
+ );
break; }
case TOK_RWORD_UNSAFE:
@@ -1364,9 +1372,11 @@ void Parse_ModRoot_Items(TokenStream& lex, AST::Crate& crate, AST::Module& mod, ::std::string name = tok.str();
mod.add_typealias(is_public, name, Parse_TypeAlias(lex, meta_items));
break; }
- case TOK_RWORD_STRUCT:
- Parse_Struct(mod, lex, is_public, meta_items);
- break;
+ case TOK_RWORD_STRUCT: {
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ ::std::string name = tok.str();
+ mod.add_struct( is_public, name, Parse_Struct(lex, meta_items) );
+ break; }
case TOK_RWORD_ENUM: {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
::std::string name = tok.str();
@@ -1384,7 +1394,7 @@ void Parse_ModRoot_Items(TokenStream& lex, AST::Crate& crate, AST::Module& mod, case TOK_RWORD_MOD: {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
::std::string name = tok.str();
- AST::Module submod(name);
+ AST::Module submod(meta_items, name);
DEBUG("Sub module '"<<name<<"'");
switch( GET_TOK(tok, lex) )
{
@@ -1402,9 +1412,9 @@ void Parse_ModRoot_Items(TokenStream& lex, AST::Crate& crate, AST::Module& mod, {
throw ParseError::Generic( FMT("Can't load from files outside of mod.rs or crate root") );
}
- else if( meta_items.has("path") )
+ else if( submod.attrs().has("path") )
{
- ::std::string newpath_dir = path + meta_items.get("path")->string();
+ ::std::string newpath_dir = path + submod.attrs().get("path")->string();
::std::ifstream ifs_dir (newpath_dir);
if( !ifs_dir.is_open() )
{
@@ -1535,7 +1545,7 @@ AST::Crate Parse_Crate(::std::string mainfile) lex.putback(tok);
// Check for crate attributes
- for( const auto& attr : rootmod.attrs() )
+ for( const auto& attr : rootmod.attrs().m_items )
{
if( attr.name() == "no_std" ) {
crate.m_load_std = false;
diff --git a/src/types.hpp b/src/types.hpp index 7c026500..500e03f7 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -182,6 +182,7 @@ public: bool is_tuple() const { return m_class == TUPLE; }
const ::std::string& type_param() const { assert(is_type_param()); return m_path[0].name(); }
AST::Path& path() { assert(is_path()); return m_path; }
+
const AST::Path& path() const { assert(is_path()); return m_path; }
::std::vector<TypeRef>& sub_types() { return m_inner_types; }
const ::std::vector<TypeRef>& sub_types() const { return m_inner_types; }
|