diff options
author | John Hodge <tpg@mutabah.net> | 2016-05-20 15:55:18 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-05-20 15:55:18 +0800 |
commit | 91e4ab1921467783122eff292359e7e9784508c7 (patch) | |
tree | 4c743b4a010cc24d29aa56ddbb2a283467fe2e69 /src | |
parent | a0c013a290f88e4ade34c08ff618d8f1ed3f63f6 (diff) | |
download | mrust-91e4ab1921467783122eff292359e7e9784508c7.tar.gz |
String primitive, bind pointers in resolve, print macro name in span
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/ast.hpp | 3 | ||||
-rw-r--r-- | src/coretypes.hpp | 2 | ||||
-rw-r--r-- | src/dump_as_rust.cpp | 1 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 3 | ||||
-rw-r--r-- | src/macros.cpp | 14 | ||||
-rw-r--r-- | src/parse/types.cpp | 4 | ||||
-rw-r--r-- | src/resolve/absolute.cpp | 238 | ||||
-rw-r--r-- | src/resolve/index.cpp | 3 | ||||
-rw-r--r-- | src/resolve/use.cpp | 12 | ||||
-rw-r--r-- | src/types.cpp | 3 |
10 files changed, 254 insertions, 29 deletions
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<MacroRuleEnt>& 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<MacroRuleEnt>& contents, ParameterMappings mappings, ::std::string crate_name):
- m_crate_name(crate_name),
+ MacroExpander(::std::string macro_name, const ::std::vector<MacroRuleEnt>& 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() << "' ("<<name_ref.path<<") in path " << path); + ), + (Trait, + auto trait_path = ::AST::Path(name_ref.path); + if( n.args().size() ) + trait_path.nodes().back().args() = mv$(n.args()); + auto new_path = ::AST::Path(::AST::Path::TagUfcs(), ::TypeRef(), mv$(trait_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); + ), + (Enum, + if( name_ref.is_import ) { + TODO(sp, "Replace path component with new path - " << path << "[.."<<i<<"] with " << name_ref.path); + } + else { + const auto& last_node = path_abs.nodes.back(); + for( const auto& var : e.enum_->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 << "[.."<<i<<"] with " << name_ref.path); + } + else { + mod = e.module_; + } + ) + ) + } + } + + // Set binding to binding of node in last module + ::AST::Path tmp; + if( ! Context::lookup_in_mod(*mod, path_abs.nodes.back().name(), mode, tmp) ) { + ERROR(sp, E0000, "Couldn't find path component '" << path_abs.nodes.back().name() << "' of " << path); + } + assert( ! tmp.binding().is_Unbound() ); + + path.bind( tmp.binding().clone() ); +} + void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, Context::LookupMode mode, ::AST::Path& path) { - DEBUG("mode = " << mode << ", path = " << path); + TRACE_FUNCTION_F("mode = " << mode << ", path = " << path); TU_MATCH(::AST::Path::Class, (path.m_class), (e), (Invalid, @@ -428,12 +630,12 @@ void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, Context:: else { // Look up value auto p = context.lookup(sp, e.nodes[0].name(), mode); - DEBUG("Found val - " << p); + DEBUG("Found val - " << p << " for " << path); path = mv$(p); } if( !path.is_trivial() ) - Resolve_Absolute_PathNodes(context, Span(), path.nodes()); + Resolve_Absolute_PathNodes(context, sp, path.nodes()); ), (Self, DEBUG("- Self"); @@ -458,27 +660,29 @@ void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, Context:: // TODO: Resolve to the actual item? if( !path.is_trivial() ) - Resolve_Absolute_PathNodes(context, Span(), np_nodes); + Resolve_Absolute_PathNodes(context, sp, np_nodes); path = mv$(np); ), (Absolute, DEBUG("- Absolute"); // Nothing to do (TODO: Bind?) - Resolve_Absolute_PathNodes(context, Span(), e.nodes); + Resolve_Absolute_PathNodes(context, sp, e.nodes); ), (UFCS, DEBUG("- UFCS"); Resolve_Absolute_Type(context, *e.type); if( e.trait ) { - Resolve_Absolute_Path(context, Span(), Context::LookupMode::Type, *e.trait); + Resolve_Absolute_Path(context, sp, Context::LookupMode::Type, *e.trait); } - Resolve_Absolute_PathNodes(context, Span(), e.nodes); + Resolve_Absolute_PathNodes(context, sp, e.nodes); ) ) - #if 0 + // TODO: Should this be deferred until the HIR? + // - Doing it here so the HIR lowering has a bit more information + // - Also handles splitting "absolute" paths into UFCS TU_MATCH_DEF(::AST::Path::Class, (path.m_class), (e), ( BUG(sp, "Path wasn't absolutised correctly"); @@ -487,20 +691,17 @@ void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, Context:: // TODO: Ensure that local paths are bound to the variable/type index ), (Absolute, - if( e.crate != "" ) { - // TODO: Handle items from other crates (back-converting HIR paths) - } - TODO(sp, "Bind absolute paths to relevant items (and expand)"); + Resolve_Absolute_Path_BindAbsolute(context, sp, mode, path); ), (UFCS, - // TODO: Resolve UFCS to item class (if possible) + Resolve_Absolute_Path_BindUFCS(context, sp, mode, path); ) ) - #endif } void Resolve_Absolute_Type(Context& context, TypeRef& type) { + TRACE_FUNCTION_F("type = " << type); const auto& sp = type.span(); TU_MATCH(TypeData, (type.m_data), (e), (None, @@ -544,6 +745,13 @@ void Resolve_Absolute_Type(Context& context, TypeRef& type) ), (Path, Resolve_Absolute_Path(context, type.span(), Context::LookupMode::Type, e.path); + TU_IFLET(::AST::Path::Class, e.path.m_class, UFCS, ufcs, + if( ufcs.nodes.size() == 0 && ! ufcs.trait ) { + type = mv$(*ufcs.type); + return ; + } + assert( ufcs.nodes.size() == 1); + ) ), (TraitObject, //context.push_lifetimes( e.hrls ); diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp index b98c3b8e..0155455d 100644 --- a/src/resolve/index.cpp +++ b/src/resolve/index.cpp @@ -42,7 +42,8 @@ void _add_item(AST::Module& mod, IndexName location, const ::std::string& name, DEBUG("Add " << location << " item '" << name << "': " << ir); auto& list = get_mod_index(mod, location); - if( false == list.insert(::std::make_pair(name, ::AST::Module::IndexEnt { is_pub, mv$(ir) } )).second ) + bool was_import = (ir != mod.path() + name); + if( false == list.insert(::std::make_pair(name, ::AST::Module::IndexEnt { is_pub, was_import, mv$(ir) } )).second ) { if( error_on_collision ) { diff --git a/src/resolve/use.cpp b/src/resolve/use.cpp index 2d86be13..2ebdc058 100644 --- a/src/resolve/use.cpp +++ b/src/resolve/use.cpp @@ -35,7 +35,17 @@ void Resolve_Use(::AST::Crate& crate) return base_path + path; ), (Self, - return base_path + path; + // EVIL HACK: If the current module is an anon module, refer to the parent + if( base_path.nodes().back().name()[0] == '#' ) { + AST::Path np("", {}); + for( unsigned int i = 0; i < base_path.nodes().size() - 1; i ++ ) + np.nodes().push_back( base_path.nodes()[i] ); + np += path; + return np; + } + else { + return base_path + path; + } ), (Super, assert(e.count >= 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"; |