From 7c774049e8a539ee32923dfbf9ad0c0f36ab4323 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Wed, 18 Mar 2015 21:37:09 +0800 Subject: Local macros, fixed array literals --- src/ast/expr.cpp | 2 -- src/ast/expr.hpp | 5 +++-- src/common.hpp | 4 ++-- src/macros.cpp | 4 ++++ src/macros.hpp | 1 + src/parse/common.hpp | 1 + src/parse/expr.cpp | 59 ++++++++++++++++++++++++++++++++++++++++------------ src/parse/root.cpp | 12 ++++++----- 8 files changed, 64 insertions(+), 24 deletions(-) (limited to 'src') 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 m_inner_mod; ::std::vector< ::std::unique_ptr > m_nodes; ExprNode_Block(): m_is_unsafe(false) {} - ExprNode_Block(::std::vector< ::std::unique_ptr >&& nodes): + ExprNode_Block(::std::vector< ::std::unique_ptr >&& nodes, ::std::unique_ptr 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 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& mod) { g_macro_module = &mod; } +const LList* 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 MacroRules; +extern const LList* Macro_GetModule(); extern void Macro_SetModule(const LList& mod); extern ::std::unique_ptr 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 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 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 nodes; - ::std::unique_ptr local_mod; + + ::std::unique_ptr local_mod( new AST::Module("") ); + bool keep_mod = false; + + const LList* prev_modstack = Macro_GetModule(); + LList 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 { -- cgit v1.2.3