164 lines
4.3 KiB
C
164 lines
4.3 KiB
C
|
#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;
|
||
|
}
|