mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-10-31 06:50:53 -07:00 
			
		
		
		
	c_library compiles and generates
This commit is contained in:
		| @@ -336,6 +336,7 @@ CodeBody parse_file( Str path ); | |||||||
|  |  | ||||||
| GEN_API CodeClass       parse_class        ( Str class_def       ); | GEN_API CodeClass       parse_class        ( Str class_def       ); | ||||||
| GEN_API CodeConstructor parse_constructor  ( Str constructor_def ); | GEN_API CodeConstructor parse_constructor  ( Str constructor_def ); | ||||||
|  | GEN_API CodeDefine      parse_define       ( Str define_def      ); | ||||||
| GEN_API CodeDestructor  parse_destructor   ( Str destructor_def  ); | GEN_API CodeDestructor  parse_destructor   ( Str destructor_def  ); | ||||||
| GEN_API CodeEnum        parse_enum         ( Str enum_def        ); | GEN_API CodeEnum        parse_enum         ( Str enum_def        ); | ||||||
| GEN_API CodeBody        parse_export_body  ( Str export_def      ); | GEN_API CodeBody        parse_export_body  ( Str export_def      ); | ||||||
|   | |||||||
| @@ -82,6 +82,21 @@ CodeConstructor parse_constructor( Str def ) | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | CodeDefine parse_define( Str def ) | ||||||
|  | { | ||||||
|  | 	check_parse_args( def ); | ||||||
|  |  | ||||||
|  | 	TokArray toks = lex( def ); | ||||||
|  | 	if ( toks.Arr == nullptr ) | ||||||
|  | 		return InvalidCode; | ||||||
|  |  | ||||||
|  | 	_ctx->parser.Tokens = toks; | ||||||
|  | 	push_scope(); | ||||||
|  | 	CodeDefine result = parser_parse_define(); | ||||||
|  | 	parser_pop(& _ctx->parser); | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  |  | ||||||
| CodeDestructor parse_destructor( Str def ) | CodeDestructor parse_destructor( Str def ) | ||||||
| { | { | ||||||
| 	check_parse_args( def ); | 	check_parse_args( def ); | ||||||
|   | |||||||
| @@ -123,19 +123,19 @@ s32 lex_preprocessor_define( LexContext* ctx ) | |||||||
| 		name.Text.Len++; | 		name.Text.Len++; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Specifier spec   = str_to_specifier( name.Text ); | 	Specifier spec    = str_to_specifier( name.Text ); | ||||||
| 	TokType   attrib = str_to_toktype( name.Text ); | 	TokType   attrib  = str_to_toktype( name.Text ); | ||||||
| 	b32 not_specifier = spec   == Spec_Invalid; | 	b32 not_specifier = spec   == Spec_Invalid; | ||||||
| 	b32 not_attribute = attrib <= Tok___Attributes_Start; | 	b32 not_attribute = attrib <= Tok___Attributes_Start; | ||||||
|  |  | ||||||
| 	PreprocessorMacro  macro            = { name.Text, MT_Statement, (MacroFlags)0 }; | 	PreprocessorMacro  macro            = { name.Text, MT_Expression, (MacroFlags)0 }; | ||||||
| 	PreprocessorMacro* registered_macro = lookup_preprocess_macro(name.Text); | 	PreprocessorMacro* registered_macro = lookup_preprocess_macro(name.Text); | ||||||
|  |  | ||||||
| 	if ( registered_macro == nullptr && not_specifier && not_attribute ) { | 	if ( registered_macro == nullptr && not_specifier && not_attribute ) { | ||||||
| 		log_fmt("Warning: '%S' was not registered before the lexer processed its #define directive, it will be registered as a statement macro\n" | 		log_fmt("Warning: '%S' was not registered before the lexer processed its #define directive, it will be registered as a expression macro\n" | ||||||
| 			, name.Text  | 			, name.Text  | ||||||
| 		); | 		); | ||||||
| 		GEN_DEBUG_TRAP(); | 		// GEN_DEBUG_TRAP(); | ||||||
| 	} | 	} | ||||||
| 	array_append( _ctx->Lexer_Tokens, name ); | 	array_append( _ctx->Lexer_Tokens, name ); | ||||||
|  |  | ||||||
| @@ -145,7 +145,7 @@ s32 lex_preprocessor_define( LexContext* ctx ) | |||||||
| 			log_fmt("Warning: %S registered macro is not flagged as functional yet the definition detects opening parenthesis '(' for arguments\n" | 			log_fmt("Warning: %S registered macro is not flagged as functional yet the definition detects opening parenthesis '(' for arguments\n" | ||||||
| 				, name.Text | 				, name.Text | ||||||
| 			); | 			); | ||||||
| 			GEN_DEBUG_TRAP(); | 			// GEN_DEBUG_TRAP(); | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| 			macro.Flags |= MF_Functional; | 			macro.Flags |= MF_Functional; | ||||||
| @@ -526,35 +526,41 @@ void lex_found_token( LexContext* ctx ) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	PreprocessorMacro* macro = lookup_preprocess_macro( ctx->token.Text ); | 	PreprocessorMacro* macro = lookup_preprocess_macro( ctx->token.Text ); | ||||||
| 	if ( macro ) | 	b32 has_args          = ctx->left && (* ctx->scanner) == '('; | ||||||
|  | 	b32 resolved_to_macro = false; | ||||||
|  | 	if (macro) { | ||||||
|  | 		ctx->token.Type   = macrotype_to_toktype(macro->Type); | ||||||
|  | 		b32 is_functional = macro_is_functional(* macro); | ||||||
|  | 		resolved_to_macro = has_args ? is_functional : ! is_functional; | ||||||
|  | 	} | ||||||
|  | 	if ( resolved_to_macro ) | ||||||
| 	{ | 	{ | ||||||
| 		ctx->token.Type = macrotype_to_toktype(macro->Type); |  | ||||||
|  |  | ||||||
| 		// TODO(Ed): When we introduce a macro AST (and expression support), we'll properly lex this section. | 		// TODO(Ed): When we introduce a macro AST (and expression support), we'll properly lex this section. | ||||||
| 		// Want to ignore any arguments the define may have as they can be execution expressions. | 		// Want to ignore any arguments the define may have as they can be execution expressions. | ||||||
| 		if ( ctx->left && (* ctx->scanner) == '(' ) | 		if ( has_args ) | ||||||
| 		{ | 		{ | ||||||
| 			ctx->token.Flags |= TF_Macro_Functional; | 			ctx->token.Flags |= TF_Macro_Functional; | ||||||
|  |  | ||||||
| 			move_forward(); | 			// move_forward(); | ||||||
| 			ctx->token.Text.Len++; | 			// ctx->token.Text.Len++; | ||||||
|  |  | ||||||
| 			s32 level = 0; | 			// s32 level = 0; | ||||||
| 			while ( ctx->left && ((* ctx->scanner) != ')' || level > 0) ) | 			// while ( ctx->left && ((* ctx->scanner) != ')' || level > 0) ) | ||||||
| 			{ | 			// { | ||||||
| 				if ( (* ctx->scanner) == '(' ) | 			// 	if ( (* ctx->scanner) == '(' ) | ||||||
| 					level++; | 			// 		level++; | ||||||
|  |  | ||||||
| 				else if ( (* ctx->scanner) == ')' && level > 0 ) | 			// 	else if ( (* ctx->scanner) == ')' && level > 0 ) | ||||||
| 					level--; | 			// 		level--; | ||||||
|  |  | ||||||
| 				move_forward(); | 			// 	move_forward(); | ||||||
| 				ctx->token.Text.Len++; | 			// 	ctx->token.Text.Len++; | ||||||
| 			} | 			// } | ||||||
|  |  | ||||||
| 			move_forward(); | 			// move_forward(); | ||||||
| 			ctx->token.Text.Len++; | 			// ctx->token.Text.Len++; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		//if ( (* ctx->scanner) == '\r' && ctx->scanner[1] == '\n' ) | 		//if ( (* ctx->scanner) == '\r' && ctx->scanner[1] == '\n' ) | ||||||
| 		//{ | 		//{ | ||||||
| 		//	move_forward(); | 		//	move_forward(); | ||||||
| @@ -1277,7 +1283,7 @@ TokArray lex( Str content ) | |||||||
| 		{ | 		{ | ||||||
| 			lex_found_token( ctx ); | 			lex_found_token( ctx ); | ||||||
| 			TokType last_type = array_back(_ctx->Lexer_Tokens)->Type; | 			TokType last_type = array_back(_ctx->Lexer_Tokens)->Type; | ||||||
| 			if ( last_type == Tok_Preprocess_Macro_Stmt ) | 			if ( last_type == Tok_Preprocess_Macro_Stmt || last_type == Tok_Preprocess_Macro_Expr ) | ||||||
| 			{ | 			{ | ||||||
| 				Token thanks_c = { { 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; | 				c.token = thanks_c; | ||||||
|   | |||||||
| @@ -93,7 +93,15 @@ bool lex__eat(TokArray* self, TokType type ) | |||||||
| 		self->Idx ++; | 		self->Idx ++; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( at_idx.Type != type ) | 	b32 not_accepted  = at_idx.Type != type; | ||||||
|  | 	b32 is_identifier = at_idx.Type == Tok_Identifier; | ||||||
|  | 	if ( not_accepted ) | ||||||
|  | 	{ | ||||||
|  | 		PreprocessorMacro* macro = lookup_preprocess_macro(at_idx.Text); | ||||||
|  | 		b32 accept_as_identifier = macro && bitfield_is_set(MacroFlags, macro->Flags, MF_Allow_As_Identifier ); | ||||||
|  | 		not_accepted             = type == Tok_Identifier && accept_as_identifier ? false : true; | ||||||
|  | 	} | ||||||
|  | 	if ( not_accepted ) | ||||||
| 	{ | 	{ | ||||||
| 		Token tok = * lex_current( self, lex_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" | ||||||
| @@ -188,7 +196,7 @@ internal CodeComment        parse_comment                      (); | |||||||
| internal Code               parse_complicated_definition       ( TokType which ); | internal Code               parse_complicated_definition       ( TokType which ); | ||||||
| internal CodeBody           parse_class_struct_body            ( TokType which, Token name ); | internal CodeBody           parse_class_struct_body            ( TokType which, Token name ); | ||||||
| internal Code               parse_class_struct                 ( TokType which, bool inplace_def ); | internal Code               parse_class_struct                 ( TokType which, bool inplace_def ); | ||||||
| internal CodeDefine         parse_define                       (); | internal CodeDefine         parser_parse_define                (); | ||||||
| internal Code               parse_expression                   (); | internal Code               parse_expression                   (); | ||||||
| internal Code               parse_forward_or_definition        ( TokType which, bool is_inplace ); | internal Code               parse_forward_or_definition        ( TokType which, bool is_inplace ); | ||||||
| internal CodeFn             parse_function_after_name          ( ModuleFlag mflags, CodeAttributes attributes, CodeSpecifiers specifiers, CodeTypename ret_type, Token name ); | internal CodeFn             parse_function_after_name          ( ModuleFlag mflags, CodeAttributes attributes, CodeSpecifiers specifiers, CodeTypename ret_type, Token name ); | ||||||
| @@ -902,7 +910,7 @@ CodeBody parse_class_struct_body( TokType which, Token name ) | |||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| 			case Tok_Preprocess_Define: { | 			case Tok_Preprocess_Define: { | ||||||
| 				member = cast(Code, parse_define()); | 				member = cast(Code, parser_parse_define()); | ||||||
| 				// #define | 				// #define | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| @@ -1286,9 +1294,14 @@ Code parse_complicated_definition( TokType which ) | |||||||
| } | } | ||||||
|  |  | ||||||
| internal inline | internal inline | ||||||
| CodeDefine parse_define() | CodeDefine parser_parse_define() | ||||||
| { | { | ||||||
| 	push_scope(); | 	push_scope(); | ||||||
|  | 	if ( check(Tok_Preprocess_Hash)) { | ||||||
|  | 		// If parse_define is called by the user the hash reach here. | ||||||
|  | 		eat(Tok_Preprocess_Hash); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	eat( Tok_Preprocess_Define ); | 	eat( Tok_Preprocess_Define ); | ||||||
| 	// #define | 	// #define | ||||||
|  |  | ||||||
| @@ -1698,7 +1711,7 @@ CodeBody parse_global_nspace( CodeType which ) | |||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 			case Tok_Preprocess_Define: | 			case Tok_Preprocess_Define: | ||||||
| 				member = cast(Code, parse_define()); | 				member = cast(Code, parser_parse_define()); | ||||||
| 				// #define ... | 				// #define ... | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| @@ -2933,6 +2946,32 @@ Code parse_simple_preprocess( TokType which ) | |||||||
| 	// <Macro> | 	// <Macro> | ||||||
|  |  | ||||||
| 	PreprocessorMacro* macro = lookup_preprocess_macro( full_macro.Text ); | 	PreprocessorMacro* macro = lookup_preprocess_macro( full_macro.Text ); | ||||||
|  | 	if ( which != Tok_Preprocess_Unsupported && macro == nullptr ) { | ||||||
|  | 		log_failure("Expected the macro %S to be registered\n%S", full_macro,  parser_to_strbuilder(_ctx->parser)); | ||||||
|  | 		return NullCode; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// TODO(Ed) : Parse this properly later (expression and statement support) | ||||||
|  | 	if ( macro && macro_is_functional(* macro) ) | ||||||
|  | 	{ | ||||||
|  | 		eat( Tok_Capture_Start ); | ||||||
|  |  | ||||||
|  | 		s32 level = 0; | ||||||
|  | 		while ( left && ( currtok.Type != Tok_Capture_End || level > 0 ) ) | ||||||
|  | 		{ | ||||||
|  | 			if ( currtok.Type == Tok_Capture_Start ) | ||||||
|  | 				level++; | ||||||
|  |  | ||||||
|  | 			else if ( currtok.Type == Tok_Capture_End && level > 0 ) | ||||||
|  | 				level--; | ||||||
|  |  | ||||||
|  | 			eat( currtok.Type ); | ||||||
|  | 		} | ||||||
|  | 		eat( Tok_Capture_End ); | ||||||
|  | 		// <Macro> ( <params> ) | ||||||
|  |  | ||||||
|  | 		full_macro.Text.Len = ( (sptr)prevtok.Text.Ptr + prevtok.Text.Len ) - (sptr)full_macro.Text.Ptr; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if ( macro && macro_expects_body(* macro) && peektok.Type == Tok_BraceCurly_Open ) | 	if ( macro && macro_expects_body(* macro) && peektok.Type == Tok_BraceCurly_Open ) | ||||||
| 	{ | 	{ | ||||||
| @@ -3619,7 +3658,7 @@ CodeEnum parser_parse_enum( bool inplace_def ) | |||||||
| 		if ( str_contains( tok_to_str(currtok), enum_underlying_macro.Name) ) | 		if ( str_contains( tok_to_str(currtok), enum_underlying_macro.Name) ) | ||||||
| 		{ | 		{ | ||||||
| 			use_macro_underlying = true; | 			use_macro_underlying = true; | ||||||
| 			underlying_macro     = parse_simple_preprocess( Tok_Preprocess_Macro_Typename ); | 			underlying_macro     = parse_simple_preprocess( Tok_Preprocess_Macro_Expr ); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -3660,7 +3699,7 @@ CodeEnum parser_parse_enum( bool inplace_def ) | |||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| 				case Tok_Preprocess_Define: | 				case Tok_Preprocess_Define: | ||||||
| 					member = cast(Code, parse_define()); | 					member = cast(Code, parser_parse_define()); | ||||||
| 					// #define | 					// #define | ||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| @@ -4916,22 +4955,32 @@ CodeTypedef parser_parse_typedef() | |||||||
| #if GEN_PARSER_DISABLE_MACRO_TYPEDEF | #if GEN_PARSER_DISABLE_MACRO_TYPEDEF | ||||||
| 	if ( false ) | 	if ( false ) | ||||||
| #else | #else | ||||||
| 	if ( check( Tok_Preprocess_Macro_Typename )) | 	b32 valid_macro = false; | ||||||
|  | 	valid_macro |= left && currtok.Type == Tok_Preprocess_Macro_Typename; | ||||||
|  | 	valid_macro |= left && currtok.Type == Tok_Preprocess_Macro_Stmt; | ||||||
|  | 	// if (currtok.Type == Tok_Preprocess_Macro_Stmt) | ||||||
|  | 	// { | ||||||
|  | 		// PreprocessMacro* macro = lookup_preprocess_macro(currtok.Text); | ||||||
|  | 		// valid_macro |= macro && macro_expects_body(* macro)); | ||||||
|  | 	// } | ||||||
|  |  | ||||||
|  | 	if ( valid_macro ) | ||||||
| #endif | #endif | ||||||
| 	{ | 	{ | ||||||
| 		type = cast(Code, t_empty); | 		type          = cast(Code, t_empty); | ||||||
| 		name = currtok; | 		Code macro    = parse_simple_preprocess(currtok.Type); | ||||||
|  | 		name          = currtok; | ||||||
|  | 		name.Text.Len = macro->Content.Len; | ||||||
| 		_ctx->parser.Scope->Name = name.Text; | 		_ctx->parser.Scope->Name = name.Text; | ||||||
| 		eat( Tok_Preprocess_Macro_Typename ); |  | ||||||
| 		// <ModuleFalgs> typedef <Preprocessed_Macro> | 		// <ModuleFalgs> typedef <Preprocessed_Macro> | ||||||
|  |  | ||||||
| 		if ( currtok.Type == Tok_Identifier ) | 		if ( currtok.Type == Tok_Identifier ) | ||||||
| 		{ | 		{ | ||||||
| 			type = untyped_str(name.Text); | 			type = macro; | ||||||
| 			name = currtok; | 			name = currtok; | ||||||
| 			eat(Tok_Identifier); | 			eat(Tok_Identifier); | ||||||
|  | 			// <ModuleFalgs> typedef <Preprocessed_Macro> <Identifier> | ||||||
| 		} | 		} | ||||||
| 		// <ModuleFalgs> typedef <Preprocessed_Macro> <Identifier> |  | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| @@ -5178,7 +5227,7 @@ CodeUnion parser_parse_union( bool inplace_def ) | |||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| 				case Tok_Preprocess_Define: | 				case Tok_Preprocess_Define: | ||||||
| 					member = cast(Code, parse_define()); | 					member = cast(Code, parser_parse_define()); | ||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| 				case Tok_Preprocess_If: | 				case Tok_Preprocess_If: | ||||||
|   | |||||||
| @@ -129,8 +129,8 @@ struct ParseContext | |||||||
|  |  | ||||||
| enum MacroType : u16 | enum MacroType : u16 | ||||||
| { | { | ||||||
| 	MT_Statement,      // A macro is assumed to be a statement if not resolved. | 	MT_Expression,     // A macro is assumed to be a expression if not resolved. | ||||||
| 	MT_Expression, | 	MT_Statement,       | ||||||
| 	MT_Typename, | 	MT_Typename, | ||||||
| 	MT_Attribute,      // More of a note to the parser than anythign else (attributes should be defined in the user attribues def). | 	MT_Attribute,      // More of a note to the parser than anythign else (attributes should be defined in the user attribues def). | ||||||
| 	MT_Specifier,      // More of a note to the parser than anythign else (specifiers should be defined in the user attribues def). | 	MT_Specifier,      // More of a note to the parser than anythign else (specifiers should be defined in the user attribues def). | ||||||
| @@ -175,8 +175,10 @@ Str macrotype_to_str( MacroType type ) | |||||||
|  |  | ||||||
| enum EMacroFlags : u16 | enum EMacroFlags : u16 | ||||||
| { | { | ||||||
| 	MF_Functional     = bit(0), // Macro has parameters (args expected to be passed) | 	MF_Functional          = bit(0), // Macro has parameters (args expected to be passed) | ||||||
| 	MF_Expects_Body   = bit(1), // Expects to assign a braced scope to its body. | 	MF_Expects_Body        = bit(1), // Expects to assign a braced scope to its body. | ||||||
|  | 	MF_Allow_As_Identifier = bit(2), // lex__eat wil treat this macro as an identifier if the parser attempts to consume it as one. | ||||||
|  |                                      //  ^^^ This is a sort of kludge because we don't support push/pop macro programs rn. ^^^ | ||||||
|  |  | ||||||
| 	MF_Null           = 0, | 	MF_Null           = 0, | ||||||
| 	MF_UnderlyingType = GEN_U16_MAX, | 	MF_UnderlyingType = GEN_U16_MAX, | ||||||
|   | |||||||
| @@ -225,7 +225,7 @@ forceinline ssize         size_remaining(Arena& arena, ssize alignment) { return | |||||||
| // This id is defined by Unreal for asserts | // This id is defined by Unreal for asserts | ||||||
| #pragma push_macro("check") | #pragma push_macro("check") | ||||||
| #undef check | #undef check | ||||||
| forceinline void check(Arena& arena) { return arena_check(& arena); }; | forceinline void check(Arena& arena) { return arena_check(& arena); } | ||||||
| #pragma pop_macro("check") | #pragma pop_macro("check") | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|   | |||||||
| @@ -65,19 +65,123 @@ int gen_main() | |||||||
| 	Context ctx {}; | 	Context ctx {}; | ||||||
| 	gen::init(& ctx); | 	gen::init(& ctx); | ||||||
|  |  | ||||||
| 	ctx.PreprocessorDefines.append(txt("GEN_API_C_BEGIN")); | 	register_preprocess_macros( args( | ||||||
| 	ctx.PreprocessorDefines.append(txt("GEN_API_C_END")); | 		(PreprocessorMacro { txt("bit"),                          MT_Expression, MF_Functional }), | ||||||
| 	ctx.PreprocessorDefines.append(txt("Array(")); | 		(PreprocessorMacro { txt("bitfield_is_set"),              MT_Expression, MF_Functional }), | ||||||
| 	ctx.PreprocessorDefines.append(txt("HashTable(")); | 		(PreprocessorMacro { txt("GEN_C_LIKE_CPP"),               MT_Expression, MF_Null       }), | ||||||
| 	ctx.PreprocessorDefines.append(txt("GEN_NS_PARSER")); | 		(PreprocessorMacro { txt("cast"),                         MT_Expression, MF_Functional }), | ||||||
| 	ctx.PreprocessorDefines.append(txt("GEN_NS_PARSER_BEGIN")); | 		(PreprocessorMacro { txt("ccast"),                        MT_Expression, MF_Functional }), | ||||||
| 	ctx.PreprocessorDefines.append(txt("GEN_NS_PARSER_END")); | 		(PreprocessorMacro { txt("rcast"),                        MT_Expression, MF_Functional }), | ||||||
| 	ctx.PreprocessorDefines.append(txt("Using_Code(")); | 		(PreprocessorMacro { txt("pcast"),                        MT_Expression, MF_Functional }), | ||||||
| 	ctx.PreprocessorDefines.append(txt("Using_CodeOps(")); | 		(PreprocessorMacro { txt("scast"),                        MT_Expression, MF_Functional }), | ||||||
| 	ctx.PreprocessorDefines.append(txt("GEN_OPTIMIZE_MAPPINGS_BEGIN")); | 		(PreprocessorMacro { txt("stringize_va"),                 MT_Expression, MF_Functional }), | ||||||
| 	ctx.PreprocessorDefines.append(txt("GEN_OPITMIZE_MAPPINGS_END")); | 		(PreprocessorMacro { txt("stringize"),                    MT_Expression, MF_Functional }), | ||||||
| 	ctx.PreprocessorDefines.append(txt("GEN_PARAM_DEFAULT")); | 		(PreprocessorMacro { txt("do_once"),                      MT_Expression, MF_Functional }),  | ||||||
| 	//PreprocessorDefines.append(txt("GEN_EXECUTION_EXPRESSION_SUPPORT")); | 		(PreprocessorMacro { txt("do_once_defer"),                MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("do_once_start"),                MT_Statement,  MF_Null       }),  | ||||||
|  | 		(PreprocessorMacro { txt("do_once_end"),                  MT_Statement,  MF_Null       }),  | ||||||
|  | 		(PreprocessorMacro { txt("labeled_scope_start"),          MT_Statement,  MF_Null       }),  | ||||||
|  | 		(PreprocessorMacro { txt("labeled_scope_end"),            MT_Statement,  MF_Null       }),  | ||||||
|  | 		(PreprocessorMacro { txt("compiler_decorated_func_name"), MT_Expression, MF_Null       }),  | ||||||
|  | 		(PreprocessorMacro { txt("num_args_impl"),                MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("num_args"),                     MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("count_of"),                     MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("clamp"),                        MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("is_between"),                   MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("size_of"),                      MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("min"),                          MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("max"),                          MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("offset_of"),                    MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("static_assert"),                MT_Statement,  MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("typeof"),                       MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("GEN_API_C_BEGIN"),              MT_Statement,  MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("GEN_API_C_END"),                MT_Statement,  MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("nullptr"),                      MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("GEN_REMOVE_PTR"),               MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("GEN_PARAM_DEFAULT"),            MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("struct_init"),                  MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("GEN_OPTIMIZE_MAPPINGS_BEGIN"),  MT_Statement,  MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("GEN_OPITMIZE_MAPPINGS_END"),    MT_Statement,  MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("Array"),                        MT_Typename,   MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("HashTable"),                    MT_Typename,   MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("Using_Code"),                   MT_Statement,  MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("Using_CodeOps"),                MT_Statement,  MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("kilobytes"),                    MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("megabytes"),                    MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("gigabytes"),                    MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("terabytes"),                    MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("GEN__ONES"),                    MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("GEN__HIGHS"),                   MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("GEN__HAS_ZERO"),                MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("zero_item"),                    MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("zero_array"),                   MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("GEN_DEFAULT_MEMORY_ALIGNMENT"), MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("GEN_DEFAULT_ALLOCATOR_FLAGS"),  MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("alloc_item"),                   MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("alloc_array"),                  MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("malloc"),                       MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("mfree"),                        MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("GEN_PRINTF_MAXLEN"),            MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("cast_to_str"),                  MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("current"),                      MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("txt"),                          MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("GEN_FILE_OPEN_PROC"),           MT_Statement,  MF_Functional | MF_Expects_Body }), | ||||||
|  | 		(PreprocessorMacro { txt("GEN_FILE_READ_AT_PROC"),        MT_Statement,  MF_Functional | MF_Expects_Body }), | ||||||
|  | 		(PreprocessorMacro { txt("GEN_FILE_WRITE_AT_PROC"),       MT_Statement,  MF_Functional | MF_Expects_Body }), | ||||||
|  | 		(PreprocessorMacro { txt("GEN_FILE_SEEK_PROC"),           MT_Statement,  MF_Functional | MF_Expects_Body }), | ||||||
|  | 		(PreprocessorMacro { txt("GEN_FILE_CLOSE_PROC"),          MT_Statement,  MF_Functional | MF_Expects_Body }), | ||||||
|  | 		(PreprocessorMacro { txt("log_failure"),                  MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("operator"),                     MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("InvalidCode"),                  MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("NullCode"),                     MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("Verify_POD"),                   MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("gen_main"),                     MT_Statement,  MF_Null       }) | ||||||
|  | 	)); | ||||||
|  | 	register_preprocess_macros( args( | ||||||
|  | 		(PreprocessorMacro { txt("name"),                         MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("code"),                         MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("args"),                         MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("code_str"),                     MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("code_fmt"),                     MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("parse_fmt"),                    MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("token_fmt"),                    MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("check_member_val"),             MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("check_member_str"),             MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("check_member_content"),         MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("check_member_ast"),             MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("check_params"),                 MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("check_param_eq_ret"),           MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("specs"),                        MT_Expression, MF_Functional | MF_Allow_As_Identifier }), | ||||||
|  | 		(PreprocessorMacro { txt("name_check"),                   MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("null_check"),                   MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("def_body_start"),               MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("def_body_code_array_start"),    MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("move_forward"),                 MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("skip_whitespace"),              MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("end_line"),                     MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("check_parse_args"),             MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("currtok_noskip"),               MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("currtok"),                      MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("peektok"),                      MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("prevtok"),                      MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("nexttok"),                      MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("nexttok_noskip"),               MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("eat"),                          MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("left"),                         MT_Expression, MF_Null       | MF_Allow_As_Identifier }), | ||||||
|  | 		(PreprocessorMacro { txt("def_assign"),                   MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("CHECK_WAS_DEFINED"),            MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("check_noskip"),                 MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("check"),                        MT_Expression, MF_Functional | MF_Allow_As_Identifier }), | ||||||
|  | 		(PreprocessorMacro { txt("push_scope"),                   MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("cut_length"),                   MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("cut_ptr"),                      MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("pos"),                          MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("move_fwd"),                     MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("Entry"),                        MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("CheckEndParams"),               MT_Expression, MF_Functional }), | ||||||
|  | 		(PreprocessorMacro { txt("UseTemplateCapture"),           MT_Expression, MF_Null       }), | ||||||
|  | 		(PreprocessorMacro { txt("check_current"),                MT_Expression, MF_Functional }) | ||||||
|  | 	)); | ||||||
|  |  | ||||||
| 	Code push_ignores           = scan_file( path_base "helpers/push_ignores.inline.hpp" ); | 	Code push_ignores           = scan_file( path_base "helpers/push_ignores.inline.hpp" ); | ||||||
| 	Code pop_ignores            = scan_file( path_base "helpers/pop_ignores.inline.hpp" ); | 	Code pop_ignores            = scan_file( path_base "helpers/pop_ignores.inline.hpp" ); | ||||||
| @@ -139,8 +243,8 @@ int gen_main() | |||||||
| 			CodeTemplate tmpl = cast(CodeTemplate, entry); | 			CodeTemplate tmpl = cast(CodeTemplate, entry); | ||||||
| 			if ( tmpl->Declaration->Name.contains(txt("swap"))) | 			if ( tmpl->Declaration->Name.contains(txt("swap"))) | ||||||
| 			{ | 			{ | ||||||
| 				log_fmt("SWAPPED"); | 				register_preprocess_macro({ txt("swap"), MT_Expression, MF_Functional }); | ||||||
| 				CodeBody macro_swap = parse_global_body( txt(R"( | 				CodeDefine macro_swap = parse_define( txt(R"( | ||||||
| #define swap( a, b )        \ | #define swap( a, b )        \ | ||||||
| do                          \ | do                          \ | ||||||
| {                           \ | {                           \ | ||||||
| @@ -241,7 +345,8 @@ do                          \ | |||||||
| 		{ | 		{ | ||||||
| 			if ( str_contains(entry->Name, txt("Msg_Invalid_Value"))) | 			if ( str_contains(entry->Name, txt("Msg_Invalid_Value"))) | ||||||
| 			{ | 			{ | ||||||
| 				CodeDefine define = def_define(entry->Name, entry->Value->Content); | 				Opts_def_define opts = { {}, entry->Value->Content }; | ||||||
|  | 				CodeDefine define = def_define(entry->Name, MT_Expression, opts ); | ||||||
| 				header_printing.append(define); | 				header_printing.append(define); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| @@ -407,7 +512,8 @@ do                          \ | |||||||
| 			CodeVar var = cast(CodeVar, entry); | 			CodeVar var = cast(CodeVar, entry); | ||||||
| 			if (var->Specs.has(Spec_Constexpr) > -1) | 			if (var->Specs.has(Spec_Constexpr) > -1) | ||||||
| 			{ | 			{ | ||||||
| 				CodeDefine define = def_define(entry->Name, entry->Value->Content); | 				Opts_def_define opts = { {}, entry->Value->Content }; | ||||||
|  | 				CodeDefine define = def_define(entry->Name, MT_Expression, opts); | ||||||
| 				header_filesystem.append(define); | 				header_filesystem.append(define); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| @@ -811,7 +917,8 @@ R"(#define AST_ArrSpecs_Cap \ | |||||||
| 					ast.append(def); | 					ast.append(def); | ||||||
| 					break; | 					break; | ||||||
| 				} | 				} | ||||||
| 				CodeDefine def = def_define(var->Name, var->Value.to_strbuilder()); | 				Opts_def_define opts = { {}, var->Value.to_strbuilder() }; | ||||||
|  | 				CodeDefine def = def_define(var->Name, MT_Expression, opts ); | ||||||
| 				ast.append(def); | 				ast.append(def); | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| @@ -832,6 +939,7 @@ R"(#define AST_ArrSpecs_Cap \ | |||||||
| 		txt("CodeClass"), | 		txt("CodeClass"), | ||||||
| 		txt("CodeConstructor"), | 		txt("CodeConstructor"), | ||||||
| 		txt("CodeDefine"), | 		txt("CodeDefine"), | ||||||
|  | 		txt("CodeDefineParams"), | ||||||
| 		txt("CodeDestructor"), | 		txt("CodeDestructor"), | ||||||
| 		txt("CodeEnum"), | 		txt("CodeEnum"), | ||||||
| 		txt("CodeExec"), | 		txt("CodeExec"), | ||||||
| @@ -1209,8 +1317,10 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 			if (var->Specs) | 			if (var->Specs) | ||||||
| 			{ | 			{ | ||||||
| 				s32 constexpr_found = var->Specs.remove( Spec_Constexpr ); | 				s32 constexpr_found = var->Specs.remove( Spec_Constexpr ); | ||||||
| 				if (constexpr_found > -1) { | 				if (constexpr_found > -1) | ||||||
| 					CodeDefine define = def_define(entry->Name, entry->Value->Content); | 				{ | ||||||
|  | 					Opts_def_define opts = { {},  entry->Value->Content }; | ||||||
|  | 					CodeDefine define = def_define(entry->Name, MT_Expression, opts ); | ||||||
| 					header_end.append(define); | 					header_end.append(define); | ||||||
| 					continue; | 					continue; | ||||||
| 				} | 				} | ||||||
|   | |||||||
| @@ -325,6 +325,7 @@ word CodeComment,        gen_CodeComment | |||||||
| word CodeClass,          gen_CodeClass | word CodeClass,          gen_CodeClass | ||||||
| word CodeConstructor,    gen_CodeConstructor | word CodeConstructor,    gen_CodeConstructor | ||||||
| word CodeDefine,         gen_CodeDefine | word CodeDefine,         gen_CodeDefine | ||||||
|  | word CodeDefineParams,   gen_CodeDefineParams | ||||||
| word CodeDestructor,     gen_CodeDestructor | word CodeDestructor,     gen_CodeDestructor | ||||||
| word CodeEnum,           gen_CodeEnum | word CodeEnum,           gen_CodeEnum | ||||||
| word CodeExec,           gen_CodeExec | word CodeExec,           gen_CodeExec | ||||||
|   | |||||||
| @@ -22,9 +22,9 @@ 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) gen_Array_##Type\n")); | 	Code type_define  = untyped_str( txt( "#define Array(Type) gen_Array_##Type\n")); | ||||||
|  |  | ||||||
| 	Code array_begin = def_define(txt("array_begin(array)"),       code( (array) )); | 	Code array_begin = def_define(txt("array_begin(array)"),       MT_Expression, { {}, code( (array) ) } ); | ||||||
| 	Code array_end   = def_define(txt("array_end(array)"),         code( (array + array_get_header(array)->Num ) )); | 	Code array_end   = def_define(txt("array_end(array)"),         MT_Expression, { {}, code( (array + array_get_header(array)->Num ) ) } ); | ||||||
| 	Code array_next  = def_define(txt("array_next(array, entry)"), code( (entry + 1) )); | 	Code array_next  = def_define(txt("array_next(array, entry)"), MT_Expression, { {}, code( (entry + 1) ) } ); | ||||||
|  |  | ||||||
| 	return def_global_body( args( | 	return def_global_body( args( | ||||||
| 		fmt_newline, | 		fmt_newline, | ||||||
|   | |||||||
| @@ -89,7 +89,14 @@ CodeBody gen_fixed_arenas() | |||||||
| 	result.append(arena_interface_2mb); | 	result.append(arena_interface_2mb); | ||||||
| 	result.append(arena_interface_4mb); | 	result.append(arena_interface_4mb); | ||||||
|  |  | ||||||
| 	CodeDefine def = def_define(txt("fixed_arena_allocator_info(fixed_arena)"), txt("( (AllocatorInfo) { arena_allocator_proc, & (fixed_arena)->arena } )")); | 	register_preprocess_macros( args( | ||||||
|  | 		( PreprocessorMacro { txt("fixed_arena_allocator_info"), MT_Expression, MF_Functional }), | ||||||
|  | 		( PreprocessorMacro { txt("fixed_arena_init"),           MT_Expression, MF_Functional }), | ||||||
|  | 		( PreprocessorMacro { txt("fixed_arena_free"),           MT_Expression, MF_Functional }), | ||||||
|  | 		( PreprocessorMacro { txt("fixed_arena_size_remaining"), MT_Expression, MF_Functional }) | ||||||
|  | 	)); | ||||||
|  |  | ||||||
|  | 	CodeDefine def = parse_define(txt("#define fixed_arena_allocator_info(fixed_arena) ( (AllocatorInfo) { arena_allocator_proc, & (fixed_arena)->arena } )\n")); | ||||||
| 	result.append(def); | 	result.append(def); | ||||||
| 	result.append(fmt_newline); | 	result.append(fmt_newline); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ void convert_cpp_enum_to_c( CodeEnum to_convert, CodeBody to_append ) | |||||||
| { | { | ||||||
| #pragma push_macro("enum_underlying") | #pragma push_macro("enum_underlying") | ||||||
| #undef enum_underlying | #undef enum_underlying | ||||||
| 	StrCached type = to_convert->UnderlyingType ? to_convert->UnderlyingType : to_convert->Name | 	StrCached type = to_convert->UnderlyingType ? to_convert->UnderlyingType.to_strbuilder().to_str() : to_convert->Name; | ||||||
| 	CodeTypedef tdef = parse_typedef(token_fmt("type", type, "name", to_convert->Name, stringize( typedef enum <type> <name>; ))); | 	CodeTypedef tdef = parse_typedef(token_fmt("type", type, "name", to_convert->Name, stringize( typedef enum <type> <name>; ))); | ||||||
| 	if (to_convert->UnderlyingType) | 	if (to_convert->UnderlyingType) | ||||||
| 	{ | 	{ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user