summaryrefslogtreecommitdiff
path: root/modules/tools
diff options
context:
space:
mode:
authorClaudius "keldu" Holeksa <mail@keldu.de>2024-03-26 17:18:20 +0100
committerClaudius "keldu" Holeksa <mail@keldu.de>2024-03-26 17:18:20 +0100
commitcdd8dab6d276d8b62b025ac98e495a258331d1e6 (patch)
tree4746bbd5a15e1327b1c49dfaeb5b44f594282f56 /modules/tools
parent1beffbce27a2beb4528a80d32bdab1b65ef6654f (diff)
tools: Breaking the C transpilation into multiple strings.
Diffstat (limited to 'modules/tools')
-rw-r--r--modules/tools/c++/c_gen_iface.hpp136
1 files changed, 96 insertions, 40 deletions
diff --git a/modules/tools/c++/c_gen_iface.hpp b/modules/tools/c++/c_gen_iface.hpp
index 7ee4613..15d9497 100644
--- a/modules/tools/c++/c_gen_iface.hpp
+++ b/modules/tools/c++/c_gen_iface.hpp
@@ -5,9 +5,10 @@
#include <forstio/codec/schema_stringify.hpp>
#include <forstio/templates.hpp>
+#include <map>
#include <string>
#include <sstream>
-#include <map>
+#include <vector>
#include <iostream>
@@ -112,20 +113,26 @@ struct language_binding_state {
std::string type;
};
std::map<uint32_t, language_binding_state::info> hashes;
+
+ struct transpiled_element {
+ uint32_t crc32;
+ std::string header;
+ std::string source;
+ };
+ std::vector<language_binding_state::transpiled_element> tp_elements;
};
struct lang_bind_helper {
- static error_or<void> append_string(buffer& buff, const std::string_view& str){
- for(uint64_t i = 0; i < str.size(); ++i){
- auto err = buff.push(static_cast<uint8_t>(str[i]));
- if(!err.template is_type<err::no_error>()){
- return err;
- }
+ static error_or<void> append_string(std::string& buff, const std::string_view& str){
+ try {
+ buff += str;
+ }catch(const std::exception&){
+ return make_error<err::out_of_memory>();
}
return void_t{};
}
- static error_or<void> append_hashed_type(buffer& buff, const std::string_view& prefix, uint32_t hash){
+ static error_or<void> append_hashed_type(std::string& buff, const std::string_view& prefix, uint32_t hash){
{
auto eov = append_string(buff, prefix);
if(eov.is_error()){
@@ -159,7 +166,8 @@ template<typename T, uint64_t L>
struct lang_bind<schema::Primitive<T,L>, binding::SyncC> {
using Schema = schema::Primitive<T,L>;
- static error_or<void> generate_c_to_cpp(buffer& src, const language_binding_config& cfg, language_binding_state& state, const std::string_view& cpp_name, const std::string_view& c_name ){
+ static error_or<void> generate_c_to_cpp(const language_binding_config& cfg, language_binding_state& state, const std::string_view& cpp_name, const std::string_view& c_name ){
+ return void_t{};
{
auto eov = lang_bind_helper::append_string(src, "\t");
if(eov.is_error()){
@@ -230,12 +238,19 @@ struct lang_bind<schema::Primitive<T,L>, binding::SyncC> {
}
static error_or<void> generate(buffer& head, buffer& src, const language_binding_config& cfg, language_binding_state& state){
- constexpr uint64_t hash = schema_hash<Schema>::apply();
+ constexpr uint32_t hash = schema_hash<Schema>::apply();
{
std::string hash_type_str = cfg.prefix + "_" + std::to_string(hash) + "_t";
auto emp = state.hashes.emplace(std::make_pair(hash, hash_type_str));
if(emp.second){
+ try {
+ language_binding_state::transpiled_element ele;
+ ele.crc32 = hash;
+ state.tp_elements.emplace_back(ele);
+ }catch(const std::exception&){
+ return make_error<err::out_of_memory>();
+ }
{
auto eov = lang_bind_helper::append_string(head, "typedef ");
if(eov.is_error()){
@@ -276,28 +291,61 @@ struct lang_bind<schema::Primitive<T,L>, binding::SyncC> {
template<typename... V, string_literal... K>
struct lang_bind<schema::Struct<schema::Member<V,K>...>, binding::SyncC> {
using Schema = schema::Struct<schema::Member<V,K>...>;
+
+ static error_or<void> generate_c_to_cpp(buffer& src, const language_binding_config& cfg, language_binding_state& state, const std::string_view& cpp_name, const std::string_view& c_name ){
+ return void_t{};
+ }
+
+ static error_or<void> generate_cpp_to_c(buffer& src, const language_binding_config& cfg, language_binding_state& state, const std::string_view& c_name, const std::string_view& cpp_name ){
+ return void_t{};
+ }
template<uint64_t i>
- static error_or<void> generate_ele(buffer& head, buffer& src, const language_binding_config& cfg, language_binding_state& state){
+ static error_or<void> guarantee_ele(buffer& head, buffer& src, const language_binding_config& cfg, language_binding_state& state){
using MT = typename parameter_pack_type<i,V...>::type;
- constexpr uint64_t hash = schema_hash<MT>::apply();
- std::string hash_type_str = cfg.prefix + "_" + std::to_string(hash) + "_t";
- auto emp = state.hashes.emplace(std::make_pair(hash, hash_type_str));
/**
- * If successful insertion did happen that means we have no struct def yet.
+ * Guarante existance of inner type
*/
- if (emp.second) {
- {
- auto eov = lang_bind_helper::append_hashed_type(head, cfg.prefix, hash);
+ {
+ auto eov = lang_bind<MT, binding::SyncC>::generate(head, src, cfg, state);
if(eov.is_error()){
return eov;
}
+ }
+ if constexpr ( (i+1) < sizeof...(V) ){
+ return guarantee_ele<i+1u>(head, src, cfg, state);
+ }
+ return void_t{};
+ }
+
+ template<uint64_t i>
+ static error_or<void> generate_ele(buffer& head, buffer& src, const language_binding_config& cfg, language_binding_state& state){
+ using MT = typename parameter_pack_type<i,V...>::type;
+ static constexpr string_literal Lit = parameter_key_pack_type<i,K...>::literal;
+
+ constexpr uint64_t hash = schema_hash<MT>::apply();
+ {
+ auto eov = lang_bind_helper::append_hashed_type(head, cfg.prefix, hash);
+ if(eov.is_error()){
+ return eov;
}
- {
- auto eov = lang_bind_helper::append_string(head, "};\n");
- if(eov.is_error()){
- return eov;
- }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(head, " ");
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(head, Lit.view());
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ auto eov = lang_bind_helper::append_string(head, ";\n");
+ if(eov.is_error()){
+ return eov;
}
}
@@ -320,6 +368,12 @@ struct lang_bind<schema::Struct<schema::Member<V,K>...>, binding::SyncC> {
/**
* Generate struct type
*/
+ if constexpr ( sizeof...(V) > 0){
+ auto eov = guarantee_ele<0u>(head, src, cfg, state);
+ if(eov.is_error()){
+ return eov;
+ }
+ }
{
auto eov = lang_bind_helper::append_string(head, "struct ");
if(eov.is_error()){
@@ -342,7 +396,7 @@ struct lang_bind<schema::Struct<schema::Member<V,K>...>, binding::SyncC> {
auto eov = generate_ele<0>(head, src, cfg, state);
}
{
- auto eov = lang_bind_helper::append_string(head, "\n};\n");
+ auto eov = lang_bind_helper::append_string(head, "};\n");
if(eov.is_error()){
return eov;
}
@@ -361,10 +415,12 @@ struct lang_bind<schema::Array<T,D>, binding::SyncC> {
static_assert(is_primitive<T>::value, "Currently only primitive type arrays are supported");
static error_or<void> generate_c_to_cpp(buffer& src, const language_binding_config& cfg, language_binding_state& state, const std::string_view& cpp_name, const std::string_view& c_name ){
+ return void_t{};
return make_error<err::not_implemented>();
}
static error_or<void> generate_cpp_to_c(buffer& src, const language_binding_config& cfg, language_binding_state& state, const std::string_view& c_name, const std::string_view& cpp_name ){
+ return void_t{};
return make_error<err::not_implemented>();
}
@@ -786,25 +842,25 @@ struct lang_bind<schema::Function<Input, Output>, binding::SyncC> {
template<typename... M>
struct lang_bind<schema::Interface<M...>, binding::SyncC> {
template<uint64_t i>
- static error_or<void> generate_element(buffer& buff, buffer& src, const language_binding_config& cfg, language_binding_state& state){
+ static error_or<void> generate_element(const language_binding_config& cfg, language_binding_state& state){
using Member = typename parameter_pack_type<i, M...>::type;
using MValue = typename Member::ValueType;
static constexpr string_literal MKey = Member::KeyLiteral;
{
- auto eov = lang_bind<MValue, binding::SyncC>::generate(buff, src, cfg, state, MKey.view());
+ auto eov = lang_bind<MValue, binding::SyncC>::generate(cfg, state, MKey.view());
if(eov.is_error()){
return eov;
}
}
if constexpr ((i+1) < sizeof...(M) ){
- return generate_element<i+1>(buff, src, cfg, state);
+ return generate_element<i+1>(cfg, state);
}
return void_t{};
}
- static error_or<void> generate(buffer& buff, buffer& src, const language_binding_config& cfg){
+ static error_or<void> generate(buffer& head, buffer& src, const language_binding_config& cfg){
if(cfg.prefix.size() == 0){
return make_error<err::invalid_state>("C interfaces need a prefix.");
}
@@ -851,21 +907,21 @@ struct lang_bind<schema::Interface<M...>, binding::SyncC> {
* Context definition
*/
/// @todo Add Macro which reduces typing time ? Not really that much shorter :/
- // SAW_CALL_AND_RETURN_ON_ERROR(lang_bind_helper::append_string(buff, "struct "));
+ // SAW_CALL_AND_RETURN_ON_ERROR(lang_bind_helper::append_string(head, "struct "));
{
- auto eov = lang_bind_helper::append_string(buff, "struct ");
+ auto eov = lang_bind_helper::append_string(head, "struct ");
if(eov.is_error()){
return eov;
}
}
{
- auto eov = lang_bind_helper::append_string(buff, cfg.prefix);
+ auto eov = lang_bind_helper::append_string(head, cfg.prefix);
if(eov.is_error()){
return eov;
}
}
{
- auto eov = lang_bind_helper::append_string(buff, "_context {\n\tvoid* ctx;\n};\n\n");
+ auto eov = lang_bind_helper::append_string(head, "_context {\n\tvoid* ctx;\n};\n\n");
if(eov.is_error()){
return eov;
}
@@ -875,43 +931,43 @@ struct lang_bind<schema::Interface<M...>, binding::SyncC> {
*/
auto ctx_func = [&](std::string_view str) -> error_or<void>{
{
- auto eov = lang_bind_helper::append_string(buff, "int ");
+ auto eov = lang_bind_helper::append_string(head, "int ");
if(eov.is_error()){
return eov;
}
}
{
- auto eov = lang_bind_helper::append_string(buff, cfg.prefix);
+ auto eov = lang_bind_helper::append_string(head, cfg.prefix);
if(eov.is_error()){
return eov;
}
}
{
- auto eov = lang_bind_helper::append_string(buff, "_context_");
+ auto eov = lang_bind_helper::append_string(head, "_context_");
if(eov.is_error()){
return eov;
}
}
{
- auto eov = lang_bind_helper::append_string(buff, str);
+ auto eov = lang_bind_helper::append_string(head, str);
if(eov.is_error()){
return eov;
}
}
{
- auto eov = lang_bind_helper::append_string(buff, " ( ");
+ auto eov = lang_bind_helper::append_string(head, " ( ");
if(eov.is_error()){
return eov;
}
}
{
- auto eov = lang_bind_helper::append_string(buff, cfg.prefix);
+ auto eov = lang_bind_helper::append_string(head, cfg.prefix);
if(eov.is_error()){
return eov;
}
}
{
- auto eov = lang_bind_helper::append_string(buff, "_context* ctx );\n\n");
+ auto eov = lang_bind_helper::append_string(head, "_context* ctx );\n\n");
if(eov.is_error()){
return eov;
}
@@ -968,7 +1024,7 @@ struct lang_bind<schema::Interface<M...>, binding::SyncC> {
}
if constexpr (sizeof...(M) > 0){
- return generate_element<0>(buff, src, cfg, state);
+ return generate_element<0>(head, src, cfg, state);
}
return void_t{};