165 lines
No EOL
4.9 KiB
Beef
165 lines
No EOL
4.9 KiB
Beef
namespace Caa;
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using libclang_beef;
|
|
|
|
class Binding
|
|
{
|
|
public static List<BindingFunction> Function = new .() ~ DeleteContainerAndItems!(_);
|
|
public static List<BindingEnum> Enums = new .() ~ DeleteContainerAndItems!(_);
|
|
public static List<BindingStruct> Structs = new .() ~ DeleteContainerAndItems!(_);
|
|
public static BindingOptions Options = new .() ~ delete _;
|
|
public static Dictionary<CXCursorKind, function void(CXCursor*)> CursorHandlers = new .() {
|
|
(.CXCursor_FunctionDecl, => HandleFunctionDecl),
|
|
(.CXCursor_StructDecl, => HandleStructDecl),
|
|
(.CXCursor_FieldDecl, => HandleFieldDecl),
|
|
(.CXCursor_EnumDecl, => HandleEnumDecl),
|
|
(.CXCursor_EnumConstantDecl, => HandleEnumConstDecl),
|
|
(.CXCursor_ParmDecl, => DoNothing),
|
|
|
|
|
|
|
|
} ~ delete _;
|
|
|
|
public static void Bind(ref String[] pArgs)
|
|
{
|
|
CXIndex index = clang_createIndex(0, 0);
|
|
CXTranslationUnit* unit;
|
|
clang_parseTranslationUnit2(
|
|
index,
|
|
pArgs[0], //TODO: This is a hack, allegedly it would be fine if we just input the file as an arg but that doesnt seem to work
|
|
(.)&pArgs, (.)pArgs.Count, null, 0,
|
|
(.)CXTranslationUnit_Flags.CXTranslationUnit_None,
|
|
out unit
|
|
);
|
|
//TODO: Error Handling
|
|
|
|
CXCursor cursor = clang_getTranslationUnitCursor(*unit);
|
|
clang_visitChildren(
|
|
cursor,
|
|
(cursor, parent, client_data) => {
|
|
|
|
switch(clang_getCursorKind(cursor))
|
|
{
|
|
case .CXCursor_FunctionDecl:
|
|
var name = clang_getCursorSpelling(cursor);
|
|
BindingFunction func = new .(name.text, clang_getCursorResultType(cursor));
|
|
var count = clang_Cursor_getNumArguments(cursor);
|
|
for(int i < count)
|
|
{
|
|
var arg = clang_Cursor_getArgument(cursor, (.)i);
|
|
var argType = clang_getCursorType(arg);
|
|
var argName = clang_getCursorSpelling(arg);
|
|
func.Args.Add(new .(argName.text, argType));
|
|
}
|
|
Function.Add(func);
|
|
case .CXCursor_StructDecl:
|
|
var name = clang_getCursorSpelling(cursor);
|
|
BindingStruct strct = new .(name.text);
|
|
Structs.Add(strct);
|
|
case .CXCursor_FieldDecl:
|
|
if(Structs.Count > 0)
|
|
Structs[Structs.Count-1].Fields.Add(new .(clang_getCursorSpelling(cursor).text, clang_getCursorType(cursor)));
|
|
case .CXCursor_EnumDecl:
|
|
var name = clang_getCursorSpelling(cursor);
|
|
BindingEnum enm = new .(name.text);
|
|
Enums.Add(enm);
|
|
case .CXCursor_EnumConstantDecl:
|
|
if(Enums.Count > 0)
|
|
Enums[Enums.Count-1].Entries.Add(new .(clang_getCursorSpelling(cursor).text, (.)clang_getEnumConstantDeclValue(cursor)));
|
|
case .CXCursor_ParmDecl:
|
|
DoNothing(&cursor);
|
|
default:
|
|
Console.WriteLine(scope $"{clang_getCursorKind(cursor)} {clang_getCursorSpelling(cursor).text}");
|
|
}
|
|
|
|
/*
|
|
if(CursorHandlers.ContainsKey(clang_getCursorKind(cursor)))
|
|
CursorHandlers[clang_getCursorKind(cursor)](&cursor);
|
|
else
|
|
Console.WriteLine(scope $"{clang_getCursorKind(cursor)} {clang_getCursorSpelling(cursor).text}");
|
|
*/
|
|
|
|
|
|
return CXChildVisitResult.CXChildVisit_Recurse;
|
|
}, null );
|
|
|
|
|
|
clang_disposeTranslationUnit(*unit);
|
|
clang_disposeIndex(index);
|
|
}
|
|
|
|
public static void HandleFunctionDecl(CXCursor* cursor)
|
|
{
|
|
var name = clang_getCursorSpelling(*cursor);
|
|
BindingFunction func = new .(name.text, clang_getCursorResultType(*cursor));
|
|
|
|
var count = clang_Cursor_getNumArguments(*cursor);
|
|
for(int i < count)
|
|
{
|
|
var arg = clang_Cursor_getArgument(*cursor, (.)i);
|
|
var argType = clang_getCursorType(arg);
|
|
var argName = clang_getCursorSpelling(arg);
|
|
func.Args.Add(new .(argName.text, argType));
|
|
}
|
|
Function.Add(func);
|
|
}
|
|
|
|
public static void HandleStructDecl(CXCursor* cursor)
|
|
{
|
|
var name = clang_getCursorSpelling(*cursor);
|
|
BindingStruct strct = new .(name.text);
|
|
Structs.Add(strct);
|
|
}
|
|
|
|
public static void HandleFieldDecl(CXCursor* cursor)
|
|
{
|
|
if(Structs.Count > 0)
|
|
Structs[Structs.Count-1].Fields.Add(new .(clang_getCursorSpelling(*cursor).text, clang_getCursorType(*cursor)));
|
|
}
|
|
|
|
public static void HandleEnumDecl(CXCursor* cursor)
|
|
{
|
|
var name = clang_getCursorSpelling(*cursor);
|
|
BindingEnum enm = new .(name.text);
|
|
Enums.Add(enm);
|
|
}
|
|
|
|
public static void HandleEnumConstDecl(CXCursor* cursor)
|
|
{
|
|
if(Enums.Count > 0)
|
|
{
|
|
Enums[Enums.Count-1].Entries.Add(new .(clang_getCursorSpelling(*cursor).text, (.)clang_getEnumConstantDeclValue(*cursor)));
|
|
}
|
|
}
|
|
|
|
private static void DoNothing(CXCursor* cursor) {}
|
|
|
|
|
|
///Generate the actual file strings and try to write them according to the input parameter and the options
|
|
public static Result<void> Generate(StringView pOutputDir = "")
|
|
{
|
|
if(pOutputDir == "")
|
|
return .Err;
|
|
|
|
String toWrite = new .(scope $"""
|
|
namespace {Binding.Options.Namespace};
|
|
static
|
|
\{\n
|
|
""");
|
|
defer delete toWrite;
|
|
|
|
for(var i in Function)
|
|
i.ToBeef(toWrite);
|
|
for(var i in Structs)
|
|
i.ToBeef(toWrite);
|
|
for(var i in Enums)
|
|
i.ToBeef(toWrite);
|
|
toWrite.Append("\n}");
|
|
|
|
return System.IO.File.WriteAllText(pOutputDir, toWrite);
|
|
}
|
|
|
|
|
|
} |