summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-03-13 08:55:41 +0800
committerJohn Hodge <tpg@mutabah.net>2016-03-13 08:55:41 +0800
commitdf7f0e6e1b384496a0d198557d73359085f46d47 (patch)
treefb47db407071d0455e37857542cfb46bde9263e4 /src
parentbc389f78562198ca5afd7c89c880da1212aa4720 (diff)
downloadmrust-df7f0e6e1b384496a0d198557d73359085f46d47.tar.gz
Parse - Store module path in module
Diffstat (limited to 'src')
-rw-r--r--src/ast/ast.cpp13
-rw-r--r--src/ast/ast.hpp19
-rw-r--r--src/ast/crate.cpp2
-rw-r--r--src/ast/expr.hpp6
-rw-r--r--src/convert/resolve.cpp20
-rw-r--r--src/dump_as_rust.cpp4
-rw-r--r--src/expand/mod.cpp9
-rw-r--r--src/parse/common.hpp12
-rw-r--r--src/parse/expr.cpp26
-rw-r--r--src/parse/lex.hpp16
-rw-r--r--src/parse/root.cpp58
-rw-r--r--src/parse/types.cpp2
12 files changed, 108 insertions, 79 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp
index 0bdbf5c0..2a6b0b39 100644
--- a/src/ast/ast.cpp
+++ b/src/ast/ast.cpp
@@ -235,7 +235,7 @@ SERIALISE_TYPE_A(MacroInvocation::, "AST_MacroInvocation", {
})
SERIALISE_TYPE_A(Module::, "AST_Module", {
- s.item(m_name);
+ s.item(m_my_path);
s.item(m_items);
@@ -246,6 +246,14 @@ SERIALISE_TYPE_A(Module::, "AST_Module", {
s.item(m_impls);
})
+::std::unique_ptr<AST::Module> Module::add_anon() {
+ auto rv = box$( Module(m_my_path + FMT("#" << m_anon_modules.size())) );
+
+ m_anon_modules.push_back( rv.get() );
+
+ return rv;
+}
+
void Module::add_item(bool is_pub, ::std::string name, Item it, MetaItems attrs) {
m_items.push_back( Named<Item>( mv$(name), mv$(it), is_pub ) );
m_items.back().data.attrs = mv$(attrs);
@@ -277,8 +285,7 @@ void Module::add_enum(bool is_public, ::std::string name, Enum item, MetaItems a
void Module::add_function(bool is_public, ::std::string name, Function item, MetaItems attrs) {
this->add_item( is_public, name, Item::make_Function({mv$(item)}), mv$(attrs) );
}
-void Module::add_submod(bool is_public, Module mod, MetaItems attrs) {
- auto name = mod.m_name;
+void Module::add_submod(bool is_public, ::std::string name, Module mod, MetaItems attrs) {
DEBUG("mod.m_name = " << name << ", attrs = " << attrs);
this->add_item( is_public, mv$(name), Item::make_Module({mv$(mod)}), mv$(attrs) );
}
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp
index 1057bc79..a84097d1 100644
--- a/src/ast/ast.hpp
+++ b/src/ast/ast.hpp
@@ -380,11 +380,11 @@ class Module:
{
typedef ::std::vector< Named<Path> > itemlist_use_t;
- ::std::string m_name;
+ ::AST::Path m_my_path;
// Module-level items
/// General items
- ::std::vector<Named<Item>> m_items;
+ ::std::vector<Named<Item>> m_items;
/// `use` imports (public and private)
itemlist_use_t m_imports;
/// Macro invocations
@@ -403,14 +403,21 @@ class Module:
::std::vector< Named<MacroRules> > m_macros;
public:
Module() {}
- Module(::std::string name):
- m_name(name)
+ Module(::AST::Path path):
+ m_my_path( mv$(path) )
{
}
+ bool is_anon() const {
+ return m_my_path.nodes().back().name()[0] == '#';
+ }
+
// Called when module is loaded from a serialised format
void prescan();
+ /// Create an anon module (for use inside expressions)
+ ::std::unique_ptr<AST::Module> add_anon();
+
void add_item(bool is_pub, ::std::string name, Item it, MetaItems attrs);
void add_ext_crate(::std::string ext_name, ::std::string imp_name, MetaItems attrs);
void add_alias(bool is_public, Path path, ::std::string name, MetaItems attrs);
@@ -420,7 +427,7 @@ public:
void add_struct(bool is_public, ::std::string name, Struct item, MetaItems attrs);
void add_enum(bool is_public, ::std::string name, Enum inst, MetaItems attrs);
void add_function(bool is_public, ::std::string name, Function item, MetaItems attrs);
- void add_submod(bool is_public, Module mod, MetaItems attrs);
+ void add_submod(bool is_public, ::std::string name, Module mod, MetaItems attrs);
void add_impl(Impl impl) {
m_impls.emplace_back( ::std::move(impl) );
@@ -450,7 +457,7 @@ public:
void iterate_functions(fcn_visitor_t* visitor, const Crate& crate);
- const ::std::string& name() const { return m_name; }
+ const ::AST::Path& path() const { return m_my_path; }
class ItemRef
{
public:
diff --git a/src/ast/crate.cpp b/src/ast/crate.cpp
index 8bb416c5..55f78ad1 100644
--- a/src/ast/crate.cpp
+++ b/src/ast/crate.cpp
@@ -26,7 +26,7 @@ namespace {
namespace AST {
Crate::Crate():
- m_root_module(""),
+ m_root_module(::AST::Path()),
m_load_std(true)
{
}
diff --git a/src/ast/expr.hpp b/src/ast/expr.hpp
index 30f1a2a9..214be267 100644
--- a/src/ast/expr.hpp
+++ b/src/ast/expr.hpp
@@ -55,15 +55,15 @@ struct ExprNode_Block:
public ExprNode
{
bool m_is_unsafe;
- ::std::unique_ptr<Module> m_inner_mod;
+ ::std::unique_ptr<AST::Module> m_local_mod;
::std::vector< ::std::unique_ptr<ExprNode> > m_nodes;
ExprNode_Block():
m_is_unsafe(false)
{}
- ExprNode_Block(::std::vector< ::std::unique_ptr<ExprNode> >&& nodes, ::std::unique_ptr<Module> inner_mod):
+ ExprNode_Block(::std::vector< ::std::unique_ptr<ExprNode> >&& nodes, ::std::unique_ptr<AST::Module> local_mod):
m_is_unsafe(false),
- m_inner_mod( move(inner_mod) ),
+ m_local_mod( move(local_mod) ),
m_nodes( move(nodes) )
{
}
diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp
index 9587eb51..e061e5e0 100644
--- a/src/convert/resolve.cpp
+++ b/src/convert/resolve.cpp
@@ -230,7 +230,7 @@ public:
void visit(AST::ExprNode_Block& node) {
// If there's an inner module on this node
- if( node.m_inner_mod.get() )
+ if( node.m_local_mod.get() )
{
// Add a reference to it to the parent node (add_anon_module will do dedup)
@@ -239,7 +239,7 @@ public:
if(e.module != nullptr)
parent_mod_p = e.module;
AST::Module& parent_mod = *parent_mod_p;
- auto idx = parent_mod.add_anon_module( node.m_inner_mod.get() );
+ auto idx = parent_mod.add_anon_module( node.m_local_mod.get() );
// Obtain the path
AST::Path local_path = m_res.m_module_path;
@@ -251,11 +251,11 @@ public:
local_path.nodes().push_back( AST::PathNode(FMT("#" << idx), {}) );
// And add to the list of modules to use in lookup
- m_res.m_scope_stack.push_back( {idx, node.m_inner_mod.get(), local_path, {}} );
+ m_res.m_scope_stack.push_back( {idx, node.m_local_mod.get(), local_path, {}} );
// Do use resolution on this module
// TODO: When is more advanced resolution done?
- ResolvePaths_HandleModule_Use(m_res.m_crate, m_res.m_scope_stack.back().module_path, *node.m_inner_mod);
+ ResolvePaths_HandleModule_Use(m_res.m_crate, m_res.m_scope_stack.back().module_path, *node.m_local_mod);
}
else {
m_res.m_scope_stack.push_back( {0, nullptr, AST::Path(), {}} );
@@ -1458,11 +1458,11 @@ bool CPathResolver::find_mod_item(const Span& span, AST::Path& path, const ::std
unsigned int idx = m_module_stack.size() - 1;
for(;;)
{
- DEBUG("modpath = " << *modpath << ", mod->name() = '" << mod->name() << "'");
+ DEBUG("modpath = " << *modpath << ", mod->path() = '" << mod->path() << "'");
if( lookup_path_in_module(span, m_crate, *mod, *modpath, path, name, path.size()==1) )
return true;
- DEBUG("mod->name() = '" << mod->name() << "', idx = " << idx);
- if( mod->name() == "" && idx > 0 ) {
+ DEBUG("mod->path() = '" << mod->path() << "', idx = " << idx);
+ if( mod->is_anon() && idx > 0 ) {
idx --;
mod = m_module_stack[idx].first;
modpath = &m_module_stack[idx].second;
@@ -1474,13 +1474,13 @@ bool CPathResolver::find_mod_item(const Span& span, AST::Path& path, const ::std
return false;
}
bool CPathResolver::find_self_mod_item(const Span& span, AST::Path& path, const ::std::string& name) {
- if( m_module->name() == "" )
+ if( m_module->is_anon() )
throw ParseError::Todo("Correct handling of 'self' in anon modules");
return lookup_path_in_module(span, m_crate, *m_module, m_module_path, path, name, path.size()==1);
}
bool CPathResolver::find_super_mod_item(const Span& span, AST::Path& path, const ::std::string& name) {
- if( m_module->name() == "" )
+ if( m_module->is_anon() )
throw ParseError::Todo("Correct handling of 'super' in anon modules");
// 1. Construct path to parent module
@@ -1727,7 +1727,7 @@ void absolutise_path(const Span& span, const AST::Crate& crate, const AST::Modul
void ResolvePaths_HandleModule_Use(const AST::Crate& crate, const AST::Path& modpath, AST::Module& mod)
{
- TRACE_FUNCTION_F("modpath = " << modpath << ", mod = {name:" << mod.name() << "}");
+ TRACE_FUNCTION_F("modpath = " << modpath << ", mod = {path:" << mod.path() << "}");
::std::vector<AST::Path> new_imports;
for( auto& imp : mod.imports() )
{
diff --git a/src/dump_as_rust.cpp b/src/dump_as_rust.cpp
index 30f27d7c..1fd5494d 100644
--- a/src/dump_as_rust.cpp
+++ b/src/dump_as_rust.cpp
@@ -43,9 +43,9 @@ public:
}
m_os << "{";
inc_indent();
- if( n.m_inner_mod.get() )
+ if( n.m_local_mod )
{
- handle_module(*n.m_inner_mod);
+ handle_module(*n.m_local_mod);
}
bool is_first = true;
for( auto& child : n.m_nodes )
diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp
index 4df507c5..ab69ce1c 100644
--- a/src/expand/mod.cpp
+++ b/src/expand/mod.cpp
@@ -173,8 +173,9 @@ struct CExpandExpr:
}
void visit(::AST::ExprNode_Macro& node) override {
+ auto& mod = *(::AST::Module*)(modstack.m_item);
auto ttl = Expand_Macro(
- is_early, crate, modstack, *(::AST::Module*)(modstack.m_item),
+ is_early, crate, modstack, mod,
Span(node.get_pos()),
node.m_name, node.m_ident, node.m_tokens
);
@@ -182,6 +183,7 @@ struct CExpandExpr:
{
if( ttl->lookahead(0) != TOK_EOF )
{
+ SET_MODULE( (*ttl), mod );
// Reparse as expression / item
auto newexpr = Parse_Expr0(*ttl);
// Then call visit on it again
@@ -197,9 +199,8 @@ struct CExpandExpr:
}
void visit(::AST::ExprNode_Block& node) override {
- // TODO! Use a proper path here
- if( node.m_inner_mod ) {
- Expand_Mod(is_early, crate, modstack, AST::Path(), *node.m_inner_mod);
+ if( node.m_local_mod ) {
+ Expand_Mod(is_early, crate, modstack, node.m_local_mod->path(), *node.m_local_mod);
}
this->visit_vector(node.m_nodes);
}
diff --git a/src/parse/common.hpp b/src/parse/common.hpp
index 552f8c4c..4581f365 100644
--- a/src/parse/common.hpp
+++ b/src/parse/common.hpp
@@ -43,23 +43,15 @@ extern ::AST::MacroInvocation Parse_MacroInvocation(ProtoSpan ps, ::AST::MetaIte
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 AST::Struct Parse_Struct(TokenStream& lex, const AST::MetaItems& meta_items);
-extern AST::Enum Parse_EnumDef(TokenStream& lex, const AST::MetaItems& meta_items);
-extern AST::Trait Parse_TraitDef(TokenStream& lex, const AST::MetaItems& meta_items);
-extern void Parse_Impl(TokenStream& lex, AST::Module& mod, AST::MetaItems attrs, bool is_unsafe=false);
extern MacroRules Parse_MacroRules(TokenStream& lex);
-extern void Parse_ExternCrate(TokenStream& lex, AST::Module& mod, AST::MetaItems meta_items);
extern void Parse_Mod_Item(TokenStream& lex, bool file_controls_dir, const ::std::string& file_path, AST::Module& mod, bool is_public, AST::MetaItems meta_items);
extern void Parse_ModRoot_Items(TokenStream& lex, AST::Module& mod, bool file_controls_dir, const ::std::string& path);
-extern AST::Function Parse_FunctionDef(TokenStream& lex, ::std::string abi, AST::MetaItems& attrs, bool allow_self, bool can_be_prototype);
-extern AST::Function Parse_FunctionDefWithCode(TokenStream& lex, ::std::string abi, AST::MetaItems& attrs, bool allow_self);
-extern AST::Expr Parse_Expr(TokenStream& lex, bool const_only);
+extern AST::Expr Parse_Expr(TokenStream& lex);
extern AST::Expr Parse_ExprBlock(TokenStream& lex);
-extern AST::ExprNodeP Parse_Expr0(TokenStream& lex);
+extern AST::ExprNodeP Parse_Expr0(TokenStream& lex);
extern bool Parse_IsTokValue(eTokenType tok_type);
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp
index 10a49dd8..eea4f101 100644
--- a/src/parse/expr.cpp
+++ b/src/parse/expr.cpp
@@ -23,6 +23,7 @@ static inline ExprNodeP mk_exprnodep(const TokenStream& lex, AST::ExprNode* en){
#define NEWNODE(type, ...) mk_exprnodep(lex, new type(__VA_ARGS__))
ExprNodeP Parse_ExprBlockNode(TokenStream& lex);
+ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *expect_end);
ExprNodeP Parse_Stmt(TokenStream& lex);
ExprNodeP Parse_Expr0(TokenStream& lex);
ExprNodeP Parse_IfStmt(TokenStream& lex);
@@ -32,19 +33,16 @@ ExprNodeP Parse_Expr_Match(TokenStream& lex);
ExprNodeP Parse_Expr1(TokenStream& lex);
ExprNodeP Parse_ExprMacro(TokenStream& lex, Token tok);
-AST::Expr Parse_Expr(TokenStream& lex, bool const_only)
+AST::Expr Parse_Expr(TokenStream& lex)
{
- return AST::Expr(Parse_Expr0(lex));
+ return ::AST::Expr( Parse_Expr0(lex) );
}
AST::Expr Parse_ExprBlock(TokenStream& lex)
{
- return AST::Expr(Parse_ExprBlockNode(lex));
+ return ::AST::Expr( Parse_ExprBlockNode(lex) );
}
-ExprNodeP Parse_ExprBlockNode(TokenStream& lex);
-ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *expect_end);
-
ExprNodeP Parse_ExprBlockNode(TokenStream& lex)
{
TRACE_FUNCTION;
@@ -52,8 +50,7 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex)
::std::vector<ExprNodeP> nodes;
- ::std::unique_ptr<AST::Module> local_mod( new AST::Module("") );
- bool keep_mod = false;
+ ::std::unique_ptr<AST::Module> local_mod;
GET_CHECK_TOK(tok, lex, TOK_BRACE_OPEN);
@@ -90,7 +87,9 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex)
case TOK_RWORD_FN:
case TOK_RWORD_MOD:
lex.putback(tok);
- keep_mod = true;
+ if( !local_mod ) {
+ local_mod = lex.parse_state().get_current_mod().add_anon();
+ }
Parse_Mod_Item(lex, false,"!", *local_mod, false, mv$(item_attrs));
break;
// 'unsafe' - Check if the next token isn't a `{`, if so it's an item. Otherwise, fall through
@@ -98,7 +97,9 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex)
if( LOOK_AHEAD(lex) != TOK_BRACE_OPEN )
{
lex.putback(tok);
- keep_mod = true;
+ if( !local_mod ) {
+ local_mod = lex.parse_state().get_current_mod().add_anon();
+ }
Parse_Mod_Item(lex, false,"!", *local_mod, false, mv$(item_attrs));
break;
}
@@ -128,10 +129,7 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex)
}
}
- if( !keep_mod ) {
- local_mod.reset();
- }
- return NEWNODE( AST::ExprNode_Block, ::std::move(nodes), ::std::move(local_mod) );
+ return NEWNODE( AST::ExprNode_Block, ::std::move(nodes), mv$(local_mod) );
}
/// Parse a single line from a block
diff --git a/src/parse/lex.hpp b/src/parse/lex.hpp
index 0dc94d12..703f26ee 100644
--- a/src/parse/lex.hpp
+++ b/src/parse/lex.hpp
@@ -109,6 +109,12 @@ public:
extern ::std::ostream& operator<<(::std::ostream& os, const Token& tok);
+
+namespace AST {
+ class Module;
+ class MetaItems;
+}
+
/// State the parser needs to pass down via a second channel.
struct ParseState
{
@@ -117,6 +123,14 @@ struct ParseState
// A debugging hook that disables expansion of macros
bool no_expand_macros = false;
+ ::AST::Module* module = nullptr;
+ ::AST::MetaItems* parent_attrs = nullptr;
+
+ ::AST::Module& get_current_mod() {
+ assert(this->module);
+ return *this->module;
+ }
+
friend ::std::ostream& operator<<(::std::ostream& os, const ParseState& ps) {
os << "ParseState {";
if(ps.disallow_struct_literal) os << " disallow_struct_literal";
@@ -170,6 +184,8 @@ public:
}
};
+#define SET_MODULE(lex, mod) SavedParseState _sps(lex, lex.parse_state()); lex.parse_state().module = &(mod)
+#define SET_ATTRS(lex, attrs) SavedParseState _sps(lex, lex.parse_state()); lex.parse_state().parent_attrs = &(attrs)
#define SET_PARSE_FLAG(lex, flag) SavedParseState _sps(lex, lex.parse_state()); lex.parse_state().flag = true
#define CLEAR_PARSE_FLAG(lex, flag) SavedParseState _sps(lex, lex.parse_state()); lex.parse_state().flag = false
#define CHECK_PARSE_FLAG(lex, flag) (lex.parse_state().flag == true)
diff --git a/src/parse/root.cpp b/src/parse/root.cpp
index a5f9da81..5cfef49e 100644
--- a/src/parse/root.cpp
+++ b/src/parse/root.cpp
@@ -431,8 +431,7 @@ AST::Struct Parse_Struct(TokenStream& lex, const AST::MetaItems& meta_items)
{
params = Parse_GenericParams(lex);
GET_CHECK_TOK(tok, lex, TOK_GT);
- tok = lex.getToken();
- if(tok.type() == TOK_RWORD_WHERE)
+ if(GET_TOK(tok, lex) == TOK_RWORD_WHERE)
{
Parse_WhereClause(lex, params);
tok = lex.getToken();
@@ -451,6 +450,7 @@ AST::Struct Parse_Struct(TokenStream& lex, const AST::MetaItems& meta_items)
GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
GET_TOK(tok, lex);
}
+ SET_ATTRS(lex, item_attrs);
bool is_pub = false;
if(tok.type() == TOK_RWORD_PUB)
@@ -493,6 +493,7 @@ AST::Struct Parse_Struct(TokenStream& lex, const AST::MetaItems& meta_items)
GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
GET_TOK(tok, lex);
}
+ SET_ATTRS(lex, item_attrs);
bool is_pub = false;
if(tok.type() == TOK_RWORD_PUB) {
@@ -521,7 +522,7 @@ AST::Struct Parse_Struct(TokenStream& lex, const AST::MetaItems& meta_items)
}
}
-AST::Trait Parse_TraitDef(TokenStream& lex, const AST::MetaItems& meta_items)
+AST::Trait Parse_TraitDef(TokenStream& lex, AST::Module& mod, const AST::MetaItems& meta_items)
{
TRACE_FUNCTION;
@@ -573,6 +574,7 @@ AST::Trait Parse_TraitDef(TokenStream& lex, const AST::MetaItems& meta_items)
GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
GET_TOK(tok, lex);
}
+ SET_ATTRS(lex, item_attrs);
::std::string abi = "rust";
switch(tok.type())
@@ -586,12 +588,12 @@ AST::Trait Parse_TraitDef(TokenStream& lex, const AST::MetaItems& meta_items)
::AST::Expr val;
if(GET_TOK(tok, lex) == TOK_EQUAL) {
- val = Parse_Expr(lex, true);
+ val = Parse_Expr(lex);
GET_TOK(tok, lex);
}
CHECK_TOK(tok, TOK_SEMICOLON);
- // TODO: Attrobutes on associated statics
+ // TODO: Attributes on associated statics
trait.add_static( mv$(name), ::AST::Static(AST::Static::STATIC, mv$(ty), val)/*, mv$(item_attrs)*/ );
break; }
case TOK_RWORD_CONST: {
@@ -602,12 +604,12 @@ AST::Trait Parse_TraitDef(TokenStream& lex, const AST::MetaItems& meta_items)
::AST::Expr val;
if(GET_TOK(tok, lex) == TOK_EQUAL) {
- val = Parse_Expr(lex, true);
+ val = Parse_Expr(lex);
GET_TOK(tok, lex);
}
CHECK_TOK(tok, TOK_SEMICOLON);
- // TODO: Attrobutes on associated constants
+ // TODO: Attributes on associated constants
trait.add_static( mv$(name), ::AST::Static(AST::Static::CONST, mv$(ty), val)/*, mv$(item_attrs)*/ );
break; }
// Associated type
@@ -669,6 +671,7 @@ AST::Trait Parse_TraitDef(TokenStream& lex, const AST::MetaItems& meta_items)
{
throw ParseError::Unexpected(lex, tok);
}
+ // TODO: Store `item_attrs`
trait.add_function( ::std::move(name), ::std::move(fcn) );
break; }
default:
@@ -679,7 +682,7 @@ AST::Trait Parse_TraitDef(TokenStream& lex, const AST::MetaItems& meta_items)
return trait;
}
-AST::Enum Parse_EnumDef(TokenStream& lex, const AST::MetaItems& meta_items)
+AST::Enum Parse_EnumDef(TokenStream& lex, AST::Module& mod, const AST::MetaItems& meta_items)
{
TRACE_FUNCTION;
@@ -692,8 +695,7 @@ AST::Enum Parse_EnumDef(TokenStream& lex, const AST::MetaItems& meta_items)
{
params = Parse_GenericParams(lex);
GET_CHECK_TOK(tok, lex, TOK_GT);
- tok = lex.getToken();
- if(tok.type() == TOK_RWORD_WHERE)
+ if(GET_TOK(tok, lex) == TOK_RWORD_WHERE)
{
Parse_WhereClause(lex, params);
tok = lex.getToken();
@@ -706,6 +708,7 @@ AST::Enum Parse_EnumDef(TokenStream& lex, const AST::MetaItems& meta_items)
while( GET_TOK(tok, lex) != TOK_BRACE_CLOSE )
{
auto sp = lex.start_span();
+
AST::MetaItems item_attrs;
while( tok.type() == TOK_ATTR_OPEN )
{
@@ -713,6 +716,7 @@ AST::Enum Parse_EnumDef(TokenStream& lex, const AST::MetaItems& meta_items)
GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
GET_TOK(tok, lex);
}
+ SET_ATTRS(lex, item_attrs);
CHECK_TOK(tok, TOK_IDENT);
::std::string name = tok.str();
@@ -775,7 +779,7 @@ AST::Enum Parse_EnumDef(TokenStream& lex, const AST::MetaItems& meta_items)
}
else if( tok.type() == TOK_EQUAL )
{
- auto node = Parse_Expr(lex, true);
+ auto node = Parse_Expr(lex);
variants.push_back( AST::EnumVariant(mv$(item_attrs), mv$(name), mv$(node)) );
GET_TOK(tok, lex);
}
@@ -822,10 +826,9 @@ AST::MetaItem Parse_MetaItem(TokenStream& lex)
}
}
-void Parse_Impl(TokenStream& lex, AST::Module& mod, AST::MetaItems attrs, bool is_unsafe/*=false*/);
void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl);
-void Parse_Impl(TokenStream& lex, AST::Module& mod, AST::MetaItems attrs, bool is_unsafe/*=false*/)
+void Parse_Impl(TokenStream& lex, AST::Module& mod, AST::MetaItems attrs, bool is_unsafe=false)
{
TRACE_FUNCTION;
Token tok;
@@ -911,7 +914,6 @@ void Parse_Impl(TokenStream& lex, AST::Module& mod, AST::MetaItems attrs, bool i
GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
}
- // TODO: Pass #[] attrs to impl blocks
AST::Impl impl( mv$(attrs), ::std::move(params), ::std::move(impl_type), ::std::move(trait_path) );
// A sequence of method implementations
@@ -949,6 +951,7 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl)
GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
GET_TOK(tok, lex);
}
+ SET_ATTRS(lex, item_attrs);
bool is_public = false;
if(tok.type() == TOK_RWORD_PUB) {
@@ -979,7 +982,7 @@ void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl)
GET_CHECK_TOK(tok, lex, TOK_COLON);
auto ty = Parse_Type(lex);
GET_CHECK_TOK(tok, lex, TOK_EQUAL);
- auto val = Parse_Expr(lex, true);
+ auto val = Parse_Expr(lex);
GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
auto i = ::AST::Static(AST::Static::CONST, mv$(ty), mv$(val));
@@ -1041,6 +1044,7 @@ void Parse_ExternBlock(TokenStream& lex, AST::Module& mod, ::std::string abi)
GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
GET_TOK(tok, lex);
}
+ SET_ATTRS(lex, meta_items);
bool is_public = false;
if( tok.type() == TOK_RWORD_PUB ) {
@@ -1258,6 +1262,9 @@ void Parse_ExternCrate(TokenStream& lex, AST::Module& mod, AST::MetaItems meta_i
void Parse_Mod_Item(TokenStream& lex, bool file_controls_dir, const ::std::string& file_path, AST::Module& mod, bool is_public, AST::MetaItems meta_items)
{
+ SET_MODULE(lex, mod);
+ lex.parse_state().parent_attrs = &meta_items;
+
//TRACE_FUNCTION;
Token tok;
@@ -1328,7 +1335,7 @@ void Parse_Mod_Item(TokenStream& lex, bool file_controls_dir, const ::std::strin
GET_CHECK_TOK(tok, lex, TOK_COLON);
TypeRef type = Parse_Type(lex);
GET_CHECK_TOK(tok, lex, TOK_EQUAL);
- AST::Expr val = Parse_Expr(lex, true);
+ AST::Expr val = Parse_Expr(lex);
GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
mod.add_static(is_public, name, AST::Static(AST::Static::CONST, type, val), mv$(meta_items));
break; }
@@ -1353,11 +1360,10 @@ void Parse_Mod_Item(TokenStream& lex, bool file_controls_dir, const ::std::strin
// `static NAME`
// `static mut NAME`
case TOK_RWORD_STATIC: {
- tok = lex.getToken();
bool is_mut = false;
- if(tok.type() == TOK_RWORD_MUT) {
+ if(GET_TOK(tok, lex) == TOK_RWORD_MUT) {
is_mut = true;
- tok = lex.getToken();
+ GET_TOK(tok, lex);
}
CHECK_TOK(tok, TOK_IDENT);
::std::string name = tok.str();
@@ -1367,7 +1373,7 @@ void Parse_Mod_Item(TokenStream& lex, bool file_controls_dir, const ::std::strin
GET_CHECK_TOK(tok, lex, TOK_EQUAL);
- AST::Expr val = Parse_Expr(lex, true);
+ AST::Expr val = Parse_Expr(lex);
GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
mod.add_static(is_public, name,
@@ -1403,6 +1409,7 @@ void Parse_Mod_Item(TokenStream& lex, bool file_controls_dir, const ::std::strin
// - self not allowed, not prototype
// TODO: Mark as unsafe
auto i = Parse_FunctionDefWithCode(lex, "rust", meta_items, false);
+ //i.set_unsafe();
mod.add_function(is_public, tok.str(), mv$(i), mv$(meta_items));
break; }
// `unsafe trait`
@@ -1410,7 +1417,8 @@ void Parse_Mod_Item(TokenStream& lex, bool file_controls_dir, const ::std::strin
GET_CHECK_TOK(tok, lex, TOK_IDENT);
::std::string name = tok.str();
// TODO: Mark as unsafe
- auto i = Parse_TraitDef(lex, meta_items);
+ auto i = Parse_TraitDef(lex, mod, meta_items);
+ //i.set_unsafe();
mod.add_trait(is_public, name, mv$(i), mv$(meta_items));
break; }
// `unsafe impl`
@@ -1447,7 +1455,7 @@ void Parse_Mod_Item(TokenStream& lex, bool file_controls_dir, const ::std::strin
case TOK_RWORD_ENUM: {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
::std::string name = tok.str();
- auto i = Parse_EnumDef(lex, meta_items);
+ auto i = Parse_EnumDef(lex, mod, meta_items);
mod.add_enum(is_public, name, mv$(i), mv$(meta_items));
break; }
// `impl`
@@ -1458,7 +1466,7 @@ void Parse_Mod_Item(TokenStream& lex, bool file_controls_dir, const ::std::strin
case TOK_RWORD_TRAIT: {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
::std::string name = tok.str();
- auto i = Parse_TraitDef(lex, meta_items);
+ auto i = Parse_TraitDef(lex, mod, meta_items);
mod.add_trait(is_public, name, mv$(i), mv$(meta_items));
break; }
@@ -1466,7 +1474,7 @@ void Parse_Mod_Item(TokenStream& lex, bool file_controls_dir, const ::std::strin
GET_CHECK_TOK(tok, lex, TOK_IDENT);
auto name = mv$(tok.str());
DEBUG("Sub module '" << name << "'");
- AST::Module submod( name );
+ AST::Module submod( mod.path() + name );
// Rules for external files (/ path handling):
// - IF using stdin (path='-') - Disallow and propagate '-' as path
@@ -1548,7 +1556,7 @@ void Parse_Mod_Item(TokenStream& lex, bool file_controls_dir, const ::std::strin
throw ParseError::Generic("Expected { or ; after module name");
}
submod.prescan();
- mod.add_submod(is_public, ::std::move(submod), mv$(meta_items));
+ mod.add_submod(is_public, mv$(name), mv$(submod), mv$(meta_items));
break; }
default:
diff --git a/src/parse/types.cpp b/src/parse/types.cpp
index 16e95f6d..d5a2679f 100644
--- a/src/parse/types.cpp
+++ b/src/parse/types.cpp
@@ -144,7 +144,7 @@ TypeRef Parse_Type_Int(TokenStream& lex)
TypeRef inner = Parse_Type(lex);
if( GET_TOK(tok, lex) == TOK_SEMICOLON ) {
// Sized array
- AST::Expr array_size = Parse_Expr(lex, true);
+ AST::Expr array_size = Parse_Expr(lex);
GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
return TypeRef(TypeRef::TagSizedArray(), inner, array_size.take_node());
}