mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-10-31 06:50:53 -07:00 
			
		
		
		
	Compare commits
	
		
			4 Commits
		
	
	
		
			ed9f719a07
			...
			79a1951861
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 79a1951861 | |||
| e786d7c3b6 | |||
| e6f30c7e1d | |||
| 6147912783 | 
| @@ -105,6 +105,7 @@ int gen_main() | ||||
|  | ||||
| 	PreprocessorDefines.append(txt("GEN_API_C_BEGIN")); | ||||
| 	PreprocessorDefines.append(txt("GEN_API_C_END")); | ||||
| 	PreprocessorDefines.append(txt("Array(")); | ||||
| 	PreprocessorDefines.append(txt("HashTable(")); | ||||
| 	PreprocessorDefines.append(txt("GEN_NS_PARSER")); | ||||
| 	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 ); | ||||
| 					if (found) break; | ||||
|  | ||||
| 					new_body.append(body_entry); | ||||
| 				} | ||||
| 				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); | ||||
| 			if (found) break; | ||||
|  | ||||
| 			header_strings.append(entry); | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| @@ -456,6 +461,15 @@ do                          \ | ||||
| 	CodeBody header_parsing        = def_body(CT_Global_Body); | ||||
| 	for ( Code entry = parsed_header_parsing.begin(); entry != parsed_header_parsing.end(); ++ entry ) switch (entry->Type) | ||||
| 	{ | ||||
| 		case CT_Preprocess_IfDef: | ||||
| 		{ | ||||
| 			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_parsing, header_parsing ); | ||||
| 			if (found) break; | ||||
|  | ||||
| 			header_parsing.append(entry); | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Preprocess_Pragma: | ||||
| 		{ | ||||
| 			if ( entry->Content.contains(txt("ADT")) ) | ||||
| @@ -538,8 +552,6 @@ do                          \ | ||||
| 	// Only has operator overload definitions that C doesn't need. | ||||
| 	// CodeBody ast_inlines = gen_ast_inlines(); | ||||
|  | ||||
| 	Code inlines 	= scan_file( project_dir "components/inlines.hpp" ); | ||||
|  | ||||
| 	CodeBody ecode       = gen_ecode     ( project_dir "enums/ECodeTypes.csv", helper_use_c_definition ); | ||||
| 	CodeBody eoperator   = gen_eoperator ( project_dir "enums/EOperator.csv",  helper_use_c_definition ); | ||||
| 	CodeBody especifier  = gen_especifier( project_dir "enums/ESpecifier.csv", helper_use_c_definition ); | ||||
| @@ -548,6 +560,24 @@ do                          \ | ||||
| 	CodeBody types        = def_body(CT_Global_Body); | ||||
| 	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: | ||||
| 		{ | ||||
| 			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_types, types ); | ||||
| 			if (found) break; | ||||
|  | ||||
| 			types.append(entry); | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Using: | ||||
| 		{ | ||||
| 			CodeUsing using_ver = cast(CodeUsing, entry); | ||||
| @@ -595,10 +625,22 @@ do                          \ | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	// Used to track which functions need generic selectors. | ||||
| 	Array(CodeFn) code_c_interface = array_init_reserve<CodeFn>(GlobalAllocator, 16); | ||||
|  | ||||
| 	CodeBody parsed_ast = parse_file( project_dir "components/ast.hpp" ); | ||||
| 	CodeBody ast        = def_body(CT_Global_Body); | ||||
| 	for ( Code entry = parsed_ast.begin(); entry != parsed_ast.end(); ++ entry ) switch (entry->Type) | ||||
| 	{ | ||||
| 		case CT_Preprocess_IfDef: | ||||
| 		{ | ||||
| 			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_ast, ast ); | ||||
| 			if (found) break; | ||||
|  | ||||
| 			ast.append(entry); | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Preprocess_If: | ||||
| 		{ | ||||
| 			CodePreprocessCond cond = cast(CodePreprocessCond, entry); | ||||
| @@ -617,6 +659,48 @@ do                          \ | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Preprocess_Pragma: | ||||
| 		{ | ||||
| 			if ( ! entry->Content.contains(txt("region Code C-Interface"))) { | ||||
| 				continue; | ||||
| 			} | ||||
| 			// Reached the #pragma region Code C-Interface | ||||
| 			for (b32 continue_for = true; continue_for; ++ entry) switch(entry->Type) | ||||
| 			{ | ||||
| 				default: | ||||
| 					// Pass through everything but function forwards or the end region pragma | ||||
| 					ast.append(entry); | ||||
| 				break; | ||||
|  | ||||
| 				case CT_Function_Fwd: | ||||
| 				{ | ||||
| 					// Were going to wrap usage of these procedures into generic selectors in code_types.hpp section, | ||||
| 					// so we're changing the namespace to code__<name> | ||||
| 					CodeFn fn = cast(CodeFn, entry); | ||||
| 					if (fn->Name.starts_with(txt("code_"))) | ||||
| 					{ | ||||
| 						StrC   old_prefix  = txt("code_"); | ||||
| 						StrC   actual_name = { fn->Name.Len  - old_prefix.Len, fn->Name.Ptr + old_prefix.Len }; | ||||
| 						String new_name    = String::fmt_buf(GlobalAllocator, "code__%SC", actual_name ); | ||||
|  | ||||
| 						fn->Name = get_cached_string(new_name); | ||||
| 						code_c_interface.append(fn); | ||||
| 					} | ||||
| 					ast.append(entry); | ||||
| 				} | ||||
| 				break; | ||||
|  | ||||
| 				case CT_Preprocess_Pragma: | ||||
| 					// Reached the end of the interface, go back to regular ast.hpp iteration. | ||||
| 					ast.append(entry); | ||||
| 					if ( entry->Content.contains(txt("endregion Code C-Interface"))) { | ||||
| 						continue_for = false; | ||||
| 					} | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Struct_Fwd: | ||||
| 		{ | ||||
| 			CodeStruct  fwd  = cast(CodeStruct, entry); | ||||
| @@ -679,6 +763,37 @@ R"(#define AST_ArrSpecs_Cap \ | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	StrC code_typenames[] = { | ||||
| 		txt("Code"), | ||||
| 		txt("CodeBody"), | ||||
| 		txt("CodeAttributes"), | ||||
| 		txt("CodeComment"), | ||||
| 		txt("CodeClass"), | ||||
| 		txt("CodeConstructor"), | ||||
| 		txt("CodeDefine"), | ||||
| 		txt("CodeDestructor"), | ||||
| 		txt("CodeEnum"), | ||||
| 		txt("CodeExec"), | ||||
| 		txt("CodeExtern"), | ||||
| 		txt("CodeInclude"), | ||||
| 		txt("CodeFriend"), | ||||
| 		txt("CodeFn"), | ||||
| 		txt("CodeModule"), | ||||
| 		txt("CodeNS"), | ||||
| 		txt("CodeOperator"), | ||||
| 		txt("CodeOpCast"), | ||||
| 		txt("CodePragma"), | ||||
| 		txt("CodeParam"), | ||||
| 		txt("CodePreprocessCond"), | ||||
| 		txt("CodeSpecifiers"), | ||||
| 		txt("CodeTemplate"), | ||||
| 		txt("CodeTypename"), | ||||
| 		txt("CodeTypedef"), | ||||
| 		txt("CodeUnion"), | ||||
| 		txt("CodeUsing"), | ||||
| 		txt("CodeVar"), | ||||
| 	}; | ||||
|  | ||||
| 	CodeBody parsed_code_types = parse_file( project_dir "components/code_types.hpp" ); | ||||
| 	CodeBody code_types        = def_body(CT_Global_Body); | ||||
| 	for ( Code entry = parsed_code_types.begin(); entry != parsed_code_types.end(); ++ entry ) switch( entry->Type ) | ||||
| @@ -688,7 +803,7 @@ R"(#define AST_ArrSpecs_Cap \ | ||||
| 		{ | ||||
| 			b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_code_types, code_types ); | ||||
| 			if (found) { | ||||
| 				++ entry; | ||||
| 				++ entry; // Skip a newline... | ||||
| 				break; | ||||
| 			} | ||||
| 			found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_code_types, code_types ); | ||||
| @@ -698,6 +813,84 @@ R"(#define AST_ArrSpecs_Cap \ | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Preprocess_Pragma: if ( entry->Content.is_equal(txt("region Code Type C-Interface")) ) | ||||
| 		{ | ||||
| 			code_types.append(entry); | ||||
| 			code_types.append(fmt_newline); | ||||
| 			/* | ||||
| 			This thing makes a: | ||||
| 			#define code_<interface_name>( code, ... ) _Generic( (code),                    \ | ||||
| 				<slots> of defintions that look like: <typeof(code)>: code__<interface_name>, \ | ||||
| 				default: gen_generic_selection (Fail case)                                    \ | ||||
| 			) GEN_RESOLVED_FUNCTION_CALL( code, ... )                                       \ | ||||
| 			*/ | ||||
| 			String generic_selector = String::make_reserve(GlobalAllocator, kilobytes(2)); | ||||
| 			for ( CodeFn fn : code_c_interface ) | ||||
| 			{ | ||||
| 				generic_selector.clear(); | ||||
| 				StrC   private_prefix  = txt("code__"); | ||||
| 				StrC   actual_name     = { fn->Name.Len - private_prefix.Len, fn->Name.Ptr + private_prefix.Len }; | ||||
| 				String interface_name  = String::fmt_buf(GlobalAllocator, "code_%SC", actual_name ); | ||||
|  | ||||
| 				// Resolve generic's arguments | ||||
| 				b32    has_args   = fn->Params->NumEntries > 1; | ||||
| 				String params_str = String::make_reserve(GlobalAllocator, 32); | ||||
| 				for (CodeParam param = fn->Params->Next; param != fn->Params.end(); ++ param) { | ||||
| 					// We skip the first parameter as its always going to be the code for selection | ||||
| 					if (param->Next == nullptr) { | ||||
| 						params_str.append_fmt( "%SC", param->Name ); | ||||
| 						continue; | ||||
| 					} | ||||
| 					params_str.append_fmt( "%SC, ", param->Name ); | ||||
| 				} | ||||
|  | ||||
| 				char const* tmpl_def_start = nullptr; | ||||
| 				if (has_args) { | ||||
| 					tmpl_def_start = | ||||
| R"(#define <interface_name>( code, <params> ) _Generic( (code),  \ | ||||
| )"; | ||||
| 				} | ||||
| 				else { | ||||
| 					tmpl_def_start = | ||||
| R"(#define <interface_name>( code ) _Generic( (code), \ | ||||
| )"; | ||||
| 				} | ||||
| 				// Definition start | ||||
| 				generic_selector.append( token_fmt( | ||||
| 							"interface_name", interface_name.to_strc() | ||||
| 					,		"params",         params_str.to_strc() // Only used if has_args | ||||
| 					, tmpl_def_start | ||||
| 				)); | ||||
|  | ||||
| 				// Append slots | ||||
| 				for(StrC type : code_typenames ) { | ||||
| 					generic_selector.append_fmt("%SC : %SC,\\\n", type, fn->Name ); | ||||
| 				} | ||||
| 				generic_selector.append(txt("default: gen_generic_selection_fail \\\n")); | ||||
|  | ||||
| 				char const* tmpl_def_end = nullptr; | ||||
| 				if (has_args) { | ||||
| 					tmpl_def_end = txt("\t)\tGEN_RESOLVED_FUNCTION_CALL( (<type>)code, <params> )"); | ||||
| 				} | ||||
| 				else { | ||||
| 					tmpl_def_end = txt("\t)\tGEN_RESOLVED_FUNCTION_CALL( (<type>)code )"); | ||||
| 				} | ||||
| 				// Definition end | ||||
| 				generic_selector.append( token_fmt( | ||||
| 						"params", params_str.to_strc() | ||||
| 				, 	"type",   fn->Params->ValueType->Name | ||||
| 				,		tmpl_def_end ) ); | ||||
|  | ||||
| 				code_types.append( untyped_str(generic_selector) ); | ||||
| 				code_types.append( fmt_newline); | ||||
| 				code_types.append( fmt_newline); | ||||
| 			} | ||||
| 		} | ||||
| 		else { | ||||
| 			code_types.append(entry); // Ignore the pragma otherwise | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| 		default: | ||||
| 			code_types.append(entry); | ||||
| 		break; | ||||
| @@ -756,7 +949,7 @@ R"(#define AST_ArrSpecs_Cap \ | ||||
| 	{ | ||||
| 		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; | ||||
|  | ||||
| 			interface.append(entry); | ||||
| @@ -768,12 +961,60 @@ R"(#define AST_ArrSpecs_Cap \ | ||||
| 		{ | ||||
| 			CodeFn fn = cast(CodeFn, entry); | ||||
| 			Code prev = entry->Prev; | ||||
|  | ||||
| 			if (prev && prev->Name.is_equal(entry->Name)) { | ||||
| 				// rename second definition so there isn't a symbol conflict | ||||
| 				String postfix_arr = String::fmt_buf(GlobalAllocator, "%SC_arr", entry->Name); | ||||
| 				entry->Name = get_cached_string(postfix_arr.to_strc()); | ||||
| 				postfix_arr.free(); | ||||
| 			} | ||||
| 			interface.append(fn); | ||||
|  | ||||
| 			b32 handled= false; | ||||
| 			for ( CodeParam opt_param : fn->Params ) if (opt_param->ValueType->Name.starts_with(txt("Opts_"))) | ||||
| 			{ | ||||
| 				// Convert the definition to use a default struct: https://vxtwitter.com/vkrajacic/status/1749816169736073295 | ||||
| 				StrC prefix      = txt("def_"); | ||||
| 				StrC actual_name = { fn->Name.Len  - prefix.Len, fn->Name.Ptr + prefix.Len }; | ||||
| 				StrC new_name    = String::fmt_buf(GlobalAllocator, "def__%SC", actual_name ).to_strc(); | ||||
|  | ||||
| 				// Resolve define's arguments | ||||
| 				b32    has_args   = fn->Params->NumEntries > 1; | ||||
| 				String params_str = String::make_reserve(GlobalAllocator, 32); | ||||
| 				for (CodeParam other_param = fn->Params; other_param != opt_param; ++ other_param) { | ||||
| 					if ( other_param == opt_param ) { | ||||
| 						params_str.append_fmt( "%SC", other_param->Name ); | ||||
| 						break; | ||||
| 					} | ||||
| 					// If there are arguments before the optional, prepare them here. | ||||
| 					params_str.append_fmt( "%SC, ", other_param->Name ); | ||||
| 				} | ||||
| 				char const* tmpl_fn_macro = nullptr; | ||||
| 				if (params_str.length() > 0 ) { | ||||
| 					tmpl_fn_macro= "#define <def_name>( <params> ... ) <def__name>( <params> (<opts_type>) { __VA_ARGS__ } )\n"; | ||||
| 				} | ||||
| 				else { | ||||
| 					tmpl_fn_macro= "#define <def_name>( ... ) <def__name>( (<opts_type>) { __VA_ARGS__ } )\n"; | ||||
| 				} | ||||
| 				Code fn_macro = untyped_str(token_fmt( | ||||
| 						"def_name",  fn->Name | ||||
| 				,		"def__name", new_name | ||||
| 				,		"params",    params_str.to_strc() | ||||
| 				,		"opts_type", opt_param->ValueType->Name | ||||
| 				,	tmpl_fn_macro | ||||
| 				)); | ||||
|  | ||||
| 				fn->Name = get_cached_string(new_name); | ||||
| 				interface.append(fn); | ||||
| 				interface.append(fn_macro); | ||||
| 				if (entry->Next && entry->Next->Type != CT_NewLine) { | ||||
| 					interface.append(fmt_newline); | ||||
| 				} | ||||
| 				handled = true; | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 			if (! handled) | ||||
| 				interface.append(fn); | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| @@ -791,11 +1032,55 @@ R"(#define AST_ArrSpecs_Cap \ | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	CodeBody parsed_inlines = parse_file( project_dir "components/inlines.hpp" ); | ||||
| 	CodeBody inlines        = def_body(CT_Global_Body); | ||||
| 	for ( Code entry = parsed_inlines.begin(); entry != parsed_inlines.end(); ++ entry ) switch( entry->Type ) | ||||
| 	{ | ||||
| 		case CT_Preprocess_IfDef: | ||||
| 		{ | ||||
| 			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_inlines, inlines ); | ||||
| 			if (found) break; | ||||
|  | ||||
| 			inlines.append(entry); | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Function: | ||||
| 		{ | ||||
| 			// Were going to wrap usage of these procedures into generic selectors in code_types.hpp section, | ||||
| 			// so we're changing the namespace to code__<name> | ||||
| 			CodeFn fn = cast(CodeFn, entry); | ||||
| 			if (fn->Name.starts_with(txt("code_"))) | ||||
| 			{ | ||||
| 				StrC   old_prefix  = txt("code_"); | ||||
| 				StrC   actual_name = { fn->Name.Len  - old_prefix.Len, fn->Name.Ptr + old_prefix.Len }; | ||||
| 				String new_name    = String::fmt_buf(GlobalAllocator, "code__%SC", actual_name ); | ||||
|  | ||||
| 				fn->Name = get_cached_string(new_name); | ||||
| 			} | ||||
| 			inlines.append(entry); | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| 		default: | ||||
| 			inlines.append(entry); | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	s32 idx = 0; | ||||
| 	CodeBody parsed_header_end = parse_file( project_dir "components/header_end.hpp" ); | ||||
| 	CodeBody header_end        = def_body(CT_Global_Body); | ||||
| 	for ( Code entry = parsed_header_end.begin(); entry != parsed_header_end.end(); ++ entry, ++ idx ) switch( entry->Type ) | ||||
| 	{ | ||||
| 		case CT_Preprocess_IfDef: | ||||
| 		{ | ||||
| 			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_end, header_end ); | ||||
| 			if (found) break; | ||||
|  | ||||
| 			header_end.append(entry); | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Variable: | ||||
| 		{ | ||||
| 			CodeVar var = cast(CodeVar, entry); | ||||
| @@ -835,17 +1120,221 @@ R"(#define AST_ArrSpecs_Cap \ | ||||
| #pragma region Resolve Components | ||||
| 	CodeBody array_arena = gen_array(txt("Arena"), txt("Array_Arena")); | ||||
| 	CodeBody array_pool  = gen_array(txt("Pool"), txt("Array_Pool")); | ||||
| 	CodeBody array_token = gen_array(txt("Token"), txt("Array_Token")); | ||||
|  | ||||
| 	Code src_static_data 	    = scan_file( project_dir "components/static_data.cpp" ); | ||||
| 	Code src_ast_case_macros    = scan_file( project_dir "components/ast_case_macros.cpp" ); | ||||
| 	Code src_ast                = scan_file( project_dir "components/ast.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_upfront            = scan_file( project_dir "components/interface.upfront.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_untyped            = scan_file( project_dir "components/interface.untyped.cpp" ); | ||||
|  | ||||
| 	CodeBody parsed_src_ast = parse_file( project_dir "components/ast.cpp" ); | ||||
| 	CodeBody src_ast        = def_body(CT_Global_Body); | ||||
| 	for ( Code entry = parsed_src_ast.begin(); entry != parsed_src_ast.end(); ++ entry ) switch( entry ->Type ) | ||||
| 	{ | ||||
| 		case CT_Preprocess_IfDef: | ||||
| 		{ | ||||
| 			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_src_ast, src_ast ); | ||||
| 			if (found) break; | ||||
|  | ||||
| 			src_ast.append(entry); | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Function: | ||||
| 		{ | ||||
| 			// Were going to wrap usage of these procedures into generic selectors in code_types.hpp section, | ||||
| 			// so we're changing the namespace to code__<name> | ||||
| 			CodeFn fn = cast(CodeFn, entry); | ||||
| 			if (fn->Name.starts_with(txt("code_"))) | ||||
| 			{ | ||||
| 				StrC   old_prefix  = txt("code_"); | ||||
| 				StrC   actual_name = { fn->Name.Len  - old_prefix.Len, fn->Name.Ptr + old_prefix.Len }; | ||||
| 				String new_name    = String::fmt_buf(GlobalAllocator, "code__%SC", actual_name ); | ||||
|  | ||||
| 				fn->Name = get_cached_string(new_name); | ||||
| 			} | ||||
| 			src_ast.append(entry); | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| 		default: | ||||
| 			src_ast.append(entry); | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	CodeBody parsed_src_upfront = parse_file( project_dir "components/interface.upfront.cpp" ); | ||||
| 	CodeBody src_upfront        = def_body(CT_Global_Body); | ||||
| 	for ( Code entry = parsed_src_upfront.begin(); entry != parsed_src_upfront.end(); ++ entry ) switch( entry ->Type ) | ||||
| 	{ | ||||
| 		case CT_Preprocess_IfDef: | ||||
| 		{ | ||||
| 			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_src_upfront, src_upfront ); | ||||
| 			if (found) break; | ||||
|  | ||||
| 			src_upfront.append(entry); | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Enum: { | ||||
| 			convert_cpp_enum_to_c(cast(CodeEnum, entry), src_upfront); | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Function: | ||||
| 		{ | ||||
| 			CodeFn fn = cast(CodeFn, entry); | ||||
| 			Code prev = entry->Prev; | ||||
|  | ||||
| 			for ( CodeParam arr_param : fn->Params ) | ||||
| 				if (	fn->Name.starts_with(txt("def_")) | ||||
| 					&&	(		arr_param->ValueType->Name.starts_with(txt("Specifier")) | ||||
| 							||	arr_param->ValueType->Name.starts_with(txt("Code")) ) | ||||
| 				) | ||||
| 				{ | ||||
| 					// rename second definition so there isn't a symbol conflict | ||||
| 					String postfix_arr = String::fmt_buf(GlobalAllocator, "%SC_arr", fn->Name); | ||||
| 					fn->Name = get_cached_string(postfix_arr.to_strc()); | ||||
| 					postfix_arr.free(); | ||||
| 				} | ||||
|  | ||||
| 			for ( CodeParam opt_param : fn->Params ) if (opt_param->ValueType->Name.starts_with(txt("Opts_"))) | ||||
| 			{ | ||||
| 				StrC prefix      = txt("def_"); | ||||
| 				StrC actual_name = { fn->Name.Len  - prefix.Len, fn->Name.Ptr + prefix.Len }; | ||||
| 				StrC new_name    = String::fmt_buf(GlobalAllocator, "def__%SC", actual_name ).to_strc(); | ||||
|  | ||||
| 				fn->Name = get_cached_string(new_name); | ||||
| 			} | ||||
|  | ||||
| 			src_upfront.append(fn); | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| 		default: | ||||
| 			src_upfront.append(entry); | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	// CodeBody hashtable_strc = gen_hashtable(txt("StrC"), txt("HashTable_StrC")); | ||||
|  | ||||
| 	CodeBody parsed_src_lexer = parse_file( project_dir "components/lexer.cpp" ); | ||||
| 	CodeBody src_lexer        = def_body(CT_Global_Body); | ||||
| 	for ( Code entry = parsed_src_lexer.begin(); entry != parsed_src_lexer.end(); ++ entry ) switch( entry ->Type ) | ||||
| 	{ | ||||
| 		case CT_Preprocess_IfDef: | ||||
| 		{ | ||||
| 			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_src_lexer, src_lexer ); | ||||
| 			if (found) break; | ||||
|  | ||||
| 			src_lexer.append(entry); | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Enum: | ||||
| 		{ | ||||
| 			if (entry->Name.Len) | ||||
| 			{ | ||||
| 				convert_cpp_enum_to_c(cast(CodeEnum, entry), src_lexer); | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 			src_lexer.append(entry); | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Struct: | ||||
| 		{ | ||||
| 			if ( entry->Name.is_equal(txt("Token"))) | ||||
| 			{ | ||||
| 				// Add struct Token forward and typedef early. | ||||
| 				CodeStruct  token_fwd     = parse_struct(code( struct Token; )); | ||||
| 				CodeTypedef token_typedef = parse_typedef(code( typedef struct Token Token; )); | ||||
| 				src_lexer.append(token_fwd); | ||||
| 				src_lexer.append(token_typedef); | ||||
|  | ||||
| 				// Skip typedef since we added it | ||||
| 				b32 continue_for = true; | ||||
| 				for (Code array_entry = array_token.begin(); continue_for && array_entry != array_token.end(); ++ array_entry) switch (array_entry->Type) | ||||
| 				{ | ||||
| 					case CT_Typedef: | ||||
| 					{ | ||||
| 						// pop the array entry | ||||
| 						array_token->NumEntries -= 1; | ||||
| 						Code next                   = array_entry->Next; | ||||
| 						Code prev                   = array_entry->Prev; | ||||
| 						next->Prev                  = array_entry->Prev; | ||||
| 						prev->Next                  = next; | ||||
| 						if ( array_token->Front == array_entry ) | ||||
| 							array_token->Front = next; | ||||
|  | ||||
| 						src_lexer.append(array_entry); | ||||
| 						continue_for = false; | ||||
| 					} | ||||
| 					break; | ||||
| 				} | ||||
|  | ||||
| 				// Append the struct | ||||
| 				src_lexer.append(entry); | ||||
|  | ||||
| 				// Append the token array | ||||
| 				src_lexer.append(array_token); | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			CodeTypedef struct_tdef = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct <name> <name>; ))); | ||||
| 			src_lexer.append(entry); | ||||
| 			src_lexer.append(struct_tdef); | ||||
| 		} | ||||
| 		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: | ||||
| 			src_lexer.append(entry); | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	CodeBody parsed_src_parser = parse_file( project_dir "components/parser.cpp" ); | ||||
| 	CodeBody src_parser        = def_body(CT_Global_Body); | ||||
| 	for ( Code entry = parsed_src_parser.begin(); entry != parsed_src_parser.end(); ++ entry ) switch( entry ->Type ) | ||||
| 	{ | ||||
| 		case CT_Preprocess_IfDef: | ||||
| 		{ | ||||
| 			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_src_parser, src_parser ); | ||||
| 			if (found) break; | ||||
|  | ||||
| 			src_parser.append(entry); | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Struct: | ||||
| 		{ | ||||
| 			CodeTypedef tdef = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct <name> <name>; ))); | ||||
| 			src_parser.append(entry); | ||||
| 			src_parser.append(tdef); | ||||
| 		} | ||||
|  | ||||
| 		default: | ||||
| 			src_parser.append(entry); | ||||
| 		break; | ||||
| 	} | ||||
| #pragma endregion Resolve Components | ||||
|  | ||||
| 	// THERE SHOULD BE NO NEW GENERIC CONTAINER DEFINTIONS PAST THIS POINT (It will not have slots for the generic selection generated macros) | ||||
| @@ -930,7 +1419,7 @@ R"(#define AST_ArrSpecs_Cap \ | ||||
| 		header.print( format_code_to_untyped(interface) ); | ||||
|  | ||||
| 		header.print_fmt("#pragma region Inlines\n"); | ||||
| 		header.print( inlines ); | ||||
| 		header.print( format_code_to_untyped(inlines) ); | ||||
| 		header.print_fmt("#pragma endregion Inlines\n"); | ||||
|  | ||||
| 		header.print(fmt_newline); | ||||
| @@ -972,7 +1461,7 @@ R"(#define AST_ArrSpecs_Cap \ | ||||
| 	#pragma endregion Print Dependencies | ||||
|  | ||||
| 	#pragma region Print Components | ||||
| 		CodeBody etoktype = gen_etoktype( project_dir "enums/ETokType.csv", project_dir "enums/AttributeTokens.csv" ); | ||||
| 		CodeBody etoktype = gen_etoktype( project_dir "enums/ETokType.csv", project_dir "enums/AttributeTokens.csv", helper_use_c_definition ); | ||||
|  | ||||
| 		header.print_fmt( "\nGEN_NS_BEGIN\n"); | ||||
|  | ||||
| @@ -989,15 +1478,15 @@ R"(#define AST_ArrSpecs_Cap \ | ||||
| 		header.print( src_code_serialization ); | ||||
| 		header.print_fmt( "#pragma endregion AST\n\n" ); | ||||
|  | ||||
| 		 header.print_fmt( "#pragma region Interface\n" ); | ||||
| 		 header.print( src_interface ); | ||||
| 		// header.print( src_upfront ); | ||||
| 		// header.print_fmt( "\n#pragma region Parsing\n\n" ); | ||||
| 		// header.print( format_code_to_untyped(parser_nspace) ); | ||||
| 		// header.print( lexer ); | ||||
| 		// header.print( parser ); | ||||
| 		header.print_fmt( "#pragma region Interface\n" ); | ||||
| 		header.print( src_interface ); | ||||
| 		header.print( format_code_to_untyped(src_upfront) ); | ||||
| 		header.print_fmt( "\n#pragma region Parsing\n\n" ); | ||||
| 		header.print( format_code_to_untyped(etoktype) ); | ||||
| 		header.print( format_code_to_untyped(src_lexer) ); | ||||
| 		header.print( format_code_to_untyped(src_parser) ); | ||||
| 		// 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_fmt( "\n#pragma endregion Interface\n\n"); | ||||
|  | ||||
|   | ||||
| @@ -23,7 +23,22 @@ CodeBody gen_array_base() | ||||
| 	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")); | ||||
|  | ||||
| 	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 ) | ||||
|   | ||||
| @@ -9,12 +9,12 @@ CodeBody gen_fixed_arenas() | ||||
| 	result.append(def_pragma(txt("region FixedArena"))); | ||||
|  | ||||
| 	char const* template_struct = stringize( | ||||
| 		struct FixedArena_<Name>_Def | ||||
| 		struct FixedArena_<Name> | ||||
| 		{ | ||||
| 			char  memory[<Size>]; | ||||
| 			Arena arena; | ||||
| 		}; | ||||
| 		typedef struct FixedArena_<Name>_Def FixedArena_<Name>; | ||||
| 		typedef struct FixedArena_<Name> FixedArena_<Name>; | ||||
| 	); | ||||
|  | ||||
| 	char const* template_interface = stringize( | ||||
| @@ -89,19 +89,20 @@ CodeBody gen_fixed_arenas() | ||||
| 	result.append(fmt_newline); | ||||
|  | ||||
| 	result.append(parse_global_body(txt(R"( | ||||
| #define fixed_arena_init(expr) _Generic((expr), \ | ||||
|     FixedArena_1KB*   : fixed_arena_init_1KB,   \ | ||||
|     FixedArena_4KB*   : fixed_arena_init_4KB,   \ | ||||
|     FixedArena_8KB*   : fixed_arena_init_8KB,   \ | ||||
|     FixedArena_16KB*  : fixed_arena_init_16KB,  \ | ||||
|     FixedArena_32KB*  : fixed_arena_init_32KB,  \ | ||||
|     FixedArena_64KB*  : fixed_arena_init_64KB,  \ | ||||
|     FixedArena_128KB* : fixed_arena_init_128KB, \ | ||||
|     FixedArena_256KB* : fixed_arena_init_256KB, \ | ||||
|     FixedArena_512KB* : fixed_arena_init_512KB, \ | ||||
|     FixedArena_1MB*   : fixed_arena_init_1MB,   \ | ||||
|     FixedArena_2MB*   : fixed_arena_init_2MB,   \ | ||||
|     FixedArena_4MB*   : fixed_arena_init_4MB    \ | ||||
| #define fixed_arena_init(expr) _Generic((expr),    \ | ||||
|     FixedArena_1KB*   : fixed_arena_init_1KB,      \ | ||||
|     FixedArena_4KB*   : fixed_arena_init_4KB,      \ | ||||
|     FixedArena_8KB*   : fixed_arena_init_8KB,      \ | ||||
|     FixedArena_16KB*  : fixed_arena_init_16KB,     \ | ||||
|     FixedArena_32KB*  : fixed_arena_init_32KB,     \ | ||||
|     FixedArena_64KB*  : fixed_arena_init_64KB,     \ | ||||
|     FixedArena_128KB* : fixed_arena_init_128KB,    \ | ||||
|     FixedArena_256KB* : fixed_arena_init_256KB,    \ | ||||
|     FixedArena_512KB* : fixed_arena_init_512KB,    \ | ||||
|     FixedArena_1MB*   : fixed_arena_init_1MB,      \ | ||||
|     FixedArena_2MB*   : fixed_arena_init_2MB,      \ | ||||
|     FixedArena_4MB*   : fixed_arena_init_4MB,      \ | ||||
| 	default           : gen_generic_selection_fail \ | ||||
| ) GEN_RESOLVED_FUNCTION_CALL(& expr) | ||||
|  | ||||
| #define fixed_arena_size_remaining(expr, alignment) _Generic((expr), \ | ||||
| @@ -116,7 +117,8 @@ CodeBody gen_fixed_arenas() | ||||
|     FixedArena_512KB* : fixed_arena_size_remaining_512KB,            \ | ||||
|     FixedArena_1MB*   : fixed_arena_size_remaining_1MB,              \ | ||||
|     FixedArena_2MB*   : fixed_arena_size_remaining_2MB,              \ | ||||
|     FixedArena_4MB*   : fixed_arena_size_remaining_4MB               \ | ||||
|     FixedArena_4MB*   : fixed_arena_size_remaining_4MB,              \ | ||||
| 	default           : gen_generic_selection_fail                   \ | ||||
| )	GEN_RESOLVED_FUNCTION_CALL(& expr, alignment) | ||||
| )" | ||||
| 	))); | ||||
|   | ||||
| @@ -246,9 +246,7 @@ int gen_main() | ||||
| 		CodeBody etoktype         = gen_etoktype( "enums/ETokType.csv", "enums/AttributeTokens.csv" ); | ||||
| 		//CodeNS   nspaced_etoktype = def_namespace( name(parser), def_namespace_body( args(etoktype)) ); | ||||
| 		CodeBody nspaced_etoktype = def_global_body( args( | ||||
| 			untyped_str(txt("GEN_NS_PARSER_BEGIN\n")), | ||||
| 			etoktype, | ||||
| 			untyped_str(txt("GEN_NS_PARSER_END\n")) | ||||
| 			etoktype | ||||
| 		)); | ||||
|  | ||||
| 		Builder | ||||
|   | ||||
| @@ -402,7 +402,7 @@ static_assert( sizeof(AST) == AST_POD_Size, "ERROR: AST is not size of AST_POD_S | ||||
| struct  InvalidCode_ImplictCaster; | ||||
| #define InvalidCode (InvalidCode_ImplictCaster{}) | ||||
| #else | ||||
| #define InvalidCode { (void*)Code_Invalid } | ||||
| #define InvalidCode (void*){ (void*)Code_Invalid } | ||||
| #endif | ||||
|  | ||||
| #if GEN_COMPILER_CPP | ||||
|   | ||||
| @@ -197,6 +197,9 @@ struct CodeParam | ||||
| 	forceinline bool      has_entries(); | ||||
| 	forceinline String    to_string(); | ||||
| 	forceinline void      to_string( String& result ); | ||||
|  | ||||
| 	forceinline CodeParam begin() { return begin_CodeParam(* this); } | ||||
| 	forceinline CodeParam end()   { return end_CodeParam(* this); } | ||||
| #endif | ||||
| 	Using_CodeOps( CodeParam ); | ||||
| 	forceinline operator Code()       { return { (AST*)ast }; } | ||||
|   | ||||
| @@ -6,9 +6,10 @@ | ||||
| // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) | ||||
|  | ||||
| GEN_NS_PARSER_BEGIN | ||||
|  | ||||
| #define GEN_DEFINE_ATTRIBUTE_TOKENS Entry( Tok_Attribute_API_Export, "GEN_API_Export_Code" ) Entry( Tok_Attribute_API_Import, "GEN_API_Import_Code" ) | ||||
|  | ||||
| enum TokType_Def : u32 | ||||
| enum TokType : u32 | ||||
| { | ||||
| 	Tok_Invalid, | ||||
| 	Tok_Access_Private, | ||||
| @@ -109,11 +110,10 @@ enum TokType_Def : u32 | ||||
| 	Tok_Attribute_API_Import, | ||||
| 	Tok_NumTokens | ||||
| }; | ||||
| typedef enum TokType_Def TokType; | ||||
|  | ||||
| inline StrC to_str( TokType type ) | ||||
| inline StrC toktype_to_str( TokType type ) | ||||
| { | ||||
| 	local_persist StrC lookup[] { | ||||
| 	local_persist StrC lookup[] = { | ||||
| 		{ sizeof( "__invalid__" ),         "__invalid__"         }, | ||||
| 		{ sizeof( "private" ),             "private"             }, | ||||
| 		{ sizeof( "protected" ),           "protected"           }, | ||||
| @@ -215,12 +215,12 @@ inline StrC to_str( TokType type ) | ||||
| 	return lookup[type]; | ||||
| } | ||||
|  | ||||
| inline TokType to_toktype( StrC str ) | ||||
| inline TokType strc_to_toktype( StrC str ) | ||||
| { | ||||
| 	local_persist u32 keymap[Tok_NumTokens]; | ||||
| 	do_once_start for ( u32 index = 0; index < Tok_NumTokens; index++ ) | ||||
| 	{ | ||||
| 		StrC enum_str = to_str( (TokType)index ); | ||||
| 		StrC enum_str = toktype_to_str( (TokType)index ); | ||||
| 		keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1 ); | ||||
| 	} | ||||
| 	do_once_end u32 hash = crc32( str.Ptr, str.Len ); | ||||
|   | ||||
| @@ -4,8 +4,8 @@ | ||||
| #endif | ||||
|  | ||||
| GEN_NS_PARSER_BEGIN | ||||
| internal void init(); | ||||
| internal void deinit(); | ||||
| internal void parser_init(); | ||||
| internal void parser_deinit(); | ||||
| GEN_NS_PARSER_END | ||||
|  | ||||
| internal | ||||
| @@ -148,9 +148,8 @@ void define_constants() | ||||
| #	define def_constant_code_type( Type_ )           \ | ||||
| 		do                                           \ | ||||
| 		{                                            \ | ||||
| 		    Opts_def_type ops = {};                  \ | ||||
| 			StrC name_str = name(Type_);             \ | ||||
| 			t_##Type_ = def_type( name_str, ops );   \ | ||||
| 			t_##Type_ = def_type( name_str );        \ | ||||
| 			code_set_global( cast(Code, t_##Type_)); \ | ||||
| 		} while(0) | ||||
|  | ||||
| @@ -323,7 +322,7 @@ void init() | ||||
| 	PreprocessorDefines = array_init_reserve(StringCached, GlobalAllocator, kilobytes(1) ); | ||||
|  | ||||
| 	define_constants(); | ||||
| 	GEN_NS_PARSER init(); | ||||
| 	GEN_NS_PARSER parser_init(); | ||||
| } | ||||
|  | ||||
| void deinit() | ||||
| @@ -368,7 +367,7 @@ void deinit() | ||||
| 	while ( left--, left ); | ||||
|  | ||||
| 	array_free(Global_AllocatorBuckets); | ||||
| 	GEN_NS_PARSER deinit(); | ||||
| 	GEN_NS_PARSER parser_deinit(); | ||||
| } | ||||
|  | ||||
| void reset() | ||||
|   | ||||
| @@ -16,7 +16,6 @@ | ||||
| */ | ||||
|  | ||||
| // Initialize the library. | ||||
| // This currently just initializes the CodePool. | ||||
| void init(); | ||||
|  | ||||
| // Currently manually free's the arenas, code for checking for leaks. | ||||
| @@ -53,13 +52,13 @@ CodeAttributes def_attributes( StrC content ); | ||||
| CodeComment    def_comment   ( StrC content ); | ||||
|  | ||||
| struct Opts_def_struct { | ||||
| 	Code           body; | ||||
| 	CodeBody       body; | ||||
| 	CodeTypename   parent; | ||||
| 	AccessSpec     parent_access; | ||||
| 	CodeAttributes attributes; | ||||
| 	ModuleFlag     mflags; | ||||
| 	CodeTypename*  interfaces; | ||||
| 	s32            num_interfaces; | ||||
| 	ModuleFlag     mflags; | ||||
| }; | ||||
| CodeClass def_class( StrC name, Opts_def_struct otps GEN_PARAM_DEFAULT ); | ||||
|  | ||||
| @@ -79,7 +78,7 @@ struct Opts_def_destructor { | ||||
| CodeDestructor def_destructor( Opts_def_destructor opts GEN_PARAM_DEFAULT ); | ||||
|  | ||||
| struct Opts_def_enum { | ||||
| 	Code           body; | ||||
| 	CodeBody       body; | ||||
| 	CodeTypename   type; | ||||
| 	EnumT          specifier; | ||||
| 	CodeAttributes attributes; | ||||
| @@ -88,13 +87,13 @@ struct Opts_def_enum { | ||||
| CodeEnum def_enum( StrC name, Opts_def_enum opts GEN_PARAM_DEFAULT ); | ||||
|  | ||||
| CodeExec   def_execution  ( StrC content ); | ||||
| CodeExtern def_extern_link( StrC name, Code body ); | ||||
| CodeExtern def_extern_link( StrC name, CodeBody body ); | ||||
| CodeFriend def_friend     ( Code symbol ); | ||||
|  | ||||
| struct Opts_def_function { | ||||
| 	CodeParam       params; | ||||
| 	CodeTypename    ret_type; | ||||
| 	Code            body; | ||||
| 	CodeBody        body; | ||||
| 	CodeSpecifiers  specs; | ||||
| 	CodeAttributes  attrs; | ||||
| 	ModuleFlag      mflags; | ||||
| @@ -104,14 +103,14 @@ CodeFn def_function( StrC name, Opts_def_function opts GEN_PARAM_DEFAULT ); | ||||
| struct Opts_def_include   { b32        foreign; }; | ||||
| struct Opts_def_module    { ModuleFlag mflags;  }; | ||||
| struct Opts_def_namespace { ModuleFlag mflags;  }; | ||||
| CodeInclude def_include  ( StrC content,         Opts_def_include   opts GEN_PARAM_DEFAULT ); | ||||
| CodeModule  def_module   ( StrC name,            Opts_def_module    opts GEN_PARAM_DEFAULT ); | ||||
| CodeNS      def_namespace( StrC name, Code body, Opts_def_namespace opts GEN_PARAM_DEFAULT ); | ||||
| CodeInclude def_include  ( StrC content,             Opts_def_include   opts GEN_PARAM_DEFAULT ); | ||||
| CodeModule  def_module   ( StrC name,                Opts_def_module    opts GEN_PARAM_DEFAULT ); | ||||
| CodeNS      def_namespace( StrC name, CodeBody body, Opts_def_namespace opts GEN_PARAM_DEFAULT ); | ||||
|  | ||||
| struct Opts_def_operator { | ||||
| 	CodeParam       params; | ||||
| 	CodeTypename    ret_type; | ||||
| 	Code            body; | ||||
| 	CodeBody        body; | ||||
| 	CodeSpecifiers  specifiers; | ||||
| 	CodeAttributes  attributes; | ||||
| 	ModuleFlag      mflags; | ||||
| @@ -119,7 +118,7 @@ struct Opts_def_operator { | ||||
| CodeOperator def_operator( Operator op, StrC nspace, Opts_def_operator opts GEN_PARAM_DEFAULT ); | ||||
|  | ||||
| struct Opts_def_operator_cast { | ||||
| 	Code           body; | ||||
| 	CodeBody       body; | ||||
| 	CodeSpecifiers specs; | ||||
| }; | ||||
| CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast opts GEN_PARAM_DEFAULT ); | ||||
| @@ -155,13 +154,13 @@ struct Opts_def_union { | ||||
| 	CodeAttributes attributes; | ||||
| 	ModuleFlag     mflags; | ||||
| }; | ||||
| CodeUnion def_union( StrC name, Code body, Opts_def_union opts GEN_PARAM_DEFAULT ); | ||||
| CodeUnion def_union( StrC name, CodeBody body, Opts_def_union opts GEN_PARAM_DEFAULT ); | ||||
|  | ||||
| struct Opts_def_using { | ||||
| 	CodeAttributes attributes; | ||||
| 	ModuleFlag     mflags; | ||||
| }; | ||||
| CodeUsing def_using( StrC name, Code type, Opts_def_using opts GEN_PARAM_DEFAULT ); | ||||
| CodeUsing def_using( StrC name, CodeTypename type, Opts_def_using opts GEN_PARAM_DEFAULT ); | ||||
|  | ||||
| CodeUsing def_using_namespace( StrC name ); | ||||
|  | ||||
|   | ||||
| @@ -12,7 +12,7 @@ CodeClass parse_class( StrC def ) | ||||
| { | ||||
| 	GEN_USING_NS_PARSER; | ||||
| 	check_parse_args( def ); | ||||
| 	 | ||||
|  | ||||
| 	TokArray toks = lex( def ); | ||||
| 	if ( toks.Arr == nullptr ) | ||||
| 		return InvalidCode; | ||||
| @@ -20,7 +20,7 @@ CodeClass parse_class( StrC def ) | ||||
| 	Context.Tokens = toks; | ||||
| 	push_scope(); | ||||
| 	CodeClass result = (CodeClass) parse_class_struct( Tok_Decl_Class ); | ||||
| 	pop(& Context); | ||||
| 	parser_pop(& Context); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| @@ -39,9 +39,9 @@ CodeConstructor parse_constructor( StrC def ) | ||||
| 	Specifier      specs_found[ 16 ] { Spec_NumSpecifiers }; | ||||
| 	s32            NumSpecifiers = 0; | ||||
|  | ||||
| 	while ( left && is_specifier(currtok) ) | ||||
| 	while ( left && tok_is_specifier(currtok) ) | ||||
| 	{ | ||||
| 		Specifier spec = strc_to_specifier( to_str(currtok) ); | ||||
| 		Specifier spec = strc_to_specifier( tok_to_str(currtok) ); | ||||
|  | ||||
| 		b32 ignore_spec = false; | ||||
|  | ||||
| @@ -59,8 +59,8 @@ CodeConstructor parse_constructor( StrC def ) | ||||
| 				break; | ||||
|  | ||||
| 			default : | ||||
| 				log_failure( "Invalid specifier %s for variable\n%s", spec_to_str( spec ), to_string(Context) ); | ||||
| 				pop(& Context); | ||||
| 				log_failure( "Invalid specifier %s for variable\n%s", spec_to_str( spec ), parser_to_string(Context) ); | ||||
| 				parser_pop(& Context); | ||||
| 				return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| @@ -109,12 +109,12 @@ CodeEnum parse_enum( StrC def ) | ||||
| 	TokArray toks = lex( def ); | ||||
| 	if ( toks.Arr == nullptr ) | ||||
| 	{ | ||||
| 		pop(& Context); | ||||
| 		parser_pop(& Context); | ||||
| 		return InvalidCode; | ||||
| 	} | ||||
|  | ||||
| 	Context.Tokens = toks; | ||||
| 	return parse_enum(); | ||||
| 	return parse_enum( parser_not_inplace_def); | ||||
| } | ||||
|  | ||||
| CodeBody parse_export_body( StrC def ) | ||||
| @@ -181,7 +181,7 @@ CodeBody parse_global_body( StrC def ) | ||||
| 	Context.Tokens = toks; | ||||
| 	push_scope(); | ||||
| 	CodeBody result = parse_global_nspace( CT_Global_Body ); | ||||
| 	pop(& Context); | ||||
| 	parser_pop(& Context); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| @@ -236,7 +236,7 @@ CodeStruct parse_struct( StrC def ) | ||||
| 	Context.Tokens = toks; | ||||
| 	push_scope(); | ||||
| 	CodeStruct result = (CodeStruct) parse_class_struct( Tok_Decl_Struct ); | ||||
| 	pop(& Context); | ||||
| 	parser_pop(& Context); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| @@ -263,7 +263,7 @@ CodeTypename parse_type( StrC def ) | ||||
| 		return InvalidCode; | ||||
|  | ||||
| 	Context.Tokens = toks; | ||||
| 	return parse_type(); | ||||
| 	return parse_type( parser_not_from_template, nullptr); | ||||
| } | ||||
|  | ||||
| CodeTypedef parse_typedef( StrC def ) | ||||
| @@ -289,7 +289,7 @@ CodeUnion parse_union( StrC def ) | ||||
| 		return InvalidCode; | ||||
|  | ||||
| 	Context.Tokens = toks; | ||||
| 	return parse_union(); | ||||
| 	return parse_union( parser_not_inplace_def); | ||||
| } | ||||
|  | ||||
| CodeUsing parse_using( StrC def ) | ||||
|   | ||||
| @@ -482,10 +482,12 @@ CodeComment def_comment( StrC content ) | ||||
| 	if ( * string_back(cmt_formatted) != '\n' ) | ||||
| 		string_append_strc( & cmt_formatted, txt("\n") ); | ||||
|  | ||||
| 	StrC name = { string_length(cmt_formatted), cmt_formatted }; | ||||
|  | ||||
| 	Code | ||||
| 	result          = make_code(); | ||||
| 	result->Type    = CT_Comment; | ||||
| 	result->Name    = get_cached_string( { string_length(cmt_formatted), cmt_formatted } ); | ||||
| 	result->Name    = get_cached_string( name ); | ||||
| 	result->Content = result->Name; | ||||
|  | ||||
| 	string_free(& cmt_formatted); | ||||
| @@ -546,7 +548,7 @@ CodeClass def_class( StrC name, Opts_def_struct p ) | ||||
| { | ||||
| 	name_check( def_class, name ); | ||||
|  | ||||
| 	Code           body           = p.body; | ||||
| 	CodeBody       body           = p.body; | ||||
| 	CodeTypename   parent         = p.parent; | ||||
| 	AccessSpec     parent_access  = p.parent_access; | ||||
| 	CodeAttributes attributes     = p.attributes; | ||||
| @@ -586,7 +588,7 @@ CodeClass def_class( StrC name, Opts_def_struct p ) | ||||
|  | ||||
| 		result->Type = CT_Class; | ||||
| 		result->Body = body; | ||||
| 		result->Body->Parent = result; // TODO(Ed): Review this? | ||||
| 		result->Body->Parent = cast(Code, result); // TODO(Ed): Review this? | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| @@ -682,7 +684,7 @@ CodeDestructor def_destructor( Opts_def_destructor p ) | ||||
|  | ||||
| CodeEnum def_enum( StrC name, Opts_def_enum p ) | ||||
| { | ||||
| 	Code           body       = p.body; | ||||
| 	CodeBody       body       = p.body; | ||||
| 	CodeTypename   type       = p.type; | ||||
| 	EnumT          specifier  = p.specifier; | ||||
| 	CodeAttributes attributes = p.attributes; | ||||
| @@ -764,7 +766,7 @@ CodeExec def_execution( StrC content ) | ||||
| 	return (CodeExec) result; | ||||
| } | ||||
|  | ||||
| CodeExtern def_extern_link( StrC name, Code body ) | ||||
| CodeExtern def_extern_link( StrC name, CodeBody body ) | ||||
| { | ||||
| 	name_check( def_extern_linkage, name ); | ||||
| 	null_check( def_extern_linkage, body ); | ||||
| @@ -818,7 +820,7 @@ CodeFn def_function( StrC name, Opts_def_function p ) | ||||
| { | ||||
| 	CodeParam       params     = p.params; | ||||
| 	CodeTypename    ret_type   = p.ret_type; | ||||
| 	Code            body       = p.body; | ||||
| 	CodeBody        body       = p.body; | ||||
| 	CodeSpecifiers  specifiers = p.specs; | ||||
| 	CodeAttributes  attributes = p.attrs; | ||||
| 	ModuleFlag      mflags     = p.mflags; | ||||
| @@ -934,7 +936,7 @@ CodeModule def_module( StrC name, Opts_def_module p ) | ||||
| 	return (CodeModule) result; | ||||
| } | ||||
|  | ||||
| CodeNS def_namespace( StrC name, Code body, Opts_def_namespace p ) | ||||
| CodeNS def_namespace( StrC name, CodeBody body, Opts_def_namespace p ) | ||||
| { | ||||
| 	name_check( def_namespace, name ); | ||||
| 	null_check( def_namespace, body); | ||||
| @@ -958,7 +960,7 @@ CodeOperator def_operator( Operator op, StrC nspace, Opts_def_operator p ) | ||||
| { | ||||
| 	CodeParam       params_code = p.params; | ||||
| 	CodeTypename    ret_type    = p.ret_type; | ||||
| 	Code            body        = p.body; | ||||
| 	CodeBody        body        = p.body; | ||||
| 	CodeSpecifiers  specifiers  = p.specifiers; | ||||
| 	CodeAttributes  attributes  = p.attributes; | ||||
| 	ModuleFlag      mflags      = p.mflags; | ||||
| @@ -989,9 +991,12 @@ CodeOperator def_operator( Operator op, StrC nspace, Opts_def_operator p ) | ||||
| 		name = str_fmt_buf( "%.*soperator %.*s", nspace.Len, nspace.Ptr, op_str.Len, op_str.Ptr ); | ||||
| 	else | ||||
| 		name = str_fmt_buf( "operator %.*s", op_str.Len, op_str.Ptr ); | ||||
|  | ||||
| 	StrC name_resolved = { str_len(name), name }; | ||||
|  | ||||
| 	CodeOperator | ||||
| 	result              = (CodeOperator) make_code(); | ||||
| 	result->Name        = get_cached_string( { str_len(name), name } ); | ||||
| 	result->Name        = get_cached_string( name_resolved ); | ||||
| 	result->ModuleFlags = mflags; | ||||
| 	result->Op          = op; | ||||
|  | ||||
| @@ -1038,7 +1043,7 @@ CodeOperator def_operator( Operator op, StrC nspace, Opts_def_operator p ) | ||||
|  | ||||
| CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast p ) | ||||
| { | ||||
| 	Code           body       = p.body; | ||||
| 	CodeBody       body       = p.body; | ||||
| 	CodeSpecifiers const_spec = p.specs; | ||||
|  | ||||
| 	null_check( def_operator_cast, type ); | ||||
| @@ -1168,7 +1173,7 @@ CodeSpecifiers def_specifier( Specifier spec ) | ||||
|  | ||||
| CodeStruct def_struct( StrC name, Opts_def_struct p ) | ||||
| { | ||||
| 	Code           body           = p.body; | ||||
| 	CodeBody       body           = p.body; | ||||
| 	CodeTypename   parent         = p.parent; | ||||
| 	AccessSpec     parent_access  = p.parent_access; | ||||
| 	CodeAttributes attributes     = p.attributes; | ||||
| @@ -1198,7 +1203,7 @@ CodeStruct def_struct( StrC name, Opts_def_struct p ) | ||||
| 	result              = (CodeStruct) make_code(); | ||||
| 	result->ModuleFlags = mflags; | ||||
|  | ||||
| 	if ( name ) | ||||
| 	if ( name.Len ) | ||||
| 		result->Name = get_cached_string( name ); | ||||
|  | ||||
| 	if ( body ) | ||||
| @@ -1338,7 +1343,7 @@ CodeTypedef def_typedef( StrC name, Code type, Opts_def_typedef p ) | ||||
| 	} | ||||
|  | ||||
| 	// Registering the type. | ||||
| 	Code registered_type = def_type( name ); | ||||
| 	CodeTypename registered_type = def_type( name ); | ||||
|  | ||||
| 	if ( ! registered_type ) | ||||
| 	{ | ||||
| @@ -1373,7 +1378,7 @@ CodeTypedef def_typedef( StrC name, Code type, Opts_def_typedef p ) | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| CodeUnion def_union( StrC name, Code body, Opts_def_union p ) | ||||
| CodeUnion def_union( StrC name, CodeBody body, Opts_def_union p ) | ||||
| { | ||||
| 	null_check( def_union, body ); | ||||
|  | ||||
| @@ -1405,12 +1410,12 @@ CodeUnion def_union( StrC name, Code body, Opts_def_union p ) | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| CodeUsing def_using( StrC name, Code type, Opts_def_using p ) | ||||
| CodeUsing def_using( StrC name, CodeTypename type, Opts_def_using p ) | ||||
| { | ||||
| 	name_check( def_using, name ); | ||||
| 	null_check( def_using, type ); | ||||
|  | ||||
| 	Code register_type = def_type( name ); | ||||
| 	CodeTypename register_type = def_type( name ); | ||||
|  | ||||
| 	if ( ! register_type ) | ||||
| 	{ | ||||
| @@ -1451,7 +1456,7 @@ CodeUsing def_using_namespace( StrC name ) | ||||
| 	return (CodeUsing) result; | ||||
| } | ||||
|  | ||||
| CodeVar def_variable( CodeTypename type, StrC name, Code value, Opts_def_variable p ) | ||||
| CodeVar def_variable( CodeTypename type, StrC name, Opts_def_variable p ) | ||||
| { | ||||
| 	name_check( def_variable, name ); | ||||
| 	null_check( def_variable, type ); | ||||
| @@ -1474,9 +1479,9 @@ CodeVar def_variable( CodeTypename type, StrC name, Code value, Opts_def_variabl | ||||
| 		return InvalidCode; | ||||
| 	} | ||||
|  | ||||
| 	if ( value && value->Type != CT_Untyped ) | ||||
| 	if ( p.value && p.value->Type != CT_Untyped ) | ||||
| 	{ | ||||
| 		log_failure( "gen::def_variable: value was not a `Untyped` type - %s", code_debug_str(value) ); | ||||
| 		log_failure( "gen::def_variable: value was not a `Untyped` type - %s", code_debug_str(p.value) ); | ||||
| 		return InvalidCode; | ||||
| 	} | ||||
|  | ||||
| @@ -1494,8 +1499,8 @@ CodeVar def_variable( CodeTypename type, StrC name, Code value, Opts_def_variabl | ||||
| 	if ( p.specifiers ) | ||||
| 		result->Specs = p.specifiers; | ||||
|  | ||||
| 	if ( value ) | ||||
| 		result->Value = value; | ||||
| 	if ( p.value ) | ||||
| 		result->Value = p.value; | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
| @@ -1915,7 +1920,7 @@ CodeBody def_global_body( s32 num, ... ) | ||||
| 		{ | ||||
| 			case CT_Global_Body: | ||||
| 				// result.body_append( entry.code_cast<CodeBody>() ) ; | ||||
| 				body_append( result, cast(CodeBody, entry) ); | ||||
| 				body_append_body( result, cast(CodeBody, entry) ); | ||||
| 				continue; | ||||
|  | ||||
| 			GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES | ||||
| @@ -1956,7 +1961,7 @@ CodeBody def_global_body( s32 num, Code* codes ) | ||||
| 		switch (entry->Type) | ||||
| 		{ | ||||
| 			case CT_Global_Body: | ||||
| 				body_append(result, cast(CodeBody, entry) ); | ||||
| 				body_append_body(result, cast(CodeBody, entry) ); | ||||
| 				continue; | ||||
|  | ||||
| 			GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES | ||||
| @@ -2090,21 +2095,21 @@ CodeParam def_params( s32 num, CodeParam* codes ) | ||||
| { | ||||
| 	def_body_code_array_start( def_params ); | ||||
|  | ||||
| #	define check_current()                                                                                      \ | ||||
| 	if ( current.ast == nullptr )                                                                               \ | ||||
| 	{                                                                                                           \ | ||||
| 		log_failure("gen::def_params: Provide a null code in codes array");                                     \ | ||||
| 		return InvalidCode;                                                                                     \ | ||||
| 	}                                                                                                           \ | ||||
| 																												\ | ||||
| 	if (current->Type != CT_Parameters )                                                                        \ | ||||
| 	{                                                                                                           \ | ||||
| 		log_failure("gen::def_params: Code in coes array is not of paramter type - %s", code_debug_str(current) );   \ | ||||
| 		return InvalidCode;                                                                                     \ | ||||
| #	define check_current(current)                                                                                      \ | ||||
| 	if ( current == nullptr )                                                                                          \ | ||||
| 	{                                                                                                                  \ | ||||
| 		log_failure("gen::def_params: Provide a null code in codes array");                                            \ | ||||
| 		return InvalidCode;                                                                                            \ | ||||
| 	}                                                                                                                  \ | ||||
| 																												       \ | ||||
| 	if (current->Type != CT_Parameters )                                                                               \ | ||||
| 	{                                                                                                                  \ | ||||
| 		log_failure("gen::def_params: Code in coes array is not of paramter type - %s", code_debug_str(current) );     \ | ||||
| 		return InvalidCode;                                                                                            \ | ||||
| 	} | ||||
|  | ||||
| 	CodeParam current = (CodeParam)code_duplicate(* codes); | ||||
| 	check_current(); | ||||
| 	check_current(current); | ||||
|  | ||||
| 	CodeParam | ||||
| 	result            = (CodeParam) make_code(); | ||||
| @@ -2114,7 +2119,7 @@ CodeParam def_params( s32 num, CodeParam* codes ) | ||||
|  | ||||
| 	while( codes++, current = * codes, num--, num > 0 ) | ||||
| 	{ | ||||
| 		check_current(); | ||||
| 		check_current(current); | ||||
| 		params_append(result, current ); | ||||
| 	} | ||||
| #	undef check_current | ||||
| @@ -2293,7 +2298,7 @@ CodeBody def_union_body( s32 num, ... ) | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| CodeBody def_union_body( s32 num, CodeUnion* codes ) | ||||
| CodeBody def_union_body( s32 num, Code* codes ) | ||||
| { | ||||
| 	def_body_code_array_start( def_union_body ); | ||||
|  | ||||
|   | ||||
| @@ -21,6 +21,7 @@ enum TokFlags : u32 | ||||
| 	TF_Literal         = bit( 12 ), | ||||
|  | ||||
| 	TF_Null = 0, | ||||
| 	TF_UnderlyingType = GEN_U32_MAX, | ||||
| }; | ||||
|  | ||||
| struct Token | ||||
| @@ -35,66 +36,67 @@ struct Token | ||||
|  | ||||
| constexpr Token NullToken { nullptr, 0, Tok_Invalid, false, 0, TF_Null }; | ||||
|  | ||||
| AccessSpec to_access_specifier(Token tok) | ||||
| AccessSpec tok_to_access_specifier(Token tok) | ||||
| { | ||||
| 	return scast(AccessSpec, tok.Type); | ||||
| } | ||||
|  | ||||
| StrC to_str(Token tok) | ||||
| StrC tok_to_str(Token tok) | ||||
| { | ||||
| 	return { tok.Length, tok.Text }; | ||||
| 	StrC str = { tok.Length, tok.Text }; | ||||
| 	return str; | ||||
| } | ||||
|  | ||||
| bool is_valid( Token tok ) | ||||
| bool tok_is_valid( Token tok ) | ||||
| { | ||||
| 	return tok.Text && tok.Length && tok.Type != Tok_Invalid; | ||||
| } | ||||
|  | ||||
| bool is_access_operator(Token tok) | ||||
| bool tok_is_access_operator(Token tok) | ||||
| { | ||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_AccessOperator ); | ||||
| } | ||||
|  | ||||
| bool is_access_specifier(Token tok) | ||||
| bool tok_is_access_specifier(Token tok) | ||||
| { | ||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_AccessSpecifier ); | ||||
| } | ||||
|  | ||||
| bool is_attribute(Token tok) | ||||
| bool tok_is_attribute(Token tok) | ||||
| { | ||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_Attribute ); | ||||
| } | ||||
|  | ||||
| bool is_operator(Token tok) | ||||
| bool tok_is_operator(Token tok) | ||||
| { | ||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_Operator ); | ||||
| } | ||||
|  | ||||
| bool is_preprocessor(Token tok) | ||||
| bool tok_is_preprocessor(Token tok) | ||||
| { | ||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_Preprocess ); | ||||
| } | ||||
|  | ||||
| bool is_preprocess_cond(Token tok) | ||||
| bool tok_is_preprocess_cond(Token tok) | ||||
| { | ||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_Preprocess_Cond ); | ||||
| } | ||||
|  | ||||
| bool is_specifier(Token tok) | ||||
| bool tok_is_specifier(Token tok) | ||||
| { | ||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_Specifier ); | ||||
| } | ||||
|  | ||||
| bool is_end_definition(Token tok) | ||||
| bool tok_is_end_definition(Token tok) | ||||
| { | ||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_EndDefinition ); | ||||
| } | ||||
|  | ||||
| String to_string(Token tok) | ||||
| String tok_to_string(Token tok) | ||||
| { | ||||
| 	String result = string_make_reserve( GlobalAllocator, kilobytes(4) ); | ||||
|  | ||||
| 	StrC type_str = to_str( tok.Type ); | ||||
| 	StrC type_str = toktype_to_str( tok.Type ); | ||||
|  | ||||
| 	string_append_fmt( & result, "Line: %d Column: %d, Type: %.*s Content: %.*s" | ||||
| 		, tok.Line, tok.Column | ||||
| @@ -111,9 +113,9 @@ struct TokArray | ||||
| 	s32          Idx; | ||||
| }; | ||||
|  | ||||
| bool __eat( TokType type ); | ||||
| bool lex__eat( TokType type ); | ||||
|  | ||||
| Token* current(TokArray* self, bool skip_formatting ) | ||||
| Token* lex_current(TokArray* self, bool skip_formatting ) | ||||
| { | ||||
| 	if ( skip_formatting ) | ||||
| 	{ | ||||
| @@ -124,7 +126,7 @@ Token* current(TokArray* self, bool skip_formatting ) | ||||
| 	return & self->Arr[self->Idx]; | ||||
| } | ||||
|  | ||||
| Token* peek(TokArray self, bool skip_formatting) | ||||
| Token* lex_peek(TokArray self, bool skip_formatting) | ||||
| { | ||||
| 	s32 idx = self.Idx; | ||||
|  | ||||
| @@ -139,7 +141,7 @@ Token* peek(TokArray self, bool skip_formatting) | ||||
| 	return & self.Arr[idx]; | ||||
| } | ||||
|  | ||||
| Token* previous(TokArray self, bool skip_formatting) | ||||
| Token* lex_previous(TokArray self, bool skip_formatting) | ||||
| { | ||||
| 	s32 idx = self.Idx; | ||||
|  | ||||
| @@ -154,7 +156,7 @@ Token* previous(TokArray self, bool skip_formatting) | ||||
| 	return & self.Arr[idx - 1]; | ||||
| } | ||||
|  | ||||
| Token* next(TokArray self, bool skip_formatting) | ||||
| Token* lex_next(TokArray self, bool skip_formatting) | ||||
| { | ||||
| 	s32 idx = self.Idx; | ||||
|  | ||||
| @@ -169,9 +171,9 @@ Token* next(TokArray self, bool skip_formatting) | ||||
| 	return & self.Arr[idx + 1]; | ||||
| } | ||||
|  | ||||
| global Arena_256KB     defines_map_arena; | ||||
| global HashTable(StrC) defines; | ||||
| global Array(Token)    Tokens; | ||||
| global FixedArena_256KB Lexer_defines_map_arena; | ||||
| global StringTable      Lexer_defines; | ||||
| global Array(Token)     Lexer_Tokens; | ||||
|  | ||||
| #define current ( * ctx->scanner ) | ||||
|  | ||||
| @@ -190,7 +192,7 @@ global Array(Token)    Tokens; | ||||
| 		ctx->scanner++;         \ | ||||
| 	} | ||||
|  | ||||
| #define SkipWhitespace()                             \ | ||||
| #define skip_whitespace()                            \ | ||||
| 	while ( ctx->left && char_is_space( current ) )  \ | ||||
| 	{                                                \ | ||||
| 		move_forward();                              \ | ||||
| @@ -228,7 +230,7 @@ struct LexContext | ||||
| 	char const*     scanner; | ||||
| 	s32             line; | ||||
| 	s32             column; | ||||
| 	HashTable(StrC) defines; | ||||
| 	StringTable     defines; | ||||
| 	Token           token; | ||||
| }; | ||||
|  | ||||
| @@ -237,10 +239,10 @@ s32 lex_preprocessor_directive( LexContext* ctx ) | ||||
| { | ||||
| 	char const* hash = ctx->scanner; | ||||
| 	Token hash_tok = { hash, 1, Tok_Preprocess_Hash, ctx->line, ctx->column, TF_Preprocess }; | ||||
| 	array_append( Tokens, hash_tok  ); | ||||
| 	array_append( Lexer_Tokens, hash_tok  ); | ||||
|  | ||||
| 	move_forward(); | ||||
| 	SkipWhitespace(); | ||||
| 	skip_whitespace(); | ||||
|  | ||||
| 	ctx->token.Text = ctx->scanner; | ||||
| 	while (ctx->left && ! char_is_space(current) ) | ||||
| @@ -249,7 +251,7 @@ s32 lex_preprocessor_directive( LexContext* ctx ) | ||||
| 		ctx->token.Length++; | ||||
| 	} | ||||
|  | ||||
| 	ctx->token.Type = to_toktype( to_str(ctx->token) ); | ||||
| 	ctx->token.Type = strc_to_toktype( tok_to_str(ctx->token) ); | ||||
|  | ||||
| 	bool   is_preprocessor = ctx->token.Type >= Tok_Preprocess_Define && ctx->token.Type <= Tok_Preprocess_Pragma; | ||||
| 	if ( ! is_preprocessor ) | ||||
| @@ -313,14 +315,14 @@ s32 lex_preprocessor_directive( LexContext* ctx ) | ||||
|  | ||||
| 		ctx->token.Length = ctx->token.Length + ctx->token.Text - hash; | ||||
| 		ctx->token.Text   = hash; | ||||
| 		array_append( Tokens, ctx->token ); | ||||
| 		array_append( Lexer_Tokens, ctx->token ); | ||||
| 		return Lex_Continue; // Skip found token, its all handled here. | ||||
| 	} | ||||
|  | ||||
| 	if ( ctx->token.Type == Tok_Preprocess_Else || ctx->token.Type == Tok_Preprocess_EndIf ) | ||||
| 	{ | ||||
| 		ctx->token.Flags |= TF_Preprocess_Cond; | ||||
| 		array_append( Tokens, ctx->token ); | ||||
| 		array_append( Lexer_Tokens, ctx->token ); | ||||
| 		end_line(); | ||||
| 		return Lex_Continue; | ||||
| 	} | ||||
| @@ -329,9 +331,9 @@ s32 lex_preprocessor_directive( LexContext* ctx ) | ||||
| 		ctx->token.Flags |= TF_Preprocess_Cond; | ||||
| 	} | ||||
|  | ||||
| 	array_append( Tokens, ctx->token ); | ||||
| 	array_append( Lexer_Tokens, ctx->token ); | ||||
|  | ||||
| 	SkipWhitespace(); | ||||
| 	skip_whitespace(); | ||||
|  | ||||
| 	if ( ctx->token.Type == Tok_Preprocess_Define ) | ||||
| 	{ | ||||
| @@ -353,10 +355,10 @@ s32 lex_preprocessor_directive( LexContext* ctx ) | ||||
| 			name.Length++; | ||||
| 		} | ||||
|  | ||||
| 		array_append( Tokens, name ); | ||||
| 		array_append( Lexer_Tokens, name ); | ||||
|  | ||||
| 		u64 key = crc32( name.Text, name.Length ); | ||||
| 		hashtable_set(ctx->defines, key, to_str(name) ); | ||||
| 		hashtable_set(ctx->defines, key, tok_to_str(name) ); | ||||
| 	} | ||||
|  | ||||
| 	Token preprocess_content = { ctx->scanner, 0, Tok_Preprocess_Content, ctx->line, ctx->column, TF_Preprocess }; | ||||
| @@ -399,7 +401,7 @@ s32 lex_preprocessor_directive( LexContext* ctx ) | ||||
| 			move_forward(); | ||||
| 		} | ||||
|  | ||||
| 		array_append( Tokens, preprocess_content ); | ||||
| 		array_append( Lexer_Tokens, preprocess_content ); | ||||
| 		return Lex_Continue; // Skip found token, its all handled here. | ||||
| 	} | ||||
|  | ||||
| @@ -462,7 +464,7 @@ s32 lex_preprocessor_directive( LexContext* ctx ) | ||||
| 		preprocess_content.Length++; | ||||
| 	} | ||||
|  | ||||
| 	array_append( Tokens, preprocess_content ); | ||||
| 	array_append( Lexer_Tokens, preprocess_content ); | ||||
| 	return Lex_Continue; // Skip found token, its all handled here. | ||||
| } | ||||
|  | ||||
| @@ -471,11 +473,11 @@ void lex_found_token( LexContext* ctx ) | ||||
| { | ||||
| 	if ( ctx->token.Type != Tok_Invalid ) | ||||
| 	{ | ||||
| 		array_append( Tokens, ctx->token ); | ||||
| 		array_append( Lexer_Tokens, ctx->token ); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	TokType type = to_toktype( to_str(ctx->token) ); | ||||
| 	TokType type = strc_to_toktype( tok_to_str(ctx->token) ); | ||||
|  | ||||
| 	if (type <= Tok_Access_Public && type >= Tok_Access_Private ) | ||||
| 	{ | ||||
| @@ -489,7 +491,7 @@ void lex_found_token( LexContext* ctx ) | ||||
|  | ||||
| 	if ( type == Tok_Decl_Extern_Linkage ) | ||||
| 	{ | ||||
| 		SkipWhitespace(); | ||||
| 		skip_whitespace(); | ||||
|  | ||||
| 		if ( current != '"' ) | ||||
| 		{ | ||||
| @@ -498,7 +500,7 @@ void lex_found_token( LexContext* ctx ) | ||||
| 		} | ||||
|  | ||||
| 		ctx->token.Type = type; | ||||
| 		array_append( Tokens, ctx->token ); | ||||
| 		array_append( Lexer_Tokens, ctx->token ); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| @@ -508,7 +510,7 @@ void lex_found_token( LexContext* ctx ) | ||||
| 	{ | ||||
| 		ctx->token.Type   = type; | ||||
| 		ctx->token.Flags |= TF_Specifier; | ||||
| 		array_append( Tokens, ctx->token ); | ||||
| 		array_append( Lexer_Tokens, ctx->token ); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| @@ -516,7 +518,7 @@ void lex_found_token( LexContext* ctx ) | ||||
| 	if ( type != Tok_Invalid ) | ||||
| 	{ | ||||
| 		ctx->token.Type = type; | ||||
| 		array_append( Tokens, ctx->token ); | ||||
| 		array_append( Lexer_Tokens, ctx->token ); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| @@ -570,7 +572,7 @@ void lex_found_token( LexContext* ctx ) | ||||
| 		ctx->token.Type = Tok_Identifier; | ||||
| 	} | ||||
|  | ||||
| 	array_append( Tokens, ctx->token ); | ||||
| 	array_append( Lexer_Tokens, ctx->token ); | ||||
| } | ||||
|  | ||||
| neverinline | ||||
| @@ -581,7 +583,7 @@ TokArray lex( StrC content ) | ||||
| 	c.content = content; | ||||
| 	c.left    = content.Len; | ||||
| 	c.scanner = content.Ptr; | ||||
| 	c.defines = defines; | ||||
| 	c.defines = Lexer_defines; | ||||
|  | ||||
| 	char const* word        = c.scanner; | ||||
| 	s32         word_length = 0; | ||||
| @@ -589,17 +591,18 @@ TokArray lex( StrC content ) | ||||
| 	c.line   = 1; | ||||
| 	c.column = 1; | ||||
|  | ||||
| 	SkipWhitespace(); | ||||
| 	skip_whitespace(); | ||||
| 	if ( c.left <= 0 ) | ||||
| 	{ | ||||
| 		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)) | ||||
| 	{ | ||||
| 		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 == '_') ) | ||||
| 		{ | ||||
| 			entry_scanner++; | ||||
| @@ -610,11 +613,11 @@ TokArray lex( StrC content ) | ||||
| 			length++; | ||||
| 		} | ||||
|  | ||||
| 		u64 key = crc32( * entry, length ); | ||||
| 		hashtable_set(c.defines, key, (StrC) * entry ); | ||||
| 		u64 key = crc32( entry->Ptr, length ); | ||||
| 		hashtable_set(c.defines, key, * entry ); | ||||
| 	} | ||||
|  | ||||
| 	array_clear(Tokens); | ||||
| 	array_clear(Lexer_Tokens); | ||||
|  | ||||
| 	while (c.left ) | ||||
| 	{ | ||||
| @@ -625,7 +628,10 @@ TokArray lex( StrC content ) | ||||
| 		} | ||||
| 		#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; | ||||
|  | ||||
| @@ -644,14 +650,14 @@ TokArray lex( StrC content ) | ||||
| 				c.token.Type = Tok_NewLine; | ||||
| 				c.token.Length++; | ||||
|  | ||||
| 				array_append( Tokens, c.token ); | ||||
| 				array_append( Lexer_Tokens, c.token ); | ||||
| 				continue; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		c.token.Length = 0; | ||||
|  | ||||
| 		SkipWhitespace(); | ||||
| 		skip_whitespace(); | ||||
| 		if ( c.left <= 0 ) | ||||
| 			break; | ||||
|  | ||||
| @@ -667,7 +673,10 @@ TokArray lex( StrC content ) | ||||
| 						//TokType last_type = Tokens[array_get_header(Tokens)->Num - 2].Type; | ||||
| 						//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') | ||||
| 							{ | ||||
| 								move_forward(); | ||||
| @@ -680,7 +689,7 @@ TokArray lex( StrC content ) | ||||
| 								c.token.Length++; | ||||
| 								move_forward(); | ||||
|  | ||||
| 								array_append( Tokens, c.token ); | ||||
| 								array_append( Lexer_Tokens, c.token ); | ||||
| 							} | ||||
| 						} | ||||
|  | ||||
| @@ -688,7 +697,10 @@ TokArray lex( StrC content ) | ||||
| 					} | ||||
|  | ||||
| 					case Lex_ReturnNull: | ||||
| 						return { {}, 0 }; | ||||
| 					{ | ||||
| 						TokArray tok_array =  {}; | ||||
| 						return tok_array; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			case '.': | ||||
| @@ -1135,7 +1147,7 @@ TokArray lex( StrC content ) | ||||
| 							move_forward(); | ||||
| 							c.token.Length++; | ||||
| 						} | ||||
| 						array_append( Tokens, c.token ); | ||||
| 						array_append( Lexer_Tokens, c.token ); | ||||
| 						continue; | ||||
| 					} | ||||
| 					else if ( current == '*' ) | ||||
| @@ -1171,7 +1183,7 @@ TokArray lex( StrC content ) | ||||
| 							move_forward(); | ||||
| 							c.token.Length++; | ||||
| 						} | ||||
| 						array_append( Tokens, c.token ); | ||||
| 						array_append( Lexer_Tokens, c.token ); | ||||
| 						// end_line(); | ||||
| 						continue; | ||||
| 					} | ||||
| @@ -1264,14 +1276,14 @@ TokArray lex( StrC content ) | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			s32 start = max( 0, array_num(Tokens) - 100 ); | ||||
| 			s32 start = max( 0, array_num(Lexer_Tokens) - 100 ); | ||||
| 			log_fmt("\n%d\n", start); | ||||
| 			for ( s32 idx = start; idx < array_num(Tokens); idx++ ) | ||||
| 			for ( s32 idx = start; idx < array_num(Lexer_Tokens); idx++ ) | ||||
| 			{ | ||||
| 				log_fmt( "Token %d Type: %s : %.*s\n" | ||||
| 					, idx | ||||
| 					, to_str( Tokens[ idx ].Type ).Ptr | ||||
| 					, Tokens[ idx ].Length, Tokens[ idx ].Text | ||||
| 					, toktype_to_str( Lexer_Tokens[ idx ].Type ).Ptr | ||||
| 					, Lexer_Tokens[ idx ].Length, Lexer_Tokens[ idx ].Text | ||||
| 				); | ||||
| 			} | ||||
|  | ||||
| @@ -1288,10 +1300,11 @@ TokArray lex( StrC content ) | ||||
| 		FoundToken: | ||||
| 		{ | ||||
| 			lex_found_token( ctx ); | ||||
| 			TokType last_type = array_back(Tokens)->Type; | ||||
| 			TokType last_type = array_back(Lexer_Tokens)->Type; | ||||
| 			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') | ||||
| 				{ | ||||
| 					move_forward(); | ||||
| @@ -1304,22 +1317,26 @@ TokArray lex( StrC content ) | ||||
| 					c.token.Length++; | ||||
| 					move_forward(); | ||||
|  | ||||
| 					array_append( Tokens, c.token ); | ||||
| 					array_append( Lexer_Tokens, c.token ); | ||||
| 					continue; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if ( array_num(Tokens) == 0 ) | ||||
| 	if ( array_num(Lexer_Tokens) == 0 ) | ||||
| 	{ | ||||
| 		log_failure( "Failed to lex any tokens" ); | ||||
| 		return { {}, 0 }; | ||||
| 		{ | ||||
| 			TokArray tok_array =  {}; | ||||
| 			return tok_array; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	hashtable_clear(defines); | ||||
| 	hashtable_clear(Lexer_defines); | ||||
| 	// defines_map_arena.free(); | ||||
| 	return { Tokens, 0 }; | ||||
| 	TokArray result = { Lexer_Tokens, 0 }; | ||||
| 	return result; | ||||
| } | ||||
| #undef current | ||||
| #undef move_forward | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -52,7 +52,7 @@ | ||||
| #	define ccast( type, value ) ( (type)(value) ) | ||||
| #	endif | ||||
| #	ifndef pcast | ||||
| #	define pcast( type, value ) ( * (type*)(value) ) | ||||
| #	define pcast( type, value ) ( * (type*)(& value) ) | ||||
| #	endif | ||||
| #	ifndef rcast | ||||
| #	define rcast( type, value ) ( (type)(value) ) | ||||
| @@ -376,7 +376,7 @@ size_t gen_example_hash__P_long_long( long long val ) { return val * 2654435761u | ||||
| (selector_arg),                                                             \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 )        \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_2 )        \ | ||||
| 	...                                                                     \ | ||||
| 	/* ... */                                                               \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT(FunctionID__ARGS_SIG_N )         \ | ||||
| 	default: gen_generic_selection_fail                                     \ | ||||
| ) GEN_RESOLVED_FUNCTION_CALL( selector_arg, __VA_ARG__ ) | ||||
|   | ||||
| @@ -365,18 +365,18 @@ ssize fixed_arena_size_remaining(FixedArena<Size>* fixed_arena, ssize alignment) | ||||
|     return size_remaining(fixed_arena->arena, alignment); | ||||
| } | ||||
|  | ||||
| using Arena_1KB   = FixedArena< kilobytes( 1 ) >; | ||||
| using Arena_4KB   = FixedArena< kilobytes( 4 ) >; | ||||
| using Arena_8KB   = FixedArena< kilobytes( 8 ) >; | ||||
| using Arena_16KB  = FixedArena< kilobytes( 16 ) >; | ||||
| using Arena_32KB  = FixedArena< kilobytes( 32 ) >; | ||||
| using Arena_64KB  = FixedArena< kilobytes( 64 ) >; | ||||
| using Arena_128KB = FixedArena< kilobytes( 128 ) >; | ||||
| using Arena_256KB = FixedArena< kilobytes( 256 ) >; | ||||
| using Arena_512KB = FixedArena< kilobytes( 512 ) >; | ||||
| using Arena_1MB   = FixedArena< megabytes( 1 ) >; | ||||
| using Arena_2MB   = FixedArena< megabytes( 2 ) >; | ||||
| using Arena_4MB   = FixedArena< megabytes( 4 ) >; | ||||
| using FixedArena_1KB   = FixedArena< kilobytes( 1 ) >; | ||||
| using FixedArena_4KB   = FixedArena< kilobytes( 4 ) >; | ||||
| using FixedArena_8KB   = FixedArena< kilobytes( 8 ) >; | ||||
| using FixedArena_16KB  = FixedArena< kilobytes( 16 ) >; | ||||
| using FixedArena_32KB  = FixedArena< kilobytes( 32 ) >; | ||||
| using FixedArena_64KB  = FixedArena< kilobytes( 64 ) >; | ||||
| using FixedArena_128KB = FixedArena< kilobytes( 128 ) >; | ||||
| using FixedArena_256KB = FixedArena< kilobytes( 256 ) >; | ||||
| using FixedArena_512KB = FixedArena< kilobytes( 512 ) >; | ||||
| using FixedArena_1MB   = FixedArena< megabytes( 1 ) >; | ||||
| using FixedArena_2MB   = FixedArena< megabytes( 2 ) >; | ||||
| using FixedArena_4MB   = FixedArena< megabytes( 4 ) >; | ||||
| #pragma endregion FixedArena | ||||
|  | ||||
| #pragma region Pool | ||||
|   | ||||
| @@ -407,14 +407,30 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_ | ||||
| #pragma pop_macro("GEN_DEFINE_ATTRIBUTE_TOKENS") | ||||
|  | ||||
| 	// We cannot parse this enum, it has Attribute names as enums | ||||
| 	CodeEnum enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), "attribute_toks", string_to_strc(attribute_entries), stringize( | ||||
| 		enum TokType_Def : u32 | ||||
| 		{ | ||||
| 			<entries> | ||||
| 			<attribute_toks> | ||||
| 			Tok_NumTokens | ||||
| 		}; | ||||
| 	))); | ||||
| 	CodeEnum enum_code; | ||||
| 	if (use_c_definition) | ||||
| 	{ | ||||
| 		enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), "attribute_toks", string_to_strc(attribute_entries), stringize( | ||||
| 			enum TokType | ||||
| 			{ | ||||
| 				<entries> | ||||
| 				<attribute_toks> | ||||
| 				Tok_NumTokens, | ||||
| 				Tok_UnderlyingType = GEN_U32_MAX | ||||
| 			}; | ||||
| 		))); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), "attribute_toks", string_to_strc(attribute_entries), stringize( | ||||
| 			enum TokType : u32 | ||||
| 			{ | ||||
| 				<entries> | ||||
| 				<attribute_toks> | ||||
| 				Tok_NumTokens | ||||
| 			}; | ||||
| 		))); | ||||
| 	} | ||||
|  | ||||
| #pragma push_macro("local_persist") | ||||
| #pragma push_macro("do_once_start") | ||||
| @@ -424,10 +440,10 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_ | ||||
| #undef do_once_end | ||||
| 	CodeFn to_str = parse_function(token_fmt("entries", string_to_strc(to_str_entries), "attribute_toks", string_to_strc(to_str_attributes), stringize( | ||||
| 		inline | ||||
| 		StrC to_str( TokType type ) | ||||
| 		StrC toktype_to_str( TokType type ) | ||||
| 		{ | ||||
| 			local_persist | ||||
| 			StrC lookup[] { | ||||
| 			StrC lookup[] = { | ||||
| 				<entries> | ||||
| 				<attribute_toks> | ||||
| 			}; | ||||
| @@ -438,14 +454,14 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_ | ||||
|  | ||||
| 	CodeFn to_type = parse_function( token_fmt( "entries", string_to_strc(to_str_entries), stringize( | ||||
| 		inline | ||||
| 		TokType to_toktype( StrC str ) | ||||
| 		TokType strc_to_toktype( StrC str ) | ||||
| 		{ | ||||
| 			local_persist | ||||
| 			u32 keymap[ Tok_NumTokens ]; | ||||
| 			do_once_start | ||||
| 				for ( u32 index = 0; index < Tok_NumTokens; index++ ) | ||||
| 				{ | ||||
| 					StrC enum_str = to_str( (TokType)index ); | ||||
| 					StrC enum_str = toktype_to_str( (TokType)index ); | ||||
|  | ||||
| 					// We subtract 1 to remove the null terminator | ||||
| 					// This is because the tokens lexed are not null terminated. | ||||
| @@ -468,16 +484,19 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_ | ||||
| #pragma pop_macro("do_once_start") | ||||
| #pragma pop_macro("do_once_end") | ||||
|  | ||||
| 	//CodeNS    nspace     = def_namespace( name(ETokType), def_namespace_body( args( attribute_entires_def, enum_code, to_str, to_type ) ) ); | ||||
| 	CodeTypedef td_toktype = parse_typedef( code( typedef enum TokType_Def TokType; )); | ||||
|  | ||||
| 	return def_global_body( args( | ||||
| 		attribute_entires_def, | ||||
| 		enum_code, | ||||
| 		td_toktype, | ||||
| 		to_str, | ||||
| 		to_type | ||||
| 	)); | ||||
| 	CodeBody result = def_body(CT_Global_Body); | ||||
| 	body_append(result, untyped_str(txt("GEN_NS_PARSER_BEGIN\n\n"))); | ||||
| 	body_append(result, attribute_entires_def); | ||||
| 	body_append(result, enum_code); | ||||
| 	if (use_c_definition) | ||||
| 	{ | ||||
| 		CodeTypedef td_toktype = parse_typedef( code( typedef enum TokType TokType; )); | ||||
| 		body_append(result, td_toktype); | ||||
| 	} | ||||
| 	body_append(result, to_str); | ||||
| 	body_append(result, to_type); | ||||
| 	body_append(result, untyped_str(txt("\nGEN_NS_PARSER_END\n\n"))); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| CodeBody gen_ast_inlines() | ||||
|   | ||||
| @@ -9,6 +9,7 @@ | ||||
| #	pragma clang diagnostic ignored "-Wunused-function" | ||||
| #	pragma clang diagnostic ignored "-Wbraced-scalar-init" | ||||
| #   pragma clang diagnostic ignored "-W#pragma-messages" | ||||
| #	pragma clang diagnostic ignored "-Wstatic-in-inline" | ||||
| #endif | ||||
|  | ||||
| #ifdef __GNUC__ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user