[examples] generate types and function decarations

This commit is contained in:
Allen Webster
2021-09-24 16:41:26 -07:00
parent 1644c02d47
commit cdb170bb86
9 changed files with 205 additions and 21 deletions
+3 -5
View File
@@ -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
View File
@@ -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
+159 -9
View File
@@ -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;
-1
View File
@@ -45,7 +45,6 @@ type_info_from_shape:
Polygon -> RoundedPolygon,
}
@map(Shape -> U32; default: 0; auto: 64)
max_slot_from_shape:
{
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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);