WIP (Broken): Major changes to handling Strings in ast (StringCached defined as StrC)

This commit is contained in:
Edward R. Gonzalez 2024-12-03 18:47:12 -05:00
parent e00b2f8afb
commit ba1dd1894a
18 changed files with 255 additions and 149 deletions

View File

@ -43,7 +43,7 @@ void Builder::print_fmt( char const* fmt, ... )
va_end( va ); va_end( va );
// log_fmt( "$%s - print_fmt: %.*s\n", File.filename, res > 80 ? 80 : res, buf ); // log_fmt( "$%s - print_fmt: %.*s\n", File.filename, res > 80 ? 80 : res, buf );
append( & Buffer, buf, res ); append( (String*) & Buffer, (char const*)buf, res );
} }
void Builder::write() void Builder::write()

View File

@ -39,7 +39,7 @@ Code scan_file( char const* path )
const StrC def_intellisense = txt("GEN_INTELLISENSE_DIRECTIVES" ); const StrC def_intellisense = txt("GEN_INTELLISENSE_DIRECTIVES" );
bool found_directive = false; bool found_directive = false;
char const* scanner = str.Data; char const* scanner = (char const*)str;
s32 left = fsize; s32 left = fsize;
while ( left ) while ( left )
{ {
@ -94,7 +94,7 @@ Code scan_file( char const* path )
move_fwd(); move_fwd();
// sptr skip_size = fsize - left; // sptr skip_size = fsize - left;
if ( (scanner + 2) >= ( str.Data + fsize ) ) if ( (scanner + 2) >= ( (char const*) str + fsize ) )
{ {
mem_move( str, scanner, left ); mem_move( str, scanner, left );
get_header(str)->Length = left; get_header(str)->Length = left;
@ -106,7 +106,6 @@ Code scan_file( char const* path )
break; break;
} }
} }
move_fwd(); move_fwd();
@ -117,7 +116,7 @@ Code scan_file( char const* path )
} }
file_close( & file ); file_close( & file );
return untyped_str( str ); return untyped_str( to_strc(str) );
} }
#if 0 #if 0

View File

@ -654,8 +654,8 @@ bool is_equal( Code self, Code other )
"so it must be verified by eye for now\n" \ "so it must be verified by eye for now\n" \
"AST Content:\n%S\n" \ "AST Content:\n%S\n" \
"Other Content:\n%S\n" \ "Other Content:\n%S\n" \
, visualize_whitespace(self->content) \ , visualize_whitespace(self->content, GlobalAllocator) \
, visualize_whitespace(other->content) \ , visualize_whitespace(other->content, GlobalAllocator) \
); \ ); \
} }
@ -711,7 +711,6 @@ bool is_equal( Code self, Code other )
case CT_Untyped: case CT_Untyped:
{ {
check_member_content( Content ); check_member_content( Content );
return true; return true;
} }

View File

@ -4,7 +4,7 @@
#endif #endif
String to_string(CodeAttributes attributes) { String to_string(CodeAttributes attributes) {
return GEN_NS duplicate( attributes->Content, GlobalAllocator ); return {(char*) duplicate( attributes->Content, GlobalAllocator ).Ptr};
} }
String to_string(CodeBody body) String to_string(CodeBody body)
@ -68,7 +68,7 @@ void to_string_export( CodeBody body, String* result )
String to_string(CodeComment comment) String to_string(CodeComment comment)
{ {
return GEN_NS duplicate( comment->Content, GlobalAllocator ); return {(char*) duplicate( comment->Content, GlobalAllocator ).Ptr};
} }
String to_string(CodeConstructor self) String to_string(CodeConstructor self)
@ -105,7 +105,7 @@ void to_string_def(CodeConstructor self, String* result )
append_fmt( result, " : %S", GEN_NS to_string(self->InitializerList) ); append_fmt( result, " : %S", GEN_NS to_string(self->InitializerList) );
if ( self->InlineCmt ) if ( self->InlineCmt )
append_fmt( result, " // %S", self->InlineCmt->Content ); append_fmt( result, " // %s", self->InlineCmt->Content.Ptr );
append_fmt( result, "\n{\n%S\n}\n", GEN_NS to_string(self->Body) ); append_fmt( result, "\n{\n%S\n}\n", GEN_NS to_string(self->Body) );
} }
@ -129,7 +129,7 @@ void to_string_fwd(CodeConstructor self, String* result )
append_fmt( result, " = %S", GEN_NS to_string(self->Body) ); append_fmt( result, " = %S", GEN_NS to_string(self->Body) );
if ( self->InlineCmt ) if ( self->InlineCmt )
append_fmt( result, "; // %S\n", self->InlineCmt->Content ); append_fmt( result, "; // %s\n", self->InlineCmt->Content.ptr );
else else
append( result, ";\n" ); append( result, ";\n" );
} }
@ -187,7 +187,7 @@ void to_string_def( CodeClass self, String* result )
if ( ast->InlineCmt ) if ( ast->InlineCmt )
{ {
append_fmt( result, " // %S", ast->InlineCmt->Content ); append_fmt( result, " // %s", ast->InlineCmt->Content.Ptr );
} }
append_fmt( result, "\n{\n%S\n}", GEN_NS to_string(ast->Body) ); append_fmt( result, "\n{\n%S\n}", GEN_NS to_string(ast->Body) );
@ -417,7 +417,7 @@ void to_string_class_fwd(CodeEnum self, String* result )
String to_string(CodeExec exec) String to_string(CodeExec exec)
{ {
return GEN_NS duplicate( exec->Content, GlobalAllocator ); return {(char*) duplicate( exec->Content, GlobalAllocator ).Ptr};
} }
void to_string(CodeExtern self, String* result ) void to_string(CodeExtern self, String* result )
@ -774,7 +774,7 @@ void to_string_def(CodeOpCast self, String* result )
} }
} }
if ( self->Name && length(self->Name) ) if ( self->Name && self->Name.Len )
append_fmt( result, "%Soperator %S()", self->Name, to_string(self->ValueType) ); append_fmt( result, "%Soperator %S()", self->Name, to_string(self->ValueType) );
else else
append_fmt( result, "operator %S()", to_string(self->ValueType) ); append_fmt( result, "operator %S()", to_string(self->ValueType) );
@ -792,7 +792,7 @@ void to_string_def(CodeOpCast self, String* result )
return; return;
} }
if ( self->Name && length(self->Name) ) if ( self->Name && self->Name.Len )
append_fmt( result, "%Soperator %S()\n{\n%S\n}\n", self->Name, to_string(self->ValueType), GEN_NS to_string(self->Body) ); append_fmt( result, "%Soperator %S()\n{\n%S\n}\n", self->Name, to_string(self->ValueType), GEN_NS to_string(self->Body) );
else else
append_fmt( result, "operator %S()\n{\n%S\n}\n", to_string(self->ValueType), GEN_NS to_string(self->Body) ); append_fmt( result, "operator %S()\n{\n%S\n}\n", to_string(self->ValueType), GEN_NS to_string(self->Body) );

