mirror of
https://github.com/Ed94/metadesk.git
synced 2026-06-15 08:42:23 -07:00
[examples] generate types and function decarations
This commit is contained in:
+3
-5
@@ -10,14 +10,12 @@ build_path=$root_path/build
|
||||
examps=$root_path/examples
|
||||
|
||||
echo ~~~ Running Type Metadata Example ~~~
|
||||
cd $build_path
|
||||
./type_metadata.exe $examps/type_metadata/types.mdesk
|
||||
cd $examps/type_metadata/generated
|
||||
$build_path/type_metadata.exe $examps/type_metadata/types.mdesk
|
||||
echo
|
||||
|
||||
echo ~~~ Running Error Generation Example ~~~
|
||||
cd $build_path
|
||||
./user_errors.exe $examps/user_errors/user_errors.mdesk
|
||||
echo
|
||||
$build_path/user_errors.exe $examps/user_errors/user_errors.mdesk
|
||||
|
||||
###### Restore Path ###########################################################
|
||||
cd $og_path
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
generated/*
|
||||
@@ -0,0 +1,31 @@
|
||||
#if !defined(META_TYEPS_H)
|
||||
#define META_TYEPS_H
|
||||
typedef struct Circle Circle;
|
||||
struct Circle
|
||||
{
|
||||
F32 r;
|
||||
V2F32 pos;
|
||||
};
|
||||
typedef struct RoundedSegment RoundedSegment;
|
||||
struct RoundedSegment
|
||||
{
|
||||
F32 r;
|
||||
V2F32 p1;
|
||||
V2F32 p2;
|
||||
};
|
||||
typedef struct RoundedPolygon RoundedPolygon;
|
||||
struct RoundedPolygon
|
||||
{
|
||||
F32 r;
|
||||
U32 count;
|
||||
V2F32 *p;
|
||||
};
|
||||
enum Shape
|
||||
{
|
||||
Shape_Circle = 1,
|
||||
Shape_Segment = 2,
|
||||
Shape_Polygon = 3,
|
||||
};
|
||||
TypeInfo* type_info_from_shape(Shape v);
|
||||
U32 max_slot_from_shape(Shape v);
|
||||
#endif // META_TYEPS_H
|
||||
@@ -40,7 +40,6 @@ struct TypeInfo
|
||||
struct TypeEnumerant *first_enumerant;
|
||||
struct TypeEnumerant *last_enumerant;
|
||||
int enumerant_count;
|
||||
|
||||
};
|
||||
|
||||
typedef struct TypeMember TypeMember;
|
||||
@@ -49,6 +48,7 @@ struct TypeMember
|
||||
TypeMember *next;
|
||||
MD_Node *node;
|
||||
TypeInfo *type;
|
||||
MD_Node *array_count;
|
||||
};
|
||||
|
||||
typedef struct TypeEnumerant TypeEnumerant;
|
||||
@@ -64,6 +64,13 @@ struct MapInfo
|
||||
{
|
||||
MapInfo *next;
|
||||
MD_Node *node;
|
||||
|
||||
MD_Node *in;
|
||||
MD_Node *out;
|
||||
|
||||
int is_complete;
|
||||
MD_Node *default_val;
|
||||
MD_Node *auto_val;
|
||||
};
|
||||
|
||||
|
||||
@@ -78,8 +85,94 @@ MapInfo *last_map = 0;
|
||||
MD_Map map_map = {0};
|
||||
|
||||
|
||||
//~ feature generators ////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
generate_type_definitions(FILE *out, TypeInfo *first_type)
|
||||
{
|
||||
for (TypeInfo *type = first_type;
|
||||
type != 0;
|
||||
type = type->next)
|
||||
{
|
||||
switch (type->kind)
|
||||
{
|
||||
default:break;
|
||||
|
||||
case TypeKind_Struct:
|
||||
{
|
||||
MD_String8 struct_name = type->node->string;
|
||||
fprintf(out, "typedef struct %.*s %.*s;\n", MD_S8VArg(struct_name), MD_S8VArg(struct_name));
|
||||
fprintf(out, "struct %.*s\n", MD_S8VArg(struct_name));
|
||||
fprintf(out, "{\n");
|
||||
for (TypeMember *member = type->first_member;
|
||||
member != 0;
|
||||
member = member->next)
|
||||
{
|
||||
MD_String8 type_name = member->type->node->string;
|
||||
MD_String8 member_name = member->node->string;
|
||||
int is_array = (!MD_NodeIsNil(member->array_count));
|
||||
if (is_array)
|
||||
{
|
||||
fprintf(out, "%.*s *%.*s;\n", MD_S8VArg(type_name), MD_S8VArg(member_name));
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(out, "%.*s %.*s;\n", MD_S8VArg(type_name), MD_S8VArg(member_name));
|
||||
}
|
||||
}
|
||||
fprintf(out, "};\n");
|
||||
}break;
|
||||
|
||||
case TypeKind_Enum:
|
||||
{
|
||||
MD_String8 enum_name = type->node->string;
|
||||
fprintf(out, "enum %.*s\n", MD_S8VArg(enum_name));
|
||||
fprintf(out, "{\n");
|
||||
for (TypeEnumerant *enumerant = type->first_enumerant;
|
||||
enumerant != 0;
|
||||
enumerant = enumerant->next)
|
||||
{
|
||||
MD_String8 member_name = enumerant->node->string;
|
||||
fprintf(out, "%.*s_%.*s = %d,\n",
|
||||
MD_S8VArg(enum_name), MD_S8VArg(member_name), enumerant->value);
|
||||
}
|
||||
fprintf(out, "};\n");
|
||||
}break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
generate_function_declarations_from_maps(FILE *out, MapInfo *first_map)
|
||||
{
|
||||
for (MapInfo *map = first_map;
|
||||
map != 0;
|
||||
map = map->next)
|
||||
{
|
||||
MD_Node *node = map->node;
|
||||
|
||||
MD_String8 in_type = map->in->string;
|
||||
MD_String8 out_type = map->out->string;
|
||||
if (MD_S8Match(out_type, MD_S8Lit("$Type"), 0))
|
||||
{
|
||||
out_type = MD_S8Lit("TypeInfo*");
|
||||
}
|
||||
|
||||
fprintf(out, "%.*s %.*s(%.*s v);\n",
|
||||
MD_S8VArg(out_type), MD_S8VArg(node->string), MD_S8VArg(in_type));
|
||||
}
|
||||
}
|
||||
|
||||
//~ main //////////////////////////////////////////////////////////////////////
|
||||
|
||||
MD_Node*
|
||||
get_md_child_value(MD_Node *parent, MD_String8 child_name)
|
||||
{
|
||||
MD_Node *child = MD_ChildFromString(parent, child_name, 0);
|
||||
MD_Node *result = child->first_child;
|
||||
return(result);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@@ -162,12 +255,37 @@ main(int argc, char **argv)
|
||||
}
|
||||
|
||||
// gather map
|
||||
MD_Node *map_tag = MD_TagFromString(node, MD_S8Lit("map"), 0);
|
||||
MD_Node *map_tag = MD_TagFromString(node, MD_S8Lit("map"), 0);
|
||||
|
||||
if (!MD_NodeIsNil(map_tag))
|
||||
{
|
||||
MapInfo *map_info = MD_PushArray(arena, MapInfo, 1);
|
||||
// NOTE we could use an expression parser here to make this fancier
|
||||
// and check for the 'In -> Out' semicolon delimited syntax more
|
||||
// carefully, this isn't checking it very rigorously. But there are
|
||||
// no other cases we need to expect so far so being a bit sloppy
|
||||
// buys us a lot of simplicity.
|
||||
MD_Node *in = map_tag->first_child;
|
||||
MD_Node *arrow = in->next;
|
||||
MD_Node *out = arrow->next;
|
||||
|
||||
if (!MD_S8Match(arrow->string, MD_S8Lit("->"), 0) ||
|
||||
MD_NodeIsNil(out))
|
||||
{
|
||||
// TODO(allen): error map type
|
||||
}
|
||||
|
||||
int is_complete = MD_NodeHasChild(map_tag, MD_S8Lit("complete"), 0);
|
||||
|
||||
MD_Node *default_val = get_md_child_value(map_tag, MD_S8Lit("default"));
|
||||
MD_Node *auto_val = get_md_child_value(map_tag, MD_S8Lit("auto"));
|
||||
|
||||
MapInfo *map_info = MD_PushArrayZero(arena, MapInfo, 1);
|
||||
map_info->node = node;
|
||||
map_info->in = in;
|
||||
map_info->out = out;
|
||||
map_info->is_complete = is_complete;
|
||||
map_info->default_val = default_val;
|
||||
map_info->auto_val = auto_val;
|
||||
|
||||
MD_QueuePush(first_map, last_map, map_info);
|
||||
MD_MapInsert(arena, &map_map, MD_MapKeyStr(node->string), map_info);
|
||||
@@ -224,11 +342,18 @@ main(int argc, char **argv)
|
||||
{
|
||||
TypeInfo *type_info = (TypeInfo*)type_info_slot->val;
|
||||
|
||||
// TODO(allen): handle the array tag
|
||||
MD_Node *array_count = MD_NilNode();
|
||||
MD_Node *array_tag = MD_TagFromString(type_name_node, MD_S8Lit("array"), 0);
|
||||
if (!MD_NodeIsNil(array_tag))
|
||||
{
|
||||
array_count = array_tag->first_child;
|
||||
// TODO(allen): error if array_count is nil
|
||||
}
|
||||
|
||||
TypeMember *member = MD_PushArray(arena, TypeMember, 1);
|
||||
member->node = member_node;
|
||||
member->type = type_info;
|
||||
member->array_count = array_count;
|
||||
MD_QueuePush(first_member, last_member, member);
|
||||
member_count += 1;
|
||||
}
|
||||
@@ -313,17 +438,42 @@ main(int argc, char **argv)
|
||||
}
|
||||
|
||||
// TODO check maps & build case lists
|
||||
// TODO generate type definitions
|
||||
// TODO generate function declarations
|
||||
// TODO generate metadata tables
|
||||
// TODO generate function definitions
|
||||
|
||||
// generate meta types header
|
||||
{
|
||||
FILE *h = fopen("meta_types.h", "wb");
|
||||
fprintf(h, "#if !defined(META_TYEPS_H)\n");
|
||||
fprintf(h, "#define META_TYEPS_H\n");
|
||||
|
||||
// generate type definitions
|
||||
generate_type_definitions(h, first_type);
|
||||
|
||||
// generate function declarations
|
||||
generate_function_declarations_from_maps(h, first_map);
|
||||
|
||||
fprintf(h, "#endif // META_TYEPS_H\n");
|
||||
fclose(h);
|
||||
}
|
||||
|
||||
// generate meta types code
|
||||
{
|
||||
// open output file
|
||||
FILE *c = fopen("meta_types.c", "wb");
|
||||
|
||||
// TODO generate metadata tables
|
||||
// TODO generate function definitions
|
||||
|
||||
// close output file
|
||||
fclose(c);
|
||||
}
|
||||
|
||||
// print state
|
||||
for (TypeInfo *type = first_type;
|
||||
type != 0;
|
||||
type = type->next){
|
||||
char *kind_string = "ERROR";
|
||||
switch (type->kind){
|
||||
switch (type->kind)
|
||||
{
|
||||
default:break;
|
||||
case TypeKind_Basic: kind_string = "basic"; break;
|
||||
case TypeKind_Struct: kind_string = "struct"; break;
|
||||
|
||||
@@ -45,7 +45,6 @@ type_info_from_shape:
|
||||
Polygon -> RoundedPolygon,
|
||||
}
|
||||
|
||||
|
||||
@map(Shape -> U32; default: 0; auto: 64)
|
||||
max_slot_from_shape:
|
||||
{
|
||||
|
||||
+2
-2
@@ -82,8 +82,8 @@ command_list =
|
||||
},
|
||||
{
|
||||
.name = "run_examples",
|
||||
.out = "*compilation*",
|
||||
.footer_panel = true,
|
||||
.out = "*run*",
|
||||
.footer_panel = false,
|
||||
.save_dirty_files = true,
|
||||
.cursor_at_end = false,
|
||||
.cmd =
|
||||
|
||||
+8
-2
@@ -3005,9 +3005,15 @@ MD_TagArgFromString(MD_Node *node, MD_String8 tag_string, MD_MatchFlags tag_str_
|
||||
}
|
||||
|
||||
MD_FUNCTION MD_b32
|
||||
MD_NodeHasTag(MD_Node *node, MD_String8 tag_string, MD_MatchFlags flags)
|
||||
MD_NodeHasChild(MD_Node *node, MD_String8 string, MD_MatchFlags flags)
|
||||
{
|
||||
return !MD_NodeIsNil(MD_TagFromString(node, tag_string, flags));
|
||||
return !MD_NodeIsNil(MD_ChildFromString(node, string, flags));
|
||||
}
|
||||
|
||||
MD_FUNCTION MD_b32
|
||||
MD_NodeHasTag(MD_Node *node, MD_String8 string, MD_MatchFlags flags)
|
||||
{
|
||||
return !MD_NodeIsNil(MD_TagFromString(node, string, flags));
|
||||
}
|
||||
|
||||
MD_FUNCTION MD_i64
|
||||
|
||||
+2
-1
@@ -1087,7 +1087,8 @@ MD_FUNCTION MD_Node * MD_ChildFromIndex(MD_Node *node, int n);
|
||||
MD_FUNCTION MD_Node * MD_TagFromIndex(MD_Node *node, int n);
|
||||
MD_FUNCTION MD_Node * MD_TagArgFromIndex(MD_Node *node, MD_String8 tag_string, MD_MatchFlags flags, int n);
|
||||
MD_FUNCTION MD_Node * MD_TagArgFromString(MD_Node *node, MD_String8 tag_string, MD_MatchFlags tag_str_flags, MD_String8 arg_string, MD_MatchFlags arg_str_flags);
|
||||
MD_FUNCTION MD_b32 MD_NodeHasTag(MD_Node *node, MD_String8 tag_string, MD_MatchFlags flags);
|
||||
MD_FUNCTION MD_b32 MD_NodeHasChild(MD_Node *node, MD_String8 string, MD_MatchFlags flags);
|
||||
MD_FUNCTION MD_b32 MD_NodeHasTag(MD_Node *node, MD_String8 string, MD_MatchFlags flags);
|
||||
MD_FUNCTION MD_i64 MD_ChildCountFromNode(MD_Node *node);
|
||||
MD_FUNCTION MD_i64 MD_TagCountFromNode(MD_Node *node);
|
||||
MD_FUNCTION MD_Node * MD_ResolveNodeFromReference(MD_Node *node);
|
||||
|
||||
Reference in New Issue
Block a user