diff options
-rw-r--r-- | src/convert/ast_iterate.cpp | 8 | ||||
-rw-r--r-- | src/dump_as_rust.cpp | 6 | ||||
-rw-r--r-- | src/macros.cpp | 169 | ||||
-rw-r--r-- | src/macros.hpp | 59 | ||||
-rw-r--r-- | src/parse/common.hpp | 1 | ||||
-rw-r--r-- | src/parse/expr.cpp | 45 | ||||
-rw-r--r-- | src/parse/lex.cpp | 45 | ||||
-rw-r--r-- | src/parse/lex.hpp | 2 | ||||
-rw-r--r-- | src/parse/parseerror.cpp | 4 | ||||
-rw-r--r-- | src/parse/parseerror.hpp | 1 | ||||
-rw-r--r-- | src/parse/root.cpp | 65 |
11 files changed, 302 insertions, 103 deletions
diff --git a/src/convert/ast_iterate.cpp b/src/convert/ast_iterate.cpp index 4d147c70..10eb4342 100644 --- a/src/convert/ast_iterate.cpp +++ b/src/convert/ast_iterate.cpp @@ -66,6 +66,14 @@ void CASTIterator::handle_pattern(AST::Pattern& pat, const TypeRef& type_hint) case AST::Pattern::ANY: // Wildcard, nothing to do break; + case AST::Pattern::REF: + if( type_hint.is_wildcard() ) + handle_pattern(pat.sub_patterns()[0], (const TypeRef&)TypeRef()); + else if( type_hint.is_reference() ) + throw ::std::runtime_error("Ref pattern on non-ref value"); + else + handle_pattern(pat.sub_patterns()[0], type_hint.sub_types()[0]); + break; case AST::Pattern::MAYBE_BIND: throw ::std::runtime_error("Calling CASTIterator::handle_pattern on MAYBE_BIND, not valid"); case AST::Pattern::VALUE: diff --git a/src/dump_as_rust.cpp b/src/dump_as_rust.cpp index fe432268..76bb99b4 100644 --- a/src/dump_as_rust.cpp +++ b/src/dump_as_rust.cpp @@ -343,6 +343,8 @@ public: case AST::ExprNode_BinOp::MULTIPLY: m_os << "*"; break; case AST::ExprNode_BinOp::DIVIDE: m_os << "/"; break; case AST::ExprNode_BinOp::MODULO: m_os << "%"; break; + case AST::ExprNode_BinOp::ADD: m_os << "+"; break; + case AST::ExprNode_BinOp::SUB: m_os << "-"; break; } m_os << " "; if( IS(*n.m_right, AST::ExprNode_BinOp) ) @@ -565,6 +567,10 @@ void RustPrinter::print_pattern(const AST::Pattern& p) case AST::Pattern::ANY: m_os << "_"; break; + case AST::Pattern::REF: + m_os << "& "; + print_pattern(p.sub_patterns()[0]); + break; case AST::Pattern::VALUE: m_os << p.node(); break; diff --git a/src/macros.cpp b/src/macros.cpp index c52f8836..29d17b8f 100644 --- a/src/macros.cpp +++ b/src/macros.cpp @@ -17,6 +17,86 @@ TokenTree g_crate_path_tt = TokenTree({ TokenTree(Token(TOK_STRING, "--CRATE--")),
});
+class MacroExpander:
+ public TokenStream
+{
+public:
+ // MultiMap (layer, name) -> TokenTree
+ // - Multiple values are only allowed for layer>0
+ typedef ::std::pair<unsigned,const char*> t_mapping_key;
+
+ 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;
+ }
+ };
+ typedef ::std::multimap<t_mapping_key, TokenTree, cmp_mk> t_mappings;
+
+private:
+ const TokenTree& m_crate_path;
+ const ::std::vector<MacroRuleEnt>& m_root_contents;
+ const t_mappings m_mappings;
+
+ /// Layer states : Index and Iteration
+ ::std::vector< ::std::pair<size_t,size_t> > m_offsets;
+
+ /// Cached pointer to the current layer
+ const ::std::vector<MacroRuleEnt>* m_cur_ents; // For faster lookup.
+ /// Iteration counts for each layer
+ ::std::vector<size_t> m_layer_counts;
+
+ ::std::unique_ptr<TTStream> m_ttstream;
+
+public:
+ MacroExpander(const MacroExpander& x):
+ m_crate_path(x.m_crate_path),
+ m_root_contents(x.m_root_contents),
+ m_mappings(x.m_mappings),
+ m_offsets({ {0,0} }),
+ m_cur_ents(&m_root_contents)
+ {
+ prep_counts();
+ }
+ MacroExpander(const ::std::vector<MacroRuleEnt>& contents, t_mappings mappings, const TokenTree& crate_path):
+ m_crate_path(crate_path),
+ m_root_contents(contents),
+ m_mappings(mappings),
+ m_offsets({ {0,0} }),
+ m_cur_ents(&m_root_contents)
+ {
+ prep_counts();
+ }
+
+ virtual Position getPosition() const override;
+ virtual Token realGetToken() override;
+private:
+ const ::std::vector<MacroRuleEnt>* getCurLayer() const;
+ void prep_counts();
+};
+
+class MacroToken:
+ public TokenStream
+{
+ Token m_tok;
+public:
+ MacroToken(Token tok);
+ virtual Position getPosition() const override;
+ virtual Token realGetToken() override;
+};
+
+class MacroStringify:
+ public TokenStream
+{
+ Token m_tok;
+public:
+ MacroStringify(const TokenTree& input);
+ virtual Position getPosition() const override;
+ virtual Token realGetToken() override;
+};
+
+::std::unique_ptr<TokenStream> Macro_Invoke_Concat(const TokenTree& input, enum eTokenType exp);
+::std::unique_ptr<TokenStream> Macro_Invoke_Cfg(const TokenTree& input);
+
void Macro_SetModule(const LList<AST::Module*>& mod)
{
g_macro_module = &mod;
@@ -161,7 +241,7 @@ void Macro_HandlePattern(TTStream& lex, const MacroPatEnt& pat, unsigned int lay }
-MacroExpander Macro_InvokeInt(const char *name, const MacroRules& rules, TokenTree input)
+::std::unique_ptr<TokenStream> Macro_InvokeInt(const char *name, const MacroRules& rules, TokenTree input)
{
TRACE_FUNCTION;
@@ -196,7 +276,7 @@ MacroExpander Macro_InvokeInt(const char *name, const MacroRules& rules, TokenTr //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 );
- return MacroExpander(rule.m_contents, bound_tts, g_crate_path_tt);
+ return ::std::unique_ptr<TokenStream>( (TokenStream*)new MacroExpander(rule.m_contents, bound_tts, g_crate_path_tt) );
}
catch(const ParseError::Base& e)
{
@@ -208,13 +288,26 @@ MacroExpander Macro_InvokeInt(const char *name, const MacroRules& rules, TokenTr throw ParseError::Todo("Error when macro fails to match");
}
-MacroExpander Macro_Invoke(const char* name, TokenTree input)
+::std::unique_ptr<TokenStream> Macro_Invoke(const TokenStream& olex, const ::std::string& name, TokenTree input)
{
// XXX: EVIL HACK! - This should be removed when std loading is implemented
if( g_macro_registrations.size() == 0 ) {
Macro_InitDefaults();
}
-
+
+ if( name == "concat_idents" ) {
+ return Macro_Invoke_Concat(input, TOK_IDENT);
+ }
+ else if( name == "concat_strings" ) {
+ return Macro_Invoke_Concat(input, TOK_STRING);
+ }
+ else if( name == "cfg" ) {
+ return Macro_Invoke_Cfg(input);
+ }
+ else if( name == "stringify" ) {
+ return ::std::unique_ptr<TokenStream>( (TokenStream*)new MacroStringify(input) );
+ }
+
// Look for macro in builtins
t_macro_regs::iterator macro_reg = g_macro_registrations.find(name);
if( macro_reg != g_macro_registrations.end() )
@@ -245,7 +338,7 @@ MacroExpander Macro_Invoke(const char* name, TokenTree input) }
}
- throw ParseError::Generic( ::std::string("Macro '") + name + "' was not found" );
+ throw ParseError::Generic(olex, FMT("Macro '" << name << "' was not found") );
}
Position MacroExpander::getPosition() const
@@ -399,6 +492,72 @@ const ::std::vector<MacroRuleEnt>* MacroExpander::getCurLayer() const return ents;
}
+::std::unique_ptr<TokenStream> Macro_Invoke_Concat(const TokenTree& input, enum eTokenType exp)
+{
+ Token tok;
+ TTStream lex(input);
+ ::std::string val;
+ do
+ {
+ GET_CHECK_TOK(tok, lex, exp);
+ val += tok.str();
+ } while( GET_TOK(tok, lex) == TOK_COMMA );
+ CHECK_TOK(tok, TOK_EOF);
+
+
+ return ::std::unique_ptr<TokenStream>( new MacroToken( Token(exp, val) ) );
+}
+
+::std::unique_ptr<TokenStream> Macro_Invoke_Cfg(const TokenTree& input)
+{
+ Token tok;
+ TTStream lex(input);
+
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ ::std::string var = tok.str();
+
+ if( GET_TOK(tok, lex) == TOK_EQUAL )
+ {
+ GET_CHECK_TOK(tok, lex, TOK_STRING);
+ ::std::string val = tok.str();
+ GET_CHECK_TOK(tok, lex, TOK_EOF);
+ return ::std::unique_ptr<TokenStream>( new MacroToken( Token(TOK_RWORD_FALSE) ) );
+ }
+ else
+ {
+ CHECK_TOK(tok, TOK_EOF);
+ return ::std::unique_ptr<TokenStream>( new MacroToken( Token(TOK_RWORD_FALSE) ) );
+ }
+}
+
+MacroToken::MacroToken(Token tok):
+ m_tok(tok)
+{
+}
+Position MacroToken::getPosition() const
+{
+ return Position("macro", 0);
+}
+Token MacroToken::realGetToken()
+{
+ Token ret = m_tok;
+ m_tok = Token(TOK_EOF);
+ return ret;
+}
+MacroStringify::MacroStringify(const TokenTree& input)
+{
+ throw ParseError::Todo("Stringify");
+}
+Position MacroStringify::getPosition() const
+{
+ return Position("stringify", 0);
+}
+Token MacroStringify::realGetToken()
+{
+ Token ret = m_tok;
+ m_tok = Token(TOK_EOF);
+ return ret;
+}
SERIALISE_TYPE_S(MacroRule, {
s.item(m_pattern);
s.item(m_contents);
diff --git a/src/macros.hpp b/src/macros.hpp index 2938cb93..2fa74698 100644 --- a/src/macros.hpp +++ b/src/macros.hpp @@ -111,64 +111,7 @@ public: /// A sigle 'macro_rules!' block
typedef ::std::vector<MacroRule> MacroRules;
-class MacroExpander:
- public TokenStream
-{
-public:
- // MultiMap (layer, name) -> TokenTree
- // - Multiple values are only allowed for layer>0
- typedef ::std::pair<unsigned,const char*> t_mapping_key;
-
- 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;
- }
- };
- typedef ::std::multimap<t_mapping_key, TokenTree, cmp_mk> t_mappings;
-
-private:
- const TokenTree& m_crate_path;
- const ::std::vector<MacroRuleEnt>& m_root_contents;
- const t_mappings m_mappings;
-
- /// Layer states : Index and Iteration
- ::std::vector< ::std::pair<size_t,size_t> > m_offsets;
-
- /// Cached pointer to the current layer
- const ::std::vector<MacroRuleEnt>* m_cur_ents; // For faster lookup.
- /// Iteration counts for each layer
- ::std::vector<size_t> m_layer_counts;
-
- ::std::auto_ptr<TTStream> m_ttstream;
-
-public:
- MacroExpander(const MacroExpander& x):
- m_crate_path(x.m_crate_path),
- m_root_contents(x.m_root_contents),
- m_mappings(x.m_mappings),
- m_offsets({ {0,0} }),
- m_cur_ents(&m_root_contents)
- {
- prep_counts();
- }
- MacroExpander(const ::std::vector<MacroRuleEnt>& contents, t_mappings mappings, const TokenTree& crate_path):
- m_crate_path(crate_path),
- m_root_contents(contents),
- m_mappings(mappings),
- m_offsets({ {0,0} }),
- m_cur_ents(&m_root_contents)
- {
- prep_counts();
- }
-
- virtual Position getPosition() const override;
- virtual Token realGetToken() override;
-private:
- const ::std::vector<MacroRuleEnt>* getCurLayer() const;
- void prep_counts();
-};
-
extern void Macro_SetModule(const LList<AST::Module*>& mod);
-extern MacroExpander Macro_Invoke(const char* name, TokenTree input);
+extern ::std::unique_ptr<TokenStream> Macro_Invoke(const TokenStream& lex, const ::std::string& name, TokenTree input);
#endif // MACROS_HPP_INCLUDED
diff --git a/src/parse/common.hpp b/src/parse/common.hpp index ff72920c..3bc599a9 100644 --- a/src/parse/common.hpp +++ b/src/parse/common.hpp @@ -3,6 +3,7 @@ #include <iostream>
#define GET_TOK(tok, lex) ((tok = lex.getToken()).type())
+#define LOOK_AHEAD(lex) (lex.lookahead(0))
#define GET_CHECK_TOK(tok, lex, exp) do {\
if((tok = lex.getToken()).type() != exp) { \
DEBUG("GET_CHECK_TOK " << __FILE__ << ":" << __LINE__); \
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 0bebbc64..10b942ac 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -256,11 +256,11 @@ ExprNodeP Parse_Stmt(TokenStream& lex, bool& opt_semicolon) case TOK_RWORD_RETURN:
return NEWNODE( AST::ExprNode_Return, Parse_Expr1(lex) );
case TOK_RWORD_LOOP:
- throw ParseError::Todo("loop");
+ throw ParseError::Todo(lex, "loop");
case TOK_RWORD_FOR:
- throw ParseError::Todo("for");
+ throw ParseError::Todo(lex, "for");
case TOK_RWORD_WHILE:
- throw ParseError::Todo("while");
+ throw ParseError::Todo(lex, "while");
case TOK_RWORD_IF:
opt_semicolon = true;
return Parse_IfStmt(lex);
@@ -575,25 +575,34 @@ ExprNodeP Parse_ExprFC(TokenStream& lex) lex.putback(tok);
val = NEWNODE( AST::ExprNode_CallObject, ::std::move(val), Parse_ParenList(lex) );
break;
- case TOK_DOT: {
+ case TOK_DOT:
// Field access / method call
// TODO: What about tuple indexing?
- GET_CHECK_TOK(tok, lex, TOK_IDENT);
- ::std::string name = tok.str();
- switch( GET_TOK(tok, lex) )
+ switch(GET_TOK(tok, lex))
{
- case TOK_PAREN_OPEN:
- lex.putback(tok);
- val = NEWNODE( AST::ExprNode_CallMethod, ::std::move(val), AST::PathNode(name, {}), Parse_ParenList(lex) );
+ case TOK_IDENT: {
+ ::std::string name = tok.str();
+ switch( GET_TOK(tok, lex) )
+ {
+ case TOK_PAREN_OPEN:
+ lex.putback(tok);
+ val = NEWNODE( AST::ExprNode_CallMethod, ::std::move(val), AST::PathNode(name, {}), Parse_ParenList(lex) );
+ break;
+ case TOK_DOUBLE_COLON:
+ throw ParseError::Todo("method calls - generic");
+ default:
+ val = NEWNODE( AST::ExprNode_Field, ::std::move(val), ::std::string(name) );
+ lex.putback(tok);
+ break;
+ }
+ break; }
+ case TOK_INTEGER:
+ val = NEWNODE( AST::ExprNode_Field, ::std::move(val), FMT(tok.intval()) );
break;
- case TOK_DOUBLE_COLON:
- throw ParseError::Todo("method calls - generic");
default:
- val = NEWNODE( AST::ExprNode_Field, ::std::move(val), ::std::string(name) );
- lex.putback(tok);
- break;
+ throw ParseError::Unexpected(lex, tok);
}
- break; }
+ break;
default:
lex.putback(tok);
return val;
@@ -737,8 +746,8 @@ ExprNodeP Parse_ExprVal(TokenStream& lex) }
else
{
- MacroExpander expanded_macro = Macro_Invoke(name.c_str(), tt);
- return Parse_Expr0(expanded_macro);
+ auto expanded_macro = Macro_Invoke(lex, name, tt);
+ return Parse_Expr0(*expanded_macro);
}
}
default:
diff --git a/src/parse/lex.cpp b/src/parse/lex.cpp index fc2c7401..b290b3f1 100644 --- a/src/parse/lex.cpp +++ b/src/parse/lex.cpp @@ -76,8 +76,8 @@ static const struct { TOKENT("==", TOK_DOUBLE_EQUAL), TOKENT("=>", TOK_FATARROW), TOKENT(">", TOK_GT), - TOKENT(">>", TOK_DOUBLE_GT), TOKENT(">=", TOK_GTE), + TOKENT(">>", TOK_DOUBLE_GT), TOKENT("?", TOK_QMARK), TOKENT("@", TOK_AT), // A-Z :: Elsewhere @@ -678,6 +678,13 @@ Token TokenStream::getToken() m_cache_valid = false; return m_cache; } + else if( m_lookahead.size() ) + { + Token ret = m_lookahead.front(); + m_lookahead.erase(m_lookahead.begin()); + ::std::cout << "getToken[" << typeid(*this).name() << "] - " << ret << ::std::endl; + return ret; + } else { Token ret = this->realGetToken(); @@ -687,6 +694,38 @@ Token TokenStream::getToken() } void TokenStream::putback(Token tok) { - m_cache_valid = true; - m_cache = tok; + if( m_cache_valid ) + { + DEBUG("" << getPosition()); + throw ParseError::BugCheck("Double putback"); + } + else + { + m_cache_valid = true; + m_cache = tok; + } } + +eTokenType TokenStream::lookahead(unsigned int i) +{ + const unsigned int MAX_LOOKAHEAD = 3; + + if( m_cache_valid ) + { + if( i == 0 ) + return m_cache.type(); + i --; + } + + if( i >= MAX_LOOKAHEAD ) + throw ParseError::BugCheck("Excessive lookahead"); + + while( i >= m_lookahead.size() ) + { + DEBUG("lookahead - read #" << m_lookahead.size()); + m_lookahead.push_back( this->realGetToken() ); + } + + return m_lookahead[i].type(); +} + diff --git a/src/parse/lex.hpp b/src/parse/lex.hpp index bea5698a..c754c61d 100644 --- a/src/parse/lex.hpp +++ b/src/parse/lex.hpp @@ -76,12 +76,14 @@ class TokenStream { bool m_cache_valid; Token m_cache; + ::std::vector<Token> m_lookahead; ParseState m_parse_state; public: TokenStream(); virtual ~TokenStream(); Token getToken(); void putback(Token tok); + eTokenType lookahead(unsigned int count); virtual Position getPosition() const = 0; ParseState& parse_state() { return m_parse_state; } diff --git a/src/parse/parseerror.cpp b/src/parse/parseerror.cpp index b0674c07..e5385257 100644 --- a/src/parse/parseerror.cpp +++ b/src/parse/parseerror.cpp @@ -12,6 +12,10 @@ ParseError::Generic::Generic(::std::string message): {
::std::cout << "Generic(" << message << ")" << ::std::endl;
}
+ParseError::Generic::Generic(const TokenStream& lex, ::std::string message)
+{
+ ::std::cout << lex.getPosition() << ": Generic(" << message << ")" << ::std::endl;
+}
ParseError::BugCheck::BugCheck(::std::string message):
m_message(message)
diff --git a/src/parse/parseerror.hpp b/src/parse/parseerror.hpp index 5868f629..bfea40b3 100644 --- a/src/parse/parseerror.hpp +++ b/src/parse/parseerror.hpp @@ -19,6 +19,7 @@ class Generic: ::std::string m_message;
public:
Generic(::std::string message);
+ Generic(const TokenStream& lex, ::std::string message);
virtual ~Generic() throw () {}
};
diff --git a/src/parse/root.cpp b/src/parse/root.cpp index b6b7af15..5b14ff02 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -8,6 +8,7 @@ #include <cassert>
extern AST::Pattern Parse_Pattern(TokenStream& lex);
+AST::MetaItem Parse_MetaItem(TokenStream& lex);
void Parse_ModRoot(TokenStream& lex, AST::Crate& crate, AST::Module& mod, LList<AST::Module*> *prev_modstack, const ::std::string& path);
::std::vector<TypeRef> Parse_Path_GenericList(TokenStream& lex)
@@ -17,12 +18,22 @@ void Parse_ModRoot(TokenStream& lex, AST::Crate& crate, AST::Module& mod, LList< ::std::vector<TypeRef> types;
::std::vector< ::std::string> lifetimes;
+ ::std::map< ::std::string, TypeRef> assoc_bounds;
+ ::std::vector<unsigned int> int_args;
do {
switch(GET_TOK(tok, lex))
{
case TOK_LIFETIME:
lifetimes.push_back( tok.str() );
break;
+ case TOK_IDENT:
+ if( LOOK_AHEAD(lex) == TOK_EQUAL )
+ {
+ ::std::string name = tok.str();
+ GET_CHECK_TOK(tok, lex, TOK_EQUAL);
+ assoc_bounds.insert( ::std::make_pair( ::std::move(name), Parse_Type(lex) ) );
+ break;
+ }
default:
lex.putback(tok);
types.push_back( Parse_Type(lex) );
@@ -38,6 +49,7 @@ void Parse_ModRoot(TokenStream& lex, AST::Crate& crate, AST::Module& mod, LList< CHECK_TOK(tok, TOK_GT);
}
+ // TODO: Actually use the lifetimes/assoc_bounds
return types;
}
@@ -477,24 +489,30 @@ void Parse_Struct(AST::Module& mod, TokenStream& lex, const bool is_public, cons }
if(tok.type() == TOK_PAREN_OPEN)
{
- TypeRef inner = Parse_Type(lex);
- tok = lex.getToken();
- if(tok.type() != TOK_PAREN_CLOSE)
+ // Tuple structs
+ ::std::vector<AST::StructItem> refs;
+ while(GET_TOK(tok, lex) != TOK_PAREN_CLOSE)
{
- ::std::vector<TypeRef> refs;
- refs.push_back(inner);
- while( (tok = lex.getToken()).type() == TOK_COMMA )
- {
- refs.push_back( Parse_Type(lex) );
- }
- CHECK_TOK(tok, TOK_PAREN_CLOSE);
- inner = TypeRef(TypeRef::TagTuple(), refs);
+ bool is_pub = false;
+ if(tok.type() == TOK_RWORD_PUB)
+ is_pub = true;
+ else
+ lex.putback(tok);
+
+ refs.push_back( AST::StructItem( "", Parse_Type(lex), is_pub ) );
+ if( GET_TOK(tok, lex) != TOK_COMMA )
+ break;
}
- throw ParseError::Todo("tuple struct");
+ CHECK_TOK(tok, TOK_PAREN_CLOSE);
+ GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
+ if( refs.size() == 0 )
+ throw ParseError::Generic(lex, "Use 'struct Name;' instead of 'struct Name();' ... ning-nong");
+ mod.add_struct(is_public, ::std::move(name), ::std::move(params), ::std::move(refs));
}
else if(tok.type() == TOK_SEMICOLON)
{
- throw ParseError::Todo("unit-like struct");
+ // Unit-like struct
+ mod.add_struct(is_public, name, params, ::std::vector<AST::StructItem>());
}
else if(tok.type() == TOK_BRACE_OPEN)
{
@@ -512,6 +530,8 @@ void Parse_Struct(AST::Module& mod, TokenStream& lex, const bool is_public, cons break;
CHECK_TOK(tok, TOK_COMMA);
}
+ if( items.size() == 0 )
+ throw ParseError::Generic(lex, "Use 'struct Name;' instead of 'struct Name { }' ... ning-nong");
mod.add_struct(is_public, name, params, items);
}
else
@@ -567,6 +587,14 @@ AST::Trait Parse_TraitDef(TokenStream& lex, const AST::MetaItems& meta_items) CHECK_TOK(tok, TOK_BRACE_OPEN);
while( GET_TOK(tok, lex) != TOK_BRACE_CLOSE )
{
+ 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);
+ }
+
switch(tok.type())
{
case TOK_RWORD_STATIC: {
@@ -721,9 +749,9 @@ AST::Impl Parse_Impl(TokenStream& lex) AST::Impl impl( ::std::move(params), ::std::move(impl_type), ::std::move(trait_type) );
// A sequence of method implementations
- AST::MetaItems item_attrs;
while( GET_TOK(tok, lex) != TOK_BRACE_CLOSE )
{
+ AST::MetaItems item_attrs;
while( tok.type() == TOK_ATTR_OPEN )
{
item_attrs.push_back( Parse_MetaItem(lex) );
@@ -774,10 +802,10 @@ void Parse_Use(TokenStream& lex, ::std::function<void(AST::Path, ::std::string)> switch( GET_TOK(tok, lex) )
{
case TOK_RWORD_SELF:
- throw ParseError::Todo("Parse_Use - self");
+ path = AST::Path( ); // relative path
break;
case TOK_RWORD_SUPER:
- throw ParseError::Todo("Parse_Use - super");
+ throw ParseError::Todo(lex, "Parse_Use - super");
break;
case TOK_IDENT:
path.append( AST::PathNode(tok.str(), {}) );
@@ -1138,8 +1166,8 @@ void Parse_ModRoot_Items(TokenStream& lex, AST::Crate& crate, AST::Module& mod, }
::std::string name = tok.str();
- MacroExpander expanded_macro = Macro_Invoke(name.c_str(), tt);
- Parse_ModRoot_Items(expanded_macro, crate, mod, modstack, path);
+ auto expanded_macro = Macro_Invoke(lex, name.c_str(), tt);
+ Parse_ModRoot_Items(*expanded_macro, crate, mod, modstack, path);
}
break;
@@ -1349,7 +1377,6 @@ void Parse_ModRoot(TokenStream& lex, AST::Crate& crate, AST::Module& mod, LList< LList<AST::Module*> modstack(prev_modstack, &mod);
Macro_SetModule(modstack);
- const bool nested_module = (path == "-"); // 'mod name { code }', as opposed to 'mod name;'
Token tok;
if( crate.m_load_std )
|