diff options
-rw-r--r-- | src/expand/macro_rules.cpp | 23 | ||||
-rw-r--r-- | src/expand/macro_rules.hpp | 3 | ||||
-rw-r--r-- | src/expand/mod.cpp | 36 | ||||
-rw-r--r-- | src/include/synext.hpp | 3 | ||||
-rw-r--r-- | src/macros.cpp | 38 | ||||
-rw-r--r-- | src/macros.hpp | 2 | ||||
-rw-r--r-- | src/parse/common.hpp | 4 | ||||
-rw-r--r-- | src/parse/expr.cpp | 10 | ||||
-rw-r--r-- | src/parse/root.cpp | 25 |
9 files changed, 49 insertions, 95 deletions
diff --git a/src/expand/macro_rules.cpp b/src/expand/macro_rules.cpp index fac6dec1..5a8e02c4 100644 --- a/src/expand/macro_rules.cpp +++ b/src/expand/macro_rules.cpp @@ -10,7 +10,7 @@ class CMacroRulesExpander: { bool expand_early() const override { return true; } - AST::Expr expand(const ::std::string& ident, const TokenTree& tt, AST::Module& mod, MacroPosition position) + ::std::unique_ptr<TokenStream> expand(const ::std::string& ident, const TokenTree& tt, AST::Module& mod) override { if( ident == "" ) { throw ::std::runtime_error( "ERROR: macro_rules! requires an identifier" ); @@ -21,7 +21,8 @@ class CMacroRulesExpander: // TODO: Place into current module using `ident` as the name mod.add_macro( false, ident, mac ); - return AST::Expr(); + static TokenTree empty_tt; + return box$( TTStream(empty_tt) ); } }; @@ -59,23 +60,9 @@ class CMacroUseHandler: }; -AST::Expr Macro_Invoke(const char* name, const MacroRules& rules, const TokenTree& tt, AST::Module& mod, MacroPosition position) +::std::unique_ptr<TokenStream> Macro_Invoke(const char* name, const MacroRules& rules, const TokenTree& tt, AST::Module& mod) { - auto out_tt = Macro_InvokeRules(name, rules, tt); - TokenStream& lex = *out_tt; - // TODO: Expand out_tt - switch(position) - { - case MacroPosition::Item: { - LList<AST::Module*> l(nullptr, &mod); - Parse_ModRoot_Items(lex, mod, l, false, "-"); - return AST::Expr(); - } - default: - throw ::std::runtime_error("TODO: Macro in non-item position"); - //case MacroPosition::Stmt: { - // break; } - } + return Macro_InvokeRules(name, rules, tt); } diff --git a/src/expand/macro_rules.hpp b/src/expand/macro_rules.hpp index 81e9b18a..b4e6e1e0 100644 --- a/src/expand/macro_rules.hpp +++ b/src/expand/macro_rules.hpp @@ -11,5 +11,6 @@ namespace AST { class Module; } class TokenTree; +class TokenStream; -extern AST::Expr Macro_Invoke(const char* name, const MacroRules& rules, const TokenTree& tt, AST::Module& mod, MacroPosition position); +extern ::std::unique_ptr<TokenStream> Macro_Invoke(const char* name, const MacroRules& rules, const TokenTree& tt, AST::Module& mod); diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index 3a19ff4e..527fa0d3 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -6,6 +6,7 @@ #include <synext.hpp> #include <map> #include "macro_rules.hpp" +#include "../parse/common.hpp" // For reparse from macros ::std::map< ::std::string, ::std::unique_ptr<ExpandDecorator> > g_decorators; ::std::map< ::std::string, ::std::unique_ptr<ExpandProcMacro> > g_macros; @@ -32,13 +33,13 @@ void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate& } } -AST::Expr Expand_Macro(bool is_early, LList<const AST::Module*> modstack, ::AST::Module& mod, ::AST::MacroInvocation& mi, MacroPosition pos) +::std::unique_ptr<TokenStream> Expand_Macro(bool is_early, LList<const AST::Module*> modstack, ::AST::Module& mod, ::AST::MacroInvocation& mi) { for( const auto& m : g_macros ) { if( mi.name() == m.first && m.second->expand_early() == is_early ) { - auto e = m.second->expand(mi.input_ident(), mi.input_tt(), mod, MacroPosition::Item); + auto e = m.second->expand(mi.input_ident(), mi.input_tt(), mod); mi.clear(); return e; } @@ -57,7 +58,7 @@ AST::Expr Expand_Macro(bool is_early, LList<const AST::Module*> modstack, ::AST: if( mi.input_ident() != "" ) ; // TODO: ERROR - macro_rules! macros can't take an ident - auto e = Macro_Invoke(mr.name.c_str(), mr.data, mi.input_tt(), mod, MacroPosition::Item); + auto e = Macro_Invoke(mr.name.c_str(), mr.data, mi.input_tt(), mod); mi.clear(); return e; } @@ -70,7 +71,7 @@ AST::Expr Expand_Macro(bool is_early, LList<const AST::Module*> modstack, ::AST: if( mi.input_ident() != "" ) ; // TODO: ERROR - macro_rules! macros can't take an ident - auto e = Macro_Invoke(mi.name().c_str(), *mri.data, mi.input_tt(), mod, MacroPosition::Item); + auto e = Macro_Invoke(mi.name().c_str(), *mri.data, mi.input_tt(), mod); mi.clear(); return e; } @@ -83,7 +84,7 @@ AST::Expr Expand_Macro(bool is_early, LList<const AST::Module*> modstack, ::AST: } // Leave valid and return an empty expression - return AST::Expr(); + return ::std::unique_ptr<TokenStream>(); } void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> modstack, ::AST::Path modpath, ::AST::Module& mod) @@ -93,6 +94,9 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo for( const auto& mi: mod.macro_imports_res() ) DEBUG("- Imports '" << mi.name << "'"); + // TODO: Have the AST representation of a module include the definition order, + // mixing macro invocations, general items, use statements, and `impl`s + // 1. Macros first //for( auto& mi : mod.macro_invs() ) for(unsigned int i = 0; i < mod.macro_invs().size(); i ++ ) @@ -104,14 +108,18 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo // Move out of the module to avoid invalidation if a new macro invocation is added auto mi_owned = mv$(mi); - auto rv = Expand_Macro(is_early, modstack, mod, mi_owned, MacroPosition::Item); - if( rv.is_valid() ) - ; // TODO: ERROR - macro yeilded an expression in item position + auto ttl = Expand_Macro(is_early, modstack, mod, mi_owned); if( mi_owned.name() != "" ) { mod.macro_invs()[i] = mv$(mi_owned); } + else + { + // Re-parse tt + assert(ttl.get()); + Parse_ModRoot_Items(*ttl, mod, false, "-"); + } } } @@ -140,24 +148,32 @@ void Expand_Mod(bool is_early, ::AST::Crate& crate, LList<const AST::Module*> mo // TODO: Struct items ), (Enum, + // TODO: Enum variants ), (Trait, + // TODO: Trait definition ), (Type, // TODO: Do type aliases require recursion? ), (Function, - // TODO: + // TODO: Recurse into function code (and types) ), (Static, - // TODO: + // TODO: Recurse into static values ) ) Expand_Attrs(i.data.attrs, (is_early ? AttrStage::EarlyPost : AttrStage::LatePost), crate, path, mod, i.data); } + DEBUG("Impls"); + for( auto& i : mod.impls() ) + { + DEBUG("- " << i); + } + for( const auto& mi: mod.macro_imports_res() ) DEBUG("- Imports '" << mi.name << "'"); diff --git a/src/include/synext.hpp b/src/include/synext.hpp index f8d128f7..05020c8c 100644 --- a/src/include/synext.hpp +++ b/src/include/synext.hpp @@ -20,6 +20,7 @@ namespace AST { class MacroInvocation; } class TokenTree; +class TokenStream; #include "../common.hpp" // for mv$ and other things @@ -59,7 +60,7 @@ class ExpandProcMacro public: virtual bool expand_early() const = 0; - virtual AST::Expr expand(const ::std::string& ident, const TokenTree& tt, AST::Module& mod, MacroPosition position) = 0; + virtual ::std::unique_ptr<TokenStream> expand(const ::std::string& ident, const TokenTree& tt, AST::Module& mod) = 0; }; #define STATIC_DECORATOR(ident, _handler_class) \ diff --git a/src/macros.cpp b/src/macros.cpp index 5a45156e..3cdbe850 100644 --- a/src/macros.cpp +++ b/src/macros.cpp @@ -11,7 +11,6 @@ typedef ::std::map< ::std::string, MacroRules> t_macro_regs;
t_macro_regs g_macro_registrations;
-const LList<AST::Module*>* g_macro_module;
class ParameterMappings
{
@@ -180,15 +179,6 @@ public: ::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;
-}
-const LList<AST::Module*>* Macro_GetModule()
-{
- return g_macro_module;
-}
-
void Macro_InitDefaults()
{
}
@@ -414,9 +404,6 @@ bool Macro_HandlePattern(TTStream& lex, const MacroPatEnt& pat, unsigned int lay {
DEBUG("Invoke " << name << " from " << olex.getPosition());
// 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);
@@ -445,31 +432,6 @@ bool Macro_HandlePattern(TTStream& lex, const MacroPatEnt& pat, unsigned int lay {
return Macro_InvokeRules(olex.getPosition(), macro_reg->first.c_str(), macro_reg->second, input);
}
-
- // Search import list
- for( auto ent = g_macro_module; ent; ent = ent->m_prev )
- {
- const AST::Module& mm = *ent->m_item;
- DEBUG("Module '" << mm.name() << "'");
- for( unsigned int i = mm.macros().size(); i --; )
- {
- const auto& m = mm.macros()[i];
- DEBUG("- [local] " << m.name);
- if( m.name == name )
- {
- return Macro_InvokeRules(olex.getPosition(), m.name.c_str(), m.data, input);
- }
- }
-
- for( const auto& mi : mm.macro_imports_res() )
- {
- DEBUG("- [imp]" << mi.name);
- if( mi.name == name )
- {
- return Macro_InvokeRules(olex.getPosition(), mi.name.c_str(), *mi.data, input);
- }
- }
- }
throw ParseError::Generic(olex, FMT("Macro '" << name << "' was not found") );
}
diff --git a/src/macros.hpp b/src/macros.hpp index 14b4add2..ff6f0dbd 100644 --- a/src/macros.hpp +++ b/src/macros.hpp @@ -147,8 +147,6 @@ public: /// A sigle 'macro_rules!' block
typedef ::std::vector<MacroRule> MacroRules;
-extern const LList<AST::Module*>* Macro_GetModule();
-extern void Macro_SetModule(const LList<AST::Module*>& mod);
extern ::std::unique_ptr<TokenStream> Macro_InvokeRules(const char *name, const MacroRules& rules, TokenTree input);
extern ::std::unique_ptr<TokenStream> Macro_Invoke(const TokenStream& lex, const ::std::string& name, TokenTree input);
diff --git a/src/parse/common.hpp b/src/parse/common.hpp index ed052a33..57d11bf6 100644 --- a/src/parse/common.hpp +++ b/src/parse/common.hpp @@ -51,8 +51,8 @@ extern void Parse_Impl(TokenStream& lex, AST::Module& mod, AST::MetaItems attrs, extern MacroRules Parse_MacroRules(TokenStream& lex);
extern void Parse_ExternCrate(TokenStream& lex, AST::Module& mod, AST::MetaItems meta_items);
-extern void Parse_Mod_Item(TokenStream& lex, LList<AST::Module*>& modstack, bool file_controls_dir, const ::std::string& file_path, AST::Module& mod, bool is_public, AST::MetaItems meta_items);
-extern void Parse_ModRoot_Items(TokenStream& lex, AST::Module& mod, LList<AST::Module*>& modstack, bool file_controls_dir, const ::std::string& path);
+extern void Parse_Mod_Item(TokenStream& lex, bool file_controls_dir, const ::std::string& file_path, AST::Module& mod, bool is_public, AST::MetaItems meta_items);
+extern void Parse_ModRoot_Items(TokenStream& lex, AST::Module& mod, bool file_controls_dir, const ::std::string& path);
extern AST::Function Parse_FunctionDef(TokenStream& lex, ::std::string abi, AST::MetaItems attrs, bool allow_self, bool can_be_prototype);
diff --git a/src/parse/expr.cpp b/src/parse/expr.cpp index 11818a45..b1cc25ce 100644 --- a/src/parse/expr.cpp +++ b/src/parse/expr.cpp @@ -56,11 +56,6 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex) ::std::unique_ptr<AST::Module> local_mod( new AST::Module("") );
bool keep_mod = false;
- const LList<AST::Module*>* prev_modstack = Macro_GetModule();
- LList<AST::Module*> modstack(prev_modstack, local_mod.get());
- Macro_SetModule(modstack);
-
-
GET_CHECK_TOK(tok, lex, TOK_BRACE_OPEN);
while( GET_TOK(tok, lex) != TOK_BRACE_CLOSE )
@@ -95,7 +90,7 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex) case TOK_RWORD_MOD:
lex.putback(tok);
keep_mod = true;
- Parse_Mod_Item(lex, modstack, false,"!", *local_mod, false, mv$(item_attrs));
+ Parse_Mod_Item(lex, false,"!", *local_mod, false, mv$(item_attrs));
break;
// 'unsafe' - Check if the next token isn't a `{`, if so it's an item. Otherwise, fall through
case TOK_RWORD_UNSAFE:
@@ -103,7 +98,7 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex) {
lex.putback(tok);
keep_mod = true;
- Parse_Mod_Item(lex, modstack, false,"!", *local_mod, false, mv$(item_attrs));
+ Parse_Mod_Item(lex, false,"!", *local_mod, false, mv$(item_attrs));
break;
}
// fall
@@ -132,7 +127,6 @@ ExprNodeP Parse_ExprBlockNode(TokenStream& lex) }
}
- Macro_SetModule( *prev_modstack );
if( !keep_mod ) {
local_mod.reset();
}
diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 0860a008..1ba68aca 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -24,7 +24,7 @@ }
AST::MetaItem Parse_MetaItem(TokenStream& lex);
-void Parse_ModRoot(TokenStream& lex, AST::Module& mod, AST::MetaItems& mod_attrs, LList<AST::Module*> *prev_modstack, bool file_controls_dir, const ::std::string& path);
+void Parse_ModRoot(TokenStream& lex, AST::Module& mod, AST::MetaItems& mod_attrs, bool file_controls_dir, const ::std::string& path);
::std::vector< ::std::string> Parse_HRB(TokenStream& lex)
{
@@ -1269,7 +1269,7 @@ void Parse_ExternCrate(TokenStream& lex, AST::Module& mod, AST::MetaItems meta_i //}
}
-void Parse_Mod_Item(TokenStream& lex, LList<AST::Module*>& modstack, bool file_controls_dir, const ::std::string& file_path, AST::Module& mod, bool is_public, AST::MetaItems meta_items)
+void Parse_Mod_Item(TokenStream& lex, bool file_controls_dir, const ::std::string& file_path, AST::Module& mod, bool is_public, AST::MetaItems meta_items)
{
//TRACE_FUNCTION;
Token tok;
@@ -1514,7 +1514,7 @@ void Parse_Mod_Item(TokenStream& lex, LList<AST::Module*>& modstack, bool file_c switch( GET_TOK(tok, lex) )
{
case TOK_BRACE_OPEN: {
- Parse_ModRoot(lex, submod, meta_items, &modstack, sub_file_controls_dir, sub_path+"/");
+ Parse_ModRoot(lex, submod, meta_items, sub_file_controls_dir, sub_path+"/");
GET_CHECK_TOK(tok, lex, TOK_BRACE_CLOSE);
break; }
case TOK_SEMICOLON:
@@ -1540,14 +1540,14 @@ void Parse_Mod_Item(TokenStream& lex, LList<AST::Module*>& modstack, bool file_c {
// Load from dir
Lexer sub_lex(newpath_dir + "mod.rs");
- Parse_ModRoot(sub_lex, submod, meta_items, &modstack, sub_file_controls_dir, newpath_dir);
+ Parse_ModRoot(sub_lex, submod, meta_items, sub_file_controls_dir, newpath_dir);
GET_CHECK_TOK(tok, sub_lex, TOK_EOF);
}
else if( ifs_file.is_open() )
{
// Load from file
Lexer sub_lex(newpath_file);
- Parse_ModRoot(sub_lex, submod, meta_items, &modstack, sub_file_controls_dir, newpath_file);
+ Parse_ModRoot(sub_lex, submod, meta_items, sub_file_controls_dir, newpath_file);
GET_CHECK_TOK(tok, sub_lex, TOK_EOF);
}
else
@@ -1562,7 +1562,6 @@ void Parse_Mod_Item(TokenStream& lex, LList<AST::Module*>& modstack, bool file_c }
submod.prescan();
mod.add_submod(is_public, ::std::move(submod), mv$(meta_items));
- Macro_SetModule(modstack);
break; }
default:
@@ -1570,7 +1569,7 @@ void Parse_Mod_Item(TokenStream& lex, LList<AST::Module*>& modstack, bool file_c }
}
-void Parse_ModRoot_Items(TokenStream& lex, AST::Module& mod, LList<AST::Module*>& modstack, bool file_controls_dir, const ::std::string& path)
+void Parse_ModRoot_Items(TokenStream& lex, AST::Module& mod, bool file_controls_dir, const ::std::string& path)
{
Token tok;
@@ -1623,15 +1622,13 @@ void Parse_ModRoot_Items(TokenStream& lex, AST::Module& mod, LList<AST::Module*> lex.putback(tok);
}
- Parse_Mod_Item(lex, modstack, file_controls_dir,path, mod, is_public, mv$(meta_items));
+ Parse_Mod_Item(lex, file_controls_dir,path, mod, is_public, mv$(meta_items));
}
}
-void Parse_ModRoot(TokenStream& lex, AST::Module& mod, AST::MetaItems& mod_attrs, LList<AST::Module*> *prev_modstack, bool file_controls_dir, const ::std::string& path)
+void Parse_ModRoot(TokenStream& lex, AST::Module& mod, AST::MetaItems& mod_attrs, bool file_controls_dir, const ::std::string& path)
{
TRACE_FUNCTION;
- LList<AST::Module*> modstack(prev_modstack, &mod);
- Macro_SetModule(modstack);
Token tok;
@@ -1645,9 +1642,7 @@ void Parse_ModRoot(TokenStream& lex, AST::Module& mod, AST::MetaItems& mod_attrs }
lex.putback(tok);
- // TODO: Iterate attributes, and check for handlers on each
-
- Parse_ModRoot_Items(lex, mod, modstack, file_controls_dir, path);
+ Parse_ModRoot_Items(lex, mod, file_controls_dir, path);
}
AST::Crate Parse_Crate(::std::string mainfile)
@@ -1661,7 +1656,7 @@ AST::Crate Parse_Crate(::std::string mainfile) AST::Crate crate;
- Parse_ModRoot(lex, crate.root_module(), crate.m_attrs, NULL, true, mainpath);
+ Parse_ModRoot(lex, crate.root_module(), crate.m_attrs, true, mainpath);
return crate;
}
|