diff --git a/include/gp/dynamic/compiler/mangle.hpp b/include/gp/dynamic/compiler/mangle.hpp new file mode 100644 index 0000000..5fdb1fa --- /dev/null +++ b/include/gp/dynamic/compiler/mangle.hpp @@ -0,0 +1,4 @@ +#pragma once + +#include "gp/dynamic/compiler/mangle/decls.hpp" +#include "gp/dynamic/compiler/mangle/mangle_function.hpp" diff --git a/include/gp/dynamic/compiler/mangle/decls.hpp b/include/gp/dynamic/compiler/mangle/decls.hpp new file mode 100644 index 0000000..2870d80 --- /dev/null +++ b/include/gp/dynamic/compiler/mangle/decls.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; + +string grMangleFunction(gp::vector, gp::allocator&); +gp::vector grUnmangleSignature(string, gp::allocator&); \ No newline at end of file diff --git a/include/gp/dynamic/compiler/mangle/mangle_function.hpp b/include/gp/dynamic/compiler/mangle/mangle_function.hpp new file mode 100644 index 0000000..05991eb --- /dev/null +++ b/include/gp/dynamic/compiler/mangle/mangle_function.hpp @@ -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) { + 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 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 signature, gp::allocator& alloc) { + string mangledName(alloc); + append(mangledName, name, grMangleFunction(signature, alloc)); + return mangledName; +} \ No newline at end of file diff --git a/include/gp/dynamic/compiler/type.hpp b/include/gp/dynamic/compiler/type.hpp new file mode 100644 index 0000000..72ea30b --- /dev/null +++ b/include/gp/dynamic/compiler/type.hpp @@ -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" \ No newline at end of file diff --git a/include/gp/dynamic/compiler/type/base_type.hpp b/include/gp/dynamic/compiler/type/base_type.hpp new file mode 100644 index 0000000..e68f06a --- /dev/null +++ b/include/gp/dynamic/compiler/type/base_type.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, +}; diff --git a/include/gp/dynamic/compiler/type/complex_types.hpp b/include/gp/dynamic/compiler/type/complex_types.hpp new file mode 100644 index 0000000..3d18782 --- /dev/null +++ b/include/gp/dynamic/compiler/type/complex_types.hpp @@ -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; + +/// Returns an array GrType of `subType` subtype. +inline gr_type grArray(gr_type subType, gp::allocator& alloc) { + auto list = gp::vector(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(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 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 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); +} \ No newline at end of file diff --git a/include/gp/dynamic/compiler/type/type.hpp b/include/gp/dynamic/compiler/type/type.hpp new file mode 100644 index 0000000..989c316 --- /dev/null +++ b/include/gp/dynamic/compiler/type/type.hpp @@ -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; + +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; + } +}; \ No newline at end of file