diff --git a/include/openscad_cpp_parser/api.hpp b/include/openscad_cpp_parser/api.hpp index c41b4ca..070a736 100644 --- a/include/openscad_cpp_parser/api.hpp +++ b/include/openscad_cpp_parser/api.hpp @@ -48,6 +48,18 @@ std::unique_ptr buildScopes(const std::vector>& // why this exists. Never takes ownership. std::unique_ptr buildScopes(const std::vector& ast); +// Same, but recording into a table the CALLER owns, and not attaching it to +// the returned root. +// +// For a resolution that spans several files: `use ` builds a separate +// root Scope per used file, but all of them are read back through one +// evaluation, so their nodes' scopes have to land in ONE table. A per-root +// table would leave the outer evaluation unable to see anything the nested +// resolutions recorded -- every node of a used file would read back as +// having no scope. +std::unique_ptr buildScopesInto(const std::vector>& ast, ScopeTable& table); +std::unique_ptr buildScopesInto(const std::vector& ast, ScopeTable& table); + // Parses `code`. Throws ParseError (with the full caret diagnostic) on a // syntax error. // diff --git a/src/scope.cpp b/src/scope.cpp index 2b669e8..07a1a72 100644 --- a/src/scope.cpp +++ b/src/scope.cpp @@ -8,26 +8,36 @@ namespace oscad { -std::unique_ptr buildScopes(const std::vector>& ast) { - auto owned = std::make_unique(); - ScopeTableScope recording(*owned); +std::unique_ptr buildScopesInto(const std::vector>& ast, ScopeTable& table) { + ScopeTableScope recording(table); auto root = std::make_unique(); collectHoistedDeclarations(ast, *root); for (auto& node : ast) { node->buildScope(*root); } - root->adoptTable(std::move(owned)); return root; } -std::unique_ptr buildScopes(const std::vector& ast) { +std::unique_ptr buildScopes(const std::vector>& ast) { auto owned = std::make_unique(); - ScopeTableScope recording(*owned); + auto root = buildScopesInto(ast, *owned); + root->adoptTable(std::move(owned)); + return root; +} + +std::unique_ptr buildScopesInto(const std::vector& ast, ScopeTable& table) { + ScopeTableScope recording(table); auto root = std::make_unique(); collectHoistedDeclarations(ast, *root); for (ASTNode* node : ast) { node->buildScope(*root); } + return root; +} + +std::unique_ptr buildScopes(const std::vector& ast) { + auto owned = std::make_unique(); + auto root = buildScopesInto(ast, *owned); root->adoptTable(std::move(owned)); return root; }