diff options
author | John Hodge <tpg@mutabah.net> | 2016-03-10 09:33:34 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-03-10 09:33:34 +0800 |
commit | 874994e677c48689036587033831af56f78797c8 (patch) | |
tree | 3bf94cf6bb51343d7f612c2798f8fa8d28dd4ee5 | |
parent | 1e8587f474adb1c37147da8d25c4fb364f8fde1c (diff) | |
download | mrust-874994e677c48689036587033831af56f78797c8.tar.gz |
Expand - Macro cleanup, add cfg! macro (stubbed)
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/expand/cfg.cpp | 26 | ||||
-rw-r--r-- | src/expand/macro_rules.cpp | 10 | ||||
-rw-r--r-- | src/expand/mod.cpp | 19 | ||||
-rw-r--r-- | src/include/synext.hpp | 3 | ||||
-rw-r--r-- | src/parse/lex.cpp | 47 | ||||
-rw-r--r-- | src/parse/tokentree.hpp | 18 |
7 files changed, 109 insertions, 16 deletions
@@ -29,7 +29,7 @@ OBJ += ast/ast.o ast/crate.o ast/path.o ast/expr.o ast/pattern.o OBJ += ast/provided_module.o OBJ += parse/parseerror.o parse/lex.o OBJ += parse/root.o parse/paths.o parse/types.o parse/expr.o parse/pattern.o parse/macro_rules.o -OBJ += expand/mod.o expand/macro_rules.o +OBJ += expand/mod.o expand/macro_rules.o expand/cfg.o OBJ += dump_as_rust.o OBJ += convert/ast_iterate.o #OBJ += convert/decorators.o diff --git a/src/expand/cfg.cpp b/src/expand/cfg.cpp new file mode 100644 index 00000000..546bb690 --- /dev/null +++ b/src/expand/cfg.cpp @@ -0,0 +1,26 @@ + +#include <synext.hpp> +#include <parse/tokentree.hpp> +#include <parse/lex.hpp> + +class CCfgExpander: + public ExpandProcMacro +{ + bool expand_early() const override { return true; } + + ::std::unique_ptr<TokenStream> expand(Span sp, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + { + if( ident != "" ) { + ERROR(sp, E0000, "cfg! doesn't take an identifier"); + } + + DEBUG("cfg!()"); + + // TODO: Handle cfg!() + + return box$( TTStreamO(TokenTree(TOK_RWORD_FALSE)) ); + } +}; + +STATIC_MACRO("cfg", CCfgExpander); +//STATIC_DECORATOR("cfg", CCfgHandler); diff --git a/src/expand/macro_rules.cpp b/src/expand/macro_rules.cpp index 5a8e02c4..fac987ff 100644 --- a/src/expand/macro_rules.cpp +++ b/src/expand/macro_rules.cpp @@ -10,19 +10,17 @@ class CMacroRulesExpander: { bool expand_early() const override { return true; } - ::std::unique_ptr<TokenStream> expand(const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override + ::std::unique_ptr<TokenStream> expand(Span sp, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override { - if( ident == "" ) { - throw ::std::runtime_error( "ERROR: macro_rules! requires an identifier" ); - } + if( ident == "" ) + ERROR(sp, E0000, "macro_rules! requires an identifier" ); TTStream lex(tt); auto mac = Parse_MacroRules(lex); // TODO: Place into current module using `ident` as the name mod.add_macro( false, ident, mac ); - static TokenTree empty_tt; - return box$( TTStream(empty_tt) ); + return box$( TTStreamO(TokenTree()) ); } }; diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index d77650d0..33f982da 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -56,7 +56,7 @@ void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate& { if( name == m.first && m.second->expand_early() == is_early ) { - auto e = m.second->expand(input_ident, input_tt, mod); + auto e = m.second->expand(mi_span, input_ident, input_tt, mod); return e; } } @@ -155,16 +155,19 @@ void Expand_Expr(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> m void visit(::AST::ExprNode_Macro& node) override { auto ttl = Expand_Macro( - false, modstack, *(::AST::Module*)(modstack.m_item), + is_early, modstack, *(::AST::Module*)(modstack.m_item), Span(node.get_pos()), node.m_name, node.m_ident, node.m_tokens ); - // Reparse as expression / item - auto newexpr = Parse_Expr0(*ttl); - // Then call visit on it again - this->visit(newexpr); - // And schedule it to replace the previous - replacement = mv$(newexpr); + if( ttl.get() != nullptr && ttl->lookahead(0) != TOK_EOF ) + { + // Reparse as expression / item + auto newexpr = Parse_Expr0(*ttl); + // Then call visit on it again + this->visit(newexpr); + // And schedule it to replace the previous + replacement = mv$(newexpr); + } } void visit(::AST::ExprNode_Block& node) override { diff --git a/src/include/synext.hpp b/src/include/synext.hpp index 05020c8c..cd1fc3b5 100644 --- a/src/include/synext.hpp +++ b/src/include/synext.hpp @@ -5,6 +5,7 @@ #define _SYNEXT_HPP_ #include "../ast/item.hpp" +#include <span.hpp> namespace AST { class Crate; @@ -60,7 +61,7 @@ class ExpandProcMacro public: virtual bool expand_early() const = 0; - virtual ::std::unique_ptr<TokenStream> expand(const ::std::string& ident, const TokenTree& tt, AST::Module& mod) = 0; + virtual ::std::unique_ptr<TokenStream> expand(Span sp, const ::std::string& ident, const TokenTree& tt, AST::Module& mod) = 0; }; #define STATIC_DECORATOR(ident, _handler_class) \ diff --git a/src/parse/lex.cpp b/src/parse/lex.cpp index a3e8c0d0..0e928bf2 100644 --- a/src/parse/lex.cpp +++ b/src/parse/lex.cpp @@ -1205,6 +1205,53 @@ Position TTStream::getPosition() const return Position("TTStream", 0,0); } + +TTStreamO::TTStreamO(TokenTree input_tt): + m_input_tt( mv$(input_tt) ) +{ + m_stack.push_back( ::std::make_pair(0, nullptr) ); +} +TTStreamO::~TTStreamO() +{ +} +Token TTStreamO::realGetToken() +{ + while(m_stack.size() > 0) + { + // If current index is above TT size, go up + unsigned int& idx = m_stack.back().first; + const TokenTree& tree = *( m_stack.back().second ? m_stack.back().second : &m_input_tt ); + + if(idx == 0 && tree.is_token()) { + idx ++; + m_last_pos = tree.tok().get_pos(); + return tree.tok(); + } + + if(idx < tree.size()) + { + const TokenTree& subtree = tree[idx]; + idx ++; + if( subtree.size() == 0 ) { + m_last_pos = subtree.tok().get_pos(); + return subtree.tok(); + } + else { + m_stack.push_back( ::std::make_pair(0, &subtree ) ); + } + } + else { + m_stack.pop_back(); + } + } + return Token(TOK_EOF); +} +Position TTStreamO::getPosition() const +{ + return m_last_pos; +} + + TokenStream::TokenStream(): m_cache_valid(false) { diff --git a/src/parse/tokentree.hpp b/src/parse/tokentree.hpp index 6b54e66e..257bd6ad 100644 --- a/src/parse/tokentree.hpp +++ b/src/parse/tokentree.hpp @@ -60,6 +60,24 @@ protected: virtual Token realGetToken() override;
};
+class TTStreamO:
+ public TokenStream
+{
+ Position m_last_pos;
+ const TokenTree m_input_tt;
+ ::std::vector< ::std::pair<unsigned int, const TokenTree*> > m_stack;
+public:
+ TTStreamO(const TokenTree input_tt);
+ ~TTStreamO();
+
+ TTStreamO& operator=(const TTStreamO& x) { m_stack = x.m_stack; return *this; }
+
+ virtual Position getPosition() const override;
+
+protected:
+ virtual Token realGetToken() override;
+};
+
// unwrapped = Exclude the enclosing brackets (used by macro parse code)
extern TokenTree Parse_TT(TokenStream& lex, bool unwrapped);
extern TokenTree Parse_TT_Pattern(TokenStream& lex);
|