From e34b3694da7cfc7d25b966fb0e1f493babb6f210 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sat, 6 May 2023 15:49:43 -0400 Subject: [PATCH] WIP: Converting api to use custom String types --- project/Bloat.hpp | 89 ++++- project/gen.cpp | 527 +++++++++++++++-------------- project/gen.hpp | 126 +++---- test/NonParsed/Array.NonParsed.hpp | 231 +++++++++++++ test/Parsed/Array.Parsed.hpp | 170 ++++++++++ 5 files changed, 815 insertions(+), 328 deletions(-) create mode 100644 test/NonParsed/Array.NonParsed.hpp create mode 100644 test/Parsed/Array.Parsed.hpp diff --git a/project/Bloat.hpp b/project/Bloat.hpp index 769fbfc..f8097ce 100644 --- a/project/Bloat.hpp +++ b/project/Bloat.hpp @@ -54,7 +54,7 @@ using zpl::ArrayHeader; using zpl::FileInfo; using zpl::FileError; using zpl::Pool; -using zpl::String; +// using zpl::String; using zpl::EFileMode_WRITE; using zpl::EFileError_NONE; @@ -77,6 +77,7 @@ using zpl::pool_allocator; using zpl::pool_init; using zpl::pool_free; using zpl::process_exit; +using zpl::str_copy; using zpl::str_fmt_out_va; using zpl::str_fmt_out_err_va; using zpl::str_compare; @@ -188,7 +189,25 @@ char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED"; #pragma endregion Memory #pragma region String -#if 0 +#if 1 + // Constant string with length. + struct StrC + { + sw Len; + char const* Ptr; + + static StrC from( char const* str ) + { + return { str_len( str ), str }; + } + + operator char const* () const + { + return Ptr; + } + }; + + // Dynamic String struct String { struct Header @@ -238,10 +257,12 @@ char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED"; void append( char c ); void append( char const* str ); void append( char const* str, sw length ); + void append( StrC str); void append( const String other ); - void append( char const* fmt, ... ); void append( const String other ); + void append_fmt( char const* fmt, ... ); + sw avail_space(); sw capacity(); @@ -251,13 +272,67 @@ char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED"; void free(); - Header& header(); + Header& get_headder() + { + return pcast( Header, Data[ - sizeof( Header ) ] ); + } - sw length(); + sw length() const; void trim( char const* cut_set ); void trim_space(); + operator bool() + { + return Data; + } + + operator char* () + { + return Data; + } + + operator char const* () const + { + return Data; + } + + operator StrC() + { + return + { + length(), + Data + }; + } + + String const& operator = ( String const& other ) const + { + if ( this == & other ) + return *this; + + String& this_ = ccast( String, *this ); + + this_.Data = other.Data; + + return this_; + } + + String& operator += ( String const& other ) + { + append( other ); + return *this; + } + + char& operator [] ( sw index ) + { + return Data[ index ]; + } + + char const& operator [] ( sw index ) const + { + return Data[ index ]; + } char* Data = nullptr; }; @@ -287,7 +362,7 @@ namespace Memory } inline -sw log_fmt(char const *fmt, ...) +sw log_fmt(char const* fmt, ...) { sw res; va_list va; @@ -300,7 +375,7 @@ sw log_fmt(char const *fmt, ...) } inline -sw fatal(char const *fmt, ...) +sw fatal(char const* fmt, ...) { local_persist thread_local char buf[ZPL_PRINTF_MAXLEN] = { 0 }; diff --git a/project/gen.cpp b/project/gen.cpp index 61177e9..d2216fa 100644 --- a/project/gen.cpp +++ b/project/gen.cpp @@ -490,15 +490,15 @@ namespace gen { # define ProcessModuleFlags() \ if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) \ - result = string_append_fmt( result, "export " ); \ + result.append( "export " ); \ \ if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Import )) \ - result = string_append_fmt( result, "import " ); \ + result.append( "import " ); \ \ if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Private )) \ - result = string_append_fmt( result, "private " ); + result.append( "private " ); - String result = string_make( g_allocator, "" ); + String result = String::make( g_allocator, "" ); // Scope indentation. char indent_str[128] = {0}; // Should be more than enough... @@ -512,6 +512,7 @@ namespace gen tab_count++; } } + StrC indent = { tab_count, indent_str }; switch ( Type ) { @@ -522,16 +523,17 @@ namespace gen break; case Untyped: - result = string_append_length( result, Content, string_length( ccast(String, Content)) ); + // result = string_append_length( result, Content, string_length( ccast(String, Content)) ); + result.append( Content ); break; case Comment: { - result = string_append_length( result, indent_str, tab_count ); + result.append( indent ); static char line[MaxCommentLineLength]; - s32 left = string_length( ccast(String, Content) ); + s32 left = Content.length(); s32 index = 0; do { @@ -539,10 +541,10 @@ namespace gen while ( left && Content[index] != '\n' ) length++; - zpl::str_copy( line, Content, length ); + str_copy( line, Content, length ); line[length] = '\0'; - result = string_append_fmt( result, "// %s\n", line ); + result.append_fmt( "// %s\n", line ); } while ( left--, left ); } @@ -551,30 +553,30 @@ namespace gen case Access_Private: case Access_Protected: case Access_Public: - result = string_append_length( result, indent_str, tab_count ); - result = string_append_length( result, Name, string_length( ccast(String, Name)) ); + result.append( indent ); + result.append( Name ); break; case Attributes: - result = string_append_length( result, Content, string_length( ccast(String, Content)) ); + result.append( Content ); case Class: { - result = string_append_length( result, indent_str, tab_count ); + result.append( indent ); ProcessModuleFlags(); - result = string_append_fmt( result, "class "); + result.append( "class " ); s32 idx = 1; if ( Entries[idx]->Type == Attributes ) { - result = string_append_fmt( result, "%s ", Entries[idx]->to_string() ); + result.append_fmt( "%s ", Entries[idx]->to_string() ); idx++; } - result = string_append_length( result, Name, string_length( ccast(String, Name)) ); + result.append( Name ); AST* parent = Entries[idx]; @@ -582,45 +584,45 @@ namespace gen { char const* access_level = to_str( ParentAccess ); - result = string_append_fmt( result, ": %s %s\n%s{\n" + result.append_fmt( ": %s %s\n%s{\n" , access_level , parent , indent_str ); } - result = string_append_fmt( result, "%s\n%s};\n", body()->to_string(), indent_str ); + result.append_fmt( "%s\n%s};\n", body()->to_string(), indent_str ); } break; case Class_Fwd: { - result = string_append_length( result, indent_str, tab_count ); + result.append( indent ); ProcessModuleFlags(); - result = string_append_fmt( result, "class %s;", Name ); + result.append_fmt( "class %s;", Name ); } break; case Enum: - result = string_append_length( result, indent_str, tab_count ); + result.append( indent ); ProcessModuleFlags(); - string_append_length( result, "enum ", 5); + result.append( "enum " ); s32 idx = 1; if ( Entries[idx]->Type == Attributes ) { - result = string_append_fmt( result, "%s ", Entries[idx]->to_string() ); + result.append_fmt( "%s ", Entries[idx]->to_string() ); idx++; } if ( Entries[idx]->Type == Typename) { - result = string_append_fmt( result, "%s : %s\n%s{\n" + result.append_fmt( "%s : %s\n%s{\n" , Name , Entries[idx]->to_string() , indent_str @@ -628,44 +630,44 @@ namespace gen } else { - result = string_append_fmt( result, "%s\n%s{\n" + result.append_fmt( result, "%s\n%s{\n" , Name , indent_str ); } - result = string_append_fmt( result, "%s\n%s};" + result.append_fmt( result, "%s\n%s};" , body()->to_string() , indent_str ); break; case Enum_Fwd: - result = string_append_length( result, indent_str, tab_count ); + result.append( indent ); ProcessModuleFlags(); - result = string_append_fmt( result, "enum %s : %s;\n", Name, Entries[1]->to_string() ); + result.append_fmt( "enum %s : %s;\n", Name, Entries[1]->to_string() ); break; case Enum_Class: - result = string_append_length( result, indent_str, tab_count ); + result.append( indent ); ProcessModuleFlags(); - result = string_append_fmt( result, "enum class " ); + result.append( "enum class " ); s32 idx = 0; if ( Entries[idx]->Type == Attributes ) { - result = string_append_fmt( result, "%s ", Entries[idx]->to_string() ); + result.append_fmt( "%s ", Entries[idx]->to_string() ); idx++; } if ( Entries[idx]->Type == Typename ) { - result = string_append_fmt( result, ": %s\n%s{\n" + result.append_fmt( ": %s\n%s{\n" , Name , Entries[idx]->to_string() , indent_str @@ -673,62 +675,62 @@ namespace gen } else { - result = string_append_fmt( result, "%s\n%s{\n" + result.append_fmt( "%s\n%s{\n" , Name , indent_str ); } - result = string_append_fmt( result, "%s\n%s};" + result.append_fmt( "%s\n%s};" , body()->to_string() , indent_str ); break; case Enum_Class_Fwd: - result = string_append_length( result, indent_str, tab_count ); + result.append( indent ); ProcessModuleFlags(); - result = string_append_fmt( result, "enum class " ); + result.append( "enum class " ); s32 idx = 0; if ( Entries[idx]->Type == Attributes ) { - result = string_append_fmt( result, "%s ", Entries[idx]->to_string() ); + result.append_fmt( "%s ", Entries[idx]->to_string() ); idx++; } - result = string_append_fmt( result, ": %s;\n", Name, Entries[idx]->to_string() ); + result.append_fmt( ": %s;\n", Name, Entries[idx]->to_string() ); break; case Execution: - result = string_append_length( result, Content, string_length( ccast(String, Content)) ); + result.append( Content ); break; case Export_Body: { - result = string_append_fmt( result, "%sexport\n%s{\n", indent_str, indent_str ); + result.append_fmt( "%sexport\n%s{\n", indent_str, indent_str ); s32 index = 0; s32 left = num_entries(); while ( left -- ) { - result = string_append_fmt( result, "%s\t%s\n", indent_str, Entries[index]->to_string() ); + result.append_fmt( "%s\t%s\n", indent_str, Entries[index]->to_string() ); index++; } - result = string_append_fmt( result, "%s};\n", indent_str ); + result.append_fmt( "%s};\n", indent_str ); } break; case Extern_Linkage: - result = string_append_length( result, indent_str, tab_count ); + result.append( indent ); ProcessModuleFlags(); - result = string_append_fmt( result, "extern %s\n%s{\n%s\n%s};\n" + result.append_fmt( "extern %s\n%s{\n%s\n%s};\n" , Name , indent_str , body()->to_string() @@ -737,12 +739,12 @@ namespace gen break; case Friend: - result = string_append_fmt( result, "%sfriend %s;\n", indent_str, Entries[0]->to_string() ); + result.append_fmt( "%sfriend %s;\n", indent_str, Entries[0]->to_string() ); break; case Function: { - result = string_append_length( result, indent_str, tab_count ); + result.append( indent ); ProcessModuleFlags(); @@ -751,34 +753,34 @@ namespace gen if ( Entries[idx]->Type == Attributes ) { - result = string_append_fmt( result, "%s ", Entries[idx]->to_string() ); + result.append_fmt( "%s ", Entries[idx]->to_string() ); idx++; left--; } if ( Entries[idx]->Type == Specifiers ) { - result = string_append_fmt( result, "%s\n", Entries[idx]->to_string() ); + result.append_fmt( "%s\n", Entries[idx]->to_string() ); idx++; left--; } - result = string_append_fmt( result, "%s %s(", Entries[idx]->to_string(), Name ); + result.append_fmt( "%s %s(", Entries[idx]->to_string(), Name ); idx++; left--; if ( left && Entries[idx]->Type == Parameters ) { - result = string_append_fmt( result, "%s", Entries[idx]->to_string() ); + result.append_fmt( "%s", Entries[idx]->to_string() ); idx++; left--; } else { - result = string_append_fmt( result, "void" ); + result.append_fmt( "void" ); } - result = string_append_fmt( result, ")\n%s{\n%s\n%s}" + result.append_fmt( ")\n%s{\n%s\n%s}" , indent_str , body()->to_string() , indent_str @@ -788,51 +790,60 @@ namespace gen case Function_Fwd: { - result = string_append_length( result, indent_str, tab_count ); + result.append( indent ); + + ProcessModuleFlags(); u32 idx = 0; u32 left = array_count( Entries ); - if ( Entries[idx]->Type == Specifiers ) + if ( Entries[idx]->Type == Attributes ) { - result = string_append_fmt( result, "%s\n", Entries[idx]->to_string() ); + result.append_fmt( "%s ", Entries[idx]->to_string() ); idx++; left--; } - result = string_append_fmt( result, "\n%s %s(", Entries[idx]->to_string(), Name ); + if ( Entries[idx]->Type == Specifiers ) + { + result.append_fmt( "%s\n", Entries[idx]->to_string() ); + idx++; + left--; + } + + result.append_fmt( "\n%s %s(", Entries[idx]->to_string(), Name ); idx++; left--; if ( left && Entries[idx]->Type == Parameters ) { - result = string_append_fmt( result, "%s", Entries[idx]->to_string() ); + result.append_fmt( "%s", Entries[idx]->to_string() ); idx++; left--; } else { - result = string_append_fmt( result, "void" ); + result.append( "void" ); } - result = string_appendc( result, ");\n" ); + result.append( ");\n" ); } break; case Module: - result = string_append_length( result, indent_str, tab_count ); + result.append( indent ); ProcessModuleFlags(); - result = string_append_fmt( result, "module %s", Content ); + result.append_fmt( "module %s", Content ); break; case Namespace: - result = string_append_length( result, indent_str, tab_count); + result.append( indent ); ProcessModuleFlags(); - result = string_append_fmt( result, "namespace %s\n%s{\n%s\n%s};\n" + result.append_fmt( "namespace %s\n%s{\n%s\n%s};\n" , Name , indent_str , body()->to_string() @@ -843,7 +854,7 @@ namespace gen case Operator: case Operator_Member: { - result = string_append_length( result, indent_str, tab_count ); + result.append( indent ); ProcessModuleFlags(); @@ -851,30 +862,30 @@ namespace gen if ( Entries[idx]->Type == Attributes ) { - result = string_append_fmt( result, "%s ", Entries[idx]->to_string() ); + result.append_fmt( "%s ", Entries[idx]->to_string() ); idx++; } if ( Entries[idx]->Type == Specifiers ) { - result = string_append_fmt( result, "%s\n", Entries[idx]->to_string() ); + result.append_fmt( "%s\n", Entries[idx]->to_string() ); idx++; } - result = string_append_fmt( result, "%s operator %s (", Entries[idx]->to_string(), Name ); + result.append_fmt( "%s operator %s (", Entries[idx]->to_string(), Name ); idx++; if ( Entries[idx]->Type == Parameters ) { - result = string_append_fmt( result, "%s", Entries[idx]->to_string() ); + result.append_fmt( "%s", Entries[idx]->to_string() ); idx++; } else { - result = string_append_fmt( result, "void" ); + result.append_fmt( "void" ); } - result = string_append_fmt( result, ")\n%s{\n%s\n%s}" + result.append_fmt( ")\n%s{\n%s\n%s}" , indent_str , body()->to_string() , indent_str @@ -885,7 +896,7 @@ namespace gen case Operator_Fwd: case Operator_Member_Fwd: { - result = string_append_length( result, indent_str, tab_count ); + result.append( indent ); ProcessModuleFlags(); @@ -893,34 +904,34 @@ namespace gen if ( Entries[idx]->Type == Specifiers ) { - result = string_append_fmt( result, "%s", Entries[idx]->to_string() ); + result.append_fmt( "%s", Entries[idx]->to_string() ); idx++; } - result = string_append_fmt( result, "%s operator%s(", Entries[idx]->to_string(), Name ); + result.append_fmt( "%s operator%s(", Entries[idx]->to_string(), Name ); idx++; if ( Entries[idx]->Type == Parameters ) { - result = string_append_fmt( result, "%s);\n", Entries[idx]->to_string() ); + result.append_fmt( "%s);\n", Entries[idx]->to_string() ); idx++; } else { - result = string_append_fmt( result, "void);\n" ); + result.append_fmt( "void);\n" ); } } break; case Parameters: { - result = string_append_fmt( result, "%s %s", Entries[0]->to_string(), Name ); + result.append_fmt( "%s %s", Entries[0]->to_string(), Name ); s32 index = 1; s32 left = array_count( Entries ) - 1; while ( left--, left > 0 ) - result = string_append_fmt( result, ", %s %s" + result.append_fmt( ", %s %s" , Entries[index]->Entries[0]->to_string() , Entries[index]->Name ); @@ -928,7 +939,7 @@ namespace gen break; case Preprocessor_Include: - result = string_append_fmt( result, "#include %s\n", Name ); + result.append_fmt( "#include %s\n", Name ); break; case Specifiers: @@ -936,62 +947,62 @@ namespace gen s32 idx = 0; s32 left = StaticIndex; while ( left--, left > 0 ) - result = string_append_fmt( result, "%s ", ESpecifier::to_str( ArrSpecs[idx]) ); + result.append_fmt( "%s ", ESpecifier::to_str( ArrSpecs[idx]) ); } break; case Struct: { - result = string_append_length( result, indent_str, tab_count ); + result.append( indent ); ProcessModuleFlags(); - result = string_append_fmt( result, "struct "); + result.append( "struct "); s32 idx = 1; if ( Entries[idx]->Type == Attributes ) { - result = string_append_fmt( result, "%s ", Entries[idx]->to_string() ); + result.append_fmt( "%s ", Entries[idx]->to_string() ); idx++; } - result = string_append_fmt( result, "%s ", Name ); + result.append_fmt( "%s ", Name ); if ( Entries[idx] ) { char const* access_str = to_str( ParentAccess ); - result = string_append_fmt( result, ": %s %s", access_str, Entries[idx]->to_string() ); + result.append_fmt( ": %s %s", access_str, Entries[idx]->to_string() ); } - result = string_append_fmt( result, "\n{\n%s\n};\n", body()->to_string() ); + result.append_fmt( "\n{\n%s\n};\n", body()->to_string() ); } break; case Struct_Fwd: { - result = string_append_length( result, indent_str, tab_count ); + result.append( indent ); ProcessModuleFlags(); - result = string_append_fmt( result, "struct "); + result.append( "struct "); s32 idx = 1; if ( Entries[idx]->Type == Specifiers ) { - result = string_append_fmt( result, "%s ", Entries[idx]->to_string() ); + result.append_fmt( "%s ", Entries[idx]->to_string() ); idx++; } - result = string_append_fmt( result, "%s;", Name ); + result.append_fmt( "%s;", Name ); } break; case Variable: { - result = string_append_length( result, indent_str, tab_count ); + result.append( indent ); ProcessModuleFlags(); @@ -999,19 +1010,19 @@ namespace gen if ( Entries[idx]->Type == Specifiers ) { - result = string_append_fmt( result, "%s", Entries[idx]->to_string() ); + result.append_fmt( "%s", Entries[idx]->to_string() ); idx++; } - result = string_append_fmt( result, "%s %s", Entries[0]->to_string(), Name ); + result.append_fmt( "%s %s", Entries[0]->to_string(), Name ); if ( Entries[idx] ) - result = string_append_fmt( result, " = %s", Entries[idx]->to_string() ); + result.append_fmt( " = %s", Entries[idx]->to_string() ); } break; case Typedef: - result = string_append_length( result, indent_str, tab_count ); + result.append( indent ); ProcessModuleFlags(); @@ -1019,48 +1030,48 @@ namespace gen if ( Entries[1] && Entries[1]->Type == Attributes ) { - result = string_append_fmt( result, "%s ", Entries[1]->to_string() ); + result.append_fmt( "%s ", Entries[1]->to_string() ); } - result = string_append_fmt( result, "typedef %s %s", type->to_string(), Name ); + result.append_fmt( "typedef %s %s", type->to_string(), Name ); if ( type->Entries[1] ) { - result = string_append_fmt( result, "[%s];", type->Entries[1]->to_string() ); + result.append_fmt( "[%s];", type->Entries[1]->to_string() ); } else { - result = string_append_length( result, ";", 1); + result.append( ";" ); } break; case Typename: if ( Entries[0] ) { - result = string_append_fmt( result, "%s %s", Name, Entries[0]->to_string() ); + result.append_fmt( "%s %s", Name, Entries[0]->to_string() ); } else { - result = string_append_fmt( result, "%s", Name ); + result.append_fmt( "%s", Name ); } break; case Union: - result = string_append_length( result, indent_str, tab_count ); + result.append( indent ); ProcessModuleFlags(); s32 idx = 0; - result = string_append_length( result, "union ", 6 ); + result.append( "union " ); if ( Entries[idx]->Type == Attributes ) { - result = string_append_fmt( result, "%s ", Entries[idx]->to_string() ); + result.append_fmt( "%s ", Entries[idx]->to_string() ); idx++; } - result = string_append_fmt( result, "%s\n%s{\n%s\n%s};\n" + result.append_fmt( "%s\n%s{\n%s\n%s};\n" , Name , indent_str , body()->to_string() @@ -1069,7 +1080,7 @@ namespace gen break; case Using: - result = string_append_length( result, indent_str, tab_count ); + result.append( indent ); ProcessModuleFlags(); @@ -1077,25 +1088,25 @@ namespace gen if ( Entries[1] && Entries[1]->Type == Attributes ) { - result = string_append_fmt( result, "%s ", Entries[1]->to_string() ); + result.append_fmt( "%s ", Entries[1]->to_string() ); } if ( type ) { - result = string_append_fmt( result, "using %s = %s", Name, type->to_string() ); + result.append_fmt( "using %s = %s", Name, type->to_string() ); if ( type->Entries[1] ) - result = string_append_fmt( result, "[%s]", type->Entries[1]->to_string() ); + result.append_fmt( "[%s]", type->Entries[1]->to_string() ); } else - result = string_append_fmt( result, "using %s", Name ); + result.append_fmt( "using %s", Name ); - result = string_append_fmt( result, ";" ); + result.append( ";" ); break; case Using_Namespace: - result = string_append_fmt( result, "using namespace %s", Name ); + result.append_fmt( "%susing namespace %s", indent_str, Name ); break; case Class_Body: @@ -1111,7 +1122,7 @@ namespace gen s32 left = num_entries(); while ( left -- ) { - result = string_append_fmt( result, "%s%s\n", indent_str, Entries[index]->to_string() ); + result.append_fmt( "%s%s\n", indent_str, Entries[index]->to_string() ); index++; } } @@ -1285,16 +1296,16 @@ namespace gen } // Will either make or retrive a code string. - StringCached get_cached_string( char const* cstr, s32 length ) + StringCached get_cached_string( StrC str ) { - s32 hash_length = length > kilobytes(1) ? kilobytes(1) : length; - u32 key = crc32( cstr, hash_length ); + s32 hash_length = str.Len > kilobytes(1) ? kilobytes(1) : str.Len; + u32 key = crc32( str.Ptr, hash_length ); String* result = str_tbl_get( & StaticData::StringMap, key ); if ( result ) return * result; - * result = string_make( get_string_allocator( length ), cstr ); + * result = String::make( get_string_allocator( str.Len ), str.Ptr ); str_tbl_set( & StaticData::StringMap, key, * result ); @@ -1334,9 +1345,9 @@ namespace gen Code result { rcast( AST*, alloc( allocator, sizeof(AST) )) }; - result->Content = nullptr; + result->Content = { nullptr }; result->Parent = nullptr; - result->Name = nullptr; + result->Name = { nullptr }; result->Type = ECode::Invalid; result->Op = EOperator::Invalid; result->ModuleFlags = ModuleFlag::Invalid; @@ -1736,19 +1747,19 @@ namespace gen #pragma region Helper Marcos // This snippet is used in nearly all the functions. -# define name_check( Context_, Length_, Name_ ) \ - { \ - if ( Length_ <= 0 ) \ - { \ - log_failure( "gen::" txt(Context_) ": Invalid name length provided - %d", length ); \ - return Code::Invalid; \ - } \ - \ - if ( Name_ == nullptr ) \ - { \ - log_failure( "gen::" txt(Context_) ": name is null" ); \ - return Code::Invalid; \ - } \ +# define name_check( Context_, Name_ ) \ + { \ + if ( Name_.Len <= 0 ) \ + { \ + log_failure( "gen::" txt(Context_) ": Invalid name length provided - %d", Name_.Len ); \ + return Code::Invalid; \ + } \ + \ + if ( Name_.Ptr == nullptr ) \ + { \ + log_failure( "gen::" txt(Context_) ": name is null" ); \ + return Code::Invalid; \ + } \ } # define null_check( Context_, Code_ ) \ @@ -1792,43 +1803,43 @@ namespace gen I decided to validate a good protion of their form and thus the argument processing for is quite a bit. */ - Code def_comment( s32 length, char const* content ) + Code def_comment( StrC content ) { - if ( length <= 0 || content == nullptr ) + if ( content.Len <= 0 || content.Ptr == nullptr ) { - log_failure( "gen::def_comment: Invalid comment provided", length ); + log_failure( "gen::def_comment: Invalid comment provided:" ); return Code::Invalid; } Code result = make_code(); result->Type = ECode::Comment; - result->Name = get_cached_string( content, length ); + result->Name = get_cached_string( content ); result->Content = result->Name; result.lock(); return result; } - Code def_attributes( s32 length, char const* content ) + Code def_attributes( StrC content ) { - if ( length <= 0 || content == nullptr ) + if ( content.Len <= 0 || content.Ptr == nullptr ) { - log_failure( "gen::def_attributes: Invalid attributes provided", length ); + log_failure( "gen::def_attributes: Invalid attributes provided" ); return Code::Invalid; } Code result = make_code(); result->Type = ECode::Attributes; - result->Name = get_cached_string( content, length ); + result->Name = get_cached_string( content ); result->Content = result->Name; result.lock(); return result; } - Code def_class( s32 length, char const* name + Code def_class( StrC name , Code body , Code parent, AccessSpec parent_access , Code attributes @@ -1836,7 +1847,7 @@ namespace gen { using namespace ECode; - name_check( def_class, length, name ); + name_check( def_class, name ); if ( attributes && attributes->Type != Attributes ) { @@ -1852,7 +1863,7 @@ namespace gen Code result = make_code(); - result->Name = get_cached_string( name, length ); + result->Name = get_cached_string( name ); result->ModuleFlags = mflags; if ( body ) @@ -1889,14 +1900,14 @@ namespace gen return result; } - Code def_enum( s32 length, char const* name + Code def_enum( StrC name , Code body, Code type , EnumT specifier, Code attributes , ModuleFlag mflags ) { using namespace ECode; - name_check( def_enum, length, name ); + name_check( def_enum, name ); if ( type && type->Type != Typename ) { @@ -1912,7 +1923,7 @@ namespace gen Code result = make_code(); - result->Name = get_cached_string( name, length ); + result->Name = get_cached_string( name ); result->ModuleFlags = mflags; if ( body ) @@ -1956,29 +1967,29 @@ namespace gen return result; } - Code def_execution( s32 length, char const* content ) + Code def_execution( StrC content ) { - if ( length <= 0 || content == nullptr ) + if ( content.Len <= 0 || content.Ptr == nullptr ) { - log_failure( "gen::def_execution: Invalid execution provided", length ); + log_failure( "gen::def_execution: Invalid execution provided" ); return Code::Invalid; } Code result = make_code(); result->Type = ECode::Execution; - result->Name = get_cached_string( content, length ); + result->Name = get_cached_string( content ); result->Content = result->Name; result.lock(); return result; } - Code def_extern_link( s32 length, char const* name, Code body, ModuleFlag mflags ) + Code def_extern_link( StrC name, Code body, ModuleFlag mflags ) { using namespace ECode; - name_check( def_extern_linkage, length, name ); + name_check( def_extern_linkage, name ); null_check( def_extern_linkage, body ); if ( body->Type != Extern_Linkage_Body || body->Type != Untyped ) @@ -1990,7 +2001,7 @@ namespace gen Code result = make_code(); result->Type = Extern_Linkage; - result->Name = get_cached_string( name, length ); + result->Name = get_cached_string( name ); result->ModuleFlags = mflags; result->add_entry( body ); @@ -2029,14 +2040,14 @@ namespace gen return result; } - Code def_function( s32 length, char const* name + Code def_function( StrC name , Code params , Code ret_type, Code body , Code specifiers, Code attributes , ModuleFlag mflags ) { using namespace ECode; - name_check( def_function, length, name ); + name_check( def_function, name ); if ( params && params->Type != Parameters ) { @@ -2064,7 +2075,7 @@ namespace gen Code result = make_code(); - result->Name = get_cached_string( name, length ); + result->Name = get_cached_string( name ); result->ModuleFlags = mflags; if ( body ) @@ -2112,43 +2123,43 @@ namespace gen return result; } - Code def_include ( s32 length, char const* path ) + Code def_include ( StrC path ) { - if ( length <= 0 || path == nullptr ) + if ( path.Len <= 0 || path.Ptr == nullptr ) { - log_failure( "gen::def_include: Invalid path provided - %d", length ); + log_failure( "gen::def_include: Invalid path provided - %d" ); return Code::Invalid; } Code result = make_code(); result->Type = ECode::Preprocessor_Include; - result->Name = get_cached_string( path, length ); + result->Name = get_cached_string( path ); result->Content = result->Name; result.lock(); return result; } - Code def_module( s32 length, char const* name, ModuleFlag mflags ) + Code def_module( StrC name, ModuleFlag mflags ) { - name_check( def_module, length, name ); + name_check( def_module, name ); Code result = make_code(); result->Type = ECode::Module; - result->Name = get_cached_string( name, length ); + result->Name = get_cached_string( name ); result->ModuleFlags = mflags; result.lock(); return result; } - Code def_namespace( s32 length, char const* name, Code body, ModuleFlag mflags ) + Code def_namespace( StrC name, Code body, ModuleFlag mflags ) { using namespace ECode; - name_check( def_namespace, length, name ); + name_check( def_namespace, name ); null_check( def_namespace, body ); if ( body->Type != Namespace_Body || body->Type != Untyped ) @@ -2160,7 +2171,7 @@ namespace gen Code result = make_code(); result->Type = Namespace; - result->Name = get_cached_string( name, length ); + result->Name = get_cached_string( name ); result->Entries = make_code_entries(); result->ModuleFlags = mflags; @@ -2206,7 +2217,7 @@ namespace gen Code result = make_code(); - result->Name = get_cached_string( name, str_len(name, MaxNameLength) ); + result->Name = get_cached_string( { str_len(name), name } ); result->ModuleFlags = mflags; if ( body ) @@ -2237,11 +2248,11 @@ namespace gen return result; } - Code def_param( Code type, s32 length, char const* name, Code value ) + Code def_param( Code type, StrC name, Code value ) { using namespace ECode; - name_check( def_param, length, name ); + name_check( def_param, name ); null_check( def_param, type ); if ( type->Type != Typename ) @@ -2259,7 +2270,7 @@ namespace gen Code result = make_code(); result->Type = Parameters; - result->Name = get_cached_string( name, length ); + result->Name = get_cached_string( name ); result->add_entry( type ); @@ -2270,7 +2281,7 @@ namespace gen return result; } - Code def_struct( u32 length, char const* name + Code def_struct( StrC name , Code body , Code parent, AccessSpec parent_access , Code attributes @@ -2278,7 +2289,7 @@ namespace gen { using namespace ECode; - name_check( def_struct, length, name ); + name_check( def_struct, name ); if ( attributes && attributes->Type != Attributes ) { @@ -2300,7 +2311,7 @@ namespace gen Code result = make_code(); - result->Name = get_cached_string( name, length ); + result->Name = get_cached_string( name ); result->ModuleFlags = mflags; if ( body ) @@ -2326,44 +2337,9 @@ namespace gen return result; } - Code def_typedef( u32 length, char const* name, Code type, Code attributes, ModuleFlag mflags ) + Code def_type( StrC name, Code ArrayExpr, Code specifiers ) { - name_check( def_typedef, length, name ); - null_check( def_typedef, type ); - - if ( type->Type != ECode::Typename ) - { - log_failure( "gen::def_typedef: type was not a Typename" ); - return Code::Invalid; - } - - // Registering the type. - Code registered_type = def_type( length, name ); - - if ( ! registered_type ) - { - log_failure( "gen::def_typedef: failed to register type" ); - return Code::Invalid; - } - - Code - result = make_code(); - result->Name = get_cached_string( name, length ); - result->Type = ECode::Typedef; - result->ModuleFlags = mflags; - - result->add_entry( type ); - - if ( attributes ) - result->add_entry( attributes ); - - result.lock(); - return result; - } - - Code def_type( u32 length, char const* name, Code ArrayExpr, Code specifiers ) - { - name_check( def_type, length, name ); + name_check( def_type, name ); if ( specifiers && specifiers->Type != ECode::Specifiers ) { @@ -2373,7 +2349,7 @@ namespace gen Code result = make_code(); - result->Name = get_cached_string( name, length ); + result->Name = get_cached_string( name ); result->Type = ECode::Typename; if ( specifiers ) @@ -2386,9 +2362,44 @@ namespace gen return result; } - Code def_union( s32 length, char const* name, Code body, Code attributes, ModuleFlag mflags ) + Code def_typedef( StrC name, Code type, Code attributes, ModuleFlag mflags ) { - name_check( def_union, length, name ); + name_check( def_typedef, name ); + null_check( def_typedef, type ); + + if ( type->Type != ECode::Typename ) + { + log_failure( "gen::def_typedef: type was not a Typename" ); + return Code::Invalid; + } + + // Registering the type. + Code registered_type = def_type( name ); + + if ( ! registered_type ) + { + log_failure( "gen::def_typedef: failed to register type" ); + return Code::Invalid; + } + + Code + result = make_code(); + result->Name = get_cached_string( name ); + result->Type = ECode::Typedef; + result->ModuleFlags = mflags; + + result->add_entry( type ); + + if ( attributes ) + result->add_entry( attributes ); + + result.lock(); + return result; + } + + Code def_union( StrC name, Code body, Code attributes, ModuleFlag mflags ) + { + name_check( def_union, name ); if ( body && body->Type != ECode::Union_Body ) { @@ -2398,7 +2409,7 @@ namespace gen Code result = make_code(); - result->Name = get_cached_string( name, length ); + result->Name = get_cached_string( name ); result->ModuleFlags = mflags; if ( body ) @@ -2418,15 +2429,15 @@ namespace gen return result; } - Code def_using( u32 length, char const* name, UsingT specifier + Code def_using( StrC name, UsingT specifier , Code type , Code attributes , ModuleFlag mflags ) { - name_check( def_using, length, name ); + name_check( def_using, name ); null_check( def_using, type ); - Code register_type = def_type( length, name ); + Code register_type = def_type( name ); if ( ! register_type ) { @@ -2436,7 +2447,7 @@ namespace gen Code result = make_code(); - result->Name = get_cached_string( name, length ); + result->Name = get_cached_string( name ); result->ModuleFlags = mflags; switch ( specifier ) @@ -2460,11 +2471,11 @@ namespace gen return result; } - Code def_variable( Code type, u32 length, char const* name, Code value + Code def_variable( Code type, StrC name, Code value , Code specifiers, Code attributes , ModuleFlag mflags ) { - name_check( def_variable, length, name ); + name_check( def_variable, name ); null_check( def_variable, type ); if ( attributes && attributes->Type != ECode::Attributes ) @@ -2493,7 +2504,7 @@ namespace gen Code result = make_code(); - result->Name = get_cached_string( name, length ); + result->Name = get_cached_string( name ); result->Type = ECode::Variable; result->ModuleFlags = mflags; @@ -2883,7 +2894,7 @@ namespace gen s32 name_length = va_arg(va, s32 ); char const* name = va_arg(va, char const*); - result->Name = get_cached_string( name, name_length ); + result->Name = get_cached_string( { name_length, name } ); if ( type->Type != Typename ) { @@ -2902,7 +2913,7 @@ namespace gen Code param = make_code(); param->Type = Parameters; - param->Name = get_cached_string(name, name_length); + param->Name = get_cached_string( { name_length, name } ); if ( type->Type != Typename ) { @@ -3095,14 +3106,14 @@ namespace gen #pragma region Incremetnal Constructors #ifdef GEN_FEATURE_INCREMENTAL - Code make_class( s32 length, char const* name + Code make_class( StrC name , Code parent, AccessSpec parent_access , Code specifiers, Code attributes , ModuleFlag mflags ) { using namespace ECode; - name_check( make_struct, length, name ); + name_check( make_struct, name ); if ( attributes && attributes->Type != Attributes ) { @@ -3125,7 +3136,7 @@ namespace gen Code result = make_code(); result->Type = Struct; - result->Name = get_cached_string( name, length ); + result->Name = get_cached_string( name ); result->ModuleFlags = mflags; Code @@ -3146,11 +3157,11 @@ namespace gen return result; } - Code make_enum( s32 length, char const* name, Code type, EnumT specifier, Code attributes, ModuleFlag mflags ) + Code make_enum( StrC name, Code type, EnumT specifier, Code attributes, ModuleFlag mflags ) { using namespace ECode; - name_check( make_enum, length, name ); + name_check( make_enum, name ); if ( attributes && attributes->Type != Attributes ) { @@ -3167,7 +3178,7 @@ namespace gen Code result = make_code(); result->Type = specifier == EnumClass ? Enum_Class : Enum; - result->Name = get_cached_string( name, length ); + result->Name = get_cached_string( name ); result->ModuleFlags = mflags; Code @@ -3182,7 +3193,7 @@ namespace gen return result; } - Code make_export_body( s32 length, char const* name ) + Code make_export_body( StrC name ) { using namespace ECode; @@ -3190,37 +3201,36 @@ namespace gen result = make_code(); result->Type = Export_Body; - if ( name && length > 0 ) - result->Name = get_cached_string( name, length ); + if ( name && name.Len > 0 ) + result->Name = get_cached_string( name ); return result; } - Code make_extern_linkage( s32 length, char const* name, ModuleFlag mflags ) + Code make_extern_linkage( StrC name, ModuleFlag mflags ) { using namespace ECode; - name_check( make_extern_linkage, length, name); + name_check( make_extern_linkage, name); Code result = make_code(); result->Type = Extern_Linkage; - result->Name = get_cached_string( name, length ); + result->Name = get_cached_string( name ); result->ModuleFlags = mflags; return result; } - Code make_function( s32 length, char const* name + Code make_function( StrC name , Code params, Code ret_type , Code specifiers, Code attributes , ModuleFlag mflags - ) { using namespace ECode; - name_check( make_function, length, name ); + name_check( make_function, name ); if ( attributes && attributes->Type != Attributes ) { @@ -3248,7 +3258,7 @@ namespace gen Code result = make_code(); - result->Name = get_cached_string( name, length ); + result->Name = get_cached_string( name ); result->Type = Function; result->ModuleFlags = mflags; @@ -3273,28 +3283,28 @@ namespace gen return result; } - Code make_global_body( s32 length, char const* name ) + Code make_global_body( StrC name ) { - name_check( make_global_body, length, name ); + name_check( make_global_body, name ); Code result = make_code(); result->Type = ECode::Global_Body; - if ( length > 0 ) - result->Name = get_cached_string( name, length ); + if ( name.Len > 0 ) + result->Name = get_cached_string( name ); return result; } - Code make_namespace( s32 length, char const* name, Code parent, ModuleFlag mflags ) + Code make_namespace( StrC name, Code parent, ModuleFlag mflags ) { - name_check( make_namespace, length, name ); + name_check( make_namespace, name ); Code result = make_code(); result->Type = ECode::Namespace; - result->Name = get_cached_string( name, length ); + result->Name = get_cached_string( name ); result->ModuleFlags = mflags; Code @@ -3327,7 +3337,7 @@ namespace gen Code result = make_code(); - result->Name = get_cached_string( name, str_len(name, MaxNameLength) ); + result->Name = get_cached_string( { str_len(name, MaxNameLength), name } ); result->ModuleFlags = mflags; if ( attributes ) @@ -3362,11 +3372,11 @@ namespace gen return result; } - Code make_struct( s32 length, char const* name, Code parent, Code specifiers, Code attributes, ModuleFlag mflags ) + Code make_struct( StrC name, Code parent, Code specifiers, Code attributes, ModuleFlag mflags ) { using namespace ECode; - name_check( make_struct, length, name ); + name_check( make_struct, name ); if ( attributes && attributes->Type != Attributes ) { @@ -3389,7 +3399,7 @@ namespace gen Code result = make_code(); result->Type = Struct; - result->Name = get_cached_string( name, length ); + result->Name = get_cached_string( name ); result->ModuleFlags = mflags; Code @@ -3588,7 +3598,7 @@ namespace gen if ( Arr[0].Type != type ) { - String token_str = string_make_length( g_allocator, Arr[Idx].Text, Arr[Idx].Length ); + String token_str = String::make( g_allocator, { Arr[Idx].Length, Arr[Idx].Text } ); log_failure( "gen::%s: expected %s, got %s", context, str_tok_type(type), str_tok_type(Arr[Idx].Type) ); @@ -3978,7 +3988,7 @@ namespace gen } else { - String context_str = zpl::string_sprintf_buf( g_allocator, "%s", scanner, min( 100, left ) ); + String context_str = String::fmt_buf( g_allocator, "%s", scanner, min( 100, left ) ); log_failure( "Failed to lex token %s", context_str ); @@ -4009,7 +4019,7 @@ namespace gen // Its most likely an identifier... - String tok_str = zpl::string_sprintf_buf( g_allocator, "%s", token.Text, token.Length ); + String tok_str = String::fmt_buf( g_allocator, "%s", token.Text, token.Length ); log_failure( "Failed to lex token %s", tok_str ); @@ -4486,7 +4496,8 @@ namespace gen switch ( currtok.Type ) { case TokType::Comment: - // TODO: Add comment to function body? + member = def_comment( currtok.Length, currtok.Text ); + eat( TokType::Comment ); break; case TokType::Decl_Class: @@ -5437,12 +5448,12 @@ namespace gen return result; } - Code parse_variable( s32 length, char const* def ) + Code parse_variable( StrC def ) { - check_parse_args( parse_variable, length, def ); + check_parse_args( parse_variable, def ); using namespace Parser; - TokArray toks = lex( length, def ); + TokArray toks = lex( def ); if ( toks.Arr == nullptr ) return Code::Invalid; @@ -5547,7 +5558,7 @@ namespace gen return result; } - Code untyped_str( s32 length, char const* str ) + Code untyped_str( StrC content ) { Code result = make_code(); @@ -5604,7 +5615,7 @@ namespace gen #pragma region Builder void Builder::print( Code code ) { - Buffer = string_append_fmt( Buffer, "%s\n\n", code.to_string() ); + Buffer.append_fmt( "%s\n\n", code.to_string() ); } bool Builder::open( char const* path ) diff --git a/project/gen.hpp b/project/gen.hpp index e33c2a0..3aa2ce7 100644 --- a/project/gen.hpp +++ b/project/gen.hpp @@ -11,7 +11,7 @@ #include "Bloat.hpp" // Temporarily here for debugging purposes. -#define GEN_DEFINE_DSL +// #define GEN_DEFINE_DSL #define GEN_DEFINE_LIBRARY_CODE_CONSTANTS // #define GEN_DONT_USE_FATAL #define GEN_ENFORCE_READONLY_AST @@ -94,11 +94,11 @@ namespace gen }; inline - char const* to_str( Type type ) + StrC to_str( Type type ) { static - char const* lookup[Num_Types] = { - # define Entry( Type ) txt( Type ), + StrC lookup[Num_Types] = { + # define Entry( Type ) { txt_n_len( Type ) }, Define_Types # undef Entry }; @@ -248,11 +248,11 @@ namespace gen // Specifier to string inline - char const* to_str( Type specifier ) + StrC to_str( Type specifier ) { local_persist - char const* lookup[ Num_Specifiers ] = { - # define Entry( Spec_, Code_ ) txt(Code_), + StrC lookup[ Num_Specifiers ] = { + # define Entry( Spec_, Code_ ) { txt_n_len(Code_) }, Define_Specifiers # undef Entry }; @@ -261,20 +261,20 @@ namespace gen } inline - Type to_type( char const* str, s32 length ) + Type to_type( StrC str ) { local_persist u32 keymap[ Num_Specifiers ]; do_once_start for ( u32 index = 0; index < Num_Specifiers; index++ ) { - char const* enum_str = to_str( (Type)index ); + StrC enum_str = to_str( (Type)index ); - keymap[index] = crc32( enum_str, str_len(enum_str, 42) ); + keymap[index] = crc32( enum_str.Ptr, enum_str.Len); } do_once_end - u32 hash = crc32(str, length ); + u32 hash = crc32( str.Ptr, str.Len ); for ( u32 index = 0; index < Num_Specifiers; index++ ) { @@ -371,7 +371,7 @@ namespace gen // Represents strings cached with the string table. // Should never be modified, if changed string is desired, cache_string( str ) another. - using StringCached = char const*; + using StringCached = String const; // Desired width of the AST data structure. constexpr u32 AST_POD_Size = 256; @@ -424,7 +424,7 @@ namespace gen // Parameter - bool add_param( AST* type, s32 length, char const* name ); + bool add_param( AST* type, StrC name ); inline AST* get_param( s32 index ) @@ -638,7 +638,7 @@ namespace gen } inline - char const* to_string() + String to_string() { return ast->to_string(); } @@ -743,7 +743,7 @@ namespace gen // Used internally to retrive or make string allocations. // Strings are stored in a series of string arenas of fixed size (SizePer_StringArena) - StringCached get_cached_string( char const* cstr, s32 length ); + StringCached get_cached_string( StrC str ); /* This provides a fresh Code AST. @@ -767,58 +767,58 @@ namespace gen void set_allocator_type_table ( AllocatorInfo type_reg_allocator ); # pragma region Upfront - Code def_comment ( s32 length, char const* content ); - Code def_attributes( s32 length, char const* content ); + Code def_comment ( StrC content ); + Code def_attributes( StrC content ); - Code def_class( s32 length, char const* name + Code def_class( StrC name , Code body = NoCode , Code parent = NoCode, AccessSpec access = AccessSpec::Public , Code attributes = NoCode , ModuleFlag mflags = ModuleFlag::None ); - Code def_enum( s32 length, char const* name + Code def_enum( StrC , Code body = NoCode, Code type = NoCode , EnumT specifier = EnumRegular, Code attributes = NoCode , ModuleFlag mflags = ModuleFlag::None ); - Code def_execution ( s32 length, char const* content ); - Code def_extern_link( s32 length, char const* name, Code body, ModuleFlag mflags = ModuleFlag::None ); + Code def_execution ( StrC content ); + Code def_extern_link( StrC name, Code body, ModuleFlag mflags = ModuleFlag::None ); Code def_friend ( Code symbol ); - Code def_function( s32 length, char const* name + Code def_function( StrC name , Code params = NoCode, Code ret_type = NoCode, Code body = NoCode , Code specifiers = NoCode, Code attributes = NoCode , ModuleFlag mflags = ModuleFlag::None ); - Code def_include ( s32 length, char const* path ); - Code def_module ( s32 length, char const* name, ModuleFlag mflags = ModuleFlag::None ); - Code def_namespace( s32 length, char const* name, Code body, ModuleFlag mflags = ModuleFlag::None ); + Code def_include ( StrC content ); + Code def_module ( StrC name, ModuleFlag mflags = ModuleFlag::None ); + Code def_namespace( StrC name, Code body, ModuleFlag mflags = ModuleFlag::None ); Code def_operator( OperatorT op , Code params = NoCode, Code ret_type = NoCode, Code body = NoCode , Code specifiers = NoCode, Code attributes = NoCode , ModuleFlag mflags = ModuleFlag::None ); - Code def_param ( Code type, s32 length, char const* name, Code value = NoCode ); + Code def_param ( Code type, StrC name, Code value = NoCode ); Code def_specifier( SpecifierT specifier ); - Code def_struct( s32 length, char const* name + Code def_struct( StrC name , Code body , Code parent = NoCode, AccessSpec access = AccessSpec::Public , Code attributes = NoCode , ModuleFlag mflags = ModuleFlag::None ); - Code def_typedef( s32 length, char const* name, Code type, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); - Code def_type ( s32 length, char const* name, Code arrayexpr = NoCode, Code specifiers = NoCode ); + Code def_typedef( StrC name, Code type, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); + Code def_type ( StrC name, Code arrayexpr = NoCode, Code specifiers = NoCode ); - Code def_union( s32 length, char const* name, Code body = NoCode, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); + Code def_union( StrC name, Code body = NoCode, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); - Code def_using( s32 length, char const* name, UsingT specifier = UsingRegular + Code def_using( StrC name, UsingT specifier = UsingRegular , Code type = NoCode , Code attributess = NoCode , ModuleFlag mflags = ModuleFlag::None ); - Code def_variable( Code type, s32 length, char const* name, Code value = NoCode + Code def_variable( Code type, StrC name, Code value = NoCode , Code specifiers = NoCode, Code attributes = NoCode , ModuleFlag mflags = ModuleFlag::None ); @@ -847,24 +847,24 @@ namespace gen # pragma region Incremental # ifdef GEN_FEATURE_INCREMENTAL - Code make_class( s32 length, char const* name + Code make_class( StrC name , Code parent = NoCode, AccessSpec access = AccessSpec::Public , Code specifiers = NoCode, Code attributes = NoCode , ModuleFlag mflags = ModuleFlag::None ); - Code make_enum( s32 length, char const* name + Code make_enum( StrC name , Code type = NoCode, EnumT specifier = EnumRegular , Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); - Code make_export_body ( s32 length = 1, char const* name = "" ); + Code make_export_body ( StrC name = { 1, "" } ); Code make_extern_linkage( s32 length, char const* name, ModuleFlag mflags = ModuleFlag::None ); - Code make_function( s32 length, char const* name + Code make_function( StrC name , Code params = NoCode, Code ret_type = NoCode , Code specifiers = NoCode, Code attributes = NoCode , ModuleFlag mflags = ModuleFlag::None ); - Code make_global_body( s32 length = 1, char const* name = "" ); + Code make_global_body( StrC name = { 1, "" } ); Code make_namespace ( s32 length, char const* name, ModuleFlag mflags = ModuleFlag::None ); Code make_operator( OperatorT op @@ -875,32 +875,32 @@ namespace gen Code make_params (); Code make_specifiers(); - Code make_struct( s32 length, char const* name + Code make_struct( StrC name , Code parent = NoCode, AccessSpec access , Code specifiers = NoCode, Code attributes = NoCode , ModuleFlag mflags = ModuleFlag::None ); - Code make_union( s32 length, char const* name, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); + Code make_union( StrC name, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); # endif # pragma endregion Incremental #pragma region Parsing #ifdef GEN_FEATURE_PARSING - Code parse_class ( s32 length, char const* class_def ); - Code parse_enum ( s32 length, char const* enum_def ); - Code parse_export_body( s32 length, char const* export_def ); - Code parse_exten_link ( s32 length, char const* exten_link_def); - Code parse_friend ( s32 length, char const* friend_def ); - Code parse_function ( s32 length, char const* fn_def ); - Code parse_global_body( s32 length, char const* body_def ); - Code parse_namespace ( s32 length, char const* namespace_def ); - Code parse_operator ( s32 length, char const* operator_def ); - Code parse_struct ( s32 length, char const* struct_def ); - Code parse_type ( s32 length, char const* type_def ); - Code parse_typedef ( s32 length, char const* typedef_def ); - Code parse_union ( s32 length, char const* union_def ); - Code parse_using ( s32 length, char const* using_def ); - Code parse_variable ( s32 length, char const* var_def ); + Code parse_class ( StrC class_def ); + Code parse_enum ( StrC enum_def ); + Code parse_export_body( StrC export_def ); + Code parse_exten_link ( StrC exten_link_def); + Code parse_friend ( StrC friend_def ); + Code parse_function ( StrC fn_def ); + Code parse_global_body( StrC body_def ); + Code parse_namespace ( StrC namespace_def ); + Code parse_operator ( StrC operator_def ); + Code parse_struct ( StrC struct_def ); + Code parse_type ( StrC type_def ); + Code parse_typedef ( StrC typedef_def ); + Code parse_union ( StrC union_def ); + Code parse_using ( StrC using_def ); + Code parse_variable ( StrC var_def ); #endif #pragma endregion Parsing @@ -921,9 +921,9 @@ namespace gen return buf; } - Code untyped_str ( s32 length, char const* str); - Code untyped_fmt ( char const* fmt, ... ); - Code untyped_token_fmt( char const* fmt, s32 num_tokens, ... ); + Code untyped_str ( StrC content); + Code untyped_fmt ( char const* fmt, ... ); + Code untyped_token_fmt( char const* fmt, s32 num_tokens, ... ); #pragma endregion Untyped text struct Builder @@ -1058,10 +1058,10 @@ namespace gen // Convienence for defining any name used with the gen interface. // Lets you provide the length and string literal to the functions without the need for the DSL. -# define name( Id_ ) txt_n_len( Id_ ) +# define name( Id_ ) { txt_n_len( Id_ ) } // Same as name just used to indicate intention of literal for code instead of names. -# define code( Code_ ) txt_n_len( Code_ ) +# define code( Code_ ) { txt_n_len( Code_ ) } /* gen's Domain Specific Langauge. @@ -1285,7 +1285,7 @@ namespace gen } inline - bool AST::add_param( AST* type, s32 length, char const* name ) + bool AST::add_param( AST* type, StrC name ) { if ( Type != ECode::Function ) { @@ -1293,9 +1293,9 @@ namespace gen return Code::Invalid; } - if ( length <= 0 ) + if ( name.Len <= 0 ) { - log_failure( "gen::AST::add_param: Invalid name length provided - %d", length ); + log_failure( "gen::AST::add_param: Invalid name length provided - %d", name.Len ); return Code::Invalid; } @@ -1317,7 +1317,7 @@ namespace gen } else if ( score == 2) { - Name = name; + Name = get_cached_string( name ); Entries[0] = type; return true; } diff --git a/test/NonParsed/Array.NonParsed.hpp b/test/NonParsed/Array.NonParsed.hpp new file mode 100644 index 0000000..92beb98 --- /dev/null +++ b/test/NonParsed/Array.NonParsed.hpp @@ -0,0 +1,231 @@ +#pragma once + +#if gen_time +#include "gen.hpp" + +using namespace gen; + +Code gen__array_base() +{ + Code t_allocator_info = def_type( name(AllocatorInfo) ); + Code header; + { + Code allocator = def_variable( t_allocator_info, name(Allocator) ); + Code capacity = def_variable( t_uw, name(Capacity) ); + Code num = def_variable( t_uw, name(Num) ); + + Code body = def_struct_body( 3, allocator, capacity, num ); + header = def_struct( name(Header), body ); + } + + Code grow_formula; + { + Code params = def_param( t_uw, name(value)); + Code body = untyped_str( code( return 2 * value * 8; )); + + Code spec = def_specifiers( ESpecifier::Static_Member, ESpecifier::Inline ); + + grow_formula = def_function( name(grow_formula), params, t_uw, body, spec ); + } + + Code body = def_struct_body( 2, header, grow_formula ); + Code array_base = def_struct( name(ArrayBase), body ); + + return array_base; +} + +Code gen__array( StrC type, sw type_size ) +{ + Code t_allocator_info = def_type( name(AllocatorInfo) ); + Code v_nullptr = untyped_str( code(nullptr)); + + static Code ArrayBase = gen__array_base(); + + StrC name; + { + char const* name_str = str_fmt_buf( "Array_%s", type.Ptr ); + s32 name_len = str_len( name ); + + name = { name_len, name_str }; + }; + + Code t_array_type = def_type( name ); + + Code t_type = def_type( type ); + Code t_type_ptr = def_type( type, __, spec_ptr ); + Code t_type_ref = def_type( type, __, spec_ref ); + + Code t_header = def_type( name(Header) ); + Code t_header_ptr = def_type( name(Header), __, spec_ptr ); + Code t_header_ref = def_type( name(Header), __, spec_ref ); + + Code spec_static_inline = def_specifiers( ESpecifier::Static_Member, ESpecifier::Inline ); + Code spec_static = def_specifiers( ESpecifier::Static_Member ); + + Code array; + { + Code using_type = def_using( name(Type), UsingRegular, t_type ); + Code data = def_variable( t_type_ptr, name(Data) ); + + Code init; + { + Code params = def_param( t_allocator_info, name(allocator) ); + Code body = untyped_str( code( + return init_reserve( allocator, grow_formula(0) ); + )); + + init = def_function( name(init), params, t_array_type, body, spec_static ); + } + + Code init_reserve; + { + Code params = def_params( 2, t_allocator_info, name(allocator), t_sw, name(capacity) ); + Code body = untyped_str( code( + Header* header = rcast( Header*, alloc( allocator, sizeof(Header) + sizeof(Type) )); + + if ( header == nullptr ) + return false; + + header->Allocator = allocator; + header->Capacity = capacity; + header->Num = 0; + + Data = rcast( Type*, header + 1 ); + + return true; + )); + + init_reserve = def_function( name(init_reserve), params, t_array_type, body, spec_static ); + } + + Code append; + { + Code params = def_param( t_type, name(value)); + + Code body = untyped_str( code( + Header& header = get_header(); + + if ( header.Num == header.Capacity ) + { + if ( ! grow( header.Allocator )) + return false; + } + + data[ header.Num ] = value; + header.Num++; + + return true; + )); + + append = def_function( name(append), params, t_bool, body ); + } + + Code back; + { + Code body = untyped_str( code( + Header& header = get_header(); + return Data[ header.Num - 1 ]; + )); + + back = def_function( name(back), __, t_type_ref, body ); + } + + Code clear; + Code fill; + + Code free; + { + Code body = untyped_str( code( + Header& header = get_header(); + ::free( header.Allocator, & header ); + )); + + free = def_function( name(free), __, t_void, body, spec_inline ); + } + + Code get_header; + Code grow; + Code pop; + Code reserve; + Code resize; + Code set_capacity; + + Code body = def_struct_body( 17 + , using_type + + , init + , init_reserve + + , append + , back + , clear + , fill + , free + , get_header + , grow + , pop + , reserve + , resize + , set_capacity + + , data + ); + + array = def_struct( name, body ); + } + + return array; +} + + +struct GenArrayRequest +{ + StrC Type; + StrC Dependency; + sw Size; +}; +Array(GenArrayRequest) GenArrayRequests; + +void gen__array_request( StrC type, StrC dep, sw size ) +{ + GenArrayRequest request = { type, dep, size }; + array_append( GenArrayRequests, request ); +} +#define Gen_Array( type ) gen__array_request( txt_n_len( type ), sizeof(type) ) + +u32 gen_array_file() +{ + Builder + gen_array_file; + gen_array_file.open( "array.gen.hpp" ); + + + GenArrayRequest* current = GenArrayRequests; + s32 left = array_count( GenArrayRequests ); + while (left--) + { + GenArrayRequest const& request = * current; + + Code generated_array = gen__array( request.Type, request.Size ); + + if ( request.Dependency ) + { + char const* cmt_str = str_fmt_buf( "// Dependency for %s type", request.Type ); + s32 cmt_len = str_len( cmt_str ); + + Code cmt = def_comment( { cmt_len, cmt_str } ); + Code include = def_include( request.Dependency ); + + gen_array_file.print( cmt ); + gen_array_file.print( include ); + } + + gen_array_file.print( generated_array ); + current++; + } + + gen_array_file.write(); + return 0; +} + +#endif diff --git a/test/Parsed/Array.Parsed.hpp b/test/Parsed/Array.Parsed.hpp new file mode 100644 index 0000000..571bf82 --- /dev/null +++ b/test/Parsed/Array.Parsed.hpp @@ -0,0 +1,170 @@ +#pragma once + +#if gen_time +#include "gen.hpp" + +using namespace gen; + +Code gen__array_base() +{ + Code array_base = parse_struct( code( + struct ArrayBase + { + struct Header + { + AllocatorInfo Allocator; + uw Capacity; + uw Num; + }; + + static inline + sw grow_formula( sw value ) + { + return 2 * value * 8; + } + }; + )); + + return array_base; +} + +Code gen__array( s32 length, char const* type_str, sw type_size ) +{ + StrC tmpl = code( + struct Array_{type} : ArrayBase + { + using Type = {type}; + + Type* Data; + + static Array_{type} init( AllocatorInfo allocator ) + { + return init_reserve( allocator, grow_formula(0) ); + } + + static Array_{type} init_reserve( AllocatorInfo allocator, uw capacity ) + { + Header* header = rcast( Header*, alloc( allocator, sizeof(Header) + sizeof(Type) )); + + if ( header == nullptr ) + return false; + + header->Allocator = allocator; + header->Capacity = capacity; + header->Num = 0; + + Array_{type} array; + array.Data = rcast( Type*, header + 1 ); + + return array; + } + + bool append( Type const& value ) + { + Header& header = get_header(); + + if ( header.Num == header.Capacity ) + { + if ( ! grow( header.Allocator )) + return false; + } + + data[ header.Num ] = value; + header.Num++; + + return true; + } + + Type& back() + { + Header& header = get_header(); + return data[ header.Num - 1 ]; + } + + void clear(); + + bool fill(); + + void free() + { + Header& header = get_header(); + ::free( header.Allocator, & header ); + } + + Header& get_header() + { + return rcast( Header*, Data ) - 1; + } + + bool grow(); + + void pop(); + + bool reserve( uw num ); + + bool resize( uw num ); + + bool set_capacity( uw capacity ); + } + ); + + char const* gen_from_tmpl = token_fmt( tmpl.Ptr, 1, "type", type_str ); + s32 gen_from_tmpl_len = str_len( gen_from_tmpl ); + + Code array = parse_struct( { gen_from_tmpl_len, gen_from_tmpl } ); +} + + +struct GenArrayRequest +{ + s32 TypeLength; + char const* Type; + sw Size; + s32 DependencyLength; + char const* Dependency; +}; +Array(GenArrayRequest) GenArrayRequests; + +void gen__array_request( s32 type_len, char const* type_str, sw type_size, s32 dep_len, char const* dep ) +{ + GenArrayRequest request = { type_len, type_str, type_size, dep_len, dep }; + array_append( GenArrayRequests, request ); +} +#define Gen_Array( type ) gen__array_request( txt_n_len( type ), sizeof(type) ) + +u32 gen_array_file() +{ + Builder + gen_array_file; + gen_array_file.open( "array.gen.hpp" ); + + + GenArrayRequest* current = GenArrayRequests; + s32 left = array_count( GenArrayRequests ); + while (left--) + { + GenArrayRequest const& request = * current; + + Code generated_array = gen__array( request.TypeLength, request.Type, request.Size ); + + if ( request.Dependency ) + { + char const* cmt_str = str_fmt_buf( "// Dependency for %s type", request.Type ); + s32 cmt_len = str_len( cmt_str ); + + Code cmt = def_comment( { cmt_len, cmt_str } ); + Code include = def_include( { request.DependencyLength, request.Dependency } ); + + gen_array_file.print( cmt ); + gen_array_file.print( include ); + } + + gen_array_file.print( generated_array ); + current++; + } + + gen_array_file.write(); + return 0; +} + +#endif