Compare commits

...

4 Commits

Author SHA1 Message Date
Ed_
99dbc499fa WIP: code_types.hpp c_library.cpp conversion (issue with C struct padding on asts) 2024-12-07 19:46:19 -05:00
Ed_
1c133bfc8d Massive total progress on c_library generation: (Summary of last 3 WIP commits)
- No longer using GEN_API_C_* macros as C-library wont need them and if you need C linkage there is no need to use the c++ library.
- GEN_C_LIKE_CPP replaces GEN_SUPPORT_CPP_MEMBER_FEATURES && GEN_SUPPORT_CPP_REFERENCES
  a. If users don't want to use member functions, function overloading, or referencese they can just this one macro to before including the library.
- Enums aren't accomodated in C++ sources, they entirely converted in c_libray.cpp
- ast.hpp now properly generates with C variant
- Fully prepared code_types.hpp for C library gen (not tested yet)
- Generated enums managed by helper.hpp now properly generate for C library.
2024-12-07 17:58:56 -05:00
Ed_
451b71884c WIP: Broken af 2024-12-07 17:17:02 -05:00
Ed_
4d638a7255 borken : lots of stuff changed, explaining in later commit...v 2024-12-07 00:21:09 -05:00
54 changed files with 3722 additions and 1952 deletions

View File

@ -1,9 +1,9 @@
{ {
"configurations": [ "configurations": [
{ {
"name": "Win32 msvc", "name": "Bootstrap",
"includePath": [ "includePath": [
"${workspaceFolder}/**" "${workspaceFolder}/project/**"
], ],
"defines": [ "defines": [
"_DEBUG", "_DEBUG",
@ -15,10 +15,39 @@
"GEN_INTELLISENSE_DIRECTIVES", "GEN_INTELLISENSE_DIRECTIVES",
"INTELLISENSE_DIRECTIVES" "INTELLISENSE_DIRECTIVES"
], ],
"cStandard": "c11",
"cppStandard": "c++17",
"windowsSdkVersion": "10.0.19041.0", "windowsSdkVersion": "10.0.19041.0",
"compilerPath": "C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.29.30133/bin/HostX64/x64/cl.exe", "compilerPath": "C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.29.30133/bin/HostX64/x64/cl.exe",
"intelliSenseMode": "msvc-x64", "intelliSenseMode": "msvc-x64",
"compileCommands": "${workspaceFolder}/project/build/compile_commands.json" "compileCommands": "C:\\projects\\gencpp\\.vscode\\tasks.json",
"compilerArgs": [
"/EHsc-",
"/GR-",
"/Zc:preprocessor",
"/FC"
]
},
{
"name": "Win32 msvc c_library",
"includePath": [
"${workspaceFolder}/gen_c_library/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE",
"GEN_TIME",
"GEN_IMPLEMENTATION",
// "GEN_DONT_USE_NAMESPACE"
"GEN_INTELLISENSE_DIRECTIVES",
"INTELLISENSE_DIRECTIVES"
],
"cppStandard": "c++17",
"windowsSdkVersion": "10.0.19041.0",
"compilerPath": "C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.29.30133/bin/HostX64/x64/cl.exe",
"intelliSenseMode": "msvc-x64",
"compileCommands": "C:\\projects\\gencpp\\.vscode\\tasks.json"
}, },
{ {
"name": "Win32 clang", "name": "Win32 clang",
@ -38,7 +67,7 @@
"windowsSdkVersion": "10.0.19041.0", "windowsSdkVersion": "10.0.19041.0",
"compilerPath": "C:/Users/Ed/scoop/apps/llvm/current/bin/clang++.exe", "compilerPath": "C:/Users/Ed/scoop/apps/llvm/current/bin/clang++.exe",
"intelliSenseMode": "windows-clang-x64", "intelliSenseMode": "windows-clang-x64",
"compileCommands": "${workspaceFolder}/project/build/compile_commands.json" "compileCommands": ".vscode/tasks.json"
} }
], ],
"version": 4 "version": 4

View File

@ -67,8 +67,10 @@
"C_Cpp.files.exclude": { "C_Cpp.files.exclude": {
"**/.vscode": true, "**/.vscode": true,
"**/.vs": true, "**/.vs": true,
"**/sanity.gen.hpp": true "**/sanity.gen.hpp": true,
"test/**":true,
}, },
"autoHide.autoHidePanel": false, "autoHide.autoHidePanel": false,
"autoHide.autoHideSideBar": false "autoHide.autoHideSideBar": false,
"dimmer.enabled": true
} }

144
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,144 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Build Bootstrap",
"type": "shell",
"command": "C:\\Program Files\\PowerShell\\7\\pwsh.exe",
"args": [
"-ExecutionPolicy",
"Bypass",
"-File",
"${workspaceFolder}/scripts/build.ci.ps1",
"bootstrap",
"msvc"
],
"group": "build",
"problemMatcher": {
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^(.*)\\((\\d+)\\)\\s*:\\s*(warning|error)\\s*(\\w+)\\s*:\\s*(.*)$",
"file": 1,
"line": 2,
"severity": 3,
"code": 4,
"message": 5
}
},
"presentation": {
"reveal": "always",
"panel": "shared",
"clear": true
}
},
{
"label": "Build C Library",
"type": "shell",
"command": "C:\\Program Files\\PowerShell\\7\\pwsh.exe",
"args": [
"-ExecutionPolicy",
"Bypass",
"-File",
"${workspaceFolder}/scripts/build.ci.ps1",
"c_library",
"msvc"
],
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": {
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^(.*)\\((\\d+)\\)\\s*:\\s*(warning|error)\\s*(\\w+)\\s*:\\s*(.*)$",
"file": 1,
"line": 2,
"severity": 3,
"code": 4,
"message": 5
}
},
"presentation": {
"reveal": "always",
"panel": "shared",
"clear": true
}
},
{
"label": "Build Singleheader (MSVC)",
"type": "shell",
"command": "C:\\Program Files\\PowerShell\\7\\pwsh.exe",
"args": [
"-ExecutionPolicy",
"Bypass",
"-File",
"${workspaceFolder}/scripts/build.ci.ps1",
"singleheader",
"msvc",
"debug"
],
"group": "build",
"problemMatcher": {
"owner": "cpp",
"fileLocation": ["relative", "${workspaceFolder}"],
"pattern": [
{
"regexp": "^(.*)\\((\\d+)\\)\\s*:\\s*(error|warning|info|note)\\s+(\\w{1,2}\\d+)\\s*:\\s*(.*)$",
"file": 1,
"line": 2,
"severity": 3,
"code": 4,
"message": 5
}
]
},
"presentation": {
"reveal": "always",
"panel": "shared",
"clear": true
}
},
{
"label": "Build Unreal (MSVC)",
"type": "shell",
"command": "C:\\Program Files\\PowerShell\\7\\pwsh.exe",
"args": [
"-ExecutionPolicy",
"Bypass",
"-File",
"${workspaceFolder}/scripts/build.ci.ps1",
"unreal",
"msvc",
"debug"
],
"group": "build",
"problemMatcher": {
"owner": "cpp",
"fileLocation": ["relative", "${workspaceFolder}"],
"pattern": [
{
"regexp": "^(.*)\\((\\d+)\\)\\s*:\\s*(error|warning|info|note)\\s+(\\w{1,2}\\d+)\\s*:\\s*(.*)$",
"file": 1,
"line": 2,
"severity": 3,
"code": 4,
"message": 5
}
]
},
"presentation": {
"reveal": "always",
"panel": "shared",
"clear": true
}
}
]
}

View File

