diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/path.cpp | 65 | ||||
-rw-r--r-- | src/ast/path.hpp | 11 | ||||
-rw-r--r-- | src/convert/resolve.cpp | 69 | ||||
-rw-r--r-- | src/coretypes.hpp | 1 | ||||
-rw-r--r-- | src/parse/types.cpp | 1 | ||||
-rw-r--r-- | src/types.cpp | 18 |
6 files changed, 108 insertions, 57 deletions
diff --git a/src/ast/path.cpp b/src/ast/path.cpp index 4f83ae34..338a0b15 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -56,9 +56,10 @@ typename ::std::vector<Item<T> >::const_iterator find_named(const ::std::vector< }); } +/// Resolve a path into a canonical form, and bind it to the target value void Path::resolve(const Crate& root_crate) { - DEBUG("*this = " << *this); + TRACE_FUNCTION_F("*this = "<< *this); if(m_class != ABSOLUTE) throw ParseError::BugCheck("Calling Path::resolve on non-absolute path"); DEBUG("m_crate = '" << m_crate << "'"); @@ -102,18 +103,7 @@ void Path::resolve(const Crate& root_crate) continue; } } - - // Start searching for: - // - Re-exports - { - auto& imp = mod->imports(); - auto it = find_named(imp, node.name()); - if( it != imp.end() ) - { - DEBUG("Re-exported path " << it->data); - throw ParseError::Todo("Path::resolve() re-export"); - } - } + // Type Aliases { auto& items = mod->type_aliases(); @@ -232,6 +222,55 @@ void Path::resolve(const Crate& root_crate) } } + // - Re-exports + // > Comes last, as it's a potentially expensive operation + { + for( const auto& imp : mod->imports() ) + { + if( !imp.is_pub ) + { + // not public, ignore + } + else if( imp.name == node.name() ) + { + // replace nodes 0:i with the source path + DEBUG("Re-exported path " << imp.data); + AST::Path newpath = imp.data; + for( unsigned int j = i+1; j < m_nodes.size(); j ++ ) + { + newpath.m_nodes.push_back( m_nodes[j] ); + } + DEBUG("- newpath = " << newpath); + // TODO: This should check for recursion somehow + newpath.resolve(root_crate); + + *this = newpath; + DEBUG("Alias resolved, *this = " << *this); + return ; + } + else if( imp.name == "" ) + { + // Loop avoidance, don't check this + if( &imp.data == this ) + continue ; + + if( !imp.data.is_bound() ) + { + // not yet bound, so run resolution (recursion) + DEBUG("Recursively resolving pub wildcard use " << imp.data); + //imp.data.resolve(root_crate); + throw ParseError::Todo("Path::resolve() wildcard re-export call resolve"); + } + + throw ParseError::Todo("Path::resolve() wildcard re-export"); + } + else + { + // Can't match, ignore + } + } + } + throw ParseError::Generic("Unable to find component '" + node.name() + "'"); } diff --git a/src/ast/path.hpp b/src/ast/path.hpp index 51dd70f5..00a1b439 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -128,13 +128,18 @@ public: } } + /// Add the all nodes except the first from 'b' to 'a' and return static Path add_tailing(const Path& a, const Path& b) { Path ret(a); - ret[ret.size()-1].args() = b[0].args(); - for(unsigned int i = 1; i < b.m_nodes.size(); i ++) - ret.m_nodes.push_back(b.m_nodes[i]); + ret.add_tailing(b); return ret; } + /// Grab the args from the first node of b, and add the rest to the end of the path + void add_tailing(const Path& b) { + m_nodes.back().args() = b[0].args(); + for(unsigned int i = 1; i < b.m_nodes.size(); i ++) + m_nodes.push_back(b.m_nodes[i]); + } Path operator+(PathNode&& pn) const { Path tmp; tmp.append( ::std::move(pn) ); diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp index 49c2e2a9..1e320e6f 100644 --- a/src/convert/resolve.cpp +++ b/src/convert/resolve.cpp @@ -381,68 +381,55 @@ void CPathResolver::handle_module(AST::Path path, AST::Module& mod) void ResolvePaths_HandleModule_Use(const AST::Crate& crate, const AST::Path& modpath, AST::Module& mod)
{
- DEBUG("modpath = " << modpath);
+ TRACE_FUNCTION_F("modpath = " << modpath);
::std::vector<AST::Path> new_imports;
for( auto& imp : mod.imports() )
{
// TODO: Handle 'super' and 'self' imports
// - Any other type of import will be absolute
+ if( !imp.data.is_absolute() )
+ {
+ if( imp.data[0].name() == "super" ) {
+ if( modpath.size() < 1 )
+ throw ParseError::Generic("Encountered 'super' at crate root");
+ auto newpath = modpath;
+ newpath.nodes().pop_back();
+ newpath.add_tailing(imp.data);
+ DEBUG("Absolutised path " << imp.data << " into " << newpath);
+ imp.data = ::std::move(newpath);
+ }
+ else {
+ auto newpath = modpath + imp.data;
+ DEBUG("Absolutised path " << imp.data << " into " << newpath);
+ imp.data = ::std::move(newpath);
+ }
+ }
+
+ // Run resolution on import
+ imp.data.resolve(crate);
+ DEBUG("Resolved import : " << imp.data);
+ // If wildcard, make sure it's sane
if( imp.name == "" )
{
- DEBUG("Wildcard of " << imp.data);
- if( imp.is_pub ) {
- throw ParseError::Generic("Wildcard uses can't be public");
- }
-
- // Wildcard import
- AST::Path& basepath = imp.data;
- basepath.resolve(crate);
- DEBUG("basepath = " << basepath);
- switch(basepath.binding_type())
+ switch(imp.data.binding_type())
{
case AST::Path::UNBOUND:
throw ParseError::BugCheck("path unbound after calling .resolve()");
case AST::Path::MODULE:
- for( auto& submod : basepath.bound_module().submods() )
- {
- if( submod.second == true )
- {
- new_imports.push_back( basepath + AST::PathNode(submod.first.name(), {}) );
- }
- }
- for(const auto& imp : basepath.bound_module().imports() )
- {
- if( imp.is_pub )
- {
- DEBUG("Re-export " << imp.data);
- if(imp.name == "")
- throw ParseError::Generic("Wilcard uses can't be public");
- AST::Path path = imp.data;
- path.resolve(crate);
- DEBUG("Re-export (resolved) " << path);
- new_imports.push_back( ::std::move(path) );
- }
- }
- //throw ParseError::Todo("ResolvePaths_HandleModule - wildcard use on module");
break;
- case AST::Path::ALIAS:
- throw ParseError::Todo("ResolvePaths_HandleModule_Use - ALIAS");
case AST::Path::ENUM:
- throw ParseError::Todo("ResolvePaths_HandleModule_Use - ENUM");
+ break;
+
+ case AST::Path::ALIAS:
case AST::Path::ENUM_VAR:
- throw ParseError::Todo("ResolvePaths_HandleModule_Use - ENUM_VAR");
case AST::Path::STRUCT:
- throw ParseError::Todo("ResolvePaths_HandleModule_Use - STRUCT");
case AST::Path::STRUCT_METHOD:
- throw ParseError::Todo("ResolvePaths_HandleModule_Use - STRUCT_METHOD");
case AST::Path::TRAIT:
- throw ParseError::Todo("ResolvePaths_HandleModule_Use - TRAIT");
case AST::Path::FUNCTION:
- throw ParseError::Todo("ResolvePaths_HandleModule_Use - FUNCTION");
case AST::Path::STATIC:
- throw ParseError::Todo("ResolvePaths_HandleModule_Use - STATIC");
+ throw ParseError::Generic("Wildcard imports are only allowed on modules and enums");
}
}
}
diff --git a/src/coretypes.hpp b/src/coretypes.hpp index 2982d42f..2fc11412 100644 --- a/src/coretypes.hpp +++ b/src/coretypes.hpp @@ -8,6 +8,7 @@ enum eCoreType {
CORETYPE_INVAL,
CORETYPE_ANY,
+ CORETYPE_BOOL,
CORETYPE_CHAR,
CORETYPE_UINT, CORETYPE_INT,
CORETYPE_U8, CORETYPE_I8,
diff --git a/src/parse/types.cpp b/src/parse/types.cpp index 3752dc85..23101dba 100644 --- a/src/parse/types.cpp +++ b/src/parse/types.cpp @@ -15,6 +15,7 @@ static const struct { const char* name; enum eCoreType type; } CORETYPES[] = { + {"bool", CORETYPE_BOOL}, {"char", CORETYPE_CHAR}, {"f32", CORETYPE_F32}, {"f64", CORETYPE_F64}, diff --git a/src/types.cpp b/src/types.cpp index abf6b2da..4082bc96 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -16,6 +16,7 @@ const char* coretype_name(const eCoreType ct ) { case CORETYPE_INVAL:return "-"; case CORETYPE_ANY: return "_"; case CORETYPE_CHAR: return "char"; + case CORETYPE_BOOL: return "bool"; case CORETYPE_UINT: return "usize"; case CORETYPE_INT: return "isize"; case CORETYPE_U8: return "u8"; @@ -38,6 +39,8 @@ bool TypeRef::deref(bool is_implicit) { switch(m_class) { + case TypeRef::NONE: + throw ::std::runtime_error("Dereferencing ! - bugcheck"); case TypeRef::ANY: // TODO: Check if the _ is bounded by Deref<Output=?>, if so use that throw ::std::runtime_error("Dereferencing _"); @@ -103,6 +106,7 @@ void TypeRef::merge_with(const TypeRef& other) switch(m_class) { + case TypeRef::NONE: case TypeRef::ANY: case TypeRef::UNIT: case TypeRef::PRIMITIVE: @@ -148,6 +152,8 @@ void TypeRef::resolve_args(::std::function<TypeRef(const char*)> fcn) DEBUG("" << *this); switch(m_class) { + case TypeRef::NONE: + throw ::std::runtime_error("TypeRef::resolve_args on !"); case TypeRef::ANY: // TODO: Is resolving args on an ANY an erorr? break; @@ -204,6 +210,8 @@ void TypeRef::match_args(const TypeRef& other, ::std::function<void(const char*, throw ::std::runtime_error("Type mismatch (class)"); switch(m_class) { + case TypeRef::NONE: + throw ::std::runtime_error("TypeRef::match_args on !"); case TypeRef::ANY: // Wait, isn't this an error? throw ::std::runtime_error("Encountered '_' in match_args"); @@ -271,6 +279,8 @@ bool TypeRef::is_concrete() const { switch(m_class) { + case TypeRef::NONE: + throw ::std::runtime_error("TypeRef::is_concrete on !"); case TypeRef::ANY: return false; case TypeRef::UNIT: @@ -317,6 +327,8 @@ bool TypeRef::operator==(const TypeRef& x) const return false; switch(m_class) { + case TypeRef::NONE: + return true; case TypeRef::ANY: case TypeRef::UNIT: return true; @@ -357,6 +369,9 @@ bool TypeRef::operator==(const TypeRef& x) const //os << "TypeRef("; switch(tr.m_class) { + case TypeRef::NONE: + os << "!"; + break; case TypeRef::ANY: //os << "TagAny"; os << "_"; @@ -420,6 +435,7 @@ void operator% (::Deserialiser& d, eCoreType& ct) { d.item(n); /* */if(n == "-") ct = CORETYPE_INVAL; else if(n == "_") ct = CORETYPE_ANY; + else if(n == "bool") ct = CORETYPE_BOOL; else if(n == "char") ct = CORETYPE_CHAR; else if(n == "usize") ct = CORETYPE_UINT; else if(n == "isize") ct = CORETYPE_INT; @@ -440,6 +456,7 @@ const char* TypeRef::class_name(TypeRef::Class c) { switch(c) { #define _(x) case TypeRef::x: return #x; + _(NONE) _(ANY) _(UNIT) _(PRIMITIVE) @@ -460,6 +477,7 @@ void operator>>(::Deserialiser& d, TypeRef::Class& c) { d.item(n); #define _(x) if(n == #x) c = TypeRef::x; /**/ _(ANY) + else _(NONE) else _(UNIT) else _(PRIMITIVE) else _(FUNCTION) |