diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/trans/codegen.cpp | 14 | ||||
-rw-r--r-- | src/trans/codegen.hpp | 2 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 318 | ||||
-rw-r--r-- | src/trans/enumerate.cpp | 16 | ||||
-rw-r--r-- | src/trans/mangle.cpp | 4 | ||||
-rw-r--r-- | src/trans/mangling.cpp | 111 | ||||
-rw-r--r-- | src/trans/mangling.hpp | 7 | ||||
-rw-r--r-- | src/trans/monomorphise.cpp | 3 |
8 files changed, 433 insertions, 42 deletions
diff --git a/src/trans/codegen.cpp b/src/trans/codegen.cpp index 4ec48f81..763920b0 100644 --- a/src/trans/codegen.cpp +++ b/src/trans/codegen.cpp @@ -14,15 +14,22 @@ void Trans_Codegen(const ::std::string& outfile, const ::HIR::Crate& crate, const TransList& list) { - auto codegen = Trans_Codegen_GetGeneratorC(outfile); + auto codegen = Trans_Codegen_GetGeneratorC(crate, outfile); // 1. Emit structure/type definitions. // - Emit in the order they're needed. // 2. Emit function prototypes - for(const auto& fcn : list.m_functions) + for(const auto& ent : list.m_functions) { - DEBUG("FUNCTION " << fcn.first); + DEBUG("FUNCTION " << ent.first); + assert( ent.second->ptr ); + if( ent.second->ptr->m_code.m_mir ) { + codegen->emit_function_proto(ent.first, *ent.second->ptr, ent.second->pp); + } + else { + codegen->emit_function_ext(ent.first, *ent.second->ptr, ent.second->pp); + } } // 3. Emit statics for(const auto& ent : list.m_statics) @@ -47,6 +54,7 @@ void Trans_Codegen(const ::std::string& outfile, const ::HIR::Crate& crate, cons DEBUG("FUNCTION CODE " << ent.first); if( ent.second->pp.has_types() ) { auto mir = Trans_Monomorphise(crate, ent.second->pp, ent.second->ptr->m_code.m_mir); + // TODO: MIR Optimisation codegen->emit_function_code(ent.first, *ent.second->ptr, ent.second->pp, mir); } else { diff --git a/src/trans/codegen.hpp b/src/trans/codegen.hpp index 0aff9412..84673eb0 100644 --- a/src/trans/codegen.hpp +++ b/src/trans/codegen.hpp @@ -42,5 +42,5 @@ public: }; -extern ::std::unique_ptr<CodeGenerator> Trans_Codegen_GetGeneratorC(const ::std::string& outfile); +extern ::std::unique_ptr<CodeGenerator> Trans_Codegen_GetGeneratorC(const ::HIR::Crate& crate, const ::std::string& outfile); diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index e0ac3b30..c2998302 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -8,14 +8,18 @@ #include "codegen.hpp" #include "mangling.hpp" #include <fstream> +#include <hir/hir.hpp> +#include <mir/mir.hpp> namespace { class CodeGenerator_C: public CodeGenerator { + const ::HIR::Crate& m_crate; ::std::ofstream m_of; public: - CodeGenerator_C(const ::std::string& outfile): + CodeGenerator_C(const ::HIR::Crate& crate, const ::std::string& outfile): + m_crate(crate), m_of(outfile) { } @@ -37,15 +41,315 @@ namespace { //virtual void emit_static_ext(const ::HIR::Path& p); //virtual void emit_static_local(const ::HIR::Path& p, const ::HIR::Static& item, const Trans_Params& params); - //virtual void emit_function_ext(const ::HIR::Path& p, const ::HIR::Function& item, const Trans_Params& params); - //virtual void emit_function_proto(const ::HIR::Path& p, const ::HIR::Function& item, const Trans_Params& params); - //virtual void emit_function_code(const ::HIR::Path& p, const ::HIR::Function& item, const Trans_Params& params); + void emit_function_ext(const ::HIR::Path& p, const ::HIR::Function& item, const Trans_Params& params) override + { + m_of << "extern "; + emit_function_header(p, item, params); + m_of << ";\n"; + } + void emit_function_proto(const ::HIR::Path& p, const ::HIR::Function& item, const Trans_Params& params) override + { + emit_function_header(p, item, params); + m_of << ";\n"; + } + void emit_function_code(const ::HIR::Path& p, const ::HIR::Function& item, const Trans_Params& params, const ::MIR::FunctionPointer& code) override + { + static Span sp; + TRACE_FUNCTION_F(p); + + emit_function_header(p, item, params); + m_of << "\n"; + m_of << "{\n"; + // Variables + m_of << "\t"; emit_ctype(params.monomorph(m_crate, item.m_return)); m_of << " rv;\n"; + for(unsigned int i = 0; i < code->named_variables.size(); i ++) { + DEBUG("var" << i << " : " << code->named_variables[i]); + m_of << "\t"; emit_ctype(code->named_variables[i]); m_of << " var" << i << ";\n"; + } + for(unsigned int i = 0; i < code->temporaries.size(); i ++) { + DEBUG("tmp" << i << " : " << code->temporaries[i]); + m_of << "\t"; emit_ctype(code->temporaries[i]); m_of << " tmp" << i << ";\n"; + } + // TODO: Code. + for(unsigned int i = 0; i < code->blocks.size(); i ++) + { + TRACE_FUNCTION_F(p << " bb" << i); + + m_of << "bb" << i << ":\n"; + + for(const auto& stmt : code->blocks[i].statements) + { + assert( stmt.is_Drop() || stmt.is_Assign() ); + if( stmt.is_Drop() ) { + } + else { + const auto& e = stmt.as_Assign(); + m_of << "\t"; emit_lvalue(e.dst); m_of << " = "; + TU_MATCHA( (e.src), (ve), + (Use, + emit_lvalue(ve); + ), + (Constant, + ), + (SizedArray, + m_of << "{"; + for(unsigned int j = ve.count; j --;) { + emit_lvalue(ve.val); + if( j != 0 ) m_of << ","; + } + m_of << "}"; + ), + (Borrow, + m_of << "& "; emit_lvalue(ve.val); + ), + (Cast, + m_of << "("; emit_ctype(ve.type); m_of << ")"; emit_lvalue(ve.val); + ), + (BinOp, + emit_lvalue(ve.val_l); + switch(ve.op) + { + case ::MIR::eBinOp::ADD: m_of << "+"; break; + case ::MIR::eBinOp::SUB: m_of << "-"; break; + case ::MIR::eBinOp::MUL: m_of << "*"; break; + case ::MIR::eBinOp::DIV: m_of << "/"; break; + case ::MIR::eBinOp::MOD: m_of << "%"; break; + + case ::MIR::eBinOp::BIT_OR: m_of << "|"; break; + case ::MIR::eBinOp::BIT_AND: m_of << "&"; break; + case ::MIR::eBinOp::BIT_XOR: m_of << "^"; break; + case ::MIR::eBinOp::BIT_SHR: m_of << ">>"; break; + case ::MIR::eBinOp::BIT_SHL: m_of << "<<"; break; + case ::MIR::eBinOp::EQ: m_of << "=="; break; + case ::MIR::eBinOp::NE: m_of << "!="; break; + case ::MIR::eBinOp::GT: m_of << ">" ; break; + case ::MIR::eBinOp::GE: m_of << ">="; break; + case ::MIR::eBinOp::LT: m_of << "<" ; break; + case ::MIR::eBinOp::LE: m_of << "<="; break; + + case ::MIR::eBinOp::ADD_OV: + case ::MIR::eBinOp::SUB_OV: + case ::MIR::eBinOp::MUL_OV: + case ::MIR::eBinOp::DIV_OV: + TODO(sp, "Overflow"); + break; + } + emit_lvalue(ve.val_r); + ), + (UniOp, + ), + (DstMeta, + emit_lvalue(ve.val); + m_of << ".META"; + ), + (DstPtr, + emit_lvalue(ve.val); + m_of << ".PTR"; + ), + (MakeDst, + m_of << "{"; + emit_lvalue(ve.ptr_val); + m_of << ","; + emit_lvalue(ve.meta_val); + m_of << "}"; + ), + (Tuple, + m_of << "{"; + for(unsigned int j = 0; j < ve.vals.size(); j ++) { + if( j != 0 ) m_of << ","; + emit_lvalue(ve.vals[j]); + } + m_of << "}"; + ), + (Array, + m_of << "{"; + for(unsigned int j = 0; j < ve.vals.size(); j ++) { + if( j != 0 ) m_of << ","; + emit_lvalue(ve.vals[j]); + } + m_of << "}"; + ), + (Variant, + TODO(sp, "Handle constructing variants"); + ), + (Struct, + m_of << "{"; + for(unsigned int j = 0; j < ve.vals.size(); j ++) { + if( j != 0 ) m_of << ","; + emit_lvalue(ve.vals[j]); + } + m_of << "}"; + ) + ) + m_of << ";\n"; + } + } + TU_MATCHA( (code->blocks[i].terminator), (e), + (Incomplete, + m_of << "\tfor(;;);\n"; + ), + (Return, + m_of << "\treturn rv;\n"; + ), + (Diverge, + m_of << "\t_Unwind_Resume();\n"; + ), + (Goto, + m_of << "\tgoto bb" << e << ";\n"; + ), + (Panic, + m_of << "\tgoto bb" << e << "; /* panic */\n"; + ), + (If, + m_of << "\tif("; emit_lvalue(e.cond); m_of << ") goto bb" << e.bb0 << "; else goto bb" << e.bb1 << ";\n"; + ), + (Switch, + m_of << "\tswitch("; emit_lvalue(e.val); m_of << ".TAG) {\n"; + for(unsigned int j = 0; j < e.targets.size(); j ++) + m_of << "\t\tcase " << j << ": goto bb" << e.targets[j] << ";\n"; + m_of << "\t}\n"; + ), + (CallValue, + ), + (CallPath, + ) + ) + } + m_of << "}\n"; + m_of.flush(); + } private: - + void emit_function_header(const ::HIR::Path& p, const ::HIR::Function& item, const Trans_Params& params) + { + emit_ctype( params.monomorph(m_crate, item.m_return) ); + m_of << " " << Trans_Mangle(p) << "("; + for(unsigned int i = 0; i < item.m_args.size(); i ++) + { + if( i != 0 ) m_of << ", "; + emit_ctype( params.monomorph(m_crate, item.m_args[i].second) ); + m_of << " arg" << i; + } + m_of << ")"; + } + void emit_lvalue(const ::MIR::LValue& val) { + } + void emit_ctype(const ::HIR::TypeRef& ty) { + TU_MATCHA( (ty.m_data), (te), + (Infer, + m_of << "@" << ty << "@"; + ), + (Diverge, + m_of << "void"; + ), + (Primitive, + switch(te) + { + case ::HIR::CoreType::Usize: m_of << "size_t"; break; + case ::HIR::CoreType::Isize: m_of << "ssize_t"; break; + case ::HIR::CoreType::U8: m_of << "uint8_t"; break; + case ::HIR::CoreType::I8: m_of << "int8_t"; break; + case ::HIR::CoreType::U16: m_of << "uint16_t"; break; + case ::HIR::CoreType::I16: m_of << "int16_t"; break; + case ::HIR::CoreType::U32: m_of << "uint32_t"; break; + case ::HIR::CoreType::I32: m_of << "int32_t"; break; + case ::HIR::CoreType::U64: m_of << "uint64_t"; break; + case ::HIR::CoreType::I64: m_of << "int64_t"; break; + + case ::HIR::CoreType::F32: m_of << "float"; break; + case ::HIR::CoreType::F64: m_of << "double"; break; + + case ::HIR::CoreType::Bool: m_of << "bool"; break; + case ::HIR::CoreType::Char: m_of << "uin32_t"; break; + case ::HIR::CoreType::Str: + BUG(Span(), "Raw str"); + } + ), + (Path, + TU_MATCHA( (te.binding), (tpb), + (Struct, + m_of << "struct s_" << Trans_Mangle(te.path); + ), + (Union, + m_of << "struct e_" << Trans_Mangle(te.path); + ), + (Enum, + m_of << "union u_" << Trans_Mangle(te.path); + ), + (Unbound, + BUG(Span(), "Unbound path in trans - " << ty); + ), + (Opaque, + BUG(Span(), "Opaque path in trans - " << ty); + ) + ) + ), + (Generic, + BUG(Span(), "Generic in trans - " << ty); + ), + (TraitObject, + BUG(Span(), "Raw trait object - " << ty); + ), + (ErasedType, + BUG(Span(), "ErasedType in trans - " << ty); + ), + (Array, + m_of << "("; emit_ctype(*te.inner); m_of << ")[" << te.size_val << "]"; + ), + (Slice, + BUG(Span(), "Raw slice object - " << ty); + ), + (Tuple, + if( te.size() == 0 ) + m_of << "tUNIT"; + else { + m_of << "TUP_" << te.size(); + for(const auto& t : te) + m_of << "_" << Trans_Mangle(t); + } + ), + (Borrow, + if( *te.inner == ::HIR::CoreType::Str ) { + m_of << "STR_PTR"; + } + else if( te.inner->m_data.is_TraitObject() ) { + m_of << "TRAITOBJ_PTR"; + } + else if( te.inner->m_data.is_Slice() ) { + m_of << "SLICE_PTR"; + } + else { + emit_ctype(*te.inner); + m_of << "*"; + } + ), + (Pointer, + if( *te.inner == ::HIR::CoreType::Str ) { + m_of << "STR_PTR"; + } + else if( te.inner->m_data.is_TraitObject() ) { + m_of << "TRAITOBJ_PTR"; + } + else if( te.inner->m_data.is_Slice() ) { + m_of << "SLICE_PTR"; + } + else { + emit_ctype(*te.inner); + m_of << "*"; + } + ), + (Function, + m_of << "void(void)*"; + //TODO(Span(), "Emit function pointer type - " << ty); + ), + (Closure, + BUG(Span(), "Closure during trans - " << ty); + ) + ) + } }; } -::std::unique_ptr<CodeGenerator> Trans_Codegen_GetGeneratorC(const ::std::string& outfile) +::std::unique_ptr<CodeGenerator> Trans_Codegen_GetGeneratorC(const ::HIR::Crate& crate, const ::std::string& outfile) { - return ::std::unique_ptr<CodeGenerator>(new CodeGenerator_C(outfile)); + return ::std::unique_ptr<CodeGenerator>(new CodeGenerator_C(crate, outfile)); } diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp index f8e64396..60bfc037 100644 --- a/src/trans/enumerate.cpp +++ b/src/trans/enumerate.cpp @@ -477,13 +477,9 @@ void Trans_Enumerate_FillFrom(TransList& out, const ::HIR::Crate& crate, const : if( function.m_code.m_mir ) { Trans_Enumerate_FillFrom_MIR(out, crate, *function.m_code.m_mir, pp); - out_fcn.ptr = &function; - out_fcn.pp = mv$(pp); - } - else - { - out_fcn.ptr = nullptr; } + out_fcn.ptr = &function; + out_fcn.pp = mv$(pp); } void Trans_Enumerate_FillFrom(TransList& out, const ::HIR::Crate& crate, const ::HIR::Static& item, TransList_Static& out_stat, Trans_Params pp) { @@ -491,12 +487,8 @@ void Trans_Enumerate_FillFrom(TransList& out, const ::HIR::Crate& crate, const : if( item.m_value.m_mir ) { Trans_Enumerate_FillFrom_MIR(out, crate, *item.m_value.m_mir, pp); - out_stat.ptr = &item; - out_stat.pp = mv$(pp); - } - else - { - out_stat.ptr = nullptr; } + out_stat.ptr = &item; + out_stat.pp = mv$(pp); } diff --git a/src/trans/mangle.cpp b/src/trans/mangle.cpp deleted file mode 100644 index 030aadce..00000000 --- a/src/trans/mangle.cpp +++ /dev/null @@ -1,4 +0,0 @@ - -extern ::std::string Trans_Mangle(const ::HIR::GenericPath& path); -extern ::std::string Trans_Mangle(const ::HIR::Path& path); -extern ::std::string Trans_Mangle(const ::HIR::TypeRef& ty); diff --git a/src/trans/mangling.cpp b/src/trans/mangling.cpp index 4e47094c..fc85f532 100644 --- a/src/trans/mangling.cpp +++ b/src/trans/mangling.cpp @@ -9,21 +9,110 @@ #include <hir/type.hpp> #include <hir/path.hpp> -::std::string Trans_Mangle(const ::HIR::GenericPath& path) +::FmtLambda Trans_Mangle(const ::HIR::GenericPath& path) { - ::std::stringstream ss; - ss << "_ZN" << path.m_path.m_crate_name.size() << path.m_path.m_crate_name; - for(const auto& comp : path.m_path.m_components) - ss << comp.size() << comp; - - return ss.str(); + return FMT_CB(ss, + ss << "_ZN" << path.m_path.m_crate_name.size() << path.m_path.m_crate_name; + for(const auto& comp : path.m_path.m_components) + ss << comp.size() << comp; + ); } -::std::string Trans_Mangle(const ::HIR::Path& path) +::FmtLambda Trans_Mangle(const ::HIR::Path& path) { - return ""; + TU_MATCHA( (path.m_data), (pe), + (Generic, + return Trans_Mangle(pe); + ), + (UfcsUnknown, + BUG(Span(), "UfcsUnknown - " << path); + ), + (UfcsKnown, + return FMT_CB(ss, ); + ), + (UfcsInherent, + return FMT_CB(ss, ); + ) + ) + throw ""; } -::std::string Trans_Mangle(const ::HIR::TypeRef& ty) +::FmtLambda Trans_Mangle(const ::HIR::TypeRef& ty) { - return ""; + TU_MATCHA( (ty.m_data), (te), + (Infer, + BUG(Span(), "Infer in trans"); + ), + (Diverge, + return FMT_CB(ss, ss << "$D";); + ), + (Primitive, + return FMT_CB(ss, ss << te;); + ), + (Path, + return Trans_Mangle(te.path); + ), + (Generic, + BUG(Span(), "Generic in trans - " << ty); + ), + (TraitObject, + BUG(Span(), "Raw trait object - " << ty); + ), + (ErasedType, + BUG(Span(), "ErasedType in trans - " << ty); + ), + (Array, + return FMT_CB(ss, ss << "$A" << te.size_val << "_" << Trans_Mangle(*te.inner);); + ), + (Slice, + return FMT_CB(ss, ss << "$A" << "_" << Trans_Mangle(*te.inner);); + ), + (Tuple, + return FMT_CB(ss, + ss << "$T"; + for(const auto& t : te) + ss << "_" << Trans_Mangle(t); + ); + ), + (Borrow, + return FMT_CB(ss, + ss << "$R"; + switch(te.type) + { + case ::HIR::BorrowType::Shared: ss << "s"; break; + case ::HIR::BorrowType::Unique: ss << "u"; break; + case ::HIR::BorrowType::Owned : ss << "o"; break; + } + ss << "_" << Trans_Mangle(*te.inner); + ); + ), + (Pointer, + return FMT_CB(ss, + ss << "$P"; + switch(te.type) + { + case ::HIR::BorrowType::Shared: ss << "s"; break; + case ::HIR::BorrowType::Unique: ss << "u"; break; + case ::HIR::BorrowType::Owned : ss << "o"; break; + } + ss << "_" << Trans_Mangle(*te.inner); + ); + ), + (Function, + return FMT_CB(ss, + if(te.m_abi != "Rust") + ss << "extern_" << te.m_abi << "_"; + if(te.is_unsafe) + ss << "unsafe_"; + ss << "fn_" << te.m_arg_types.size(); + for(const auto& ty : te.m_arg_types) + ss << "_" << Trans_Mangle(ty); + ss << "_" << Trans_Mangle(*te.m_rettype); + ); + ), + (Closure, + BUG(Span(), "Closure during trans - " << ty); + ) + ) + + throw ""; } diff --git a/src/trans/mangling.hpp b/src/trans/mangling.hpp index b9ead23d..ad6c9add 100644 --- a/src/trans/mangling.hpp +++ b/src/trans/mangling.hpp @@ -7,6 +7,7 @@ */ #pragma once #include <string> +#include <debug.hpp> namespace HIR { class GenericPath; @@ -14,7 +15,7 @@ namespace HIR { class TypeRef; } -extern ::std::string Trans_Mangle(const ::HIR::GenericPath& path); -extern ::std::string Trans_Mangle(const ::HIR::Path& path); -extern ::std::string Trans_Mangle(const ::HIR::TypeRef& ty); +extern ::FmtLambda Trans_Mangle(const ::HIR::GenericPath& path); +extern ::FmtLambda Trans_Mangle(const ::HIR::Path& path); +extern ::FmtLambda Trans_Mangle(const ::HIR::TypeRef& ty); diff --git a/src/trans/monomorphise.cpp b/src/trans/monomorphise.cpp index 9d2f1b1c..e27369f8 100644 --- a/src/trans/monomorphise.cpp +++ b/src/trans/monomorphise.cpp @@ -72,7 +72,7 @@ namespace { output.temporaries.reserve( tpl->temporaries.size() ); for(const auto& ty : tpl->temporaries) { - output.named_variables.push_back( params.monomorph(crate, ty) ); + output.temporaries.push_back( params.monomorph(crate, ty) ); } // 2. Monomorphise all paths @@ -82,6 +82,7 @@ namespace { { ::std::vector< ::MIR::Statement> statements; + TRACE_FUNCTION_F("bb" << output.blocks.size()); statements.reserve( block.statements.size() ); for(const auto& stmt : block.statements) { |