Compare commits

...

5 Commits

Author SHA1 Message Date
Ed_
a2bcafbec6 Basic changes to build/target/uproject while dealing with Seekers boostrap 2025-01-23 00:00:03 -05:00
Ed_
66a15a7a02 ignore binaries
deciding not to keep them in the repo
2024-12-25 19:58:51 -05:00
Ed_
a4969ee266 latest gencpp 2024-12-16 21:05:13 -05:00
Ed_
3109ea4641 fixes for running GasaGen more than once in editor 2024-12-15 19:54:01 -05:00
Ed_
c895772cff fixes etc for gasa gen 2024-12-15 18:22:59 -05:00
34 changed files with 4049 additions and 3079 deletions

1
.gitignore vendored
View File

@ -42,3 +42,4 @@ GasaGen_*.pdb
Project/Content/
.vs
.vs
Project/Binaries

22
.vscode/settings.json vendored
View File

@ -4,5 +4,25 @@
"files.associations": {
"*.rmd": "markdown",
"*.rh": "cpp"
}
},
"workbench.colorCustomizations": {
"activityBar.activeBackground": "#65c89b",
"activityBar.background": "#65c89b",
"activityBar.foreground": "#15202b",
"activityBar.inactiveForeground": "#15202b99",
"activityBarBadge.background": "#945bc4",
"activityBarBadge.foreground": "#e7e7e7",
"commandCenter.border": "#15202b99",
"sash.hoverBorder": "#65c89b",
"statusBar.background": "#42b883",
"statusBar.foreground": "#15202b",
"statusBarItem.hoverBackground": "#359268",
"statusBarItem.remoteBackground": "#42b883",
"statusBarItem.remoteForeground": "#15202b",
"titleBar.activeBackground": "#42b883",
"titleBar.activeForeground": "#15202b",
"titleBar.inactiveBackground": "#42b88399",
"titleBar.inactiveForeground": "#15202b99"
},
"peacock.color": "#42b883"
}

Binary file not shown.

View File

@ -17,175 +17,12 @@
}
],
"Plugins": [
{
"Name": "ModelingToolsEditorMode",
"Enabled": true,
"TargetAllowList": [
"Editor"
]
},
{
"Name": "AssetManagerEditor",
"Enabled": true
},
{
"Name": "ContentBrowserAliasDataSource",
"Enabled": true
},
{
"Name": "ContentBrowserAssetDataSource",
"Enabled": true
},
{
"Name": "ContentBrowserClassDataSource",
"Enabled": true
},
{
"Name": "ContentBrowserFileDataSource",
"Enabled": true
},
{
"Name": "EngineAssetDefinitions",
"Enabled": true
},
{
"Name": "LevelSequenceEditor",
"Enabled": true
},
{
"Name": "Niagara",
"Enabled": true
},
{
"Name": "PluginBrowser",
"Enabled": true
},
{
"Name": "RiderSourceCodeAccess",
"Enabled": true
},
{
"Name": "WorldPartitionHLODUtilities",
"Enabled": true
},
{
"Name": "PropertyAccessEditor",
"Enabled": true
},
{
"Name": "BlueprintMaterialTextureNodes",
"Enabled": true
},
{
"Name": "RenderDocPlugin",
"Enabled": true
},
{
"Name": "N10XSourceCodeAccess",
"Enabled": true
},
{
"Name": "OnlineSubsystemSteam",
"Enabled": true
},
{
"Name": "OnlineSubsystemNull",
"Enabled": true
},
{
"Name": "OnlineSubsystem",
"Enabled": true
},
{
"Name": "SteamController",
"Enabled": true
},
{
"Name": "GameInput",
"Enabled": true,
"SupportedTargetPlatforms": [
"Win64"
]
},
{
"Name": "GameInputWindows",
"Enabled": true,
"SupportedTargetPlatforms": [
"Win64"
]
},
{
"Name": "WinDualShock",
"Enabled": true,
"SupportedTargetPlatforms": [
"Win64"
]
},
{
"Name": "RawInput",
"Enabled": true
},
{
"Name": "XInputDevice",
"Enabled": true,
"SupportedTargetPlatforms": [
"Win64"
]
},
{
"Name": "EnhancedInput",
"Enabled": true
},
{
"Name": "InputDebugging",
"Enabled": true
},
{
"Name": "AISupport",
"Enabled": true
},
{
"Name": "Spatialization",
"Enabled": true
},
{
"Name": "SoundUtilities",
"Enabled": true
},
{
"Name": "SoundMod",
"Enabled": true
},
{
"Name": "Metasound",
"Enabled": true
},
{
"Name": "AudioWidgets",
"Enabled": true
},
{
"Name": "TextureFormatOodle",
"Enabled": true
},
{
"Name": "OodleNetwork",
"Enabled": true
},
{
"Name": "GameplayTagsEditor",
"Enabled": true
},
{
"Name": "MeshPainting",
"Enabled": true
},
{
"Name": "NiagaraFluids",
"Enabled": true
},
{
"Name": "XRVisualization",
"Name": "AssetManagerEditor",
"Enabled": true
},
{
@ -193,7 +30,15 @@
"Enabled": true
},
{
"Name": "ReplicationGraph",
"Name": "AudioWidgets",
"Enabled": true
},
{
"Name": "BlueprintMaterialTextureNodes",
"Enabled": true
},
{
"Name": "BlueprintStats",
"Enabled": true
},
{
@ -201,61 +46,7 @@
"Enabled": true
},
{
"Name": "SlateScripting",
"Enabled": true
},
{
"Name": "OpenXR",
"Enabled": true,
"SupportedTargetPlatforms": [
"Win64",
"Linux",
"Android"
]
},
{
"Name": "OpenXREyeTracker",
"Enabled": true,
"SupportedTargetPlatforms": [
"Win64",
"Linux",
"Android"
]
},
{
"Name": "OpenXRMsftHandInteraction",
"Enabled": true,
"SupportedTargetPlatforms": [
"Win64",
"Android"
]
},
{
"Name": "XRBase",
"Enabled": true
},
{
"Name": "SimpleHMD",
"Enabled": true,
"SupportedTargetPlatforms": [
"Win64",
"Linux",
"Android",
"Mac",
"IOS",
"VisionOS"
]
},
{
"Name": "SlateModelViewViewModel",
"Enabled": true
},
{
"Name": "ModelViewViewModel",
"Enabled": true
},
{
"Name": "SteamAudio",
"Name": "ColorCorrectRegions",
"Enabled": true
},
{
@ -278,14 +69,145 @@
"Name": "CogAll",
"Enabled": true
},
{
"Name": "ContentBrowserAliasDataSource",
"Enabled": true
},
{
"Name": "ContentBrowserAssetDataSource",
"Enabled": true
},
{
"Name": "ContentBrowserClassDataSource",
"Enabled": true
},
{
"Name": "ContentBrowserFileDataSource",
"Enabled": true
},
{
"Name": "ControlFlows",
"Enabled": true
},
{
"Name": "EngineAssetDefinitions",
"Enabled": true
},
{
"Name": "EnhancedInput",
"Enabled": true
},
{
"Name": "GameplayInsights",
"Enabled": true
},
{
"Name": "GameInput",
"Enabled": true,
"SupportedTargetPlatforms": [
"Win64"
]
},
{
"Name": "GameInputWindows",
"Enabled": true,
"SupportedTargetPlatforms": [
"Win64"
]
},
{
"Name": "GameplayAbilities",
"Enabled": true
},
{
"Name": "GameplayTagsEditor",
"Enabled": true
},
{
"Name": "InputDebugging",
"Enabled": true
},
{
"Name": "LevelSequenceEditor",
"Enabled": true
},
{
"Name": "LiveLink",
"Enabled": true
},
{
"Name": "LiveUpdateForSlate",
"Enabled": true
},
{
"Name": "MeshPainting",
"Enabled": true
},
{
"Name": "Metasound",
"Enabled": true
},
{
"Name": "ModelingToolsEditorMode",
"Enabled": true,
"TargetAllowList": [
"Editor"
]
},
{
"Name": "ModelViewViewModel",
"Enabled": true
},
{
"Name": "N10XSourceCodeAccess",
"Enabled": true
},
{
"Name": "NetworkPredictionInsights",
"Enabled": true
},
{
"Name": "Niagara",
"Enabled": true
},
{
"Name": "NiagaraFluids",
"Enabled": true
},
{
"Name": "OodleNetwork",
"Enabled": true
},
{
"Name": "OnlineSubsystem",
"Enabled": true
},
{
"Name": "OnlineSubsystemNull",
"Enabled": true
},
{
"Name": "OnlineSubsystemSteam",
"Enabled": true
},
{
"Name": "OpenXR",
"Enabled": true,
"SupportedTargetPlatforms": [
"Win64",
"Linux",
"Android"
]
},
{
"Name": "OpenXREyeTracker",
"Enabled": true,
"SupportedTargetPlatforms": [
"Win64",
"Linux",
"Android"
]
},
{
"Name": "OpenXRHandTracking",
"Enabled": true,
@ -296,27 +218,27 @@
]
},
{
"Name": "VisualStudioSourceCodeAccess",
"Name": "OpenXRMsftHandInteraction",
"Enabled": true,
"SupportedTargetPlatforms": [
"Win64",
"Android"
]
},
{
"Name": "PluginBrowser",
"Enabled": true
},
{
"Name": "SlateInsights",
"Name": "PropertyAccessEditor",
"Enabled": true
},
{
"Name": "TraceUtilities",
"Name": "RawInput",
"Enabled": true
},
{
"Name": "NetworkPredictionInsights",
"Enabled": true
},
{
"Name": "TraceSourceFilters",
"Enabled": true
},
{
"Name": "GameplayInsights",
"Name": "RenderDocPlugin",
"Enabled": true
},
{
@ -324,24 +246,102 @@
"Enabled": true
},
{
"Name": "BlueprintStats",
"Name": "ReplicationGraph",
"Enabled": true
},
{
"Name": "ColorCorrectRegions",
"Name": "RiderSourceCodeAccess",
"Enabled": true
},
{
"Name": "ControlFlows",
"Name": "SimpleHMD",
"Enabled": true,
"SupportedTargetPlatforms": [
"Win64",
"Linux",
"Android",
"Mac",
"IOS",
"VisionOS"
]
},
{
"Name": "SlateInsights",
"Enabled": true
},
{
"Name": "LiveUpdateForSlate",
"Name": "SlateModelViewViewModel",
"Enabled": true
},
{
"Name": "SlateScripting",
"Enabled": true
},
{
"Name": "SoundMod",
"Enabled": true
},
{
"Name": "Spatialization",
"Enabled": true
},
{
"Name": "SoundUtilities",
"Enabled": true
},
{
"Name": "SteamAudio",
"Enabled": true
},
{
"Name": "SteamController",
"Enabled": true
},
{
"Name": "SunPosition",
"Enabled": true
},
{
"Name": "TextureFormatOodle",
"Enabled": true
},
{
"Name": "TraceUtilities",
"Enabled": true
},
{
"Name": "TraceSourceFilters",
"Enabled": true
},
{
"Name": "VisualStudioSourceCodeAccess",
"Enabled": true
},
{
"Name": "WinDualShock",
"Enabled": true,
"SupportedTargetPlatforms": [
"Win64"
]
},
{
"Name": "WorldPartitionHLODUtilities",
"Enabled": true
},
{
"Name": "XRBase",
"Enabled": true
},
{
"Name": "XInputDevice",
"Enabled": true,
"SupportedTargetPlatforms": [
"Win64"
]
},
{
"Name": "XRVisualization",
"Enabled": false
}
]
}

View File

