@ -0,0 +1,4 @@ | |||||
#pragma once | |||||
#include "gp/dynamic/compiler/mangle/decls.hpp" | |||||
#include "gp/dynamic/compiler/mangle/mangle_function.hpp" |
@ -0,0 +1,10 @@ | |||||
#pragma once | |||||
#include "gp/containers/vector.hpp" | |||||
#include "gp/dynamic/compiler/type/type.hpp" | |||||
#include "gp/utils/allocators/allocator.hpp" | |||||
using string = gp::vector<char>; | |||||
string grMangleFunction(gp::vector<gr_type>, gp::allocator&); | |||||
gp::vector<gr_type> grUnmangleSignature(string, gp::allocator&); |
@ -0,0 +1,82 @@ | |||||
#pragma once | |||||
#include "gp/containers/vector.hpp" | |||||
#include "gp/dynamic/compiler/mangle/decls.hpp" | |||||
constexpr auto append = [] (string& target, auto... var) { | |||||
constexpr auto append_str = [] (string& target, auto& var) { | |||||
if constexpr (std::is_same_v<decltype(var), const char*&>) { | |||||
for(auto it = var; *it != 0; it++) { | |||||
char c = *it; | |||||
target.push_back(c); | |||||
} | |||||
} else { | |||||
for(char c : var) { | |||||
target.push_back(c); | |||||
} | |||||
} | |||||
}; | |||||
(append_str(target, var), ...); | |||||
}; | |||||
string grMangleFunction(gp::vector<gr_type> signature, gp::allocator& alloc) { | |||||
string mangledName(alloc); | |||||
for(auto& type : signature) { | |||||
append(mangledName, "$"); | |||||
switch(type.base_type){ | |||||
case gr_base_type::void_: | |||||
append(mangledName, "*"); | |||||
break; | |||||
case gr_base_type::null_: | |||||
append(mangledName, "0"); | |||||
break; | |||||
case gr_base_type::int_: | |||||
append(mangledName, "i"); | |||||
break; | |||||
case gr_base_type::float_: | |||||
append(mangledName, "r"); | |||||
break; | |||||
case gr_base_type::bool_: | |||||
append(mangledName, "b"); | |||||
break; | |||||
case gr_base_type::string_: | |||||
append(mangledName, "s"); | |||||
break; | |||||
case gr_base_type::array_: | |||||
append(mangledName, "n(", type.mangled_type, ")"); | |||||
break; | |||||
case gr_base_type::class_: | |||||
append(mangledName, "p(", type.mangled_type, ")"); | |||||
break; | |||||
case gr_base_type::enum_: | |||||
append(mangledName, "e(", type.mangled_type, ")"); | |||||
break; | |||||
case gr_base_type::foreign: | |||||
append(mangledName, "u(", type.mangled_type, ")"); | |||||
break; | |||||
case gr_base_type::function_: | |||||
append(mangledName, "f(", type.mangled_type, ")(", type.mangled_return_type, ")"); | |||||
break; | |||||
case gr_base_type::task: | |||||
append(mangledName, "t(", type.mangled_type, ")"); | |||||
break; | |||||
case gr_base_type::chan: | |||||
append(mangledName, "c(", type.mangled_type, ")"); | |||||
break; | |||||
case gr_base_type::reference: | |||||
append(mangledName, "h(", type.mangled_type, ")"); | |||||
break; | |||||
case gr_base_type::internalTuple: | |||||
gp_config::assertion(false, "Trying to mangle a tuple. Tuples should not exist here."); | |||||
} | |||||
} | |||||
return mangledName; | |||||
} | |||||
string grMangleNamedFunction(string name,gp::vector<gr_type> signature, gp::allocator& alloc) { | |||||
string mangledName(alloc); | |||||
append(mangledName, name, grMangleFunction(signature, alloc)); | |||||
return mangledName; | |||||
} |
@ -0,0 +1,5 @@ | |||||
#pragma once | |||||
#include "gp/dynamic/compiler/type/base_type.hpp" | |||||
#include "gp/dynamic/compiler/type/type.hpp" | |||||
#include "gp/dynamic/compiler/type/complex_types.hpp" |
@ -0,0 +1,9 @@ | |||||
#pragma once | |||||
enum class gr_base_type { | |||||
void_, null_, int_, float_, bool_, string_, | |||||
array_, function_, task, | |||||
class_, foreign, chan, enum_, | |||||
internalTuple, | |||||
reference, | |||||
}; |
@ -0,0 +1,35 @@ | |||||
#pragma once | |||||
#include "gp/containers/vector.hpp" | |||||
#include "gp/dynamic/compiler/type/type.hpp" | |||||
#include "gp/dynamic/compiler/mangle/decls.hpp" | |||||
#include "gp/utils/allocators/allocator.hpp" | |||||
using string = gp::vector<char>; | |||||
/// Returns an array GrType of `subType` subtype. | |||||
inline gr_type grArray(gr_type subType, gp::allocator& alloc) { | |||||
auto list = gp::vector<gr_type>(alloc); | |||||
list.push_back(subType); | |||||
return gr_type(gr_base_type::array_, grMangleFunction(list, alloc), alloc); | |||||
} | |||||
/// Returns a channel GrType of `subType` subtype. | |||||
inline gr_type grChannel(gr_type subType, gp::allocator& alloc) { | |||||
auto list = gp::vector<gr_type>(alloc); | |||||
list.push_back(subType); | |||||
return gr_type(gr_base_type::chan, grMangleFunction(list, alloc), alloc); | |||||
} | |||||
/// Pack multiple types as a single one. | |||||
inline gr_type grPackTuple(gp::vector<gr_type> types, gp::allocator& alloc) { | |||||
const string mangledName = grMangleFunction(types, alloc); | |||||
gr_type type(gr_base_type::internalTuple, mangledName, alloc); | |||||
return type; | |||||
} | |||||
/// Unpack multiple types from a single one. | |||||
inline gp::vector<gr_type> grUnpackTuple(gr_type type, gp::allocator& alloc) { | |||||
gp_config::assertion(type.base_type != gr_base_type::internalTuple, "Cannot unpack a not tuple type."); | |||||
return grUnmangleSignature(type.mangled_type); | |||||
} |
@ -0,0 +1,30 @@ | |||||
#pragma once | |||||
#include "gp/containers/vector.hpp" | |||||
#include "gp/dynamic/compiler/type/base_type.hpp" | |||||
#include "gp/utils/allocators/allocator.hpp" | |||||
using string = gp::vector<char>; | |||||
struct gr_type { | |||||
gr_base_type base_type; | |||||
string mangled_type; | |||||
string mangled_return_type; | |||||
bool is_field; | |||||
gr_type(gr_base_type base, gp::allocator& alloc) | |||||
: base_type(base) | |||||
, mangled_type(alloc) | |||||
, mangled_return_type(alloc) | |||||
{} | |||||
gr_type(gr_base_type base, string mangled_name, gp::allocator& alloc) | |||||
: base_type(base) | |||||
, mangled_type(alloc) | |||||
, mangled_return_type(alloc) | |||||
{ | |||||
mangled_type = mangled_name; | |||||
} | |||||
}; |