mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-10-31 15:00:53 -07:00 
			
		
		
		
	WIP: more progress on new macro handling
This commit is contained in:
		| @@ -36,7 +36,6 @@ Str code_debug_str(Code self) | |||||||
| 		case CT_Execution: | 		case CT_Execution: | ||||||
| 		case CT_Comment: | 		case CT_Comment: | ||||||
| 		case CT_PlatformAttributes: | 		case CT_PlatformAttributes: | ||||||
| 		case CT_Preprocess_Define: |  | ||||||
| 		case CT_Preprocess_Include: | 		case CT_Preprocess_Include: | ||||||
| 		case CT_Preprocess_Pragma: | 		case CT_Preprocess_Pragma: | ||||||
| 		case CT_Preprocess_If: | 		case CT_Preprocess_If: | ||||||
| @@ -52,6 +51,11 @@ Str code_debug_str(Code self) | |||||||
| 			strbuilder_append_fmt( result, "\n\tContent: %S", self->Content ); | 			strbuilder_append_fmt( result, "\n\tContent: %S", self->Content ); | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
|  | 		case CT_Preprocess_Define: | ||||||
|  | 			// TODO(ED): Needs implementaton | ||||||
|  | 			log_failure("code_debug_str: NOT IMPLEMENTED for CT_Preprocess_Define"); | ||||||
|  | 		break; | ||||||
|  |  | ||||||
| 		case CT_Class: | 		case CT_Class: | ||||||
| 		case CT_Struct: | 		case CT_Struct: | ||||||
| 			if ( self->Prev ) | 			if ( self->Prev ) | ||||||
| @@ -259,6 +263,11 @@ Str code_debug_str(Code self) | |||||||
| 			strbuilder_append_fmt( result, "\n\tValue     : %S", self->Value     ? strbuilder_to_str( code_to_strbuilder(self->Value))     : txt("Null") ); | 			strbuilder_append_fmt( result, "\n\tValue     : %S", self->Value     ? strbuilder_to_str( code_to_strbuilder(self->Value))     : txt("Null") ); | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
|  | 		case CT_Parameters_Define: | ||||||
|  | 			// TODO(ED): Needs implementaton | ||||||
|  | 			log_failure("code_debug_str: NOT IMPLEMENTED for CT_Parameters_Define"); | ||||||
|  | 		break; | ||||||
|  |  | ||||||
| 		case CT_Specifiers: | 		case CT_Specifiers: | ||||||
| 		{ | 		{ | ||||||
| 			strbuilder_append_fmt( result, "\n\tNumEntries: %d", self->NumEntries ); | 			strbuilder_append_fmt( result, "\n\tNumEntries: %d", self->NumEntries ); | ||||||
| @@ -497,6 +506,10 @@ void code_to_strbuilder_ptr( Code self, StrBuilder* result ) | |||||||
| 			params_to_strbuilder_ref(cast(CodeParams, self), result ); | 			params_to_strbuilder_ref(cast(CodeParams, self), result ); | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
|  | 		case CT_Parameters_Define: | ||||||
|  | 			define_params_to_strbuilder_ref(cast(CodeDefineParams, self), result); | ||||||
|  | 		break; | ||||||
|  |  | ||||||
| 		case CT_Preprocess_Define: | 		case CT_Preprocess_Define: | ||||||
| 			define_to_strbuilder_ref(cast(CodeDefine, self), result ); | 			define_to_strbuilder_ref(cast(CodeDefine, self), result ); | ||||||
| 		break; | 		break; | ||||||
| @@ -987,11 +1000,17 @@ bool code_is_equal( Code self, Code other ) | |||||||
| 			return true; | 			return true; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		case CT_Parameters_Define: | ||||||
|  | 		{ | ||||||
|  | 			// TODO(ED): Needs implementaton | ||||||
|  | 			log_failure("code_is_equal: NOT IMPLEMENTED for CT_Parameters_Define"); | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		case CT_Preprocess_Define: | 		case CT_Preprocess_Define: | ||||||
| 		{ | 		{ | ||||||
| 			check_member_str( Name ); | 			check_member_str( Name ); | ||||||
| 			check_member_content( Content ); | 			check_member_content( Body->Content ); | ||||||
|  |  | ||||||
| 			return true; | 			return true; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -176,7 +176,7 @@ void class_to_strbuilder_def( CodeClass self, StrBuilder* result ) | |||||||
| { | { | ||||||
| 	GEN_ASSERT(self); | 	GEN_ASSERT(self); | ||||||
|  |  | ||||||
| 	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) | 	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export )) | ||||||
| 		strbuilder_append_str( result, txt("export ") ); | 		strbuilder_append_str( result, txt("export ") ); | ||||||
|  |  | ||||||
| 	strbuilder_append_str( result, txt("class ") ); | 	strbuilder_append_str( result, txt("class ") ); | ||||||
| @@ -221,7 +221,7 @@ void class_to_strbuilder_fwd( CodeClass self, StrBuilder* result ) | |||||||
| { | { | ||||||
| 	GEN_ASSERT(self); | 	GEN_ASSERT(self); | ||||||
|  |  | ||||||
| 	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) | 	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export )) | ||||||
| 		strbuilder_append_str( result, txt("export ") ); | 		strbuilder_append_str( result, txt("export ") ); | ||||||
|  |  | ||||||
| 	if ( self->Attributes ) | 	if ( self->Attributes ) | ||||||
| @@ -241,12 +241,48 @@ void class_to_strbuilder_fwd( CodeClass self, StrBuilder* result ) | |||||||
|  |  | ||||||
| StrBuilder define_to_strbuilder(CodeDefine define) | StrBuilder define_to_strbuilder(CodeDefine define) | ||||||
| { | { | ||||||
| 	return strbuilder_fmt_buf( _ctx->Allocator_Temp, "#define %S %S", define->Name, define->Content ); | 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 ); | ||||||
|  | 	define_to_strbuilder_ref(define, & result); | ||||||
|  | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| void define_to_strbuilder_ref(CodeDefine define, StrBuilder* result ) | void define_to_strbuilder_ref(CodeDefine define, StrBuilder* result ) | ||||||
| { | { | ||||||
| 	strbuilder_append_fmt( result, "#define %S %S", define->Name, define->Content ); | 	GEN_ASSERT(define); | ||||||
|  | 	GEN_ASSERT(define->Body); | ||||||
|  | 	GEN_ASSERT(define->Body->Content); | ||||||
|  | 	if (define->Params) { | ||||||
|  | 		StrBuilder params_builder = define_params_to_strbuilder(define->Params) | ||||||
|  | 		strbuilder_append_fmt( result, "#define %S(%S) %S", define->Name, strbuilder_to_str(params_builder), define->Body->Content ); | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 		strbuilder_append_fmt( result, "#define %S %S", define->Name, define->Body->Content ); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | StrBuilder define_params_to_strbuilder(CodeDefineParams params) | ||||||
|  | { | ||||||
|  | 	GEN_ASSERT(params); | ||||||
|  | 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 ); | ||||||
|  | 	define_params_to_strbuilder_ref( params, & result ); | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void define_params_to_strbuilder_ref(CodeDefineParams params, StrBuilder* result) | ||||||
|  | { | ||||||
|  | 	GEN_ASSERT(self); | ||||||
|  | 	GEN_ASSERT(result); | ||||||
|  | 	if ( self->Name.Ptr && self->Name.Len ) | ||||||
|  | 	{ | ||||||
|  | 		strbuilder_append_fmt( result, " %S", self->Name ); | ||||||
|  | 	} | ||||||
|  | 	if ( self->NumEntries - 1 > 0 ) | ||||||
|  | 	{ | ||||||
|  | 		for ( CodeParams param = begin_CodeDefineParams(self->Next); param != end_CodeDefineParams(self->Next); param = next_CodeDefineParams(self->Next, param) ) | ||||||
|  | 		{ | ||||||
|  | 			strbuilder_append_fmt( result, ", %SB", params_to_strbuilder(param) ); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| StrBuilder destructor_to_strbuilder(CodeDestructor self) | StrBuilder destructor_to_strbuilder(CodeDestructor self) | ||||||
| @@ -329,7 +365,7 @@ StrBuilder enum_to_strbuilder(CodeEnum self) | |||||||
|  |  | ||||||
| void enum_to_strbuilder_def(CodeEnum self, StrBuilder* result ) | void enum_to_strbuilder_def(CodeEnum self, StrBuilder* result ) | ||||||
| { | { | ||||||
| 	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) | 	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export )) | ||||||
| 		strbuilder_append_str( result, txt("export ") ); | 		strbuilder_append_str( result, txt("export ") ); | ||||||
|  |  | ||||||
| 	if ( self->Attributes || self->UnderlyingType || self->UnderlyingTypeMacro ) | 	if ( self->Attributes || self->UnderlyingType || self->UnderlyingTypeMacro ) | ||||||
| @@ -362,7 +398,7 @@ void enum_to_strbuilder_def(CodeEnum self, StrBuilder* result ) | |||||||
|  |  | ||||||
| void enum_to_strbuilder_fwd(CodeEnum self, StrBuilder* result ) | void enum_to_strbuilder_fwd(CodeEnum self, StrBuilder* result ) | ||||||
| { | { | ||||||
| 	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) | 	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export )) | ||||||
| 		strbuilder_append_str( result, txt("export ") ); | 		strbuilder_append_str( result, txt("export ") ); | ||||||
|  |  | ||||||
| 	if ( self->Attributes ) | 	if ( self->Attributes ) | ||||||
| @@ -389,7 +425,7 @@ void enum_to_strbuilder_fwd(CodeEnum self, StrBuilder* result ) | |||||||
|  |  | ||||||
| void enum_to_strbuilder_class_def(CodeEnum self, StrBuilder* result ) | void enum_to_strbuilder_class_def(CodeEnum self, StrBuilder* result ) | ||||||
| { | { | ||||||
| 	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) | 	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export )) | ||||||
| 		strbuilder_append_str( result, txt("export ") ); | 		strbuilder_append_str( result, txt("export ") ); | ||||||
|  |  | ||||||
| 	if ( self->Attributes || self->UnderlyingType ) | 	if ( self->Attributes || self->UnderlyingType ) | ||||||
| @@ -421,7 +457,7 @@ void enum_to_strbuilder_class_def(CodeEnum self, StrBuilder* result ) | |||||||
|  |  | ||||||
| void enum_to_strbuilder_class_fwd(CodeEnum self, StrBuilder* result ) | void enum_to_strbuilder_class_fwd(CodeEnum self, StrBuilder* result ) | ||||||
| { | { | ||||||
| 	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) | 	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export )) | ||||||
| 		strbuilder_append_str( result, txt("export ") ); | 		strbuilder_append_str( result, txt("export ") ); | ||||||
|  |  | ||||||
| 	strbuilder_append_str( result, txt("enum class ") ); | 	strbuilder_append_str( result, txt("enum class ") ); | ||||||
| @@ -505,7 +541,7 @@ StrBuilder fn_to_strbuilder(CodeFn self) | |||||||
|  |  | ||||||
| void fn_to_strbuilder_def(CodeFn self, StrBuilder* result ) | void fn_to_strbuilder_def(CodeFn self, StrBuilder* result ) | ||||||
| { | { | ||||||
| 	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) | 	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export )) | ||||||
| 		strbuilder_append_str( result, txt("export") ); | 		strbuilder_append_str( result, txt("export") ); | ||||||
|  |  | ||||||
| 	if ( self->Attributes ) | 	if ( self->Attributes ) | ||||||
| @@ -558,7 +594,7 @@ void fn_to_strbuilder_def(CodeFn self, StrBuilder* result ) | |||||||
|  |  | ||||||
| void fn_to_strbuilder_fwd(CodeFn self, StrBuilder* result ) | void fn_to_strbuilder_fwd(CodeFn self, StrBuilder* result ) | ||||||
| { | { | ||||||
| 	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) | 	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export )) | ||||||
| 		strbuilder_append_str( result, txt("export ") ); | 		strbuilder_append_str( result, txt("export ") ); | ||||||
|  |  | ||||||
| 	if ( self->Attributes ) | 	if ( self->Attributes ) | ||||||
| @@ -646,7 +682,7 @@ StrBuilder namespace_to_strbuilder(CodeNS self) | |||||||
|  |  | ||||||
| void namespace_to_strbuilder_ref(CodeNS self, StrBuilder* result ) | void namespace_to_strbuilder_ref(CodeNS self, StrBuilder* result ) | ||||||
| { | { | ||||||
| 	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) | 	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export )) | ||||||
| 		strbuilder_append_str( result, txt("export ") ); | 		strbuilder_append_str( result, txt("export ") ); | ||||||
|  |  | ||||||
| 	strbuilder_append_fmt( result, "namespace %S\n{\n%SB\n}\n", self->Name, body_to_strbuilder(self->Body) ); | 	strbuilder_append_fmt( result, "namespace %S\n{\n%SB\n}\n", self->Name, body_to_strbuilder(self->Body) ); | ||||||
| @@ -671,7 +707,7 @@ StrBuilder code_op_to_strbuilder(CodeOperator self) | |||||||
|  |  | ||||||
| void code_op_to_strbuilder_def(CodeOperator self, StrBuilder* result ) | void code_op_to_strbuilder_def(CodeOperator self, StrBuilder* result ) | ||||||
| { | { | ||||||
| 	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) | 	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export )) | ||||||
| 		strbuilder_append_str( result, txt("export ") ); | 		strbuilder_append_str( result, txt("export ") ); | ||||||
|  |  | ||||||
| 	if ( self->Attributes ) | 	if ( self->Attributes ) | ||||||
| @@ -725,7 +761,7 @@ void code_op_to_strbuilder_def(CodeOperator self, StrBuilder* result ) | |||||||
|  |  | ||||||
| void code_op_to_strbuilder_fwd(CodeOperator self, StrBuilder* result ) | void code_op_to_strbuilder_fwd(CodeOperator self, StrBuilder* result ) | ||||||
| { | { | ||||||
| 	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) | 	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export )) | ||||||
| 		strbuilder_append_str( result, txt("export ") ); | 		strbuilder_append_str( result, txt("export ") ); | ||||||
|  |  | ||||||
| 	if ( self->Attributes ) | 	if ( self->Attributes ) | ||||||
| @@ -865,7 +901,6 @@ void opcast_to_strbuilder_fwd(CodeOpCast self, StrBuilder* result ) | |||||||
|  |  | ||||||
| StrBuilder params_to_strbuilder(CodeParams self) | StrBuilder params_to_strbuilder(CodeParams self) | ||||||
| { | { | ||||||
| 	GEN_ASSERT(self); |  | ||||||
| 	GEN_ASSERT(self); | 	GEN_ASSERT(self); | ||||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 ); | 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 ); | ||||||
| 	params_to_strbuilder_ref( self, & result ); | 	params_to_strbuilder_ref( self, & result ); | ||||||
| @@ -1030,7 +1065,7 @@ void struct_to_strbuilder_def( CodeStruct self, StrBuilder* result ) | |||||||
| { | { | ||||||
| 	GEN_ASSERT(self); | 	GEN_ASSERT(self); | ||||||
| 	GEN_ASSERT(result); | 	GEN_ASSERT(result); | ||||||
| 	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) | 	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export )) | ||||||
| 		strbuilder_append_str( result, txt("export ") ); | 		strbuilder_append_str( result, txt("export ") ); | ||||||
|  |  | ||||||
| 	strbuilder_append_str( result, txt("struct ") ); | 	strbuilder_append_str( result, txt("struct ") ); | ||||||
| @@ -1076,7 +1111,7 @@ void struct_to_strbuilder_fwd( CodeStruct self, StrBuilder* result ) | |||||||
| { | { | ||||||
| 	GEN_ASSERT(self); | 	GEN_ASSERT(self); | ||||||
| 	GEN_ASSERT(result); | 	GEN_ASSERT(result); | ||||||
| 	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) | 	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export )) | ||||||
| 		strbuilder_append_str( result, txt("export ") ); | 		strbuilder_append_str( result, txt("export ") ); | ||||||
|  |  | ||||||
| 	if ( self->Attributes ) | 	if ( self->Attributes ) | ||||||
| @@ -1105,7 +1140,7 @@ void template_to_strbuilder_ref(CodeTemplate self, StrBuilder* result ) | |||||||
| { | { | ||||||
| 	GEN_ASSERT(self); | 	GEN_ASSERT(self); | ||||||
| 	GEN_ASSERT(result); | 	GEN_ASSERT(result); | ||||||
| 	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) | 	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export )) | ||||||
| 		strbuilder_append_str( result, txt("export ") ); | 		strbuilder_append_str( result, txt("export ") ); | ||||||
|  |  | ||||||
| 	if ( self->Params ) | 	if ( self->Params ) | ||||||
| @@ -1123,7 +1158,7 @@ StrBuilder typedef_to_strbuilder(CodeTypedef self) | |||||||
|  |  | ||||||
| void typedef_to_strbuilder_ref(CodeTypedef self, StrBuilder* result ) | void typedef_to_strbuilder_ref(CodeTypedef self, StrBuilder* result ) | ||||||
| { | { | ||||||
| 	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) | 	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export )) | ||||||
| 		strbuilder_append_str( result, txt("export ") ); | 		strbuilder_append_str( result, txt("export ") ); | ||||||
|  |  | ||||||
| 	strbuilder_append_str( result, txt("typedef ")); | 	strbuilder_append_str( result, txt("typedef ")); | ||||||
| @@ -1236,7 +1271,7 @@ StrBuilder union_to_strbuilder(CodeUnion self) | |||||||
|  |  | ||||||
| void union_to_strbuilder_def(CodeUnion self, StrBuilder* result ) | void union_to_strbuilder_def(CodeUnion self, StrBuilder* result ) | ||||||
| { | { | ||||||
| 	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) | 	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export )) | ||||||
| 		strbuilder_append_str( result, txt("export ") ); | 		strbuilder_append_str( result, txt("export ") ); | ||||||
|  |  | ||||||
| 	strbuilder_append_str( result, txt("union ") ); | 	strbuilder_append_str( result, txt("union ") ); | ||||||
| @@ -1267,7 +1302,7 @@ void union_to_strbuilder_fwd(CodeUnion self, StrBuilder* result ) | |||||||
| { | { | ||||||
| 	GEN_ASSERT(self); | 	GEN_ASSERT(self); | ||||||
| 	GEN_ASSERT(result); | 	GEN_ASSERT(result); | ||||||
| 	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) | 	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export )) | ||||||
| 		strbuilder_append_str( result, txt("export ") ); | 		strbuilder_append_str( result, txt("export ") ); | ||||||
|  |  | ||||||
| 	strbuilder_append_str( result, txt("union ") ); | 	strbuilder_append_str( result, txt("union ") ); | ||||||
| @@ -1304,7 +1339,7 @@ void using_to_strbuilder_ref(CodeUsing self, StrBuilder* result ) | |||||||
| { | { | ||||||
| 	GEN_ASSERT(self); | 	GEN_ASSERT(self); | ||||||
| 	GEN_ASSERT(result); | 	GEN_ASSERT(result); | ||||||
| 	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) | 	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export )) | ||||||
| 		strbuilder_append_str( result, txt("export ") ); | 		strbuilder_append_str( result, txt("export ") ); | ||||||
|  |  | ||||||
| 	if ( self->Attributes ) | 	if ( self->Attributes ) | ||||||
| @@ -1401,7 +1436,7 @@ void var_to_strbuilder_ref(CodeVar self, StrBuilder* result ) | |||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) | 	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export )) | ||||||
| 		strbuilder_append_str( result, txt("export ") ); | 		strbuilder_append_str( result, txt("export ") ); | ||||||
|  |  | ||||||
| 	if ( self->Attributes || self->Specs ) | 	if ( self->Attributes || self->Specs ) | ||||||
|   | |||||||
| @@ -46,6 +46,7 @@ enum CodeType : u32 | |||||||
| 	CT_Operator_Cast, | 	CT_Operator_Cast, | ||||||
| 	CT_Operator_Cast_Fwd, | 	CT_Operator_Cast_Fwd, | ||||||
| 	CT_Parameters, | 	CT_Parameters, | ||||||
|  | 	CT_Parameters_Define, | ||||||
| 	CT_Preprocess_Define, | 	CT_Preprocess_Define, | ||||||
| 	CT_Preprocess_Include, | 	CT_Preprocess_Include, | ||||||
| 	CT_Preprocess_If, | 	CT_Preprocess_If, | ||||||
| @@ -114,6 +115,7 @@ inline Str codetype_to_str( CodeType type ) | |||||||
| 		{ "Operator_Cast",       sizeof( "Operator_Cast" ) - 1       }, | 		{ "Operator_Cast",       sizeof( "Operator_Cast" ) - 1       }, | ||||||
| 		{ "Operator_Cast_Fwd",   sizeof( "Operator_Cast_Fwd" ) - 1   }, | 		{ "Operator_Cast_Fwd",   sizeof( "Operator_Cast_Fwd" ) - 1   }, | ||||||
| 		{ "Parameters",          sizeof( "Parameters" ) - 1          }, | 		{ "Parameters",          sizeof( "Parameters" ) - 1          }, | ||||||
|  | 		{ "Parameters_Define",   sizeof( "Parameters_Define" ) - 1   }, | ||||||
| 		{ "Preprocess_Define",   sizeof( "Preprocess_Define" ) - 1   }, | 		{ "Preprocess_Define",   sizeof( "Preprocess_Define" ) - 1   }, | ||||||
| 		{ "Preprocess_Include",  sizeof( "Preprocess_Include" ) - 1  }, | 		{ "Preprocess_Include",  sizeof( "Preprocess_Include" ) - 1  }, | ||||||
| 		{ "Preprocess_If",       sizeof( "Preprocess_If" ) - 1       }, | 		{ "Preprocess_If",       sizeof( "Preprocess_If" ) - 1       }, | ||||||
| @@ -182,6 +184,7 @@ inline Str codetype_to_keyword_str( CodeType type ) | |||||||
| 		{ "operator",        sizeof( "operator" ) - 1        }, | 		{ "operator",        sizeof( "operator" ) - 1        }, | ||||||
| 		{ "operator",        sizeof( "operator" ) - 1        }, | 		{ "operator",        sizeof( "operator" ) - 1        }, | ||||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
|  | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ "define",          sizeof( "define" ) - 1          }, | 		{ "define",          sizeof( "define" ) - 1          }, | ||||||
| 		{ "include",         sizeof( "include" ) - 1         }, | 		{ "include",         sizeof( "include" ) - 1         }, | ||||||
| 		{ "if",              sizeof( "if" ) - 1              }, | 		{ "if",              sizeof( "if" ) - 1              }, | ||||||
|   | |||||||
| @@ -53,6 +53,7 @@ enum TokType : u32 | |||||||
| 	Tok_Operator, | 	Tok_Operator, | ||||||
| 	Tok_Preprocess_Hash, | 	Tok_Preprocess_Hash, | ||||||
| 	Tok_Preprocess_Define, | 	Tok_Preprocess_Define, | ||||||
|  | 	Tok_Preprocess_Define_Param, | ||||||
| 	Tok_Preprocess_If, | 	Tok_Preprocess_If, | ||||||
| 	Tok_Preprocess_IfDef, | 	Tok_Preprocess_IfDef, | ||||||
| 	Tok_Preprocess_IfNotDef, | 	Tok_Preprocess_IfNotDef, | ||||||
| @@ -62,7 +63,9 @@ enum TokType : u32 | |||||||
| 	Tok_Preprocess_Include, | 	Tok_Preprocess_Include, | ||||||
| 	Tok_Preprocess_Pragma, | 	Tok_Preprocess_Pragma, | ||||||
| 	Tok_Preprocess_Content, | 	Tok_Preprocess_Content, | ||||||
| 	Tok_Preprocess_Macro, | 	Tok_Preprocess_Macro_Expr, | ||||||
|  | 	Tok_Preprocess_Macro_Stmt, | ||||||
|  | 	Tok_Preprocess_Macro_Typename, | ||||||
| 	Tok_Preprocess_Unsupported, | 	Tok_Preprocess_Unsupported, | ||||||
| 	Tok_Spec_Alignas, | 	Tok_Spec_Alignas, | ||||||
| 	Tok_Spec_Const, | 	Tok_Spec_Const, | ||||||
| @@ -155,6 +158,7 @@ inline Str toktype_to_str( TokType type ) | |||||||
| 		{ "__operator__",      sizeof( "__operator__" ) - 1      }, | 		{ "__operator__",      sizeof( "__operator__" ) - 1      }, | ||||||
| 		{ "#",		         sizeof( "#" ) - 1                 }, | 		{ "#",		         sizeof( "#" ) - 1                 }, | ||||||
| 		{ "define",            sizeof( "define" ) - 1            }, | 		{ "define",            sizeof( "define" ) - 1            }, | ||||||
|  | 		{ "__define_param__",  sizeof( "__define__param__" ) - 1  }, | ||||||
| 		{ "if",		        sizeof( "if" ) - 1                }, | 		{ "if",		        sizeof( "if" ) - 1                }, | ||||||
| 		{ "ifdef",             sizeof( "ifdef" ) - 1             }, | 		{ "ifdef",             sizeof( "ifdef" ) - 1             }, | ||||||
| 		{ "ifndef",            sizeof( "ifndef" ) - 1            }, | 		{ "ifndef",            sizeof( "ifndef" ) - 1            }, | ||||||
| @@ -164,7 +168,9 @@ inline Str toktype_to_str( TokType type ) | |||||||
| 		{ "include",           sizeof( "include" ) - 1           }, | 		{ "include",           sizeof( "include" ) - 1           }, | ||||||
| 		{ "pragma",            sizeof( "pragma" ) - 1            }, | 		{ "pragma",            sizeof( "pragma" ) - 1            }, | ||||||
| 		{ "__macro_content__", sizeof( "__macro_content__" ) - 1 }, | 		{ "__macro_content__", sizeof( "__macro_content__" ) - 1 }, | ||||||
| 		{ "__macro__",         sizeof( "__macro__" ) - 1         }, | 		{ "__macro_expression__", sizeof( "__macro_expression__" ) - 1         }, | ||||||
|  | 		{ "__macro_statment__",   sizeof( "__macro_statment__" ) - 1         }, | ||||||
|  | 		{ "__macro_typename__",   sizeof( "__macro_typename__" ) - 1         }, | ||||||
| 		{ "__unsupported__",   sizeof( "__unsupported__" ) - 1   }, | 		{ "__unsupported__",   sizeof( "__unsupported__" ) - 1   }, | ||||||
| 		{ "alignas",           sizeof( "alignas" ) - 1           }, | 		{ "alignas",           sizeof( "alignas" ) - 1           }, | ||||||
| 		{ "const",             sizeof( "const" ) - 1             }, | 		{ "const",             sizeof( "const" ) - 1             }, | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ | |||||||
|  |  | ||||||
| #pragma region Constants | #pragma region Constants | ||||||
|  |  | ||||||
| extern Str enum_underlying_sig; | extern PreprocessorMacro enum_underlying_macro; | ||||||
|  |  | ||||||
| extern Code access_public; | extern Code access_public; | ||||||
| extern Code access_protected; | extern Code access_protected; | ||||||
|   | |||||||
| @@ -206,10 +206,12 @@ void define_constants() | |||||||
| 	spec_local_persist = def_specifiers( 1, Spec_Local_Persist ); | 	spec_local_persist = def_specifiers( 1, Spec_Local_Persist ); | ||||||
| 	code_set_global(cast(Code, spec_local_persist)); | 	code_set_global(cast(Code, spec_local_persist)); | ||||||
|  |  | ||||||
| 	if (enum_underlying_sig.Len == 0) { | 	if (enum_underlying_macro.Name.Len == 0) { | ||||||
| 		enum_underlying_sig = txt("enum_underlying("); | 		enum_underlying_macro.Name  = txt("enum_underlying("); | ||||||
|  | 		enum_underlying_macro.Type  = MT_Expression; | ||||||
|  | 		enum_underlying_macro.Flags = MF_Functional; | ||||||
| 	} | 	} | ||||||
| 	array_append( _ctx->PreprocessorDefines, enum_underlying_sig); | 	register_preprocess_macro(enum_underlying_macro); | ||||||
| } | } | ||||||
|  |  | ||||||
| void init(Context* ctx) | void init(Context* ctx) | ||||||
| @@ -301,9 +303,6 @@ void init(Context* ctx) | |||||||
| 			GEN_FATAL( "gen::init: Failed to initialize the code pool" ); | 			GEN_FATAL( "gen::init: Failed to initialize the code pool" ); | ||||||
| 		array_append( ctx->CodePools, code_pool ); | 		array_append( ctx->CodePools, code_pool ); | ||||||
|  |  | ||||||
| 		// TODO(Ed): This is going to be phased out most likely. |  | ||||||
| 		ctx->LexArena = arena_init_from_allocator( ctx->Allocator_DyanmicContainers, ctx->InitSize_LexArena ); |  | ||||||
|  |  | ||||||
| 		// TODO(Ed): Eventually the string arenas needs to be phased out for a dedicated string slab allocator | 		// TODO(Ed): Eventually the string arenas needs to be phased out for a dedicated string slab allocator | ||||||
| 		Arena strbuilder_arena = arena_init_from_allocator( ctx->Allocator_StrCache, ctx->SizePer_StringArena ); | 		Arena strbuilder_arena = arena_init_from_allocator( ctx->Allocator_StrCache, ctx->SizePer_StringArena ); | ||||||
| 		if ( strbuilder_arena.PhysicalStart == nullptr ) | 		if ( strbuilder_arena.PhysicalStart == nullptr ) | ||||||
| @@ -315,9 +314,12 @@ void init(Context* ctx) | |||||||
| 		ctx->StrCache = hashtable_init(StrCached, ctx->Allocator_DyanmicContainers); | 		ctx->StrCache = hashtable_init(StrCached, ctx->Allocator_DyanmicContainers); | ||||||
| 		if ( ctx->StrCache.Entries == nullptr ) | 		if ( ctx->StrCache.Entries == nullptr ) | ||||||
| 			GEN_FATAL( "gen::init: Failed to initialize the StringCache"); | 			GEN_FATAL( "gen::init: Failed to initialize the StringCache"); | ||||||
|  |  | ||||||
|  | 		ctx->PreprocessorMacros = hashtable_init(PreprocessorMacros, ctx->Allocator_DyanmicContainers); | ||||||
|  | 		if (ctx->PreprocessorMacros.Hashes == nullptr || ctx->PreprocessorMacros.Entries == nullptr) { | ||||||
|  | 			GEN_FATAL( "gen::init: Failed to initialize the PreprocessMacros table" ); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	// Preprocessor Defines |  | ||||||
| 	ctx->PreprocessorDefines = array_init_reserve(StrCached, ctx->Allocator_DyanmicContainers, kilobytes(1) ); |  | ||||||
|  |  | ||||||
| 	define_constants(); | 	define_constants(); | ||||||
| 	parser_init(); | 	parser_init(); | ||||||
| @@ -354,9 +356,7 @@ void deinit(Context* ctx) | |||||||
| 	array_free( ctx->CodePools); | 	array_free( ctx->CodePools); | ||||||
| 	array_free( ctx->StringArenas); | 	array_free( ctx->StringArenas); | ||||||
|  |  | ||||||
| 	// arena_free(& ctx->LexArena); | 	hashtable_destroy(ctx->PreprocessorMacros); | ||||||
|  |  | ||||||
| 	array_free(ctx->PreprocessorDefines); |  | ||||||
|  |  | ||||||
| 	left  = array_num( ctx->Fallback_AllocatorBuckets); | 	left  = array_num( ctx->Fallback_AllocatorBuckets); | ||||||
| 	if (left) | 	if (left) | ||||||
| @@ -401,6 +401,7 @@ void reset(Context* ctx) | |||||||
| 	while ( left--, left ); | 	while ( left--, left ); | ||||||
|  |  | ||||||
| 	hashtable_clear(ctx->StrCache); | 	hashtable_clear(ctx->StrCache); | ||||||
|  | 	hashtable_clear(ctx->PreprocessorMacros); | ||||||
| 	define_constants(); | 	define_constants(); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -156,6 +156,7 @@ GEN_API CodeConstructor def_constructor( Opts_def_constructor opts GEN_PARAM_DEF | |||||||
| struct Opts_def_define { | struct Opts_def_define { | ||||||
| 	MacroFlags       flags; | 	MacroFlags       flags; | ||||||
| 	CodeDefineParams params; | 	CodeDefineParams params; | ||||||
|  | 	Str              content; | ||||||
| 	b32              dont_register_to_preprocess_macros; | 	b32              dont_register_to_preprocess_macros; | ||||||
| }; | }; | ||||||
| GEN_API CodeDefine def_define( Str name, MacroType type, Opts_def_define opts GEN_PARAM_DEFAULT ); | GEN_API CodeDefine def_define( Str name, MacroType type, Opts_def_define opts GEN_PARAM_DEFAULT ); | ||||||
| @@ -269,28 +270,30 @@ GEN_API CodeBody def_body( CodeType type ); | |||||||
| // There are two options for defining a struct body, either varadically provided with the args macro to auto-deduce the arg num, | // There are two options for defining a struct body, either varadically provided with the args macro to auto-deduce the arg num, | ||||||
| /// or provide as an array of Code objects. | /// or provide as an array of Code objects. | ||||||
|  |  | ||||||
| GEN_API CodeBody       def_class_body      ( s32 num, ... ); | GEN_API CodeBody         def_class_body      ( s32 num, ... ); | ||||||
| GEN_API CodeBody       def_class_body      ( s32 num, Code* codes ); | GEN_API CodeBody         def_class_body      ( s32 num, Code* codes ); | ||||||
| GEN_API CodeBody       def_enum_body       ( s32 num, ... ); | GEN_API CodeDefineParams def_define_params   ( s32 num, ... ); | ||||||
| GEN_API CodeBody       def_enum_body       ( s32 num, Code* codes ); | GEN_API CodeDefineParams def_define_params   ( s32 num, CodeDefineParams* codes ) | ||||||
| GEN_API CodeBody       def_export_body     ( s32 num, ... ); | GEN_API CodeBody         def_enum_body       ( s32 num, ... ); | ||||||
| GEN_API CodeBody       def_export_body     ( s32 num, Code* codes); | GEN_API CodeBody         def_enum_body       ( s32 num, Code* codes ); | ||||||
| GEN_API CodeBody       def_extern_link_body( s32 num, ... ); | GEN_API CodeBody         def_export_body     ( s32 num, ... ); | ||||||
| GEN_API CodeBody       def_extern_link_body( s32 num, Code* codes ); | GEN_API CodeBody         def_export_body     ( s32 num, Code* codes); | ||||||
| GEN_API CodeBody       def_function_body   ( s32 num, ... ); | GEN_API CodeBody         def_extern_link_body( s32 num, ... ); | ||||||
| GEN_API CodeBody       def_function_body   ( s32 num, Code* codes ); | GEN_API CodeBody         def_extern_link_body( s32 num, Code* codes ); | ||||||
| GEN_API CodeBody       def_global_body     ( s32 num, ... ); | GEN_API CodeBody         def_function_body   ( s32 num, ... ); | ||||||
| GEN_API CodeBody       def_global_body     ( s32 num, Code* codes ); | GEN_API CodeBody         def_function_body   ( s32 num, Code* codes ); | ||||||
| GEN_API CodeBody       def_namespace_body  ( s32 num, ... ); | GEN_API CodeBody         def_global_body     ( s32 num, ... ); | ||||||
| GEN_API CodeBody       def_namespace_body  ( s32 num, Code* codes ); | GEN_API CodeBody         def_global_body     ( s32 num, Code* codes ); | ||||||
| GEN_API CodeParams     def_params          ( s32 num, ... ); | GEN_API CodeBody         def_namespace_body  ( s32 num, ... ); | ||||||
| GEN_API CodeParams     def_params          ( s32 num, CodeParams* params ); | GEN_API CodeBody         def_namespace_body  ( s32 num, Code* codes ); | ||||||
| GEN_API CodeSpecifiers def_specifiers      ( s32 num, ... ); | GEN_API CodeParams       def_params          ( s32 num, ... ); | ||||||
| GEN_API CodeSpecifiers def_specifiers      ( s32 num, Specifier* specs ); | GEN_API CodeParams       def_params          ( s32 num, CodeParams* params ); | ||||||
| GEN_API CodeBody       def_struct_body     ( s32 num, ... ); | GEN_API CodeSpecifiers   def_specifiers      ( s32 num, ... ); | ||||||
| GEN_API CodeBody       def_struct_body     ( s32 num, Code* codes ); | GEN_API CodeSpecifiers   def_specifiers      ( s32 num, Specifier* specs ); | ||||||
| GEN_API CodeBody       def_union_body      ( s32 num, ... ); | GEN_API CodeBody         def_struct_body     ( s32 num, ... ); | ||||||
| GEN_API CodeBody       def_union_body      ( s32 num, Code* codes ); | GEN_API CodeBody         def_struct_body     ( s32 num, Code* codes ); | ||||||
|  | GEN_API CodeBody         def_union_body      ( s32 num, ... ); | ||||||
|  | GEN_API CodeBody         def_union_body      ( s32 num, Code* codes ); | ||||||
|  |  | ||||||
| #pragma endregion Upfront | #pragma endregion Upfront | ||||||
|  |  | ||||||
|   | |||||||
| @@ -516,7 +516,6 @@ CodeClass def_class( Str name, Opts_def_struct p ) | |||||||
| 		GEN_DEBUG_TRAP(); | 		GEN_DEBUG_TRAP(); | ||||||
| 		return InvalidCode; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( p.attributes && p.attributes->Type != CT_PlatformAttributes ) { | 	if ( p.attributes && p.attributes->Type != CT_PlatformAttributes ) { | ||||||
| 		log_failure( "gen::def_class: attributes was not a 'PlatformAttributes' type: %s", code_debug_str(p.attributes) ); | 		log_failure( "gen::def_class: attributes was not a 'PlatformAttributes' type: %s", code_debug_str(p.attributes) ); | ||||||
| 		GEN_DEBUG_TRAP(); | 		GEN_DEBUG_TRAP(); | ||||||
| @@ -529,9 +528,12 @@ CodeClass def_class( Str name, Opts_def_struct p ) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeClass | 	CodeClass | ||||||
| 	result              = (CodeClass) make_code(); | 	result               = (CodeClass) make_code(); | ||||||
| 	result->Name        = cache_str( name ); | 	result->Name         = cache_str( name ); | ||||||
| 	result->ModuleFlags = p.mflags; | 	result->ModuleFlags  = p.mflags; | ||||||
|  | 	result->Attributes   = p.attributes; | ||||||
|  | 	result->ParentAccess = p.parent_access; | ||||||
|  | 	result->ParentType   = p.parent; | ||||||
| 	if ( p.body ) | 	if ( p.body ) | ||||||
| 	{ | 	{ | ||||||
| 		switch ( p.body->Type ) | 		switch ( p.body->Type ) | ||||||
| @@ -552,44 +554,32 @@ CodeClass def_class( Str name, Opts_def_struct p ) | |||||||
| 	else { | 	else { | ||||||
| 		result->Type = CT_Class_Fwd; | 		result->Type = CT_Class_Fwd; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	result->Attributes   = p.attributes; |  | ||||||
| 	result->ParentAccess = p.parent_access; |  | ||||||
| 	result->ParentType   = p.parent; |  | ||||||
|  |  | ||||||
| 	for (s32 idx = 0; idx < p.num_interfaces; idx++ ) { | 	for (s32 idx = 0; idx < p.num_interfaces; idx++ ) { | ||||||
| 		class_add_interface(result, p.interfaces[idx] ); | 		class_add_interface(result, p.interfaces[idx] ); | ||||||
| 	} | 	} | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeDefine def_define( Str name, Str content, Opts_def_define p ) | CodeDefine def_define( Str name, MacroType type, Opts_def_define p ) | ||||||
| { | { | ||||||
| 	if ( ! name_check( def_define, name ) ) { | 	if ( ! name_check( def_define, name ) ) { | ||||||
| 		GEN_DEBUG_TRAP(); | 		GEN_DEBUG_TRAP(); | ||||||
| 		return InvalidCode; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeDefine | 	CodeDefine | ||||||
| 	result          = (CodeDefine) make_code(); | 	result          = (CodeDefine) make_code(); | ||||||
| 	result->Type    = CT_Preprocess_Define; | 	result->Type    = CT_Preprocess_Define; | ||||||
| 	result->Name    = cache_str( name ); | 	result->Name    = cache_str( name ); | ||||||
|  | 	result->Params  = p.params; | ||||||
| 	if ( content.Len <= 0 || content.Ptr == nullptr ) | 	if ( p.content.Len <= 0 || p.content.Ptr == nullptr ) | ||||||
| 		result->Content = cache_str( txt("") ); | 		result->Content = cache_str( txt("\n") ); | ||||||
| 	else | 	else | ||||||
| 		result->Content = cache_str( strbuilder_to_str(strbuilder_fmt_buf(_ctx->Allocator_Temp, "%S\n", content)) ); | 		result->Content = cache_str( strbuilder_to_str(strbuilder_fmt_buf(_ctx->Allocator_Temp, "%S\n", content)) ); | ||||||
|  |  | ||||||
| 	b32  append_preprocess_defines = ! p.dont_append_preprocess_defines; | 	b32  register_define = ! p.dont_register_to_preprocess_macros; | ||||||
| 	if ( append_preprocess_defines ) { | 	if ( register_define ) { | ||||||
| 		// Add the define to PreprocessorDefines for usage in parsing | 		macro_entry = { result->Name, type, p.flags }; | ||||||
| 		s32 lex_id_len = 0; | 		register_preprocess_macro(macro_entry); | ||||||
| 		for (; lex_id_len < result->Name.Len; ++ lex_id_len ) { |  | ||||||
| 			if ( result->Name.Ptr[lex_id_len] == '(' ) |  | ||||||
| 				break; |  | ||||||
| 		} |  | ||||||
| 		Str lex_id = { result->Name.Ptr,  lex_id_len }; |  | ||||||
| 		array_append(_ctx->PreprocessorDefines, cache_str(lex_id) ); |  | ||||||
| 	} | 	} | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| @@ -1410,6 +1400,67 @@ CodeBody def_class_body( s32 num, Code* codes ) | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | CodeDefineParams def_define_params( s32 num, ... ) | ||||||
|  | { | ||||||
|  | 	def_body_start( def_define_params ); | ||||||
|  |  | ||||||
|  | 	va_list va; | ||||||
|  | 	va_start(va, num); | ||||||
|  |  | ||||||
|  | 	Code_POD         pod   = va_arg(va, Code_POD); | ||||||
|  | 	CodeDefineParams param = pcast( CodeDefineParams, pod ); | ||||||
|  |  | ||||||
|  | 	null_check( def_define_params, param ); | ||||||
|  | 	if ( param->Type != CT_Parameters_Define ) { | ||||||
|  | 		log_failure( "gen::def_define_params: param %d is not a parameter for a preprocessor define", num - num + 1 ); | ||||||
|  | 		return InvalidCode; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	CodeDefineParams result = (CodeDefineParams) code_duplicate(param); | ||||||
|  | 	while ( -- num ) | ||||||
|  | 	{ | ||||||
|  | 		pod   = va_arg(va, Code_POD); | ||||||
|  | 		param = pcast( CodeDefineParams, pod ); | ||||||
|  | 		if ( param->Type != CT_Parameters_Define ) { | ||||||
|  | 			log_failure( "gen::def_define_params: param %d is not a parameter for a preprocessor define", num - num + 1 ); | ||||||
|  | 			return InvalidCode; | ||||||
|  | 		} | ||||||
|  | 		define_params_append(result, param ); | ||||||
|  | 	} | ||||||
|  | 	va_end(va); | ||||||
|  |  | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | CodeDefineParams def_define_params( s32 num, CodeDefineParams* codes ) | ||||||
|  | { | ||||||
|  | 	def_body_code_array_start( def_define_params ); | ||||||
|  |  | ||||||
|  | #	define check_current(current)                                                                                                                 \ | ||||||
|  | 	if ( current == nullptr ) {                                                                                                                   \ | ||||||
|  | 		log_failure("gen::def_define_params: Provide a null code in codes array");                                                                \ | ||||||
|  | 		return InvalidCode;                                                                                                                       \ | ||||||
|  | 	}                                                                                                                                             \ | ||||||
|  | 	if (current->Type != CT_Parameters_Define ) {                                                                                                 \ | ||||||
|  | 		log_failure("gen::def_define_params: Code in coes array is not of paramter for preprocessor define type - %s", code_debug_str(current) ); \ | ||||||
|  | 		return InvalidCode;                                                                                                                       \ | ||||||
|  | 	} | ||||||
|  | 	CodeDefineParams current = (CodeDefineParams)code_duplicate(* codes); | ||||||
|  | 	check_current(current); | ||||||
|  |  | ||||||
|  | 	CodeDefineParams | ||||||
|  | 	result            = (CodeDefineParams) make_code(); | ||||||
|  | 	result->Name      = current->Name; | ||||||
|  | 	result->Type      = current->Type; | ||||||
|  | 	while( codes++, current = * codes, num--, num > 0 ) { | ||||||
|  | 		check_current(current); | ||||||
|  | 		define_params_append(result, current ); | ||||||
|  | 	} | ||||||
|  | #	undef check_current | ||||||
|  |  | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  |  | ||||||
| CodeBody def_enum_body( s32 num, ... ) | CodeBody def_enum_body( s32 num, ... ) | ||||||
| { | { | ||||||
| 	def_body_start( def_enum_body ); | 	def_body_start( def_enum_body ); | ||||||
|   | |||||||
| @@ -112,6 +112,102 @@ void lexer_end_line( LexContext* ctx ) | |||||||
| } | } | ||||||
| #define end_line() lexer_end_line(ctx) | #define end_line() lexer_end_line(ctx) | ||||||
|  |  | ||||||
|  | // TODO(Ed): We need to to attempt to recover from a lex failure? | ||||||
|  | s32 lex_preprocessor_define( LexContext* ctx ) | ||||||
|  | { | ||||||
|  | 	Token name = { { ctx->scanner, 1 }, Tok_Identifier, ctx->line, ctx->column, TF_Preprocess }; | ||||||
|  | 	move_forward(); | ||||||
|  |  | ||||||
|  | 	PreprocessorMacro  macro            = { name.Text, MT_Statement, 0 }; | ||||||
|  | 	PreprocessorMacro* registered_macro = lookup_preprocess_macro(name.Text); | ||||||
|  | 	if ( registered_macro == nullptr ) { | ||||||
|  | 		log_fmt("Warning: %S is was not registered before the lexer processed its #define directive, it will be registered as a statement macro" | ||||||
|  | 			, name.Text  | ||||||
|  | 		); | ||||||
|  | 	} | ||||||
|  | 	while ( ctx->left && ( char_is_alphanumeric((* ctx->scanner)) || (* ctx->scanner) == '_' ) ) { | ||||||
|  | 		move_forward(); | ||||||
|  | 		name.Text.Len++; | ||||||
|  | 	} | ||||||
|  | 	array_append( _ctx->Lexer_Tokens, name ); | ||||||
|  |  | ||||||
|  | 	if ( ctx->left && (* ctx->scanner) == '(' ) | ||||||
|  | 	{ | ||||||
|  | 		if (registered_macro && ! macro_is_functional(* registered_macro)) { | ||||||
|  | 			log_fmt("Warning: %S registered macro is not flagged as functional yet the definition detects opening parenthesis '(' for arguments" | ||||||
|  | 				, name.Text | ||||||
|  | 			); | ||||||
|  | 		} | ||||||
|  | 		else { | ||||||
|  | 			macro.Flags |= MF_Functional; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		Token opening_paren = { { ctx->scanner, 1 }, Tok_Capture_Start, ctx->line, ctx->column, TF_Preprocess }; | ||||||
|  | 		array_append( _ctx->Lexer_Tokens, opening_paren ); | ||||||
|  | 		move_forward(); | ||||||
|  |  | ||||||
|  | 		// We need to tokenize the define's arguments now: | ||||||
|  | 		while( ctx->left && * ctx->scanner != ')') | ||||||
|  | 		{ | ||||||
|  | 			skip_whitespace(); | ||||||
|  | 			if ( char_is_alpha( (* ctx->scanner) ) || (* ctx->scanner) == '_' ) | ||||||
|  | 			{ | ||||||
|  | 				Token parameter = { { ctx->scanner, 1 }, Tok_Preprocess_Define_Param, ctx->line, ctx->column, TF_Preprocess }; | ||||||
|  | 				move_forward(); | ||||||
|  |  | ||||||
|  | 				while ( ctx->left && ( char_is_alphanumeric((* ctx->scanner)) || (* ctx->scanner) == '_' ) ) | ||||||
|  | 				{ | ||||||
|  | 					move_forward(); | ||||||
|  | 					parameter.Text.Len++; | ||||||
|  | 				} | ||||||
|  | 				array_append(_ctx->Lexer_Tokens, parameter); | ||||||
|  | 				skip_whitespace(); | ||||||
|  | 			} | ||||||
|  | 			else { | ||||||
|  | 				log_failure("lex_preprocessor_define(%d, %d): Expected a '_' or alpha character for a parameter name for %S\n" | ||||||
|  | 					, ctx->line | ||||||
|  | 					, ctx->column | ||||||
|  | 					, name.Text | ||||||
|  | 				); | ||||||
|  | 				return Lex_ReturnNull; | ||||||
|  | 			} | ||||||
|  | 			// There should be a comma | ||||||
|  | 			if ( * ctx->scanner != ',' ) { | ||||||
|  | 				log_failure("lex_preprocessor_define(%d, %d): Expected a comma after parameter %S for %S\n" | ||||||
|  | 					, ctx->line | ||||||
|  | 					, ctx->column | ||||||
|  | 					, parameter.Text | ||||||
|  | 					, name.Text | ||||||
|  | 				); | ||||||
|  | 				return Lex_ReturnNull; | ||||||
|  | 			} | ||||||
|  | 			Token comma = { { ctx->scanner, 1 }, Tok_Comma, ctx->line, ctx->column, TF_Preprocess }; | ||||||
|  | 			array_append(_ctx->Lexer_Tokens, comma); | ||||||
|  | 			move_forward(); | ||||||
|  | 		} | ||||||
|  | 		 | ||||||
|  | 		if ( * ctx->scanner != ')' ) { | ||||||
|  | 			log_failure("lex_preprocessor_define(%d, %d): Expected a ')' after last_parameter %S for %S (ran out of characters...)\n" | ||||||
|  | 				, ctx->line | ||||||
|  | 				, ctx->column | ||||||
|  | 				, parameter.Text | ||||||
|  | 				, name.Text | ||||||
|  | 			); | ||||||
|  | 			return Lex_ReturnNull; | ||||||
|  | 		} | ||||||
|  | 		Token closing_paren = { { ctx->scanner, 1 }, Tok_Capture_End, ctx->line, ctx->column, TF_Preprocess }; | ||||||
|  | 		array_append(_ctx->Lexer_Tokens, closing_paren); | ||||||
|  | 		move_forward(); | ||||||
|  | 	} | ||||||
|  | 	if ( registered_macro == nullptr ) { | ||||||
|  | 		register_preprocess_macro(macro); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Define's content handled by lex_preprocessor_directive (the original caller of this) | ||||||
|  | 	return Lex_Continue; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // TODO(Ed): We need to to attempt to recover from a lex failure? | ||||||
| forceinline | forceinline | ||||||
| s32 lex_preprocessor_directive( LexContext* ctx ) | s32 lex_preprocessor_directive( LexContext* ctx ) | ||||||
| { | { | ||||||
| @@ -215,31 +311,9 @@ s32 lex_preprocessor_directive( LexContext* ctx ) | |||||||
|  |  | ||||||
| 	if ( ctx->token.Type == Tok_Preprocess_Define ) | 	if ( ctx->token.Type == Tok_Preprocess_Define ) | ||||||
| 	{ | 	{ | ||||||
| 		Token name = { { ctx->scanner, 0 }, Tok_Identifier, ctx->line, ctx->column, TF_Preprocess }; | 		u32 result = lex_preprocessor_define(ctx); // handles: #define <name>( <params> ) - define's content handled later on within this scope. | ||||||
|  | 		if (result != Lex_Continue) | ||||||
| 		name.Text.Ptr = ctx->scanner; | 			return Lex_ReturnNull; | ||||||
| 		name.Text.Len = 1; |  | ||||||
| 		move_forward(); |  | ||||||
|  |  | ||||||
| 		PreprocessorMacro* registered_macro = lookup_preprocess_macro(name.Text); |  | ||||||
| 		 |  | ||||||
|  |  | ||||||
| 		while ( ctx->left && ( char_is_alphanumeric((* ctx->scanner)) || (* ctx->scanner) == '_' ) ) |  | ||||||
| 		{ |  | ||||||
| 			move_forward(); |  | ||||||
| 			name.Text.Len++; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if ( ctx->left && (* ctx->scanner) == '(' ) |  | ||||||
| 		{ |  | ||||||
| 			move_forward(); |  | ||||||
| 			name.Text.Len++; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		array_append( _ctx->Lexer_Tokens, name ); |  | ||||||
|  |  | ||||||
| 		u64 key = crc32( name.Text.Ptr, name.Text.Len ); |  | ||||||
| 		hashtable_set(ctx->defines, key, tok_to_str(name) ); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Token preprocess_content = { { ctx->scanner, 0 }, Tok_Preprocess_Content, ctx->line, ctx->column, TF_Preprocess }; | 	Token preprocess_content = { { ctx->scanner, 0 }, Tok_Preprocess_Content, ctx->line, ctx->column, TF_Preprocess }; | ||||||
| @@ -289,7 +363,7 @@ s32 lex_preprocessor_directive( LexContext* ctx ) | |||||||
| 	s32 within_string = false; | 	s32 within_string = false; | ||||||
| 	s32 within_char   = false; | 	s32 within_char   = false; | ||||||
|  |  | ||||||
| 	// SkipWhitespace(); | 	// Consume preprocess content | ||||||
| 	while ( ctx->left ) | 	while ( ctx->left ) | ||||||
| 	{ | 	{ | ||||||
| 		if ( (* ctx->scanner) == '"' && ! within_char ) | 		if ( (* ctx->scanner) == '"' && ! within_char ) | ||||||
| @@ -325,6 +399,7 @@ s32 lex_preprocessor_directive( LexContext* ctx ) | |||||||
| 					, (* ctx->scanner), ctx->line, ctx->column | 					, (* ctx->scanner), ctx->line, ctx->column | ||||||
| 					, directive_str, preprocess_content.Line, preprocess_content.Column | 					, directive_str, preprocess_content.Line, preprocess_content.Column | ||||||
| 					, content_str ); | 					, content_str ); | ||||||
|  | 				return Lex_ReturnNull; | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| @@ -404,14 +479,15 @@ void lex_found_token( LexContext* ctx ) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	u64 key = 0; | 	u64 key = 0; | ||||||
| 	if ( (* ctx->scanner) == '(') | 	// if ( (* ctx->scanner) == '(') | ||||||
| 		key = crc32( ctx->token.Text.Ptr, ctx->token.Text.Len + 1 ); | 	// 	key = crc32( ctx->token.Text.Ptr, ctx->token.Text.Len + 1 ); | ||||||
| 	else | 	// else | ||||||
| 		key = crc32( ctx->token.Text.Ptr, ctx->token.Text.Len ); | 	key = crc32( ctx->token.Text.Ptr, ctx->token.Text.Len ); | ||||||
|  |  | ||||||
| 	Str* define = hashtable_get(ctx->defines, key ); | 	Str* define = hashtable_get(_ctx->PreprocessMacros, key ); | ||||||
| 	if ( define ) | 	if ( define ) | ||||||
| 	{ | 	{ | ||||||
|  | 		// TODO(Ed): Needs updating (Macros) | ||||||
| 		ctx->token.Type = Tok_Preprocess_Macro; | 		ctx->token.Type = Tok_Preprocess_Macro; | ||||||
|  |  | ||||||
| 		// 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. | ||||||
| @@ -456,6 +532,7 @@ void lex_found_token( LexContext* ctx ) | |||||||
| 	array_append( _ctx->Lexer_Tokens, ctx->token ); | 	array_append( _ctx->Lexer_Tokens, ctx->token ); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // TODO(Ed): We need to to attempt to recover from a lex failure? | ||||||
| neverinline | neverinline | ||||||
| // TokArray lex( Array<Token> tokens, Str content ) | // TokArray lex( Array<Token> tokens, Str content ) | ||||||
| TokArray lex( Str content ) | TokArray lex( Str content ) | ||||||
| @@ -480,27 +557,10 @@ TokArray lex( Str content ) | |||||||
| 		return null_array; | 		return null_array; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// TODO(ED): Remove this when preprocess defines has been converted |  | ||||||
| 	// for ( StrCached* entry = array_begin(_ctx->PreprocessorDefines); entry != array_end(_ctx->PreprocessorDefines); entry = array_next(_ctx->PreprocessorDefines, entry)) |  | ||||||
| 	// { |  | ||||||
| 	// 	s32         length  = 0; |  | ||||||
| 	// 	char const* entry_scanner = (*entry).Ptr; |  | ||||||
| 	// 	while ( entry->Len > length && (char_is_alphanumeric( *entry_scanner ) || *entry_scanner == '_') ) |  | ||||||
| 	// 	{ |  | ||||||
| 	// 		entry_scanner++; |  | ||||||
| 	// 		length ++; |  | ||||||
| 	// 	} |  | ||||||
| 	// 	if ( entry_scanner[0] == '(' ) |  | ||||||
| 	// 	{ |  | ||||||
| 	// 		length++; |  | ||||||
| 	// 	} |  | ||||||
|  |  | ||||||
| 	// 	u64 key = crc32( entry->Ptr, length ); |  | ||||||
| 	// 	hashtable_set(c.defines, key, * entry ); |  | ||||||
| 	// } |  | ||||||
|  |  | ||||||
| 	array_clear(_ctx->Lexer_Tokens); | 	array_clear(_ctx->Lexer_Tokens); | ||||||
|  |  | ||||||
|  | 	b32 preprocess_args = true; | ||||||
|  |  | ||||||
| 	while (c.left ) | 	while (c.left ) | ||||||
| 	{ | 	{ | ||||||
| 		#if 0 | 		#if 0 | ||||||
| @@ -1182,6 +1242,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; | ||||||
|  | 			// TODO(Ed): Change this to just detect if its a MACRO THAT SHOULD ACCEPT NEWLINES | ||||||
| 			if ( last_type == Tok_Preprocess_Macro ) | 			if ( last_type == Tok_Preprocess_Macro ) | ||||||
| 			{ | 			{ | ||||||
| 				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 }; | ||||||
| @@ -1217,6 +1278,7 @@ TokArray lex( Str content ) | |||||||
| 	TokArray result = { _ctx->Lexer_Tokens, 0 }; | 	TokArray result = { _ctx->Lexer_Tokens, 0 }; | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| #undef move_forward | #undef move_forward | ||||||
| #undef skip_whitespace | #undef skip_whitespace | ||||||
| #undef end_line | #undef end_line | ||||||
|   | |||||||
| @@ -825,22 +825,21 @@ CodeBody parse_class_struct_body( TokType which, Token name ) | |||||||
|  |  | ||||||
| 		switch ( currtok_noskip.Type ) | 		switch ( currtok_noskip.Type ) | ||||||
| 		{ | 		{ | ||||||
| 			case Tok_Statement_End: | 			case Tok_Statement_End: { | ||||||
| 			{ |  | ||||||
| 				// TODO(Ed): Convert this to a general warning procedure | 				// TODO(Ed): Convert this to a general warning procedure | ||||||
| 				log_fmt("Dangling end statement found %SB\n", tok_to_strbuilder(currtok_noskip)); | 				log_fmt("Dangling end statement found %SB\n", tok_to_strbuilder(currtok_noskip)); | ||||||
| 				eat( Tok_Statement_End ); | 				eat( Tok_Statement_End ); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			case Tok_NewLine: | 			case Tok_NewLine: { | ||||||
| 				member = fmt_newline; | 				member = fmt_newline; | ||||||
| 				eat( Tok_NewLine ); | 				eat( Tok_NewLine ); | ||||||
| 			break; | 				break; | ||||||
|  | 			} | ||||||
| 			case Tok_Comment: | 			case Tok_Comment: { | ||||||
| 				member = cast(Code, parse_comment()); | 				member = cast(Code, parse_comment()); | ||||||
| 			break; | 				break; | ||||||
|  | 			} | ||||||
| 			case Tok_Access_Public: | 			case Tok_Access_Public: | ||||||
| 				member = access_public; | 				member = access_public; | ||||||
| 				eat( Tok_Access_Public ); | 				eat( Tok_Access_Public ); | ||||||
| @@ -1727,8 +1726,8 @@ CodeBody parse_global_nspace( CodeType which ) | |||||||
| 				// <Macro> | 				// <Macro> | ||||||
| 				macro_found = true; | 				macro_found = true; | ||||||
| 				goto Preprocess_Macro_Bare_In_Body; | 				goto Preprocess_Macro_Bare_In_Body; | ||||||
|  | 				// TODO(Ed): MACRO UPDATE | ||||||
| 			} | 			} | ||||||
| 			break; |  | ||||||
|  |  | ||||||
| 			case Tok_Preprocess_Pragma: { | 			case Tok_Preprocess_Pragma: { | ||||||
| 				member = cast(Code, parse_pragma()); | 				member = cast(Code, parse_pragma()); | ||||||
| @@ -2727,7 +2726,7 @@ CodeParams parse_params( bool use_template_capture ) | |||||||
| 		// In template captures you can have a typename have direct assignment without a name | 		// In template captures you can have a typename have direct assignment without a name | ||||||
| 		// typename = typename ... | 		// typename = typename ... | ||||||
| 		// Which would result in a static value type from a struct expansion (traditionally) | 		// Which would result in a static value type from a struct expansion (traditionally) | ||||||
| 		if ( ( name.Text.Ptr || use_template_capture ) && bitfield_is_equal( u32, currtok.Flags, TF_Assign ) ) | 		if ( ( name.Text.Ptr || use_template_capture ) && bitfield_is_set( u32, currtok.Flags, TF_Assign ) ) | ||||||
| 		{ | 		{ | ||||||
| 			eat( Tok_Operator ); | 			eat( Tok_Operator ); | ||||||
| 			// ( <Macro> <ValueType> <Name> = | 			// ( <Macro> <ValueType> <Name> = | ||||||
| @@ -2839,7 +2838,7 @@ CodeParams parse_params( bool use_template_capture ) | |||||||
| 			// In template captures you can have a typename have direct assignment without a name | 			// In template captures you can have a typename have direct assignment without a name | ||||||
| 			// typename = typename ... | 			// typename = typename ... | ||||||
| 			// Which would result in a static value type from a struct expansion (traditionally) | 			// Which would result in a static value type from a struct expansion (traditionally) | ||||||
| 			if ( ( name.Text.Ptr || use_template_capture ) && bitfield_is_equal( u32, currtok.Flags, TF_Assign ) ) | 			if ( ( name.Text.Ptr || use_template_capture ) && bitfield_is_set( u32, currtok.Flags, TF_Assign ) ) | ||||||
| 			{ | 			{ | ||||||
| 				eat( Tok_Operator ); | 				eat( Tok_Operator ); | ||||||
| 				// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> = | 				// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> = | ||||||
| @@ -3166,7 +3165,7 @@ CodeVar parse_variable_after_name( | |||||||
|  |  | ||||||
| 	b32 using_constructor_initializer = false; | 	b32 using_constructor_initializer = false; | ||||||
|  |  | ||||||
| 	if ( bitfield_is_equal( u32, currtok.Flags, TF_Assign ) ) | 	if ( bitfield_is_set( u32, currtok.Flags, TF_Assign ) ) | ||||||
| 	{ | 	{ | ||||||
| 		// <Attributes> <Specifiers> <ValueType> <Name> = <Expression> | 		// <Attributes> <Specifiers> <ValueType> <Name> = <Expression> | ||||||
| 		expr = parse_assignment_expression(); | 		expr = parse_assignment_expression(); | ||||||
| @@ -4645,6 +4644,7 @@ else if ( currtok.Type == Tok_DeclType ) | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 	// TODO(Ed): This needs updating | ||||||
| 	else if ( currtok.Type == Tok_Preprocess_Macro ) { | 	else if ( currtok.Type == Tok_Preprocess_Macro ) { | ||||||
| 		// Typename is a macro | 		// Typename is a macro | ||||||
| 		name = currtok; | 		name = currtok; | ||||||
| @@ -4988,6 +4988,7 @@ CodeTypedef parser_parse_typedef() | |||||||
|  |  | ||||||
| 	const bool from_typedef = true; | 	const bool from_typedef = true; | ||||||
|  |  | ||||||
|  | 	// TODO(Ed): UPDATE MACRO USAGE HERE | ||||||
| #if GEN_PARSER_DISABLE_MACRO_TYPEDEF | #if GEN_PARSER_DISABLE_MACRO_TYPEDEF | ||||||
| 	if ( false ) | 	if ( false ) | ||||||
| #else | #else | ||||||
| @@ -5365,7 +5366,7 @@ CodeUsing parser_parse_using() | |||||||
|  |  | ||||||
| 	if ( ! is_namespace ) | 	if ( ! is_namespace ) | ||||||
| 	{ | 	{ | ||||||
| 		if ( bitfield_is_equal( u32, currtok.Flags, TF_Assign ) ) | 		if ( bitfield_is_set( u32, currtok.Flags, TF_Assign ) ) | ||||||
| 		{ | 		{ | ||||||
| 			attributes = parse_attributes(); | 			attributes = parse_attributes(); | ||||||
| 			// <ModuleFlags> using <Name> <Attributes> | 			// <ModuleFlags> using <Name> <Attributes> | ||||||
|   | |||||||
| @@ -6,34 +6,6 @@ | |||||||
| #include "gen/especifier.hpp" | #include "gen/especifier.hpp" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| enum MacroTypes : u16 |  | ||||||
| { |  | ||||||
| 	MT_Block_Start,    // Not Supported yet |  | ||||||
| 	MT_Block_End,      // Not Supported yet |  | ||||||
| 	MT_Case_Statement, // Not Supported yet |  | ||||||
| 	MT_Expression, |  | ||||||
| 	MT_Statement, |  | ||||||
| 	MT_Typename, |  | ||||||
|  |  | ||||||
| 	MF_UnderlyingType = GEN_U16_Max, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| enum MacroFlags : u16 |  | ||||||
| { |  | ||||||
| 	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_Null           = 0, |  | ||||||
| 	MF_UnderlyingType = GEN_U16_Max, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| struct PreprocessorMacro |  | ||||||
| { |  | ||||||
| 	StrCached  Name; |  | ||||||
| 	MacroTypes Type; |  | ||||||
| 	MacroFlags Flags; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| enum TokFlags : u32 | enum TokFlags : u32 | ||||||
| { | { | ||||||
| 	TF_Operator		         = bit(0), | 	TF_Operator		         = bit(0), | ||||||
| @@ -82,42 +54,42 @@ bool tok_is_valid( Token tok ) { | |||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| bool tok_is_access_operator(Token tok) { | bool tok_is_access_operator(Token tok) { | ||||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_AccessOperator ); | 	return bitfield_is_set( u32, tok.Flags, TF_AccessOperator ); | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| bool tok_is_access_specifier(Token tok) { | bool tok_is_access_specifier(Token tok) { | ||||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_AccessSpecifier ); | 	return bitfield_is_set( u32, tok.Flags, TF_AccessSpecifier ); | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| bool tok_is_attribute(Token tok) { | bool tok_is_attribute(Token tok) { | ||||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_Attribute ); | 	return bitfield_is_set( u32, tok.Flags, TF_Attribute ); | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| bool tok_is_operator(Token tok) { | bool tok_is_operator(Token tok) { | ||||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_Operator ); | 	return bitfield_is_set( u32, tok.Flags, TF_Operator ); | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| bool tok_is_preprocessor(Token tok) { | bool tok_is_preprocessor(Token tok) { | ||||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_Preprocess ); | 	return bitfield_is_set( u32, tok.Flags, TF_Preprocess ); | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| bool tok_is_preprocess_cond(Token tok) { | bool tok_is_preprocess_cond(Token tok) { | ||||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_Preprocess_Cond ); | 	return bitfield_is_set( u32, tok.Flags, TF_Preprocess_Cond ); | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| bool tok_is_specifier(Token tok) { | bool tok_is_specifier(Token tok) { | ||||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_Specifier ); | 	return bitfield_is_set( u32, tok.Flags, TF_Specifier ); | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| bool tok_is_end_definition(Token tok) { | bool tok_is_end_definition(Token tok) { | ||||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_EndDefinition ); | 	return bitfield_is_set( u32, tok.Flags, TF_EndDefinition ); | ||||||
| } | } | ||||||
|  |  | ||||||
| StrBuilder tok_to_strbuilder(Token tok); | StrBuilder tok_to_strbuilder(Token tok); | ||||||
| @@ -153,3 +125,60 @@ struct ParseContext | |||||||
| 	TokArray   Tokens; | 	TokArray   Tokens; | ||||||
| 	StackNode* Scope; | 	StackNode* Scope; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | enum MacroType : u16 | ||||||
|  | { | ||||||
|  | 	MT_Statement,      // A macro is assumed to be a statement if not resolved. | ||||||
|  | 	MT_Expression, | ||||||
|  | 	MT_Typename, | ||||||
|  | 	MT_Block_Start,    // Not Supported yet | ||||||
|  | 	MT_Block_End,      // Not Supported yet | ||||||
|  | 	MT_Case_Statement, // Not Supported yet | ||||||
|  |  | ||||||
|  | 	MF_UnderlyingType = GEN_U16_Max, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | Str macro_type_to_str( MacroType type ) | ||||||
|  | { | ||||||
|  | 	local_persist | ||||||
|  | 	Str lookup[ (u32)Num_ModuleFlags ] = { | ||||||
|  | 		{ "Statement",      sizeof("Statement")      - 1 }, | ||||||
|  | 		{ "Expression",     sizeof("Expression")     - 1 }, | ||||||
|  | 		{ "Typename",       sizeof("Typename")       - 1 }, | ||||||
|  | 		{ "Block_Start",    sizeof("Block_Start")    - 1 }, | ||||||
|  | 		{ "Block_End",      sizeof("Block_End")      - 1 }, | ||||||
|  | 		{ "Case_Statement", sizeof("Case_Statement") - 1 }, | ||||||
|  | 	}; | ||||||
|  | 	local_persist | ||||||
|  | 	Str invalid_flag = { "Invalid", sizeof("Invalid") }; | ||||||
|  | 	if ( flag > ModuleFlag_Import ) | ||||||
|  | 		return invalid_flag; | ||||||
|  |  | ||||||
|  | 	return lookup[ (u32)flag ]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | enum MacroFlags : u16 | ||||||
|  | { | ||||||
|  | 	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_Null           = 0, | ||||||
|  | 	MF_UnderlyingType = GEN_U16_Max, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | struct PreprocessorMacro | ||||||
|  | { | ||||||
|  | 	StrCached  Name; | ||||||
|  | 	MacroType  Type; | ||||||
|  | 	MacroFlags Flags; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | forceinine | ||||||
|  | b32 macro_is_functional( PreprocessorMacro macro ) { | ||||||
|  | 	return bitfield_is_set( macro->Flags, MF_Functional ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | forceinline | ||||||
|  | b32 macro_expects_body( PreprocessorMacro macro ) { | ||||||
|  | 	return bitfield_is_set( macro->Flags, MF_Expects_Body ); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ global Context* _ctx; | |||||||
| #pragma region Constants | #pragma region Constants | ||||||
| global u32 context_counter; | global u32 context_counter; | ||||||
|  |  | ||||||
| global Str enum_underlying_sig; | global PreprocessorMacro enum_underlying_macro; | ||||||
|  |  | ||||||
| global Code Code_Global; | global Code Code_Global; | ||||||
| global Code Code_Invalid; | global Code Code_Invalid; | ||||||
|   | |||||||
| @@ -34,8 +34,8 @@ | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #ifndef bit | #ifndef bit | ||||||
| #define bit( Value )                             ( 1 << Value ) | #define bit( Value )                         ( 1 << Value ) | ||||||
| #define bitfield_is_equal( Type, Field, Mask ) ( (scast(Type, Mask) & scast(Type, Field)) == scast(Type, Mask) ) | #define bitfield_is_set( Type, Field, Mask ) ( (scast(Type, Mask) & scast(Type, Field)) == scast(Type, Mask) ) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| // Mainly intended for forcing the base library to utilize only C-valid constructs or type coercion | // Mainly intended for forcing the base library to utilize only C-valid constructs or type coercion | ||||||
|   | |||||||
| @@ -42,6 +42,7 @@ Number,                     "__number__" | |||||||
| Operator,                   "__operator__" | Operator,                   "__operator__" | ||||||
| Preprocess_Hash,            "#" | Preprocess_Hash,            "#" | ||||||
| Preprocess_Define,          "define" | Preprocess_Define,          "define" | ||||||
|  | Preprocess_Define_Param,    "__define_param__" | ||||||
| Preprocess_If,              "if" | Preprocess_If,              "if" | ||||||
| Preprocess_IfDef,           "ifdef" | Preprocess_IfDef,           "ifdef" | ||||||
| Preprocess_IfNotDef,        "ifndef" | Preprocess_IfNotDef,        "ifndef" | ||||||
|   | |||||||
| 
 | 
| @@ -41,7 +41,7 @@ | |||||||
| #undef local_persist | #undef local_persist | ||||||
|  |  | ||||||
| #undef bit | #undef bit | ||||||
| #undef bitfield_is_equal | #undef bitfield_is_set | ||||||
|  |  | ||||||
| #undef cast | #undef cast | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ word global,                       gen_global | |||||||
| word internal,                     gen_internal | word internal,                     gen_internal | ||||||
| word local_persist,                gen_local_persist | word local_persist,                gen_local_persist | ||||||
| word bit,                          gen_bit | word bit,                          gen_bit | ||||||
| word bitfield_is_equal,            gen_bitfield_is_equal | word bitfield_is_set,            gen_bitfield_is_set | ||||||
| word cast,                         gen_cast | word cast,                         gen_cast | ||||||
| word ccast,                        gen_ccast | word ccast,                        gen_ccast | ||||||
| word pcast,                        gen_pcast | word pcast,                        gen_pcast | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user