diff options
author | John Hodge <tpg@mutabah.net> | 2016-05-23 22:16:29 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-05-23 22:16:29 +0800 |
commit | b96c1a08cec9be6cc29f47eb151c3ad91075a819 (patch) | |
tree | faf4259c8d8e59c7433a0dfca7313d0c7c686f5b /src | |
parent | 1f9a4180a3b54f85f37919ba4ca709f8e8250bb6 (diff) | |
download | mrust-b96c1a08cec9be6cc29f47eb151c3ad91075a819.tar.gz |
HIR - Add type alias replacement. Other related changes below
- Added pretty printing for HIR paths and types
- Added a sub-pass to resolve/index that makes all index paths point at
the actual item (no imports involved)
- Split up some contents of main_bindings.hpp
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/crate_ptr.hpp | 2 | ||||
-rw-r--r-- | src/hir/expr.cpp | 130 | ||||
-rw-r--r-- | src/hir/expr.hpp | 42 | ||||
-rw-r--r-- | src/hir/expr_ptr.hpp | 2 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 15 | ||||
-rw-r--r-- | src/hir/hir.hpp | 16 | ||||
-rw-r--r-- | src/hir/path.cpp | 93 | ||||
-rw-r--r-- | src/hir/path.hpp | 19 | ||||
-rw-r--r-- | src/hir/type.cpp | 144 | ||||
-rw-r--r-- | src/hir/type.hpp | 8 | ||||
-rw-r--r-- | src/hir_conv/expand_type.cpp | 288 | ||||
-rw-r--r-- | src/hir_conv/main_bindings.hpp | 9 | ||||
-rw-r--r-- | src/include/main_bindings.hpp | 13 | ||||
-rw-r--r-- | src/main.cpp | 19 | ||||
-rw-r--r-- | src/resolve/index.cpp | 85 | ||||
-rw-r--r-- | src/resolve/main_bindings.hpp | 12 |
16 files changed, 825 insertions, 72 deletions
diff --git a/src/hir/crate_ptr.hpp b/src/hir/crate_ptr.hpp index df60329e..06e04a6e 100644 --- a/src/hir/crate_ptr.hpp +++ b/src/hir/crate_ptr.hpp @@ -27,6 +27,8 @@ public: return *this; } ~CratePtr(); + + Crate& operator*() { return *m_ptr; } }; } // namespace HIR diff --git a/src/hir/expr.cpp b/src/hir/expr.cpp index d42c2678..efa02dfc 100644 --- a/src/hir/expr.cpp +++ b/src/hir/expr.cpp @@ -6,37 +6,105 @@ { } -#define DEF_VISIT(nt) void ::HIR::nt::visit(ExprVisitor& nv) { nv.visit(*this); } - -DEF_VISIT(ExprNode_Block) -DEF_VISIT(ExprNode_Return) -DEF_VISIT(ExprNode_Let) -DEF_VISIT(ExprNode_Loop) -DEF_VISIT(ExprNode_LoopControl) -DEF_VISIT(ExprNode_Match) -DEF_VISIT(ExprNode_If) - -DEF_VISIT(ExprNode_Assign) -DEF_VISIT(ExprNode_BinOp) -DEF_VISIT(ExprNode_UniOp) -DEF_VISIT(ExprNode_Cast) -DEF_VISIT(ExprNode_Index) -DEF_VISIT(ExprNode_Deref) - -DEF_VISIT(ExprNode_CallPath) -DEF_VISIT(ExprNode_CallValue) -DEF_VISIT(ExprNode_CallMethod) -DEF_VISIT(ExprNode_Field) - -DEF_VISIT(ExprNode_Literal) -DEF_VISIT(ExprNode_PathValue); -DEF_VISIT(ExprNode_Variable); -DEF_VISIT(ExprNode_StructLiteral); -DEF_VISIT(ExprNode_Tuple) -DEF_VISIT(ExprNode_ArrayList) -DEF_VISIT(ExprNode_ArraySized) - -DEF_VISIT(ExprNode_Closure); +#define DEF_VISIT(nt, n, code) void ::HIR::nt::visit(ExprVisitor& nv) { nv.visit(*this); } void ::HIR::ExprVisitorDef::visit(::HIR::nt& n) { code } + +DEF_VISIT(ExprNode_Block, node, + for(const auto& subnode : node.m_nodes) + subnode->visit(*this); +) +DEF_VISIT(ExprNode_Return, node, + node.m_value->visit(*this); +) +DEF_VISIT(ExprNode_Let, node, + if( node.m_value ) { + node.m_value->visit(*this); + } +) +DEF_VISIT(ExprNode_Loop, node, + node.m_code->visit(*this); +) +DEF_VISIT(ExprNode_LoopControl, , ) +DEF_VISIT(ExprNode_Match, node, + node.m_value->visit(*this); + for(auto& arm : node.m_arms) + { + if( arm.m_cond ) + arm.m_cond->visit(*this); + arm.m_code->visit(*this); + } +) +DEF_VISIT(ExprNode_If, node, + node.m_cond->visit(*this); + node.m_true->visit(*this); + if( node.m_false ) + node.m_false->visit(*this); +) + +DEF_VISIT(ExprNode_Assign, node, + node.m_slot->visit(*this); + node.m_value->visit(*this); +) +DEF_VISIT(ExprNode_BinOp, node, + node.m_left->visit(*this); + node.m_right->visit(*this); +) +DEF_VISIT(ExprNode_UniOp, node, + node.m_value->visit(*this); +) +DEF_VISIT(ExprNode_Cast, node, + node.m_value->visit(*this); +) +DEF_VISIT(ExprNode_Index, node, + node.m_val->visit(*this); + node.m_index->visit(*this); +) +DEF_VISIT(ExprNode_Deref, node, + node.m_val->visit(*this); +) + +DEF_VISIT(ExprNode_CallPath, node, + for(auto& arg : node.m_args) + arg->visit(*this); +) +DEF_VISIT(ExprNode_CallValue, node, + node.m_val->visit(*this); + for(auto& arg : node.m_args) + arg->visit(*this); +) +DEF_VISIT(ExprNode_CallMethod, node, + node.m_val->visit(*this); + for(auto& arg : node.m_args) + arg->visit(*this); +) +DEF_VISIT(ExprNode_Field, node, + node.m_val->visit(*this); +) + +DEF_VISIT(ExprNode_Literal, , ) +DEF_VISIT(ExprNode_PathValue, , ) +DEF_VISIT(ExprNode_Variable, , ) +DEF_VISIT(ExprNode_StructLiteral, node, + if( node.m_base_value ) + node.m_base_value->visit(*this); + for(auto& val : node.m_values) + val.second->visit( *this ); +) +DEF_VISIT(ExprNode_Tuple, node, + for(auto& val : node.m_vals) + val->visit( *this ); +) +DEF_VISIT(ExprNode_ArrayList, node, + for(auto& val : node.m_vals) + val->visit( *this ); +) +DEF_VISIT(ExprNode_ArraySized, node, + node.m_val->visit( *this ); + node.m_size->visit( *this ); +) + +DEF_VISIT(ExprNode_Closure, node, + node.m_code->visit( *this ); +) #undef DEF_VISIT diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp index 6b9482fb..910dac8b 100644 --- a/src/hir/expr.hpp +++ b/src/hir/expr.hpp @@ -13,6 +13,8 @@ class ExprVisitor; class ExprNode { public: + //::HIR::TypeRef m_res_type; + virtual void visit(ExprVisitor& v) = 0; virtual ~ExprNode(); }; @@ -461,6 +463,46 @@ public: NV(ExprNode_ArraySized); NV(ExprNode_Closure); + #undef NV +}; + +class ExprVisitorDef: + public ExprVisitor +{ +public: + #define NV(nt) virtual void visit(nt& n); + + NV(ExprNode_Block) + NV(ExprNode_Return) + NV(ExprNode_Let) + NV(ExprNode_Loop) + NV(ExprNode_LoopControl) + NV(ExprNode_Match) + NV(ExprNode_If) + + NV(ExprNode_Assign) + NV(ExprNode_BinOp) + NV(ExprNode_UniOp) + NV(ExprNode_Cast) + NV(ExprNode_Index) + NV(ExprNode_Deref) + + NV(ExprNode_CallPath); + NV(ExprNode_CallValue); + NV(ExprNode_CallMethod); + NV(ExprNode_Field); + + NV(ExprNode_Literal); + NV(ExprNode_PathValue); + NV(ExprNode_Variable); + + NV(ExprNode_StructLiteral); + NV(ExprNode_Tuple); + NV(ExprNode_ArrayList); + NV(ExprNode_ArraySized); + + NV(ExprNode_Closure); + #undef NV }; } diff --git a/src/hir/expr_ptr.hpp b/src/hir/expr_ptr.hpp index ba53b58f..59663310 100644 --- a/src/hir/expr_ptr.hpp +++ b/src/hir/expr_ptr.hpp @@ -20,6 +20,8 @@ public: x.node = nullptr; } ~ExprPtr(); + + ::HIR::ExprNode& operator*() { return *node; } }; } // namespace HIR diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 9595ca02..37690503 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -402,7 +402,7 @@ if( ! e.trait ) { return ::HIR::Path(::HIR::Path::Data::make_UfcsInherent({ - LowerHIR_Type(*e.type), + box$( LowerHIR_Type(*e.type) ), e.nodes[0].name(), {} })); @@ -410,19 +410,19 @@ else if( ! e.trait->is_valid() ) { return ::HIR::Path(::HIR::Path::Data::make_UfcsUnknown({ - LowerHIR_Type(*e.type), + box$( LowerHIR_Type(*e.type) ), e.nodes[0].name(), {} })); } else { - return ::HIR::Path( - LowerHIR_Type(*e.type), + return ::HIR::Path(::HIR::Path::Data::make_UfcsKnown({ + box$(LowerHIR_Type(*e.type)), LowerHIR_GenericPath(sp, *e.trait), e.nodes[0].name(), {} - ); + })); } ) ) @@ -720,11 +720,10 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H (Struct, /// Add value reference TU_IFLET( ::AST::StructData, e.m_data, Struct, e2, - ::HIR::TypeRef ty = ::HIR::TypeRef( ::HIR::Path(mv$(item_path)) ); if( e2.ents.size() == 0 ) - _add_mod_val_item( mod, item.name, item.is_pub, ::HIR::ValueItem::make_StructConstant({mv$(ty)}) ); + _add_mod_val_item( mod, item.name, item.is_pub, ::HIR::ValueItem::make_StructConstant({mv$(item_path)}) ); else - _add_mod_val_item( mod, item.name, item.is_pub, ::HIR::ValueItem::make_StructConstructor({mv$(ty)}) ); + _add_mod_val_item( mod, item.name, item.is_pub, ::HIR::ValueItem::make_StructConstructor({mv$(item_path)}) ); ) _add_mod_ns_item( mod, item.name, item.is_pub, LowerHIR_Struct(e) ); ), diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index cc63626f..bbc32bed 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -38,6 +38,15 @@ struct VisEnt Ent ent; }; +/// Literal type used for constant evaluation +/// NOTE: Intentionally minimal, just covers the values (not the types) +TAGGED_UNION(Literal, Invalid, + (Invalid, struct {}), + (List, ::std::vector<Literal>), + (Integer, uint64_t), + (Float, double), + (String, ::std::string) + ); // -------------------------------------------------------------------- // Type structures @@ -48,7 +57,9 @@ struct Static bool m_is_mut; TypeRef m_type; + ExprPtr m_value; + //Literal m_value_res; }; struct Constant { @@ -56,6 +67,7 @@ struct Constant TypeRef m_type; ExprPtr m_value; + //Literal m_value_res; }; struct Function { @@ -169,9 +181,9 @@ TAGGED_UNION(ValueItem, Import, (Import, ::HIR::SimplePath), (Constant, Constant), (Static, Static), - (StructConstant, struct { ::HIR::TypeRef ty; }), + (StructConstant, struct { ::HIR::SimplePath ty; }), (Function, Function), - (StructConstructor, struct { ::HIR::TypeRef ty; }) + (StructConstructor, struct { ::HIR::SimplePath ty; }) ); class Crate diff --git a/src/hir/path.cpp b/src/hir/path.cpp index e5243958..4fcd46e5 100644 --- a/src/hir/path.cpp +++ b/src/hir/path.cpp @@ -29,11 +29,62 @@ namespace HIR { } return os; } + + ::std::ostream& operator<<(::std::ostream& os, const PathParams& x) + { + bool has_args = ( x.m_types.size() > 0 ); + + if(has_args) { + os << "<"; + } + for(const auto& ty : x.m_types) { + os << ty << ","; + } + if(has_args) { + os << ">"; + } + return os; + } + ::std::ostream& operator<<(::std::ostream& os, const GenericPath& x) + { + os << x.m_path << x.m_params; + return os; + } + ::std::ostream& operator<<(::std::ostream& os, const Path& x) + { + TU_MATCH(::HIR::Path::Data, (x.m_data), (e), + (Generic, + return os << e; + ), + (UfcsInherent, + return os << "<" << *e.type << ">::" << e.item << e.params; + ), + (UfcsKnown, + return os << "<" << *e.type << " as " << e.trait << ">::" << e.item << e.params; + ), + (UfcsUnknown, + return os << "<" << *e.type << " as _>::" << e.item << e.params; + ) + ) + return os; + } +} + +::HIR::SimplePath HIR::SimplePath::clone() const +{ + return SimplePath( m_crate_name, m_components ); } ::HIR::PathParams::PathParams() { } +::HIR::PathParams HIR::PathParams::clone() const +{ + PathParams rv; + for( const auto& t : m_types ) + rv.m_types.push_back( t.clone() ); + return rv; +} ::HIR::GenericPath::GenericPath() { @@ -47,20 +98,50 @@ namespace HIR { m_params( mv$(params) ) { } +::HIR::GenericPath HIR::GenericPath::clone() const +{ + return GenericPath(m_path.clone(), m_params.clone()); +} ::HIR::Path::Path(::HIR::GenericPath gp): m_data( ::HIR::Path::Data::make_Generic( mv$(gp) ) ) { } -::HIR::Path::Path(::HIR::TypeRefPtr type, ::HIR::GenericPath trait, ::std::string item, ::HIR::PathParams params): - m_data( ::HIR::Path::Data::make_UfcsKnown({ - mv$(type), mv$(trait), mv$(item), mv$(params) - }) ) -{ -} ::HIR::Path::Path(::HIR::SimplePath sp): m_data( ::HIR::Path::Data::make_Generic(::HIR::GenericPath(mv$(sp))) ) { } +::HIR::Path HIR::Path::clone() const +{ + TU_MATCH(Data, (m_data), (e), + (Generic, + return Path( Data::make_Generic(e.clone()) ); + ), + (UfcsInherent, + return Path(Data::make_UfcsUnknown({ + box$( e.type->clone() ), + e.item, + e.params.clone() + })); + ), + (UfcsKnown, + return Path(Data::make_UfcsKnown({ + box$( e.type->clone() ), + e.trait.clone(), + e.item, + e.params.clone() + })); + ), + (UfcsUnknown, + return Path(Data::make_UfcsInherent({ + box$( e.type->clone() ), + e.item, + e.params.clone() + })); + ) + ) + throw ""; +} + diff --git a/src/hir/path.hpp b/src/hir/path.hpp index 9d66b135..acf24274 100644 --- a/src/hir/path.hpp +++ b/src/hir/path.hpp @@ -29,6 +29,7 @@ struct SimplePath { } + SimplePath clone() const; SimplePath operator+(const ::std::string& s) const; friend ::std::ostream& operator<<(::std::ostream& os, const SimplePath& x); @@ -40,6 +41,7 @@ struct PathParams ::std::vector<TypeRef> m_types; PathParams(); + PathParams clone() const; }; /// Generic path - Simple path with one lot of generic params @@ -52,6 +54,10 @@ public: GenericPath(); GenericPath(::HIR::SimplePath sp); GenericPath(::HIR::SimplePath sp, ::HIR::PathParams params); + + GenericPath clone() const; + + friend ::std::ostream& operator<<(::std::ostream& os, const GenericPath& x); }; class TraitPath @@ -70,34 +76,35 @@ public: TAGGED_UNION(Data, Generic, (Generic, GenericPath), (UfcsInherent, struct { - TypeRefPtr type; + ::std::unique_ptr<TypeRef> type; ::std::string item; PathParams params; }), (UfcsKnown, struct { - TypeRefPtr type; + ::std::unique_ptr<TypeRef> type; GenericPath trait; ::std::string item; PathParams params; }), (UfcsUnknown, struct { - TypeRefPtr type; + ::std::unique_ptr<TypeRef> type; //GenericPath ??; ::std::string item; PathParams params; }) ); -private: Data m_data; -public: Path(Data data): m_data(mv$(data)) {} Path(GenericPath _); - Path(TypeRefPtr type, GenericPath trait, ::std::string item, PathParams params); Path(SimplePath _); + + Path clone() const; + + friend ::std::ostream& operator<<(::std::ostream& os, const Path& x); }; } // namespace HIR diff --git a/src/hir/type.cpp b/src/hir/type.cpp index 286136f9..2bbfafa8 100644 --- a/src/hir/type.cpp +++ b/src/hir/type.cpp @@ -1,7 +1,151 @@ /* */ #include "type.hpp" +#include <span.hpp> namespace HIR { + ::std::ostream& operator<<(::std::ostream& os, const ::HIR::TypeRef& ty) + { + ty.fmt(os); + return os; + } + + ::std::ostream& operator<<(::std::ostream& os, const CoreType& ct) + { + switch(ct) + { + case CoreType::Usize: return os << "usize"; + case CoreType::Isize: return os << "isize"; + case CoreType::U8: return os << "u8"; + case CoreType::I8: return os << "i8"; + case CoreType::U16: return os << "u16"; + case CoreType::I16: return os << "i16"; + case CoreType::U32: return os << "u32"; + case CoreType::I32: return os << "i32"; + case CoreType::U64: return os << "u64"; + case CoreType::I64: return os << "i64"; + + case CoreType::F32: return os << "f32"; + case CoreType::F64: return os << "f64"; + + case CoreType::Bool: return os << "bool"; + case CoreType::Char: return os << "char"; + case CoreType::Str: return os << "str"; + } + return os; + } +} + +void ::HIR::TypeRef::fmt(::std::ostream& os) const +{ + TU_MATCH(::HIR::TypeRef::Data, (m_data), (e), + (Infer, + os << "_"; + ), + (Diverge, + os << "!"; + ), + (Primitive, + os << e; + ), + (Path, + os << e; + ), + (Generic, + os << e.name << "/*#" << e.binding << "*/"; + ), + (TraitObject, + os << "("; + os << e.m_traits; + if( e.m_lifetime.name != "" ) + os << "+ '" << e.m_lifetime.name; + os << ")"; + ), + (Array, + os << "[" << *e.inner << "; " << "/*sz*/" << "]"; + ), + (Tuple, + os << "("; + for(const auto& t : e) + os << t << ", "; + os << ")"; + ), + (Borrow, + switch(e.type) + { + case ::HIR::BorrowType::Shared: os << "&"; break; + case ::HIR::BorrowType::Unique: os << "&mut "; break; + case ::HIR::BorrowType::Owned: os << "&move "; break; + } + os << *e.inner; + ), + (Pointer, + if( e.is_mut ) { + os << "*mut "; + } + else { + os << "*const "; + } + os << *e.inner; + ), + (Function, + if( e.is_unsafe ) { + os << "unsafe "; + } + if( e.m_abi != "" ) { + os << "extern \"" << e.m_abi << "\" "; + } + os << "fn("; + for(const auto& t : e.m_arg_types) + os << t << ", "; + os << ") -> " << *e.m_rettype; + ) + ) +} +::HIR::TypeRef HIR::TypeRef::clone() const +{ + TU_MATCH(::HIR::TypeRef::Data, (m_data), (e), + (Infer, + return ::HIR::TypeRef( Data::make_Infer({}) ); + ), + (Diverge, + return ::HIR::TypeRef( Data::make_Diverge({}) ); + ), + (Primitive, + return ::HIR::TypeRef( Data::make_Primitive(e) ); + ), + (Path, + return ::HIR::TypeRef( Data::make_Path(e.clone()) ); + ), + (Generic, + return ::HIR::TypeRef( Data::make_Generic(e) ); + ), + (TraitObject, + TODO(Span(), "TypeRef::clone() - this = " << *this); + ), + (Array, + TODO(Span(), "TypeRef::clone() - this = " << *this); + //return ::HIR::TypeRef( Data::make_Array({ + // box$( e.inner->clone() ), + // /* huh */ + // }) ); + ), + (Tuple, + ::std::vector< ::HIR::TypeRef> types; + for(const auto& t : e) + types.push_back( t.clone() ); + return ::HIR::TypeRef( Data::make_Tuple(mv$(types)) ); + ), + (Borrow, + return ::HIR::TypeRef( Data::make_Borrow({e.type, box$(e.inner->clone())}) ); + ), + (Pointer, + return ::HIR::TypeRef( Data::make_Pointer({e.is_mut, box$(e.inner->clone())}) ); + ), + (Function, + TODO(Span(), "TypeRef::clone() - this = " << *this); + ) + ) + throw ""; } diff --git a/src/hir/type.hpp b/src/hir/type.hpp index 95a3cd1d..06535dfb 100644 --- a/src/hir/type.hpp +++ b/src/hir/type.hpp @@ -24,6 +24,8 @@ enum class CoreType Bool, Char, Str, }; +extern ::std::ostream& operator<<(::std::ostream& os, const CoreType& ct); + enum class BorrowType { Shared, @@ -103,8 +105,14 @@ struct TypeRef TypeRef(::HIR::Path p): m_data( Data::make_Path(mv$(p)) ) {} + + TypeRef clone() const; + + void fmt(::std::ostream& os) const; }; +extern ::std::ostream& operator<<(::std::ostream& os, const ::HIR::TypeRef& ty); + } // namespace HIR #endif diff --git a/src/hir_conv/expand_type.cpp b/src/hir_conv/expand_type.cpp new file mode 100644 index 00000000..b9f016e6 --- /dev/null +++ b/src/hir_conv/expand_type.cpp @@ -0,0 +1,288 @@ +/* + * Expand `type` aliases in HIR + */ +#include <hir/hir.hpp> +#include <hir/expr.hpp> + +void ConvertHIR_ExpandAliases_Type(const ::HIR::Crate& crate, ::HIR::TypeRef& ty); + +::HIR::TypeRef ConvertHIR_ExpandAliases_GetExpansion(const ::HIR::Crate& crate, const ::HIR::Path& path) +{ + TU_MATCH(::HIR::Path::Data, (path.m_data), (e), + (Generic, + const ::HIR::Module* mod = &crate.m_root_module; + assert( e.m_path.m_crate_name == "" && "TODO: Handle extern crates" ); + for( unsigned int i = 0; i < e.m_path.m_components.size() - 1; i ++ ) + { + const auto& pc = e.m_path.m_components[i]; + auto it = mod->m_mod_items.find( pc ); + if( it == mod->m_mod_items.end() ) { + BUG(Span(), "Couldn't find component " << i << " of " << e.m_path); + } + TU_MATCH_DEF( ::HIR::TypeItem, (it->second->ent), (e2), + ( + BUG(Span(), "Node " << i << " of path " << e.m_path << " wasn't a module"); + ), + (Module, + mod = &e2; + ) + ) + } + auto it = mod->m_mod_items.find( e.m_path.m_components.back() ); + if( it == mod->m_mod_items.end() ) { + BUG(Span(), "Could not find type name in " << e.m_path); + } + + TU_MATCH_DEF( ::HIR::TypeItem, (it->second->ent), (e2), + ( + ), + (TypeAlias, + if( e2.m_params.m_types.size() > 0 ) { + TODO(Span(), "Replace type params in type alias"); + } + return e2.m_type.clone(); + ) + ) + ), + (UfcsInherent, + DEBUG("TODO: Locate impl blocks for types - path=" << path); + ), + (UfcsKnown, + DEBUG("TODO: Locate impl blocks for traits on types - path=" << path); + ), + (UfcsUnknown, + DEBUG("TODO: Locate impl blocks for traits on types - path=" << path); + ) + ) + return ::HIR::TypeRef(); +} + +void ConvertHIR_ExpandAliases_PathParams(const ::HIR::Crate& crate, ::HIR::PathParams& p) +{ + for(auto& ty : p.m_types) + { + ConvertHIR_ExpandAliases_Type(crate, ty); + } +} +void ConvertHIR_ExpandAliases_Path(const ::HIR::Crate& crate, ::HIR::GenericPath& p) +{ + ConvertHIR_ExpandAliases_PathParams(crate, p.m_params); +} + +void ConvertHIR_ExpandAliases_Path(const ::HIR::Crate& crate, ::HIR::Path& p) +{ + TU_MATCH(::HIR::Path::Data, (p.m_data), (e), + (Generic, + ConvertHIR_ExpandAliases_Path(crate, e); + ), + (UfcsInherent, + ConvertHIR_ExpandAliases_Type(crate, *e.type); + ConvertHIR_ExpandAliases_PathParams(crate, e.params); + ), + (UfcsKnown, + ConvertHIR_ExpandAliases_Type(crate, *e.type); + ConvertHIR_ExpandAliases_Path(crate, e.trait); + ConvertHIR_ExpandAliases_PathParams(crate, e.params); + ), + (UfcsUnknown, + ConvertHIR_ExpandAliases_Type(crate, *e.type); + ConvertHIR_ExpandAliases_PathParams(crate, e.params); + ) + ) +} + +void ConvertHIR_ExpandAliases_Type(const ::HIR::Crate& crate, ::HIR::TypeRef& ty) +{ + TU_MATCH(::HIR::TypeRef::Data, (ty.m_data), (e), + (Infer, + ), + (Diverge, + ), + (Primitive, + ), + (Path, + ConvertHIR_ExpandAliases_Path(crate, e); + + auto new_type = ConvertHIR_ExpandAliases_GetExpansion(crate, e); + if( ! new_type.m_data.is_Infer() ) { + DEBUG("Replacing " << ty << " with " << new_type); + } + ), + (Generic, + ), + (TraitObject, + for(auto& trait : e.m_traits) { + ConvertHIR_ExpandAliases_Path(crate, trait); + } + ), + (Array, + ConvertHIR_ExpandAliases_Type(crate, *e.inner); + // TODO: Expression? + ), + (Tuple, + for(auto& t : e) { + ConvertHIR_ExpandAliases_Type(crate, t); + } + ), + (Borrow, + ConvertHIR_ExpandAliases_Type(crate, *e.inner); + ), + (Pointer, + ConvertHIR_ExpandAliases_Type(crate, *e.inner); + ), + (Function, + for(auto& t : e.m_arg_types) { + ConvertHIR_ExpandAliases_Type(crate, t); + } + ConvertHIR_ExpandAliases_Type(crate, *e.m_rettype); + ) + ) +} +void ConvertHIR_ExpandAliases_Expr(const ::HIR::Crate& crate, ::HIR::ExprPtr& ep) +{ + struct Visitor: + public ::HIR::ExprVisitorDef + { + const ::HIR::Crate& crate; + + Visitor(const ::HIR::Crate& crate): + crate(crate) + {} + + void visit(::HIR::ExprNode_Let& node) override + { + ConvertHIR_ExpandAliases_Type(crate, node.m_type); + ::HIR::ExprVisitorDef::visit(node); + } + void visit(::HIR::ExprNode_Cast& node) override + { + ConvertHIR_ExpandAliases_Type(crate, node.m_type); + ::HIR::ExprVisitorDef::visit(node); + } + + void visit(::HIR::ExprNode_CallPath& node) override + { + ConvertHIR_ExpandAliases_Path(crate, node.m_path); + ::HIR::ExprVisitorDef::visit(node); + } + void visit(::HIR::ExprNode_CallMethod& node) override + { + ConvertHIR_ExpandAliases_PathParams(crate, node.m_params); + ::HIR::ExprVisitorDef::visit(node); + } + + void visit(::HIR::ExprNode_Closure& node) override + { + ConvertHIR_ExpandAliases_Type(crate, node.m_return); + for(auto& arg : node.m_args) + ConvertHIR_ExpandAliases_Type(crate, arg.second); + ::HIR::ExprVisitorDef::visit(node); + } + }; + + if( &*ep != nullptr ) + { + Visitor v { crate }; + (*ep).visit(v); + } +} +void ConvertHIR_ExpandAliases_GenericParams(const ::HIR::Crate& crate, ::HIR::GenericParams& gp) +{ +} + +void ConvertHIR_ExpandAliases_Mod(const ::HIR::Crate& crate, ::HIR::Module& mod) +{ + for( auto& named : mod.m_mod_items ) + { + auto& item = named.second->ent; + TU_MATCH(::HIR::TypeItem, (item), (e), + (Import, ), + (Module, + ConvertHIR_ExpandAliases_Mod(crate, e); + ), + (TypeAlias, + ConvertHIR_ExpandAliases_GenericParams(crate, e.m_params); + ConvertHIR_ExpandAliases_Type(crate, e.m_type); + ), + (Enum, + ConvertHIR_ExpandAliases_GenericParams(crate, e.m_params); + for(auto& var : e.m_variants) + { + TU_MATCH(::HIR::Enum::Variant, (var.second), (v), + (Unit, + ), + (Value, + ConvertHIR_ExpandAliases_Expr(crate, v); + ), + (Tuple, + for(auto& ty : v) { + ConvertHIR_ExpandAliases_Type(crate, ty); + } + ), + (Struct, + for(auto& field : v) { + ConvertHIR_ExpandAliases_Type(crate, field.second); + } + ) + ) + } + ), + (Struct, + ConvertHIR_ExpandAliases_GenericParams(crate, e.m_params); + TU_MATCH(::HIR::Struct::Data, (e.m_data), (e2), + (Unit, + ), + (Tuple, + for(auto& ty : e2) { + ConvertHIR_ExpandAliases_Type(crate, ty.ent); + } + ), + (Named, + for(auto& field : e2) { + ConvertHIR_ExpandAliases_Type(crate, field.second.ent); + } + ) + ) + ), + (Trait, + ConvertHIR_ExpandAliases_GenericParams(crate, e.m_params); + ) + ) + } + for( auto& named : mod.m_value_items ) + { + auto& item = named.second->ent; + TU_MATCH(::HIR::ValueItem, (item), (e), + (Import, ), + (Constant, + ConvertHIR_ExpandAliases_GenericParams(crate, e.m_params); + ConvertHIR_ExpandAliases_Type(crate, e.m_type); + ConvertHIR_ExpandAliases_Expr(crate, e.m_value); + ), + (Static, + ConvertHIR_ExpandAliases_Type(crate, e.m_type); + ConvertHIR_ExpandAliases_Expr(crate, e.m_value); + ), + (StructConstant, + // Just a path + ), + (Function, + ConvertHIR_ExpandAliases_GenericParams(crate, e.m_params); + for(auto& arg : e.m_args) + { + ConvertHIR_ExpandAliases_Type(crate, arg.second); + } + ConvertHIR_ExpandAliases_Type(crate, e.m_return); + ConvertHIR_ExpandAliases_Expr(crate, e.m_code); + ), + (StructConstructor, + // Just a path + ) + ) + } +} + +void ConvertHIR_ExpandAliases(::HIR::Crate& crate) +{ + ConvertHIR_ExpandAliases_Mod(crate, crate.m_root_module); +} diff --git a/src/hir_conv/main_bindings.hpp b/src/hir_conv/main_bindings.hpp new file mode 100644 index 00000000..1a1a56d5 --- /dev/null +++ b/src/hir_conv/main_bindings.hpp @@ -0,0 +1,9 @@ +/* + */ +#pragma once + +namespace HIR { + class Crate; +}; + +extern void ConvertHIR_ExpandAliases(::HIR::Crate& crate); diff --git a/src/include/main_bindings.hpp b/src/include/main_bindings.hpp index 299ec94f..63169b61 100644 --- a/src/include/main_bindings.hpp +++ b/src/include/main_bindings.hpp @@ -21,21 +21,8 @@ extern void Expand(::AST::Crate& crate); /// Process #[] decorators extern void Process_Decorators(AST::Crate& crate); -extern void Resolve_Use(::AST::Crate& crate); -extern void Resolve_Index(::AST::Crate& crate); -extern void Resolve_Absolutise(::AST::Crate& crate); - extern ::HIR::CratePtr LowerHIR_FromAST(::AST::Crate crate); -/// Resolve all in-text paths to absolute variants -extern void ResolvePaths(AST::Crate& crate); -/// Check that generic bounds are valid -extern void Typecheck_GenericBounds(AST::Crate& crate); -/// Check that parameters for generics are valid -extern void Typecheck_GenericParams(AST::Crate& crate); -/// Type resolution (and hence checking) for expressions -extern void Typecheck_Expr(AST::Crate& crate); - /// Convert the AST to a flat tree extern AST::Flat Convert_Flatten(const AST::Crate& crate); diff --git a/src/main.cpp b/src/main.cpp index 8bd944ef..c949d703 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,6 +14,8 @@ #include <serialiser_texttree.hpp>
#include <cstring>
#include <main_bindings.hpp>
+#include "resolve/main_bindings.hpp"
+#include "hir_conv/main_bindings.hpp"
#include "expand/cfg.hpp"
@@ -119,9 +121,6 @@ int main(int argc, char *argv[]) Resolve_Use(crate); // - Absolutise and resolve use statements
Resolve_Index(crate); // - Build up a per-module index of avalable names (faster and simpler later resolve)
Resolve_Absolutise(crate); // - Convert all paths to Absolute or UFCS, and resolve variables
-
- // OLD resolve code, kinda bad
- //ResolvePaths(crate);
});
// XXX: Dump crate before typecheck
@@ -133,17 +132,25 @@ int main(int argc, char *argv[]) return 0;
}
+ // --------------------------------------
+ // HIR Section
+ // --------------------------------------
+ // Construc the HIR from the AST
::HIR::CratePtr hir_crate = CompilePhase< ::HIR::CratePtr>("HIR Lower", [&]() {
return LowerHIR_FromAST(mv$( crate ));
});
// Deallocate the original crate
crate = ::AST::Crate();
- // Perform type checking on items
- // - Replace type aliases (`type`) into the actual type
+ // Replace type aliases (`type`) into the actual type
CompilePhaseV("Resolve Type Aliases", [&]() {
- //ConvertHIR_ExpandAliases(hir_crate);
+ ConvertHIR_ExpandAliases(*hir_crate);
});
+
+ CompilePhaseV("Constant Evaluate", [&]() {
+ //ConvertHIR_ConstantEvaluate(hir_crate);
+ });
+
// Typecheck / type propagate module (type annotations of all values)
// - Check all generic conditions (ensure referenced trait is valid)
// > Binds the trait path to the actual trait definition
diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp index a1892238..e84bddd1 100644 --- a/src/resolve/index.cpp +++ b/src/resolve/index.cpp @@ -43,6 +43,9 @@ void _add_item(AST::Module& mod, IndexName location, const ::std::string& name, auto& list = get_mod_index(mod, location); bool was_import = (ir != mod.path() + name); + if( was_import ) { + DEBUG("### Import " << name << " = " << ir); + } if( false == list.insert(::std::make_pair(name, ::AST::Module::IndexEnt { is_pub, was_import, mv$(ir) } )).second ) { if( error_on_collision ) @@ -281,9 +284,91 @@ void Resolve_Index_Module_Wildcard(AST::Module& mod, bool handle_pub) } } + +void Resolve_Index_Module_Normalise_Path(const ::AST::Crate& crate, ::AST::Path& path) +{ + const auto& info = path.m_class.as_Absolute(); + if( info.crate != "" ) TODO(Span(), "Resolve_Index_Module_Normalise_Path - Crates"); + + const ::AST::Module* mod = &crate.m_root_module; + for( unsigned int i = 0; i < info.nodes.size(); i ++ ) + { + const auto& node = info.nodes[i]; + bool is_last = (i == info.nodes.size() - 1); + + if( is_last ) { + auto it = mod->m_namespace_items.find( node.name() ); + if( it == mod->m_namespace_items.end() ) + it = mod->m_value_items.find( node.name() ); + if( it == mod->m_value_items.end() ) + ERROR(Span(), E0000, "Couldn't find final node of path " << path); + const auto& ie = it->second; + + if( ie.is_import ) { + // TODO: Prevent infinite recursion if the user does something dumb + path = ::AST::Path(ie.path); + Resolve_Index_Module_Normalise_Path(crate, path); + } + else { + // All good + } + } + else { + auto it = mod->m_namespace_items.find( node.name() ); + if( it == mod->m_namespace_items.end() ) + ERROR(Span(), E0000, "Couldn't find node " << i << " of path " << path); + const auto& ie = it->second; + + if( ie.is_import ) { + TODO(Span(), "Replace imports"); + } + else { + TU_MATCH_DEF(::AST::PathBinding, (ie.path.binding()), (e), + ( + BUG(Span(), "Path " << path << " pointed to non-module " << ie.path); + ), + (Module, + mod = e.module_; + ), + (Enum, + // NOTE: Just assuming that if an Enum is hit, it's sane + return ; + ) + ) + } + } + } +} +void Resolve_Index_Module_Normalise(const ::AST::Crate& crate, ::AST::Module& mod) +{ + TRACE_FUNCTION_F("mod = " << mod.path()); + for( auto& item : mod.items() ) + { + TU_IFLET(AST::Item, item.data, Module, e, + Resolve_Index_Module_Normalise(crate, e); + ) + } + + for( auto& ent : mod.m_namespace_items ) { + Resolve_Index_Module_Normalise_Path(crate, ent.second.path); + } + for( auto& ent : mod.m_type_items ) { + Resolve_Index_Module_Normalise_Path(crate, ent.second.path); + } + for( auto& ent : mod.m_value_items ) { + Resolve_Index_Module_Normalise_Path(crate, ent.second.path); + } +} + void Resolve_Index(AST::Crate& crate) { + // - Index all explicitly named items Resolve_Index_Module_Base(crate.m_root_module); + // - Add all public glob imported items - `pub use module::*` Resolve_Index_Module_Wildcard(crate.m_root_module, true); + // - Add all private glob imported items Resolve_Index_Module_Wildcard(crate.m_root_module, false); + + // - Normalise the index (ensuring all paths point directly to the item) + Resolve_Index_Module_Normalise(crate, crate.m_root_module); } diff --git a/src/resolve/main_bindings.hpp b/src/resolve/main_bindings.hpp new file mode 100644 index 00000000..cc6c74d7 --- /dev/null +++ b/src/resolve/main_bindings.hpp @@ -0,0 +1,12 @@ +/* + */ + +#pragma once + +namespace AST { + class Crate; +}; + +extern void Resolve_Use(::AST::Crate& crate); +extern void Resolve_Index(::AST::Crate& crate); +extern void Resolve_Absolutise(::AST::Crate& crate); |