diff options
author | John Hodge <tpg@mutabah.net> | 2016-05-24 13:34:01 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-05-24 13:34:01 +0800 |
commit | ba6f4df093bc8bfc330b2205279f3f0fca225e77 (patch) | |
tree | 685633cde5f8ccc24675a18564cc818cc7e2dec9 | |
parent | b96c1a08cec9be6cc29f47eb151c3ad91075a819 (diff) | |
download | mrust-ba6f4df093bc8bfc330b2205279f3f0fca225e77.tar.gz |
HIR Lower - Lower impl blocks
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/ast/ast.cpp | 6 | ||||
-rw-r--r-- | src/ast/ast.hpp | 4 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 164 | ||||
-rw-r--r-- | src/hir/from_ast_expr.cpp | 24 | ||||
-rw-r--r-- | src/hir/hir.hpp | 41 | ||||
-rw-r--r-- | src/hir/path.hpp | 14 | ||||
-rw-r--r-- | src/hir_conv/constant_evaluation.cpp | 10 | ||||
-rw-r--r-- | src/hir_conv/expand_type.cpp | 1 | ||||
-rw-r--r-- | src/hir_conv/main_bindings.hpp | 1 | ||||
-rw-r--r-- | src/main.cpp | 2 | ||||
-rw-r--r-- | src/resolve/absolute.cpp | 47 |
12 files changed, 275 insertions, 41 deletions
@@ -41,7 +41,7 @@ OBJ += resolve/use.o resolve/index.o resolve/absolute.o OBJ += hir/from_ast.o hir/from_ast_expr.o OBJ += hir/crate_ptr.o hir/type_ptr.o hir/expr_ptr.o OBJ += hir/type.o hir/path.o hir/expr.o -OBJ += hir_conv/expand_type.o +OBJ += hir_conv/expand_type.o hir_conv/constant_evaluation.o OBJ += dump_as_rust.o PCHS := ast/ast.hpp diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 84218591..c7202797 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -530,6 +530,12 @@ void Trait::add_function(::std::string name, Function fcn) { void Trait::add_static(::std::string name, Static v) {
m_items.push_back( Named<Item>(mv$(name), Item::make_Static({mv$(v)}), true) );
}
+void Trait::set_is_marker() {
+ m_is_marker = true;
+}
+bool Trait::is_marker() const {
+ return m_is_marker;
+}
bool Trait::has_named_item(const ::std::string& name, bool& out_is_fcn) const
{
for( const auto& i : m_items )
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index d1e8c6a2..8b42c0bb 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -202,6 +202,7 @@ class Trait: GenericParams m_params;
::std::vector<AST::Path> m_supertraits;
+ bool m_is_marker;
NamedList<Item> m_items;
public:
Trait() {}
@@ -223,6 +224,9 @@ public: void add_function(::std::string name, Function fcn);
void add_static(::std::string name, Static v);
+ void set_is_marker();
+ bool is_marker() const;
+
bool has_named_item(const ::std::string& name, bool& out_is_fcn) const;
SERIALISABLE_PROTOTYPES();
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 37690503..46a49e75 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -9,30 +9,6 @@ ::HIR::Module LowerHIR_Module(const ::AST::Module& module, ::HIR::SimplePath path); ::HIR::Function LowerHIR_Function(const ::AST::Function& f); -/// \brief Converts the AST into HIR format -/// -/// - Removes all possibility for unexpanded macros -/// - Performs desugaring of for/if-let/while-let/... -::HIR::CratePtr LowerHIR_FromAST(::AST::Crate crate) -{ - ::std::unordered_map< ::std::string, MacroRules > macros; - - // - Extract macros from root module - for( const auto& mac : crate.m_root_module.macros() ) { - //if( mac.data.export ) { - macros.insert( ::std::make_pair( mac.name, mv$(*mac.data) ) ); - //} - } - for( const auto& mac : crate.m_root_module.macro_imports_res() ) { - //if( mac.data->export ) { - macros.insert( ::std::make_pair( mac.name, *mac.data ) ); - //} - } - - auto rootmod = LowerHIR_Module( crate.m_root_module, ::HIR::SimplePath("") ); - return ::HIR::CratePtr( ::HIR::Crate { mv$(rootmod), mv$(macros) } ); -} - // -------------------------------------------------------------------- ::HIR::GenericParams LowerHIR_GenericParams(const ::AST::GenericParams& gp) { @@ -762,10 +738,150 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H _add_mod_ns_item( mod, mv$(name), false, ::HIR::TypeItem::make_Module( LowerHIR_Module(submod, mv$(item_path)) ) ); } + // TODO: Impl blocks // TODO: Populate trait list return mod; } +void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crate) +{ + // Sub-modules + for( const auto& item : ast_mod.items() ) + { + TU_IFLET(::AST::Item, item.data, Module, e, + LowerHIR_Module_Impls(e, hir_crate); + ) + } + for( const auto& submod_ptr : ast_mod.anon_mods() ) + { + LowerHIR_Module_Impls(*submod_ptr, hir_crate); + } + + // + for( const auto& impl : ast_mod.impls() ) + { + auto params = LowerHIR_GenericParams(impl.def().params()); + auto type = LowerHIR_Type(impl.def().type()); + + if( impl.def().trait().is_valid() ) + { + bool is_marker = impl.def().trait().binding().as_Trait().trait_->is_marker(); + auto trait = LowerHIR_GenericPath(Span(), impl.def().trait()); + auto trait_name = mv$(trait.m_path); + auto trait_args = mv$(trait.m_params); + + // TODO: Determine if a trait is a marker (i.e. is a OIBIT) + + if( is_marker ) + { + hir_crate.m_marker_impls.insert( ::std::make_pair( mv$(trait_name), ::HIR::MarkerImpl { + mv$(params), + mv$(trait_args), + true, + mv$(type) + } ) ); + } + else + { + ::std::map< ::std::string, ::HIR::Function> methods; + ::std::map< ::std::string, ::HIR::Constant> constants; + ::std::map< ::std::string, ::HIR::TypeAlias> types; + + for(const auto& item : impl.items()) + { + TU_MATCH_DEF(::AST::Item, (item.data), (e), + ( + ERROR(Span(), E0000, "Unexpected item type in trait impl"); + ), + (Type, + types.insert( ::std::make_pair(item.name, LowerHIR_TypeAlias(e)) ); + ), + (Function, + methods.insert( ::std::make_pair(item.name, LowerHIR_Function(e)) ); + ) + ) + } + + hir_crate.m_trait_impls.insert( ::std::make_pair(mv$(trait_name), ::HIR::TraitImpl { + mv$(params), + mv$(trait_args), + mv$(type), + + mv$(methods), + mv$(constants), + mv$(types) + }) ); + } + } + else + { + // Inherent impls + ::std::map< ::std::string, ::HIR::Function> methods; + + for(const auto& item : impl.items()) + { + TU_MATCH_DEF(::AST::Item, (item.data), (e), + ( + ERROR(Span(), E0000, "Unexpected item type in inherent impl"); + ), + (Function, + methods.insert( ::std::make_pair(item.name, LowerHIR_Function(e)) ); + ) + ) + } + + hir_crate.m_type_impls.push_back( ::HIR::TypeImpl { + mv$(params), + mv$(type), + mv$( methods ) + } ); + } + } + for( const auto& impl : ast_mod.neg_impls() ) + { + auto params = LowerHIR_GenericParams(impl.params()); + auto type = LowerHIR_Type(impl.type()); + auto trait = LowerHIR_GenericPath(Span(), impl.trait()); + auto trait_name = mv$(trait.m_path); + auto trait_args = mv$(trait.m_params); + + hir_crate.m_marker_impls.insert( ::std::make_pair( mv$(trait_name), ::HIR::MarkerImpl { + mv$(params), + mv$(trait_args), + false, + mv$(type) + } ) ); + } +} + +/// \brief Converts the AST into HIR format +/// +/// - Removes all possibility for unexpanded macros +/// - Performs desugaring of for/if-let/while-let/... +::HIR::CratePtr LowerHIR_FromAST(::AST::Crate crate) +{ + ::HIR::Crate rv; + auto& macros = rv.m_exported_macros; + + // - Extract macros from root module + for( const auto& mac : crate.m_root_module.macros() ) { + //if( mac.data.export ) { + macros.insert( ::std::make_pair( mac.name, mv$(*mac.data) ) ); + //} + } + for( const auto& mac : crate.m_root_module.macro_imports_res() ) { + //if( mac.data->export ) { + macros.insert( ::std::make_pair( mac.name, *mac.data ) ); + //} + } + + rv.m_root_module = LowerHIR_Module( crate.m_root_module, ::HIR::SimplePath("") ); + + LowerHIR_Module_Impls(crate.m_root_module, rv); + + return ::HIR::CratePtr( mv$(rv) ); +} + diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp index eac8e756..ffcb82ce 100644 --- a/src/hir/from_ast_expr.cpp +++ b/src/hir/from_ast_expr.cpp @@ -95,7 +95,7 @@ struct LowerHIR_ExprNode_Visitor: switch(v.m_type) { case ::AST::ExprNode_BinOp::RANGE: { - // TODO: Lang items + // NOTE: Not language items auto path_Range = ::HIR::GenericPath( ::HIR::SimplePath("", {"ops", "Range"}) ); auto path_RangeFrom = ::HIR::GenericPath( ::HIR::SimplePath("", {"ops", "RangeFrom"}) ); auto path_RangeTo = ::HIR::GenericPath( ::HIR::SimplePath("", {"ops", "RangeTo"}) ); @@ -124,9 +124,25 @@ struct LowerHIR_ExprNode_Visitor: } } break; } - case ::AST::ExprNode_BinOp::RANGE_INC: - TODO(v.get_pos(), "Desugar range (inclusive)"); - break; + case ::AST::ExprNode_BinOp::RANGE_INC: { + // NOTE: Not language items + auto path_RangeInclusive_NonEmpty = ::HIR::GenericPath( ::HIR::SimplePath("", {"ops", "RangeInclusive", "NonEmpty"}) ); + auto path_RangeToInclusive = ::HIR::GenericPath( ::HIR::SimplePath("", {"ops", "RangeToInclusive"}) ); + + if( v.m_left ) + { + ::HIR::ExprNode_StructLiteral::t_values values; + values.push_back( ::std::make_pair( ::std::string("start"), LowerHIR_ExprNode_Inner( *v.m_left ) ) ); + values.push_back( ::std::make_pair( ::std::string("end") , LowerHIR_ExprNode_Inner( *v.m_right ) ) ); + m_rv.reset( new ::HIR::ExprNode_StructLiteral(mv$(path_RangeInclusive_NonEmpty), nullptr, mv$(values)) ); + } + else + { + ::HIR::ExprNode_StructLiteral::t_values values; + values.push_back( ::std::make_pair( ::std::string("end") , LowerHIR_ExprNode_Inner( *v.m_right ) ) ); + m_rv.reset( new ::HIR::ExprNode_StructLiteral(mv$(path_RangeToInclusive), nullptr, mv$(values)) ); + } + break; } case ::AST::ExprNode_BinOp::PLACE_IN: TODO(v.get_pos(), "Desugar placement syntax"); break; diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index bbc32bed..afb742cf 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -147,6 +147,8 @@ struct Trait ::std::string m_lifetime; ::std::vector< ::HIR::GenericPath > m_parent_traits; + bool m_is_marker; + ::std::unordered_map< ::std::string, AssociatedType > m_types; ::std::unordered_map< ::std::string, TraitValueItem > m_values; }; @@ -165,6 +167,8 @@ public: Module() {} Module(const Module&) = delete; Module(Module&& x) = default; + Module& operator=(const Module&) = delete; + Module& operator=(Module&&) = default; }; // -------------------------------------------------------------------- @@ -186,11 +190,48 @@ TAGGED_UNION(ValueItem, Import, (StructConstructor, struct { ::HIR::SimplePath ty; }) ); +class TypeImpl +{ +public: + ::HIR::GenericParams m_params; + ::HIR::TypeRef m_type; + + ::std::map< ::std::string, ::HIR::Function> m_methods; +}; + +class TraitImpl +{ +public: + ::HIR::GenericParams m_params; + ::HIR::PathParams m_trait_args; + ::HIR::TypeRef m_type; + + ::std::map< ::std::string, ::HIR::Function> m_methods; + ::std::map< ::std::string, ::HIR::Constant> m_constants; + ::std::map< ::std::string, ::HIR::TypeAlias> m_types; +}; + +class MarkerImpl +{ +public: + ::HIR::GenericParams m_params; + ::HIR::PathParams m_trait_args; + bool is_positive; + ::HIR::TypeRef m_type; +}; + class Crate { public: Module m_root_module; + /// Impl blocks on just a type + ::std::vector< ::HIR::TypeImpl > m_type_impls; + /// Impl blocks + ::std::multimap< ::HIR::SimplePath, ::HIR::TraitImpl > m_trait_impls; + ::std::multimap< ::HIR::SimplePath, ::HIR::MarkerImpl > m_marker_impls; + + /// Macros exported by this crate ::std::unordered_map< ::std::string, ::MacroRules > m_exported_macros; }; diff --git a/src/hir/path.hpp b/src/hir/path.hpp index acf24274..e482469e 100644 --- a/src/hir/path.hpp +++ b/src/hir/path.hpp @@ -32,6 +32,14 @@ struct SimplePath SimplePath clone() const; SimplePath operator+(const ::std::string& s) const; + bool operator==(const SimplePath& x) const { + return m_crate_name == x.m_crate_name && m_components == x.m_components; + } + bool operator<(const SimplePath& x) const { + if( m_crate_name < x.m_crate_name ) return true; + if( m_components < x.m_components ) return true; + return false; + } friend ::std::ostream& operator<<(::std::ostream& os, const SimplePath& x); }; @@ -42,6 +50,9 @@ struct PathParams PathParams(); PathParams clone() const; + + //bool operator==(const PathParams& x) const; + //bool operator<(const PathParams& x) const; }; /// Generic path - Simple path with one lot of generic params @@ -57,6 +68,9 @@ public: GenericPath clone() const; + //bool operator==(const GenericPath& x) const; + //bool operator<(const GenericPath& x) const; + friend ::std::ostream& operator<<(::std::ostream& os, const GenericPath& x); }; diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp new file mode 100644 index 00000000..0c8fe8fd --- /dev/null +++ b/src/hir_conv/constant_evaluation.cpp @@ -0,0 +1,10 @@ +/* + * Evaluate constants + */ +#include "main_bindings.hpp" +#include <hir/hir.hpp> +#include <hir/expr.hpp> + +void ConvertHIR_ConstantEvaluate(::HIR::Crate& hir_crate) +{ +} diff --git a/src/hir_conv/expand_type.cpp b/src/hir_conv/expand_type.cpp index b9f016e6..ac34f2a8 100644 --- a/src/hir_conv/expand_type.cpp +++ b/src/hir_conv/expand_type.cpp @@ -1,6 +1,7 @@ /* * Expand `type` aliases in HIR */ +#include "main_bindings.hpp" #include <hir/hir.hpp> #include <hir/expr.hpp> diff --git a/src/hir_conv/main_bindings.hpp b/src/hir_conv/main_bindings.hpp index 1a1a56d5..286b7d9d 100644 --- a/src/hir_conv/main_bindings.hpp +++ b/src/hir_conv/main_bindings.hpp @@ -7,3 +7,4 @@ namespace HIR { }; extern void ConvertHIR_ExpandAliases(::HIR::Crate& crate); +extern void ConvertHIR_ConstantEvaluate(::HIR::Crate& hir_crate); diff --git a/src/main.cpp b/src/main.cpp index c949d703..a02fbac6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -148,7 +148,7 @@ int main(int argc, char *argv[]) });
CompilePhaseV("Constant Evaluate", [&]() {
- //ConvertHIR_ConstantEvaluate(hir_crate);
+ ConvertHIR_ConstantEvaluate(*hir_crate);
});
// Typecheck / type propagate module (type annotations of all values)
diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index e828827b..45e70e98 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -928,6 +928,12 @@ void Resolve_Absolute_Expr(Context& context, ::AST::ExprNode& node) Resolve_Absolute_Path(this->context, Span(node.get_pos()), Context::LookupMode::Variable, node.m_path); AST::NodeVisitorDef::visit(node); } + void visit(AST::ExprNode_CallMethod& node) override { + DEBUG("ExprNode_CallMethod"); + for(auto& param : node.m_method.args()) + Resolve_Absolute_Type(this->context, param); + AST::NodeVisitorDef::visit(node); + } void visit(AST::ExprNode_NamedValue& node) override { DEBUG("ExprNode_NamedValue - " << node.m_path); Resolve_Absolute_Path(this->context, Span(node.get_pos()), Context::LookupMode::Variable, node.m_path); @@ -1251,18 +1257,37 @@ void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod ) for(auto& impl : mod.impls()) { - item_context.push_self( impl.def().type() ); - item_context.push(impl.def().params(), GenericSlot::Level::Top); - Resolve_Absolute_Generic(item_context, impl.def().params()); - - Resolve_Absolute_Type(item_context, impl.def().type()); - if( impl.def().trait().is_valid() ) + if( ! impl.def().type().is_valid() ) + { + item_context.push(impl.def().params(), GenericSlot::Level::Top); + Resolve_Absolute_Generic(item_context, impl.def().params()); + assert( impl.def().trait().is_valid() ); Resolve_Absolute_Path(item_context, Span(), Context::LookupMode::Type, impl.def().trait()); - - Resolve_Absolute_ImplItems(item_context, impl.items()); - - item_context.pop(impl.def().params()); - item_context.pop_self( impl.def().type() ); + + if( impl.items().size() != 0 ) { + ERROR(Span(), E0000, "impl Trait for .. with methods"); + } + + item_context.pop(impl.def().params()); + + const_cast< ::AST::Trait*>(impl.def().trait().binding().as_Trait().trait_)->set_is_marker(); + } + else + { + item_context.push_self( impl.def().type() ); + item_context.push(impl.def().params(), GenericSlot::Level::Top); + Resolve_Absolute_Generic(item_context, impl.def().params()); + + Resolve_Absolute_Type(item_context, impl.def().type()); + if( impl.def().trait().is_valid() ) { + Resolve_Absolute_Path(item_context, Span(), Context::LookupMode::Type, impl.def().trait()); + } + + Resolve_Absolute_ImplItems(item_context, impl.items()); + + item_context.pop(impl.def().params()); + item_context.pop_self( impl.def().type() ); + } } for(auto& impl_def : mod.neg_impls()) |