diff --git a/Readme.md b/Readme.md index 12b05cf..9ba25dd 100644 --- a/Readme.md +++ b/Readme.md @@ -93,24 +93,6 @@ Code header; } ``` -### Incremental - -```cpp -// Types are done the same with upfront. Incremental does not have a full interface replacment. - -// Get a Code AST from the CodePool. -Code header = make_struct( name(ArrayHeader) ); -{ - // Make a struct body. - Code body = header.body(); - - // Members - body->add( def_variable( t_uw, name(Num)) ); - body->add( def_variable( t_uw, name(Capacity)) ); - body->add( def_variable( t_allocator, name(Allocator)) ); -} -``` - ### Parse ```cpp @@ -272,10 +254,9 @@ Data Notes: * This library treats memory failures as fatal. * Strings are stored in their own set of arenas. AST constructors use cached strings for names, and content. -## There are four sets of interfaces for Code AST generation the library provides +## There are three sets of interfaces for Code AST generation the library provides * Upfront -* Incremental * Parsing * Untyped @@ -335,40 +316,6 @@ Code ``` -### Incremental construction - -A Code AST is provided but the body is not complete. - -* code.add( AST* ) // Adds AST with validation. -* code.add_entry( AST* ) // Adds AST entry without validation. - -Code ASTs may be explictly validated at anytime using Code's check() member function. - -Interface : - -* make_class -* make_enum -* make_export_body -* make_extern_linkage -* make_function -* make_global_body -* make_namespace -* make_operator -* make_params -* make_specifiers -* make_struct -* make_union - -Usage: - -```cpp -Code = make_( ... ) -{ - ->add( ... ); - ... -} -``` - ### Parse construction A string provided to the API is parsed for the intended language construct. @@ -616,8 +563,3 @@ Names or Content fields are interned strings and thus showed be cached using `ge * Generate a single-header library. * Generate a C-supported single-header library. * Actually get to version 1. -* Review if the upfront or incremental constructors are actually a net benefit vs just using the parse constructors. - * They exist as a artifact of learning what was possible or not possible with staged metaprogramming in C++ (the parse interface was the last to get fleshed out) - * Most likely at least Incremental could possibly be removed in favor of just using the parse constructors. - * Possible merits are ergonomics for very dynamic generation or performance reasons. - * They'll most likely stay until its evident that they are not necessary. diff --git a/project/Readme.md b/project/Readme.md index d884b61..b7a2edb 100644 --- a/project/Readme.md +++ b/project/Readme.md @@ -32,7 +32,6 @@ While getting fleshed out, all feature macros are defined on the top of the head These macros are: -* `GEN_DEFINE_DSL` : Define the preprocessor DSL for using the library interface * `GEN_DEFINE_LIBRARY_CORE_CONSTANTS` : Optional typename codes as they are non-standard to C/C++ and not necessary to library usage * `GEN_ENCORCE_READONLY_AST` : Defines checks in Code when accessing the AST to make sure readonly marked ASTs are not mutated * `GEN_FEATURE_INCREMENTAL` : Defines the incremental constructors @@ -71,7 +70,7 @@ AST with. First set of fowards are either backend functions used for various aspects of AST generation or configurating allocators used for different containers. -Interface fowards defined in order of: Upfront, Incremental, Parsing, Untyped. +Interface fowards defined in order of: Upfront, Parsing, Untyped. From there forwards for the File handlers are defined: Builder, Editor, Scanner. diff --git a/project/gen.cpp b/project/gen.cpp index c446e3a..a3167ba 100644 --- a/project/gen.cpp +++ b/project/gen.cpp @@ -5,8 +5,7 @@ #ifdef gen_time namespace gen { - ZPL_TABLE_DEFINE( StringTable, str_tbl_, String ); - // ZPL_TABLE_DEFINE( TypeTable, type_tbl_ , Code ); + ZPL_TABLE_DEFINE( StringTable, str_tbl_, String ); namespace StaticData { @@ -151,278 +150,6 @@ namespace gen #pragma region AST Code Code::Invalid; - bool AST::add( AST* other ) - { - #ifdef GEN_FEATURE_INCREMENTAL - if ( other == nullptr ) - { - log_failure( "AST::add: Provided a null AST" ); - return false; - } - - if ( other->Type == ECode::Invalid ) - { - log_failure( "AST::add: Provided an invalid AST" ); - return false; - } - - switch ( Type ) - { - using namespace ECode; - - case Invalid: - log_failure( "AST::add: Cannot add an AST to an invalid AST." ); - return false; - - case Untyped: - log_failure( "AST::add: Cannot add an AST to an untyped AST." ); - return false; - - case Comment: - log_failure( "AST::add: Cannot add an AST to a comment." ); - return false; - - case Access_Private: - log_failure( "AST::add: Cannot add an AST to a private access specifier." ); - return false; - - case Access_Protected: - log_failure( "AST::add: Cannot add an AST to a protected access specifier." ); - return false; - - case Access_Public: - log_failure( "AST::add: Cannot add an AST to a public access specifier." ); - return false; - - case Attributes: - log_failure( "AST::add: Cannot add an AST to an attribute." ); - return false; - - case Class: - log_failure( "AST::add: Cannot add an AST to a class, only to its body" ); - return false; - - case Class_Fwd: - log_failure( "AST::add: Cannot add an AST to a class forward declaration." ); - return false; - - case Class_Body: - switch ( other->Type ) - { - AST_BODY_CLASS_UNALLOWED_TYPES - { - log_failure( "AST::add: Cannot add %s to a class body.", other->type_str() ); - return false; - } - - default: - break; - } - break; - - case Enum: - log_failure( "AST::add: Cannot add an AST to an enum, only to its body" ); - return false; - - case Enum_Fwd: - log_failure( "AST::add: Cannot add an AST to an enum forward declaration." ); - return false; - - case Enum_Body: - if ( other->Type != Untyped ) - { - log_failure( "AST::add: Cannot add an AST which is not untyped to an enum body." ); - return false; - } - break; - - case Execution: - log_failure( "AST::add: Cannot add an AST to an execution block." ); - return false; - break; - - case Export_Body: - switch ( other->Type ) - { - AST_BODY_EXPORT_UNALLOWED_TYPES - { - log_failure( "AST::add: Cannot add %s to an export body.", other->type_str() ); - return false; - } - - default: - break; - } - break; - - case Extern_Linkage: - log_failure( "AST::add: Cannot add an AST to an extern linkage, only to its body." ); - return false; - - case Extern_Linkage_Body: - switch ( other->Type ) - { - AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES - { - log_failure( "AST::add: Cannot add %s to an extern linkage body.", other->type_str() ); - return false; - } - - default: - break; - } - - case Enum_Class: - log_failure( "AST::add: Cannot add an AST to an enum class, only to its body" ); - return false; - - case Enum_Class_Fwd: - log_failure( "AST::add: Cannot add an AST to an enum class forward declaration." ); - return false; - - case Friend: - log_failure( "AST::add: Cannot add an AST to a friend declaration." ); - return false; - - case Function: - log_failure( "AST::add: Cannot add an AST to a function, only to its body" ); - return false; - - case Function_Body: - switch ( other->Type ) - { - AST_BODY_FUNCTION_UNALLOWED_TYPES - { - log_failure( "AST::add: Cannot add %s to a function body.", other->type_str() ); - return false; - } - - default: - break; - } - break; - - case Function_Fwd: - log_failure( "AST::add: Cannot add an AST to a function forward declaration." ); - return false; - - case Global_Body: - switch ( other->Type ) - { - AST_BODY_GLOBAL_UNALLOWED_TYPES - { - log_failure( "AST::add: Cannot add %s to a global body.", other->type_str() ); - return false; - } - - default: - break; - } - break; - - case Module: - log_failure( "AST::add: Cannot add an AST to a module, only to its body" ); - return false; - - case Namespace: - if ( Type != Global_Body ) - { - log_failure( "AST::add: Cannot add a namespace to a non-global body." ); - return false; - } - - case Namespace_Body: - switch ( other-> Type ) - { - AST_BODY_NAMESPACE_UNALLOWED_TYPES - { - log_failure( "AST::add: Cannot add %s to a namespace body.", other->type_str() ); - return false; - } - - default: - break; - } - break; - - case Operator: - log_failure( "AST::add: Cannot add an operator, only to its body" ); - return false; - - case Operator_Fwd: - log_failure( "AST::add: Cannot add an operator forward declaration." ); - return false; - - case Parameters: - log_failure( "AST::add: Cannot add to a parameter list, use AST::add_param instead" ); - return false; - - case Preprocessor_Include: - log_failure( "AST::add: Cannot add an AST to a preprocessor include." ); - return false; - - case Specifiers: - log_failure( "AST::add: Cannot add to a specifier, use AST::add_specifier instead." ); - return false; - - case Struct: - log_failure( "AST::add: Cannot add to a struct, only to its body." ); - return false; - - case Struct_Body: - switch ( other->Type ) - { - AST_BODY_STRUCT_UNALLOWED_TYPES - { - log_failure( "AST::add: Cannot add %s to a struct body.", other->type_str() ); - return false; - } - - default: - break; - } - break; - - case Typedef: - log_failure( "AST::add: Cannot add to a typedef." ); - return false; - - case Typename: - log_failure( "AST::add: Cannot add to a typename." ); - return false; - - case Union: - log_failure( "AST::add: Cannot add to a union, only to its body." ); - return false; - - case Union_Body: - if ( other->Type != Untyped ) - { - log_failure( "AST::add: Cannot add an AST which is not untyped to a union body." ); - return false; - } - - case Using: - log_failure( "AST::add: Cannot add to a using statement." ); - return false; - - case Using_Namespace: - log_failure( "AST::add: Cannot add to a using namespace statement." ); - return false; - - case Variable: - log_failure( "AST::add: Cannot add to a variable." ); - return false; - } - - add_entry( other ); - return true; - #else - log_failure( "AST::add: Incremental AST building is not enabled." ); - return false; - #endif - } - AST* AST::duplicate() { using namespace ECode; @@ -563,7 +290,6 @@ namespace gen break; case Untyped: - // result = string_append_length( result, Content, string_length( ccast(String, Content)) ); result.append( Content ); break; @@ -623,7 +349,7 @@ namespace gen result.append( Name ); - AST* parent = entry( idx ); + AST const* parent = entry( idx ); if ( parent ) { @@ -671,7 +397,7 @@ namespace gen { s32 idx = 1; - AST* Entry = entry( idx); + AST const* Entry = entry( idx); if ( Entry->Type == Attributes ) { @@ -724,33 +450,34 @@ namespace gen result.append( "enum class " ); - s32 idx = 0; - - if ( entry( idx )->Type == Attributes ) + if ( num_entries() > 1 ) { - result.append_fmt( "%s ", entry( idx )->to_string() ); - idx++; + s32 idx = 1; + + if ( entry( idx )->Type == Attributes ) + { + result.append_fmt( "%s ", entry( idx )->to_string() ); + idx++; + } + + if ( entry( idx )->Type == Typename ) + { + result.append_fmt( "%s : %s\n%s{\n" + , Name + , entry( idx )->to_string() + , indent_str + ); + } + else + { + result.append_fmt( "%s\n{\n" + , Name + ); + } } - if ( entry( idx )->Type == Typename ) - { - result.append_fmt( "%s : %s\n%s{\n" - , Name - , entry( idx )->to_string() - , indent_str - ); - } - else - { - result.append_fmt( "%s\n%s{\n" - , Name - , indent_str - ); - } - - result.append_fmt( "%s\n%s};" + result.append_fmt( "%s};" , body()->to_string() - , indent_str ); } break; @@ -968,7 +695,7 @@ namespace gen idx++; } - result.append_fmt( "%s operator %s (", entry( idx )->to_string(), Name ); + result.append_fmt( "%s %s (", entry( idx )->to_string(), Name ); idx++; if ( entry( idx )->Type == Parameters ) @@ -981,10 +708,9 @@ namespace gen result.append_fmt( "void" ); } - result.append_fmt( ")\n%s{\n%s\n%s}" + result.append_fmt( ")\n%s{\n%s\n}" , indent_str , body()->to_string() - , indent_str ); } break; @@ -1004,7 +730,7 @@ namespace gen idx++; } - result.append_fmt( "%s operator%s(", entry( idx )->to_string(), Name ); + result.append_fmt( "%s %s (", entry( idx )->to_string(), Name ); idx++; if ( entry( idx )->Type == Parameters ) @@ -1241,6 +967,38 @@ namespace gen #undef ProcessModuleFlags } + + bool AST::is_equal( AST* other ) + { + if ( Type != other->Type ) + return false; + + switch ( Type ) + { + case ECode::Typedef: + case ECode::Typename: + { + if ( Name != other->Name ) + return false; + + if ( num_entries() != other->num_entries() ) + return false; + + for ( s32 i = 0; i < num_entries(); ++i ) + { + if ( entry( i ) != other->entry( i ) ) + return false; + } + + return true; + } + } + + if ( Name != other->Name ) + return false; + + return true; + } #pragma endregion AST #pragma region Gen Interface @@ -1728,7 +1486,7 @@ namespace gen switch ( params_code->param_count() ) { case 1: - if ( params_code->param_type() == type_ns(int) ) + if ( params_code->param_type()->is_equal( type_ns(int) ) ) is_member_symbol = true; else @@ -1738,7 +1496,7 @@ namespace gen case 2: check_param_eq_ret(); - if ( params_code->get_param(1) != type_ns(int) ) + if ( ! params_code->get_param(1)->is_equal( type_ns(int) ) ) { log_failure("gen::def_operator: " "operator%s requires second parameter of non-member definition to be int for post-decrement", @@ -1772,7 +1530,7 @@ namespace gen return OpValidateResult::Fail; } - if ( params_code->param_type() == ret_type ) + if ( params_code->param_type()->is_equal( ret_type ) ) { log_failure("gen::def_operator: " "operator%s is non-member symbol yet first paramter does not equal return type\n" @@ -1814,7 +1572,7 @@ namespace gen break; case 2: - if ( params_code->param_type() != ret_type ) + if ( ! params_code->param_type()->is_equal( ret_type ) ) { log_failure("gen::def_operator: " "operator%s is non-member symbol yet first paramter does not equal return type\n" @@ -1858,7 +1616,7 @@ namespace gen } } - if ( ret_type != type_ns(bool) ) + if ( ! ret_type->is_equal( type_ns(bool) )) { log_failure("gen::def_operator: operator%s return type must be of type bool - %s" , to_str(op) @@ -2402,7 +2160,7 @@ namespace gen { using namespace ECode; - if ( body && body->Type != Function_Body ) + if ( body && body->Type != Function_Body && body->Type != Untyped ) { log_failure( "gen::def_operator: Body was provided but its not of function body type: %s", body->debug_str() ); return Code::Invalid; @@ -2427,7 +2185,7 @@ namespace gen return Code::Invalid; } - char const* name = str_fmt_buf( "operator%s", to_str(op) ); + char const* name = str_fmt_buf( "operator %s", to_str(op) ); Code result = make_code(); @@ -2561,10 +2319,6 @@ namespace gen return Code::Invalid; } - // Code cached = get_cached_type( name ); - // if ( cached ) - // return cached; - Code result = make_code(); result->Name = get_cached_string( name ); @@ -2578,11 +2332,6 @@ namespace gen result.lock(); - // s32 hash_length = name.Len > kilobytes(1) ? kilobytes(1) : name.Len; - // s32 key = crc32( name.Ptr, hash_length ); - - // type_tbl_set( & StaticData::TypeMap, key, result ); - return result; } @@ -3196,7 +2945,7 @@ namespace gen result->Name = current->Name; result->Type = current->Type; - result->add_entry( current->entry( 0) ); + result->add_entry( current->entry( 0 ) ); while( codes++, current = * codes, num--, num > 0 ) { @@ -3344,329 +3093,11 @@ namespace gen result.lock(); return result; } -#pragma endregion Upfront Constructors - -#pragma region Incremetnal Constructors -#ifdef GEN_FEATURE_INCREMENTAL - Code make_class( StrC name - , Code parent, AccessSpec parent_access - , Code specifiers, Code attributes - , ModuleFlag mflags ) - { - using namespace ECode; - - name_check( make_struct, name ); - - if ( attributes && attributes->Type != Attributes ) - { - log_failure( "gen::make_class: attributes was not a `Attributes` type: %s", attributes->debug_str() ); - return Code::Invalid; - } - - if ( specifiers && specifiers->Type != Specifiers ) - { - log_failure( "gen::make_class: specifiers was not a `Specifiers` type: %s", specifiers->debug_str() ); - return Code::Invalid; - } - - if ( parent && parent->Type != Struct ) - { - log_failure( "gen::make_class: parent was not a `Struct` type: %s", parent->debug_str() ); - return Code::Invalid; - } - - Code - result = make_code(); - result->Type = Struct; - result->Name = get_cached_string( name ); - result->ModuleFlags = mflags; - - Code - body = make_code(); - body->Type = Struct_Body; - - result->add_entry( body ); - - if ( attributes ) - result->add_entry( attributes ); - - if ( specifiers ) - result->add_entry( specifiers ); - - if ( parent ) - result->add_entry( parent ); - - return result; - } - - Code make_enum( StrC name, Code type, EnumT specifier, Code attributes, ModuleFlag mflags ) - { - using namespace ECode; - - name_check( make_enum, name ); - - if ( attributes && attributes->Type != Attributes ) - { - log_failure( "gen::make_enum: attributes was not a `Attributes` type: %s", attributes->debug_str() ); - return Code::Invalid; - } - - if ( type && type->Type != Typename ) - { - log_failure("gen::make_enum: type provided is not of code type typename - %s", type->debug_str() ); - return Code::Invalid; - } - - Code - result = make_code(); - result->Type = specifier == EnumClass ? Enum_Class : Enum; - result->Name = get_cached_string( name ); - result->ModuleFlags = mflags; - - Code - body = make_code(); - body->Type = Enum_Body; - - result->add_entry( body ); - - if ( type ) - result->add_entry( type ); - - return result; - } - - Code make_export_body( StrC name ) - { - using namespace ECode; - - Code - result = make_code(); - result->Type = Export_Body; - - if ( name && name.Len > 0 ) - result->Name = get_cached_string( name ); - - return result; - } - - Code make_extern_link( StrC name, ModuleFlag mflags ) - { - using namespace ECode; - - name_check( make_extern_linkage, name); - - Code - result = make_code(); - result->Type = Extern_Linkage; - result->Name = get_cached_string( name ); - result->ModuleFlags = mflags; - - return result; - } - - Code make_function( StrC name - , Code params, Code ret_type - , Code specifiers, Code attributes - , ModuleFlag mflags - ) - { - using namespace ECode; - - name_check( make_function, name ); - - if ( attributes && attributes->Type != Attributes ) - { - log_failure( "gen::make_function: attributes was not a `Attributes` type: %s", attributes->debug_str() ); - return Code::Invalid; - } - - if ( specifiers && specifiers->Type != Specifiers ) - { - log_failure( "gen::def_function: specifiers was not a `Specifiers` type" ); - return Code::Invalid; - } - - if ( params && params->Type != Parameters ) - { - log_failure( "gen::def_function: params was not a `Parameters` type" ); - return Code::Invalid; - } - - if ( ret_type == nullptr || ret_type->Type != Typename ) - { - log_failure( "gen::def_function: ret_type was not a Typename" ); - return Code::Invalid; - } - - Code - result = make_code(); - result->Name = get_cached_string( name ); - result->Type = Function; - result->ModuleFlags = mflags; - - Code - body = make_code(); - body->Type = Function_Body; - - result->add_entry( body ); - - if ( attributes ) - result->add_entry( attributes ); - - if ( specifiers ) - result->add_entry( specifiers ); - - if ( ret_type ) - result->add_entry( ret_type ); - - if ( params ) - result->add_entry( params ); - - return result; - } - - Code make_global_body( StrC name ) - { - name_check( make_global_body, name ); - - Code - result = make_code(); - result->Type = ECode::Global_Body; - - if ( name.Len > 0 ) - result->Name = get_cached_string( name ); - - return result; - } - - Code make_namespace( StrC name, Code parent, ModuleFlag mflags ) - { - name_check( make_namespace, name ); - - Code - result = make_code(); - result->Type = ECode::Namespace; - result->Name = get_cached_string( name ); - result->ModuleFlags = mflags; - - Code - body = make_code(); - body->Type = ECode::Namespace_Body; - - result->add_entry( body ); - - return result; - } - - Code make_operator( OperatorT op, Code params_code, Code ret_type, Code specifiers, Code attributes, ModuleFlag mflags ) - { - using namespace ECode; - - if ( attributes && attributes->Type != Attributes ) - { - log_failure( "gen::make_operator: attributes was not a `Attributes` type: %s", attributes->debug_str() ); - return Code::Invalid; - } - - OpValidateResult check_result = operator__validate( op, params_code, ret_type, specifiers ); - - if ( check_result == OpValidateResult::Fail ) - { - return Code::Invalid; - } - - char const* name = str_fmt_buf( "operator%s", to_str(op) ); - - Code - result = make_code(); - result->Name = get_cached_string( { str_len(name, MaxNameLength), name } ); - result->ModuleFlags = mflags; - - if ( attributes ) - result->add_entry( attributes ); - - if ( specifiers ) - result->add_entry( specifiers ); - - if (params_code) - result->add_entry( params_code ); - - result->add_entry( ret_type ); - - return result; - } - - Code make_params() - { - Code - result = make_code(); - result->Type = ECode::Parameters; - - return result; - } - - Code make_specifiers() - { - Code - result = make_code(); - result->Type = ECode::Specifiers; - - return result; - } - - Code make_struct( StrC name, Code parent, Code specifiers, Code attributes, ModuleFlag mflags ) - { - using namespace ECode; - - name_check( make_struct, name ); - - if ( attributes && attributes->Type != Attributes ) - { - log_failure( "gen::make_struct: attributes was not a `Attributes` type: %s", attributes->debug_str() ); - return Code::Invalid; - } - - if ( specifiers && specifiers->Type != Specifiers ) - { - log_failure( "gen::make_struct: specifiers was not a `Specifiers` type" ); - return Code::Invalid; - } - - if ( parent && parent->Type != Struct ) - { - log_failure( "gen::make_struct: parent was not a `Struct` type" ); - return Code::Invalid; - } - - Code - result = make_code(); - result->Type = Struct; - result->Name = get_cached_string( name ); - result->ModuleFlags = mflags; - - Code - body = make_code(); - body->Type = Function_Body; - - result->add_entry( make_code() ); - - if ( attributes ) - result->add_entry( attributes ); - - if ( specifiers ) - result->add_entry( specifiers ); - - if ( parent ) - result->add_entry( parent ); - - return result; - } # undef name_check # undef null_check # undef null_or_invalid_check -#endif // GEN_FEATURE_INCREMENTAL -#pragma endregion Incremetnal Constructions +#pragma endregion Upfront Constructors #pragma region Parsing Constructors #ifdef GEN_FEATURE_PARSING diff --git a/project/gen.hpp b/project/gen.hpp index 18d7740..81502cc 100644 --- a/project/gen.hpp +++ b/project/gen.hpp @@ -11,7 +11,6 @@ #include "Bloat.hpp" // Temporarily here for debugging purposes. -// #define GEN_DEFINE_DSL #define GEN_DEFINE_LIBRARY_CODE_CONSTANTS // #define GEN_DONT_USE_FATAL // #define GEN_ENFORCE_READONLY_AST @@ -390,11 +389,6 @@ namespace gen struct AST { #pragma region Member Functions - - // Used with incremental constructors - // Adds and checks entries to see if they are valid additions the type of ast. - bool add( AST* other ); - void add_entry( AST* other ); inline @@ -413,7 +407,7 @@ namespace gen inline bool has_entries() { - return entry( 0 ); + return num_entries(); } inline @@ -422,6 +416,9 @@ namespace gen return Type != ECode::Invalid; } + inline + bool is_equal( AST* other ); + inline s32 num_entries() { @@ -640,13 +637,13 @@ namespace gen } inline - String to_string() + String to_string() const { return ast->to_string(); } inline - operator bool() + operator bool() const { return ast; } @@ -718,21 +715,6 @@ namespace gen // Used when the its desired when omission is allowed in a definition. constexpr Code NoCode = { nullptr }; - // extern const Code InvalidCode; - - /* - Type Table: Used to store Typename ASTs. Types are registered by their string literal value. - - Provides interning specific to Typename ASTs. - Interning for other types should be possible (specifiers) with this, so long as they - don't have an set of child AST entries (Use the content field). - - TODO: I'm not sure if this is viable. - ASTs are duplicated when added (parent is unique), - Parent is currently used for debug and serialization. - If these features are considered unnecessary, then caching would be fine. - */ - // ZPL_TABLE_DECLARE( ZPL_EXTERN, TypeTable, type_tbl_, Code ); #pragma endregion Data Structures #pragma region Gen Interface @@ -856,45 +838,6 @@ namespace gen Code def_union_body ( s32 num, Code* codes ); # pragma endregion Upfront -# pragma region Incremental -# ifdef GEN_FEATURE_INCREMENTAL - Code make_class( StrC name - , Code parent = NoCode, AccessSpec access = AccessSpec::Default - , Code specifiers = NoCode, Code attributes = NoCode - , ModuleFlag mflags = ModuleFlag::None ); - - Code make_enum( StrC name - , Code type = NoCode, EnumT specifier = EnumRegular - , Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); - - Code make_export_body( StrC name = { 1, "" } ); - Code make_extern_link( s32 length, char const* name, ModuleFlag mflags = ModuleFlag::None ); - - 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( StrC name = { 1, "" } ); - Code make_namespace ( s32 length, char const* name, ModuleFlag mflags = ModuleFlag::None ); - - Code make_operator( OperatorT op - , Code params = NoCode, Code ret_type = NoCode - , Code specifiers = NoCode, Code attributes = NoCode - , ModuleFlag mflags = ModuleFlag::None ); - - Code make_params (); - Code make_specifiers(); - - Code make_struct( StrC name - , Code parent = NoCode, AccessSpec access = AccessSpec::Default - , Code specifiers = NoCode, 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 ( StrC class_def ); @@ -1061,11 +1004,9 @@ namespace gen #pragma region Macros # define gen_main main -# define __ NoCode -# define spec_alignas( Value_ ) ESpecifier::Alignas, Value +# define __ NoCode // This represents the naming convention for all typename Codes generated. -// Used by the DSL but can also be used without it. # define type_ns( Name_ ) t_##Name_ // Convienence for defining any name used with the gen api. @@ -1075,6 +1016,9 @@ namespace gen // Same as name just used to indicate intention of literal for code instead of names. # define code( Code_ ) { txt_n_len( Code_ ) } +# define code_args( num, ... ) num, (Code[num]){ __VA_ARGS__ } + +# define enum_entry( id ) "\t" #id ",\n" #pragma endregion Macros #pragma region Constants diff --git a/scripts/build.ci.ps1 b/scripts/build.ci.ps1 index 0bf6e2d..9e03259 100644 --- a/scripts/build.ci.ps1 +++ b/scripts/build.ci.ps1 @@ -37,7 +37,7 @@ $path_scripts = Join-Path $path_root scripts $args_meson += $path_gen_build Push-Location $path_gen - & meson $args_meson + & meson $args_meson Pop-Location } @@ -52,12 +52,29 @@ $path_scripts = Join-Path $path_root scripts $gencpp = Join-Path $path_gen_build gencpp.exe Push-location $path_gen - # & $gencpp + + Write-Host `nGenerating files... + & $gencpp + + Write-Host `nBeginning format... + $formatParams = @( + '-i' # In-place + '-style=file' # Search for a .clang-format file in the parent directory of the source file. + '-verbose' + ) + + $include = @('*.gen.hpp', '*.gen.cpp') + $exclude = $null + + $targetFiles = @(Get-ChildItem -Recurse -Path $path_gen -Include $include -Exclude $exclude | Select-Object -ExpandProperty FullName) + + clang-format $formatParams $targetFiles + Write-Host "`nFormatting complete" Pop-Location # Build the program depending on generated files. - # if ( -not( Test-Path $path_test_build ) ) + # if ( -not( Test-Path $path_test_build ) )k # { # $args_meson = @() # $args_meson += "setup" diff --git a/singleheader/gen/Readme.md b/singleheader/gen/Readme.md new file mode 100644 index 0000000..565f337 --- /dev/null +++ b/singleheader/gen/Readme.md @@ -0,0 +1,5 @@ +# Singleheader generator + +This will require the scanner to be implemented before it can be done properly. + + diff --git a/singleheader/gen/gen.singleheader.cpp b/singleheader/gen/gen.singleheader.cpp new file mode 100644 index 0000000..e69de29 diff --git a/singleheader/genc.refactor b/singleheader/genc.refactor deleted file mode 100644 index ecf0643..0000000 --- a/singleheader/genc.refactor +++ /dev/null @@ -1,4 +0,0 @@ -// Removes the genc_ namespace if desired - -namespace genc_ - diff --git a/singleheader/meson.build b/singleheader/meson.build new file mode 100644 index 0000000..e69de29 diff --git a/test/gen/DummyInclude.hpp b/test/DummyInclude.hpp similarity index 100% rename from test/gen/DummyInclude.hpp rename to test/DummyInclude.hpp diff --git a/test/NonParsed/Sanity.hpp b/test/NonParsed/Sanity.hpp index 7932c4b..d0d5c92 100644 --- a/test/NonParsed/Sanity.hpp +++ b/test/NonParsed/Sanity.hpp @@ -56,11 +56,9 @@ u32 gen_sanity() Code def; { Code body = untyped_str( StrC::from( - #define enum_entry( id ) "\t" #id ",\n" enum_entry( A ) enum_entry( B ) enum_entry( C ) - #undef enum_entry )); def = def_enum( name(ETestEnum), body, t_u8 ); @@ -120,7 +118,7 @@ u32 gen_sanity() // Include { - Code include = def_include( StrC::from("DummyInclude.hpp") ); + Code include = def_include( StrC::from("../DummyInclude.hpp") ); gen_sanity_file.print(include); } @@ -161,7 +159,37 @@ u32 gen_sanity() // Operator { - // This is nasty... + // Going to make a bit flag set of overloads for this. + + + Code bitflagtest; + { + Code body = def_enum_body( 1, untyped_str( StrC::from( + enum_entry( A = 1 << 0 ) + enum_entry( B = 1 << 1 ) + enum_entry( C = 1 << 2 ) + ))); + bitflagtest = def_enum( name(EBitFlagtest), body, t_u8, EnumClass ); + } + Code t_bitflag = def_type( name(EBitFlagtest) ); + + Code op_fwd, op_or; + { + Code params = def_params( code_args( 2, + def_param( t_bitflag, name(a) ), + def_param( t_bitflag, name(b) ) + )); + + op_fwd = def_operator( EOperator::BOr, params, t_bitflag ); + op_or = def_operator( EOperator::BOr, params, t_bitflag, untyped_str( code( + return EBitFlagtest( (u8)a | (u8)b ); + ))); + } + + gen_sanity_file.print(bitflagtest); + gen_sanity_file.print_fmt("\n"); + gen_sanity_file.print(op_fwd); + gen_sanity_file.print(op_or); } gen_sanity_file.print_fmt("\n"); diff --git a/test/gen/.clang-format b/test/gen/.clang-format new file mode 100644 index 0000000..83822bb --- /dev/null +++ b/test/gen/.clang-format @@ -0,0 +1,163 @@ +# Format Style Options - Created with Clang Power Tools +--- +AccessModifierOffset: -4 + +AlignAfterOpenBracket: BlockIndent +AlignArrayOfStructures: Right +AlignConsecutiveAssignments: + Enabled: true + AcrossEmptyLines: false + AcrossComments: true + AlignCompound: true + PadOperators: true +AlignConsecutiveBitFields: AcrossComments +AlignConsecutiveDeclarations: AcrossComments +AlignConsecutiveMacros: AcrossComments +AlignEscapedNewlines: Right +AlignOperands: DontAlign + +AlignTrailingComments: true + +AllowAllArgumentsOnNextLine: false +AllowAllConstructorInitializersOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortLambdasOnASingleLine: None +AllowShortEnumsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false + +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: Yes + +BinPackArguments: false +BinPackParameters: false + +BitFieldColonSpacing: Both + +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: false + BeforeLambdaBody: false + BeforeWhile: false + +# BreakAfterAttributes: Always +# BreakArrays: false +# BreakBeforeInlineASMColon: OnlyMultiline +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeBraces: Allman +BreakBeforeInheritanceComma: true +BreakInheritanceList: BeforeComma +BreakBeforeConceptDeclarations: true +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeComma +BreakStringLiterals: true + +ColumnLimit: 180 + +CompactNamespaces: true + +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth : 4 + +ContinuationIndentWidth: 4 + +Cpp11BracedListStyle: false + +DeriveLineEnding: true + +ExperimentalAutoDetectBinPacking: false + +FixNamespaceComments: true + +IncludeBlocks: Preserve + + +IndentCaseBlocks: true +IndentCaseLabels: true +IndentExternBlock: AfterExternBlock +IndentGotoLabels: true +IndentPPDirectives: AfterHash +IndentRequires: true +IndentWidth: 4 +IndentWrappedFunctionNames: false + +# InsertNewlineAtEOF: true +InsertTrailingCommas: Wrapped + +LambdaBodyIndentation: OuterScope + +Language: Cpp + +MaxEmptyLinesToKeep: 4 + +NamespaceIndentation: All + +PointerAlignment: Left + +QualifierAlignment: Leave + +ReferenceAlignment: Left + +ReflowComments: true + +# RequiresExpressionIndentation: OuterScope + +SeparateDefinitionBlocks: Always + +ShortNamespaceLines: 40 + +SortIncludes: true +SortUsingDeclarations: true + +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: true +SpaceAfterTemplateKeyword: false + +SpaceAroundPointerQualifiers: Default + +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: true +SpaceBeforeCpp11BracedList: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatementsExceptControlMacros +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpacesBeforeTrailingComments: 4 + +SpaceInEmptyBlock: true +SpaceInEmptyParentheses: false +SpacesInAngles: true +SpacesInCStyleCastParentheses: true +SpacesInConditionalStatement: true +SpacesInContainerLiterals: true +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: 20 +SpacesInParentheses: true +SpacesInSquareBrackets: true + +Standard: c++17 + +TabWidth: 4 + +UseTab: ForIndentation +... diff --git a/test/gen/sanity.gen.hpp b/test/gen/sanity.gen.hpp index ef180dd..a27a965 100644 --- a/test/gen/sanity.gen.hpp +++ b/test/gen/sanity.gen.hpp @@ -3,15 +3,16 @@ // The following will show a series of base cases for the gen api. class TestEmptyClass; + class TestEmptyClass { // Empty class body - }; typedef unsigned char u8; enum ETestEnum : u8; + enum ETestEnum : u8 { A, @@ -23,24 +24,21 @@ enum class ETestEnumClass : u8; extern "C" { // Empty extern body - } class TestFriend { - friend class TestFriendFwd; - + friend class TestFriendFwd; }; -void test_function(void); -void test_function(void) +void test_function( void ); + +void test_function( void ) { // Empty function body - } -#include "DummyInclude.hpp" - +#include "../DummyInclude.hpp" namespace TestNamespace { @@ -48,31 +46,43 @@ namespace TestNamespace }; - -void test_function_wparam(u8 a); -void test_function_wparams(u8 a, u8 b) +enum class EBitFlagtest : u8 { - // Empty function body + A = 1 << 0, + B = 1 << 1, + C = 1 << 2, +}; +EBitFlagtest operator|( EBitFlagtest a, EBitFlagtest b ); + +EBitFlagtest operator|( EBitFlagtest a, EBitFlagtest b ) +{ + return EBitFlagtest( ( u8 )a | ( u8 )b ); } -void test_function_wparams2(u8 a, u8 b) + +void test_function_wparam( u8 a ); + +void test_function_wparams( u8 a, u8 b ) { // Empty function body +} +void test_function_wparams2( u8 a, u8 b ) +{ + // Empty function body } class TestEmptyStruct; + class TestEmptyStruct { // Empty class body - }; union TestEmptyUnion { // Empty union body - }; using TestUsing = u8; @@ -82,4 +92,3 @@ u8 test_variable; u8 test_variable2 = 0x12; // End of base case tests. - diff --git a/test/sanity_suite.cpp b/test/sanity_suite.cpp deleted file mode 100644 index f7e0ab5..0000000 --- a/test/sanity_suite.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "Bloat.cpp" - - -#ifdef gen_time -#include "gen.cpp" - - -void case_untyped() -{ - - -} - - - - - - - - - - - - - - - - -int gen_main() -{ - Memory::setup(); - - log_fmt("\nPress any key after attaching to process\n"); - getchar(); - - gen::init(); - - case_untyped(); - - Memory::cleanup(); - return 0; -} -#endif - - -#ifdef runtime -int main() -{ - return 0; -} -#endif