Skip to content

Commit

Permalink
Expand - Hackily parse macro_rules early
Browse files Browse the repository at this point in the history
  • Loading branch information
thepowersgang committed Dec 5, 2023
1 parent 1bc671d commit 27d9838
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 11 deletions.
38 changes: 38 additions & 0 deletions src/expand/mod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1987,6 +1987,44 @@ void Expand_Mod_Early(::AST::Crate& crate, ::AST::Module& mod, std::vector<std::
else {
}
}

DEBUG("Items");
for( unsigned int idx = 0; idx < mod.m_items.size(); idx ++ )
{
auto& i = *mod.m_items[idx];
if(auto* mi = i.data.opt_MacroInv() )
{
// 1.74 HACK - Parse `macro_rules` during the first pass, so they're present for `use` to refer to
if( mi->path().is_trivial() && mi->path().as_trivial() == "macro_rules" ) {
auto mi_owned = mv$(*mi);

TRACE_FUNCTION_F("Macro invoke " << mi_owned.path());

auto ttl = Expand_Macro(crate, {}, mod, mi_owned);
assert( mi_owned.path().is_valid() );

if( ttl.get() )
{
// Re-parse tt
assert(ttl.get());
DEBUG("-- Parsing as mod items");
// Move the item list out
auto old_items = std::move(mod.m_items);
// Parse module items
Parse_ModRoot_Items(*ttl, mod);
auto new_item_count = mod.m_items.size();
// Then insert the newly created items
old_items.insert(old_items.begin() + idx + 1, std::make_move_iterator(mod.m_items.begin()), std::make_move_iterator(mod.m_items.end()));
// and move the (updated) item list back in
mod.m_items = std::move(old_items);

auto next_non_macro_item = idx + 1 + new_item_count;
//macro_recursion_stack.push_back(next_non_macro_item == mod.m_items.size() ? nullptr : &*mod.m_items[next_non_macro_item]);
}
mod.m_items[idx]->data.as_MacroInv() = mv$(mi_owned);
}
}
}
}

void Expand(::AST::Crate& crate)
Expand Down
30 changes: 19 additions & 11 deletions src/resolve/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,16 +152,23 @@ namespace {
auto ec_it = AST::g_implicit_crates.find(name);
if(ec_it != AST::g_implicit_crates.end())
{
const auto& ec = crate.m_extern_crates.at(ec_it->second);
DEBUG("Implicitly imported crate");
//if( e.nodes.size() > 1 )
//{
return get_module_hir(ec.m_hir->m_root_module, path, 1, ignore_last, out_path);
//}
//else
//{
// return ResolveModuleRef::make_ImplicitPrelude({});
//}
if( ec_it->second == "" ) {
// This crate!
return get_module_ast(crate.m_root_module, path, 1, ignore_last, out_path);
}
else {
ASSERT_BUG(sp, crate.m_extern_crates.count(ec_it->second), "Crate \"" << ec_it->second << "\" not loaded (for \"" << ec_it->first << "\")");
const auto& ec = crate.m_extern_crates.at(ec_it->second);
DEBUG("Implicitly imported crate");
//if( e.nodes.size() > 1 )
//{
return get_module_hir(ec.m_hir->m_root_module, path, 1, ignore_last, out_path);
//}
//else
//{
// return ResolveModuleRef::make_ImplicitPrelude({});
//}
}
}
}
DEBUG("Not found");
Expand Down Expand Up @@ -447,7 +454,7 @@ namespace {
ResolveItemRef find_item(const AST::Module& mod, const RcString& name, ResolveNamespace ns, ::AST::AbsolutePath* out_path=nullptr)
//ResolveModuleRef get_source_module_for_name(const AST::Module& mod, const RcString& name, ResolveNamespace ns, ::AST::AbsolutePath* out_path=nullptr)
{
TRACE_FUNCTION_F("Looking for " << name << " in " << mod.path());
TRACE_FUNCTION_F("Looking for " << name << " in " << mod.path() << " (ns=" << ns << ")");
if( mod.m_index_populated )
{
TODO(sp, "Look up in index");
Expand Down Expand Up @@ -477,6 +484,7 @@ namespace {
{
for(const auto& i : mod.macros())
{
DEBUG("> MACRO " << i.name);
if(i.name == name)
{
DEBUG("Found in ast (macro)");
Expand Down
8 changes: 8 additions & 0 deletions src/resolve/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ enum class ResolveNamespace
Value,
Macro,
};
static inline ::std::ostream& operator<<(::std::ostream& os, ResolveNamespace ns) {
switch(ns) {
case ResolveNamespace::Namespace: return os << "Namespace";
case ResolveNamespace::Value: return os << "Value";
case ResolveNamespace::Macro: return os << "Macro";
}
return os << "?";
}

/// <summary>
/// Obtain a reference to the module pointed to by `path` (relative to `base_path`)
Expand Down

0 comments on commit 27d9838

Please sign in to comment.