@ -1,7 +1,7 @@
using BuildSettingsVersion = UnrealBuildTool.BuildSettingsVersion;
using TargetInfo = UnrealBuildTool.TargetInfo;
using TargetRules = UnrealBuildTool.TargetRules;
using TargetType = UnrealBuildTool.TargetType;
using TargetInfo = UnrealBuildTool.TargetInfo;
using TargetRules = UnrealBuildTool.TargetRules;
using TargetType = UnrealBuildTool.TargetType;
public class GasaTarget : TargetRules
{

View File

@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using UnrealBuildTool;
using ModuleRules = UnrealBuildTool.ModuleRules;
using ReadOnlyTargetRules = UnrealBuildTool.ReadOnlyTargetRules;
using TargetRules = UnrealBuildTool.TargetRules;
using ModuleRules = UnrealBuildTool.ModuleRules;
using ReadOnlyTargetRules = UnrealBuildTool.ReadOnlyTargetRules;
using TargetRules = UnrealBuildTool.TargetRules;
using UnrealTargetConfiguration = UnrealBuildTool.UnrealTargetConfiguration;
public class Gasa : ModuleRules
@ -26,8 +26,10 @@ public class Gasa : ModuleRules
bEnableExceptions = false;
bEnableBufferSecurityChecks = false;
bEnableNonInlinedGenCppWarnings = false;
bEnableUndefinedIdentifierWarnings = false;
// bEnableUndefinedIdentifierWarnings = false;
bIgnoreUnresolvedSymbols = false;
UndefinedIdentifierWarningLevel = WarningLevel.Off;
bEnableObjCAutomaticReferenceCounting = false;
bEnableObjCExceptions = false;

View File

@ -7,7 +7,6 @@ USTRUCT()
struct GASA_API FGasaDevOptionsCache
{
GENERATED_BODY()
UPROPERTY()
TArray<UObject*> AttributeSets;
UPROPERTY()

View File

@ -1,42 +1,50 @@
using UnrealBuildTool;
using ModuleRules = UnrealBuildTool.ModuleRules;
using ReadOnlyTargetRules = UnrealBuildTool.ReadOnlyTargetRules;
public class GasaEditor : ModuleRules
{
public GasaEditor(ReadOnlyTargetRules Target) : base(Target)
{
#region Engine
PrivateIncludePathModuleNames.AddRange(new string[] {
"Core",
"CoreUObject",
"Engine",
});
PrivateDependencyModuleNames.AddRange(new string[] {
"Core",
"Engine",
"CoreUObject",
public GasaEditor(ReadOnlyTargetRules Target) : base(Target)
{
#region Engine
PrivateIncludePathModuleNames.AddRange(new string[]
{
"Core",
"CoreUObject",
"Engine",
});
PrivateDependencyModuleNames.AddRange(new string[]
{
"Core",
"Engine",
"CoreUObject",
"EditorStyle",
"PropertyEditor",
"SlateCore",
"Slate",
"UMG",
"UnrealEd",
});
#endregion Engine
"PropertyEditor",
"SlateCore",
"Slate",
"UMG",
"UnrealEd",
});
#endregion Engine
PublicIncludePaths.Add("GasaEditor");
PrivateDependencyModuleNames.Add("Gasa");
bWarningsAsErrors = false;
ShadowVariableWarningLevel = UnrealBuildTool.WarningLevel.Off;
bWarningsAsErrors = false;
ShadowVariableWarningLevel = UnrealBuildTool.WarningLevel.Off;
UndefinedIdentifierWarningLevel = UnrealBuildTool.WarningLevel.Off;
// gencpp related defines
PublicDefinitions.Add("Build_Debug=1");
PublicDefinitions.Add("GEN_TIME=1");
PublicDefinitions.Add("GEN_EXECUTION_EXPRESSION_SUPPORT=0");
PublicDefinitions.Add("GEN_EXPOSE_BACKEND=1");
PublicDefinitions.Add("GEN_PARSER_DISABLE_MACRO_TYPEDEF=0");
PublicDefinitions.Add("GEN_DONT_USE_NAMESPACE=0");
PublicDefinitions.Add("GEN_BUILD_DEBUG=1");
PublicDefinitions.Add("GEN_SUPPORT_CPP_REFERENCES=1");
OptimizeCode = CodeOptimization.Never;
}
}

View File

@ -36,22 +36,22 @@ void gen_attribute_set_from_table( UDataTable* table, FString asset_name )
check( asset_name.StartsWith(TEXT("DT_") ))
asset_name = asset_name.RightChop(3);
String str_AssetName = to_string(asset_name);
Str str_AssetName = to_string(asset_name);
String class_name = String::fmt_buf(GlobalAllocator, "U%S", str_AssetName);
String header_file_name = String::fmt_buf(GlobalAllocator, "%S.h", str_AssetName);
String inlines_file_name = String::fmt_buf(GlobalAllocator, "%S_Inlines.h", str_AssetName);
String path_header_file = String::fmt_buf(GlobalAllocator, path_gasa_ability_system "%S.h", str_AssetName);
String path_inlines_file = String::fmt_buf(GlobalAllocator, path_gasa_ability_system "%S_Inlines.h", str_AssetName);
String path_source_file = String::fmt_buf(GlobalAllocator, path_gasa_ability_system "%S.cpp", str_AssetName);
String uht_include_file = String::fmt_buf(GlobalAllocator, "%S.generated.h", str_AssetName);
Str class_name = StrBuilder::fmt_buf(gen_ctx.Allocator_Temp, "U%S", str_AssetName);
Str header_file_name = StrBuilder::fmt_buf(gen_ctx.Allocator_Temp, "%S.h", str_AssetName);
Str inlines_file_name = StrBuilder::fmt_buf(gen_ctx.Allocator_Temp, "%S_Inlines.h", str_AssetName);
Str path_header_file = StrBuilder::fmt_buf(gen_ctx.Allocator_Temp, path_gasa_ability_system "%S.h", str_AssetName);
Str path_inlines_file = StrBuilder::fmt_buf(gen_ctx.Allocator_Temp, path_gasa_ability_system "%S_Inlines.h", str_AssetName);
Str path_source_file = StrBuilder::fmt_buf(gen_ctx.Allocator_Temp, path_gasa_ability_system "%S.cpp", str_AssetName);
Str uht_include_file = StrBuilder::fmt_buf(gen_ctx.Allocator_Temp, "%S.generated.h", str_AssetName);
CodeType type_UAttributeSet = def_type( txt("UAttributeSet") );
CodeComment generation_notice = def_comment(txt("Generated by GasaEditor/GasaGen/GasaGen_AttributeSets.cpp"));
CodeTypename type_UAttributeSet = def_type( txt("UAttributeSet") );
CodeComment generation_notice = def_comment(txt("Generated by GasaEditor/GasaGen/GasaGen_AttributeSets.cpp"));
CodeAttributes api_attribute = def_attributes( UModule_GASA_API->Name);
Builder header = builder_open( path_header_file );
Builder header = gasa_builder_open( path_header_file );
{
header.print(generation_notice);
header.print(pragma_once);
@ -65,7 +65,7 @@ void gen_attribute_set_from_table( UDataTable* table, FString asset_name )
gen::CodeClass attribute_set_class = {};
{
CodeBody body = def_body( CodeT::Class_Body );
CodeBody body = def_body( CT_Class_Body );
{
body.append( UHT_GENERATED_BODY);
body.append( access_public );
@ -76,15 +76,15 @@ void gen_attribute_set_from_table( UDataTable* table, FString asset_name )
// Generate UPROPERTIES for each attribute field, organized by category
for ( TPair< FName, TArray<FAttributeSetField>>& attributes : AttributesByCategory )
{
String category_name = to_string(attributes.Key);
CodeComment category_cmt = def_comment(token_fmt("category_name", (StrC)category_name, "<category_name> Attributes"));
Str category_name = to_string(attributes.Key);
CodeComment category_cmt = def_comment(token_fmt("category_name", category_name, "<category_name> Attributes"));
body.append(category_cmt);
body.append(fmt_newline);
for (FAttributeSetField attribute : attributes.Value)
{
Code field_uproperty = code_fmt(
"category", (StrC)to_string(attribute.Category),
"property", (StrC)to_string(attribute.Name),
"category", to_string(attribute.Category),
"property", to_string(attribute.Name),
stringize(
UPROPERTY(ReplicatedUsing = Client_OnRep_<property>, EditAnywhere, BlueprintReadWrite, Category = "Attributes|<category>")
FGameplayAttributeData <property>;
@ -104,7 +104,7 @@ void gen_attribute_set_from_table( UDataTable* table, FString asset_name )
body.append(fmt_newline);
body.append(umeta_UFUNCTION);
body.append(fmt_newline);
body.append(code_fmt("property", (StrC)to_string(attribute.Name), stringize(
body.append(code_fmt("property", to_string(attribute.Name), stringize(
void Client_OnRep_<property>(FGameplayAttributeData& Prev<property>);
)));
}
@ -118,8 +118,8 @@ void gen_attribute_set_from_table( UDataTable* table, FString asset_name )
for (FAttributeSetField attribute : attributes.Value)
{
CodeFn generated_get_attribute = parse_function(token_fmt(
"class_name", (StrC)class_name,
"property", (StrC)to_string(attribute.Name),
"class_name", class_name,
"property", to_string(attribute.Name),
stringize(
static FGameplayAttribute Get<property>Attribute()
{
@ -135,7 +135,7 @@ void gen_attribute_set_from_table( UDataTable* table, FString asset_name )
for ( TPair< FName, TArray<FAttributeSetField>>& attributes : AttributesByCategory )
for (FAttributeSetField attribute : attributes.Value)
{
body.append(code_fmt("property", (StrC)to_string(attribute.Name),
body.append(code_fmt("property", to_string(attribute.Name),
stringize(
FORCEINLINE float Get<property>() const
{
@ -154,7 +154,7 @@ void gen_attribute_set_from_table( UDataTable* table, FString asset_name )
for ( TPair< FName, TArray<FAttributeSetField>>& attributes : AttributesByCategory )
for (FAttributeSetField attribute : attributes.Value)
{
body.append(code_fmt("property", (StrC)to_string(attribute.Name),
body.append(code_fmt("property", to_string(attribute.Name),
stringize(
FORCEINLINE void Set<property>(float NewVal);
)));
@ -180,10 +180,10 @@ void gen_attribute_set_from_table( UDataTable* table, FString asset_name )
body.append(fmt_newline);
}
attribute_set_class = def_class( class_name, body
, type_UAttributeSet, AccessSpec::Public
attribute_set_class = def_class( class_name, { body
, type_UAttributeSet, AccessSpec_Public
, api_attribute
);
});
header.print(UHT_UCLASS);
header.print(attribute_set_class);
}
@ -192,7 +192,7 @@ void gen_attribute_set_from_table( UDataTable* table, FString asset_name )
format_file(path_header_file);
}
Builder inlines = builder_open( path_inlines_file );
Builder inlines = gasa_builder_open( path_inlines_file );
{
inlines.print(generation_notice);
inlines.print(pragma_once);
@ -201,7 +201,7 @@ void gen_attribute_set_from_table( UDataTable* table, FString asset_name )
inlines.print(def_include(txt("AbilitySystemComponent.h")));
inlines.print(fmt_newline);
CodeBody body = def_body(ECode::Global_Body);
CodeBody body = def_body(CT_Global_Body);
{
body.append(def_pragma(txt("region Attribute Setters")));
{
@ -209,8 +209,8 @@ void gen_attribute_set_from_table( UDataTable* table, FString asset_name )
for (FAttributeSetField attribute : attributes.Value)
{
CodeFn generated_get_attribute = parse_function(token_fmt(
"class_name", (StrC)class_name,
"property", (StrC)to_string(attribute.Name),
"class_name", class_name,
"property", to_string(attribute.Name),
stringize(
FORCEINLINE void <class_name>::Set<property>(float NewVal)
{
@ -230,7 +230,7 @@ void gen_attribute_set_from_table( UDataTable* table, FString asset_name )
inlines.print(fmt_newline);
CodeNS ns_gasa = parse_namespace(token_fmt(
"class_name", (StrC)class_name,
"class_name", class_name,
stringize(
namespace Gasa
{
@ -247,7 +247,7 @@ void gen_attribute_set_from_table( UDataTable* table, FString asset_name )
format_file(path_inlines_file);
}
Builder source = builder_open( path_source_file );
Builder source = gasa_builder_open( path_source_file );
{
source.print(generation_notice);
header.print(fmt_newline);
@ -260,7 +260,7 @@ void gen_attribute_set_from_table( UDataTable* table, FString asset_name )
source.print(def_include(txt("Networking/GasaNetLibrary.h")));
source.print(def_include(txt("GameplayEffectExtension.h")));
{
CodeBody body = def_body(CodeT::Global_Body);
CodeBody body = def_body(CT_Global_Body);
body.append(fmt_newline);
CodeConstructor constructor_for_UGasaAttributeSet = parse_constructor(code(
@ -278,8 +278,8 @@ void gen_attribute_set_from_table( UDataTable* table, FString asset_name )
for (FAttributeSetField attribute : attributes.Value)
{
CodeFn field_impl = parse_function(token_fmt(
"class_name", (StrC)class_name,
"property", (StrC)to_string(attribute.Name),
"class_name", class_name,
"property", to_string(attribute.Name),
"from_notice", txt("\n// From GAMEPLAYATTRIBUTE_REPNOTIFY\n"),
stringize(
void <class_name>::Client_OnRep_<property>(FGameplayAttributeData & Prev<property>)
@ -298,8 +298,8 @@ void gen_attribute_set_from_table( UDataTable* table, FString asset_name )
CodeFn PostGameplayEffectExecute;
CodeFn PreAttributeChange;
{
CodeBody pre_attribute_clamps = def_body(CodeT::Function_Body);
CodeBody post_attribute_clamps = def_body(CodeT::Function_Body);
CodeBody pre_attribute_clamps = def_body(CT_Function_Body);
CodeBody post_attribute_clamps = def_body(CT_Function_Body);
// Generate field clamping ops for the pre & post functions
{
@ -311,22 +311,22 @@ void gen_attribute_set_from_table( UDataTable* table, FString asset_name )
for (TPair< FName, TArray<FAttributeSetField>>& attributes : AttributesByCategory)
for (FAttributeSetField attribute : attributes.Value)
{
String clamp_min;
Str clamp_min;
if (attribute.bUseMinAttribute)
clamp_min = get_cached_string(token_fmt("MinName", (StrC)to_string(attribute.MinAttribute), "Get<MinName>()"));
clamp_min = cache_str(token_fmt("MinName", to_string(attribute.MinAttribute), "Get<MinName>()"));
else
clamp_min = String::fmt_buf(GlobalAllocator, "%f", attribute.MinValue);
clamp_min = StrBuilder::fmt_buf(gen_ctx.Allocator_Temp, "%f", attribute.MinValue);
String clamp_max;
Str clamp_max;
if (attribute.bUseMaxAttribute)
clamp_max = get_cached_string(token_fmt("MaxName", (StrC)to_string(attribute.MaxAttribute), "Get<MaxName>()"));
clamp_max = cache_str(token_fmt("MaxName", to_string(attribute.MaxAttribute), "Get<MaxName>()"));
else
clamp_max = String::fmt_buf(GlobalAllocator, "%f", attribute.MaxValue);
clamp_max = StrBuilder::fmt_buf(gen_ctx.Allocator_Temp, "%f", attribute.MaxValue);
pre_attribute_clamps.append(code_fmt(
"field", (StrC)to_string(attribute.Name),
"clamp_min", (StrC)clamp_min,
"clamp_max", (StrC)clamp_max,
"field", to_string(attribute.Name),
"clamp_min", clamp_min,
"clamp_max", clamp_max,
stringize(
if (Attribute == Get<field>Attribute())
{
@ -335,9 +335,9 @@ void gen_attribute_set_from_table( UDataTable* table, FString asset_name )
)));
post_attribute_clamps.append(code_fmt(
"field", (StrC)to_string(attribute.Name),
"clamp_min", (StrC)clamp_min,
"clamp_max", (StrC)clamp_max,
"field", to_string(attribute.Name),
"clamp_min", clamp_min,
"clamp_max", clamp_max,
stringize(
if (Data.EvaluatedData.Attribute == Get<field>Attribute())
{
@ -353,8 +353,8 @@ void gen_attribute_set_from_table( UDataTable* table, FString asset_name )
}
PreAttributeChange = parse_function(token_fmt(
"class_name", (StrC)class_name,
"attribute_clamps", (StrC)pre_attribute_clamps.to_string(),
"class_name", class_name,
"attribute_clamps", pre_attribute_clamps.to_strbuilder().to_str(),
stringize(
void <class_name>::PreAttributeChange(FGameplayAttribute const& Attribute, float& NewValue)
{
@ -365,8 +365,8 @@ void gen_attribute_set_from_table( UDataTable* table, FString asset_name )
)));
PostGameplayEffectExecute = parse_function(token_fmt(
"class_name", (StrC)class_name,
"attribute_clamps", (StrC)post_attribute_clamps.to_string(),
"class_name", class_name,
"attribute_clamps", post_attribute_clamps.to_strbuilder().to_str(),
stringize(
void <class_name>::PostGameplayEffectExecute(FGameplayEffectModCallbackData const& Data)
{
@ -387,23 +387,23 @@ void gen_attribute_set_from_table( UDataTable* table, FString asset_name )
CodeFn GetLifetimeOfReplicatedProps;
{
CodeBody field_lifetimes = def_body(CodeT::Function_Body);
CodeBody field_lifetimes = def_body(CT_Function_Body);
field_lifetimes.append(fmt_newline);
field_lifetimes.append(fmt_newline);
for (TPair< FName, TArray<FAttributeSetField>>& attributes : AttributesByCategory)
for (FAttributeSetField attribute : attributes.Value)
{
field_lifetimes.append(code_fmt(
"class_name", (StrC)class_name,
"property", (StrC)to_string(attribute.Name),
"class_name", class_name,
"property", to_string(attribute.Name),
stringize(
DOREPLIFETIME_DEFAULT_GAS( <class_name>, <property> );
)));
}
GetLifetimeOfReplicatedProps = parse_function(token_fmt(
"class_name", (StrC)class_name,
"property_lifetimes", (StrC)(field_lifetimes.to_string()),
"class_name", class_name,
"property_lifetimes", field_lifetimes.to_strbuilder().to_str(),
stringize(
void <class_name>::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{

View File

@ -2,7 +2,7 @@
#include "ChangeBPActionMenu.h"
#include "GasaGen_Common.h"
constexpr StrC SBlueprintActionMenu_Construct_Replacement = txt(R"(
constexpr Str SBlueprintActionMenu_Construct_Replacement = txt(R"(
void SBlueprintActionMenu::Construct( const FArguments& InArgs, TSharedPtr<FBlueprintEditor> InEditor )
{
bActionExecuted = false;
@ -244,23 +244,22 @@ void change_SBlueprintActionMenu_Construct()
#define path_SBlueprintActionMenuCpp \
R"(C:\projects\Unreal\Surgo\UE\Engine\Source\Editor\Kismet\Private\SBlueprintActionMenu.cpp)"
FileContents content = file_read_contents( GlobalAllocator, true, path_SBlueprintActionMenuCpp );
CodeBody parsed_SBlueprintActionMenu = parse_global_body( StrC { content.size, (char const*)content.data });
FileContents content = file_read_contents( gen_ctx.Allocator_Temp, true, path_SBlueprintActionMenuCpp );
CodeBody parsed_SBlueprintActionMenu = parse_global_body( Str { (char const*)content.data, content.size });
CodeFn signature_to_change = parse_function( code(
void SBlueprintActionMenu::Construct( const FArguments& InArgs, TSharedPtr<FBlueprintEditor> InEditor ) {}
));
CodeBody changed_SBlueprintActionMenu = def_body(ECode::Global_Body);
CodeBody changed_SBlueprintActionMenu = def_body(CT_Global_Body);
for ( Code code : parsed_SBlueprintActionMenu )
{
switch ( code->Type )
{
using namespace ECode;
case Function:
CodeFn function_def = code.cast<CodeFn>();
case CT_Function:
CodeFn function_def = cast(CodeFn, code);
if ( String::are_equal(function_def->Name, signature_to_change->Name)
if ( str_are_equal(function_def->Name, signature_to_change->Name)
&& function_def->Params.is_equal(signature_to_change->Params))
{
code = parse_function( SBlueprintActionMenu_Construct_Replacement );

View File

@ -3,7 +3,7 @@
#include "GasaGen_Common.h"
#include "GasaEditorCommon.h"
constexpr StrC SAssetView_Construct_Replacement = txt(R"(
constexpr Str SAssetView_Construct_Replacement = txt(R"(
void SAssetView::Construct( const FArguments& InArgs )
{
ViewCorrelationGuid = FGuid::NewGuid();
@ -391,7 +391,7 @@ void SAssetView::Construct( const FArguments& InArgs )
}
})");
constexpr StrC SAssetView_GetThumbnailScale_Replacement = txt(R"(
constexpr Str SAssetView_GetThumbnailScale_Replacement = txt(R"(
float SAssetView::GetThumbnailScale() const
{
float BaseScale;
@ -423,7 +423,7 @@ float SAssetView::GetThumbnailScale() const
return BaseScale * GetTickSpaceGeometry().Scale;
})");
constexpr StrC SPropertyMenuAssetPicker_Construct_Replacement = txt(R"(
constexpr Str SPropertyMenuAssetPicker_Construct_Replacement = txt(R"(
void SPropertyMenuAssetPicker::Construct( const FArguments& InArgs )
{
CurrentObject = InArgs._InitialObject;
@ -595,27 +595,26 @@ void change_EditorContentList()
#define path_PropertyEditorAssetConstantsHeader \
R"(C:\Projects\Unreal\Surgo\UE\Engine\Source\Editor\PropertyEditor\Private\UserInterface\PropertyEditor\PropertyEditorAssetConstants.h)"
FileContents content = file_read_contents( GlobalAllocator, true, path_PropertyEditorAssetConstantsHeader );
CodeBody parsed_PropertyEditorAssetConstantsHeader = parse_global_body( StrC { content.size, (char const*)content.data });
FileContents content = file_read_contents( gen_ctx.Allocator_Temp, true, path_PropertyEditorAssetConstantsHeader );
CodeBody parsed_PropertyEditorAssetConstantsHeader = parse_global_body( Str { (char const*)content.data, content.size });
CodeBody changed_PropertyEditorAssetConstantsHeader = def_body(ECode::Global_Body);
CodeBody changed_PropertyEditorAssetConstantsHeader = def_body(CT_Global_Body);
for ( Code code : parsed_PropertyEditorAssetConstantsHeader )
{
switch ( code->Type )
{
using namespace ECode;
case Namespace:
CodeNS ns = code.cast<CodeNS>();
case CT_Namespace:
CodeNS ns = cast(CodeNS, code);
for ( Code ns_code : ns->Body )
{
switch ( ns_code->Type )
{
case Variable:
CodeVar var = ns_code.cast<CodeVar>();
case CT_Variable:
CodeVar var = cast(CodeVar, ns_code);
if ( var->Name.starts_with(txt("ContentBrowserWindowSize")) )
{
// Swap value with new value
var->Value->Content = get_cached_string(txt("300.0f, 600.0f"));
var->Value->Content = cache_str(txt("300.0f, 600.0f"));
Gasa::LogEditor("Swapped: " + to_fstring(var->Name));
}
@ -639,8 +638,8 @@ void change_EditorContentList()
#define path_SAssetView \
R"(C:\projects\Unreal\Surgo\UE\Engine\Source\Editor\ContentBrowser\Private\SAssetView.cpp)"
FileContents content = file_read_contents( GlobalAllocator, true, path_SAssetView );
CodeBody parsed_SAssetViewCpp = parse_global_body( StrC { content.size, (char const*)content.data });
FileContents content = file_read_contents( gen_ctx.Allocator_Temp, true, path_SAssetView );
CodeBody parsed_SAssetViewCpp = parse_global_body( Str { (char const*)content.data, content.size });
CodeFn signature_Construct = parse_function( code(
void SAssetView::Construct( const FArguments& InArgs ) {}
@ -649,24 +648,23 @@ void change_EditorContentList()
float SAssetView::GetThumbnailScale() const {}
));
CodeBody changed_SAssetViewCpp = def_body(ECode::Global_Body);
CodeBody changed_SAssetViewCpp = def_body(CT_Global_Body);
for ( Code code : parsed_SAssetViewCpp )
{
switch ( code->Type )
{
using namespace ECode;
case Function:
case CT_Function:
{
CodeFn function_def = code.cast<CodeFn>();
CodeFn function_def = cast(CodeFn, code);
if ( String::are_equal(function_def->Name, signature_Construct->Name)
&& function_def->Params.is_equal(signature_Construct->Params))
if ( str_are_equal(function_def->Name, signature_Construct->Name)
&& function_def->Params && function_def->Params.is_equal(signature_Construct->Params))
{
code = parse_function( SAssetView_Construct_Replacement );
Gasa::LogEditor("Swapped: " + to_fstring(function_def->Name));
}
else if ( String::are_equal(function_def->Name, signature_GetThumbnailScale->Name)
&& function_def->Params.is_equal(signature_GetThumbnailScale->Params))
else if ( str_are_equal(function_def->Name, signature_GetThumbnailScale->Name)
&& function_def->Params && function_def->Params.is_equal(signature_GetThumbnailScale->Params))
{
code = parse_function( SAssetView_GetThumbnailScale_Replacement );
Gasa::LogEditor("Swapped: " + to_fstring(function_def->Name));
@ -689,24 +687,23 @@ void change_EditorContentList()
#define path_SPropertyMenuAssetPicker \
R"(C:\projects\Unreal\Surgo\UE\Engine\Source\Editor\PropertyEditor\Private\UserInterface\PropertyEditor\SPropertyMenuAssetPicker.cpp)"
FileContents content = file_read_contents( GlobalAllocator, true, path_SPropertyMenuAssetPicker );
CodeBody parsed = parse_global_body( StrC { content.size, (char const*)content.data });
FileContents content = file_read_contents( gen_ctx.Allocator_Temp, true, path_SPropertyMenuAssetPicker );
CodeBody parsed = parse_global_body( Str { (char const*)content.data, content.size });
CodeFn signature = parse_function( code(
void SPropertyMenuAssetPicker::Construct( const FArguments& InArgs ) {}
));
CodeBody changed = def_body(ECode::Global_Body);
CodeBody changed = def_body(CT_Global_Body);
for ( Code code : parsed )
{
switch ( code->Type )
{
using namespace ECode;
case Function:
case CT_Function:
{
CodeFn function_def = code.cast<CodeFn>();
CodeFn function_def = cast(CodeFn, code);
if ( String::are_equal(function_def->Name, signature->Name)
if ( str_are_equal(function_def->Name, signature->Name)
&& function_def->Params.is_equal(signature->Params))
{
code = parse_function( SPropertyMenuAssetPicker_Construct_Replacement );

View File

@ -8,38 +8,38 @@
void generate_DevOptionsCache()
{
Array<CodeVar> GasaDevOptions_UPROPERTIES = Array<CodeVar>::init(GlobalAllocator);
Array<CodeVar> GasaDevOptions_UPROPERTIES = Array<CodeVar>::init(gen_ctx.Allocator_Temp);
{
CodeBody header_GasaDevOptions = parse_file( path_module_gasa "GasaDevOptions.h" );
CodeClass UGasaDevOptions = NoCode;
CodeClass UGasaDevOptions = NullCode;
for (Code entry : header_GasaDevOptions)
{
if ( entry->Type == ECode::Class && entry->Name.starts_with( txt("UGasaDevOptions")) )
if ( entry->Type == CT_Class && entry->Name.starts_with( txt("UGasaDevOptions")) )
{
UGasaDevOptions = entry.cast<CodeClass>();
UGasaDevOptions = cast(CodeClass, entry);
break;
}
}
for (Code member = UGasaDevOptions->Body.begin(); member != UGasaDevOptions->Body.end(); ++ member)
{
if ( member->Type == ECode::Untyped && member->Name.starts_with(str_UPROPERTY) )
if ( member->Type == CT_Untyped && member->Name.starts_with(str_UPROPERTY) )
++ member;
if ( member->Type == ECode::Variable
if ( member->Type == CT_Variable
&& ( member->ValueType->Name.starts_with( txt("TArray< TSoftObjectPtr"))
|| member->ValueType->Name.starts_with( txt("TSoftClassPtr"))
|| member->ValueType->Name.starts_with( txt("TSoftObjectPtr")) )
)
GasaDevOptions_UPROPERTIES.append(member.cast<CodeVar>());
GasaDevOptions_UPROPERTIES.append(cast(CodeVar, member));
}
}
CodeComment generation_notice = def_comment(txt("Generated by GasaGen/GasaGen_DevOptionsCache.cpp"));
CodeType t_UClassPtr = parse_type(code(UClass*));
CodeType t_UObjectPtr = parse_type(code(UObject*));
CodeType t_Array_UObjectPtr = parse_type(code(TArray< UObject* >));
CodeTypename t_UClassPtr = parse_type(code(UClass*));
CodeTypename t_UObjectPtr = parse_type(code(UObject*));
CodeTypename t_Array_UObjectPtr = parse_type(code(TArray< UObject* >));
Builder header = builder_open( path_module_gasa "GasaDevOptionsCache.h" );
Builder header = gasa_builder_open( path_module_gasa "GasaDevOptionsCache.h" );
{
header.print( generation_notice );
header.print( pragma_once );
@ -50,7 +50,7 @@ void generate_DevOptionsCache()
header.print( UHT_USTRUCT );
CodeStruct FGasaDevOptionsCache;
{
CodeBody body = def_body(ECode::Struct_Body);
CodeBody body = def_body(CT_Struct_Body);
{
body.append(UHT_GENERATED_BODY);
body.append(fmt_newline);
@ -72,7 +72,7 @@ void generate_DevOptionsCache()
body.append(fmt_newline);
body.append( parse_function(code( void CachedDevOptions(); )));
}
FGasaDevOptionsCache = parse_struct( token_fmt( "body", (StrC)body.to_string(), stringize(
FGasaDevOptionsCache = parse_struct( token_fmt( "body", body.to_strbuilder().to_str(), stringize(
struct GASA_API FGasaDevOptionsCache {
<body>
};
@ -84,15 +84,15 @@ void generate_DevOptionsCache()
format_file( path_module_gasa "GasaDevOptionsCache.h" );
}
Builder source = builder_open( path_module_gasa "GasaDevOptionsCache.cpp" );
Builder source = gasa_builder_open( path_module_gasa "GasaDevOptionsCache.cpp" );
{
Array<CodeInclude> GasaDevOptions_Includes = Array<CodeInclude>::init(GlobalAllocator);
Array<CodeInclude> GasaDevOptions_Includes = Array<CodeInclude>::init(gen_ctx.Allocator_Temp);
{
CodeBody source_GasaDevOptions = parse_file( path_module_gasa "GasaDevOptions.cpp");
for ( Code entry : source_GasaDevOptions )
{
if ( entry->Type == ECode::Preprocess_Include )
GasaDevOptions_Includes.append( entry.cast<CodeInclude>() );
if ( entry->Type == CT_Preprocess_Include )
GasaDevOptions_Includes.append( cast(CodeInclude, entry));
}
}
@ -105,17 +105,17 @@ void generate_DevOptionsCache()
source.print( parse_using(code( using namespace Gasa; )));
source.print(fmt_newline);
CodeBody cached_property_assignments = def_body(ECode::Function_Body);
CodeBody cached_property_assignments = def_body(CT_Function_Body);
{
cached_property_assignments.append(fmt_newline);
cached_property_assignments.append(fmt_newline);
for (CodeVar var : GasaDevOptions_UPROPERTIES)
{
if ( var->ValueType.to_string().starts_with(txt("TArray")) )
if ( var->ValueType->Name.starts_with(txt("TArray")) )
{
#pragma push_macro("TEXT")
#undef TEXT
Code assignment = code_fmt( "property_array", (StrC)var->Name, stringize(
Code assignment = code_fmt( "property_array", var->Name, stringize(
for ( auto& entry : DevOpts-> <property_array> )
{
<property_array>.Push( entry.LoadSynchronous() );
@ -132,7 +132,7 @@ void generate_DevOptionsCache()
#pragma push_macro("TEXT")
#undef TEXT
Code assignment = code_fmt( "property", (StrC)var->Name, stringize(
Code assignment = code_fmt( "property", var->Name, stringize(
<property> = DevOpts-> <property>.LoadSynchronous();
ensureMsgf(<property> != nullptr, TEXT("<property> is null, DO NOT RUN PIE or else you may get a crash if not handled in BP or C++"));
));
@ -144,7 +144,7 @@ void generate_DevOptionsCache()
}
CodeFn CachedDevOptions = parse_function( token_fmt(
"cached_property_assignments", (StrC)cached_property_assignments.to_string(),
"cached_property_assignments", cached_property_assignments.to_strbuilder().to_str(),
stringize(
void FGasaDevOptionsCache::CachedDevOptions()
{
@ -163,4 +163,3 @@ void generate_DevOptionsCache()
#pragma pop_macro("ensureMsgf")
#pragma pop_macro("GASA_API")

View File

@ -10,8 +10,8 @@
#define LOCTEXT_NAMESPACE "GasaEditor"
global String Project_Path;
global String Root_Path;
global Str Project_Path;
global Str Root_Path;
global Code UHT_GENERATED_BODY;
global Code UHT_UCLASS;
@ -19,6 +19,8 @@ global Code UHT_UPROPERTY;
global Code UHT_USTRUCT;
global Code UModule_GASA_API;
global Context gen_ctx = {};
void Execute_GasaModule_Codegen()
{
FScopedSlowTask SlowTask(100.0f, LOCTEXT("RunningGasaGen", "Running GasaGen..."));
@ -28,8 +30,7 @@ void Execute_GasaModule_Codegen()
{
Gasa::LogEditor("Executing: Gasa Module code generation.");
gen::init();
gen::init( & gen_ctx);
FString ue_project_path = FPaths::ConvertRelativePathToFull(FPaths::ProjectDir());
FPaths::NormalizeDirectoryName(ue_project_path);
char const* ue_ansi_project_path = TCHAR_TO_ANSI(*ue_project_path);
@ -38,8 +39,8 @@ void Execute_GasaModule_Codegen()
FPaths::NormalizeDirectoryName(ue_root_path);
char const* ue_ansi_rooot_path = TCHAR_TO_ANSI(*ue_project_path);
Project_Path = String::make_length(GlobalAllocator, ue_ansi_project_path, ue_project_path.Len());
Root_Path = String::make_length(GlobalAllocator, ue_ansi_rooot_path, ue_root_path.Len());
Project_Path = StrBuilder::make_length(gen_ctx.Allocator_Temp, ue_ansi_project_path, ue_project_path.Len());
Root_Path = StrBuilder::make_length(gen_ctx.Allocator_Temp, ue_ansi_rooot_path, ue_root_path.Len());
// Initialize Globals
{
@ -66,62 +67,72 @@ void Execute_GasaModule_Codegen()
}
// Populate Defines
{
PreprocessorDefines.append(get_cached_string(str_DECLARE_CLASS));
PreprocessorDefines.append(get_cached_string(str_DECLARE_DELEGATE_RetVal_OneParam));
PreprocessorDefines.append(get_cached_string(str_DECLARE_DELEGATE_RetVal_ThreeParams));
PreprocessorDefines.append(get_cached_string(str_DECLARE_DELEGATE_SixParams));
PreprocessorDefines.append(get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam));
PreprocessorDefines.append(get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FiveParams));
PreprocessorDefines.append(get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FourParams));
PreprocessorDefines.append(get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_NineParams));
PreprocessorDefines.append(get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam));
PreprocessorDefines.append(get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SevenParams));
PreprocessorDefines.append(get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_TwoParams));
PreprocessorDefines.append(get_cached_string(str_DECLARE_EVENT_ThreeParams));
PreprocessorDefines.append(get_cached_string(str_DECLARE_EVENT_TwoParams));
PreprocessorDefines.append(get_cached_string(str_DECLARE_FUNCTION));
PreprocessorDefines.append(get_cached_string(str_DECLARE_LOG_CATEGORY_EXTERN));
PreprocessorDefines.append(get_cached_string(str_DECLARE_MULTICAST_DELEGATE_OneParam));
PreprocessorDefines.append(get_cached_string(str_DECLARE_MULTICAST_DELEGATE_ThreeParams));
PreprocessorDefines.append(get_cached_string(str_DECLARE_MULTICAST_DELEGATE_TwoParams));
PreprocessorDefines.append(get_cached_string(str_DECLARE_TS_MULTICAST_DELEGATE_OneParam));
PreprocessorDefines.append(get_cached_string(str_DECLARE_TS_MULTICAST_DELEGATE_TwoParams));
PreprocessorDefines.append(get_cached_string(str_DECLARE_TS_MULTICAST_DELEGATE_ThreeParams));
PreprocessorDefines.append(get_cached_string(str_DEFINE_ACTORDESC_TYPE));
PreprocessorDefines.append(get_cached_string(str_DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL));
PreprocessorDefines.append(get_cached_string(str_ENUM_CLASS_FLAGS));
PreprocessorDefines.append(get_cached_string(str_FORCEINLINE_DEBUGGABLE));
// PreprocessorDefines.append( get_cached_string(str_FORCEINLINE));
PreprocessorDefines.append(get_cached_string(str_GENERATED_BODY));
PreprocessorDefines.append(get_cached_string(str_GENERATED_UCLASS_BODY));
PreprocessorDefines.append(get_cached_string(str_GENERATED_USTRUCT_BODY));
PreprocessorDefines.append(get_cached_string(str_PRAGMA_DISABLE_DEPRECATION_WARNINGS));
PreprocessorDefines.append(get_cached_string(str_PRAGMA_ENABLE_DEPRECATION_WARNINGS));
PreprocessorDefines.append(get_cached_string(str_PROPERTY_BINDING_IMPLEMENTATION));
PreprocessorDefines.append(get_cached_string(str_RESULT_DECL));
PreprocessorDefines.append(get_cached_string(str_SLATE_BEGIN_ARGS));
PreprocessorDefines.append(get_cached_string(str_SLATE_END_ARGS));
PreprocessorDefines.append(get_cached_string(str_TEXT));
PreprocessorDefines.append(get_cached_string(str_UCLASS));
PreprocessorDefines.append(get_cached_string(str_UENUM));
PreprocessorDefines.append(get_cached_string(str_UFUNCTION));
PreprocessorDefines.append(get_cached_string(str_UMETA));
PreprocessorDefines.append(get_cached_string(str_UPARAM));
PreprocessorDefines.append(get_cached_string(str_UPROPERTY));
PreprocessorDefines.append(get_cached_string(str_USTRUCT));
PreprocessorDefines.append(get_cached_string(str_UE_REQUIRES));
}
register_macros( args(
(Macro { str_DECLARE_CLASS, MT_Statement, MF_Functional }),
(Macro { str_DECLARE_DELEGATE_RetVal_OneParam, MT_Statement, MF_Functional }),
(Macro { str_DECLARE_DELEGATE_RetVal_ThreeParams, MT_Statement, MF_Functional }),
(Macro { str_DECLARE_DELEGATE_SixParams, MT_Statement, MF_Functional }),
(Macro { str_DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam, MT_Statement, MF_Functional }),
(Macro { str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FiveParams, MT_Statement, MF_Functional }),
(Macro { str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FourParams, MT_Statement, MF_Functional }),
(Macro { str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_NineParams, MT_Statement, MF_Functional }),
(Macro { str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam, MT_Statement, MF_Functional }),
(Macro { str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SevenParams, MT_Statement, MF_Functional }),
(Macro { str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_TwoParams, MT_Statement, MF_Functional }),
(Macro { str_DECLARE_EVENT_ThreeParams, MT_Statement, MF_Functional }),
(Macro { str_DECLARE_EVENT_TwoParams, MT_Statement, MF_Functional }),
(Macro { str_DECLARE_FUNCTION, MT_Statement, MF_Functional }),
(Macro { str_DECLARE_LOG_CATEGORY_EXTERN, MT_Statement, MF_Functional | MF_Allow_As_Definition }),
(Macro { str_DECLARE_MULTICAST_DELEGATE_OneParam, MT_Statement, MF_Functional }),
(Macro { str_DECLARE_MULTICAST_DELEGATE_ThreeParams, MT_Statement, MF_Functional }),
(Macro { str_DECLARE_MULTICAST_DELEGATE_TwoParams, MT_Statement, MF_Functional }),
(Macro { str_DECLARE_TS_MULTICAST_DELEGATE_OneParam, MT_Statement, MF_Functional }),
(Macro { str_DECLARE_TS_MULTICAST_DELEGATE_TwoParams, MT_Statement, MF_Functional }),
(Macro { str_DECLARE_TS_MULTICAST_DELEGATE_ThreeParams, MT_Statement, MF_Functional }),
(Macro { str_DEFINE_ACTORDESC_TYPE, MT_Statement, MF_Functional }),
(Macro { str_DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL, MT_Statement, MF_Functional }),
(Macro { str_ENUM_CLASS_FLAGS, MT_Statement, MF_Functional }),
(Macro { str_GENERATED_BODY, MT_Statement, MF_Functional }),
(Macro { str_GENERATED_UCLASS_BODY, MT_Statement, MF_Functional }),
(Macro { str_GENERATED_USTRUCT_BODY, MT_Statement, MF_Functional }),
(Macro { str_PRAGMA_DISABLE_DEPRECATION_WARNINGS, MT_Statement, MF_Null | MF_Allow_As_Attribute }),
(Macro { str_PRAGMA_ENABLE_DEPRECATION_WARNINGS, MT_Statement, MF_Null | MF_Allow_As_Attribute }),
(Macro { str_PROPERTY_BINDING_IMPLEMENTATION, MT_Statement, MF_Functional }),
(Macro { str_RESULT_DECL, MT_Expression, MF_Functional }),
(Macro { str_SLATE_BEGIN_ARGS, MT_Statement, MF_Functional | MF_Expects_Body }),
(Macro { str_SLATE_END_ARGS, MT_Statement, MF_Functional }),
(Macro { str_TEXT, MT_Expression, MF_Functional }),
(Macro { str_UCLASS, MT_Statement, MF_Functional }),
(Macro { str_UENUM, MT_Statement, MF_Functional }),
(Macro { str_UFUNCTION, MT_Statement, MF_Functional }),
(Macro { str_UMETA, MT_Expression, MF_Functional }),
(Macro { str_UPARAM, MT_Expression, MF_Functional }),
(Macro { str_UPROPERTY, MT_Statement, MF_Functional }),
(Macro { str_USTRUCT, MT_Statement, MF_Functional }),
(Macro { str_UE_REQUIRES, MT_Expression, MF_Functional }),
(Macro { str_UE_DEPRECATED, MT_Statement, MF_Functional | MF_Allow_As_Attribute }),
(Macro { str_ACTOR_HAS_LABELS, MT_Expression, MF_Null }),
(Macro { str_HIDE_ACTOR_TRANSFORM_FUNCTIONS, MT_Statement, MF_Functional }),
(Macro { str_SCENECOMPONENT_QUAT_TOLERANCE, MT_Expression, MF_Null }),
(Macro { str_SCENECOMPONENT_ROTATOR_TOLERANCE, MT_Expression, MF_Null }),
(Macro { str_GAMEPLAYATTRIBUTE_REPNOTIFY, MT_Statement, MF_Functional }),
(Macro { str_GAMEPLAYATTRIBUTE_PROPERTY_GETTER, MT_Statement, MF_Functional }),
(Macro { str_GAMEPLAYATTRIBUTE_VALUE_GETTER, MT_Statement, MF_Functional }),
(Macro { str_GAMEPLAYATTRIBUTE_VALUE_SETTER, MT_Statement, MF_Functional }),
(Macro { str_GAMEPLAYATTRIBUTE_VALUE_INITTER, MT_Statement, MF_Functional }),
(Macro { str_LOCTEXT_NAMESPACE, MT_Statement, MF_Null })
));
// generate_AttributeSets();
//generate_DevOptionsCache();
//generate_HostWidgetController();
change_SBlueprintActionMenu_Construct();
change_EditorContentList();
// register_macros()
gen::deinit();
generate_AttributeSets();
generate_DevOptionsCache();
// generate_HostWidgetController();
// change_SBlueprintActionMenu_Construct();
// change_EditorContentList();
gen::deinit( & gen_ctx);
});
}
#undef LOCTEXT_NAMESPACE

View File

@ -17,54 +17,65 @@ using namespace gen;
#define path_gasa_game path_module_gasa "Game/"
#define path_gasa_ui path_module_gasa "UI/"
constexpr StrC str_DECLARE_CLASS = txt("DECLARE_CLASS(");
constexpr StrC str_DECLARE_DELEGATE_RetVal_OneParam = txt("DECLARE_DELEGATE_RetVal_OneParam(");
constexpr StrC str_DECLARE_DELEGATE_RetVal_ThreeParams = txt("DECLARE_DELEGATE_RetVal_ThreeParams(");
constexpr StrC str_DECLARE_DELEGATE_SixParams = txt("DECLARE_DELEGATE_SixParams(");
constexpr StrC str_DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam = txt("DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(");
constexpr StrC str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FiveParams = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FiveParams(");
constexpr StrC str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FourParams = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FourParams(");
constexpr StrC str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_NineParams = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_NineParams(");
constexpr StrC str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam(");
constexpr StrC str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SevenParams = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SevenParams(");
constexpr StrC str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_TwoParams = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_TwoParams(");
constexpr StrC str_DECLARE_EVENT_ThreeParams = txt("DECLARE_EVENT_ThreeParams(");
constexpr StrC str_DECLARE_EVENT_TwoParams = txt("DECLARE_EVENT_TwoParams(");
constexpr StrC str_DECLARE_FUNCTION = txt("DECLARE_FUNCTION(");
constexpr StrC str_DECLARE_LOG_CATEGORY_EXTERN = txt("DECLARE_LOG_CATEGORY_EXTERN(");
constexpr StrC str_DECLARE_MULTICAST_DELEGATE_OneParam = txt("DECLARE_MULTICAST_DELEGATE_OneParam(");
constexpr StrC str_DECLARE_MULTICAST_DELEGATE_ThreeParams = txt("DECLARE_MULTICAST_DELEGATE_ThreeParams(");
constexpr StrC str_DECLARE_MULTICAST_DELEGATE_TwoParams = txt("DECLARE_MULTICAST_DELEGATE_TwoParams(");
constexpr StrC str_DECLARE_TS_MULTICAST_DELEGATE_OneParam = txt("DECLARE_TS_MULTICAST_DELEGATE_OneParam(");
constexpr StrC str_DECLARE_TS_MULTICAST_DELEGATE_TwoParams = txt("DECLARE_TS_MULTICAST_DELEGATE_TwoParams(");
constexpr StrC str_DECLARE_TS_MULTICAST_DELEGATE_ThreeParams = txt("DECLARE_TS_MULTICAST_DELEGATE_ThreeParams(");
constexpr StrC str_DEFINE_ACTORDESC_TYPE = txt("DEFINE_ACTORDESC_TYPE(");
constexpr StrC str_DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL = txt("DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL(");
constexpr StrC str_ENUM_CLASS_FLAGS = txt("ENUM_CLASS_FLAGS(");
// constexpr StrC str_FORCEINLINE = txt("FORCEINLINE");
constexpr StrC str_FORCEINLINE_DEBUGGABLE = txt("FORCEINLINE_DEBUGGABLE");
constexpr StrC str_GENERATED_BODY = txt("GENERATED_BODY(");
constexpr StrC str_GENERATED_UCLASS_BODY = txt("GENERATED_UCLASS_BODY(");
constexpr StrC str_GENERATED_USTRUCT_BODY = txt("GENERATED_USTRUCT_BODY(");
constexpr StrC str_PRAGMA_DISABLE_DEPRECATION_WARNINGS = txt("PRAGMA_DISABLE_DEPRECATION_WARNINGS");
constexpr StrC str_PRAGMA_ENABLE_DEPRECATION_WARNINGS = txt("PRAGMA_ENABLE_DEPRECATION_WARNINGS");
constexpr StrC str_PROPERTY_BINDING_IMPLEMENTATION = txt("PROPERTY_BINDING_IMPLEMENTATION(");
constexpr StrC str_RESULT_DECL = txt("RESULT_DECL");
constexpr StrC str_SLATE_BEGIN_ARGS = txt("SLATE_BEGIN_ARGS(");
constexpr StrC str_SLATE_END_ARGS = txt("SLATE_END_ARGS(");
constexpr StrC str_TEXT = txt("TEXT(");
constexpr StrC str_UCLASS = txt("UCLASS(");
constexpr StrC str_UENUM = txt("UENUM(");
constexpr StrC str_UFUNCTION = txt("UFUNCTION(");
constexpr StrC str_UMETA = txt("UMETA(");
constexpr StrC str_UPARAM = txt("UPARAM(");
constexpr StrC str_UPROPERTY = txt("UPROPERTY(");
constexpr StrC str_USTRUCT = txt("USTRUCT(");
constexpr StrC str_UE_REQUIRES = txt("UE_REQUIRES(");
constexpr Str str_DECLARE_CLASS = txt("DECLARE_CLASS");
constexpr Str str_DECLARE_DELEGATE_RetVal_OneParam = txt("DECLARE_DELEGATE_RetVal_OneParam");
constexpr Str str_DECLARE_DELEGATE_RetVal_ThreeParams = txt("DECLARE_DELEGATE_RetVal_ThreeParams");
constexpr Str str_DECLARE_DELEGATE_SixParams = txt("DECLARE_DELEGATE_SixParams");
constexpr Str str_DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam = txt("DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam");
constexpr Str str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FiveParams = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FiveParams");
constexpr Str str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FourParams = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FourParams");
constexpr Str str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_NineParams = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_NineParams");
constexpr Str str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam");
constexpr Str str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SevenParams = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SevenParams");
constexpr Str str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_TwoParams = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_TwoParams");
constexpr Str str_DECLARE_EVENT_ThreeParams = txt("DECLARE_EVENT_ThreeParams");
constexpr Str str_DECLARE_EVENT_TwoParams = txt("DECLARE_EVENT_TwoParams");
constexpr Str str_DECLARE_FUNCTION = txt("DECLARE_FUNCTION");
constexpr Str str_DECLARE_LOG_CATEGORY_EXTERN = txt("DECLARE_LOG_CATEGORY_EXTERN");
constexpr Str str_DECLARE_MULTICAST_DELEGATE_OneParam = txt("DECLARE_MULTICAST_DELEGATE_OneParam");
constexpr Str str_DECLARE_MULTICAST_DELEGATE_ThreeParams = txt("DECLARE_MULTICAST_DELEGATE_ThreeParams");
constexpr Str str_DECLARE_MULTICAST_DELEGATE_TwoParams = txt("DECLARE_MULTICAST_DELEGATE_TwoParams");
constexpr Str str_DECLARE_TS_MULTICAST_DELEGATE_OneParam = txt("DECLARE_TS_MULTICAST_DELEGATE_OneParam");
constexpr Str str_DECLARE_TS_MULTICAST_DELEGATE_TwoParams = txt("DECLARE_TS_MULTICAST_DELEGATE_TwoParams");
constexpr Str str_DECLARE_TS_MULTICAST_DELEGATE_ThreeParams = txt("DECLARE_TS_MULTICAST_DELEGATE_ThreeParams");
constexpr Str str_DEFINE_ACTORDESC_TYPE = txt("DEFINE_ACTORDESC_TYPE");
constexpr Str str_DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL = txt("DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL");
constexpr Str str_ENUM_CLASS_FLAGS = txt("ENUM_CLASS_FLAGS");
constexpr Str str_GENERATED_BODY = txt("GENERATED_BODY");
constexpr Str str_GENERATED_UCLASS_BODY = txt("GENERATED_UCLASS_BODY");
constexpr Str str_GENERATED_USTRUCT_BODY = txt("GENERATED_USTRUCT_BODY");
constexpr Str str_PRAGMA_DISABLE_DEPRECATION_WARNINGS = txt("PRAGMA_DISABLE_DEPRECATION_WARNINGS");
constexpr Str str_PRAGMA_ENABLE_DEPRECATION_WARNINGS = txt("PRAGMA_ENABLE_DEPRECATION_WARNINGS");
constexpr Str str_PROPERTY_BINDING_IMPLEMENTATION = txt("PROPERTY_BINDING_IMPLEMENTATION");
constexpr Str str_RESULT_DECL = txt("RESULT_DECL");
constexpr Str str_SLATE_BEGIN_ARGS = txt("SLATE_BEGIN_ARGS");
constexpr Str str_SLATE_END_ARGS = txt("SLATE_END_ARGS");
constexpr Str str_TEXT = txt("TEXT");
constexpr Str str_UCLASS = txt("UCLASS");
constexpr Str str_UENUM = txt("UENUM");
constexpr Str str_UFUNCTION = txt("UFUNCTION");
constexpr Str str_UMETA = txt("UMETA");
constexpr Str str_UPARAM = txt("UPARAM");
constexpr Str str_UPROPERTY = txt("UPROPERTY");
constexpr Str str_USTRUCT = txt("USTRUCT");
constexpr Str str_UE_REQUIRES = txt("UE_REQUIRES");
constexpr Str str_UE_DEPRECATED = txt("UE_DEPRECATED");
constexpr Str str_ACTOR_HAS_LABELS = txt("ACTOR_HAS_LABELS");
constexpr Str str_HIDE_ACTOR_TRANSFORM_FUNCTIONS = txt("HIDE_ACTOR_TRANSFORM_FUNCTIONS");
constexpr Str str_SCENECOMPONENT_QUAT_TOLERANCE = txt("SCENECOMPONENT_QUAT_TOLERANCE");
constexpr Str str_SCENECOMPONENT_ROTATOR_TOLERANCE = txt("SCENECOMPONENT_ROTATOR_TOLERANCE");
constexpr Str str_GAMEPLAYATTRIBUTE_REPNOTIFY = txt("GAMEPLAYATTRIBUTE_REPNOTIFY");
constexpr Str str_GAMEPLAYATTRIBUTE_PROPERTY_GETTER = txt("GAMEPLAYATTRIBUTE_PROPERTY_GETTER");
constexpr Str str_GAMEPLAYATTRIBUTE_VALUE_GETTER = txt("GAMEPLAYATTRIBUTE_VALUE_GETTER");
constexpr Str str_GAMEPLAYATTRIBUTE_VALUE_SETTER = txt("GAMEPLAYATTRIBUTE_VALUE_SETTER");
constexpr Str str_GAMEPLAYATTRIBUTE_VALUE_INITTER = txt("GAMEPLAYATTRIBUTE_VALUE_INITTER");
constexpr Str str_LOCTEXT_NAMESPACE = txt("LOCTEXT_NAMESPACE");
constexpr Str str_GASA_API = txt("GASA_API");
#pragma region Globals
extern String Project_Path;
extern String Root_Path;
extern Str Project_Path;
extern Str Root_Path;
// These Code objects are created before anything else after gencpp does its initializatioon
extern Code UHT_GENERATED_BODY;
@ -72,24 +83,26 @@ extern Code UHT_UCLASS;
extern Code UHT_UPROPERTY;
extern Code UHT_USTRUCT;
extern Code UModule_GASA_API;
extern Context gen_ctx;
#pragma endregion Globals
inline
CodeBody parse_file( char const* path ) {
String
resolved_path = String::make(GlobalAllocator, StrC(Project_Path));
StrBuilder
resolved_path = StrBuilder::make(gen_ctx.Allocator_Temp, Project_Path);
resolved_path.append(path);
FileContents content = file_read_contents( GlobalAllocator, true, resolved_path );
CodeBody code = parse_global_body( StrC { content.size, (char const*)content.data });
FileContents content = file_read_contents( gen_ctx.Allocator_Temp, true, resolved_path );
CodeBody code = parse_global_body( Str { (char const*)content.data, content.size });
return code;
}
// Automatically handles resolving project path
inline
Builder builder_open(char const* path) {
String
resolved_path = String::make(GlobalAllocator, StrC(Project_Path));
Builder gasa_builder_open(char const* path) {
StrBuilder
resolved_path = StrBuilder::make(gen_ctx.Allocator_Temp, Project_Path);
resolved_path.append(path);
return Builder::open( resolved_path );
}
@ -100,13 +113,13 @@ Builder builder_open(char const* path) {
inline
void format_file( char const* path, bool relative_path = true )
{
String
resolved_path = String::make_reserve(GlobalAllocator, Project_Path.length());
StrBuilder
resolved_path = StrBuilder::make_reserve(gen_ctx.Allocator_Temp, Project_Path.Len);
if (relative_path)
resolved_path.append(StrC(Project_Path));
resolved_path.append(Project_Path);
resolved_path.append(path);
String style_arg = String::make(GlobalAllocator, txt("-style=file:"));
StrBuilder style_arg = StrBuilder::make(gen_ctx.Allocator_Temp, txt("-style=file:"));
style_arg.append(Root_Path);
style_arg.append("/scripts/.clang-format ");
@ -114,7 +127,7 @@ void format_file( char const* path, bool relative_path = true )
#define clang_format "clang-format "
#define cf_format_inplace "-i "
#define cf_verbose "-verbose "
String command = String::make( GlobalAllocator, clang_format );
StrBuilder command = StrBuilder::make( gen_ctx.Allocator_Temp, clang_format );
command.append( cf_format_inplace );
command.append( cf_verbose );
command.append( style_arg );
@ -129,19 +142,19 @@ void format_file( char const* path, bool relative_path = true )
}
FORCEINLINE
String to_string( FString ue_string ) {
Str to_string( FString ue_string ) {
char const* ansi_str = TCHAR_TO_ANSI(*ue_string);
return String::make_length(GlobalAllocator, ansi_str, ue_string.Len());
return StrBuilder::make_length(gen_ctx.Allocator_Temp, ansi_str, ue_string.Len()).to_str();
}
FORCEINLINE
String to_string( FName ue_fname ) {
Str to_string( FName ue_fname ) {
char const* ansi_str = TCHAR_TO_ANSI(*ue_fname.ToString());
return String::make_length(GlobalAllocator, ansi_str, ue_fname.GetStringLength());
return StrBuilder::make_length(gen_ctx.Allocator_Temp, ansi_str, ue_fname.GetStringLength()).to_str();
}
FORCEINLINE
FString to_fstring( String string )
FString to_fstring( Str string )
{
return FString::ConstructFromPtrSize( string.Data, string.length() );
return FString::ConstructFromPtrSize( string.Ptr, string.Len );
}

View File

@ -53,6 +53,7 @@ StrBuilder <prefix>_to_strbuilder(Code code);
Where the first generates strings allocated using Allocator_StringArena and the other appends an existing strings with their backed allocator.
Serialization of for the AST is defined for `Code` in [`ast.chpp`](../base/components/ast.cpp) with `code_to_strbuilder_ptr` & `code_to_strbuilder`.
Serialization of for the AST is defined for `Code` in [`ast.cpp`](../base/components/ast.cpp) with `code_to_strbuilder_ptr` & `code_to_strbuilder`.
Serializtion for the rest of the code types is within [`code_serialization.cpp`](../base/components/code_serialization.cpp).
Gencpp's serialization does not provide coherent formatting of the code. The user should use a formatter after serializing.

View File

@ -25,13 +25,13 @@ These are containers representing a scope body of a definition that can be of th
Fields:
```cpp
StrCached Name;
Code Front;
Code Back;
Token* Tok;
Code Parent;
CodeT Type;
s32 NumEntries;
StrCached Name;
Code Front;
Code Back;
Token* Tok;
Code Parent;
CodeType Type;
s32 NumEntries;
```
The `Front` member represents the start of the link list and `Back` the end.
@ -56,13 +56,13 @@ Represent standard or vendor specific C/C++ attributes.
Fields:
```cpp
StrCached Content;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeT Type;
StrCached Content;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeType Type;
```
Serialization:
@ -80,13 +80,13 @@ Stores a comment.
Fields:
```cpp
StrCached Content;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeT Type;
StrCached Content;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeType Type;
```
Serialization:
@ -109,12 +109,12 @@ CodeComment InlineCmt; // Only supported by forward declarations
CodeAttributes Attributes;
CodeType ParentType;
CodeBody Body;
StrCached Name;
StrCached Name;
CodeType Prev;
CodeType Next;
Token* Tok;
Code Parent;
CodeT Type;
CodeType Type;
ModuleFlag ModuleFlags;
AccessSpec ParentAccess;
```
@ -139,16 +139,16 @@ You'll notice that only one parent type is supported only with parent access. Th
Fields:
```cpp
CodeComment InlineCmt; // Only supported by forward declarations
Code InitializerList;
CodeParams Params;
Code Body;
CodeComment InlineCmt; // Only supported by forward declarations
Code InitializerList;
CodeParams Params;
Code Body;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeT Type;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeType Type;
```
Serialization:
@ -178,13 +178,14 @@ Represents a preprocessor define
Fields:
```cpp
StrCached Content;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeT Type;
CodeDefineParams Params;
Code Body;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeType Type;
```
Serialization:
@ -193,6 +194,28 @@ Serialization:
#define <Name> <Content>
```
## DefineParams
Preprocessor define's parameters.
Fields:
```cpp
StrCached Name;
Code Last;
Code Next;
Token* Tok;
Code Parent;
CodeType Type;
s32 NumEntries;
```
Serialization:
```cpp
<Name>, <Next> ...
```
## Destructor
Fields:
@ -201,12 +224,12 @@ Fields:
CodeComment InlineCmt;
CodeSpecifiers Specs;
Code Body;
StrCached Name;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeT Type;
CodeType Type;
```
Serialization:
@ -242,8 +265,8 @@ Code Prev;
Code Next;
Token* Tok;
Code Parent;
StrCached Name;
CodeT Type;
StrCached Name;
CodeType Type;
ModuleFlag ModuleFlags;
```
@ -271,13 +294,13 @@ Will be obsolute when function body parsing is implemented.
Fields:
```cpp
StrCached Content;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeT Type;
StrCached Content;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeType Type;
```
Serialization:
@ -286,18 +309,18 @@ Serialization:
<Content>
```
## External Linkage
## External Linkage (Extern)
Fields:
```cpp
CodeBody Body;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeT Type;
CodeBody Body;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeType Type;
```
Serialization:
@ -314,13 +337,13 @@ extern "<Name>"
Fields:
```cpp
StrCached Content;
StrCached Name;
Code Prev;
Code Next;
Code Parent;
Token* Tok;
CodeT Type;
StrCached Content;
StrCached Name;
Code Prev;
Code Next;
Code Parent;
Token* Tok;
CodeType Type;
```
Serialization:
@ -336,14 +359,14 @@ This library (until its necessary become some third-party library to do otherwis
Fields:
```cpp
CodeComment InlineCmt;
Code Declaration;
CodeComment InlineCmt;
Code Declaration;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeT Type;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeType Type;
```
Serialization:
@ -363,12 +386,12 @@ CodeSpecifiers Specs;
CodeType ReturnType;
CodeParams Params;
CodeBody Body;
StrCached Name;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeT Type;
CodeType Type;
ModuleFlag ModuleFlags;
```
@ -390,13 +413,13 @@ Serialization:
Fields:
```cpp
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeT Type;
ModuleFlag ModuleFlags;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeType Type;
ModuleFlag ModuleFlags;
```
Serialization:
@ -410,14 +433,14 @@ Serialization:
Fields:
```cpp
CodeBody Body;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeT Type;
ModuleFlag ModuleFlags;
CodeBody Body;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeType Type;
ModuleFlag ModuleFlags;
```
Serialization:
@ -440,12 +463,12 @@ CodeSpecifiers Specs;
CodeType ReturnType;
CodeParams Params;
CodeBody Body;
StrCached Name;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeT Type;
CodeType Type;
ModuleFlag ModuleFlags;
OperatorT Op;
```
@ -472,12 +495,12 @@ CodeComment InlineCmt;
CodeSpecifiers Specs;
CodeType ValueType;
CodeBody Body;
StrCached Name;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeT Type;
CodeType Type;
```
Serialization:
@ -498,17 +521,17 @@ Serialization:
Fields:
```cpp
CodeType ValueType;
Code Macro;
Code Value;
Code PostNameMacro;
StrCached Name;
CodeParams Last;
CodeParams Next;
Token* Tok;
Code Parent;
CodeT Type;
s32 NumEntries;
CodeType ValueType;
Code Macro;
Code Value;
Code PostNameMacro;
StrCached Name;
CodeParams Last;
CodeParams Next;
Token* Tok;
Code Parent;
CodeType Type;
s32 NumEntries;
```
Serialization:
@ -524,13 +547,13 @@ Serialization:
Fields:
```cpp
StrCached Content;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeT Type;
StrCached Content;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeType Type;
```
Serialization:
@ -544,13 +567,13 @@ Serialization:
Fields:
```cpp
StrCached Content;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeT Type;
StrCached Content;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeType Type;
```
Serialization:
@ -566,12 +589,12 @@ Fields:
```cpp
SpecifierT ArrSpecs[ AST_ArrSpecs_Cap ];
CodeSpecifiers NextSpecs;
StrCached Name;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeT Type;
CodeType Type;
s32 NumEntries;
```
@ -586,15 +609,15 @@ Serialization:
Fields:
```cpp
CodeParams Params;
Code Declaration;
CodeParams Params;
Code Declaration;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeT Type;
ModuleFlag ModuleFlags;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeType Type;
ModuleFlag ModuleFlags;
```
Serialization:
@ -621,8 +644,8 @@ Code Prev;
Code Next;
Token* Tok;
Code Parent;
StrCached Name;
CodeT Type;
StrCached Name;
CodeType Type;
b32 IsParamPack;
ETypenameTag TypeTag;
```
@ -647,16 +670,16 @@ Those (macros) don't use the underlying type field as everything was serialized
Fields:
```cpp
CodeComment InlineCmt;
Code UnderlyingType;
StrCached Name;
Code Prev;
Code Next;
Token* Tok
Code Parent;
CodeT Type;
ModuleFlag ModuleFlags;
b32 IsFunction;
CodeComment InlineCmt;
Code UnderlyingType;
StrCached Name;
Code Prev;
Code Next;
Token* Tok
Code Parent;
CodeType Type;
ModuleFlag ModuleFlags;
b32 IsFunction;
```
Serialization:
@ -682,12 +705,12 @@ Fields:
```cpp
CodeAttributes Attributes;
CodeBody Body;
StrCached Name;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeT Type;
CodeType Type;
ModuleFlag ModuleFlags;
```
@ -708,12 +731,12 @@ Fields:
CodeComment InlineCmt;
CodeAttributes Attributes;
CodeType UnderlyingType;
StrCached Name;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeT Type;
CodeType Type;
ModuleFlag ModuleFlags;
```
@ -740,13 +763,13 @@ CodeSpecifiers Specs;
CodeType ValueType;
Code BitfieldSize;
Code Value;
StrCached Name;
StrCached Name;
CodeVar NextVar;
Code Prev;
Code Next;
Token* Tok;
Code Parent;
CodeT Type;
CodeType Type;
ModuleFlag ModuleFlags;
s32 VarParenthesizedInit;
```

View File

@ -26,3 +26,19 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Source URL: https://github.com/Ed94/gencpp
Acknowledgements
* The dependencies for gencpp source are derived from the zpl library: https://github.com/zpl-c/zpl
Special thanks to:
* The Handmade Community.
* Casey Muratori, Ginger Bill (Bill Hall), Mr. 4th (Allen Webster), Ryan Fluery: Influnced conceptually how to handle staged metaprograming.
* Jonathan Blow: Jai's metaprogramming influenced the design of this library.
* My friends for putting up with discord spam on this library.

File diff suppressed because it is too large Load Diff

View File

@ -6,9 +6,9 @@
# Parsing
The library features a naive single-pass parser tailored for only what the library needs to construct the supported syntax of C++ into its AST for *"front-end"* meta-programming purposes.
The library features a naive single-pass parser, tailored for only what the library needs; for construction of C++ code into gencpp's AST for *"front-end"* meta-programming purposes.
This parser does not, and should not do the compiler's job. By only supporting this minimal set of features, the parser is kept (so far) around ~7000 loc. I hope to keep it under 10k loc worst case.
This parser does not, and should not do the compiler's job. By only supporting this minimal set of features, the parser is kept (so far) around ~7000 loc. I hope to keep it under 10-15k loc worst case.
You can think of this parser as *frontend parser* vs a *semantic parser*. Its intuitively similar to WYSIWYG. What you ***precerive*** as the syntax from the user-side before the compiler gets a hold of it, is what you get.
@ -17,6 +17,7 @@ User exposed interface:
```cpp
CodeClass parse_class ( Str class_def );
CodeConstructor parse_constructor ( Str constructor_def );
CodeDefine parse_define ( Str define_def );
CodeDestructor parse_destructor ( Str destructor_def );
CodeEnum parse_enum ( Str enum_def );
CodeBody parse_export_body ( Str export_def );
@ -53,38 +54,98 @@ The keywords supported for the preprocessor are:
* endif
* pragma
Each directive `#` line is considered one preproecessor unit, and will be treated as one Preprocessor AST.
Each directive `#` line is considered one preproecessor unit, and will be treated as one Preprocessor AST node.
If a directive is used with an unsupported keyword its will be processed as an untyped AST.
The preprocessor lines are stored as members of their associated scope they are parsed within. ( Global, Namespace, Class/Struct )
***Again (Its not standard): These ASTs will be considered members or entries of braced scope they reside within***
The preprocessor lines are stored as members of their associated scope they are parsed within ( Global, Namespace, Class/Struct ).
***Again: These ASTs will be considered members or entries of braced scope they reside within***
Any preprocessor definition abuse that changes the syntax of the core language is unsupported and will fail to parse if not kept within an execution scope (function body, or expression assignment).
Exceptions:
* function signatures are allowed for a preprocessed macro: `neverinline MACRO() { ... }`
* varaible definitions are allowed for a preprocessed macro `extern MACRO();`
* function definitions are allowed for a preprocessed macro: `neverinline MACRO() { ... }`
* Disable with: `#define GEN_PARSER_DISABLE_MACRO_FUNCTION_SIGNATURES`
* typedefs allow for a preprocessed macro: `typedef MACRO();`
* Disable with: `#define GEN_PARSER_DISABLE_MACRO_TYPEDEF`
* Macros can behave as typenames
* There is some macro support in paramters for functions or templates *(Specifically added to support parsing Unreal Engine source)*.
* There is some macro support in parameters for functions or templates *(Specifically added to support parsing Unreal Engine source)*.
*(Exceptions are added on an on-demand basis)*
*(See functions `parse_operator_function_or_variable` and `parse_typedef` )*
Adding your own exceptions is possible by simply modifying the parser to allow for the syntax you need.
*Note: You could interpret this strictness as a feature. This would allow the user to see if their codebase or a third-party's codebase some some egregious preprocessor abuse.*
*Note: You could interpret this strictness as a feature. This would allow the user to see if their codebase or a third-party's codebase contains some egregious preprocessor abuse.*
If a macro is not defined withint e scope of parsing a set of files, it can be defined beforehand by:
Macros used within a file should be registered by the user before parsing. This can be done two ways:
* Appending the [`PreprocessorDefines`](https://github.com/Ed94/gencpp/blob/a18b5b97aa5cfd20242065cbf53462a623cd18fa/base/components/header_end.hpp#L137) array.
* For functional macros a "(" just needs to be added after the name like: `<name>(` so that it will tokenize its arguments as part of the token during lexing.
* Defining a CodeDefine using `def_define`. The definition will be processed by the interface for user into `PreprocessorDefines`.
* This can be prevented by setting the optional prameter `dont_append_preprocess_defines`.
1. The register macro interface within [interface.hpp](../base/components/interface.hpp).
2. Using `def_define` to create a CodeDefine and making sure to not set `opts.dont_register_to_preprocess_macros` to `true`.
The lexing and parsing takes shortcuts from whats expected in the standard.
## Registering macros
While the registeration of macros in the meta-program's side for parsing can be considered tedius, its necessary for the parser to accurately resolve the macros intent in one pass (and it provides some hygenics by verifying that they are used as intended).
The following can be used to register a macro:
```c
GEN_API void register_macro( Macro macro );
GEN_API void register_macros( s32 num, ... );
GEN_API void register_macros_arr( s32 num, Macro* macros );
```
The Macro typename is defined with the following in [parser_types.hpp](../base/components/parser_types.hpp):
```c
struct Macro
{
StrCached Name;
MacroType Type;
MacroFlags Flags;
};
```
The macro can be designated one of the following types:
* `MT_Expression`: Intended to resolve to an expression expansion.
* `MT_Statement`: Intended to resolve an statement expansion.
* `MT_Typename`: Intended to resolve to a typename.
Additioonally tthe following flags may be set:
* `MF_Functional`: The macro intended to be passed arguments are at least have the calling `()` as part of its usage.
* `MF_Expects_Body`: The parser should expect a braced-body `{ ... }` after the macro signature `<name> <params>`
* `MF_Allow_As_Identifier`: Will allow the macro to be an acceptable token/s when an `Tok_Identifier` is expected.
* `MF_Allow_As_Attribute`: Will allow the macro to be an acceptable token/s when an attribute token/s is expected.
* `MF_Allow_As_Definition`: Will allow the macro be an acceptable token/s when the parser expects a declartion or definition to resolve after attributes or specifiers have been identified beforehand.
* This flag requires that the macro is of type `MT_Statement` to make any sense of usage.
If a macro is not defined the following warning will be issued if `GEN_BUILD_DEBUG=1` during lexing within [lexer.cpp](../base/components/lexer.cpp) - `lex_preprocessor_define`:
```c
log_fmt("Warning: '%S' was not registered before the lexer processed its #define directive, it will be registered as a expression macro\n"
, name.Text
);
```
Further within the same scope, the lexer will issue a warning if it detects a macro was not flagged as function but has an open parenthesis `(` token right after is name with no whitespace:
```c
log_fmt("Warning: %S registered macro is not flagged as functional yet the definition detects opening parenthesis '(' for arguments\n"
, name.Text
);
```
Macros are tracked using a `MacroTable Macros;` defined as a member of the library's `Context`.
```c
typedef HashTable(Macro) MacroTable;
```
## Notes
* Empty lines used throughout the file are preserved for formatting purposes during ast serialization (they have a dedicated Token: `Tok_NewLine`).
* Numeric literals are not checked for validity.
* The parse API treats any execution scope definitions with no validation and are turned into untyped Code ASTs. (There is a [todo](https://github.com/Ed94/gencpp/issues/49) to add support)
* *This includes the assignment of variables.*
@ -95,4 +156,4 @@ The lexing and parsing takes shortcuts from whats expected in the standard.
* Parsing attributes can be extended to support user defined macros by defining `GEN_DEFINE_ATTRIBUTE_TOKENS` (see `gen.hpp` for the formatting)
* This is useful for example: parsing Unreal `Module_API` macros.
Empty lines used throughout the file are preserved for formatting purposes during ast serialization.
**The lexer & parser do not gracefully attempt to continue when it comes across incorrect code, and doesn't properly track errors into a listing (yet).**

View File

@ -15,3 +15,20 @@ If using the library's provided build scripts:
```ps1
.\build.ps1 <compiler> <debug or omit> unreal
```
## Notables
For the most part this follows the same conventions as `gen_segmented`.
This generator uses a separate enumeration definitions for the following:
* [AttributeTokens.csv](./enums/AttributeTokens.csv) : Add your own <MODULE>_API attributes, etc here that are encountered within the Engine.
* [ESpecifier.csv](./enums/ESpecifier.csv) : Adds the `FORCEINLINE` & `FORCEINLINE_DEBUGGABLE` specfiers (additions are made as they are encountered)
* [ETokType.csv](./enums/ETokType.csv) : Same modifications as ESpecifier.csv.
A separate [parser_case_macros.cpp](./components/parser_case_macros.cpp) is used to accomodate for the new forceinline specifiers.
The `global` macro the library uses is redefined as an empty substiution.
The expected usage of this library is to put into into a third-party plugin module to then use either in editor modules or in shell script done in some stage of hot-reloading or building the Unreal Engine or Project.

View File

@ -26,7 +26,7 @@ This means that the typename entry for the parameter AST would be either:
***Concepts and Constraints are not supported***
Its a [todo](https://github.com/Ed94/gencpp/issues/21)
### Feature Macros:
### Feature Macros
* `GEN_DEFINE_ATTRIBUTE_TOKENS` : Allows user to define their own attribute macros for use in parsing.
* This can be generated using base.cpp.
@ -36,10 +36,41 @@ Its a [todo](https://github.com/Ed94/gencpp/issues/21)
* `GEN_EXPOSE_BACKEND` : Will expose symbols meant for internal use only.
* `GEN_ROLL_OWN_DEPENDENCIES` : Optional override so that user may define the dependencies themselves.
* `GEN_DONT_ALLOW_INVALID_CODE` (Not implemented yet) : Will fail when an invalid code is constructed, parsed, or serialized.
* `GEN_C_LIKE_PP` : Setting to `<true or 1>` Will prevent usage of function defnitions using references and structs with member functions. Structs will still have user-defined operator conversions, for-range support, and other operator overloads
* `GEN_C_LIKE_CPP` : Setting to `<true or 1>` Will prevent usage of function defnitions using references and structs with member functions. Structs will still have user-defined operator conversions, for-range support, and other operator overloads
### The Data & Interface
The library's persistent state is managed tracked by a context struct: `global Context* _ctx;` defined within [static_data.cpp](../base/components/static_data.cpp)
https://github.com/Ed94/gencpp/blob/967a044637f1615c709cb723dc61118fcc08dcdb/base/components/interface.hpp#L39-L97
The interface for the context:
* `init`: Initializtion
* `deinit`: De-initialization.
* `reset`: Clears the allocations, but doesn't free the memoery, then calls `init()` on `_ctx` again.
* `get_context`: Retreive the currently tracked context.
* `set_context`: Swap out the current tracked context.
#### Allocato usage
* `Allocator_DyanmicContainers`: Growing arrays, hash tables. (Unbounded sized containers)
* `Allocator_Pool`: Fixed-sized object allocations (ASTs, etc)
* `Allocator_StrCache`: StrCached allocations
* `Allocator_Temp`: Temporary alloations mostly intended for StrBuilder usage. Manually cleared by the user by their own discretion.
The allocator definitions used are exposed to the user incase they want to dictate memory usage
* Allocators are defined with the `AllocatorInfo` structure found in [`memory.hpp`](../base/dependencies/memory.hpp)
* Most of the work is just defining the allocation procedure:
```cpp
void* ( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
```
For any allocator above that the user does not define before `init`, a fallback allocator will be assigned that utiizes the `fallback_allocator_proc` wtihin [interface.cpp](../base/components/interface.cpp).
As mentioned in root readme, the user is provided Code objects by calling the constructor's functions to generate them or find existing matches.
The AST is managed by the library and provided to the user via its interface.
@ -47,14 +78,14 @@ However, the user may specifiy memory configuration.
[Data layout of AST struct (Subject to heavily change with upcoming todos)](../base/components/ast.hpp#L396-461)
https://github.com/Ed94/gencpp/blob/eea4ebf5c40d5d87baa465abfb1be30845b2377e/base/components/ast.hpp#L396-L461
https://github.com/Ed94/gencpp/blob/967a044637f1615c709cb723dc61118fcc08dcdb/base/components/ast.hpp#L369-L435
*`StringCahced` is a typedef for `Str` (a string slice), to denote it is an interned string*
*`CodeType` is enum taggin the type of code. Has an underlying type of `u32`*
*`OperatorT` is a typedef for `EOperator::Type` which has an underlying type of `u32`*
*`StrBuilder` is the dynamically allocated string type for the library*
*`StrBuilder` is the dynamically allocating string builder type for the library*
AST widths are setup to be AST_POD_Size.
AST widths are setup to be AST_POD_Size (128 bytes by default).
The width dictates how much the static array can hold before it must give way to using an allocated array:
```cpp
@ -73,41 +104,16 @@ int AST_ArrSpecs_Cap =
)
/ sizeof(Specifier) - 1;
```
*Ex: If the AST_POD_Size is 128 the capacity of the static array is 20.*
Data Notes:
* The allocator definitions used are exposed to the user incase they want to dictate memory usage
* You'll find the memory handling in `init`, `deinit`, `reset`, `gen_strbuilder_allocator`, `cache_str`, `make_code`.
* Allocators are defined with the `AllocatorInfo` structure found in [`memory.hpp`](../base/dependencies/memory.hpp)
* Most of the work is just defining the allocation procedure:
```cpp
void* ( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
```
* ASTs are wrapped for the user in a Code struct which is a wrapper for a AST* type.
* Code types have member symbols but their data layout is enforced to be POD types.
* This library treats memory failures as fatal.
* Cached Strings are stored in their own set of arenas. AST constructors use cached strings for names, and content.
* `StringArenas`, `StringCache`, `Allocator_StringArena`, and `Allocator_StringTable` are the associated containers or allocators.
* Strings used for serialization and file buffers are not contained by those used for cached strings.
* They are currently using `FallbackAllocator`, which are tracked array of arenas that grows as needed (adds buckets when one runs out).
* Memory within the buckets is not reused, so its inherently wasteful.
* I will be augmenting the default allocator with virtual memory & a slab allocator in the [future](https://github.com/Ed94/gencpp/issues/12)
* Intrusive linked lists used children nodes on bodies, and parameters.
* `_ctx->Allocator_Temp` is used.
* Its intended to generate the AST in one go and serialize after. The constructors and serializer are designed to be a "one pass, front to back" setup.
* Allocations can be tuned by defining the folloiwng macros (will be moved to runtime configuration in the future):
* `GEN_GLOBAL_BUCKET_SIZE` : Size of each bucket area for the global allocator
* `GEN_CODEPOOL_NUM_BLOCKS` : Number of blocks per code pool in the code allocator
* `GEN_SIZE_PER_STRING_ARENA` : Size per arena used with string caching.
* `GEN_MAX_COMMENT_LINE_LENGTH` : Longest length a comment can have per line.
* `GEN_MAX_NAME_LENGTH` : Max length of any identifier.
* `GEN_MAX_UNTYPED_STR_LENGTH` : Max content length for any untyped code.
* `TokenMap_FixedArena` : token_fmt_va uses local_persit memory of this arena type for the hashtable.
* `GEN_LEX_ALLOCATOR_SIZE`
* `GEN_BUILDER_STR_BUFFER_RESERVE`
* Any modifcations to an existing AST should be to just construct another with the modifications done on-demand while traversing the AST (non-destructive).
The following CodeTypes are used which the user may optionally use strong typing with if they enable: `GEN_ENFORCE_STRONG_CODE_TYPES`
@ -117,6 +123,7 @@ The following CodeTypes are used which the user may optionally use strong typing
* CodeClass
* CodeConstructor
* CodeDefine
* CodeDefineParams
* CodeDestructor
* CodeEnum
* CodeExec
@ -127,7 +134,7 @@ The following CodeTypes are used which the user may optionally use strong typing
* CodeModule
* CodeNS
* CodeOperator
* CodeOpCast
* CodeOpCast : User defined member operator conversion
* CodeParams : Has support for `for : range` iterating across parameters.
* CodePreprocessCond
* CodePragma
@ -140,11 +147,15 @@ The following CodeTypes are used which the user may optionally use strong typing
* CodeUsing
* CodeVar
Each Code boy has an associated "filtered AST" with the naming convention: `AST_<CodeName>`
Each `struct Code<Name>` has an associated "filtered AST" with the naming convention: `AST_<CodeName>`
Unrelated fields of the AST for that node type are omitted and only necessary padding members are defined otherwise.
Retrieving a raw version of the ast can be done using the `raw()` function defined in each AST.
## There are three sets of interfaces for Code AST generation the library provides
For the interface related to these code types see:
* [ast.hpp](../base/components/ast.hpp): Under the region pragma `Code C-Interface`
* [code_types.hpp](../base/components/code_types.hpp): Under the region pragma `Code C-Interface`. Additional functionlity for c++ will be within the struct definitions or at the end of the file.
## There are three categories of interfaces for Code AST generation & reflection
* Upfront
* Parsing
@ -164,6 +175,7 @@ Interface :``
* def_class
* def_constructor
* def_define
* def_define_params
* def_destructor
* def_enum
* def_execution
@ -218,6 +230,27 @@ Code <name>
```
All optional parmeters are defined within `struct Opts_def_<functon name>`. This was done to setup a [macro trick](https://x.com/vkrajacic/status/1749816169736073295) for default optional parameers in the C library:
```cpp
struct gen_Opts_def_struct
{
gen_CodeBody body;
gen_CodeTypename parent;
gen_AccessSpec parent_access;
gen_CodeAttributes attributes;
gen_CodeTypename* interfaces;
gen_s32 num_interfaces;
gen_ModuleFlag mflags;
};
typedef struct gen_Opts_def_struct gen_Opts_def_struct;
GEN_API gen_CodeClass gen_def__struct( gen_Str name, gen_Opts_def_struct opts GEN_PARAM_DEFAULT );
#define gen_def_struct( name, ... ) gen_def__struct( name, ( gen_Opts_def_struct ) { __VA_ARGS__ } )
```
In the C++ library, the `def_<funtion name>` is not wrapped in a macro.
When using the body functions, its recommended to use the args macro to auto determine the number of arguments for the varadic:
```cpp
@ -228,7 +261,7 @@ def_global_body( 3, ht_entry, array_ht_entry, hashtable );
```
If a more incremental approach is desired for the body ASTs, `Code def_body( CodeT type )` can be used to create an empty body.
When the members have been populated use: `AST::validate_body` to verify that the members are valid entires for that type.
When the members have been populated use: `code_validate_body` to verify that the members are valid entires for that type.
### Parse construction
@ -238,12 +271,12 @@ Interface :
* parse_class
* parse_constructor
* parse_define
* parse_destructor
* parse_enum
* parse_export_body
* parse_extern_link
* parse_friend
* Purposefully are only support forward declares with this constructor.
* parse_function
* parse_global_body
* parse_namespace
@ -322,6 +355,7 @@ Code <name> = parse_<function name>( gen_code_str );
The following are provided predefined by the library as they are commonly used:
* `enum_underlying_macro`
* `access_public`
* `access_protected`
* `access_private`

View File

@ -39,7 +39,9 @@ Builder builder_open( char const* path )
return result;
}
result.Buffer = strbuilder_make_reserve( _ctx->Allocator_Temp, _ctx->InitSize_BuilderBuffer );
Context* ctx = get_context();
GEN_ASSERT_NOT_NULL(ctx);
result.Buffer = strbuilder_make_reserve( ctx->Allocator_Temp, ctx->InitSize_BuilderBuffer );
// log_fmt("$Builder - Opened file: %s\n", result.File.filename );
return result;

View File

@ -37,13 +37,14 @@ Builder builder_open ( char const* path );
void builder_pad_lines ( Builder* builder, s32 num );
void builder_print ( Builder* builder, Code code );
void builder_print_fmt_va( Builder* builder, char const* fmt, va_list va );
void builder_print_fmt ( Builder* builder, char const* fmt, ... ) {
void builder_write ( Builder* builder );
FORCEINLINE void builder_print_fmt ( Builder* builder, char const* fmt, ... ) {
va_list va;
va_start( va, fmt );
builder_print_fmt_va( builder, fmt, va );
va_end( va );
}
void builder_write( Builder* builder );
struct Builder
{
@ -68,10 +69,10 @@ struct Builder
};
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
void builder_pad_lines( Builder& builder, s32 num ) { return builder_pad_lines(& builder, num); }
void builder_print ( Builder& builder, Code code ) { return builder_print(& builder, code); }
void builder_write ( Builder& builder ) { return builder_write(& builder ); }
void builder_print_fmt( Builder& builder, char const* fmt, ...) {
FORCEINLINE void builder_pad_lines( Builder& builder, s32 num ) { return builder_pad_lines(& builder, num); }
FORCEINLINE void builder_print ( Builder& builder, Code code ) { return builder_print(& builder, code); }
FORCEINLINE void builder_write ( Builder& builder ) { return builder_write(& builder ); }
FORCEINLINE void builder_print_fmt( Builder& builder, char const* fmt, ...) {
va_list va;
va_start( va, fmt );
builder_print_fmt_va( & builder, fmt, va );

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -267,13 +267,15 @@ GEN_NS_BEGIN
#define stringize( ... ) stringize_va( __VA_ARGS__ )
#endif
#define src_line_str stringize( __LINE__ )
#ifndef do_once
#define do_once() \
static int __do_once_counter_##__LINE__ = 0; \
for ( ; __do_once_counter_##__LINE__ != 1; __do_once_counter_##__LINE__ = 1 )
#define do_once_defer( expression ) \
static int __do_once_counter_##__LINE__ = 0; \
for ( ; __do_once_counter_##__LINE__ != 1; __do_once_counter_##__LINE__ = 1, ( expression ) )
#define do_once() \
local_persist int __do_once_counter_##src_line_str = 0; \
for ( ; __do_once_counter_##src_line_str != 1; __do_once_counter_##src_line_str = 1 )
#define do_once_defer( expression ) \
local_persist int __do_once_counter_##src_line_str = 0; \
for ( ; __do_once_counter_##src_line_str != 1; __do_once_counter_##src_line_str = 1, ( expression ) )
#define do_once_start \
do \
{ \
@ -850,10 +852,10 @@ template<typename Type> mem_ptr_const to_mem_ptr_const( Type ptr ) { return (mem
#if GEN_BUILD_DEBUG
# if defined( GEN_COMPILER_MSVC )
# if _MSC_VER < 1300
#pragma message("GEN_BUILD_DEBUG: __asm int 3")
// #pragma message("GEN_BUILD_DEBUG: __asm int 3")
# define GEN_DEBUG_TRAP() __asm int 3 /* Trap to debugger! */
# else
#pragma message("GEN_BUILD_DEBUG: __debugbreak()")
// #pragma message("GEN_BUILD_DEBUG: __debugbreak()")
# define GEN_DEBUG_TRAP() __debugbreak()
# endif
# elif defined( GEN_COMPILER_TINYC )
@ -862,7 +864,7 @@ template<typename Type> mem_ptr_const to_mem_ptr_const( Type ptr ) { return (mem
# define GEN_DEBUG_TRAP() __builtin_trap()
# endif
#else
#pragma message("GEN_BUILD_DEBUG: omitted")
// #pragma message("GEN_BUILD_DEBUG: omitted")
# define GEN_DEBUG_TRAP()
#endif
@ -883,7 +885,7 @@ template<typename Type> mem_ptr_const to_mem_ptr_const( Type ptr ) { return (mem
// NOTE: Things that shouldn't happen with a message!
#define GEN_PANIC( msg, ... ) GEN_ASSERT_MSG( 0, msg, ##__VA_ARGS__ )
#if GEN_BULD_DEBUG
#if GEN_BUILD_DEBUG
#define GEN_FATAL( ... ) \
do \
{ \
@ -1138,7 +1140,6 @@ FORCEINLINE void check(Arena& arena) { return arena_check(& arena); }
#pragma pop_macro("check")
#endif
inline
AllocatorInfo arena_allocator_info( Arena* arena ) {
GEN_ASSERT(arena != nullptr);
@ -1301,9 +1302,9 @@ void pool_clear(Pool* pool);
void pool_free(Pool* pool);
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
AllocatorInfo allocator_info(Pool& pool) { return pool_allocator_info(& pool); }
void clear(Pool& pool) { return pool_clear(& pool); }
void free(Pool& pool) { return pool_free(& pool); }
FORCEINLINE AllocatorInfo allocator_info(Pool& pool) { return pool_allocator_info(& pool); }
FORCEINLINE void clear(Pool& pool) { return pool_clear(& pool); }
FORCEINLINE void free(Pool& pool) { return pool_free(& pool); }
#endif
struct Pool
@ -2042,6 +2043,7 @@ Array<Type> array_init_reserve(AllocatorInfo allocator, ssize capacity)
return {rcast(Type*, header + 1)};
}
FORCEINLINE
usize array_grow_formula(ssize value) {
return 2 * value + 8;
}
@ -2101,7 +2103,7 @@ bool array_append_at(Array<Type>* array, Type item, usize idx)
ArrayHeader* header = array_get_header(* array);
ssize slot = idx;
if (slot >= header->Num)
if (slot >= (ssize)(header->Num))
slot = header->Num - 1;
if (slot < 0)
@ -2180,10 +2182,9 @@ bool array_fill(Array<Type> array, usize begin, usize end, Type value)
ArrayHeader* header = array_get_header(array);
if (begin < 0 || end > header->Num)
return false;
return false;
for (ssize idx = ssize(begin); idx < ssize(end); idx++)
{
for (ssize idx = ssize(begin); idx < ssize(end); idx++) {
array[idx] = value;
}
@ -2253,7 +2254,6 @@ bool array_reserve(Array<Type>* array, usize new_capacity)
{
GEN_ASSERT( array != nullptr);
GEN_ASSERT(* array != nullptr);
GEN_ASSERT(num > 0)
ArrayHeader* header = array_get_header(array);
if (header->Capacity < new_capacity)
@ -2653,7 +2653,7 @@ HashTableFindResult hashtable__find(HashTable<Type> table, u64 key)
if (table.Entries[result.EntryIndex].Key == key)
break;
result.PrevIndex = result.EntryIndex;
result.PrevIndex = result.EntryIndex;
result.EntryIndex = table.Entries[result.EntryIndex].Next;
}
}
@ -2662,7 +2662,7 @@ HashTableFindResult hashtable__find(HashTable<Type> table, u64 key)
}
template<typename Type> FORCEINLINE
bool hashtable_full(HashTable<Type> table) {
b32 hashtable_full(HashTable<Type> table) {
GEN_ASSERT_NOT_NULL(table.Hashes);
GEN_ASSERT_NOT_NULL(table.Entries);
usize critical_load = usize(HashTable_CriticalLoadScale * f32(array_num(table.Hashes)));
@ -3089,6 +3089,7 @@ bool strbuilder_append_string(StrBuilder* str, StrBuilder const other) {
return strbuilder_append_c_str_len(str, (char const*)other, strbuilder_length(other));
}
inline
bool strbuilder_append_fmt(StrBuilder* str, char const* fmt, ...) {
GEN_ASSERT(str != nullptr);
ssize res;
@ -3837,6 +3838,435 @@ u64 time_rel_ms( void );
#pragma endregion Timing
#pragma region ADT
enum ADT_Type : u32
{
EADT_TYPE_UNINITIALISED, /* node was not initialised, this is a programming error! */
EADT_TYPE_ARRAY,
EADT_TYPE_OBJECT,
EADT_TYPE_STRING,
EADT_TYPE_MULTISTRING,
EADT_TYPE_INTEGER,
EADT_TYPE_REAL,
};
enum ADT_Props : u32
{
EADT_PROPS_NONE,
EADT_PROPS_NAN,
EADT_PROPS_NAN_NEG,
EADT_PROPS_INFINITY,
EADT_PROPS_INFINITY_NEG,
EADT_PROPS_FALSE,
EADT_PROPS_TRUE,
EADT_PROPS_NULL,
EADT_PROPS_IS_EXP,
EADT_PROPS_IS_HEX,
// Used internally so that people can fill in real numbers they plan to write.
EADT_PROPS_IS_PARSED_REAL,
};
enum ADT_NamingStyle : u32
{
EADT_NAME_STYLE_DOUBLE_QUOTE,
EADT_NAME_STYLE_SINGLE_QUOTE,
EADT_NAME_STYLE_NO_QUOTES,
};
enum ADT_AssignStyle : u32
{
EADT_ASSIGN_STYLE_COLON,
EADT_ASSIGN_STYLE_EQUALS,
EADT_ASSIGN_STYLE_LINE,
};
enum ADT_DelimStyle : u32
{
EADT_DELIM_STYLE_COMMA,
EADT_DELIM_STYLE_LINE,
EADT_DELIM_STYLE_NEWLINE,
};
enum ADT_Error : u32
{
EADT_ERROR_NONE,
EADT_ERROR_INTERNAL,
EADT_ERROR_ALREADY_CONVERTED,
EADT_ERROR_INVALID_TYPE,
EADT_ERROR_OUT_OF_MEMORY,
};
struct ADT_Node
{
char const* name;
struct ADT_Node* parent;
/* properties */
ADT_Type type : 4;
u8 props : 4;
#ifndef GEN_PARSER_DISABLE_ANALYSIS
u8 cfg_mode : 1;
u8 name_style : 2;
u8 assign_style : 2;
u8 delim_style : 2;
u8 delim_line_width : 4;
u8 assign_line_width : 4;
#endif
/* adt data */
union
{
char const* string;
Array(ADT_Node) nodes; ///< zpl_array
struct
{
union
{
f64 real;
s64 integer;
};
#ifndef GEN_PARSER_DISABLE_ANALYSIS
/* number analysis */
s32 base;
s32 base2;
u8 base2_offset : 4;
s8 exp : 4;
u8 neg_zero : 1;
u8 lead_digit : 1;
#endif
};
};
};
/* ADT NODE LIMITS
* delimiter and assignment segment width is limited to 128 whitespace symbols each.
* real number limits decimal position to 128 places.
* real number exponent is limited to 64 digits.
*/
/**
* @brief Initialise an ADT object or array
*
* @param node
* @param backing Memory allocator used for descendants
* @param name Node's name
* @param is_array
* @return error code
*/
u8 adt_make_branch( ADT_Node* node, AllocatorInfo backing, char const* name, b32 is_array );
/**
* @brief Destroy an ADT branch and its descendants
*
* @param node
* @return error code
*/
u8 adt_destroy_branch( ADT_Node* node );
/**
* @brief Initialise an ADT leaf
*
* @param node
* @param name Node's name
* @param type Node's type (use zpl_adt_make_branch for container nodes)
* @return error code
*/
u8 adt_make_leaf( ADT_Node* node, char const* name, ADT_Type type );
/**
* @brief Fetch a node using provided URI string.
*
* This method uses a basic syntax to fetch a node from the ADT. The following features are available
* to retrieve the data:
*
* - "a/b/c" navigates through objects "a" and "b" to get to "c"
* - "arr/[foo=123]/bar" iterates over "arr" to find any object with param "foo" that matches the value "123", then gets its field called "bar"
* - "arr/3" retrieves the 4th element in "arr"
* - "arr/[apple]" retrieves the first element of value "apple" in "arr"
*
* @param node ADT node
* @param uri Locator string as described above
* @return zpl_adt_node*
*
* @see code/apps/examples/json_get.c
*/
ADT_Node* adt_query( ADT_Node* node, char const* uri );
/**
* @brief Find a field node within an object by the given name.
*
* @param node
* @param name
* @param deep_search Perform search recursively
* @return zpl_adt_node * node
*/
ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search );
/**
* @brief Allocate an unitialised node within a container at a specified index.
*
* @param parent
* @param index
* @return zpl_adt_node * node
*/
ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index );
/**
* @brief Allocate an unitialised node within a container.
*
* @param parent
* @return zpl_adt_node * node
*/
ADT_Node* adt_alloc( ADT_Node* parent );
/**
* @brief Move an existing node to a new container at a specified index.
*
* @param node
* @param new_parent
* @param index
* @return zpl_adt_node * node
*/
ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, ssize index );
/**
* @brief Move an existing node to a new container.
*
* @param node
* @param new_parent
* @return zpl_adt_node * node
*/
ADT_Node* adt_move_node( ADT_Node* node, ADT_Node* new_parent );
/**
* @brief Swap two nodes.
*
* @param node
* @param other_node
* @return
*/
void adt_swap_nodes( ADT_Node* node, ADT_Node* other_node );
/**
* @brief Remove node from container.
*
* @param node
* @return
*/
void adt_remove_node( ADT_Node* node );
/**
* @brief Initialise a node as an object
*
* @param obj
* @param name
* @param backing
* @return
*/
b8 adt_set_obj( ADT_Node* obj, char const* name, AllocatorInfo backing );
/**
* @brief Initialise a node as an array
*
* @param obj
* @param name
* @param backing
* @return
*/
b8 adt_set_arr( ADT_Node* obj, char const* name, AllocatorInfo backing );
/**
* @brief Initialise a node as a string
*
* @param obj
* @param name
* @param value
* @return
*/
b8 adt_set_str( ADT_Node* obj, char const* name, char const* value );
/**
* @brief Initialise a node as a float
*
* @param obj
* @param name
* @param value
* @return
*/
b8 adt_set_flt( ADT_Node* obj, char const* name, f64 value );
/**
* @brief Initialise a node as a signed integer
*
* @param obj
* @param name
* @param value
* @return
*/
b8 adt_set_int( ADT_Node* obj, char const* name, s64 value );
/**
* @brief Append a new node to a container as an object
*
* @param parent
* @param name
* @return*
*/
ADT_Node* adt_append_obj( ADT_Node* parent, char const* name );
/**
* @brief Append a new node to a container as an array
*
* @param parent
* @param name
* @return*
*/
ADT_Node* adt_append_arr( ADT_Node* parent, char const* name );
/**
* @brief Append a new node to a container as a string
*
* @param parent
* @param name
* @param value
* @return*
*/
ADT_Node* adt_append_str( ADT_Node* parent, char const* name, char const* value );
/**
* @brief Append a new node to a container as a float
*
* @param parent
* @param name
* @param value
* @return*
*/
ADT_Node* adt_append_flt( ADT_Node* parent, char const* name, f64 value );
/**
* @brief Append a new node to a container as a signed integer
*
* @param parent
* @param name
* @param value
* @return*
*/
ADT_Node* adt_append_int( ADT_Node* parent, char const* name, s64 value );
/* parser helpers */
/**
* @brief Parses a text and stores the result into an unitialised node.
*
* @param node
* @param base
* @return*
*/
char* adt_parse_number( ADT_Node* node, char* base );
/**
* @brief Parses a text and stores the result into an unitialised node.
* This function expects the entire input to be a number.
*
* @param node
* @param base
* @return*
*/
char* adt_parse_number_strict( ADT_Node* node, char* base_str );
/**
* @brief Parses and converts an existing string node into a number.
*
* @param node
* @return
*/
ADT_Error adt_c_str_to_number( ADT_Node* node );
/**
* @brief Parses and converts an existing string node into a number.
* This function expects the entire input to be a number.
*
* @param node
* @return
*/
ADT_Error adt_c_str_to_number_strict( ADT_Node* node );
/**
* @brief Prints a number into a file stream.
*
* The provided file handle can also be a memory mapped stream.
*
* @see zpl_file_stream_new
* @param file
* @param node
* @return
*/
ADT_Error adt_print_number( FileInfo* file, ADT_Node* node );
/**
* @brief Prints a string into a file stream.
*
* The provided file handle can also be a memory mapped stream.
*
* @see zpl_file_stream_new
* @param file
* @param node
* @param escaped_chars
* @param escape_symbol
* @return
*/
ADT_Error adt_print_string( FileInfo* file, ADT_Node* node, char const* escaped_chars, char const* escape_symbol );
#pragma endregion ADT
#pragma region CSV
enum CSV_Error : u32
{
ECSV_Error__NONE,
ECSV_Error__INTERNAL,
ECSV_Error__UNEXPECTED_END_OF_INPUT,
ECSV_Error__MISMATCHED_ROWS,
};
typedef ADT_Node CSV_Object;
u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header );
u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header, char delim );
void csv_free( CSV_Object* obj );
void csv_write( FileInfo* file, CSV_Object* obj );
StrBuilder csv_write_string( AllocatorInfo a, CSV_Object* obj );
void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim );
StrBuilder csv_write_strbuilder_delimiter( AllocatorInfo a, CSV_Object* obj, char delim );
/* inline */
inline
u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header )
{
return csv_parse_delimiter( root, text, allocator, has_header, ',' );
}
inline
void csv_write( FileInfo* file, CSV_Object* obj )
{
csv_write_delimiter( file, obj, ',' );
}
inline
StrBuilder csv_write_string( AllocatorInfo a, CSV_Object* obj )
{
return csv_write_strbuilder_delimiter( a, obj, ',' );
}
#pragma endregion CSV
GEN_NS_END
#ifdef __clang__

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -28,435 +28,6 @@
GEN_NS_BEGIN
#pragma region ADT
enum ADT_Type : u32
{
EADT_TYPE_UNINITIALISED, /* node was not initialised, this is a programming error! */
EADT_TYPE_ARRAY,
EADT_TYPE_OBJECT,
EADT_TYPE_STRING,
EADT_TYPE_MULTISTRING,
EADT_TYPE_INTEGER,
EADT_TYPE_REAL,
};
enum ADT_Props : u32
{
EADT_PROPS_NONE,
EADT_PROPS_NAN,
EADT_PROPS_NAN_NEG,
EADT_PROPS_INFINITY,
EADT_PROPS_INFINITY_NEG,
EADT_PROPS_FALSE,
EADT_PROPS_TRUE,
EADT_PROPS_NULL,
EADT_PROPS_IS_EXP,
EADT_PROPS_IS_HEX,
// Used internally so that people can fill in real numbers they plan to write.
EADT_PROPS_IS_PARSED_REAL,
};
enum ADT_NamingStyle : u32
{
EADT_NAME_STYLE_DOUBLE_QUOTE,
EADT_NAME_STYLE_SINGLE_QUOTE,
EADT_NAME_STYLE_NO_QUOTES,
};
enum ADT_AssignStyle : u32
{
EADT_ASSIGN_STYLE_COLON,
EADT_ASSIGN_STYLE_EQUALS,
EADT_ASSIGN_STYLE_LINE,
};
enum ADT_DelimStyle : u32
{
EADT_DELIM_STYLE_COMMA,
EADT_DELIM_STYLE_LINE,
EADT_DELIM_STYLE_NEWLINE,
};
enum ADT_Error : u32
{
EADT_ERROR_NONE,
EADT_ERROR_INTERNAL,
EADT_ERROR_ALREADY_CONVERTED,
EADT_ERROR_INVALID_TYPE,
EADT_ERROR_OUT_OF_MEMORY,
};
struct ADT_Node
{
char const* name;
struct ADT_Node* parent;
/* properties */
ADT_Type type : 4;
u8 props : 4;
#ifndef GEN_PARSER_DISABLE_ANALYSIS
u8 cfg_mode : 1;
u8 name_style : 2;
u8 assign_style : 2;
u8 delim_style : 2;
u8 delim_line_width : 4;
u8 assign_line_width : 4;
#endif
/* adt data */
union
{
char const* string;
Array(ADT_Node) nodes; ///< zpl_array
struct
{
union
{
f64 real;
s64 integer;
};
#ifndef GEN_PARSER_DISABLE_ANALYSIS
/* number analysis */
s32 base;
s32 base2;
u8 base2_offset : 4;
s8 exp : 4;
u8 neg_zero : 1;
u8 lead_digit : 1;
#endif
};
};
};
/* ADT NODE LIMITS
* delimiter and assignment segment width is limited to 128 whitespace symbols each.
* real number limits decimal position to 128 places.
* real number exponent is limited to 64 digits.
*/
/**
* @brief Initialise an ADT object or array
*
* @param node
* @param backing Memory allocator used for descendants
* @param name Node's name
* @param is_array
* @return error code
*/
u8 adt_make_branch( ADT_Node* node, AllocatorInfo backing, char const* name, b32 is_array );
/**
* @brief Destroy an ADT branch and its descendants
*
* @param node
* @return error code
*/
u8 adt_destroy_branch( ADT_Node* node );
/**
* @brief Initialise an ADT leaf
*
* @param node
* @param name Node's name
* @param type Node's type (use zpl_adt_make_branch for container nodes)
* @return error code
*/
u8 adt_make_leaf( ADT_Node* node, char const* name, ADT_Type type );
/**
* @brief Fetch a node using provided URI string.
*
* This method uses a basic syntax to fetch a node from the ADT. The following features are available
* to retrieve the data:
*
* - "a/b/c" navigates through objects "a" and "b" to get to "c"
* - "arr/[foo=123]/bar" iterates over "arr" to find any object with param "foo" that matches the value "123", then gets its field called "bar"
* - "arr/3" retrieves the 4th element in "arr"
* - "arr/[apple]" retrieves the first element of value "apple" in "arr"
*
* @param node ADT node
* @param uri Locator string as described above
* @return zpl_adt_node*
*
* @see code/apps/examples/json_get.c
*/
ADT_Node* adt_query( ADT_Node* node, char const* uri );
/**
* @brief Find a field node within an object by the given name.
*
* @param node
* @param name
* @param deep_search Perform search recursively
* @return zpl_adt_node * node
*/
ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search );
/**
* @brief Allocate an unitialised node within a container at a specified index.
*
* @param parent
* @param index
* @return zpl_adt_node * node
*/
ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index );
/**
* @brief Allocate an unitialised node within a container.
*
* @param parent
* @return zpl_adt_node * node
*/
ADT_Node* adt_alloc( ADT_Node* parent );
/**
* @brief Move an existing node to a new container at a specified index.
*
* @param node
* @param new_parent
* @param index
* @return zpl_adt_node * node
*/
ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, ssize index );
/**
* @brief Move an existing node to a new container.
*
* @param node
* @param new_parent
* @return zpl_adt_node * node
*/
ADT_Node* adt_move_node( ADT_Node* node, ADT_Node* new_parent );
/**
* @brief Swap two nodes.
*
* @param node
* @param other_node
* @return
*/
void adt_swap_nodes( ADT_Node* node, ADT_Node* other_node );
/**
* @brief Remove node from container.
*
* @param node
* @return
*/
void adt_remove_node( ADT_Node* node );
/**
* @brief Initialise a node as an object
*
* @param obj
* @param name
* @param backing
* @return
*/
b8 adt_set_obj( ADT_Node* obj, char const* name, AllocatorInfo backing );
/**
* @brief Initialise a node as an array
*
* @param obj
* @param name
* @param backing
* @return
*/
b8 adt_set_arr( ADT_Node* obj, char const* name, AllocatorInfo backing );
/**
* @brief Initialise a node as a string
*
* @param obj
* @param name
* @param value
* @return
*/
b8 adt_set_str( ADT_Node* obj, char const* name, char const* value );
/**
* @brief Initialise a node as a float
*
* @param obj
* @param name
* @param value
* @return
*/
b8 adt_set_flt( ADT_Node* obj, char const* name, f64 value );
/**
* @brief Initialise a node as a signed integer
*
* @param obj
* @param name
* @param value
* @return
*/
b8 adt_set_int( ADT_Node* obj, char const* name, s64 value );
/**
* @brief Append a new node to a container as an object
*
* @param parent
* @param name
* @return*
*/
ADT_Node* adt_append_obj( ADT_Node* parent, char const* name );
/**
* @brief Append a new node to a container as an array
*
* @param parent
* @param name
* @return*
*/
ADT_Node* adt_append_arr( ADT_Node* parent, char const* name );
/**
* @brief Append a new node to a container as a string
*
* @param parent
* @param name
* @param value
* @return*
*/
ADT_Node* adt_append_str( ADT_Node* parent, char const* name, char const* value );
/**
* @brief Append a new node to a container as a float
*
* @param parent
* @param name
* @param value
* @return*
*/
ADT_Node* adt_append_flt( ADT_Node* parent, char const* name, f64 value );
/**
* @brief Append a new node to a container as a signed integer
*
* @param parent
* @param name
* @param value
* @return*
*/
ADT_Node* adt_append_int( ADT_Node* parent, char const* name, s64 value );
/* parser helpers */
/**
* @brief Parses a text and stores the result into an unitialised node.
*
* @param node
* @param base
* @return*
*/
char* adt_parse_number( ADT_Node* node, char* base );
/**
* @brief Parses a text and stores the result into an unitialised node.
* This function expects the entire input to be a number.
*
* @param node
* @param base
* @return*
*/
char* adt_parse_number_strict( ADT_Node* node, char* base_str );
/**
* @brief Parses and converts an existing string node into a number.
*
* @param node
* @return
*/
ADT_Error adt_c_str_to_number( ADT_Node* node );
/**
* @brief Parses and converts an existing string node into a number.
* This function expects the entire input to be a number.
*
* @param node
* @return
*/
ADT_Error adt_c_str_to_number_strict( ADT_Node* node );
/**
* @brief Prints a number into a file stream.
*
* The provided file handle can also be a memory mapped stream.
*
* @see zpl_file_stream_new
* @param file
* @param node
* @return
*/
ADT_Error adt_print_number( FileInfo* file, ADT_Node* node );
/**
* @brief Prints a string into a file stream.
*
* The provided file handle can also be a memory mapped stream.
*
* @see zpl_file_stream_new
* @param file
* @param node
* @param escaped_chars
* @param escape_symbol
* @return
*/
ADT_Error adt_print_string( FileInfo* file, ADT_Node* node, char const* escaped_chars, char const* escape_symbol );
#pragma endregion ADT
#pragma region CSV
enum CSV_Error : u32
{
ECSV_Error__NONE,
ECSV_Error__INTERNAL,
ECSV_Error__UNEXPECTED_END_OF_INPUT,
ECSV_Error__MISMATCHED_ROWS,
};
typedef ADT_Node CSV_Object;
u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header );
u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header, char delim );
void csv_free( CSV_Object* obj );
void csv_write( FileInfo* file, CSV_Object* obj );
StrBuilder csv_write_string( AllocatorInfo a, CSV_Object* obj );
void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim );
StrBuilder csv_write_strbuilder_delimiter( AllocatorInfo a, CSV_Object* obj, char delim );
/* inline */
inline
u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header )
{
return csv_parse_delimiter( root, text, allocator, has_header, ',' );
}
inline
void csv_write( FileInfo* file, CSV_Object* obj )
{
csv_write_delimiter( file, obj, ',' );
}
inline
StrBuilder csv_write_string( AllocatorInfo a, CSV_Object* obj )
{
return csv_write_strbuilder_delimiter( a, obj, ',' );
}
#pragma endregion CSV
#pragma region Scanner
// This is a simple file reader that reads the entire file into memory.

View File

@ -39,7 +39,9 @@ Builder builder_open( char const* path )
return result;
}
result.Buffer = strbuilder_make_reserve( _ctx->Allocator_Temp, _ctx->InitSize_BuilderBuffer );
Context* ctx = get_context();
GEN_ASSERT_NOT_NULL(ctx);
result.Buffer = strbuilder_make_reserve( ctx->Allocator_Temp, ctx->InitSize_BuilderBuffer );
// log_fmt("$Builder - Opened file: %s\n", result.File.filename );
return result;

View File

@ -3403,6 +3403,10 @@ void deinit(Context* ctx)
-- context_counter;
}
Context* get_context() {
return _ctx;
}
void reset(Context* ctx)
{
s32 index = 0;

View File

@ -883,7 +883,7 @@ template<typename Type> mem_ptr_const to_mem_ptr_const( Type ptr ) { return (mem
// NOTE: Things that shouldn't happen with a message!
#define GEN_PANIC( msg, ... ) GEN_ASSERT_MSG( 0, msg, ##__VA_ARGS__ )
#if GEN_BULD_DEBUG
#if GEN_BUILD_DEBUG
#define GEN_FATAL( ... ) \
do \
{ \

View File

@ -886,7 +886,7 @@ inline TokType str_to_toktype( Str str )
enum TokFlags : u32
{
TF_Operator = bit(0),
TF_Operator = bit(0),
TF_Assign = bit(1),
TF_Preprocess = bit(2),
TF_Preprocess_Cond = bit(3),
@ -3980,6 +3980,9 @@ GEN_API void init(Context* ctx);
// However on Windows at least, it doesn't need to occur as the OS will clean up after the process.
GEN_API void deinit(Context* ctx);
// Retrieves the active context (not usually needed, but here in case...)
GEN_API Context* get_contex();
// Clears the allocations, but doesn't free the memoery, then calls init() again.
// Ease of use.
GEN_API void reset(Context* ctx);