@ -1,9 +1,9 @@
# gencpp # gencpp
An attempt at simple staged metaprogramming for c/c++. An attempt at simple staged metaprogramming for C/C++.
The library API is a composition of code element constructors. The library API is a composition of code element constructors, and a non-standards-compliant single-pass C/C++ parser.
These build up a code AST to then serialize with a file builder. These build up a code AST to then serialize with a file builder, or can be traversed for staged-reflection of C/C++ code.
This code base attempts follow the [handmade philosophy](https://handmade.network/manifesto). This code base attempts follow the [handmade philosophy](https://handmade.network/manifesto).
Its not meant to be a black box metaprogramming utility, it should be easy to intergrate into a user's project domain. Its not meant to be a black box metaprogramming utility, it should be easy to intergrate into a user's project domain.
@ -31,7 +31,7 @@ A metaprogram is built to generate files before the main program is built. We'll
`gen.cpp` \`s `main()` is defined as `gen_main()` which the user will have to define once for their program. There they will dictate everything that should be generated. `gen.cpp` \`s `main()` is defined as `gen_main()` which the user will have to define once for their program. There they will dictate everything that should be generated.
In order to keep the locality of this code within the same files the following pattern may be used (although this pattern isn't required at all): In order to keep the locality of this code within the same files the following pattern may be used (although this pattern isn't the best to use):
Within `program.cpp` : Within `program.cpp` :
@ -54,7 +54,6 @@ u32 gen_main()
// Regular runtime dependent on the generated code here. // Regular runtime dependent on the generated code here.
#endif #endif
``` ```
The design uses a constructive builder API for the code to generate. The design uses a constructive builder API for the code to generate.

1146
gen_c_library/Test.jsonc Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,6 @@
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS #define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
#define GEN_ENFORCE_STRONG_CODE_TYPES #define GEN_ENFORCE_STRONG_CODE_TYPES
#define GEN_EXPOSE_BACKEND #define GEN_EXPOSE_BACKEND
#define GEN_SUPPORT_CPP_MEMBER_FEATURES 1
#define GEN_SUPPORT_CPP_REFERENCES 1
#include "../project/gen.cpp" #include "../project/gen.cpp"
#include "helpers/push_ignores.inline.hpp" #include "helpers/push_ignores.inline.hpp"
@ -97,6 +95,8 @@ CodeBody parse_file( const char* path )
return code; return code;
} }
constexpr bool helper_use_c_definition = true;
int gen_main() int gen_main()
{ {
#define project_dir "../project/" #define project_dir "../project/"
@ -108,6 +108,10 @@ int gen_main()
PreprocessorDefines.append(txt("GEN_NS_PARSER")); PreprocessorDefines.append(txt("GEN_NS_PARSER"));
PreprocessorDefines.append(txt("GEN_NS_PARSER_BEGIN")); PreprocessorDefines.append(txt("GEN_NS_PARSER_BEGIN"));
PreprocessorDefines.append(txt("GEN_NS_PARSER_END")); PreprocessorDefines.append(txt("GEN_NS_PARSER_END"));
PreprocessorDefines.append(txt("Using_Code("));
PreprocessorDefines.append(txt("Using_CodeOps("));
PreprocessorDefines.append(txt("GEN_OPTIMIZE_MAPPINGS_BEGIN"));
PreprocessorDefines.append(txt("GEN_OPITMIZE_MAPPINGS_END"));
//PreprocessorDefines.append(txt("GEN_EXECUTION_EXPRESSION_SUPPORT")); //PreprocessorDefines.append(txt("GEN_EXECUTION_EXPRESSION_SUPPORT"));
Code push_ignores = scan_file( project_dir "helpers/push_ignores.inline.hpp" ); Code push_ignores = scan_file( project_dir "helpers/push_ignores.inline.hpp" );
@ -125,6 +129,17 @@ int gen_main()
header.print( c_library_header_start ); header.print( c_library_header_start );
#pragma region Scan, Parse, and Generate Components #pragma region Scan, Parse, and Generate Components
// Only has operator overload definitions that C doesn't need.
// CodeBody ast_inlines = gen_ast_inlines();
Code interface = scan_file( project_dir "components/interface.hpp" );
Code inlines = scan_file( project_dir "components/inlines.hpp" );
Code header_end = scan_file( project_dir "components/header_end.hpp" );
CodeBody ecode = gen_ecode ( project_dir "enums/ECodeTypes.csv", helper_use_c_definition );
CodeBody eoperator = gen_eoperator ( project_dir "enums/EOperator.csv", helper_use_c_definition );
CodeBody especifier = gen_especifier( project_dir "enums/ESpecifier.csv", helper_use_c_definition );
CodeBody parsed_types = parse_file( project_dir "components/types.hpp" ); CodeBody parsed_types = parse_file( project_dir "components/types.hpp" );
CodeBody types = def_body(CT_Global_Body); CodeBody types = def_body(CT_Global_Body);
for ( Code entry = parsed_types.begin(); entry != parsed_types.end(); ++ entry ) for ( Code entry = parsed_types.begin(); entry != parsed_types.end(); ++ entry )
@ -138,7 +153,7 @@ int gen_main()
if (using_ver->UnderlyingType->ReturnType) if (using_ver->UnderlyingType->ReturnType)
{ {
CodeTypename type = using_ver->UnderlyingType; CodeTypename type = using_ver->UnderlyingType;
CodeTypedef typedef_ver = parse_typedef(token_fmt( CodeTypedef typedef_ver = parse_typedef(token_fmt(
"ReturnType", to_string(type->ReturnType).to_strc() "ReturnType", to_string(type->ReturnType).to_strc()
, "Name" , using_ver->Name , "Name" , using_ver->Name
, "Parameters", to_string(type->Params).to_strc() , "Parameters", to_string(type->Params).to_strc()
@ -155,26 +170,16 @@ int gen_main()
case CT_Enum: case CT_Enum:
{ {
CodeEnum enum_def = cast(CodeEnum, entry); log_fmt("Detected ENUM: %S", entry->Name);
CodeTypedef typedef_enum = parse_typedef(token_fmt("name", enum_def->Name, stringize( typedef enum <name> <name>; ))); convert_cpp_enum_to_c(cast(CodeEnum, entry), types);
types.append(enum_def);
types.append(typedef_enum);
} }
break; break;
default:
types.append(entry);
break;
} }
} }
Code ast_types = scan_file( project_dir "components/ast_types.hpp" );
Code code_types = scan_file( project_dir "components/code_types.hpp" );
Code interface = scan_file( project_dir "components/interface.hpp" );
Code inlines = scan_file( project_dir "components/inlines.hpp" );
Code header_end = scan_file( project_dir "components/header_end.hpp" );
CodeBody ecode = gen_ecode ( project_dir "enums/ECode.csv" );
CodeBody eoperator = gen_eoperator ( project_dir "enums/EOperator.csv" );
CodeBody especifier = gen_especifier( project_dir "enums/ESpecifier.csv" );
CodeBody ast_inlines = gen_ast_inlines();
CodeBody parsed_ast = parse_file( project_dir "components/ast.hpp" ); CodeBody parsed_ast = parse_file( project_dir "components/ast.hpp" );
CodeBody ast = def_body(CT_Global_Body); CodeBody ast = def_body(CT_Global_Body);
for ( Code entry = parsed_ast.begin(); entry != parsed_ast.end(); ++ entry ) for ( Code entry = parsed_ast.begin(); entry != parsed_ast.end(); ++ entry )
@ -185,19 +190,13 @@ int gen_main()
CodePreprocessCond cond = cast(CodePreprocessCond, entry); CodePreprocessCond cond = cast(CodePreprocessCond, entry);
if (cond->Content.contains(txt("GEN_COMPILER_C"))) if (cond->Content.contains(txt("GEN_COMPILER_C")))
{ {
//++ entry; // //++ entry; //
//ast.append(entry) // typedef //ast.append(entry) // typedef
//for ( ; entry != parsed_ast.end() && entry->Type != CT_Preprocess_EndIf; ++ entry) {} //for ( ; entry != parsed_ast.end() && entry->Type != CT_Preprocess_EndIf; ++ entry) {}
//++ entry; // Consume endif //++ entry; // Consume endif
} }
b32 found = ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_MEMBER_FEATURES"), entry, parsed_ast, ast ); b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_ast, ast);
if (found) break;
found = ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_REFERENCES"), entry, parsed_ast, ast);
if (found) break;
found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_ast, ast);
if (found) break; if (found) break;
ast.append(entry); ast.append(entry);
@ -206,11 +205,21 @@ int gen_main()
case CT_Struct_Fwd: case CT_Struct_Fwd:
{ {
CodeStruct fwd = cast(CodeStruct, entry); CodeStruct fwd = cast(CodeStruct, entry);
if (fwd->Name.starts_with(txt("AST"))) { CodeTypedef tdef = parse_typedef(token_fmt("name", fwd->Name, stringize( typedef struct <name> <name>; )));
ast.append(fwd); ast.append(fwd);
CodeTypedef td = parse_typedef(token_fmt("name", fwd->Name, stringize( typedef struct <name> <name>; ))); ast.append(tdef);
ast.append(td); }
break;
case CT_Struct:
{
CodeStruct struct_def = cast(CodeStruct, entry);
ast.append(struct_def);
if ( ! entry->Name.is_equal(txt("AST")))
{
CodeTypedef tdef = parse_typedef(token_fmt("name", struct_def->Name, stringize( typedef struct <name> <name>; )));
ast.append(tdef);
} }
} }
break; break;
@ -219,7 +228,7 @@ int gen_main()
{ {
CodeVar var = cast(CodeVar, entry); CodeVar var = cast(CodeVar, entry);
s32 constexpr_found = var->Specs.remove( Spec_Constexpr ); s32 constexpr_found = var->Specs ? var->Specs.remove( Spec_Constexpr ) : - 1;
if (constexpr_found > -1) { if (constexpr_found > -1) {
log_fmt("Found constexpr: %S\n", entry.to_string()); log_fmt("Found constexpr: %S\n", entry.to_string());
if (var->Name.contains(txt("AST_ArrSpecs_Cap"))) if (var->Name.contains(txt("AST_ArrSpecs_Cap")))
@ -254,6 +263,56 @@ R"(#define AST_ArrSpecs_Cap \
ast.append(entry); ast.append(entry);
break; break;
} }
CodeBody parsed_code_types = parse_file( project_dir "components/code_types.hpp" );
CodeBody code_types = def_body(CT_Global_Body);
for ( Code entry = parsed_code_types.begin(); entry != parsed_code_types.end(); ++ entry ) switch( entry->Type )
{
case CT_Preprocess_If:
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_code_types, code_types );
if (found) {
++ entry;
break;
}
found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_code_types, code_types );
if (found) break;
code_types.append(entry);
}
break;
default:
code_types.append(entry);
break;
}
CodeBody parsed_ast_types = parse_file( project_dir "components/ast_types.hpp" );
CodeBody ast_types = def_body(CT_Global_Body);
for ( Code entry = parsed_ast_types.begin(); entry != parsed_ast_types.end(); ++ entry ) switch( entry->Type )
{
case CT_Preprocess_If:
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_code_types, code_types );
if (found) break;
ast_types.append(entry);
}
break;
case CT_Struct:
{
CodeStruct struct_def = cast(CodeStruct, entry);
CodeTypedef tdef = parse_typedef(token_fmt("name", struct_def->Name, stringize( typedef struct <name> <name>; )));
ast_types.append(struct_def);
ast_types.append(tdef);
}
break;
default:
ast_types.append(entry);
break;
}
#pragma endregion Scan, Parse, and Generate Components #pragma endregion Scan, Parse, and Generate Components
#pragma region Scan, Parse, and Generate Dependencies #pragma region Scan, Parse, and Generate Dependencies
@ -292,15 +351,13 @@ R"(#define AST_ArrSpecs_Cap \
case CT_Function: case CT_Function:
{ {
CodeFn fn = cast(CodeFn, entry); CodeFn fn = cast(CodeFn, entry);
s32 constexpr_found = fn->Specs.remove( Spec_Constexpr ); if (fn->Specs) {
if (constexpr_found > -1) { s32 constexpr_found = fn->Specs.remove( Spec_Constexpr );
log_fmt("Found constexpr: %S\n", entry.to_string()); if (constexpr_found > -1) {
fn->Specs.append(Spec_Inline); log_fmt("Found constexpr: %S\n", entry.to_string());
fn->Specs.append(Spec_Inline);
}
} }
// for ( StrC id : to_rename ) if (fn->Name.is_equal(id)) {
// Array(CodeFn) list = * needs_selectors.get(id);
// list.append(rename_function_to_unique_symbol(fn));
// }
memory.append(fn); memory.append(fn);
} }
break; break;
@ -323,6 +380,18 @@ R"(#define AST_ArrSpecs_Cap \
} }
} }
break; break;
case CT_Enum:
{
convert_cpp_enum_to_c(cast(CodeEnum, entry), memory);
}
break;
case CT_Struct_Fwd:
{
CodeTypedef tdef = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct <name> <name>; )));
memory.append(entry);
memory.append(tdef);
}
break;
case CT_Class: case CT_Class:
case CT_Struct: case CT_Struct:
{ {
@ -332,7 +401,8 @@ R"(#define AST_ArrSpecs_Cap \
(body_entry->Type) { (body_entry->Type) {
case CT_Preprocess_If: case CT_Preprocess_If:
{ {
ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_MEMBER_FEATURES"), body_entry, body, new_body ); b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP"), body_entry, body, new_body );
if (found) break;
} }
break; break;
@ -340,17 +410,16 @@ R"(#define AST_ArrSpecs_Cap \
new_body.append(body_entry); new_body.append(body_entry);
break; break;
} }
entry->Body = new_body; entry->Body = new_body;
CodeTypedef tdef = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct <name> <name>; )));
memory.append(entry); memory.append(entry);
memory.append(tdef);
} }
break; break;
case CT_Preprocess_If: case CT_Preprocess_If:
{ {
b32 found = ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_MEMBER_FEATURES"), entry, parsed_memory, memory ); b32 found = ignore_preprocess_cond_block(txt("! GEN_C_LIKE_CPP"), entry, parsed_memory, memory );
if (found) break;
found = ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_REFERENCES"), entry, parsed_memory, memory );
if (found) break; if (found) break;
memory.append(entry); memory.append(entry);
@ -418,93 +487,104 @@ R"(#define AST_ArrSpecs_Cap \
CodeBody parsed_strings = parse_file( project_dir "dependencies/strings.hpp" ); CodeBody parsed_strings = parse_file( project_dir "dependencies/strings.hpp" );
CodeBody strings = def_body(CT_Global_Body); CodeBody strings = def_body(CT_Global_Body);
for ( Code entry = parsed_strings.begin(); entry != parsed_strings.end(); ++ entry ) for ( Code entry = parsed_strings.begin(); entry != parsed_strings.end(); ++ entry ) switch (entry->Type)
{ {
switch (entry->Type) case CT_Preprocess_If:
{ {
case CT_Preprocess_If: CodePreprocessCond cond = cast(CodePreprocessCond, entry);
if (cond->Content.is_equal(txt("GEN_COMPILER_C")))
{ {
CodePreprocessCond cond = cast(CodePreprocessCond, entry); ++ entry; // Remove #if GEN_COMPILER_C
if (cond->Content.starts_with(txt("GEN_COMPILER_C || ! GEN_SUPPORT_CPP_MEMBER_FEATURES"))) for ( ; entry->Type != CT_Preprocess_Else
{ && entry->Type != CT_Preprocess_EndIf; ++ entry ) {
for (; entry != end(parsed_strings) && entry->Type != CT_Typedef; ++ entry) {} strings.append(entry); // Preserve content
strings.append(entry);
strings.append(fmt_newline);
for (; entry != end(parsed_strings) && entry->Type != CT_Preprocess_EndIf; ++ entry) {}
++ entry;
break;
} }
for ( ; entry->Type != CT_Preprocess_EndIf; ++ entry ) {} // Discard C++
bool found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_strings, strings); // #endif discarded by for loop
if (found) break; break;
found = ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_REFERENCES"), entry, parsed_strings, strings );
} }
break;
case CT_Preprocess_IfDef: bool found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_strings, strings);
{ if (found) break;
ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_strings, strings );
}
break;
case CT_Struct_Fwd: found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP"), entry, parsed_strings, strings);
{ if (found) break;
if ( entry->Name.is_equal(txt("String")) )
{
CodeTypedef c_def = parse_typedef(code( typedef char* String; ));
strings.append(c_def);
strings.append(fmt_newline);
++ entry;
continue;
}
strings.append(entry);
}
break;
case CT_Struct:
{
CodeBody body = cast(CodeBody, entry->Body);
CodeBody new_body = def_body( entry->Body->Type );
for ( Code body_entry = body.begin(); body_entry != body.end(); ++ body_entry ) switch
(body_entry->Type) {
case CT_Preprocess_If:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), body_entry, body, new_body );
if (found) break;
new_body.append(body_entry);
}
break;
default:
new_body.append(body_entry);
break;
}
entry->Body = new_body;
strings.append(entry);
}
break;
case CT_Typedef:
{
StrC name_string_table = txt("StringTable");
CodeTypedef td = cast(CodeTypedef, entry);
if (td->Name.contains(name_string_table))
{
CodeBody ht = gen_hashtable(txt("StrC"), name_string_table);
strings.append(ht);
break;
}
strings.append(td);
}
break;
default:
strings.append(entry);
break;
} }
break;
case CT_Preprocess_IfDef:
{
ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_strings, strings );
}
break;
case CT_Preprocess_IfNotDef:
{
log_fmt("\nIFNDEF: %SC\n", entry->Content);
strings.append(entry);
}
break;
case CT_Struct_Fwd:
{
if ( entry->Name.is_equal(txt("String")) )
{
CodeTypedef c_def = parse_typedef(code( typedef char* String; ));
strings.append(c_def);
strings.append(fmt_newline);
++ entry;
continue;
}
else
{
CodeTypedef c_def = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct <name> <name>; )));
strings.append(c_def);
}
strings.append(entry);
}
break;
case CT_Struct:
{
CodeBody body = cast(CodeBody, entry->Body);
CodeBody new_body = def_body( entry->Body->Type );
for ( Code body_entry = body.begin(); body_entry != body.end(); ++ body_entry ) switch
(body_entry->Type) {
case CT_Preprocess_If:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), body_entry, body, new_body );
if (found) break;
new_body.append(body_entry);
}
break;
default:
new_body.append(body_entry);
break;
}
entry->Body = new_body;
strings.append(entry);
}
break;
case CT_Typedef:
{
StrC name_string_table = txt("StringTable");
CodeTypedef td = cast(CodeTypedef, entry);
if (td->Name.contains(name_string_table))
{
CodeBody ht = gen_hashtable(txt("StrC"), name_string_table);
strings.append(ht);
break;
}
strings.append(td);
}
break;
default:
strings.append(entry);
break;
} }
CodeBody parsed_filesystem = parse_file( project_dir "dependencies/filesystem.hpp" ); CodeBody parsed_filesystem = parse_file( project_dir "dependencies/filesystem.hpp" );
@ -521,6 +601,34 @@ R"(#define AST_ArrSpecs_Cap \
filesystem.append(entry); filesystem.append(entry);
} }
break; break;
case CT_Enum:
{
if (entry->Name.is_equal(txt("FileOperations")))
continue;
convert_cpp_enum_to_c(cast(CodeEnum, entry), filesystem);
}
break;
case CT_Enum_Fwd:
case CT_Struct_Fwd:
case CT_Struct:
case CT_Union:
case CT_Union_Fwd:
{
StrC type_str = codetype_to_keyword_str(entry->Type);
StrC formated_tmpl = token_fmt_impl( 3,
"type", type_str
, "name", entry->Name,
stringize(
typedef <type> <name> <name>;
));
CodeTypedef tdef = parse_typedef(formated_tmpl);
filesystem.append(entry);
filesystem.append(tdef);
}
break;
case CT_Variable: case CT_Variable:
{ {
CodeVar var = cast(CodeVar, entry); CodeVar var = cast(CodeVar, entry);
@ -604,6 +712,8 @@ R"(#define AST_ArrSpecs_Cap \
header.print_fmt("#pragma region AST\n"); header.print_fmt("#pragma region AST\n");
header.print( dump_to_scratch_and_retireve(ast) ); header.print( dump_to_scratch_and_retireve(ast) );
header.print( dump_to_scratch_and_retireve(code_types) );
header.print( dump_to_scratch_and_retireve(ast_types) );
header.print_fmt("\n#pragma endregion AST\n"); header.print_fmt("\n#pragma endregion AST\n");
header.print_fmt( "\nGEN_API_C_END\n" ); header.print_fmt( "\nGEN_API_C_END\n" );

View File

@ -3,11 +3,26 @@
using namespace gen; using namespace gen;
void convert_cpp_enum_to_c( CodeEnum to_convert, CodeBody to_append )
{
#pragma push_macro("enum_underlying")
#undef enum_underlying
if (to_convert->UnderlyingType)
{
to_convert->UnderlyingTypeMacro = untyped_str(token_fmt("type", to_convert->UnderlyingType->Name, stringize(enum_underlying(<type>))));
to_convert->UnderlyingType = CodeTypename{nullptr};
}
CodeTypedef tdef = parse_typedef(token_fmt("name", to_convert->Name, stringize( typedef enum <name> <name>; )));
to_append.append(to_convert);
to_append.append(tdef);
#pragma pop_macro("enum_underlying")
}
b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& parsed_body, CodeBody& body ) b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& parsed_body, CodeBody& body )
{ {
b32 found = false; b32 found = false;
CodePreprocessCond cond = cast(CodePreprocessCond, entry_iter); CodePreprocessCond cond = cast(CodePreprocessCond, entry_iter);
if ( cond->Content.contains(cond_sig) ) if ( cond->Content.is_equal(cond_sig) )
{ {
log_fmt("Preprocess cond found: %SC\n", cond->Content); log_fmt("Preprocess cond found: %SC\n", cond->Content);
found = true; found = true;
@ -193,8 +208,8 @@ CodeFn rename_function_to_unique_symbol(CodeFn fn, StrC optional_prefix = txt(""
if (fn->Specs && fn->Specs->NumEntries > 0) if (fn->Specs && fn->Specs->NumEntries > 0)
{ {
new_name.append("_S_"); new_name.append("_S_");
for (Specifier* spec = begin(fn->Specs); for (Specifier* spec = begin(fn->Specs);
spec != end(fn->Specs); spec != end(fn->Specs);
++spec) ++spec)
{ {
new_name.append_fmt("%SC_", spec_to_str(*spec)); new_name.append_fmt("%SC_", spec_to_str(*spec));

View File

@ -1,8 +1,6 @@
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS #define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
#define GEN_ENFORCE_STRONG_CODE_TYPES #define GEN_ENFORCE_STRONG_CODE_TYPES
#define GEN_EXPOSE_BACKEND #define GEN_EXPOSE_BACKEND
#define GEN_SUPPORT_CPP_MEMBER_FEATURES 1
#define GEN_SUPPORT_CPP_REFERENCES 0
#include "gen.cpp" #include "gen.cpp"
#include "helpers/push_ignores.inline.hpp" #include "helpers/push_ignores.inline.hpp"
@ -157,7 +155,7 @@ int gen_main()
Code inlines = scan_file( project_dir "components/inlines.hpp" ); Code inlines = scan_file( project_dir "components/inlines.hpp" );
Code header_end = scan_file( project_dir "components/header_end.hpp" ); Code header_end = scan_file( project_dir "components/header_end.hpp" );
CodeBody ecode = gen_ecode ( project_dir "enums/ECode.csv" ); CodeBody ecode = gen_ecode ( project_dir "enums/ECodeTypes.csv" );
CodeBody eoperator = gen_eoperator ( project_dir "enums/EOperator.csv" ); CodeBody eoperator = gen_eoperator ( project_dir "enums/EOperator.csv" );
CodeBody especifier = gen_especifier( project_dir "enums/ESpecifier.csv" ); CodeBody especifier = gen_especifier( project_dir "enums/ESpecifier.csv" );
CodeBody ast_inlines = gen_ast_inlines(); CodeBody ast_inlines = gen_ast_inlines();

View File

@ -217,7 +217,7 @@ int gen_main()
Code inlines = scan_file( project_dir "components/inlines.hpp" ); Code inlines = scan_file( project_dir "components/inlines.hpp" );
Code header_end = scan_file( project_dir "components/header_end.hpp" ); Code header_end = scan_file( project_dir "components/header_end.hpp" );
CodeBody ecode = gen_ecode ( project_dir "enums/ECode.csv" ); CodeBody ecode = gen_ecode ( project_dir "enums/ECodeTypes.csv" );
CodeBody eoperator = gen_eoperator ( project_dir "enums/EOperator.csv" ); CodeBody eoperator = gen_eoperator ( project_dir "enums/EOperator.csv" );
CodeBody especifier = gen_especifier( project_dir "enums/ESpecifier.csv" ); CodeBody especifier = gen_especifier( project_dir "enums/ESpecifier.csv" );
CodeBody ast_inlines = gen_ast_inlines(); CodeBody ast_inlines = gen_ast_inlines();

View File

@ -257,6 +257,7 @@
<None Include="test\Readme.md" /> <None Include="test\Readme.md" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="gen_c_library\gen\gen.h" />
<ClInclude Include="project\auxillary\builder.hpp" /> <ClInclude Include="project\auxillary\builder.hpp" />
<ClInclude Include="project\auxillary\editor.hpp" /> <ClInclude Include="project\auxillary\editor.hpp" />
<ClInclude Include="project\auxillary\scanner.hpp" /> <ClInclude Include="project\auxillary\scanner.hpp" />

View File

@ -1,8 +1,7 @@
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS #define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
#define GEN_ENFORCE_STRONG_CODE_TYPES #define GEN_ENFORCE_STRONG_CODE_TYPES
#define GEN_EXPOSE_BACKEND #define GEN_EXPOSE_BACKEND
#define GEN_SUPPORT_CPP_MEMBER_FEATURES 0 #define GEN_C_LIKE_CPP 1
#define GEN_SUPPORT_CPP_REFERENCES 0
#include "gen.cpp" #include "gen.cpp"
#include "helpers/push_ignores.inline.hpp" #include "helpers/push_ignores.inline.hpp"
@ -161,7 +160,7 @@ int gen_main()
Code inlines = scan_file( "components/inlines.hpp" ); Code inlines = scan_file( "components/inlines.hpp" );
Code header_end = scan_file( "components/header_end.hpp" ); Code header_end = scan_file( "components/header_end.hpp" );
CodeBody ecode = gen_ecode ( "enums/ECode.csv" ); CodeBody ecode = gen_ecode ( "enums/ECodeTypes.csv" );
CodeBody eoperator = gen_eoperator ( "enums/EOperator.csv" ); CodeBody eoperator = gen_eoperator ( "enums/EOperator.csv" );
CodeBody especifier = gen_especifier( "enums/ESpecifier.csv" ); CodeBody especifier = gen_especifier( "enums/ESpecifier.csv" );
CodeBody ast_inlines = gen_ast_inlines(); CodeBody ast_inlines = gen_ast_inlines();

View File

@ -20,7 +20,7 @@ char const* code_debug_str(Code self)
string_append_fmt( result, "\n\tName : %S", self->Name ? self->Name : "Null" ); string_append_fmt( result, "\n\tName : %S", self->Name ? self->Name : "Null" );
string_append_fmt( result, "\n\tType : %S", code_type_str(self) ); string_append_fmt( result, "\n\tType : %S", code_type_str(self) );
string_append_fmt( result, "\n\tModule Flags : %S", to_str( self->ModuleFlags ) ); string_append_fmt( result, "\n\tModule Flags : %S", module_flag_to_str( self->ModuleFlags ) );
switch ( self->Type ) switch ( self->Type )
{ {
@ -64,7 +64,7 @@ char const* code_debug_str(Code self)
string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
string_append_fmt( result, "\n\tAttributes : %S", self->Attributes ? code_to_string(self->Attributes) : "Null" ); string_append_fmt( result, "\n\tAttributes : %S", self->Attributes ? code_to_string(self->Attributes) : "Null" );
string_append_fmt( result, "\n\tParentAccess: %s", self->ParentType ? to_str( self->ParentAccess ) : "No Parent" ); string_append_fmt( result, "\n\tParentAccess: %s", self->ParentType ? access_spec_to_str( self->ParentAccess ) : "No Parent" );
string_append_fmt( result, "\n\tParentType : %s", self->ParentType ? code_type_str(self->ParentType) : "Null" ); string_append_fmt( result, "\n\tParentType : %s", self->ParentType ? code_type_str(self->ParentType) : "Null" );
string_append_fmt( result, "\n\tBody : %S", self->Body ? code_debug_str(self->Body) : "Null" ); string_append_fmt( result, "\n\tBody : %S", self->Body ? code_debug_str(self->Body) : "Null" );
break; break;
@ -78,7 +78,7 @@ char const* code_debug_str(Code self)
string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
string_append_fmt( result, "\n\tAttributes : %S", self->Attributes ? code_to_string(self->Attributes) : "Null" ); string_append_fmt( result, "\n\tAttributes : %S", self->Attributes ? code_to_string(self->Attributes) : "Null" );
string_append_fmt( result, "\n\tParentAccess: %s", self->ParentType ? to_str( self->ParentAccess ) : "No Parent" ); string_append_fmt( result, "\n\tParentAccess: %s", self->ParentType ? access_spec_to_str( self->ParentAccess ) : "No Parent" );
string_append_fmt( result, "\n\tParentType : %s", self->ParentType ? code_type_str(self->ParentType) : "Null" ); string_append_fmt( result, "\n\tParentType : %s", self->ParentType ? code_type_str(self->ParentType) : "Null" );
break; break;
@ -362,7 +362,9 @@ Code code_duplicate(Code self)
{ {
Code result = make_code(); Code result = make_code();
mem_copy( result.ast, self.ast, sizeof( AST ) ); void* mem_result = rcast(void*, cast(AST*, result));
void* mem_self = rcast(void*, cast(AST*, self));
mem_copy( mem_result, mem_self, sizeof( AST ) );
result->Parent = { nullptr }; result->Parent = { nullptr };
return result; return result;
@ -409,173 +411,173 @@ void code_to_string_ptr( Code self, String* result )
break; break;
case CT_Class: case CT_Class:
to_string_def(cast(CodeClass, self), result ); class_to_string_def(cast(CodeClass, self), result );
break; break;
case CT_Class_Fwd: case CT_Class_Fwd:
to_string_fwd(cast(CodeClass, self), result ); class_to_string_fwd(cast(CodeClass, self), result );
break; break;
case CT_Constructor: case CT_Constructor:
to_string_def(cast(CodeConstructor, self), result ); constructor_to_string_def(cast(CodeConstructor, self), result );
break; break;
case CT_Constructor_Fwd: case CT_Constructor_Fwd:
to_string_fwd(cast(CodeConstructor, self), result ); constructor_to_string_fwd(cast(CodeConstructor, self), result );
break; break;
case CT_Destructor: case CT_Destructor:
to_string_def(cast(CodeDestructor, self), result ); destructor_to_string_def(cast(CodeDestructor, self), result );
break; break;
case CT_Destructor_Fwd: case CT_Destructor_Fwd:
to_string_fwd(cast(CodeDestructor, self), result ); destructor_to_string_fwd(cast(CodeDestructor, self), result );
break; break;
case CT_Enum: case CT_Enum:
to_string_def(cast(CodeEnum, self), result ); enum_to_string_def(cast(CodeEnum, self), result );
break; break;
case CT_Enum_Fwd: case CT_Enum_Fwd:
to_string_fwd(cast(CodeEnum, self), result ); enum_to_string_fwd(cast(CodeEnum, self), result );
break; break;
case CT_Enum_Class: case CT_Enum_Class:
to_string_class_def(cast(CodeEnum, self), result ); enum_to_string_class_def(cast(CodeEnum, self), result );
break; break;
case CT_Enum_Class_Fwd: case CT_Enum_Class_Fwd:
to_string_class_fwd(cast(CodeEnum, self), result ); enum_to_string_class_fwd(cast(CodeEnum, self), result );
break; break;
case CT_Export_Body: case CT_Export_Body:
to_string_export(cast(CodeBody, self), result ); body_to_string_export(cast(CodeBody, self), result );
break; break;
case CT_Extern_Linkage: case CT_Extern_Linkage:
to_string(cast(CodeExtern, self), result ); extern_to_string(cast(CodeExtern, self), result );
break; break;
case CT_Friend: case CT_Friend:
to_string(cast(CodeFriend, self), result ); friend_to_string_ref(cast(CodeFriend, self), result );
break; break;
case CT_Function: case CT_Function:
to_string_def(cast(CodeFn, self), result ); fn_to_string_def(cast(CodeFn, self), result );
break; break;
case CT_Function_Fwd: case CT_Function_Fwd:
to_string_fwd(cast(CodeFn, self), result ); fn_to_string_fwd(cast(CodeFn, self), result );
break; break;
case CT_Module: case CT_Module:
to_string(cast(CodeModule, self), result ); module_to_string_ref(cast(CodeModule, self), result );
break; break;
case CT_Namespace: case CT_Namespace:
to_string(cast(CodeNS, self), result ); namespace_to_string_ref(cast(CodeNS, self), result );
break; break;
case CT_Operator: case CT_Operator:
case CT_Operator_Member: case CT_Operator_Member:
to_string_def(cast(CodeOperator, self), result ); code_op_to_string_def(cast(CodeOperator, self), result );
break; break;
case CT_Operator_Fwd: case CT_Operator_Fwd:
case CT_Operator_Member_Fwd: case CT_Operator_Member_Fwd:
to_string_fwd(cast(CodeOperator, self), result ); code_op_to_string_fwd(cast(CodeOperator, self), result );
break; break;
case CT_Operator_Cast: case CT_Operator_Cast:
to_string_def(cast(CodeOpCast, self), result ); opcast_to_string_def(cast(CodeOpCast, self), result );
break; break;
case CT_Operator_Cast_Fwd: case CT_Operator_Cast_Fwd:
to_string_fwd(cast(CodeOpCast, self), result ); opcast_to_string_fwd(cast(CodeOpCast, self), result );
break; break;
case CT_Parameters: case CT_Parameters:
to_string(cast(CodeParam, self), result ); params_to_string_ref(cast(CodeParam, self), result );
break; break;
case CT_Preprocess_Define: case CT_Preprocess_Define:
to_string(cast(CodeDefine, self), result ); define_to_string_ref(cast(CodeDefine, self), result );
break; break;
case CT_Preprocess_If: case CT_Preprocess_If:
to_string_if(cast(CodePreprocessCond, self), result ); preprocess_to_string_if(cast(CodePreprocessCond, self), result );
break; break;
case CT_Preprocess_IfDef: case CT_Preprocess_IfDef:
to_string_ifdef(cast(CodePreprocessCond, self), result ); preprocess_to_string_ifdef(cast(CodePreprocessCond, self), result );
break; break;
case CT_Preprocess_IfNotDef: case CT_Preprocess_IfNotDef:
to_string_ifndef(cast(CodePreprocessCond, self), result ); preprocess_to_string_ifndef(cast(CodePreprocessCond, self), result );
break; break;
case CT_Preprocess_Include: case CT_Preprocess_Include:
to_string(cast(CodeInclude, self), result ); include_to_string_ref(cast(CodeInclude, self), result );
break; break;
case CT_Preprocess_ElIf: case CT_Preprocess_ElIf:
to_string_elif(cast(CodePreprocessCond, self), result ); preprocess_to_string_elif(cast(CodePreprocessCond, self), result );
break; break;
case CT_Preprocess_Else: case CT_Preprocess_Else:
to_string_else(cast(CodePreprocessCond, self), result ); preprocess_to_string_else(cast(CodePreprocessCond, self), result );
break; break;
case CT_Preprocess_EndIf: case CT_Preprocess_EndIf:
to_string_endif(cast(CodePreprocessCond, self), result ); preprocess_to_string_endif(cast(CodePreprocessCond, self), result );
break; break;
case CT_Preprocess_Pragma: case CT_Preprocess_Pragma:
to_string(cast(CodePragma, self), result ); pragma_to_string_ref(cast(CodePragma, self), result );
break; break;
case CT_Specifiers: case CT_Specifiers:
to_string(cast(CodeSpecifiers, self), result ); specifiers_to_string_ref(cast(CodeSpecifiers, self), result );
break; break;
case CT_Struct: case CT_Struct:
to_string_def(cast(CodeStruct, self), result ); struct_to_string_def(cast(CodeStruct, self), result );
break; break;
case CT_Struct_Fwd: case CT_Struct_Fwd:
to_string_fwd(cast(CodeStruct, self), result ); struct_to_string_fwd(cast(CodeStruct, self), result );
break; break;
case CT_Template: case CT_Template:
to_string(cast(CodeTemplate, self), result ); template_to_string_ref(cast(CodeTemplate, self), result );
break; break;
case CT_Typedef: case CT_Typedef:
to_string(cast(CodeTypedef, self), result ); typedef_to_string_ref(cast(CodeTypedef, self), result );
break; break;
case CT_Typename: case CT_Typename:
to_string(cast(CodeTypename, self), result ); typename_to_string_ref(cast(CodeTypename, self), result );
break; break;
case CT_Union: case CT_Union:
to_string_def( cast(CodeUnion, self), result ); union_to_string_def( cast(CodeUnion, self), result );
break; break;
case CT_Union_Fwd: case CT_Union_Fwd:
to_string_fwd( cast(CodeUnion, self), result ); union_to_string_fwd( cast(CodeUnion, self), result );
break; break;
case CT_Using: case CT_Using:
to_string(cast(CodeUsing, self), result ); using_to_string_ref(cast(CodeUsing, self), result );
break; break;
case CT_Using_Namespace: case CT_Using_Namespace:
to_string_ns(cast(CodeUsing, self), result ); using_to_string_ns(cast(CodeUsing, self), result );
break; break;
case CT_Variable: case CT_Variable:
to_string(cast(CodeVar, self), result ); var_to_string_ref(cast(CodeVar, self), result );
break; break;
case CT_Enum_Body: case CT_Enum_Body:
@ -586,7 +588,7 @@ void code_to_string_ptr( Code self, String* result )
case CT_Namespace_Body: case CT_Namespace_Body:
case CT_Struct_Body: case CT_Struct_Body:
case CT_Union_Body: case CT_Union_Body:
to_string( cast(CodeBody, self), result ); body_to_string_ref( cast(CodeBody, self), result );
break; break;
} }
} }
@ -624,8 +626,8 @@ bool code_is_equal( Code self, Code other )
log_fmt("\nAST::is_equal: Member - " #val " failed\n" \ log_fmt("\nAST::is_equal: Member - " #val " failed\n" \
"AST : %S\n" \ "AST : %S\n" \
"Other: %S\n" \ "Other: %S\n" \
, code_debug_str(self) \ , code_debug_str(self) \
,code_debug_str(other) \ ,code_debug_str(other) \
); \ ); \
\ \
return false; \ return false; \
@ -637,8 +639,8 @@ bool code_is_equal( Code self, Code other )
log_fmt("\nAST::is_equal: Member string - "#str " failed\n" \ log_fmt("\nAST::is_equal: Member string - "#str " failed\n" \
"AST : %S\n" \ "AST : %S\n" \
"Other: %S\n" \ "Other: %S\n" \
, code_debug_str(self) \ , code_debug_str(self) \
,code_debug_str(other) \ ,code_debug_str(other) \
); \ ); \
\ \
return false; \ return false; \
@ -650,8 +652,8 @@ bool code_is_equal( Code self, Code other )
log_fmt("\nAST::is_equal: Member content - "#content " failed\n" \ log_fmt("\nAST::is_equal: Member content - "#content " failed\n" \
"AST : %S\n" \ "AST : %S\n" \
"Other: %S\n" \ "Other: %S\n" \
, code_debug_str(self) \ , code_debug_str(self) \
, code_debug_str(other) \ , code_debug_str(other) \
); \ ); \
\ \
log_fmt("Content cannot be trusted to be unique with this check " \ log_fmt("Content cannot be trusted to be unique with this check " \
@ -672,25 +674,25 @@ bool code_is_equal( Code self, Code other )
"AST : %s\n" \ "AST : %s\n" \
"Other: %s\n" \ "Other: %s\n" \
"For ast member: %s\n" \ "For ast member: %s\n" \
, code_debug_str(self) \ , code_debug_str(self) \
, code_debug_str(other) \ , code_debug_str(other) \
, code_debug_str(self->ast) \ , code_debug_str(self->ast) \
); \ ); \
\ \
return false; \ return false; \
} \ } \
\ \
if ( ! code_is_equal(self->ast, other->ast ) ) \ if ( ! code_is_equal(self->ast, other->ast ) ) \
{ \ { \
log_fmt( "\nAST::is_equal: Failed for " #ast"\n" \ log_fmt( "\nAST::is_equal: Failed for " #ast"\n" \
"AST : %S\n" \ "AST : %S\n" \
"Other: %S\n" \ "Other: %S\n" \
"For ast member: %S\n" \ "For ast member: %S\n" \
"other's ast member: %S\n" \ "other's ast member: %S\n" \
, code_debug_str(self) \ , code_debug_str(self) \
, code_debug_str(other) \ , code_debug_str(other) \
, code_debug_str(self->ast) \ , code_debug_str(self->ast) \
, code_debug_str(other->ast) \ , code_debug_str(other->ast) \
); \ ); \
\ \
return false; \ return false; \
@ -916,10 +918,10 @@ bool code_is_equal( Code self, Code other )
if ( curr_other == nullptr ) if ( curr_other == nullptr )
{ {
log_fmt("\nAST::is_equal: Failed for parameter, other equivalent param is null\n" log_fmt("\nAST::is_equal: Failed for parameter, other equivalent param is null\n"
"AST : %S\n" "AST : %S\n"
"Other: %S\n" "Other: %S\n"
"For ast member: %S\n" "For ast member: %S\n"
, code_debug_str(curr) , code_debug_str(curr)
); );
return false; return false;
@ -1064,7 +1066,7 @@ bool code_is_equal( Code self, Code other )
return true; return true;
} }
case CT_Union_Fwd: case CT_Union_Fwd:
{ {
check_member_val( ModuleFlags ); check_member_val( ModuleFlags );
@ -1115,10 +1117,10 @@ bool code_is_equal( Code self, Code other )
if ( curr_other == nullptr ) if ( curr_other == nullptr )
{ {
log_fmt("\nAST::is_equal: Failed for body, other equivalent param is null\n" log_fmt("\nAST::is_equal: Failed for body, other equivalent param is null\n"
"AST : %S\n" "AST : %S\n"
"Other: %S\n" "Other: %S\n"
"For ast member: %S\n" "For ast member: %S\n"
, code_debug_str(curr) , code_debug_str(curr)
); );
return false; return false;
@ -1159,20 +1161,20 @@ bool code_is_equal( Code self, Code other )
bool code_validate_body(Code self) bool code_validate_body(Code self)
{ {
#define CheckEntries( Unallowed_Types ) \ #define CheckEntries( Unallowed_Types ) \
do \ do \
{ \ { \
CodeBody body = cast(CodeBody, self); \ CodeBody body = cast(CodeBody, self); \
for ( Code code_entry = begin(body); code_entry != end(body); next(body, code_entry) ) \ for ( Code code_entry = begin_CodeBody(body); code_entry != end_CodeBody(body); next_CodeBody(body, code_entry) ) \
{ \ { \
switch ( code_entry->Type ) \ switch ( code_entry->Type ) \
{ \ { \
Unallowed_Types \ Unallowed_Types \
log_failure( "AST::validate_body: Invalid entry in body %s", code_debug_str(code_entry) ); \ log_failure( "AST::validate_body: Invalid entry in body %s", code_debug_str(code_entry) ); \
return false; \ return false; \
} \ } \
} \ } \
} \ } \
while (0); while (0);
switch ( self->Type ) switch ( self->Type )
@ -1185,7 +1187,7 @@ bool code_validate_body(Code self)
case CT_Enum_Body: case CT_Enum_Body:
{ {
CodeBody body = cast(CodeBody, self); CodeBody body = cast(CodeBody, self);
for ( Code entry = begin(body); entry != end(body); next(body, entry) ) for ( Code entry = begin_CodeBody(body); entry != end_CodeBody(body); next_CodeBody(body, entry) )
{ {
if ( entry->Type != CT_Untyped ) if ( entry->Type != CT_Untyped )
{ {
@ -1213,7 +1215,7 @@ bool code_validate_body(Code self)
case CT_Global_Body: case CT_Global_Body:
{ {
CodeBody body = cast(CodeBody, self); CodeBody body = cast(CodeBody, self);
for ( Code entry = begin(body); entry != end(body); next(body, entry) ) for ( Code entry = begin_CodeBody(body); entry != end_CodeBody(body); next_CodeBody(body, entry) )
{ {
switch (entry->Type) switch (entry->Type)
{ {
@ -1253,7 +1255,7 @@ bool code_validate_body(Code self)
case CT_Union_Body: case CT_Union_Body:
{ {
CodeBody body = cast(CodeBody, self); CodeBody body = cast(CodeBody, self);
for ( Code entry = begin(body); entry != end(body); next(body, entry) ) for ( Code entry = begin_CodeBody(body); entry != end_CodeBody(body); next_CodeBody(body, entry) )
{ {
if ( entry->Type != CT_Untyped ) if ( entry->Type != CT_Untyped )
{ {

View File

@ -6,8 +6,6 @@
#include "gen/especifier.hpp" #include "gen/especifier.hpp"
#endif #endif
GEN_API_C_BEGIN
struct AST; struct AST;
struct AST_Body; struct AST_Body;
struct AST_Attributes; struct AST_Attributes;
@ -155,20 +153,25 @@ Define_Code(Var);
#undef Define_Code #undef Define_Code
GEN_NS_PARSER_BEGIN GEN_NS_PARSER_BEGIN
struct Token; struct Token;
GEN_NS_PARSER_END GEN_NS_PARSER_END
#define Token_Typedef struct Token Token
typedef Token_Typedef;
#undef Token_Typedef
#if GEN_COMPILER_CPP #if GEN_COMPILER_CPP
GEN_API_C_END // Note(Ed): This is to alleviate an edge case with parsing usings or typedefs where I don't really have it setup
template< class Type> forceinline Type tmpl_cast( Code self ) { return * rcast( Type*, & self ); } // to parse a 'namespace' macro or a type with a macro.
GEN_API_C_BEGIN // I have ideas for ways to pack that into the typedef/using ast, but for now just keeping it like this
#define ParserTokenType GEN_NS_PARSER Token
typedef ParserTokenType Token;
#undef ParserTokenType
#endif #endif
#pragma region Code Interface #if GEN_COMPILER_CPP
template< class Type> forceinline Type tmpl_cast( Code self ) { return * rcast( Type*, & self ); }
#endif
#pragma region Code C-Interface
void code_append (Code code, Code other ); void code_append (Code code, Code other );
char const* code_debug_str (Code code); char const* code_debug_str (Code code);
Code code_duplicate (Code code); Code code_duplicate (Code code);
@ -182,10 +185,9 @@ String code_to_string (Code self );
void code_to_string_ptr(Code self, String* result ); void code_to_string_ptr(Code self, String* result );
char const* code_type_str (Code self ); char const* code_type_str (Code self );
bool code_validate_body(Code self ); bool code_validate_body(Code self );
#pragma endregion Code Interface #pragma endregion Code C-Interface
#if GEN_COMPILER_CPP #if GEN_COMPILER_CPP
GEN_API_C_END
/* /*
AST* wrapper AST* wrapper
- Not constantly have to append the '*' as this is written often.. - Not constantly have to append the '*' as this is written often..
@ -195,34 +197,36 @@ struct Code
{ {
AST* ast; AST* ast;
# define Using_Code( Typename ) \ # define Using_Code( Typename ) \
char const* debug_str() { return code_debug_str(* this); } \ forceinline char const* debug_str() { return code_debug_str(* this); } \
Code duplicate() { return code_duplicate(* this); } \ forceinline Code duplicate() { return code_duplicate(* this); } \
bool is_equal( Code other ) { return code_is_equal(* this, other); } \ forceinline bool is_equal( Code other ) { return code_is_equal(* this, other); } \
bool is_body() { return code_is_body(* this); } \ forceinline bool is_body() { return code_is_body(* this); } \
bool is_valid() { return code_is_valid(* this); } \ forceinline bool is_valid() { return code_is_valid(* this); } \
void set_global() { return code_set_global(* this); } forceinline void set_global() { return code_set_global(* this); }
# define Using_CodeOps( Typename ) \ # define Using_CodeOps( Typename ) \
Typename& operator = ( Code other ); \ forceinline Typename& operator = ( Code other ); \
bool operator ==( Code other ) { return (AST*)ast == other.ast; } \ forceinline bool operator ==( Code other ) { return (AST*)ast == other.ast; } \
bool operator !=( Code other ) { return (AST*)ast != other.ast; } \ forceinline bool operator !=( Code other ) { return (AST*)ast != other.ast; } \
forceinline bool operator ==(std::nullptr_t) const { return ast == nullptr; } \
forceinline bool operator !=(std::nullptr_t) const { return ast != nullptr; } \
operator bool(); operator bool();
#if GEN_SUPPORT_CPP_MEMBER_FEATURES #if ! GEN_C_LIKE_CPP
Using_Code( Code ); Using_Code( Code );
void append(Code other) { return code_append(* this, other); } forceinline void append(Code other) { return code_append(* this, other); }
Code* entry(u32 idx) { return code_entry(* this, idx); } forceinline Code* entry(u32 idx) { return code_entry(* this, idx); }
bool has_entries() { return code_has_entries(* this); } forceinline bool has_entries() { return code_has_entries(* this); }
String to_string() { return code_to_string(* this); } forceinline String to_string() { return code_to_string(* this); }
void to_string(String& result) { return code_to_string_ptr(* this, & result); } forceinline void to_string(String& result) { return code_to_string_ptr(* this, & result); }
char const* type_str() { return code_type_str(* this); } forceinline char const* type_str() { return code_type_str(* this); }
bool validate_body() { return code_validate_body(*this); } forceinline bool validate_body() { return code_validate_body(*this); }
#endif #endif
Using_CodeOps( Code ); Using_CodeOps( Code );
forceinline AST* operator ->() { return ast; }
AST* operator ->() { return ast; }
Code& operator ++(); Code& operator ++();
// TODO(Ed) : Remove this overload. // TODO(Ed) : Remove this overload.
@ -237,11 +241,6 @@ struct Code
return *this; return *this;
} }
bool operator==(std::nullptr_t) const { return ast == nullptr; }
bool operator!=(std::nullptr_t) const { return ast != nullptr; }
friend bool operator==(std::nullptr_t, const Code code) { return code.ast == nullptr; }
friend bool operator!=(std::nullptr_t, const Code code) { return code.ast != nullptr; }
#ifdef GEN_ENFORCE_STRONG_CODE_TYPES #ifdef GEN_ENFORCE_STRONG_CODE_TYPES
# define operator explicit operator # define operator explicit operator
#endif #endif
@ -276,7 +275,6 @@ struct Code
operator CodeVar() const; operator CodeVar() const;
#undef operator #undef operator
}; };
GEN_API_C_BEGIN
#endif #endif
#pragma region Statics #pragma region Statics
@ -287,7 +285,6 @@ extern Code Code_Global;
extern Code Code_Invalid; extern Code Code_Invalid;
#pragma endregion Statics #pragma endregion Statics
typedef struct Code_POD Code_POD;
struct Code_POD struct Code_POD
{ {
AST* ast; AST* ast;
@ -362,7 +359,7 @@ struct AST
Code Next; Code Next;
Code Back; Code Back;
}; };
Token* Token; // Reference to starting token, only avaialble if it was derived from parsing. Token* Token; // Reference to starting token, only avaialble if it was derived from parsing.
Code Parent; Code Parent;
StringCached Name; StringCached Name;
CodeType Type; CodeType Type;
@ -385,10 +382,13 @@ static_assert( sizeof(AST) == AST_POD_Size, "ERROR: AST POD is not size of AST_P
struct InvalidCode_ImplictCaster; struct InvalidCode_ImplictCaster;
#define InvalidCode (InvalidCode_ImplictCaster{}) #define InvalidCode (InvalidCode_ImplictCaster{})
#else #else
#define InvalidCode Code_Invalid #define InvalidCode { (void*)Code_Invalid }
#endif #endif
#if GEN_COMPILER_CPP
struct NullCode_ImplicitCaster;
// Used when the its desired when omission is allowed in a definition. // Used when the its desired when omission is allowed in a definition.
#define NullCode { nullptr } #define NullCode (NullCode_ImplicitCaster{})
#else
GEN_API_C_END #define NullCode nullptr
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES #ifdef GEN_INTELLISENSE_DIRECTIVES
#pragma once #include "components/types.hpp" #pragma once
#include "components/types.hpp"
#endif #endif
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
@ -8,7 +9,7 @@
inline Code& Code::operator=( Code other ) inline Code& Code::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -24,7 +25,7 @@ inline Code::operator bool()
inline CodeBody& CodeBody::operator=( Code other ) inline CodeBody& CodeBody::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -40,7 +41,7 @@ inline CodeBody::operator bool()
inline CodeAttributes& CodeAttributes::operator=( Code other ) inline CodeAttributes& CodeAttributes::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -71,7 +72,7 @@ inline AST_Attributes* CodeAttributes::operator->()
inline CodeComment& CodeComment::operator=( Code other ) inline CodeComment& CodeComment::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -102,7 +103,7 @@ inline AST_Comment* CodeComment::operator->()
inline CodeConstructor& CodeConstructor::operator=( Code other ) inline CodeConstructor& CodeConstructor::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -133,7 +134,7 @@ inline AST_Constructor* CodeConstructor::operator->()
inline CodeClass& CodeClass::operator=( Code other ) inline CodeClass& CodeClass::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -149,7 +150,7 @@ inline CodeClass::operator bool()
inline CodeDefine& CodeDefine::operator=( Code other ) inline CodeDefine& CodeDefine::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -180,7 +181,7 @@ inline AST_Define* CodeDefine::operator->()
inline CodeDestructor& CodeDestructor::operator=( Code other ) inline CodeDestructor& CodeDestructor::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -211,7 +212,7 @@ inline AST_Destructor* CodeDestructor::operator->()
inline CodeEnum& CodeEnum::operator=( Code other ) inline CodeEnum& CodeEnum::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -242,7 +243,7 @@ inline AST_Enum* CodeEnum::operator->()
inline CodeExec& CodeExec::operator=( Code other ) inline CodeExec& CodeExec::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -273,7 +274,7 @@ inline AST_Exec* CodeExec::operator->()
inline CodeExtern& CodeExtern::operator=( Code other ) inline CodeExtern& CodeExtern::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -304,7 +305,7 @@ inline AST_Extern* CodeExtern::operator->()
inline CodeFriend& CodeFriend::operator=( Code other ) inline CodeFriend& CodeFriend::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -335,7 +336,7 @@ inline AST_Friend* CodeFriend::operator->()
inline CodeFn& CodeFn::operator=( Code other ) inline CodeFn& CodeFn::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -366,7 +367,7 @@ inline AST_Fn* CodeFn::operator->()
inline CodeInclude& CodeInclude::operator=( Code other ) inline CodeInclude& CodeInclude::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -397,7 +398,7 @@ inline AST_Include* CodeInclude::operator->()
inline CodeModule& CodeModule::operator=( Code other ) inline CodeModule& CodeModule::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -428,7 +429,7 @@ inline AST_Module* CodeModule::operator->()
inline CodeNS& CodeNS::operator=( Code other ) inline CodeNS& CodeNS::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -459,7 +460,7 @@ inline AST_NS* CodeNS::operator->()
inline CodeOperator& CodeOperator::operator=( Code other ) inline CodeOperator& CodeOperator::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -490,7 +491,7 @@ inline AST_Operator* CodeOperator::operator->()
inline CodeOpCast& CodeOpCast::operator=( Code other ) inline CodeOpCast& CodeOpCast::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -521,7 +522,7 @@ inline AST_OpCast* CodeOpCast::operator->()
inline CodeParam& CodeParam::operator=( Code other ) inline CodeParam& CodeParam::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -537,7 +538,7 @@ inline CodeParam::operator bool()
inline CodePragma& CodePragma::operator=( Code other ) inline CodePragma& CodePragma::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -568,7 +569,7 @@ inline AST_Pragma* CodePragma::operator->()
inline CodePreprocessCond& CodePreprocessCond::operator=( Code other ) inline CodePreprocessCond& CodePreprocessCond::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -599,7 +600,7 @@ inline AST_PreprocessCond* CodePreprocessCond::operator->()
inline CodeSpecifiers& CodeSpecifiers::operator=( Code other ) inline CodeSpecifiers& CodeSpecifiers::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -615,7 +616,7 @@ inline CodeSpecifiers::operator bool()
inline CodeStruct& CodeStruct::operator=( Code other ) inline CodeStruct& CodeStruct::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -631,7 +632,7 @@ inline CodeStruct::operator bool()
inline CodeTemplate& CodeTemplate::operator=( Code other ) inline CodeTemplate& CodeTemplate::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -662,7 +663,7 @@ inline AST_Template* CodeTemplate::operator->()
inline CodeTypename& CodeTypename::operator=( Code other ) inline CodeTypename& CodeTypename::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -693,7 +694,7 @@ inline AST_Typename* CodeTypename::operator->()
inline CodeTypedef& CodeTypedef::operator=( Code other ) inline CodeTypedef& CodeTypedef::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -724,7 +725,7 @@ inline AST_Typedef* CodeTypedef::operator->()
inline CodeUnion& CodeUnion::operator=( Code other ) inline CodeUnion& CodeUnion::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -755,7 +756,7 @@ inline AST_Union* CodeUnion::operator->()
inline CodeUsing& CodeUsing::operator=( Code other ) inline CodeUsing& CodeUsing::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -786,7 +787,7 @@ inline AST_Using* CodeUsing::operator->()
inline CodeVar& CodeVar::operator=( Code other ) inline CodeVar& CodeVar::operator=( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast( decltype( ast ), code_duplicate( other ).ast );
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -816,146 +817,149 @@ inline AST_Var* CodeVar::operator->()
} }
#pragma endregion generated code inline implementation #pragma endregion generated code inline implementation
#pragma region generated AST/Code cast implementation
inline Code::operator CodeBody() const #pragma region generated AST/Code cast implementation
GEN_OPTIMIZE_MAPPINGS_BEGIN
forceinline Code::operator CodeBody() const
{ {
return { (AST_Body*)ast }; return { (AST_Body*)ast };
} }
inline Code::operator CodeAttributes() const forceinline Code::operator CodeAttributes() const
{ {
return { (AST_Attributes*)ast }; return { (AST_Attributes*)ast };
} }
inline Code::operator CodeComment() const forceinline Code::operator CodeComment() const
{ {
return { (AST_Comment*)ast }; return { (AST_Comment*)ast };
} }
inline Code::operator CodeConstructor() const forceinline Code::operator CodeConstructor() const
{ {
return { (AST_Constructor*)ast }; return { (AST_Constructor*)ast };
} }
inline Code::operator CodeClass() const forceinline Code::operator CodeClass() const
{ {
return { (AST_Class*)ast }; return { (AST_Class*)ast };
} }
inline Code::operator CodeDefine() const forceinline Code::operator CodeDefine() const
{ {
return { (AST_Define*)ast }; return { (AST_Define*)ast };
} }
inline Code::operator CodeDestructor() const forceinline Code::operator CodeDestructor() const
{ {
return { (AST_Destructor*)ast }; return { (AST_Destructor*)ast };
} }
inline Code::operator CodeEnum() const forceinline Code::operator CodeEnum() const
{ {
return { (AST_Enum*)ast }; return { (AST_Enum*)ast };
} }
inline Code::operator CodeExec() const forceinline Code::operator CodeExec() const
{ {
return { (AST_Exec*)ast }; return { (AST_Exec*)ast };
} }
inline Code::operator CodeExtern() const forceinline Code::operator CodeExtern() const
{ {
return { (AST_Extern*)ast }; return { (AST_Extern*)ast };
} }
inline Code::operator CodeFriend() const forceinline Code::operator CodeFriend() const
{ {
return { (AST_Friend*)ast }; return { (AST_Friend*)ast };
} }
inline Code::operator CodeFn() const forceinline Code::operator CodeFn() const
{ {
return { (AST_Fn*)ast }; return { (AST_Fn*)ast };
} }
inline Code::operator CodeInclude() const forceinline Code::operator CodeInclude() const
{ {
return { (AST_Include*)ast }; return { (AST_Include*)ast };
} }
inline Code::operator CodeModule() const forceinline Code::operator CodeModule() const
{ {
return { (AST_Module*)ast }; return { (AST_Module*)ast };
} }
inline Code::operator CodeNS() const forceinline Code::operator CodeNS() const
{ {
return { (AST_NS*)ast }; return { (AST_NS*)ast };
} }
inline Code::operator CodeOperator() const forceinline Code::operator CodeOperator() const
{ {
return { (AST_Operator*)ast }; return { (AST_Operator*)ast };
} }
inline Code::operator CodeOpCast() const forceinline Code::operator CodeOpCast() const
{ {
return { (AST_OpCast*)ast }; return { (AST_OpCast*)ast };
} }
inline Code::operator CodeParam() const forceinline Code::operator CodeParam() const
{ {
return { (AST_Param*)ast }; return { (AST_Param*)ast };
} }
inline Code::operator CodePragma() const forceinline Code::operator CodePragma() const
{ {
return { (AST_Pragma*)ast }; return { (AST_Pragma*)ast };
} }
inline Code::operator CodePreprocessCond() const forceinline Code::operator CodePreprocessCond() const
{ {
return { (AST_PreprocessCond*)ast }; return { (AST_PreprocessCond*)ast };
} }
inline Code::operator CodeSpecifiers() const forceinline Code::operator CodeSpecifiers() const
{ {
return { (AST_Specifiers*)ast }; return { (AST_Specifiers*)ast };
} }
inline Code::operator CodeStruct() const forceinline Code::operator CodeStruct() const
{ {
return { (AST_Struct*)ast }; return { (AST_Struct*)ast };
} }
inline Code::operator CodeTemplate() const forceinline Code::operator CodeTemplate() const
{ {
return { (AST_Template*)ast }; return { (AST_Template*)ast };
} }
inline Code::operator CodeTypename() const forceinline Code::operator CodeTypename() const
{ {
return { (AST_Typename*)ast }; return { (AST_Typename*)ast };
} }
inline Code::operator CodeTypedef() const forceinline Code::operator CodeTypedef() const
{ {
return { (AST_Typedef*)ast }; return { (AST_Typedef*)ast };
} }
inline Code::operator CodeUnion() const forceinline Code::operator CodeUnion() const
{ {
return { (AST_Union*)ast }; return { (AST_Union*)ast };
} }
inline Code::operator CodeUsing() const forceinline Code::operator CodeUsing() const
{ {
return { (AST_Using*)ast }; return { (AST_Using*)ast };
} }
inline Code::operator CodeVar() const forceinline Code::operator CodeVar() const
{ {
return { (AST_Var*)ast }; return { (AST_Var*)ast };
} }
GEN_OPITMIZE_MAPPINGS_END
#pragma endregion generated AST / Code cast implementation #pragma endregion generated AST / Code cast implementation

View File

@ -1,74 +1,75 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES #ifdef GEN_INTELLISENSE_DIRECTIVES
#pragma once #include "components/types.hpp" #pragma once
#include "components/types.hpp"
#endif #endif
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
enum CodeType_Def enum_underlying( u32 ) enum CodeType : u32
{
{ CT_Invalid, CT_Invalid,
CT_Untyped, CT_Untyped,
CT_NewLine, CT_NewLine,
CT_Comment, CT_Comment,
CT_Access_Private, CT_Access_Private,
CT_Access_Protected, CT_Access_Protected,
CT_Access_Public, CT_Access_Public,
CT_PlatformAttributes, CT_PlatformAttributes,
CT_Class, CT_Class,
CT_Class_Fwd, CT_Class_Fwd,
CT_Class_Body, CT_Class_Body,
CT_Constructor, CT_Constructor,
CT_Constructor_Fwd, CT_Constructor_Fwd,
CT_Destructor, CT_Destructor,
CT_Destructor_Fwd, CT_Destructor_Fwd,
CT_Enum, CT_Enum,
CT_Enum_Fwd, CT_Enum_Fwd,
CT_Enum_Body, CT_Enum_Body,
CT_Enum_Class, CT_Enum_Class,
CT_Enum_Class_Fwd, CT_Enum_Class_Fwd,
CT_Execution, CT_Execution,
CT_Export_Body, CT_Export_Body,
CT_Extern_Linkage, CT_Extern_Linkage,
CT_Extern_Linkage_Body, CT_Extern_Linkage_Body,
CT_Friend, CT_Friend,
CT_Function, CT_Function,
CT_Function_Fwd, CT_Function_Fwd,
CT_Function_Body, CT_Function_Body,
CT_Global_Body, CT_Global_Body,
CT_Module, CT_Module,
CT_Namespace, CT_Namespace,
CT_Namespace_Body, CT_Namespace_Body,
CT_Operator, CT_Operator,
CT_Operator_Fwd, CT_Operator_Fwd,
CT_Operator_Member, CT_Operator_Member,
CT_Operator_Member_Fwd, CT_Operator_Member_Fwd,
CT_Operator_Cast, CT_Operator_Cast,
CT_Operator_Cast_Fwd, CT_Operator_Cast_Fwd,
CT_Parameters, CT_Parameters,
CT_Preprocess_Define, CT_Preprocess_Define,
CT_Preprocess_Include, CT_Preprocess_Include,
CT_Preprocess_If, CT_Preprocess_If,
CT_Preprocess_IfDef, CT_Preprocess_IfDef,
CT_Preprocess_IfNotDef, CT_Preprocess_IfNotDef,
CT_Preprocess_ElIf, CT_Preprocess_ElIf,
CT_Preprocess_Else, CT_Preprocess_Else,
CT_Preprocess_EndIf, CT_Preprocess_EndIf,
CT_Preprocess_Pragma, CT_Preprocess_Pragma,
CT_Specifiers, CT_Specifiers,
CT_Struct, CT_Struct,
CT_Struct_Fwd, CT_Struct_Fwd,
CT_Struct_Body, CT_Struct_Body,
CT_Template, CT_Template,
CT_Typedef, CT_Typedef,
CT_Typename, CT_Typename,
CT_Union, CT_Union,
CT_Union_Fwd, CT_Union_Fwd,
CT_Union_Body, CT_Union_Body,
CT_Using, CT_Using,
CT_Using_Namespace, CT_Using_Namespace,
CT_Variable, CT_Variable,
CT_NumTypes }; CT_NumTypes
typedef enum CodeType_Def CodeType; };
inline StrC codetype_to_str( CodeType type ) inline StrC codetype_to_str( CodeType type )
{ {
@ -137,3 +138,81 @@ inline StrC codetype_to_str( CodeType type )
}; };
return lookup[type]; return lookup[type];
} }
inline StrC codetype_to_keyword_str( CodeType type )
{
local_persist StrC lookup[61] = {
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "//" ) - 1, "//" },
{ sizeof( "private" ) - 1, "private" },
{ sizeof( "protected" ) - 1, "protected" },
{ sizeof( "public" ) - 1, "public" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "class" ) - 1, "class" },
{ sizeof( "clsss" ) - 1, "clsss" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "enum" ) - 1, "enum" },
{ sizeof( "enum" ) - 1, "enum" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "enum class" ) - 1, "enum class" },
{ sizeof( "enum class" ) - 1, "enum class" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "extern" ) - 1, "extern" },
{ sizeof( "extern" ) - 1, "extern" },
{ sizeof( "friend" ) - 1, "friend" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "module" ) - 1, "module" },
{ sizeof( "namespace" ) - 1, "namespace" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "operator" ) - 1, "operator" },
{ sizeof( "operator" ) - 1, "operator" },
{ sizeof( "operator" ) - 1, "operator" },
{ sizeof( "operator" ) - 1, "operator" },
{ sizeof( "operator" ) - 1, "operator" },
{ sizeof( "operator" ) - 1, "operator" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "define" ) - 1, "define" },
{ sizeof( "include" ) - 1, "include" },
{ sizeof( "if" ) - 1, "if" },
{ sizeof( "ifdef" ) - 1, "ifdef" },
{ sizeof( "ifndef" ) - 1, "ifndef" },
{ sizeof( "elif" ) - 1, "elif" },
{ sizeof( "else" ) - 1, "else" },
{ sizeof( "endif" ) - 1, "endif" },
{ sizeof( "pragma" ) - 1, "pragma" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "struct" ) - 1, "struct" },
{ sizeof( "struct" ) - 1, "struct" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "template" ) - 1, "template" },
{ sizeof( "typedef" ) - 1, "typedef" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "union" ) - 1, "union" },
{ sizeof( "union" ) - 1, "union" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
{ sizeof( "using" ) - 1, "using" },
{ sizeof( "using namespace" ) - 1, "using namespace" },
{ sizeof( "__NA__" ) - 1, "__NA__" },
};
return lookup[type];
}
forceinline StrC to_str( CodeType type )
{
return codetype_to_str( type );
}
forceinline StrC to_keyword_str( CodeType type )
{
return codetype_to_keyword_str( type );
}

View File

@ -1,60 +1,61 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES #ifdef GEN_INTELLISENSE_DIRECTIVES
#pragma once #include "components/types.hpp" #pragma once
#include "components/types.hpp"
#endif #endif
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
enum Operator_Def enum_underlying( u32 ) enum Operator : u32
{
{ Op_Invalid, Op_Invalid,
Op_Assign, Op_Assign,
Op_Assign_Add, Op_Assign_Add,
Op_Assign_Subtract, Op_Assign_Subtract,
Op_Assign_Multiply, Op_Assign_Multiply,
Op_Assign_Divide, Op_Assign_Divide,
Op_Assign_Modulo, Op_Assign_Modulo,
Op_Assign_BAnd, Op_Assign_BAnd,
Op_Assign_BOr, Op_Assign_BOr,
Op_Assign_BXOr, Op_Assign_BXOr,
Op_Assign_LShift, Op_Assign_LShift,
Op_Assign_RShift, Op_Assign_RShift,
Op_Increment, Op_Increment,
Op_Decrement, Op_Decrement,
Op_Unary_Plus, Op_Unary_Plus,
Op_Unary_Minus, Op_Unary_Minus,
Op_UnaryNot, Op_UnaryNot,
Op_Add, Op_Add,
Op_Subtract, Op_Subtract,
Op_Multiply, Op_Multiply,
Op_Divide, Op_Divide,
Op_Modulo, Op_Modulo,
Op_BNot, Op_BNot,
Op_BAnd, Op_BAnd,
Op_BOr, Op_BOr,
Op_BXOr, Op_BXOr,
Op_LShift, Op_LShift,
Op_RShift, Op_RShift,
Op_LAnd, Op_LAnd,
Op_LOr, Op_LOr,
Op_LEqual, Op_LEqual,
Op_LNot, Op_LNot,
Op_Lesser, Op_Lesser,
Op_Greater, Op_Greater,
Op_LesserEqual, Op_LesserEqual,
Op_GreaterEqual, Op_GreaterEqual,
Op_Subscript, Op_Subscript,
Op_Indirection, Op_Indirection,
Op_AddressOf, Op_AddressOf,
Op_MemberOfPointer, Op_MemberOfPointer,
Op_PtrToMemOfPtr, Op_PtrToMemOfPtr,
Op_FunctionCall, Op_FunctionCall,
Op_Comma, Op_Comma,
Op_New, Op_New,
Op_NewArray, Op_NewArray,
Op_Delete, Op_Delete,
Op_DeleteArray, Op_DeleteArray,
NumOps }; NumOps
typedef enum Operator_Def Operator; };
inline StrC operator_to_str( Operator op ) inline StrC operator_to_str( Operator op )
{ {
@ -109,3 +110,8 @@ inline StrC operator_to_str( Operator op )
}; };
return lookup[op]; return lookup[op];
} }
forceinline StrC to_str( Operator op )
{
return operator_to_str( op );
}

View File

@ -1,21 +1,40 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES #ifdef GEN_INTELLISENSE_DIRECTIVES
#pragma once #include "components/types.hpp" #pragma once
#include "components/types.hpp"
#endif #endif
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
enum Specifier_Def enum_underlying( u32 ) enum Specifier : u32
{ Spec_Invalid, Spec_Consteval, Spec_Constexpr, Spec_Constinit, Spec_Explicit, Spec_External_Linkage, Spec_ForceInline,
Spec_Global, Spec_Inline, Spec_Internal_Linkage, Spec_Local_Persist, Spec_Mutable, Spec_NeverInline, Spec_Ptr,
Spec_Ref, Spec_Register, Spec_RValue, Spec_Static, Spec_Thread_Local, Spec_Virtual, Spec_Const,
Spec_Final, Spec_NoExceptions, Spec_Override, Spec_Pure, Spec_Volatile, Spec_NumSpecifiers };
typedef enum Specifier_Def Specifier;
inline bool spec_is_trailing( Specifier specifier )
{ {
return specifier > Spec_Virtual; Spec_Invalid,
} Spec_Consteval,
Spec_Constexpr,
Spec_Constinit,
Spec_Explicit,
Spec_External_Linkage,
Spec_ForceInline,
Spec_Global,
Spec_Inline,
Spec_Internal_Linkage,
Spec_Local_Persist,
Spec_Mutable,
Spec_NeverInline,
Spec_Ptr,
Spec_Ref,
Spec_Register,
Spec_RValue,
Spec_Static,
Spec_Thread_Local,
Spec_Virtual,
Spec_Const,
Spec_Final,
Spec_NoExceptions,
Spec_Override,
Spec_Pure,
Spec_Volatile,
Spec_NumSpecifiers
};
inline StrC spec_to_str( Specifier type ) inline StrC spec_to_str( Specifier type )
{ {
@ -50,6 +69,11 @@ inline StrC spec_to_str( Specifier type )
return lookup[type]; return lookup[type];
} }
inline bool spec_is_trailing( Specifier specifier )
{
return specifier > Spec_Virtual;
}
inline Specifier strc_to_specifier( StrC str ) inline Specifier strc_to_specifier( StrC str )
{ {
local_persist u32 keymap[Spec_NumSpecifiers]; local_persist u32 keymap[Spec_NumSpecifiers];
@ -66,3 +90,18 @@ inline Specifier strc_to_specifier( StrC str )
} }
return Spec_Invalid; return Spec_Invalid;
} }
forceinline StrC to_str( Specifier spec )
{
return spec_to_str( spec );
}
forceinline Specifier to_type( StrC str )
{
return strc_to_specifier( str );
}
forceinline bool is_trailing( Specifier specifier )
{
return spec_is_trailing( specifier );
}

View File

@ -1,5 +1,6 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES #ifdef GEN_INTELLISENSE_DIRECTIVES
#pragma once #include "components/types.hpp" #pragma once
#include "components/types.hpp"
#endif #endif
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)

View File

@ -25,7 +25,7 @@
# define GEN_MAX_UNTYPED_STR_LENGTH megabytes(1) # define GEN_MAX_UNTYPED_STR_LENGTH megabytes(1)
#endif #endif
#ifndef GEN_TOKEN_FMT_TOKEN_MAP_MEM_SIZE #ifndef GEN_TOKEN_FMT_TOKEN_MAP_MEM_SIZE
# define GEN_TOKEN_FMT_TOKEN_MAP_MEM_SIZE kilobytes(4) # define GEN_TOKEN_FMT_TOKEN_MAP_MEM_SIZE kilobytes(8)
#endif #endif
#ifndef GEN_LEX_ALLOCATOR_SIZE #ifndef GEN_LEX_ALLOCATOR_SIZE
# define GEN_LEX_ALLOCATOR_SIZE megabytes(4) # define GEN_LEX_ALLOCATOR_SIZE megabytes(4)
@ -42,7 +42,7 @@ constexpr s32 InitSize_DataArrays = 16;
// NOTE: This limits the maximum size of an allocation // NOTE: This limits the maximum size of an allocation
// If you are generating a string larger than this, increase the size of the bucket here. // If you are generating a string larger than this, increase the size of the bucket here.
constexpr usize Global_BucketSize = GEN_GLOBAL_BUCKET_SIZE; constexpr usize Global_BucketSize = GEN_GLOBAL_BUCKET_SIZE;
constexpr s32 CodePool_NumBlocks = GEN_CODEPOOL_NUM_BLOCKS; constexpr s32 CodePool_NumBlocks = GEN_CODEPOOL_NUM_BLOCKS;
constexpr s32 SizePer_StringArena = GEN_SIZE_PER_STRING_ARENA; constexpr s32 SizePer_StringArena = GEN_SIZE_PER_STRING_ARENA;
@ -131,38 +131,12 @@ extern CodeTypename t_typename;
#pragma endregion Constants #pragma endregion Constants
#pragma region Macros
#ifndef token_fmt
# define gen_main main
# define __ NullCode
// Convienence for defining any name used with the gen api.
// Lets you provide the length and string literal to the functions without the need for the DSL.
# define name( Id_ ) { sizeof(stringize( Id_ )) - 1, stringize(Id_) }
// Same as name just used to indicate intention of literal for code instead of names.
# define code( ... ) { sizeof(stringize(__VA_ARGS__)) - 1, stringize( __VA_ARGS__ ) }
# define args( ... ) num_args( __VA_ARGS__ ), __VA_ARGS__
# define code_str( ... ) GEN_NS untyped_str( code( __VA_ARGS__ ) )
# define code_fmt( ... ) GEN_NS untyped_str( token_fmt( __VA_ARGS__ ) )
// Takes a format string (char const*) and a list of tokens (StrC) and returns a StrC of the formatted string.
# define token_fmt( ... ) GEN_NS token_fmt_impl( (num_args( __VA_ARGS__ ) + 1) / 2, __VA_ARGS__ )
#endif
#pragma endregion Macros
// Used by the lexer to persistently treat all these identifiers as preprocessor defines. // Used by the lexer to persistently treat all these identifiers as preprocessor defines.
// Populate with strings via gen::get_cached_string. // Populate with strings via gen::get_cached_string.
// Functional defines must have format: id( ;at minimum to indicate that the define is only valid with arguments. // Functional defines must have format: id( ;at minimum to indicate that the define is only valid with arguments.
extern Array(StringCached) PreprocessorDefines; extern Array(StringCached) PreprocessorDefines;
#ifdef GEN_EXPOSE_BACKEND #ifdef GEN_EXPOSE_BACKEND
// Global allocator used for data with process lifetime. // Global allocator used for data with process lifetime.
extern AllocatorInfo GlobalAllocator; extern AllocatorInfo GlobalAllocator;
extern Array(Arena) Global_AllocatorBuckets; extern Array(Arena) Global_AllocatorBuckets;
@ -180,5 +154,4 @@ extern Array(StringCached) PreprocessorDefines;
extern AllocatorInfo Allocator_StringArena; extern AllocatorInfo Allocator_StringArena;
extern AllocatorInfo Allocator_StringTable; extern AllocatorInfo Allocator_StringTable;
extern AllocatorInfo Allocator_TypeTable; extern AllocatorInfo Allocator_TypeTable;
#endif #endif

View File

@ -7,10 +7,11 @@
inline inline
void code_append( Code self, Code other ) void code_append( Code self, Code other )
{ {
GEN_ASSERT(self.ast != nullptr); GEN_ASSERT(self);
GEN_ASSERT(other.ast != nullptr); GEN_ASSERT(other);
GEN_ASSERT_MSG(self != other, "Attempted to recursively append Code AST to itself.");
if ( other->Parent ) if ( other->Parent != nullptr )
other = code_duplicate(other); other = code_duplicate(other);
other->Parent = self; other->Parent = self;
@ -34,7 +35,7 @@ void code_append( Code self, Code other )
inline inline
bool code_is_body(Code self) bool code_is_body(Code self)
{ {
GEN_ASSERT(self != nullptr); GEN_ASSERT(self);
switch (self->Type) switch (self->Type)
{ {
case CT_Enum_Body: case CT_Enum_Body:
@ -53,7 +54,7 @@ bool code_is_body(Code self)
inline inline
Code* code_entry( Code self, u32 idx ) Code* code_entry( Code self, u32 idx )
{ {
GEN_ASSERT(self.ast != nullptr); GEN_ASSERT(self != nullptr);
Code* current = & self->Front; Code* current = & self->Front;
while ( idx >= 0 && current != nullptr ) while ( idx >= 0 && current != nullptr )
{ {
@ -66,29 +67,31 @@ Code* code_entry( Code self, u32 idx )
return rcast( Code*, current); return rcast( Code*, current);
} }
inline forceinline
bool code_is_valid(Code self) bool code_is_valid(Code self)
{ {
return self.ast != nullptr && self.ast->Type != CT_Invalid; GEN_ASSERT(self);
return self != nullptr && self->Type != CT_Invalid;
} }
inline forceinline
bool code_has_entries(AST* self) bool code_has_entries(AST* self)
{ {
GEN_ASSERT(self != nullptr); GEN_ASSERT(self);
return self->NumEntries > 0; return self->NumEntries > 0;
} }
inline forceinline
void code_set_global(Code self) void code_set_global(Code self)
{ {
if ( self.ast == nullptr ) if ( self == nullptr )
{ {
log_failure("Code::set_global: Cannot set code as global, AST is null!"); log_failure("Code::set_global: Cannot set code as global, AST is null!");
return; return;
} }
self->Parent.ast = Code_Global.ast; self->Parent = Code_Global;
} }
inline #if GEN_COMPILER_CPP
forceinline
Code& Code::operator ++() Code& Code::operator ++()
{ {
if ( ast ) if ( ast )
@ -96,7 +99,8 @@ Code& Code::operator ++()
return * this; return * this;
} }
inline #endif
forceinline
char const* code_type_str(Code self) char const* code_type_str(Code self)
{ {
GEN_ASSERT(self != nullptr); GEN_ASSERT(self != nullptr);
@ -106,49 +110,57 @@ char const* code_type_str(Code self)
#pragma region CodeBody #pragma region CodeBody
inline inline
void append( CodeBody self, Code other ) void body_append( CodeBody self, Code other )
{ {
GEN_ASSERT(other.ast != nullptr); GEN_ASSERT(self);
GEN_ASSERT(other);
if (code_is_body(other)) { if (code_is_body(other)) {
append( self, cast(CodeBody, other) ); body_append_body( self, cast(CodeBody, other) );
return; return;
} }
code_append( cast(Code, self), other ); code_append( cast(Code, self), other );
} }
inline inline
void append( CodeBody self, CodeBody body ) void body_append_body( CodeBody self, CodeBody body )
{ {
GEN_ASSERT(self.ast != nullptr); GEN_ASSERT(self);
GEN_ASSERT(body);
GEN_ASSERT_MSG(self != body, "Attempted to append body to itself.");
for ( Code entry : body ) { for ( Code entry = begin_CodeBody(body); entry != end_CodeBody(body); entry = next_CodeBody(body, entry) ) {
append( self, entry ); body_append( self, entry );
} }
} }
inline inline
Code begin( CodeBody body) { Code begin_CodeBody( CodeBody body) {
if ( body.ast ) GEN_ASSERT(body);
return { rcast( AST*, body.ast)->Front }; if ( body != nullptr )
return body->Front;
return { nullptr }; return { nullptr };
} }
inline forceinline
Code end(CodeBody body ){ Code end_CodeBody(CodeBody body ){
return { rcast(AST*, body.ast)->Back->Next }; GEN_ASSERT(body);
return body->Back->Next;
} }
inline inline
Code next(CodeBody body, Code entry) { Code next_CodeBody(CodeBody body, Code entry) {
GEN_ASSERT(body);
GEN_ASSERT(entry);
return entry->Next; return entry->Next;
} }
#pragma endregion CodeBody #pragma endregion CodeBody
#pragma region CodeClass #pragma region CodeClass
inline inline
void add_interface( CodeClass self, CodeTypename type ) void class_add_interface( CodeClass self, CodeTypename type )
{ {
GEN_ASSERT(self.ast !=nullptr); GEN_ASSERT(self);
GEN_ASSERT(type);
CodeTypename possible_slot = self->ParentType; CodeTypename possible_slot = self->ParentType;
if ( possible_slot.ast ) if ( possible_slot != nullptr )
{ {
// Were adding an interface to parent type, so we need to make sure the parent type is public. // Were adding an interface to parent type, so we need to make sure the parent type is public.
self->ParentAccess = AccessSpec_Public; self->ParentAccess = AccessSpec_Public;
@ -156,24 +168,26 @@ void add_interface( CodeClass self, CodeTypename type )
// then you'll need to move this over to ParentType->next and update ParentAccess accordingly. // then you'll need to move this over to ParentType->next and update ParentAccess accordingly.
} }
while ( possible_slot.ast != nullptr ) while ( possible_slot != nullptr )
{ {
possible_slot.ast = (AST_Typename*) possible_slot->Next.ast; possible_slot = possible_slot->Next;
} }
possible_slot.ast = type.ast; possible_slot = type;
} }
#pragma endregion CodeClass #pragma endregion CodeClass
#pragma region CodeParam #pragma region CodeParam
inline inline
void append( CodeParam appendee, CodeParam other ) void params_append( CodeParam appendee, CodeParam other )
{ {
GEN_ASSERT(appendee.ast != nullptr); GEN_ASSERT(appendee);
GEN_ASSERT(other);
GEN_ASSERT_MSG(appendee != other, "Attempted to append parameter to itself.");
Code self = cast(Code, appendee); Code self = cast(Code, appendee);
Code entry = cast(Code, other); Code entry = cast(Code, other);
if ( entry->Parent ) if ( entry->Parent != nullptr )
entry = code_duplicate( entry ); entry = code_duplicate( entry );
entry->Parent = self; entry->Parent = self;
@ -191,54 +205,62 @@ void append( CodeParam appendee, CodeParam other )
self->NumEntries++; self->NumEntries++;
} }
inline inline
CodeParam get(CodeParam self, s32 idx ) CodeParam params_get(CodeParam self, s32 idx )
{ {
GEN_ASSERT(self.ast != nullptr); GEN_ASSERT(self);
CodeParam param = * self; CodeParam param = self;
do do
{ {
if ( ! ++ param ) if ( ++ param != nullptr )
return { nullptr }; return { nullptr };
param = cast(Code, param)->Next; param = cast(CodeParam, cast(Code, param)->Next);
} }
while ( --idx ); while ( --idx );
return param; return param;
} }
inline forceinline
bool has_entries(CodeParam self) bool params_has_entries(CodeParam self)
{ {
GEN_ASSERT(self.ast != nullptr); GEN_ASSERT(self);
return self->NumEntries > 0; return self->NumEntries > 0;
} }
inline #if GEN_COMPILER_CPP
forceinline
CodeParam& CodeParam::operator ++() CodeParam& CodeParam::operator ++()
{ {
ast = ast->Next.ast; * this = ast->Next;
return * this; return * this;
} }
inline #endif
CodeParam begin(CodeParam params) forceinline
CodeParam begin_CodeParam(CodeParam params)
{ {
if ( params.ast ) if ( params != nullptr )
return { params.ast }; return params;
return { nullptr }; return NullCode;
} }
inline forceinline
CodeParam end(CodeParam params) CodeParam end_CodeParam(CodeParam params)
{ {
// return { (AST_Param*) rcast( AST*, ast)->Last }; // return { (AST_Param*) rcast( AST*, ast)->Last };
return { nullptr }; return { nullptr };
} }
forceinline
CodeParam next_CodeParam(CodeParam params, CodeParam param_iter)
{
GEN_ASSERT(param_iter);
return param_iter->Next;
}
#pragma endregion CodeParam #pragma endregion CodeParam
#pragma region CodeSpecifiers #pragma region CodeSpecifiers
inline inline
bool append(CodeSpecifiers self, Specifier spec ) bool specifiers_append(CodeSpecifiers self, Specifier spec )
{ {
if ( self.ast == nullptr ) if ( self == nullptr )
{ {
log_failure("CodeSpecifiers: Attempted to append to a null specifiers AST!"); log_failure("CodeSpecifiers: Attempted to append to a null specifiers AST!");
return false; return false;
@ -254,9 +276,9 @@ bool append(CodeSpecifiers self, Specifier spec )
return true; return true;
} }
inline inline
s32 has(CodeSpecifiers self, Specifier spec) s32 specifiers_has(CodeSpecifiers self, Specifier spec)
{ {
GEN_ASSERT(self.ast != nullptr); GEN_ASSERT(self != nullptr);
for ( s32 idx = 0; idx < self->NumEntries; idx++ ) { for ( s32 idx = 0; idx < self->NumEntries; idx++ ) {
if ( self->ArrSpecs[ idx ] == spec ) if ( self->ArrSpecs[ idx ] == spec )
return idx; return idx;
@ -264,10 +286,9 @@ s32 has(CodeSpecifiers self, Specifier spec)
return -1; return -1;
} }
inline inline
s32 remove( CodeSpecifiers self, Specifier to_remove ) s32 specifiers_remove( CodeSpecifiers self, Specifier to_remove )
{ {
AST_Specifiers* ast = self.ast; if ( self == nullptr )
if ( ast == nullptr )
{ {
log_failure("CodeSpecifiers: Attempted to append to a null specifiers AST!"); log_failure("CodeSpecifiers: Attempted to append to a null specifiers AST!");
return -1; return -1;
@ -304,19 +325,24 @@ s32 remove( CodeSpecifiers self, Specifier to_remove )
} }
return result; return result;
} }
inline forceinline
Specifier* begin(CodeSpecifiers self) Specifier* begin_CodeSpecifiers(CodeSpecifiers self)
{ {
if ( self.ast ) if ( self != nullptr )
return & self->ArrSpecs[0]; return & self->ArrSpecs[0];
return nullptr; return nullptr;
} }
inline forceinline
Specifier* end(CodeSpecifiers self) Specifier* end_CodeSpecifiers(CodeSpecifiers self)
{ {
return self->ArrSpecs + self->NumEntries; return self->ArrSpecs + self->NumEntries;
} }
forceinline
Specifier* next_CodeSpecifiers(CodeSpecifiers self, Specifier* spec_iter)
{
return spec_iter + 1;
}
#pragma endregion CodeSpecifiers #pragma endregion CodeSpecifiers
#pragma region CodeStruct #pragma region CodeStruct
@ -324,7 +350,7 @@ inline
void add_interface(CodeStruct self, CodeTypename type ) void add_interface(CodeStruct self, CodeTypename type )
{ {
CodeTypename possible_slot = self->ParentType; CodeTypename possible_slot = self->ParentType;
if ( possible_slot.ast ) if ( possible_slot != nullptr )
{ {
// Were adding an interface to parent type, so we need to make sure the parent type is public. // Were adding an interface to parent type, so we need to make sure the parent type is public.
self->ParentAccess = AccessSpec_Public; self->ParentAccess = AccessSpec_Public;
@ -332,12 +358,12 @@ void add_interface(CodeStruct self, CodeTypename type )
// then you'll need to move this over to ParentType->next and update ParentAccess accordingly. // then you'll need to move this over to ParentType->next and update ParentAccess accordingly.
} }
while ( possible_slot.ast != nullptr ) while ( possible_slot != nullptr )
{ {
possible_slot.ast = (AST_Typename*) possible_slot->Next.ast; possible_slot = possible_slot->Next;
} }
possible_slot.ast = type.ast; possible_slot = type;
} }
#pragma endregion Code #pragma endregion Code

View File

@ -3,10 +3,10 @@
#include "code_serialization.cpp" #include "code_serialization.cpp"
#endif #endif
namespace parser { GEN_NS_PARSER_BEGIN
internal void init(); internal void init();
internal void deinit(); internal void deinit();
} GEN_NS_PARSER_END
internal internal
void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ) void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
@ -84,12 +84,12 @@ void define_constants()
t_empty = (CodeTypename) make_code(); t_empty = (CodeTypename) make_code();
t_empty->Type = CT_Typename; t_empty->Type = CT_Typename;
t_empty->Name = get_cached_string( txt("") ); t_empty->Name = get_cached_string( txt("") );
code_set_global(t_empty); code_set_global(cast(Code, t_empty));
access_private = make_code(); access_private = make_code();
access_private->Type = CT_Access_Private; access_private->Type = CT_Access_Private;
access_private->Name = get_cached_string( txt("private:\n") ); access_private->Name = get_cached_string( txt("private:\n") );
code_set_global(access_private); code_set_global(cast(Code, access_private));
access_protected = make_code(); access_protected = make_code();
access_protected->Type = CT_Access_Protected; access_protected->Type = CT_Access_Protected;
@ -102,50 +102,50 @@ void define_constants()
code_set_global(access_public); code_set_global(access_public);
attrib_api_export = def_attributes( code(GEN_API_Export_Code)); attrib_api_export = def_attributes( code(GEN_API_Export_Code));
code_set_global(attrib_api_export); code_set_global(cast(Code, attrib_api_export));
attrib_api_import = def_attributes( code(GEN_API_Import_Code)); attrib_api_import = def_attributes( code(GEN_API_Import_Code));
code_set_global(attrib_api_import); code_set_global(cast(Code, attrib_api_import));
module_global_fragment = make_code(); module_global_fragment = make_code();
module_global_fragment->Type = CT_Untyped; module_global_fragment->Type = CT_Untyped;
module_global_fragment->Name = get_cached_string( txt("module;") ); module_global_fragment->Name = get_cached_string( txt("module;") );
module_global_fragment->Content = module_global_fragment->Name; module_global_fragment->Content = module_global_fragment->Name;
code_set_global(module_global_fragment); code_set_global(cast(Code, module_global_fragment));
module_private_fragment = make_code(); module_private_fragment = make_code();
module_private_fragment->Type = CT_Untyped; module_private_fragment->Type = CT_Untyped;
module_private_fragment->Name = get_cached_string( txt("module : private;") ); module_private_fragment->Name = get_cached_string( txt("module : private;") );
module_private_fragment->Content = module_private_fragment->Name; module_private_fragment->Content = module_private_fragment->Name;
code_set_global(module_private_fragment); code_set_global(cast(Code, module_private_fragment));
fmt_newline = make_code(); fmt_newline = make_code();
fmt_newline->Type = CT_NewLine; fmt_newline->Type = CT_NewLine;
code_set_global(fmt_newline); code_set_global((Code)fmt_newline);
pragma_once = (CodePragma) make_code(); pragma_once = (CodePragma) make_code();
pragma_once->Type = CT_Preprocess_Pragma; pragma_once->Type = CT_Preprocess_Pragma;
pragma_once->Name = get_cached_string( txt("once") ); pragma_once->Name = get_cached_string( txt("once") );
pragma_once->Content = pragma_once->Name; pragma_once->Content = pragma_once->Name;
code_set_global(pragma_once); code_set_global((Code)pragma_once);
param_varadic = (CodeTypename) make_code(); param_varadic = (CodeParam) make_code();
param_varadic->Type = CT_Parameters; param_varadic->Type = CT_Parameters;
param_varadic->Name = get_cached_string( txt("...") ); param_varadic->Name = get_cached_string( txt("...") );
param_varadic->ValueType = t_empty; param_varadic->ValueType = t_empty;
code_set_global(param_varadic); code_set_global((Code)param_varadic);
preprocess_else = (CodePreprocessCond) make_code(); preprocess_else = (CodePreprocessCond) make_code();
preprocess_else->Type = CT_Preprocess_Else; preprocess_else->Type = CT_Preprocess_Else;
code_set_global(preprocess_else); code_set_global((Code)preprocess_else);
preprocess_endif = (CodePreprocessCond) make_code(); preprocess_endif = (CodePreprocessCond) make_code();
preprocess_endif->Type = CT_Preprocess_EndIf; preprocess_endif->Type = CT_Preprocess_EndIf;
code_set_global(preprocess_endif); code_set_global((Code)preprocess_endif);
# define def_constant_code_type( Type_ ) \ # define def_constant_code_type( Type_ ) \
t_##Type_ = def_type( name(Type_) ); \ t_##Type_ = def_type( name(Type_) ); \
code_set_global(t_##Type_); code_set_global( cast(Code, t_##Type_));
def_constant_code_type( auto ); def_constant_code_type( auto );
def_constant_code_type( void ); def_constant_code_type( void );
@ -180,7 +180,7 @@ void define_constants()
# define def_constant_spec( Type_, ... ) \ # define def_constant_spec( Type_, ... ) \
spec_##Type_ = def_specifiers( num_args(__VA_ARGS__), __VA_ARGS__); \ spec_##Type_ = def_specifiers( num_args(__VA_ARGS__), __VA_ARGS__); \
code_set_global(spec_##Type_); code_set_global( cast(Code, spec_##Type_));
# pragma push_macro("forceinline") # pragma push_macro("forceinline")
# pragma push_macro("global") # pragma push_macro("global")
@ -218,7 +218,7 @@ void define_constants()
def_constant_spec( volatile, Spec_Volatile) def_constant_spec( volatile, Spec_Volatile)
spec_local_persist = def_specifiers( 1, Spec_Local_Persist ); spec_local_persist = def_specifiers( 1, Spec_Local_Persist );
code_set_global(spec_local_persist); code_set_global(cast(Code, spec_local_persist));
# pragma pop_macro("forceinline") # pragma pop_macro("forceinline")
# pragma pop_macro("global") # pragma pop_macro("global")
@ -426,7 +426,7 @@ Code make_code()
} }
Code result { rcast( AST*, alloc( pool_allocator_info(allocator), sizeof(AST) )) }; Code result { rcast( AST*, alloc( pool_allocator_info(allocator), sizeof(AST) )) };
mem_set( result.ast, 0, sizeof(AST) ); mem_set( rcast(void*, cast(AST*, result)), 0, sizeof(AST) );
// result->Type = ECode::Invalid; // result->Type = ECode::Invalid;
// result->Content = { nullptr }; // result->Content = { nullptr };

View File

@ -161,7 +161,7 @@ struct Opts_def_variable
CodeAttributes attributes; CodeAttributes attributes;
ModuleFlag mflags; ModuleFlag mflags;
}; };
CodeVar def_variable( CodeTypename type, StrC name, Opts_def_variable opts GEN_PARAM_DEFAULT ); CodeVar def_variable( CodeTypename type, StrC name, Opts_def_variable opts GEN_PARAM_DEFAULT );
// Constructs an empty body. Use AST::validate_body() to check if the body is was has valid entries. // Constructs an empty body. Use AST::validate_body() to check if the body is was has valid entries.
CodeBody def_body( CodeTypename type ); CodeBody def_body( CodeTypename type );
@ -266,4 +266,55 @@ Code untyped_token_fmt( char const* fmt, s32 num_tokens, ... );
#pragma endregion Untyped text #pragma endregion Untyped text
#pragma region Macros
#ifndef token_fmt
# define gen_main main
# define __ NullCode
// Convienence for defining any name used with the gen api.
// Lets you provide the length and string literal to the functions without the need for the DSL.
# define name( Id_ ) { sizeof(stringize( Id_ )) - 1, stringize(Id_) }
// Same as name just used to indicate intention of literal for code instead of names.
# define code( ... ) { sizeof(stringize(__VA_ARGS__)) - 1, stringize( __VA_ARGS__ ) }
// Provides the number of arguments while passing args inplace.
# define args( ... ) num_args( __VA_ARGS__ ), __VA_ARGS__
// Just wrappers over common untyped code definition constructions.
# define code_str( ... ) GEN_NS untyped_str( code( __VA_ARGS__ ) )
# define code_fmt( ... ) GEN_NS untyped_str( token_fmt( __VA_ARGS__ ) )
# define parse_fmt( type, ... ) GEN_NS parse_##type( token_fmt( __VA_ARGS__ ) )
/*
Takes a format string (char const*) and a list of tokens (StrC) and returns a StrC of the formatted string.
Tokens are provided in '<'identifier'>' format where '<' '>' are just angle brakcets (you can change it in token_fmt_va)
---------------------------------------------------------
Example - A string with:
typedef <type> <name> <name>;
Will have a token_fmt arguments populated with:
"type", strc_for_type,
"name", strc_for_name,
and:
stringize( typedef <type> <name> <name>; ) )
-----------------------------------------------------------
So the full call for this example would be:
token_fmt(
"type", strc_for_type
, "name", strc_for_name
, stringize(
typedef <type> <name> <name>
));
!----------------------------------------------------------
! Note: token_fmt_va is whitespace sensitive for the tokens.
! This can be alleviated by skipping whitespace between brackets but it was choosen to not have that implementation by default.
*/
# define token_fmt( ... ) GEN_NS token_fmt_impl( (num_args( __VA_ARGS__ ) + 1) / 2, __VA_ARGS__ )
#endif
#pragma endregion Macros
#pragma endregion Gen Interface #pragma endregion Gen Interface

View File

@ -21,29 +21,29 @@ OpValidateResult operator__validate( Operator op, CodeParam params_code, CodeTyp
} }
#pragma region Helper Macros #pragma region Helper Macros
# define check_params() \ # define check_params() \
if ( ! params_code ) \ if ( ! params_code ) \
{ \ { \
log_failure("gen::def_operator: params is null and operator%s requires it", operator_to_str(op)); \ log_failure("gen::def_operator: params is null and operator%s requires it", operator_to_str(op)); \
return OpValResult_Fail; \ return OpValResult_Fail; \
} \ } \
if ( params_code->Type != CT_Parameters ) \ if ( params_code->Type != CT_Parameters ) \
{ \ { \
log_failure("gen::def_operator: params is not of Parameters type - %s", code_debug_str(params_code)); \ log_failure("gen::def_operator: params is not of Parameters type - %s", code_debug_str( cast(Code, params_code))); \
return OpValResult_Fail; \ return OpValResult_Fail; \
} }
# define check_param_eq_ret() \ # define check_param_eq_ret() \
if ( ! is_member_symbol && ! code_is_equal(params_code->ValueType, ret_type) ) \ if ( ! is_member_symbol && ! code_is_equal(cast(Code, params_code->ValueType), cast(Code, ret_type)) ) \
{ \ { \
log_failure("gen::def_operator: operator%s requires first parameter to equal return type\n" \ log_failure("gen::def_operator: operator%s requires first parameter to equal return type\n" \
"param types: %s\n" \ "param types: %s\n" \
"return type: %s", \ "return type: %s", \
operator_to_str(op).Ptr, \ operator_to_str(op).Ptr, \
code_debug_str(params_code), \ code_debug_str(cast(Code, params_code)), \
code_debug_str(ret_type) \ code_debug_str(cast(Code, ret_type)) \
); \ ); \
return OpValResult_Fail; \ return OpValResult_Fail; \
} }
#pragma endregion Helper Macros #pragma endregion Helper Macros
@ -54,7 +54,7 @@ OpValidateResult operator__validate( Operator op, CodeParam params_code, CodeTyp
if ( ret_type->Type != CT_Typename ) if ( ret_type->Type != CT_Typename )
{ {
log_failure("gen::def_operator: ret_type is not of typename type - %s", code_debug_str(ret_type)); log_failure("gen::def_operator: ret_type is not of typename type - %s", code_debug_str(cast(Code, ret_type)));
return OpValResult_Fail; return OpValResult_Fail;
} }
@ -71,7 +71,7 @@ OpValidateResult operator__validate( Operator op, CodeParam params_code, CodeTyp
log_failure("gen::def_operator: " log_failure("gen::def_operator: "
"operator%s does not support non-member definition (more than one parameter provided) - %s", "operator%s does not support non-member definition (more than one parameter provided) - %s",
operator_to_str(op), operator_to_str(op),
code_debug_str(params_code) code_debug_str(cast(Code, params_code))
); );
return OpValResult_Fail; return OpValResult_Fail;
} }
@ -102,7 +102,7 @@ OpValidateResult operator__validate( Operator op, CodeParam params_code, CodeTyp
log_failure("gen::def_operator: operator%s may not be defined with more than two parametes - param count; %d\n%s" log_failure("gen::def_operator: operator%s may not be defined with more than two parametes - param count; %d\n%s"
, operator_to_str(op) , operator_to_str(op)
, params_code->NumEntries , params_code->NumEntries
, code_debug_str(params_code) , code_debug_str(cast(Code, params_code))
); );
return OpValResult_Fail; return OpValResult_Fail;
} }
@ -117,7 +117,7 @@ OpValidateResult operator__validate( Operator op, CodeParam params_code, CodeTyp
{ {
log_failure("gen::def_operator: operator%s params code provided is not of Parameters type - %s" log_failure("gen::def_operator: operator%s params code provided is not of Parameters type - %s"
, operator_to_str(op) , operator_to_str(op)
, code_debug_str(params_code) , code_debug_str(cast(Code, params_code))
); );
return OpValResult_Fail; return OpValResult_Fail;
} }
@ -125,7 +125,7 @@ OpValidateResult operator__validate( Operator op, CodeParam params_code, CodeTyp
switch ( params_code->NumEntries ) switch ( params_code->NumEntries )
{ {
case 1: case 1:
if ( code_is_equal(params_code->ValueType, t_int ) ) if ( code_is_equal((Code)params_code->ValueType, (Code)t_int ) )
is_member_symbol = true; is_member_symbol = true;
else else
@ -135,7 +135,7 @@ OpValidateResult operator__validate( Operator op, CodeParam params_code, CodeTyp
case 2: case 2:
check_param_eq_ret(); check_param_eq_ret();
if ( ! code_is_equal(get(params_code, 1), t_int ) ) if ( ! code_is_equal((Code)params_get(params_code, 1), (Code)t_int ) )
{ {
log_failure("gen::def_operator: " log_failure("gen::def_operator: "
"operator%s requires second parameter of non-member definition to be int for post-decrement", "operator%s requires second parameter of non-member definition to be int for post-decrement",
@ -164,18 +164,18 @@ OpValidateResult operator__validate( Operator op, CodeParam params_code, CodeTyp
{ {
if ( params_code->Type != CT_Parameters ) if ( params_code->Type != CT_Parameters )
{ {
log_failure("gen::def_operator: params is not of Parameters type - %s", code_debug_str(params_code)); log_failure("gen::def_operator: params is not of Parameters type - %s", code_debug_str((Code)params_code));
return OpValResult_Fail; return OpValResult_Fail;
} }
if ( code_is_equal(params_code->ValueType, ret_type ) ) if ( code_is_equal((Code)params_code->ValueType, (Code)ret_type ) )
{ {
log_failure("gen::def_operator: " log_failure("gen::def_operator: "
"operator%s is non-member symbol yet first paramter does not equal return type\n" "operator%s is non-member symbol yet first paramter does not equal return type\n"
"param type: %s\n" "param type: %s\n"
"return type: %s\n" "return type: %s\n"
, code_debug_str(params_code) , code_debug_str((Code)params_code)
, code_debug_str(ret_type) , code_debug_str((Code)ret_type)
); );
return OpValResult_Fail; return OpValResult_Fail;
} }
@ -209,16 +209,16 @@ OpValidateResult operator__validate( Operator op, CodeParam params_code, CodeTyp
{ {
if ( params_code->Type != CT_Parameters ) if ( params_code->Type != CT_Parameters )
{ {
log_failure( "gen::def_operator: params is not of Parameters type - %s", code_debug_str(params_code) ); log_failure( "gen::def_operator: params is not of Parameters type - %s", code_debug_str((Code)params_code) );
return OpValResult_Fail; return OpValResult_Fail;
} }
if ( params_code->NumEntries > 1 ) if ( params_code->NumEntries > 1 )
{ {
log_failure( log_failure(
"gen::def_operator: operator%s may not have more than one parameter - param count: %d", "gen::def_operator: operator%s may not have more than one parameter - param count: %d",
operator_to_str( op ), operator_to_str( op ),
params_code->NumEntries params_code->NumEntries
); );
return OpValResult_Fail; return OpValResult_Fail;
} }
@ -245,14 +245,14 @@ OpValidateResult operator__validate( Operator op, CodeParam params_code, CodeTyp
break; break;
case 2: case 2:
if ( ! code_is_equal(params_code->ValueType, ret_type ) ) if ( ! code_is_equal((Code)params_code->ValueType, (Code)ret_type ) )
{ {
log_failure("gen::def_operator: " log_failure("gen::def_operator: "
"operator%s is non-member symbol yet first paramter does not equal return type\n" "operator%s is non-member symbol yet first paramter does not equal return type\n"
"param type: %s\n" "param type: %s\n"
"return type: %s\n" "return type: %s\n"
, code_debug_str(params_code) , code_debug_str((Code)params_code)
, code_debug_str(ret_type) , code_debug_str((Code)ret_type)
); );
return OpValResult_Fail; return OpValResult_Fail;
} }
@ -275,7 +275,7 @@ OpValidateResult operator__validate( Operator op, CodeParam params_code, CodeTyp
{ {
if ( params_code->Type != CT_Parameters ) if ( params_code->Type != CT_Parameters )
{ {
log_failure("gen::def_operator: params is not of Parameters type - %s", code_debug_str(params_code)); log_failure("gen::def_operator: params is not of Parameters type - %s", code_debug_str((Code)params_code));
return OpValResult_Fail; return OpValResult_Fail;
} }
@ -289,11 +289,11 @@ OpValidateResult operator__validate( Operator op, CodeParam params_code, CodeTyp
} }
} }
if ( ! code_is_equal(ret_type, t_bool )) if ( ! code_is_equal((Code)ret_type, (Code)t_bool ))
{ {
log_failure("gen::def_operator: operator%s return type must be of type bool - %s" log_failure("gen::def_operator: operator%s return type must be of type bool - %s"
, operator_to_str(op) , operator_to_str(op)
, code_debug_str(ret_type) , code_debug_str((Code)ret_type)
); );
return OpValResult_Fail; return OpValResult_Fail;
} }
@ -347,7 +347,7 @@ OpValidateResult operator__validate( Operator op, CodeParam params_code, CodeTyp
case Op_PtrToMemOfPtr: case Op_PtrToMemOfPtr:
if ( params_code ) if ( params_code )
{ {
log_failure("gen::def_operator: operator%s expects no paramters - %s", operator_to_str(op), code_debug_str(params_code)); log_failure("gen::def_operator: operator%s expects no paramters - %s", operator_to_str(op), code_debug_str((Code)params_code));
return OpValResult_Fail; return OpValResult_Fail;
} }
break; break;
@ -390,7 +390,7 @@ OpValidateResult operator__validate( Operator op, CodeParam params_code, CodeTyp
} }
#define null_check( Context_, Code_ ) \ #define null_check( Context_, Code_ ) \
if ( ! Code_ ) \ if ( Code_ != nullptr ) \
{ \ { \
log_failure( "gen::" stringize(Context_) ": " stringize(Code_) " provided is null" ); \ log_failure( "gen::" stringize(Context_) ": " stringize(Code_) " provided is null" ); \
return InvalidCode; \ return InvalidCode; \
@ -501,7 +501,7 @@ CodeConstructor def_constructor( Opts_def_constructor p )
if ( params && params->Type != CT_Parameters ) if ( params && params->Type != CT_Parameters )
{ {
log_failure("gen::def_constructor: params must be of Parameters type - %s", code_debug_str(params)); log_failure("gen::def_constructor: params must be of Parameters type - %s", code_debug_str((Code)params));
return InvalidCode; return InvalidCode;
} }
@ -606,7 +606,7 @@ CodeClass def_class( StrC name, Opts_def_struct p )
{ {
for (s32 idx = 0; idx < num_interfaces; idx++ ) for (s32 idx = 0; idx < num_interfaces; idx++ )
{ {
add_interface(result, interfaces[idx] ); class_add_interface(result, interfaces[idx] );
} }
} }
@ -692,13 +692,13 @@ CodeEnum def_enum( StrC name, Opts_def_enum p )
if ( type && type->Type != CT_Typename ) if ( type && type->Type != CT_Typename )
{ {
log_failure( "gen::def_enum: enum underlying type provided was not of type Typename: %s", code_debug_str(type) ); log_failure( "gen::def_enum: enum underlying type provided was not of type Typename: %s", code_debug_str((Code)type) );
return InvalidCode; return InvalidCode;
} }
if ( attributes && attributes->Type != CT_PlatformAttributes ) if ( attributes && attributes->Type != CT_PlatformAttributes )
{ {
log_failure( "gen::def_enum: attributes was not a 'PlatformAttributes' type: %s", code_debug_str(attributes) ); log_failure( "gen::def_enum: attributes was not a 'PlatformAttributes' type: %s", code_debug_str((Code)attributes) );
return InvalidCode; return InvalidCode;
} }
@ -1161,7 +1161,7 @@ CodeSpecifiers def_specifier( Specifier spec )
CodeSpecifiers CodeSpecifiers
result = (CodeSpecifiers) make_code(); result = (CodeSpecifiers) make_code();
result->Type = CT_Specifiers; result->Type = CT_Specifiers;
append(result, spec ); specifiers_append(result, spec );
return result; return result;
} }
@ -1178,7 +1178,7 @@ CodeStruct def_struct( StrC name, Opts_def_struct p )
if ( attributes && attributes->Type != CT_PlatformAttributes ) if ( attributes && attributes->Type != CT_PlatformAttributes )
{ {
log_failure( "gen::def_struct: attributes was not a `PlatformAttributes` type - %s", code_debug_str(attributes) ); log_failure( "gen::def_struct: attributes was not a `PlatformAttributes` type - %s", code_debug_str(cast(Code, attributes)) );
return InvalidCode; return InvalidCode;
} }
@ -1273,19 +1273,19 @@ CodeTypename def_type( StrC name, Opts_def_type p )
if ( attributes && attributes->Type != CT_PlatformAttributes ) if ( attributes && attributes->Type != CT_PlatformAttributes )
{ {
log_failure( "gen::def_type: attributes is not of attributes type - %s", code_debug_str(attributes) ); log_failure( "gen::def_type: attributes is not of attributes type - %s", code_debug_str((Code)attributes) );
return InvalidCode; return InvalidCode;
} }
if ( specifiers && specifiers->Type != CT_Specifiers ) if ( specifiers && specifiers->Type != CT_Specifiers )
{ {
log_failure( "gen::def_type: specifiers is not of specifiers type - %s", code_debug_str(specifiers) ); log_failure( "gen::def_type: specifiers is not of specifiers type - %s", code_debug_str((Code)specifiers) );
return InvalidCode; return InvalidCode;
} }
if ( arrayexpr && arrayexpr->Type != CT_Untyped ) if ( arrayexpr && arrayexpr->Type != CT_Untyped )
{ {
log_failure( "gen::def_type: arrayexpr is not of untyped type - %s", code_debug_str(arrayexpr) ); log_failure( "gen::def_type: arrayexpr is not of untyped type - %s", code_debug_str((Code)arrayexpr) );
return InvalidCode; return InvalidCode;
} }
@ -1325,13 +1325,13 @@ CodeTypedef def_typedef( StrC name, Code type, Opts_def_typedef p )
case CT_Typename: case CT_Typename:
break; break;
default: default:
log_failure( "gen::def_typedef: type was not a Class, Enum, Function Forward, Struct, Typename, or Union - %s", code_debug_str(type) ); log_failure( "gen::def_typedef: type was not a Class, Enum, Function Forward, Struct, Typename, or Union - %s", code_debug_str((Code)type) );
return InvalidCode; return InvalidCode;
} }
if ( p.attributes && p.attributes->Type != CT_PlatformAttributes ) if ( p.attributes && p.attributes->Type != CT_PlatformAttributes )
{ {
log_failure( "gen::def_typedef: attributes was not a PlatformAttributes - %s", code_debug_str(p.attributes) ); log_failure( "gen::def_typedef: attributes was not a PlatformAttributes - %s", code_debug_str((Code)p.attributes) );
return InvalidCode; return InvalidCode;
} }
@ -1553,7 +1553,7 @@ CodeBody def_class_body( s32 num, ... )
break; break;
} }
append(result, entry); body_append(result, entry);
} }
while (num--, num > 0); while (num--, num > 0);
va_end(va); va_end(va);
@ -1590,7 +1590,7 @@ CodeBody def_class_body( s32 num, Code* codes )
break; break;
} }
append(result, entry); body_append(result, entry);
} }
while (num--, num > 0); while (num--, num > 0);
@ -1624,7 +1624,7 @@ CodeBody def_enum_body( s32 num, ... )
return InvalidCode; return InvalidCode;
} }
append(result, entry ); body_append(result, entry );
} }
while ( num--, num > 0 ); while ( num--, num > 0 );
va_end(va); va_end(va);
@ -1656,7 +1656,7 @@ CodeBody def_enum_body( s32 num, Code* codes )
return InvalidCode; return InvalidCode;
} }
append(result, entry ); body_append(result, entry );
} }
while ( codes++, num--, num > 0 ); while ( codes++, num--, num > 0 );
@ -1694,7 +1694,7 @@ CodeBody def_export_body( s32 num, ... )
break; break;
} }
append(result, entry); body_append(result, entry);
} }
while (num--, num > 0); while (num--, num > 0);
va_end(va); va_end(va);
@ -1731,7 +1731,7 @@ CodeBody def_export_body( s32 num, Code* codes )
break; break;
} }
append(result, entry); body_append(result, entry);
} }
while (num--, num > 0); while (num--, num > 0);
@ -1769,7 +1769,7 @@ CodeBody def_extern_link_body( s32 num, ... )
break; break;
} }
append(result, entry); body_append(result, entry);
} }
while (num--, num > 0); while (num--, num > 0);
va_end(va); va_end(va);
@ -1806,8 +1806,7 @@ CodeBody def_extern_link_body( s32 num, Code* codes )
break; break;
} }
append(result, entry); body_append(result, entry);
} }
while (num--, num > 0); while (num--, num > 0);
@ -1846,7 +1845,7 @@ CodeBody def_function_body( s32 num, ... )
break; break;
} }
append(result, entry); body_append(result, entry);
} }
while (num--, num > 0); while (num--, num > 0);
va_end(va); va_end(va);
@ -1882,7 +1881,7 @@ CodeBody def_function_body( s32 num, Code* codes )
default: default:
break; break;
} }
append(result, entry); body_append(result, entry);
} }
while (num--, num > 0); while (num--, num > 0);
@ -1913,8 +1912,8 @@ CodeBody def_global_body( s32 num, ... )
switch (entry->Type) switch (entry->Type)
{ {
case CT_Global_Body: case CT_Global_Body:
// result.append( entry.code_cast<CodeBody>() ) ; // result.body_append( entry.code_cast<CodeBody>() ) ;
append( result, cast(CodeBody, entry) ); body_append( result, cast(CodeBody, entry) );
continue; continue;
GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES
@ -1925,7 +1924,7 @@ CodeBody def_global_body( s32 num, ... )
break; break;
} }
append(result, entry); body_append(result, entry);
} }
while (num--, num > 0); while (num--, num > 0);
va_end(va); va_end(va);
@ -1955,7 +1954,7 @@ CodeBody def_global_body( s32 num, Code* codes )
switch (entry->Type) switch (entry->Type)
{ {
case CT_Global_Body: case CT_Global_Body:
append(result, cast(CodeBody, entry) ); body_append(result, cast(CodeBody, entry) );
continue; continue;
GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES
@ -1966,7 +1965,7 @@ CodeBody def_global_body( s32 num, Code* codes )
break; break;
} }
append(result, entry); body_append(result, entry);
} }
while (num--, num > 0); while (num--, num > 0);
@ -2004,7 +2003,7 @@ CodeBody def_namespace_body( s32 num, ... )
break; break;
} }
append(result, entry); body_append(result, entry);
} }
while (num--, num > 0); while (num--, num > 0);
va_end(va); va_end(va);
@ -2040,7 +2039,7 @@ CodeBody def_namespace_body( s32 num, Code* codes )
default: break; default: break;
} }
append(result, entry); body_append(result, entry);
} }
while (num--, num > 0); while (num--, num > 0);
@ -2078,7 +2077,7 @@ CodeParam def_params( s32 num, ... )
return InvalidCode; return InvalidCode;
} }
append(result, param ); params_append(result, param );
} }
va_end(va); va_end(va);
@ -2114,7 +2113,7 @@ CodeParam def_params( s32 num, CodeParam* codes )
while( codes++, current = * codes, num--, num > 0 ) while( codes++, current = * codes, num--, num > 0 )
{ {
check_current(); check_current();
append(result, current ); params_append(result, current );
} }
# undef check_current # undef check_current
@ -2145,7 +2144,7 @@ CodeSpecifiers def_specifiers( s32 num, ... )
{ {
Specifier type = (Specifier)va_arg(va, int); Specifier type = (Specifier)va_arg(va, int);
append(result, type ); specifiers_append(result, type );
} }
while ( --num, num ); while ( --num, num );
va_end(va); va_end(va);
@ -2174,7 +2173,7 @@ CodeSpecifiers def_specifiers( s32 num, Specifier* specs )
s32 idx = 0; s32 idx = 0;
do do
{ {
append(result, specs[idx] ); specifiers_append(result, specs[idx] );
idx++; idx++;
} }
while ( --num, num ); while ( --num, num );
@ -2213,7 +2212,7 @@ CodeBody def_struct_body( s32 num, ... )
break; break;
} }
append(result, entry); body_append(result, entry);
} }
while (num--, num > 0); while (num--, num > 0);
va_end(va); va_end(va);
@ -2250,7 +2249,7 @@ CodeBody def_struct_body( s32 num, Code* codes )
break; break;
} }
append(result, entry); body_append(result, entry);
} }
while (num--, num > 0); while (num--, num > 0);
@ -2284,7 +2283,7 @@ CodeBody def_union_body( s32 num, ... )
return InvalidCode; return InvalidCode;
} }
append(result, entry ); body_append(result, entry );
} }
while ( num--, num > 0 ); while ( num--, num > 0 );
va_end(va); va_end(va);
@ -2316,7 +2315,7 @@ CodeBody def_union_body( s32 num, CodeUnion* codes )
return InvalidCode; return InvalidCode;
} }
append(result, entry ); body_append(result, entry );
} }
while ( codes++, num--, num > 0 ); while ( codes++, num--, num > 0 );

View File

@ -1124,7 +1124,7 @@ CodeBody parse_class_struct_body( TokType which, Token name )
return InvalidCode; return InvalidCode;
} }
append(result, member ); body_append(result, member );
} }
eat( Tok_BraceCurly_Close ); eat( Tok_BraceCurly_Close );
@ -1438,7 +1438,7 @@ CodeFn parse_function_after_name(
CodeParam params = parse_params(); CodeParam params = parse_params();
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Parameters> ) // <Attributes> <Specifiers> <ReturnType> <Name> ( <Parameters> )
// TODO(Ed), Review old comment : These have to be kept separate from the return type's specifiers. // TODO(Ed), Review old comment : These have to be kept separate from the return type's specifiers.
while ( left && is_specifier(currtok) ) while ( left && is_specifier(currtok) )
{ {
if ( specifiers.ast == nullptr ) if ( specifiers.ast == nullptr )
@ -1448,7 +1448,7 @@ CodeFn parse_function_after_name(
continue; continue;
} }
append(specifiers, strc_to_specifier( to_str(currtok)) ); specifiers_append(specifiers, strc_to_specifier( to_str(currtok)) );
eat( currtok.Type ); eat( currtok.Type );
} }
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> // <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers>
@ -1468,7 +1468,7 @@ CodeFn parse_function_after_name(
else if ( check(Tok_Operator) && currtok.Text[0] == '=' ) else if ( check(Tok_Operator) && currtok.Text[0] == '=' )
{ {
eat(Tok_Operator); eat(Tok_Operator);
append(specifiers, Spec_Pure ); specifiers_append(specifiers, Spec_Pure );
eat( Tok_Number); eat( Tok_Number);
Token stmt_end = currtok; Token stmt_end = currtok;
@ -1544,7 +1544,7 @@ CodeFn parse_function_after_name(
internal internal
Code parse_function_body() Code parse_function_body()
{ {
push_scope(); push_scope();
eat( Tok_BraceCurly_Open ); eat( Tok_BraceCurly_Open );
@ -1574,7 +1574,7 @@ Code parse_function_body()
if ( len > 0 ) if ( len > 0 )
{ {
append( result, def_execution( { len, start.Text } ) ); body_append( result, def_execution( { len, start.Text } ) );
} }
eat( Tok_BraceCurly_Close ); eat( Tok_BraceCurly_Close );
@ -1614,6 +1614,13 @@ CodeBody parse_global_nspace( CodeType which )
switch ( currtok_noskip.Type ) switch ( currtok_noskip.Type )
{ {
case Tok_Comma:
{
log_failure("Dangling comma found: %S\nContext:\n%S", to_string(currtok), to_string(Context));
pop( & Context);
return InvalidCode;
}
break;
case Tok_Statement_End: case Tok_Statement_End:
{ {
// TODO(Ed): Convert this to a general warning procedure // TODO(Ed): Convert this to a general warning procedure
@ -1885,13 +1892,13 @@ CodeBody parse_global_nspace( CodeType which )
if ( member == Code_Invalid ) if ( member == Code_Invalid )
{ {
log_failure( "Failed to parse member\n%s", to_string(Context) ); log_failure( "Failed to parse member\nToken: %s\nContext:\n%s", to_string(currtok_noskip), to_string(Context) );
pop(& Context); pop(& Context);
return InvalidCode; return InvalidCode;
} }
// log_fmt("Global Body Member: %s", member->debug_str()); // log_fmt("Global Body Member: %s", member->debug_str());
append(result, member ); body_append(result, member );
} }
if ( which != CT_Global_Body ) if ( which != CT_Global_Body )
@ -2032,7 +2039,7 @@ Code parse_global_nspace_constructor_destructor( CodeSpecifiers specifiers )
// TODO(Ed): I want to eventually change the identifier to its own AST type. // TODO(Ed): I want to eventually change the identifier to its own AST type.
// This would allow distinction of the qualifier for a symbol <qualifier>::<nested symboL> // This would allow distinction of the qualifier for a symbol <qualifier>::<nested symboL>
// This would also allow // This would also allow
internal internal
Token parse_identifier( bool* possible_member_function ) Token parse_identifier( bool* possible_member_function )
{ {
@ -2455,7 +2462,7 @@ CodeOperator parse_operator_after_ret_type(
continue; continue;
} }
append(specifiers, strc_to_specifier( to_str(currtok)) ); specifiers_append(specifiers, strc_to_specifier( to_str(currtok)) );
eat( currtok.Type ); eat( currtok.Type );
} }
// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> ( <Parameters> ) <Specifiers> // <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> ( <Parameters> ) <Specifiers>
@ -2771,7 +2778,7 @@ CodeParam parse_params( bool use_template_capture )
if ( check( Tok_Varadic_Argument ) ) if ( check( Tok_Varadic_Argument ) )
{ {
eat( Tok_Varadic_Argument ); eat( Tok_Varadic_Argument );
append(result, param_varadic ); params_append(result, param_varadic );
continue; continue;
// ( <Macro> <ValueType> <Name> = <Expression>, ... // ( <Macro> <ValueType> <Name> = <Expression>, ...
} }
@ -2875,7 +2882,7 @@ CodeParam parse_params( bool use_template_capture )
if ( value ) if ( value )
param->Value = value; param->Value = value;
append(result, param ); params_append(result, param );
} }
if ( ! use_template_capture ) if ( ! use_template_capture )
@ -2933,7 +2940,7 @@ CodePreprocessCond parse_preprocess_cond()
return cond; return cond;
} }
internal internal
Code parse_simple_preprocess( TokType which, bool dont_consume_braces ) Code parse_simple_preprocess( TokType which, bool dont_consume_braces )
{ {
// TODO(Ed): We can handle a macro a bit better than this. It's AST can be made more robust.. // TODO(Ed): We can handle a macro a bit better than this. It's AST can be made more robust..
@ -2985,6 +2992,10 @@ Code parse_simple_preprocess( TokType which, bool dont_consume_braces )
} }
else else
{ {
// If the macro is just a macro in the body of an AST it may have a semi-colon for the user to close on purpsoe
// (especially for functional macros)
StrC& calling_proc = Context.Scope->Prev->ProcName;
if (strc_contains(Context.Scope->Prev->ProcName, txt("parse_enum"))) if (strc_contains(Context.Scope->Prev->ProcName, txt("parse_enum")))
{ {
// Do nothing // Do nothing
@ -2992,17 +3003,30 @@ Code parse_simple_preprocess( TokType which, bool dont_consume_braces )
} }
else if (strc_contains(Context.Scope->Prev->ProcName, txt("parse_typedef"))) else if (strc_contains(Context.Scope->Prev->ProcName, txt("parse_typedef")))
{ {
// TODO(Ed): Reveiw the context for this?
if ( peektok.Type == Tok_Statement_End ) if ( peektok.Type == Tok_Statement_End )
{ {
Token stmt_end = currtok; Token stmt_end = currtok;
eat( Tok_Statement_End ); eat( Tok_Statement_End );
// <Macro>; // <Macro>;
// TODO(Ed): Reveiw the context for this? (ESPECIALLY THIS)
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line ) if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
eat( Tok_Comment ); eat( Tok_Comment );
// <Macro>; <InlineCmt> // <Macro>; <InlineCmt>
} }
}
else if (
strc_contains(calling_proc, txt("parse_global_nspace"))
&& strc_contains(calling_proc, txt("parse_class_struct_body"))
)
{
if (peektok.Type == Tok_Statement_End)
{
Token stmt_end = currtok;
eat( Tok_Statement_End );
// <Macro>;
}
} }
tok.Length = ( (sptr)currtok_noskip.Text + currtok_noskip.Length ) - (sptr)tok.Text; tok.Length = ( (sptr)currtok_noskip.Text + currtok_noskip.Length ) - (sptr)tok.Text;
@ -3305,7 +3329,7 @@ CodeVar parse_variable_declaration_list()
"(Parser will add and continue to specifiers, but will most likely fail to compile)\n%s" "(Parser will add and continue to specifiers, but will most likely fail to compile)\n%s"
, to_string(Context) ); , to_string(Context) );
append(specifiers, spec ); specifiers_append(specifiers, spec );
} }
break; break;
@ -3327,7 +3351,7 @@ CodeVar parse_variable_declaration_list()
// eat(currtok.Type); // eat(currtok.Type);
if ( specifiers ) if ( specifiers )
append(specifiers, spec ); specifiers_append(specifiers, spec );
else else
specifiers = def_specifier( spec ); specifiers = def_specifier( spec );
} }
@ -3467,7 +3491,7 @@ CodeDestructor parse_destructor( CodeSpecifiers specifiers )
if ( check( Tok_Spec_Virtual ) ) if ( check( Tok_Spec_Virtual ) )
{ {
if ( specifiers ) if ( specifiers )
append(specifiers, Spec_Virtual ); specifiers_append(specifiers, Spec_Virtual );
else else
specifiers = def_specifier( Spec_Virtual ); specifiers = def_specifier( Spec_Virtual );
eat( Tok_Spec_Virtual ); eat( Tok_Spec_Virtual );
@ -3510,7 +3534,7 @@ CodeDestructor parse_destructor( CodeSpecifiers specifiers )
eat( Tok_Number ); eat( Tok_Number );
// <Virtual Specifier> ~<Name>() = 0 // <Virtual Specifier> ~<Name>() = 0
append(specifiers, Spec_Pure ); specifiers_append(specifiers, Spec_Pure );
} }
else if ( left && str_compare_len( upcoming.Text, "default", sizeof("default") - 1 ) == 0) else if ( left && str_compare_len( upcoming.Text, "default", sizeof("default") - 1 ) == 0)
{ {
@ -3762,7 +3786,7 @@ CodeEnum parse_enum( bool inplace_def )
return InvalidCode; return InvalidCode;
} }
append(body, member ); body_append(body, member );
} }
eat( Tok_BraceCurly_Close ); eat( Tok_BraceCurly_Close );
@ -4206,7 +4230,7 @@ CodeOpCast parse_operator_cast( CodeSpecifiers specifiers )
specifiers = def_specifier( Spec_Const ); specifiers = def_specifier( Spec_Const );
else else
append(specifiers, Spec_Const ); specifiers_append(specifiers, Spec_Const );
eat( Tok_Spec_Const ); eat( Tok_Spec_Const );
} }
@ -4965,6 +4989,7 @@ CodeTypedef parse_typedef()
name = currtok; name = currtok;
eat(Tok_Identifier); eat(Tok_Identifier);
} }
// <ModuleFalgs> typedef <Preprocessed_Macro> <Identifier>
} }
else else
{ {
@ -5250,7 +5275,7 @@ CodeUnion parse_union( bool inplace_def )
} }
if ( member ) if ( member )
append(body, member ); body_append(body, member );
} }
// <ModuleFlags> union <Attributes> <Name> { <Body> // <ModuleFlags> union <Attributes> <Name> { <Body>

View File

@ -13,7 +13,7 @@ using LogFailType = ssize(*)(char const*, ...);
#define log_failure GEN_FATAL #define log_failure GEN_FATAL
#endif #endif
enum AccessSpec enum_underlying(u32) enum AccessSpec : u32
{ {
AccessSpec_Default, AccessSpec_Default,
AccessSpec_Private, AccessSpec_Private,
@ -28,7 +28,7 @@ enum AccessSpec enum_underlying(u32)
static_assert( size_of(AccessSpec) == size_of(u32), "AccessSpec not u32 size" ); static_assert( size_of(AccessSpec) == size_of(u32), "AccessSpec not u32 size" );
inline inline
char const* to_str( AccessSpec type ) char const* access_spec_to_str( AccessSpec type )
{ {
local_persist local_persist
char const* lookup[ (u32)AccessSpec_Num_AccessSpec ] = { char const* lookup[ (u32)AccessSpec_Num_AccessSpec ] = {
@ -44,7 +44,7 @@ char const* to_str( AccessSpec type )
return lookup[ (u32)type ]; return lookup[ (u32)type ];
} }
enum CodeFlag enum_underlying(u32) enum CodeFlag : u32
{ {
CodeFlag_None = 0, CodeFlag_None = 0,
CodeFlag_FunctionType = bit(0), CodeFlag_FunctionType = bit(0),
@ -57,7 +57,7 @@ enum CodeFlag enum_underlying(u32)
static_assert( size_of(CodeFlag) == size_of(u32), "CodeFlag not u32 size" ); static_assert( size_of(CodeFlag) == size_of(u32), "CodeFlag not u32 size" );
// Used to indicate if enum definitoin is an enum class or regular enum. // Used to indicate if enum definitoin is an enum class or regular enum.
enum EnumDecl enum_underlying(u8) enum EnumDecl : u8
{ {
EnumDecl_Regular, EnumDecl_Regular,
EnumDecl_Class, EnumDecl_Class,
@ -66,7 +66,7 @@ enum EnumDecl enum_underlying(u8)
}; };
typedef u8 EnumT; typedef u8 EnumT;
enum ModuleFlag enum_underlying(u32) enum ModuleFlag : u32
{ {
ModuleFlag_None = 0, ModuleFlag_None = 0,
ModuleFlag_Export = bit(0), ModuleFlag_Export = bit(0),
@ -80,28 +80,24 @@ enum ModuleFlag enum_underlying(u32)
static_assert( size_of(ModuleFlag) == size_of(u32), "ModuleFlag not u32 size" ); static_assert( size_of(ModuleFlag) == size_of(u32), "ModuleFlag not u32 size" );
inline inline
StrC to_str( ModuleFlag flag ) StrC module_flag_to_str( ModuleFlag flag )
{ {
local_persist local_persist
StrC lookup[ (u32)ModuleFlag::Num_ModuleFlags ] = { StrC lookup[ (u32)Num_ModuleFlags ] = {
{ sizeof("__none__"), "__none__" }, { sizeof("__none__"), "__none__" },
{ sizeof("export"), "export" }, { sizeof("export"), "export" },
{ sizeof("import"), "import" }, { sizeof("import"), "import" },
}; };
local_persist
StrC invalid_flag = { sizeof("invalid"), "invalid" };
if ( flag > ModuleFlag_Import ) if ( flag > ModuleFlag_Import )
return { sizeof("invalid"), "invalid" }; return invalid_flag;
return lookup[ (u32)flag ]; return lookup[ (u32)flag ];
} }
inline enum EPreprocessCond : u32
ModuleFlag operator|( ModuleFlag A, ModuleFlag B)
{
return (ModuleFlag)( (u32)A | (u32)B );
}
enum EPreprocessCond enum_underlying(u32)
{ {
PreprocessCond_If, PreprocessCond_If,
PreprocessCond_IfDef, PreprocessCond_IfDef,

View File

@ -5,7 +5,6 @@
#endif #endif
#pragma region Basic Types #pragma region Basic Types
GEN_API_C_BEGIN
#define GEN_U8_MIN 0u #define GEN_U8_MIN 0u
#define GEN_U8_MAX 0xffu #define GEN_U8_MAX 0xffu
@ -127,14 +126,12 @@ typedef s32 b32;
typedef void* mem_ptr; typedef void* mem_ptr;
typedef void const* mem_ptr_const ; typedef void const* mem_ptr_const ;
#if ! GEN_COMPILER_C #if GEN_COMPILER_CPP
GEN_API_C_END
template<typename Type> uptr to_uptr( Type* ptr ) { return (uptr)ptr; } template<typename Type> uptr to_uptr( Type* ptr ) { return (uptr)ptr; }
template<typename Type> sptr to_sptr( Type* ptr ) { return (sptr)ptr; } template<typename Type> sptr to_sptr( Type* ptr ) { return (sptr)ptr; }
template<typename Type> mem_ptr to_mem_ptr ( Type ptr ) { return (mem_ptr) ptr; } template<typename Type> mem_ptr to_mem_ptr ( Type ptr ) { return (mem_ptr) ptr; }
template<typename Type> mem_ptr_const to_mem_ptr_const( Type ptr ) { return (mem_ptr_const)ptr; } template<typename Type> mem_ptr_const to_mem_ptr_const( Type ptr ) { return (mem_ptr_const)ptr; }
GEN_API_C_BEGIN
#else #else
#define to_uptr( ptr ) ((uptr)(ptr)) #define to_uptr( ptr ) ((uptr)(ptr))
#define to_sptr( ptr ) ((sptr)(ptr)) #define to_sptr( ptr ) ((sptr)(ptr))
@ -143,5 +140,4 @@ GEN_API_C_BEGIN
#define to_mem_ptr_const( ptr) ((mem_ptr)ptr) #define to_mem_ptr_const( ptr) ((mem_ptr)ptr)
#endif #endif
GEN_API_C_END
#pragma endregion Basic Types #pragma endregion Basic Types

View File

@ -26,12 +26,9 @@ template <class TType> using TRemovePtr = typename RemovePtr<TType>::Type;
struct ArrayHeader; struct ArrayHeader;
#if GEN_SUPPORT_CPP_MEMBER_FEATURES #if GEN_COMPILER_CPP
template<class Type> struct Array; template<class Type> struct Array;
# define get_array_underlying_type(array) typename TRemovePtr<typeof(array)>:: DataType # define get_array_underlying_type(array) typename TRemovePtr<typeof(array)>:: DataType
#else
template<class Type> using Array = Type*;
# define get_array_underlying_type(array) TRemovePtr<typeof(array)>
#endif #endif
usize array_grow_formula(ssize value); usize array_grow_formula(ssize value);
@ -62,34 +59,34 @@ struct ArrayHeader {
usize Num; usize Num;
}; };
#if GEN_SUPPORT_CPP_MEMBER_FEATURES #if GEN_COMPILER_CPP
template<class Type> template<class Type>
struct Array struct Array
{ {
Type* Data; Type* Data;
#pragma region Member Mapping #pragma region Member Mapping
forceinline static Array init(AllocatorInfo allocator) { return GEN_NS array_init<Type>(allocator); } forceinline static Array init(AllocatorInfo allocator) { return array_init<Type>(allocator); }
forceinline static Array init_reserve(AllocatorInfo allocator, ssize capacity) { return GEN_NS array_init_reserve<Type>(allocator, capacity); } forceinline static Array init_reserve(AllocatorInfo allocator, ssize capacity) { return array_init_reserve<Type>(allocator, capacity); }
forceinline static usize grow_formula(ssize value) { return GEN_NS array_grow_formula<Type>(value); } forceinline static usize grow_formula(ssize value) { return array_grow_formula<Type>(value); }
forceinline bool append(Array other) { return GEN_NS array_append_array<Type>(this, other); } forceinline bool append(Array other) { return array_append_array<Type>(this, other); }
forceinline bool append(Type value) { return GEN_NS array_append<Type>(this, value); } forceinline bool append(Type value) { return array_append<Type>(this, value); }
forceinline bool append(Type* items, usize item_num) { return GEN_NS array_append_items<Type>(this, items, item_num); } forceinline bool append(Type* items, usize item_num) { return array_append_items<Type>(this, items, item_num); }
forceinline bool append_at(Type item, usize idx) { return GEN_NS array_append_at<Type>(this, item, idx); } forceinline bool append_at(Type item, usize idx) { return array_append_at<Type>(this, item, idx); }
forceinline bool append_at(Type* items, usize item_num, usize idx) { return GEN_NS array_append_items_at<Type>(this, items, item_num, idx); } forceinline bool append_at(Type* items, usize item_num, usize idx) { return array_append_items_at<Type>(this, items, item_num, idx); }
forceinline Type* back() { return GEN_NS array_back<Type>(* this); } forceinline Type* back() { return array_back<Type>(* this); }
forceinline void clear() { GEN_NS array_clear<Type>(* this); } forceinline void clear() { array_clear<Type>(* this); }
forceinline bool fill(usize begin, usize end, Type value) { return GEN_NS array_fill<Type>(* this, begin, end, value); } forceinline bool fill(usize begin, usize end, Type value) { return array_fill<Type>(* this, begin, end, value); }
forceinline void free() { GEN_NS array_free<Type>(this); } forceinline void free() { array_free<Type>(this); }
forceinline ArrayHeader* get_header() { return GEN_NS array_get_header<Type>(* this); } forceinline ArrayHeader* get_header() { return array_get_header<Type>(* this); }
forceinline bool grow(usize min_capacity) { return GEN_NS array_grow<Type>(this, min_capacity); } forceinline bool grow(usize min_capacity) { return array_grow<Type>(this, min_capacity); }
forceinline usize num() { return GEN_NS array_num<Type>(*this); } forceinline usize num() { return array_num<Type>(*this); }
forceinline void pop() { GEN_NS array_pop<Type>(* this); } forceinline void pop() { array_pop<Type>(* this); }
forceinline void remove_at(usize idx) { GEN_NS array_remove_at<Type>(* this, idx); } forceinline void remove_at(usize idx) { array_remove_at<Type>(* this, idx); }
forceinline bool reserve(usize new_capacity) { return GEN_NS array_reserve<Type>(this, new_capacity); } forceinline bool reserve(usize new_capacity) { return array_reserve<Type>(this, new_capacity); }
forceinline bool resize(usize num) { return GEN_NS array_resize<Type>(this, num); } forceinline bool resize(usize num) { return array_resize<Type>(this, num); }
forceinline bool set_capacity(usize new_capacity) { return GEN_NS array_set_capacity<Type>(this, new_capacity); } forceinline bool set_capacity(usize new_capacity) { return array_set_capacity<Type>(this, new_capacity); }
#pragma endregion Member Mapping #pragma endregion Member Mapping
forceinline operator Type*() { return Data; } forceinline operator Type*() { return Data; }
@ -104,17 +101,17 @@ struct Array
}; };
#endif #endif
#if GEN_SUPPORT_CPP_REFERENCES #if GEN_COMPILER_CPP && 0
template<class Type> bool append(Array<Type>& array, Array<Type> other) { return GEN_NS append( & array, other ); } template<class Type> bool append(Array<Type>& array, Array<Type> other) { return append( & array, other ); }
template<class Type> bool append(Array<Type>& array, Type value) { return GEN_NS append( & array, value ); } template<class Type> bool append(Array<Type>& array, Type value) { return append( & array, value ); }
template<class Type> bool append(Array<Type>& array, Type* items, usize item_num) { return GEN_NS append( & array, items, item_num ); } template<class Type> bool append(Array<Type>& array, Type* items, usize item_num) { return append( & array, items, item_num ); }
template<class Type> bool append_at(Array<Type>& array, Type item, usize idx) { return GEN_NS append_at( & array, item, idx ); } template<class Type> bool append_at(Array<Type>& array, Type item, usize idx) { return append_at( & array, item, idx ); }
template<class Type> bool append_at(Array<Type>& array, Type* items, usize item_num, usize idx) { return GEN_NS append_at( & array, items, item_num, idx ); } template<class Type> bool append_at(Array<Type>& array, Type* items, usize item_num, usize idx) { return append_at( & array, items, item_num, idx ); }
template<class Type> void free(Array<Type>& array) { return GEN_NS free( & array ); } template<class Type> void free(Array<Type>& array) { return free( & array ); }
template<class Type> bool grow(Array<Type>& array, usize min_capacity) { return GEN_NS grow( & array, min_capacity); } template<class Type> bool grow(Array<Type>& array, usize min_capacity) { return grow( & array, min_capacity); }
template<class Type> bool reserve(Array<Type>& array, usize new_capacity) { return GEN_NS reserve( & array, new_capacity); } template<class Type> bool reserve(Array<Type>& array, usize new_capacity) { return reserve( & array, new_capacity); }
template<class Type> bool resize(Array<Type>& array, usize num) { return GEN_NS resize( & array, num); } template<class Type> bool resize(Array<Type>& array, usize num) { return resize( & array, num); }
template<class Type> bool set_capacity(Array<Type>& array, usize new_capacity) { return GEN_NS set_capacity( & array, new_capacity); } template<class Type> bool set_capacity(Array<Type>& array, usize new_capacity) { return set_capacity( & array, new_capacity); }
template<class Type> forceinline Type* begin(Array<Type>& array) { return array; } template<class Type> forceinline Type* begin(Array<Type>& array) { return array; }
template<class Type> forceinline Type* end(Array<Type>& array) { return array + array_get_header(array)->Num; } template<class Type> forceinline Type* end(Array<Type>& array) { return array + array_get_header(array)->Num; }
@ -137,7 +134,7 @@ Array<Type> array_init_reserve(AllocatorInfo allocator, ssize capacity)
ArrayHeader* header = rcast(ArrayHeader*, alloc(allocator, sizeof(ArrayHeader) + sizeof(Type) * capacity)); ArrayHeader* header = rcast(ArrayHeader*, alloc(allocator, sizeof(ArrayHeader) + sizeof(Type) * capacity));
if (header == nullptr) if (header == nullptr)
return {nullptr}; return {nullptr};
header->Allocator = allocator; header->Allocator = allocator;
header->Capacity = capacity; header->Capacity = capacity;
@ -206,10 +203,10 @@ bool array_append_at(Array<Type>* array, Type item, usize idx)
ssize slot = idx; ssize slot = idx;
if (slot >= header->Num) if (slot >= header->Num)
slot = header->Num - 1; slot = header->Num - 1;
if (slot < 0) if (slot < 0)
slot = 0; slot = 0;
if (header->Capacity < header->Num + 1) if (header->Capacity < header->Num + 1)
{ {
@ -237,7 +234,7 @@ bool array_append_items_at(Array<Type>* array, Type* items, usize item_num, usiz
if (idx >= header->Num) if (idx >= header->Num)
{ {
return array_append_items(array, items, item_num); return array_append_items(array, items, item_num);
} }
if (item_num > header->Capacity) if (item_num > header->Capacity)
{ {
@ -361,7 +358,7 @@ bool array_reserve(Array<Type>* array, usize new_capacity)
ArrayHeader* header = array_get_header(array); ArrayHeader* header = array_get_header(array);
if (header->Capacity < new_capacity) if (header->Capacity < new_capacity)
return set_capacity(array, new_capacity); return set_capacity(array, new_capacity);
return true; return true;
} }
@ -380,7 +377,7 @@ bool array_resize(Array<Type>* array, usize num)
} }
header->Num = num; header->Num = num;
return true; return true;
} }
template<class Type> inline template<class Type> inline
@ -496,23 +493,23 @@ struct HashTable
Array<ssize> Hashes; Array<ssize> Hashes;
Array<HashTableEntry<Type>> Entries; Array<HashTableEntry<Type>> Entries;
#if GEN_SUPPORT_CPP_MEMBER_FEATURES #if ! GEN_C_LIKE_CPP
#pragma region Member Mapping #pragma region Member Mapping
forceinline static HashTable init(AllocatorInfo allocator) { return GEN_NS hashtable_init<Type>(allocator); } forceinline static HashTable init(AllocatorInfo allocator) { return hashtable_init<Type>(allocator); }
forceinline static HashTable init_reserve(AllocatorInfo allocator, usize num) { return GEN_NS hashtable_init_reserve<Type>(allocator, num); } forceinline static HashTable init_reserve(AllocatorInfo allocator, usize num) { return hashtable_init_reserve<Type>(allocator, num); }
forceinline void clear() { GEN_NS clear<Type>(*this); } forceinline void clear() { clear<Type>(*this); }
forceinline void destroy() { GEN_NS destroy<Type>(*this); } forceinline void destroy() { destroy<Type>(*this); }
forceinline Type* get(u64 key) { return GEN_NS get<Type>(*this, key); } forceinline Type* get(u64 key) { return get<Type>(*this, key); }
forceinline void grow() { GEN_NS grow<Type>(*this); } forceinline void grow() { grow<Type>(*this); }
forceinline void rehash(ssize new_num) { GEN_NS rehash<Type>(*this, new_num); } forceinline void rehash(ssize new_num) { rehash<Type>(*this, new_num); }
forceinline void rehash_fast() { GEN_NS rehash_fast<Type>(*this); } forceinline void rehash_fast() { rehash_fast<Type>(*this); }
forceinline void remove(u64 key) { GEN_NS remove<Type>(*this, key); } forceinline void remove(u64 key) { remove<Type>(*this, key); }
forceinline void remove_entry(ssize idx) { GEN_NS remove_entry<Type>(*this, idx); } forceinline void remove_entry(ssize idx) { remove_entry<Type>(*this, idx); }
forceinline void set(u64 key, Type value) { GEN_NS set<Type>(*this, key, value); } forceinline void set(u64 key, Type value) { set<Type>(*this, key, value); }
forceinline ssize slot(u64 key) { return GEN_NS slot<Type>(*this, key); } forceinline ssize slot(u64 key) { return slot<Type>(*this, key); }
forceinline void map(void (*proc)(u64, Type)) { GEN_NS map<Type>(*this, proc); } forceinline void map(void (*proc)(u64, Type)) { map<Type>(*this, proc); }
forceinline void map_mut(void (*proc)(u64, Type*)) { GEN_NS map_mut<Type>(*this, proc); } forceinline void map_mut(void (*proc)(u64, Type*)) { map_mut<Type>(*this, proc); }
#pragma endregion Member Mapping #pragma endregion Member Mapping
#endif #endif

View File

@ -6,11 +6,10 @@
#endif #endif
#pragma region Debug #pragma region Debug
GEN_API_C_BEGIN
void assert_handler( char const* condition, char const* file, s32 line, char const* msg, ... ) void assert_handler( char const* condition, char const* file, char const* function, s32 line, char const* msg, ... )
{ {
_printf_err( "%s:(%d): Assert Failure: ", file, line ); _printf_err( "%s - %s:(%d): Assert Failure: ", file, function, line );
if ( condition ) if ( condition )
_printf_err( "`%s` \n", condition ); _printf_err( "`%s` \n", condition );
@ -46,5 +45,4 @@ s32 assert_crash( char const* condition )
} }
#endif #endif
GEN_API_C_END
#pragma endregion Debug #pragma endregion Debug

View File

@ -19,14 +19,14 @@
#define GEN_ASSERT( cond ) GEN_ASSERT_MSG( cond, NULL ) #define GEN_ASSERT( cond ) GEN_ASSERT_MSG( cond, NULL )
#define GEN_ASSERT_MSG( cond, msg, ... ) \ #define GEN_ASSERT_MSG( cond, msg, ... ) \
do \ do \
{ \ { \
if ( ! ( cond ) ) \ if ( ! ( cond ) ) \
{ \ { \
assert_handler( #cond, __FILE__, scast( s64, __LINE__ ), msg, ##__VA_ARGS__ ); \ assert_handler( #cond, __FILE__, __func__, scast( s64, __LINE__ ), msg, ##__VA_ARGS__ ); \
GEN_DEBUG_TRAP(); \ GEN_DEBUG_TRAP(); \
} \ } \
} while ( 0 ) } while ( 0 )
#define GEN_ASSERT_NOT_NULL( ptr ) GEN_ASSERT_MSG( ( ptr ) != NULL, #ptr " must not be NULL" ) #define GEN_ASSERT_NOT_NULL( ptr ) GEN_ASSERT_MSG( ( ptr ) != NULL, #ptr " must not be NULL" )
@ -56,10 +56,8 @@
while (0) while (0)
#endif #endif
GEN_API_C_BEGIN void assert_handler( char const* condition, char const* file, char const* function, s32 line, char const* msg, ... );
void assert_handler( char const* condition, char const* file, s32 line, char const* msg, ... );
s32 assert_crash( char const* condition ); s32 assert_crash( char const* condition );
void process_exit( u32 code ); void process_exit( u32 code );
GEN_API_C_END
#pragma endregion Debug #pragma endregion Debug

View File

@ -4,7 +4,6 @@
#endif #endif
#pragma region File Handling #pragma region File Handling
GEN_API_C_BEGIN
#if defined( GEN_SYSTEM_WINDOWS ) || defined( GEN_SYSTEM_CYGWIN ) #if defined( GEN_SYSTEM_WINDOWS ) || defined( GEN_SYSTEM_CYGWIN )
@ -656,5 +655,4 @@ GEN_FILE_CLOSE_PROC( _memory_file_close )
FileOperations const memory_file_operations = { _memory_file_read, _memory_file_write, _memory_file_seek, _memory_file_close }; FileOperations const memory_file_operations = { _memory_file_read, _memory_file_write, _memory_file_seek, _memory_file_close };
GEN_API_C_END
#pragma endregion File Handling #pragma endregion File Handling

View File

@ -4,11 +4,8 @@
#endif #endif
#pragma region File Handling #pragma region File Handling
GEN_API_C_BEGIN
typedef u32 FileMode; enum FileModeFlag
enum FileModeFlag_Def
{ {
EFileMode_READ = bit( 0 ), EFileMode_READ = bit( 0 ),
EFileMode_WRITE = bit( 1 ), EFileMode_WRITE = bit( 1 ),
@ -16,18 +13,16 @@ enum FileModeFlag_Def
EFileMode_RW = bit( 3 ), EFileMode_RW = bit( 3 ),
GEN_FILE_MODES = EFileMode_READ | EFileMode_WRITE | EFileMode_APPEND | EFileMode_RW, GEN_FILE_MODES = EFileMode_READ | EFileMode_WRITE | EFileMode_APPEND | EFileMode_RW,
}; };
typedef enum FileModeFlag_Def FileModeFlag;
// NOTE: Only used internally and for the file operations // NOTE: Only used internally and for the file operations
enum SeekWhenceType_Def enum SeekWhenceType
{ {
ESeekWhence_BEGIN = 0, ESeekWhence_BEGIN = 0,
ESeekWhence_CURRENT = 1, ESeekWhence_CURRENT = 1,
ESeekWhence_END = 2, ESeekWhence_END = 2,
}; };
typedef enum SeekWhenceType_Def SeekWhenceType;
enum FileError_Def enum FileError
{ {
EFileError_NONE, EFileError_NONE,
EFileError_INVALID, EFileError_INVALID,
@ -40,17 +35,16 @@ enum FileError_Def
EFileError_NAME_TOO_LONG, EFileError_NAME_TOO_LONG,
EFileError_UNKNOWN, EFileError_UNKNOWN,
}; };
typedef enum FileError_Def FileError;
union FileDescriptor_Def union FileDescriptor
{ {
void* p; void* p;
sptr i; sptr i;
uptr u; uptr u;
}; };
typedef union FileDescriptor_Def FileDescriptor;
typedef struct FileOperations_Def FileOperations; typedef u32 FileMode;
typedef struct FileOperations FileOperations;
#define GEN_FILE_OPEN_PROC( name ) FileError name( FileDescriptor* fd, FileOperations* ops, FileMode mode, char const* filename ) #define GEN_FILE_OPEN_PROC( name ) FileError name( FileDescriptor* fd, FileOperations* ops, FileMode mode, char const* filename )
#define GEN_FILE_READ_AT_PROC( name ) b32 name( FileDescriptor fd, void* buffer, ssize size, s64 offset, ssize* bytes_read, b32 stop_at_newline ) #define GEN_FILE_READ_AT_PROC( name ) b32 name( FileDescriptor fd, void* buffer, ssize size, s64 offset, ssize* bytes_read, b32 stop_at_newline )
@ -64,39 +58,35 @@ typedef GEN_FILE_WRITE_AT_PROC( FileWriteProc );
typedef GEN_FILE_SEEK_PROC( FileSeekProc ); typedef GEN_FILE_SEEK_PROC( FileSeekProc );
typedef GEN_FILE_CLOSE_PROC( FileCloseProc ); typedef GEN_FILE_CLOSE_PROC( FileCloseProc );
struct FileOperations_Def struct FileOperations
{ {
FileReadProc* read_at; FileReadProc* read_at;
FileWriteProc* write_at; FileWriteProc* write_at;
FileSeekProc* seek; FileSeekProc* seek;
FileCloseProc* close; FileCloseProc* close;
}; };
typedef struct FileOperations_Def FileOperations;
extern FileOperations const default_file_operations; extern FileOperations const default_file_operations;
typedef u64 FileTime; typedef u64 FileTime;
enum DirType_Def enum DirType
{ {
GEN_DIR_TYPE_FILE, GEN_DIR_TYPE_FILE,
GEN_DIR_TYPE_FOLDER, GEN_DIR_TYPE_FOLDER,
GEN_DIR_TYPE_UNKNOWN, GEN_DIR_TYPE_UNKNOWN,
}; };
typedef enum DirType_Def DirType;
struct DirInfo_Def; struct DirInfo;
typedef struct DirInfo_Def DirInfo;
struct DirEntry_Def struct DirEntry
{ {
char const* filename; char const* filename;
DirInfo* dir_info; DirInfo* dir_info;
u8 type; u8 type;
}; };
typedef struct DirEntry_Def DirEntry;
struct DirInfo_Def struct DirInfo
{ {
char const* fullpath; char const* fullpath;
DirEntry* entries; // zpl_array DirEntry* entries; // zpl_array
@ -106,7 +96,7 @@ struct DirInfo_Def
String buf; String buf;
}; };
struct FileInfo_Def struct FileInfo
{ {
FileOperations ops; FileOperations ops;
FileDescriptor fd; FileDescriptor fd;
@ -116,9 +106,8 @@ struct FileInfo_Def
FileTime last_write_time; FileTime last_write_time;
DirEntry* dir; DirEntry* dir;
}; };
typedef struct FileInfo_Def FileInfo;
enum FileStandardType_Def enum FileStandardType
{ {
EFileStandard_INPUT, EFileStandard_INPUT,
EFileStandard_OUTPUT, EFileStandard_OUTPUT,
@ -126,7 +115,6 @@ enum FileStandardType_Def
EFileStandard_COUNT, EFileStandard_COUNT,
}; };
typedef enum FileStandardType_Def FileStandardType;
/** /**
* Get standard file I/O. * Get standard file I/O.
@ -269,7 +257,7 @@ b32 file_write_at( FileInfo* file, void const* buffer, ssize size, s64 offset );
*/ */
b32 file_write_at_check( FileInfo* file, void const* buffer, ssize size, s64 offset, ssize* bytes_written ); b32 file_write_at_check( FileInfo* file, void const* buffer, ssize size, s64 offset, ssize* bytes_written );
enum FileStreamFlags_Def enum_underlying(u32) enum FileStreamFlags : u32
{ {
/* Allows us to write to the buffer directly. Beware: you can not append a new data! */ /* Allows us to write to the buffer directly. Beware: you can not append a new data! */
EFileStream_WRITABLE = bit( 0 ), EFileStream_WRITABLE = bit( 0 ),
@ -280,7 +268,6 @@ enum FileStreamFlags_Def enum_underlying(u32)
EFileStream_UNDERLYING = GEN_U32_MAX, EFileStream_UNDERLYING = GEN_U32_MAX,
}; };
typedef enum FileStreamFlags_Def FileStreamFlags;
/** /**
* Opens a new memory stream * Opens a new memory stream
@ -396,5 +383,4 @@ b32 file_write_at_check( FileInfo* f, void const* buffer, ssize size, s64 offset
return f->ops.write_at( f->fd, buffer, size, offset, bytes_written ); return f->ops.write_at( f->fd, buffer, size, offset, bytes_written );
} }
GEN_API_C_END
#pragma endregion File Handling #pragma endregion File Handling

View File

@ -4,7 +4,6 @@
#endif #endif
#pragma region Hashing #pragma region Hashing
GEN_API_C_BEGIN
global u32 const _crc32_table[ 256 ] = { global u32 const _crc32_table[ 256 ] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd,
@ -88,5 +87,4 @@ u64 crc64( void const* data, ssize len )
return result; return result;
} }
GEN_API_C_END
#pragma endregion Hashing #pragma endregion Hashing

View File

@ -4,10 +4,8 @@
#endif #endif
#pragma region Hashing #pragma region Hashing
GEN_API_C_BEGIN
u32 crc32( void const* data, ssize len ); u32 crc32( void const* data, ssize len );
u64 crc64( void const* data, ssize len ); u64 crc64( void const* data, ssize len );
GEN_API_C_END
#pragma endregion Hashing #pragma endregion Hashing

View File

@ -19,10 +19,22 @@
#define bitfield_is_equal( Type, Field, Mask ) ( (Type(Mask) & Type(Field)) == Type(Mask) ) #define bitfield_is_equal( Type, Field, Mask ) ( (Type(Mask) & Type(Field)) == Type(Mask) )
#endif #endif
// Mainly intended for forcing the base library to utilize only C-valid constructs or type coercion
#ifndef GEN_C_LIKE_CPP
#define GEN_C_LIKE_CPP 0
#endif
#if GEN_COMPILER_CPP #if GEN_COMPILER_CPP
# ifndef cast # ifndef cast
# define cast( type, value ) (tmpl_cast<type>( value )) # define cast( type, value ) (tmpl_cast<type>( value ))
# endif # endif
#else
# ifndef cast
# define cast( type, value ) ( (type)(value) )
# endif
#endif
#if GEN_COMPILER_CPP
# ifndef ccast # ifndef ccast
# define ccast( type, value ) ( const_cast< type >( (value) ) ) # define ccast( type, value ) ( const_cast< type >( (value) ) )
# endif # endif
@ -36,9 +48,6 @@
# define scast( type, value ) static_cast< type >( value ) # define scast( type, value ) static_cast< type >( value )
# endif # endif
#else #else
# ifndef cast
# define cast( type, value ) ( (type)(value) )
# endif
# ifndef ccast # ifndef ccast
# define ccast( type, value ) ( (type)(value) ) # define ccast( type, value ) ( (type)(value) )
# endif # endif
@ -210,22 +219,6 @@
# error "No thread local support" # error "No thread local support"
#endif #endif
#if !defined(GEN_SUPPORT_CPP_REFERENCES)
# define GEN_SUPPORT_CPP_REFERENCES 1
#endif
#if GEN_COMPILER_C && defined(GEN_SUPPORT_CPP_REFERENCES)
# undef GEN_SUPPORT_CPP_REFERENCES
# define GEN_SUPPORT_CPP_REFERENCES 0
#endif
#if !defined(GEN_SUPPORT_CPP_MEMBER_FEATURES)
# define GEN_SUPPORT_CPP_MEMBER_FEATURES 1
#endif
#if GEN_COMPILER_C && defined(GEN_SUPPORT_CPP_MEMBER_FEATURES)
# undef GEN_SUPPORT_CPP_MEMBER_FEATURES
# define GEN_SUPPORT_CPP_MEMBER_FEATURES 0
#endif
#if ! defined(typeof) && (!GEN_COMPILER_C || __STDC_VERSION__ < 202311L) #if ! defined(typeof) && (!GEN_COMPILER_C || __STDC_VERSION__ < 202311L)
# if ! GEN_COMPILER_C # if ! GEN_COMPILER_C
# define typeof decltype # define typeof decltype
@ -239,12 +232,12 @@
#endif #endif
#ifndef GEN_API_C_BEGIN #ifndef GEN_API_C_BEGIN
# if GEN_COMPILER_C || (GEN_COMPILER_CPP && GEN_SUPPORT_CPP_REFERENCES) # if GEN_COMPILER_C
# define GEN_API_C_BEGIN # define GEN_API_C_BEGIN
# define GEN_API_C_END # define GEN_API_C_END
# else # else
# define GEN_API_C_BEGIN extern "C" { # define GEN_API_C_BEGIN extern "C" {
# define GEN_API_C_END } # define GEN_API_C_END }
# endif # endif
#endif #endif
@ -280,6 +273,16 @@
#define struct_init(type, value) {value} #define struct_init(type, value) {value}
#endif #endif
#if 0
#ifndef GEN_OPTIMIZE_MAPPINGS_BEGIN
# define GEN_OPTIMIZE_MAPPINGS_BEGIN _pragma(optimize("gt", on))
# define GEN_OPITMIZE_MAPPINGS_END _pragma(optimize("", on))
#endif
#else
# define GEN_OPTIMIZE_MAPPINGS_BEGIN
# define GEN_OPITMIZE_MAPPINGS_END
#endif
#if GEN_COMPILER_C #if GEN_COMPILER_C
// ------------------------ _Generic function overloading ----------------------------------------- // ------------------------ _Generic function overloading -----------------------------------------
// This implemnents macros for utilizing "The Naive Extendible _Generic Macro" explained in: // This implemnents macros for utilizing "The Naive Extendible _Generic Macro" explained in:
@ -295,12 +298,7 @@
// Helper macros for argument selection // Helper macros for argument selection
#define GEN_SELECT_ARG_1( _1, ... ) _1 // <-- Of all th args passed pick _1. #define GEN_SELECT_ARG_1( _1, ... ) _1 // <-- Of all th args passed pick _1.
#define GEN_SELECT_ARG_2( _1, _2, ... ) _2 // <-- Of all the args passed pick _2. #define GEN_SELECT_ARG_2( _1, _2, ... ) _2 // <-- Of all the args passed pick _2.
#define GEN_SELECT_ARG_3( _1, _2, _3, ... ) _3 // etc.. (by induction until _8, which we don't support any more beyond) #define GEN_SELECT_ARG_3( _1, _2, _3, ... ) _3 // etc..
// #define GEN_SELECT_ARG_4( _1, _2, _3, _4, ... ) _4
// #define GEN_SELECT_ARG_5( _1, _2, _3, _4, _5, ... ) _5
// #define GEN_SELECT_ARG_6( _1, _2, _3, _4, _5, _6, ... ) _6
// #define GEN_SELECT_ARG_7( _1, _2, _3, _4, _5, _6, _7, ... ) _7
// #define GEN_SELECT_ARG_8( _1, _2, _3, _4, _5, _6, _7, _8, ... ) _8
#define GEN_GENERIC_SEL_ENTRY_TYPE GEN_SELECT_ARG_1 // Use the arg expansion macro to select arg 1 which should have the type. #define GEN_GENERIC_SEL_ENTRY_TYPE GEN_SELECT_ARG_1 // Use the arg expansion macro to select arg 1 which should have the type.
#define GEN_GENERIC_SEL_ENTRY_FUNCTION GEN_SELECT_ARG_2 // Use the arg expansion macro to select arg 2 which should have the function. #define GEN_GENERIC_SEL_ENTRY_FUNCTION GEN_SELECT_ARG_2 // Use the arg expansion macro to select arg 2 which should have the function.
@ -314,27 +312,27 @@
// Expands to ',' if it can find (type): (function) <comma_operator: ',' > // Expands to ',' if it can find (type): (function) <comma_operator: ',' >
// Where GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER is specifically looking for that <comma> , // Where GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER is specifically looking for that <comma> ,
#define GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( slot_exp ) GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER( slot_exp, GEN_GENERIC_SEL_ENTRY_TYPE( slot_exp, ): GEN_GENERIC_SEL_ENTRY_FUNCTION( slot_exp, ) GEN_COMMA_OPERATOR, , ) #define GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( slot_exp ) GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER( slot_exp, GEN_GENERIC_SEL_ENTRY_TYPE( slot_exp, ): GEN_GENERIC_SEL_ENTRY_FUNCTION( slot_exp, ) GEN_COMMA_OPERATOR, , )
// ^ Selects the comma ^ is the type ^ is the function ^ Insert a comma // ^ Selects the comma ^ is the type ^ is the function ^ Insert a comma
// The slot won't exist if that comma is not found. | // The slot won't exist if that comma is not found. |
// | // |
// This is the same as above but it does not insert a comma V no comma here. // This is the same as above but it does not insert a comma V no comma here.
#define GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT_LAST( slot_exp ) GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER( slot_exp, GEN_GENERIC_SEL_ENTRY_TYPE( slot_exp, ): GEN_GENERIC_SEL_ENTRY_FUNCTION( slot_exp, ), , ) #define GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT_LAST( slot_exp ) GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER( slot_exp, GEN_GENERIC_SEL_ENTRY_TYPE( slot_exp, ): GEN_GENERIC_SEL_ENTRY_FUNCTION( slot_exp, ), , )
// Needed for the last slot as they don't allow trailing commas. // Needed for the last slot as they don't allow trailing commas.
// ---------------------------------------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------------------------
// Below are generated on demand for an overlaod depdendent on a type: // Below are generated on demand for an overlaod depdendent on a type:
// ---------------------------------------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------------------------
#define GEN_FUNCTION_GENERIC_EXAMPLE( selector_arg ) _Generic( \ #define GEN_FUNCTION_GENERIC_EXAMPLE( selector_arg ) _Generic( \
(selector_arg), /* Select Via Expression*/ \ (selector_arg), /* Select Via Expression*/ \
/* Extendibility slots: */ \ /* Extendibility slots: */ \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \ GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \ GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \ GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \ GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \ GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \ GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \ GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT_LAST(FunctionID__ARGS_SIG_1 ) \ GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT_LAST(FunctionID__ARGS_SIG_1 ) \
) GEN_RESOLVED_FUNCTION_CALL( selector_arg ) ) GEN_RESOLVED_FUNCTION_CALL( selector_arg )
// ---------------------------------------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------------------------
@ -357,17 +355,17 @@ size_t gen_example_hash__P_long_long( long long val ) { return val * 2654435761u
// If using an Editor with support for syntax hightlighting macros: HASH__ARGS_SIG_1 and HASH_ARGS_SIG_2 should show color highlighting indicating the slot is enabled, // If using an Editor with support for syntax hightlighting macros: HASH__ARGS_SIG_1 and HASH_ARGS_SIG_2 should show color highlighting indicating the slot is enabled,
// or, "defined" for usage during the compilation pass that handles the _Generic instrinsic. // or, "defined" for usage during the compilation pass that handles the _Generic instrinsic.
#define hash( function_arguments ) _Generic( \ #define hash( function_arguments ) _Generic( \
(function_arguments), /* Select Via Expression*/ \ (function_arguments), /* Select Via Expression*/ \
/* Extendibility slots: */ \ /* Extendibility slots: */ \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_1 ) \ GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_1 ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_2 ) \ GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_2 ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_3 ) \ GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_3 ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_4 ) \ GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_4 ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_5 ) \ GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_5 ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_6 ) \ GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_6 ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_7 ) \ GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_7 ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT_LAST( HASH__ARGS_SIG_8 ) \ GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT_LAST( HASH__ARGS_SIG_8 ) \
) GEN_RESOLVED_FUNCTION_CALL( function_arguments ) ) GEN_RESOLVED_FUNCTION_CALL( function_arguments )
// Additional Variations: // Additional Variations:
@ -392,6 +390,7 @@ size_t gen_example_hash__P_long_long( long long val ) { return val * 2654435761u
// typedef void* GEN_GenericExampleType; // typedef void* GEN_GenericExampleType;
// GEN_FUNCTION_GENERIC_EXAMPLE_DIRECT_TYPE( GEN_GenericExampleType ); // GEN_FUNCTION_GENERIC_EXAMPLE_DIRECT_TYPE( GEN_GenericExampleType );
// END OF ------------------------ _Generic function overloading ----------------------------------------- END OF // END OF ------------------------ _Generic function overloading ----------------------------------------- END OF
#endif #endif

View File

@ -4,13 +4,12 @@
#endif #endif
#pragma region Memory #pragma region Memory
GEN_API_C_BEGIN
void* mem_copy( void* dest, void const* source, ssize n ) void* mem_copy( void* dest, void const* source, ssize n )
{ {
if ( dest == NULL ) if ( dest == nullptr )
{ {
return NULL; return nullptr;
} }
return memcpy( dest, source, n ); return memcpy( dest, source, n );
@ -518,5 +517,4 @@ void pool_clear(Pool* pool)
pool->FreeList = pool->PhysicalStart; pool->FreeList = pool->PhysicalStart;
} }
GEN_API_C_END
#pragma endregion Memory #pragma endregion Memory

View File

@ -22,8 +22,6 @@ void swap( Type& a, Type& b )
b = tmp; b = tmp;
} }
GEN_API_C_BEGIN
//! Checks if value is power of 2. //! Checks if value is power of 2.
b32 is_power_of_two( ssize x ); b32 is_power_of_two( ssize x );
@ -64,23 +62,21 @@ void zero_size( void* ptr, ssize size );
//! Clears up an array. //! Clears up an array.
#define zero_array( a, count ) zero_size( ( a ), size_of( *( a ) ) * count ) #define zero_array( a, count ) zero_size( ( a ), size_of( *( a ) ) * count )
enum AllocType_Def //enum_underlying(u8) enum AllocType : u8
{ {
EAllocation_ALLOC, EAllocation_ALLOC,
EAllocation_FREE, EAllocation_FREE,
EAllocation_FREE_ALL, EAllocation_FREE_ALL,
EAllocation_RESIZE, EAllocation_RESIZE,
}; };
typedef enum AllocType_Def AllocType;
typedef void*(AllocatorProc)( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ); typedef void*(AllocatorProc)( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
struct AllocatorInfo_Def struct AllocatorInfo
{ {
AllocatorProc* Proc; AllocatorProc* Proc;
void* Data; void* Data;
}; };
typedef struct AllocatorInfo_Def AllocatorInfo;
enum AllocFlag enum AllocFlag
{ {
@ -144,12 +140,11 @@ constexpr AllocatorInfo heap( void ) { AllocatorInfo allocator = { heap_allocato
//! Helper to free memory allocated by heap allocator. //! Helper to free memory allocated by heap allocator.
#define mfree( ptr ) free( heap(), ptr ) #define mfree( ptr ) free( heap(), ptr )
struct VirtualMemory_Def struct VirtualMemory
{ {
void* data; void* data;
ssize size; ssize size;
}; };
typedef struct VirtualMemory_Def VirtualMemory;
//! Initialize virtual memory from existing data. //! Initialize virtual memory from existing data.
VirtualMemory vm_from_memory( void* data, ssize size ); VirtualMemory vm_from_memory( void* data, ssize size );
@ -173,8 +168,7 @@ b32 vm_purge( VirtualMemory vm );
ssize virtual_memory_page_size( ssize* alignment_out ); ssize virtual_memory_page_size( ssize* alignment_out );
#pragma region Arena #pragma region Arena
struct Arena_Def; struct Arena;
typedef struct Arena_Def Arena;
AllocatorInfo arena_allocator_info( Arena* arena ); AllocatorInfo arena_allocator_info( Arena* arena );
@ -191,7 +185,7 @@ void arena_check (Arena* arena);
void arena_free (Arena* arena); void arena_free (Arena* arena);
ssize arena_size_remaining(Arena* arena, ssize alignment); ssize arena_size_remaining(Arena* arena, ssize alignment);
struct Arena_Def struct Arena
{ {
AllocatorInfo Backing; AllocatorInfo Backing;
void* PhysicalStart; void* PhysicalStart;
@ -199,17 +193,17 @@ struct Arena_Def
ssize TotalUsed; ssize TotalUsed;
ssize TempCount; ssize TempCount;
#if GEN_SUPPORT_CPP_MEMBER_FEATURES #if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
#pragma region Member Mapping #pragma region Member Mapping
forceinline operator AllocatorInfo() { return GEN_NS arena_allocator_info(this); } forceinline operator AllocatorInfo() { return arena_allocator_info(this); }
forceinline static void* allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ) { return GEN_NS arena_allocator_proc( allocator_data, type, size, alignment, old_memory, old_size, flags ); } forceinline static void* allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ) { return arena_allocator_proc( allocator_data, type, size, alignment, old_memory, old_size, flags ); }
forceinline static Arena init_from_memory( void* start, ssize size ) { return GEN_NS arena_init_from_memory( start, size ); } forceinline static Arena init_from_memory( void* start, ssize size ) { return arena_init_from_memory( start, size ); }
forceinline static Arena init_from_allocator( AllocatorInfo backing, ssize size ) { return GEN_NS arena_init_from_allocator( backing, size ); } forceinline static Arena init_from_allocator( AllocatorInfo backing, ssize size ) { return arena_init_from_allocator( backing, size ); }
forceinline static Arena init_sub( Arena& parent, ssize size ) { return GEN_NS arena_init_from_allocator( parent.Backing, size ); } forceinline static Arena init_sub( Arena& parent, ssize size ) { return arena_init_from_allocator( parent.Backing, size ); }
forceinline ssize alignment_of( ssize alignment ) { return GEN_NS arena_alignment_of(this, alignment); } forceinline ssize alignment_of( ssize alignment ) { return arena_alignment_of(this, alignment); }
forceinline void free() { return GEN_NS arena_free(this); } forceinline void free() { return arena_free(this); }
forceinline ssize size_remaining( ssize alignment ) { return GEN_NS arena_size_remaining(this, alignment); } forceinline ssize size_remaining( ssize alignment ) { return arena_size_remaining(this, alignment); }
// This id is defined by Unreal for asserts // This id is defined by Unreal for asserts
#pragma push_macro("check") #pragma push_macro("check")
@ -221,8 +215,7 @@ struct Arena_Def
#endif #endif
}; };
#if GEN_SUPPORT_CPP_REFERENCES #if GEN_COMPILER_CPP
GEN_API_C_END
forceinline AllocatorInfo allocator_info(Arena& arena ) { return arena_allocator_info(& arena); } forceinline AllocatorInfo allocator_info(Arena& arena ) { return arena_allocator_info(& arena); }
forceinline Arena init_sub (Arena& parent, ssize size) { return arena_init_sub( & parent, size); } forceinline Arena init_sub (Arena& parent, ssize size) { return arena_init_sub( & parent, size); }
forceinline ssize alignment_of (Arena& arena, ssize alignment) { return arena_alignment_of( & arena, alignment); } forceinline ssize alignment_of (Arena& arena, ssize alignment) { return arena_alignment_of( & arena, alignment); }
@ -234,7 +227,6 @@ forceinline ssize size_remaining(Arena& arena, ssize alignment) { return
#undef check #undef check
forceinline void check(Arena& arena) { return arena_check(& arena); }; forceinline void check(Arena& arena) { return arena_check(& arena); };
#pragma pop_macro("check") #pragma pop_macro("check")
GEN_API_C_BEGIN
#endif #endif
@ -320,8 +312,6 @@ ssize arena_size_remaining(Arena* arena, ssize alignment)
} }
#pragma endregion Arena #pragma endregion Arena
GEN_API_C_END
#pragma region FixedArena #pragma region FixedArena
template<s32 Size> template<s32 Size>
struct FixedArena; struct FixedArena;
@ -330,7 +320,7 @@ template<s32 Size> FixedArena<Size> fixed_arena_init();
template<s32 Size> AllocatorInfo fixed_arena_allocator_info(FixedArena<Size>* fixed_arena ); template<s32 Size> AllocatorInfo fixed_arena_allocator_info(FixedArena<Size>* fixed_arena );
template<s32 Size> ssize fixed_arena_size_remaining(FixedArena<Size>* fixed_arena, ssize alignment); template<s32 Size> ssize fixed_arena_size_remaining(FixedArena<Size>* fixed_arena, ssize alignment);
#if GEN_SUPPORT_CPP_REFERENCES #if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
template<s32 Size> AllocatorInfo allocator_info( FixedArena<Size>& fixed_arena ) { return allocator_info(& fixed_arena); } template<s32 Size> AllocatorInfo allocator_info( FixedArena<Size>& fixed_arena ) { return allocator_info(& fixed_arena); }
template<s32 Size> ssize size_remaining(FixedArena<Size>& fixed_arena, ssize alignment) { return size_remaining( & fixed_arena, alignment); } template<s32 Size> ssize size_remaining(FixedArena<Size>& fixed_arena, ssize alignment) { return size_remaining( & fixed_arena, alignment); }
#endif #endif
@ -343,12 +333,12 @@ struct FixedArena
char memory[Size]; char memory[Size];
Arena arena; Arena arena;
#if GEN_SUPPORT_CPP_MEMBER_FEATURES #if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
#pragma region Member Mapping #pragma region Member Mapping
forceinline operator AllocatorInfo() { return GEN_NS allocator_info(this); } forceinline operator AllocatorInfo() { return GEN_NS allocator_info(this); }
forceinline static FixedArena init() { FixedArena result; GEN_NS fixed_arena_init<Size>(result); return result; } forceinline static FixedArena init() { FixedArena result; fixed_arena_init<Size>(result); return result; }
forceinline ssize size_remaining(ssize alignment) { GEN_NS size_remaining(this, alignment); } forceinline ssize size_remaining(ssize alignment) { fixed_arena_size_remaining(this, alignment); }
#pragma endregion Member Mapping #pragma endregion Member Mapping
#endif #endif
}; };
@ -389,11 +379,8 @@ using Arena_2MB = FixedArena< megabytes( 2 ) >;
using Arena_4MB = FixedArena< megabytes( 4 ) >; using Arena_4MB = FixedArena< megabytes( 4 ) >;
#pragma endregion FixedArena #pragma endregion FixedArena
GEN_API_C_BEGIN
#pragma region Pool #pragma region Pool
struct Pool_Def; struct Pool;
typedef struct Pool_Def Pool;
void* pool_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags); void* pool_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags);
@ -403,15 +390,13 @@ AllocatorInfo pool_allocator_info(Pool* pool);
void pool_clear(Pool* pool); void pool_clear(Pool* pool);
void pool_free(Pool* pool); void pool_free(Pool* pool);
#if GEN_SUPPORT_CPP_REFERENCES #if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
GEN_API_C_END
AllocatorInfo allocator_info(Pool& pool) { return pool_allocator_info(& pool); } AllocatorInfo allocator_info(Pool& pool) { return pool_allocator_info(& pool); }
void clear(Pool& pool) { return pool_clear(& pool); } void clear(Pool& pool) { return pool_clear(& pool); }
void free(Pool& pool) { return pool_free(& pool); } void free(Pool& pool) { return pool_free(& pool); }
GEN_API_C_BEGIN
#endif #endif
struct Pool_Def struct Pool
{ {
AllocatorInfo Backing; AllocatorInfo Backing;
void* PhysicalStart; void* PhysicalStart;
@ -421,15 +406,15 @@ struct Pool_Def
ssize TotalSize; ssize TotalSize;
ssize NumBlocks; ssize NumBlocks;
#if GEN_SUPPORT_CPP_MEMBER_FEATURES #if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
#pragma region Member Mapping #pragma region Member Mapping
forceinline operator AllocatorInfo() { return GEN_NS pool_allocator_info(this); } forceinline operator AllocatorInfo() { return pool_allocator_info(this); }
forceinline static void* allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags) { return GEN_NS pool_allocator_proc(allocator_data, type, size, alignment, old_memory, old_size, flags); } forceinline static void* allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags) { return pool_allocator_proc(allocator_data, type, size, alignment, old_memory, old_size, flags); }
forceinline static Pool init(AllocatorInfo backing, ssize num_blocks, ssize block_size) { return GEN_NS pool_init(backing, num_blocks, block_size); } forceinline static Pool init(AllocatorInfo backing, ssize num_blocks, ssize block_size) { return pool_init(backing, num_blocks, block_size); }
forceinline static Pool init_align(AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align) { return GEN_NS pool_init_align(backing, num_blocks, block_size, block_align); } forceinline static Pool init_align(AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align) { return pool_init_align(backing, num_blocks, block_size, block_align); }
forceinline void clear() { GEN_NS pool_clear( this); } forceinline void clear() { pool_clear( this); }
forceinline void free() { GEN_NS pool_free( this); } forceinline void free() { pool_free( this); }
#pragma endregion #pragma endregion
#endif #endif
}; };
@ -442,14 +427,14 @@ AllocatorInfo pool_allocator_info(Pool* pool) {
inline inline
Pool pool_init(AllocatorInfo backing, ssize num_blocks, ssize block_size) { Pool pool_init(AllocatorInfo backing, ssize num_blocks, ssize block_size) {
return pool_init_align(backing, num_blocks, block_size, GEN_DEFAULT_MEMORY_ALIGNMENT); return pool_init_align(backing, num_blocks, block_size, GEN_DEFAULT_MEMORY_ALIGNMENT);
} }
inline inline
void pool_free(Pool* pool) { void pool_free(Pool* pool) {
if(pool->Backing.Proc) { if(pool->Backing.Proc) {
allocator_free(pool->Backing, pool->PhysicalStart); allocator_free(pool->Backing, pool->PhysicalStart);
} }
} }
#pragma endregion Pool #pragma endregion Pool
@ -684,6 +669,4 @@ void zero_size( void* ptr, ssize size ) {
mem_set( ptr, 0, size ); mem_set( ptr, 0, size );
} }
GEN_API_C_END
#pragma endregion Memory #pragma endregion Memory

View File

@ -4,7 +4,6 @@
#endif #endif
#pragma region ADT #pragma region ADT
GEN_API_C_BEGIN
#define _adt_fprintf( s_, fmt_, ... ) \ #define _adt_fprintf( s_, fmt_, ... ) \
do \ do \
@ -1112,5 +1111,4 @@ String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delimi
return output; return output;
} }
GEN_API_C_END
#pragma endregion CSV #pragma endregion CSV

View File

@ -3,7 +3,6 @@
#endif #endif
#pragma region ADT #pragma region ADT
GEN_API_C_BEGIN
enum ADT_Type : u32 enum ADT_Type : u32
{ {
@ -430,5 +429,4 @@ String csv_write_string( AllocatorInfo a, CSV_Object* obj )
return csv_write_string_delimiter( a, obj, ',' ); return csv_write_string_delimiter( a, obj, ',' );
} }
GEN_API_C_END
#pragma endregion CSV #pragma endregion CSV

View File

@ -76,17 +76,20 @@
/* Platform compiler */ /* Platform compiler */
#if defined( _MSC_VER ) #if defined( _MSC_VER )
# define GEN_COMPILER_CLANG 0 # pragma message("Detected MSVC")
// # define GEN_COMPILER_CLANG 0
# define GEN_COMPILER_MSVC 1 # define GEN_COMPILER_MSVC 1
# define GEN_COMPILER_GCC 0 // # define GEN_COMPILER_GCC 0
#elif defined( __GNUC__ ) #elif defined( __GNUC__ )
# define GEN_COMPILER_CLANG 0 # pragma message("Detected GCC")
# define GEN_COMPILER_MSVC 0 // # define GEN_COMPILER_CLANG 0
// # define GEN_COMPILER_MSVC 0
# define GEN_COMPILER_GCC 1 # define GEN_COMPILER_GCC 1
#elif defined( __clang__ ) #elif defined( __clang__ )
# pragma message("Detected CLANG")
# define GEN_COMPILER_CLANG 1 # define GEN_COMPILER_CLANG 1
# define GEN_COMPILER_MSVC 0 // # define GEN_COMPILER_MSVC 0
# define GEN_COMPILER_GCC 1 // # define GEN_COMPILER_GCC 0
#else #else
# error Unknown compiler # error Unknown compiler
#endif #endif

View File

@ -6,7 +6,6 @@
#endif #endif
#pragma region Printing #pragma region Printing
GEN_API_C_BEGIN
enum enum
{ {
@ -598,5 +597,4 @@ ssize str_fmt_out_err( char const* fmt, ... )
return res; return res;
} }
GEN_API_C_END
#pragma endregion Printing #pragma endregion Printing

View File

@ -5,9 +5,7 @@
#pragma region Printing #pragma region Printing
GEN_API_C_BEGIN typedef struct FileInfo FileInfo;
typedef struct FileInfo_Def FileInfo;
#ifndef GEN_PRINTF_MAXLEN #ifndef GEN_PRINTF_MAXLEN
# define GEN_PRINTF_MAXLEN kilobytes(128) # define GEN_PRINTF_MAXLEN kilobytes(128)
@ -41,6 +39,4 @@ ssize log_fmt(char const* fmt, ...)
return res; return res;
} }
GEN_API_C_END
#pragma endregion Printing #pragma endregion Printing

View File

@ -5,7 +5,6 @@
#endif #endif
#pragma region String Ops #pragma region String Ops
GEN_API_C_BEGIN
internal internal
ssize _scan_zpl_i64( const char* text, s32 base, s64* value ) ssize _scan_zpl_i64( const char* text, s32 base, s64* value )
@ -213,5 +212,4 @@ f64 str_to_f64( const char* str, char** end_ptr )
return result; return result;
} }
GEN_API_C_END
#pragma endregion String Ops #pragma endregion String Ops

View File

@ -5,8 +5,6 @@
#pragma region String Ops #pragma region String Ops
GEN_API_C_BEGIN
const char* char_first_occurence( const char* str, char c ); const char* char_first_occurence( const char* str, char c );
b32 char_is_alpha( char c ); b32 char_is_alpha( char c );
@ -286,6 +284,4 @@ void str_to_upper( char* str )
} }
} }
GEN_API_C_END
#pragma endregion String Ops #pragma endregion String Ops

View File

@ -4,7 +4,6 @@
#endif #endif
#pragma region String #pragma region String
GEN_API_C_BEGIN
String string_make_length( AllocatorInfo allocator, char const* str, ssize length ) String string_make_length( AllocatorInfo allocator, char const* str, ssize length )
{ {
@ -54,5 +53,4 @@ String string_make_reserve( AllocatorInfo allocator, ssize capacity )
return result; return result;
} }
GEN_API_C_END
#pragma endregion String #pragma endregion String

View File

@ -5,10 +5,7 @@
#pragma region Strings #pragma region Strings
GEN_API_C_BEGIN struct StrC;
struct StrC_Def;
typedef struct StrC_Def StrC;
bool strc_are_equal (StrC lhs, StrC rhs); bool strc_are_equal (StrC lhs, StrC rhs);
char const* strc_back (StrC str); char const* strc_back (StrC str);
@ -18,10 +15,8 @@ b32 strc_starts_with (StrC str, StrC substring);
StrC strc_to_str (char const* bad_string); StrC strc_to_str (char const* bad_string);
StrC strc_visualize_whitespace(StrC str, AllocatorInfo allocator); StrC strc_visualize_whitespace(StrC str, AllocatorInfo allocator);
GEN_API_C_END
// Constant string with length. // Constant string with length.
struct StrC_Def struct StrC
{ {
ssize Len; ssize Len;
char const* Ptr; char const* Ptr;
@ -30,13 +25,13 @@ struct StrC_Def
forceinline operator char const* () const { return Ptr; } forceinline operator char const* () const { return Ptr; }
forceinline char const& operator[]( ssize index ) const { return Ptr[index]; } forceinline char const& operator[]( ssize index ) const { return Ptr[index]; }
#if GEN_SUPPORT_CPP_MEMBER_FEATURES #if ! GEN_C_LIKE_CPP
forceinline bool is_equal (StrC rhs) const { return GEN_NS strc_are_equal(* this, rhs); } forceinline bool is_equal (StrC rhs) const { return strc_are_equal(* this, rhs); }
forceinline char const* back () const { return GEN_NS strc_back(* this); } forceinline char const* back () const { return strc_back(* this); }
forceinline bool contains (StrC substring) const { return GEN_NS strc_contains(* this, substring); } forceinline bool contains (StrC substring) const { return strc_contains(* this, substring); }
forceinline StrC duplicate (AllocatorInfo allocator) const { return GEN_NS strc_duplicate(* this, allocator); } forceinline StrC duplicate (AllocatorInfo allocator) const { return strc_duplicate(* this, allocator); }
forceinline b32 starts_with (StrC substring) const { return GEN_NS strc_starts_with(* this, substring); } forceinline b32 starts_with (StrC substring) const { return strc_starts_with(* this, substring); }
forceinline StrC visualize_whitespace(AllocatorInfo allocator) const { return GEN_NS strc_visualize_whitespace(* this, allocator); } forceinline StrC visualize_whitespace(AllocatorInfo allocator) const { return strc_visualize_whitespace(* this, allocator); }
#endif #endif
#endif #endif
}; };
@ -63,8 +58,6 @@ forceinline char const* end (StrC str) { return str.Ptr + str
forceinline char const* next (StrC str, char const* iter) { return iter + 1; } forceinline char const* next (StrC str, char const* iter) { return iter + 1; }
#endif #endif
GEN_API_C_BEGIN
inline inline
bool strc_are_equal(StrC lhs, StrC rhs) bool strc_are_equal(StrC lhs, StrC rhs)
{ {
@ -113,24 +106,20 @@ StrC to_strc_from_c_str( char const* bad_str ) {
StrC result = { str_len( bad_str ), bad_str }; StrC result = { str_len( bad_str ), bad_str };
return result; return result;
} }
GEN_API_C_END
// Dynamic String // Dynamic String
// This is directly based off the ZPL string api. // This is directly based off the ZPL string api.
// They used a header pattern // They used a header pattern
// I kept it for simplicty of porting but its not necessary to keep it that way. // I kept it for simplicty of porting but its not necessary to keep it that way.
#pragma region String #pragma region String
struct StringHeader_Def; struct StringHeader;
typedef struct StringHeader_Def StringHeader;
#if GEN_COMPILER_C || ! GEN_SUPPORT_CPP_MEMBER_FEATURES #if GEN_COMPILER_C
typedef char* String; typedef char* String;
#else #else
struct String; struct String;
#endif #endif
GEN_API_C_BEGIN
forceinline usize string_grow_formula(usize value); forceinline usize string_grow_formula(usize value);
String string_make_c_str (AllocatorInfo allocator, char const* str); String string_make_c_str (AllocatorInfo allocator, char const* str);
@ -168,15 +157,13 @@ void string_trim (String str, char const* cut_set)
void string_trim_space (String str); void string_trim_space (String str);
String string_visualize_whitespace(String const str); String string_visualize_whitespace(String const str);
GEN_API_C_END struct StringHeader {
struct StringHeader_Def {
AllocatorInfo Allocator; AllocatorInfo Allocator;
ssize Capacity; ssize Capacity;
ssize Length; ssize Length;
}; };
#if GEN_COMPILER_CPP && GEN_SUPPORT_CPP_MEMBER_FEATURES #if GEN_COMPILER_CPP
struct String struct String
{ {
char* Data; char* Data;
@ -203,6 +190,7 @@ struct String
friend forceinline bool operator==(std::nullptr_t, const String str) { return str.Data == nullptr; } friend forceinline bool operator==(std::nullptr_t, const String str) { return str.Data == nullptr; }
friend forceinline bool operator!=(std::nullptr_t, const String str) { return str.Data != nullptr; } friend forceinline bool operator!=(std::nullptr_t, const String str) { return str.Data != nullptr; }
#if ! GEN_C_LIKE_CPP
forceinline char* begin() const { return Data; } forceinline char* begin() const { return Data; }
forceinline char* end() const { return Data + string_length(* this); } forceinline char* end() const { return Data + string_length(* this); }
@ -273,22 +261,21 @@ struct String
return string_append_c_str_len(this, buf, res); return string_append_c_str_len(this, buf, res);
} }
#pragma endregion Member Mapping #pragma endregion Member Mapping
#endif
}; };
#endif #endif
GEN_API_C_BEGIN
forceinline char* string_begin(String str) { return ((char*) str); } forceinline char* string_begin(String str) { return ((char*) str); }
forceinline char* string_end (String str) { return ((char*) str + string_length(str)); } forceinline char* string_end (String str) { return ((char*) str + string_length(str)); }
forceinline char* string_next (String str, char const* iter) { return ((char*) iter + 1); } forceinline char* string_next (String str, char const* iter) { return ((char*) iter + 1); }
GEN_API_C_END
#if GEN_COMPILER_CPP && 0 #if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
forceinline char* begin(String str) { return ((char*) str); } forceinline char* begin(String str) { return ((char*) str); }
forceinline char* end (String str) { return ((char*) str + string_length(str)); } forceinline char* end (String str) { return ((char*) str + string_length(str)); }
forceinline char* next (String str, char* iter) { return ((char*) iter + 1); } forceinline char* next (String str, char* iter) { return ((char*) iter + 1); }
#endif #endif
#if GEN_SUPPORT_CPP_REFERENCES #if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
forceinline bool make_space_for(String& str, char const* to_append, ssize add_len); forceinline bool make_space_for(String& str, char const* to_append, ssize add_len);
forceinline bool append(String& str, char c); forceinline bool append(String& str, char c);
forceinline bool append(String& str, char const* str_to_append); forceinline bool append(String& str, char const* str_to_append);
@ -301,8 +288,6 @@ forceinline void clear(String& str);
forceinline void free(String& str); forceinline void free(String& str);
#endif #endif
GEN_API_C_BEGIN
forceinline forceinline
usize string_grow_formula(usize value) { usize string_grow_formula(usize value) {
// Using a very aggressive growth formula to reduce time mem_copying with recursive calls to append in this library. // Using a very aggressive growth formula to reduce time mem_copying with recursive calls to append in this library.
@ -499,18 +484,18 @@ bool string_contains_string(String const str, String const substring)
forceinline forceinline
ssize string_capacity(String const str) { ssize string_capacity(String const str) {
StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
return header->Capacity; return header->Capacity;
} }
forceinline forceinline
void string_clear(String str) { void string_clear(String str) {
string_get_header(str)->Length = 0; string_get_header(str)->Length = 0;
} }
forceinline forceinline
String string_duplicate(String const str, AllocatorInfo allocator) { String string_duplicate(String const str, AllocatorInfo allocator) {
return string_make_length(allocator, str, string_length(str)); return string_make_length(allocator, str, string_length(str));
} }
forceinline forceinline
@ -525,14 +510,14 @@ void string_free(String* str) {
forceinline forceinline
StringHeader* string_get_header(String str) { StringHeader* string_get_header(String str) {
return (StringHeader*)(scast(char*, str) - sizeof(StringHeader)); return (StringHeader*)(scast(char*, str) - sizeof(StringHeader));
} }
forceinline forceinline
ssize string_length(String const str) ssize string_length(String const str)
{ {
StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
return header->Length; return header->Length;
} }
inline inline
@ -597,7 +582,7 @@ void string_skip_line(String str)
#define current (*scanner) #define current (*scanner)
char* scanner = str; char* scanner = str;
while (current != '\r' && current != '\n') { while (current != '\r' && current != '\n') {
++scanner; ++scanner;
} }
s32 new_length = scanner - str; s32 new_length = scanner - str;
@ -616,23 +601,22 @@ void string_skip_line(String str)
inline inline
void strip_space(String str) void strip_space(String str)
{ {
char* write_pos = str; char* write_pos = str;
char* read_pos = str; char* read_pos = str;
while (* read_pos)
{
if (! char_is_space(* read_pos))
{
* write_pos = * read_pos;
write_pos++;
}
read_pos++;
}
while (* read_pos)
{
if (! char_is_space(* read_pos))
{
* write_pos = * read_pos;
write_pos++;
}
read_pos++;
}
write_pos[0] = '\0'; // Null-terminate the modified string write_pos[0] = '\0'; // Null-terminate the modified string
// Update the length if needed // Update the length if needed
string_get_header(str)->Length = write_pos - str; string_get_header(str)->Length = write_pos - str;
} }
forceinline forceinline
@ -662,12 +646,12 @@ void trim(String str, char const* cut_set)
str[len] = '\0'; str[len] = '\0';
string_get_header(str)->Length = len; string_get_header(str)->Length = len;
} }
forceinline forceinline
void trim_space(String str) { void trim_space(String str) {
trim(str, " \t\r\n\v\f"); trim(str, " \t\r\n\v\f");
} }
inline inline
@ -723,7 +707,7 @@ inline
StrC strc_visualize_whitespace(StrC str, AllocatorInfo allocator) StrC strc_visualize_whitespace(StrC str, AllocatorInfo allocator)
{ {
String result = string_make_reserve(allocator, str.Len * 2); // Assume worst case for space requirements. String result = string_make_reserve(allocator, str.Len * 2); // Assume worst case for space requirements.
for (char const* c = strc_begin(str); c != strc_end(str); c = strc_next(str, c)) for (char const* c = strc_begin(str); c != strc_end(str); c = strc_next(str, c))
switch ( * c ) switch ( * c )
{ {
case ' ': case ' ':
@ -755,8 +739,6 @@ StrC strc_visualize_whitespace(StrC str, AllocatorInfo allocator)
// Should never be modified, if changed string is desired, cache_string( str ) another. // Should never be modified, if changed string is desired, cache_string( str ) another.
typedef StrC StringCached; typedef StrC StringCached;
GEN_API_C_END
// Implements basic string interning. Data structure is based off the ZPL Hashtable. // Implements basic string interning. Data structure is based off the ZPL Hashtable.
typedef HashTable(StringCached) StringTable; typedef HashTable(StringCached) StringTable;
#pragma endregion Strings #pragma endregion Strings

View File

@ -4,7 +4,6 @@
#endif #endif
#pragma region Timing #pragma region Timing
GEN_API_C_BEGIN
#ifdef GEN_BENCHMARK #ifdef GEN_BENCHMARK
#if defined( GEN_COMPILER_MSVC ) && ! defined( __clang__ ) #if defined( GEN_COMPILER_MSVC ) && ! defined( __clang__ )
@ -165,5 +164,4 @@ GEN_API_C_BEGIN
} }
#endif #endif
GEN_API_C_END
#pragma endregion Timing #pragma endregion Timing

View File

@ -5,8 +5,6 @@
#pragma region Timing #pragma region Timing
GEN_API_C_BEGIN
#ifdef GEN_BENCHMARK #ifdef GEN_BENCHMARK
//! Return CPU timestamp. //! Return CPU timestamp.
u64 read_cpu_time_stamp_counter( void ); u64 read_cpu_time_stamp_counter( void );
@ -18,6 +16,4 @@ f64 time_rel( void );
u64 time_rel_ms( void ); u64 time_rel_ms( void );
#endif #endif
GEN_API_C_END
#pragma endregion Timing #pragma endregion Timing

View File

@ -1,61 +0,0 @@
Invalid
Untyped
NewLine
Comment
Access_Private
Access_Protected
Access_Public
PlatformAttributes
Class
Class_Fwd
Class_Body
Constructor
Constructor_Fwd
Destructor
Destructor_Fwd
Enum
Enum_Fwd
Enum_Body
Enum_Class
Enum_Class_Fwd
Execution
Export_Body
Extern_Linkage
Extern_Linkage_Body
Friend
Function
Function_Fwd
Function_Body
Global_Body
Module
Namespace
Namespace_Body
Operator
Operator_Fwd
Operator_Member
Operator_Member_Fwd
Operator_Cast
Operator_Cast_Fwd
Parameters
Preprocess_Define
Preprocess_Include
Preprocess_If
Preprocess_IfDef
Preprocess_IfNotDef
Preprocess_ElIf
Preprocess_Else
Preprocess_EndIf
Preprocess_Pragma
Specifiers
Struct
Struct_Fwd
Struct_Body
Template
Typedef
Typename
Union
Union_Fwd
Union_Body
Using
Using_Namespace
Variable
1 Invalid
2 Untyped
3 NewLine
4 Comment
5 Access_Private
6 Access_Protected
7 Access_Public
8 PlatformAttributes
9 Class
10 Class_Fwd
11 Class_Body
12 Constructor
13 Constructor_Fwd
14 Destructor
15 Destructor_Fwd
16 Enum
17 Enum_Fwd
18 Enum_Body
19 Enum_Class
20 Enum_Class_Fwd
21 Execution
22 Export_Body
23 Extern_Linkage
24 Extern_Linkage_Body
25 Friend
26 Function
27 Function_Fwd
28 Function_Body
29 Global_Body
30 Module
31 Namespace
32 Namespace_Body
33 Operator
34 Operator_Fwd
35 Operator_Member
36 Operator_Member_Fwd
37 Operator_Cast
38 Operator_Cast_Fwd
39 Parameters
40 Preprocess_Define
41 Preprocess_Include
42 Preprocess_If
43 Preprocess_IfDef
44 Preprocess_IfNotDef
45 Preprocess_ElIf
46 Preprocess_Else
47 Preprocess_EndIf
48 Preprocess_Pragma
49 Specifiers
50 Struct
51 Struct_Fwd
52 Struct_Body
53 Template
54 Typedef
55 Typename
56 Union
57 Union_Fwd
58 Union_Body
59 Using
60 Using_Namespace
61 Variable

View File

@ -0,0 +1,61 @@
Invalid, "__NA__"
Untyped, "__NA__"
NewLine, "__NA__"
Comment, "//"
Access_Private, "private"
Access_Protected, "protected"
Access_Public, "public"
PlatformAttributes, "__NA__"
Class, "class"
Class_Fwd, "clsss"
Class_Body, "__NA__"
Constructor, "__NA__"
Constructor_Fwd, "__NA__"
Destructor, "__NA__"
Destructor_Fwd, "__NA__"
Enum, "enum"
Enum_Fwd, "enum"
Enum_Body, "__NA__"
Enum_Class, "enum class"
Enum_Class_Fwd, "enum class"
Execution, "__NA__"
Export_Body, "__NA__"
Extern_Linkage, "extern"
Extern_Linkage_Body, "extern"
Friend, "friend"
Function, "__NA__"
Function_Fwd, "__NA__"
Function_Body, "__NA__"
Global_Body, "__NA__"
Module, "module"
Namespace, "namespace"
Namespace_Body, "__NA__"
Operator, "operator"
Operator_Fwd, "operator"
Operator_Member, "operator"
Operator_Member_Fwd, "operator"
Operator_Cast, "operator"
Operator_Cast_Fwd, "operator"
Parameters, "__NA__"
Preprocess_Define, "define"
Preprocess_Include, "include"
Preprocess_If, "if"
Preprocess_IfDef, "ifdef"
Preprocess_IfNotDef, "ifndef"
Preprocess_ElIf, "elif"
Preprocess_Else, "else"
Preprocess_EndIf, "endif"
Preprocess_Pragma, "pragma"
Specifiers, "__NA__"
Struct, "struct"
Struct_Fwd, "struct"
Struct_Body, "__NA__"
Template, "template"
Typedef, "typedef"
Typename, "__NA__"
Union, "union"
Union_Fwd, "union"
Union_Body, "__NA__"
Using, "using"
Using_Namespace, "using namespace"
Variable, "__NA__"
1 Invalid __NA__
2 Untyped __NA__
3 NewLine __NA__
4 Comment //
5 Access_Private private
6 Access_Protected protected
7 Access_Public public
8 PlatformAttributes __NA__
9 Class class
10 Class_Fwd clsss
11 Class_Body __NA__
12 Constructor __NA__
13 Constructor_Fwd __NA__
14 Destructor __NA__
15 Destructor_Fwd __NA__
16 Enum enum
17 Enum_Fwd enum
18 Enum_Body __NA__
19 Enum_Class enum class
20 Enum_Class_Fwd enum class
21 Execution __NA__
22 Export_Body __NA__
23 Extern_Linkage extern
24 Extern_Linkage_Body extern
25 Friend friend
26 Function __NA__
27 Function_Fwd __NA__
28 Function_Body __NA__
29 Global_Body __NA__
30 Module module
31 Namespace namespace
32 Namespace_Body __NA__
33 Operator operator
34 Operator_Fwd operator
35 Operator_Member operator
36 Operator_Member_Fwd operator
37 Operator_Cast operator
38 Operator_Cast_Fwd operator
39 Parameters __NA__
40 Preprocess_Define define
41 Preprocess_Include include
42 Preprocess_If if
43 Preprocess_IfDef ifdef
44 Preprocess_IfNotDef ifndef
45 Preprocess_ElIf elif
46 Preprocess_Else else
47 Preprocess_EndIf endif
48 Preprocess_Pragma pragma
49 Specifiers __NA__
50 Struct struct
51 Struct_Fwd struct
52 Struct_Body __NA__
53 Template template
54 Typedef typedef
55 Typename __NA__
56 Union union
57 Union_Fwd union
58 Union_Body __NA__
59 Using using
60 Using_Namespace using namespace
61 Variable __NA__

View File

@ -8,9 +8,9 @@ GEN_NS_END
using namespace gen; using namespace gen;
CodeBody gen_ecode( char const* path ) CodeBody gen_ecode( char const* path, bool use_c_definition = false )
{ {
char scratch_mem[kilobytes(1)]; char scratch_mem[kilobytes(4)];
Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) ); Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) );
file_read_contents( arena_allocator_info( & scratch), file_zero_terminate, path ); file_read_contents( arena_allocator_info( & scratch), file_zero_terminate, path );
@ -18,29 +18,46 @@ CodeBody gen_ecode( char const* path )
CSV_Object csv_nodes; CSV_Object csv_nodes;
csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false ); csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false );
Array<ADT_Node> enum_strs = csv_nodes.nodes[0].nodes; Array<ADT_Node> enum_strs = csv_nodes.nodes[0].nodes;
Array<ADT_Node> keyword_strs = csv_nodes.nodes[1].nodes;
String enum_entries = string_make_reserve( GlobalAllocator, kilobytes(1) ); String enum_entries = string_make_reserve( GlobalAllocator, kilobytes(1) );
String to_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) ); String to_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) );
String to_keyword_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) );
for ( ADT_Node* node = array_begin(enum_strs); node != array_end(enum_strs); node = array_next(enum_strs, node) ) for ( ssize idx = 0; idx < array_num(enum_strs); ++ idx )
{ {
char const* code = node->string; char const* code = enum_strs [idx].string;
char const* keyword = keyword_strs[idx].string;
string_append_fmt( & enum_entries, "CT_%s,\n", code ); // TODO(Ed): to_str_entries and the others in here didn't have proper sizing of the StrC slice.
string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", code, code );
string_append_fmt( & enum_entries, "CT_%s,\n", code );
string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", code, code );
string_append_fmt( & to_keyword_str_entries, "{ sizeof(\"%s\") - 1, \"%s\" },\n", keyword, keyword );
} }
CodeEnum enum_code = parse_enum(gen::token_fmt_impl((3 + 1) / 2, "entries", string_to_strc(enum_entries), CodeEnum enum_code;
"enum CodeType_Def enum_underlying(u32) { <entries> CT_NumTypes };" if (use_c_definition)
)); {
enum_code = parse_enum(token_fmt_impl((3 + 1) / 2, "entries", string_to_strc(enum_entries),
"enum CodeType enum_underlying(u32) { <entries> CT_NumTypes };"
));
}
else
{
enum_code = parse_enum(token_fmt_impl((3 + 1) / 2, "entries", string_to_strc(enum_entries),
"enum CodeType : u32 { <entries> CT_NumTypes };"
));
}
#pragma push_macro("local_persist") #pragma push_macro("local_persist")
#undef local_persist #undef local_persist
StrC lookup_size = string_to_strc(string_fmt_buf(GlobalAllocator, "%d", array_num(enum_strs) )); StrC lookup_size = string_to_strc(string_fmt_buf(GlobalAllocator, "%d", array_num(enum_strs) ));
CodeFn to_str = parse_function( token_fmt( CodeBody to_str_fns = parse_global_body( token_fmt(
"entries", string_to_strc(to_str_entries) "entries", string_to_strc(to_str_entries)
, "num", lookup_size , "keywords", string_to_strc(to_keyword_str_entries)
, "num", lookup_size
, stringize( , stringize(
inline inline
StrC codetype_to_str( CodeType type ) StrC codetype_to_str( CodeType type )
@ -49,20 +66,47 @@ CodeBody gen_ecode( char const* path )
StrC lookup[<num>] = { StrC lookup[<num>] = {
<entries> <entries>
}; };
return lookup[ type ];
}
inline
StrC codetype_to_keyword_str( CodeType type )
{
local_persist
StrC lookup[ <num> ] = {
<keywords>
};
return lookup[ type ]; return lookup[ type ];
} }
))); )));
#pragma pop_macro("local_persist") #pragma pop_macro("local_persist")
//CodeNS nspace = def_namespace( name(ECode), def_namespace_body( args( enum_code, to_str ) ) ); CodeBody result = def_body(CT_Global_Body);
//CodeUsing code_t = def_using( name(CodeT), def_type( name(ECode::Type) ) ); body_append(result, enum_code);
CodeTypedef code_t = parse_typedef(code(typedef enum CodeType_Def CodeType; ));
return def_global_body( args( enum_code, code_t, to_str, fmt_newline ) ); if (use_c_definition)
{
CodeTypedef code_t = parse_typedef(code(typedef enum CodeType CodeType; ));
body_append(result, code_t);
}
body_append(result, to_str_fns);
if (! use_c_definition)
{
#pragma push_macro("forceinline")
#undef forceinline
CodeBody alias_mappings = parse_global_body(code(
forceinline StrC to_str (CodeType type) { return codetype_to_str(type); }
forceinline StrC to_keyword_str(CodeType type) { return codetype_to_keyword_str(type); }
));
#pragma pop_macro("forceinline")
body_append(result, alias_mappings);
}
return result;
} }
CodeBody gen_eoperator( char const* path ) CodeBody gen_eoperator( char const* path, bool use_c_definition = false )
{ {
char scratch_mem[kilobytes(4)]; char scratch_mem[kilobytes(4)];
Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) ); Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) );
@ -87,16 +131,30 @@ CodeBody gen_eoperator( char const* path )
string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
} }
#pragma push_macro("enum_underlying") CodeEnum enum_code;
#undef enum_underlying if (use_c_definition)
CodeEnum enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize( {
enum Operator_Def enum_underlying(u32) #pragma push_macro("enum_underlying")
{ #undef enum_underlying
<entries> enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize(
NumOps enum Operator enum_underlying(u32)
}; {
))); <entries>
#pragma pop_macro("enum_underlying") NumOps
};
)));
#pragma pop_macro("enum_underlying")
}
else
{
enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize(
enum Operator : u32
{
<entries>
NumOps
};
)));
}
#pragma push_macro("local_persist") #pragma push_macro("local_persist")
#undef local_persist #undef local_persist
@ -118,14 +176,30 @@ CodeBody gen_eoperator( char const* path )
))); )));
#pragma pop_macro("local_persist") #pragma pop_macro("local_persist")
//CodeNS nspace = def_namespace( name(EOperator), def_namespace_body( args( enum_code, to_str ) ) ); CodeBody result = def_body(CT_Global_Body);
//CodeUsing operator_t = def_using( name(OperatorT), def_type( name(EOperator::Type) ) ); body_append(result, enum_code);
CodeTypedef operator_t = parse_typedef(code( typedef enum Operator_Def Operator; )); if ( use_c_definition )
{
CodeTypedef operator_t = parse_typedef(code( typedef enum Operator Operator; ));
body_append(result, operator_t);
}
return def_global_body( args( enum_code, operator_t, to_str, fmt_newline ) ); body_append(result, to_str);
if (! use_c_definition)
{
#pragma push_macro("forceinline")
#undef forceinline
CodeBody alias_mappings = parse_global_body(code(
forceinline StrC to_str(Operator op) { return operator_to_str(op); }
));
#pragma pop_macro("forceinline")
body_append(result, alias_mappings);
}
return result;
} }
CodeBody gen_especifier( char const* path ) CodeBody gen_especifier( char const* path, bool use_c_definition = false )
{ {
char scratch_mem[kilobytes(4)]; char scratch_mem[kilobytes(4)];
Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) ); Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) );
@ -150,16 +224,30 @@ CodeBody gen_especifier( char const* path )
string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
} }
#pragma push_macro("enum_underlying") CodeEnum enum_code;
#undef enum_underlying if (use_c_definition)
CodeEnum enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize( {
enum Specifier_Def enum_underlying(u32) #pragma push_macro("enum_underlying")
{ #undef enum_underlying
<entries> enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize(
Spec_NumSpecifiers enum Specifier enum_underlying(u32)
}; {
))); <entries>
#pragma pop_macro("enum_underlying") Spec_NumSpecifiers
};
)));
#pragma pop_macro("enum_underlying")
}
else
{
enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize(
enum Specifier : u32
{
<entries>
Spec_NumSpecifiers
};
)));
}
CodeFn is_trailing = parse_function(token_fmt("specifier", string_to_strc(to_str_entries), stringize( CodeFn is_trailing = parse_function(token_fmt("specifier", string_to_strc(to_str_entries), stringize(
inline inline
@ -179,7 +267,6 @@ CodeBody gen_especifier( char const* path )
#undef do_once_end #undef do_once_end
#undef forceinline #undef forceinline
#undef neverinline #undef neverinline
StrC lookup_size = string_to_strc(string_fmt_buf(GlobalAllocator, "%d", array_num(enum_strs) )); StrC lookup_size = string_to_strc(string_fmt_buf(GlobalAllocator, "%d", array_num(enum_strs) ));
CodeFn to_str = parse_function(token_fmt( CodeFn to_str = parse_function(token_fmt(
"entries", string_to_strc(to_str_entries) "entries", string_to_strc(to_str_entries)
@ -231,11 +318,31 @@ CodeBody gen_especifier( char const* path )
#pragma pop_macro("forceinline") #pragma pop_macro("forceinline")
#pragma pop_macro("neverinline") #pragma pop_macro("neverinline")
//CodeNS nspace = def_namespace( name(ESpecifier), def_namespace_body( args( enum_code, is_trailing, to_str, to_type ) ) ); CodeBody result = def_body(CT_Global_Body);
//CodeUsing specifier_t = def_using( name(SpecifierT), def_type( name(ESpecifier::Type) ) ); body_append(result, enum_code);
CodeTypedef specifier_t = parse_typedef( code(typedef enum Specifier_Def Specifier; )); if (use_c_definition)
{
CodeTypedef specifier_t = parse_typedef( code(typedef u32 Specifier; ));
body_append(result, specifier_t);
}
return def_global_body( args( enum_code, specifier_t, is_trailing, to_str, to_type, fmt_newline ) ); body_append(result, to_str);
body_append(result, is_trailing);
body_append(result, to_type);
if (! use_c_definition)
{
#pragma push_macro("forceinline")
#undef forceinline
CodeBody alias_mappings = parse_global_body(code(
forceinline StrC to_str (Specifier spec) { return spec_to_str(spec); }
forceinline Specifier to_type( StrC str ) { return strc_to_specifier(str); }
forceinline bool is_trailing( Specifier specifier ) { return spec_is_trailing(specifier); }
));
#pragma pop_macro("forceinline")
body_append(result, alias_mappings);
}
return result;
} }
CodeBody gen_etoktype( char const* etok_path, char const* attr_path ) CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
@ -384,7 +491,7 @@ CodeBody gen_ast_inlines()
inline inline
<typename>& <typename>::operator =( Code other ) <typename>& <typename>::operator =( Code other )
{ {
if ( other.ast && other->Parent ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
ast = rcast( decltype(ast), code_duplicate(other).ast); ast = rcast( decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
@ -451,36 +558,39 @@ CodeBody gen_ast_inlines()
CodeBody impl_code_using = parse_global_body( token_fmt( "typename", StrC name(CodeUsing), code_impl_tmpl )); CodeBody impl_code_using = parse_global_body( token_fmt( "typename", StrC name(CodeUsing), code_impl_tmpl ));
CodeBody impl_code_var = parse_global_body( token_fmt( "typename", StrC name(CodeVar), code_impl_tmpl )); CodeBody impl_code_var = parse_global_body( token_fmt( "typename", StrC name(CodeVar), code_impl_tmpl ));
append(impl_code_attr, parse_global_body( token_fmt( "typename", StrC name(Attributes), codetype_impl_tmpl ))); body_append(impl_code_attr, parse_global_body( token_fmt( "typename", StrC name(Attributes), codetype_impl_tmpl )));
append(impl_code_cmt, parse_global_body( token_fmt( "typename", StrC name(Comment), codetype_impl_tmpl ))); body_append(impl_code_cmt, parse_global_body( token_fmt( "typename", StrC name(Comment), codetype_impl_tmpl )));
append(impl_code_constr, parse_global_body( token_fmt( "typename", StrC name(Constructor), codetype_impl_tmpl ))); body_append(impl_code_constr, parse_global_body( token_fmt( "typename", StrC name(Constructor), codetype_impl_tmpl )));
append(impl_code_define, parse_global_body( token_fmt( "typename", StrC name(Define), codetype_impl_tmpl ))); body_append(impl_code_define, parse_global_body( token_fmt( "typename", StrC name(Define), codetype_impl_tmpl )));
append(impl_code_destruct, parse_global_body( token_fmt( "typename", StrC name(Destructor), codetype_impl_tmpl ))); body_append(impl_code_destruct, parse_global_body( token_fmt( "typename", StrC name(Destructor), codetype_impl_tmpl )));
append(impl_code_enum, parse_global_body( token_fmt( "typename", StrC name(Enum), codetype_impl_tmpl ))); body_append(impl_code_enum, parse_global_body( token_fmt( "typename", StrC name(Enum), codetype_impl_tmpl )));
append(impl_code_exec, parse_global_body( token_fmt( "typename", StrC name(Exec), codetype_impl_tmpl ))); body_append(impl_code_exec, parse_global_body( token_fmt( "typename", StrC name(Exec), codetype_impl_tmpl )));
append(impl_code_extern, parse_global_body( token_fmt( "typename", StrC name(Extern), codetype_impl_tmpl ))); body_append(impl_code_extern, parse_global_body( token_fmt( "typename", StrC name(Extern), codetype_impl_tmpl )));
append(impl_code_include, parse_global_body( token_fmt( "typename", StrC name(Include), codetype_impl_tmpl ))); body_append(impl_code_include, parse_global_body( token_fmt( "typename", StrC name(Include), codetype_impl_tmpl )));
append(impl_code_friend, parse_global_body( token_fmt( "typename", StrC name(Friend), codetype_impl_tmpl ))); body_append(impl_code_friend, parse_global_body( token_fmt( "typename", StrC name(Friend), codetype_impl_tmpl )));
append(impl_code_fn, parse_global_body( token_fmt( "typename", StrC name(Fn), codetype_impl_tmpl ))); body_append(impl_code_fn, parse_global_body( token_fmt( "typename", StrC name(Fn), codetype_impl_tmpl )));
append(impl_code_module, parse_global_body( token_fmt( "typename", StrC name(Module), codetype_impl_tmpl ))); body_append(impl_code_module, parse_global_body( token_fmt( "typename", StrC name(Module), codetype_impl_tmpl )));
append(impl_code_ns, parse_global_body( token_fmt( "typename", StrC name(NS), codetype_impl_tmpl ))); body_append(impl_code_ns, parse_global_body( token_fmt( "typename", StrC name(NS), codetype_impl_tmpl )));
append(impl_code_op, parse_global_body( token_fmt( "typename", StrC name(Operator), codetype_impl_tmpl ))); body_append(impl_code_op, parse_global_body( token_fmt( "typename", StrC name(Operator), codetype_impl_tmpl )));
append(impl_code_opcast, parse_global_body( token_fmt( "typename", StrC name(OpCast), codetype_impl_tmpl ))); body_append(impl_code_opcast, parse_global_body( token_fmt( "typename", StrC name(OpCast), codetype_impl_tmpl )));
append(impl_code_pragma, parse_global_body( token_fmt( "typename", StrC name(Pragma), codetype_impl_tmpl ))); body_append(impl_code_pragma, parse_global_body( token_fmt( "typename", StrC name(Pragma), codetype_impl_tmpl )));
append(impl_code_precond, parse_global_body( token_fmt( "typename", StrC name(PreprocessCond), codetype_impl_tmpl ))); body_append(impl_code_precond, parse_global_body( token_fmt( "typename", StrC name(PreprocessCond), codetype_impl_tmpl )));
append(impl_code_tmpl, parse_global_body( token_fmt( "typename", StrC name(Template), codetype_impl_tmpl ))); body_append(impl_code_tmpl, parse_global_body( token_fmt( "typename", StrC name(Template), codetype_impl_tmpl )));
append(impl_code_type, parse_global_body( token_fmt( "typename", StrC name(Typename), codetype_impl_tmpl ))); body_append(impl_code_type, parse_global_body( token_fmt( "typename", StrC name(Typename), codetype_impl_tmpl )));
append(impl_code_typedef, parse_global_body( token_fmt( "typename", StrC name(Typedef), codetype_impl_tmpl ))); body_append(impl_code_typedef, parse_global_body( token_fmt( "typename", StrC name(Typedef), codetype_impl_tmpl )));
append(impl_code_union, parse_global_body( token_fmt( "typename", StrC name(Union), codetype_impl_tmpl ))); body_append(impl_code_union, parse_global_body( token_fmt( "typename", StrC name(Union), codetype_impl_tmpl )));
append(impl_code_using, parse_global_body( token_fmt( "typename", StrC name(Using), codetype_impl_tmpl ))); body_append(impl_code_using, parse_global_body( token_fmt( "typename", StrC name(Using), codetype_impl_tmpl )));
append(impl_code_var, parse_global_body( token_fmt( "typename", StrC name(Var), codetype_impl_tmpl ))); body_append(impl_code_var, parse_global_body( token_fmt( "typename", StrC name(Var), codetype_impl_tmpl )));
#pragma push_macro("forceinline")
#undef forceinline
char const* cast_tmpl = stringize( char const* cast_tmpl = stringize(
inline Code::operator Code<typename>() const forceinline Code::operator Code<typename>() const
{ {
return { (AST_<typename>*) ast }; return { (AST_<typename>*) ast };
} }
); );
#pragma pop_macro("forceinline")
CodeBody impl_cast_body = parse_global_body( token_fmt( "typename", StrC name(Body), cast_tmpl )); CodeBody impl_cast_body = parse_global_body( token_fmt( "typename", StrC name(Body), cast_tmpl ));
CodeBody impl_cast_attribute = parse_global_body( token_fmt( "typename", StrC name(Attributes), cast_tmpl )); CodeBody impl_cast_attribute = parse_global_body( token_fmt( "typename", StrC name(Attributes), cast_tmpl ));
@ -547,6 +657,7 @@ CodeBody gen_ast_inlines()
def_pragma( txt("endregion generated code inline implementation")), def_pragma( txt("endregion generated code inline implementation")),
fmt_newline, fmt_newline,
def_pragma( txt("region generated AST/Code cast implementation")), def_pragma( txt("region generated AST/Code cast implementation")),
untyped_str(txt("GEN_OPTIMIZE_MAPPINGS_BEGIN\n")),
fmt_newline, fmt_newline,
impl_cast_body, impl_cast_body,
impl_cast_attribute, impl_cast_attribute,
@ -577,6 +688,7 @@ CodeBody gen_ast_inlines()
impl_cast_using, impl_cast_using,
impl_cast_var, impl_cast_var,
fmt_newline, fmt_newline,
untyped_str(txt("GEN_OPITMIZE_MAPPINGS_END\n")),
def_pragma( txt("endregion generated AST/Code cast implementation")), def_pragma( txt("endregion generated AST/Code cast implementation")),
fmt_newline fmt_newline
)); ));

View File

@ -2,15 +2,12 @@
# It will most likely need a partial rewrite to segment the build process into separate script invocations based on the OS. # It will most likely need a partial rewrite to segment the build process into separate script invocations based on the OS.
# That or just rewrite it in an sh script and call it a day. # That or just rewrite it in an sh script and call it a day.
$target_arch = Join-Path $PSScriptRoot 'helpers/target_arch.psm1'
$devshell = Join-Path $PSScriptRoot 'helpers/devshell.ps1' $devshell = Join-Path $PSScriptRoot 'helpers/devshell.ps1'
$format_cpp = Join-Path $PSScriptRoot 'helpers/format_cpp.psm1' $format_cpp = Join-Path $PSScriptRoot 'helpers/format_cpp.psm1'
$refactor_unreal = Join-Path $PSScriptRoot 'refactor_unreal.ps1' $refactor_unreal = Join-Path $PSScriptRoot 'refactor_unreal.ps1'
$incremental_checks = Join-Path $PSScriptRoot 'helpers/incremental_checks.ps1' $incremental_checks = Join-Path $PSScriptRoot 'helpers/incremental_checks.ps1'
$vendor_toolchain = Join-Path $PSScriptRoot 'helpers/vendor_toolchain.ps1' $vendor_toolchain = Join-Path $PSScriptRoot 'helpers/vendor_toolchain.ps1'
Import-Module $target_arch
function Get-ScriptRepoRoot { function Get-ScriptRepoRoot {
$currentPath = $PSScriptRoot $currentPath = $PSScriptRoot
while ($currentPath -ne $null -and $currentPath -ne "") while ($currentPath -ne $null -and $currentPath -ne "")
@ -33,7 +30,7 @@ function Get-ScriptRepoRoot {
} }
$path_root = Get-ScriptRepoRoot $path_root = Get-ScriptRepoRoot
Import-Module $target_arch # Import-Module $target_arch
Import-Module $format_cpp Import-Module $format_cpp
Push-Location $path_root Push-Location $path_root
@ -94,7 +91,6 @@ if ( $bootstrap -eq $false -and $singleheader -eq $false -and $c_library -eq $fa
throw "No build target specified. One must be specified, this script will not assume one" throw "No build target specified. One must be specified, this script will not assume one"
} }
. $vendor_toolchain . $vendor_toolchain
. $incremental_checks . $incremental_checks

View File

@ -1,4 +1,7 @@
# This is meant to be used with build.ps1, and is not a standalone script. # This is meant to be used with build.ps1, and is not a standalone script.
$target_arch = Join-Path $PSScriptRoot 'target_arch.psm1'
import-module $target_arch
if ($IsWindows) { if ($IsWindows) {
# This HandmadeHero implementation is only designed for 64-bit systems # This HandmadeHero implementation is only designed for 64-bit systems
@ -188,7 +191,7 @@ if ( $vendor -match "clang" )
# $compiler_args += $flag_time_trace # $compiler_args += $flag_time_trace
} }
if ( $optimize ) { if ( $optimize ) {
$compiler_args += $flag_optimize_fast $compiler_args += $flag_optimize_size
} }
else { else {
$compiler_args += $flag_no_optimization $compiler_args += $flag_no_optimization
@ -268,7 +271,7 @@ if ( $vendor -match "clang" )
# $compiler_args += $flag_time_trace # $compiler_args += $flag_time_trace
} }
if ( $optimize ) { if ( $optimize ) {
$compiler_args += $flag_optimize_fast $compiler_args += $flag_optimize_size
} }
else { else {
$compiler_args += $flag_no_optimization $compiler_args += $flag_no_optimization
@ -316,48 +319,50 @@ if ( $vendor -match "clang" )
if ( $vendor -match "msvc" ) if ( $vendor -match "msvc" )
{ {
# https://learn.microsoft.com/en-us/cpp/build/reference/compiler-options-listed-by-category?view=msvc-170 # https://learn.microsoft.com/en-us/cpp/build/reference/compiler-options-listed-by-category?view=msvc-170
$flag_all_c = '/TC' $flag_all_c = '/TC'
$flag_all_cpp = '/TP' $flag_all_cpp = '/TP'
$flag_compile = '/c' $flag_compile = '/c'
$flag_debug = '/Zi' $flag_debug = '/Zi'
$flag_define = '/D' $flag_define = '/D'
$flag_exceptions_disabled = '/EHsc-' $flag_exceptions_disabled = '/EHsc-'
$flag_RTTI_disabled = '/GR-' $flag_RTTI_disabled = '/GR-'
$flag_include = '/I' $flag_include = '/I'
$flag_full_src_path = '/FC' $flag_full_src_path = '/FC'
$flag_nologo = '/nologo' $flag_nologo = '/nologo'
$flag_dll = '/LD' $flag_dll = '/LD'
$flag_dll_debug = '/LDd' $flag_dll_debug = '/LDd'
$flag_linker = '/link' $flag_linker = '/link'
$flag_link_dll = '/DLL' $flag_link_dll = '/DLL'
$flag_link_no_incremental = '/INCREMENTAL:NO' $flag_link_no_incremental = '/INCREMENTAL:NO'
$flag_link_mapfile = '/MAP:' $flag_link_mapfile = '/MAP:'
$flag_link_optimize_references = '/OPT:REF' $flag_link_optimize_references = '/OPT:REF'
$flag_link_win_debug = '/DEBUG' $flag_link_win_debug = '/DEBUG'
$flag_link_win_pdb = '/PDB:' $flag_link_win_pdb = '/PDB:'
$flag_link_win_machine_32 = '/MACHINE:X86' $flag_link_win_machine_32 = '/MACHINE:X86'
$flag_link_win_machine_64 = '/MACHINE:X64' $flag_link_win_machine_64 = '/MACHINE:X64'
$flag_link_win_path_output = '/OUT:' $flag_link_win_path_output = '/OUT:'
$flag_link_win_rt_dll = '/MD' $flag_link_win_rt_dll = '/MD'
$flag_link_win_rt_dll_debug = '/MDd' $flag_link_win_rt_dll_debug = '/MDd'
$flag_link_win_rt_static = '/MT' $flag_link_win_rt_static = '/MT'
$flag_link_win_rt_static_debug = '/MTd' $flag_link_win_rt_static_debug = '/MTd'
$flag_link_win_subsystem_console = '/SUBSYSTEM:CONSOLE' $flag_link_win_subsystem_console = '/SUBSYSTEM:CONSOLE'
$flag_link_win_subsystem_windows = '/SUBSYSTEM:WINDOWS' $flag_link_win_subsystem_windows = '/SUBSYSTEM:WINDOWS'
$flag_no_optimization = '/Od' $flag_no_optimization = '/Od'
$flag_optimize_fast = '/O2' $flag_optimize_fast = '/O2'
$flag_optimize_size = '/O1' $flag_optimize_size = '/O1'
$flag_optimize_intrinsics = '/Oi' $flag_optimize_intrinsics = '/Oi'
$flag_optimized_debug = '/Zo' $flag_optimized_debug_forceinline = '/d2Obforceinline'
$flag_out_name = '/OUT:' $flag_optimized_debug = '/Zo'
$flag_path_interm = '/Fo' $flag_
$flag_path_debug = '/Fd' $flag_out_name = '/OUT:'
$flag_path_output = '/Fe' $flag_path_interm = '/Fo'
$flag_preprocess_conform = '/Zc:preprocessor' $flag_path_debug = '/Fd'
$flag_set_stack_size = '/F' $flag_path_output = '/Fe'
$flag_syntax_only = '/Zs' $flag_preprocess_conform = '/Zc:preprocessor'
$flag_wall = '/Wall' $flag_set_stack_size = '/F'
$flag_warnings_as_errors = '/WX' $flag_syntax_only = '/Zs'
$flag_wall = '/Wall'
$flag_warnings_as_errors = '/WX'
function build function build
{ {
@ -388,7 +393,7 @@ if ( $vendor -match "msvc" )
} }
if ( $optimize ) { if ( $optimize ) {
$compiler_args += $flag_optimize_fast $compiler_args += $flag_optimize_size
} }
else { else {
$compiler_args += $flag_no_optimization $compiler_args += $flag_no_optimization
@ -403,6 +408,7 @@ if ( $vendor -match "msvc" )
if ( $optimize ) { if ( $optimize ) {
$compiler_args += $flag_optimized_debug $compiler_args += $flag_optimized_debug
$compiler_args += $flag_optimized_debug_forceinline
} }
} }
else { else {
@ -474,7 +480,7 @@ if ( $vendor -match "msvc" )
} }
if ( $optimize ) { if ( $optimize ) {
$compiler_args += $flag_optimize_fast $compiler_args += $flag_optimize_size
} }
else { else {
$compiler_args += $flag_no_optimization $compiler_args += $flag_no_optimization