summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/trans/codegen.cpp14
-rw-r--r--src/trans/codegen.hpp2
-rw-r--r--src/trans/codegen_c.cpp318
-rw-r--r--src/trans/enumerate.cpp16
-rw-r--r--src/trans/mangle.cpp4
-rw-r--r--src/trans/mangling.cpp111
-rw-r--r--src/trans/mangling.hpp7
-rw-r--r--src/trans/monomorphise.cpp3
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)
{