diff options
author | John Hodge <tpg@mutabah.net> | 2016-12-12 22:08:18 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-12-12 22:08:18 +0800 |
commit | 4c97c1d984eb2812fe3e9dbd4656826a54d80d9f (patch) | |
tree | cbc665caf0dc219aa95f72aa1316e37716167a6c | |
parent | 48560772db858bcd142886a0c277e2b2dae9cf14 (diff) | |
download | mrust-4c97c1d984eb2812fe3e9dbd4656826a54d80d9f.tar.gz |
Trans C - Constants
-rw-r--r-- | src/main.cpp | 15 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 157 |
2 files changed, 167 insertions, 5 deletions
diff --git a/src/main.cpp b/src/main.cpp index 96d05f29..33bed1bb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -315,6 +315,7 @@ int main(int argc, char *argv[]) CompilePhaseV("Resolve HIR Markings", [&]() {
ConvertHIR_Markings(*hir_crate);
});
+ // Basic constant evalulation (intergers/floats only)
CompilePhaseV("Constant Evaluate", [&]() {
ConvertHIR_ConstantEvaluate(*hir_crate);
});
@@ -389,14 +390,24 @@ int main(int argc, char *argv[]) CompilePhaseV("Constant Evaluate Full", [&]() {
ConvertHIR_ConstantEvaluateFull(*hir_crate);
});
-
CompilePhaseV("Dump HIR", [&]() {
::std::ofstream os (FMT(params.outfile << "_2_hir.rs"));
HIR_Dump( os, *hir_crate );
});
+ // - Expand constants in MIR
+ CompilePhaseV("MIR Const Expand", [&]() {
+ //MIR_ExpandConstants(*hir_crate);
+ });
// Optimise the MIR
- // TODO: MIR Optimisation
+ CompilePhaseV("MIR Optimise", [&]() {
+ //MIR_Optimise(*hir_crate);
+ });
+
+ CompilePhaseV("Dump MIR", [&]() {
+ ::std::ofstream os (FMT(params.outfile << "_3_mir.rs"));
+ MIR_Dump( os, *hir_crate );
+ });
if( params.last_stage == ProgramParams::STAGE_MIR ) {
return 0;
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index a676bb29..67fbb79e 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -319,7 +319,9 @@ namespace { m_of << e; ), (BorrowOf, - //m_of << "&" << Trans_Mangle( params.monomorph(m_crate, e)); + if( ! ty.m_data.is_Function() ) + m_of << "&"; + m_of << Trans_Mangle( params.monomorph(m_crate, e)); ), (String, m_of << "{ "; @@ -457,8 +459,10 @@ namespace { ), (Const, // TODO: This should have been eliminated? - emit_lvalue(e.dst); - m_of << " = /*CONST*/"; + ::HIR::TypeRef tmp; + const auto& ty = mir_res.get_lvalue_type(tmp, e.dst); + const auto& lit = get_literal_for_const(c.p); + assign_from_literal([&](){ emit_lvalue(e.dst); }, ty, lit); ), (ItemAddr, emit_lvalue(e.dst); @@ -722,6 +726,9 @@ namespace { //emit_lvalue(e.ret_val); m_of << " = alignof("; emit_ctype(params.m_types.at(0)); m_of << ")"; emit_lvalue(e.ret_val); m_of << " = __alignof__("; emit_ctype(params.m_types.at(0)); m_of << ")"; } + else if( name == "type_id" ) { + emit_lvalue(e.ret_val); m_of << " = __typeid_" << Trans_Mangle(params.m_types.at(0)); + } else if( name == "transmute" ) { m_of << "memcpy( &"; emit_lvalue(e.ret_val); m_of << ", &"; emit_lvalue(e.args.at(0)); m_of << ", sizeof("; emit_ctype(params.m_types.at(0)); m_of << "))"; } @@ -911,6 +918,150 @@ namespace { } )); } + + const ::HIR::Literal& get_literal_for_const(const ::HIR::Path& path) + { + TU_MATCHA( (path.m_data), (pe), + (Generic, + if( pe.m_params.m_types.size() > 0 ) + MIR_TODO(*m_mir_res, "Paths with generics " << path); + return m_crate.get_constant_by_path(Span(), pe.m_path).m_value_res; + ), + (UfcsUnknown, + MIR_BUG(*m_mir_res, "UfcsUnknown " << path); + ), + (UfcsKnown, + MIR_TODO(*m_mir_res, "UfcsKnown " << path); + ), + (UfcsInherent, + MIR_TODO(*m_mir_res, "UfcsInherent " << path); + ) + ) + throw ""; + } + + void assign_from_literal(::std::function<void()> emit_dst, const ::HIR::TypeRef& ty, const ::HIR::Literal& lit) + { + //TRACE_FUNCTION_F("ty=" << ty << ", lit=" << lit); + Span sp; + ::HIR::TypeRef tmp; + auto monomorph_with = [&](const ::HIR::PathParams& pp, const ::HIR::TypeRef& ty)->const ::HIR::TypeRef& { + if( monomorphise_type_needed(ty) ) { + tmp = monomorphise_type_with(sp, ty, monomorphise_type_get_cb(sp, nullptr, &pp, nullptr), false); + m_resolve.expand_associated_types(sp, tmp); + return tmp; + } + else { + return ty; + } + }; + auto get_inner_type = [&](unsigned int var, unsigned int idx)->const ::HIR::TypeRef& { + TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Array, te, + return *te.inner; + ) + else TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Path, te, + const auto& pp = te.path.m_data.as_Generic().m_params; + TU_MATCHA((te.binding), (pbe), + (Unbound, BUG(sp, "Unbound type path " << ty); ), + (Opaque, BUG(sp, "Opaque type path " << ty); ), + (Struct, + TU_MATCHA( (pbe->m_data), (se), + (Unit, + BUG(sp, "Unit struct " << ty); + ), + (Tuple, + return monomorph_with(pp, se.at(idx).ent); + ), + (Named, + return monomorph_with(pp, se.at(idx).second.ent); + ) + ) + ), + (Union, + TODO(Span(), "Union literals"); + ), + (Enum, + const auto& evar = pbe->m_variants.at(var); + TU_MATCHA( (evar.second), (se), + (Unit, + BUG(sp, "Unit enum var " << ty << " #" << var << " - fld " << idx); + ), + (Value, + BUG(sp, "Value enum var " << ty << " #" << var << " - fld " << idx); + ), + (Tuple, + return monomorph_with(pp, se.at(idx).ent); + ), + (Struct, + return monomorph_with(pp, se.at(idx).second.ent); + ) + ) + ) + ) + throw ""; + ) + else TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Tuple, te, + return te.at(idx); + ) + else { + TODO(Span(), "Unknown type in list literal - " << ty); + } + }; + TU_MATCHA( (lit), (e), + (Invalid, + m_of << "/* INVALID */"; + ), + (List, + if( ty.m_data.is_Array() ) + { + for(unsigned int i = 0; i < e.size(); i ++) { + if(i != 0) m_of << ";\n\t"; + assign_from_literal([&](){ emit_dst(); m_of << ".DATA[" << i << "]"; }, *ty.m_data.as_Array().inner, e[i]); + } + } + else + { + for(unsigned int i = 0; i < e.size(); i ++) { + if(i != 0) m_of << ";\n\t"; + assign_from_literal([&](){ emit_dst(); m_of << "._" << i; }, get_inner_type(0, i), e[i]); + } + } + ), + (Variant, + emit_dst(); m_of << ".TAG = " << e.idx; + for(unsigned int i = 0; i < e.vals.size(); i ++) { + m_of << ";\n\t"; + assign_from_literal([&](){ emit_dst(); m_of << ".DATA.var_" << e.idx << "._" << i; }, get_inner_type(e.idx, i), e.vals[i]); + } + ), + (Integer, + emit_dst(); m_of << " = " << ::std::hex << "0x" << e << ::std::dec; + ), + (Float, + emit_dst(); m_of << " = " << e; + ), + (BorrowOf, + emit_dst(); m_of << " = "; + if( ! ty.m_data.is_Function() ) + m_of << "&"; + m_of << Trans_Mangle(e); + ), + (String, + emit_dst(); m_of << ".PTR = "; + m_of << "\"" << ::std::oct; + for(const auto& v : e) { + if( ' ' <= v && v < 0x7F && v != '"' && v != '\\' ) + m_of << v; + else + m_of << "\\" << (unsigned int)v; + } + m_of << "\"" << ::std::dec; + m_of << ";\n\t"; + emit_dst(); m_of << ".META = " << e.size(); + ) + ) + } + void emit_lvalue(const ::MIR::LValue& val) { TU_MATCHA( (val), (e), (Variable, |