summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast/path.cpp65
-rw-r--r--src/ast/path.hpp11
-rw-r--r--src/convert/resolve.cpp69
-rw-r--r--src/coretypes.hpp1
-rw-r--r--src/parse/types.cpp1
-rw-r--r--src/types.cpp18
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)