From 472189a3229996f1a6192b463e1fd17e6e35aaeb Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sat, 8 Jul 2023 23:29:18 -0400 Subject: [PATCH] Base case for extern link parse working. --- project/gen.cpp | 446 +++++++++++++++++++++------- project/gen.hpp | 123 ++++---- test/NonParsed/Sanity.NonParsed.hpp | 20 +- test/Parsed/Sanity.Parsed.hpp | 227 +++++++++++++- 4 files changed, 645 insertions(+), 171 deletions(-) diff --git a/project/gen.cpp b/project/gen.cpp index 3a5f7b3..f622abf 100644 --- a/project/gen.cpp +++ b/project/gen.cpp @@ -27,31 +27,31 @@ namespace gen } #pragma region Constants - Code type_ns(auto); - Code type_ns(void); - Code type_ns(int); - Code type_ns(bool); - Code type_ns(char); - Code type_ns(wchar_t); + Code t_auto; + Code t_void; + Code t_int; + Code t_bool; + Code t_char; + Code t_wchar_t; #ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS - Code type_ns(b32); + Code t_b32; - Code type_ns(s8); - Code type_ns(s16); - Code type_ns(s32); - Code type_ns(s64); + Code t_s8; + Code t_s16; + Code t_s32; + Code t_s64; - Code type_ns(u8); - Code type_ns(u16); - Code type_ns(u32); - Code type_ns(u64); + Code t_u8; + Code t_u16; + Code t_u32; + Code t_u64; - Code type_ns(sw); - Code type_ns(uw); + Code t_sw; + Code t_uw; - Code type_ns(f32); - Code type_ns(f64); + Code t_f32; + Code t_f64; #endif Code access_public; @@ -68,6 +68,7 @@ namespace gen Code spec_constexpr; Code spec_constinit; Code spec_extern_linkage; + Code spec_global; Code spec_inline; Code spec_internal_linkage; Code spec_local_persist; @@ -79,10 +80,6 @@ namespace gen Code spec_static_member; Code spec_thread_local; Code spec_volatile; - Code spec_type_signed; - Code spec_type_unsigned; - Code spec_type_short; - Code spec_type_long; #pragma endregion Constants #pragma region AST Body Case Macros @@ -1004,8 +1001,8 @@ namespace gen Code::Invalid.set_global(); # define def_constant_code_type( Type_ ) \ - type_ns(Type_) = def_type( name(Type_) ); \ - type_ns(Type_).set_global(); + t_##Type_ = def_type( name(Type_) ); \ + t_##Type_.set_global(); def_constant_code_type( auto ); def_constant_code_type( void ); @@ -1015,7 +1012,7 @@ namespace gen def_constant_code_type( wchar_t ); #ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS - type_ns(b32) = def_type( name(b32) ); + t_b32 = def_type( name(b32) ); def_constant_code_type( s8 ); def_constant_code_type( s16 ); @@ -1068,17 +1065,26 @@ namespace gen pragma_once->Content = pragma_once->Name; pragma_once.set_global(); + # pragma push_macro( "global" ) + # pragma push_macro( "internal" ) + # pragma push_macro( "local_persist" ) + # define global global + # define internal internal + # define local_persist local_persist + # define def_constant_spec( Type_, ... ) \ spec_##Type_ = def_specifiers( macro_num_args(__VA_ARGS__), __VA_ARGS__); \ spec_##Type_.set_global(); + def_constant_spec( const, ESpecifier::Const ); def_constant_spec( consteval, ESpecifier::Consteval ); def_constant_spec( constexpr, ESpecifier::Constexpr ); def_constant_spec( constinit, ESpecifier::Constinit ); def_constant_spec( extern_linkage, ESpecifier::External_Linkage ); - def_constant_spec( const, ESpecifier::Const ); + def_constant_spec( global, ESpecifier::Global ); def_constant_spec( inline, ESpecifier::Inline ); def_constant_spec( internal_linkage, ESpecifier::Internal_Linkage ); + def_constant_spec( local_persist, ESpecifier::Local_Persist ); def_constant_spec( mutable, ESpecifier::Mutable ); def_constant_spec( ptr, ESpecifier::Ptr ); def_constant_spec( ref, ESpecifier::Ref ); @@ -1091,6 +1097,10 @@ namespace gen spec_local_persist = def_specifiers( 1, ESpecifier::Local_Persist ); spec_local_persist.set_global(); + # pragma pop_macro( "global" ) + # pragma pop_macro( "internal" ) + # pragma pop_macro( "local_persist" ) + # undef def_constant_spec } @@ -1415,7 +1425,7 @@ namespace gen switch ( params_code->param_count() ) { case 1: - if ( params_code->param_type()->is_equal( type_ns(int) ) ) + if ( params_code->param_type()->is_equal( t_int ) ) is_member_symbol = true; else @@ -1425,7 +1435,7 @@ namespace gen case 2: check_param_eq_ret(); - if ( ! params_code->get_param(1)->is_equal( type_ns(int) ) ) + if ( ! params_code->get_param(1)->is_equal( t_int ) ) { log_failure("gen::def_operator: " "operator%s requires second parameter of non-member definition to be int for post-decrement", @@ -1545,7 +1555,7 @@ namespace gen } } - if ( ! ret_type->is_equal( type_ns(bool) )) + if ( ! ret_type->is_equal( t_bool )) { log_failure("gen::def_operator: operator%s return type must be of type bool - %s" , to_str(op) @@ -2008,7 +2018,7 @@ namespace gen } else { - result->add_entry( type_ns(void) ); + result->add_entry( t_void ); } if ( params ) @@ -3031,57 +3041,59 @@ namespace gen // Any angle brackets found will be considered an operator token. # define Define_TokType \ - Entry( Access_Private, "private" ) \ - Entry( Access_Protected, "protected" ) \ - Entry( Access_Public, "public" ) \ - Entry( Access_MemberSymbol, "." ) \ - Entry( Access_StaticSymbol, "::") \ - Entry( Ampersand, "&" ) \ - Entry( Ampersand_DBL, "&&" ) \ - Entry( Assign_Classifer, ":" ) \ - Entry( BraceCurly_Open, "{" ) \ - Entry( BraceCurly_Close, "}" ) \ - Entry( BraceSquare_Open, "[" ) \ - Entry( BraceSquare_Close, "]" ) \ - Entry( Capture_Start, "(" ) \ - Entry( Capture_End, ")" ) \ - Entry( Comment, "__comment__" ) \ - Entry( Char, "__char__" ) \ - Entry( Comma, "," ) \ - Entry( Decl_Class, "class" ) \ - Entry( Decl_Enum, "enum" ) \ - Entry( Decl_Extern_Linkage, "extern" ) \ - Entry( Decl_Friend, "friend" ) \ - Entry( Decl_Module, "module" ) \ - Entry( Decl_Namespace, "namespace" ) \ - Entry( Decl_Struct, "struct" ) \ - Entry( Decl_Typedef, "typedef" ) \ - Entry( Decl_Using, "using" ) \ - Entry( Decl_Union, "union" ) \ - Entry( Identifier, "__SymID__" ) \ - Entry( Module_Import, "import" ) \ - Entry( Module_Export, "export" ) \ - Entry( Number, "number" ) \ - Entry( Operator, "operator" ) \ - Entry( Spec_Alignas, "alignas" ) \ - Entry( Spec_Const, "const" ) \ - Entry( Spec_Consteval, "consteval" ) \ - Entry( Spec_Constexpr, "constexpr" ) \ - Entry( Spec_Constinit, "constinit" ) \ - Entry( Spec_Extern, "extern" ) \ - Entry( Spec_Inline, "inline" ) \ - Entry( Spec_LocalPersist, "local_persist" ) \ - Entry( Spec_Mutable, "mutable" ) \ - Entry( Spec_Static, "static" ) \ - Entry( Spec_ThreadLocal, "thread_local" ) \ - Entry( Spec_Volatile, "volatile") \ - Entry( Star, "*" ) \ - Entry( Statement_End, ";" ) \ - Entry( String, "__String__" ) \ - Entry( Type_Unsigned, "unsigned" ) \ - Entry( Type_Signed, "signed" ) \ - Entry( Type_Short, "short" ) \ - Entry( Type_Long, "long" ) + Entry( Access_Private, "private" ) \ + Entry( Access_Protected, "protected" ) \ + Entry( Access_Public, "public" ) \ + Entry( Access_MemberSymbol, "." ) \ + Entry( Access_StaticSymbol, "::") \ + Entry( Ampersand, "&" ) \ + Entry( Ampersand_DBL, "&&" ) \ + Entry( Assign_Classifer, ":" ) \ + Entry( BraceCurly_Open, "{" ) \ + Entry( BraceCurly_Close, "}" ) \ + Entry( BraceSquare_Open, "[" ) \ + Entry( BraceSquare_Close, "]" ) \ + Entry( Capture_Start, "(" ) \ + Entry( Capture_End, ")" ) \ + Entry( Comment, "__comment__" ) \ + Entry( Char, "__char__" ) \ + Entry( Comma, "," ) \ + Entry( Decl_Class, "class" ) \ + Entry( Decl_Enum, "enum" ) \ + Entry( Decl_Extern_Linkage, "extern" ) \ + Entry( Decl_Friend, "friend" ) \ + Entry( Decl_Module, "module" ) \ + Entry( Decl_Namespace, "namespace" ) \ + Entry( Decl_Struct, "struct" ) \ + Entry( Decl_Typedef, "typedef" ) \ + Entry( Decl_Using, "using" ) \ + Entry( Decl_Union, "union" ) \ + Entry( Identifier, "__SymID__" ) \ + Entry( Module_Import, "import" ) \ + Entry( Module_Export, "export" ) \ + Entry( Number, "number" ) \ + Entry( Operator, "operator" ) \ + Entry( Spec_Alignas, "alignas" ) \ + Entry( Spec_Const, "const" ) \ + Entry( Spec_Consteval, "consteval" ) \ + Entry( Spec_Constexpr, "constexpr" ) \ + Entry( Spec_Constinit, "constinit" ) \ + Entry( Spec_Extern, "extern" ) \ + Entry( Spec_Global, "global" ) \ + Entry( Spec_Inline, "inline" ) \ + Entry( Spec_Internal_Linkage, "internal" ) \ + Entry( Spec_LocalPersist, "local_persist" ) \ + Entry( Spec_Mutable, "mutable" ) \ + Entry( Spec_Static, "static" ) \ + Entry( Spec_ThreadLocal, "thread_local" ) \ + Entry( Spec_Volatile, "volatile") \ + Entry( Star, "*" ) \ + Entry( Statement_End, ";" ) \ + Entry( String, "__String__" ) \ + Entry( Type_Unsigned, "unsigned" ) \ + Entry( Type_Signed, "signed" ) \ + Entry( Type_Short, "short" ) \ + Entry( Type_Long, "long" ) enum class TokType : u32 { @@ -3674,6 +3686,7 @@ namespace gen Code parse_exten_link ( Parser::TokArray& toks, char const* context ); Code parse_friend ( Parser::TokArray& toks, char const* context ); Code parse_function ( Parser::TokArray& toks, char const* context ); + Code parse_namespace ( Parser::TokArray& toks, char const* context ); Code parse_struct ( Parser::TokArray& toks, char const* context ); Code parse_variable ( Parser::TokArray& toks, char const* context ); Code parse_type ( Parser::TokArray& toks, char const* context ); @@ -3942,7 +3955,8 @@ namespace gen while ( left && currtok.Type != TokType::BraceCurly_Close ) { - Code member = Code::Invalid; + Code member = Code::Invalid; + Code specifiers = Code::Invalid; switch ( currtok.Type ) { @@ -4002,8 +4016,6 @@ namespace gen case TokType::Spec_ThreadLocal: case TokType::Spec_Volatile: { - Code specifiers = Code::Invalid; - SpecifierT specs_found[16] { ESpecifier::Num_Specifiers }; s32 num_specifiers = 0; @@ -4045,33 +4057,35 @@ namespace gen case TokType::Type_Short: case TokType::Type_Long: { - Code specifiers = Code::Invalid; - Code type = parse_type( toks, context ); if ( type == Code::Invalid ) + { + log_failure( "gen::parse_variable: failed to parse type" ); return Code::Invalid; + } Token name = currtok; - - if ( check( TokType::Identifier ) ) - { - name = currtok; - } + eat( TokType::Identifier ); // Parsing a member function if ( check( TokType::Capture_Start )) { Code params = parse_params( toks, context ); if ( params == Code::Invalid ) + { + log_failure( "gen::parse_variable: failed to parse function parameters" ); return Code::Invalid; + } if ( check( TokType::BraceCurly_Open ) ) { Code body = parse_function_body( toks, context); if ( body == Code::Invalid ) + { + log_failure( "gen::parse_variable: failed to parse function body" ); return Code::Invalid; + } - Code member = make_code(); member->Name = get_cached_string( name ); @@ -4128,7 +4142,10 @@ namespace gen } if ( member == Code::Invalid ) + { + log_failure( "gen::parse_variable: failed to parse member" ); return Code::Invalid; + } result->add_entry( member ); } @@ -4176,7 +4193,6 @@ namespace gen case TokType::Decl_Typedef: member = parse_typedef( toks, context ); - break; case TokType::Decl_Union: @@ -4375,22 +4391,248 @@ namespace gen return Code::Invalid; } - Code parse_export_body( StrC def ) + Code parse_extern_link_body( Parser::TokArray& toks, char const* context ) { - not_implemented(); - return Code::Invalid; + using namespace Parser; + using namespace ECode; + + eat( TokType::BraceCurly_Open ); + + Code + result = make_code(); + result->Type = Extern_Linkage_Body; + + while ( left && currtok.Type != TokType::BraceCurly_Close ) + { + Code member = Code::Invalid; + Code specifiers = Code::Invalid; + + switch ( currtok.Type ) + { + case TokType::Comment: + def_comment( currtok ); + eat( TokType::Comment ); + break; + + case TokType::Decl_Enum: + member = parse_enum( toks, context); + break; + + case TokType::Decl_Class: + member = parse_class( toks, context ); + break; + + case TokType::Decl_Extern_Linkage: + log_failure( "gen::parse_extern_link_body: nested extern linkage" ); + return Code::Invalid; + + case TokType::Decl_Namespace: + member = parse_namespace( toks, context ); + break; + + case TokType::Decl_Struct: + member = parse_struct( toks, context ); + break; + + case TokType::Decl_Typedef: + member = parse_typedef( toks, context ); + break; + + case TokType::Decl_Union: + member = parse_union( toks, context ); + break; + + case TokType::Decl_Using: + member = parse_using( toks, context ); + break; + + // TODO: Module support. + // case TokType::Module_Export: + // case TokType::Module_Import: + + case TokType::Spec_Extern: + case TokType::Spec_Global: + case TokType::Spec_Inline: + case TokType::Spec_Internal_Linkage: + case TokType::Spec_Static: + { + SpecifierT specs_found[16] { ESpecifier::Invalid }; + s32 num_specs = 0; + + while ( left && tok_is_specifier( currtok ) ) + { + SpecifierT spec = ESpecifier::to_type( currtok ); + + switch ( spec ) + { + case ESpecifier::Const: + case ESpecifier::External_Linkage: + case ESpecifier::Global: + case ESpecifier::Inline: + case ESpecifier::Internal_Linkage: + break; + + default: + log_failure( "gen::parse_variable: invalid specifier " txt(spec) " for extern linkage scope" ); + return Code::Invalid; + } + + specs_found[num_specs] = spec; + num_specs++; + eat( currtok.Type ); + } + + if ( num_specs ) + { + specifiers = def_specifiers( num_specs, specs_found ); + } + } + case TokType::Identifier: + case TokType::Spec_Const: + case TokType::Type_Long: + case TokType::Type_Short: + case TokType::Type_Signed: + case TokType::Type_Unsigned: + { + Code type = parse_type( toks, context ); + if ( type == Code::Invalid ) + { + log_failure( "gen::parse_extern_link_body: failed to parse type" ); + return Code::Invalid; + } + + Token name = currtok; + eat( TokType::Identifier ); + + // Parsing a function + if ( check( TokType::Capture_Start )) + { + Code params = parse_params( toks, context ); + if ( params == Code::Invalid ) + { + log_failure( "gen::parse_extern_link_body: failed to parse function params" ); + return Code::Invalid; + } + + if ( check( TokType::BraceCurly_Open )) + { + Code body = parse_function_body( toks, context ); + if ( body == Code::Invalid ) + { + log_failure( "gen::parse_extern_link_body: failed to parse function body" ); + return Code::Invalid; + } + + member = make_code(); + member->Name = get_cached_string( name ); + + if ( body ) + { + switch ( body->Type ) + { + case Function_Body: + case Untyped: + break; + + default: + { + log_failure( "gen::parse_extern_link_body: invalid function body" ); + return Code::Invalid; + } + } + + member->Type = Function; + member->add_entry( body ); + } + else + { + member->Type = Function_Fwd; + } + + member->add_entry( type ); + + if ( params ) + member->add_entry( params ); + + break; + } + } + + // Parsing a variable + Code array_expr = parse_array_decl( toks, context ); + Code expr = parse_variable_assignment( toks, context ); + + member = make_code(); + member->Type = Variable; + member->Name = get_cached_string( name ); + + member->add_entry( type ); + + if ( array_expr ) + type->add_entry( array_expr ); + + if ( specifiers ) + member->add_entry( specifiers ); + + if ( expr ) + member->add_entry( expr ); + } + + if ( member == Code::Invalid ) + { + log_failure( "gen::parse_extern_link_body: failed to parse extern linkage member" ); + return Code::Invalid; + } + + result->add_entry( member ); + } + + eat( currtok.Type ); + } + + eat( TokType::BraceCurly_Close ); + return result; } Code parse_extern_link( Parser::TokArray& toks, char const* context ) { - not_implemented(); - return Code::Invalid; + using namespace Parser; + + eat( TokType::Decl_Extern_Linkage ); + + Token name = currtok; + eat( TokType::String ); + + name.Text += 1; + name.Length -= 1; + + Code + result = make_code(); + result->Type = ECode::Extern_Linkage; + result->Name = get_cached_string( name ); + + Code entry = parse_extern_link_body( toks, context ); + if ( entry == Code::Invalid ) + { + log_failure( "gen::parse_extern_link: failed to parse body" ); + return result; + } + + result->add_entry( entry ); + + return result; } Code parse_extern_link( StrC def ) { - not_implemented(); - return Code::Invalid; + check_parse_args( parse_extern_link, def ); + using namespace Parser; + + TokArray toks = lex( def ); + if ( toks.Arr == nullptr ) + return Code::Invalid; + + return parse_extern_link( toks, txt(parse_extern_link) ); } Code parse_friend( Parser::TokArray& toks, char const* context ) @@ -5056,7 +5298,7 @@ namespace gen # undef eat # undef left // End GEN_FEATURE_PARSING -# endif +#endif #pragma endregion Parsing Constructors #pragma region Untyped Constructors diff --git a/project/gen.hpp b/project/gen.hpp index f0d1188..b068380 100644 --- a/project/gen.hpp +++ b/project/gen.hpp @@ -207,16 +207,17 @@ namespace gen alignas */ - #define Define_Specifiers \ + # define Define_Specifiers \ Entry( Invalid, INVALID ) \ Entry( Const, const ) \ Entry( Consteval, consteval ) \ Entry( Constexpr, constexpr ) \ Entry( Constinit, constinit ) \ Entry( External_Linkage, extern ) \ + Entry( Global, global ) \ Entry( Inline, inline ) \ - Entry( Internal_Linkage, static ) \ - Entry( Local_Persist, static ) \ + Entry( Internal_Linkage, internal ) \ + Entry( Local_Persist, local_persist ) \ Entry( Mutable, mutable ) \ Entry( Ptr, * ) \ Entry( Ref, & ) \ @@ -241,9 +242,20 @@ namespace gen { local_persist StrC lookup[ Num_Specifiers ] = { + # pragma push_macro( "global" ) + # pragma push_macro( "internal" ) + # pragma push_macro( "local_persist" ) + # define global global + # define internal internal + # define local_persist local_persist + # define Entry( Spec_, Code_ ) { txt_n_len(Code_) }, Define_Specifiers # undef Entry + + # pragma pop_macro( "global" ) + # pragma pop_macro( "internal" ) + # pragma pop_macro( "local_persist" ) }; return lookup[ specifier ]; @@ -274,7 +286,7 @@ namespace gen return Invalid; } - #undef Define_Specifiers + # undef Define_Specifiers } using SpecifierT = ESpecifier::Type; @@ -382,7 +394,7 @@ namespace gen */ struct AST { - #pragma region Member Functions + # pragma region Member Functions void add_entry( AST* other ); inline @@ -524,7 +536,7 @@ namespace gen } String to_string(); - #pragma endregion Member Functions + # pragma endregion Member Functions constexpr static uw ArrS_Cap = @@ -582,15 +594,15 @@ namespace gen */ struct Code { - #pragma region Statics + # pragma region Statics // Used to identify ASTs that should always be duplicated. (Global constant ASTs) static Code Global; // Used to identify invalid generated code. static Code Invalid; - #pragma endregion Statics + # pragma endregion Statics - #pragma region Member Functions + # pragma region Member Functions inline Code body() { @@ -676,7 +688,7 @@ namespace gen return ast; } - #pragma endregion Member Functions + # pragma endregion Member Functions AST* ast; }; @@ -814,27 +826,26 @@ namespace gen Code def_union_body ( s32 num, Code* codes ); # pragma endregion Upfront - #pragma region Parsing - #ifdef GEN_FEATURE_PARSING - 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 +# pragma region Parsing +# ifdef GEN_FEATURE_PARSING + Code parse_class ( StrC class_def ); + Code parse_enum ( StrC enum_def ); + Code parse_extern_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 - #pragma region Untyped text +# pragma region Untyped text sw token_fmt_va( char* buf, uw buf_size, char const* fmt, s32 num_tokens, va_list va ); inline @@ -855,7 +866,7 @@ namespace gen 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 +# pragma endregion Untyped text struct Builder { @@ -945,7 +956,7 @@ namespace gen }; #endif -# ifdef GEN_FEATURE_SCANNER +#ifdef GEN_FEATURE_SCANNER struct Scanner { struct RequestEntry @@ -974,7 +985,7 @@ namespace gen bool process_requests( Array(Receipt) out_receipts ); }; -# endif +#endif #pragma endregion Gen Interface } @@ -983,9 +994,6 @@ namespace gen # define __ NoCode -// This represents the naming convention for all typename Codes generated. -# define type_ns( Name_ ) t_##Name_ - // Convienence for defining any name used with the gen api. // Lets you provide the length and string literal to the functions without the need for the DSL. # define name( Id_ ) { txt_n_len( Id_ ) } @@ -1000,23 +1008,23 @@ namespace gen { // Predefined typename codes. Are set to readonly and are setup during gen::init() - extern Code type_ns( b32 ); + extern Code t_b32; - extern Code type_ns( s8 ); - extern Code type_ns( s16 ); - extern Code type_ns( s32 ); - extern Code type_ns( s64 ); + extern Code t_s8; + extern Code t_s16; + extern Code t_s32; + extern Code t_s64; - extern Code type_ns( u8 ); - extern Code type_ns( u16 ); - extern Code type_ns( u32 ); - extern Code type_ns( u64 ); + extern Code t_u8; + extern Code t_u16; + extern Code t_u32; + extern Code t_u64; - extern Code type_ns( sw ); - extern Code type_ns( uw ); + extern Code t_sw; + extern Code t_uw; - extern Code type_ns( f32 ); - extern Code type_ns( f64 ); + extern Code t_f32; + extern Code t_f64; } #endif @@ -1042,12 +1050,12 @@ namespace gen // Predefined Codes. Are set to readonly and are setup during gen::init() - extern Code type_ns( auto ); - extern Code type_ns( void ); - extern Code type_ns( int ); - extern Code type_ns( bool ); - extern Code type_ns( char ); - extern Code type_ns( wchar_t ); + extern Code t_auto; + extern Code t_void; + extern Code t_int; + extern Code t_bool; + extern Code t_char; + extern Code t_wchar_t; extern Code access_public; extern Code access_protected; @@ -1063,6 +1071,7 @@ namespace gen extern Code spec_constexpr; extern Code spec_constinit; extern Code spec_extern_linkage; + extern Code spec_global; extern Code spec_inline; extern Code spec_internal_linkage; extern Code spec_local_persist; @@ -1074,10 +1083,6 @@ namespace gen extern Code spec_static_member; extern Code spec_thread_local; extern Code spec_volatile; - extern Code spec_type_signed; - extern Code spec_type_unsigned; - extern Code spec_type_short; - extern Code spec_type_long; } #pragma endregion Constants diff --git a/test/NonParsed/Sanity.NonParsed.hpp b/test/NonParsed/Sanity.NonParsed.hpp index 415b3d7..9c909f9 100644 --- a/test/NonParsed/Sanity.NonParsed.hpp +++ b/test/NonParsed/Sanity.NonParsed.hpp @@ -7,7 +7,7 @@ u32 gen_sanity() { Builder gen_sanity_file; - gen_sanity_file.open("./sanity.gen.hpp"); + gen_sanity_file.open("./sanity.NonParsed.gen.hpp"); // Comment { @@ -159,7 +159,6 @@ u32 gen_sanity() { // Going to make a bit flag set of overloads for this. - Code bitflagtest; { Code body = def_enum_body( 1, untyped_str( code( @@ -185,7 +184,6 @@ u32 gen_sanity() } gen_sanity_file.print(bitflagtest); - gen_sanity_file.print_fmt("\n"); gen_sanity_file.print(op_fwd); gen_sanity_file.print(op_or); } @@ -207,7 +205,10 @@ u32 gen_sanity() , def_comment( StrC::from("Empty function body") ) ); - Code params = def_params( 2 * 3, t_u8, 1, "a", t_u8, 1, "b" ); + Code params = def_params( 2 + , def_param( t_u8, name(a) ) + , def_param( t_u8, name(b) ) + ); def = def_function( name(test_function_wparams), params, __, body ); @@ -231,10 +232,13 @@ u32 gen_sanity() { Code fwd_fn = def_function( name(test_function_specifiers), __, __, __, spec_inline ); - // Need an op overload here + // TODO: Need an op overload here - Code t_ct_u8 = def_type( name(u8), __, spec_constexpr ); - Code typedef_ConstExprTest = def_typedef( name(ConstExprTest), t_ct_u8 ); + Code u8_ptr = def_type( name(u8), __, spec_ptr ); + Code typedef_u8_ptr = def_typedef( name(ConstExprTest), u8_ptr ); + + gen_sanity_file.print(fwd_fn); + gen_sanity_file.print(typedef_u8_ptr); } gen_sanity_file.print_fmt("\n"); @@ -244,7 +248,7 @@ u32 gen_sanity() Code fwd = def_class( name(TestEmptyStruct) ); Code empty_body; { - Code cmt = def_comment( StrC::from("Empty class body") ); + Code cmt = def_comment( StrC::from("Empty struct body") ); Code body = def_class_body( 1, cmt ); empty_body = def_class( name(TestEmptyStruct), body ); diff --git a/test/Parsed/Sanity.Parsed.hpp b/test/Parsed/Sanity.Parsed.hpp index fe53acd..45b2c1d 100644 --- a/test/Parsed/Sanity.Parsed.hpp +++ b/test/Parsed/Sanity.Parsed.hpp @@ -4,11 +4,11 @@ using namespace gen; -void gen_sanity() +u32 gen_sanity() { Builder gen_sanity_file; - gen_sanity_file.open("./sanity.gen.hpp"); + gen_sanity_file.open("./sanity.Parsed.gen.hpp"); gen_sanity_file.print( def_comment( StrC::from( "The following will show a series of base cases for the gen parsed api.\n" @@ -72,11 +72,234 @@ void gen_sanity() // External Linkage { + Code empty_comment = def_comment( StrC::from("Empty external linkage") ); + Code c_extern = parse_extern_link( code( + extern "C" + { + }; + )); + + c_extern.body()->add_entry( empty_comment ); + + gen_sanity_file.print(c_extern); } gen_sanity_file.print_fmt("\n"); + // Friend + if (0) + { + Code fwd = parse_class( code( + class TestFriendClass; + )); + + Code def = parse_class( code( + class TestFriend + { + friend class TestFriendClass; + }; + )); + + gen_sanity_file.print(fwd); + gen_sanity_file.print(def); + } + + gen_sanity_file.print_fmt("\n"); + + // Function + if (0) + { + Code fwd = parse_function( code( + void test_function(); + )); + + Code def = parse_function( code( + void test_function() + { + } + )); + + def.body()->add_entry( def_comment( StrC::from("Empty function body") ) ); + + gen_sanity_file.print(fwd); + gen_sanity_file.print(def); + } + + gen_sanity_file.print_fmt("\n"); + + // Namespace + if (0) + { + Code def = parse_namespace( code( + namespace TestNamespace + { + } + )); + + def.body()->add_entry( def_comment( StrC::from("Empty namespace body") ) ); + + gen_sanity_file.print(def); + } + + gen_sanity_file.print_fmt("\n"); + + // Operator + + if (0) + { + Code bitflagtest = parse_class( code( + enum class EBitFlagTest : u8 + { + A = 1 << 0, + B = 1 << 1, + C = 1 << 2 + }; + )); + + Code op_fwd = parse_operator( code( + EBitFlagTest operator | ( EBitFlagTest a, EBitFlagTest b ); + )); + + Code op_or = parse_operator( code( + EBitFlagTest operator | ( EBitFlagTest a, EBitFlagTest b ) + { + return EBitFlagTest( (u8)a | (u8)b ); + } + )); + + gen_sanity_file.print(bitflagtest); + gen_sanity_file.print(op_fwd); + gen_sanity_file.print(op_or); + } + + gen_sanity_file.print_fmt("\n"); + + // Parameters + if (0) + { + Code fwd = parse_function( code( + void test_function( int a ); + )); + + Code def = parse_function( code( + void test_function( int a, int b ) + { + } + )); + + def.body()->add_entry( def_comment( StrC::from("Empty function body") ) ); + + gen_sanity_file.print(fwd); + gen_sanity_file.print(def); + } + + gen_sanity_file.print_fmt("\n"); + + // Specifiers + if (0) + { + Code fwd_fn = parse_function( code( + inline + void test_function_specifiers(); + )); + + Code typedef_u8_ptr = parse_typedef( code( + typedef u8* u8_ptr; + )); + + gen_sanity_file.print(fwd_fn); + gen_sanity_file.print(typedef_u8_ptr); + } + + gen_sanity_file.print_fmt("\n"); + + // Struct + if (0) + { + Code fwd = parse_struct( code( + struct TestEmptyStruct; + )); + + Code empty_body = parse_struct( code( + struct TestEmptyStruct + {}; + )); + + empty_body.body()->add_entry( def_comment( StrC::from("Empty struct body") ) ); + + gen_sanity_file.print(fwd); + gen_sanity_file.print(empty_body); + } + + gen_sanity_file.print_fmt("\n"); + + // Union + if (0) + { + Code empty = parse_union( code( + union TestEmptyUnion + { + }; + )); + + empty.body()->add_entry( def_comment( StrC::from("Empty union body") ) ); + + Code def = parse_union( code( + union TestUnion + { + u8 a; + u16 b; + u32 c; + }; + )); + + gen_sanity_file.print(empty); + gen_sanity_file.print(def); + } + + gen_sanity_file.print_fmt("\n"); + + // Using + if (0) + { + Code reg = parse_using( code( + using TestUsing = u8; + )); + + Code nspace = parse_using( code( + namespace TestNamespace + { + }; + + using namespace TestUsing; + )); + + gen_sanity_file.print(reg); + gen_sanity_file.print(nspace); + } + + gen_sanity_file.print_fmt("\n"); + + // Variable + if (0) + { + Code bss = parse_variable( code( + u8 test_variable; + )); + + Code data = parse_variable( code( + u8 test_variable = 0x12; + )); + } + + gen_sanity_file.print_fmt("\n"); + + gen_sanity_file.print( def_comment( StrC::from( + "End of base case tests\n" + ))); + gen_sanity_file.write(); + return 0; } #endif