View File

@ -211,9 +211,9 @@ struct CodeSpecifiers
#if GEN_SUPPORT_CPP_MEMBER_FEATURES #if GEN_SUPPORT_CPP_MEMBER_FEATURES
Using_Code( CodeSpecifiers ); Using_Code( CodeSpecifiers );
bool append( SpecifierT spec ) { return GEN_NS append(* this, spec); } bool append( Specifier spec ) { return GEN_NS append(* this, spec); }
s32 has( SpecifierT spec ) { return GEN_NS has(* this, spec); } s32 has( Specifier spec ) { return GEN_NS has(* this, spec); }
s32 remove( SpecifierT to_remove ) { return GEN_NS remove(* this, to_remove); } s32 remove( Specifier to_remove ) { return GEN_NS remove(* this, to_remove); }
String to_string() { return GEN_NS to_string(* this ); } String to_string() { return GEN_NS to_string(* this ); }
void to_string( String& result ) { return GEN_NS to_string(* this, & result); } void to_string( String& result ) { return GEN_NS to_string(* this, & result); }
#endif #endif

View File

@ -5,8 +5,6 @@
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
typedef enum CodeType_Def CodeType;
enum CodeType_Def : u32 enum CodeType_Def : u32
{ {
CT_Invalid, CT_Invalid,
@ -71,6 +69,7 @@ enum CodeType_Def : u32
CT_Variable, CT_Variable,
CT_NumTypes CT_NumTypes
}; };
typedef enum CodeType_Def CodeType;
inline StrC to_str( CodeType type ) inline StrC to_str( CodeType type )
{ {

View File

@ -5,8 +5,6 @@
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
typedef enum Operator_Def Operator;
enum Operator_Def : u32 enum Operator_Def : u32
{ {
Op_Invalid, Op_Invalid,
@ -58,6 +56,7 @@ enum Operator_Def : u32
Op_DeleteArray, Op_DeleteArray,
NumOps NumOps
}; };
typedef enum Operator_Def Operator;
inline StrC to_str( Operator op ) inline StrC to_str( Operator op )
{ {

View File

@ -5,8 +5,6 @@
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
typedef enum Specifier_Def Specifier;
enum Specifier_Def : u32 enum Specifier_Def : u32
{ {
Spec_Invalid, Spec_Invalid,
@ -37,6 +35,7 @@ enum Specifier_Def : u32
Spec_Volatile, Spec_Volatile,
Spec_NumSpecifiers Spec_NumSpecifiers
}; };
typedef enum Specifier_Def Specifier;
inline bool is_trailing( Specifier specifier ) inline bool is_trailing( Specifier specifier )
{ {

View File

@ -8,8 +8,6 @@
GEN_NS_PARSER_BEGIN GEN_NS_PARSER_BEGIN
#define GEN_DEFINE_ATTRIBUTE_TOKENS Entry( Tok_Attribute_API_Export, "GEN_API_Export_Code" ) Entry( Tok_Attribute_API_Import, "GEN_API_Import_Code" ) #define GEN_DEFINE_ATTRIBUTE_TOKENS Entry( Tok_Attribute_API_Export, "GEN_API_Export_Code" ) Entry( Tok_Attribute_API_Import, "GEN_API_Import_Code" )
typedef enum TokType_Def TokType;
enum TokType_Def : u32 enum TokType_Def : u32
{ {
Tok_Invalid, Tok_Invalid,
@ -111,6 +109,7 @@ enum TokType_Def : u32
Tok_Attribute_API_Import, Tok_Attribute_API_Import,
Tok_NumTokens Tok_NumTokens
}; };
typedef enum TokType_Def TokType;
inline StrC to_str( TokType type ) inline StrC to_str( TokType type )
{ {

View File

@ -75,8 +75,8 @@ internal
void define_constants() void define_constants()
{ {
Code_Global = make_code(); Code_Global = make_code();
scast(String, Code_Global->Name) = get_cached_string( txt("Global Code") ); Code_Global->Name = get_cached_string( txt("Global Code") );
scast(String, Code_Global->Content) = Code_Global->Name; Code_Global->Content = Code_Global->Name;
Code_Invalid = make_code(); Code_Invalid = make_code();
set_global(Code_Invalid); set_global(Code_Invalid);
@ -403,9 +403,9 @@ StringCached get_cached_string( StrC str )
} }
String result = string_make( get_string_allocator( str.Len ), str ); String result = string_make( get_string_allocator( str.Len ), str );
set<StringCached>(& StringCache, key, result ); set(& StringCache, key, { length(result), result } );
return result; return { length(result), result };
} }
// Used internally to retireve a Code object form the CodePool. // Used internally to retireve a Code object form the CodePool.

View File

@ -11,13 +11,13 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
local_persist local_persist
Arena tok_map_arena; Arena tok_map_arena;
HashTable<StrC> tok_map; HashTable(StrC) tok_map;
{ {
local_persist local_persist
char tok_map_mem[ TokenFmt_TokenMap_MemSize ]; char tok_map_mem[ TokenFmt_TokenMap_MemSize ];
tok_map_arena = arena_init_from_memory( tok_map_mem, sizeof(tok_map_mem) ); tok_map_arena = arena_init_from_memory( tok_map_mem, sizeof(tok_map_mem) );
tok_map = hashtable_init<StrC>( allocator_info(& tok_map_arena) ); tok_map = hashtable_init(StrC, allocator_info(& tok_map_arena) );
s32 left = num_tokens - 1; s32 left = num_tokens - 1;

View File

@ -485,7 +485,7 @@ CodeComment def_comment( StrC content )
Code Code
result = make_code(); result = make_code();
result->Type = CT_Comment; result->Type = CT_Comment;
result->Name = get_cached_string( cmt_formatted ); result->Name = get_cached_string( { length(cmt_formatted), cmt_formatted } );
result->Content = result->Name; result->Content = result->Name;
free(& cmt_formatted); free(& cmt_formatted);

View File

@ -357,7 +357,7 @@ s32 lex_preprocessor_directive( LexContext* ctx )
, current , current
, preprocess_content.Line , preprocess_content.Line
, preprocess_content.Column , preprocess_content.Column
, directive_str.Data , (char*) directive_str
); );
return Lex_ReturnNull; return Lex_ReturnNull;
} }
@ -578,11 +578,11 @@ TokArray lex( StrC content )
return { {}, 0 }; return { {}, 0 };
} }
foreach( StringCached, entry, PreprocessorDefines ) foreach( StringCached*, entry, PreprocessorDefines )
{ {
s32 length = 0; s32 length = 0;
char const* scanner = entry.Data; char const* scanner = * entry;
while ( GEN_NS length(entry) > length && (char_is_alphanumeric( *scanner ) || *scanner == '_') ) while ( entry->Len > length && (char_is_alphanumeric( *scanner ) || *scanner == '_') )
{ {
c.scanner++; c.scanner++;
length ++; length ++;
@ -592,8 +592,8 @@ TokArray lex( StrC content )
length++; length++;
} }
u64 key = crc32( entry.Data, length ); u64 key = crc32( * entry, length );
set(& c.defines, key, (StrC)entry ); set(& c.defines, key, (StrC) * entry );
} }
clear(Tokens); clear(Tokens);

View File

@ -669,7 +669,7 @@ CodeAttributes parse_attributes()
Code result = make_code(); Code result = make_code();
result->Type = CT_PlatformAttributes; result->Type = CT_PlatformAttributes;
result->Name = get_cached_string( name_stripped ); result->Name = get_cached_string( { length(name_stripped), name_stripped } );
result->Content = result->Name; result->Content = result->Name;
// result->Token = // result->Token =
@ -1047,10 +1047,10 @@ CodeBody parse_class_struct_body( TokType which, Token name )
if ( attributes ) if ( attributes )
{ {
String fused = string_make_reserve( GlobalAllocator, length(attributes->Content) + length(more_attributes->Content) ); String fused = string_make_reserve( GlobalAllocator, attributes->Content.Len + more_attributes->Content.Len );
append_fmt( & fused, "%S %S", attributes->Content, more_attributes->Content ); append_fmt( & fused, "%S %S", attributes->Content, more_attributes->Content );
attributes->Name = get_cached_string(fused); attributes->Name = get_cached_string({ length(fused), fused });
attributes->Content = attributes->Name; attributes->Content = attributes->Name;
// <Attributes> <Specifiers> <Attributes> // <Attributes> <Specifiers> <Attributes>
} }
@ -1344,7 +1344,7 @@ CodeDefine parse_define()
return define; return define;
} }
define->Content = get_cached_string( strip_formatting( to_str(currtok), strip_formatting_dont_preserve_newlines ) ); define->Content = get_cached_string( to_strc( strip_formatting( to_str(currtok), strip_formatting_dont_preserve_newlines )) );
eat( Tok_Preprocess_Content ); eat( Tok_Preprocess_Content );
// #define <Name> <Content> // #define <Name> <Content>
@ -1494,7 +1494,7 @@ CodeFn parse_function_after_name(
CodeFn CodeFn
result = (CodeFn) make_code(); result = (CodeFn) make_code();
result->Name = get_cached_string( name_stripped ); result->Name = get_cached_string( to_strc(name_stripped) );
result->ModuleFlags = mflags; result->ModuleFlags = mflags;
if ( body ) if ( body )
@ -2730,7 +2730,7 @@ CodeParam parse_params( bool use_template_capture )
eat( currtok.Type ); eat( currtok.Type );
} }
value = untyped_str( strip_formatting( to_str(value_tok), strip_formatting_dont_preserve_newlines ) ); value = untyped_str( to_strc(strip_formatting( to_str(value_tok), strip_formatting_dont_preserve_newlines )) );
// ( <Macro> <ValueType> <Name> = <Expression> // ( <Macro> <ValueType> <Name> = <Expression>
} }
} }
@ -2845,7 +2845,7 @@ CodeParam parse_params( bool use_template_capture )
eat( currtok.Type ); eat( currtok.Type );
} }
value = untyped_str( strip_formatting( to_str(value_tok), strip_formatting_dont_preserve_newlines ) ); value = untyped_str( to_strc(strip_formatting( to_str(value_tok), strip_formatting_dont_preserve_newlines )) );
// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> = <Expression> // ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> = <Expression>
} }
// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> = <Expression>, .. // ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> = <Expression>, ..
@ -4132,7 +4132,7 @@ CodeOpCast parse_operator_cast( CodeSpecifiers specifiers )
Code type = parse_type(); Code type = parse_type();
// <Specifiers> <Qualifier> :: ... operator <UnderlyingType> // <Specifiers> <Qualifier> :: ... operator <UnderlyingType>
Context.Scope->Name = { type->Name.Data, length(type->Name) }; Context.Scope->Name = { type->Name.Ptr, type->Name.Len };
eat( Tok_Capture_Start ); eat( Tok_Capture_Start );
eat( Tok_Capture_End ); eat( Tok_Capture_End );
@ -4820,7 +4820,7 @@ else if ( currtok.Type == Tok_DeclType )
} }
#endif #endif
result->Name = get_cached_string( name_stripped ); result->Name = get_cached_string( to_strc(name_stripped) );
if ( attributes ) if ( attributes )
result->Attributes = attributes; result->Attributes = attributes;

