added most parsing

This commit is contained in:
Booklordofthedings 2024-05-24 10:27:28 +02:00
parent 9186c0b444
commit cf1fc0e042
8 changed files with 1102 additions and 33 deletions

View file

@ -9,9 +9,20 @@ 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;
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),
public static void Bind(ref String[] pArgs, BindingOptions pOptions)
} ~ delete _;
public static void Bind(ref String[] pArgs)
{
CXIndex index = clang_createIndex(0, 0);
CXTranslationUnit* unit;
@ -28,33 +39,11 @@ class Binding
clang_visitChildren(
cursor,
(cursor, parent, client_data) => {
if(clang_getCursorKind(cursor) == .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);
}
else if(clang_getCursorKind(cursor) == .CXCursor_StructDecl)
{
var name = clang_getCursorSpelling(cursor);
BindingStruct strct = new .(name.text);
Structs.Add(strct);
}
else if(clang_getCursorKind(cursor) == .CXCursor_FieldDecl)
{
if(Structs.Count > 0)
Structs[Structs.Count-1].Fields.Add(new .(clang_getCursorSpelling(cursor).text, clang_getCursorType(cursor)));
}
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;
@ -65,13 +54,64 @@ class Binding
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 .();
String toWrite = new .(scope $"""
namespace {Binding.Options.Namespace};
static
\{\n
""");
defer delete toWrite;
for(var i in Function)
@ -80,6 +120,7 @@ class Binding
i.ToBeef(toWrite);
for(var i in Enums)
i.ToBeef(toWrite);
toWrite.Append("\n}");
return System.IO.File.WriteAllText(pOutputDir, toWrite);
}

View file

@ -14,23 +14,30 @@ class BindingEnum
public this(StringView pName, c_int pValue)
{
Name = new .(pName);
if(Binding.Options.LowercaseEnums)
Name.ToLower();
Value = pValue;
}
}
public String Name ~ delete _;
public List<BindingEnumEntry> Entries = new .() ~ delete _;
public List<BindingEnumEntry> Entries = new .() ~ DeleteContainerAndItems!(_);
public this(StringView pName)
{
Name = new .(pName);
if(Name.StartsWith(Binding.Options.Namespace) && Name.Length > Binding.Options.Namespace.Length)
Name.Remove(0, Binding.Options.Namespace.Length);
}
///Generate the beef representation of an enum
public void ToBeef(String pBuffer)
{
if(Binding.Options.RemoveEnumStart)
CalcCommonDenominator();
pBuffer.Append(scope $"""
[AllowDublicates]
[AllowDuplicates]
public enum {Name}
\{\n
""");
@ -38,4 +45,33 @@ class BindingEnum
pBuffer.Append(scope $"{i.Name} = {i.Value},\n");
pBuffer.Append("}\n");
}
private void CalcCommonDenominator()
{
if(Entries.Count < 2)
return; //Otherwise we remove too much
StringView? denominator = null;
for(var i in Entries)
{
if(denominator == null)
denominator = i.Name;
else
{
for(int j = 0; j < i.Name.Length && j < denominator.Value.Length; j++)
{
if(denominator.Value[j] == i.Name[j])
continue;
else
{
denominator = i.Name.Substring(0, j);
}
}
}
}
for(var i in Entries)
i.Name.Remove(0, denominator.Value.Length);
}
}

View file

@ -15,6 +15,9 @@ class BindingFunction
{
Name = new .(pName);
Type = new .(pType);
if(Name.StartsWith(Binding.Options.Namespace) && Name.Length > Binding.Options.Namespace.Length)
Name.Remove(0, Binding.Options.Namespace.Length);
}
}
@ -26,6 +29,9 @@ class BindingFunction
{
Name = new .(pName);
Output = new .(pOutput);
if(Name.StartsWith(Binding.Options.Namespace) && Name.Length > Binding.Options.Namespace.Length)
Name.Remove(0, Binding.Options.Namespace.Length);
}
public void ToBeef(String pBuffer)

View file

@ -1,5 +1,24 @@
namespace Caa;
using System;
class BindingOptions
{
/*
This handles the C way of namespacing
If something has the namespace infront of it we remove it and incase of functions, generate the linkname property
*/
private String _Namespace = new .("") ~ delete _;
public String Namespace
{
get => _Namespace;
set
{
delete _Namespace;
_Namespace = new .(value);
}
};
public bool RemoveEnumStart = true;
public bool LowercaseEnums = false;
}

View file

@ -15,6 +15,9 @@ class BindingStruct
{
Name = new .(pName);
Type = new .(pType);
if(Name.StartsWith(Binding.Options.Namespace) && Name.Length > Binding.Options.Namespace.Length)
Name.Remove(0, Binding.Options.Namespace.Length);
}
}
@ -25,6 +28,9 @@ class BindingStruct
public this(StringView pName)
{
Name = new .(pName);
if(Name.StartsWith(Binding.Options.Namespace) && Name.Length > Binding.Options.Namespace.Length)
Name.Remove(0, Binding.Options.Namespace.Length);
}
public void ToBeef(String pBuffer)

View file

@ -42,5 +42,10 @@ class BindingType
TypeName.Replace(" ", "");
//TODO: bools exist and we should really be able to autoparse those
if(TypeName.StartsWith(Binding.Options.Namespace) && TypeName.Length > Binding.Options.Namespace.Length)
TypeName.Remove(0, Binding.Options.Namespace.Length);
if(TypeName.Length > Binding.Options.Namespace.Length)
TypeName.Replace(Binding.Options.Namespace, "");
}
}

View file

@ -44,8 +44,7 @@ class Program
arguments[i] = arg;
}
BindingOptions options = scope .();
Binding.Bind(ref arguments, options);
Binding.Bind(ref arguments);
Console.WriteLine("Finished analyzing the file now please input your output directory/file");
String output = scope .();