1
0
mirror of https://github.com/Ed94/gencpp.git synced 2025-07-16 02:18:58 -07:00

ECode, ESpecifier, and ETokType are now all generated.

There is a redundant pattern for generating all three (as expected).

I'll use it to define a general way of doing this sort of behavior.
This commit is contained in:
2023-07-27 02:51:36 -04:00
parent cf65638979
commit b00c1ae522
8 changed files with 334 additions and 184 deletions

@ -209,7 +209,129 @@ CodeBody gen_especifier( char const* path )
return def_global_body( args( nspace, specifier_t ) );
}
CodeBody gen_etoktype()
CodeBody gen_etoktype( char const* path )
{
return CodeInvalid;
char scratch_mem[kilobytes(4)];
Arena scratch = Arena::init_from_memory( scratch_mem, sizeof(scratch_mem) );
file_read_contents( scratch, zero_terminate, path );
CSV_Object csv_nodes;
csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false );
Array<ADT_Node> enum_strs = csv_nodes.nodes[0].nodes;
Array<ADT_Node> str_strs = csv_nodes.nodes[1].nodes;
String enum_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
String to_str_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
for (uw idx = 0; idx < enum_strs.num(); idx++)
{
char const* enum_str = enum_strs[idx].string;
char const* entry_to_str = str_strs [idx].string;
enum_entries.append_fmt( "%s,\n", enum_str );
to_str_entries.append_fmt( "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
}
CodeEnum enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, stringize(
enum Type : u32
{
<entries>
NumTokenTypes
};
)));
#pragma push_macro( "local_persist" )
#pragma push_macro( "do_once_start" )
#pragma push_macro( "do_once_end" )
#undef local_persist
#undef do_once_start
#undef do_once_end
CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, stringize(
StrC to_str( Type type )
{
local_persist
StrC lookup[] {
<entries>
NumTokens
};
return lookup[ type ];
}
)));
CodeFn to_type = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
Type to_type( StrC str )
{
local_persist
u32 keymap[ NumTokens ];
do_once_start
for ( u32 index = 0; index < NumTokens; index++ )
{
StrC enum_str = to_str( (Type)index );
// We subtract 1 to remove the null terminator
// This is because the tokens lexed are not null terminated.
keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1);
}
do_once_end
u32 hash = crc32( str.Ptr, str.Len );
for ( u32 index = 0; index < NumTokens; index++ )
{
if ( keymap[index] == hash )
return (Type)index;
}
return Invalid;
}
)));
#pragma pop_macro( "local_persist" )
#pragma pop_macro( "do_once_start" )
#pragma pop_macro( "do_once_end" )
CodeFn is_specifier = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
bool tok_is_specifier( Type type )
{
return (tok.Type <= TokType::Star && tok.Type >= TokType::Spec_Alignas)
|| tok.Type == TokType::Ampersand
|| tok.Type == TokType::Ampersand_DBL
;
}
)));
CodeFn is_access_specifier = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
bool tok_is_access_specifier( Type type )
{
return tok.Type >= TokType::Access_Private && tok.Type <= TokType::Access_Public;
}
)));
#pragma push_macro( "internal" )
#pragma push_macro( "scast" )
CodeFn to_access_specifier = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
internal inline
AccessSpec tok_to_access_specifier( Type type )
{
return scast(AccessSpec, tok.Type);
}
)));
#pragma pop_macro( "internal" )
#pragma pop_macro( "scast" )
CodeFn is_attribute = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
bool tok_is_attribute( const Token type )
{
return tok.Type >= TokType::Attr_Alignas && tok.Type <= TokType::Attr_Visibility;
}
)));
CodeNamespace nspace = def_namespace( name(ETokType), def_namespace_body( args( enum_code, to_str, to_type, is_specifier, is_access_specifier, to_access_specifier, is_attribute ) ) );
CodeUsing td_toktype = def_using( name(TokTypeT), def_type( name(ETokType::Type) ) );
return def_global_body( args( nspace, td_toktype ) );
}