View File

@ -175,7 +175,7 @@ bool append(Array<Type>* array, Type* items, usize item_num)
header = get_header(array); header = get_header(array);
} }
mem_copy(array.Data + header->Num, items, item_num * sizeof(Type)); mem_copy((Type*)array + header->Num, items, item_num * sizeof(Type));
header->Num += item_num; header->Num += item_num;
return true; return true;

View File

@ -212,11 +212,7 @@
// This is intended to only really be used internally or with the C-library variant // This is intended to only really be used internally or with the C-library variant
// C++ users can just use the for-range directly. // C++ users can just use the for-range directly.
#if GEN_COMPILER_C
#define foreach(Type, entry_id, iterable) for ( Type entry_id = begin(iterable); entry_id != end(iterable); entry_id = next(iterable, entry_id) ) #define foreach(Type, entry_id, iterable) for ( Type entry_id = begin(iterable); entry_id != end(iterable); entry_id = next(iterable, entry_id) )
#else
# define foreach(Type, entry_id, iterable) for ( Type entry_id : iterable )
#endif
#if GEN_COMPILER_C #if GEN_COMPILER_C
# if __STDC_VERSION__ >= 202311L # if __STDC_VERSION__ >= 202311L

View File

@ -5,6 +5,16 @@
#pragma region Strings #pragma region Strings
struct StrC;
bool are_equal (StrC lhs, StrC rhs);
char const* back (StrC str);
bool contains (StrC str, StrC substring);
StrC duplicate (StrC str, AllocatorInfo allocator);
b32 starts_with (StrC str, StrC substring);
StrC to_str (char const* bad_string);
StrC visualize_whitespace(StrC str, AllocatorInfo allocator);
// Constant string with length. // Constant string with length.
struct StrC struct StrC
{ {
@ -14,15 +24,71 @@ struct StrC
#if ! GEN_COMPILER_C #if ! GEN_COMPILER_C
operator char const* () const { return Ptr; } operator char const* () const { return Ptr; }
char const& operator[]( ssize index ) const { return Ptr[index]; } char const& operator[]( ssize index ) const { return Ptr[index]; }
#endif
#if GEN_SUPPORT_CPP_MEMBER_FUNCTIONS
bool is_equal (StrC rhs) { return are_equal(* this, rhs); }
char* back () { return back(* this); }
bool contains (StrC substring) { return contains(* this, substring); }
String duplicate (AllocatorInfo allocator) { return duplicate(* this, allocator); }
b32 starts_with (StrC substring) { return starts_with(* this, substring); }
String visualize_whitespace() { return visualize_whitespace(* this); }
#endif // GEN_SUPPORT_CPP_MEMBER_FUNCTIONS
#endif // GEN_COMPILERC
}; };
#define cast_to_strc( str ) * rcast( StrC*, (str) - sizeof(ssize) ) #define cast_to_strc( str ) * rcast( StrC*, (str) - sizeof(ssize) )
#define txt( text ) StrC { sizeof( text ) - 1, ( text ) } #define txt( text ) StrC { sizeof( text ) - 1, ( text ) }
inline char const* begin(StrC str) { return str.Ptr; }
inline char const* end (StrC str) { return str.Ptr + str.Len; }
inline char const* next (StrC str, char const* iter) { return iter + 1; }
inline inline
StrC to_str( char const* str ) { bool are_equal(StrC lhs, StrC rhs)
return { str_len( str ), str }; {
if (lhs.Len != rhs.Len)
return false;
for (ssize idx = 0; idx < lhs.Len; ++idx)
if (lhs[idx] != rhs[idx])
return false;
return true;
}
inline
char const* back(StrC str) {
return & str.Ptr[str.Len - 1];
}
inline
bool contains(StrC str, StrC substring)
{
if (substring.Len > str.Len)
return false;
ssize main_len = str.Len;
ssize sub_len = substring.Len;
for (ssize idx = 0; idx <= main_len - sub_len; ++idx)
{
if (str_compare(str.Ptr + idx, substring.Ptr, sub_len) == 0)
return true;
}
return false;
}
inline
b32 starts_with(StrC str, StrC substring) {
if (substring.Len > str.Len)
return false;
b32 result = str_compare(str.Ptr, substring.Ptr, substring.Len) == 0;
return result;
}
inline
StrC to_str( char const* bad_str ) {
return { str_len( bad_str ), bad_str };
} }
// Dynamic String // Dynamic String
@ -31,7 +97,12 @@ StrC to_str( char const* str ) {
// I kept it for simplicty of porting but its not necessary to keep it that way. // I kept it for simplicty of porting but its not necessary to keep it that way.
#pragma region String #pragma region String
struct StringHeader; struct StringHeader;
#if GEN_COMPILER_C || ! GEN_SUPPORT_CPP_MEMBER_FEATURES
typedef char* String;
#else
struct String; struct String;
#endif
usize string_grow_formula(usize value); usize string_grow_formula(usize value);
@ -65,6 +136,7 @@ b32 starts_with (String const str, StrC substring);
b32 starts_with (String const str, String substring); b32 starts_with (String const str, String substring);
void skip_line (String str); void skip_line (String str);
void strip_space (String str); void strip_space (String str);
StrC to_strc (String str);
void trim (String str, char const* cut_set); void trim (String str, char const* cut_set);
void trim_space (String str); void trim_space (String str);
String visualize_whitespace(String const str); String visualize_whitespace(String const str);
@ -75,12 +147,11 @@ struct StringHeader {
ssize Length; ssize Length;
}; };
#if ! GEN_COMPILER_C #if ! GEN_COMPILER_C && GEN_SUPPORT_CPP_MEMBER_FEATURES
struct String struct String
{ {
char* Data; char* Data;
forceinline operator bool() { return Data != nullptr; }
forceinline operator char*() { return Data; } forceinline operator char*() { return Data; }
forceinline operator char const*() const { return Data; } forceinline operator char const*() const { return Data; }
forceinline operator StrC() const { return { GEN_NS length(* this), Data }; } forceinline operator StrC() const { return { GEN_NS length(* this), Data }; }
@ -98,10 +169,14 @@ struct String
forceinline char& operator[](ssize index) { return Data[index]; } forceinline char& operator[](ssize index) { return Data[index]; }
forceinline char const& operator[](ssize index) const { return Data[index]; } forceinline char const& operator[](ssize index) const { return Data[index]; }
bool operator==(std::nullptr_t) const { return Data == nullptr; }
bool operator!=(std::nullptr_t) const { return Data != nullptr; }
friend bool operator==(std::nullptr_t, const String str) { return str.Data == nullptr; }
friend bool operator!=(std::nullptr_t, const String str) { return str.Data != nullptr; }
forceinline char* begin() const { return Data; } forceinline char* begin() const { return Data; }
forceinline char* end() const { return Data + GEN_NS length(* this); } forceinline char* end() const { return Data + GEN_NS length(* this); }
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
#pragma region Member Mapping #pragma region Member Mapping
forceinline static String make(AllocatorInfo allocator, char const* str) { return GEN_NS string_make(allocator, str); } forceinline static String make(AllocatorInfo allocator, char const* str) { return GEN_NS string_make(allocator, str); }
forceinline static String make(AllocatorInfo allocator, StrC str) { return GEN_NS string_make(allocator, str); } forceinline static String make(AllocatorInfo allocator, StrC str) { return GEN_NS string_make(allocator, str); }
@ -151,6 +226,7 @@ struct String
forceinline b32 starts_with(String substring) const { return GEN_NS starts_with(* this, substring); } forceinline b32 starts_with(String substring) const { return GEN_NS starts_with(* this, substring); }
forceinline void skip_line() { GEN_NS skip_line(* this); } forceinline void skip_line() { GEN_NS skip_line(* this); }
forceinline void strip_space() { GEN_NS strip_space(* this); } forceinline void strip_space() { GEN_NS strip_space(* this); }
forceinline StrC to_strc() { return { length(), Data}; }
forceinline void trim(char const* cut_set) { GEN_NS trim(* this, cut_set); } forceinline void trim(char const* cut_set) { GEN_NS trim(* this, cut_set); }
forceinline void trim_space() { GEN_NS trim_space(* this); } forceinline void trim_space() { GEN_NS trim_space(* this); }
forceinline String visualize_whitespace() const { return GEN_NS visualize_whitespace(* this); } forceinline String visualize_whitespace() const { return GEN_NS visualize_whitespace(* this); }
@ -168,26 +244,25 @@ struct String
return GEN_NS append(this, buf, res); return GEN_NS append(this, buf, res);
} }
#pragma endregion Member Mapping #pragma endregion Member Mapping
#endif
}; };
#endif #endif
#if GEN_SUPPORT_CPP_REFERENCES inline char* begin(String str) { return ((char*) str); }
bool make_space_for(String& str, char const* to_append, ssize add_len); inline char* end (String str) { return ((char*) str + length(str)); }
bool append(String& str, char c); inline char* next (String str, char* iter) { return ((char*) iter + 1); }
bool append(String& str, char const* str_to_append);
bool append(String& str, char const* str_to_append, ssize length);
bool append(String& str, StrC str_to_append);
bool append(String& str, const String other);
bool append_fmt(String& str, char const* fmt, ...);
char& back(String& str);
void clear(String& str);
void free(String& str);
#endif
inline char* begin(String str) { return str; } #if GEN_SUPPORT_CPP_REFERENCES
inline char* end(String str) { return scast(char*, str) + length(str); } inline bool make_space_for(String& str, char const* to_append, ssize add_len);
inline char* next(String str) { return scast(char*, str) + 1; } inline bool append(String& str, char c);
inline bool append(String& str, char const* str_to_append);
inline bool append(String& str, char const* str_to_append, ssize length);
inline bool append(String& str, StrC str_to_append);
inline bool append(String& str, const String other);
inline bool append_fmt(String& str, char const* fmt, ...);
inline char& back(String& str);
inline void clear(String& str);
inline void free(String& str);
#endif
inline inline
usize string_grow_formula(usize value) { usize string_grow_formula(usize value) {
@ -249,7 +324,7 @@ String string_join(AllocatorInfo allocator, char const** parts, ssize num_parts,
inline inline
bool append(String* str, char c) { bool append(String* str, char c) {
GEN_ASSERT(str != nullptr); GEN_ASSERT(str != nullptr);
return append(str, &c, 1); return append( str, (char const*)& c, (ssize)1);
} }
inline inline
@ -288,9 +363,9 @@ bool append(String* str, StrC str_to_append) {
} }
inline inline
bool append(String* str, const String other) { bool append(String* str, String const other) {
GEN_ASSERT(str != nullptr); GEN_ASSERT(str != nullptr);
return append(str, other, length(other)); return append(str, (char const*)other, length(other));
} }
bool append_fmt(String* str, char const* fmt, ...) { bool append_fmt(String* str, char const* fmt, ...) {
@ -303,7 +378,7 @@ bool append_fmt(String* str, char const* fmt, ...) {
res = str_fmt_va(buf, count_of(buf) - 1, fmt, va) - 1; res = str_fmt_va(buf, count_of(buf) - 1, fmt, va) - 1;
va_end(va); va_end(va);
return append(str, buf, res); return append(str, (char const*)buf, res);
} }
inline inline
@ -464,7 +539,7 @@ b32 starts_with(String const str, StrC substring) {
if (substring.Len > length(str)) if (substring.Len > length(str))
return false; return false;
b32 result = str_compare(str.Data, substring.Ptr, substring.Len) == 0; b32 result = str_compare(str, substring.Ptr, substring.Len) == 0;
return result; return result;
} }
@ -473,7 +548,7 @@ b32 starts_with(String const str, String substring) {
if (length(substring) > length(str)) if (length(substring) > length(str))
return false; return false;
b32 result = str_compare(str.Data, substring.Data, length(substring) - 1) == 0; b32 result = str_compare(str, substring, length(substring) - 1) == 0;
return result; return result;
} }
@ -481,18 +556,18 @@ inline
void skip_line(String str) void skip_line(String str)
{ {
#define current (*scanner) #define current (*scanner)
char* scanner = str.Data; char* scanner = str;
while (current != '\r' && current != '\n') { while (current != '\r' && current != '\n') {
++scanner; ++scanner;
} }
s32 new_length = scanner - str.Data; s32 new_length = scanner - str;
if (current == '\r') { if (current == '\r') {
new_length += 1; new_length += 1;
} }
mem_move(str.Data, scanner, new_length); mem_move((char*)str, scanner, new_length);
StringHeader* header = get_header(str); StringHeader* header = get_header(str);
header->Length = new_length; header->Length = new_length;
@ -518,7 +593,12 @@ void strip_space(String str)
write_pos[0] = '\0'; // Null-terminate the modified string write_pos[0] = '\0'; // Null-terminate the modified string
// Update the length if needed // Update the length if needed
get_header(str)->Length = write_pos - str.Data; get_header(str)->Length = write_pos - str;
}
inline
StrC to_strc(String str) {
return { length(str), (char const*)str };
} }
inline inline
@ -526,8 +606,8 @@ void trim(String str, char const* cut_set)
{ {
ssize len = 0; ssize len = 0;
char* start_pos = str.Data; char* start_pos = str;
char* end_pos = str.Data + length(str) - 1; char* end_pos = scast(char*, str) + length(str) - 1;
while (start_pos <= end_pos && char_first_occurence(cut_set, *start_pos)) while (start_pos <= end_pos && char_first_occurence(cut_set, *start_pos))
start_pos++; start_pos++;
@ -537,10 +617,10 @@ void trim(String str, char const* cut_set)
len = scast(ssize, (start_pos > end_pos) ? 0 : ((end_pos - start_pos) + 1)); len = scast(ssize, (start_pos > end_pos) ? 0 : ((end_pos - start_pos) + 1));
if (str.Data != start_pos) if (str != start_pos)
mem_move(str.Data, start_pos, len); mem_move(str, start_pos, len);
str.Data[len] = '\0'; str[len] = '\0';
get_header(str)->Length = len; get_header(str)->Length = len;
} }
@ -556,7 +636,7 @@ String visualize_whitespace(String const str)
StringHeader* header = (StringHeader*)(scast(char const*, str) - sizeof(StringHeader)); StringHeader* header = (StringHeader*)(scast(char const*, str) - sizeof(StringHeader));
String result = string_make_reserve(header->Allocator, length(str) * 2); // Assume worst case for space requirements. String result = string_make_reserve(header->Allocator, length(str) * 2); // Assume worst case for space requirements.
for (auto c : str) switch (c) foreach (char*, c, str) switch ( * c )
{ {
case ' ': case ' ':
append(& result, txt("·")); append(& result, txt("·"));
@ -590,11 +670,47 @@ struct String_POD {
}; };
static_assert( sizeof( String_POD ) == sizeof( String ), "String is not a POD" ); static_assert( sizeof( String_POD ) == sizeof( String ), "String is not a POD" );
// Implements basic string interning. Data structure is based off the ZPL Hashtable. inline
typedef HashTable<String const> StringTable; StrC duplicate(StrC str, AllocatorInfo allocator) {
String result = string_make_length(allocator, str.Ptr, str.Len);
return { get_header(result)->Length, result };
}
inline
StrC visualize_whitespace(StrC str, AllocatorInfo allocator)
{
String result = string_make_reserve(allocator, str.Len * 2); // Assume worst case for space requirements.
foreach (char const*, c, str) switch ( * c )
{
case ' ':
append(& result, txt("·"));
break;
case '\t':
append(& result, txt(""));
break;
case '\n':
append(& result, txt(""));
break;
case '\r':
append(& result, txt(""));
break;
case '\v':
append(& result, txt(""));
break;
case '\f':
append(& result, txt(""));
break;
default:
append(& result, c);
break;
}
return to_strc(result);
}
// Represents strings cached with the string table. // Represents strings cached with the string table.
// Should never be modified, if changed string is desired, cache_string( str ) another. // Should never be modified, if changed string is desired, cache_string( str ) another.
typedef String const StringCached; typedef StrC StringCached;
// Implements basic string interning. Data structure is based off the ZPL Hashtable.
typedef HashTable<StringCached> StringTable;
#pragma endregion Strings #pragma endregion Strings

View File

@ -31,11 +31,11 @@ CodeBody gen_ecode( char const* path )
append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", code, code ); append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", code, code );
} }
CodeEnum enum_code = parse_enum(gen::token_fmt_impl((3 + 1) / 2, "entries", (StrC)enum_entries, "enum CodeType_Def : u32 { <entries> CT_NumTypes };")); CodeEnum enum_code = parse_enum(gen::token_fmt_impl((3 + 1) / 2, "entries", to_strc(enum_entries), "enum CodeType_Def : u32 { <entries> CT_NumTypes };"));
#pragma push_macro("local_persist") #pragma push_macro("local_persist")
#undef local_persist #undef local_persist
CodeFn to_str = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize( CodeFn to_str = parse_function( token_fmt( "entries", to_strc(to_str_entries), stringize(
inline inline
StrC to_str( CodeType type ) StrC to_str( CodeType type )
{ {
@ -53,7 +53,7 @@ CodeBody gen_ecode( char const* path )
//CodeUsing code_t = def_using( name(CodeT), def_type( name(ECode::Type) ) ); //CodeUsing code_t = def_using( name(CodeT), def_type( name(ECode::Type) ) );
CodeTypedef code_t = parse_typedef(code(typedef enum CodeType_Def CodeType; )); CodeTypedef code_t = parse_typedef(code(typedef enum CodeType_Def CodeType; ));
return def_global_body( args( code_t, enum_code, to_str, fmt_newline ) ); return def_global_body( args( enum_code, code_t, to_str, fmt_newline ) );
} }
CodeBody gen_eoperator( char const* path ) CodeBody gen_eoperator( char const* path )
@ -81,7 +81,7 @@ CodeBody gen_eoperator( char const* path )
append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
} }
CodeEnum enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, stringize( CodeEnum enum_code = parse_enum(token_fmt("entries", to_strc(enum_entries), stringize(
enum Operator_Def : u32 enum Operator_Def : u32
{ {
<entries> <entries>
@ -91,7 +91,7 @@ CodeBody gen_eoperator( char const* path )
#pragma push_macro("local_persist") #pragma push_macro("local_persist")
#undef local_persist #undef local_persist
CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, stringize( CodeFn to_str = parse_function(token_fmt("entries", to_strc(to_str_entries), stringize(
inline inline
StrC to_str( Operator op ) StrC to_str( Operator op )
{ {
@ -109,7 +109,7 @@ CodeBody gen_eoperator( char const* path )
//CodeUsing operator_t = def_using( name(OperatorT), def_type( name(EOperator::Type) ) ); //CodeUsing operator_t = def_using( name(OperatorT), def_type( name(EOperator::Type) ) );
CodeTypedef operator_t = parse_typedef(code( typedef enum Operator_Def Operator; )); CodeTypedef operator_t = parse_typedef(code( typedef enum Operator_Def Operator; ));
return def_global_body( args( operator_t, enum_code, to_str, fmt_newline ) ); return def_global_body( args( enum_code, operator_t, to_str, fmt_newline ) );
} }
CodeBody gen_especifier( char const* path ) CodeBody gen_especifier( char const* path )
@ -137,7 +137,7 @@ CodeBody gen_especifier( char const* path )
append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
} }
CodeEnum enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, stringize( CodeEnum enum_code = parse_enum(token_fmt("entries", to_strc(enum_entries), stringize(
enum Specifier_Def : u32 enum Specifier_Def : u32
{ {
<entries> <entries>
@ -145,7 +145,7 @@ CodeBody gen_especifier( char const* path )
}; };
))); )));
CodeFn is_trailing = parse_function(token_fmt("specifier", (StrC)to_str_entries, stringize( CodeFn is_trailing = parse_function(token_fmt("specifier", to_strc(to_str_entries), stringize(
inline inline
bool is_trailing( Specifier specifier ) bool is_trailing( Specifier specifier )
{ {
@ -163,7 +163,7 @@ CodeBody gen_especifier( char const* path )
#undef do_once_end #undef do_once_end
#undef forceinline #undef forceinline
#undef neverinline #undef neverinline
CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, stringize( CodeFn to_str = parse_function(token_fmt("entries", to_strc(to_str_entries), stringize(
inline inline
StrC to_str( Specifier type ) StrC to_str( Specifier type )
{ {
@ -176,7 +176,7 @@ CodeBody gen_especifier( char const* path )
} }
))); )));
CodeFn to_type = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize( CodeFn to_type = parse_function( token_fmt( "entries", to_strc(to_str_entries), stringize(
inline inline
Specifier to_specifier( StrC str ) Specifier to_specifier( StrC str )
{ {
@ -214,7 +214,7 @@ CodeBody gen_especifier( char const* path )
//CodeUsing specifier_t = def_using( name(SpecifierT), def_type( name(ESpecifier::Type) ) ); //CodeUsing specifier_t = def_using( name(SpecifierT), def_type( name(ESpecifier::Type) ) );
CodeTypedef specifier_t = parse_typedef( code(typedef enum Specifier_Def Specifier; )); CodeTypedef specifier_t = parse_typedef( code(typedef enum Specifier_Def Specifier; ));
return def_global_body( args( specifier_t, enum_code, is_trailing, to_str, to_type, fmt_newline ) ); return def_global_body( args( enum_code, specifier_t, is_trailing, to_str, to_type, fmt_newline ) );
} }
CodeBody gen_etoktype( char const* etok_path, char const* attr_path ) CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
@ -271,11 +271,11 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
#pragma push_macro("GEN_DEFINE_ATTRIBUTE_TOKENS") #pragma push_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
#undef GEN_DEFINE_ATTRIBUTE_TOKENS #undef GEN_DEFINE_ATTRIBUTE_TOKENS
CodeDefine attribute_entires_def = def_define( name(GEN_DEFINE_ATTRIBUTE_TOKENS), attribute_define_entries ); CodeDefine attribute_entires_def = def_define( name(GEN_DEFINE_ATTRIBUTE_TOKENS), to_strc(attribute_define_entries) );
#pragma pop_macro("GEN_DEFINE_ATTRIBUTE_TOKENS") #pragma pop_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
// We cannot parse this enum, it has Attribute names as enums // We cannot parse this enum, it has Attribute names as enums
CodeEnum enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, "attribute_toks", (StrC)attribute_entries, stringize( CodeEnum enum_code = parse_enum(token_fmt("entries", to_str(enum_entries), "attribute_toks", to_str(attribute_entries), stringize(
enum TokType_Def : u32 enum TokType_Def : u32
{ {
<entries> <entries>
@ -290,7 +290,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
#undef local_persist #undef local_persist
#undef do_once_start #undef do_once_start
#undef do_once_end #undef do_once_end
CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, "attribute_toks", (StrC)to_str_attributes, stringize( CodeFn to_str = parse_function(token_fmt("entries", to_strc(to_str_entries), "attribute_toks", to_strc(to_str_attributes), stringize(
inline inline
StrC to_str( TokType type ) StrC to_str( TokType type )
{ {
@ -304,7 +304,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
} }
))); )));
CodeFn to_type = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize( CodeFn to_type = parse_function( token_fmt( "entries", to_strc(to_str_entries), stringize(
inline inline
TokType to_toktype( StrC str ) TokType to_toktype( StrC str )
{ {
@ -341,8 +341,8 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
return def_global_body( args( return def_global_body( args(
attribute_entires_def, attribute_entires_def,
td_toktype,
enum_code, enum_code,
td_toktype,
to_str, to_str,
to_type to_type
)); ));