Skip to content

Instantly share code, notes, and snippets.

@UplinkCoder
Created August 10, 2021 22:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save UplinkCoder/93cb06e4921ab4c96752c6325e03e42d to your computer and use it in GitHub Desktop.
Save UplinkCoder/93cb06e4921ab4c96752c6325e03e42d to your computer and use it in GitHub Desktop.
import core.reflect.reflect;
import core.reflect.transitiveVisitor;
final class Collector(CollectNodeTypes...) : TransitiveVisitor
{
static if (CollectNodeTypes.length == 1)
{
CollectNodeTypes[0][] collected_nodes;
}
else
{
Node[] collected_nodes;
}
alias visit = typeof(super).visit;
static foreach (T; CollectNodeTypes)
{
override void visit(T node)
{
collected_nodes ~= node;
// continue visiting transitivly
super.visit(node);
}
}
}
import ctx_ = ctx;
pragma(msg, () {
auto node = nodeFromName("ctx_");
scope structCollector = new Collector!StructDeclaration();
scope functionCollector = new Collector!FunctionDeclaration();
(cast() node).accept(structCollector);
(cast() node).accept(functionCollector);
string result;
// assert(structCollector.collected_nodes.length == 1, "only 1 struct expected");
auto struct_ = structCollector.collected_nodes[0];
result = "class " ~ struct_.name ~ "Wrapper {\n";
bool isPointerToContextType(Type pt)
{
if (auto tp = cast(TypePointer) pt)
{
if (tp.nextOf.unqual() is struct_.type)
{
return true;
}
}
return false;
}
foreach(f;functionCollector.collected_nodes)
{
auto params = f.type.parameterTypes;
int structTypeOccured = 0;
foreach(param;params)
{
auto pt = param.type;
if (isPointerToContextType(pt))
{
structTypeOccured++;
}
}
if (structTypeOccured == 1)
{
result ~= " ";
result ~= f.type.returnType.identifier;
result ~= " ";
result ~= f.name;
result ~= " (";
int ctx_idx;
bool wasCtx;
foreach(i,p;params)
{
wasCtx = isPointerToContextType(p.type);
if (wasCtx)
{
ctx_idx = cast(int) i;
continue;
}
{
result ~= p.type.identifier
~ " "
~ p.identifier ~ ", ";
}
}
if (!wasCtx) result = result[0 .. $-2];
result ~= ") {\n";
result ~= " ";
result ~= " ";
// now build the call
result ~= f.name ~ "(";
foreach(i,p;params)
{
if (i == ctx_idx)
result ~= "ctx" ~ ", ";
else
result ~= p.identifier ~ ", ";
}
result = result[0 .. $-2];
result ~= ");\n";
// and close the body
result ~= " }\n\n";
}
}
result ~= "}\n";
return result;
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment