diff --git a/project/gen.cpp b/project/gen.cpp index 5553959..11553ec 100644 --- a/project/gen.cpp +++ b/project/gen.cpp @@ -65,6 +65,7 @@ namespace gen # define AST_BODY_CLASS_UNALLOWED_TYPES \ case Class_Body: \ case Enum_Body: \ + case Extern_Linkage: \ case Friend: \ case Function_Body: \ case Function_Fwd: \ @@ -84,6 +85,7 @@ namespace gen case Access_Private: \ case Class_Body: \ case Enum_Body: \ + case Extern_Linkage: \ case Friend: \ case Function_Body: \ case Function_Fwd: \ @@ -135,8 +137,27 @@ namespace gen case Struct_Body: \ case Typename: +# define AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES \ + case Access_Public: \ + case Access_Protected: \ + case Access_Private: \ + case Class_Body: \ + case Enum_Body: \ + case Execution: \ + case Friend: \ + case Function_Body: \ + case Global_Body: \ + case Namespace_Body: \ + case Operator_Member: \ + case Operator_Member_Fwd: \ + case Parameters: \ + case Specifiers: \ + case Struct_Body: \ + case Typename: + # define AST_BODY_STRUCT_UNALLOWED_TYPES \ case Enum_Body: \ + case Extern_Linkage: \ case Execution: \ case Function_Body: \ case Global_Body: \ @@ -206,7 +227,7 @@ namespace gen { AST_BODY_CLASS_UNALLOWED_TYPES { - log_failure( "AST::add: Cannot add an AST to a class body." ); + log_failure( "AST::add: Cannot add %s to a class body.", other->type_str() ); return false; } @@ -223,6 +244,23 @@ namespace gen log_failure( "AST::add: Cannot add an AST to an enum forward declaration." ); return false; + 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_Body: if ( other->Type != Untyped ) { @@ -252,7 +290,7 @@ namespace gen { AST_BODY_FUNCTION_UNALLOWED_TYPES { - log_failure( "AST::add: Cannot add an AST to a function body." ); + log_failure( "AST::add: Cannot add %s to a function body.", other->type_str() ); return false; } @@ -270,7 +308,7 @@ namespace gen { AST_BODY_GLOBAL_UNALLOWED_TYPES { - log_failure( "AST::add: Cannot add an AST to a global body." ); + log_failure( "AST::add: Cannot add %s to a global body.", other->type_str() ); return false; } @@ -279,7 +317,6 @@ namespace gen } break; - case Namespace: if ( Type != Global_Body ) { @@ -292,7 +329,7 @@ namespace gen { AST_BODY_NAMESPACE_UNALLOWED_TYPES { - log_failure( "AST::add: Cannot add an AST to a namespace body." ); + log_failure( "AST::add: Cannot add %s to a namespace body.", other->type_str() ); return false; } @@ -326,7 +363,7 @@ namespace gen { AST_BODY_STRUCT_UNALLOWED_TYPES { - log_failure( "AST::add: Cannot add to a struct body." ); + log_failure( "AST::add: Cannot add %s to a struct body.", other->type_str() ); return false; } @@ -384,10 +421,6 @@ namespace gen case Access_Public: case Access_Protected: case Access_Private: - case Class_Fwd: - case Enum_Fwd: - case Function_Fwd: - case Specifiers: // Can just be the same, as its a cached string. result->Content = Content; return result; @@ -395,16 +428,28 @@ namespace gen // The main purpose of this is to make sure entires in the AST are unique, // So that we can assign the new parent without corrupting the existing AST. case Class: + case Class_Fwd: case Class_Body: case Enum: + case Enum_Fwd: case Enum_Body: + case Enum_Class: + case Enum_Class_Fwd: + case Extern_Linkage: + case Extern_Linkage_Body: case Friend: + case Function: + case Function_Fwd: + case Function_Body: case Global_Body: case Namespace: case Namespace_Body: + case Operator: + case Operator_Fwd: + case Operator_Member: + case Operator_Member_Fwd: case Parameters: - case Function: - case Function_Body: + case Specifiers: case Struct: case Struct_Fwd: case Struct_Body: @@ -412,6 +457,7 @@ namespace gen case Typedef: case Typename: case Using: + case Using_Namespace: s32 index = 0; s32 left = num_entries(); while ( left -- ) @@ -532,6 +578,10 @@ namespace gen result = string_append_fmt( result, "enum class %s : %s;\n", Name, underlying_type()->to_string() ); break; + case Extern_Linkage: + result = string_append_fmt( result, "extern %s\n{\n%s\n};\n", Name, body()->to_string() ); + break; + case Friend: result = string_append_fmt( result, "friend %s;\n", Entries[0]->to_string() ); break; @@ -773,6 +823,7 @@ namespace gen case Class_Body: case Enum_Body: + case Extern_Linkage_Body: case Function_Body: case Global_Body: case Namespace_Body: @@ -1581,6 +1632,32 @@ namespace gen result = make_code(); result->Type = ECode::Execution; + result->add_entry( untyped_code ); + + result.lock(); + return result; + } + + Code def_extern_linkage( s32 length, char const* name, Code body ) + { + using namespace ECode; + + name_check( def_extern_linkage, length, name ); + null_check( def_extern_linkage, body ); + + if ( body->Type != Extern_Linkage_Body || body->Type != Untyped ) + { + log_failure("gen::def_extern_linkage: body is not of extern_linkage or untyped type %s", body->debug_str()); + return Code::Invalid; + } + + Code + result = make_code(); + result->Type = Extern_Linkage; + result->Name = get_cached_string( name, length ); + + result->add_entry( body ); + result.lock(); return result; } @@ -1697,18 +1774,18 @@ namespace gen name_check( def_namespace, length, name ); null_check( def_namespace, body ); - Code - result = make_code(); - result->Type = Namespace; - result->Name = get_cached_string( name, length ); - result->Entries = make_code_entries(); - if ( body->Type != Namespace_Body || body->Type != Untyped ) { log_failure("gen::def_namespace: body is not of namespace or untyped type %s", body->debug_str()); return Code::Invalid; } + Code + result = make_code(); + result->Type = Namespace; + result->Name = get_cached_string( name, length ); + result->Entries = make_code_entries(); + result->add_entry( body ); result.lock(); @@ -1763,7 +1840,7 @@ namespace gen return result; } - Code def_param( Code type, s32 length, char const* name ) + Code def_param( Code type, s32 length, char const* name, Code value ) { using namespace ECode; @@ -1776,6 +1853,12 @@ namespace gen return Code::Invalid; } + if ( value && value->Type != Untyped ) + { + log_failure( "gen::def_param: value is not untyped - %s", value->debug_str() ); + return Code::Invalid; + } + Code result = make_code(); result->Type = Parameters; @@ -1783,6 +1866,9 @@ namespace gen result->add_entry( type ); + if ( value ) + result->add_entry( value ); + result.lock(); return result; } @@ -2141,6 +2227,41 @@ namespace gen return result; } + Code def_extern_linkage_body( s32 num, ... ) + { + def_body_start( def_extern_linkage_body ); + + Code + result = make_code(); + result->Type = Extern_Linkage_Body; + + va_list va; + va_start(va, num); + def_body_code_validation_start( def_extern_linkage_body, va_arg(va, Code) ); + AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES + def_body_code_validation_end( def_extern_linkage_body ); + va_end(va); + + result.lock(); + return result; + } + + Code def_extern_linkage_body( s32 num, Code* codes ) + { + def_body_code_array_start( def_extern_linkage_body ); + + Code + result = make_code(); + result->Type = Extern_Linkage_Body; + + def_body_code_validation_start( def_extern_linkage_body, *codes; codes++ ); + AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES + def_body_code_validation_end( def_extern_linkage_body ); + + result.lock(); + return result; + } + Code def_function_body( s32 num, ... ) { def_body_start( def_function_body ); @@ -2267,8 +2388,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->Entries = make_code_entries(); + result->Name = get_cached_string( name, name_length ); if ( type->Type != Typename ) { @@ -2531,14 +2651,18 @@ namespace gen return result; } - Code make_global_body( s32 length, char const* name, s32 num, ... ) + Code make_global_body( s32 length, char const* name ) { name_check( make_global_body, length, name ); Code result = make_code(); result->Type = ECode::Global_Body; - result->Name = get_cached_string( name, length ); + + if ( length > 0 ) + result->Name = get_cached_string( name, length ); + + return result; } @@ -2744,6 +2868,11 @@ namespace gen sptr Length; TokType Type; bool IsAssign; + + operator bool() + { + return Text && Length && Type != TokType::Invalid; + } }; TokType get_tok_type( char const* word, s32 length ) @@ -3266,6 +3395,160 @@ namespace gen # define check( Type_ ) left && currtok.Type == Type_ #pragma endregion Helper Macros + Code parse_type( Parser::TokArray& toks, char const* func_name ); + + inline + Code parse_array_decl( Parser::TokArray& toks, char const* func_name ) + { + using namespace Parser; + + if ( check( TokType::BraceSquare_Open ) ) + { + eat( TokType::BraceSquare_Open ); + + if ( left == 0 ) + { + log_failure( "%s: Error, unexpected end of typedef definition ( '[]' scope started )", txt(parse_typedef) ); + return Code::Invalid; + } + + if ( currtok.Type == TokType::BraceSquare_Close ) + { + log_failure( "%s: Error, empty array expression in typedef definition", txt(parse_typedef) ); + return Code::Invalid; + } + + Token untyped_tok = currtok; + + while ( left && currtok.Type != TokType::BraceSquare_Close ) + { + untyped_tok.Length = ( (sptr)currtok.Text + currtok.Length ) - (sptr)untyped_tok.Text; + } + + Code array_expr = untyped_str( untyped_tok.Length, untyped_tok.Text ); + + if ( left == 0 ) + { + log_failure( "%s: Error, unexpected end of type definition, expected ]", txt(parse_typedef) ); + return Code::Invalid; + } + + if ( currtok.Type != TokType::BraceSquare_Close ) + { + log_failure( "%s: Error, expected ] in type definition, not %s", txt(parse_typedef), str_tok_type( currtok.Type ) ); + return Code::Invalid; + } + + eat( TokType::BraceSquare_Close ); + return array_expr; + } + + return Code::Invalid; + } + + inline + Parser::Token parse_identifier( Parser::TokArray& toks, char const* func_name ) + { + using namespace Parser; + Token name = currtok; + + eat( TokType::Identifier ); + + while ( left && currtok.Type == TokType::Access_StaticSymbol ) + { + eat( TokType::Access_StaticSymbol ); + + if ( left == 0 ) + { + log_failure( "%s: Error, unexpected end of type definition, expected identifier", func_name ); + return { nullptr, 0, TokType::Invalid }; + } + + if ( currtok.Type != TokType::Identifier ) + { + log_failure( "%s: Error, expected identifier in type definition, not %s", func_name, str_tok_type( currtok.Type ) ); + return { nullptr, 0, TokType::Invalid }; + } + + name.Length = ( (sptr)currtok.Text + currtok.Length ) - (sptr)name.Text; + eat( TokType::Identifier ); + } + + return name; + } + + Code parse_params( Parser::TokArray& toks, char const* context ) + { + using namespace Parser; + using namespace ECode; + + eat( TokType::Capture_Start ); + + if ( check(TokType::Capture_End) ) + { + eat( TokType::Capture_End ); + return { nullptr }; + } + + Code + result = make_code(); + result->Type = Parameters; + + while ( left && currtok.Type != TokType::Capture_End) + { + Code type = { nullptr }; + Code value = { nullptr }; + + type = parse_type( toks, context ); + if ( type == Code::Invalid ) + return Code::Invalid; + + Token name = currtok; + eat( TokType::Identifier ); + + if ( currtok.IsAssign ) + { + eat( TokType::Operator ); + + Token value_tok = currtok; + + if ( currtok.Type == TokType::Statement_End ) + { + log_failure( "gen::%s: Expected value after assignment operator", context ); + return Code::Invalid; + } + + while ( left && currtok.Type != TokType::Statement_End ) + { + value_tok.Length = ( (sptr)currtok.Text + currtok.Length ) - (sptr)value_tok.Text; + eat( currtok.Type ); + } + + value = parse_type( toks, context ); + } + + Code + param = make_code(); + param->Type = Parameters; + param->Name = get_cached_string( name.Text, name.Length ); + + param->add_entry( type ); + + if ( value ) + param->add_entry( value ); + + param.lock(); + + result->add_entry( param ); + eat( TokType::Comma ); + } + eat( TokType::Capture_End ); + + result.lock(); + return result; + # undef context + } + Code parse_class( s32 length, char const* def ) { using namespace Parser; @@ -3391,14 +3674,10 @@ namespace gen # undef context } - Code parse_execution( s32 length, char const* exec_def ) - { - not_implemented( parse_execution ); - } - Code parse_friend( s32 length, char const* def ) { using namespace Parser; + using namespace ECode; # define context parse_friend check_parse_args( parse_friend, length, def ); @@ -3409,19 +3688,46 @@ namespace gen eat( TokType::Decl_Friend ); - // This can either be a simple type, or a function declaration. - // If its a function declaration, it will have a return type, followed by a name, followed by a parameter list. - // If its a simple type, it will have a type, followed by a name. + Code function = { nullptr }; + // Type declaration or return type + Code type = parse_type( toks, txt(parse_friend) ); + if ( type == Code::Invalid ) + return Code::Invalid; + // Funciton declaration + if ( currtok.Type == TokType::Identifier ) + { + // Name + Token name = parse_identifier( toks, txt(parse_friend) ); + // Parameter list + Code params = parse_params( toks, txt(parse_friend) ); - using namespace ECode; + function = make_code(); + function->Type = Function_Fwd; + function->Name = get_cached_string( name.Text, name.Length ); + function->add_entry( type ); - Code result = make_code(); + if ( params ) + function->add_entry( params ); + function.lock(); + } + eat( TokType::Statement_End ); + Code + result = make_code(); + result->Type = Friend; + + if ( function ) + result->add_entry( function ); + + else + result->add_entry( type ); + + result.lock(); return result; } @@ -3441,48 +3747,12 @@ namespace gen arena_init_from_allocator( & mem, heap(), kilobytes( 10 ) ); do_once_end - // Pretty sure its impossible to have more than this. - SpecifierT specs_found[16] { ESpecifier::Num_Specifiers }; - - u8 num_specifiers; - - // Making all significant tokens have a max length of 128 for this parser. - constexpr sw LengthID = 128; - - struct Param - { - char const Type[LengthID]; - char const Name[LengthID]; - }; - - static - Param Params[ 64 ] { 0 }; - - using namespace ECode; - - Code specifiers = def_specifiers( num_specifiers, specs_found ); - - Code params = make_code(); - // Code ret_type = def_type( ret_length, ret_type_str ); - // Code body = untyped_str( body_length, body_str ); - Code - result = make_code(); - // result->Name = get_cached_string( name, name_length ); - result->Type = Function; + result = make_code(); - // result->add_entry( body ); - - if ( specifiers ) - result->add_entry( specifiers ); - - // result->add_entry( ret_type ); - - if ( params ) - result->add_entry( params ); result.lock(); return result; @@ -3530,7 +3800,7 @@ namespace gen if ( toks.Arr == nullptr ) return Code::Invalid; - Token* name = nullptr; + Token name = { nullptr, 0, TokType::Invalid }; SpecifierT specs_found[16] { ESpecifier::Num_Specifiers }; s32 num_specifiers = 0; @@ -3613,7 +3883,7 @@ namespace gen return Code::Invalid; } - name = & currtok; + name = currtok; eat( TokType::Identifier ); Code expr = { nullptr }; @@ -3639,46 +3909,7 @@ namespace gen expr = untyped_str( expr_tok.Length, expr_tok.Text ); } - if ( check( TokType::BraceSquare_Open ) ) - { - eat( TokType::BraceSquare_Open ); - - if ( left == 0 ) - { - log_failure( "%s: Error, unexpected end of typedef definition ( '[]' scope started )", txt(parse_typedef) ); - return Code::Invalid; - } - - if ( currtok.Type == TokType::BraceSquare_Close ) - { - log_failure( "%s: Error, empty array expression in typedef definition", txt(parse_typedef) ); - return Code::Invalid; - } - - Token - untyped_tok = currtok; - - while ( left && currtok.Type != TokType::BraceSquare_Close ) - { - untyped_tok.Length = ( (sptr)currtok.Text + currtok.Length ) - (sptr)untyped_tok.Text; - } - - array_expr = untyped_str( untyped_tok.Length, untyped_tok.Text ); - - if ( left == 0 ) - { - log_failure( "%s: Error, unexpected end of type definition, expected ]", txt(parse_typedef) ); - return Code::Invalid; - } - - if ( currtok.Type != TokType::BraceSquare_Close ) - { - log_failure( "%s: Error, expected ] in type definition, not %s", txt(parse_typedef), str_tok_type( currtok.Type ) ); - return Code::Invalid; - } - - eat( TokType::BraceSquare_Close ); - } + array_expr = parse_array_decl( toks, txt(parse_variable) ); eat( TokType::Statement_End ); @@ -3686,7 +3917,7 @@ namespace gen Code result = make_code(); result->Type = Variable; - result->Name = get_cached_string( name->Text, name->Length ); + result->Name = get_cached_string( name.Text, name.Length ); result->add_entry( type ); @@ -3742,13 +3973,14 @@ namespace gen name = currtok; eat( currtok.Type ); - name.Length = ( (sptr)currtok.Text + currtok.Length ) - (sptr)name.Text; + name.Length = ( (sptr)currtok.Text + currtok.Length ) - (sptr)name.Text; eat( TokType::Identifier ); } else { - name = currtok; - eat( TokType::Identifier ); + name = parse_identifier( toks, func_name ); + if ( ! name ) + return Code::Invalid; } while ( left && tok_is_specifier( currtok ) ) @@ -3836,45 +4068,7 @@ namespace gen name = currtok; eat( TokType::Identifier ); - if ( check( TokType::BraceSquare_Open ) ) - { - eat( TokType::BraceSquare_Open ); - - if ( left == 0 ) - { - log_failure( "%s: Error, unexpected end of typedef definition ( '[]' scope started )", txt(parse_typedef) ); - return Code::Invalid; - } - - if ( currtok.Type == TokType::BraceSquare_Close ) - { - log_failure( "%s: Error, empty array expression in typedef definition", txt(parse_typedef) ); - return Code::Invalid; - } - - Token untyped_tok = currtok; - - while ( left && currtok.Type != TokType::BraceSquare_Close ) - { - untyped_tok.Length = ( (sptr)currtok.Text + currtok.Length ) - (sptr)untyped_tok.Text; - } - - array_expr = untyped_str( untyped_tok.Length, untyped_tok.Text ); - - if ( left == 0 ) - { - log_failure( "%s: Error, unexpected end of type definition, expected ]", txt(parse_typedef) ); - return Code::Invalid; - } - - if ( currtok.Type != TokType::BraceSquare_Close ) - { - log_failure( "%s: Error, expected ] in type definition, not %s", txt(parse_typedef), str_tok_type( currtok.Type ) ); - return Code::Invalid; - } - - eat( TokType::BraceSquare_Close ); - } + array_expr = parse_array_decl( toks, txt(parse_typedef) ); eat( TokType::Statement_End ); @@ -3932,46 +4126,7 @@ namespace gen type = parse_type( toks, txt(parse_typedef) ); } - if ( ! is_namespace && check( TokType::BraceSquare_Open ) ) - { - eat( TokType::BraceSquare_Open ); - - if ( left == 0 ) - { - log_failure( "%s: Error, unexpected end of typedef definition ( '[]' scope started )", txt(parse_typedef) ); - return Code::Invalid; - } - - if ( currtok.Type == TokType::BraceSquare_Close ) - { - log_failure( "%s: Error, empty array expression in typedef definition", txt(parse_typedef) ); - return Code::Invalid; - } - - Token - untyped_tok = currtok; - - while ( left && currtok.Type != TokType::BraceSquare_Close ) - { - untyped_tok.Length = ( (sptr)currtok.Text + currtok.Length ) - (sptr)untyped_tok.Text; - } - - array_expr = untyped_str( untyped_tok.Length, untyped_tok.Text ); - - if ( left == 0 ) - { - log_failure( "%s: Error, unexpected end of type definition, expected ]", txt(parse_typedef) ); - return Code::Invalid; - } - - if ( currtok.Type != TokType::BraceSquare_Close ) - { - log_failure( "%s: Error, expected ] in type definition, not %s", txt(parse_typedef), str_tok_type( currtok.Type ) ); - return Code::Invalid; - } - - eat( TokType::BraceSquare_Close ); - } + array_expr = parse_array_decl( toks, txt(parse_typedef) ); eat( TokType::Statement_End ); diff --git a/project/gen.hpp b/project/gen.hpp index 1ee55b0..f55e67c 100644 --- a/project/gen.hpp +++ b/project/gen.hpp @@ -51,6 +51,8 @@ namespace gen Entry( Enum_Class ) \ Entry( Enum_Class_Fwd ) \ Entry( Execution ) \ + Entry( Extern_Linkage ) \ + Entry( Extern_Linkage_Body ) \ Entry( Friend ) \ Entry( Function ) \ Entry( Function_Fwd ) \ @@ -214,7 +216,6 @@ namespace gen Entry( API_Export, API_Import_Code ) \ Entry( Alignas, alignas ) \ Entry( Array_Decl, "You cannot stringize an array declare this way" ) \ - Entry( C_Linkage, extern "C" ) \ Entry( Const, const ) \ Entry( Consteval, consteval ) \ Entry( Constexpr, constexpr ) \ @@ -714,10 +715,11 @@ namespace gen Code def_friend ( Code symbol ); Code def_function ( s32 length, char const* name, Code params = NoCode, Code ret_type = NoCode, Code specifiers = NoCode, Code body = NoCode ); + Code def_extern_linkage ( s32 length, char const* name, Code body ); Code def_namespace ( s32 length, char const* name, Code body ); Code def_operator ( OperatorT op, Code params = NoCode, Code ret_type = NoCode, Code specifiers = NoCode, Code body = NoCode ); - Code def_param ( Code type, s32 length, char const* name ); + Code def_param ( Code type, s32 length, char const* name, Code value = NoCode ); Code def_specifier ( SpecifierT specifier ); @@ -728,34 +730,37 @@ namespace gen Code def_variable ( Code type, s32 length, char const* name, Code value = NoCode, Code specifiers = NoCode ); - Code def_class_body ( s32 num, ... ); - Code def_enum_body ( u32 num, ... ); - Code def_enum_body ( u32 num, Code* codes ); - Code def_global_body ( s32 num, ... ); - Code def_global_body ( s32 num, Code* codes ); - Code def_function_body ( s32 num, ... ); - Code def_function_body ( s32 num, Code* codes ); - Code def_namespace_body ( s32 num, ... ); - Code def_namespace_body ( s32 num, Code* codes ); - Code def_params ( s32 num, ... ); - Code def_params ( s32 num, Code* params ); - Code def_specifiers ( s32 num , ... ); - Code def_specifiers ( s32 num, SpecifierT* specs ); - Code def_struct_body ( s32 num, ... ); - Code def_struct_body ( s32 num, Code* codes ); + Code def_class_body ( s32 num, ... ); + Code def_enum_body ( s32 num, ... ); + Code def_enum_body ( s32 num, Code* codes ); + Code def_extern_linkage_body( s32 num, ... ); + Code def_extern_linkage_body( s32 num, Code* codes ); + Code def_global_body ( s32 num, ... ); + Code def_global_body ( s32 num, Code* codes ); + Code def_function_body ( s32 num, ... ); + Code def_function_body ( s32 num, Code* codes ); + Code def_namespace_body ( s32 num, ... ); + Code def_namespace_body ( s32 num, Code* codes ); + Code def_params ( s32 num, ... ); + Code def_params ( s32 num, Code* params ); + Code def_specifiers ( s32 num , ... ); + Code def_specifiers ( s32 num, SpecifierT* specs ); + Code def_struct_body ( s32 num, ... ); + Code def_struct_body ( s32 num, Code* codes ); # pragma endregion Upfront # pragma region Incremental # ifdef GEN_FEATURE_INCREMENTAL - Code make_class ( s32 length, char const* name, Code parent = NoCode, Code specifiers = NoCode ); - Code make_enum ( s32 length, char const* name, Code type = NoCode, EnumT specifier = EnumRegular ); - Code make_function ( s32 length, char const* name, Code params = NoCode, Code ret_type = NoCode, Code specifiers = NoCode ); - Code make_global_body ( s32 length = 1, char const* name = "", s32 num = 0, ... ); - Code make_namespace ( s32 length, char const* name ); - Code make_operator ( OperatorT op, Code params = NoCode, Code ret_type = NoCode, Code specifiers = NoCode ); - Code make_params (); - Code make_specifiers (); - Code make_struct ( s32 length, char const* name, Code parent = NoCode, Code specifiers = NoCode ); + Code make_class ( s32 length, char const* name, Code parent = NoCode, Code specifiers = NoCode ); + Code make_enum ( s32 length, char const* name, Code type = NoCode, EnumT specifier = EnumRegular ); + Code make_extern_linkage( s32 length, char const* name ); + Code make_function ( s32 length, char const* name, Code params = NoCode, Code ret_type = NoCode, Code specifiers = NoCode ); + Code make_global_body ( s32 length = 1, char const* name = "" ); + Code make_namespace ( s32 length, char const* name ); + Code make_operator ( OperatorT op, Code params = NoCode, Code ret_type = NoCode, Code specifiers = NoCode ); + Code make_params (); + Code make_specifiers (); + Code make_struct ( s32 length, char const* name, Code parent = NoCode, Code specifiers = NoCode ); # endif # pragma endregion Incremental @@ -763,7 +768,6 @@ namespace gen #ifdef GEN_FEATURE_PARSING Code parse_class ( s32 length, char const* class_def ); Code parse_enum ( s32 length, char const* enum_def ); - Code parse_execution ( s32 length, char const* exec_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 ); @@ -1007,28 +1011,29 @@ namespace gen // Upfront -# define class( Name_, ... ) gen::def_class( txt_n_len(Name_), __VA_ARGS__ ) -# define enum( Name_, Type_, Body_ ) gen::def_enum ( txt_n_len(Name_), type_ns(Type_), Body_ ) +# define class( Name_, ... ) gen::def_class( txt_n_len(Name_), __VA_ARGS__ ) +# define enum( Name_, Type_, Body_ ) gen::def_enum ( txt_n_len(Name_), type_ns(Type_), Body_ ) -# define function( ... ) macrofn_polymorphic( function, __VA_ARGS__ ) -# define namespace( Name_, Body_ ) gen::def_namespace ( txt_n_len(Name_), Body_ ) -# define operator( Op_, ... ) macrofn_polymorphic( operator, __VA_ARGS__ ) -# define params( ... ) macrofn_polymorphic( params, __VA_ARGS__ ) -# define specifiers( ... ) gen::def_specifiers ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ ) -# define struct( Name_, ... ) gen::def_struct ( txt_n_len(Name_), __VA_ARGS__ ) -# define variable( Type_, Name_, ... ) gen::def_variable ( type_ns(Type_), txt_n_len(Name_), __VA_ARGS__ ) -# define type( Value_, ... ) gen::def_type ( txt_n_len(Value_), __VA_ARGS__ ) -# define type_fmt( Fmt_, ... ) gen::def_type ( bprintf( Fmt_, __VA_ARGS__ ) ) -# define using( Name_, Type_ ) gen::def_using ( txt_n_len(Name_), type_ns(Type_) ) -# define using_namespace( Name_ ) gen::def_using_namespace( txt_n_len(Name_) ) +# define extern_linkage( Name_, Body_ ) gen::def_extern_linkage( txt_n_len(Name_), Body_ ) +# define function( ... ) macrofn_polymorphic( function, __VA_ARGS__ ) +# define namespace( Name_, Body_ ) gen::def_namespace ( txt_n_len(Name_), Body_ ) +# define operator( Op_, ... ) macrofn_polymorphic( operator, __VA_ARGS__ ) +# define params( ... ) macrofn_polymorphic( params, __VA_ARGS__ ) +# define specifiers( ... ) gen::def_specifiers ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ ) +# define struct( Name_, ... ) gen::def_struct ( txt_n_len(Name_), __VA_ARGS__ ) +# define variable( Type_, Name_, ... ) gen::def_variable ( type_ns(Type_), txt_n_len(Name_), __VA_ARGS__ ) +# define type( Value_, ... ) gen::def_type ( txt_n_len(Value_), __VA_ARGS__ ) +# define type_fmt( Fmt_, ... ) gen::def_type ( bprintf( Fmt_, __VA_ARGS__ ) ) +# define using( Name_, Type_ ) gen::def_using ( txt_n_len(Name_), type_ns(Type_) ) +# define using_namespace( Name_ ) gen::def_using_namespace( txt_n_len(Name_) ) -# define class_body( ... ) gen::def_class_body ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ ) -# define enum_body( ... ) gen::def_enum_body ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ ) -# define global_body( ... ) gen::def_global_body ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ ) -# define function_body( ... ) gen::def_function_body ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ ) -# define namespace_body( ... ) gen::def_namespace_body( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ ) -# define operator_body( ... ) gen::def_operator_body ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ ) -# define struct_body( ... ) gen::def_struct_body ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ ) +# define class_body( ... ) gen::def_class_body ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ ) +# define enum_body( ... ) gen::def_enum_body ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ ) +# define global_body( ... ) gen::def_global_body ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ ) +# define function_body( ... ) gen::def_function_body ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ ) +# define namespace_body( ... ) gen::def_namespace_body( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ ) +# define operator_body( ... ) gen::def_operator_body ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ ) +# define struct_body( ... ) gen::def_struct_body ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ ) # ifdef GEN_FEATURE_INCREMENTAL // Incremental