summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ast/ast.cpp29
-rw-r--r--src/ast/ast.hpp38
-rw-r--r--src/ast/path.cpp2
-rw-r--r--src/convert/resolve.cpp46
4 files changed, 80 insertions, 35 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp
index edbaa33e..d1e8c9fd 100644
--- a/src/ast/ast.cpp
+++ b/src/ast/ast.cpp
@@ -119,7 +119,7 @@ ExternCrate ExternCrate_std()
Module prelude(crate.crate(), "prelude");
// Re-exports
- #define USE(mod, name, ...) do{ Path p({__VA_ARGS__}); mod.add_alias(true, ::std::move(p), name); } while(0)
+ #define USE(mod, name, ...) do{ Path p({__VA_ARGS__}); p.set_crate("std"); mod.add_alias(true, ::std::move(p), name); } while(0)
USE(prelude, "Option", PathNode("option", {}), PathNode("Option",{}) );
USE(prelude, "Some", PathNode("option", {}), PathNode("Option",{}), PathNode("Some",{}) );
USE(prelude, "None", PathNode("option", {}), PathNode("Option",{}), PathNode("None",{}) );
@@ -144,17 +144,6 @@ void Module::add_ext_crate(::std::string ext_name, ::std::string int_name)
m_extern_crates.push_back( Item< ::std::string>( ::std::move(int_name), ::std::move(ext_name), false ) );
}
-void Module::add_constant(bool is_public, ::std::string name, TypeRef type, Expr val)
-{
- ::std::cout << "add_constant()" << ::std::endl;
-}
-void Module::add_global(bool is_public, bool is_mut, ::std::string name, TypeRef type, Expr val)
-{
- ::std::cout << "add_global()" << ::std::endl;
-}
-void Module::add_struct(bool is_public, ::std::string name, TypeParams params, ::std::vector<StructItem> items)
-{
-}
void Module::add_impl(Impl impl)
{
}
@@ -166,6 +155,22 @@ void Module::iterate_functions(fcn_visitor_t *visitor, const Crate& crate)
}
}
+::Serialiser& operator<<(::Serialiser& s, Static::Class fc)
+{
+ switch(fc)
+ {
+ case Static::CONST: s << "CONST"; break;
+ case Static::STATIC: s << "STATIC"; break;
+ case Static::MUT: s << "MUT"; break;
+ }
+ return s;
+}
+SERIALISE_TYPE(Static::, "AST_Static", {
+ s << m_class;
+ s << m_type;
+ //s << m_value;
+})
+
::Serialiser& operator<<(::Serialiser& s, Function::Class fc)
{
switch(fc)
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp
index 70e6f497..3ec689f8 100644
--- a/src/ast/ast.hpp
+++ b/src/ast/ast.hpp
@@ -59,6 +59,30 @@ public:
SERIALISABLE_PROTOTYPES();
};
+class Static:
+ public Serialisable
+{
+public:
+ enum Class
+ {
+ CONST,
+ STATIC,
+ MUT,
+ };
+private:
+ Class m_class;
+ TypeRef m_type;
+ Expr m_value;
+public:
+ Static(Class s_class, TypeRef type, Expr value):
+ m_class(s_class),
+ m_type( move(type) ),
+ m_value( move(value) )
+ {}
+
+ SERIALISABLE_PROTOTYPES();
+};
+
class Function:
public Serialisable
{
@@ -179,6 +203,7 @@ class Module:
typedef ::std::vector< ::std::pair<Module, bool> > itemlist_mod_t;
typedef ::std::vector< Item<Path> > itemlist_use_t;
typedef ::std::vector< Item< ::std::string> > itemlist_ext_t;
+ typedef ::std::vector< Item<Static> > itemlist_static_t;
typedef ::std::vector< Item<Enum> > itemlist_enum_t;
typedef ::std::vector< Item<Struct> > itemlist_struct_t;
@@ -190,6 +215,7 @@ class Module:
itemlist_use_t m_imports;
itemlist_ext_t m_extern_crates;
+ itemlist_static_t m_statics;
itemlist_enum_t m_enums;
itemlist_struct_t m_structs;
public:
@@ -202,9 +228,15 @@ public:
void add_alias(bool is_public, Path path, ::std::string name) {
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);
- void add_struct(bool is_public, ::std::string name, TypeParams params, ::std::vector<StructItem> items);
+ void add_constant(bool is_public, ::std::string name, TypeRef type, Expr val) {
+ m_statics.push_back( Item<Static>( move(name), Static(Static::CONST, move(type), move(val)), is_public) );
+ }
+ void add_global(bool is_public, bool is_mut, ::std::string name, TypeRef type, Expr val) {
+ m_statics.push_back( Item<Static>( move(name), Static(is_mut ? Static::MUT : Static::STATIC, move(type), move(val)), is_public) );
+ }
+ void add_struct(bool is_public, ::std::string name, TypeParams params, ::std::vector<StructItem> items) {
+ m_structs.push_back( Item<Struct>( move(name), Struct(move(params), move(items)), is_public) );
+ }
void add_enum(bool is_public, ::std::string name, Enum inst) {
m_enums.push_back( Item<Enum>( move(name), move(inst), is_public ) );
}
diff --git a/src/ast/path.cpp b/src/ast/path.cpp
index 648d4055..354da4da 100644
--- a/src/ast/path.cpp
+++ b/src/ast/path.cpp
@@ -161,6 +161,7 @@ void Path::bind_module(const Module& mod)
}
void Path::bind_enum(const Enum& ent, const ::std::vector<TypeRef>& args)
{
+ DEBUG("Bound to enum");
m_binding_type = ENUM;
m_binding.enum_ = &ent;
if( args.size() > 0 )
@@ -189,6 +190,7 @@ void Path::bind_enum_var(const Enum& ent, const ::std::string& name, const ::std
throw ParseError::Todo("Bind enum variant with params passed");
}
+ DEBUG("Bound to enum variant '" << name << "' (#" << idx << ")");
m_binding_type = ENUM_VAR;
m_binding.enumvar = {&ent, idx};
}
diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp
index ce9433dd..ee906150 100644
--- a/src/convert/resolve.cpp
+++ b/src/convert/resolve.cpp
@@ -20,7 +20,13 @@ class CPathResolver
public:
CPathResolver(const AST::Crate& crate, const AST::Module& mod);
- void resolve_path(AST::Path& path, bool allow_variables) const;
+ enum ResolvePathMode {
+ MODE_EXPR, // Variables allowed
+ MODE_TYPE,
+ MODE_BIND, // Failure is allowed
+ };
+
+ void resolve_path(AST::Path& path, ResolvePathMode mode) const;
void resolve_type(TypeRef& type) const;
void handle_function(AST::Function& fcn);
@@ -62,7 +68,7 @@ public:
}
void visit(AST::ExprNode_NamedValue& node) {
- m_res.resolve_path(node.m_path, true);
+ m_res.resolve_path(node.m_path, CPathResolver::MODE_EXPR);
}
void visit(AST::ExprNode_Match& node)
@@ -85,7 +91,7 @@ CPathResolver::CPathResolver(const AST::Crate& crate, const AST::Module& mod):
{
}
-void CPathResolver::resolve_path(AST::Path& path, bool allow_variables) const
+void CPathResolver::resolve_path(AST::Path& path, ResolvePathMode mode) const
{
DEBUG("path = " << path);
@@ -101,6 +107,7 @@ void CPathResolver::resolve_path(AST::Path& path, bool allow_variables) const
// Convert to absolute
if( !path.is_relative() )
{
+ DEBUG("Absolute - binding");
// Already absolute, our job is done
// - However, if the path isn't bound, bind it
if( !path.is_bound() ) {
@@ -109,7 +116,7 @@ void CPathResolver::resolve_path(AST::Path& path, bool allow_variables) const
}
else
{
- if( allow_variables && path.size() == 1 && path[0].args().size() == 0 )
+ if( mode == MODE_EXPR && path.size() == 1 && path[0].args().size() == 0 )
{
// One non-generic component, look in the current function for a variable
const ::std::string& var = path[0].name();
@@ -129,6 +136,7 @@ void CPathResolver::resolve_path(AST::Path& path, bool allow_variables) const
return ;
}
}
+
// Search relative to current module
// > Search local use definitions (function-level)
// - TODO: Local use statements (scoped)
@@ -139,14 +147,16 @@ void CPathResolver::resolve_path(AST::Path& path, bool allow_variables) const
// Check name down?
// Add current module path
path = m_module_path + path;
- break;
+ path.resolve( m_crate );
+ return ;
}
}
for( const auto& item_fcn : m_module.functions() )
{
if( item_fcn.name == path[0].name() ) {
path = m_module_path + path;
- break;
+ path.resolve( m_crate );
+ return ;
}
}
for( const auto& import : m_module.imports() )
@@ -154,21 +164,18 @@ void CPathResolver::resolve_path(AST::Path& path, bool allow_variables) const
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);
- break;
+ path.resolve( m_crate );
+ return ;
}
}
- DEBUG("path = " << path);
- path.resolve(m_crate);
-
-
- throw ParseError::Todo("CPathResolver::resolve_path()");
+ DEBUG("no matches found for path = " << path);
+ assert( path.is_relative() );
+ if( mode != MODE_BIND )
+ throw ParseError::Generic("Name resolution failed");
}
}
@@ -194,7 +201,7 @@ void CPathResolver::handle_pattern(AST::Pattern& pat)
// - Variables don't count
AST::Path newpath;
newpath.append( AST::PathNode(name, {}) );
- resolve_path(newpath, false);
+ resolve_path(newpath, CPathResolver::MODE_BIND);
if( newpath.is_relative() )
{
// It's a name binding (desugar to 'name @ _')
@@ -203,8 +210,7 @@ void CPathResolver::handle_pattern(AST::Pattern& pat)
}
else
{
- // It's a constant (value)
-
+ // It's a constant (enum variant usually)
pat = AST::Pattern(
AST::Pattern::TagValue(),
::std::unique_ptr<AST::ExprNode>( new AST::ExprNode_NamedValue( ::std::move(newpath) ) )
@@ -221,7 +227,7 @@ void CPathResolver::handle_pattern(AST::Pattern& pat)
case AST::Pattern::TUPLE_STRUCT:
// Resolve the path!
// - TODO: Restrict to types and enum variants
- resolve_path( pat.path(), false );
+ resolve_path( pat.path(), CPathResolver::MODE_TYPE );
break;
}
// Extract bindings and add to namespace
@@ -231,7 +237,7 @@ void CPathResolver::handle_pattern(AST::Pattern& pat)
handle_pattern(subpat);
- throw ParseError::Todo("CPathResolver::handle_pattern()");
+ //throw ParseError::Todo("CPathResolver::handle_pattern()");
}
/// Perform name resolution in a function