[examples] enum member lists

This commit is contained in:
Allen Webster
2021-09-19 17:26:51 -07:00
parent f0ca7effc5
commit 426de7ca2e
4 changed files with 204 additions and 22 deletions
+94 -2
View File
@@ -31,10 +31,16 @@ struct TypeInfo
TypeKind kind; TypeKind kind;
MD_Node *node; MD_Node *node;
// struct member list // member list
struct TypeMember *first_member; struct TypeMember *first_member;
struct TypeMember *last_member; struct TypeMember *last_member;
int member_count; int member_count;
// enumerant list
struct TypeEnumerant *first_enumerant;
struct TypeEnumerant *last_enumerant;
int enumerant_count;
}; };
typedef struct TypeMember TypeMember; typedef struct TypeMember TypeMember;
@@ -45,6 +51,14 @@ struct TypeMember
TypeInfo *type; TypeInfo *type;
}; };
typedef struct TypeEnumerant TypeEnumerant;
struct TypeEnumerant
{
TypeEnumerant *next;
MD_Node *node;
int value;
};
typedef struct MapInfo MapInfo; typedef struct MapInfo MapInfo;
struct MapInfo struct MapInfo
{ {
@@ -161,13 +175,14 @@ main(int argc, char **argv)
} }
} }
// build struct member lists // build member lists
for (TypeInfo *type = first_type; for (TypeInfo *type = first_type;
type != 0; type != 0;
type = type->next) type = type->next)
{ {
if (type->kind == TypeKind_Struct) if (type->kind == TypeKind_Struct)
{ {
// build the list
MD_b32 got_list = 1; MD_b32 got_list = 1;
TypeMember *first_member = 0; TypeMember *first_member = 0;
TypeMember *last_member = 0; TypeMember *last_member = 0;
@@ -207,6 +222,8 @@ main(int argc, char **argv)
{ {
TypeInfo *type_info = (TypeInfo*)type_info_slot->val; TypeInfo *type_info = (TypeInfo*)type_info_slot->val;
// TODO(allen): handle the array tag
TypeMember *member = MD_PushArray(arena, TypeMember, 1); TypeMember *member = MD_PushArray(arena, TypeMember, 1);
member->node = member_node; member->node = member_node;
member->type = type_info; member->type = type_info;
@@ -217,6 +234,7 @@ main(int argc, char **argv)
skip_member:; skip_member:;
} }
// save the list
if (got_list) if (got_list)
{ {
type->first_member = first_member; type->first_member = first_member;
@@ -226,6 +244,71 @@ main(int argc, char **argv)
} }
} }
// build enumerant lists
for (TypeInfo *type = first_type;
type != 0;
type = type->next)
{
if (type->kind == TypeKind_Enum)
{
// build the list
MD_b32 got_list = 1;
TypeEnumerant *first_enumerant = 0;
TypeEnumerant *last_enumerant = 0;
int enumerant_count = 0;
int next_implicit_value = 0;
MD_Node *type_root_node = type->node;
for (MD_EachNode(enumerant_node, type_root_node->first_child))
{
MD_Node *value_node = enumerant_node->first_child;
int value = 0;
// missing value node?
if (MD_NodeIsNil(value_node))
{
value = next_implicit_value;
next_implicit_value += 1;
}
// has value node
else
{
MD_String8 value_string = value_node->string;
if (!MD_StringIsCStyleInt(value_string))
{
got_list = 0;
goto skip_enumerant;
}
value = (int)MD_CStyleIntFromString(value_string);
}
// set next implicit value
next_implicit_value = value + 1;
// save enumerant
if (got_list)
{
TypeEnumerant *enumerant = MD_PushArray(arena, TypeEnumerant, 1);
enumerant->node = enumerant_node;
enumerant->value = value;
MD_QueuePush(first_enumerant, last_enumerant, enumerant);
enumerant_count += 1;
}
skip_enumerant:;
}
// save the list
if (got_list)
{
type->first_enumerant = first_enumerant;
type->last_enumerant = last_enumerant;
type->enumerant_count = enumerant_count;
}
}
}
// TODO check types & build member lists // TODO check types & build member lists
// TODO check maps & build case lists // TODO check maps & build case lists
@@ -257,6 +340,15 @@ main(int argc, char **argv)
MD_S8VArg(member->node->string), MD_S8VArg(member->node->string),
MD_S8VArg(member->type->node->string)); MD_S8VArg(member->type->node->string));
} }
// print enumerant lists
for (TypeEnumerant *enumerant = type->first_enumerant;
enumerant != 0;
enumerant = enumerant->next){
printf(" %.*s: %d\n",
MD_S8VArg(enumerant->node->string),
enumerant->value);
}
} }
for (MapInfo *map = first_map; for (MapInfo *map = first_map;
+2 -2
View File
@@ -33,8 +33,8 @@ RoundedPolygon:
Shape: Shape:
{ {
Circle: 1, Circle: 1,
Segment: 2, Segment,
Polygon: 3, Polygon,
} }
@map(Shape -> `$Type`; complete) @map(Shape -> `$Type`; complete)
+104 -17
View File
@@ -1500,21 +1500,99 @@ MD_S8ChopWhitespace(MD_String8 string)
//~ Numeric Strings //~ Numeric Strings
MD_FUNCTION MD_u64 MD_GLOBAL MD_u8 md_char_to_value[] = {
MD_U64FromString(MD_String8 string, MD_u32 radix)
{
MD_Assert(2 <= radix && radix <= 16);
static MD_u8 char_to_value[] = {
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
0x08,0x09,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0x08,0x09,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0xFF, 0xFF,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
}; };
MD_GLOBAL MD_u8 md_char_is_integer[] = {
0,0,0,0,0,0,1,1,
1,0,0,0,1,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
};
MD_FUNCTION MD_b32
MD_StringIsU64(MD_String8 string, MD_u32 radix)
{
MD_b32 result = 0;
if (string.size > 0)
{
result = 1;
for (MD_u8 *ptr = string.str, *opl = string.str + string.size;
ptr < opl;
ptr += 1)
{
MD_u8 c = *ptr;
if (!md_char_is_integer[c >> 3])
{
result = 0;
break;
}
if (md_char_to_value[(c - 0x30)&0x1F] >= radix)
{
result = 0;
break;
}
}
}
return(result);
}
MD_FUNCTION MD_b32
MD_StringIsCStyleInt(MD_String8 string)
{
MD_u8 *ptr = string.str;
MD_u8 *opl = string.str + string.size;
// consume sign
for (;ptr < opl && (*ptr == '+' || *ptr == '-'); ptr += 1);
// radix from prefix
MD_u64 radix = 10;
if (ptr < opl)
{
MD_u8 c0 = *ptr;
if (c0 == '0')
{
ptr += 1;
radix = 8;
if (ptr < opl)
{
MD_u8 c1 = *ptr;
if (c1 == 'x')
{
ptr += 1;
radix = 0x10;
}
else if (c1 == 'b')
{
ptr += 1;
radix = 2;
}
}
}
}
// check integer "digits"
MD_String8 digits_substr = MD_S8Range(ptr, opl);
MD_b32 result = MD_StringIsU64(digits_substr, radix);
return(result);
}
MD_FUNCTION MD_u64
MD_U64FromString(MD_String8 string, MD_u32 radix)
{
MD_Assert(2 <= radix && radix <= 16);
MD_u64 value = 0; MD_u64 value = 0;
for (MD_u64 i = 0; i < string.size; i += 1){ for (MD_u64 i = 0; i < string.size; i += 1)
{
value *= radix; value *= radix;
MD_u8 c = string.str[i]; MD_u8 c = string.str[i];
value += char_to_value[(c - 0x30)&0x1F]; value += md_char_to_value[(c - 0x30)&0x1F];
} }
return(value); return(value);
} }
@@ -1526,31 +1604,39 @@ MD_CStyleIntFromString(MD_String8 string)
// consume sign // consume sign
MD_i64 sign = +1; MD_i64 sign = +1;
if (p < string.size){ if (p < string.size)
{
MD_u8 c = string.str[p]; MD_u8 c = string.str[p];
if (c == '-'){ if (c == '-')
{
sign = -1; sign = -1;
p += 1; p += 1;
} }
else if (c == '+'){ else if (c == '+')
{
p += 1; p += 1;
} }
} }
// radix from prefix // radix from prefix
MD_u64 radix = 10; MD_u64 radix = 10;
if (p < string.size){ if (p < string.size)
{
MD_u8 c0 = string.str[p]; MD_u8 c0 = string.str[p];
if (c0 == '0'){ if (c0 == '0')
{
p += 1; p += 1;
radix = 8; radix = 8;
if (p < string.size){ if (p < string.size)
{
MD_u8 c1 = string.str[p]; MD_u8 c1 = string.str[p];
if (c1 == 'x'){ if (c1 == 'x')
{
p += 1; p += 1;
radix = 16; radix = 16;
} }
else if (c1 == 'b'){ else if (c1 == 'b')
{
p += 1; p += 1;
radix = 2; radix = 2;
} }
@@ -1572,7 +1658,8 @@ MD_F64FromString(MD_String8 string)
{ {
char str[64]; char str[64];
MD_u64 str_size = string.size; MD_u64 str_size = string.size;
if (str_size > sizeof(str) - 1){ if (str_size > sizeof(str) - 1)
{
str_size = sizeof(str) - 1; str_size = sizeof(str) - 1;
} }
MD_MemoryCopy(str, string.str, str_size); MD_MemoryCopy(str, string.str, str_size);
+3
View File
@@ -1005,6 +1005,9 @@ MD_FUNCTION MD_String8 MD_S8ChopWhitespace(MD_String8 string);
//~ Numeric Strings //~ Numeric Strings
MD_FUNCTION MD_b32 MD_StringIsU64(MD_String8 string, MD_u32 radix);
MD_FUNCTION MD_b32 MD_StringIsCStyleInt(MD_String8 string);
MD_FUNCTION MD_u64 MD_U64FromString(MD_String8 string, MD_u32 radix); MD_FUNCTION MD_u64 MD_U64FromString(MD_String8 string, MD_u32 radix);
MD_FUNCTION MD_i64 MD_CStyleIntFromString(MD_String8 string); MD_FUNCTION MD_i64 MD_CStyleIntFromString(MD_String8 string);
MD_FUNCTION MD_f64 MD_F64FromString(MD_String8 string); MD_FUNCTION MD_f64 MD_F64FromString(MD_String8 string);