From 645ecea1a60e913ada6bdc8665d098d4b00a5f01 Mon Sep 17 00:00:00 2001 From: "John Hodge (sonata)" Date: Mon, 12 Jan 2015 16:29:22 +0800 Subject: Added statics, fix minor quirk in resolve handling --- src/ast/ast.cpp | 29 +++++++++++++++++------------ src/ast/ast.hpp | 38 +++++++++++++++++++++++++++++++++++--- src/ast/path.cpp | 2 ++ src/convert/resolve.cpp | 46 ++++++++++++++++++++++++++-------------------- 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 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 > itemlist_mod_t; typedef ::std::vector< Item > itemlist_use_t; typedef ::std::vector< Item< ::std::string> > itemlist_ext_t; + typedef ::std::vector< Item > itemlist_static_t; typedef ::std::vector< Item > itemlist_enum_t; typedef ::std::vector< Item > 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( 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 items); + void add_constant(bool is_public, ::std::string name, TypeRef type, Expr val) { + m_statics.push_back( Item( 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( 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 items) { + m_structs.push_back( Item( 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( 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& 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( 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 -- cgit v1.2.3