diff options
author | John Hodge <tpg@mutabah.net> | 2016-12-04 15:13:38 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-12-04 15:13:38 +0800 |
commit | bb2dfa78922acb5e1b8a2510412a8384acb99669 (patch) | |
tree | 34cbe4eb8464c9855e7fa21f168113e9d7594b00 /src/trans/codegen.cpp | |
parent | e20f170181ac1b5bd101d57b2248288727b26e59 (diff) | |
download | mrust-bb2dfa78922acb5e1b8a2510412a8384acb99669.tar.gz |
Trans - Coming along
Diffstat (limited to 'src/trans/codegen.cpp')
-rw-r--r-- | src/trans/codegen.cpp | 187 |
1 files changed, 184 insertions, 3 deletions
diff --git a/src/trans/codegen.cpp b/src/trans/codegen.cpp index 93032876..3aa6926a 100644 --- a/src/trans/codegen.cpp +++ b/src/trans/codegen.cpp @@ -8,16 +8,195 @@ #include "main_bindings.hpp" #include "trans_list.hpp" #include <hir/hir.hpp> +#include <mir/mir.hpp> #include "codegen.hpp" #include "monomorphise.hpp" +namespace { + struct PtrComp + { + template<typename T> + bool operator()(const T* lhs, const T* rhs) const { return *lhs < *rhs; } + }; + + struct TypeVisitor + { + CodeGenerator& codegen; + ::std::set< ::HIR::TypeRef> visited; + ::std::set< const ::HIR::TypeRef*, PtrComp> active_set; + + TypeVisitor(CodeGenerator& codegen): + codegen(codegen) + {} + + void visit_struct(const ::HIR::GenericPath& path, const ::HIR::Struct& item) { + static Span sp; + ::HIR::TypeRef tmp; + auto monomorph = [&](const auto& x)->const auto& { + if( monomorphise_type_needed(x) ) { + tmp = monomorphise_type(sp, item.m_params, path.m_params, x); + //m_resolve.expand_associated_types(sp, tmp); + return tmp; + } + else { + return x; + } + }; + TU_MATCHA( (item.m_data), (e), + (Unit, + ), + (Tuple, + for(const auto& fld : e) { + visit_type( monomorph(fld.ent) ); + } + ), + (Named, + for(const auto& fld : e) + visit_type( monomorph(fld.second.ent) ); + ) + ) + codegen.emit_struct(sp, path, item); + } + void visit_union(const ::HIR::GenericPath& path, const ::HIR::Union& item) { + } + void visit_enum(const ::HIR::GenericPath& path, const ::HIR::Enum& item) { + static Span sp; + ::HIR::TypeRef tmp; + auto monomorph = [&](const auto& x)->const auto& { + if( monomorphise_type_needed(x) ) { + tmp = monomorphise_type(sp, item.m_params, path.m_params, x); + //m_resolve.expand_associated_types(sp, tmp); + return tmp; + } + else { + return x; + } + }; + for(const auto& variant : item.m_variants) + { + TU_MATCHA( (variant.second), (e), + (Unit, + ), + (Value, + ), + (Tuple, + for(const auto& ty : e) + visit_type( monomorph(ty.ent) ); + ), + (Struct, + for(const auto& fld : e) + visit_type( monomorph(fld.second.ent) ); + ) + ) + } + + codegen.emit_enum(sp, path, item); + } + + void visit_type(const ::HIR::TypeRef& ty) + { + // Already done + if( visited.find(ty) != visited.end() ) + return ; + + if( active_set.find(&ty) != active_set.end() ) { + // TODO: Handle recursion + return ; + } + active_set.insert( &ty ); + + TU_MATCHA( (ty.m_data), (te), + // Impossible + (Infer, + ), + (Generic, + ), + (ErasedType, + ), + (Closure, + ), + // Nothing to do + (Diverge, + ), + (Primitive, + ), + // Recursion! + (Path, + TU_MATCHA( (te.binding), (tpb), + (Unbound, ), + (Opaque, ), + (Struct, + visit_struct(te.path.m_data.as_Generic(), *tpb); + ), + (Union, + visit_union(te.path.m_data.as_Generic(), *tpb); + ), + (Enum, + visit_enum(te.path.m_data.as_Generic(), *tpb); + ) + ) + ), + (TraitObject, + ), + (Array, + visit_type(*te.inner); + ), + (Slice, + visit_type(*te.inner); + ), + (Borrow, + visit_type(*te.inner); + ), + (Pointer, + visit_type(*te.inner); + ), + (Tuple, + for(const auto& sty : te) + visit_type(sty); + ), + (Function, + visit_type(*te.m_rettype); + for(const auto& sty : te.m_arg_types) + visit_type(sty); + ) + ) + active_set.erase( active_set.find(&ty) ); + + codegen.emit_type(ty); + visited.insert( ty.clone() ); + } + }; +} + void Trans_Codegen(const ::std::string& outfile, const ::HIR::Crate& crate, const TransList& list) { auto codegen = Trans_Codegen_GetGeneratorC(crate, outfile); // 1. Emit structure/type definitions. // - Emit in the order they're needed. + { + TypeVisitor tv { *codegen }; + for(const auto& ent : list.m_functions) + { + assert(ent.second->ptr); + const auto& fcn = *ent.second->ptr; + const auto& pp = ent.second->pp; + + tv.visit_type( pp.monomorph(crate, fcn.m_return) ); + for(const auto& arg : fcn.m_args) + tv.visit_type( pp.monomorph(crate, arg.second) ); + + if( fcn.m_code.m_mir ) + { + const auto& mir = *fcn.m_code.m_mir; + for(const auto& ty : mir.named_variables) + tv.visit_type(pp.monomorph(crate, ty)); + for(const auto& ty : mir.temporaries) + tv.visit_type(pp.monomorph(crate, ty)); + } + } + } // 2. Emit function prototypes for(const auto& ent : list.m_functions) @@ -35,14 +214,16 @@ void Trans_Codegen(const ::std::string& outfile, const ::HIR::Crate& crate, cons for(const auto& ent : list.m_statics) { DEBUG("STATIC " << ent.first); + assert(ent.second->ptr); + const auto& stat = *ent.second->ptr; - if( ent.second->ptr ) + if( stat.m_value ) { - codegen->emit_static_ext(ent.first); + codegen->emit_static_local(ent.first, stat, ent.second->pp); } else { - codegen->emit_static_local(ent.first, *ent.second->ptr, ent.second->pp); + codegen->emit_static_ext(ent.first, stat, ent.second->pp); } } |