summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-03-10 09:33:34 +0800
committerJohn Hodge <tpg@mutabah.net>2016-03-10 09:33:34 +0800
commit874994e677c48689036587033831af56f78797c8 (patch)
tree3bf94cf6bb51343d7f612c2798f8fa8d28dd4ee5
parent1e8587f474adb1c37147da8d25c4fb364f8fde1c (diff)
downloadmrust-874994e677c48689036587033831af56f78797c8.tar.gz
Expand - Macro cleanup, add cfg! macro (stubbed)
-rw-r--r--Makefile2
-rw-r--r--src/expand/cfg.cpp26
-rw-r--r--src/expand/macro_rules.cpp10
-rw-r--r--src/expand/mod.cpp19
-rw-r--r--src/include/synext.hpp3
-rw-r--r--src/parse/lex.cpp47
-rw-r--r--src/parse/tokentree.hpp18
7 files changed, 109 insertions, 16 deletions
diff --git a/Makefile b/Makefile
index c97be0e0..f34e5e01 100644
--- a/Makefile
+++ b/Makefile
@@ -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);