From 2cd588ca7d71b00c93429c733ce28d78cdd415eb Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 13 Mar 2015 23:11:34 +0800 Subject: Various other features for libcore, now on to loops --- src/convert/ast_iterate.cpp | 8 +++ src/dump_as_rust.cpp | 6 ++ src/macros.cpp | 169 ++++++++++++++++++++++++++++++++++++++++++-- src/macros.hpp | 59 +--------------- src/parse/common.hpp | 1 + src/parse/expr.cpp | 45 +++++++----- src/parse/lex.cpp | 45 +++++++++++- src/parse/lex.hpp | 2 + src/parse/parseerror.cpp | 4 ++ src/parse/parseerror.hpp | 1 + src/parse/root.cpp | 65 ++++++++++++----- 11 files changed, 302 insertions(+), 103 deletions(-) (limited to 'src') 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 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_mappings; + +private: + const TokenTree& m_crate_path; + const ::std::vector& m_root_contents; + const t_mappings m_mappings; + + /// Layer states : Index and Iteration + ::std::vector< ::std::pair > m_offsets; + + /// Cached pointer to the current layer + const ::std::vector* m_cur_ents; // For faster lookup. + /// Iteration counts for each layer + ::std::vector m_layer_counts; + + ::std::unique_ptr 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& 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* 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 Macro_Invoke_Concat(const TokenTree& input, enum eTokenType exp); +::std::unique_ptr Macro_Invoke_Cfg(const TokenTree& input); + void Macro_SetModule(const LList& 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 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*)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 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*)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* MacroExpander::getCurLayer() const return ents; } +::std::unique_ptr 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( new MacroToken( Token(exp, val) ) ); +} + +::std::unique_ptr 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( new MacroToken( Token(TOK_RWORD_FALSE) ) ); + } + else + { + CHECK_TOK(tok, TOK_EOF); + return ::std::unique_ptr( 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 MacroRules; -class MacroExpander: - public TokenStream -{ -public: - // MultiMap (layer, name) -> TokenTree - // - Multiple values are only allowed for layer>0 - typedef ::std::pair 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_mappings; - -private: - const TokenTree& m_crate_path; - const ::std::vector& m_root_contents; - const t_mappings m_mappings; - - /// Layer states : Index and Iteration - ::std::vector< ::std::pair > m_offsets; - - /// Cached pointer to the current layer - const ::std::vector* m_cur_ents; // For faster lookup. - /// Iteration counts for each layer - ::std::vector m_layer_counts; - - ::std::auto_ptr 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& 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* getCurLayer() const; - void prep_counts(); -}; - extern void Macro_SetModule(const LList& mod); -extern MacroExpander Macro_Invoke(const char* name, TokenTree input); +extern ::std::unique_ptr 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 #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 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 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 *prev_modstack, const ::std::string& path); ::std::vector Parse_Path_GenericList(TokenStream& lex) @@ -17,12 +18,22 @@ void Parse_ModRoot(TokenStream& lex, AST::Crate& crate, AST::Module& mod, LList< ::std::vector types; ::std::vector< ::std::string> lifetimes; + ::std::map< ::std::string, TypeRef> assoc_bounds; + ::std::vector 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 refs; + while(GET_TOK(tok, lex) != TOK_PAREN_CLOSE) { - ::std::vector 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()); } 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 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 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 ) -- cgit v1.2.3