From 91e4ab1921467783122eff292359e7e9784508c7 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 20 May 2016 15:55:18 +0800 Subject: String primitive, bind pointers in resolve, print macro name in span --- src/ast/ast.hpp | 3 +- src/coretypes.hpp | 2 +- src/dump_as_rust.cpp | 1 + src/hir/from_ast.cpp | 3 +- src/macros.cpp | 14 ++- src/parse/types.cpp | 4 - src/resolve/absolute.cpp | 238 ++++++++++++++++++++++++++++++++++++++++++++--- src/resolve/index.cpp | 3 +- src/resolve/use.cpp | 12 ++- src/types.cpp | 3 + 10 files changed, 254 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index a5d4ec8c..06ff857e 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -554,7 +554,8 @@ public: char m_index_populated = 0; // 0 = no, 1 = partial, 2 = complete // TODO: Add "namespace" list (separate to types) struct IndexEnt { - bool is_pub; + bool is_pub; // Used as part of glob import checking + bool is_import; // Set if this item has a path that isn't `mod->path() + name` ::AST::Path path; }; ::std::unordered_map< ::std::string, IndexEnt > m_namespace_items; diff --git a/src/coretypes.hpp b/src/coretypes.hpp index 1d3cba67..bdf161e1 100644 --- a/src/coretypes.hpp +++ b/src/coretypes.hpp @@ -9,7 +9,7 @@ enum eCoreType CORETYPE_INVAL, CORETYPE_ANY, CORETYPE_BOOL, - CORETYPE_CHAR, + CORETYPE_CHAR, CORETYPE_STR, CORETYPE_UINT, CORETYPE_INT, CORETYPE_U8, CORETYPE_I8, CORETYPE_U16, CORETYPE_I16, diff --git a/src/dump_as_rust.cpp b/src/dump_as_rust.cpp index 361bd245..4e233663 100644 --- a/src/dump_as_rust.cpp +++ b/src/dump_as_rust.cpp @@ -327,6 +327,7 @@ public: { case CORETYPE_INVAL: break; case CORETYPE_BOOL: + case CORETYPE_STR: break; case CORETYPE_CHAR: m_os << "'\\u{" << ::std::hex << n.m_value << ::std::dec << "}'"; diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index d8e21496..3acb64ac 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -424,7 +424,8 @@ switch(e.core_type) { case CORETYPE_BOOL: return ::HIR::TypeRef( ::HIR::CoreType::Bool ); - case CORETYPE_CHAR: return ::HIR::TypeRef( ::HIR::CoreType::Char ); + case CORETYPE_CHAR: return ::HIR::TypeRef( ::HIR::CoreType::Str ); + case CORETYPE_STR : return ::HIR::TypeRef( ::HIR::CoreType::Char ); case CORETYPE_F32: return ::HIR::TypeRef( ::HIR::CoreType::F32 ); case CORETYPE_F64: return ::HIR::TypeRef( ::HIR::CoreType::F64 ); diff --git a/src/macros.cpp b/src/macros.cpp index 89fcbe86..12f6df05 100644 --- a/src/macros.cpp +++ b/src/macros.cpp @@ -107,6 +107,8 @@ class MacroExpander: public: private: + const ::std::string m_macro_name; + const ::std::string m_crate_name; const ::std::vector& m_root_contents; const ParameterMappings m_mappings; @@ -129,6 +131,7 @@ private: public: MacroExpander(const MacroExpander& x): + m_macro_name( x.m_macro_name ), m_crate_name(x.m_crate_name), m_root_contents(x.m_root_contents), m_mappings(x.m_mappings), @@ -137,10 +140,11 @@ public: { prep_counts(); } - MacroExpander(const ::std::vector& contents, ParameterMappings mappings, ::std::string crate_name): - m_crate_name(crate_name), + MacroExpander(::std::string macro_name, const ::std::vector& contents, ParameterMappings mappings, ::std::string crate_name): + m_macro_name( mv$(macro_name) ), + m_crate_name( mv$(crate_name) ), m_root_contents(contents), - m_mappings(mappings), + m_mappings( mv$(mappings) ), m_offsets({ {0,0,0} }), m_cur_ents(&m_root_contents) { @@ -383,7 +387,7 @@ bool Macro_HandlePattern(TTStream& lex, const MacroPatEnt& pat, unsigned int lay } DEBUG("TODO: Obtain crate name correctly"); - TokenStream* ret_ptr = new MacroExpander(rule.m_contents, bound_tts, ""); + TokenStream* ret_ptr = new MacroExpander(name, rule.m_contents, bound_tts, ""); // HACK! Disable nested macro expansion //ret_ptr->parse_state().no_expand_macros = true; @@ -440,7 +444,7 @@ bool Macro_HandlePattern(TTStream& lex, const MacroPatEnt& pat, unsigned int lay Position MacroExpander::getPosition() const { - return Position(FMT("Macro:" << ""), 0, m_offsets[0].read_pos); + return Position(FMT("Macro:" << m_macro_name << ":"), 0, m_offsets[0].read_pos); } Token MacroExpander::realGetToken() { diff --git a/src/parse/types.cpp b/src/parse/types.cpp index 01acf074..fe23b509 100644 --- a/src/parse/types.cpp +++ b/src/parse/types.cpp @@ -86,10 +86,6 @@ TypeRef Parse_Type_Int(TokenStream& lex) { return TypeRef(TypeRef::TagPrimitive(), Span(tok.get_pos()), ct); } - if( tok.str() == "str" ) - { - return TypeRef(TypeRef::TagPath(), Span(tok.get_pos()), AST::Path("", { AST::PathNode("#",{}), AST::PathNode("str",{}) })); - } lex.putback(tok); return Parse_Type_Path(lex, {}); // - Fall through to path handling diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index 5685ae82..a41ef04a 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -197,7 +197,7 @@ struct Context } return rv; } - bool lookup_in_mod(const ::AST::Module& mod, const ::std::string& name, LookupMode mode, ::AST::Path& path) const { + static bool lookup_in_mod(const ::AST::Module& mod, const ::std::string& name, LookupMode mode, ::AST::Path& path) { switch(mode) { case LookupMode::Namespace: @@ -386,9 +386,211 @@ void Resolve_Absolute_PathNodes(/*const*/ Context& context, const Span& sp, ::st } } } + +void Resolve_Absolute_Path_BindUFCS(Context& context, const Span& sp, Context::LookupMode& mode, ::AST::Path& path) +{ + const auto& ufcs = path.m_class.as_UFCS(); + + if( ufcs.nodes.size() > 1 ) + { + // More than one node, break into inner UFCS + TODO(sp, "Split multi-node UFCS - " << path); + } + if( ufcs.nodes.size() == 0 ) { + + if( mode == Context::LookupMode::Type && ! ufcs.trait ) { + return ; + } + + BUG(sp, "UFCS with no nodes encountered - " << path); + } + const auto& node = ufcs.nodes.at(0); + + if( ufcs.trait && ufcs.trait->is_valid() ) + { + // Trait is specified, definitely a trait item + // - Must resolve here + if( ! ufcs.trait->binding().is_Trait() ) { + ERROR(sp, E0000, "UFCS trait was not a trait - " << *ufcs.trait); + } + const auto& tr = *ufcs.trait->binding().as_Trait().trait_; + + switch(mode) + { + case Context::LookupMode::Pattern: + ERROR(sp, E0000, "Invalid use of UFCS in pattern"); + break; + case Context::LookupMode::Namespace: + case Context::LookupMode::Type: + for( const auto& item : tr.items() ) + { + if( item.name != node.name() ) { + break; + } + TU_MATCH_DEF(::AST::Item, (item.data), (e), + ( + // TODO: Error + ), + (Type, + // Resolve to asociated type + ) + ) + } + break; + case Context::LookupMode::Constant: + case Context::LookupMode::Variable: + for( const auto& item : tr.items() ) + { + if( item.name != node.name() ) { + break; + } + TU_MATCH_DEF(::AST::Item, (item.data), (e), + ( + // TODO: Error + ), + (Static, + // Resolve to asociated type + ) + ) + } + break; + } + } + else + { + // Trait is unknown or inherent, search for items on the type (if known) otherwise leave it until type resolution + // - Methods can't be known until typeck (after the impl map is created) + } +} +void Resolve_Absolute_Path_BindAbsolute(Context& context, const Span& sp, Context::LookupMode& mode, ::AST::Path& path) +{ + const auto& path_abs = path.m_class.as_Absolute(); + + if( path_abs.crate != "" ) { + // TODO: Handle items from other crates (back-converting HIR paths) + TODO(sp, "Handle binding to items from extern crates"); + } + + const ::AST::Module* mod = &context.m_crate.m_root_module; + for(unsigned int i = 0; i < path_abs.nodes.size() - 1; i ++ ) + { + const auto& n = path_abs.nodes[i]; + + //::AST::Path tmp; + //if( ! Context::lookup_in_mod(*mod, e.name(), Context::LookupMode::Namespace, tmp) ) { + // ERROR(sp, E0000, "Couldn't find path component '" << e.name() << "' of " << path); + //} + + + if( n.name()[0] == '#' ) { + if( n.args().size() > 0 ) { + ERROR(sp, E0000, "Type parameters were not expected here"); + } + + if( n.name() == "#" ) { + TODO(sp, "magic module"); + } + + char c; + unsigned int idx; + ::std::stringstream ss( n.name() ); + ss >> c; + ss >> idx; + assert( idx < mod->anon_mods().size() ); + mod = mod->anon_mods()[idx]; + } + else + { + auto it = mod->m_namespace_items.find( n.name() ); + if( it == mod->m_namespace_items.end() ) { + ERROR(sp, E0000, "Couldn't find path component '" << n.name() << "' of " << path); + } + const auto& name_ref = it->second; + + TU_MATCH_DEF(::AST::PathBinding, (name_ref.path.binding()), (e), + ( + ERROR(sp, E0000, "Encountered non-namespace item '" << n.name() << "' ("<variants() ) { + if( var.m_name == last_node.name() ) { + + if( i != path_abs.nodes.size() - 2 ) { + ERROR(sp, E0000, "Unexpected enum in path " << path); + } + // NOTE: Type parameters for enums go after the _variant_ + if( n.args().size() ) { + ERROR(sp, E0000, "Type parameters were not expected here (enum params go on the variant)"); + } + + path.bind_enum_var(*e.enum_, var.m_name); + return; + } + } + + auto type_path = ::AST::Path(name_ref.path); + if( n.args().size() ) + type_path.nodes().back().args() = mv$(n.args()); + auto new_path = ::AST::Path(::AST::Path::TagUfcs(), ::TypeRef(sp, mv$(type_path)), ::AST::Path()); + for( unsigned int j = i+1; j < path_abs.nodes.size(); j ++ ) + new_path.nodes().push_back( mv$(path_abs.nodes[j]) ); + + path = mv$(new_path); + return Resolve_Absolute_Path_BindUFCS(context, sp, mode, path); + } + ), + (Struct, + auto type_path = ::AST::Path(name_ref.path); + if( n.args().size() ) + type_path.nodes().back().args() = mv$(n.args()); + auto new_path = ::AST::Path(::AST::Path::TagUfcs(), ::TypeRef(sp, mv$(type_path)), ::AST::Path()); + for( unsigned int j = i+1; j < path_abs.nodes.size(); j ++ ) + new_path.nodes().push_back( mv$(path_abs.nodes[j]) ); + + path = mv$(new_path); + return Resolve_Absolute_Path_BindUFCS(context, sp, mode, path); + ), + (Module, + if( name_ref.is_import ) { + TODO(sp, "Replace path component with new path - " << path << "[.."<= 1); diff --git a/src/types.cpp b/src/types.cpp index ffa4db42..a75506d1 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -16,6 +16,7 @@ static const struct { const char* name; enum eCoreType type; } CORETYPES[] = { + // NOTE: Sorted {"bool", CORETYPE_BOOL}, {"char", CORETYPE_CHAR}, {"f32", CORETYPE_F32}, @@ -26,6 +27,7 @@ static const struct { {"i8", CORETYPE_I8}, {"int", CORETYPE_INT}, {"isize", CORETYPE_INT}, + {"str", CORETYPE_STR}, {"u16", CORETYPE_U16}, {"u32", CORETYPE_U32}, {"u64", CORETYPE_U64}, @@ -52,6 +54,7 @@ const char* coretype_name(const eCoreType ct ) { case CORETYPE_INVAL:return "-"; case CORETYPE_ANY: return "_"; case CORETYPE_CHAR: return "char"; + case CORETYPE_STR: return "str"; case CORETYPE_BOOL: return "bool"; case CORETYPE_UINT: return "usize"; case CORETYPE_INT: return "isize"; -- cgit v1.2.3