Skip to content

Commit

Permalink
Added support for auto custom type and members
Browse files Browse the repository at this point in the history
  • Loading branch information
AjayBrahmakshatriya committed Apr 5, 2024
1 parent 0e320b7 commit 76a296c
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 5 deletions.
52 changes: 48 additions & 4 deletions include/builder/block_type_extractor.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,62 @@ namespace builder {

struct custom_type_base;



template <typename T>
struct check_valid_type {
typedef void type;
};

extern int type_naming_counter;

template <typename T, typename V=void>
struct type_namer {
static std::string obtained_name;
static std::string get_type_name() {
if (obtained_name == "") {
obtained_name = "custom_struct" + std::to_string(type_naming_counter++);
}
return obtained_name;
}
};
template <typename T, typename V>
std::string type_namer<T, V>::obtained_name = "";

template <typename T>
struct type_namer<T, typename check_valid_type<decltype(T::type_name)>::type> {
static std::string get_type_name() {
return T::type_name;
}
};

template <typename T, typename V=void>
struct type_template {
static std::vector<block::type::Ptr> get_templates() {
return {};
}
};

template <typename T>
struct type_template<T, typename check_valid_type<decltype(T::get_template_arg_types)>::type> {
static std::vector<block::type::Ptr> get_templates() {
return T::get_template_arg_types();
}
};


// The main definition of the type extractor classes
template <typename T>
class type_extractor {
public:
// This implementation is currenty only used
// by custom types which are derived from custom_type_base
static block::type::Ptr extract_type(void) {
static_assert(std::is_base_of<custom_type_base, T>::value,
"Custom types should inherit from builder::custom_type_base");
//static_assert(std::is_base_of<custom_type_base, T>::value,
//"Custom types should inherit from builder::custom_type_base");
block::named_type::Ptr type = std::make_shared<block::named_type>();
type->type_name = T::type_name;
type->template_args = T::get_template_arg_types();
type->type_name = type_namer<T>::get_type_name();
type->template_args = type_template<T>::get_templates();
return type;
}
};
Expand Down
41 changes: 40 additions & 1 deletion include/builder/dyn_var.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class var {

// Feature to gather members of this type
std::vector<var *> members;
// Counter for naming unnamed members
int member_counter = 0;

static block::type::Ptr create_block_type(void) {
// Cannot create block type for abstract class
Expand Down Expand Up @@ -146,6 +148,22 @@ class dyn_var_impl : public var {
}

dyn_var_impl() {
// implementation for auto member detection
if (parents_stack && parents_stack->size() != 0) {
current_state = member_var;
parent_var = parents_stack->back();
var_name = "mem" + std::to_string(parent_var->member_counter++);
block_var = nullptr;
block_decl_stmt = nullptr;

if (options::track_members) {
parent_var->members.push_back(this);
block_var = std::make_shared<block::var>();
block_var->var_type = create_block_type();
block_var->var_name = var_name;
}
return;
}
create_dyn_var(false);
}
// Basic and other constructors
Expand All @@ -165,6 +183,21 @@ class dyn_var_impl : public var {
*ptr_to_leak = block_var;
}
dyn_var_impl(const with_name &v) {
if (parents_stack && parents_stack->size() != 0) {
current_state = member_var;
parent_var = parents_stack->back();
var_name = v.name;
block_var = nullptr;
block_decl_stmt = nullptr;

if (options::track_members) {
parent_var->members.push_back(this);
block_var = std::make_shared<block::var>();
block_var->var_type = create_block_type();
block_var->var_name = var_name;
}
return;
}
// with_name constructors don't usually get declarations
create_dyn_var(!v.with_decl);
block_var->var_name = v.name;
Expand All @@ -174,6 +207,8 @@ class dyn_var_impl : public var {

dyn_var_impl(const defer_init &) {
// Do nothing here
// Defer init "automatically" supports custom types
// because well, we don't create declarations anyway
}
// The function to actually initialize a dyn_var, if it
// has been deferred. It is OKAY to call this even if defer_init
Expand Down Expand Up @@ -302,7 +337,11 @@ struct member_initializer_end {
};

template <typename T>
struct dyn_var_parent_selector<T, typename std::enable_if<std::is_base_of<custom_type_base, T>::value>::type>
struct dyn_var_parent_selector<T,
typename std::enable_if<
std::is_class<T>::value && !std::is_base_of<var, T>::value
&& !std::is_base_of<static_var_base, T>::value
>::type>
: public member_initializer_begin<T>, public T, public member_initializer_end {};

// Actual dyn_var implementation
Expand Down
44 changes: 44 additions & 0 deletions samples/sample56.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "blocks/c_code_generator.h"
#include "builder/builder.h"
#include "builder/builder_context.h"
#include "builder/dyn_var.h"
#include "builder/static_var.h"
#include <iostream>

using builder::as_member;
using builder::dyn_var;
using builder::static_var;


struct struct_type {
dyn_var<int> x;
dyn_var<float> y;
};

struct my_type {
static constexpr const char* type_name = "my_type";
dyn_var<struct_type> nested = builder::with_name("nested");
dyn_var<int> another;
};

static void bar(void) {
dyn_var<my_type> a;
dyn_var<struct_type> b;

a.nested = b;
a.nested.x = a.another;

a.nested.y++;
}

int main(int argc, char *argv[]) {

builder::builder_context context;
auto ast = context.extract_function_ast(bar, "bar");
ast->dump(std::cout, 0);

block::c_code_generator::generate_struct_decl<dyn_var<struct_type>>(std::cout);
block::c_code_generator::generate_struct_decl<dyn_var<my_type>>(std::cout);
block::c_code_generator::generate_code(ast, std::cout, 0);
return 0;
}
5 changes: 5 additions & 0 deletions src/builder/block_type_extractor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "builder/block_type_extractor.h"

namespace builder {
int type_naming_counter = 0;
}

0 comments on commit 76a296c

Please sign in to comment.