summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-11-27 19:40:15 +0800
committerJohn Hodge <tpg@mutabah.net>2016-11-27 19:40:15 +0800
commit264bb4feab3e128db025a77f127b256ebf4f0e49 (patch)
tree34c17b08d0b2c1dfbe760a48e69d0242d0b96b33
parent3aa77e8cd45c4597867751814bebabb9daad5ae8 (diff)
downloadmrust-264bb4feab3e128db025a77f127b256ebf4f0e49.tar.gz
Trans - Initial rough up (untested) of enumeration
-rw-r--r--Makefile1
-rw-r--r--src/hir_typeck/common.hpp1
-rw-r--r--src/trans/enumerate.cpp378
-rw-r--r--src/trans/main_bindings.hpp17
-rw-r--r--src/trans/trans_list.cpp19
-rw-r--r--src/trans/trans_list.hpp26
6 files changed, 442 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index eefc87c4..3c3caa5e 100644
--- a/Makefile
+++ b/Makefile
@@ -95,6 +95,7 @@ OBJ += mir/dump.o
OBJ += mir/from_hir.o mir/from_hir_match.o mir/mir_builder.o
OBJ += mir/check.o
OBJ += hir/serialise.o hir/deserialise.o hir/serialise_lowlevel.o
+OBJ += trans/trans_list.o trans/enumerate.o
PCHS := ast/ast.hpp
diff --git a/src/hir_typeck/common.hpp b/src/hir_typeck/common.hpp
index 7e203002..07ad9ff5 100644
--- a/src/hir_typeck/common.hpp
+++ b/src/hir_typeck/common.hpp
@@ -25,6 +25,7 @@ extern bool monomorphise_type_needed(const ::HIR::TypeRef& tpl);
extern ::HIR::PathParams monomorphise_path_params_with(const Span& sp, const ::HIR::PathParams& tpl, t_cb_generic callback, bool allow_infer);
extern ::HIR::GenericPath monomorphise_genericpath_with(const Span& sp, const ::HIR::GenericPath& tpl, t_cb_generic callback, bool allow_infer);
extern ::HIR::TraitPath monomorphise_traitpath_with(const Span& sp, const ::HIR::TraitPath& tpl, t_cb_generic callback, bool allow_infer);
+extern ::HIR::Path monomorphise_path_with(const Span& sp, const ::HIR::Path& tpl, t_cb_generic callback, bool allow_infer);
extern ::HIR::TypeRef monomorphise_type_with(const Span& sp, const ::HIR::TypeRef& tpl, t_cb_generic callback, bool allow_infer=true);
extern ::HIR::TypeRef monomorphise_type(const Span& sp, const ::HIR::GenericParams& params_def, const ::HIR::PathParams& params, const ::HIR::TypeRef& tpl);
diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp
new file mode 100644
index 00000000..33a9867c
--- /dev/null
+++ b/src/trans/enumerate.cpp
@@ -0,0 +1,378 @@
+/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * trans/enumerate.cpp
+ * - Translation item enumeration
+ *
+ * Enumerates items required for translation.
+ */
+#include "main_bindings.hpp"
+#include "trans_list.hpp"
+#include <hir/hir.hpp>
+#include <mir/mir.hpp>
+#include <hir_typeck/common.hpp>
+
+struct Params {
+ Span sp;
+ ::HIR::PathParams pp_method;
+ ::HIR::PathParams pp_impl;
+
+ t_cb_generic get_cb() const;
+ ::HIR::TypeRef monomorph(const ::HIR::TypeRef& p) const;
+ ::HIR::Path monomorph(const ::HIR::Path& p) const;
+};
+
+void Trans_Enumerate_FillFrom(TransList& out, const ::HIR::Crate& crate, const ::HIR::Function& function, Params pp={});
+void Trans_Enumerate_FillFrom(TransList& out, const ::HIR::Crate& crate, const ::HIR::Static& stat, Params pp={});
+
+/// Enumerate trans items starting from `::main` (binary crate)
+TransList Trans_Enumerate_Main(const ::HIR::Crate& crate)
+{
+ TransList rv;
+ auto main_path = ::HIR::SimplePath("", {"main"});
+ const auto& fcn = crate.get_function_by_path(Span(), main_path);
+ rv.add_function(main_path, fcn);
+ Trans_Enumerate_FillFrom(rv, crate, fcn);
+ return rv;
+}
+
+/// Enumerate trans items for all public non-generic items (library crate)
+TransList Trans_Enumerate_Public(const ::HIR::Crate& crate)
+{
+ TransList rv;
+
+ for(const auto& vi : crate.m_root_module.m_value_items)
+ {
+ if( vi.second->is_public ) {
+ TU_MATCHA( (vi.second->ent), (e),
+ (Import,
+ ),
+ (StructConstant,
+ ),
+ (StructConstructor,
+ ),
+ (Constant,
+ ),
+ (Static,
+ Trans_Enumerate_FillFrom(rv,crate, e);
+ ),
+ (Function,
+ // - Only add if there are no generics.
+ Trans_Enumerate_FillFrom(rv,crate, e);
+ )
+ )
+ }
+ }
+
+ return rv;
+}
+
+namespace {
+ TAGGED_UNION(EntPtr, NotFound,
+ (NotFound, struct{}),
+ (Function, const ::HIR::Function*),
+ (Static, const ::HIR::Static*)
+ );
+ EntPtr get_ent_simplepath(const Span& sp, const ::HIR::Crate& crate, const ::HIR::SimplePath& path)
+ {
+ const ::HIR::Module* mod;
+ if( path.m_crate_name != "" ) {
+ ASSERT_BUG(sp, crate.m_ext_crates.count(path.m_crate_name) > 0, "Crate '" << path.m_crate_name << "' not loaded");
+ mod = &crate.m_ext_crates.at(path.m_crate_name)->m_root_module;
+ }
+ else {
+ mod = &crate.m_root_module;
+ }
+
+ for( unsigned int i = 0; i < path.m_components.size() - 1; i ++ )
+ {
+ const auto& pc = path.m_components[i];
+ auto it = mod->m_mod_items.find( pc );
+ if( it == mod->m_mod_items.end() ) {
+ BUG(sp, "Couldn't find component " << i << " of " << path);
+ }
+ TU_MATCH_DEF( ::HIR::TypeItem, (it->second->ent), (e2),
+ (
+ BUG(sp, "Node " << i << " of path " << path << " wasn't a module");
+ ),
+ (Module,
+ mod = &e2;
+ )
+ )
+ }
+
+ auto it = mod->m_value_items.find( path.m_components.back() );
+ if( it == mod->m_value_items.end() ) {
+ return EntPtr {};
+ }
+
+ TU_MATCH( ::HIR::ValueItem, (it->second->ent), (e),
+ (Import,
+ ),
+ (StructConstant,
+ ),
+ (StructConstructor,
+ ),
+ (Function,
+ return EntPtr { &e };
+ ),
+ (Constant,
+ //return EntPtr { &e };
+ ),
+ (Static,
+ return EntPtr { &e };
+ )
+ )
+ BUG(sp, "Path " << path << " pointed to a invalid item - " << it->second->ent.tag_str());
+ }
+ EntPtr get_ent_fullpath(const Span& sp, const ::HIR::Crate& crate, const ::HIR::Path& path)
+ {
+ TU_MATCH(::HIR::Path::Data, (path.m_data), (e),
+ (Generic,
+ return get_ent_simplepath(sp, crate, e.m_path);
+ ),
+ (UfcsInherent,
+ // Easy (ish)
+ EntPtr rv;
+ crate.find_type_impls(*e.type, [](const auto&x)->const auto& { return x; }, [&](const auto& impl) {
+ {
+ auto fit = impl.m_methods.find(e.item);
+ if( fit != impl.m_methods.end() )
+ {
+ DEBUG("Found impl" << impl.m_params.fmt_args() << " " << impl.m_type);
+ rv = EntPtr { &fit->second.data };
+ return true;
+ }
+ }
+ //{
+ // auto it = impl.m_constants.find(e.item);
+ // if( it != impl.m_constants.end() )
+ // {
+ // rv = EntPtr { &it->second.data };
+ // return true;
+ // }
+ //}
+ return false;
+ });
+ return rv;
+ ),
+ (UfcsKnown,
+ EntPtr rv;
+ crate.find_trait_impls(e.trait.m_path, *e.type, [](const auto&x)->const auto& { return x; }, [&](const auto& impl) {
+ // Hacky selection of impl.
+ // - TODO: Specialisation
+ {
+ auto fit = impl.m_methods.find(e.item);
+ if( fit != impl.m_methods.end() )
+ {
+ DEBUG("Found impl" << impl.m_params.fmt_args() << " " << impl.m_type);
+ rv = EntPtr { &fit->second.data };
+ return true;
+ }
+ }
+ //{
+ // auto it = impl.m_constants.find(e.item);
+ // if( it != impl.m_constants.end() )
+ // {
+ // rv = EntPtr { &it->second.data };
+ // return true;
+ // }
+ //}
+ return false;
+ });
+ return rv;
+ ),
+ (UfcsUnknown,
+ // TODO: Are these valid at this point in compilation?
+ TODO(sp, "get_ent_fullpath(path = " << path << ")");
+ )
+ )
+ throw "";
+ }
+}
+
+void Trans_Enumerate_FillFrom_Path(TransList& out, const ::HIR::Crate& crate, const ::HIR::Path& path, const Params& pp)
+{
+ Span sp;
+ auto path_mono = pp.monomorph(path);
+ Params sub_pp;
+ TU_MATCHA( (path_mono.m_data), (pe),
+ (Generic,
+ sub_pp = Params { sp, pe.m_params.clone() };
+ ),
+ (UfcsKnown,
+ sub_pp = Params { sp, pe.params.clone(), pe.impl_params.clone() };
+ ),
+ (UfcsInherent,
+ sub_pp = Params { sp, pe.params.clone(), pe.impl_params.clone() };
+ ),
+ (UfcsUnknown,
+ BUG(sp, "UfcsUnknown - " << path);
+ )
+ )
+ // Get the item type
+ // - Valid types are Function and Static
+ auto item_ref = get_ent_fullpath(sp, crate, path_mono);
+ TU_MATCHA( (item_ref), (e),
+ (NotFound,
+ ),
+ (Function,
+ // Add this path (monomorphised) to the queue
+ if( out.add_function( mv$(path_mono), *e ) )
+ {
+ Trans_Enumerate_FillFrom(out,crate, *e, mv$(sub_pp));
+ }
+ ),
+ (Static,
+ if( out.add_static( mv$(path_mono), *e ) )
+ {
+ Trans_Enumerate_FillFrom(out,crate, *e, mv$(sub_pp));
+ }
+ )
+ )
+}
+void Trans_Enumerate_FillFrom_MIR_LValue(TransList& out, const ::HIR::Crate& crate, const ::MIR::LValue& lv, const Params& pp)
+{
+ TU_MATCHA( (lv), (e),
+ (Variable,
+ ),
+ (Temporary,
+ ),
+ (Argument,
+ ),
+ (Static,
+ Trans_Enumerate_FillFrom_Path(out,crate, e, pp);
+ ),
+ (Return,
+ ),
+ (Field,
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, *e.val, pp);
+ ),
+ (Deref,
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, *e.val, pp);
+ ),
+ (Index,
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, *e.val, pp);
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, *e.idx, pp);
+ ),
+ (Downcast,
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, *e.val, pp);
+ )
+ )
+}
+void Trans_Enumerate_FillFrom_MIR(TransList& out, const ::HIR::Crate& crate, const ::MIR::Function& code, const Params& pp)
+{
+ for(const auto& bb : code.blocks)
+ {
+ for(const auto& stmt : bb.statements)
+ {
+ TU_MATCHA((stmt), (se),
+ (Assign,
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, se.dst, pp);
+ TU_MATCHA( (se.src), (e),
+ (Use,
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e, pp);
+ ),
+ (Constant,
+ TU_MATCHA( (e), (ce),
+ (Int, ),
+ (Uint,),
+ (Float, ),
+ (Bool, ),
+ (Bytes, ),
+ (StaticString, ), // String
+ (Const,
+ // TODO: Should this trigger anything?
+ ),
+ (ItemAddr,
+ Trans_Enumerate_FillFrom_Path(out,crate, ce, pp);
+ )
+ )
+ ),
+ (SizedArray,
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.val, pp);
+ ),
+ (Borrow,
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.val, pp);
+ ),
+ (Cast,
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.val, pp);
+ ),
+ (BinOp,
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.val_l, pp);
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.val_r, pp);
+ ),
+ (UniOp,
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.val, pp);
+ ),
+ (DstMeta,
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.val, pp);
+ ),
+ (MakeDst,
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.ptr_val, pp);
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.meta_val, pp);
+ ),
+ (Tuple,
+ for(const auto& val : e.vals)
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, val, pp);
+ ),
+ (Array,
+ for(const auto& val : e.vals)
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, val, pp);
+ ),
+ (Variant,
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.val, pp);
+ ),
+ (Struct,
+ for(const auto& val : e.vals)
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, val, pp);
+ )
+ )
+ ),
+ (Drop,
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, se.slot, pp);
+ // TODO: Ensure that the drop glue for this type is generated
+ )
+ )
+ }
+ TU_MATCHA( (bb.terminator), (e),
+ (Incomplete, ),
+ (Return, ),
+ (Diverge, ),
+ (Goto, ),
+ (Panic, ),
+ (If,
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.cond, pp);
+ ),
+ (Switch,
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.val, pp);
+ ),
+ (Call,
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.ret_val, pp);
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.fcn_val, pp);
+ for(const auto& arg : e.args)
+ Trans_Enumerate_FillFrom_MIR_LValue(out,crate, arg, pp);
+ )
+ )
+ }
+}
+
+void Trans_Enumerate_FillFrom(TransList& out, const ::HIR::Crate& crate, const ::HIR::Function& function, Params pp)
+{
+ Trans_Enumerate_FillFrom_MIR(out, crate, *function.m_code.m_mir, pp);
+}
+void Trans_Enumerate_FillFrom(TransList& out, const ::HIR::Crate& crate, const ::HIR::Static& item, Params pp)
+{
+ Trans_Enumerate_FillFrom_MIR(out, crate, *item.m_value.m_mir, pp);
+}
+
+t_cb_generic Params::get_cb() const
+{
+ return monomorphise_type_get_cb(sp, nullptr, &pp_impl, &pp_method);
+}
+::HIR::Path Params::monomorph(const ::HIR::Path& p) const
+{
+ return monomorphise_path_with(sp, p, this->get_cb(), false);
+}
+
diff --git a/src/trans/main_bindings.hpp b/src/trans/main_bindings.hpp
new file mode 100644
index 00000000..e5615fa9
--- /dev/null
+++ b/src/trans/main_bindings.hpp
@@ -0,0 +1,17 @@
+/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * trans/main_bindings.hpp
+ * - Trans functions called by main()
+ */
+#pragma once
+
+#include "trans_list.hpp"
+
+namespace HIR {
+class Crate;
+}
+
+extern TransList Trans_Enumerate_Main(const ::HIR::Crate& crate);
+extern TransList Trans_Enumerate_Public(const ::HIR::Crate& crate);
diff --git a/src/trans/trans_list.cpp b/src/trans/trans_list.cpp
new file mode 100644
index 00000000..4df20373
--- /dev/null
+++ b/src/trans/trans_list.cpp
@@ -0,0 +1,19 @@
+/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * trans/trans_list.cpp
+ * - A list of items that require translation
+ */
+#include "trans_list.hpp"
+
+bool TransList::add_function(::HIR::Path p, const ::HIR::Function& f)
+{
+ TODO(Span(), "");
+ return false;
+}
+bool TransList::add_static(::HIR::Path p, const ::HIR::Static& f)
+{
+ TODO(Span(), "");
+ return false;
+}
diff --git a/src/trans/trans_list.hpp b/src/trans/trans_list.hpp
new file mode 100644
index 00000000..9e2476b2
--- /dev/null
+++ b/src/trans/trans_list.hpp
@@ -0,0 +1,26 @@
+/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * trans/trans_list.hpp
+ * - A list of items that require translation
+ */
+#pragma once
+
+#include <hir/type.hpp>
+#include <hir/path.hpp>
+
+namespace HIR {
+class Function;
+class Static;
+}
+
+class TransList
+{
+ ::std::vector< ::std::pair<::HIR::Path, const ::HIR::Function*> > m_functions;
+ ::std::vector< ::std::pair<::HIR::Path, const ::HIR::Static*> > m_statics;
+public:
+ bool add_function(::HIR::Path p, const ::HIR::Function& f);
+ bool add_static(::HIR::Path p, const ::HIR::Static& s);
+};
+