diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/ast/pattern.hpp | 7 | ||||
-rw-r--r-- | src/common.hpp | 22 | ||||
-rw-r--r-- | src/macros.cpp | 18 | ||||
-rw-r--r-- | src/parse/expr.cpp | 4 | ||||
-rw-r--r-- | src/parse/root.cpp | 127 |
6 files changed, 126 insertions, 54 deletions
@@ -31,7 +31,7 @@ clean: output/%.ast: samples/%.rs $(BIN) @mkdir -p output/ - $(DBG) $(BIN) $< --emit ast -o $@ 2>&1 | tee $@_dbg.txt ; test $${PIPESTATUS[0]} -eq 0 + $(DBG) $(BIN) $< --emit ast -o $@ 2>&1 | tee $@_dbg.txt | tail -n 20 ; test $${PIPESTATUS[0]} -eq 0 TEST_FILE = ../../../Source/rust/rustc-nightly/src/libcore/lib.rs test: $(TEST_FILE) $(BIN) output/std.ast output/log.ast output/env_logger.ast output/getopts.ast diff --git a/src/ast/pattern.hpp b/src/ast/pattern.hpp index 7544d53c..a2f9a24b 100644 --- a/src/ast/pattern.hpp +++ b/src/ast/pattern.hpp @@ -69,6 +69,13 @@ public: m_class(ANY) {} + // Wildcard = '..', distinct from '_' + // TODO: Store wildcard as a different pattern type + struct TagWildcard {}; + Pattern(TagWildcard): + m_class(ANY) + {} + struct TagBind {}; Pattern(TagBind, ::std::string name): m_class(ANY), diff --git a/src/common.hpp b/src/common.hpp index 545a0adf..01c710b9 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -62,6 +62,12 @@ inline ::std::ostream& operator<<(::std::ostream& os, const ::std::vector<T>& v) } template <typename T, typename U> +inline ::std::ostream& operator<<(::std::ostream& os, const ::std::pair<T,U>& v) { + os << "(" << v.first << ", " << v.second << ")"; + return os; +} + +template <typename T, typename U> inline ::std::ostream& operator<<(::std::ostream& os, const ::std::map<T,U>& v) { if( v.size() > 0 ) { @@ -77,6 +83,22 @@ inline ::std::ostream& operator<<(::std::ostream& os, const ::std::map<T,U>& v) return os; } +template <typename T, typename U, class Cmp> +inline ::std::ostream& operator<<(::std::ostream& os, const ::std::multimap<T,U,Cmp>& v) { + if( v.size() > 0 ) + { + bool is_first = true; + for( const auto& i : v ) + { + if(!is_first) + os << ", "; + is_first = false; + os << i.first << ": " << i.second; + } + } + return os; +} + } #endif diff --git a/src/macros.cpp b/src/macros.cpp index 3b6147e3..45175620 100644 --- a/src/macros.cpp +++ b/src/macros.cpp @@ -27,7 +27,13 @@ public: struct cmp_mk {
bool operator()(const t_mapping_key& a, const t_mapping_key& b) const {
- return a.first < b.first || ::std::strcmp(a.second, b.second) < 0;
+ if( a.first < b.first )
+ return true;
+ if( a.first == b.first ) {
+ if( ::std::strcmp(a.second, b.second) < 0 )
+ return true;
+ }
+ return false;
}
};
typedef ::std::multimap<t_mapping_key, TokenTree, cmp_mk> t_mappings;
@@ -281,6 +287,10 @@ void Macro_HandlePattern(TTStream& lex, const MacroPatEnt& pat, unsigned int lay //GET_CHECK_TOK(tok, lex, close);
GET_CHECK_TOK(tok, lex, TOK_EOF);
DEBUG( rule.m_contents.size() << " rule contents bound to " << bound_tts.size() << " values - " << name );
+ for( const auto& v : bound_tts )
+ {
+ DEBUG("- " << v.first.first << "#" << v.first.second << " = [" << v.second << "]");
+ }
return ::std::unique_ptr<TokenStream>( (TokenStream*)new MacroExpander(olex, rule.m_contents, bound_tts, g_crate_path_tt) );
}
catch(const ParseError::Base& e)
@@ -399,9 +409,11 @@ Token MacroExpander::realGetToken() {
// - Name
const size_t iter_idx = m_offsets.back().second;
+ DEBUG("m_mappings = " << m_mappings);
const auto tt_i = m_mappings.equal_range( ::std::make_pair(layer, ent.name.c_str()) );
- if( tt_i.first == tt_i.second )
- throw ParseError::Generic( FMT("Cannot find mapping name: " << ent.name << " for layer " << layer) );
+ if( tt_i.first == tt_i.second ) {
+ throw ParseError::Generic(*this, FMT("Cannot find mapping name: " << ent.name << " for layer " << layer) );
+ }
size_t i = 0;
for( auto it = tt_i.first; it != tt_i.second; it ++ )
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 88bb021f..e568bcbb 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -160,6 +160,8 @@ AST::Pattern Parse_PatternReal1(TokenStream& lex) {
case TOK_UNDERSCORE:
return AST::Pattern( );
+ case TOK_DOUBLE_DOT:
+ return AST::Pattern( AST::Pattern::TagWildcard() );
case TOK_AMP:
DEBUG("Ref");
if( GET_TOK(tok, lex) == TOK_RWORD_MUT )
@@ -326,8 +328,6 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex) /// - use/extern/const/let
ExprNodeP Parse_ExprBlockLine(TokenStream& lex, bool *expect_end)
{
- TRACE_FUNCTION;
-
Token tok;
if( GET_TOK(tok, lex) == TOK_LIFETIME )
diff --git a/src/parse/root.cpp b/src/parse/root.cpp index acd0e9e9..e721017a 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -607,7 +607,6 @@ AST::Function Parse_FunctionDef(TokenStream& lex, ::std::string abi, AST::MetaIt AST::Function Parse_FunctionDefWithCode(TokenStream& lex, ::std::string abi, AST::MetaItems attrs, bool allow_self)
{
- TRACE_FUNCTION;
Token tok;
auto ret = Parse_FunctionDef(lex, abi, ::std::move(attrs), allow_self, false);
GET_CHECK_TOK(tok, lex, TOK_BRACE_OPEN);
@@ -946,6 +945,9 @@ AST::MetaItem Parse_MetaItem(TokenStream& lex) }
}
+AST::Impl Parse_Impl(TokenStream& lex, bool is_unsafe/*=false*/);
+void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl);
+
AST::Impl Parse_Impl(TokenStream& lex, bool is_unsafe/*=false*/)
{
TRACE_FUNCTION;
@@ -1018,59 +1020,88 @@ AST::Impl Parse_Impl(TokenStream& lex, bool is_unsafe/*=false*/) // A sequence of method implementations
while( GET_TOK(tok, lex) != TOK_BRACE_CLOSE )
{
- AST::MetaItems item_attrs;
- while( tok.type() == TOK_ATTR_OPEN )
+ lex.putback(tok);
+ Parse_Impl_Item(lex, impl);
+ }
+
+ return impl;
+}
+
+void Parse_Impl_Item(TokenStream& lex, AST::Impl& impl)
+{
+ Token tok;
+
+ GET_TOK(tok, lex);
+
+ AST::MetaItems item_attrs;
+ while( tok.type() == TOK_ATTR_OPEN )
+ {
+ item_attrs.push_back( Parse_MetaItem(lex) );
+ GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
+ GET_TOK(tok, lex);
+ }
+
+ bool is_public = false;
+ if(tok.type() == TOK_RWORD_PUB) {
+ is_public = true;
+ GET_TOK(tok, lex);
+ }
+
+ if(tok.type() == TOK_RWORD_UNSAFE) {
+ item_attrs.push_back( AST::MetaItem("#UNSAFE") );
+ GET_TOK(tok, lex);
+ }
+
+ ::std::string abi = "rust";
+ switch(tok.type())
+ {
+ case TOK_MACRO:
{
- item_attrs.push_back( Parse_MetaItem(lex) );
- GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
- GET_TOK(tok, lex);
- }
-
- bool is_public = false;
- if(tok.type() == TOK_RWORD_PUB) {
- is_public = true;
- GET_TOK(tok, lex);
+ TokenTree tt = Parse_TT(lex, true);
+ if( tt.is_token() ) {
+ DEBUG("TT was a single token (not a sub-tree)");
+ throw ParseError::Unexpected(lex, tt.tok());
+ }
+
+ auto expanded_macro = Macro_Invoke(lex, tok.str().c_str(), tt);
+ auto& lex = *expanded_macro;
+ while( GET_TOK(tok, lex) != TOK_EOF )
+ {
+ lex.putback(tok);
+ Parse_Impl_Item(lex, impl);
+ }
}
-
- if(tok.type() == TOK_RWORD_UNSAFE) {
- item_attrs.push_back( AST::MetaItem("#UNSAFE") );
+ if(GET_TOK(tok, lex) != TOK_SEMICOLON)
+ lex.putback(tok);
+ break;
+ case TOK_RWORD_TYPE: {
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ ::std::string name = tok.str();
+ GET_CHECK_TOK(tok, lex, TOK_EQUAL);
+ impl.add_type(is_public, name, Parse_Type(lex));
+ GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
+ break; }
+ case TOK_RWORD_EXTERN:
+ {
+ abi = "C";
+ if( GET_TOK(tok, lex) == TOK_STRING )
+ abi = tok.str();
+ else
+ lex.putback(tok);
+
GET_TOK(tok, lex);
}
-
- ::std::string abi = "rust";
- switch(tok.type())
- {
- case TOK_RWORD_TYPE: {
- GET_CHECK_TOK(tok, lex, TOK_IDENT);
- ::std::string name = tok.str();
- GET_CHECK_TOK(tok, lex, TOK_EQUAL);
- impl.add_type(is_public, name, Parse_Type(lex));
- GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
- break; }
- case TOK_RWORD_EXTERN:
- {
- abi = "C";
- if( GET_TOK(tok, lex) == TOK_STRING )
- abi = tok.str();
- else
- lex.putback(tok);
-
- GET_TOK(tok, lex);
- }
- CHECK_TOK(tok, TOK_RWORD_FN);
- case TOK_RWORD_FN: {
- GET_CHECK_TOK(tok, lex, TOK_IDENT);
- ::std::string name = tok.str();
- // - Self allowed, can't be prototype-form
- impl.add_function(is_public, ::std::move(name), Parse_FunctionDefWithCode(lex, abi, ::std::move(item_attrs), true));
- break; }
+ CHECK_TOK(tok, TOK_RWORD_FN);
+ case TOK_RWORD_FN: {
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ ::std::string name = tok.str();
+ // - Self allowed, can't be prototype-form
+ impl.add_function(is_public, ::std::move(name), Parse_FunctionDefWithCode(lex, abi, ::std::move(item_attrs), true));
+ break; }
- default:
- throw ParseError::Unexpected(lex, tok);
- }
+ default:
+ throw ParseError::Unexpected(lex, tok);
}
-
- return impl;
}
void Parse_ExternBlock(TokenStream& lex, AST::Module& mod, ::std::string abi)
|