Lumenarium/meta/gs_meta_generator.h

164 lines
4.3 KiB
C
Raw Normal View History

2019-10-30 14:28:02 +00:00
#define CODE_SIZE 256
struct generated_code
{
s32 Used;
char* Code;
generated_code* Next;
};
internal void
InitGeneratedCode (generated_code* Code)
{
Code->Used = 0;
Code->Code = (char*)malloc(sizeof(char) * CODE_SIZE);
*(Code->Code + CODE_SIZE - 1) = 0;
Code->Next = 0;
}
// NOTE(Peter): This ONLY supports printing strings into the buffer at the moment
static void
PrintF_ (
generated_code* Dest,
char* Format,
va_list Args
)
{
if (!Dest->Code) {
InitGeneratedCode(Dest);
}
char* Src = Format;
char* Dst = Dest->Code + Dest->Used;
while (*Src && (Dst - Dest->Code) < CODE_SIZE)
{
if (*Src == '\\' && *(Src + 1) && *(Src + 1) == '%')
{
*Src++;
*Dst++ = *Src++;
}
else if (*Src == '%')
{
Src++;
if (*Src == 's')
{
Src++;
s32 StringLength = va_arg(Args, s32);
char* String = va_arg(Args, char*);
char* C = String;
while(*C && StringLength > 0 && (Dst - Dest->Code) < CODE_SIZE)
{
StringLength--;
*Dst++ = *C++;
}
}
else
{
InvalidCodePath;
}
}
else
{
*Dst++ = *Src++;
}
}
if (!*Dst && *Src)
{
Dest->Next = (generated_code*)malloc(sizeof(generated_code));
InitGeneratedCode(Dest->Next);
PrintF_(Dest->Next, Src, Args);
}
if (*Dst && !*Src) { *Dst = 0; }
Dest->Used = (s32)(Dst - Dest->Code);
}
static void
PrintF (
generated_code* Dest,
char* Format,
...)
{
va_list Args;
va_start(Args, Format);
PrintF_(Dest, Format, Args);
va_end(Args);
}
static void
PrintCode (generated_code* Code)
{
GS_PRINTF(Code->Code);
if (Code->Next) { PrintCode(Code->Next); }
}
static void
GenerateFieldCode (ast_field_declaration* Field, string_buffer* CodeBuffer, string_partition* Partition,
s32 IndentLevel, char* Terminator)
{
for (s32 i = 0; i < IndentLevel; i++)
{
PrintStringBufferFormat(CodeBuffer, Partition, " ");
}
PrintStringBufferFormat(CodeBuffer, Partition, "%s%s %s%s",
Field->TypeLength, Field->Type,
(Field->TypePointer ? 1 : 0), (Field->TypePointer ? "*" : ""),
Field->NameLength, Field->Name,
(Field->TypeArray ? 2 : 0), (Field->TypeArray ? "[]" : ""));
PrintStringBufferFormat(CodeBuffer, Partition, Terminator);
}
static string_buffer*
GenerateStructCode (ast_node* Struct, string_partition* StringPartition)
{
Assert(Struct->Type == ASTNode_StructDeclaration);
string_buffer* StructCodeBuffer = GetStringBuffer(StringPartition);
PrintStringBufferFormat(StructCodeBuffer, StringPartition, "struct %s\n{\n",
Struct->StructDeclaration.NameLength, Struct->StructDeclaration.Name);
ast_field_declaration* Member = Struct->StructDeclaration.Members;
while (Member)
{
GenerateFieldCode(Member, StructCodeBuffer, StringPartition, 1, ";\n");
Member = Member->Next;
}
PrintStringBufferFormat(StructCodeBuffer, StringPartition, "}\n\n");
return StructCodeBuffer;
}
static string_buffer*
GenerateFunctionDeclaration (ast_node* Function, string_partition* Partition)
{
Assert(Function->Type == ASTNode_FunctionDeclaration);
ast_function_declaration* FuncDecl = &Function->FunctionDeclaration;
string_buffer* FunctionDeclBuffer = GetStringBuffer(Partition);
PrintStringBufferFormat(FunctionDeclBuffer, Partition, "%s %s (",
FuncDecl->ReturnTypeLength, FuncDecl->ReturnType,
FuncDecl->NameLength, FuncDecl->Name);
ast_field_declaration* Param = FuncDecl->Arguments;
while (Param)
{
GenerateFieldCode(Param, FunctionDeclBuffer, Partition, 0, "");
if (Param->Next)
{
PrintStringBufferFormat(FunctionDeclBuffer, Partition, ", ");
}
Param = Param->Next;
}
PrintStringBufferFormat(FunctionDeclBuffer, Partition, ")\n");
return FunctionDeclBuffer;
}