diff options
| author | Raymaekers Luca <luca@spacehb.net> | 2025-10-24 12:58:52 +0200 |
|---|---|---|
| committer | Raymaekers Luca <luca@spacehb.net> | 2025-10-24 12:58:52 +0200 |
| commit | 856fd58549e5bf50e800a665f9deb27d967df2fb (patch) | |
| tree | 6950210e5ae3618b501a7045f10f8fc06dd903df /src/sim86_meta.c | |
| parent | d8b3ca9d02377cf04a09e0f518a3385b7324bc4d (diff) | |
checkpoint
Diffstat (limited to 'src/sim86_meta.c')
| -rw-r--r-- | src/sim86_meta.c | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/src/sim86_meta.c b/src/sim86_meta.c new file mode 100644 index 0000000..f5046a7 --- /dev/null +++ b/src/sim86_meta.c @@ -0,0 +1,173 @@ +#if __clang__ +# define COMPILER_CLANG 1 +#elif _MSC_VER +# define COMPILER_MSVC 1 +#elif __GNUC__ +# define COMPILER_GNU 1 +#endif + +#if defined(COMPILER_GNU) +# define PUSH_WARNINGS \ +_Pragma("GCC diagnostic push") \ +_Pragma("GCC diagnostic ignored \"-Weverything\"") +# define POP_WARNINGS \ +_Pragma("GCC diagnostic pop") +#elif defined(COMPILER_CLANG) +# define PUSH_WARNINGS \ +_Pragma("clang diagnostic push") \ +_Pragma("clang diagnostic ignored \"-Weverything\"") +# define POP_WARNINGS \ +_Pragma("clang diagnostic pop") +#else +# define PUSH_WARNINGS \ +_Pragma("message \"No compatible compiler found\"") +# define POP_WARNINGS +#endif + +PUSH_WARNINGS +#include "md.h" +#include "md.c" +POP_WARNINGS + +#define Assert(Expression) if(!(Expression)) { __asm__ volatile("int3"); } + +static MD_Arena *Arena = 0; + +int main(int ArgsCount, char *Args[]) +{ + if(ArgsCount > 1) + { + Arena = MD_ArenaAlloc(); + MD_String8 FileName = MD_S8CString(Args[1]); + MD_ParseResult Parse = MD_ParseWholeFile(Arena, FileName); + + // print metadesk errors + for(MD_Message *Message = Parse.errors.first; + Message != 0; + Message = Message->next) + { + MD_CodeLoc code_loc = MD_CodeLocFromNode(Message->node); + MD_PrintMessage(stdout, code_loc, Message->kind, Message->string); + } + + if(Parse.errors.max_message_kind < MD_MessageKind_Error) + { + MD_Node *Root = Parse.node->first_child; + + MD_String8List Stream = {0}; + for(MD_EachNode(Node, Root)) + { + + // 1. If we find a table_gen_enum_flags tag + if(MD_NodeHasTag(Node, MD_S8Lit("table_gen_enum_flags"), 0)) + { + MD_String8 TableName = MD_NodeAtIndex(Node->first_tag->first_child, 0)->string; + MD_String8 MemberName = MD_NodeAtIndex(Node->first_tag->first_child, 1)->string; + + // 2. Find the table in the first argument + // TODO(luca): Check for not nil otherwise print error + MD_Node *TableNode = MD_FirstNodeWithString(Root, TableName, 0); + MD_Node *TableTag = MD_TagFromString(TableNode, MD_S8Lit("table"), 0); + + // TODO(luca): Check for not nil otherwise print error + MD_Node *MemberNode = MD_FirstNodeWithString(TableTag->first_child, MemberName, 0); + int MemberIndex = MD_IndexFromNode(MemberNode); + + // Header + MD_S8ListPushFmt(Arena, &Stream, "enum %S\n{\n", Node->string); + + int MemberCount = 0; + for(MD_EachNode(Member, TableNode->first_child)) + { + // 3. Use the member of it in the second argument + MD_Node *MemberNode = MD_NodeAtIndex(Member->first_child, MemberIndex); + + // 4. For each member in the table + // 1. Create an enum where you create flags in the form + // Flag_None 0 << 1 + // Flag_First 1 << 1 + // ... + MD_S8ListPushFmt(Arena, &Stream, " Flag_%S = (1 << %d),\n", + MemberNode->string, MemberCount); + MemberCount++; + } + + MD_S8ListPush(Arena, &Stream, MD_S8Lit("};\n\n")); + } + + // 1. If we find a table_gen_data tag + if(MD_NodeHasTag(Node, MD_S8Lit("table_gen_data"), 0)) + { + MD_String8 TableName = MD_NodeAtIndex(Node->first_tag->first_child, 0)->string; + MD_String8 Type = MD_NodeAtIndex(Node->first_tag->first_child, 1)->string; + MD_String8 MemberName = MD_NodeAtIndex(Node->first_tag->first_child, 2)->string; + + MD_Node *Table = MD_FirstNodeWithString(Root, TableName, 0); + + MD_Node *TableTag = MD_TagFromString(Table, MD_S8Lit("table"), 0); + MD_Node *MemberNode = MD_FirstNodeWithString(TableTag->first_child, MemberName, 0); + int MemberIndex = MD_IndexFromNode(MemberNode); + + int MemberCount = MD_ChildCountFromNode(Table); + + MD_S8ListPushFmt(Arena, &Stream, "int %S_count = %d;\n", Node->string, MemberCount); + // Header + MD_S8ListPushFmt(Arena, &Stream, "%S%S[] =\n{\n", Type, Node->string); + + for(MD_EachNode(Member, Table->first_child)) + { + MD_Node *ValueNode = MD_NodeAtIndex(Member->first_child, MemberIndex); + MD_S8ListPushFmt(Arena, &Stream, " %S,\n", ValueNode->raw_string); + } + + MD_S8ListPush(Arena, &Stream, MD_S8Lit("};\n\n")); + } + + if(MD_NodeHasTag(Node, MD_S8Lit("table_gen_enum"), 0)) + { + // Header + MD_S8ListPushFmt(Arena, &Stream, "enum %S\n{\n", Node->string); + + for(MD_EachNode(Member, Node->first_child)) + { + if(MD_NodeHasTag(Member, MD_S8Lit("expand"), 0)) + { + MD_Node *Tag = MD_TagFromString(Member, MD_S8Lit("expand"), 0); + MD_String8 TableName = MD_NodeAtIndex(Tag->first_child, 0)->string; + MD_Node *Table = MD_FirstNodeWithString(Root, TableName, 0); + + // 2. For each node in the table + for(MD_EachNode(TableMember, Table->first_child)) + { + // 3. Evaluate the expression + // 1. Search Member->string for a '$' sign + // 2. If it's followed by a dot and a name, parse that name. + // 3. Store the name and use it to lookup the members + // TODO(luca): + + + Member->string; + } + + } + else + { + MD_S8ListPush(Arena, &Stream, Member->string); + MD_S8ListPush(Arena, &Stream, MD_S8Lit("\n")); + } + + } + + MD_S8ListPush(Arena, &Stream, MD_S8Lit("};\n")); + } + + // MD_PrintDebugDumpFromNode(stderr, Node, MD_GenerateFlags_All); + } + + MD_String8 Str = MD_S8ListJoin(Arena, Stream, 0); + fwrite(Str.str, 1, Str.size, stdout); + } + + } + return 0; +}
\ No newline at end of file |
