mirror of
https://github.com/Ed94/metadesk.git
synced 2026-08-07 08:08:48 +00:00
[examples] more type metadata commentary; write some usage code for the generated type info
This commit is contained in:
@@ -30,12 +30,20 @@ $build_path/type_metadata.exe $examps_path/type_metadata/types.mdesk
|
|||||||
echo
|
echo
|
||||||
|
|
||||||
if [ -f $examps_path/type_metadata/generated/meta_types.h ]; then
|
if [ -f $examps_path/type_metadata/generated/meta_types.h ]; then
|
||||||
echo ~~~ Building Program ~~~
|
echo ~~~ Building Final Program ~~~
|
||||||
$bin_path/bld_core.sh unit type_info $examps/type_metadata/type_info_final_program.c
|
$bin_path/bld_core.sh unit type_info_final $examps/type_metadata/type_info_final_program.c
|
||||||
else
|
|
||||||
echo !!! Skipping Program !!!
|
|
||||||
fi
|
|
||||||
echo
|
echo
|
||||||
|
|
||||||
|
echo ~~~ Running Final Program ~~~
|
||||||
|
$build_path/type_info_final
|
||||||
|
echo
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
echo !!! Skipping Final Program !!!
|
||||||
|
echo
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
###### Restore Path ###########################################################
|
###### Restore Path ###########################################################
|
||||||
cd $og_path
|
cd $og_path
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// generated by W:/metadesk/examples/type_metadata/type_metadata.c:837
|
// generated by W:/metadesk/examples/type_metadata/type_metadata.c:874
|
||||||
TypeInfoMember Circle_members[2] = {
|
TypeInfoMember Circle_members[2] = {
|
||||||
{"r", 1, -1, &F32_type_info},
|
{"r", 1, -1, &F32_type_info},
|
||||||
{"pos", 3, -1, &V2F32_type_info},
|
{"pos", 3, -1, &V2F32_type_info},
|
||||||
@@ -14,14 +14,14 @@ TypeInfoMember RoundedPolygon_members[3] = {
|
|||||||
{"p", 1, 1, &V2F32_type_info},
|
{"p", 1, 1, &V2F32_type_info},
|
||||||
};
|
};
|
||||||
|
|
||||||
// generated by W:/metadesk/examples/type_metadata/type_metadata.c:876
|
// generated by W:/metadesk/examples/type_metadata/type_metadata.c:913
|
||||||
TypeInfoEnumerant Shape_members[3] = {
|
TypeInfoEnumerant Shape_members[3] = {
|
||||||
{"Circle", 6, 1},
|
{"Circle", 6, 1},
|
||||||
{"Segment", 7, 2},
|
{"Segment", 7, 2},
|
||||||
{"Polygon", 7, 3},
|
{"Polygon", 7, 3},
|
||||||
};
|
};
|
||||||
|
|
||||||
// generated by W:/metadesk/examples/type_metadata/type_metadata.c:912
|
// generated by W:/metadesk/examples/type_metadata/type_metadata.c:949
|
||||||
TypeInfo U32_type_info = {TypeKind_Basic, "U32", 3, 4, 0, 0};
|
TypeInfo U32_type_info = {TypeKind_Basic, "U32", 3, 4, 0, 0};
|
||||||
TypeInfo F32_type_info = {TypeKind_Basic, "F32", 3, 4, 0, 0};
|
TypeInfo F32_type_info = {TypeKind_Basic, "F32", 3, 4, 0, 0};
|
||||||
TypeInfo V2F32_type_info = {TypeKind_Basic, "V2F32", 5, 8, 0, 0};
|
TypeInfo V2F32_type_info = {TypeKind_Basic, "V2F32", 5, 8, 0, 0};
|
||||||
@@ -30,7 +30,7 @@ TypeInfo RoundedSegment_type_info = {TypeKind_Struct, "RoundedSegment", 14, 3, R
|
|||||||
TypeInfo RoundedPolygon_type_info = {TypeKind_Struct, "RoundedPolygon", 14, 3, RoundedPolygon_members, 0};
|
TypeInfo RoundedPolygon_type_info = {TypeKind_Struct, "RoundedPolygon", 14, 3, RoundedPolygon_members, 0};
|
||||||
TypeInfo Shape_type_info = {TypeKind_Enum, "Shape", 5, 3, Shape_members, &U32_type_info};
|
TypeInfo Shape_type_info = {TypeKind_Enum, "Shape", 5, 3, Shape_members, &U32_type_info};
|
||||||
|
|
||||||
// generated by W:/metadesk/examples/type_metadata/type_metadata.c:972
|
// generated by W:/metadesk/examples/type_metadata/type_metadata.c:1009
|
||||||
TypeInfo*
|
TypeInfo*
|
||||||
type_info_from_shape(Shape v)
|
type_info_from_shape(Shape v)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#if !defined(META_TYPES_H)
|
#if !defined(META_TYPES_H)
|
||||||
#define META_TYPES_H
|
#define META_TYPES_H
|
||||||
// generated by W:/metadesk/examples/type_metadata/type_metadata.c:714
|
// generated by W:/metadesk/examples/type_metadata/type_metadata.c:751
|
||||||
typedef struct Circle Circle;
|
typedef struct Circle Circle;
|
||||||
struct Circle
|
struct Circle
|
||||||
{
|
{
|
||||||
@@ -29,11 +29,11 @@ Shape_Segment = 2,
|
|||||||
Shape_Polygon = 3,
|
Shape_Polygon = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
// generated by W:/metadesk/examples/type_metadata/type_metadata.c:798
|
// generated by W:/metadesk/examples/type_metadata/type_metadata.c:835
|
||||||
TypeInfo* type_info_from_shape(Shape v);
|
TypeInfo* type_info_from_shape(Shape v);
|
||||||
U32 max_slot_from_shape(Shape v);
|
U32 max_slot_from_shape(Shape v);
|
||||||
|
|
||||||
// generated by W:/metadesk/examples/type_metadata/type_metadata.c:821
|
// generated by W:/metadesk/examples/type_metadata/type_metadata.c:858
|
||||||
extern TypeInfo U32_type_info;
|
extern TypeInfo U32_type_info;
|
||||||
extern TypeInfo F32_type_info;
|
extern TypeInfo F32_type_info;
|
||||||
extern TypeInfo V2F32_type_info;
|
extern TypeInfo V2F32_type_info;
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
/*
|
/*
|
||||||
** Example: type metadata
|
** Example: type metadata
|
||||||
**
|
**
|
||||||
** This file shows including the generated type information into a final
|
** This file shows including the generated types and metadata in the a final
|
||||||
** program and using that type info to unpack a buffer of data.
|
** program and using it to unpack a buffer of data.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//~ setup base types //////////////////////////////////////////////////////////
|
//~ setup base types //////////////////////////////////////////////////////////
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
typedef uint8_t U8;
|
||||||
|
typedef uint16_t U16;
|
||||||
typedef uint32_t U32;
|
typedef uint32_t U32;
|
||||||
typedef float F32;
|
typedef float F32;
|
||||||
typedef struct V2F32 V2F32;
|
typedef struct V2F32 V2F32;
|
||||||
@@ -26,12 +28,184 @@ struct V2F32
|
|||||||
|
|
||||||
//~ main //////////////////////////////////////////////////////////////////////
|
//~ main //////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
U8 raw_buffer[] = {
|
||||||
|
0x03,0x00,0x00,0x00,0x00,0x00,0x90,0x40,0x06,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,
|
||||||
|
0x2D,0xB2,0x5D,0x3F,0x00,0x00,0x00,0xBF,0x2D,0xB2,0x5D,0x3F,
|
||||||
|
0x00,0x00,0x80,0xBF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBF,
|
||||||
|
0x2D,0xB2,0x5D,0xBF,0x00,0x00,0x00,0x3F,0x2D,0xB2,0x5D,0xBF,
|
||||||
|
0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,
|
||||||
|
0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0xC0,
|
||||||
|
0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,
|
||||||
|
0x00,0x00,0x00,0xC0,0x00,0x00,0x80,0x40,0x00,0x00,0x00,0x00,
|
||||||
|
};
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
print_data_from_type_info(U8 **ptr_inout, U8 *opl, TypeInfo *type_info, int indent){
|
||||||
|
static char spaces[] =
|
||||||
|
" ";
|
||||||
|
|
||||||
|
int result = 1;
|
||||||
|
|
||||||
|
switch (type_info->kind){
|
||||||
|
case TypeKind_Basic:
|
||||||
|
{
|
||||||
|
// special case each basic type
|
||||||
|
|
||||||
|
if (type_info == &U32_type_info)
|
||||||
|
{
|
||||||
|
if (*ptr_inout + sizeof(U32) > opl)
|
||||||
|
{
|
||||||
|
result = 0;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
U32 x = *(U32*)*ptr_inout;
|
||||||
|
*ptr_inout += sizeof(x);
|
||||||
|
fprintf(stdout, "%u\n", x);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type_info == &F32_type_info)
|
||||||
|
{
|
||||||
|
if (*ptr_inout + sizeof(F32) > opl)
|
||||||
|
{
|
||||||
|
result = 0;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
F32 x = *(F32*)*ptr_inout;
|
||||||
|
*ptr_inout += sizeof(x);
|
||||||
|
fprintf(stdout, "%f\n", x);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type_info == &V2F32_type_info)
|
||||||
|
{
|
||||||
|
if (*ptr_inout + sizeof(V2F32) > opl)
|
||||||
|
{
|
||||||
|
result = 0;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
V2F32 x = *(V2F32*)*ptr_inout;
|
||||||
|
*ptr_inout += sizeof(x);
|
||||||
|
fprintf(stdout, "(%f,%f)\n", x.x, x.y);
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case TypeKind_Struct:
|
||||||
|
{
|
||||||
|
U32 member_value_memory[20] = {0};
|
||||||
|
|
||||||
|
// iterate members
|
||||||
|
TypeInfoMember *first_member = (TypeInfoMember*)type_info->children;
|
||||||
|
TypeInfoMember *member = first_member;
|
||||||
|
int child_count = type_info->child_count;
|
||||||
|
for (int i = 0; i < child_count; i += 1, member += 1)
|
||||||
|
{
|
||||||
|
assert(i < 20);
|
||||||
|
TypeInfo *member_type_info = member->type;
|
||||||
|
|
||||||
|
// decode single members
|
||||||
|
if (member->array_count_member_index == -1)
|
||||||
|
{
|
||||||
|
// save the offset of this member for later
|
||||||
|
U8 *ptr_og = *ptr_inout;
|
||||||
|
// decode this member
|
||||||
|
fprintf(stdout, "%.*s%.*s: ", indent, spaces, member->name_length, member->name);
|
||||||
|
if (!print_data_from_type_info(ptr_inout, opl, member_type_info, indent + 1))
|
||||||
|
{
|
||||||
|
result = 0;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
// if we see a U32 we want to remember it in case it's an array count
|
||||||
|
if (member_type_info == &U32_type_info)
|
||||||
|
{
|
||||||
|
member_value_memory[i] = *(U32*)ptr_og;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// decode arrays
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(member->array_count_member_index < i);
|
||||||
|
U32 count = member_value_memory[member->array_count_member_index];
|
||||||
|
fprintf(stdout, "%.*s%.*s:\n", indent, spaces, member->name_length, member->name);
|
||||||
|
indent += 1;
|
||||||
|
for (U32 j = 0; j < count; j += 1)
|
||||||
|
{
|
||||||
|
fprintf(stdout, "%.*s[%d]: ", indent, spaces, j);
|
||||||
|
if (!print_data_from_type_info(ptr_inout, opl, member_type_info, indent + 1))
|
||||||
|
{
|
||||||
|
result = 0;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
indent -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case TypeKind_Enum:
|
||||||
|
{
|
||||||
|
// rely on the underlying type (default to U32) to print enums
|
||||||
|
TypeInfo *underlying_type = type_info->underlying_type;
|
||||||
|
if (underlying_type == 0)
|
||||||
|
{
|
||||||
|
underlying_type = &U32_type_info;
|
||||||
|
}
|
||||||
|
fprintf(stdout, "(%.*s)", type_info->name_length, type_info->name);
|
||||||
|
if (!print_data_from_type_info(ptr_inout, opl, underlying_type, indent))
|
||||||
|
{
|
||||||
|
result = 0;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
result = 0;
|
||||||
|
goto finish;
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
|
||||||
|
finish:;
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
// TODO(allen): write example final program
|
// decode the raw buffer
|
||||||
|
U8 *ptr = raw_buffer;
|
||||||
|
U8 *opl = ptr + sizeof(raw_buffer);
|
||||||
|
for (;ptr < opl;)
|
||||||
|
{
|
||||||
|
// decode a shape discriminator
|
||||||
|
if (ptr + sizeof(Shape) > opl){
|
||||||
|
fprintf(stdout, "Could not decode shape discriminator\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Shape shape = *(Shape*)ptr;
|
||||||
|
ptr += sizeof(shape);
|
||||||
|
|
||||||
|
// get type info
|
||||||
|
TypeInfo *type_info = type_info_from_shape(shape);
|
||||||
|
if (type_info == 0){
|
||||||
|
fprintf(stdout, "Unrecognized shape discriminator\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print type name
|
||||||
|
fprintf(stdout, "%.*s:\n", type_info->name_length, type_info->name);
|
||||||
|
|
||||||
|
// print contents
|
||||||
|
if (!print_data_from_type_info(&ptr, opl, type_info, 1))
|
||||||
|
{
|
||||||
|
fprintf(stdout, "Decoding error\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
** type_info_final_program.c - In addition to the metaprogram this example
|
** type_info_final_program.c - In addition to the metaprogram this example
|
||||||
** includes a "final program", i.e. one that depends on
|
** includes a "final program", i.e. one that depends on
|
||||||
** generated code. There is more commentary there.
|
** generated code. There is more commentary there.
|
||||||
** generated/* - This is the output folder where the generated files
|
** generated/ * - This is the output folder where the generated files
|
||||||
** should be saved by the metaprogram.
|
** should be saved by the metaprogram.
|
||||||
** types.mdesk - Sample input for this metaprogram. The code generated
|
** types.mdesk - Sample input for this metaprogram. The code generated
|
||||||
** from this metadesk file will be necessary to make
|
** from this metadesk file will be necessary to make
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
** Example: type metadata
|
** Example: type metadata
|
||||||
**
|
**
|
||||||
** TODO full commentary
|
** The header file for the metaprogram's main file. There isn't much commentary
|
||||||
|
** here, this file is just to help us keep the example organized.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -94,16 +94,16 @@ command_list =
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "type_info_example",
|
.name = "type_metadata_example",
|
||||||
.out = "*run*",
|
.out = "*run*",
|
||||||
.footer_panel = false,
|
.footer_panel = false,
|
||||||
.save_dirty_files = true,
|
.save_dirty_files = true,
|
||||||
.cursor_at_end = false,
|
.cursor_at_end = false,
|
||||||
.cmd =
|
.cmd =
|
||||||
{
|
{
|
||||||
{ "git_bash bin\\type_info_example.sh", .os = "win" },
|
{ "git_bash bin\\type_metadata_example.sh", .os = "win" },
|
||||||
{ "bin/type_info_example.sh", .os = "linux" },
|
{ "bin/type_metadata_example.sh", .os = "linux" },
|
||||||
{ "bin/type_info_example.sh", .os = "mac" },
|
{ "bin/type_metadata_example.sh", .os = "mac" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -112,4 +112,4 @@ fkey_command[1] = "build_tests";
|
|||||||
fkey_command[2] = "run_tests";
|
fkey_command[2] = "run_tests";
|
||||||
fkey_command[3] = "build_examples";
|
fkey_command[3] = "build_examples";
|
||||||
fkey_command[4] = "run_examples";
|
fkey_command[4] = "run_examples";
|
||||||
fkey_command[5] = "type_info_example";
|
fkey_command[5] = "type_metadata_example";
|
||||||
|
|||||||
Reference in New Issue
Block a user