Started sanity test suite (Non-parsed api)

Made some fixes based on errors found while iterating on first generation
This commit is contained in:
Edward R. Gonzalez 2023-06-28 14:43:21 -04:00
parent e74b498686
commit 0192cd49ef
10 changed files with 192 additions and 108 deletions

4
.vscode/launch.json vendored
View File

@ -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"
}
]

View File

@ -19,5 +19,6 @@
"limits": "cpp"
},
"C_Cpp.intelliSenseEngineFallback": "disabled",
"mesonbuild.configureOnOpen": true
"mesonbuild.configureOnOpen": true,
"C_Cpp.errorSquiggles": "enabled"
}

View File

@ -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.

View File

@ -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';

View File

@ -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 ) );

View File

@ -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();

View File

@ -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()
{

47
test/NonParsed/Sanity.hpp Normal file
View File

@ -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

12
test/gen/sanity.gen.hpp Normal file
View File

@ -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);

View File

@ -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;