mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-10-30 22:40:54 -07:00 
			
		
		
		
	Finished sanity suite except for operators.
Adjusted upfront api a bit, def_using no longer handles the namespace case, a sepearate function: def_using_namespace now does. Mostly fixes to the seralization as I generate more cases to find the bugs.
This commit is contained in:
		
							
								
								
									
										176
									
								
								project/gen.cpp
									
									
									
									
									
								
							
							
						
						
									
										176
									
								
								project/gen.cpp
									
									
									
									
									
								
							| @@ -54,6 +54,9 @@ namespace gen | |||||||
| 	Code access_protected; | 	Code access_protected; | ||||||
| 	Code access_private; | 	Code access_private; | ||||||
|  |  | ||||||
|  | 	Code module_global_fragment; | ||||||
|  | 	Code module_private_fragment; | ||||||
|  |  | ||||||
| 	Code spec_const; | 	Code spec_const; | ||||||
| 	Code spec_consteval; | 	Code spec_consteval; | ||||||
| 	Code spec_constexpr; | 	Code spec_constexpr; | ||||||
| @@ -82,7 +85,6 @@ namespace gen | |||||||
| 	case Class_Body:                      \ | 	case Class_Body:                      \ | ||||||
| 	case Enum_Body:                       \ | 	case Enum_Body:                       \ | ||||||
| 	case Extern_Linkage:                  \ | 	case Extern_Linkage:                  \ | ||||||
| 	case Friend:                          \ |  | ||||||
| 	case Function_Body:                   \ | 	case Function_Body:                   \ | ||||||
| 	case Function_Fwd:                    \ | 	case Function_Fwd:                    \ | ||||||
| 	case Global_Body:                     \ | 	case Global_Body:                     \ | ||||||
| @@ -511,9 +513,6 @@ namespace gen | |||||||
|                                                                          \ |                                                                          \ | ||||||
| 		if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Import ))  \ | 		if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Import ))  \ | ||||||
| 			result.append( "import " );             \ | 			result.append( "import " );             \ | ||||||
|                                                                          \ |  | ||||||
| 		if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Private )) \ |  | ||||||
| 			result.append( "private " ); |  | ||||||
|  |  | ||||||
| 		String result = String::make( g_allocator, "" ); | 		String result = String::make( g_allocator, "" ); | ||||||
|  |  | ||||||
| @@ -639,11 +638,11 @@ namespace gen | |||||||
| 						result.append( "\n{\n" ); | 						result.append( "\n{\n" ); | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					result.append_fmt( "%s\n%s};\n", body()->to_string(), indent_str ); | 					result.append_fmt( "%s\n%s};", body()->to_string(), indent_str ); | ||||||
| 				} | 				} | ||||||
| 				else | 				else | ||||||
| 				{ | 				{ | ||||||
| 					result.append_fmt( "class %s\n{\n%s\n%s};\n", Name, body()->to_string(), indent_str ); | 					result.append_fmt( "class %s\n{\n%s\n%s};", Name, body()->to_string(), indent_str ); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
| @@ -733,7 +732,7 @@ namespace gen | |||||||
|  |  | ||||||
| 				if ( entry( idx )->Type == Typename ) | 				if ( entry( idx )->Type == Typename ) | ||||||
| 				{ | 				{ | ||||||
| 					result.append_fmt( ": %s\n%s{\n" | 					result.append_fmt( "%s : %s\n%s{\n" | ||||||
| 						, Name | 						, Name | ||||||
| 						, entry( idx )->to_string() | 						, entry( idx )->to_string() | ||||||
| 						, indent_str | 						, indent_str | ||||||
| @@ -770,7 +769,7 @@ namespace gen | |||||||
| 					idx++; | 					idx++; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				result.append_fmt( ": %s;\n", Name, entry( idx )->to_string() ); | 				result.append_fmt( "%s : %s;", Name, entry( idx )->to_string() ); | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| @@ -790,7 +789,7 @@ namespace gen | |||||||
| 					index++; | 					index++; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				result.append_fmt( "%s};\n", indent_str ); | 				result.append_fmt( "%s};", indent_str ); | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| @@ -799,7 +798,7 @@ namespace gen | |||||||
|  |  | ||||||
| 				ProcessModuleFlags(); | 				ProcessModuleFlags(); | ||||||
|  |  | ||||||
| 				result.append_fmt( "extern %s\n%s{\n%s\n%s};\n" | 				result.append_fmt( "extern \"%s\"\n%s{\n%s\n%s}" | ||||||
| 					, Name | 					, Name | ||||||
| 					, indent_str | 					, indent_str | ||||||
| 					, body()->to_string() | 					, body()->to_string() | ||||||
| @@ -808,7 +807,7 @@ namespace gen | |||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 			case Friend: | 			case Friend: | ||||||
| 				result.append_fmt( "%sfriend %s;\n", indent_str, entry( 0 )->to_string() ); | 				result.append_fmt( "%sfriend %s", indent_str, entry( 0 )->to_string() ); | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 			case Function: | 			case Function: | ||||||
| @@ -820,33 +819,44 @@ namespace gen | |||||||
| 				u32 idx  = 1; | 				u32 idx  = 1; | ||||||
| 				u32 left = num_entries(); | 				u32 left = num_entries(); | ||||||
|  |  | ||||||
| 				if ( entry( idx )->Type == Attributes ) | 				AST* Entry = entry( idx ); | ||||||
|  |  | ||||||
|  | 				if ( Entry && Entry->Type == Attributes ) | ||||||
| 				{ | 				{ | ||||||
| 					result.append_fmt( "%s ", entry( idx )->to_string() ); | 					result.append_fmt( "%s ", Entry->to_string() ); | ||||||
| 					idx++; | 					idx++; | ||||||
| 					left--; | 					left--; | ||||||
|  | 					Entry = entry( idx ); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				if ( entry( idx )->Type == Specifiers ) | 				if ( Entry && Entry->Type == Specifiers ) | ||||||
| 				{ | 				{ | ||||||
| 					result.append_fmt( "%s\n", entry( idx )->to_string() ); | 					result.append_fmt( "%s\n", Entry->to_string() ); | ||||||
| 					idx++; | 					idx++; | ||||||
| 					left--; | 					left--; | ||||||
|  | 					Entry = entry( idx ); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				result.append_fmt( "%s %s(", entry( idx )->to_string(), Name ); | 				if ( Entry && Entry->Type == Typename ) | ||||||
| 				idx++; |  | ||||||
| 				left--; |  | ||||||
|  |  | ||||||
| 				if ( left && entry( idx )->Type == Parameters ) |  | ||||||
| 				{ | 				{ | ||||||
| 					result.append_fmt( "%s", entry( idx )->to_string() ); | 					result.append_fmt( "%s ", Entry->to_string() ); | ||||||
| 					idx++; | 					idx++; | ||||||
| 					left--; | 					left--; | ||||||
|  | 					Entry = entry( idx ); | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				result.append_fmt( "%s(", Name ); | ||||||
|  |  | ||||||
|  | 				if ( left && Entry && Entry->Type == Parameters ) | ||||||
|  | 				{ | ||||||
|  | 					result.append_fmt("%s", Entry->to_string() ); | ||||||
|  | 					idx++; | ||||||
|  | 					left--; | ||||||
|  | 					Entry = entry( idx ); | ||||||
| 				} | 				} | ||||||
| 				else | 				else | ||||||
| 				{ | 				{ | ||||||
| 					result.append_fmt( "void" ); | 					result.append( "void" ); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				result.append_fmt( ")\n%s{\n%s\n%s}" | 				result.append_fmt( ")\n%s{\n%s\n%s}" | ||||||
| @@ -906,24 +916,28 @@ namespace gen | |||||||
| 					result.append( "void" ); | 					result.append( "void" ); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				result.append( ");\n" ); | 				result.append( ");" ); | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 			case Module: | 			case Module: | ||||||
| 				result.append( indent ); | 				result.append( indent ); | ||||||
|  |  | ||||||
| 				ProcessModuleFlags(); | 				if (((u32(ModuleFlag::Export) & u32(ModuleFlags)) == u32(ModuleFlag::Export))) | ||||||
|  | 					result.append("export "); | ||||||
|  |  | ||||||
| 				result.append_fmt( "module %s", Content ); | 				if (((u32(ModuleFlag::Import) & u32(ModuleFlags)) == u32(ModuleFlag::Import))) | ||||||
| 			break; | 					result.append("import "); | ||||||
|  |  | ||||||
|  | 				result.append_fmt( "%s;", Name ); | ||||||
|  | 				break; | ||||||
|  |  | ||||||
| 			case Namespace: | 			case Namespace: | ||||||
| 				result.append( indent ); | 				result.append( indent ); | ||||||
|  |  | ||||||
| 				ProcessModuleFlags(); | 				ProcessModuleFlags(); | ||||||
|  |  | ||||||
| 				result.append_fmt( "namespace %s\n%s{\n%s\n%s};\n" | 				result.append_fmt( "namespace %s\n%s{\n%s\n%s};" | ||||||
| 					, Name | 					, Name | ||||||
| 					, indent_str | 					, indent_str | ||||||
| 					, body()->to_string() | 					, body()->to_string() | ||||||
| @@ -993,12 +1007,12 @@ namespace gen | |||||||
|  |  | ||||||
| 				if ( entry( idx )->Type == Parameters ) | 				if ( entry( idx )->Type == Parameters ) | ||||||
| 				{ | 				{ | ||||||
| 					result.append_fmt( "%s);\n", entry( idx )->to_string() ); | 					result.append_fmt( "%s);", entry( idx )->to_string() ); | ||||||
| 					idx++; | 					idx++; | ||||||
| 				} | 				} | ||||||
| 				else | 				else | ||||||
| 				{ | 				{ | ||||||
| 					result.append_fmt( "void);\n" ); | 					result.append_fmt( "void);" ); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
| @@ -1008,7 +1022,7 @@ namespace gen | |||||||
| 				result.append_fmt( "%s %s", entry( 0 )->to_string(), Name ); | 				result.append_fmt( "%s %s", entry( 0 )->to_string(), Name ); | ||||||
|  |  | ||||||
| 				s32 index = 1; | 				s32 index = 1; | ||||||
| 				s32 left  = num_entries() - 1; | 				s32 left  = num_entries(); | ||||||
|  |  | ||||||
| 				while ( left--, left > 0 ) | 				while ( left--, left > 0 ) | ||||||
| 					result.append_fmt( ", %s %s" | 					result.append_fmt( ", %s %s" | ||||||
| @@ -1019,7 +1033,7 @@ namespace gen | |||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 			case Preprocessor_Include: | 			case Preprocessor_Include: | ||||||
| 				result.append_fmt( "#include %s\n", Name ); | 				result.append_fmt( "#include \"%s\"", Name ); | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 			case Specifiers: | 			case Specifiers: | ||||||
| @@ -1056,7 +1070,7 @@ namespace gen | |||||||
| 					result.append_fmt( ": %s %s", access_str, entry( idx )->to_string() ); | 					result.append_fmt( ": %s %s", access_str, entry( idx )->to_string() ); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				result.append_fmt( "\n{\n%s\n};\n", body()->to_string() ); | 				result.append_fmt( "\n{\n%s\n};", body()->to_string() ); | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| @@ -1088,16 +1102,23 @@ namespace gen | |||||||
|  |  | ||||||
| 				s32 idx = 1; | 				s32 idx = 1; | ||||||
|  |  | ||||||
| 				if ( entry( idx )->Type == Specifiers ) | 				if ( num_entries() > 1 ) | ||||||
| 				{ | 				{ | ||||||
| 					result.append_fmt( "%s", entry( idx )->to_string() ); | 					if ( entry( idx )->Type == Specifiers ) | ||||||
| 					idx++; | 					{ | ||||||
|  | 						result.append_fmt( "%s", entry( idx )->to_string() ); | ||||||
|  | 						idx++; | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					result.append_fmt( "%s %s", entry( 0 )->to_string(), Name ); | ||||||
|  |  | ||||||
|  | 					if ( entry( idx ) ) | ||||||
|  | 						result.append_fmt( " = %s;", entry( idx )->to_string() ); | ||||||
|  |  | ||||||
|  | 					break; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				result.append_fmt( "%s %s", entry( 0 )->to_string(), Name ); | 				result.append_fmt( "%s %s;", entry( 0 )->to_string(), Name ); | ||||||
|  |  | ||||||
| 				if ( entry( idx ) ) |  | ||||||
| 					result.append_fmt( " = %s", entry( idx )->to_string() ); |  | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| @@ -1154,7 +1175,7 @@ namespace gen | |||||||
| 					idx++; | 					idx++; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				result.append_fmt( "%s\n%s{\n%s\n%s};\n" | 				result.append_fmt( "%s\n%s{\n%s\n%s};" | ||||||
| 					, Name | 					, Name | ||||||
| 					, indent_str | 					, indent_str | ||||||
| 					, body()->to_string() | 					, body()->to_string() | ||||||
| @@ -1183,16 +1204,15 @@ namespace gen | |||||||
| 					if ( type->entry( 1 ) ) | 					if ( type->entry( 1 ) ) | ||||||
| 						result.append_fmt( "[%s]", type->entry( 1 )->to_string() ); | 						result.append_fmt( "[%s]", type->entry( 1 )->to_string() ); | ||||||
|  |  | ||||||
|  | 					result.append( ";" ); | ||||||
| 				} | 				} | ||||||
| 				else | 				else | ||||||
| 					result.append_fmt( "using %s", Name ); | 					result.append_fmt( "using %s;", Name ); | ||||||
|  |  | ||||||
| 				result.append( ";" ); |  | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 			case Using_Namespace: | 			case Using_Namespace: | ||||||
| 				result.append_fmt( "%susing namespace %s", indent_str, Name ); | 				result.append_fmt( "%susing namespace %s;", indent_str, Name ); | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 			case Class_Body: | 			case Class_Body: | ||||||
| @@ -1333,6 +1353,18 @@ namespace gen | |||||||
| 		access_public_write->Name = get_cached_string( { sizeof("public"), "public" } ); | 		access_public_write->Name = get_cached_string( { sizeof("public"), "public" } ); | ||||||
| 		access_public_write.lock(); | 		access_public_write.lock(); | ||||||
|  |  | ||||||
|  | 		module_global_fragment          = make_code(); | ||||||
|  | 		module_global_fragment->Type    = ECode::Untyped; | ||||||
|  | 		module_global_fragment->Name    = get_cached_string( StrC::from("module;") ); | ||||||
|  | 		module_global_fragment->Content = module_global_fragment->Name; | ||||||
|  | 		module_global_fragment.lock(); | ||||||
|  |  | ||||||
|  | 		module_private_fragment          = make_code(); | ||||||
|  | 		module_private_fragment->Type    = ECode::Untyped; | ||||||
|  | 		module_private_fragment->Name    = get_cached_string( StrC::from("module : private;") ); | ||||||
|  | 		module_private_fragment->Content = module_private_fragment->Name; | ||||||
|  | 		module_private_fragment.lock(); | ||||||
|  |  | ||||||
| 		Code& | 		Code& | ||||||
| 		spec_local_persist_write = ccast( Code, spec_local_persist ); | 		spec_local_persist_write = ccast( Code, spec_local_persist ); | ||||||
| 		spec_local_persist_write = def_specifiers( 1, ESpecifier::Local_Persist ); | 		spec_local_persist_write = def_specifiers( 1, ESpecifier::Local_Persist ); | ||||||
| @@ -2167,7 +2199,7 @@ namespace gen | |||||||
| 		name_check( def_extern_linkage, name ); | 		name_check( def_extern_linkage, name ); | ||||||
| 		null_check( def_extern_linkage, body ); | 		null_check( def_extern_linkage, body ); | ||||||
|  |  | ||||||
| 		if ( body->Type != Extern_Linkage_Body || body->Type != Untyped ) | 		if ( body->Type != Extern_Linkage_Body && body->Type != Untyped ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::def_extern_linkage: body is not of extern_linkage or untyped type %s", body->debug_str()); | 			log_failure("gen::def_extern_linkage: body is not of extern_linkage or untyped type %s", body->debug_str()); | ||||||
| 			return Code::Invalid; | 			return Code::Invalid; | ||||||
| @@ -2324,6 +2356,7 @@ namespace gen | |||||||
| 		result = make_code(); | 		result = make_code(); | ||||||
| 		result->Type        = ECode::Module; | 		result->Type        = ECode::Module; | ||||||
| 		result->Name        = get_cached_string( name ); | 		result->Name        = get_cached_string( name ); | ||||||
|  | 		result->Content     = result->Name; | ||||||
| 		result->ModuleFlags = mflags; | 		result->ModuleFlags = mflags; | ||||||
|  |  | ||||||
| 		result.lock(); | 		result.lock(); | ||||||
| @@ -2337,7 +2370,7 @@ namespace gen | |||||||
| 		name_check( def_namespace, name ); | 		name_check( def_namespace, name ); | ||||||
| 		null_check( def_namespace, body ); | 		null_check( def_namespace, body ); | ||||||
|  |  | ||||||
| 		if ( body->Type != Namespace_Body || body->Type != Untyped ) | 		if ( body->Type != Namespace_Body && body->Type != Untyped ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::def_namespace: body is not of namespace or untyped type %s", body->debug_str()); | 			log_failure("gen::def_namespace: body is not of namespace or untyped type %s", body->debug_str()); | ||||||
| 			return Code::Invalid; | 			return Code::Invalid; | ||||||
| @@ -2584,8 +2617,9 @@ namespace gen | |||||||
| 	Code def_union( StrC name, Code body, Code attributes, ModuleFlag mflags ) | 	Code def_union( StrC name, Code body, Code attributes, ModuleFlag mflags ) | ||||||
| 	{ | 	{ | ||||||
| 		name_check( def_union, name ); | 		name_check( def_union, name ); | ||||||
|  | 		null_check( def_union, body ); | ||||||
|  |  | ||||||
| 		if ( body && body->Type != ECode::Union_Body ) | 		if ( body->Type != ECode::Union_Body ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure( "gen::def_union: body was not a Union_Body type" ); | 			log_failure( "gen::def_union: body was not a Union_Body type" ); | ||||||
| 			return Code::Invalid; | 			return Code::Invalid; | ||||||
| @@ -2595,16 +2629,9 @@ namespace gen | |||||||
| 		result = make_code(); | 		result = make_code(); | ||||||
| 		result->Name        = get_cached_string( name ); | 		result->Name        = get_cached_string( name ); | ||||||
| 		result->ModuleFlags = mflags; | 		result->ModuleFlags = mflags; | ||||||
|  | 		result->Type        = ECode::Union; | ||||||
|  |  | ||||||
| 		if ( body ) | 		result->add_entry( body ); | ||||||
| 		{ |  | ||||||
| 			result->Type = ECode::Union; |  | ||||||
| 			result->add_entry( body ); |  | ||||||
| 		} |  | ||||||
| 		else |  | ||||||
| 		{ |  | ||||||
| 			result->Type = ECode::Union_Fwd; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if ( attributes ) | 		if ( attributes ) | ||||||
| 			result->add_entry( attributes ); | 			result->add_entry( attributes ); | ||||||
| @@ -2613,8 +2640,7 @@ namespace gen | |||||||
| 		return result; | 		return result; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Code def_using( StrC name, UsingT specifier | 	Code def_using( StrC name, Code type | ||||||
| 		, Code type |  | ||||||
| 		, Code attributes | 		, Code attributes | ||||||
| 		, ModuleFlag mflags ) | 		, ModuleFlag mflags ) | ||||||
| 	{ | 	{ | ||||||
| @@ -2633,20 +2659,10 @@ namespace gen | |||||||
| 		result              = make_code(); | 		result              = make_code(); | ||||||
| 		result->Name        = get_cached_string( name ); | 		result->Name        = get_cached_string( name ); | ||||||
| 		result->ModuleFlags = mflags; | 		result->ModuleFlags = mflags; | ||||||
|  | 		result->Type = ECode::Using; | ||||||
|  |  | ||||||
| 		switch ( specifier ) | 		if ( type ) | ||||||
| 		{ | 			result->add_entry( type ); | ||||||
| 			case UsingRegular: |  | ||||||
| 				result->Type = ECode::Using; |  | ||||||
|  |  | ||||||
| 				if ( type ) |  | ||||||
| 					result->add_entry( type ); |  | ||||||
| 			break; |  | ||||||
|  |  | ||||||
| 			case UsingNamespace: |  | ||||||
| 				result->Type = ECode::Using_Namespace; |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if ( attributes ) | 		if ( attributes ) | ||||||
| 			result->add_entry( attributes ); | 			result->add_entry( attributes ); | ||||||
| @@ -2655,6 +2671,20 @@ namespace gen | |||||||
| 		return result; | 		return result; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	Code def_using_namespace( StrC name ) | ||||||
|  | 	{ | ||||||
|  | 		name_check( def_using_namespace, name ); | ||||||
|  |  | ||||||
|  | 		Code | ||||||
|  | 		result          = make_code(); | ||||||
|  | 		result->Name    = get_cached_string( name ); | ||||||
|  | 		result->Content = result->Name; | ||||||
|  | 		result->Type    = ECode::Using_Namespace; | ||||||
|  |  | ||||||
|  | 		result.lock(); | ||||||
|  | 		return result; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	Code def_variable( Code type, StrC name, Code value | 	Code def_variable( Code type, StrC name, Code value | ||||||
| 		, Code specifiers, Code attributes | 		, Code specifiers, Code attributes | ||||||
| 		, ModuleFlag mflags ) | 		, ModuleFlag mflags ) | ||||||
| @@ -3159,6 +3189,8 @@ namespace gen | |||||||
| 		result->Name = current->Name; | 		result->Name = current->Name; | ||||||
| 		result->Type = current->Type; | 		result->Type = current->Type; | ||||||
|  |  | ||||||
|  | 		result->add_entry( current->entry( 0) ); | ||||||
|  |  | ||||||
| 		while( codes++, current = * codes, num--, num > 0 ) | 		while( codes++, current = * codes, num--, num > 0 ) | ||||||
| 		{ | 		{ | ||||||
| 			check_current(); | 			check_current(); | ||||||
| @@ -3259,7 +3291,7 @@ namespace gen | |||||||
| 				return Code::Invalid; | 				return Code::Invalid; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if ( entry->Type != Untyped ) | 			if ( entry->Type != Untyped && entry->Type != Comment ) | ||||||
| 			{ | 			{ | ||||||
| 				log_failure("gen::def_union_body: Entry type is not allowed - %s. Must be of untyped type.", entry->debug_str() ); \ | 				log_failure("gen::def_union_body: Entry type is not allowed - %s. Must be of untyped type.", entry->debug_str() ); \ | ||||||
| 				return Code::Invalid; | 				return Code::Invalid; | ||||||
|   | |||||||
| @@ -77,7 +77,6 @@ namespace gen | |||||||
| 		Entry( Typedef )              \ | 		Entry( Typedef )              \ | ||||||
| 		Entry( Typename )             \ | 		Entry( Typename )             \ | ||||||
| 		Entry( Union )			      \ | 		Entry( Union )			      \ | ||||||
| 		Entry( Union_Fwd )		      \ |  | ||||||
| 		Entry( Union_Body) 		      \ | 		Entry( Union_Body) 		      \ | ||||||
| 		Entry( Using )                \ | 		Entry( Using )                \ | ||||||
| 		Entry( Using_Namespace )      \ | 		Entry( Using_Namespace )      \ | ||||||
| @@ -319,12 +318,17 @@ namespace gen | |||||||
| 		None    = 0, | 		None    = 0, | ||||||
| 		Export  = bit(0), | 		Export  = bit(0), | ||||||
| 		Import  = bit(1), | 		Import  = bit(1), | ||||||
| 		Private = bit(2), | 		// Private = bit(2), | ||||||
|  |  | ||||||
| 		Num_ModuleFlags, | 		Num_ModuleFlags, | ||||||
| 		Invalid, | 		Invalid, | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|  | 	ModuleFlag operator|( ModuleFlag A, ModuleFlag B) | ||||||
|  | 	{ | ||||||
|  | 		return (ModuleFlag)( (u32)A | (u32)B ); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| 		Predefined attributes | 		Predefined attributes | ||||||
|  |  | ||||||
| @@ -818,13 +822,14 @@ namespace gen | |||||||
| 	Code def_typedef( StrC name, Code type, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); | 	Code def_typedef( StrC name, Code type, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); | ||||||
| 	Code def_type   ( StrC name, Code arrayexpr = NoCode, Code specifiers = NoCode ); | 	Code def_type   ( StrC name, Code arrayexpr = NoCode, Code specifiers = NoCode ); | ||||||
|  |  | ||||||
| 	Code def_union( StrC name, Code body = NoCode, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); | 	Code def_union( StrC name, Code body, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); | ||||||
|  |  | ||||||
| 	Code def_using( StrC name, UsingT specifier = UsingRegular | 	Code def_using( StrC name, Code type = NoCode | ||||||
| 		, Code       type        = NoCode |  | ||||||
| 		, Code       attributess = NoCode | 		, Code       attributess = NoCode | ||||||
| 		, ModuleFlag mflags      = ModuleFlag::None ); | 		, ModuleFlag mflags      = ModuleFlag::None ); | ||||||
|  |  | ||||||
|  | 	Code def_using_namespace( StrC name ); | ||||||
|  |  | ||||||
| 	Code def_variable( Code type, StrC name, Code value = NoCode | 	Code def_variable( Code type, StrC name, Code value = NoCode | ||||||
| 		, Code       specifiers = NoCode, Code attributes = NoCode | 		, Code       specifiers = NoCode, Code attributes = NoCode | ||||||
| 		, ModuleFlag mflags     = ModuleFlag::None ); | 		, ModuleFlag mflags     = ModuleFlag::None ); | ||||||
| @@ -1130,6 +1135,9 @@ namespace gen | |||||||
| 	extern Code access_protected; | 	extern Code access_protected; | ||||||
| 	extern Code access_private; | 	extern Code access_private; | ||||||
|  |  | ||||||
|  | 	extern Code module_global_fragment; | ||||||
|  | 	extern Code module_private_fragment; | ||||||
|  |  | ||||||
| 	extern Code spec_const; | 	extern Code spec_const; | ||||||
| 	extern Code spec_consteval; | 	extern Code spec_consteval; | ||||||
| 	extern Code spec_constexpr; | 	extern Code spec_constexpr; | ||||||
|   | |||||||
| @@ -64,7 +64,7 @@ Code gen__array( StrC type, sw type_size ) | |||||||
|  |  | ||||||
| 	Code array; | 	Code array; | ||||||
| 	{ | 	{ | ||||||
| 		Code using_type = def_using( name(Type), UsingRegular, t_type ); | 		Code using_type = def_using( name(Type), t_type ); | ||||||
| 		Code data       = def_variable( t_type_ptr, name(Data) ); | 		Code data       = def_variable( t_type_ptr, name(Data) ); | ||||||
|  |  | ||||||
| 		Code init; | 		Code init; | ||||||
|   | |||||||
| @@ -13,21 +13,25 @@ u32 gen_sanity() | |||||||
|  |  | ||||||
| 	// Comment | 	// Comment | ||||||
| 	{ | 	{ | ||||||
| 		Code comment_test = def_comment( StrC::from("Sanity check: def_omment test") ); | 		Code comment_test = def_comment( StrC::from("Sanity check: def_comment test") ); | ||||||
|  |  | ||||||
| 		gen_sanity_file.print(comment_test); | 		gen_sanity_file.print(comment_test); | ||||||
| 		gen_sanity_file.print_fmt("\n"); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	gen_sanity_file.print_fmt("\n"); | ||||||
|  | 	gen_sanity_file.print( def_comment( StrC::from( | ||||||
|  | 		"The following will show a series of base cases for the gen api.\n" | ||||||
|  | 	))); | ||||||
|  |  | ||||||
| 	// Class | 	// Class | ||||||
| 	{ | 	{ | ||||||
| 		Code fwd = def_class( StrC::from("Test_EmptyClass") ); | 		Code fwd = def_class( name(TestEmptyClass) ); | ||||||
| 		Code empty_body; | 		Code empty_body; | ||||||
| 		{ | 		{ | ||||||
| 			Code cmt  = def_comment( StrC::from("Empty class") ); | 			Code cmt  = def_comment( StrC::from("Empty class body") ); | ||||||
| 			Code body = def_class_body( 1, cmt ); | 			Code body = def_class_body( 1, cmt ); | ||||||
|  |  | ||||||
| 			empty_body = def_class( StrC::from("Test_EmptyClass"), body ); | 			empty_body = def_class( name(TestEmptyClass), body ); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		gen_sanity_file.print(fwd); | 		gen_sanity_file.print(fwd); | ||||||
| @@ -39,8 +43,7 @@ u32 gen_sanity() | |||||||
| 	// Typedef | 	// Typedef | ||||||
| 	{ | 	{ | ||||||
| 		Code t_unsigned_char = def_type( name(unsigned char) ); | 		Code t_unsigned_char = def_type( name(unsigned char) ); | ||||||
|  | 		Code u8_typedef      = def_typedef( name(u8), t_unsigned_char ); | ||||||
| 		Code u8_typedef = def_typedef( name(u8), t_unsigned_char ); |  | ||||||
|  |  | ||||||
| 		gen_sanity_file.print(u8_typedef); | 		gen_sanity_file.print(u8_typedef); | ||||||
| 	} | 	} | ||||||
| @@ -49,10 +52,9 @@ u32 gen_sanity() | |||||||
|  |  | ||||||
| 	// Enum | 	// Enum | ||||||
| 	{ | 	{ | ||||||
| 		Code fwd = def_enum( StrC::from("Test_Enum"), NoCode, t_u8 ); | 		Code fwd = def_enum( name(ETestEnum), NoCode, t_u8 ); | ||||||
| 		Code def; | 		Code def; | ||||||
| 		{ | 		{ | ||||||
|  |  | ||||||
| 			Code body = untyped_str( StrC::from( | 			Code body = untyped_str( StrC::from( | ||||||
| 			#define enum_entry( id ) "\t" #id ",\n" | 			#define enum_entry( id ) "\t" #id ",\n" | ||||||
| 				enum_entry( A ) | 				enum_entry( A ) | ||||||
| @@ -61,13 +63,212 @@ u32 gen_sanity() | |||||||
| 			#undef enum_entry | 			#undef enum_entry | ||||||
| 			)); | 			)); | ||||||
|  |  | ||||||
| 			def = def_enum( StrC::from("Test_Enum"), body, t_u8 ); | 			def = def_enum( name(ETestEnum), body, t_u8 ); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		Code fwd_enum_class = def_enum( name(ETestEnumClass), NoCode, t_u8, EnumClass ); | ||||||
|  |  | ||||||
|  | 		gen_sanity_file.print(fwd); | ||||||
|  | 		gen_sanity_file.print(def); | ||||||
|  | 		gen_sanity_file.print(fwd_enum_class); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	gen_sanity_file.print_fmt("\n"); | ||||||
|  |  | ||||||
|  | 	// External Linkage | ||||||
|  | 	{ | ||||||
|  | 		Code body = def_extern_link_body( 1 | ||||||
|  | 			, def_comment( StrC::from("Empty extern body") ) | ||||||
|  | 		); | ||||||
|  |  | ||||||
|  | 		Code c_extern = def_extern_link( name(C), body ); | ||||||
|  |  | ||||||
|  | 		gen_sanity_file.print(c_extern); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	gen_sanity_file.print_fmt("\n"); | ||||||
|  |  | ||||||
|  | 	// Friend | ||||||
|  | 	{ | ||||||
|  | 		Code fwd  = def_class( name(TestFriendFwd)); | ||||||
|  | 		Code body = def_class_body( 1 | ||||||
|  | 			, def_friend( fwd ) | ||||||
|  | 		); | ||||||
|  |  | ||||||
|  | 		gen_sanity_file.print( def_class( name(TestFriend), body ) ); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	gen_sanity_file.print_fmt("\n"); | ||||||
|  |  | ||||||
|  | 	// Function | ||||||
|  | 	{ | ||||||
|  | 		Code fwd = def_function( name(test_function) ); | ||||||
|  | 		Code def; | ||||||
|  | 		{ | ||||||
|  | 			Code body = def_function_body( 1 | ||||||
|  | 				, def_comment( StrC::from("Empty function body") ) | ||||||
|  | 			); | ||||||
|  |  | ||||||
|  | 			def = def_function( name(test_function), __, __, body ); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		gen_sanity_file.print(fwd); | 		gen_sanity_file.print(fwd); | ||||||
| 		gen_sanity_file.print(def); | 		gen_sanity_file.print(def); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	gen_sanity_file.print_fmt("\n"); | ||||||
|  |  | ||||||
|  | 	// Include | ||||||
|  | 	{ | ||||||
|  | 		Code include = def_include( StrC::from("DummyInclude.hpp") ); | ||||||
|  |  | ||||||
|  | 		gen_sanity_file.print(include); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	gen_sanity_file.print_fmt("\n"); | ||||||
|  |  | ||||||
|  | 	// Module | ||||||
|  | 	if (0) | ||||||
|  | 	{ | ||||||
|  | 		Code module_export = def_module( name(TestModule), ModuleFlag::Export ); | ||||||
|  | 		Code module_import = def_module( name(TestModule), ModuleFlag::Import ); | ||||||
|  | 		Code module_both   = def_module( name(TestModule), ModuleFlag::Export | ModuleFlag::Import ); | ||||||
|  |  | ||||||
|  | 		gen_sanity_file.print(module_global_fragment); | ||||||
|  | 		gen_sanity_file.print(module_private_fragment); | ||||||
|  | 		gen_sanity_file.print(module_export); | ||||||
|  | 		gen_sanity_file.print(module_import); | ||||||
|  | 		gen_sanity_file.print(module_both); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	gen_sanity_file.print_fmt("\n"); | ||||||
|  |  | ||||||
|  | 	// Namespace | ||||||
|  | 	{ | ||||||
|  | 		Code namespace_def; | ||||||
|  | 		{ | ||||||
|  | 			Code body = def_namespace_body( 1 | ||||||
|  | 				, def_comment( StrC::from("Empty namespace body") ) | ||||||
|  | 			); | ||||||
|  |  | ||||||
|  | 			namespace_def = def_namespace( name(TestNamespace), body ); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		gen_sanity_file.print(namespace_def); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	gen_sanity_file.print_fmt("\n"); | ||||||
|  |  | ||||||
|  | 	// Operator | ||||||
|  | 	{ | ||||||
|  | 		// This is nasty... | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	gen_sanity_file.print_fmt("\n"); | ||||||
|  |  | ||||||
|  | 	// Parameters | ||||||
|  | 	{ | ||||||
|  | 		Code fwd; | ||||||
|  | 		{ | ||||||
|  | 			Code params = def_param( t_u8, name(a) ); | ||||||
|  |  | ||||||
|  | 			fwd = def_function( name(test_function_wparam), params ); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		Code def, def2; | ||||||
|  | 		{ | ||||||
|  | 			Code body = def_function_body( 1 | ||||||
|  | 				, def_comment( StrC::from("Empty function body") ) | ||||||
|  | 			); | ||||||
|  |  | ||||||
|  | 			Code params = def_params( 2 * 3, t_u8, 1, "a", t_u8, 1, "b" ); | ||||||
|  |  | ||||||
|  | 			def = def_function( name(test_function_wparams), params, __, body ); | ||||||
|  |  | ||||||
|  | 			Code param_a = def_param( t_u8, name(a)); | ||||||
|  | 			Code param_b = def_param( t_u8, name(b)); | ||||||
|  | 			Code params_arr[2] = { param_a, param_b }; | ||||||
|  |  | ||||||
|  | 			Code params2 = def_params( 2, params_arr ); | ||||||
|  |  | ||||||
|  | 			def2 = def_function( name(test_function_wparams2), params2, __, body ); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		gen_sanity_file.print(fwd); | ||||||
|  | 		gen_sanity_file.print(def); | ||||||
|  | 		gen_sanity_file.print(def2); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	gen_sanity_file.print_fmt("\n"); | ||||||
|  |  | ||||||
|  | 	// Specifiers | ||||||
|  | 	{ | ||||||
|  | 		Code fwd_fn         = def_function( name(test_function_specifiers), __, __, __, spec_inline ); | ||||||
|  |  | ||||||
|  | 		// Need an op overload here | ||||||
|  |  | ||||||
|  | 		Code t_ct_u8               = def_type( name(u8), __, spec_constexpr ); | ||||||
|  | 		Code typedef_ConstExprTest = def_typedef( name(ConstExprTest), t_ct_u8 ); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	gen_sanity_file.print_fmt("\n"); | ||||||
|  |  | ||||||
|  | 	// Struct | ||||||
|  | 	{ | ||||||
|  | 		Code fwd = def_class( name(TestEmptyStruct) ); | ||||||
|  | 		Code empty_body; | ||||||
|  | 		{ | ||||||
|  | 			Code cmt  = def_comment( StrC::from("Empty class body") ); | ||||||
|  | 			Code body = def_class_body( 1, cmt ); | ||||||
|  |  | ||||||
|  | 			empty_body = def_class( name(TestEmptyStruct), body ); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		gen_sanity_file.print(fwd); | ||||||
|  | 		gen_sanity_file.print(empty_body); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	gen_sanity_file.print_fmt("\n"); | ||||||
|  |  | ||||||
|  | 	// Union | ||||||
|  | 	{ | ||||||
|  | 		Code body = def_union_body( 1 | ||||||
|  | 			, def_comment( StrC::from("Empty union body") ) | ||||||
|  | 		); | ||||||
|  |  | ||||||
|  | 		Code def = def_union( name(TestEmptyUnion), body ); | ||||||
|  |  | ||||||
|  | 		gen_sanity_file.print(def); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	gen_sanity_file.print_fmt("\n"); | ||||||
|  |  | ||||||
|  | 	// Using | ||||||
|  | 	{ | ||||||
|  | 		Code reg    = def_using( name(TestUsing), t_u8 ); | ||||||
|  | 		Code nspace = def_using_namespace( name(TestNamespace) ); | ||||||
|  |  | ||||||
|  | 		gen_sanity_file.print(reg); | ||||||
|  | 		gen_sanity_file.print(nspace); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	gen_sanity_file.print_fmt("\n"); | ||||||
|  |  | ||||||
|  | 	// Variable | ||||||
|  | 	{ | ||||||
|  | 		Code bss  = def_variable( t_u8, name(test_variable) ); | ||||||
|  | 		Code data = def_variable( t_u8, name(test_variable2), untyped_str( code( 0x12 )) ); | ||||||
|  |  | ||||||
|  | 		gen_sanity_file.print(bss); | ||||||
|  | 		gen_sanity_file.print(data); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	gen_sanity_file.print_fmt("\n"); | ||||||
|  |  | ||||||
|  | 	gen_sanity_file.print( def_comment( StrC::from( | ||||||
|  | 		"End of base case tests.\n" | ||||||
|  | 	))); | ||||||
|  |  | ||||||
| 	gen_sanity_file.write(); | 	gen_sanity_file.write(); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								test/gen/DummyInclude.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/gen/DummyInclude.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | // Only for gen testing. | ||||||
| @@ -1,19 +1,85 @@ | |||||||
| // Sanity check: def_omment test | // Sanity check: def_comment test | ||||||
|  |  | ||||||
| class Test_EmptyClass; | // The following will show a series of base cases for the gen api. | ||||||
| class Test_EmptyClass |  | ||||||
|  | class TestEmptyClass; | ||||||
|  | class TestEmptyClass | ||||||
| { | { | ||||||
| 	// Empty class | 	// Empty class body | ||||||
|  |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
| typedef unsigned char u8; | typedef unsigned char u8; | ||||||
|  |  | ||||||
| enum Test_Enum : u8; | enum ETestEnum : u8; | ||||||
| enum Test_Enum : u8 | enum ETestEnum : u8 | ||||||
| { | { | ||||||
| 	A, | 	A, | ||||||
| 	B, | 	B, | ||||||
| 	C, | 	C, | ||||||
| }; | }; | ||||||
|  | enum class ETestEnumClass : u8; | ||||||
|  |  | ||||||
|  | extern "C" | ||||||
|  | { | ||||||
|  | 	// Empty extern body | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class TestFriend | ||||||
|  | { | ||||||
|  | 	friend 	class TestFriendFwd; | ||||||
|  |  | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | void test_function(void); | ||||||
|  | void test_function(void) | ||||||
|  | { | ||||||
|  | 	// Empty function body | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #include "DummyInclude.hpp" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | namespace TestNamespace | ||||||
|  | { | ||||||
|  | 	// Empty namespace body | ||||||
|  |  | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void test_function_wparam(u8 a); | ||||||
|  | void test_function_wparams(u8 a, u8 b) | ||||||
|  | { | ||||||
|  | 	// Empty function body | ||||||
|  |  | ||||||
|  | } | ||||||
|  | void test_function_wparams2(u8 a, u8 b) | ||||||
|  | { | ||||||
|  | 	// Empty function body | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class TestEmptyStruct; | ||||||
|  | class TestEmptyStruct | ||||||
|  | { | ||||||
|  | 	// Empty class body | ||||||
|  |  | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | union TestEmptyUnion | ||||||
|  | { | ||||||
|  | 	// Empty union body | ||||||
|  |  | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | using TestUsing = u8; | ||||||
|  | using namespace TestNamespace; | ||||||
|  |  | ||||||
|  | u8 test_variable; | ||||||
|  | u8 test_variable2 = 0x12; | ||||||
|  |  | ||||||
|  | // End of base case tests. | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user