mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-10-31 06:50:53 -07:00 
			
		
		
		
	more prep for parser.cpp for c-library gen
This commit is contained in:
		| @@ -105,6 +105,7 @@ int gen_main() | |||||||
|  |  | ||||||
| 	PreprocessorDefines.append(txt("GEN_API_C_BEGIN")); | 	PreprocessorDefines.append(txt("GEN_API_C_BEGIN")); | ||||||
| 	PreprocessorDefines.append(txt("GEN_API_C_END")); | 	PreprocessorDefines.append(txt("GEN_API_C_END")); | ||||||
|  | 	PreprocessorDefines.append(txt("Array(")); | ||||||
| 	PreprocessorDefines.append(txt("HashTable(")); | 	PreprocessorDefines.append(txt("HashTable(")); | ||||||
| 	PreprocessorDefines.append(txt("GEN_NS_PARSER")); | 	PreprocessorDefines.append(txt("GEN_NS_PARSER")); | ||||||
| 	PreprocessorDefines.append(txt("GEN_NS_PARSER_BEGIN")); | 	PreprocessorDefines.append(txt("GEN_NS_PARSER_BEGIN")); | ||||||
| @@ -212,6 +213,8 @@ do                          \ | |||||||
| 				{ | 				{ | ||||||
| 					b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP"), body_entry, body, new_body ); | 					b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP"), body_entry, body, new_body ); | ||||||
| 					if (found) break; | 					if (found) break; | ||||||
|  |  | ||||||
|  | 					new_body.append(body_entry); | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| @@ -313,6 +316,8 @@ do                          \ | |||||||
|  |  | ||||||
| 			found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP"), entry, parsed_header_strings, header_strings); | 			found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP"), entry, parsed_header_strings, header_strings); | ||||||
| 			if (found) break; | 			if (found) break; | ||||||
|  |  | ||||||
|  | 			header_strings.append(entry); | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| @@ -458,7 +463,10 @@ do                          \ | |||||||
| 	{ | 	{ | ||||||
| 		case CT_Preprocess_IfDef: | 		case CT_Preprocess_IfDef: | ||||||
| 		{ | 		{ | ||||||
| 			ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings ); | 			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_parsing, header_parsing ); | ||||||
|  | 			if (found) break; | ||||||
|  |  | ||||||
|  | 			header_parsing.append(entry); | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| @@ -552,9 +560,21 @@ do                          \ | |||||||
| 	CodeBody types        = def_body(CT_Global_Body); | 	CodeBody types        = def_body(CT_Global_Body); | ||||||
| 	for ( Code entry = parsed_types.begin(); entry != parsed_types.end(); ++ entry ) switch(entry->Type) | 	for ( Code entry = parsed_types.begin(); entry != parsed_types.end(); ++ entry ) switch(entry->Type) | ||||||
| 	{ | 	{ | ||||||
|  | 		case CT_Preprocess_If: | ||||||
|  | 		{ | ||||||
|  | 			b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_types, types ); | ||||||
|  | 			if (found) break; | ||||||
|  |  | ||||||
|  | 			types.append(entry); | ||||||
|  | 		} | ||||||
|  | 		break; | ||||||
|  |  | ||||||
| 		case CT_Preprocess_IfDef: | 		case CT_Preprocess_IfDef: | ||||||
| 		{ | 		{ | ||||||
| 			ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings ); | 			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_types, types ); | ||||||
|  | 			if (found) break; | ||||||
|  |  | ||||||
|  | 			types.append(entry); | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| @@ -614,7 +634,10 @@ do                          \ | |||||||
| 	{ | 	{ | ||||||
| 		case CT_Preprocess_IfDef: | 		case CT_Preprocess_IfDef: | ||||||
| 		{ | 		{ | ||||||
| 			ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings ); | 			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_ast, ast ); | ||||||
|  | 			if (found) break; | ||||||
|  |  | ||||||
|  | 			ast.append(entry); | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| @@ -780,7 +803,7 @@ R"(#define AST_ArrSpecs_Cap \ | |||||||
| 		{ | 		{ | ||||||
| 			b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_code_types, code_types ); | 			b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_code_types, code_types ); | ||||||
| 			if (found) { | 			if (found) { | ||||||
| 				++ entry; | 				++ entry; // Skip a newline... | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| 			found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_code_types, code_types ); | 			found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_code_types, code_types ); | ||||||
| @@ -926,7 +949,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 	{ | 	{ | ||||||
| 		case CT_Preprocess_IfDef: | 		case CT_Preprocess_IfDef: | ||||||
| 		{ | 		{ | ||||||
| 			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_code_types, code_types ); | 			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_interface, interface ); | ||||||
| 			if (found) break; | 			if (found) break; | ||||||
|  |  | ||||||
| 			interface.append(entry); | 			interface.append(entry); | ||||||
| @@ -983,6 +1006,9 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 				fn->Name = get_cached_string(new_name); | 				fn->Name = get_cached_string(new_name); | ||||||
| 				interface.append(fn); | 				interface.append(fn); | ||||||
| 				interface.append(fn_macro); | 				interface.append(fn_macro); | ||||||
|  | 				if (entry->Next && entry->Next->Type != CT_NewLine) { | ||||||
|  | 					interface.append(fmt_newline); | ||||||
|  | 				} | ||||||
| 				handled = true; | 				handled = true; | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| @@ -1012,7 +1038,10 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 	{ | 	{ | ||||||
| 		case CT_Preprocess_IfDef: | 		case CT_Preprocess_IfDef: | ||||||
| 		{ | 		{ | ||||||
| 			ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings ); | 			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_inlines, inlines ); | ||||||
|  | 			if (found) break; | ||||||
|  |  | ||||||
|  | 			inlines.append(entry); | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| @@ -1045,7 +1074,10 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 	{ | 	{ | ||||||
| 		case CT_Preprocess_IfDef: | 		case CT_Preprocess_IfDef: | ||||||
| 		{ | 		{ | ||||||
| 			ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings ); | 			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_end, header_end ); | ||||||
|  | 			if (found) break; | ||||||
|  |  | ||||||
|  | 			header_end.append(entry); | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| @@ -1094,8 +1126,6 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 	Code src_ast_case_macros    = scan_file( project_dir "components/ast_case_macros.cpp" ); | 	Code src_ast_case_macros    = scan_file( project_dir "components/ast_case_macros.cpp" ); | ||||||
| 	Code src_code_serialization = scan_file( project_dir "components/code_serialization.cpp" ); | 	Code src_code_serialization = scan_file( project_dir "components/code_serialization.cpp" ); | ||||||
| 	Code src_interface          = scan_file( project_dir "components/interface.cpp" ); | 	Code src_interface          = scan_file( project_dir "components/interface.cpp" ); | ||||||
| 	// Code src_lexer              = scan_file( project_dir "components/lexer.cpp" ); |  | ||||||
| 	// Code src_parser             = scan_file( project_dir "components/parser.cpp" ); |  | ||||||
| 	Code src_parsing_interface  = scan_file( project_dir "components/interface.parsing.cpp" ); | 	Code src_parsing_interface  = scan_file( project_dir "components/interface.parsing.cpp" ); | ||||||
| 	Code src_untyped            = scan_file( project_dir "components/interface.untyped.cpp" ); | 	Code src_untyped            = scan_file( project_dir "components/interface.untyped.cpp" ); | ||||||
|  |  | ||||||
| @@ -1105,7 +1135,10 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 	{ | 	{ | ||||||
| 		case CT_Preprocess_IfDef: | 		case CT_Preprocess_IfDef: | ||||||
| 		{ | 		{ | ||||||
| 			ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings ); | 			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_src_ast, src_ast ); | ||||||
|  | 			if (found) break; | ||||||
|  |  | ||||||
|  | 			src_ast.append(entry); | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| @@ -1137,7 +1170,10 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 	{ | 	{ | ||||||
| 		case CT_Preprocess_IfDef: | 		case CT_Preprocess_IfDef: | ||||||
| 		{ | 		{ | ||||||
| 			ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings ); | 			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_src_upfront, src_upfront ); | ||||||
|  | 			if (found) break; | ||||||
|  |  | ||||||
|  | 			src_upfront.append(entry); | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| @@ -1181,34 +1217,42 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// CodeBody hashtable_strc = gen_hashtable(txt("StrC"), txt("HashTable_StrC")); | ||||||
|  |  | ||||||
| 	CodeBody parsed_src_lexer = parse_file( project_dir "components/lexer.cpp" ); | 	CodeBody parsed_src_lexer = parse_file( project_dir "components/lexer.cpp" ); | ||||||
| 	CodeBody src_lexer        = def_body(CT_Global_Body); | 	CodeBody src_lexer        = def_body(CT_Global_Body); | ||||||
| 	for ( Code entry = parsed_src_ast.begin(); entry != parsed_src_ast.end(); ++ entry ) switch( entry ->Type ) | 	for ( Code entry = parsed_src_lexer.begin(); entry != parsed_src_lexer.end(); ++ entry ) switch( entry ->Type ) | ||||||
| 	{ | 	{ | ||||||
| 		case CT_Preprocess_IfDef: | 		case CT_Preprocess_IfDef: | ||||||
| 		{ | 		{ | ||||||
| 			ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings ); | 			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_src_lexer, src_lexer ); | ||||||
|  | 			if (found) break; | ||||||
|  |  | ||||||
|  | 			src_lexer.append(entry); | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 		CT_Enum: | 		case CT_Enum: | ||||||
| 		{ | 		{ | ||||||
| 			if (entry->Name.Len) | 			if (entry->Name.Len) | ||||||
| 			{ | 			{ | ||||||
| 				convert_cpp_enum_to_c() | 				convert_cpp_enum_to_c(cast(CodeEnum, entry), src_lexer); | ||||||
|  | 				break; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | 			src_lexer.append(entry); | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 		CT_Struct: | 		case CT_Struct: | ||||||
| 		{ | 		{ | ||||||
| 			if ( entry->Name.is_equal(txt("Token"))) | 			if ( entry->Name.is_equal(txt("Token"))) | ||||||
| 			{ | 			{ | ||||||
| 				// Add struct Token forward and typedef early. | 				// Add struct Token forward and typedef early. | ||||||
| 				CodeStruct  token_fwd     = parse_struct(code( struct Token; )); | 				CodeStruct  token_fwd     = parse_struct(code( struct Token; )); | ||||||
| 				CodeTypedef token_typedef = parse_typedef(code( typedef struct Token Token; )); | 				CodeTypedef token_typedef = parse_typedef(code( typedef struct Token Token; )); | ||||||
| 				header_parsing.append(token_fwd); | 				src_lexer.append(token_fwd); | ||||||
| 				header_parsing.append(token_typedef); | 				src_lexer.append(token_typedef); | ||||||
|  |  | ||||||
| 				// Skip typedef since we added it | 				// Skip typedef since we added it | ||||||
| 				b32 continue_for = true; | 				b32 continue_for = true; | ||||||
| @@ -1239,12 +1283,29 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			CodeTypedef struct_tdef = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct <name> <name>; ))) | 			CodeTypedef struct_tdef = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct <name> <name>; ))); | ||||||
| 			src_lexer.append(entry); | 			src_lexer.append(entry); | ||||||
| 			src_lexer.append(struct_tdef); | 			src_lexer.append(struct_tdef); | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
|  | 		case CT_Variable: | ||||||
|  | 		{ | ||||||
|  | 			CodeVar var = cast(CodeVar, entry); | ||||||
|  | 			if (var->Specs && var->Specs.has(Spec_Constexpr) > -1) { | ||||||
|  | 				Code define_ver = untyped_str(token_fmt( | ||||||
|  | 						"name",  var->Name | ||||||
|  | 					,	"value", var->Value->Content | ||||||
|  | 					,	"type",  var->ValueType.to_string().to_strc() | ||||||
|  | 					,	"#define <name> (<type>) <value>\n" | ||||||
|  | 				)); | ||||||
|  | 				src_lexer.append(define_ver); | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			src_lexer.append(entry); | ||||||
|  | 		} | ||||||
|  | 		break; | ||||||
|  |  | ||||||
| 		default: | 		default: | ||||||
| 			src_lexer.append(entry); | 			src_lexer.append(entry); | ||||||
| 		break; | 		break; | ||||||
| @@ -1256,15 +1317,18 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 	{ | 	{ | ||||||
| 		case CT_Preprocess_IfDef: | 		case CT_Preprocess_IfDef: | ||||||
| 		{ | 		{ | ||||||
| 			ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings ); | 			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_src_parser, src_parser ); | ||||||
|  | 			if (found) break; | ||||||
|  |  | ||||||
|  | 			src_parser.append(entry); | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 		case CT_Struct: | 		case CT_Struct: | ||||||
| 		{ | 		{ | ||||||
| 			CodeTypedef tdef = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct <name> <name>; ))); | 			CodeTypedef tdef = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct <name> <name>; ))); | ||||||
| 			header_memory.append(entry); | 			src_parser.append(entry); | ||||||
| 			header_memory.append(tdef); | 			src_parser.append(tdef); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		default: | 		default: | ||||||
| @@ -1419,8 +1483,8 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 		header.print( format_code_to_untyped(src_upfront) ); | 		header.print( format_code_to_untyped(src_upfront) ); | ||||||
| 		header.print_fmt( "\n#pragma region Parsing\n\n" ); | 		header.print_fmt( "\n#pragma region Parsing\n\n" ); | ||||||
| 		header.print( format_code_to_untyped(etoktype) ); | 		header.print( format_code_to_untyped(etoktype) ); | ||||||
| 		header.print( lexer ); | 		header.print( format_code_to_untyped(src_lexer) ); | ||||||
| 		// header.print( parser ); | 		header.print( format_code_to_untyped(src_parser) ); | ||||||
| 		// header.print( parsing_interface ); | 		// header.print( parsing_interface ); | ||||||
| 		header.print_fmt( "\n#pragma endregion Parsing\n" ); | 		header.print_fmt( "\n#pragma endregion Parsing\n" ); | ||||||
| 		// header.print( untyped ); | 		// header.print( untyped ); | ||||||
|   | |||||||
| @@ -23,7 +23,22 @@ CodeBody gen_array_base() | |||||||
| 	Code get_header   = untyped_str( txt( "#define array_get_header( self ) ( (ArrayHeader*)( self ) - 1)\n" )); | 	Code get_header   = untyped_str( txt( "#define array_get_header( self ) ( (ArrayHeader*)( self ) - 1)\n" )); | ||||||
| 	Code type_define  = untyped_str( txt( "#define Array(Type) Array_##Type\n")); | 	Code type_define  = untyped_str( txt( "#define Array(Type) Array_##Type\n")); | ||||||
|  |  | ||||||
| 	return def_global_body( args( fmt_newline, td_header, header, type_define, grow_formula, get_header, fmt_newline ) ); | 	Code array_begin = def_define(txt("array_begin(array)"),       code( (array) )); | ||||||
|  | 	Code array_end   = def_define(txt("array_end(array)"),         code( (array + array_get_header(array)->Num ) )); | ||||||
|  | 	Code array_next  = def_define(txt("array_next(array, entry)"), code( (entry + 1) )); | ||||||
|  |  | ||||||
|  | 	return def_global_body( args( | ||||||
|  | 		fmt_newline, | ||||||
|  | 		td_header, | ||||||
|  | 		header, | ||||||
|  | 		type_define, | ||||||
|  | 		grow_formula, | ||||||
|  | 		get_header, | ||||||
|  | 		array_begin, | ||||||
|  | 		array_end, | ||||||
|  | 		array_next, | ||||||
|  | 		fmt_newline | ||||||
|  | 	)); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| CodeBody gen_array( StrC type, StrC array_name ) | CodeBody gen_array( StrC type, StrC array_name ) | ||||||
|   | |||||||
| @@ -9,12 +9,12 @@ CodeBody gen_fixed_arenas() | |||||||
| 	result.append(def_pragma(txt("region FixedArena"))); | 	result.append(def_pragma(txt("region FixedArena"))); | ||||||
|  |  | ||||||
| 	char const* template_struct = stringize( | 	char const* template_struct = stringize( | ||||||
| 		struct FixedArena_<Name>_Def | 		struct FixedArena_<Name> | ||||||
| 		{ | 		{ | ||||||
| 			char  memory[<Size>]; | 			char  memory[<Size>]; | ||||||
| 			Arena arena; | 			Arena arena; | ||||||
| 		}; | 		}; | ||||||
| 		typedef struct FixedArena_<Name>_Def FixedArena_<Name>; | 		typedef struct FixedArena_<Name> FixedArena_<Name>; | ||||||
| 	); | 	); | ||||||
|  |  | ||||||
| 	char const* template_interface = stringize( | 	char const* template_interface = stringize( | ||||||
|   | |||||||
| @@ -114,7 +114,7 @@ CodeEnum parse_enum( StrC def ) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Context.Tokens = toks; | 	Context.Tokens = toks; | ||||||
| 	return parse_enum(); | 	return parse_enum( parser_not_inplace_def); | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeBody parse_export_body( StrC def ) | CodeBody parse_export_body( StrC def ) | ||||||
| @@ -263,7 +263,7 @@ CodeTypename parse_type( StrC def ) | |||||||
| 		return InvalidCode; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	Context.Tokens = toks; | 	Context.Tokens = toks; | ||||||
| 	return parse_type(); | 	return parse_type( parser_not_from_template, nullptr); | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeTypedef parse_typedef( StrC def ) | CodeTypedef parse_typedef( StrC def ) | ||||||
| @@ -289,7 +289,7 @@ CodeUnion parse_union( StrC def ) | |||||||
| 		return InvalidCode; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	Context.Tokens = toks; | 	Context.Tokens = toks; | ||||||
| 	return parse_union(); | 	return parse_union( parser_not_inplace_def); | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeUsing parse_using( StrC def ) | CodeUsing parse_using( StrC def ) | ||||||
|   | |||||||
| @@ -21,6 +21,7 @@ enum TokFlags : u32 | |||||||
| 	TF_Literal         = bit( 12 ), | 	TF_Literal         = bit( 12 ), | ||||||
|  |  | ||||||
| 	TF_Null = 0, | 	TF_Null = 0, | ||||||
|  | 	TF_UnderlyingType = GEN_U32_MAX, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| struct Token | struct Token | ||||||
| @@ -42,7 +43,8 @@ AccessSpec tok_to_access_specifier(Token tok) | |||||||
|  |  | ||||||
| StrC tok_to_str(Token tok) | StrC tok_to_str(Token tok) | ||||||
| { | { | ||||||
| 	return { tok.Length, tok.Text }; | 	StrC str = { tok.Length, tok.Text }; | ||||||
|  | 	return str; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool tok_is_valid( Token tok ) | bool tok_is_valid( Token tok ) | ||||||
| @@ -169,9 +171,9 @@ Token* lex_next(TokArray self, bool skip_formatting) | |||||||
| 	return & self.Arr[idx + 1]; | 	return & self.Arr[idx + 1]; | ||||||
| } | } | ||||||
|  |  | ||||||
| global Arena_256KB     Lexer_defines_map_arena; | global FixedArena_256KB Lexer_defines_map_arena; | ||||||
| global HashTable(StrC) Lexer_defines; | global StringTable      Lexer_defines; | ||||||
| global Array(Token)    Lexer_Tokens; | global Array(Token)     Lexer_Tokens; | ||||||
|  |  | ||||||
| #define current ( * ctx->scanner ) | #define current ( * ctx->scanner ) | ||||||
|  |  | ||||||
| @@ -228,7 +230,7 @@ struct LexContext | |||||||
| 	char const*     scanner; | 	char const*     scanner; | ||||||
| 	s32             line; | 	s32             line; | ||||||
| 	s32             column; | 	s32             column; | ||||||
| 	HashTable(StrC) defines; | 	StringTable     defines; | ||||||
| 	Token           token; | 	Token           token; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -593,13 +595,14 @@ TokArray lex( StrC content ) | |||||||
| 	if ( c.left <= 0 ) | 	if ( c.left <= 0 ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::lex: no tokens found (only whitespace provided)" ); | 		log_failure( "gen::lex: no tokens found (only whitespace provided)" ); | ||||||
| 		return { {}, 0 }; | 		TokArray null_array = {}; | ||||||
|  | 		return null_array; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for ( StringCached* entry = array_begin(PreprocessorDefines); entry != array_end(PreprocessorDefines); entry = array_next(PreprocessorDefines, entry)) | 	for ( StringCached* entry = array_begin(PreprocessorDefines); entry != array_end(PreprocessorDefines); entry = array_next(PreprocessorDefines, entry)) | ||||||
| 	{ | 	{ | ||||||
| 		s32         length  = 0; | 		s32         length  = 0; | ||||||
| 		char const* entry_scanner = * entry; | 		char const* entry_scanner = (*entry).Ptr; | ||||||
| 		while ( entry->Len > length && (char_is_alphanumeric( *entry_scanner ) || *entry_scanner == '_') ) | 		while ( entry->Len > length && (char_is_alphanumeric( *entry_scanner ) || *entry_scanner == '_') ) | ||||||
| 		{ | 		{ | ||||||
| 			entry_scanner++; | 			entry_scanner++; | ||||||
| @@ -610,8 +613,8 @@ TokArray lex( StrC content ) | |||||||
| 			length++; | 			length++; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		u64 key = crc32( * entry, length ); | 		u64 key = crc32( entry->Ptr, length ); | ||||||
| 		hashtable_set(c.defines, key, (StrC) * entry ); | 		hashtable_set(c.defines, key, * entry ); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	array_clear(Lexer_Tokens); | 	array_clear(Lexer_Tokens); | ||||||
| @@ -625,7 +628,10 @@ TokArray lex( StrC content ) | |||||||
| 		} | 		} | ||||||
| 		#endif | 		#endif | ||||||
|  |  | ||||||
| 		c.token = { c.scanner, 0, Tok_Invalid, c.line, c.column, TF_Null }; | 		{ | ||||||
|  | 			Token thanks_c = { c.scanner, 0, Tok_Invalid, c.line, c.column, TF_Null }; | ||||||
|  | 			c.token = thanks_c; | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		bool is_define = false; | 		bool is_define = false; | ||||||
|  |  | ||||||
| @@ -667,7 +673,10 @@ TokArray lex( StrC content ) | |||||||
| 						//TokType last_type = Tokens[array_get_header(Tokens)->Num - 2].Type; | 						//TokType last_type = Tokens[array_get_header(Tokens)->Num - 2].Type; | ||||||
| 						//if ( last_type == Tok_Preprocess_Pragma ) | 						//if ( last_type == Tok_Preprocess_Pragma ) | ||||||
| 						{ | 						{ | ||||||
| 							c.token = { c.scanner, 0, Tok_Invalid, c.line, c.column, TF_Null }; | 							{ | ||||||
|  | 								Token thanks_c = { c.scanner, 0, Tok_Invalid, c.line, c.column, TF_Null }; | ||||||
|  | 								c.token = thanks_c; | ||||||
|  | 							} | ||||||
| 							if ( current == '\r') | 							if ( current == '\r') | ||||||
| 							{ | 							{ | ||||||
| 								move_forward(); | 								move_forward(); | ||||||
| @@ -688,7 +697,10 @@ TokArray lex( StrC content ) | |||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					case Lex_ReturnNull: | 					case Lex_ReturnNull: | ||||||
| 						return { {}, 0 }; | 					{ | ||||||
|  | 						TokArray tok_array =  {}; | ||||||
|  | 						return tok_array; | ||||||
|  | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			case '.': | 			case '.': | ||||||
| @@ -1291,7 +1303,8 @@ TokArray lex( StrC content ) | |||||||
| 			TokType last_type = array_back(Lexer_Tokens)->Type; | 			TokType last_type = array_back(Lexer_Tokens)->Type; | ||||||
| 			if ( last_type == Tok_Preprocess_Macro ) | 			if ( last_type == Tok_Preprocess_Macro ) | ||||||
| 			{ | 			{ | ||||||
| 				c.token = { c.scanner, 0, Tok_Invalid, c.line, c.column, TF_Null }; | 				Token thanks_c = { c.scanner, 0, Tok_Invalid, c.line, c.column, TF_Null }; | ||||||
|  | 				c.token = thanks_c; | ||||||
| 				if ( current == '\r') | 				if ( current == '\r') | ||||||
| 				{ | 				{ | ||||||
| 					move_forward(); | 					move_forward(); | ||||||
| @@ -1314,7 +1327,10 @@ TokArray lex( StrC content ) | |||||||
| 	if ( array_num(Lexer_Tokens) == 0 ) | 	if ( array_num(Lexer_Tokens) == 0 ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Failed to lex any tokens" ); | 		log_failure( "Failed to lex any tokens" ); | ||||||
| 		return { {}, 0 }; | 		{ | ||||||
|  | 			TokArray tok_array =  {}; | ||||||
|  | 			return tok_array; | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	hashtable_clear(Lexer_defines); | 	hashtable_clear(Lexer_defines); | ||||||
|   | |||||||
| @@ -9,8 +9,8 @@ GEN_NS_PARSER_BEGIN | |||||||
|  |  | ||||||
| // TODO(Ed) : Rename ETok_Capture_Start, ETok_Capture_End to Open_Parenthesis adn Close_Parenthesis | // TODO(Ed) : Rename ETok_Capture_Start, ETok_Capture_End to Open_Parenthesis adn Close_Parenthesis | ||||||
|  |  | ||||||
| constexpr bool dont_skip_formatting = false; | constexpr bool lex_dont_skip_formatting = false; | ||||||
| constexpr bool      skip_formatting = true; | constexpr bool      lex_skip_formatting = true; | ||||||
|  |  | ||||||
| struct StackNode | struct StackNode | ||||||
| { | { | ||||||
| @@ -113,7 +113,7 @@ bool lex__eat(TokArray* self, TokType type ) | |||||||
|  |  | ||||||
| 	if ( at_idx.Type != type ) | 	if ( at_idx.Type != type ) | ||||||
| 	{ | 	{ | ||||||
| 		Token tok = * lex_current( self, skip_formatting ); | 		Token tok = * lex_current( self, lex_skip_formatting ); | ||||||
| 		log_failure( "Parse Error, TokArray::eat, Expected: ' %s ' not ' %.*s ' (%d, %d)`\n%s" | 		log_failure( "Parse Error, TokArray::eat, Expected: ' %s ' not ' %.*s ' (%d, %d)`\n%s" | ||||||
| 			, toktype_to_str(type).Ptr | 			, toktype_to_str(type).Ptr | ||||||
| 			, at_idx.Length, at_idx.Text | 			, at_idx.Length, at_idx.Text | ||||||
| @@ -170,11 +170,12 @@ bool _check_parse_args( StrC def, char const* func_name ) | |||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| #	define currtok_noskip (* lex_current( &  Context.Tokens, dont_skip_formatting )) | #	define currtok_noskip (* lex_current( &  Context.Tokens, lex_dont_skip_formatting )) | ||||||
| #	define currtok        (* lex_current( & Context.Tokens, skip_formatting )) | #	define currtok        (* lex_current( & Context.Tokens, lex_skip_formatting )) | ||||||
| #	define peektok        (* lex_peek(Context.Tokens, skip_formatting)) | #	define peektok        (* lex_peek(Context.Tokens, lex_skip_formatting)) | ||||||
| #	define prevtok        (* lex_previous( Context.Tokens, dont_skip_formatting)) | #	define prevtok        (* lex_previous( Context.Tokens, lex_dont_skip_formatting)) | ||||||
| #	define nexttok		  (* lex_next( Context.Tokens, skip_formatting )) | #	define nexttok		  (* lex_next( Context.Tokens, lex_skip_formatting )) | ||||||
|  | #	define nexttok_noskip (* lex_next( Context.Tokens, lex_dont_skip_formatting)) | ||||||
| #	define eat( Type_ )   lex__eat( & Context.Tokens, Type_ ) | #	define eat( Type_ )   lex__eat( & Context.Tokens, Type_ ) | ||||||
| #	define left           ( array_num(Context.Tokens.Arr) - Context.Tokens.Idx ) | #	define left           ( array_num(Context.Tokens.Arr) - Context.Tokens.Idx ) | ||||||
|  |  | ||||||
| @@ -208,23 +209,23 @@ internal CodeFn             parse_function_after_name          ( ModuleFlag mfla | |||||||
| internal Code               parse_function_body                (); | internal Code               parse_function_body                (); | ||||||
| internal Code               parse_global_nspace                (); | internal Code               parse_global_nspace                (); | ||||||
| internal Code               parse_global_nspace_constructor_destructor( CodeSpecifiers specifiers ); | internal Code               parse_global_nspace_constructor_destructor( CodeSpecifiers specifiers ); | ||||||
| internal Token              parse_identifier                   ( bool* possible_member_function = nullptr ); | internal Token              parse_identifier                   ( bool* possible_member_function ); | ||||||
| internal CodeInclude        parse_include                      (); | internal CodeInclude        parse_include                      (); | ||||||
| internal CodeOperator       parse_operator_after_ret_type      ( ModuleFlag mflags, CodeAttributes attributes, CodeSpecifiers specifiers, CodeTypename ret_type ); | internal CodeOperator       parse_operator_after_ret_type      ( ModuleFlag mflags, CodeAttributes attributes, CodeSpecifiers specifiers, CodeTypename ret_type ); | ||||||
| internal Code               parse_operator_function_or_variable( bool expects_function, CodeAttributes attributes, CodeSpecifiers specifiers ); | internal Code               parse_operator_function_or_variable( bool expects_function, CodeAttributes attributes, CodeSpecifiers specifiers ); | ||||||
| internal CodePragma         parse_pragma                       (); | internal CodePragma         parse_pragma                       (); | ||||||
| internal CodeParam          parse_params                       ( bool use_template_capture = false ); | internal CodeParam          parse_params                       ( bool use_template_capture ); | ||||||
| internal CodePreprocessCond parse_preprocess_cond              (); | internal CodePreprocessCond parse_preprocess_cond              (); | ||||||
| internal Code               parse_simple_preprocess            ( TokType which, bool dont_consume_braces = false ); | internal Code               parse_simple_preprocess            ( TokType which, bool dont_consume_braces ); | ||||||
| internal Code               parse_static_assert                (); | internal Code               parse_static_assert                (); | ||||||
| internal void               parse_template_args                ( Token& token ); | internal void               parse_template_args                ( Token& token ); | ||||||
| internal CodeVar            parse_variable_after_name          ( ModuleFlag mflags, CodeAttributes attributes, CodeSpecifiers specifiers, CodeTypename type, StrC name ); | internal CodeVar            parse_variable_after_name          ( ModuleFlag mflags, CodeAttributes attributes, CodeSpecifiers specifiers, CodeTypename type, StrC name ); | ||||||
| internal CodeVar            parse_variable_declaration_list    (); | internal CodeVar            parse_variable_declaration_list    (); | ||||||
|  |  | ||||||
| internal CodeClass       parse_class           ( bool inplace_def = false ); | internal CodeClass       parse_class           ( bool inplace_def ); | ||||||
| internal CodeConstructor parse_constructor     ( CodeSpecifiers specifiers ); | internal CodeConstructor parse_constructor     ( CodeSpecifiers specifiers ); | ||||||
| internal CodeDestructor  parse_destructor      ( CodeSpecifiers specifiers = NullCode ); | internal CodeDestructor  parse_destructor      ( CodeSpecifiers specifiers = NullCode ); | ||||||
| internal CodeEnum        parse_enum            ( bool inplace_def = false ); | internal CodeEnum        parse_enum            ( bool inplace_def ); | ||||||
| internal CodeBody        parse_export_body     (); | internal CodeBody        parse_export_body     (); | ||||||
| internal CodeBody        parse_extern_link_body(); | internal CodeBody        parse_extern_link_body(); | ||||||
| internal CodeExtern      parse_extern_link     (); | internal CodeExtern      parse_extern_link     (); | ||||||
| @@ -232,20 +233,25 @@ internal CodeFriend      parse_friend          (); | |||||||
| internal CodeFn          parse_function        (); | internal CodeFn          parse_function        (); | ||||||
| internal CodeNS          parse_namespace       (); | internal CodeNS          parse_namespace       (); | ||||||
| internal CodeOpCast      parse_operator_cast   ( CodeSpecifiers specifiers = NullCode ); | internal CodeOpCast      parse_operator_cast   ( CodeSpecifiers specifiers = NullCode ); | ||||||
| internal CodeStruct      parse_struct          ( bool inplace_def = false ); | internal CodeStruct      parse_struct          ( bool inplace_def ); | ||||||
| internal CodeVar         parse_variable        (); | internal CodeVar         parse_variable        (); | ||||||
| internal CodeTemplate    parse_template        (); | internal CodeTemplate    parse_template        (); | ||||||
| internal CodeTypename    parse_type            ( bool from_template = false, bool* is_function = nullptr ); | internal CodeTypename    parse_type            ( bool from_template, bool* is_function ); | ||||||
| internal CodeTypedef     parse_typedef         (); | internal CodeTypedef     parse_typedef         (); | ||||||
| internal CodeUnion       parse_union           ( bool inplace_def = false ); | internal CodeUnion       parse_union           ( bool inplace_def ); | ||||||
| internal CodeUsing       parse_using           (); | internal CodeUsing       parse_using           (); | ||||||
|  |  | ||||||
| constexpr bool inplace_def         = true; | constexpr bool parser_inplace_def         = true; | ||||||
| constexpr bool dont_consume_braces = true; | constexpr bool parser_not_inplace_def     = false; | ||||||
|  | constexpr bool parser_dont_consume_braces = true; | ||||||
|  | constexpr bool parser_consume_braces      = false; | ||||||
|  | constexpr bool parser_not_from_template   = false; | ||||||
|  |  | ||||||
|  | constexpr bool parser_use_parenthesis = false; | ||||||
|  |  | ||||||
| // Internal parsing functions | // Internal parsing functions | ||||||
|  |  | ||||||
| constexpr bool strip_formatting_dont_preserve_newlines = false; | constexpr bool parser_strip_formatting_dont_preserve_newlines = false; | ||||||
| /* | /* | ||||||
| 	This function was an attempt at stripping formatting from any c++ code. | 	This function was an attempt at stripping formatting from any c++ code. | ||||||
| 	It has edge case failures that prevent it from being used in function bodies. | 	It has edge case failures that prevent it from being used in function bodies. | ||||||
| @@ -667,7 +673,7 @@ CodeAttributes parse_attributes() | |||||||
| 		StrC attribute_txt = { len, start.Text }; | 		StrC attribute_txt = { len, start.Text }; | ||||||
| 		parser_pop(& Context); | 		parser_pop(& Context); | ||||||
|  |  | ||||||
| 		String name_stripped = strip_formatting( attribute_txt, strip_formatting_dont_preserve_newlines ); | 		String name_stripped = strip_formatting( attribute_txt, parser_strip_formatting_dont_preserve_newlines ); | ||||||
|  |  | ||||||
| 		Code result     = make_code(); | 		Code result     = make_code(); | ||||||
| 		result->Type    = CT_PlatformAttributes; | 		result->Type    = CT_PlatformAttributes; | ||||||
| @@ -716,7 +722,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false ) | |||||||
|  |  | ||||||
| 	if ( check( Tok_Identifier ) ) | 	if ( check( Tok_Identifier ) ) | ||||||
| 	{ | 	{ | ||||||
| 		name = parse_identifier(); | 		name = parse_identifier(nullptr); | ||||||
| 		Context.Scope->Name = name; | 		Context.Scope->Name = name; | ||||||
| 	} | 	} | ||||||
| 	// <ModuleFlags> <class/struct> <Attributes> <Name> | 	// <ModuleFlags> <class/struct> <Attributes> <Name> | ||||||
| @@ -741,7 +747,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false ) | |||||||
| 			eat( currtok.Type ); | 			eat( currtok.Type ); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		Token parent_tok = parse_identifier(); | 		Token parent_tok = parse_identifier(nullptr); | ||||||
| 		parent = def_type( tok_to_str(parent_tok) ); | 		parent = def_type( tok_to_str(parent_tok) ); | ||||||
| 		// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Parent/Interface Name> | 		// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Parent/Interface Name> | ||||||
|  |  | ||||||
| @@ -754,7 +760,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false ) | |||||||
| 			{ | 			{ | ||||||
| 				eat(currtok.Type); | 				eat(currtok.Type); | ||||||
| 			} | 			} | ||||||
| 			Token interface_tok = parse_identifier(); | 			Token interface_tok = parse_identifier(nullptr); | ||||||
|  |  | ||||||
| 			array_append( interfaces, def_type( tok_to_str(interface_tok) ) ); | 			array_append( interfaces, def_type( tok_to_str(interface_tok) ) ); | ||||||
| 			// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Name>, ... | 			// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Name>, ... | ||||||
| @@ -822,6 +828,8 @@ CodeBody parse_class_struct_body( TokType which, Token name ) | |||||||
| 		if ( currtok_noskip.Type == Tok_Preprocess_Hash ) | 		if ( currtok_noskip.Type == Tok_Preprocess_Hash ) | ||||||
| 			eat( Tok_Preprocess_Hash ); | 			eat( Tok_Preprocess_Hash ); | ||||||
|  |  | ||||||
|  | 		b32 macro_found = true; | ||||||
|  |  | ||||||
| 		switch ( currtok_noskip.Type ) | 		switch ( currtok_noskip.Type ) | ||||||
| 		{ | 		{ | ||||||
| 			case Tok_Statement_End: | 			case Tok_Statement_End: | ||||||
| @@ -948,8 +956,9 @@ CodeBody parse_class_struct_body( TokType which, Token name ) | |||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 			case Tok_Preprocess_Macro: | 			case Tok_Preprocess_Macro: | ||||||
| 				member = parse_simple_preprocess( Tok_Preprocess_Macro ); |  | ||||||
| 				// <Macro> | 				// <Macro> | ||||||
|  | 				macro_found = true; | ||||||
|  | 				goto Preprocess_Macro_Bare_In_Body; | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 			case Tok_Preprocess_Pragma: | 			case Tok_Preprocess_Pragma: | ||||||
| @@ -958,7 +967,7 @@ CodeBody parse_class_struct_body( TokType which, Token name ) | |||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 			case Tok_Preprocess_Unsupported: | 			case Tok_Preprocess_Unsupported: | ||||||
| 				member = parse_simple_preprocess( Tok_Preprocess_Unsupported ); | 				member = parse_simple_preprocess( Tok_Preprocess_Unsupported, parser_consume_braces ); | ||||||
| 				// #<UNKNOWN> | 				// #<UNKNOWN> | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| @@ -1097,6 +1106,28 @@ CodeBody parse_class_struct_body( TokType which, Token name ) | |||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|  | 				if (macro_found) | ||||||
|  | 				{ | ||||||
|  | 				Preprocess_Macro_Bare_In_Body: | ||||||
|  | 					b32 lone_macro = nexttok.Type == Tok_Statement_End || nexttok_noskip.Type == Tok_NewLine; | ||||||
|  | 					if (lone_macro) | ||||||
|  | 					{ | ||||||
|  | 						member = parse_simple_preprocess( Tok_Preprocess_Macro, parser_consume_braces ); | ||||||
|  | 						// <Macro>; | ||||||
|  |  | ||||||
|  | 						if ( member == Code_Invalid ) | ||||||
|  | 						{ | ||||||
|  | 							log_failure( "Failed to parse member\n%s", parser_to_string(Context) ); | ||||||
|  | 							parser_pop(& Context); | ||||||
|  | 							return InvalidCode; | ||||||
|  | 						} | ||||||
|  | 						continue; | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					// We have a macro but its most likely behaving as a typename | ||||||
|  | 					// <Macro ... | ||||||
|  | 				} | ||||||
|  |  | ||||||
| 				member = parse_operator_function_or_variable( expects_function, attributes, specifiers ); | 				member = parse_operator_function_or_variable( expects_function, attributes, specifiers ); | ||||||
| 				// <Attributes> <Specifiers> operator <Op> ... | 				// <Attributes> <Specifiers> operator <Op> ... | ||||||
| 				// or | 				// or | ||||||
| @@ -1239,7 +1270,7 @@ Code parse_complicated_definition( TokType which ) | |||||||
| 			// <enum>         <type_identifier> : <identifier>; | 			// <enum>         <type_identifier> : <identifier>; | ||||||
| 			// <enum> <class> <type_identifier> : <identifier>; | 			// <enum> <class> <type_identifier> : <identifier>; | ||||||
| 			ok_to_parse = true; | 			ok_to_parse = true; | ||||||
| 			Code result = parse_enum(); | 			Code result = parse_enum( ! parser_inplace_def); | ||||||
| 			parser_pop(& Context); | 			parser_pop(& Context); | ||||||
| 			return result; | 			return result; | ||||||
| 		} | 		} | ||||||
| @@ -1279,7 +1310,7 @@ Code parse_complicated_definition( TokType which ) | |||||||
| 		// Its a forward declaration of an enum class | 		// Its a forward declaration of an enum class | ||||||
| 		// <enum>         <type_identifier> : <identifier>; | 		// <enum>         <type_identifier> : <identifier>; | ||||||
| 		// <enum> <class> <type_identifier> : <identifier>; | 		// <enum> <class> <type_identifier> : <identifier>; | ||||||
| 		Code result = parse_enum(); | 		Code result = parse_enum( ! parser_inplace_def); | ||||||
| 		parser_pop(& Context); | 		parser_pop(& Context); | ||||||
| 		return result; | 		return result; | ||||||
| 	} | 	} | ||||||
| @@ -1347,7 +1378,7 @@ CodeDefine parse_define() | |||||||
| 		return define; | 		return define; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	define->Content = get_cached_string( string_to_strc( strip_formatting( tok_to_str(currtok), strip_formatting_dont_preserve_newlines )) ); | 	define->Content = get_cached_string( string_to_strc( strip_formatting( tok_to_str(currtok), parser_strip_formatting_dont_preserve_newlines )) ); | ||||||
| 	eat( Tok_Preprocess_Content ); | 	eat( Tok_Preprocess_Content ); | ||||||
| 	// #define <Name> <Content> | 	// #define <Name> <Content> | ||||||
|  |  | ||||||
| @@ -1436,7 +1467,7 @@ CodeFn parse_function_after_name( | |||||||
| ) | ) | ||||||
| { | { | ||||||
| 	push_scope(); | 	push_scope(); | ||||||
| 	CodeParam params = parse_params(); | 	CodeParam params = parse_params(parser_use_parenthesis); | ||||||
| 	// <Attributes> <Specifiers> <ReturnType> <Name> ( <Parameters> ) | 	// <Attributes> <Specifiers> <ReturnType> <Name> ( <Parameters> ) | ||||||
|  |  | ||||||
| 	// TODO(Ed), Review old comment : These have to be kept separate from the return type's specifiers. | 	// TODO(Ed), Review old comment : These have to be kept separate from the return type's specifiers. | ||||||
| @@ -1612,6 +1643,8 @@ CodeBody parse_global_nspace( CodeType which ) | |||||||
| 		if ( currtok_noskip.Type == Tok_Preprocess_Hash ) | 		if ( currtok_noskip.Type == Tok_Preprocess_Hash ) | ||||||
| 			eat( Tok_Preprocess_Hash ); | 			eat( Tok_Preprocess_Hash ); | ||||||
|  |  | ||||||
|  | 		b32 macro_found = false; | ||||||
|  |  | ||||||
| 		switch ( currtok_noskip.Type ) | 		switch ( currtok_noskip.Type ) | ||||||
| 		{ | 		{ | ||||||
| 			case Tok_Comma: | 			case Tok_Comma: | ||||||
| @@ -1716,45 +1749,41 @@ CodeBody parse_global_nspace( CodeType which ) | |||||||
| 				// #endif | 				// #endif | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 			case Tok_Preprocess_Macro: | 			case Tok_Preprocess_Macro: { | ||||||
| 			{ |  | ||||||
| 				member = parse_simple_preprocess( Tok_Preprocess_Macro ); |  | ||||||
| 				// <Macro> | 				// <Macro> | ||||||
|  | 				macro_found = true; | ||||||
| 				if ( member == Code_Invalid ) | 				goto Preprocess_Macro_Bare_In_Body; | ||||||
| 				{ |  | ||||||
| 					log_failure( "Failed to parse member\n%s", parser_to_string(Context) ); |  | ||||||
| 					parser_pop(& Context); |  | ||||||
| 					return InvalidCode; |  | ||||||
| 				} |  | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 			case Tok_Preprocess_Pragma: | 			case Tok_Preprocess_Pragma: { | ||||||
| 				member = parse_pragma(); | 				member = parse_pragma(); | ||||||
| 				// #pragma ... | 				// #pragma ... | ||||||
|  | 			} | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 			case Tok_Preprocess_Unsupported: | 			case Tok_Preprocess_Unsupported: { | ||||||
| 				member = parse_simple_preprocess( Tok_Preprocess_Unsupported ); | 				member = parse_simple_preprocess( Tok_Preprocess_Unsupported, parser_consume_braces ); | ||||||
| 				// #<UNSUPPORTED> ... | 				// #<UNSUPPORTED> ... | ||||||
|  | 			} | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 			case Tok_StaticAssert: | 			case Tok_StaticAssert: { | ||||||
| 				member = parse_static_assert(); | 				member = parse_static_assert(); | ||||||
| 				// static_assert( <Conditional Expression>, ... ); | 				// static_assert( <Conditional Expression>, ... ); | ||||||
|  | 			} | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 			case Tok_Module_Export: | 			case Tok_Module_Export: { | ||||||
| 				if ( which == CT_Export_Body ) | 				if ( which == CT_Export_Body ) | ||||||
| 					log_failure( "Nested export declaration\n%s", parser_to_string(Context) ); | 					log_failure( "Nested export declaration\n%s", parser_to_string(Context) ); | ||||||
|  |  | ||||||
| 				member = parse_export_body(); | 				member = parse_export_body(); | ||||||
| 				// export { ... } | 				// export { ... } | ||||||
|  | 			} | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 			case Tok_Module_Import: | 			case Tok_Module_Import: { | ||||||
| 			{ |  | ||||||
| 				not_implemented( context ); | 				not_implemented( context ); | ||||||
| 				// import ... | 				// import ... | ||||||
| 			} | 			} | ||||||
| @@ -1847,42 +1876,67 @@ CodeBody parse_global_nspace( CodeType which ) | |||||||
| 			case Tok_Type_double: | 			case Tok_Type_double: | ||||||
| 			case Tok_Type_int: | 			case Tok_Type_int: | ||||||
| 			{ | 			{ | ||||||
| 				Code constructor_destructor = parse_global_nspace_constructor_destructor( specifiers ); | 				// This s only in a scope so that Preprocess_Macro_Bare_In_Body works without microsoft extension warnings | ||||||
| 				// Possible constructor implemented at global file scope. |  | ||||||
| 				if ( constructor_destructor ) |  | ||||||
| 				{ | 				{ | ||||||
| 					member = constructor_destructor; | 					Code constructor_destructor = parse_global_nspace_constructor_destructor( specifiers ); | ||||||
| 					break; | 					// Possible constructor implemented at global file scope. | ||||||
| 				} | 					if ( constructor_destructor ) | ||||||
|  |  | ||||||
| 				bool found_operator_cast_outside_class_implmentation = false; |  | ||||||
| 				s32  idx = Context.Tokens.Idx; |  | ||||||
|  |  | ||||||
| 				for ( ; idx < array_num(Context.Tokens.Arr); idx++ ) |  | ||||||
| 				{ |  | ||||||
| 					Token tok = Context.Tokens.Arr[ idx ]; |  | ||||||
|  |  | ||||||
| 					if ( tok.Type == Tok_Identifier ) |  | ||||||
| 					{ | 					{ | ||||||
| 						idx++; | 						member = constructor_destructor; | ||||||
| 						tok = Context.Tokens.Arr[ idx ]; | 						break; | ||||||
| 						if ( tok.Type == Tok_Access_StaticSymbol ) | 					} | ||||||
| 							continue; |  | ||||||
|  | 					bool found_operator_cast_outside_class_implmentation = false; | ||||||
|  | 					s32  idx = Context.Tokens.Idx; | ||||||
|  |  | ||||||
|  | 					for ( ; idx < array_num(Context.Tokens.Arr); idx++ ) | ||||||
|  | 					{ | ||||||
|  | 						Token tok = Context.Tokens.Arr[ idx ]; | ||||||
|  |  | ||||||
|  | 						if ( tok.Type == Tok_Identifier ) | ||||||
|  | 						{ | ||||||
|  | 							idx++; | ||||||
|  | 							tok = Context.Tokens.Arr[ idx ]; | ||||||
|  | 							if ( tok.Type == Tok_Access_StaticSymbol ) | ||||||
|  | 								continue; | ||||||
|  |  | ||||||
|  | 							break; | ||||||
|  | 						} | ||||||
|  |  | ||||||
|  | 						if ( tok.Type == Tok_Decl_Operator ) | ||||||
|  | 							found_operator_cast_outside_class_implmentation = true; | ||||||
|  |  | ||||||
| 						break; | 						break; | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					if ( tok.Type == Tok_Decl_Operator ) | 					if ( found_operator_cast_outside_class_implmentation ) | ||||||
| 						found_operator_cast_outside_class_implmentation = true; | 					{ | ||||||
|  | 						member = parse_operator_cast( specifiers ); | ||||||
| 					break; | 						// <Attributes> <Specifiers> <Name>::operator <Type>() { ... } | ||||||
|  | 						break; | ||||||
|  | 					} | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				if ( found_operator_cast_outside_class_implmentation ) | 				if (macro_found) | ||||||
| 				{ | 				{ | ||||||
| 					member = parse_operator_cast( specifiers ); | 				Preprocess_Macro_Bare_In_Body: | ||||||
| 					// <Attributes> <Specifiers> <Name>::operator <Type>() { ... } | 					b32 lone_macro = nexttok.Type == Tok_Statement_End || nexttok_noskip.Type == Tok_NewLine; | ||||||
| 					break; | 					if (lone_macro) | ||||||
|  | 					{ | ||||||
|  | 						member = parse_simple_preprocess( Tok_Preprocess_Macro, parser_consume_braces ); | ||||||
|  | 						// <Macro>; | ||||||
|  |  | ||||||
|  | 						if ( member == Code_Invalid ) | ||||||
|  | 						{ | ||||||
|  | 							log_failure( "Failed to parse member\n%s", parser_to_string(Context) ); | ||||||
|  | 							parser_pop(& Context); | ||||||
|  | 							return InvalidCode; | ||||||
|  | 						} | ||||||
|  | 						goto Member_Resolved_To_Lone_Macro; | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					// We have a macro but its most likely behaving as a typename | ||||||
|  | 					// <Macro ... | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				member = parse_operator_function_or_variable( expects_function, attributes, specifiers ); | 				member = parse_operator_function_or_variable( expects_function, attributes, specifiers ); | ||||||
| @@ -1890,6 +1944,7 @@ CodeBody parse_global_nspace( CodeType which ) | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 	Member_Resolved_To_Lone_Macro: | ||||||
| 		if ( member == Code_Invalid ) | 		if ( member == Code_Invalid ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure( "Failed to parse member\nToken: %S\nContext:\n%S", tok_to_string(currtok_noskip), parser_to_string(Context) ); | 			log_failure( "Failed to parse member\nToken: %S\nContext:\n%S", tok_to_string(currtok_noskip), parser_to_string(Context) ); | ||||||
| @@ -2447,7 +2502,7 @@ CodeOperator parse_operator_after_ret_type( | |||||||
| 	// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> | 	// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> | ||||||
|  |  | ||||||
| 	// Parse Params | 	// Parse Params | ||||||
| 	CodeParam params = parse_params(); | 	CodeParam params = parse_params(parser_use_parenthesis); | ||||||
| 	// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> ( <Parameters> ) | 	// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> ( <Parameters> ) | ||||||
|  |  | ||||||
| 	if ( params.ast == nullptr && op == Op_Multiply ) | 	if ( params.ast == nullptr && op == Op_Multiply ) | ||||||
| @@ -2509,17 +2564,19 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes | |||||||
| 	Code result = InvalidCode; | 	Code result = InvalidCode; | ||||||
|  |  | ||||||
| #ifndef GEN_PARSER_DISABLE_MACRO_FUNCTION_SIGNATURES | #ifndef GEN_PARSER_DISABLE_MACRO_FUNCTION_SIGNATURES | ||||||
| 	if ( currtok.Type == Tok_Preprocess_Macro ) | 	b32 lone_macro = false; | ||||||
|  |  | ||||||
|  | 	if ( currtok.Type == Tok_Preprocess_Macro && nexttok.Type == Tok_Statement_End ) | ||||||
| 	{ | 	{ | ||||||
| 		// Were dealing with a macro after attributes/specifiers. | 		// Were dealing with a lone macro after attributes/specifiers, there was a end statement ';' after. | ||||||
| 		result = parse_simple_preprocess( Tok_Preprocess_Macro ); | 		result = parse_simple_preprocess( Tok_Preprocess_Macro, parser_consume_braces ); | ||||||
| 		parser_pop(& Context); | 		parser_pop(& Context); | ||||||
| 		return result; | 		return result; | ||||||
| 		// <Attributes> <Specifiers> <Macro> | 		// <Attributes> <Specifiers> <Macro> | ||||||
| 	} | 	} | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| 	CodeTypename type = parse_type(); | 	CodeTypename type = parse_type( parser_not_from_template, nullptr ); | ||||||
| 	// <Attributes> <Specifiers> <ReturnType/ValueType> | 	// <Attributes> <Specifiers> <ReturnType/ValueType> | ||||||
|  |  | ||||||
| 	if ( type == InvalidCode ) | 	if ( type == InvalidCode ) | ||||||
| @@ -2559,7 +2616,7 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes | |||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		Token name = parse_identifier(); | 		Token name = parse_identifier(nullptr); | ||||||
| 		Context.Scope->Name = name; | 		Context.Scope->Name = name; | ||||||
|  |  | ||||||
| 		bool detected_capture = check( Tok_Capture_Start ); | 		bool detected_capture = check( Tok_Capture_Start ); | ||||||
| @@ -2679,12 +2736,12 @@ CodeParam parse_params( bool use_template_capture ) | |||||||
| 	// AddComponentByClass(UPARAM(meta = (AllowAbstract = "false")) TSubclassOf<UActorComponent> Class, bool bManualAttachment, ... | 	// AddComponentByClass(UPARAM(meta = (AllowAbstract = "false")) TSubclassOf<UActorComponent> Class, bool bManualAttachment, ... | ||||||
| 	if ( check(Tok_Preprocess_Macro)) | 	if ( check(Tok_Preprocess_Macro)) | ||||||
| 	{ | 	{ | ||||||
| 		macro = parse_simple_preprocess(Tok_Preprocess_Macro); | 		macro = parse_simple_preprocess(Tok_Preprocess_Macro, parser_consume_braces); | ||||||
| 		// ( <Macro> | 		// ( <Macro> | ||||||
| 	} | 	} | ||||||
| 	if ( currtok.Type != Tok_Comma ) | 	if ( currtok.Type != Tok_Comma ) | ||||||
| 	{ | 	{ | ||||||
| 		type = parse_type( use_template_capture ); | 		type = parse_type( use_template_capture, nullptr ); | ||||||
| 		if ( type == Code_Invalid ) | 		if ( type == Code_Invalid ) | ||||||
| 		{ | 		{ | ||||||
| 			parser_pop(& Context); | 			parser_pop(& Context); | ||||||
| @@ -2705,7 +2762,7 @@ CodeParam parse_params( bool use_template_capture ) | |||||||
| 		// So we need to consume that. | 		// So we need to consume that. | ||||||
| 		if ( check( Tok_Preprocess_Macro )) | 		if ( check( Tok_Preprocess_Macro )) | ||||||
| 		{ | 		{ | ||||||
| 			post_name_macro = parse_simple_preprocess( Tok_Preprocess_Macro ); | 			post_name_macro = parse_simple_preprocess( Tok_Preprocess_Macro, parser_consume_braces ); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// In template captures you can have a typename have direct assignment without a name | 		// In template captures you can have a typename have direct assignment without a name | ||||||
| @@ -2747,7 +2804,7 @@ CodeParam parse_params( bool use_template_capture ) | |||||||
| 				eat( currtok.Type ); | 				eat( currtok.Type ); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			value = untyped_str( string_to_strc(strip_formatting( tok_to_str(value_tok), strip_formatting_dont_preserve_newlines )) ); | 			value = untyped_str( string_to_strc(strip_formatting( tok_to_str(value_tok), parser_strip_formatting_dont_preserve_newlines )) ); | ||||||
| 			// ( <Macro> <ValueType> <Name> = <Expression> | 			// ( <Macro> <ValueType> <Name> = <Expression> | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -2789,12 +2846,12 @@ CodeParam parse_params( bool use_template_capture ) | |||||||
| 		// AddComponentByClass(UPARAM(meta = (AllowAbstract = "false")) TSubclassOf<UActorComponent> Class, bool bManualAttachment, ... | 		// AddComponentByClass(UPARAM(meta = (AllowAbstract = "false")) TSubclassOf<UActorComponent> Class, bool bManualAttachment, ... | ||||||
| 		if ( check(Tok_Preprocess_Macro)) | 		if ( check(Tok_Preprocess_Macro)) | ||||||
| 		{ | 		{ | ||||||
| 			macro = parse_simple_preprocess(Tok_Preprocess_Macro); | 			macro = parse_simple_preprocess(Tok_Preprocess_Macro, parser_dont_consume_braces); | ||||||
| 			// ( <Macro> | 			// ( <Macro> | ||||||
| 		} | 		} | ||||||
| 		if ( currtok.Type != Tok_Comma ) | 		if ( currtok.Type != Tok_Comma ) | ||||||
| 		{ | 		{ | ||||||
| 			type = parse_type( use_template_capture ); | 			type = parse_type( use_template_capture, nullptr ); | ||||||
| 			if ( type == Code_Invalid ) | 			if ( type == Code_Invalid ) | ||||||
| 			{ | 			{ | ||||||
| 				parser_pop(& Context); | 				parser_pop(& Context); | ||||||
| @@ -2817,7 +2874,7 @@ CodeParam parse_params( bool use_template_capture ) | |||||||
| 			// So we need to consume that. | 			// So we need to consume that. | ||||||
| 			if ( check( Tok_Preprocess_Macro )) | 			if ( check( Tok_Preprocess_Macro )) | ||||||
| 			{ | 			{ | ||||||
| 				post_name_macro = parse_simple_preprocess( Tok_Preprocess_Macro ); | 				post_name_macro = parse_simple_preprocess( Tok_Preprocess_Macro, parser_dont_consume_braces ); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			// In template captures you can have a typename have direct assignment without a name | 			// In template captures you can have a typename have direct assignment without a name | ||||||
| @@ -2862,7 +2919,7 @@ CodeParam parse_params( bool use_template_capture ) | |||||||
| 					eat( currtok.Type ); | 					eat( currtok.Type ); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				value = untyped_str( string_to_strc(strip_formatting( tok_to_str(value_tok), strip_formatting_dont_preserve_newlines )) ); | 				value = untyped_str( string_to_strc(strip_formatting( tok_to_str(value_tok), parser_strip_formatting_dont_preserve_newlines )) ); | ||||||
| 				// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> = <Expression> | 				// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> = <Expression> | ||||||
| 			} | 			} | ||||||
| 			// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> = <Expression>, .. | 			// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> = <Expression>, .. | ||||||
| @@ -3402,8 +3459,8 @@ CodeConstructor parse_constructor( CodeSpecifiers specifiers ) | |||||||
| { | { | ||||||
| 	push_scope(); | 	push_scope(); | ||||||
|  |  | ||||||
| 	Token     identifier = parse_identifier(); | 	Token     identifier = parse_identifier(nullptr); | ||||||
| 	CodeParam params     = parse_params(); | 	CodeParam params     = parse_params(parser_not_from_template); | ||||||
| 	// <Name> ( <Parameters> ) | 	// <Name> ( <Parameters> ) | ||||||
|  |  | ||||||
| 	Code        initializer_list = NullCode; | 	Code        initializer_list = NullCode; | ||||||
| @@ -3507,7 +3564,7 @@ CodeDestructor parse_destructor( CodeSpecifiers specifiers ) | |||||||
|  |  | ||||||
| 	Token prefix_identifier = NullToken; | 	Token prefix_identifier = NullToken; | ||||||
| 	if (is_in_global_nspace) | 	if (is_in_global_nspace) | ||||||
| 		prefix_identifier = parse_identifier(); | 		prefix_identifier = parse_identifier(nullptr); | ||||||
|  |  | ||||||
| 	if ( left && currtok.Text[ 0 ] == '~' ) | 	if ( left && currtok.Text[ 0 ] == '~' ) | ||||||
| 		eat( Tok_Operator ); | 		eat( Tok_Operator ); | ||||||
| @@ -3519,7 +3576,7 @@ CodeDestructor parse_destructor( CodeSpecifiers specifiers ) | |||||||
| 	} | 	} | ||||||
| 	// <Virtual Specifier> ~ | 	// <Virtual Specifier> ~ | ||||||
|  |  | ||||||
| 	Token       identifier = parse_identifier(); | 	Token       identifier = parse_identifier(nullptr); | ||||||
| 	CodeBody    body       = { nullptr }; | 	CodeBody    body       = { nullptr }; | ||||||
| 	CodeComment inline_cmt = NullCode; | 	CodeComment inline_cmt = NullCode; | ||||||
| 	// <Virtual Specifier> ~<Name> | 	// <Virtual Specifier> ~<Name> | ||||||
| @@ -3646,7 +3703,7 @@ CodeEnum parse_enum( bool inplace_def ) | |||||||
| 		eat( Tok_Assign_Classifer ); | 		eat( Tok_Assign_Classifer ); | ||||||
| 		// enum <class> <Attributes> <Name> : | 		// enum <class> <Attributes> <Name> : | ||||||
|  |  | ||||||
| 		type = parse_type(); | 		type = parse_type(parser_not_from_template, nullptr); | ||||||
| 		if ( type == Code_Invalid ) | 		if ( type == Code_Invalid ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure( "Failed to parse enum classifier\n%s", parser_to_string(Context) ); | 			log_failure( "Failed to parse enum classifier\n%s", parser_to_string(Context) ); | ||||||
| @@ -3662,7 +3719,7 @@ CodeEnum parse_enum( bool inplace_def ) | |||||||
| 		if ( strc_contains( tok_to_str(currtok), sig) ) | 		if ( strc_contains( tok_to_str(currtok), sig) ) | ||||||
| 		{ | 		{ | ||||||
| 			use_macro_underlying = true; | 			use_macro_underlying = true; | ||||||
| 			underlying_macro     = parse_simple_preprocess( Tok_Preprocess_Macro, dont_consume_braces ); | 			underlying_macro     = parse_simple_preprocess( Tok_Preprocess_Macro, parser_dont_consume_braces ); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -3726,7 +3783,7 @@ CodeEnum parse_enum( bool inplace_def ) | |||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| 				case Tok_Preprocess_Macro: | 				case Tok_Preprocess_Macro: | ||||||
| 					member = parse_simple_preprocess( Tok_Preprocess_Macro ); | 					member = parse_simple_preprocess( Tok_Preprocess_Macro, parser_consume_braces); | ||||||
| 					// <Macro> | 					// <Macro> | ||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| @@ -3736,7 +3793,7 @@ CodeEnum parse_enum( bool inplace_def ) | |||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| 				case Tok_Preprocess_Unsupported: | 				case Tok_Preprocess_Unsupported: | ||||||
| 					member = parse_simple_preprocess( Tok_Preprocess_Unsupported ); | 					member = parse_simple_preprocess( Tok_Preprocess_Unsupported, parser_consume_braces ); | ||||||
| 					// #<UNSUPPORTED> | 					// #<UNSUPPORTED> | ||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| @@ -3781,7 +3838,7 @@ CodeEnum parse_enum( bool inplace_def ) | |||||||
| 						// <Name> = <Expression> <Macro>, // <Inline Comment> | 						// <Name> = <Expression> <Macro>, // <Inline Comment> | ||||||
| 					// } | 					// } | ||||||
|  |  | ||||||
| 					Token prev = * lex_previous(Context.Tokens, dont_skip_formatting); | 					Token prev = * lex_previous(Context.Tokens, lex_dont_skip_formatting); | ||||||
| 					entry.Length = ( (sptr)prev.Text + prev.Length ) - (sptr)entry.Text; | 					entry.Length = ( (sptr)prev.Text + prev.Length ) - (sptr)entry.Text; | ||||||
|  |  | ||||||
| 					member = untyped_str( tok_to_str(entry) ); | 					member = untyped_str( tok_to_str(entry) ); | ||||||
| @@ -3948,7 +4005,7 @@ CodeFriend parse_friend() | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Type declaration or return type | 	// Type declaration or return type | ||||||
| 	CodeTypename type = parse_type(); | 	CodeTypename type = parse_type(parser_not_from_template, nullptr); | ||||||
| 	if ( type == Code_Invalid ) | 	if ( type == Code_Invalid ) | ||||||
| 	{ | 	{ | ||||||
| 		parser_pop(& Context); | 		parser_pop(& Context); | ||||||
| @@ -3960,7 +4017,7 @@ CodeFriend parse_friend() | |||||||
| 	if ( currtok.Type == Tok_Identifier ) | 	if ( currtok.Type == Tok_Identifier ) | ||||||
| 	{ | 	{ | ||||||
| 		// Name | 		// Name | ||||||
| 		Token name          = parse_identifier(); | 		Token name          = parse_identifier(nullptr); | ||||||
| 		Context.Scope->Name = name; | 		Context.Scope->Name = name; | ||||||
| 		// friend <ReturnType> <Name> | 		// friend <ReturnType> <Name> | ||||||
|  |  | ||||||
| @@ -4074,7 +4131,7 @@ CodeFn parse_function() | |||||||
| 	} | 	} | ||||||
| 	// <export> <Attributes> <Specifiers> | 	// <export> <Attributes> <Specifiers> | ||||||
|  |  | ||||||
| 	CodeTypename ret_type = parse_type(); | 	CodeTypename ret_type = parse_type(parser_not_from_template, nullptr); | ||||||
| 	if ( ret_type == Code_Invalid ) | 	if ( ret_type == Code_Invalid ) | ||||||
| 	{ | 	{ | ||||||
| 		parser_pop(& Context); | 		parser_pop(& Context); | ||||||
| @@ -4082,7 +4139,7 @@ CodeFn parse_function() | |||||||
| 	} | 	} | ||||||
| 	// <export> <Attributes> <Specifiers> <ReturnType> | 	// <export> <Attributes> <Specifiers> <ReturnType> | ||||||
|  |  | ||||||
| 	Token name = parse_identifier(); | 	Token name = parse_identifier(nullptr); | ||||||
| 	Context.Scope->Name = name; | 	Context.Scope->Name = name; | ||||||
| 	if ( ! tok_is_valid(name) ) | 	if ( ! tok_is_valid(name) ) | ||||||
| 	{ | 	{ | ||||||
| @@ -4106,7 +4163,7 @@ CodeNS parse_namespace() | |||||||
| 	eat( Tok_Decl_Namespace ); | 	eat( Tok_Decl_Namespace ); | ||||||
| 	// namespace | 	// namespace | ||||||
|  |  | ||||||
| 	Token name = parse_identifier(); | 	Token name = parse_identifier(nullptr); | ||||||
| 	Context.Scope->Name = name; | 	Context.Scope->Name = name; | ||||||
| 	// namespace <Name> | 	// namespace <Name> | ||||||
|  |  | ||||||
| @@ -4186,7 +4243,7 @@ CodeOperator parse_operator() | |||||||
| 	// <export> <Attributes> <Specifiers> | 	// <export> <Attributes> <Specifiers> | ||||||
|  |  | ||||||
| 	// Parse Return Type | 	// Parse Return Type | ||||||
| 	CodeTypename ret_type = parse_type(); | 	CodeTypename ret_type = parse_type(parser_not_from_template, nullptr); | ||||||
| 	// <export> <Attributes> <Specifiers> <ReturnType> | 	// <export> <Attributes> <Specifiers> <ReturnType> | ||||||
|  |  | ||||||
| 	CodeOperator result = parse_operator_after_ret_type( mflags, attributes, specifiers, ret_type ); | 	CodeOperator result = parse_operator_after_ret_type( mflags, attributes, specifiers, ret_type ); | ||||||
| @@ -4223,7 +4280,7 @@ CodeOpCast parse_operator_cast( CodeSpecifiers specifiers ) | |||||||
| 	eat( Tok_Decl_Operator ); | 	eat( Tok_Decl_Operator ); | ||||||
| 	// <Specifiers> <Qualifier> :: ... operator | 	// <Specifiers> <Qualifier> :: ... operator | ||||||
|  |  | ||||||
| 	Code type = parse_type(); | 	Code type = parse_type(parser_not_from_template, nullptr); | ||||||
| 	// <Specifiers> <Qualifier> :: ... operator <UnderlyingType> | 	// <Specifiers> <Qualifier> :: ... operator <UnderlyingType> | ||||||
|  |  | ||||||
| 	Context.Scope->Name = { type->Name.Ptr, type->Name.Len }; | 	Context.Scope->Name = { type->Name.Ptr, type->Name.Len }; | ||||||
| @@ -4350,21 +4407,21 @@ CodeTemplate parse_template() | |||||||
| 	{ | 	{ | ||||||
| 		if ( check( Tok_Decl_Class ) ) | 		if ( check( Tok_Decl_Class ) ) | ||||||
| 		{ | 		{ | ||||||
| 			definition = parse_class(); | 			definition = parse_class( parser_not_inplace_def); | ||||||
| 			// <export> template< <Parameters> > class ... | 			// <export> template< <Parameters> > class ... | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if ( check( Tok_Decl_Struct ) ) | 		if ( check( Tok_Decl_Struct ) ) | ||||||
| 		{ | 		{ | ||||||
| 			definition = parse_struct(); | 			definition = parse_struct( parser_not_inplace_def); | ||||||
| 			// <export> template< <Parameters> > struct ... | 			// <export> template< <Parameters> > struct ... | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if ( check( Tok_Decl_Union ) ) | 		if ( check( Tok_Decl_Union ) ) | ||||||
| 		{ | 		{ | ||||||
| 			definition = parse_union(); | 			definition = parse_union( parser_not_inplace_def); | ||||||
| 			// <export> template< <Parameters> > union ... | 			// <export> template< <Parameters> > union ... | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| @@ -4583,7 +4640,7 @@ CodeTypename parse_type( bool from_template, bool* typedef_is_function ) | |||||||
| 		eat( currtok.Type ); | 		eat( currtok.Type ); | ||||||
| 		// <Attributes> <Specifiers> <class, enum, struct, union> | 		// <Attributes> <Specifiers> <class, enum, struct, union> | ||||||
|  |  | ||||||
| 		name = parse_identifier(); | 		name = parse_identifier(nullptr); | ||||||
|  |  | ||||||
| 		// name.Length = ( ( sptr )currtok.Text + currtok.Length ) - ( sptr )name.Text; | 		// name.Length = ( ( sptr )currtok.Text + currtok.Length ) - ( sptr )name.Text; | ||||||
| 		// eat( Tok_Identifier ); | 		// eat( Tok_Identifier ); | ||||||
| @@ -4643,7 +4700,7 @@ else if ( currtok.Type == Tok_DeclType ) | |||||||
|  |  | ||||||
| 		if ( ! from_template ) | 		if ( ! from_template ) | ||||||
| 		{ | 		{ | ||||||
| 			name                = parse_identifier(); | 			name                = parse_identifier(nullptr); | ||||||
| 			Context.Scope->Name = name; | 			Context.Scope->Name = name; | ||||||
| 			if ( ! tok_is_valid(name) ) | 			if ( ! tok_is_valid(name) ) | ||||||
| 			{ | 			{ | ||||||
| @@ -4653,11 +4710,16 @@ else if ( currtok.Type == Tok_DeclType ) | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 	else if ( currtok.Type == Tok_Preprocess_Macro ) { | ||||||
|  | 		// Typename is a macro | ||||||
|  | 		name = currtok; | ||||||
|  | 		eat(Tok_Preprocess_Macro); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// The usual Identifier type signature that may have namespace qualifiers | 	// The usual Identifier type signature that may have namespace qualifiers | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		name                = parse_identifier(); | 		name                = parse_identifier(nullptr); | ||||||
| 		Context.Scope->Name = name; | 		Context.Scope->Name = name; | ||||||
| 		if ( ! tok_is_valid(name) ) | 		if ( ! tok_is_valid(name) ) | ||||||
| 		{ | 		{ | ||||||
| @@ -4782,7 +4844,7 @@ else if ( currtok.Type == Tok_DeclType ) | |||||||
| 		if ( ! check( Tok_Capture_Start ) ) | 		if ( ! check( Tok_Capture_Start ) ) | ||||||
| 		{ | 		{ | ||||||
| 			// Started with an identifier immeidately, which means its of the format: <ReturnType> <identifier> <capture>; | 			// Started with an identifier immeidately, which means its of the format: <ReturnType> <identifier> <capture>; | ||||||
| 			name = parse_identifier(); | 			name = parse_identifier(nullptr); | ||||||
| 		} | 		} | ||||||
| 		// <Attributes> <ReturnType> <Identifier> | 		// <Attributes> <ReturnType> <Identifier> | ||||||
|  |  | ||||||
| @@ -4866,7 +4928,7 @@ else if ( currtok.Type == Tok_DeclType ) | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Were now dealing with the parameters of the function | 		// Were now dealing with the parameters of the function | ||||||
| 		params = parse_params(); | 		params = parse_params(parser_use_parenthesis); | ||||||
| 		// <Attributes> <ReturnType> <All Kinds of nonsense> ( <Parameters> ) | 		// <Attributes> <ReturnType> <All Kinds of nonsense> ( <Parameters> ) | ||||||
|  |  | ||||||
| 		// Look for suffix specifiers for the function | 		// Look for suffix specifiers for the function | ||||||
| @@ -4913,7 +4975,7 @@ else if ( currtok.Type == Tok_DeclType ) | |||||||
| 	// result->Token = Context.Scope->Start; | 	// result->Token = Context.Scope->Start; | ||||||
|  |  | ||||||
| 	// Need to wait until were using the new parsing method to do this. | 	// Need to wait until were using the new parsing method to do this. | ||||||
| 	String name_stripped = strip_formatting( tok_to_str(name), strip_formatting_dont_preserve_newlines ); | 	String name_stripped = strip_formatting( tok_to_str(name), parser_strip_formatting_dont_preserve_newlines ); | ||||||
|  |  | ||||||
| 	// name_stripped.strip_space(); | 	// name_stripped.strip_space(); | ||||||
|  |  | ||||||
| @@ -5105,7 +5167,7 @@ CodeTypedef parse_typedef() | |||||||
| 				{ | 				{ | ||||||
| 					// Its an array definition | 					// Its an array definition | ||||||
| 					// <which> <type_identifier> <identifier> [ ... ]; | 					// <which> <type_identifier> <identifier> [ ... ]; | ||||||
| 					type = parse_type(); | 					type = parse_type(parser_not_from_template, nullptr); | ||||||
| 					// <ModuleFalgs> typedef <UnderlyingType> | 					// <ModuleFalgs> typedef <UnderlyingType> | ||||||
| 				} | 				} | ||||||
| 				else | 				else | ||||||
| @@ -5278,7 +5340,13 @@ CodeUnion parse_union( bool inplace_def ) | |||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| 				case Tok_Preprocess_Macro: | 				case Tok_Preprocess_Macro: | ||||||
| 					member = parse_simple_preprocess( Tok_Preprocess_Macro ); | 					if ( nexttok.Type == Tok_Identifier ) { | ||||||
|  | 						// Its a variable with a macro typename | ||||||
|  | 						member = parse_variable(); | ||||||
|  | 						break; | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					member = parse_simple_preprocess( Tok_Preprocess_Macro, parser_consume_braces ); | ||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| 				case Tok_Preprocess_Pragma: | 				case Tok_Preprocess_Pragma: | ||||||
| @@ -5286,7 +5354,7 @@ CodeUnion parse_union( bool inplace_def ) | |||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| 				case Tok_Preprocess_Unsupported: | 				case Tok_Preprocess_Unsupported: | ||||||
| 					member = parse_simple_preprocess( Tok_Preprocess_Unsupported ); | 					member = parse_simple_preprocess( Tok_Preprocess_Unsupported, parser_consume_braces ); | ||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| 				default: | 				default: | ||||||
| @@ -5371,7 +5439,7 @@ CodeUsing parse_using() | |||||||
| 			eat( Tok_Operator ); | 			eat( Tok_Operator ); | ||||||
| 			// <ModuleFlags> using <Name> <Attributes> = | 			// <ModuleFlags> using <Name> <Attributes> = | ||||||
|  |  | ||||||
| 			type = parse_type(); | 			type = parse_type(parser_not_from_template, nullptr); | ||||||
| 			// <ModuleFlags> using <Name> <Attributes> = <UnderlyingType> | 			// <ModuleFlags> using <Name> <Attributes> = <UnderlyingType> | ||||||
|  |  | ||||||
| 			array_expr = parse_array_decl(); | 			array_expr = parse_array_decl(); | ||||||
| @@ -5481,13 +5549,13 @@ CodeVar parse_variable() | |||||||
| 	} | 	} | ||||||
| 	// <ModuleFlags> <Attributes> <Specifiers> | 	// <ModuleFlags> <Attributes> <Specifiers> | ||||||
|  |  | ||||||
| 	CodeTypename type = parse_type(); | 	CodeTypename type = parse_type(parser_not_from_template, nullptr); | ||||||
| 	// <ModuleFlags> <Attributes> <Specifiers> <ValueType> | 	// <ModuleFlags> <Attributes> <Specifiers> <ValueType> | ||||||
|  |  | ||||||
| 	if ( type == Code_Invalid ) | 	if ( type == Code_Invalid ) | ||||||
| 		return InvalidCode; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	Context.Scope->Name = parse_identifier(); | 	Context.Scope->Name = parse_identifier(nullptr); | ||||||
| 	// <ModuleFlags> <Attributes> <Specifiers> <ValueType> <Name> | 	// <ModuleFlags> <Attributes> <Specifiers> <ValueType> <Name> | ||||||
|  |  | ||||||
| 	CodeVar result = parse_variable_after_name( mflags, attributes, specifiers, type, tok_to_str(Context.Scope->Name) ); | 	CodeVar result = parse_variable_after_name( mflags, attributes, specifiers, type, tok_to_str(Context.Scope->Name) ); | ||||||
|   | |||||||
| @@ -365,18 +365,18 @@ ssize fixed_arena_size_remaining(FixedArena<Size>* fixed_arena, ssize alignment) | |||||||
|     return size_remaining(fixed_arena->arena, alignment); |     return size_remaining(fixed_arena->arena, alignment); | ||||||
| } | } | ||||||
|  |  | ||||||
| using Arena_1KB   = FixedArena< kilobytes( 1 ) >; | using FixedArena_1KB   = FixedArena< kilobytes( 1 ) >; | ||||||
| using Arena_4KB   = FixedArena< kilobytes( 4 ) >; | using FixedArena_4KB   = FixedArena< kilobytes( 4 ) >; | ||||||
| using Arena_8KB   = FixedArena< kilobytes( 8 ) >; | using FixedArena_8KB   = FixedArena< kilobytes( 8 ) >; | ||||||
| using Arena_16KB  = FixedArena< kilobytes( 16 ) >; | using FixedArena_16KB  = FixedArena< kilobytes( 16 ) >; | ||||||
| using Arena_32KB  = FixedArena< kilobytes( 32 ) >; | using FixedArena_32KB  = FixedArena< kilobytes( 32 ) >; | ||||||
| using Arena_64KB  = FixedArena< kilobytes( 64 ) >; | using FixedArena_64KB  = FixedArena< kilobytes( 64 ) >; | ||||||
| using Arena_128KB = FixedArena< kilobytes( 128 ) >; | using FixedArena_128KB = FixedArena< kilobytes( 128 ) >; | ||||||
| using Arena_256KB = FixedArena< kilobytes( 256 ) >; | using FixedArena_256KB = FixedArena< kilobytes( 256 ) >; | ||||||
| using Arena_512KB = FixedArena< kilobytes( 512 ) >; | using FixedArena_512KB = FixedArena< kilobytes( 512 ) >; | ||||||
| using Arena_1MB   = FixedArena< megabytes( 1 ) >; | using FixedArena_1MB   = FixedArena< megabytes( 1 ) >; | ||||||
| using Arena_2MB   = FixedArena< megabytes( 2 ) >; | using FixedArena_2MB   = FixedArena< megabytes( 2 ) >; | ||||||
| using Arena_4MB   = FixedArena< megabytes( 4 ) >; | using FixedArena_4MB   = FixedArena< megabytes( 4 ) >; | ||||||
| #pragma endregion FixedArena | #pragma endregion FixedArena | ||||||
|  |  | ||||||
| #pragma region Pool | #pragma region Pool | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user