summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-05-24 13:34:01 +0800
committerJohn Hodge <tpg@mutabah.net>2016-05-24 13:34:01 +0800
commitba6f4df093bc8bfc330b2205279f3f0fca225e77 (patch)
tree685633cde5f8ccc24675a18564cc818cc7e2dec9
parentb96c1a08cec9be6cc29f47eb151c3ad91075a819 (diff)
downloadmrust-ba6f4df093bc8bfc330b2205279f3f0fca225e77.tar.gz
HIR Lower - Lower impl blocks
-rw-r--r--Makefile2
-rw-r--r--src/ast/ast.cpp6
-rw-r--r--src/ast/ast.hpp4
-rw-r--r--src/hir/from_ast.cpp164
-rw-r--r--src/hir/from_ast_expr.cpp24
-rw-r--r--src/hir/hir.hpp41
-rw-r--r--src/hir/path.hpp14
-rw-r--r--src/hir_conv/constant_evaluation.cpp10
-rw-r--r--src/hir_conv/expand_type.cpp1
-rw-r--r--src/hir_conv/main_bindings.hpp1
-rw-r--r--src/main.cpp2
-rw-r--r--src/resolve/absolute.cpp47
12 files changed, 275 insertions, 41 deletions
diff --git a/Makefile b/Makefile
index df67eac8..ebd04120 100644
--- a/Makefile
+++ b/Makefile
@@ -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())