summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2015-03-18 21:37:09 +0800
committerJohn Hodge <tpg@mutabah.net>2015-03-18 21:37:09 +0800
commit7c774049e8a539ee32923dfbf9ad0c0f36ab4323 (patch)
tree181288bbff011178de807dccb4cb5f5c61bd7952 /src
parentafd9fe2cc7f43fd036837db10e71b04410fadf9a (diff)
downloadmrust-7c774049e8a539ee32923dfbf9ad0c0f36ab4323.tar.gz
Local macros, fixed array literals
Diffstat (limited to 'src')
-rw-r--r--src/ast/expr.cpp2
-rw-r--r--src/ast/expr.hpp5
-rw-r--r--src/common.hpp4
-rw-r--r--src/macros.cpp4
-rw-r--r--src/macros.hpp1
-rw-r--r--src/parse/common.hpp1
-rw-r--r--src/parse/expr.cpp59
-rw-r--r--src/parse/root.cpp12
8 files changed, 64 insertions, 24 deletions
diff --git a/src/ast/expr.cpp b/src/ast/expr.cpp
index 7e0437db..3c1d3c66 100644
--- a/src/ast/expr.cpp
+++ b/src/ast/expr.cpp
@@ -95,8 +95,6 @@ ExprNode::~ExprNode() {
void class::print(::std::ostream& os) const _print \
SERIALISE_TYPE_S(class, serialise) \
-ExprNode_Block::~ExprNode_Block() {
-}
NODE(ExprNode_Block, {
s.item(m_nodes);
},{
diff --git a/src/ast/expr.hpp b/src/ast/expr.hpp
index ddcfbae9..d455f3cb 100644
--- a/src/ast/expr.hpp
+++ b/src/ast/expr.hpp
@@ -44,17 +44,18 @@ struct ExprNode_Block:
public ExprNode
{
bool m_is_unsafe;
+ ::std::unique_ptr<Module> m_inner_mod;
::std::vector< ::std::unique_ptr<ExprNode> > m_nodes;
ExprNode_Block():
m_is_unsafe(false)
{}
- ExprNode_Block(::std::vector< ::std::unique_ptr<ExprNode> >&& nodes):
+ ExprNode_Block(::std::vector< ::std::unique_ptr<ExprNode> >&& nodes, ::std::unique_ptr<Module> inner_mod):
m_is_unsafe(false),
+ m_inner_mod( move(inner_mod) ),
m_nodes( move(nodes) )
{
}
- virtual ~ExprNode_Block() override;
void set_unsafe() { m_is_unsafe = true; }
diff --git a/src/common.hpp b/src/common.hpp
index 01c710b9..c386b729 100644
--- a/src/common.hpp
+++ b/src/common.hpp
@@ -17,10 +17,10 @@
template <typename T>
struct LList
{
- LList* m_prev;
+ const LList* m_prev;
T m_item;
- LList(LList* prev, T item):
+ LList(const LList* prev, T item):
m_prev(prev),
m_item( ::std::move(item) )
{
diff --git a/src/macros.cpp b/src/macros.cpp
index 45175620..841758f1 100644
--- a/src/macros.cpp
+++ b/src/macros.cpp
@@ -112,6 +112,10 @@ void Macro_SetModule(const LList<AST::Module*>& mod)
{
g_macro_module = &mod;
}
+const LList<AST::Module*>* Macro_GetModule()
+{
+ return g_macro_module;
+}
void Macro_InitDefaults()
{
diff --git a/src/macros.hpp b/src/macros.hpp
index bb25f38a..df16a4c5 100644
--- a/src/macros.hpp
+++ b/src/macros.hpp
@@ -127,6 +127,7 @@ public:
/// A sigle 'macro_rules!' block
typedef ::std::vector<MacroRule> MacroRules;
+extern const LList<AST::Module*>* Macro_GetModule();
extern void Macro_SetModule(const LList<AST::Module*>& mod);
extern ::std::unique_ptr<TokenStream> Macro_Invoke(const TokenStream& lex, const ::std::string& name, TokenTree input);
diff --git a/src/parse/common.hpp b/src/parse/common.hpp
index a5938591..ee334f01 100644
--- a/src/parse/common.hpp
+++ b/src/parse/common.hpp
@@ -33,6 +33,7 @@ extern TypeRef Parse_Type(TokenStream& lex);
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::Impl Parse_Impl(TokenStream& lex, bool is_unsafe=false);
+extern void Parse_MacroRules(TokenStream& lex, AST::Module& mod, AST::MetaItems meta_items);
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);
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp
index e568bcbb..4960d275 100644
--- a/src/parse/expr.cpp
+++ b/src/parse/expr.cpp
@@ -213,12 +213,19 @@ AST::Pattern Parse_PatternReal_Path(TokenStream& lex, AST::Path path)
TRACE_FUNCTION;
Token tok;
::std::vector<AST::Pattern> child_pats;
+
+ auto end = TOK_PAREN_CLOSE;
do {
+ if( GET_TOK(tok, lex) == end )
+ break;
+ else
+ lex.putback(tok);
+
AST::Pattern pat = Parse_Pattern(lex);
DEBUG("pat = " << pat);
child_pats.push_back( ::std::move(pat) );
} while( GET_TOK(tok, lex) == TOK_COMMA );
- CHECK_TOK(tok, TOK_PAREN_CLOSE);
+ CHECK_TOK(tok, end);
return child_pats;
}
@@ -232,7 +239,14 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex)
Token tok;
::std::vector<ExprNodeP> nodes;
- ::std::unique_ptr<AST::Module> local_mod;
+
+ ::std::unique_ptr<AST::Module> local_mod( new AST::Module("") );
+ bool keep_mod = false;
+
+ const LList<AST::Module*>* prev_modstack = Macro_GetModule();
+ LList<AST::Module*> modstack(prev_modstack, local_mod.get());
+ Macro_SetModule(modstack);
+
GET_CHECK_TOK(tok, lex, TOK_BRACE_OPEN);
while( GET_TOK(tok, lex) != TOK_BRACE_CLOSE )
@@ -250,7 +264,7 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex)
// Items:
// - 'use'
case TOK_RWORD_USE:
- if( !local_mod.get() ) local_mod.reset( new AST::Module("") );
+ keep_mod = true;
Parse_Use(
lex,
[&local_mod](AST::Path p, std::string s) {
@@ -261,12 +275,12 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex)
break;
// 'extern' blocks
case TOK_RWORD_EXTERN:
- if( !local_mod.get() ) local_mod.reset( new AST::Module("") );
+ keep_mod = true;
Parse_ExternBlock(lex, ::std::move(item_attrs), local_mod->functions());
break;
// - 'const'
case TOK_RWORD_CONST:
- if( !local_mod.get() ) local_mod.reset( new AST::Module("") );
+ keep_mod = true;
{
GET_CHECK_TOK(tok, lex, TOK_IDENT);
::std::string name = tok.str();
@@ -284,23 +298,32 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex)
}
// - 'struct'
case TOK_RWORD_STRUCT:
- if( !local_mod.get() ) local_mod.reset( new AST::Module("") );
+ keep_mod = true;
Parse_Struct(*local_mod, lex, false, item_attrs);
break;
// - 'impl'
case TOK_RWORD_IMPL:
- if( !local_mod.get() ) local_mod.reset( new AST::Module("") );
+ keep_mod = true;
local_mod->add_impl(Parse_Impl(lex, false));
break;
// - 'fn'
case TOK_RWORD_FN:
- if( !local_mod.get() ) local_mod.reset( new AST::Module("") );
+ keep_mod = true;
GET_CHECK_TOK(tok, lex, TOK_IDENT);
// - self not allowed, not prototype
local_mod->add_function(
false, tok.str(), Parse_FunctionDefWithCode(lex, "rust", ::std::move(item_attrs), false)
);
break;
+ // Macros - If not macro_rules, fall though to expression
+ case TOK_MACRO:
+ if( tok.str() == "macro_rules" )
+ {
+ keep_mod = true;
+ Parse_MacroRules(lex, *local_mod, ::std::move(item_attrs));
+ break;
+ }
+ // fall
default: {
lex.putback(tok);
bool expect_end = false;
@@ -318,7 +341,13 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex)
}
}
}
- return NEWNODE( AST::ExprNode_Block, ::std::move(nodes) );
+
+ Macro_SetModule( *prev_modstack );
+ if( !keep_mod )
+ {
+ local_mod.reset();
+ }
+ return NEWNODE( AST::ExprNode_Block, ::std::move(nodes), ::std::move(local_mod) );
}
/// Parse a single line from a block
@@ -372,12 +401,12 @@ ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *expect_end)
TypeRef type;
if( GET_TOK(tok, lex) == TOK_COLON ) {
type = Parse_Type(lex);
- GET_CHECK_TOK(tok, lex, TOK_EQUAL);
+ GET_TOK(tok, lex);
}
- else {
- CHECK_TOK(tok, TOK_EQUAL);
+ ExprNodeP val;
+ if( tok.type() == TOK_EQUAL ) {
+ val = Parse_Expr0(lex);
}
- ExprNodeP val = Parse_Expr0(lex);
return NEWNODE( AST::ExprNode_LetBinding, ::std::move(pat), ::std::move(type), ::std::move(val) );
}
@@ -1168,6 +1197,10 @@ ExprNodeP Parse_ExprVal(TokenStream& lex)
items.push_back( ::std::move(first) );
while( tok.type() == TOK_COMMA )
{
+ if( GET_TOK(tok, lex) == TOK_SQUARE_CLOSE )
+ break;
+ else
+ lex.putback(tok);
items.push_back( Parse_Expr0(lex) );
GET_TOK(tok, lex);
}
diff --git a/src/parse/root.cpp b/src/parse/root.cpp
index e721017a..f1e1acf9 100644
--- a/src/parse/root.cpp
+++ b/src/parse/root.cpp
@@ -316,8 +316,11 @@ TypeRef Parse_Type(TokenStream& lex)
lex.putback(tok);
do
{
- TypeRef type = Parse_Type(lex);
- types.push_back(type);
+ if( GET_TOK(tok, lex) == TOK_PAREN_CLOSE )
+ break;
+ else
+ lex.putback(tok);
+ types.push_back(Parse_Type(lex));
} while( GET_TOK(tok, lex) == TOK_COMMA );
CHECK_TOK(tok, TOK_PAREN_CLOSE);
return TypeRef(TypeRef::TagTuple(), types); }
@@ -1425,7 +1428,7 @@ MacroRule Parse_MacroRules_Var(TokenStream& lex)
return rule;
}
-void Parse_MacroRules(TokenStream& lex, AST::Module& mod, AST::MetaItems& meta_items)
+void Parse_MacroRules(TokenStream& lex, AST::Module& mod, AST::MetaItems meta_items)
{
TRACE_FUNCTION;
@@ -1507,8 +1510,7 @@ void Parse_ModRoot_Items(TokenStream& lex, AST::Crate& crate, AST::Module& mod,
case TOK_MACRO:
if( tok.str() == "macro_rules" )
{
- // TODO: Handle #[macro_export]
- Parse_MacroRules(lex, mod, meta_items);
+ Parse_MacroRules(lex, mod, ::std::move(meta_items));
}
else
{