General Purpose library for Freestanding C++ and POSIX systems
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 

122 linhas
3.7 KiB

#pragma once
#include "gp/containers/vector.hpp"
#include "gp/dynamic/compiler/type/type.hpp"
#include "gp/dynamic/compiler/mangle/decls.hpp"
struct gr_function;
namespace _hidden {
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 gr_mangle_function(gp::vector<gr_type> signature, gp::allocator& alloc) {
string mangledName(alloc);
for(auto& type : signature) {
_hidden::append(mangledName, "$");
switch(type.base_type){
case gr_base_type::void_:
_hidden::append(mangledName, "*");
break;
case gr_base_type::null_:
_hidden::append(mangledName, "0");
break;
case gr_base_type::int_:
_hidden::append(mangledName, "i");
break;
case gr_base_type::float_:
_hidden::append(mangledName, "r");
break;
case gr_base_type::bool_:
_hidden::append(mangledName, "b");
break;
case gr_base_type::string_:
_hidden::append(mangledName, "s");
break;
case gr_base_type::array_:
_hidden::append(mangledName, "n(", type.mangled_type, ")");
break;
case gr_base_type::class_:
_hidden::append(mangledName, "p(", type.mangled_type, ")");
break;
case gr_base_type::enum_:
_hidden::append(mangledName, "e(", type.mangled_type, ")");
break;
case gr_base_type::foreign:
_hidden::append(mangledName, "u(", type.mangled_type, ")");
break;
case gr_base_type::function_:
_hidden::append(mangledName, "f(", type.mangled_type, ")(", type.mangled_return_type, ")");
break;
case gr_base_type::task:
_hidden::append(mangledName, "t(", type.mangled_type, ")");
break;
case gr_base_type::chan:
_hidden::append(mangledName, "c(", type.mangled_type, ")");
break;
case gr_base_type::reference:
_hidden::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 gr_mangle_named_function(string name,gp::vector<gr_type> signature, gp::allocator& alloc) {
string mangledName(alloc);
_hidden::append(mangledName, name, grMangleFunction(signature, alloc));
return mangledName;
}
gr_type gr_get_function_as_type(gr_function func, gp::allocator&);/* {
GrType type = func.isTask ? GrBaseType.task : GrBaseType.function_;
type.mangledType = grMangleNamedFunction("", func.inSignature);
type.mangledReturnType = grMangleNamedFunction("", func.outSignature);
return type;
}*/
string gr_unmangle_sub_function(string mangledSignature, int& i, gp::allocator& alloc) {
string subString(alloc);
int blockCount = 1;
if(i >= mangledSignature.length && mangledSignature[i] != '(')
throw new Exception("Invalid subType mangling format, missing (");
i ++;
for(; i < mangledSignature.length; i ++) {
switch(mangledSignature[i]) {
case '(':
blockCount ++;
break;
case ')':
blockCount --;
if(blockCount == 0) {
return subString;
}
break;
default:
break;
}
subString ~= mangledSignature[i];
}
throw new Exception("Invalid subType mangling format, missing )");
}