From 0192cd49ef2d8767cd995d41c18b5e13d64232bc Mon Sep 17 00:00:00 2001 From: Ed_ Date: Wed, 28 Jun 2023 14:43:21 -0400 Subject: [PATCH] Started sanity test suite (Non-parsed api) Made some fixes based on errors found while iterating on first generation --- .vscode/launch.json | 4 +- .vscode/settings.json | 3 +- Readme.md | 41 -------- project/Bloat.hpp | 30 +++--- project/gen.cpp | 149 ++++++++++++++++++++--------- project/gen.hpp | 3 +- test/NonParsed/Array.NonParsed.hpp | 4 +- test/NonParsed/Sanity.hpp | 47 +++++++++ test/gen/sanity.gen.hpp | 12 +++ test/test.cpp | 7 +- 10 files changed, 192 insertions(+), 108 deletions(-) create mode 100644 test/NonParsed/Sanity.hpp create mode 100644 test/gen/sanity.gen.hpp diff --git a/.vscode/launch.json b/.vscode/launch.json index c05ad50..70945c9 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,7 +10,7 @@ "name": "Debug gentime lldb", "program": "${workspaceFolder}/test/gen/build/gencpp.exe", "args": [], - "cwd": "${workspaceFolder}", + "cwd": "${workspaceFolder}/test/gen/", "postRunCommands": [ "command script import \"${workspaceFolder}/.vscode/gencpp_lldbvis.py\"" ] @@ -21,7 +21,7 @@ "name": "Debug gentime vsdbg", "program": "${workspaceFolder}/test/gen/build/gencpp.exe", "args": [], - "cwd": "${workspaceFolder}", + "cwd": "${workspaceFolder}/test/gen/", "visualizerFile": "${workspaceFolder}/.vscode/gencpp.natvis" } ] diff --git a/.vscode/settings.json b/.vscode/settings.json index e1cdd77..b2b244d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -19,5 +19,6 @@ "limits": "cpp" }, "C_Cpp.intelliSenseEngineFallback": "disabled", - "mesonbuild.configureOnOpen": true + "mesonbuild.configureOnOpen": true, + "C_Cpp.errorSquiggles": "enabled" } \ No newline at end of file diff --git a/Readme.md b/Readme.md index dbb724c..4fa5e2e 100644 --- a/Readme.md +++ b/Readme.md @@ -154,47 +154,6 @@ struct ArrayHeader **Note: The formatting shown here is not how it will look. For your desired formatting its recommended to run a pass through the files with an auto-formatter.** -## Gen's DSL - -If you don't mind a low amount of macros (~80 sloc), a DSL may be optionally defined with: - -```cpp -GEN_DEFINE_DSL -``` - -Using the previous example to show usage: - -```cpp -Code type_ns(uw) = type( uw ); -Code type_ns(allocator) = type( allocator ); -Code type_ns(string_const) = type( char, specifiers( Const, Ptr ) ); - -make( struct, ArrayHeader ) -{ - Code - body = ArrayHeader.body(); - body->add( variable( uw, Num )); - body->add( variable( uw, Capacity )); - body->add( variable( allocaotr, Allocator )); -} - -// Or using parse! -Code type_ns(uw) = type_code( uw ); -Code type_ns(allocator) = type_code( allocator ); -Code type_ns(string_const) = type_code( char const* ); - -Code header = struct_code( - struct ArrayHeader - { - uw Num; - uw Capacity; - allocator Allocator; - }; -); -``` - -`type_ns` is a helper macro for providing refering to a typename if using the c-namespace naming convention. - ## Building An example of building is provided in the test directory. diff --git a/project/Bloat.hpp b/project/Bloat.hpp index 2f011d0..2898546 100644 --- a/project/Bloat.hpp +++ b/project/Bloat.hpp @@ -84,12 +84,12 @@ using zpl::str_fmt_va; using zpl::str_fmt_out_va; using zpl::str_fmt_out_err_va; using zpl::str_compare; -using zpl::string_appendc; -using zpl::string_append_fmt; -using zpl::string_append_length; -using zpl::string_make_length; -using zpl::string_length; -using zpl::string_make; +// using zpl::string_appendc; +// using zpl::string_append_fmt; +// using zpl::string_append_length; +// using zpl::string_make_length; +// using zpl::string_length; +// using zpl::string_make; using zpl::str_len; #if __clang__ @@ -198,7 +198,8 @@ char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED"; sw Len; char const* Ptr; - static StrC from( char const* str ) + static constexpr + StrC from( char const* str ) { return { str_len( str ), str }; } @@ -210,7 +211,7 @@ char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED"; }; // Dynamic String - // This is directly based off the ZPL string api. + // This is directly based off the ZPL string api. // They used a header pattern // I kept it for simplicty of porting but its not necessary to keep it that way. struct String @@ -268,7 +269,7 @@ char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED"; if ( ! str ) mem_set( allocation, 0, alloc_size ); - Header& + Header& header = * rcast(Header*, allocation); header = { allocator, length, length }; @@ -339,7 +340,7 @@ char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED"; // NOTE: Return if there is enough space left if ( available >= add_len ) { - return false; + return true; } else { @@ -371,7 +372,6 @@ char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED"; } } - bool append( char const* str ) { return append( str, str_len( str ) ); @@ -379,15 +379,15 @@ char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED"; bool append( char const* str, sw length ) { - Header& header = get_header(); - if ( sptr(str) > 0 ) { - sw curr_len = header.Length; + sw curr_len = this->length(); - if ( make_space_for( str, length ) ) + if ( ! make_space_for( str, length ) ) return false; + Header& header = get_header(); + mem_copy( Data + curr_len, str, length ); Data[ curr_len + length ] = '\0'; diff --git a/project/gen.cpp b/project/gen.cpp index 6bcb6e7..aa098c6 100644 --- a/project/gen.cpp +++ b/project/gen.cpp @@ -506,8 +506,8 @@ namespace gen } String AST::to_string() - { - # define ProcessModuleFlags() \ +{ +# define ProcessModuleFlags() \ if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) \ result.append( "export " ); \ \ @@ -524,11 +524,33 @@ namespace gen s32 tab_count = 0; { AST* curr_parent = Parent; - - while ( Parent ) + while ( curr_parent ) { + switch ( curr_parent->Type ) + { + using namespace ECode; + + case Class_Body: + case Enum_Body: + case Extern_Linkage_Body: + case Function_Body: + case Global_Body: + case Namespace_Body: + case Struct_Body: + case Union_Body: + break; + + default: + { + curr_parent = curr_parent->Parent; + continue; + } + } + indent_str[tab_count] = '\t'; tab_count++; + + curr_parent = curr_parent->Parent; } } StrC indent = { tab_count, indent_str }; @@ -558,14 +580,17 @@ namespace gen { s32 length = 0; while ( left && Content[index] != '\n' ) + { length++; + left--; + } str_copy( line, Content, length ); line[length] = '\0'; - result.append_fmt( "// %s\n", line ); + result.append_fmt( "// %s", line ); } - while ( left--, left ); + while ( left--, left > 0 ); } break; @@ -585,32 +610,43 @@ namespace gen ProcessModuleFlags(); - result.append( "class " ); - - s32 idx = 1; - - if ( Entries[idx]->Type == Attributes ) + if ( num_entries() > 1 ) { - result.append_fmt( "%s ", Entries[idx]->to_string() ); - idx++; + result.append( "class " ); + + s32 idx = 1; + + if ( Entries[idx]->Type == Attributes ) + { + result.append_fmt( "%s ", Entries[idx]->to_string() ); + idx++; + } + + result.append( Name ); + + AST* parent = Entries[idx]; + + if ( parent ) + { + char const* access_level = to_str( ParentAccess ); + + result.append_fmt( ": %s %s\n%s{\n" + , access_level + , parent + , indent_str + ); + } + else + { + result.append( "\n{\n" ); + } + + result.append_fmt( "%s\n%s};\n", body()->to_string(), indent_str ); } - - result.append( Name ); - - AST* parent = Entries[idx]; - - if ( parent ) + else { - char const* access_level = to_str( ParentAccess ); - - result.append_fmt( ": %s %s\n%s{\n" - , access_level - , parent - , indent_str - ); + result.append_fmt( "class %s\n{\n%s\n%s};\n", Name, body()->to_string(), indent_str ); } - - result.append_fmt( "%s\n%s};\n", body()->to_string(), indent_str ); } break; @@ -820,31 +856,42 @@ namespace gen ProcessModuleFlags(); u32 idx = 0; - u32 left = array_count( Entries ); + u32 left = num_entries(); - if ( Entries[idx]->Type == Attributes ) + AST* Entry = Entries[idx]; + + if ( Entry && Entry->Type == Attributes ) { - result.append_fmt( "%s ", Entries[idx]->to_string() ); + result.append_fmt( "%s ", Entry->to_string() ); idx++; left--; + Entry = Entries[idx]; } - if ( Entries[idx]->Type == Specifiers ) + if ( Entry && Entry->Type == Specifiers ) { - result.append_fmt( "%s\n", Entries[idx]->to_string() ); + result.append_fmt( "%s\n", Entry->to_string() ); idx++; left--; + Entry = Entries[idx]; } - result.append_fmt( "\n%s %s(", Entries[idx]->to_string(), Name ); - idx++; - left--; - - if ( left && Entries[idx]->Type == Parameters ) + if ( Entry && Entry->Type == Typename ) { - result.append_fmt( "%s", Entries[idx]->to_string() ); + result.append_fmt( "%s ", Entry->to_string() ); idx++; left--; + Entry = Entries[idx]; + } + + result.append_fmt( "%s(", Name ); + + if ( left && Entry && Entry->Type == Parameters ) + { + result.append_fmt("%s", Entry->to_string() ); + idx++; + left--; + Entry = Entries[idx]; } else { @@ -1073,7 +1120,7 @@ namespace gen break; case Typename: - if ( Entries[0] ) + if ( num_entries() && Entries[0] ) { result.append_fmt( "%s %s", Name, Entries[0]->to_string() ); } @@ -1486,6 +1533,7 @@ namespace gen result->StaticIndex = 0; result->Readonly = false; result->DynamicEntries = false; + result->Entries = result->ArrStatic; return result; } @@ -2189,7 +2237,7 @@ namespace gen return Code::Invalid; } - if ( ret_type == nullptr || ret_type->Type != Typename ) + if ( ret_type && ret_type->Type != Typename ) { log_failure( "gen::def_function: ret_type was not a Typename: %s", ret_type->debug_str() ); return Code::Invalid; @@ -5738,7 +5786,7 @@ namespace gen return result; } - Code untyped_fmt(char const* fmt, ...) + Code untyped_fmt( char const* fmt, ...) { local_persist thread_local char buf[ZPL_PRINTF_MAXLEN] = { 0 }; @@ -5783,7 +5831,20 @@ namespace gen #pragma region Builder void Builder::print( Code code ) { - Buffer.append_fmt( "%s\n\n", code.to_string() ); + Buffer.append_fmt( "%s\n", code.to_string() ); + } + + void Builder::print_fmt( char const* fmt, ... ) + { + sw res; + char buf[ ZPL_PRINTF_MAXLEN ] = { 0 }; + + va_list va; + va_start( va, fmt ); + res = str_fmt_va( buf, count_of( buf ) - 1, fmt, va ) - 1; + va_end( va ); + + Buffer.append( buf, res ); } bool Builder::open( char const* path ) @@ -5803,7 +5864,7 @@ namespace gen void Builder::write() { - bool result = file_write( & File, Buffer, string_length(Buffer) ); + bool result = file_write( & File, Buffer, Buffer.length() ); if ( result == false ) log_failure("gen::File::write - Failed to write to file: %s", file_name( & File ) ); diff --git a/project/gen.hpp b/project/gen.hpp index be46ec2..3a549f9 100644 --- a/project/gen.hpp +++ b/project/gen.hpp @@ -14,7 +14,7 @@ // #define GEN_DEFINE_DSL #define GEN_DEFINE_LIBRARY_CODE_CONSTANTS // #define GEN_DONT_USE_FATAL -#define GEN_ENFORCE_READONLY_AST +// #define GEN_ENFORCE_READONLY_AST #define GEN_FEATURE_INCREMENTAL // #define GEN_FEATURE_PARSING @@ -939,6 +939,7 @@ namespace gen String Buffer; void print( Code ); + void print_fmt( char const* fmt, ... ); bool open( char const* path ); void write(); diff --git a/test/NonParsed/Array.NonParsed.hpp b/test/NonParsed/Array.NonParsed.hpp index 6ecee41..524f1c1 100644 --- a/test/NonParsed/Array.NonParsed.hpp +++ b/test/NonParsed/Array.NonParsed.hpp @@ -307,12 +307,12 @@ struct GenArrayRequest }; Array(GenArrayRequest) GenArrayRequests; -void gen__array_request( StrC type, StrC dep, sw size ) +void gen__array_request( StrC type, sw size, StrC dep = {} ) { GenArrayRequest request = { type, dep, size }; array_append( GenArrayRequests, request ); } -#define Gen_Array( type ) gen__array_request( txt_n_len( type ), sizeof(type) ) +#define Gen_Array( type ) gen__array_request( { txt_n_len(type) }, sizeof(type) ) u32 gen_array_file() { diff --git a/test/NonParsed/Sanity.hpp b/test/NonParsed/Sanity.hpp new file mode 100644 index 0000000..dbf3108 --- /dev/null +++ b/test/NonParsed/Sanity.hpp @@ -0,0 +1,47 @@ + + +#ifdef gen_time +#include "gen.hpp" + +using namespace gen; + +u32 gen_sanity() +{ + Builder + gen_sanity_file; + gen_sanity_file.open("./sanity.gen.hpp"); + + // Comment + { + Code comment_test = def_comment( StrC::from("Sanity check: def_omment test") ); + + gen_sanity_file.print(comment_test); + gen_sanity_file.print_fmt("\n"); + } + + // Class + { + Code fwd = def_class( StrC::from("Test_EmptyClass") ); + Code empty_body; + { + Code cmt = def_comment( StrC::from("Empty class") ); + Code body = def_class_body( 1, cmt ); + + empty_body = def_class( StrC::from("Test_EmptyClass"), body ); + } + + gen_sanity_file.print(fwd); + gen_sanity_file.print(empty_body); + } + + gen_sanity_file.print_fmt("\n"); + + // + { + + } + + gen_sanity_file.write(); + return 0; +} +#endif diff --git a/test/gen/sanity.gen.hpp b/test/gen/sanity.gen.hpp new file mode 100644 index 0000000..f825726 --- /dev/null +++ b/test/gen/sanity.gen.hpp @@ -0,0 +1,12 @@ +// Sanity check: def_omment test + +class Test_EmptyClass; +class Test_EmptyClass +{ + // Empty class +}; + + +UFUNCTION( BlueprintCallable, Category = "Test" ) +void Test_UFunction(void); + diff --git a/test/test.cpp b/test/test.cpp index 996394c..29e888f 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -1,4 +1,6 @@ #include "Bloat.cpp" +#include "NonParsed\Array.NonParsed.hpp" +#include "NonParsed\Sanity.hpp" #ifdef gen_time @@ -9,13 +11,14 @@ using namespace gen; - int gen_main() { Memory::setup(); - gen::init(); + gen_sanity(); + // gen_array_file(); + gen::deinit(); Memory::cleanup(); return 0;