diff options
-rw-r--r-- | src/ast/ast.cpp | 25 | ||||
-rw-r--r-- | src/ast/ast.hpp | 43 | ||||
-rw-r--r-- | src/ast/path.hpp | 5 | ||||
-rw-r--r-- | src/convert/resolve.cpp | 39 | ||||
-rw-r--r-- | src/parse/root.cpp | 7 |
5 files changed, 109 insertions, 10 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 7d151063..994d3999 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -88,14 +88,37 @@ void Crate::iterate_functions(fcn_visitor_t* visitor) m_root_module.iterate_functions(visitor, *this);
}
+ExternCrate::ExternCrate()
+{
+}
+
+ExternCrate::ExternCrate(const char *path)
+{
+ throw ParseError::Todo("Load extern crate from a file");
+}
+
+ExternCrate ExternCrate_std()
+{
+ ExternCrate crate;
+ Module& std_mod = crate.root_module();
+
+ // TODO: Add modules
+
+ return crate;
+}
+
void Module::add_ext_crate(::std::string ext_name, ::std::string int_name)
{
DEBUG("add_ext_crate(\"" << ext_name << "\" as " << int_name << ")");
if( ext_name == "std" )
{
// HACK! Load std using a hackjob (included within the compiler)
+ m_extern_crates.push_back( Item<ExternCrate>( ::std::move(int_name), ExternCrate_std(), false ) );
+ }
+ else
+ {
+ throw ParseError::Todo("'extern crate' (not hackjob std)");
}
- throw ParseError::Todo("'extern crate'");
}
void Module::add_constant(bool is_public, ::std::string name, TypeRef type, Expr val)
{
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 0b124ad7..25876310 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -183,15 +183,33 @@ public: class Crate;
+class ExternCrate;
class Module;
typedef void fcn_visitor_t(const AST::Crate& crate, const AST::Module& mod, Function& fcn);
+template <typename T>
+struct Item
+{
+ ::std::string name;
+ T data;
+ bool is_pub;
+
+ Item(::std::string&& name, T&& data, bool is_pub):
+ name( move(name) ),
+ data( move(data) ),
+ is_pub( is_pub )
+ {
+ }
+};
+
+/// Representation of a parsed (and being converted) function
class Module
{
typedef ::std::vector< ::std::pair<Function, bool> > itemlist_fcn_t;
typedef ::std::vector< ::std::pair<Module, bool> > itemlist_mod_t;
- typedef ::std::vector< ::std::tuple< ::std::string, Path, bool > > itemlist_use_t;
+ typedef ::std::vector< Item<Path> > itemlist_use_t;
+ typedef ::std::vector< Item<ExternCrate> > itemlist_ext_t;
const Crate& m_crate;
::std::string m_name;
@@ -199,6 +217,7 @@ class Module itemlist_fcn_t m_functions;
itemlist_mod_t m_submods;
itemlist_use_t m_imports;
+ itemlist_ext_t m_extern_crates;
public:
Module(const Crate& crate, ::std::string name):
m_crate(crate),
@@ -207,7 +226,7 @@ public: }
void add_ext_crate(::std::string ext_name, ::std::string imp_name);
void add_alias(bool is_public, Path path, ::std::string name) {
- m_imports.push_back( ::std::make_tuple(name, path, is_public) );
+ m_imports.push_back( Item<Path>( move(name), move(path), is_public) );
}
void add_constant(bool is_public, ::std::string name, TypeRef type, Expr val);
void add_global(bool is_public, bool is_mut, ::std::string name, TypeRef type, Expr val);
@@ -224,11 +243,18 @@ public: const Crate& crate() const { return m_crate; }
const ::std::string& name() const { return m_name; }
+
+ ::std::vector<MetaItem>& attrs() { return m_attrs; }
+ itemlist_fcn_t& functions() { return m_functions; }
+ itemlist_mod_t& submods() { return m_submods; }
+ itemlist_use_t& imports() { return m_imports; }
+ itemlist_ext_t& extern_crates() { return m_extern_crates; }
const ::std::vector<MetaItem>& attrs() const { return m_attrs; }
const itemlist_fcn_t& functions() const { return m_functions; }
const itemlist_mod_t& submods() const { return m_submods; }
const itemlist_use_t& imports() const { return m_imports; }
+ const itemlist_ext_t& extern_crates() const { return m_extern_crates; }
};
class Crate
@@ -240,10 +266,23 @@ public: Crate();
Module& root_module() { return m_root_module; }
+ const Module& root_module() const { return m_root_module; }
void iterate_functions( fcn_visitor_t* visitor );
};
+/// Representation of an imported crate
+/// - Functions are stored as resolved+typechecked ASTs
+class ExternCrate
+{
+ Crate m_crate;
+public:
+ ExternCrate();
+ ExternCrate(const char *path);
+ Module& root_module() { return m_crate.root_module(); }
+ const Module& root_module() const { return m_crate.root_module(); }
+};
+
class CStruct
{
::std::vector<StructItem> m_fields;
diff --git a/src/ast/path.hpp b/src/ast/path.hpp index 9887d192..182802f2 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -73,6 +73,11 @@ public: ret.m_nodes.push_back(ent); return ret; } + Path operator+(const ::std::string& s) const { + Path tmp; + tmp.append(PathNode(s, {})); + return Path(*this) += tmp; + } Path operator+(const Path& x) const { return Path(*this) += x; } diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp index e1dea29f..b32b10a5 100644 --- a/src/convert/resolve.cpp +++ b/src/convert/resolve.cpp @@ -144,9 +144,14 @@ void CPathResolver::resolve_path(AST::Path& path, bool allow_variables) const }
for( const auto& import : m_module.imports() )
{
- const ::std::string& bind_name = ::std::get<0>(import);
- const AST::Path& bind_path = ::std::get<1>(import);
- if( bind_name == path[0].name() ) {
+ const ::std::string& bind_name = import.name;
+ const AST::Path& bind_path = import.data;
+ if( bind_name == "" ) {
+ // wildcard import!
+ // TODO: Import should be tagged with
+ throw ParseError::Todo("CPathResolver::resolve_path() - Wildcards");
+ }
+ else if( bind_name == path[0].name() ) {
path = AST::Path::add_tailing(bind_path, path);
}
}
@@ -243,7 +248,33 @@ void ResolvePaths_HandleFunction(const AST::Crate& crate, const AST::Module& mod pr.handle_function(fcn);
}
+void ResolvePaths_HandleModule(const AST::Crate& crate, const AST::Path& modpath, AST::Module& mod)
+{
+ // TODO: Handle 'use' statements in an earlier pass, to avoid dependency issues?
+ // - Maybe resolve wildcards etc when used?
+ for( auto& imp : mod.imports() )
+ {
+ // TODO: Handle 'super' and 'self' imports
+
+ if( imp.name == "" )
+ {
+ // Wildcard import
+ throw ParseError::Todo("ResolvePaths_HandleModule - wildcard use");
+ }
+ }
+
+ for( auto& fcn : mod.functions() )
+ {
+ ResolvePaths_HandleFunction(crate, mod, fcn.first);
+ }
+
+ for( auto& submod : mod.submods() )
+ {
+ ResolvePaths_HandleModule(crate, modpath + submod.first.name(), submod.first);
+ }
+}
+
void ResolvePaths(AST::Crate& crate)
{
- crate.iterate_functions(ResolvePaths_HandleFunction);
+ ResolvePaths_HandleModule(crate, AST::Path(AST::Path::TagAbsolute()), crate.root_module());
}
diff --git a/src/parse/root.cpp b/src/parse/root.cpp index e922b39f..1c2582f7 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -483,7 +483,7 @@ AST::Impl Parse_Impl(TokenStream& lex) void Parse_Use_Wildcard(const AST::Path& base_path, ::std::function<void(AST::Path, ::std::string)> fcn)
{
- throw ParseError::Todo("Wildcard imports");
+ fcn(base_path, ""); // HACK! Empty path indicates wilcard import
}
void Parse_Use(Preproc& lex, ::std::function<void(AST::Path, ::std::string)> fcn)
@@ -520,8 +520,9 @@ void Parse_Use(Preproc& lex, ::std::function<void(AST::Path, ::std::string)> fcn throw ParseError::Todo("Parse_Use - multiples");
break;
case TOK_STAR:
- throw ParseError::Todo("Parse_Use - wildcard/glob");
- break;
+ Parse_Use_Wildcard(path, fcn);
+ // early return - can't have anything else after
+ return;
default:
throw ParseError::Unexpected(tok);
}
|