21 Commits

Author SHA1 Message Date
Ed_
5705196710 formatting fixes to C library generator 2024-12-13 15:56:57 -05:00
Ed_
cf0d787196 corrected formatting for gen_segmented 2024-12-13 15:44:29 -05:00
Ed_
8d436fe546 correct formatting in singleheader.cpp 2024-12-13 15:42:13 -05:00
Ed_
e15ac22132 Made Token::Text/Length into Str Text; (Str slice) 2024-12-13 15:36:40 -05:00
Ed_
bac57a5872 Corrected enum serialization of ecodetypes, eoperator, especifier, and etoktype, some more naming refactors for strbuilder... formatting 2024-12-13 14:38:27 -05:00
Ed_
012fcb6bd5 Corrected order of Str to how the slice type is defined in Odin and RAD Debugger (my reference on slice types) 2024-12-13 13:20:16 -05:00
Ed_
6ffdca8595 formatting, fixes from testing latest in Odin fork 2024-12-13 11:56:07 -05:00
Ed_
e3172057d3 working to towards https://github.com/Ed94/gencpp/issues/56 2024-12-12 12:55:15 -05:00
Ed_
8d48da0b9e reduced macro usage in lexer.cpp 2024-12-12 11:56:16 -05:00
Ed_
30dea2e9fd reduce 'large macro' usage in ast.cpp and interface.cpp
Properly disabled GEN_DEBUG_TRAP in non-debug builds
2024-12-12 11:35:50 -05:00
Ed_
633879d35f more typo correction 2024-12-12 10:42:01 -05:00
Ed_
831b52129d readme fixes 2024-12-12 10:27:55 -05:00
Ed_
55427822a0 Proofing docs 2024-12-12 10:24:21 -05:00
Ed_
71b7320e1c codestruct mssing frm c_library.reefactor 2024-12-11 16:00:39 -05:00
Ed_
2a025cb073 Merge branch 'de_oop' 2024-12-11 14:57:47 -05:00
Ed_
0e782cdf99 minor fixees 2024-12-11 14:57:38 -05:00
Ed_
a390e7f895 Merge pull request #62 from Ed94/de_oop
De oop
2024-12-11 11:54:14 -08:00
Ed_
65427bd0f1 Update undef.macros.h 2024-12-11 14:08:34 -05:00
Ed_
cb898595b0 Updates to docs and various changes to project from working on them.
- CodeParam -> CodeParams
- interfaces array weren't being used in parse_class_struct
- added enum_underlying_sig
2024-12-11 13:33:35 -05:00
Ed_
9b86d84dd6 typo fix 2024-12-11 12:43:46 -05:00
Ed_
4dfb9031d7 separated _generic macros from base/dependencies/macro.shpp 2024-12-11 08:52:05 -05:00
72 changed files with 4068 additions and 4512 deletions

View File

View File

@ -5,42 +5,37 @@ An attempt at simple staged metaprogramming for C/C++.
The library API is a composition of code element constructors, and a non-standards-compliant single-pass C/C++ parser. 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, or can be traversed for staged-reflection of C/C++ code. 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 integrate into a user's project domain.
## Documentation ## Documentation
If your going to metaprogram, you can never have enough docs on your tooling...
* [docs - General](./docs/Readme.md): Overview and additional docs * [docs - General](./docs/Readme.md): Overview and additional docs
* [AST_Design](./docs/AST_Design.md): Overvie of ASTs * [AST_Design](./docs/AST_Design.md): Overview of ASTs
* [AST Types](./docs/AST_Types.md): Listing of all AST types along with their Code type interface. * [AST Types](./docs/AST_Types.md): Listing of all AST types along with their Code type interface.
* [Parsing](./docs/Parsing.md): Overview of the parsing interface. * [Parsing](./docs/Parsing.md): Overview of the parsing interface.
* [Parser Algo](./docs/Parser_Algo.md): In-depth breakdown of the parser's implementation. * [Parser Algo](./docs/Parser_Algo.md): In-depth breakdown of the parser's implementation.
* [base](./base/Readme.md): Essential (base) library. * [base](./base/Readme.md): Essential (base) library.
* [gen_c_library](./gen_c_library/Readme.md): C11 library variant generation (single header and segmeented). * [gen_c_library](./gen_c_library/): C11 library variant generation (single header and segmented).
* [gen_segmented](./gen_segmented/Readme.md): Segemented C++ (`gen.<hpp/cpp>`, `gen.dep.<hpp/cpp>`) generation * [gen_segmented](./gen_segmented/): Segmented C++ (`gen.<hpp/cpp>`, `gen.dep.<hpp/cpp>`) generation
* [gen_singleheader](./gen_singleheader/Readme.md): Singlehader C++ generation `gen.hpp` * [gen_singleheader](./gen_singleheader/): Singlehader C++ generation `gen.hpp`
* [gen_unreal_engine](./gen_unreal_engine/Readme.md): Unreal Engine thirdparty code generation. * [gen_unreal_engine](./gen_unreal_engine/): Unreal Engine thirdparty code generation.
## Notes ## Notes
**On Partial Hiatus: Life has got me tackling other issues..**
I will be passively updating the library with bug fixes and minor improvements as I use it for my personal projects.
There won't be any major reworks or features to this thing for a while.
This project is still in development (very much an alpha state), so expect bugs and missing features. This project is still in development (very much an alpha state), so expect bugs and missing features.
See [issues](https://github.com/Ed94/gencpp/issues) for a list of known bugs or todos. See [issues](https://github.com/Ed94/gencpp/issues) for a list of known bugs or todos.
The library can already be used to generate code just fine, but the parser is where the most work is needed. If your C++ isn't "down to earth" expect issues. The library can already be used to generate code just fine, but the parser is where the most work is needed. If your C++ isn't "down to earth" expect issues.
A `natvis` and `natstepfilter` are provided in the scripts directory (its outdated, I'll update this readme when its not). A `natvis` and `natstepfilter` are provided in the scripts directory (its outdated, I'll update this readme when its not).
*Minor update: I've been using [RAD Debugger](https://github.com/EpicGamesExt/raddebugger) with this and the code structures should be easy to debug even without natvis.*
## Usage ## Usage
A metaprogram is built to generate files before the main program is built. We'll term runtime for this program as `GEN_TIME`. The metaprogram's core implementation are within `gen.hpp` and `gen.cpp` in the project directory. A metaprogram is built to generate files before the main program is built. We'll term runtime for this program as `GEN_TIME`. The metaprogram's core implementation are within `gen.hpp` and `gen.cpp` in the project directory.
`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 may reflect and/or generate code.
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): 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):
@ -100,8 +95,8 @@ Validation through ast construction.
Code header = parse_struct( code( Code header = parse_struct( code(
struct ArrayHeader struct ArrayHeader
{ {
usize Num; usize Num;
usize Capacity; usize Capacity;
allocator Allocator; allocator Allocator;
}; };
)); ));
@ -116,8 +111,8 @@ No validation, just glorified text injection.
Code header = code_str( Code header = code_str(
struct ArrayHeader struct ArrayHeader
{ {
usize Num; usize Num;
usize Capacity; usize Capacity;
allocator Allocator; allocator Allocator;
}; };
); );
@ -126,15 +121,15 @@ Code header = code_str(
`name` is a helper macro for providing a string literal with its size, intended for the name parameter of functions. `name` is a helper macro for providing a string literal with its size, intended for the name parameter of functions.
`code` is a helper macro for providing a string literal with its size, but intended for code string parameters. `code` is a helper macro for providing a string literal with its size, but intended for code string parameters.
`args` is a helper macro for providing the number of arguments to varadic constructors. `args` is a helper macro for providing the number of arguments to varadic constructors.
`code_str` is a helper macro for writting `untyped_str( code( <content> ))` `code_str` is a helper macro for writing `untyped_str( code( <content> ))`
All three constrcuton interfaces will generate the following C code: All three construction interfaces will generate the following C code:
```cpp ```cpp
struct ArrayHeader struct ArrayHeader
{ {
usize Num; usize Num;
usize Capacity; usize Capacity;
allocator Allocator; allocator Allocator;
}; };
``` ```

View File

@ -13,11 +13,11 @@ Standard formats:
* **base**: Files are in granular pieces separated into four directories: * **base**: Files are in granular pieces separated into four directories:
* **dependencies**: Originally from the c-zpl library and modified thereafter. * **dependencies**: Originally from the c-zpl library and modified thereafter.
* **components**: The essential definitions of the library. * **components**: The essential definitions of the library.
* **helpers**: Contains helper functionality used by base and other libraries to regenerate or generate the other library formats. * **helpers**: Contains helper functionality used by base and the variant library generators.
* `base_codegen.hpp`: Helps with self-hosted code generation of enums, and operator overload inlines of the code types. * `base_codegen.hpp`: Helps with self-hosted code generation of enums, and operator overload inlines of the code types.
* `<push/pop>.<name>.inline.<hpp>`: macros that are meant to be injected at specific locations of the library. * `<push/pop>.<name>.inline.<hpp>`: macros that are meant to be injected at specific locations of the library file/s.
* `misc.hpp`: Misc functionality used by the library generation metaprograms. * `misc.hpp`: Misc functionality used by the library generation metaprograms.
* `undef.macros.h`: Undefines all macros from library that original were intended to leak into user code. * `undef.macros.h`: Undefines all macros from library.
* **auxillary**: Non-essential tooling: * **auxillary**: Non-essential tooling:
* `Builder`: Similar conceptually to Jai programming language's *builder*, just opens a file and prepares a string buffer to serialize code into (`builder_print`, `builder_print_fmt`). Then write & close the file when completed (`builder_write`). * `Builder`: Similar conceptually to Jai programming language's *builder*, just opens a file and prepares a string buffer to serialize code into (`builder_print`, `builder_print_fmt`). Then write & close the file when completed (`builder_write`).
* **`Scanner`**: Interface to load up `Code` from files two basic funcctions are currently provided. * **`Scanner`**: Interface to load up `Code` from files two basic funcctions are currently provided.
@ -31,8 +31,6 @@ Standard formats:
Code not making up the core library is located in `auxiliary/<auxiliary_name>.<hpp/cpp>`. These are optional extensions or tools for the library. Code not making up the core library is located in `auxiliary/<auxiliary_name>.<hpp/cpp>`. These are optional extensions or tools for the library.
*Note: A variant of the C++ library could be generated where those additonal support features are removed (see gen_c_library implementation for an idea of how)*
## Dependencies ## Dependencies
The project has no external dependencies beyond: The project has no external dependencies beyond:
@ -71,7 +69,9 @@ This library was written in a subset of C++ where the following are not used at
* Exceptions * Exceptions
Polymorphic & Member-functions are used as an ergonomic choice, along with a conserative use of operator overloads. Polymorphic & Member-functions are used as an ergonomic choice, along with a conserative use of operator overloads.
The base library itself does not use anything but C-like features to allow for generating a derviative compatiable with C (WIP). The base library itself does not use anything but C-like features to allow for generating a derviative compatiable with C.
Member function support or free-functions with reference object passing are wrapped in `! GEN_C_LIKE CPP` preprocess conditionals.
## C++ template usage ## C++ template usage
@ -117,7 +117,7 @@ The vast majority of macros should be single-line subsitutions that either add:
There are ***five*** header files which are automatically generated using [base_codegen.hpp](./helpers/base_codegen.hpp) by [base.cpp](./base.cpp). They are all located in [components/gen](./components/gen/). There are ***five*** header files which are automatically generated using [base_codegen.hpp](./helpers/base_codegen.hpp) by [base.cpp](./base.cpp). They are all located in [components/gen](./components/gen/).
* [`ecode.hpp`](./components/gen/ecode.hpp): `CodeType` enum definition and related implementaiton. Generation is based off of [`ECodeType.csv](./enums/ECodeTypes.csv). * [`ecodetypes.hpp`](./components/gen/ecode.hpp): `CodeType` enum definition and related implementaiton. Generation is based off of [`ECodeType.csv](./enums/ECodeTypes.csv).
* [`especifier.hpp`](./components/gen/especifier.hpp): `Specifier` enum definition, etc. Generated using [`ESpecifier.csv`](./enums/ESpecifier.csv). * [`especifier.hpp`](./components/gen/especifier.hpp): `Specifier` enum definition, etc. Generated using [`ESpecifier.csv`](./enums/ESpecifier.csv).
* [`eoperator.hpp`](./components/gen/eoperator.hpp): `Operator` enum definition, etc. Generated using [`EOperator.hpp`](./enums/EOperator.csv). * [`eoperator.hpp`](./components/gen/eoperator.hpp): `Operator` enum definition, etc. Generated using [`EOperator.hpp`](./enums/EOperator.csv).
* [`etoktype.cpp`](./components/gen/etoktype.cpp): `TokType` enum defininition, etc. Used by the lexer and parser backend. Uses two csvs: * [`etoktype.cpp`](./components/gen/etoktype.cpp): `TokType` enum defininition, etc. Used by the lexer and parser backend. Uses two csvs:
@ -127,6 +127,14 @@ There are ***five*** header files which are automatically generated using [base_
[`misc.hpp`](./helpers/misc.hpp): Has shared functions used by the library generation meta-programs throughout this codebase. [`misc.hpp`](./helpers/misc.hpp): Has shared functions used by the library generation meta-programs throughout this codebase.
If using the library's provided build scripts:
```ps1
.\build.ps1 <compiler> <debug or omit> base
```
Will refresh those files.
## On multi-threading ## On multi-threading
Currently unsupported. I want the library to be *stable* and *correct*, with the addition of exhausting all basic single-threaded optimizations before I consider multi-threading. Currently unsupported. I want the library to be *stable* and *correct*, with the addition of exhausting all basic single-threaded optimizations before I consider multi-threading.
@ -135,18 +143,18 @@ Currently unsupported. I want the library to be *stable* and *correct*, with the
This library is relatively very small (for parsing C++), and can be extended without much hassle. This library is relatively very small (for parsing C++), and can be extended without much hassle.
The convention you'll see used throughout the interface of the library is as follows: The convention you'll see used throughout the upfront interface of the library is as follows:
1. Check name or parameters to make sure they are valid for the construction requested 1. Check name or parameters to make sure they are valid for the construction requested
2. Create a code object using `make_code`. 2. Create a code object using `make_code`.
3. Populate immediate fields (Name, Type, ModuleFlags, etc) 3. Populate immediate fields (Name, Type, ModuleFlags, etc)
4. Populate sub-entires using `add_entry`. If using the default serialization function `to_string`, follow the order at which entires are expected to appear (there is a strong ordering expected). 4. Populate sub-entires using `add_entry`. If using the default serialization function `to_strbuilder`, follow the order at which entires are expected to appear (there is a strong ordering expected).
Names or Content fields are interned strings and thus showed be cached using `get_cached_string` if its desired to preserve that behavior. Names or Content fields are interned strings and thus showed be cached using `get_cached_string` if its desired to preserve that behavior.
`def_operator` is the most sophisticated upfront constructor as it has multiple permutations of definitions that could be created that are not trivial to determine if valid. `def_operator` is the most sophisticated upfront constructor as it has multiple permutations of definitions that could be created that are not trivial to determine if valid.
The parser is documented under `docs/Parsing.md` and `docs/Parser_Algo.md`. Extending it is more serious, but resolution of a parse for a given internal parse procedure is well documented. The parser is documented under [`docs/Parsing.md`](../docs/Parsing.md) and [`docs/Parser_Algo.md`](../docs/Parser_Algo.md).
## A note on compilation and runtime generation speed ## A note on compilation and runtime generation speed

View File

@ -15,7 +15,7 @@ Builder builder_open( char const* path )
return result; return result;
} }
result.Buffer = string_make_reserve( GlobalAllocator, Builder_StrBufferReserve ); result.Buffer = strbuilder_make_reserve( GlobalAllocator, Builder_StrBufferReserve );
// log_fmt("$Builder - Opened file: %s\n", result.File.filename ); // log_fmt("$Builder - Opened file: %s\n", result.File.filename );
return result; return result;
@ -23,15 +23,15 @@ Builder builder_open( char const* path )
void builder_pad_lines( Builder* builder, s32 num ) void builder_pad_lines( Builder* builder, s32 num )
{ {
string_append_strc( & builder->Buffer, txt("\n") ); strbuilder_append_str( & builder->Buffer, txt("\n") );
} }
void builder_print( Builder* builder, Code code ) void builder_print( Builder* builder, Code code )
{ {
String str = code_to_string(code); StrBuilder str = code_to_strbuilder(code);
// const ssize len = str.length(); // const ssize len = str.length();
// log_fmt( "%s - print: %.*s\n", File.filename, len > 80 ? 80 : len, str.Data ); // log_fmt( "%s - print: %.*s\n", File.filename, len > 80 ? 80 : len, str.Data );
string_append_string( & builder->Buffer, str ); strbuilder_append_string( & builder->Buffer, str );
} }
void builder_print_fmt_va( Builder* builder, char const* fmt, va_list va ) void builder_print_fmt_va( Builder* builder, char const* fmt, va_list va )
@ -39,21 +39,21 @@ void builder_print_fmt_va( Builder* builder, char const* fmt, va_list va )
ssize res; ssize res;
char buf[ GEN_PRINTF_MAXLEN ] = { 0 }; char buf[ GEN_PRINTF_MAXLEN ] = { 0 };
res = str_fmt_va( buf, count_of( buf ) - 1, fmt, va ) - 1; res = c_str_fmt_va( buf, count_of( buf ) - 1, fmt, va ) - 1;
string_append_c_str_len( (String*) & (builder->Buffer), (char const*)buf, res); strbuilder_append_c_str_len( (StrBuilder*) & (builder->Buffer), (char const*)buf, res);
} }
void builder_write(Builder* builder) void builder_write(Builder* builder)
{ {
b32 result = file_write( & builder->File, builder->Buffer, string_length(builder->Buffer) ); b32 result = file_write( & builder->File, builder->Buffer, strbuilder_length(builder->Buffer) );
if ( result == false ) if ( result == false )
log_failure("gen::File::write - Failed to write to file: %s\n", file_name( & builder->File ) ); log_failure("gen::File::write - Failed to write to file: %s\n", file_name( & builder->File ) );
log_fmt( "Generated: %s\n", builder->File.filename ); log_fmt( "Generated: %s\n", builder->File.filename );
file_close( & builder->File ); file_close( & builder->File );
string_free(& builder->Buffer); strbuilder_free(& builder->Buffer);
} }
#pragma endregion Builder #pragma endregion Builder

View File

@ -36,7 +36,7 @@ void builder_write( Builder* builder );
struct Builder struct Builder
{ {
FileInfo File; FileInfo File;
String Buffer; StrBuilder Buffer;
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP #if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
forceinline static Builder open( char const* path ) { return builder_open(path); } forceinline static Builder open( char const* path ) { return builder_open(path); }

View File

@ -32,4 +32,4 @@ CodeFn gen_func_template( CodeTemplate template, ... );
Code gen_class_struct_template( CodeTemplate template, ... ); Code gen_class_struct_template( CodeTemplate template, ... );
Code gen_template( CodeTemplate template, ... ); Code gen_template( CodeTemplate template, ... );
Code gen_template( StrC template, StrC instantiation ); Code gen_template( Str template, Str instantiation );

View File

@ -20,9 +20,9 @@ Code scan_file( char const* path )
GEN_FATAL("scan_file: %s is empty", path ); GEN_FATAL("scan_file: %s is empty", path );
} }
String str = string_make_reserve( GlobalAllocator, fsize ); StrBuilder str = strbuilder_make_reserve( GlobalAllocator, fsize );
file_read( & file, str, fsize ); file_read( & file, str, fsize );
string_get_header(str)->Length = fsize; strbuilder_get_header(str)->Length = fsize;
// Skip GEN_INTELLISENSE_DIRECTIVES preprocessor blocks // Skip GEN_INTELLISENSE_DIRECTIVES preprocessor blocks
// Its designed so that the directive should be the first thing in the file. // Its designed so that the directive should be the first thing in the file.
@ -31,9 +31,9 @@ Code scan_file( char const* path )
#define current (*scanner) #define current (*scanner)
#define matched 0 #define matched 0
#define move_fwd() do { ++ scanner; -- left; } while (0) #define move_fwd() do { ++ scanner; -- left; } while (0)
const StrC directive_start = txt( "ifdef" ); const Str directive_start = txt( "ifdef" );
const StrC directive_end = txt( "endif" ); const Str directive_end = txt( "endif" );
const StrC def_intellisense = txt("GEN_INTELLISENSE_DIRECTIVES" ); const Str def_intellisense = txt("GEN_INTELLISENSE_DIRECTIVES" );
bool found_directive = false; bool found_directive = false;
char const* scanner = (char const*)str; char const* scanner = (char const*)str;
@ -49,7 +49,7 @@ Code scan_file( char const* path )
if ( ! found_directive ) if ( ! found_directive )
{ {
if ( left && str_compare_len( scanner, directive_start.Ptr, directive_start.Len ) == matched ) if ( left && c_str_compare_len( scanner, directive_start.Ptr, directive_start.Len ) == matched )
{ {
scanner += directive_start.Len; scanner += directive_start.Len;
left -= directive_start.Len; left -= directive_start.Len;
@ -57,7 +57,7 @@ Code scan_file( char const* path )
while ( left && char_is_space( current ) ) while ( left && char_is_space( current ) )
move_fwd(); move_fwd();
if ( left && str_compare_len( scanner, def_intellisense.Ptr, def_intellisense.Len ) == matched ) if ( left && c_str_compare_len( scanner, def_intellisense.Ptr, def_intellisense.Len ) == matched )
{ {
scanner += def_intellisense.Len; scanner += def_intellisense.Len;
left -= def_intellisense.Len; left -= def_intellisense.Len;
@ -77,7 +77,7 @@ Code scan_file( char const* path )
continue; continue;
} }
if ( left && str_compare_len( scanner, directive_end.Ptr, directive_end.Len ) == matched ) if ( left && c_str_compare_len( scanner, directive_end.Ptr, directive_end.Len ) == matched )
{ {
scanner += directive_end.Len; scanner += directive_end.Len;
left -= directive_end.Len; left -= directive_end.Len;
@ -94,12 +94,12 @@ Code scan_file( char const* path )
if ( (scanner + 2) >= ( (char const*) str + fsize ) ) if ( (scanner + 2) >= ( (char const*) str + fsize ) )
{ {
mem_move( str, scanner, left ); mem_move( str, scanner, left );
string_get_header(str)->Length = left; strbuilder_get_header(str)->Length = left;
break; break;
} }
mem_move( str, scanner, left ); mem_move( str, scanner, left );
string_get_header(str)->Length = left; strbuilder_get_header(str)->Length = left;
break; break;
} }
@ -113,12 +113,12 @@ Code scan_file( char const* path )
} }
file_close( & file ); file_close( & file );
return untyped_str( string_to_strc(str) ); return untyped_str( strbuilder_to_str(str) );
} }
CodeBody parse_file( const char* path ) { CodeBody parse_file( const char* path ) {
FileContents file = file_read_contents( GlobalAllocator, true, path ); FileContents file = file_read_contents( GlobalAllocator, true, path );
StrC content = { file.size, (char const*)file.data }; Str content = { (char const*)file.data, file.size };
CodeBody code = parse_global_body( content ); CodeBody code = parse_global_body( content );
log_fmt("\nParsed: %s\n", path); log_fmt("\nParsed: %s\n", path);
return code; return code;

View File

@ -35,15 +35,16 @@ int gen_main()
def_include(txt("components/types.hpp")), def_include(txt("components/types.hpp")),
preprocess_endif, preprocess_endif,
fmt_newline, fmt_newline,
untyped_str( to_strc_from_c_str(generation_notice) ) untyped_str( to_str_from_c_str(generation_notice) )
)); ));
CodeBody ecode = gen_ecode ( "enums/ECodeTypes.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 etoktype = gen_etoktype ( "enums/ETokType.csv", "enums/AttributeTokens.csv" );
CodeBody ast_inlines = gen_ast_inlines(); CodeBody ast_inlines = gen_ast_inlines();
Builder header_ecode = builder_open( "components/gen/ecode.hpp" ); Builder header_ecode = builder_open( "components/gen/ecodetypes.hpp" );
builder_print( & header_ecode, gen_component_header ); builder_print( & header_ecode, gen_component_header );
builder_print( & header_ecode, format(ecode) ); builder_print( & header_ecode, format(ecode) );
builder_write( & header_ecode); builder_write( & header_ecode);
@ -57,6 +58,11 @@ int gen_main()
builder_print( & header_especifier, gen_component_header ); builder_print( & header_especifier, gen_component_header );
builder_print( & header_especifier, format(especifier) ); builder_print( & header_especifier, format(especifier) );
builder_write( & header_especifier); builder_write( & header_especifier);
Builder header_etoktype = builder_open( "components/gen/etoktype.cpp" );
builder_print( & header_etoktype, gen_component_header );
builder_print( & header_etoktype, format(etoktype) );
builder_write( & header_etoktype);
Builder header_ast_inlines = builder_open( "components/gen/ast_inlines.hpp" ); Builder header_ast_inlines = builder_open( "components/gen/ast_inlines.hpp" );
builder_print( & header_ast_inlines, gen_component_header ); builder_print( & header_ast_inlines, gen_component_header );

File diff suppressed because it is too large Load Diff

View File

@ -37,7 +37,7 @@ struct AST_Module;
struct AST_NS; struct AST_NS;
struct AST_Operator; struct AST_Operator;
struct AST_OpCast; struct AST_OpCast;
struct AST_Param; struct AST_Params;
struct AST_Pragma; struct AST_Pragma;
struct AST_PreprocessCond; struct AST_PreprocessCond;
struct AST_Specifiers; struct AST_Specifiers;
@ -109,7 +109,7 @@ typedef AST_Module* CodeModule;
typedef AST_NS* CodeNS; typedef AST_NS* CodeNS;
typedef AST_Operator* CodeOperator; typedef AST_Operator* CodeOperator;
typedef AST_OpCast* CodeOpCast; typedef AST_OpCast* CodeOpCast;
typedef AST_Param* CodeParam; typedef AST_Params* CodeParams;
typedef AST_PreprocessCond* CodePreprocessCond; typedef AST_PreprocessCond* CodePreprocessCond;
typedef AST_Pragma* CodePragma; typedef AST_Pragma* CodePragma;
typedef AST_Specifiers* CodeSpecifiers; typedef AST_Specifiers* CodeSpecifiers;
@ -131,7 +131,7 @@ struct CodeModule;
struct CodeNS; struct CodeNS;
struct CodeOperator; struct CodeOperator;
struct CodeOpCast; struct CodeOpCast;
struct CodeParam; struct CodeParams;
struct CodePreprocessCond; struct CodePreprocessCond;
struct CodePragma; struct CodePragma;
struct CodeSpecifiers; struct CodeSpecifiers;
@ -209,6 +209,7 @@ struct CodeStmt_Switch;
struct CodeStmt_While; struct CodeStmt_While;
#endif #endif
// GEN_EXECUTION_EXPRESSION_SUPPORT
#endif #endif
#if GEN_COMPILER_C #if GEN_COMPILER_C
@ -229,8 +230,6 @@ struct CodeUsing;
struct CodeVar; struct CodeVar;
#endif #endif
#undef Define_Code
GEN_NS_PARSER_BEGIN GEN_NS_PARSER_BEGIN
struct Token; struct Token;
@ -243,7 +242,7 @@ GEN_NS_PARSER_END
// I have ideas for ways to pack that into the typedef/using ast, but for now just keeping it like this // 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 #define ParserTokenType GEN_NS_PARSER Token
typedef ParserTokenType Token; typedef ParserTokenType Token;
#undef ParserTokenType #undef ParserTokenType
#endif #endif
#if GEN_COMPILER_CPP #if GEN_COMPILER_CPP
@ -252,19 +251,19 @@ template< class Type> forceinline Type tmpl_cast( Code self ) { return * rcast(
#pragma region Code C-Interface #pragma region Code C-Interface
void code_append (Code code, Code other ); void code_append (Code code, Code other );
StrC code_debug_str (Code code); Str code_debug_str (Code code);
Code code_duplicate (Code code); Code code_duplicate (Code code);
Code* code_entry (Code code, u32 idx ); Code* code_entry (Code code, u32 idx );
bool code_has_entries (Code code); bool code_has_entries (Code code);
bool code_is_body (Code code); bool code_is_body (Code code);
bool code_is_equal (Code code, Code other); bool code_is_equal (Code code, Code other);
bool code_is_valid (Code code); bool code_is_valid (Code code);
void code_set_global (Code code); void code_set_global (Code code);
String code_to_string (Code self ); StrBuilder code_to_strbuilder (Code self );
void code_to_string_ptr(Code self, String* result ); void code_to_strbuilder_ptr(Code self, StrBuilder* result );
StrC code_type_str (Code self ); Str code_type_str (Code self );
bool code_validate_body(Code self ); bool code_validate_body (Code self );
#pragma endregion Code C-Interface #pragma endregion Code C-Interface
@ -279,7 +278,7 @@ struct Code
AST* ast; AST* ast;
# define Using_Code( Typename ) \ # define Using_Code( Typename ) \
forceinline StrC debug_str() { return code_debug_str(* this); } \ forceinline Str debug_str() { return code_debug_str(* this); } \
forceinline Code duplicate() { return code_duplicate(* this); } \ forceinline Code duplicate() { return code_duplicate(* this); } \
forceinline bool is_equal( Code other ) { return code_is_equal(* this, other); } \ forceinline bool is_equal( Code other ) { return code_is_equal(* this, other); } \
forceinline bool is_body() { return code_is_body(* this); } \ forceinline bool is_body() { return code_is_body(* this); } \
@ -296,32 +295,21 @@ struct Code
#if ! GEN_C_LIKE_CPP #if ! GEN_C_LIKE_CPP
Using_Code( Code ); Using_Code( Code );
forceinline void append(Code other) { return code_append(* this, other); } forceinline void append(Code other) { return code_append(* this, other); }
forceinline Code* entry(u32 idx) { return code_entry(* this, idx); } forceinline Code* entry(u32 idx) { return code_entry(* this, idx); }
forceinline bool has_entries() { return code_has_entries(* this); } forceinline bool has_entries() { return code_has_entries(* this); }
forceinline String to_string() { return code_to_string(* this); } forceinline StrBuilder to_strbuilder() { return code_to_strbuilder(* this); }
forceinline void to_string(String& result) { return code_to_string_ptr(* this, & result); } forceinline void to_strbuilder(StrBuilder& result) { return code_to_strbuilder_ptr(* this, & result); }
forceinline StrC type_str() { return code_type_str(* this); } forceinline Str type_str() { return code_type_str(* this); }
forceinline 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 Code operator *() { return * this; } // Required to support for-range iteration.
forceinline AST* operator ->() { return ast; } forceinline AST* operator ->() { return ast; }
Code& operator ++(); Code& operator ++();
// TODO(Ed) : Remove this overload.
auto& operator*()
{
local_persist thread_local
Code NullRef = { nullptr };
if ( ast == nullptr )
return NullRef;
return *this;
}
#ifdef GEN_ENFORCE_STRONG_CODE_TYPES #ifdef GEN_ENFORCE_STRONG_CODE_TYPES
# define operator explicit operator # define operator explicit operator
#endif #endif
@ -343,7 +331,7 @@ struct Code
operator CodeNS() const; operator CodeNS() const;
operator CodeOperator() const; operator CodeOperator() const;
operator CodeOpCast() const; operator CodeOpCast() const;
operator CodeParam() const; operator CodeParams() const;
operator CodePragma() const; operator CodePragma() const;
operator CodePreprocessCond() const; operator CodePreprocessCond() const;
operator CodeSpecifiers() const; operator CodeSpecifiers() const;
@ -423,7 +411,7 @@ struct AST
union { union {
Code NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value ) Code NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value )
Code SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed ) Code SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed )
Code PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal) Code PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal)
}; };
}; };
StringCached Content; // Attributes, Comment, Execution, Include StringCached Content; // Attributes, Comment, Execution, Include
@ -456,7 +444,7 @@ struct AST
Operator Op; Operator Op;
AccessSpec ParentAccess; AccessSpec ParentAccess;
s32 NumEntries; s32 NumEntries;
s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression. s32 VarParenthesizedInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression.
}; };
}; };
static_assert( sizeof(AST) == AST_POD_Size, "ERROR: AST is not size of AST_POD_Size" ); static_assert( sizeof(AST) == AST_POD_Size, "ERROR: AST is not size of AST_POD_Size" );

View File

@ -1,4 +1,6 @@
# define GEN_AST_BODY_CLASS_UNALLOWED_TYPES \ // These macros are used in the swtich cases are used within ast.cpp, inteface.upfront.cpp, parser.cpp
# define GEN_AST_BODY_CLASS_UNALLOWED_TYPES \
case CT_PlatformAttributes: \ case CT_PlatformAttributes: \
case CT_Class_Body: \ case CT_Class_Body: \
case CT_Enum_Body: \ case CT_Enum_Body: \
@ -13,7 +15,7 @@
case CT_Parameters: \ case CT_Parameters: \
case CT_Specifiers: \ case CT_Specifiers: \
case CT_Struct_Body: \ case CT_Struct_Body: \
case CT_Typename: case CT_Typename
# define GEN_AST_BODY_STRUCT_UNALLOWED_TYPES GEN_AST_BODY_CLASS_UNALLOWED_TYPES # define GEN_AST_BODY_STRUCT_UNALLOWED_TYPES GEN_AST_BODY_CLASS_UNALLOWED_TYPES
# define GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES \ # define GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES \
@ -37,7 +39,7 @@
case CT_Parameters: \ case CT_Parameters: \
case CT_Specifiers: \ case CT_Specifiers: \
case CT_Struct_Body: \ case CT_Struct_Body: \
case CT_Typename: case CT_Typename
# define GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES \ # define GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES \
case CT_Access_Public: \ case CT_Access_Public: \
@ -55,7 +57,7 @@
case CT_Parameters: \ case CT_Parameters: \
case CT_Specifiers: \ case CT_Specifiers: \
case CT_Struct_Body: \ case CT_Struct_Body: \
case CT_Typename: case CT_Typename
# define GEN_AST_BODY_EXPORT_UNALLOWED_TYPES GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES # define GEN_AST_BODY_EXPORT_UNALLOWED_TYPES GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES
# define GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES # define GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES
@ -75,4 +77,4 @@
case CT_Parameters: \ case CT_Parameters: \
case CT_Specifiers: \ case CT_Specifiers: \
case CT_Struct_Body: \ case CT_Struct_Body: \
case CT_Typename: case CT_Typename

View File

@ -127,7 +127,7 @@ struct AST_Constructor
char _PAD_PROPERTIES_ [ sizeof(AST*) * 1 ]; char _PAD_PROPERTIES_ [ sizeof(AST*) * 1 ];
CodeSpecifiers Specs; CodeSpecifiers Specs;
Code InitializerList; Code InitializerList;
CodeParam Params; CodeParams Params;
Code Body; Code Body;
char _PAD_PROPERTIES_2_ [ sizeof(AST*) * 2 ]; char _PAD_PROPERTIES_2_ [ sizeof(AST*) * 2 ];
}; };
@ -550,7 +550,7 @@ struct AST_Fn
CodeAttributes Attributes; CodeAttributes Attributes;
CodeSpecifiers Specs; CodeSpecifiers Specs;
CodeTypename ReturnType; CodeTypename ReturnType;
CodeParam Params; CodeParams Params;
CodeBody Body; CodeBody Body;
char _PAD_PROPERTIES_ [ sizeof(AST*) ]; char _PAD_PROPERTIES_ [ sizeof(AST*) ];
}; };
@ -613,7 +613,7 @@ struct AST_Operator
CodeAttributes Attributes; CodeAttributes Attributes;
CodeSpecifiers Specs; CodeSpecifiers Specs;
CodeTypename ReturnType; CodeTypename ReturnType;
CodeParam Params; CodeParams Params;
CodeBody Body; CodeBody Body;
char _PAD_PROPERTIES_ [ sizeof(AST*) ]; char _PAD_PROPERTIES_ [ sizeof(AST*) ];
}; };
@ -639,9 +639,9 @@ struct AST_OpCast
char _PAD_PROPERTIES_[ sizeof(AST*) ]; char _PAD_PROPERTIES_[ sizeof(AST*) ];
CodeSpecifiers Specs; CodeSpecifiers Specs;
CodeTypename ValueType; CodeTypename ValueType;
char _PAD_PROPERTIES_2_[ sizeof(AST*) ]; char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
CodeBody Body; CodeBody Body;
char _PAD_PROPERTIES_3_[ sizeof(AST*) ]; char _PAD_PROPERTIES_3_[ sizeof(AST*) ];
}; };
}; };
StringCached Name; StringCached Name;
@ -654,7 +654,7 @@ struct AST_OpCast
}; };
static_assert( sizeof(AST_OpCast) == sizeof(AST), "ERROR: AST_OpCast is not the same size as AST"); static_assert( sizeof(AST_OpCast) == sizeof(AST), "ERROR: AST_OpCast is not the same size as AST");
struct AST_Param struct AST_Params
{ {
union { union {
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ]; char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
@ -669,15 +669,15 @@ struct AST_Param
}; };
}; };
StringCached Name; StringCached Name;
CodeParam Last; CodeParams Last;
CodeParam Next; CodeParams Next;
Token* Tok; Token* Tok;
Code Parent; Code Parent;
CodeType Type; CodeType Type;
char _PAD_UNUSED_[ sizeof(ModuleFlag) ]; char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
s32 NumEntries; s32 NumEntries;
}; };
static_assert( sizeof(AST_Param) == sizeof(AST), "ERROR: AST_Param is not the same size as AST"); static_assert( sizeof(AST_Params) == sizeof(AST), "ERROR: AST_Params is not the same size as AST");
struct AST_Pragma struct AST_Pragma
{ {
@ -971,7 +971,7 @@ struct AST_Template
struct struct
{ {
char _PAD_PROPERTIES_[ sizeof(AST*) * 4 ]; char _PAD_PROPERTIES_[ sizeof(AST*) * 4 ];
CodeParam Params; CodeParams Params;
Code Declaration; Code Declaration;
char _PAD_PROPERTIES_2_[ sizeof(AST*) ]; char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
}; };
@ -1000,7 +1000,7 @@ struct AST_Type
CodeSpecifiers Specs; CodeSpecifiers Specs;
Code QualifierID; Code QualifierID;
// CodeTypename ReturnType; // Only used for function signatures // CodeTypename ReturnType; // Only used for function signatures
// CodeParam Params; // Only used for function signatures // CodeParams Params; // Only used for function signatures
Code ArrExpr; Code ArrExpr;
// CodeSpecifiers SpecsFuncSuffix; // Only used for function signatures // CodeSpecifiers SpecsFuncSuffix; // Only used for function signatures
}; };
@ -1017,7 +1017,6 @@ struct AST_Type
static_assert( sizeof(AST_Type) == sizeof(AST), "ERROR: AST_Type is not the same size as AST"); static_assert( sizeof(AST_Type) == sizeof(AST), "ERROR: AST_Type is not the same size as AST");
#endif #endif
// TODO(Ed): Add support for preserving the typename's keyword qualifier (struct, class, enum, etc), mostly needed for C.
struct AST_Typename struct AST_Typename
{ {
union { union {
@ -1028,7 +1027,7 @@ struct AST_Typename
CodeAttributes Attributes; CodeAttributes Attributes;
CodeSpecifiers Specs; CodeSpecifiers Specs;
CodeTypename ReturnType; // Only used for function signatures CodeTypename ReturnType; // Only used for function signatures
CodeParam Params; // Only used for function signatures CodeParams Params; // Only used for function signatures
Code ArrExpr; Code ArrExpr;
CodeSpecifiers SpecsFuncSuffix; // Only used for function signatures CodeSpecifiers SpecsFuncSuffix; // Only used for function signatures
}; };
@ -1140,7 +1139,7 @@ struct AST_Var
Code Parent; Code Parent;
CodeType Type; CodeType Type;
ModuleFlag ModuleFlags; ModuleFlag ModuleFlags;
s32 VarConstructorInit; s32 VarParenthesizedInit;
}; };
static_assert( sizeof(AST_Var) == sizeof(AST), "ERROR: AST_Var is not the same size as AST"); static_assert( sizeof(AST_Var) == sizeof(AST), "ERROR: AST_Var is not the same size as AST");

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -64,7 +64,7 @@ inline AST_Attributes* CodeAttributes::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -95,7 +95,7 @@ inline AST_Comment* CodeComment::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -126,7 +126,7 @@ inline AST_Constructor* CodeConstructor::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -173,7 +173,7 @@ inline AST_Define* CodeDefine::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -204,7 +204,7 @@ inline AST_Destructor* CodeDestructor::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -235,7 +235,7 @@ inline AST_Enum* CodeEnum::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -266,7 +266,7 @@ inline AST_Exec* CodeExec::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -297,7 +297,7 @@ inline AST_Extern* CodeExtern::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -328,7 +328,7 @@ inline AST_Friend* CodeFriend::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -359,7 +359,7 @@ inline AST_Fn* CodeFn::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -390,7 +390,7 @@ inline AST_Include* CodeInclude::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -421,7 +421,7 @@ inline AST_Module* CodeModule::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -452,7 +452,7 @@ inline AST_NS* CodeNS::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -483,7 +483,7 @@ inline AST_Operator* CodeOperator::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -514,13 +514,13 @@ inline AST_OpCast* CodeOpCast::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeParam& CodeParam::operator=( Code other ) inline CodeParams& CodeParams::operator=( Code other )
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if ( other.ast != nullptr && other->Parent != nullptr )
{ {
@ -531,7 +531,7 @@ inline CodeParam& CodeParam::operator=( Code other )
return *this; return *this;
} }
inline CodeParam::operator bool() inline CodeParams::operator bool()
{ {
return ast != nullptr; return ast != nullptr;
} }
@ -561,7 +561,7 @@ inline AST_Pragma* CodePragma::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -592,7 +592,7 @@ inline AST_PreprocessCond* CodePreprocessCond::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -655,7 +655,7 @@ inline AST_Template* CodeTemplate::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -686,7 +686,7 @@ inline AST_Typename* CodeTypename::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -717,7 +717,7 @@ inline AST_Typedef* CodeTypedef::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -748,7 +748,7 @@ inline AST_Union* CodeUnion::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -779,7 +779,7 @@ inline AST_Using* CodeUsing::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -810,7 +810,7 @@ inline AST_Var* CodeVar::operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -906,9 +906,9 @@ forceinline Code::operator CodeOpCast() const
return { (AST_OpCast*)ast }; return { (AST_OpCast*)ast };
} }
forceinline Code::operator CodeParam() const forceinline Code::operator CodeParams() const
{ {
return { (AST_Param*)ast }; return { (AST_Params*)ast };
} }
forceinline Code::operator CodePragma() const forceinline Code::operator CodePragma() const

View File

@ -1,219 +0,0 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#pragma once
#include "components/types.hpp"
#endif
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
enum CodeType : u32
{
CT_Invalid,
CT_Untyped,
CT_NewLine,
CT_Comment,
CT_Access_Private,
CT_Access_Protected,
CT_Access_Public,
CT_PlatformAttributes,
CT_Class,
CT_Class_Fwd,
CT_Class_Body,
CT_Constructor,
CT_Constructor_Fwd,
CT_Destructor,
CT_Destructor_Fwd,
CT_Enum,
CT_Enum_Fwd,
CT_Enum_Body,
CT_Enum_Class,
CT_Enum_Class_Fwd,
CT_Execution,
CT_Export_Body,
CT_Extern_Linkage,
CT_Extern_Linkage_Body,
CT_Friend,
CT_Function,
CT_Function_Fwd,
CT_Function_Body,
CT_Global_Body,
CT_Module,
CT_Namespace,
CT_Namespace_Body,
CT_Operator,
CT_Operator_Fwd,
CT_Operator_Member,
CT_Operator_Member_Fwd,
CT_Operator_Cast,
CT_Operator_Cast_Fwd,
CT_Parameters,
CT_Preprocess_Define,
CT_Preprocess_Include,
CT_Preprocess_If,
CT_Preprocess_IfDef,
CT_Preprocess_IfNotDef,
CT_Preprocess_ElIf,
CT_Preprocess_Else,
CT_Preprocess_EndIf,
CT_Preprocess_Pragma,
CT_Specifiers,
CT_Struct,
CT_Struct_Fwd,
CT_Struct_Body,
CT_Template,
CT_Typedef,
CT_Typename,
CT_Union,
CT_Union_Fwd,
CT_Union_Body,
CT_Using,
CT_Using_Namespace,
CT_Variable,
CT_NumTypes,
CT_UnderlyingType = GEN_U32_MAX
};
inline StrC codetype_to_str( CodeType type )
{
local_persist StrC lookup[61] = {
{ sizeof( "Invalid" ), "Invalid" },
{ sizeof( "Untyped" ), "Untyped" },
{ sizeof( "NewLine" ), "NewLine" },
{ sizeof( "Comment" ), "Comment" },
{ sizeof( "Access_Private" ), "Access_Private" },
{ sizeof( "Access_Protected" ), "Access_Protected" },
{ sizeof( "Access_Public" ), "Access_Public" },
{ sizeof( "PlatformAttributes" ), "PlatformAttributes" },
{ sizeof( "Class" ), "Class" },
{ sizeof( "Class_Fwd" ), "Class_Fwd" },
{ sizeof( "Class_Body" ), "Class_Body" },
{ sizeof( "Constructor" ), "Constructor" },
{ sizeof( "Constructor_Fwd" ), "Constructor_Fwd" },
{ sizeof( "Destructor" ), "Destructor" },
{ sizeof( "Destructor_Fwd" ), "Destructor_Fwd" },
{ sizeof( "Enum" ), "Enum" },
{ sizeof( "Enum_Fwd" ), "Enum_Fwd" },
{ sizeof( "Enum_Body" ), "Enum_Body" },
{ sizeof( "Enum_Class" ), "Enum_Class" },
{ sizeof( "Enum_Class_Fwd" ), "Enum_Class_Fwd" },
{ sizeof( "Execution" ), "Execution" },
{ sizeof( "Export_Body" ), "Export_Body" },
{ sizeof( "Extern_Linkage" ), "Extern_Linkage" },
{ sizeof( "Extern_Linkage_Body" ), "Extern_Linkage_Body" },
{ sizeof( "Friend" ), "Friend" },
{ sizeof( "Function" ), "Function" },
{ sizeof( "Function_Fwd" ), "Function_Fwd" },
{ sizeof( "Function_Body" ), "Function_Body" },
{ sizeof( "Global_Body" ), "Global_Body" },
{ sizeof( "Module" ), "Module" },
{ sizeof( "Namespace" ), "Namespace" },
{ sizeof( "Namespace_Body" ), "Namespace_Body" },
{ sizeof( "Operator" ), "Operator" },
{ sizeof( "Operator_Fwd" ), "Operator_Fwd" },
{ sizeof( "Operator_Member" ), "Operator_Member" },
{ sizeof( "Operator_Member_Fwd" ), "Operator_Member_Fwd" },
{ sizeof( "Operator_Cast" ), "Operator_Cast" },
{ sizeof( "Operator_Cast_Fwd" ), "Operator_Cast_Fwd" },
{ sizeof( "Parameters" ), "Parameters" },
{ sizeof( "Preprocess_Define" ), "Preprocess_Define" },
{ sizeof( "Preprocess_Include" ), "Preprocess_Include" },
{ sizeof( "Preprocess_If" ), "Preprocess_If" },
{ sizeof( "Preprocess_IfDef" ), "Preprocess_IfDef" },
{ sizeof( "Preprocess_IfNotDef" ), "Preprocess_IfNotDef" },
{ sizeof( "Preprocess_ElIf" ), "Preprocess_ElIf" },
{ sizeof( "Preprocess_Else" ), "Preprocess_Else" },
{ sizeof( "Preprocess_EndIf" ), "Preprocess_EndIf" },
{ sizeof( "Preprocess_Pragma" ), "Preprocess_Pragma" },
{ sizeof( "Specifiers" ), "Specifiers" },
{ sizeof( "Struct" ), "Struct" },
{ sizeof( "Struct_Fwd" ), "Struct_Fwd" },
{ sizeof( "Struct_Body" ), "Struct_Body" },
{ sizeof( "Template" ), "Template" },
{ sizeof( "Typedef" ), "Typedef" },
{ sizeof( "Typename" ), "Typename" },
{ sizeof( "Union" ), "Union" },
{ sizeof( "Union_Fwd" ), "Union_Fwd" },
{ sizeof( "Union_Body" ), "Union_Body" },
{ sizeof( "Using" ), "Using" },
{ sizeof( "Using_Namespace" ), "Using_Namespace" },
{ sizeof( "Variable" ), "Variable" },
};
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

@ -0,0 +1,219 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#pragma once
#include "components/types.hpp"
#endif
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
enum CodeType : u32
{
CT_Invalid,
CT_Untyped,
CT_NewLine,
CT_Comment,
CT_Access_Private,
CT_Access_Protected,
CT_Access_Public,
CT_PlatformAttributes,
CT_Class,
CT_Class_Fwd,
CT_Class_Body,
CT_Constructor,
CT_Constructor_Fwd,
CT_Destructor,
CT_Destructor_Fwd,
CT_Enum,
CT_Enum_Fwd,
CT_Enum_Body,
CT_Enum_Class,
CT_Enum_Class_Fwd,
CT_Execution,
CT_Export_Body,
CT_Extern_Linkage,
CT_Extern_Linkage_Body,
CT_Friend,
CT_Function,
CT_Function_Fwd,
CT_Function_Body,
CT_Global_Body,
CT_Module,
CT_Namespace,
CT_Namespace_Body,
CT_Operator,
CT_Operator_Fwd,
CT_Operator_Member,
CT_Operator_Member_Fwd,
CT_Operator_Cast,
CT_Operator_Cast_Fwd,
CT_Parameters,
CT_Preprocess_Define,
CT_Preprocess_Include,
CT_Preprocess_If,
CT_Preprocess_IfDef,
CT_Preprocess_IfNotDef,
CT_Preprocess_ElIf,
CT_Preprocess_Else,
CT_Preprocess_EndIf,
CT_Preprocess_Pragma,
CT_Specifiers,
CT_Struct,
CT_Struct_Fwd,
CT_Struct_Body,
CT_Template,
CT_Typedef,
CT_Typename,
CT_Union,
CT_Union_Fwd,
CT_Union_Body,
CT_Using,
CT_Using_Namespace,
CT_Variable,
CT_NumTypes,
CT_UnderlyingType = GEN_U32_MAX
};
inline Str codetype_to_str( CodeType type )
{
local_persist Str lookup[61] = {
{ "Invalid", sizeof( "Invalid" ) - 1 },
{ "Untyped", sizeof( "Untyped" ) - 1 },
{ "NewLine", sizeof( "NewLine" ) - 1 },
{ "Comment", sizeof( "Comment" ) - 1 },
{ "Access_Private", sizeof( "Access_Private" ) - 1 },
{ "Access_Protected", sizeof( "Access_Protected" ) - 1 },
{ "Access_Public", sizeof( "Access_Public" ) - 1 },
{ "PlatformAttributes", sizeof( "PlatformAttributes" ) - 1 },
{ "Class", sizeof( "Class" ) - 1 },
{ "Class_Fwd", sizeof( "Class_Fwd" ) - 1 },
{ "Class_Body", sizeof( "Class_Body" ) - 1 },
{ "Constructor", sizeof( "Constructor" ) - 1 },
{ "Constructor_Fwd", sizeof( "Constructor_Fwd" ) - 1 },
{ "Destructor", sizeof( "Destructor" ) - 1 },
{ "Destructor_Fwd", sizeof( "Destructor_Fwd" ) - 1 },
{ "Enum", sizeof( "Enum" ) - 1 },
{ "Enum_Fwd", sizeof( "Enum_Fwd" ) - 1 },
{ "Enum_Body", sizeof( "Enum_Body" ) - 1 },
{ "Enum_Class", sizeof( "Enum_Class" ) - 1 },
{ "Enum_Class_Fwd", sizeof( "Enum_Class_Fwd" ) - 1 },
{ "Execution", sizeof( "Execution" ) - 1 },
{ "Export_Body", sizeof( "Export_Body" ) - 1 },
{ "Extern_Linkage", sizeof( "Extern_Linkage" ) - 1 },
{ "Extern_Linkage_Body", sizeof( "Extern_Linkage_Body" ) - 1 },
{ "Friend", sizeof( "Friend" ) - 1 },
{ "Function", sizeof( "Function" ) - 1 },
{ "Function_Fwd", sizeof( "Function_Fwd" ) - 1 },
{ "Function_Body", sizeof( "Function_Body" ) - 1 },
{ "Global_Body", sizeof( "Global_Body" ) - 1 },
{ "Module", sizeof( "Module" ) - 1 },
{ "Namespace", sizeof( "Namespace" ) - 1 },
{ "Namespace_Body", sizeof( "Namespace_Body" ) - 1 },
{ "Operator", sizeof( "Operator" ) - 1 },
{ "Operator_Fwd", sizeof( "Operator_Fwd" ) - 1 },
{ "Operator_Member", sizeof( "Operator_Member" ) - 1 },
{ "Operator_Member_Fwd", sizeof( "Operator_Member_Fwd" ) - 1 },
{ "Operator_Cast", sizeof( "Operator_Cast" ) - 1 },
{ "Operator_Cast_Fwd", sizeof( "Operator_Cast_Fwd" ) - 1 },
{ "Parameters", sizeof( "Parameters" ) - 1 },
{ "Preprocess_Define", sizeof( "Preprocess_Define" ) - 1 },
{ "Preprocess_Include", sizeof( "Preprocess_Include" ) - 1 },
{ "Preprocess_If", sizeof( "Preprocess_If" ) - 1 },
{ "Preprocess_IfDef", sizeof( "Preprocess_IfDef" ) - 1 },
{ "Preprocess_IfNotDef", sizeof( "Preprocess_IfNotDef" ) - 1 },
{ "Preprocess_ElIf", sizeof( "Preprocess_ElIf" ) - 1 },
{ "Preprocess_Else", sizeof( "Preprocess_Else" ) - 1 },
{ "Preprocess_EndIf", sizeof( "Preprocess_EndIf" ) - 1 },
{ "Preprocess_Pragma", sizeof( "Preprocess_Pragma" ) - 1 },
{ "Specifiers", sizeof( "Specifiers" ) - 1 },
{ "Struct", sizeof( "Struct" ) - 1 },
{ "Struct_Fwd", sizeof( "Struct_Fwd" ) - 1 },
{ "Struct_Body", sizeof( "Struct_Body" ) - 1 },
{ "Template", sizeof( "Template" ) - 1 },
{ "Typedef", sizeof( "Typedef" ) - 1 },
{ "Typename", sizeof( "Typename" ) - 1 },
{ "Union", sizeof( "Union" ) - 1 },
{ "Union_Fwd", sizeof( "Union_Fwd" ) - 1 },
{ "Union_Body", sizeof( "Union_Body" ) - 1 },
{ "Using", sizeof( "Using" ) - 1 },
{ "Using_Namespace", sizeof( "Using_Namespace" ) - 1 },
{ "Variable", sizeof( "Variable" ) - 1 },
};
return lookup[type];
}
inline Str codetype_to_keyword_str( CodeType type )
{
local_persist Str lookup[61] = {
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "//", sizeof( "//" ) - 1 },
{ "private", sizeof( "private" ) - 1 },
{ "protected", sizeof( "protected" ) - 1 },
{ "public", sizeof( "public" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "class", sizeof( "class" ) - 1 },
{ "clsss", sizeof( "clsss" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "enum", sizeof( "enum" ) - 1 },
{ "enum", sizeof( "enum" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "enum class", sizeof( "enum class" ) - 1 },
{ "enum class", sizeof( "enum class" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "extern", sizeof( "extern" ) - 1 },
{ "extern", sizeof( "extern" ) - 1 },
{ "friend", sizeof( "friend" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "module", sizeof( "module" ) - 1 },
{ "namespace", sizeof( "namespace" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "operator", sizeof( "operator" ) - 1 },
{ "operator", sizeof( "operator" ) - 1 },
{ "operator", sizeof( "operator" ) - 1 },
{ "operator", sizeof( "operator" ) - 1 },
{ "operator", sizeof( "operator" ) - 1 },
{ "operator", sizeof( "operator" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "define", sizeof( "define" ) - 1 },
{ "include", sizeof( "include" ) - 1 },
{ "if", sizeof( "if" ) - 1 },
{ "ifdef", sizeof( "ifdef" ) - 1 },
{ "ifndef", sizeof( "ifndef" ) - 1 },
{ "elif", sizeof( "elif" ) - 1 },
{ "else", sizeof( "else" ) - 1 },
{ "endif", sizeof( "endif" ) - 1 },
{ "pragma", sizeof( "pragma" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "struct", sizeof( "struct" ) - 1 },
{ "struct", sizeof( "struct" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "template", sizeof( "template" ) - 1 },
{ "typedef", sizeof( "typedef" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "union", sizeof( "union" ) - 1 },
{ "union", sizeof( "union" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
{ "using", sizeof( "using" ) - 1 },
{ "using namespace", sizeof( "using namespace" ) - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 },
};
return lookup[type];
}
forceinline Str to_str( CodeType type )
{
return codetype_to_str( type );
}
forceinline Str to_keyword_str( CodeType type )
{
return codetype_to_keyword_str( type );
}

View File

@ -58,61 +58,61 @@ enum Operator : u32
Op_UnderlyingType = 0xffffffffu Op_UnderlyingType = 0xffffffffu
}; };
inline StrC operator_to_str( Operator op ) inline Str operator_to_str( Operator op )
{ {
local_persist StrC lookup[47] = { local_persist Str lookup[47] = {
{ sizeof( "INVALID" ), "INVALID" }, { "INVALID", sizeof( "INVALID" ) - 1 },
{ sizeof( "=" ), "=" }, { "=", sizeof( "=" ) - 1 },
{ sizeof( "+=" ), "+=" }, { "+=", sizeof( "+=" ) - 1 },
{ sizeof( "-=" ), "-=" }, { "-=", sizeof( "-=" ) - 1 },
{ sizeof( "*=" ), "*=" }, { "*=", sizeof( "*=" ) - 1 },
{ sizeof( "/=" ), "/=" }, { "/=", sizeof( "/=" ) - 1 },
{ sizeof( "%=" ), "%=" }, { "%=", sizeof( "%=" ) - 1 },
{ sizeof( "&=" ), "&=" }, { "&=", sizeof( "&=" ) - 1 },
{ sizeof( "|=" ), "|=" }, { "|=", sizeof( "|=" ) - 1 },
{ sizeof( "^=" ), "^=" }, { "^=", sizeof( "^=" ) - 1 },
{ sizeof( "<<=" ), "<<=" }, { "<<=", sizeof( "<<=" ) - 1 },
{ sizeof( ">>=" ), ">>=" }, { ">>=", sizeof( ">>=" ) - 1 },
{ sizeof( "++" ), "++" }, { "++", sizeof( "++" ) - 1 },
{ sizeof( "--" ), "--" }, { "--", sizeof( "--" ) - 1 },
{ sizeof( "+" ), "+" }, { "+", sizeof( "+" ) - 1 },
{ sizeof( "-" ), "-" }, { "-", sizeof( "-" ) - 1 },
{ sizeof( "!" ), "!" }, { "!", sizeof( "!" ) - 1 },
{ sizeof( "+" ), "+" }, { "+", sizeof( "+" ) - 1 },
{ sizeof( "-" ), "-" }, { "-", sizeof( "-" ) - 1 },
{ sizeof( "*" ), "*" }, { "*", sizeof( "*" ) - 1 },
{ sizeof( "/" ), "/" }, { "/", sizeof( "/" ) - 1 },
{ sizeof( "%" ), "%" }, { "%", sizeof( "%" ) - 1 },
{ sizeof( "~" ), "~" }, { "~", sizeof( "~" ) - 1 },
{ sizeof( "&" ), "&" }, { "&", sizeof( "&" ) - 1 },
{ sizeof( "|" ), "|" }, { "|", sizeof( "|" ) - 1 },
{ sizeof( "^" ), "^" }, { "^", sizeof( "^" ) - 1 },
{ sizeof( "<<" ), "<<" }, { "<<", sizeof( "<<" ) - 1 },
{ sizeof( ">>" ), ">>" }, { ">>", sizeof( ">>" ) - 1 },
{ sizeof( "&&" ), "&&" }, { "&&", sizeof( "&&" ) - 1 },
{ sizeof( "||" ), "||" }, { "||", sizeof( "||" ) - 1 },
{ sizeof( "==" ), "==" }, { "==", sizeof( "==" ) - 1 },
{ sizeof( "!=" ), "!=" }, { "!=", sizeof( "!=" ) - 1 },
{ sizeof( "<" ), "<" }, { "<", sizeof( "<" ) - 1 },
{ sizeof( ">" ), ">" }, { ">", sizeof( ">" ) - 1 },
{ sizeof( "<=" ), "<=" }, { "<=", sizeof( "<=" ) - 1 },
{ sizeof( ">=" ), ">=" }, { ">=", sizeof( ">=" ) - 1 },
{ sizeof( "[]" ), "[]" }, { "[]", sizeof( "[]" ) - 1 },
{ sizeof( "*" ), "*" }, { "*", sizeof( "*" ) - 1 },
{ sizeof( "&" ), "&" }, { "&", sizeof( "&" ) - 1 },
{ sizeof( "->" ), "->" }, { "->", sizeof( "->" ) - 1 },
{ sizeof( "->*" ), "->*" }, { "->*", sizeof( "->*" ) - 1 },
{ sizeof( "()" ), "()" }, { "()", sizeof( "()" ) - 1 },
{ sizeof( "," ), "," }, { ",", sizeof( "," ) - 1 },
{ sizeof( "new" ), "new" }, { "new", sizeof( "new" ) - 1 },
{ sizeof( "new[]" ), "new[]" }, { "new[]", sizeof( "new[]" ) - 1 },
{ sizeof( "delete" ), "delete" }, { "delete", sizeof( "delete" ) - 1 },
{ sizeof( "delete[]" ), "delete[]" }, { "delete[]", sizeof( "delete[]" ) - 1 },
}; };
return lookup[op]; return lookup[op];
} }
forceinline StrC to_str( Operator op ) forceinline Str to_str( Operator op )
{ {
return operator_to_str( op ); return operator_to_str( op );
} }

View File

@ -37,35 +37,35 @@ enum Specifier : u32
Spec_UnderlyingType = 0xffffffffu Spec_UnderlyingType = 0xffffffffu
}; };
inline StrC spec_to_str( Specifier type ) inline Str spec_to_str( Specifier type )
{ {
local_persist StrC lookup[26] = { local_persist Str lookup[26] = {
{ sizeof( "INVALID" ), "INVALID" }, { "INVALID", sizeof( "INVALID" ) - 1 },
{ sizeof( "consteval" ), "consteval" }, { "consteval", sizeof( "consteval" ) - 1 },
{ sizeof( "constexpr" ), "constexpr" }, { "constexpr", sizeof( "constexpr" ) - 1 },
{ sizeof( "constinit" ), "constinit" }, { "constinit", sizeof( "constinit" ) - 1 },
{ sizeof( "explicit" ), "explicit" }, { "explicit", sizeof( "explicit" ) - 1 },
{ sizeof( "extern" ), "extern" }, { "extern", sizeof( "extern" ) - 1 },
{ sizeof( "forceinline" ), "forceinline" }, { "forceinline", sizeof( "forceinline" ) - 1 },
{ sizeof( "global" ), "global" }, { "global", sizeof( "global" ) - 1 },
{ sizeof( "inline" ), "inline" }, { "inline", sizeof( "inline" ) - 1 },
{ sizeof( "internal" ), "internal" }, { "internal", sizeof( "internal" ) - 1 },
{ sizeof( "local_persist" ), "local_persist" }, { "local_persist", sizeof( "local_persist" ) - 1 },
{ sizeof( "mutable" ), "mutable" }, { "mutable", sizeof( "mutable" ) - 1 },
{ sizeof( "neverinline" ), "neverinline" }, { "neverinline", sizeof( "neverinline" ) - 1 },
{ sizeof( "*" ), "*" }, { "*", sizeof( "*" ) - 1 },
{ sizeof( "&" ), "&" }, { "&", sizeof( "&" ) - 1 },
{ sizeof( "register" ), "register" }, { "register", sizeof( "register" ) - 1 },
{ sizeof( "&&" ), "&&" }, { "&&", sizeof( "&&" ) - 1 },
{ sizeof( "static" ), "static" }, { "static", sizeof( "static" ) - 1 },
{ sizeof( "thread_local" ), "thread_local" }, { "thread_local", sizeof( "thread_local" ) - 1 },
{ sizeof( "virtual" ), "virtual" }, { "virtual", sizeof( "virtual" ) - 1 },
{ sizeof( "const" ), "const" }, { "const", sizeof( "const" ) - 1 },
{ sizeof( "final" ), "final" }, { "final", sizeof( "final" ) - 1 },
{ sizeof( "noexcept" ), "noexcept" }, { "noexcept", sizeof( "noexcept" ) - 1 },
{ sizeof( "override" ), "override" }, { "override", sizeof( "override" ) - 1 },
{ sizeof( "= 0" ), "= 0" }, { "= 0", sizeof( "= 0" ) - 1 },
{ sizeof( "volatile" ), "volatile" }, { "volatile", sizeof( "volatile" ) - 1 },
}; };
return lookup[type]; return lookup[type];
} }
@ -75,13 +75,13 @@ inline bool spec_is_trailing( Specifier specifier )
return specifier > Spec_Virtual; return specifier > Spec_Virtual;
} }
inline Specifier strc_to_specifier( StrC str ) inline Specifier str_to_specifier( Str str )
{ {
local_persist u32 keymap[Spec_NumSpecifiers]; local_persist u32 keymap[Spec_NumSpecifiers];
do_once_start for ( u32 index = 0; index < Spec_NumSpecifiers; index++ ) do_once_start for ( u32 index = 0; index < Spec_NumSpecifiers; index++ )
{ {
StrC enum_str = spec_to_str( (Specifier)index ); Str enum_str = spec_to_str( (Specifier)index );
keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1 ); keymap[index] = crc32( enum_str.Ptr, enum_str.Len );
} }
do_once_end u32 hash = crc32( str.Ptr, str.Len ); do_once_end u32 hash = crc32( str.Ptr, str.Len );
for ( u32 index = 0; index < Spec_NumSpecifiers; index++ ) for ( u32 index = 0; index < Spec_NumSpecifiers; index++ )
@ -92,14 +92,14 @@ inline Specifier strc_to_specifier( StrC str )
return Spec_Invalid; return Spec_Invalid;
} }
forceinline StrC to_str( Specifier spec ) forceinline Str to_str( Specifier spec )
{ {
return spec_to_str( spec ); return spec_to_str( spec );
} }
forceinline Specifier to_type( StrC str ) forceinline Specifier to_type( Str str )
{ {
return strc_to_specifier( str ); return str_to_specifier( str );
} }
forceinline bool is_trailing( Specifier specifier ) forceinline bool is_trailing( Specifier specifier )

View File

@ -111,117 +111,117 @@ enum TokType : u32
Tok_NumTokens Tok_NumTokens
}; };
inline StrC toktype_to_str( TokType type ) inline Str toktype_to_str( TokType type )
{ {
local_persist StrC lookup[] = { local_persist Str lookup[] = {
{ sizeof( "__invalid__" ), "__invalid__" }, { "__invalid__", sizeof( "__invalid__" ) - 1 },
{ sizeof( "private" ), "private" }, { "private", sizeof( "private" ) - 1 },
{ sizeof( "protected" ), "protected" }, { "protected", sizeof( "protected" ) - 1 },
{ sizeof( "public" ), "public" }, { "public", sizeof( "public" ) - 1 },
{ sizeof( "." ), "." }, { ".", sizeof( "." ) - 1 },
{ sizeof( "::" ), "::" }, { "::", sizeof( "::" ) - 1 },
{ sizeof( "&" ), "&" }, { "&", sizeof( "&" ) - 1 },
{ sizeof( "&&" ), "&&" }, { "&&", sizeof( "&&" ) - 1 },
{ sizeof( ":" ), ":" }, { ":", sizeof( ":" ) - 1 },
{ sizeof( "[[" ), "[[" }, { "[[", sizeof( "[[" ) - 1 },
{ sizeof( "]]" ), "]]" }, { "]]", sizeof( "]]" ) - 1 },
{ sizeof( "{" ), "{" }, { "{", sizeof( "{" ) - 1 },
{ sizeof( "}" ), "}" }, { "}", sizeof( "}" ) - 1 },
{ sizeof( "[" ), "[" }, { "[", sizeof( "[" ) - 1 },
{ sizeof( "]" ), "]" }, { "]", sizeof( "]" ) - 1 },
{ sizeof( "(" ), "(" }, { "(", sizeof( "(" ) - 1 },
{ sizeof( ")" ), ")" }, { ")", sizeof( ")" ) - 1 },
{ sizeof( "__comment__" ), "__comment__" }, { "__comment__", sizeof( "__comment__" ) - 1 },
{ sizeof( "__comment_end__" ), "__comment_end__" }, { "__comment_end__", sizeof( "__comment_end__" ) - 1 },
{ sizeof( "__comment_start__" ), "__comment_start__" }, { "__comment_start__", sizeof( "__comment_start__" ) - 1 },
{ sizeof( "__character__" ), "__character__" }, { "__character__", sizeof( "__character__" ) - 1 },
{ sizeof( "," ), "," }, { ",", sizeof( "," ) - 1 },
{ sizeof( "class" ), "class" }, { "class", sizeof( "class" ) - 1 },
{ sizeof( "__attribute__" ), "__attribute__" }, { "__attribute__", sizeof( "__attribute__" ) - 1 },
{ sizeof( "__declspec" ), "__declspec" }, { "__declspec", sizeof( "__declspec" ) - 1 },
{ sizeof( "enum" ), "enum" }, { "enum", sizeof( "enum" ) - 1 },
{ sizeof( "extern" ), "extern" }, { "extern", sizeof( "extern" ) - 1 },
{ sizeof( "friend" ), "friend" }, { "friend", sizeof( "friend" ) - 1 },
{ sizeof( "module" ), "module" }, { "module", sizeof( "module" ) - 1 },
{ sizeof( "namespace" ), "namespace" }, { "namespace", sizeof( "namespace" ) - 1 },
{ sizeof( "operator" ), "operator" }, { "operator", sizeof( "operator" ) - 1 },
{ sizeof( "struct" ), "struct" }, { "struct", sizeof( "struct" ) - 1 },
{ sizeof( "template" ), "template" }, { "template", sizeof( "template" ) - 1 },
{ sizeof( "typedef" ), "typedef" }, { "typedef", sizeof( "typedef" ) - 1 },
{ sizeof( "using" ), "using" }, { "using", sizeof( "using" ) - 1 },
{ sizeof( "union" ), "union" }, { "union", sizeof( "union" ) - 1 },
{ sizeof( "__identifier__" ), "__identifier__" }, { "__identifier__", sizeof( "__identifier__" ) - 1 },
{ sizeof( "import" ), "import" }, { "import", sizeof( "import" ) - 1 },
{ sizeof( "export" ), "export" }, { "export", sizeof( "export" ) - 1 },
{ sizeof( "__new_line__" ), "__new_line__" }, { "__new_line__", sizeof( "__new_line__" ) - 1 },
{ sizeof( "__number__" ), "__number__" }, { "__number__", sizeof( "__number__" ) - 1 },
{ sizeof( "__operator__" ), "__operator__" }, { "__operator__", sizeof( "__operator__" ) - 1 },
{ sizeof( "#" ), "#" }, { "#", sizeof( "#" ) - 1 },
{ sizeof( "define" ), "define" }, { "define", sizeof( "define" ) - 1 },
{ sizeof( "if" ), "if" }, { "if", sizeof( "if" ) - 1 },
{ sizeof( "ifdef" ), "ifdef" }, { "ifdef", sizeof( "ifdef" ) - 1 },
{ sizeof( "ifndef" ), "ifndef" }, { "ifndef", sizeof( "ifndef" ) - 1 },
{ sizeof( "elif" ), "elif" }, { "elif", sizeof( "elif" ) - 1 },
{ sizeof( "else" ), "else" }, { "else", sizeof( "else" ) - 1 },
{ sizeof( "endif" ), "endif" }, { "endif", sizeof( "endif" ) - 1 },
{ sizeof( "include" ), "include" }, { "include", sizeof( "include" ) - 1 },
{ sizeof( "pragma" ), "pragma" }, { "pragma", sizeof( "pragma" ) - 1 },
{ sizeof( "__macro_content__" ), "__macro_content__" }, { "__macro_content__", sizeof( "__macro_content__" ) - 1 },
{ sizeof( "__macro__" ), "__macro__" }, { "__macro__", sizeof( "__macro__" ) - 1 },
{ sizeof( "__unsupported__" ), "__unsupported__" }, { "__unsupported__", sizeof( "__unsupported__" ) - 1 },
{ sizeof( "alignas" ), "alignas" }, { "alignas", sizeof( "alignas" ) - 1 },
{ sizeof( "const" ), "const" }, { "const", sizeof( "const" ) - 1 },
{ sizeof( "consteval" ), "consteval" }, { "consteval", sizeof( "consteval" ) - 1 },
{ sizeof( "constexpr" ), "constexpr" }, { "constexpr", sizeof( "constexpr" ) - 1 },
{ sizeof( "constinit" ), "constinit" }, { "constinit", sizeof( "constinit" ) - 1 },
{ sizeof( "explicit" ), "explicit" }, { "explicit", sizeof( "explicit" ) - 1 },
{ sizeof( "extern" ), "extern" }, { "extern", sizeof( "extern" ) - 1 },
{ sizeof( "final" ), "final" }, { "final", sizeof( "final" ) - 1 },
{ sizeof( "forceinline" ), "forceinline" }, { "forceinline", sizeof( "forceinline" ) - 1 },
{ sizeof( "global" ), "global" }, { "global", sizeof( "global" ) - 1 },
{ sizeof( "inline" ), "inline" }, { "inline", sizeof( "inline" ) - 1 },
{ sizeof( "internal" ), "internal" }, { "internal", sizeof( "internal" ) - 1 },
{ sizeof( "local_persist" ), "local_persist" }, { "local_persist", sizeof( "local_persist" ) - 1 },
{ sizeof( "mutable" ), "mutable" }, { "mutable", sizeof( "mutable" ) - 1 },
{ sizeof( "neverinline" ), "neverinline" }, { "neverinline", sizeof( "neverinline" ) - 1 },
{ sizeof( "override" ), "override" }, { "override", sizeof( "override" ) - 1 },
{ sizeof( "static" ), "static" }, { "static", sizeof( "static" ) - 1 },
{ sizeof( "thread_local" ), "thread_local" }, { "thread_local", sizeof( "thread_local" ) - 1 },
{ sizeof( "volatile" ), "volatile" }, { "volatile", sizeof( "volatile" ) - 1 },
{ sizeof( "virtual" ), "virtual" }, { "virtual", sizeof( "virtual" ) - 1 },
{ sizeof( "*" ), "*" }, { "*", sizeof( "*" ) - 1 },
{ sizeof( ";" ), ";" }, { ";", sizeof( ";" ) - 1 },
{ sizeof( "static_assert" ), "static_assert" }, { "static_assert", sizeof( "static_assert" ) - 1 },
{ sizeof( "__string__" ), "__string__" }, { "__string__", sizeof( "__string__" ) - 1 },
{ sizeof( "typename" ), "typename" }, { "typename", sizeof( "typename" ) - 1 },
{ sizeof( "unsigned" ), "unsigned" }, { "unsigned", sizeof( "unsigned" ) - 1 },
{ sizeof( "signed" ), "signed" }, { "signed", sizeof( "signed" ) - 1 },
{ sizeof( "short" ), "short" }, { "short", sizeof( "short" ) - 1 },
{ sizeof( "long" ), "long" }, { "long", sizeof( "long" ) - 1 },
{ sizeof( "bool" ), "bool" }, { "bool", sizeof( "bool" ) - 1 },
{ sizeof( "char" ), "char" }, { "char", sizeof( "char" ) - 1 },
{ sizeof( "int" ), "int" }, { "int", sizeof( "int" ) - 1 },
{ sizeof( "double" ), "double" }, { "double", sizeof( "double" ) - 1 },
{ sizeof( "__int8" ), "__int8" }, { "__int8", sizeof( "__int8" ) - 1 },
{ sizeof( "__int16" ), "__int16" }, { "__int16", sizeof( "__int16" ) - 1 },
{ sizeof( "__int32" ), "__int32" }, { "__int32", sizeof( "__int32" ) - 1 },
{ sizeof( "__int64" ), "__int64" }, { "__int64", sizeof( "__int64" ) - 1 },
{ sizeof( "_W64" ), "_W64" }, { "_W64", sizeof( "_W64" ) - 1 },
{ sizeof( "..." ), "..." }, { "...", sizeof( "..." ) - 1 },
{ sizeof( "__attrib_start__" ), "__attrib_start__" }, { "__attrib_start__", sizeof( "__attrib_start__" ) - 1 },
{ sizeof( "GEN_API_Export_Code" ), "GEN_API_Export_Code" }, { "GEN_API_Export_Code", sizeof( "GEN_API_Export_Code" ) - 1 },
{ sizeof( "GEN_API_Import_Code" ), "GEN_API_Import_Code" }, { "GEN_API_Import_Code", sizeof( "GEN_API_Import_Code" ) - 1 },
}; };
return lookup[type]; return lookup[type];
} }
inline TokType strc_to_toktype( StrC str ) inline TokType str_to_toktype( Str str )
{ {
local_persist u32 keymap[Tok_NumTokens]; local_persist u32 keymap[Tok_NumTokens];
do_once_start for ( u32 index = 0; index < Tok_NumTokens; index++ ) do_once_start for ( u32 index = 0; index < Tok_NumTokens; index++ )
{ {
StrC enum_str = toktype_to_str( (TokType)index ); Str enum_str = toktype_to_str( (TokType)index );
keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1 ); keymap[index] = crc32( enum_str.Ptr, enum_str.Len );
} }
do_once_end u32 hash = crc32( str.Ptr, str.Len ); do_once_end u32 hash = crc32( str.Ptr, str.Len );
for ( u32 index = 0; index < Tok_NumTokens; index++ ) for ( u32 index = 0; index < Tok_NumTokens; index++ )

View File

@ -53,6 +53,8 @@ constexpr s32 MaxUntypedStrLength = GEN_MAX_UNTYPED_STR_LENGTH;
constexpr s32 LexAllocator_Size = GEN_LEX_ALLOCATOR_SIZE; constexpr s32 LexAllocator_Size = GEN_LEX_ALLOCATOR_SIZE;
constexpr s32 Builder_StrBufferReserve = GEN_BUILDER_STR_BUFFER_RESERVE; constexpr s32 Builder_StrBufferReserve = GEN_BUILDER_STR_BUFFER_RESERVE;
extern Str enum_underlying_sig;
extern Code access_public; extern Code access_public;
extern Code access_protected; extern Code access_protected;
extern Code access_private; extern Code access_private;
@ -67,7 +69,7 @@ extern Code fmt_newline;
extern CodePragma pragma_once; extern CodePragma pragma_once;
extern CodeParam param_varadic; extern CodeParams param_varadic;
extern CodePreprocessCond preprocess_else; extern CodePreprocessCond preprocess_else;
extern CodePreprocessCond preprocess_endif; extern CodePreprocessCond preprocess_endif;

View File

@ -101,7 +101,7 @@ Code& Code::operator ++()
} }
#endif #endif
forceinline forceinline
StrC code_type_str(Code self) Str code_type_str(Code self)
{ {
GEN_ASSERT(self != nullptr); GEN_ASSERT(self != nullptr);
return codetype_to_str( self->Type ); return codetype_to_str( self->Type );
@ -178,9 +178,9 @@ void class_add_interface( CodeClass self, CodeTypename type )
} }
#pragma endregion CodeClass #pragma endregion CodeClass
#pragma region CodeParam #pragma region CodeParams
inline inline
void params_append( CodeParam appendee, CodeParam other ) void params_append( CodeParams appendee, CodeParams other )
{ {
GEN_ASSERT(appendee); GEN_ASSERT(appendee);
GEN_ASSERT(other); GEN_ASSERT(other);
@ -206,37 +206,37 @@ void params_append( CodeParam appendee, CodeParam other )
self->NumEntries++; self->NumEntries++;
} }
inline inline
CodeParam params_get(CodeParam self, s32 idx ) CodeParams params_get(CodeParams self, s32 idx )
{ {
GEN_ASSERT(self); GEN_ASSERT(self);
CodeParam param = self; CodeParams param = self;
do do
{ {
if ( ++ param != nullptr ) if ( ++ param != nullptr )
return NullCode; return NullCode;
param = cast(CodeParam, cast(Code, param)->Next); param = cast(CodeParams, cast(Code, param)->Next);
} }
while ( --idx ); while ( --idx );
return param; return param;
} }
forceinline forceinline
bool params_has_entries(CodeParam self) bool params_has_entries(CodeParams self)
{ {
GEN_ASSERT(self); GEN_ASSERT(self);
return self->NumEntries > 0; return self->NumEntries > 0;
} }
#if GEN_COMPILER_CPP #if GEN_COMPILER_CPP
forceinline forceinline
CodeParam& CodeParam::operator ++() CodeParams& CodeParams::operator ++()
{ {
* this = ast->Next; * this = ast->Next;
return * this; return * this;
} }
#endif #endif
forceinline forceinline
CodeParam begin_CodeParam(CodeParam params) CodeParams begin_CodeParams(CodeParams params)
{ {
if ( params != nullptr ) if ( params != nullptr )
return params; return params;
@ -244,18 +244,18 @@ CodeParam begin_CodeParam(CodeParam params)
return NullCode; return NullCode;
} }
forceinline forceinline
CodeParam end_CodeParam(CodeParam params) CodeParams end_CodeParams(CodeParams params)
{ {
// return { (AST_Param*) rcast( AST*, ast)->Last }; // return { (AST_Params*) rcast( AST*, ast)->Last };
return NullCode; return NullCode;
} }
forceinline forceinline
CodeParam next_CodeParam(CodeParam params, CodeParam param_iter) CodeParams next_CodeParams(CodeParams params, CodeParams param_iter)
{ {
GEN_ASSERT(param_iter); GEN_ASSERT(param_iter);
return param_iter->Next; return param_iter->Next;
} }
#pragma endregion CodeParam #pragma endregion CodeParams
#pragma region CodeSpecifiers #pragma region CodeSpecifiers
inline inline
@ -397,7 +397,7 @@ CodeBody def_body( CodeType type )
} }
inline inline
StrC token_fmt_impl( ssize num, ... ) Str token_fmt_impl( ssize num, ... )
{ {
local_persist thread_local local_persist thread_local
char buf[GEN_PRINTF_MAXLEN] = { 0 }; char buf[GEN_PRINTF_MAXLEN] = { 0 };
@ -408,7 +408,7 @@ StrC token_fmt_impl( ssize num, ... )
ssize result = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num, va); ssize result = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num, va);
va_end(va); va_end(va);
StrC str = { result, buf }; Str str = { buf, result };
return str; return str;
} }
#pragma endregion Interface #pragma endregion Interface

View File

@ -101,11 +101,11 @@ void define_constants()
access_public->Name = get_cached_string( txt("public:\n") ); access_public->Name = get_cached_string( txt("public:\n") );
code_set_global(access_public); code_set_global(access_public);
StrC api_export_str = code(GEN_API_Export_Code); Str api_export_str = code(GEN_API_Export_Code);
attrib_api_export = def_attributes( api_export_str ); attrib_api_export = def_attributes( api_export_str );
code_set_global(cast(Code, attrib_api_export)); code_set_global(cast(Code, attrib_api_export));
StrC api_import_str = code(GEN_API_Import_Code); Str api_import_str = code(GEN_API_Import_Code);
attrib_api_import = def_attributes( api_import_str ); attrib_api_import = def_attributes( api_import_str );
code_set_global(cast(Code, attrib_api_import)); code_set_global(cast(Code, attrib_api_import));
@ -131,7 +131,7 @@ void define_constants()
pragma_once->Content = pragma_once->Name; pragma_once->Content = pragma_once->Name;
code_set_global((Code)pragma_once); code_set_global((Code)pragma_once);
param_varadic = (CodeParam) make_code(); param_varadic = (CodeParams) 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;
@ -145,44 +145,34 @@ void define_constants()
preprocess_endif->Type = CT_Preprocess_EndIf; preprocess_endif->Type = CT_Preprocess_EndIf;
code_set_global((Code)preprocess_endif); code_set_global((Code)preprocess_endif);
# define def_constant_code_type( Type_ ) \ Str auto_str = txt("auto"); t_auto = def_type( auto_str ); code_set_global( t_auto );
do \ Str void_str = txt("void"); t_void = def_type( void_str ); code_set_global( t_void );
{ \ Str int_str = txt("int"); t_int = def_type( int_str ); code_set_global( t_int );
StrC name_str = name(Type_); \ Str bool_str = txt("bool"); t_bool = def_type( bool_str ); code_set_global( t_bool );
t_##Type_ = def_type( name_str ); \ Str char_str = txt("char"); t_char = def_type( char_str ); code_set_global( t_char );
code_set_global( cast(Code, t_##Type_)); \ Str wchar_str = txt("wchar_t"); t_wchar_t = def_type( wchar_str ); code_set_global( t_wchar_t );
} while(0) Str class_str = txt("class"); t_class = def_type( class_str ); code_set_global( t_class );
Str typename_str = txt("typename"); t_typename = def_type( typename_str ); code_set_global( t_typename );
def_constant_code_type( auto );
def_constant_code_type( void );
def_constant_code_type( int );
def_constant_code_type( bool );
def_constant_code_type( char );
def_constant_code_type( wchar_t );
def_constant_code_type( class );
def_constant_code_type( typename );
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS #ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
t_b32 = def_type( name(b32) ); t_b32 = def_type( name(b32) ); code_set_global( t_b32 );
def_constant_code_type( s8 ); Str s8_str = txt("s8"); t_s8 = def_type( s8_str ); code_set_global( t_s8 );
def_constant_code_type( s16 ); Str s16_str = txt("s16"); t_s16 = def_type( s16_str ); code_set_global( t_s16 );
def_constant_code_type( s32 ); Str s32_str = txt("s32"); t_s32 = def_type( s32_str ); code_set_global( t_s32 );
def_constant_code_type( s64 ); Str s64_str = txt("s64"); t_s64 = def_type( s64_str ); code_set_global( t_s64 );
def_constant_code_type( u8 ); Str u8_str = txt("u8"); t_u8 = def_type( u8_str ); code_set_global( t_u8 );
def_constant_code_type( u16 ); Str u16_str = txt("u16"); t_u16 = def_type( u16_str ); code_set_global( t_u16 );
def_constant_code_type( u32 ); Str u32_str = txt("u32"); t_u32 = def_type( u32_str ); code_set_global( t_u32 );
def_constant_code_type( u64 ); Str u64_str = txt("u64"); t_u64 = def_type( u64_str ); code_set_global( t_u64 );
def_constant_code_type( ssize ); Str ssize_str = txt("ssize"); t_ssize = def_type( ssize_str ); code_set_global( t_ssize );
def_constant_code_type( usize ); Str usize_str = txt("usize"); t_usize = def_type( usize_str ); code_set_global( t_usize );
def_constant_code_type( f32 ); Str f32_str = txt("f32"); t_f32 = def_type( f32_str ); code_set_global( t_f32 );
def_constant_code_type( f64 ); Str f64_str = txt("f64"); t_f64 = def_type( f64_str ); code_set_global( t_f64 );
#endif #endif
# undef def_constant_code_type
spec_const = def_specifier( Spec_Const); code_set_global( cast(Code, spec_const )); spec_const = def_specifier( Spec_Const); code_set_global( cast(Code, spec_const ));
spec_consteval = def_specifier( Spec_Consteval); code_set_global( cast(Code, spec_consteval ));; spec_consteval = def_specifier( Spec_Consteval); code_set_global( cast(Code, spec_consteval ));;
@ -212,9 +202,10 @@ void define_constants()
spec_local_persist = def_specifiers( 1, Spec_Local_Persist ); spec_local_persist = def_specifiers( 1, Spec_Local_Persist );
code_set_global(cast(Code, spec_local_persist)); code_set_global(cast(Code, spec_local_persist));
# pragma push_macro("enum_underlying") if (enum_underlying_sig.Len == 0) {
array_append(PreprocessorDefines, txt("enum_underlying(")); enum_underlying_sig = txt("enum_underlying(");
# pragma pop_macro("enum_underlying") }
array_append(PreprocessorDefines, enum_underlying_sig);
# undef def_constant_spec # undef def_constant_spec
} }
@ -282,12 +273,12 @@ void init()
LexArena = arena_init_from_allocator( Allocator_Lexer, LexAllocator_Size ); LexArena = arena_init_from_allocator( Allocator_Lexer, LexAllocator_Size );
Arena string_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena ); Arena strbuilder_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena );
if ( string_arena.PhysicalStart == nullptr ) if ( strbuilder_arena.PhysicalStart == nullptr )
GEN_FATAL( "gen::init: Failed to initialize the string arena" ); GEN_FATAL( "gen::init: Failed to initialize the string arena" );
array_append( StringArenas, string_arena ); array_append( StringArenas, strbuilder_arena );
} }
// Setup the hash tables // Setup the hash tables
@ -321,8 +312,8 @@ void deinit()
left = array_num(StringArenas); left = array_num(StringArenas);
do do
{ {
Arena* string_arena = & StringArenas[index]; Arena* strbuilder_arena = & StringArenas[index];
arena_free(string_arena); arena_free(strbuilder_arena);
index++; index++;
} }
while ( left--, left ); while ( left--, left );
@ -366,8 +357,8 @@ void reset()
left = array_num(StringArenas); left = array_num(StringArenas);
do do
{ {
Arena* string_arena = & StringArenas[index]; Arena* strbuilder_arena = & StringArenas[index];
string_arena->TotalUsed = 0;; strbuilder_arena->TotalUsed = 0;;
index++; index++;
} }
while ( left--, left ); while ( left--, left );
@ -377,18 +368,18 @@ void reset()
define_constants(); define_constants();
} }
AllocatorInfo get_string_allocator( s32 str_length ) AllocatorInfo get_strbuilder_allocator( s32 c_str_length )
{ {
Arena* last = array_back(StringArenas); Arena* last = array_back(StringArenas);
usize size_req = str_length + sizeof(StringHeader) + sizeof(char*); usize size_req = c_str_length + sizeof(StrBuilderHeader) + sizeof(char*);
if ( last->TotalUsed + scast(ssize, size_req) > last->TotalSize ) if ( last->TotalUsed + scast(ssize, size_req) > last->TotalSize )
{ {
Arena new_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena ); Arena new_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena );
if ( ! array_append( StringArenas, new_arena ) ) if ( ! array_append( StringArenas, new_arena ) )
GEN_FATAL( "gen::get_string_allocator: Failed to allocate a new string arena" ); GEN_FATAL( "gen::get_strbuilder_allocator: Failed to allocate a new string arena" );
last = array_back(StringArenas); last = array_back(StringArenas);
} }
@ -397,7 +388,7 @@ AllocatorInfo get_string_allocator( s32 str_length )
} }
// Will either make or retrive a code string. // Will either make or retrive a code string.
StringCached get_cached_string( StrC str ) StringCached get_cached_string( Str str )
{ {
s32 hash_length = str.Len > kilobytes(1) ? kilobytes(1) : str.Len; s32 hash_length = str.Len > kilobytes(1) ? kilobytes(1) : str.Len;
u64 key = crc32( str.Ptr, hash_length ); u64 key = crc32( str.Ptr, hash_length );
@ -408,7 +399,7 @@ StringCached get_cached_string( StrC str )
return * result; return * result;
} }
StrC result = string_to_strc( string_make_strc( get_string_allocator( str.Len ), str )); Str result = strbuilder_to_str( strbuilder_make_str( get_strbuilder_allocator( str.Len ), str ));
hashtable_set(StringCache, key, result ); hashtable_set(StringCache, key, result );
return result; return result;
@ -451,12 +442,12 @@ void set_allocator_lexer( AllocatorInfo allocator )
Allocator_Lexer = allocator; Allocator_Lexer = allocator;
} }
void set_allocator_string_arena( AllocatorInfo allocator ) void set_allocator_strbuilder_arena( AllocatorInfo allocator )
{ {
Allocator_StringArena = allocator; Allocator_StringArena = allocator;
} }
void set_allocator_string_table( AllocatorInfo allocator ) void set_allocator_strbuilder_table( AllocatorInfo allocator )
{ {
Allocator_StringArena = allocator; Allocator_StringArena = allocator;
} }

View File

@ -28,7 +28,7 @@ void reset();
// Used internally to retrive or make string allocations. // Used internally to retrive or make string allocations.
// Strings are stored in a series of string arenas of fixed size (SizePer_StringArena) // Strings are stored in a series of string arenas of fixed size (SizePer_StringArena)
StringCached get_cached_string( StrC str ); StringCached get_cached_string( Str str );
/* /*
This provides a fresh Code AST. This provides a fresh Code AST.
@ -42,14 +42,14 @@ Code make_code();
void set_allocator_data_arrays ( AllocatorInfo data_array_allocator ); void set_allocator_data_arrays ( AllocatorInfo data_array_allocator );
void set_allocator_code_pool ( AllocatorInfo pool_allocator ); void set_allocator_code_pool ( AllocatorInfo pool_allocator );
void set_allocator_lexer ( AllocatorInfo lex_allocator ); void set_allocator_lexer ( AllocatorInfo lex_allocator );
void set_allocator_string_arena( AllocatorInfo string_allocator ); void set_allocator_strbuilder_arena( AllocatorInfo strbuilder_allocator );
void set_allocator_string_table( AllocatorInfo string_allocator ); void set_allocator_strbuilder_table( AllocatorInfo strbuilder_allocator );
void set_allocator_type_table ( AllocatorInfo type_reg_allocator ); void set_allocator_type_table ( AllocatorInfo type_reg_allocator );
#pragma region Upfront #pragma region Upfront
CodeAttributes def_attributes( StrC content ); CodeAttributes def_attributes( Str content );
CodeComment def_comment ( StrC content ); CodeComment def_comment ( Str content );
struct Opts_def_struct { struct Opts_def_struct {
CodeBody body; CodeBody body;
@ -60,10 +60,10 @@ struct Opts_def_struct {
s32 num_interfaces; s32 num_interfaces;
ModuleFlag mflags; ModuleFlag mflags;
}; };
CodeClass def_class( StrC name, Opts_def_struct opts GEN_PARAM_DEFAULT ); CodeClass def_class( Str name, Opts_def_struct opts GEN_PARAM_DEFAULT );
struct Opts_def_constructor { struct Opts_def_constructor {
CodeParam params; CodeParams params;
Code initializer_list; Code initializer_list;
Code body; Code body;
}; };
@ -72,7 +72,7 @@ CodeConstructor def_constructor( Opts_def_constructor opts GEN_PARAM_DEFAULT );
struct Opts_def_define { struct Opts_def_define {
b32 dont_append_preprocess_defines; b32 dont_append_preprocess_defines;
}; };
CodeDefine def_define( StrC name, StrC content, Opts_def_define opts GEN_PARAM_DEFAULT ); CodeDefine def_define( Str name, Str content, Opts_def_define opts GEN_PARAM_DEFAULT );
struct Opts_def_destructor { struct Opts_def_destructor {
Code body; Code body;
@ -86,39 +86,40 @@ struct Opts_def_enum {
EnumT specifier; EnumT specifier;
CodeAttributes attributes; CodeAttributes attributes;
ModuleFlag mflags; ModuleFlag mflags;
Code type_macro;
}; };
CodeEnum def_enum( StrC name, Opts_def_enum opts GEN_PARAM_DEFAULT ); CodeEnum def_enum( Str name, Opts_def_enum opts GEN_PARAM_DEFAULT );
CodeExec def_execution ( StrC content ); CodeExec def_execution ( Str content );
CodeExtern def_extern_link( StrC name, CodeBody body ); CodeExtern def_extern_link( Str name, CodeBody body );
CodeFriend def_friend ( Code symbol ); CodeFriend def_friend ( Code symbol );
struct Opts_def_function { struct Opts_def_function {
CodeParam params; CodeParams params;
CodeTypename ret_type; CodeTypename ret_type;
CodeBody body; CodeBody body;
CodeSpecifiers specs; CodeSpecifiers specs;
CodeAttributes attrs; CodeAttributes attrs;
ModuleFlag mflags; ModuleFlag mflags;
}; };
CodeFn def_function( StrC name, Opts_def_function opts GEN_PARAM_DEFAULT ); CodeFn def_function( Str name, Opts_def_function opts GEN_PARAM_DEFAULT );
struct Opts_def_include { b32 foreign; }; struct Opts_def_include { b32 foreign; };
struct Opts_def_module { ModuleFlag mflags; }; struct Opts_def_module { ModuleFlag mflags; };
struct Opts_def_namespace { ModuleFlag mflags; }; struct Opts_def_namespace { ModuleFlag mflags; };
CodeInclude def_include ( StrC content, Opts_def_include opts GEN_PARAM_DEFAULT ); CodeInclude def_include ( Str content, Opts_def_include opts GEN_PARAM_DEFAULT );
CodeModule def_module ( StrC name, Opts_def_module opts GEN_PARAM_DEFAULT ); CodeModule def_module ( Str name, Opts_def_module opts GEN_PARAM_DEFAULT );
CodeNS def_namespace( StrC name, CodeBody body, Opts_def_namespace opts GEN_PARAM_DEFAULT ); CodeNS def_namespace( Str name, CodeBody body, Opts_def_namespace opts GEN_PARAM_DEFAULT );
struct Opts_def_operator { struct Opts_def_operator {
CodeParam params; CodeParams params;
CodeTypename ret_type; CodeTypename ret_type;
CodeBody body; CodeBody body;
CodeSpecifiers specifiers; CodeSpecifiers specifiers;
CodeAttributes attributes; CodeAttributes attributes;
ModuleFlag mflags; ModuleFlag mflags;
}; };
CodeOperator def_operator( Operator op, StrC nspace, Opts_def_operator opts GEN_PARAM_DEFAULT ); CodeOperator def_operator( Operator op, Str nspace, Opts_def_operator opts GEN_PARAM_DEFAULT );
struct Opts_def_operator_cast { struct Opts_def_operator_cast {
CodeBody body; CodeBody body;
@ -127,17 +128,17 @@ struct Opts_def_operator_cast {
CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast opts GEN_PARAM_DEFAULT ); CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast opts GEN_PARAM_DEFAULT );
struct Opts_def_param { Code value; }; struct Opts_def_param { Code value; };
CodeParam def_param ( CodeTypename type, StrC name, Opts_def_param opts GEN_PARAM_DEFAULT ); CodeParams def_param ( CodeTypename type, Str name, Opts_def_param opts GEN_PARAM_DEFAULT );
CodePragma def_pragma( StrC directive ); CodePragma def_pragma( Str directive );
CodePreprocessCond def_preprocess_cond( EPreprocessCond type, StrC content ); CodePreprocessCond def_preprocess_cond( EPreprocessCond type, Str content );
CodeSpecifiers def_specifier( Specifier specifier ); CodeSpecifiers def_specifier( Specifier specifier );
CodeStruct def_struct( StrC name, Opts_def_struct opts GEN_PARAM_DEFAULT ); CodeStruct def_struct( Str name, Opts_def_struct opts GEN_PARAM_DEFAULT );
struct Opts_def_template { ModuleFlag mflags; }; struct Opts_def_template { ModuleFlag mflags; };
CodeTemplate def_template( CodeParam params, Code definition, Opts_def_template opts GEN_PARAM_DEFAULT ); CodeTemplate def_template( CodeParams params, Code definition, Opts_def_template opts GEN_PARAM_DEFAULT );
struct Opts_def_type { struct Opts_def_type {
ETypenameTag type_tag; ETypenameTag type_tag;
@ -145,27 +146,27 @@ struct Opts_def_type {
CodeSpecifiers specifiers; CodeSpecifiers specifiers;
CodeAttributes attributes; CodeAttributes attributes;
}; };
CodeTypename def_type( StrC name, Opts_def_type opts GEN_PARAM_DEFAULT ); CodeTypename def_type( Str name, Opts_def_type opts GEN_PARAM_DEFAULT );
struct Opts_def_typedef { struct Opts_def_typedef {
CodeAttributes attributes; CodeAttributes attributes;
ModuleFlag mflags; ModuleFlag mflags;
}; };
CodeTypedef def_typedef( StrC name, Code type, Opts_def_typedef opts GEN_PARAM_DEFAULT ); CodeTypedef def_typedef( Str name, Code type, Opts_def_typedef opts GEN_PARAM_DEFAULT );
struct Opts_def_union { struct Opts_def_union {
CodeAttributes attributes; CodeAttributes attributes;
ModuleFlag mflags; ModuleFlag mflags;
}; };
CodeUnion def_union( StrC name, CodeBody body, Opts_def_union opts GEN_PARAM_DEFAULT ); CodeUnion def_union( Str name, CodeBody body, Opts_def_union opts GEN_PARAM_DEFAULT );
struct Opts_def_using { struct Opts_def_using {
CodeAttributes attributes; CodeAttributes attributes;
ModuleFlag mflags; ModuleFlag mflags;
}; };
CodeUsing def_using( StrC name, CodeTypename type, Opts_def_using opts GEN_PARAM_DEFAULT ); CodeUsing def_using( Str name, CodeTypename type, Opts_def_using opts GEN_PARAM_DEFAULT );
CodeUsing def_using_namespace( StrC name ); CodeUsing def_using_namespace( Str name );
struct Opts_def_variable struct Opts_def_variable
{ {
@ -174,7 +175,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, Str 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( CodeType type ); CodeBody def_body( CodeType type );
@ -196,8 +197,8 @@ CodeBody def_global_body ( s32 num, ... );
CodeBody def_global_body ( s32 num, Code* codes ); CodeBody def_global_body ( s32 num, Code* codes );
CodeBody def_namespace_body ( s32 num, ... ); CodeBody def_namespace_body ( s32 num, ... );
CodeBody def_namespace_body ( s32 num, Code* codes ); CodeBody def_namespace_body ( s32 num, Code* codes );
CodeParam def_params ( s32 num, ... ); CodeParams def_params ( s32 num, ... );
CodeParam def_params ( s32 num, CodeParam* params ); CodeParams def_params ( s32 num, CodeParams* params );
CodeSpecifiers def_specifiers ( s32 num, ... ); CodeSpecifiers def_specifiers ( s32 num, ... );
CodeSpecifiers def_specifiers ( s32 num, Specifier* specs ); CodeSpecifiers def_specifiers ( s32 num, Specifier* specs );
CodeBody def_struct_body ( s32 num, ... ); CodeBody def_struct_body ( s32 num, ... );
@ -219,13 +220,13 @@ struct StackNode
Token Start; Token Start;
Token Name; // The name of the AST node (if parsed) Token Name; // The name of the AST node (if parsed)
StrC FailedProc; // The name of the procedure that failed Str FailedProc; // The name of the procedure that failed
}; };
// Stack nodes are allocated the error's allocator // Stack nodes are allocated the error's allocator
struct Error struct Error
{ {
String message; StrBuilder message;
StackNode* context_stack; StackNode* context_stack;
}; };
GEN_NS_PARSER_END GEN_NS_PARSER_END
@ -242,28 +243,28 @@ struct ParseInfo
// Errors are allocated to a dedicated general arena. // Errors are allocated to a dedicated general arena.
}; };
CodeBody parse_file( StrC path ); CodeBody parse_file( Str path );
#endif #endif
CodeClass parse_class ( StrC class_def ); CodeClass parse_class ( Str class_def );
CodeConstructor parse_constructor ( StrC constructor_def ); CodeConstructor parse_constructor ( Str constructor_def );
CodeDestructor parse_destructor ( StrC destructor_def ); CodeDestructor parse_destructor ( Str destructor_def );
CodeEnum parse_enum ( StrC enum_def ); CodeEnum parse_enum ( Str enum_def );
CodeBody parse_export_body ( StrC export_def ); CodeBody parse_export_body ( Str export_def );
CodeExtern parse_extern_link ( StrC exten_link_def ); CodeExtern parse_extern_link ( Str exten_link_def );
CodeFriend parse_friend ( StrC friend_def ); CodeFriend parse_friend ( Str friend_def );
CodeFn parse_function ( StrC fn_def ); CodeFn parse_function ( Str fn_def );
CodeBody parse_global_body ( StrC body_def ); CodeBody parse_global_body ( Str body_def );
CodeNS parse_namespace ( StrC namespace_def ); CodeNS parse_namespace ( Str namespace_def );
CodeOperator parse_operator ( StrC operator_def ); CodeOperator parse_operator ( Str operator_def );
CodeOpCast parse_operator_cast( StrC operator_def ); CodeOpCast parse_operator_cast( Str operator_def );
CodeStruct parse_struct ( StrC struct_def ); CodeStruct parse_struct ( Str struct_def );
CodeTemplate parse_template ( StrC template_def ); CodeTemplate parse_template ( Str template_def );
CodeTypename parse_type ( StrC type_def ); CodeTypename parse_type ( Str type_def );
CodeTypedef parse_typedef ( StrC typedef_def ); CodeTypedef parse_typedef ( Str typedef_def );
CodeUnion parse_union ( StrC union_def ); CodeUnion parse_union ( Str union_def );
CodeUsing parse_using ( StrC using_def ); CodeUsing parse_using ( Str using_def );
CodeVar parse_variable ( StrC var_def ); CodeVar parse_variable ( Str var_def );
#pragma endregion Parsing #pragma endregion Parsing
@ -271,9 +272,9 @@ CodeVar parse_variable ( StrC var_def );
ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va ); ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va );
//! Do not use directly. Use the token_fmt macro instead. //! Do not use directly. Use the token_fmt macro instead.
StrC token_fmt_impl( ssize, ... ); Str token_fmt_impl( ssize, ... );
Code untyped_str ( StrC content); Code untyped_str ( Str content);
Code untyped_fmt ( char const* fmt, ... ); Code untyped_fmt ( char const* fmt, ... );
Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... ); Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... );
@ -288,12 +289,12 @@ Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... );
#ifndef name #ifndef name
// Convienence for defining any name used with the gen api. // 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. // 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_) } #define name( Id_ ) { stringize(Id_), sizeof(stringize( Id_ )) - 1 }
#endif #endif
#ifndef code #ifndef code
// Same as name just used to indicate intention of literal for code instead of names. // 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 code( ... ) { stringize( __VA_ARGS__ ), sizeof(stringize(__VA_ARGS__)) - 1 }
#endif #endif
#ifndef args #ifndef args
@ -316,21 +317,21 @@ Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... );
#ifndef token_fmt #ifndef token_fmt
/* /*
Takes a format string (char const*) and a list of tokens (StrC) and returns a StrC of the formatted string. Takes a format string (char const*) and a list of tokens (Str) and returns a Str of the formatted string.
Tokens are provided in '<'identifier'>' format where '<' '>' are just angle brackets (you can change it in token_fmt_va) Tokens are provided in '<'identifier'>' format where '<' '>' are just angle brackets (you can change it in token_fmt_va)
--------------------------------------------------------- ---------------------------------------------------------
Example - A string with: Example - A string with:
typedef <type> <name> <name>; typedef <type> <name> <name>;
Will have a token_fmt arguments populated with: Will have a token_fmt arguments populated with:
"type", strc_for_type, "type", str_for_type,
"name", strc_for_name, "name", str_for_name,
and: and:
stringize( typedef <type> <name> <name>; ) stringize( typedef <type> <name> <name>; )
----------------------------------------------------------- -----------------------------------------------------------
So the full call for this example would be: So the full call for this example would be:
token_fmt( token_fmt(
"type", strc_for_type "type", str_for_type
, "name", strc_for_name , "name", str_for_name
, stringize( , stringize(
typedef <type> <name> <name> typedef <type> <name> <name>
)); ));

View File

@ -8,7 +8,7 @@
// Publically Exposed Interface // Publically Exposed Interface
CodeClass parse_class( StrC def ) CodeClass parse_class( Str def )
{ {
GEN_USING_NS_PARSER; GEN_USING_NS_PARSER;
check_parse_args( def ); check_parse_args( def );
@ -24,7 +24,7 @@ CodeClass parse_class( StrC def )
return result; return result;
} }
CodeConstructor parse_constructor( StrC def ) CodeConstructor parse_constructor( Str def )
{ {
GEN_USING_NS_PARSER; GEN_USING_NS_PARSER;
check_parse_args( def ); check_parse_args( def );
@ -41,7 +41,7 @@ CodeConstructor parse_constructor( StrC def )
while ( left && tok_is_specifier(currtok) ) while ( left && tok_is_specifier(currtok) )
{ {
Specifier spec = strc_to_specifier( tok_to_str(currtok) ); Specifier spec = str_to_specifier( tok_to_str(currtok) );
b32 ignore_spec = false; b32 ignore_spec = false;
@ -59,7 +59,7 @@ CodeConstructor parse_constructor( StrC def )
break; break;
default : default :
log_failure( "Invalid specifier %s for variable\n%s", spec_to_str( spec ), parser_to_string(Context) ); log_failure( "Invalid specifier %s for variable\n%S", spec_to_str( spec ), parser_to_strbuilder(Context) );
parser_pop(& Context); parser_pop(& Context);
return InvalidCode; return InvalidCode;
} }
@ -84,7 +84,7 @@ CodeConstructor parse_constructor( StrC def )
return result; return result;
} }
CodeDestructor parse_destructor( StrC def ) CodeDestructor parse_destructor( Str def )
{ {
GEN_USING_NS_PARSER; GEN_USING_NS_PARSER;
check_parse_args( def ); check_parse_args( def );
@ -101,7 +101,7 @@ CodeDestructor parse_destructor( StrC def )
return result; return result;
} }
CodeEnum parse_enum( StrC def ) CodeEnum parse_enum( Str def )
{ {
GEN_USING_NS_PARSER; GEN_USING_NS_PARSER;
check_parse_args( def ); check_parse_args( def );
@ -117,7 +117,7 @@ CodeEnum parse_enum( StrC def )
return parser_parse_enum( parser_not_inplace_def); return parser_parse_enum( parser_not_inplace_def);
} }
CodeBody parse_export_body( StrC def ) CodeBody parse_export_body( Str def )
{ {
GEN_USING_NS_PARSER; GEN_USING_NS_PARSER;
check_parse_args( def ); check_parse_args( def );
@ -130,7 +130,7 @@ CodeBody parse_export_body( StrC def )
return parser_parse_export_body(); return parser_parse_export_body();
} }
CodeExtern parse_extern_link( StrC def ) CodeExtern parse_extern_link( Str def )
{ {
GEN_USING_NS_PARSER; GEN_USING_NS_PARSER;
check_parse_args( def ); check_parse_args( def );
@ -143,7 +143,7 @@ CodeExtern parse_extern_link( StrC def )
return parser_parse_extern_link(); return parser_parse_extern_link();
} }
CodeFriend parse_friend( StrC def ) CodeFriend parse_friend( Str def )
{ {
GEN_USING_NS_PARSER; GEN_USING_NS_PARSER;
check_parse_args( def ); check_parse_args( def );
@ -156,7 +156,7 @@ CodeFriend parse_friend( StrC def )
return parser_parse_friend(); return parser_parse_friend();
} }
CodeFn parse_function( StrC def ) CodeFn parse_function( Str def )
{ {
GEN_USING_NS_PARSER; GEN_USING_NS_PARSER;
check_parse_args( def ); check_parse_args( def );
@ -169,7 +169,7 @@ CodeFn parse_function( StrC def )
return (CodeFn) parser_parse_function(); return (CodeFn) parser_parse_function();
} }
CodeBody parse_global_body( StrC def ) CodeBody parse_global_body( Str def )
{ {
GEN_USING_NS_PARSER; GEN_USING_NS_PARSER;
check_parse_args( def ); check_parse_args( def );
@ -185,7 +185,7 @@ CodeBody parse_global_body( StrC def )
return result; return result;
} }
CodeNS parse_namespace( StrC def ) CodeNS parse_namespace( Str def )
{ {
GEN_USING_NS_PARSER; GEN_USING_NS_PARSER;
check_parse_args( def ); check_parse_args( def );
@ -198,7 +198,7 @@ CodeNS parse_namespace( StrC def )
return parser_parse_namespace(); return parser_parse_namespace();
} }
CodeOperator parse_operator( StrC def ) CodeOperator parse_operator( Str def )
{ {
GEN_USING_NS_PARSER; GEN_USING_NS_PARSER;
check_parse_args( def ); check_parse_args( def );
@ -211,7 +211,7 @@ CodeOperator parse_operator( StrC def )
return (CodeOperator) parser_parse_operator(); return (CodeOperator) parser_parse_operator();
} }
CodeOpCast parse_operator_cast( StrC def ) CodeOpCast parse_operator_cast( Str def )
{ {
GEN_USING_NS_PARSER; GEN_USING_NS_PARSER;
check_parse_args( def ); check_parse_args( def );
@ -224,7 +224,7 @@ CodeOpCast parse_operator_cast( StrC def )
return parser_parse_operator_cast(NullCode); return parser_parse_operator_cast(NullCode);
} }
CodeStruct parse_struct( StrC def ) CodeStruct parse_struct( Str def )
{ {
GEN_USING_NS_PARSER; GEN_USING_NS_PARSER;
check_parse_args( def ); check_parse_args( def );
@ -240,7 +240,7 @@ CodeStruct parse_struct( StrC def )
return result; return result;
} }
CodeTemplate parse_template( StrC def ) CodeTemplate parse_template( Str def )
{ {
GEN_USING_NS_PARSER; GEN_USING_NS_PARSER;
check_parse_args( def ); check_parse_args( def );
@ -253,7 +253,7 @@ CodeTemplate parse_template( StrC def )
return parser_parse_template(); return parser_parse_template();
} }
CodeTypename parse_type( StrC def ) CodeTypename parse_type( Str def )
{ {
GEN_USING_NS_PARSER; GEN_USING_NS_PARSER;
check_parse_args( def ); check_parse_args( def );
@ -266,7 +266,7 @@ CodeTypename parse_type( StrC def )
return parser_parse_type( parser_not_from_template, nullptr); return parser_parse_type( parser_not_from_template, nullptr);
} }
CodeTypedef parse_typedef( StrC def ) CodeTypedef parse_typedef( Str def )
{ {
GEN_USING_NS_PARSER; GEN_USING_NS_PARSER;
check_parse_args( def ); check_parse_args( def );
@ -279,7 +279,7 @@ CodeTypedef parse_typedef( StrC def )
return parser_parse_typedef(); return parser_parse_typedef();
} }
CodeUnion parse_union( StrC def ) CodeUnion parse_union( Str def )
{ {
GEN_USING_NS_PARSER; GEN_USING_NS_PARSER;
check_parse_args( def ); check_parse_args( def );
@ -292,7 +292,7 @@ CodeUnion parse_union( StrC def )
return parser_parse_union( parser_not_inplace_def); return parser_parse_union( parser_not_inplace_def);
} }
CodeUsing parse_using( StrC def ) CodeUsing parse_using( Str def )
{ {
GEN_USING_NS_PARSER; GEN_USING_NS_PARSER;
check_parse_args( def ); check_parse_args( def );
@ -305,7 +305,7 @@ CodeUsing parse_using( StrC def )
return parser_parse_using(); return parser_parse_using();
} }
CodeVar parse_variable( StrC def ) CodeVar parse_variable( Str def )
{ {
GEN_USING_NS_PARSER; GEN_USING_NS_PARSER;
check_parse_args( def ); check_parse_args( def );

View File

@ -15,16 +15,16 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
local_persist local_persist
StringTable tok_map; StringTable tok_map;
{ {
tok_map = hashtable_init(StrC, fixed_arena_allocator_info(& tok_map_arena) ); tok_map = hashtable_init(Str, fixed_arena_allocator_info(& tok_map_arena) );
s32 left = num_tokens - 1; s32 left = num_tokens - 1;
while ( left-- ) while ( left-- )
{ {
char const* token = va_arg( va, char const* ); char const* token = va_arg( va, char const* );
StrC value = va_arg( va, StrC ); Str value = va_arg( va, Str );
u32 key = crc32( token, str_len(token) ); u32 key = crc32( token, c_str_len(token) );
hashtable_set( tok_map, key, value ); hashtable_set( tok_map, key, value );
} }
} }
@ -61,7 +61,7 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
char const* token = fmt + 1; char const* token = fmt + 1;
u32 key = crc32( token, tok_len ); u32 key = crc32( token, tok_len );
StrC* value = hashtable_get(tok_map, key ); Str* value = hashtable_get(tok_map, key );
if ( value ) if ( value )
{ {
@ -99,7 +99,7 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
return result; return result;
} }
Code untyped_str( StrC content ) Code untyped_str( Str content )
{ {
if ( content.Len == 0 ) if ( content.Len == 0 )
{ {
@ -135,11 +135,11 @@ Code untyped_fmt( char const* fmt, ...)
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
ssize length = str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va); ssize length = c_str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va);
va_end(va); va_end(va);
StrC buf_str = { str_len_capped(fmt, MaxNameLength), fmt }; Str buf_str = { fmt, c_str_len_capped(fmt, MaxNameLength) };
StrC uncapped_str = { length, buf }; Str uncapped_str = { buf, length };
Code Code
result = make_code(); result = make_code();
@ -172,7 +172,7 @@ Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... )
ssize length = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num_tokens, va); ssize length = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num_tokens, va);
va_end(va); va_end(va);
StrC buf_str = { length, buf }; Str buf_str = { buf, length };
Code Code
result = make_code(); result = make_code();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,8 @@ global AllocatorInfo Allocator_TypeTable = {0};
#pragma region Constants #pragma region Constants
global Str enum_underlying_sig;
global Code access_public; global Code access_public;
global Code access_protected; global Code access_protected;
global Code access_private; global Code access_private;
@ -40,7 +42,7 @@ global Code module_private_fragment;
global Code fmt_newline; global Code fmt_newline;
global CodeParam param_varadic; global CodeParams param_varadic;
global CodePragma pragma_once; global CodePragma pragma_once;

View File

@ -44,17 +44,17 @@ enum AccessSpec : 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
StrC access_spec_to_str( AccessSpec type ) Str access_spec_to_str( AccessSpec type )
{ {
local_persist local_persist
StrC lookup[ (u32)AccessSpec_Num_AccessSpec ] = { Str lookup[ (u32)AccessSpec_Num_AccessSpec ] = {
{ sizeof("") - 1, "" }, { "", sizeof( "" ) - 1 },
{ sizeof("prviate") - 1, "private" }, { "private", sizeof("prviate") - 1 },
{ sizeof("protected") - 1, "private" }, { "private", sizeof("protected") - 1 },
{ sizeof("public") - 1, "public" }, { "public", sizeof("public") - 1 },
}; };
StrC invalid = { sizeof("Invalid") - 1, "Invalid" }; Str invalid = { "Invalid", sizeof("Invalid") - 1 };
if ( type > AccessSpec_Public ) if ( type > AccessSpec_Public )
return invalid; return invalid;
@ -97,17 +97,17 @@ enum ModuleFlag : 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 module_flag_to_str( ModuleFlag flag ) Str module_flag_to_str( ModuleFlag flag )
{ {
local_persist local_persist
StrC lookup[ (u32)Num_ModuleFlags ] = { Str lookup[ (u32)Num_ModuleFlags ] = {
{ sizeof("__none__"), "__none__" }, { "__none__", sizeof("__none__") - 1 },
{ sizeof("export"), "export" }, { "export", sizeof("export") - 1 },
{ sizeof("import"), "import" }, { "import", sizeof("import") - 1 },
}; };
local_persist local_persist
StrC invalid_flag = { sizeof("invalid"), "invalid" }; Str invalid_flag = { "invalid", sizeof("invalid") };
if ( flag > ModuleFlag_Import ) if ( flag > ModuleFlag_Import )
return invalid_flag; return invalid_flag;

View File

@ -102,16 +102,16 @@ struct Array
#endif #endif
#if GEN_COMPILER_CPP && 0 #if GEN_COMPILER_CPP && 0
template<class Type> bool append(Array<Type>& array, Array<Type> other) { return 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 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 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 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 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 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 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 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 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 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; }
@ -440,8 +440,6 @@ bool array_set_capacity(Array<Type>* array, usize new_capacity)
#pragma endregion Array #pragma endregion Array
// TODO(Ed) : This thing needs ALOT of work.
#pragma region HashTable #pragma region HashTable
#define HashTable(Type) HashTable<Type> #define HashTable(Type) HashTable<Type>

View File

@ -8,16 +8,23 @@
#pragma region Debug #pragma region Debug
#if defined( _MSC_VER ) #if GEN_BUILD_DEBUG
# if _MSC_VER < 1300 # if defined( GEN_COMPILER_MSVC )
# define GEN_DEBUG_TRAP() __asm int 3 /* Trap to debugger! */ # if _MSC_VER < 1300
#pragma message("GEN_BUILD_DEBUG: __asm int 3")
# define GEN_DEBUG_TRAP() __asm int 3 /* Trap to debugger! */
# else
#pragma message("GEN_BUILD_DEBUG: __debugbreak()")
# define GEN_DEBUG_TRAP() __debugbreak()
# endif
# elif defined( GEN_COMPILER_TINYC )
# define GEN_DEBUG_TRAP() process_exit( 1 )
# else # else
# define GEN_DEBUG_TRAP() __debugbreak() # define GEN_DEBUG_TRAP() __builtin_trap()
# endif # endif
#elif defined( GEN_COMPILER_TINYC )
# define GEN_DEBUG_TRAP() process_exit( 1 )
#else #else
# define GEN_DEBUG_TRAP() __builtin_trap() #pragma message("GEN_BUILD_DEBUG: omitted")
# define GEN_DEBUG_TRAP()
#endif #endif
#define GEN_ASSERT( cond ) GEN_ASSERT_MSG( cond, NULL ) #define GEN_ASSERT( cond ) GEN_ASSERT_MSG( cond, NULL )
@ -37,14 +44,14 @@
// NOTE: Things that shouldn't happen with a message! // NOTE: Things that shouldn't happen with a message!
#define GEN_PANIC( msg, ... ) GEN_ASSERT_MSG( 0, msg, ##__VA_ARGS__ ) #define GEN_PANIC( msg, ... ) GEN_ASSERT_MSG( 0, msg, ##__VA_ARGS__ )
#if Build_Debug #if GEN_BULD_DEBUG
#define GEN_FATAL( ... ) \ #define GEN_FATAL( ... ) \
do \ do \
{ \ { \
local_persist thread_local \ local_persist thread_local \
char buf[GEN_PRINTF_MAXLEN] = { 0 }; \ char buf[GEN_PRINTF_MAXLEN] = { 0 }; \
\ \
str_fmt(buf, GEN_PRINTF_MAXLEN, __VA_ARGS__); \ c_str_fmt(buf, GEN_PRINTF_MAXLEN, __VA_ARGS__); \
GEN_PANIC(buf); \ GEN_PANIC(buf); \
} \ } \
while (0) while (0)
@ -53,7 +60,8 @@
# define GEN_FATAL( ... ) \ # define GEN_FATAL( ... ) \
do \ do \
{ \ { \
str_fmt_out_err( __VA_ARGS__ ); \ c_str_fmt_out_err( __VA_ARGS__ ); \
GEN_DEBUG_TRAP(); \
process_exit(1); \ process_exit(1); \
} \ } \
while (0) while (0)

View File

@ -18,7 +18,7 @@ wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, ssize* w_len_ )
*w_len_ = w_len; *w_len_ = w_len;
return NULL; return NULL;
} }
len = str_len( text ); len = c_str_len( text );
if ( len == 0 ) if ( len == 0 )
{ {
if ( w_len_ ) if ( w_len_ )
@ -375,7 +375,7 @@ FileError file_close( FileInfo* f )
FileError file_new( FileInfo* f, FileDescriptor fd, FileOperations ops, char const* filename ) FileError file_new( FileInfo* f, FileDescriptor fd, FileOperations ops, char const* filename )
{ {
FileError err = EFileError_NONE; FileError err = EFileError_NONE;
ssize len = str_len( filename ); ssize len = c_str_len( filename );
f->ops = ops; f->ops = ops;
f->fd = fd; f->fd = fd;

View File

@ -93,7 +93,7 @@ struct DirInfo
// Internals // Internals
char** filenames; // zpl_array char** filenames; // zpl_array
String buf; StrBuilder buf;
}; };
struct FileInfo struct FileInfo

View File

@ -284,121 +284,4 @@
# define GEN_OPITMIZE_MAPPINGS_END # define GEN_OPITMIZE_MAPPINGS_END
#endif #endif
#if GEN_COMPILER_C
// ____ _ ______ _ _ ____ _ __ _
// / ___} (_) | ____} | | (_) / __ \ | | | |(_)
// | | ___ ___ _ __ ___ _ __ _ ___ | |__ _ _ _ __ ___| |_ _ ___ _ __ | | | |_ _____ _ __ | | ___ __ _ __| | _ _ __ __ _
// | |{__ |/ _ \ '_ \ / _ \ '__} |/ __| | __} | | | '_ \ / __} __} |/ _ \| '_ \ | | | \ \ / / _ \ '_ \| |/ _ \ / _` |/ _` || | '_ \ / _` |
// | |__j | __/ | | | __/ | | | (__ | | | |_| | | | | (__| l_| | (_) | | | | | l__| |\ V / __/ | | | | (_) | (_| | (_| || | | | | (_| |
// \____/ \___}_l l_l\___}_l l_l\___| l_l \__,_l_l l_l\___}\__}_l\___/l_l l_l \____/ \_/ \___}_l l_l_l\___/ \__,_l\__,_l|_|_| |_|\__, |
// This implemnents macros for utilizing "The Naive Extendible _Generic Macro" explained in: __| |
// https://github.com/JacksonAllan/CC/blob/main/articles/Better_C_Generics_Part_1_The_Extendible_Generic.md {___/
// Since gencpp is used to generate the c-library, it was choosen over the more novel implementations to keep the macros as easy to understand and unobfuscated as possible.
#define GEN_COMMA_OPERATOR , // The comma operator is used by preprocessor macros to delimit arguments, so we have to represent it via a macro to prevent parsing incorrectly.
// Helper macros for argument selection
#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_3( _1, _2, _3, ... ) _3 // etc..
#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_COMMA_DELIMITER GEN_SELECT_ARG_3 // Use the arg expansion macro to select arg 3 which should have the comma delimiter ','.
#define GEN_RESOLVED_FUNCTION_CALL // Just used to indicate where the call "occurs"
// ----------------------------------------------------------------------------------------------------------------------------------
// GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( macro ) includes a _Generic slot only if the specified macro is defined (as type, function_name).
// It takes advantage of the fact that if the macro is defined, then the expanded text will contain a comma.
// Expands to ',' if it can find (type): (function) <comma_operator: ',' >
// 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, , )
// ^ Selects the comma ^ is the type ^ is the function ^ Insert a comma
// The slot won't exist if that comma is not found. |
// For the occastion where an expression didn't resolve to a selection option the "default: <value>" will be set to:
typedef struct GENCPP_NO_RESOLVED_GENERIC_SELECTION GENCPP_NO_RESOLVED_GENERIC_SELECTION;
struct GENCPP_NO_RESOLVED_GENERIC_SELECTION {
void* _THE_VOID_SLOT_;
};
GENCPP_NO_RESOLVED_GENERIC_SELECTION const gen_generic_selection_fail = {0};
// Which will provide the message: error: called object type 'struct NO_RESOLVED_GENERIC_SELECTION' is not a function or function pointer
// ----------------------------------------------------------------------------------------------------------------------------------
// Below are generated on demand for an overlaod depdendent on a type:
// ----------------------------------------------------------------------------------------------------------------------------------
#define GEN_FUNCTION_GENERIC_EXAMPLE( selector_arg ) _Generic( \
(selector_arg), /* Select Via Expression*/ \
/* Extendibility slots: */ \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
default: gen_generic_selection_fail \
) GEN_RESOLVED_FUNCTION_CALL( selector_arg )
// ----------------------------------------------------------------------------------------------------------------------------------
// Then each definiton of a function has an associated define:
#// #define GENERIC_SLOT_<#>_<generic identifier> <typename>, <function_to_resolve>
// Then somehwere later on
// <etc> <return_type> <function_id> ( <arguments> ) { <implementation> }
// Concrete example:
// To add support for long:
#define GENERIC_SLOT_1_gen_example_hash long, gen_example_hash__P_long
size_t gen_example_hash__P_long( long val ) { return val * 2654435761ull; }
// To add support for long long:
#define GENERIC_SLOT_2_gen_example_hash long long, gen_example_hash__P_long_long
size_t gen_example_hash__P_long_long( long long val ) { return val * 2654435761ull; }
// 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.
#define gen_hash_example( function_arguments ) _Generic( \
(function_arguments), /* Select Via Expression*/ \
/* Extendibility slots: */ \
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_3 ) \
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_6 ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_7 ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_8 ) \
default: gen_generic_selection_fail \
) GEN_RESOLVED_FUNCTION_CALL( function_arguments )
// Additional Variations:
// If the function takes more than one argument the following is used:
#define GEN_FUNCTION_GENERIC_EXAMPLE_VARADIC( selector_arg, ... ) _Generic( \
(selector_arg), \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_2 ) \
/* ... */ \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT(FunctionID__ARGS_SIG_N ) \
default: gen_generic_selection_fail \
) GEN_RESOLVED_FUNCTION_CALL( selector_arg, __VA_ARG__ )
// If the function does not take the arugment as a parameter:
#define GEN_FUNCTION_GENERIC_EXAMPLE_DIRECT_TYPE( selector_arg ) _Generic( \
( GEN_TYPE_TO_EXP(selector_arg) ), \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_2 ) \
/* ... */ \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT(FunctionID__ARGS_SIG_N ) \
default: gen_generic_selection_fail \
) GEN_RESOLVED_FUNCTION_CALL()
// Used to keep the _Generic keyword happy as bare types are not considered "expressions"
#define GEN_TYPE_TO_EXP(type) (* (type*)NULL)
// Instead of using this macro, you'll see it directly expanded by the code generation.
// typedef void* GEN_GenericExampleType;
// GEN_FUNCTION_GENERIC_EXAMPLE_DIRECT_TYPE( GEN_GenericExampleType );
// END OF ------------------------ _Generic function overloading ----------------------------------------- END OF
#endif
#pragma endregion Macros #pragma endregion Macros

View File

@ -8,7 +8,7 @@
#define _adt_fprintf( s_, fmt_, ... ) \ #define _adt_fprintf( s_, fmt_, ... ) \
do \ do \
{ \ { \
if ( str_fmt_file( s_, fmt_, ##__VA_ARGS__ ) < 0 ) \ if ( c_str_fmt_file( s_, fmt_, ##__VA_ARGS__ ) < 0 ) \
return EADT_ERROR_OUT_OF_MEMORY; \ return EADT_ERROR_OUT_OF_MEMORY; \
} while ( 0 ) } while ( 0 )
@ -69,7 +69,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search )
for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ ) for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ )
{ {
if ( ! str_compare( node->nodes[ i ].name, name ) ) if ( ! c_str_compare( node->nodes[ i ].name, name ) )
{ {
return ( node->nodes + i ); return ( node->nodes + i );
} }
@ -96,7 +96,7 @@ internal ADT_Node* _adt_get_value( ADT_Node* node, char const* value )
case EADT_TYPE_MULTISTRING : case EADT_TYPE_MULTISTRING :
case EADT_TYPE_STRING : case EADT_TYPE_STRING :
{ {
if ( node->string && ! str_compare( node->string, value ) ) if ( node->string && ! c_str_compare( node->string, value ) )
{ {
return node; return node;
} }
@ -115,7 +115,7 @@ internal ADT_Node* _adt_get_value( ADT_Node* node, char const* value )
ssize fsize = 0; ssize fsize = 0;
u8* buf = file_stream_buf( &tmp, &fsize ); u8* buf = file_stream_buf( &tmp, &fsize );
if ( ! str_compare( ( char const* )buf, value ) ) if ( ! c_str_compare( ( char const* )buf, value ) )
{ {
file_close( &tmp ); file_close( &tmp );
return node; return node;
@ -135,7 +135,7 @@ internal ADT_Node* _adt_get_field( ADT_Node* node, char* name, char* value )
{ {
for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ ) for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ )
{ {
if ( ! str_compare( node->nodes[ i ].name, name ) ) if ( ! c_str_compare( node->nodes[ i ].name, name ) )
{ {
ADT_Node* child = &node->nodes[ i ]; ADT_Node* child = &node->nodes[ i ];
if ( _adt_get_value( child, value ) ) if ( _adt_get_value( child, value ) )
@ -168,22 +168,22 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri )
} }
#if defined EADT_URI_DEBUG || 0 #if defined EADT_URI_DEBUG || 0
str_fmt_out( "uri: %s\n", uri ); c_str_fmt_out( "uri: %s\n", uri );
#endif #endif
char * p = ( char* )uri, *b = p, *e = p; char * p = ( char* )uri, *b = p, *e = p;
ADT_Node* found_node = NULL; ADT_Node* found_node = NULL;
b = p; b = p;
p = e = ( char* )str_skip( p, '/' ); p = e = ( char* )c_str_skip( p, '/' );
char* buf = str_fmt_buf( "%.*s", ( int )( e - b ), b ); char* buf = c_str_fmt_buf( "%.*s", ( int )( e - b ), b );
/* handle field value lookup */ /* handle field value lookup */
if ( *b == '[' ) if ( *b == '[' )
{ {
char *l_p = buf + 1, *l_b = l_p, *l_e = l_p, *l_b2 = l_p, *l_e2 = l_p; char *l_p = buf + 1, *l_b = l_p, *l_e = l_p, *l_b2 = l_p, *l_e2 = l_p;
l_e = ( char* )str_skip( l_p, '=' ); l_e = ( char* )c_str_skip( l_p, '=' );
l_e2 = ( char* )str_skip( l_p, ']' ); l_e2 = ( char* )c_str_skip( l_p, ']' );
if ( ( ! *l_e && node->type != EADT_TYPE_ARRAY ) || ! *l_e2 ) if ( ( ! *l_e && node->type != EADT_TYPE_ARRAY ) || ! *l_e2 )
{ {
@ -257,7 +257,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri )
/* handle array index lookup */ /* handle array index lookup */
else else
{ {
ssize idx = ( ssize )str_to_i64( buf, NULL, 10 ); ssize idx = ( ssize )c_str_to_i64( buf, NULL, 10 );
if ( idx >= 0 && idx < scast(ssize, array_num(node->nodes)) ) if ( idx >= 0 && idx < scast(ssize, array_num(node->nodes)) )
{ {
found_node = &node->nodes[ idx ]; found_node = &node->nodes[ idx ];
@ -511,7 +511,7 @@ char* adt_parse_number( ADT_Node* node, char* base_str )
} }
else else
{ {
if ( ! str_compare_len( e, "0x", 2 ) || ! str_compare_len( e, "0X", 2 ) ) if ( ! c_str_compare_len( e, "0x", 2 ) || ! c_str_compare_len( e, "0X", 2 ) )
{ {
node_props = EADT_PROPS_IS_HEX; node_props = EADT_PROPS_IS_HEX;
} }
@ -575,12 +575,12 @@ char* adt_parse_number( ADT_Node* node, char* base_str )
} }
} }
orig_exp = exp = ( u8 )str_to_i64( expbuf, NULL, 10 ); orig_exp = exp = ( u8 )c_str_to_i64( expbuf, NULL, 10 );
} }
if ( node_type == EADT_TYPE_INTEGER ) if ( node_type == EADT_TYPE_INTEGER )
{ {
node->integer = str_to_i64( buf, 0, 0 ); node->integer = c_str_to_i64( buf, 0, 0 );
#ifndef GEN_PARSER_DISABLE_ANALYSIS #ifndef GEN_PARSER_DISABLE_ANALYSIS
/* special case: negative zero */ /* special case: negative zero */
if ( node->integer == 0 && buf[ 0 ] == '-' ) if ( node->integer == 0 && buf[ 0 ] == '-' )
@ -595,19 +595,19 @@ char* adt_parse_number( ADT_Node* node, char* base_str )
} }
else else
{ {
node->real = str_to_f64( buf, 0 ); node->real = c_str_to_f64( buf, 0 );
#ifndef GEN_PARSER_DISABLE_ANALYSIS #ifndef GEN_PARSER_DISABLE_ANALYSIS
char *q = buf, *base_string = q, *base_string2 = q; char *q = buf, *base_string = q, *base_string2 = q;
base_string = ccast( char*, str_skip( base_string, '.' )); base_string = ccast( char*, c_str_skip( base_string, '.' ));
*base_string = '\0'; *base_string = '\0';
base_string2 = base_string + 1; base_string2 = base_string + 1;
char* base_string_off = base_string2; char* base_strbuilder_off = base_string2;
while ( *base_string_off++ == '0' ) while ( *base_strbuilder_off++ == '0' )
base2_offset++; base2_offset++;
base = ( s32 )str_to_i64( q, 0, 0 ); base = ( s32 )c_str_to_i64( q, 0, 0 );
base2 = ( s32 )str_to_i64( base_string2, 0, 0 ); base2 = ( s32 )c_str_to_i64( base_string2, 0, 0 );
if ( exp ) if ( exp )
{ {
exp = exp * ( ! ( eb == 10.0f ) ? -1 : 1 ); exp = exp * ( ! ( eb == 10.0f ) ? -1 : 1 );
@ -750,7 +750,7 @@ ADT_Error adt_print_string( FileInfo* file, ADT_Node* node, char const* escaped_
do do
{ {
p = str_skip_any( p, escaped_chars ); p = c_str_skip_any( p, escaped_chars );
_adt_fprintf( file, "%.*s", pointer_diff( b, p ), b ); _adt_fprintf( file, "%.*s", pointer_diff( b, p ), b );
if ( *p && ! ! char_first_occurence( escaped_chars, *p ) ) if ( *p && ! ! char_first_occurence( escaped_chars, *p ) )
{ {
@ -763,7 +763,7 @@ ADT_Error adt_print_string( FileInfo* file, ADT_Node* node, char const* escaped_
return EADT_ERROR_NONE; return EADT_ERROR_NONE;
} }
ADT_Error adt_str_to_number( ADT_Node* node ) ADT_Error adt_c_str_to_number( ADT_Node* node )
{ {
GEN_ASSERT( node ); GEN_ASSERT( node );
@ -779,7 +779,7 @@ ADT_Error adt_str_to_number( ADT_Node* node )
return EADT_ERROR_NONE; return EADT_ERROR_NONE;
} }
ADT_Error adt_str_to_number_strict( ADT_Node* node ) ADT_Error adt_c_str_to_number_strict( ADT_Node* node )
{ {
GEN_ASSERT( node ); GEN_ASSERT( node );
@ -826,7 +826,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
do do
{ {
char delimiter = 0; char delimiter = 0;
currentChar = ccast( char*, str_trim( currentChar, false )); currentChar = ccast( char*, c_str_trim( currentChar, false ));
if ( *currentChar == 0 ) if ( *currentChar == 0 )
break; break;
@ -850,7 +850,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
#endif #endif
do do
{ {
endChar = ccast( char*, str_skip( endChar, '"' )); endChar = ccast( char*, c_str_skip( endChar, '"' ));
if ( *endChar && *( endChar + 1 ) == '"' ) if ( *endChar && *( endChar + 1 ) == '"' )
{ {
@ -869,7 +869,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
} }
*endChar = 0; *endChar = 0;
currentChar = ccast( char*, str_trim( endChar + 1, true )); currentChar = ccast( char*, c_str_trim( endChar + 1, true ));
delimiter = * currentChar; delimiter = * currentChar;
/* unescape escaped quotes (so that unescaped text escapes :) */ /* unescape escaped quotes (so that unescaped text escapes :) */
@ -879,7 +879,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
{ {
if ( *escapedChar == '"' && *( escapedChar + 1 ) == '"' ) if ( *escapedChar == '"' && *( escapedChar + 1 ) == '"' )
{ {
mem_move( escapedChar, escapedChar + 1, str_len( escapedChar ) ); mem_move( escapedChar, escapedChar + 1, c_str_len( escapedChar ) );
} }
escapedChar++; escapedChar++;
} }
@ -906,7 +906,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
if ( * endChar ) if ( * endChar )
{ {
currentChar = ccast( char*, str_trim( endChar, true )); currentChar = ccast( char*, c_str_trim( endChar, true ));
while ( char_is_space( *( endChar - 1 ) ) ) while ( char_is_space( *( endChar - 1 ) ) )
{ {
@ -927,7 +927,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
char* num_p = beginChar; char* num_p = beginChar;
// We only consider hexadecimal values if they start with 0x // We only consider hexadecimal values if they start with 0x
if ( str_len(num_p) > 2 && num_p[0] == '0' && (num_p[1] == 'x' || num_p[1] == 'X') ) if ( c_str_len(num_p) > 2 && num_p[0] == '0' && (num_p[1] == 'x' || num_p[1] == 'X') )
{ {
num_p += 2; // skip '0x' prefix num_p += 2; // skip '0x' prefix
do do
@ -946,7 +946,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
if (!skip_number) if (!skip_number)
{ {
adt_str_to_number(&rowItem); adt_c_str_to_number(&rowItem);
} }
} }
@ -1021,16 +1021,16 @@ void _csv_write_record( FileInfo* file, CSV_Object* node )
{ {
case EADT_NAME_STYLE_DOUBLE_QUOTE : case EADT_NAME_STYLE_DOUBLE_QUOTE :
{ {
str_fmt_file( file, "\"" ); c_str_fmt_file( file, "\"" );
adt_print_string( file, node, "\"", "\"" ); adt_print_string( file, node, "\"", "\"" );
str_fmt_file( file, "\"" ); c_str_fmt_file( file, "\"" );
} }
break; break;
case EADT_NAME_STYLE_NO_QUOTES : case EADT_NAME_STYLE_NO_QUOTES :
{ {
#endif #endif
str_fmt_file( file, "%s", node->string ); c_str_fmt_file( file, "%s", node->string );
#ifndef GEN_PARSER_DISABLE_ANALYSIS #ifndef GEN_PARSER_DISABLE_ANALYSIS
} }
break; break;
@ -1078,10 +1078,10 @@ void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delimiter )
_csv_write_header( file, &obj->nodes[ i ] ); _csv_write_header( file, &obj->nodes[ i ] );
if ( i + 1 != cols ) if ( i + 1 != cols )
{ {
str_fmt_file( file, "%c", delimiter ); c_str_fmt_file( file, "%c", delimiter );
} }
} }
str_fmt_file( file, "\n" ); c_str_fmt_file( file, "\n" );
} }
for ( ssize r = 0; r < rows; r++ ) for ( ssize r = 0; r < rows; r++ )
@ -1091,14 +1091,14 @@ void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delimiter )
_csv_write_record( file, &obj->nodes[ i ].nodes[ r ] ); _csv_write_record( file, &obj->nodes[ i ].nodes[ r ] );
if ( i + 1 != cols ) if ( i + 1 != cols )
{ {
str_fmt_file( file, "%c", delimiter ); c_str_fmt_file( file, "%c", delimiter );
} }
} }
str_fmt_file( file, "\n" ); c_str_fmt_file( file, "\n" );
} }
} }
String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delimiter ) StrBuilder csv_write_strbuilder_delimiter( AllocatorInfo a, CSV_Object* obj, char delimiter )
{ {
FileInfo tmp; FileInfo tmp;
file_stream_new( &tmp, a ); file_stream_new( &tmp, a );
@ -1106,9 +1106,11 @@ String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delimi
ssize fsize; ssize fsize;
u8* buf = file_stream_buf( &tmp, &fsize ); u8* buf = file_stream_buf( &tmp, &fsize );
String output = string_make_length( a, ( char* )buf, fsize ); StrBuilder output = strbuilder_make_length( a, ( char* )buf, fsize );
file_close( &tmp ); file_close( &tmp );
return output; return output;
} }
#undef _adt_fprintf
#pragma endregion CSV #pragma endregion CSV

View File

@ -350,7 +350,7 @@ char* adt_parse_number_strict( ADT_Node* node, char* base_str );
* @param node * @param node
* @return * @return
*/ */
ADT_Error adt_str_to_number( ADT_Node* node ); ADT_Error adt_c_str_to_number( ADT_Node* node );
/** /**
* @brief Parses and converts an existing string node into a number. * @brief Parses and converts an existing string node into a number.
@ -359,7 +359,7 @@ ADT_Error adt_str_to_number( ADT_Node* node );
* @param node * @param node
* @return * @return
*/ */
ADT_Error adt_str_to_number_strict( ADT_Node* node ); ADT_Error adt_c_str_to_number_strict( ADT_Node* node );
/** /**
* @brief Prints a number into a file stream. * @brief Prints a number into a file stream.
@ -406,9 +406,9 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator,
void csv_free( CSV_Object* obj ); void csv_free( CSV_Object* obj );
void csv_write( FileInfo* file, CSV_Object* obj ); void csv_write( FileInfo* file, CSV_Object* obj );
String csv_write_string( AllocatorInfo a, CSV_Object* obj ); StrBuilder csv_write_string( AllocatorInfo a, CSV_Object* obj );
void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim ); void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim );
String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delim ); StrBuilder csv_write_strbuilder_delimiter( AllocatorInfo a, CSV_Object* obj, char delim );
/* inline */ /* inline */
@ -425,9 +425,9 @@ void csv_write( FileInfo* file, CSV_Object* obj )
} }
inline inline
String csv_write_string( AllocatorInfo a, CSV_Object* obj ) StrBuilder csv_write_string( AllocatorInfo a, CSV_Object* obj )
{ {
return csv_write_string_delimiter( a, obj, ',' ); return csv_write_strbuilder_delimiter( a, obj, ',' );
} }
#pragma endregion CSV #pragma endregion CSV

View File

@ -29,12 +29,6 @@
# ifndef GEN_SYSTEM_MACOS # ifndef GEN_SYSTEM_MACOS
# define GEN_SYSTEM_MACOS 1 # define GEN_SYSTEM_MACOS 1
# endif # endif
# include <TargetConditionals.h>
# if TARGET_IPHONE_SIMULATOR == 1 || TARGET_OS_IPHONE == 1
# ifndef GEN_SYSTEM_IOS
# define GEN_SYSTEM_IOS 1
# endif
# endif
#elif defined( __unix__ ) #elif defined( __unix__ )
# ifndef GEN_SYSTEM_UNIX # ifndef GEN_SYSTEM_UNIX
# define GEN_SYSTEM_UNIX 1 # define GEN_SYSTEM_UNIX 1

View File

@ -1,6 +1,6 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES #ifdef GEN_INTELLISENSE_DIRECTIVES
# pragma once # pragma once
# include "string_ops.cpp" # include "strbuilder_ops.cpp"
#endif #endif
#pragma region Printing #pragma region Printing
@ -48,7 +48,7 @@ internal ssize _print_string( char* text, ssize max_len, _format_info* info, cha
if ( str == NULL && max_len >= 6 ) if ( str == NULL && max_len >= 6 )
{ {
res += str_copy_nulpad( text, "(null)", 6 ); res += c_str_copy_nulpad( text, "(null)", 6 );
return res; return res;
} }
@ -56,7 +56,7 @@ internal ssize _print_string( char* text, ssize max_len, _format_info* info, cha
// Made the design decision for this library that precision is the length of the string. // Made the design decision for this library that precision is the length of the string.
len = info->precision; len = info->precision;
else else
len = str_len( str ); len = c_str_len( str );
if ( info && ( info->width == 0 && info->flags & GEN_FMT_WIDTH ) ) if ( info && ( info->width == 0 && info->flags & GEN_FMT_WIDTH ) )
{ {
@ -69,7 +69,7 @@ internal ssize _print_string( char* text, ssize max_len, _format_info* info, cha
len = info->precision < len ? info->precision : len; len = info->precision < len ? info->precision : len;
if ( res + len > max_len ) if ( res + len > max_len )
return res; return res;
res += str_copy_nulpad( text, str, len ); res += c_str_copy_nulpad( text, str, len );
text += res; text += res;
if ( info->width > res ) if ( info->width > res )
@ -93,15 +93,15 @@ internal ssize _print_string( char* text, ssize max_len, _format_info* info, cha
if ( res + len > max_len ) if ( res + len > max_len )
return res; return res;
res += str_copy_nulpad( text, str, len ); res += c_str_copy_nulpad( text, str, len );
} }
if ( info ) if ( info )
{ {
if ( info->flags & GEN_FMT_UPPER ) if ( info->flags & GEN_FMT_UPPER )
str_to_upper( begin ); c_str_to_upper( begin );
else if ( info->flags & GEN_FMT_LOWER ) else if ( info->flags & GEN_FMT_LOWER )
str_to_lower( begin ); c_str_to_lower( begin );
} }
return res; return res;
@ -238,7 +238,7 @@ internal ssize _print_f64( char* text, ssize max_len, _format_info* info, b32 is
return ( text - text_begin ); return ( text - text_begin );
} }
neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_list va ) neverinline ssize c_str_fmt_va( char* text, ssize max_len, char const* fmt, va_list va )
{ {
char const* text_begin = text; char const* text_begin = text;
ssize remaining = max_len, res; ssize remaining = max_len, res;
@ -310,7 +310,7 @@ neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_lis
} }
else else
{ {
info.width = scast( s32, str_to_i64( fmt, ccast( char**, & fmt), 10 )); info.width = scast( s32, c_str_to_i64( fmt, ccast( char**, & fmt), 10 ));
if ( info.width != 0 ) if ( info.width != 0 )
{ {
info.flags |= GEN_FMT_WIDTH; info.flags |= GEN_FMT_WIDTH;
@ -328,7 +328,7 @@ neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_lis
} }
else else
{ {
info.precision = scast( s32, str_to_i64( fmt, ccast( char**, & fmt), 10 )); info.precision = scast( s32, c_str_to_i64( fmt, ccast( char**, & fmt), 10 ));
} }
info.flags &= ~GEN_FMT_ZERO; info.flags &= ~GEN_FMT_ZERO;
} }
@ -419,19 +419,20 @@ neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_lis
case 'S': case 'S':
{ {
if ( *(fmt + 1) == 'C' ) if ( *(fmt + 1) == 'B' )
{ {
++ fmt; ++ fmt;
StrC gen_str = va_arg( va, StrC); StrBuilder gen_str = { va_arg( va, char*) };
info.precision = gen_str.Len;
len = _print_string( text, remaining, &info, gen_str.Ptr ); info.precision = strbuilder_length(gen_str);
len = _print_string( text, remaining, &info, gen_str );
break; break;
} }
String gen_str = { va_arg( va, char*) }; Str gen_str = va_arg( va, Str);
info.precision = gen_str.Len;
info.precision = string_length(gen_str); len = _print_string( text, remaining, &info, gen_str.Ptr );
len = _print_string( text, remaining, &info, gen_str );
} }
break; break;
@ -531,67 +532,67 @@ neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_lis
return ( res >= max_len || res < 0 ) ? -1 : res; return ( res >= max_len || res < 0 ) ? -1 : res;
} }
char* str_fmt_buf_va( char const* fmt, va_list va ) char* c_str_fmt_buf_va( char const* fmt, va_list va )
{ {
local_persist thread_local char buffer[ GEN_PRINTF_MAXLEN ]; local_persist thread_local char buffer[ GEN_PRINTF_MAXLEN ];
str_fmt_va( buffer, size_of( buffer ), fmt, va ); c_str_fmt_va( buffer, size_of( buffer ), fmt, va );
return buffer; return buffer;
} }
char* str_fmt_buf( char const* fmt, ... ) char* c_str_fmt_buf( char const* fmt, ... )
{ {
va_list va; va_list va;
char* str; char* str;
va_start( va, fmt ); va_start( va, fmt );
str = str_fmt_buf_va( fmt, va ); str = c_str_fmt_buf_va( fmt, va );
va_end( va ); va_end( va );
return str; return str;
} }
ssize str_fmt_file_va( FileInfo* f, char const* fmt, va_list va ) ssize c_str_fmt_file_va( FileInfo* f, char const* fmt, va_list va )
{ {
local_persist thread_local char buf[ GEN_PRINTF_MAXLEN ]; local_persist thread_local char buf[ GEN_PRINTF_MAXLEN ];
ssize len = str_fmt_va( buf, size_of( buf ), fmt, va ); ssize len = c_str_fmt_va( buf, size_of( buf ), fmt, va );
b32 res = file_write( f, buf, len - 1 ); // NOTE: prevent extra whitespace b32 res = file_write( f, buf, len - 1 ); // NOTE: prevent extra whitespace
return res ? len : -1; return res ? len : -1;
} }
ssize str_fmt_file( FileInfo* f, char const* fmt, ... ) ssize c_str_fmt_file( FileInfo* f, char const* fmt, ... )
{ {
ssize res; ssize res;
va_list va; va_list va;
va_start( va, fmt ); va_start( va, fmt );
res = str_fmt_file_va( f, fmt, va ); res = c_str_fmt_file_va( f, fmt, va );
va_end( va ); va_end( va );
return res; return res;
} }
ssize str_fmt( char* str, ssize n, char const* fmt, ... ) ssize c_str_fmt( char* str, ssize n, char const* fmt, ... )
{ {
ssize res; ssize res;
va_list va; va_list va;
va_start( va, fmt ); va_start( va, fmt );
res = str_fmt_va( str, n, fmt, va ); res = c_str_fmt_va( str, n, fmt, va );
va_end( va ); va_end( va );
return res; return res;
} }
ssize str_fmt_out_va( char const* fmt, va_list va ) ssize c_str_fmt_out_va( char const* fmt, va_list va )
{ {
return str_fmt_file_va( file_get_standard( EFileStandard_OUTPUT ), fmt, va ); return c_str_fmt_file_va( file_get_standard( EFileStandard_OUTPUT ), fmt, va );
} }
ssize str_fmt_out_err_va( char const* fmt, va_list va ) ssize c_str_fmt_out_err_va( char const* fmt, va_list va )
{ {
return str_fmt_file_va( file_get_standard( EFileStandard_ERROR ), fmt, va ); return c_str_fmt_file_va( file_get_standard( EFileStandard_ERROR ), fmt, va );
} }
ssize str_fmt_out_err( char const* fmt, ... ) ssize c_str_fmt_out_err( char const* fmt, ... )
{ {
ssize res; ssize res;
va_list va; va_list va;
va_start( va, fmt ); va_start( va, fmt );
res = str_fmt_out_err_va( fmt, va ); res = c_str_fmt_out_err_va( fmt, va );
va_end( va ); va_end( va );
return res; return res;
} }

View File

@ -1,6 +1,6 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES #ifdef GEN_INTELLISENSE_DIRECTIVES
# pragma once # pragma once
# include "string_ops.hpp" # include "strbuilder_ops.hpp"
#endif #endif
#pragma region Printing #pragma region Printing
@ -13,15 +13,15 @@ typedef struct FileInfo FileInfo;
typedef char PrintF_Buffer[GEN_PRINTF_MAXLEN]; typedef char PrintF_Buffer[GEN_PRINTF_MAXLEN];
// NOTE: A locally persisting buffer is used internally // NOTE: A locally persisting buffer is used internally
char* str_fmt_buf ( char const* fmt, ... ); char* c_str_fmt_buf ( char const* fmt, ... );
char* str_fmt_buf_va ( char const* fmt, va_list va ); char* c_str_fmt_buf_va ( char const* fmt, va_list va );
ssize str_fmt ( char* str, ssize n, char const* fmt, ... ); ssize c_str_fmt ( char* str, ssize n, char const* fmt, ... );
ssize str_fmt_va ( char* str, ssize n, char const* fmt, va_list va ); ssize c_str_fmt_va ( char* str, ssize n, char const* fmt, va_list va );
ssize str_fmt_out_va ( char const* fmt, va_list va ); ssize c_str_fmt_out_va ( char const* fmt, va_list va );
ssize str_fmt_out_err ( char const* fmt, ... ); ssize c_str_fmt_out_err ( char const* fmt, ... );
ssize str_fmt_out_err_va( char const* fmt, va_list va ); ssize c_str_fmt_out_err_va( char const* fmt, va_list va );
ssize str_fmt_file ( FileInfo* f, char const* fmt, ... ); ssize c_str_fmt_file ( FileInfo* f, char const* fmt, ... );
ssize str_fmt_file_va ( FileInfo* f, char const* fmt, va_list va ); ssize c_str_fmt_file_va ( FileInfo* f, char const* fmt, va_list va );
constexpr constexpr
char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED"; char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
@ -33,7 +33,7 @@ ssize log_fmt(char const* fmt, ...)
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
res = str_fmt_out_va(fmt, va); res = c_str_fmt_out_va(fmt, va);
va_end(va); va_end(va);
return res; return res;

View File

@ -13,9 +13,9 @@
# define _printf_err( fmt, ... ) fprintf( stderr, fmt, __VA_ARGS__ ) # define _printf_err( fmt, ... ) fprintf( stderr, fmt, __VA_ARGS__ )
# define _printf_err_va( fmt, va ) vfprintf( stderr, fmt, va ) # define _printf_err_va( fmt, va ) vfprintf( stderr, fmt, va )
# else # else
# define _strlen str_len # define _strlen c_str_len
# define _printf_err( fmt, ... ) str_fmt_out_err( fmt, __VA_ARGS__ ) # define _printf_err( fmt, ... ) c_str_fmt_out_err( fmt, __VA_ARGS__ )
# define _printf_err_va( fmt, va ) str_fmt_out_err_va( fmt, va ) # define _printf_err_va( fmt, va ) c_str_fmt_out_err_va( fmt, va )
# endif # endif
# endif # endif
# #

View File

@ -18,7 +18,7 @@ ssize _scan_zpl_i64( const char* text, s32 base, s64* value )
text++; text++;
} }
if ( base == 16 && str_compare_len( text, "0x", 2 ) == 0 ) if ( base == 16 && c_str_compare_len( text, "0x", 2 ) == 0 )
text += 2; text += 2;
for ( ;; ) for ( ;; )
@ -53,14 +53,14 @@ global const char _num_to_char_table[] =
"abcdefghijklmnopqrstuvwxyz" "abcdefghijklmnopqrstuvwxyz"
"@$"; "@$";
s64 str_to_i64( const char* str, char** end_ptr, s32 base ) s64 c_str_to_i64( const char* str, char** end_ptr, s32 base )
{ {
ssize len; ssize len;
s64 value; s64 value;
if ( ! base ) if ( ! base )
{ {
if ( ( str_len( str ) > 2 ) && ( str_compare_len( str, "0x", 2 ) == 0 ) ) if ( ( c_str_len( str ) > 2 ) && ( c_str_compare_len( str, "0x", 2 ) == 0 ) )
base = 16; base = 16;
else else
base = 10; base = 10;
@ -100,7 +100,7 @@ void i64_to_str( s64 value, char* string, s32 base )
if ( negative ) if ( negative )
*buf++ = '-'; *buf++ = '-';
*buf = '\0'; *buf = '\0';
str_reverse( string ); c_str_reverse( string );
} }
void u64_to_str( u64 value, char* string, s32 base ) void u64_to_str( u64 value, char* string, s32 base )
@ -121,10 +121,10 @@ void u64_to_str( u64 value, char* string, s32 base )
} }
*buf = '\0'; *buf = '\0';
str_reverse( string ); c_str_reverse( string );
} }
f64 str_to_f64( const char* str, char** end_ptr ) f64 c_str_to_f64( const char* str, char** end_ptr )
{ {
f64 result, value, sign, scale; f64 result, value, sign, scale;
s32 frac; s32 frac;

View File

@ -18,25 +18,25 @@ char char_to_upper( char c );
s32 digit_to_int( char c ); s32 digit_to_int( char c );
s32 hex_digit_to_int( char c ); s32 hex_digit_to_int( char c );
s32 str_compare( const char* s1, const char* s2 ); s32 c_str_compare( const char* s1, const char* s2 );
s32 str_compare_len( const char* s1, const char* s2, ssize len ); s32 c_str_compare_len( const char* s1, const char* s2, ssize len );
char* str_copy( char* dest, const char* source, ssize len ); char* c_str_copy( char* dest, const char* source, ssize len );
ssize str_copy_nulpad( char* dest, const char* source, ssize len ); ssize c_str_copy_nulpad( char* dest, const char* source, ssize len );
ssize str_len( const char* str ); ssize c_str_len( const char* str );
ssize str_len_capped( const char* str, ssize max_len ); ssize c_str_len_capped( const char* str, ssize max_len );
char* str_reverse( char* str ); // NOTE: ASCII only char* c_str_reverse( char* str ); // NOTE: ASCII only
char const* str_skip( char const* str, char c ); char const* c_str_skip( char const* str, char c );
char const* str_skip_any( char const* str, char const* char_list ); char const* c_str_skip_any( char const* str, char const* char_list );
char const* str_trim( char const* str, b32 catch_newline ); char const* c_str_trim( char const* str, b32 catch_newline );
// NOTE: ASCII only // NOTE: ASCII only
void str_to_lower( char* str ); void c_str_to_lower( char* str );
void str_to_upper( char* str ); void c_str_to_upper( char* str );
s64 str_to_i64( const char* str, char** end_ptr, s32 base ); s64 c_str_to_i64( const char* str, char** end_ptr, s32 base );
void i64_to_str( s64 value, char* string, s32 base ); void i64_to_str( s64 value, char* string, s32 base );
void u64_to_str( u64 value, char* string, s32 base ); void u64_to_str( u64 value, char* string, s32 base );
f64 str_to_f64( const char* str, char** end_ptr ); f64 c_str_to_f64( const char* str, char** end_ptr );
inline inline
const char* char_first_occurence( const char* s, char c ) const char* char_first_occurence( const char* s, char c )
@ -122,7 +122,7 @@ s32 hex_digit_to_int( char c )
} }
inline inline
s32 str_compare( const char* s1, const char* s2 ) s32 c_str_compare( const char* s1, const char* s2 )
{ {
while ( *s1 && ( *s1 == *s2 ) ) while ( *s1 && ( *s1 == *s2 ) )
{ {
@ -132,7 +132,7 @@ s32 str_compare( const char* s1, const char* s2 )
} }
inline inline
s32 str_compare_len( const char* s1, const char* s2, ssize len ) s32 c_str_compare_len( const char* s1, const char* s2, ssize len )
{ {
for ( ; len > 0; s1++, s2++, len-- ) for ( ; len > 0; s1++, s2++, len-- )
{ {
@ -145,7 +145,7 @@ s32 str_compare_len( const char* s1, const char* s2, ssize len )
} }
inline inline
char* str_copy( char* dest, const char* source, ssize len ) char* c_str_copy( char* dest, const char* source, ssize len )
{ {
GEN_ASSERT_NOT_NULL( dest ); GEN_ASSERT_NOT_NULL( dest );
if ( source ) if ( source )
@ -166,7 +166,7 @@ char* str_copy( char* dest, const char* source, ssize len )
} }
inline inline
ssize str_copy_nulpad( char* dest, const char* source, ssize len ) ssize c_str_copy_nulpad( char* dest, const char* source, ssize len )
{ {
ssize result = 0; ssize result = 0;
GEN_ASSERT_NOT_NULL( dest ); GEN_ASSERT_NOT_NULL( dest );
@ -191,7 +191,7 @@ ssize str_copy_nulpad( char* dest, const char* source, ssize len )
} }
inline inline
ssize str_len( const char* str ) ssize c_str_len( const char* str )
{ {
if ( str == NULL ) if ( str == NULL )
{ {
@ -204,7 +204,7 @@ ssize str_len( const char* str )
} }
inline inline
ssize str_len_capped( const char* str, ssize max_len ) ssize c_str_len_capped( const char* str, ssize max_len )
{ {
const char* end = rcast(const char*, mem_find( str, 0, max_len )); const char* end = rcast(const char*, mem_find( str, 0, max_len ));
if ( end ) if ( end )
@ -213,9 +213,9 @@ ssize str_len_capped( const char* str, ssize max_len )
} }
inline inline
char* str_reverse( char* str ) char* c_str_reverse( char* str )
{ {
ssize len = str_len( str ); ssize len = c_str_len( str );
char* a = str + 0; char* a = str + 0;
char* b = str + len - 1; char* b = str + len - 1;
len /= 2; len /= 2;
@ -228,7 +228,7 @@ char* str_reverse( char* str )
} }
inline inline
char const* str_skip( char const* str, char c ) char const* c_str_skip( char const* str, char c )
{ {
while ( *str && *str != c ) while ( *str && *str != c )
{ {
@ -238,20 +238,20 @@ char const* str_skip( char const* str, char c )
} }
inline inline
char const* str_skip_any( char const* str, char const* char_list ) char const* c_str_skip_any( char const* str, char const* char_list )
{ {
char const* closest_ptr = rcast( char const*, pointer_add_const( rcast(mem_ptr_const, str), str_len( str ) )); char const* closest_ptr = rcast( char const*, pointer_add_const( rcast(mem_ptr_const, str), c_str_len( str ) ));
ssize char_list_count = str_len( char_list ); ssize char_list_count = c_str_len( char_list );
for ( ssize i = 0; i < char_list_count; i++ ) for ( ssize i = 0; i < char_list_count; i++ )
{ {
char const* p = str_skip( str, char_list[ i ] ); char const* p = c_str_skip( str, char_list[ i ] );
closest_ptr = min( closest_ptr, p ); closest_ptr = min( closest_ptr, p );
} }
return closest_ptr; return closest_ptr;
} }
inline inline
char const* str_trim( char const* str, b32 catch_newline ) char const* c_str_trim( char const* str, b32 catch_newline )
{ {
while ( *str && char_is_space( *str ) && ( ! catch_newline || ( catch_newline && *str != '\n' ) ) ) while ( *str && char_is_space( *str ) && ( ! catch_newline || ( catch_newline && *str != '\n' ) ) )
{ {
@ -261,7 +261,7 @@ char const* str_trim( char const* str, b32 catch_newline )
} }
inline inline
void str_to_lower( char* str ) void c_str_to_lower( char* str )
{ {
if ( ! str ) if ( ! str )
return; return;
@ -273,7 +273,7 @@ void str_to_lower( char* str )
} }
inline inline
void str_to_upper( char* str ) void c_str_to_upper( char* str )
{ {
if ( ! str ) if ( ! str )
return; return;

View File

@ -3,27 +3,27 @@
# include "hashing.cpp" # include "hashing.cpp"
#endif #endif
#pragma region String #pragma region StrBuilder
String string_make_length( AllocatorInfo allocator, char const* str, ssize length ) StrBuilder strbuilder_make_length( AllocatorInfo allocator, char const* str, ssize length )
{ {
ssize const header_size = sizeof( StringHeader ); ssize const header_size = sizeof( StrBuilderHeader );
s32 alloc_size = header_size + length + 1; s32 alloc_size = header_size + length + 1;
void* allocation = alloc( allocator, alloc_size ); void* allocation = alloc( allocator, alloc_size );
if ( allocation == nullptr ) { if ( allocation == nullptr ) {
String null_string = {nullptr}; StrBuilder null_string = {nullptr};
return null_string; return null_string;
} }
StringHeader* StrBuilderHeader*
header = rcast(StringHeader*, allocation); header = rcast(StrBuilderHeader*, allocation);
header->Allocator = allocator; header->Allocator = allocator;
header->Capacity = length; header->Capacity = length;
header->Length = length; header->Length = length;
String result = { rcast( char*, allocation) + header_size }; StrBuilder result = { rcast( char*, allocation) + header_size };
if ( length && str ) if ( length && str )
mem_copy( result, str, length ); mem_copy( result, str, length );
@ -35,27 +35,27 @@ String string_make_length( AllocatorInfo allocator, char const* str, ssize lengt
return result; return result;
} }
String string_make_reserve( AllocatorInfo allocator, ssize capacity ) StrBuilder strbuilder_make_reserve( AllocatorInfo allocator, ssize capacity )
{ {
ssize const header_size = sizeof( StringHeader ); ssize const header_size = sizeof( StrBuilderHeader );
s32 alloc_size = header_size + capacity + 1; s32 alloc_size = header_size + capacity + 1;
void* allocation = alloc( allocator, alloc_size ); void* allocation = alloc( allocator, alloc_size );
if ( allocation == nullptr ) { if ( allocation == nullptr ) {
String null_string = {nullptr}; StrBuilder null_string = {nullptr};
return null_string; return null_string;
} }
mem_set( allocation, 0, alloc_size ); mem_set( allocation, 0, alloc_size );
StringHeader* StrBuilderHeader*
header = rcast(StringHeader*, allocation); header = rcast(StrBuilderHeader*, allocation);
header->Allocator = allocator; header->Allocator = allocator;
header->Capacity = capacity; header->Capacity = capacity;
header->Length = 0; header->Length = 0;
String result = { rcast(char*, allocation) + header_size }; StrBuilder result = { rcast(char*, allocation) + header_size };
return result; return result;
} }
#pragma endregion String #pragma endregion StrBuilder

View File

@ -5,61 +5,61 @@
#pragma region Strings #pragma region Strings
struct StrC; struct Str;
StrC to_strc_from_c_str (char const* bad_string); Str to_str_from_c_str (char const* bad_string);
bool strc_are_equal (StrC lhs, StrC rhs); bool str_are_equal (Str lhs, Str rhs);
char const* strc_back (StrC str); char const* str_back (Str str);
bool strc_contains (StrC str, StrC substring); bool str_contains (Str str, Str substring);
StrC strc_duplicate (StrC str, AllocatorInfo allocator); Str str_duplicate (Str str, AllocatorInfo allocator);
b32 strc_starts_with (StrC str, StrC substring); b32 str_starts_with (Str str, Str substring);
StrC strc_visualize_whitespace(StrC str, AllocatorInfo allocator); Str str_visualize_whitespace(Str str, AllocatorInfo allocator);
// Constant string with length. // Constant string with length.
struct StrC struct Str
{ {
ssize Len;
char const* Ptr; char const* Ptr;
ssize Len;
#if GEN_COMPILER_CPP #if GEN_COMPILER_CPP
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_C_LIKE_CPP #if ! GEN_C_LIKE_CPP
forceinline bool is_equal (StrC rhs) const { return strc_are_equal(* this, rhs); } forceinline bool is_equal (Str rhs) const { return str_are_equal(* this, rhs); }
forceinline char const* back () const { return strc_back(* this); } forceinline char const* back () const { return str_back(* this); }
forceinline bool contains (StrC substring) const { return strc_contains(* this, substring); } forceinline bool contains (Str substring) const { return str_contains(* this, substring); }
forceinline StrC duplicate (AllocatorInfo allocator) const { return strc_duplicate(* this, allocator); } forceinline Str duplicate (AllocatorInfo allocator) const { return str_duplicate(* this, allocator); }
forceinline b32 starts_with (StrC substring) const { return strc_starts_with(* this, substring); } forceinline b32 starts_with (Str substring) const { return str_starts_with(* this, substring); }
forceinline StrC visualize_whitespace(AllocatorInfo allocator) const { return strc_visualize_whitespace(* this, allocator); } forceinline Str visualize_whitespace(AllocatorInfo allocator) const { return str_visualize_whitespace(* this, allocator); }
#endif #endif
#endif #endif
}; };
#define cast_to_strc( str ) * rcast( StrC*, (str) - sizeof(ssize) ) #define cast_to_str( str ) * rcast( Str*, (str) - sizeof(ssize) )
#ifndef txt #ifndef txt
# if GEN_COMPILER_CPP # if GEN_COMPILER_CPP
# define txt( text ) StrC { sizeof( text ) - 1, ( text ) } # define txt( text ) Str { ( text ), sizeof( text ) - 1 }
# else # else
# define txt( text ) (StrC){ sizeof( text ) - 1, ( text ) } # define txt( text ) (Str){ ( text ), sizeof( text ) - 1 }
# endif # endif
#endif #endif
GEN_API_C_BEGIN GEN_API_C_BEGIN
forceinline char const* strc_begin(StrC str) { return str.Ptr; } forceinline char const* str_begin(Str str) { return str.Ptr; }
forceinline char const* strc_end (StrC str) { return str.Ptr + str.Len; } forceinline char const* str_end (Str str) { return str.Ptr + str.Len; }
forceinline char const* strc_next (StrC str, char const* iter) { return iter + 1; } forceinline char const* str_next (Str str, char const* iter) { return iter + 1; }
GEN_API_C_END GEN_API_C_END
#if GEN_COMPILER_CPP #if GEN_COMPILER_CPP
forceinline char const* begin(StrC str) { return str.Ptr; } forceinline char const* begin(Str str) { return str.Ptr; }
forceinline char const* end (StrC str) { return str.Ptr + str.Len; } forceinline char const* end (Str str) { return str.Ptr + str.Len; }
forceinline char const* next (StrC str, char const* iter) { return iter + 1; } forceinline char const* next (Str str, char const* iter) { return iter + 1; }
#endif #endif
inline inline
bool strc_are_equal(StrC lhs, StrC rhs) bool str_are_equal(Str lhs, Str rhs)
{ {
if (lhs.Len != rhs.Len) if (lhs.Len != rhs.Len)
return false; return false;
@ -72,12 +72,12 @@ bool strc_are_equal(StrC lhs, StrC rhs)
} }
inline inline
char const* strc_back(StrC str) { char const* str_back(Str str) {
return & str.Ptr[str.Len - 1]; return & str.Ptr[str.Len - 1];
} }
inline inline
bool strc_contains(StrC str, StrC substring) bool str_contains(Str str, Str substring)
{ {
if (substring.Len > str.Len) if (substring.Len > str.Len)
return false; return false;
@ -86,97 +86,97 @@ bool strc_contains(StrC str, StrC substring)
ssize sub_len = substring.Len; ssize sub_len = substring.Len;
for (ssize idx = 0; idx <= main_len - sub_len; ++idx) for (ssize idx = 0; idx <= main_len - sub_len; ++idx)
{ {
if (str_compare_len(str.Ptr + idx, substring.Ptr, sub_len) == 0) if (c_str_compare_len(str.Ptr + idx, substring.Ptr, sub_len) == 0)
return true; return true;
} }
return false; return false;
} }
inline inline
b32 strc_starts_with(StrC str, StrC substring) { b32 str_starts_with(Str str, Str substring) {
if (substring.Len > str.Len) if (substring.Len > str.Len)
return false; return false;
b32 result = str_compare_len(str.Ptr, substring.Ptr, substring.Len) == 0; b32 result = c_str_compare_len(str.Ptr, substring.Ptr, substring.Len) == 0;
return result; return result;
} }
inline inline
StrC to_strc_from_c_str( char const* bad_str ) { Str to_str_from_c_str( char const* bad_str ) {
StrC result = { str_len( bad_str ), bad_str }; Str result = { bad_str, c_str_len( bad_str ) };
return result; return result;
} }
// Dynamic String // Dynamic StrBuilder
// 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 StrBuilder
struct StringHeader; struct StrBuilderHeader;
#if GEN_COMPILER_C #if GEN_COMPILER_C
typedef char* String; typedef char* StrBuilder;
#else #else
struct String; struct StrBuilder;
#endif #endif
forceinline usize string_grow_formula(usize value); forceinline usize strbuilder_grow_formula(usize value);
String string_make_c_str (AllocatorInfo allocator, char const* str); StrBuilder strbuilder_make_c_str (AllocatorInfo allocator, char const* str);
String string_make_strc (AllocatorInfo allocator, StrC str); StrBuilder strbuilder_make_str (AllocatorInfo allocator, Str str);
String string_make_reserve (AllocatorInfo allocator, ssize capacity); StrBuilder strbuilder_make_reserve (AllocatorInfo allocator, ssize capacity);
String string_make_length (AllocatorInfo allocator, char const* str, ssize length); StrBuilder strbuilder_make_length (AllocatorInfo allocator, char const* str, ssize length);
String string_fmt (AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...); StrBuilder strbuilder_fmt (AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...);
String string_fmt_buf (AllocatorInfo allocator, char const* fmt, ...); StrBuilder strbuilder_fmt_buf (AllocatorInfo allocator, char const* fmt, ...);
String string_join (AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue); StrBuilder strbuilder_join (AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue);
bool string_are_equal (String const lhs, String const rhs); bool strbuilder_are_equal (StrBuilder const lhs, StrBuilder const rhs);
bool string_are_equal_strc (String const lhs, StrC rhs); bool strbuilder_are_equal_str (StrBuilder const lhs, Str rhs);
bool string_make_space_for (String* str, char const* to_append, ssize add_len); bool strbuilder_make_space_for (StrBuilder* str, char const* to_append, ssize add_len);
bool string_append_char (String* str, char c); bool strbuilder_append_char (StrBuilder* str, char c);
bool string_append_c_str (String* str, char const* str_to_append); bool strbuilder_append_c_str (StrBuilder* str, char const* c_str_to_append);
bool string_append_c_str_len (String* str, char const* str_to_append, ssize length); bool strbuilder_append_c_str_len (StrBuilder* str, char const* c_str_to_append, ssize length);
bool string_append_strc (String* str, StrC str_to_append); bool strbuilder_append_str (StrBuilder* str, Str c_str_to_append);
bool string_append_string (String* str, String const other); bool strbuilder_append_string (StrBuilder* str, StrBuilder const other);
bool string_append_fmt (String* str, char const* fmt, ...); bool strbuilder_append_fmt (StrBuilder* str, char const* fmt, ...);
ssize string_avail_space (String const str); ssize strbuilder_avail_space (StrBuilder const str);
char* string_back (String str); char* strbuilder_back (StrBuilder str);
bool string_contains_strc (String const str, StrC substring); bool strbuilder_contains_str (StrBuilder const str, Str substring);
bool string_contains_string (String const str, String const substring); bool strbuilder_contains_string (StrBuilder const str, StrBuilder const substring);
ssize string_capacity (String const str); ssize strbuilder_capacity (StrBuilder const str);
void string_clear (String str); void strbuilder_clear (StrBuilder str);
String string_duplicate (String const str, AllocatorInfo allocator); StrBuilder strbuilder_duplicate (StrBuilder const str, AllocatorInfo allocator);
void string_free (String* str); void strbuilder_free (StrBuilder* str);
StringHeader* string_get_header (String str); StrBuilderHeader* strbuilder_get_header (StrBuilder str);
ssize string_length (String const str); ssize strbuilder_length (StrBuilder const str);
b32 string_starts_with_strc (String const str, StrC substring); b32 strbuilder_starts_with_str (StrBuilder const str, Str substring);
b32 string_starts_with_string (String const str, String substring); b32 strbuilder_starts_with_string (StrBuilder const str, StrBuilder substring);
void string_skip_line (String str); void strbuilder_skip_line (StrBuilder str);
void string_strip_space (String str); void strbuilder_strip_space (StrBuilder str);
StrC string_to_strc (String str); Str strbuilder_to_str (StrBuilder str);
void string_trim (String str, char const* cut_set); void strbuilder_trim (StrBuilder str, char const* cut_set);
void string_trim_space (String str); void strbuilder_trim_space (StrBuilder str);
String string_visualize_whitespace(String const str); StrBuilder strbuilder_visualize_whitespace(StrBuilder const str);
struct StringHeader { struct StrBuilderHeader {
AllocatorInfo Allocator; AllocatorInfo Allocator;
ssize Capacity; ssize Capacity;
ssize Length; ssize Length;
}; };
#if GEN_COMPILER_CPP #if GEN_COMPILER_CPP
struct String struct StrBuilder
{ {
char* Data; char* Data;
forceinline operator char*() { return Data; } forceinline operator char*() { return Data; }
forceinline operator char const*() const { return Data; } forceinline operator char const*() const { return Data; }
forceinline operator StrC() const { return { string_length(* this), Data }; } forceinline operator Str() const { return { Data, strbuilder_length(* this) }; }
String const& operator=(String const& other) const { StrBuilder const& operator=(StrBuilder const& other) const {
if (this == &other) if (this == &other)
return *this; return *this;
String* this_ = ccast(String*, this); StrBuilder* this_ = ccast(StrBuilder*, this);
this_->Data = other.Data; this_->Data = other.Data;
return *this; return *this;
@ -185,69 +185,69 @@ struct String
forceinline char& operator[](ssize index) { return Data[index]; } forceinline char& operator[](ssize index) { return Data[index]; }
forceinline char const& operator[](ssize index) const { return Data[index]; } forceinline char const& operator[](ssize index) const { return Data[index]; }
forceinline bool operator==(std::nullptr_t) const { return Data == nullptr; } forceinline bool operator==(std::nullptr_t) const { return Data == nullptr; }
forceinline bool operator!=(std::nullptr_t) const { return Data != nullptr; } forceinline bool operator!=(std::nullptr_t) const { return Data != nullptr; }
friend forceinline bool operator==(std::nullptr_t, const String str) { return str.Data == nullptr; } friend forceinline bool operator==(std::nullptr_t, const StrBuilder 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 StrBuilder str) { return str.Data != nullptr; }
#if ! GEN_C_LIKE_CPP #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 + strbuilder_length(* this); }
#pragma region Member Mapping #pragma region Member Mapping
forceinline static String make(AllocatorInfo allocator, char const* str) { return string_make_c_str(allocator, str); } forceinline static StrBuilder make(AllocatorInfo allocator, char const* str) { return strbuilder_make_c_str(allocator, str); }
forceinline static String make(AllocatorInfo allocator, StrC str) { return string_make_strc(allocator, str); } forceinline static StrBuilder make(AllocatorInfo allocator, Str str) { return strbuilder_make_str(allocator, str); }
forceinline static String make_reserve(AllocatorInfo allocator, ssize cap) { return string_make_reserve(allocator, cap); } forceinline static StrBuilder make_reserve(AllocatorInfo allocator, ssize cap) { return strbuilder_make_reserve(allocator, cap); }
forceinline static String make_length(AllocatorInfo a, char const* s, ssize l) { return string_make_length(a, s, l); } forceinline static StrBuilder make_length(AllocatorInfo a, char const* s, ssize l) { return strbuilder_make_length(a, s, l); }
forceinline static String join(AllocatorInfo a, char const** p, ssize n, char const* g) { return string_join(a, p, n, g); } forceinline static StrBuilder join(AllocatorInfo a, char const** p, ssize n, char const* g) { return strbuilder_join(a, p, n, g); }
forceinline static usize grow_formula(usize value) { return string_grow_formula(value); } forceinline static usize grow_formula(usize value) { return strbuilder_grow_formula(value); }
static static
String fmt(AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...) { StrBuilder fmt(AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...) {
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
ssize res = str_fmt_va(buf, buf_size, fmt, va) - 1; ssize res = c_str_fmt_va(buf, buf_size, fmt, va) - 1;
va_end(va); va_end(va);
return string_make_length(allocator, buf, res); return strbuilder_make_length(allocator, buf, res);
} }
static static
String fmt_buf(AllocatorInfo allocator, char const* fmt, ...) { StrBuilder fmt_buf(AllocatorInfo allocator, char const* fmt, ...) {
local_persist thread_local local_persist thread_local
char buf[GEN_PRINTF_MAXLEN] = { 0 }; char buf[GEN_PRINTF_MAXLEN] = { 0 };
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
ssize res = str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va) - 1; ssize res = c_str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va) - 1;
va_end(va); va_end(va);
return string_make_length(allocator, buf, res); return strbuilder_make_length(allocator, buf, res);
} }
forceinline bool make_space_for(char const* str, ssize add_len) { return string_make_space_for(this, str, add_len); } forceinline bool make_space_for(char const* str, ssize add_len) { return strbuilder_make_space_for(this, str, add_len); }
forceinline bool append(char c) { return string_append_char(this, c); } forceinline bool append(char c) { return strbuilder_append_char(this, c); }
forceinline bool append(char const* str) { return string_append_c_str(this, str); } forceinline bool append(char const* str) { return strbuilder_append_c_str(this, str); }
forceinline bool append(char const* str, ssize length) { return string_append_c_str_len(this, str, length); } forceinline bool append(char const* str, ssize length) { return strbuilder_append_c_str_len(this, str, length); }
forceinline bool append(StrC str) { return string_append_strc(this, str); } forceinline bool append(Str str) { return strbuilder_append_str(this, str); }
forceinline bool append(const String other) { return string_append_string(this, other); } forceinline bool append(const StrBuilder other) { return strbuilder_append_string(this, other); }
forceinline ssize avail_space() const { return string_avail_space(* this); } forceinline ssize avail_space() const { return strbuilder_avail_space(* this); }
forceinline char* back() { return string_back(* this); } forceinline char* back() { return strbuilder_back(* this); }
forceinline bool contains(StrC substring) const { return string_contains_strc(* this, substring); } forceinline bool contains(Str substring) const { return strbuilder_contains_str(* this, substring); }
forceinline bool contains(String const& substring) const { return string_contains_string(* this, substring); } forceinline bool contains(StrBuilder const& substring) const { return strbuilder_contains_string(* this, substring); }
forceinline ssize capacity() const { return string_capacity(* this); } forceinline ssize capacity() const { return strbuilder_capacity(* this); }
forceinline void clear() { string_clear(* this); } forceinline void clear() { strbuilder_clear(* this); }
forceinline String duplicate(AllocatorInfo allocator) const { return string_duplicate(* this, allocator); } forceinline StrBuilder duplicate(AllocatorInfo allocator) const { return strbuilder_duplicate(* this, allocator); }
forceinline void free() { string_free(this); } forceinline void free() { strbuilder_free(this); }
forceinline bool is_equal(String const& other) const { return string_are_equal(* this, other); } forceinline bool is_equal(StrBuilder const& other) const { return strbuilder_are_equal(* this, other); }
forceinline bool is_equal(StrC other) const { return string_are_equal_strc(* this, other); } forceinline bool is_equal(Str other) const { return strbuilder_are_equal_str(* this, other); }
forceinline ssize length() const { return string_length(* this); } forceinline ssize length() const { return strbuilder_length(* this); }
forceinline b32 starts_with(StrC substring) const { return string_starts_with_strc(* this, substring); } forceinline b32 starts_with(Str substring) const { return strbuilder_starts_with_str(* this, substring); }
forceinline b32 starts_with(String substring) const { return string_starts_with_string(* this, substring); } forceinline b32 starts_with(StrBuilder substring) const { return strbuilder_starts_with_string(* this, substring); }
forceinline void skip_line() { string_skip_line(* this); } forceinline void skip_line() { strbuilder_skip_line(* this); }
forceinline void strip_space() { string_strip_space(* this); } forceinline void strip_space() { strbuilder_strip_space(* this); }
forceinline StrC to_strc() { return { string_length(*this), Data}; } forceinline Str to_str() { return { Data, strbuilder_length(*this) }; }
forceinline void trim(char const* cut_set) { string_trim(* this, cut_set); } forceinline void trim(char const* cut_set) { strbuilder_trim(* this, cut_set); }
forceinline void trim_space() { string_trim_space(* this); } forceinline void trim_space() { strbuilder_trim_space(* this); }
forceinline String visualize_whitespace() const { return string_visualize_whitespace(* this); } forceinline StrBuilder visualize_whitespace() const { return strbuilder_visualize_whitespace(* this); }
forceinline StringHeader& get_header() { return * string_get_header(* this); } forceinline StrBuilderHeader& get_header() { return * strbuilder_get_header(* this); }
bool append_fmt(char const* fmt, ...) { bool append_fmt(char const* fmt, ...) {
ssize res; ssize res;
@ -255,163 +255,163 @@ struct String
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
res = str_fmt_va(buf, count_of(buf) - 1, fmt, va) - 1; res = c_str_fmt_va(buf, count_of(buf) - 1, fmt, va) - 1;
va_end(va); va_end(va);
return string_append_c_str_len(this, buf, res); return strbuilder_append_c_str_len(this, buf, res);
} }
#pragma endregion Member Mapping #pragma endregion Member Mapping
#endif #endif
}; };
#endif #endif
forceinline char* string_begin(String str) { return ((char*) str); } forceinline char* strbuilder_begin(StrBuilder str) { return ((char*) str); }
forceinline char* string_end (String str) { return ((char*) str + string_length(str)); } forceinline char* strbuilder_end (StrBuilder str) { return ((char*) str + strbuilder_length(str)); }
forceinline char* string_next (String str, char const* iter) { return ((char*) iter + 1); } forceinline char* strbuilder_next (StrBuilder str, char const* iter) { return ((char*) iter + 1); }
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP #if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
forceinline char* begin(String str) { return ((char*) str); } forceinline char* begin(StrBuilder str) { return ((char*) str); }
forceinline char* end (String str) { return ((char*) str + string_length(str)); } forceinline char* end (StrBuilder str) { return ((char*) str + strbuilder_length(str)); }
forceinline char* next (String str, char* iter) { return ((char*) iter + 1); } forceinline char* next (StrBuilder str, char* iter) { return ((char*) iter + 1); }
#endif #endif
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP #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(StrBuilder& str, char const* to_append, ssize add_len);
forceinline bool append(String& str, char c); forceinline bool append(StrBuilder& str, char c);
forceinline bool append(String& str, char const* str_to_append); forceinline bool append(StrBuilder& str, char const* c_str_to_append);
forceinline bool append(String& str, char const* str_to_append, ssize length); forceinline bool append(StrBuilder& str, char const* c_str_to_append, ssize length);
forceinline bool append(String& str, StrC str_to_append); forceinline bool append(StrBuilder& str, Str c_str_to_append);
forceinline bool append(String& str, const String other); forceinline bool append(StrBuilder& str, const StrBuilder other);
forceinline bool append_fmt(String& str, char const* fmt, ...); forceinline bool append_fmt(StrBuilder& str, char const* fmt, ...);
forceinline char& back(String& str); forceinline char& back(StrBuilder& str);
forceinline void clear(String& str); forceinline void clear(StrBuilder& str);
forceinline void free(String& str); forceinline void free(StrBuilder& str);
#endif #endif
forceinline forceinline
usize string_grow_formula(usize value) { usize strbuilder_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.
return 4 * value + 8; return 4 * value + 8;
} }
forceinline forceinline
String string_make_c_str(AllocatorInfo allocator, char const* str) { StrBuilder strbuilder_make_c_str(AllocatorInfo allocator, char const* str) {
ssize length = str ? str_len(str) : 0; ssize length = str ? c_str_len(str) : 0;
return string_make_length(allocator, str, length); return strbuilder_make_length(allocator, str, length);
} }
forceinline forceinline
String string_make_strc(AllocatorInfo allocator, StrC str) { StrBuilder strbuilder_make_str(AllocatorInfo allocator, Str str) {
return string_make_length(allocator, str.Ptr, str.Len); return strbuilder_make_length(allocator, str.Ptr, str.Len);
} }
inline inline
String string_fmt(AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...) { StrBuilder strbuilder_fmt(AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...) {
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
ssize res = str_fmt_va(buf, buf_size, fmt, va) - 1; ssize res = c_str_fmt_va(buf, buf_size, fmt, va) - 1;
va_end(va); va_end(va);
return string_make_length(allocator, buf, res); return strbuilder_make_length(allocator, buf, res);
} }
inline inline
String string_fmt_buf(AllocatorInfo allocator, char const* fmt, ...) StrBuilder strbuilder_fmt_buf(AllocatorInfo allocator, char const* fmt, ...)
{ {
local_persist thread_local local_persist thread_local
PrintF_Buffer buf = struct_init(PrintF_Buffer, {0}); PrintF_Buffer buf = struct_init(PrintF_Buffer, {0});
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
ssize res = str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va) -1; ssize res = c_str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va) -1;
va_end(va); va_end(va);
return string_make_length(allocator, buf, res); return strbuilder_make_length(allocator, buf, res);
} }
inline inline
String string_join(AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue) StrBuilder strbuilder_join(AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue)
{ {
String result = string_make_c_str(allocator, ""); StrBuilder result = strbuilder_make_c_str(allocator, "");
for (ssize idx = 0; idx < num_parts; ++idx) for (ssize idx = 0; idx < num_parts; ++idx)
{ {
string_append_c_str(& result, parts[idx]); strbuilder_append_c_str(& result, parts[idx]);
if (idx < num_parts - 1) if (idx < num_parts - 1)
string_append_c_str(& result, glue); strbuilder_append_c_str(& result, glue);
} }
return result; return result;
} }
forceinline forceinline
bool string_append_char(String* str, char c) { bool strbuilder_append_char(StrBuilder* str, char c) {
GEN_ASSERT(str != nullptr); GEN_ASSERT(str != nullptr);
return string_append_c_str_len( str, (char const*)& c, (ssize)1); return strbuilder_append_c_str_len( str, (char const*)& c, (ssize)1);
} }
forceinline forceinline
bool string_append_c_str(String* str, char const* str_to_append) { bool strbuilder_append_c_str(StrBuilder* str, char const* c_str_to_append) {
GEN_ASSERT(str != nullptr); GEN_ASSERT(str != nullptr);
return string_append_c_str_len(str, str_to_append, str_len(str_to_append)); return strbuilder_append_c_str_len(str, c_str_to_append, c_str_len(c_str_to_append));
} }
inline inline
bool string_append_c_str_len(String* str, char const* str_to_append, ssize append_length) bool strbuilder_append_c_str_len(StrBuilder* str, char const* c_str_to_append, ssize append_length)
{ {
GEN_ASSERT(str != nullptr); GEN_ASSERT(str != nullptr);
if ( rcast(sptr, str_to_append) > 0) if ( rcast(sptr, c_str_to_append) > 0)
{ {
ssize curr_len = string_length(* str); ssize curr_len = strbuilder_length(* str);
if ( ! string_make_space_for(str, str_to_append, append_length)) if ( ! strbuilder_make_space_for(str, c_str_to_append, append_length))
return false; return false;
StringHeader* header = string_get_header(* str); StrBuilderHeader* header = strbuilder_get_header(* str);
char* Data = * str; char* Data = * str;
mem_copy( Data + curr_len, str_to_append, append_length); mem_copy( Data + curr_len, c_str_to_append, append_length);
Data[curr_len + append_length] = '\0'; Data[curr_len + append_length] = '\0';
header->Length = curr_len + append_length; header->Length = curr_len + append_length;
} }
return str_to_append != nullptr; return c_str_to_append != nullptr;
} }
forceinline forceinline
bool string_append_strc(String* str, StrC str_to_append) { bool strbuilder_append_str(StrBuilder* str, Str c_str_to_append) {
GEN_ASSERT(str != nullptr); GEN_ASSERT(str != nullptr);
return string_append_c_str_len(str, str_to_append.Ptr, str_to_append.Len); return strbuilder_append_c_str_len(str, c_str_to_append.Ptr, c_str_to_append.Len);
} }
forceinline forceinline
bool string_append_string(String* str, String const other) { bool strbuilder_append_string(StrBuilder* str, StrBuilder const other) {
GEN_ASSERT(str != nullptr); GEN_ASSERT(str != nullptr);
return string_append_c_str_len(str, (char const*)other, string_length(other)); return strbuilder_append_c_str_len(str, (char const*)other, strbuilder_length(other));
} }
bool string_append_fmt(String* str, char const* fmt, ...) { bool strbuilder_append_fmt(StrBuilder* str, char const* fmt, ...) {
GEN_ASSERT(str != nullptr); GEN_ASSERT(str != nullptr);
ssize res; ssize res;
char buf[GEN_PRINTF_MAXLEN] = { 0 }; char buf[GEN_PRINTF_MAXLEN] = { 0 };
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
res = str_fmt_va(buf, count_of(buf) - 1, fmt, va) - 1; res = c_str_fmt_va(buf, count_of(buf) - 1, fmt, va) - 1;
va_end(va); va_end(va);
return string_append_c_str_len(str, (char const*)buf, res); return strbuilder_append_c_str_len(str, (char const*)buf, res);
} }
inline inline
bool string_are_equal_string(String const lhs, String const rhs) bool strbuilder_are_equal_string(StrBuilder const lhs, StrBuilder const rhs)
{ {
if (string_length(lhs) != string_length(rhs)) if (strbuilder_length(lhs) != strbuilder_length(rhs))
return false; return false;
for (ssize idx = 0; idx < string_length(lhs); ++idx) for (ssize idx = 0; idx < strbuilder_length(lhs); ++idx)
if (lhs[idx] != rhs[idx]) if (lhs[idx] != rhs[idx])
return false; return false;
@ -419,12 +419,12 @@ bool string_are_equal_string(String const lhs, String const rhs)
} }
inline inline
bool string_are_equal_strc(String const lhs, StrC rhs) bool strbuilder_are_equal_str(StrBuilder const lhs, Str rhs)
{ {
if (string_length(lhs) != (rhs.Len)) if (strbuilder_length(lhs) != (rhs.Len))
return false; return false;
for (ssize idx = 0; idx < string_length(lhs); ++idx) for (ssize idx = 0; idx < strbuilder_length(lhs); ++idx)
if (lhs[idx] != rhs.Ptr[idx]) if (lhs[idx] != rhs.Ptr[idx])
return false; return false;
@ -432,20 +432,20 @@ bool string_are_equal_strc(String const lhs, StrC rhs)
} }
forceinline forceinline
ssize string_avail_space(String const str) { ssize strbuilder_avail_space(StrBuilder const str) {
StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); StrBuilderHeader const* header = rcast(StrBuilderHeader const*, scast(char const*, str) - sizeof(StrBuilderHeader));
return header->Capacity - header->Length; return header->Capacity - header->Length;
} }
forceinline forceinline
char* string_back(String str) { char* strbuilder_back(StrBuilder str) {
return & (str)[string_length(str) - 1]; return & (str)[strbuilder_length(str) - 1];
} }
inline inline
bool string_contains_StrC(String const str, StrC substring) bool strbuilder_contains_StrC(StrBuilder const str, Str substring)
{ {
StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); StrBuilderHeader const* header = rcast(StrBuilderHeader const*, scast(char const*, str) - sizeof(StrBuilderHeader));
if (substring.Len > header->Length) if (substring.Len > header->Length)
return false; return false;
@ -455,7 +455,7 @@ bool string_contains_StrC(String const str, StrC substring)
for (ssize idx = 0; idx <= main_len - sub_len; ++idx) for (ssize idx = 0; idx <= main_len - sub_len; ++idx)
{ {
if (str_compare_len(str + idx, substring.Ptr, sub_len) == 0) if (c_str_compare_len(str + idx, substring.Ptr, sub_len) == 0)
return true; return true;
} }
@ -463,19 +463,19 @@ bool string_contains_StrC(String const str, StrC substring)
} }
inline inline
bool string_contains_string(String const str, String const substring) bool strbuilder_contains_string(StrBuilder const str, StrBuilder const substring)
{ {
StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); StrBuilderHeader const* header = rcast(StrBuilderHeader const*, scast(char const*, str) - sizeof(StrBuilderHeader));
if (string_length(substring) > header->Length) if (strbuilder_length(substring) > header->Length)
return false; return false;
ssize main_len = header->Length; ssize main_len = header->Length;
ssize sub_len = string_length(substring); ssize sub_len = strbuilder_length(substring);
for (ssize idx = 0; idx <= main_len - sub_len; ++idx) for (ssize idx = 0; idx <= main_len - sub_len; ++idx)
{ {
if (str_compare_len(str + idx, substring, sub_len) == 0) if (c_str_compare_len(str + idx, substring, sub_len) == 0)
return true; return true;
} }
@ -483,47 +483,47 @@ bool string_contains_string(String const str, String const substring)
} }
forceinline forceinline
ssize string_capacity(String const str) { ssize strbuilder_capacity(StrBuilder const str) {
StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); StrBuilderHeader const* header = rcast(StrBuilderHeader const*, scast(char const*, str) - sizeof(StrBuilderHeader));
return header->Capacity; return header->Capacity;
} }
forceinline forceinline
void string_clear(String str) { void strbuilder_clear(StrBuilder str) {
string_get_header(str)->Length = 0; strbuilder_get_header(str)->Length = 0;
} }
forceinline forceinline
String string_duplicate(String const str, AllocatorInfo allocator) { StrBuilder strbuilder_duplicate(StrBuilder const str, AllocatorInfo allocator) {
return string_make_length(allocator, str, string_length(str)); return strbuilder_make_length(allocator, str, strbuilder_length(str));
} }
forceinline forceinline
void string_free(String* str) { void strbuilder_free(StrBuilder* str) {
GEN_ASSERT(str != nullptr); GEN_ASSERT(str != nullptr);
if (! (* str)) if (! (* str))
return; return;
StringHeader* header = string_get_header(* str); StrBuilderHeader* header = strbuilder_get_header(* str);
allocator_free(header->Allocator, header); allocator_free(header->Allocator, header);
} }
forceinline forceinline
StringHeader* string_get_header(String str) { StrBuilderHeader* strbuilder_get_header(StrBuilder str) {
return (StringHeader*)(scast(char*, str) - sizeof(StringHeader)); return (StrBuilderHeader*)(scast(char*, str) - sizeof(StrBuilderHeader));
} }
forceinline forceinline
ssize string_length(String const str) ssize strbuilder_length(StrBuilder const str)
{ {
StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); StrBuilderHeader const* header = rcast(StrBuilderHeader const*, scast(char const*, str) - sizeof(StrBuilderHeader));
return header->Length; return header->Length;
} }
inline inline
bool string_make_space_for(String* str, char const* to_append, ssize add_len) bool strbuilder_make_space_for(StrBuilder* str, char const* to_append, ssize add_len)
{ {
ssize available = string_avail_space(* str); ssize available = strbuilder_avail_space(* str);
if (available >= add_len) { if (available >= add_len) {
return true; return true;
@ -534,20 +534,20 @@ bool string_make_space_for(String* str, char const* to_append, ssize add_len)
void* ptr; void* ptr;
void* new_ptr; void* new_ptr;
AllocatorInfo allocator = string_get_header(* str)->Allocator; AllocatorInfo allocator = strbuilder_get_header(* str)->Allocator;
StringHeader* header = nullptr; StrBuilderHeader* header = nullptr;
new_len = string_grow_formula(string_length(* str) + add_len); new_len = strbuilder_grow_formula(strbuilder_length(* str) + add_len);
ptr = string_get_header(* str); ptr = strbuilder_get_header(* str);
old_size = size_of(StringHeader) + string_length(* str) + 1; old_size = size_of(StrBuilderHeader) + strbuilder_length(* str) + 1;
new_size = size_of(StringHeader) + new_len + 1; new_size = size_of(StrBuilderHeader) + new_len + 1;
new_ptr = resize(allocator, ptr, old_size, new_size); new_ptr = resize(allocator, ptr, old_size, new_size);
if (new_ptr == nullptr) if (new_ptr == nullptr)
return false; return false;
header = rcast(StringHeader*, new_ptr); header = rcast(StrBuilderHeader*, new_ptr);
header->Allocator = allocator; header->Allocator = allocator;
header->Capacity = new_len; header->Capacity = new_len;
@ -559,25 +559,25 @@ bool string_make_space_for(String* str, char const* to_append, ssize add_len)
} }
forceinline forceinline
b32 string_starts_with_strc(String const str, StrC substring) { b32 strbuilder_starts_with_str(StrBuilder const str, Str substring) {
if (substring.Len > string_length(str)) if (substring.Len > strbuilder_length(str))
return false; return false;
b32 result = str_compare_len(str, substring.Ptr, substring.Len) == 0; b32 result = c_str_compare_len(str, substring.Ptr, substring.Len) == 0;
return result; return result;
} }
forceinline forceinline
b32 string_starts_with_string(String const str, String substring) { b32 strbuilder_starts_with_string(StrBuilder const str, StrBuilder substring) {
if (string_length(substring) > string_length(str)) if (strbuilder_length(substring) > strbuilder_length(str))
return false; return false;
b32 result = str_compare_len(str, substring, string_length(substring) - 1) == 0; b32 result = c_str_compare_len(str, substring, strbuilder_length(substring) - 1) == 0;
return result; return result;
} }
inline inline
void string_skip_line(String str) void strbuilder_skip_line(StrBuilder str)
{ {
#define current (*scanner) #define current (*scanner)
char* scanner = str; char* scanner = str;
@ -593,13 +593,13 @@ void string_skip_line(String str)
mem_move((char*)str, scanner, new_length); mem_move((char*)str, scanner, new_length);
StringHeader* header = string_get_header(str); StrBuilderHeader* header = strbuilder_get_header(str);
header->Length = new_length; header->Length = new_length;
#undef current #undef current
} }
inline inline
void strip_space(String str) void strip_space(StrBuilder str)
{ {
char* write_pos = str; char* write_pos = str;
char* read_pos = str; char* read_pos = str;
@ -616,22 +616,22 @@ void strip_space(String str)
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; strbuilder_get_header(str)->Length = write_pos - str;
} }
forceinline forceinline
StrC string_to_strc(String str) { Str strbuilder_to_str(StrBuilder str) {
StrC result = { string_length(str), (char const*)str }; Str result = { (char const*)str, strbuilder_length(str) };
return result; return result;
} }
inline inline
void string_trim(String str, char const* cut_set) void strbuilder_trim(StrBuilder str, char const* cut_set)
{ {
ssize len = 0; ssize len = 0;
char* start_pos = str; char* start_pos = str;
char* end_pos = scast(char*, str) + string_length(str) - 1; char* end_pos = scast(char*, str) + strbuilder_length(str) - 1;
while (start_pos <= end_pos && char_first_occurence(cut_set, *start_pos)) while (start_pos <= end_pos && char_first_occurence(cut_set, *start_pos))
start_pos++; start_pos++;
@ -646,98 +646,98 @@ void string_trim(String str, char const* cut_set)
str[len] = '\0'; str[len] = '\0';
string_get_header(str)->Length = len; strbuilder_get_header(str)->Length = len;
} }
forceinline forceinline
void string_trim_space(String str) { void strbuilder_trim_space(StrBuilder str) {
string_trim(str, " \t\r\n\v\f"); strbuilder_trim(str, " \t\r\n\v\f");
} }
inline inline
String string_visualize_whitespace(String const str) StrBuilder strbuilder_visualize_whitespace(StrBuilder const str)
{ {
StringHeader* header = (StringHeader*)(scast(char const*, str) - sizeof(StringHeader)); StrBuilderHeader* header = (StrBuilderHeader*)(scast(char const*, str) - sizeof(StrBuilderHeader));
String result = string_make_reserve(header->Allocator, string_length(str) * 2); // Assume worst case for space requirements. StrBuilder result = strbuilder_make_reserve(header->Allocator, strbuilder_length(str) * 2); // Assume worst case for space requirements.
for (char const* c = string_begin(str); c != string_end(str); c = string_next(str, c)) for (char const* c = strbuilder_begin(str); c != strbuilder_end(str); c = strbuilder_next(str, c))
switch ( * c ) switch ( * c )
{ {
case ' ': case ' ':
string_append_strc(& result, txt("·")); strbuilder_append_str(& result, txt("·"));
break; break;
case '\t': case '\t':
string_append_strc(& result, txt("")); strbuilder_append_str(& result, txt(""));
break; break;
case '\n': case '\n':
string_append_strc(& result, txt("")); strbuilder_append_str(& result, txt(""));
break; break;
case '\r': case '\r':
string_append_strc(& result, txt("")); strbuilder_append_str(& result, txt(""));
break; break;
case '\v': case '\v':
string_append_strc(& result, txt("")); strbuilder_append_str(& result, txt(""));
break; break;
case '\f': case '\f':
string_append_strc(& result, txt("")); strbuilder_append_str(& result, txt(""));
break; break;
default: default:
string_append_char(& result, * c); strbuilder_append_char(& result, * c);
break; break;
} }
return result; return result;
} }
#pragma endregion String #pragma endregion StrBuilder
#if GEN_COMPILER_CPP #if GEN_COMPILER_CPP
struct String_POD { struct StrBuilder_POD {
char* Data; char* Data;
}; };
static_assert( sizeof( String_POD ) == sizeof( String ), "String is not a POD" ); static_assert( sizeof( StrBuilder_POD ) == sizeof( StrBuilder ), "StrBuilder is not a POD" );
#endif #endif
forceinline forceinline
StrC strc_duplicate(StrC str, AllocatorInfo allocator) { Str str_duplicate(Str str, AllocatorInfo allocator) {
StrC result = string_to_strc( string_make_length(allocator, str.Ptr, str.Len)); Str result = strbuilder_to_str( strbuilder_make_length(allocator, str.Ptr, str.Len));
return result; return result;
} }
inline inline
StrC strc_visualize_whitespace(StrC str, AllocatorInfo allocator) Str str_visualize_whitespace(Str str, AllocatorInfo allocator)
{ {
String result = string_make_reserve(allocator, str.Len * 2); // Assume worst case for space requirements. StrBuilder result = strbuilder_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 = str_begin(str); c != str_end(str); c = str_next(str, c))
switch ( * c ) switch ( * c )
{ {
case ' ': case ' ':
string_append_strc(& result, txt("·")); strbuilder_append_str(& result, txt("·"));
break; break;
case '\t': case '\t':
string_append_strc(& result, txt("")); strbuilder_append_str(& result, txt(""));
break; break;
case '\n': case '\n':
string_append_strc(& result, txt("")); strbuilder_append_str(& result, txt(""));
break; break;
case '\r': case '\r':
string_append_strc(& result, txt("")); strbuilder_append_str(& result, txt(""));
break; break;
case '\v': case '\v':
string_append_strc(& result, txt("")); strbuilder_append_str(& result, txt(""));
break; break;
case '\f': case '\f':
string_append_strc(& result, txt("")); strbuilder_append_str(& result, txt(""));
break; break;
default: default:
string_append_char(& result, * c); strbuilder_append_char(& result, * c);
break; break;
} }
return string_to_strc(result); return strbuilder_to_str(result);
} }
// Represents strings cached with the string table. // Represents strings cached with the string table.
// 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 Str StringCached;
// 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;

View File

@ -17,7 +17,7 @@
GEN_NS_BEGIN GEN_NS_BEGIN
#include "components/types.hpp" #include "components/types.hpp"
#include "components/gen/ecode.hpp" #include "components/gen/ecodetypes.hpp"
#include "components/gen/eoperator.hpp" #include "components/gen/eoperator.hpp"
#include "components/gen/especifier.hpp" #include "components/gen/especifier.hpp"

View File

@ -1,423 +0,0 @@
__VERSION 1
// This is a example template to be used with the refactor program
// Use it to refactor the naming convention of this library to your own.
// Can be used as an aid to help use use your project's implementation if it fullfills the dependencies of this project.
// Example: Most likely have a memory and string library already, just rename the functions and make sure the args are the same.
// Program: https://github.com/Ed94/refactor
// NOTE: Due to the current limitations of the program, not every symbol in the library can be renamed.
// This is due to the program not actually parsing C/C++.
// not : Ignore
// include : #includes
// word : Alphanumeric or underscore
// namespace : Prefix search and replace (c-namspaces).
// regex : Unavailable in __VERSION 1.
// Precedence (highest to lowest):
// word, namespace, regex
// TODO(ED): THIS IS VERY OUTDATED
// Gen Macro namespace
// namespace GEN_, new_namespace_
// ---------- Dependency Macros
// Platform
// word GEN_ARCH_64_BIT, new_name
// word GEN_ARCH_32_BIT, new_name
// word GEN_SYSTEM_ANDROID, new_name
// word GEN_SYSTEM_CYGWIN, new_name
// word GEN_SYSTEM_EMSCRIPTEN, new_name
// word GEN_SYSTEM_FREEBSD, new_name
// word GEN_SYSTEM_IOS, new_name
// word GEN_SYSTEM_LINUX, new_name
// word GEN_SYSTEM_MACOS, new_name
// word GEN_SYSTEM_OPENBSD, new_name
// word GEN_SYSTEM_OSX, new_name
// word GEN_SYSTEM_UNIX, new_name
// word GEN_SYSTEM_WINDOWS, new_name
// word GEN_COMPILER_CLANG, new_name
// word GEN_COMPILER_GCC, new_name
// word GEN_COMPILER_MINGW, new_name
// word GEN_COMPILER_MSVC, new_name
// word global, new_name
// word internal, new_name
// word local_persist, new_name
// word forceinline, new_name
// word neverinline, new_name
// word bit, new_name
// word bitfield_is_equal, new_name
// word ccast, new_name
// word pcast, new_name
// word rcast, new_name
// word scast, new_name
// word num_args, new_name
// word num_args_impl, new_name
// word stringize, new_name
// word stringize_va, new_name
// word do_once, new_name
// word do_once_start, new_name
// word do_once_end, new_name
// word label_scope_start, new_name
// word label_scope_end, new_name
// word count_of, new_name
// word is_between, new_name
// word min, new_name
// word size_of, new_name
// word offset_of, new_name
// word swap, new_name
// Basic Types
// word GEN_U8_MIN, new_name
// word GEN_U8_MAX, new_name
// word GEN_I8_MIN, new_name
// word GEN_I8_MAX, new_name
// word GEN_U16_MIN, new_name
// word GEN_U16_MAX, new_name
// word GEN_I16_MIN, new_name
// word GEN_I16_MAX, new_name
// word GEN_U32_MIN, new_name
// word GEN_U32_MAX, new_name
// word GEN_I32_MIN, new_name
// word GEN_I32_MAX, new_name
// word GEN_U64_MIN, new_name
// word GEN_U64_MAX, new_name
// word GEN_I64_MIN, new_name
// word GEN_I64_MAX, new_name
// word GEN_USIZE_MIN, new_name
// word GEN_USIZE_MAX, new_name
// word GEN_ISIZE_MIN, new_name
// word GEN_ISIZE_MAX, new_name
// word GEN_F32_MIN, new_name
// word GEN_F32_MAX, new_name
// word GEN_F64_MIN, new_name
// word GEN_F64_MAX, new_name
// Debug
// word GEN_DEBUG_TRAP, new_name
// word GEN_ASSERT, new_name
// word GEN_ASSERT_MSG, new_name
// word GEN_ASSERT_NOT_NULL, new_name
// word GEN_PANIC, new_name
// word GEN_FATAL, new_name
// Memory
// word kilobytes, new_name
// word megabytes, new_name
// word gigabytes, new_name
// word terabytes, new_name
// word zero_item, new_name
// word zero_array, new_name
// word alloc_item, new_name
// word alloc_array, new_name
// word malloc, new_name
// word mfree, new_name
// Strings
// word txt, new_name
// word cast_to_strc, new_name
// ---------- Dependency Types
// word b8, new_name
// word b16, new_name
// word b32, new_name
// word s8, new_name
// word s16, new_name
// word s32, new_name
// word s64, new_name
// word u8, new_name
// word u16, new_name
// word u32, new_name
// word u64, new_name
// word usize, new_name
// word ssize, new_name
// word sptr, new_name
// word uptr, new_name
// word f32, new_name
// word f64, new_name
// namespace EAllocator_, new_namespace_
// namespace EFileMode_, new_namespace_
// namespace EFileError_, new_namespace_
// word AllocatorInfo, new_name
// word AllocatorProc, new_name
// word AllocFlag, new_name
// word AllocType, new_name
// word ArrayHeader, new_name
// word DirEntry, new_name
// word DirInfo, new_name
// word DirType, new_name
// word FileDescriptor, new_name
// word FileError, new_name
// word FileInfo, new_name
// word FileTime, new_name
// word FileModeFlag, new_name
// word FileOperations, new_name
// word FileStandardType, new_name
// word SeekWhenceType, new_name
// ---------- Dependency Data
// word default_file_operations, new_name
// ---------- Dependency Procedures
// word align_forward, new_name
// word align_fordward_i64, new_name
// word alloc, new_name
// word alloc_align, new_name
// word assert_handler, new_name
// word assert_crash, new_name
// word char_first_occurence, new_name
// word char_is_alpha, new_name
// word char_is_alphanumeric, new_name
// word char_is_digit, new_name
// word char_is_hex_digit, new_name
// word char_is_space, new_name
// word char_to_lower, new_name
// word char_to_upper, new_name
// word crc32, new_name
// word default_resize_align, new_name
// word digit_to_int, new_name
// word file_close, new_name
// word file_get_standard, new_name
// word file_name, new_name
// word file_open, new_name
// word file_open_mode, new_name
// word file_seek, new_name
// word file_tell, new_name
// word file_write, new_name
// word file_write_at, new_name
// word file_write_at_check, new_name
// word free, new_name
// word free_all, new_name
// word heap, new_name
// word heap_allocator_proc, new_name
// word heap_stats_check, new_name
// word heap_stats_alloc_count, new_name
// word heap_stats_init, new_name
// word heap_stats_used_memory, new_name
// word hex_digit_to_int, new_name
// word i64_to_str, new_name
// word is_power_of_two, new_name
// word log_fmt, new_name
// word mem_copy, new_name
// word mem_move, new_name
// word mem_set, new_name
// word pointer_add, new_name
// word mem_copy, new_name
// word mem_find, new_name
// word mem_move, new_name
// word mem_set, new_name
// word resize, new_name
// word resize_align, new_name
// word process_exit, new_name
// word str_compare, new_name
// word str_copy, new_name
// word str_copy_nulpad, new_name
// word str_fmt_buf, new_name
// word str_fmt_buf_va, new_name
// word str_fmt_file_va, new_name
// word str_fmt_out_va, new_name
// word str_fmt_out_err, new_name
// word str_fmt_out_err_va, new_name
// word str_fmt_va, new_name
// word str_len, new_name
// word str_reverse, new_name
// word str_to_i64, new_name
// word str_to_lower, new_name
// word str_to_upper, new_name
// word u64_to_str, new_name
// word zero_size, new_name
// ---------- gencpp Macros
// word log_failure, new_name
// word NullCode, new_name
// word CodeInvalid, new_name
// ------------ gencpp common
// word Arena, new_name
// word Array, new_name
// word HashTable, new_name
// word Pool, new_name
// word StrC, new_name
// word String, new_name
// word to_str, new_name
// word to_str, new_name
// word to_type, new_name
// ------------ gencpp Types & Constants
// word LogFailType, new_name
// word AccessSpec, new_name
// word ECode, new_name
// word EnumClass, new_name
// word EnumRegular, new_name
// word EnumT, new_name
// word EOperator, new_name
// word ESpecifier, new_name
// word OperatorT, new_name
// word ModuleFlag, new_name
// word SpecifierT, new_name
// word StringCached, new_name
// word StringTable, new_name
// word UsingRegular, new_name
// word UsingNamespace, new_name
// ------------ gencpp Data
// word API_Export, new_name
// word API_Import, new_name
// word AST_POD_Size, new_name
// word AST, new_name
// word AST_POD, new_name
// word Code, new_name
// word Code_POD, new_name
// word Keyword, new_name
// ------------ gencpp API
// word init, new_name
// word deinit, new_name
// word get_cached_string, new_name
// word make_code, new_name
// word make_code_entries, new_name
// word set_allocator_data_arrays, new_name
// word set_allocator_code_pool, new_name
// word set_allocator_code_entries_arena, new_name
// word set_allocator_string_arena, new_name
// word set_allocator_string_table, new_name
// word set_allocator_type_table, new_name
// ------------ upfront constructor namespace
// namespace def_ new_namespace_
// ------------ upfront constructor individual
// word def_attributes, new_name
// word def_comment, new_name
// word def_class, new_name
// word def_constructor, new_name
// word def_destructor, new_name
// word def_define, new_name
// word def_enum, new_name
// word def_execution, new_name
// word def_extern_link, new_name
// word def_friend, new_name
// word def_function, new_name
// word def_include, new_name
// word def_module, new_name
// word def_namespace, new_name
// word def_operator, new_name
// word def_operator_cast, new_name
// word def_param, new_name
// word def_pargma, new_name
// word def_preprocess_cond, new_name
// word def_specifier, new_name
// word def_struct, new_name
// word def_template, new_name
// word def_type, new_name
// word def_typedef, new_name
// word def_union, new_name
// word def_using, new_name
// word def_using_namespace, new_name
// word def_variable, new_name
// word def_body, new_name
// word def_class_body, new_name
// word def_enum_body, new_name
// word def_export_body, new_name
// word def_extern_link_body, new_name
// word def_function_body, new_name
// word def_global_body, new_name
// word def_namespace_body, new_name
// word def_params, new_name
// word def_specifiers, new_name
// word def_struct_body, new_name
// word def_union_body, new_name
// ------------ parse constructor namespace
// namespace parse_, new_namespace_
// ------------ parse constructor individual
// word parse_class, new_name
// word parse_enum, new_name
// word parse_export_body, new_name
// word parse_extern_link, new_name
// word parse_friend, new_name
// word parse_function, new_name
// word parse_global_body, new_name
// word parse_namespace, new_name
// word parse_operator, new_name
// word parse_struct, new_name
// word parse_template, new_name
// word parse_type, new_name
// word parse_typedef, new_name
// word parse_union, new_name
// word parse_using, new_name
// word parse_variable, new_name
// ------------ untyped constructor namespace
// namespace untyped_, new_namespace_
// ------------ untyped constructor individual
// word token_fmt_impl, new_name
// word token_fmt_va, new_name
// word untyped_str, new_name
// word untyped_fmt, new_name
// word untyped_token_fmt, new_name
// ------------ File Ops
// word Builder, new_name
// word Editor, new_name
// word Scanner, new_name
// ------------ gencpp user macros
// word gen_main, new_name
// word GEN_TIME, new_name
// word __, new_name
// word name, new_name
// word code, new_name
// word args, new_name
// word code_str, new_name
// word code_fmt, new_name
// word token_fmt, new_name
// ------------ Type AST namespace
// namespace t_, new_namespace_
// ------------ Specifier AST namespace
// namespace spec_, new_namespace_

View File

@ -9,58 +9,58 @@ using namespace gen;
CodeBody gen_ecode( char const* path, bool use_c_definition = false ) CodeBody gen_ecode( char const* path, bool use_c_definition = false )
{ {
FixedArena_32KB scratch; fixed_arena_init(& scratch); FixedArena_32KB scratch; fixed_arena_init(& scratch);
AllocatorInfo scratch_info = fixed_arena_allocator_info(& scratch); AllocatorInfo scratch_info = fixed_arena_allocator_info(& scratch);
CSV_Columns2 csv_enum = parse_csv_two_columns( scratch_info, path ); CSV_Columns2 csv_enum = parse_csv_two_columns( scratch_info, path );
String enum_entries = string_make_reserve( GlobalAllocator, kilobytes(1) ); StrBuilder enum_entries = strbuilder_make_reserve( GlobalAllocator, kilobytes(1) );
String to_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) ); StrBuilder to_c_str_entries = strbuilder_make_reserve( GlobalAllocator, kilobytes(1) );
String to_keyword_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) ); StrBuilder to_keyword_c_str_entries = strbuilder_make_reserve( GlobalAllocator, kilobytes(1) );
for ( ssize idx = 0; idx < array_num(csv_enum.Col_1); ++ idx ) { for ( ssize idx = 0; idx < array_num(csv_enum.Col_1); ++ idx ) {
char const* code = csv_enum.Col_1[idx].string; char const* code = csv_enum.Col_1[idx].string;
char const* keyword = csv_enum.Col_2[idx].string; char const* keyword = csv_enum.Col_2[idx].string;
// TODO(Ed): to_str_entries and the others in here didn't have proper sizing of the StrC slice. // TODO(Ed): to_c_str_entries and the others in here didn't have proper sizing of the Str slice.
string_append_fmt( & enum_entries, "CT_%s,\n", code ); strbuilder_append_fmt( & enum_entries, "CT_%s,\n", code );
string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", code, code ); strbuilder_append_fmt( & to_c_str_entries, "{ \"%s\", sizeof(\"%s\") - 1 },\n", code, code );
string_append_fmt( & to_keyword_str_entries, "{ sizeof(\"%s\") - 1, \"%s\" },\n", keyword, keyword ); strbuilder_append_fmt( & to_keyword_c_str_entries, "{ \"%s\", sizeof(\"%s\") - 1 },\n", keyword, keyword );
} }
CodeEnum enum_code; CodeEnum enum_code;
if (use_c_definition) { if (use_c_definition) {
enum_code = parse_enum(token_fmt_impl((3 + 1) / 2, "entries", string_to_strc(enum_entries), enum_code = parse_enum(token_fmt_impl((3 + 1) / 2, "entries", strbuilder_to_str(enum_entries),
"enum CodeType enum_underlying(u32) { <entries> CT_NumTypes, CT_UnderlyingType = GEN_U32_MAX };" "enum CodeType enum_underlying(u32) { <entries> CT_NumTypes, CT_UnderlyingType = GEN_U32_MAX };"
)); ));
} }
else { else {
enum_code = parse_enum(token_fmt_impl((3 + 1) / 2, "entries", string_to_strc(enum_entries), enum_code = parse_enum(token_fmt_impl((3 + 1) / 2, "entries", strbuilder_to_str(enum_entries),
"enum CodeType : u32 { <entries> CT_NumTypes, CT_UnderlyingType = GEN_U32_MAX };" "enum CodeType : u32 { <entries> CT_NumTypes, CT_UnderlyingType = GEN_U32_MAX };"
)); ));
} }
#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(csv_enum.Col_1) )); Str lookup_size = strbuilder_to_str(strbuilder_fmt_buf(GlobalAllocator, "%d", array_num(csv_enum.Col_1) ));
CodeBody to_str_fns = parse_global_body( token_fmt( CodeBody to_c_str_fns = parse_global_body( token_fmt(
"entries", string_to_strc(to_str_entries) "entries", strbuilder_to_str(to_c_str_entries)
, "keywords", string_to_strc(to_keyword_str_entries) , "keywords", strbuilder_to_str(to_keyword_c_str_entries)
, "num", lookup_size , "num", lookup_size
, stringize( , stringize(
inline inline
StrC codetype_to_str( CodeType type ) Str codetype_to_str( CodeType type )
{ {
local_persist local_persist
StrC lookup[<num>] = { Str lookup[<num>] = {
<entries> <entries>
}; };
return lookup[ type ]; return lookup[ type ];
} }
inline inline
StrC codetype_to_keyword_str( CodeType type ) Str codetype_to_keyword_str( CodeType type )
{ {
local_persist local_persist
StrC lookup[ <num> ] = { Str lookup[ <num> ] = {
<keywords> <keywords>
}; };
return lookup[ type ]; return lookup[ type ];
@ -76,14 +76,14 @@ CodeBody gen_ecode( char const* path, bool use_c_definition = false )
body_append(result, code_t); body_append(result, code_t);
} }
body_append(result, to_str_fns); body_append(result, to_c_str_fns);
if (! use_c_definition) { if (! use_c_definition) {
#pragma push_macro("forceinline") #pragma push_macro("forceinline")
#undef forceinline #undef forceinline
CodeBody alias_mappings = parse_global_body(code( CodeBody alias_mappings = parse_global_body(code(
forceinline StrC to_str (CodeType type) { return codetype_to_str(type); } forceinline Str to_str (CodeType type) { return codetype_to_str(type); }
forceinline StrC to_keyword_str(CodeType type) { return codetype_to_keyword_str(type); } forceinline Str to_keyword_str(CodeType type) { return codetype_to_keyword_str(type); }
)); ));
#pragma pop_macro("forceinline") #pragma pop_macro("forceinline")
body_append(result, alias_mappings); body_append(result, alias_mappings);
@ -93,19 +93,18 @@ CodeBody gen_ecode( char const* path, bool use_c_definition = false )
CodeBody gen_eoperator( char const* path, bool use_c_definition = false ) CodeBody gen_eoperator( char const* path, bool use_c_definition = false )
{ {
FixedArena_16KB scratch; fixed_arena_init(& scratch); FixedArena_16KB scratch; fixed_arena_init(& scratch);
AllocatorInfo scratch_info = fixed_arena_allocator_info(& scratch); AllocatorInfo scratch_info = fixed_arena_allocator_info(& scratch);
CSV_Columns2 csv_enum = parse_csv_two_columns( scratch_info, path ); CSV_Columns2 csv_enum = parse_csv_two_columns( scratch_info, path );
String enum_entries = string_make_reserve( GlobalAllocator, 32 ); StrBuilder enum_entries = strbuilder_make_reserve( GlobalAllocator, 32 );
String to_str_entries = string_make_reserve( GlobalAllocator, 32 ); StrBuilder to_c_str_entries = strbuilder_make_reserve( GlobalAllocator, 32 );
for (usize idx = 0; idx < array_num(csv_enum.Col_1); idx++) { for (usize idx = 0; idx < array_num(csv_enum.Col_1); idx++) {
char const* enum_str = csv_enum.Col_1[idx].string; char const* enum_str = csv_enum.Col_1[idx].string;
char const* entry_to_str = csv_enum.Col_2[idx].string; char const* entry_to_str = csv_enum.Col_2[idx].string;
strbuilder_append_fmt( & enum_entries, "Op_%s,\n", enum_str );
string_append_fmt( & enum_entries, "Op_%s,\n", enum_str ); strbuilder_append_fmt( & to_c_str_entries, "{ \"%s\", sizeof(\"%s\") - 1 },\n", entry_to_str, entry_to_str);
string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
} }
CodeEnum enum_code; CodeEnum enum_code;
@ -113,7 +112,7 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false )
{ {
#pragma push_macro("enum_underlying") #pragma push_macro("enum_underlying")
#undef enum_underlying #undef enum_underlying
enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize( enum_code = parse_enum(token_fmt("entries", strbuilder_to_str(enum_entries), stringize(
enum Operator enum_underlying(u32) enum Operator enum_underlying(u32)
{ {
<entries> <entries>
@ -125,7 +124,7 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false )
} }
else else
{ {
enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize( enum_code = parse_enum(token_fmt("entries", strbuilder_to_str(enum_entries), stringize(
enum Operator : u32 enum Operator : u32
{ {
<entries> <entries>
@ -137,16 +136,16 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false )
#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(csv_enum.Col_1) )); Str lookup_size = strbuilder_to_str(strbuilder_fmt_buf(GlobalAllocator, "%d", array_num(csv_enum.Col_1) ));
CodeFn to_str = parse_function(token_fmt( CodeFn to_str = parse_function(token_fmt(
"entries", string_to_strc(to_str_entries) "entries", strbuilder_to_str(to_c_str_entries)
, "num", lookup_size , "num", lookup_size
, stringize( , stringize(
inline inline
StrC operator_to_str( Operator op ) Str operator_to_str( Operator op )
{ {
local_persist local_persist
StrC lookup[<num>] = { Str lookup[<num>] = {
<entries> <entries>
}; };
@ -169,7 +168,7 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false )
#pragma push_macro("forceinline") #pragma push_macro("forceinline")
#undef forceinline #undef forceinline
CodeBody alias_mappings = parse_global_body(code( CodeBody alias_mappings = parse_global_body(code(
forceinline StrC to_str(Operator op) { return operator_to_str(op); } forceinline Str to_str(Operator op) { return operator_to_str(op); }
)); ));
#pragma pop_macro("forceinline") #pragma pop_macro("forceinline")
body_append(result, alias_mappings); body_append(result, alias_mappings);
@ -179,20 +178,19 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false )
CodeBody gen_especifier( char const* path, bool use_c_definition = false ) CodeBody gen_especifier( char const* path, bool use_c_definition = false )
{ {
FixedArena_16KB scratch; fixed_arena_init(& scratch); FixedArena_16KB scratch; fixed_arena_init(& scratch);
AllocatorInfo scratch_info = fixed_arena_allocator_info(& scratch); AllocatorInfo scratch_info = fixed_arena_allocator_info(& scratch);
CSV_Columns2 csv_enum = parse_csv_two_columns( scratch_info, path ); CSV_Columns2 csv_enum = parse_csv_two_columns( scratch_info, path );
String enum_entries = string_make_reserve( scratch_info, kilobytes(1) ); StrBuilder enum_entries = strbuilder_make_reserve( scratch_info, kilobytes(1) );
String to_str_entries = string_make_reserve( scratch_info, kilobytes(1) ); StrBuilder to_c_str_entries = strbuilder_make_reserve( scratch_info, kilobytes(1) );
for (usize idx = 0; idx < array_num(csv_enum.Col_1); idx++) for (usize idx = 0; idx < array_num(csv_enum.Col_1); idx++)
{ {
char const* enum_str = csv_enum.Col_1[idx].string; char const* enum_str = csv_enum.Col_1[idx].string;
char const* entry_to_str = csv_enum.Col_2[idx].string; char const* entry_to_str = csv_enum.Col_2[idx].string;
strbuilder_append_fmt( & enum_entries, "Spec_%s,\n", enum_str );
string_append_fmt( & enum_entries, "Spec_%s,\n", enum_str ); strbuilder_append_fmt( & to_c_str_entries, "{ \"%s\", sizeof(\"%s\") - 1 },\n", entry_to_str, entry_to_str);
string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
} }
CodeEnum enum_code; CodeEnum enum_code;
@ -200,7 +198,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
{ {
#pragma push_macro("enum_underlying") #pragma push_macro("enum_underlying")
#undef enum_underlying #undef enum_underlying
enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize( enum_code = parse_enum(token_fmt("entries", strbuilder_to_str(enum_entries), stringize(
enum Specifier enum_underlying(u32) enum Specifier enum_underlying(u32)
{ {
<entries> <entries>
@ -212,7 +210,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
} }
else else
{ {
enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize( enum_code = parse_enum(token_fmt("entries", strbuilder_to_str(enum_entries), stringize(
enum Specifier : u32 enum Specifier : u32
{ {
<entries> <entries>
@ -221,8 +219,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
}; };
))); )));
} }
CodeFn is_trailing = parse_function(token_fmt("specifier", strbuilder_to_str(to_c_str_entries), stringize(
CodeFn is_trailing = parse_function(token_fmt("specifier", string_to_strc(to_str_entries), stringize(
inline inline
bool spec_is_trailing( Specifier specifier ) bool spec_is_trailing( Specifier specifier )
{ {
@ -240,16 +237,16 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
#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(csv_enum.Col_1) )); Str lookup_size = strbuilder_to_str(strbuilder_fmt_buf(GlobalAllocator, "%d", array_num(csv_enum.Col_1) ));
CodeFn to_str = parse_function(token_fmt( CodeFn to_str = parse_function(token_fmt(
"entries", string_to_strc(to_str_entries) "entries", strbuilder_to_str(to_c_str_entries)
, "num", lookup_size , "num", lookup_size
, stringize( , stringize(
inline inline
StrC spec_to_str( Specifier type ) Str spec_to_str( Specifier type )
{ {
local_persist local_persist
StrC lookup[<num>] = { Str lookup[<num>] = {
<entries> <entries>
}; };
@ -257,20 +254,20 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
} }
))); )));
CodeFn to_type = parse_function( token_fmt( "entries", string_to_strc(to_str_entries), stringize( CodeFn to_type = parse_function( token_fmt( "entries", strbuilder_to_str(to_c_str_entries), stringize(
inline inline
Specifier strc_to_specifier( StrC str ) Specifier str_to_specifier( Str str )
{ {
local_persist local_persist
u32 keymap[ Spec_NumSpecifiers ]; u32 keymap[ Spec_NumSpecifiers ];
do_once_start do_once_start
for ( u32 index = 0; index < Spec_NumSpecifiers; index++ ) for ( u32 index = 0; index < Spec_NumSpecifiers; index++ )
{ {
StrC enum_str = spec_to_str( (Specifier)index ); Str enum_str = spec_to_str( (Specifier)index );
// We subtract 1 to remove the null terminator // We subtract 1 to remove the null terminator
// This is because the tokens lexed are not null terminated. // This is because the tokens lexed are not null terminated.
keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1); keymap[index] = crc32( enum_str.Ptr, enum_str.Len );
} }
do_once_end do_once_end
@ -308,8 +305,8 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
#pragma push_macro("forceinline") #pragma push_macro("forceinline")
#undef forceinline #undef forceinline
CodeBody alias_mappings = parse_global_body(code( CodeBody alias_mappings = parse_global_body(code(
forceinline StrC to_str (Specifier spec) { return spec_to_str(spec); } forceinline Str to_str (Specifier spec) { return spec_to_str(spec); }
forceinline Specifier to_type( StrC str ) { return strc_to_specifier(str); } forceinline Specifier to_type( Str str ) { return str_to_specifier(str); }
forceinline bool is_trailing( Specifier specifier ) { return spec_is_trailing(specifier); } forceinline bool is_trailing( Specifier specifier ) { return spec_is_trailing(specifier); }
)); ));
#pragma pop_macro("forceinline") #pragma pop_macro("forceinline")
@ -320,7 +317,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_definition = false ) CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_definition = false )
{ {
FixedArena_64KB scratch; fixed_arena_init(& scratch); FixedArena_64KB scratch; fixed_arena_init(& scratch);
AllocatorInfo scratch_info = fixed_arena_allocator_info(& scratch); AllocatorInfo scratch_info = fixed_arena_allocator_info(& scratch);
FileContents enum_content = file_read_contents( scratch_info, file_zero_terminate, etok_path ); FileContents enum_content = file_read_contents( scratch_info, file_zero_terminate, etok_path );
@ -333,51 +330,51 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_
CSV_Object csv_attr_nodes; CSV_Object csv_attr_nodes;
csv_parse( &csv_attr_nodes, rcast(char*, attrib_content.data), scratch_info, false ); csv_parse( &csv_attr_nodes, rcast(char*, attrib_content.data), scratch_info, false );
Array<ADT_Node> enum_strs = csv_enum_nodes.nodes[0].nodes; Array<ADT_Node> enum_strs = csv_enum_nodes.nodes[0].nodes;
Array<ADT_Node> enum_str_strs = csv_enum_nodes.nodes[1].nodes; Array<ADT_Node> enum_c_str_strs = csv_enum_nodes.nodes[1].nodes;
Array<ADT_Node> attribute_strs = csv_attr_nodes.nodes[0].nodes; Array<ADT_Node> attribute_strs = csv_attr_nodes.nodes[0].nodes;
Array<ADT_Node> attribute_str_strs = csv_attr_nodes.nodes[1].nodes; Array<ADT_Node> attribute_c_str_strs = csv_attr_nodes.nodes[1].nodes;
String enum_entries = string_make_reserve( scratch_info, kilobytes(2) ); StrBuilder enum_entries = strbuilder_make_reserve( scratch_info, kilobytes(2) );
String to_str_entries = string_make_reserve( scratch_info, kilobytes(4) ); StrBuilder to_c_str_entries = strbuilder_make_reserve( scratch_info, kilobytes(4) );
String attribute_entries = string_make_reserve( scratch_info, kilobytes(2) ); StrBuilder attribute_entries = strbuilder_make_reserve( scratch_info, kilobytes(2) );
String to_str_attributes = string_make_reserve( scratch_info, kilobytes(4) ); StrBuilder to_c_str_attributes = strbuilder_make_reserve( scratch_info, kilobytes(4) );
String attribute_define_entries = string_make_reserve( scratch_info, kilobytes(4) ); StrBuilder attribute_define_entries = strbuilder_make_reserve( scratch_info, kilobytes(4) );
for (usize idx = 0; idx < array_num(enum_strs); idx++) for (usize idx = 0; idx < array_num(enum_strs); idx++)
{ {
char const* enum_str = enum_strs[idx].string; char const* enum_str = enum_strs[idx].string;
char const* entry_to_str = enum_str_strs [idx].string; char const* entry_to_str = enum_c_str_strs [idx].string;
string_append_fmt( & enum_entries, "Tok_%s,\n", enum_str ); strbuilder_append_fmt( & enum_entries, "Tok_%s,\n", enum_str );
string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); strbuilder_append_fmt( & to_c_str_entries, "{ \"%s\", sizeof(\"%s\") - 1 },\n", entry_to_str, entry_to_str);
} }
for ( usize idx = 0; idx < array_num(attribute_strs); idx++ ) for ( usize idx = 0; idx < array_num(attribute_strs); idx++ )
{ {
char const* attribute_str = attribute_strs[idx].string; char const* attribute_str = attribute_strs[idx].string;
char const* entry_to_str = attribute_str_strs [idx].string; char const* entry_to_str = attribute_c_str_strs [idx].string;
string_append_fmt( & attribute_entries, "Tok_Attribute_%s,\n", attribute_str ); strbuilder_append_fmt( & attribute_entries, "Tok_Attribute_%s,\n", attribute_str );
string_append_fmt( & to_str_attributes, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); strbuilder_append_fmt( & to_c_str_attributes, "{ \"%s\", sizeof(\"%s\") - 1 },\n", entry_to_str, entry_to_str);
string_append_fmt( & attribute_define_entries, "Entry( Tok_Attribute_%s, \"%s\" )", attribute_str, entry_to_str ); strbuilder_append_fmt( & attribute_define_entries, "Entry( Tok_Attribute_%s, \"%s\" )", attribute_str, entry_to_str );
if ( idx < array_num(attribute_strs) - 1 ) if ( idx < array_num(attribute_strs) - 1 )
string_append_strc( & attribute_define_entries, txt(" \\\n")); strbuilder_append_str( & attribute_define_entries, txt(" \\\n"));
else else
string_append_strc( & attribute_define_entries, txt("\n")); strbuilder_append_str( & attribute_define_entries, txt("\n"));
} }
#pragma push_macro("GEN_DEFINE_ATTRIBUTE_TOKENS") #pragma push_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
#undef GEN_DEFINE_ATTRIBUTE_TOKENS #undef GEN_DEFINE_ATTRIBUTE_TOKENS
CodeDefine attribute_entires_def = def_define( name(GEN_DEFINE_ATTRIBUTE_TOKENS), string_to_strc(attribute_define_entries) ); CodeDefine attribute_entires_def = def_define( name(GEN_DEFINE_ATTRIBUTE_TOKENS), strbuilder_to_str(attribute_define_entries) );
#pragma pop_macro("GEN_DEFINE_ATTRIBUTE_TOKENS") #pragma pop_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
// We cannot parse this enum, it has Attribute names as enums // We cannot parse this enum, it has Attribute names as enums
CodeEnum enum_code; CodeEnum enum_code;
if (use_c_definition) if (use_c_definition)
{ {
enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), "attribute_toks", string_to_strc(attribute_entries), stringize( enum_code = parse_enum(token_fmt("entries", strbuilder_to_str(enum_entries), "attribute_toks", strbuilder_to_str(attribute_entries), stringize(
enum TokType enum TokType
{ {
<entries> <entries>
@ -389,7 +386,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_
} }
else else
{ {
enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), "attribute_toks", string_to_strc(attribute_entries), stringize( enum_code = parse_enum(token_fmt("entries", strbuilder_to_str(enum_entries), "attribute_toks", strbuilder_to_str(attribute_entries), stringize(
enum TokType : u32 enum TokType : u32
{ {
<entries> <entries>
@ -405,12 +402,12 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_
#undef local_persist #undef local_persist
#undef do_once_start #undef do_once_start
#undef do_once_end #undef do_once_end
CodeFn to_str = parse_function(token_fmt("entries", string_to_strc(to_str_entries), "attribute_toks", string_to_strc(to_str_attributes), stringize( CodeFn to_str = parse_function(token_fmt("entries", strbuilder_to_str(to_c_str_entries), "attribute_toks", strbuilder_to_str(to_c_str_attributes), stringize(
inline inline
StrC toktype_to_str( TokType type ) Str toktype_to_str( TokType type )
{ {
local_persist local_persist
StrC lookup[] = { Str lookup[] = {
<entries> <entries>
<attribute_toks> <attribute_toks>
}; };
@ -419,20 +416,20 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_
} }
))); )));
CodeFn to_type = parse_function( token_fmt( "entries", string_to_strc(to_str_entries), stringize( CodeFn to_type = parse_function( token_fmt( "entries", strbuilder_to_str(to_c_str_entries), stringize(
inline inline
TokType strc_to_toktype( StrC str ) TokType str_to_toktype( Str str )
{ {
local_persist local_persist
u32 keymap[ Tok_NumTokens ]; u32 keymap[ Tok_NumTokens ];
do_once_start do_once_start
for ( u32 index = 0; index < Tok_NumTokens; index++ ) for ( u32 index = 0; index < Tok_NumTokens; index++ )
{ {
StrC enum_str = toktype_to_str( (TokType)index ); Str enum_str = toktype_to_str( (TokType)index );
// We subtract 1 to remove the null terminator // We subtract 1 to remove the null terminator
// This is because the tokens lexed are not null terminated. // This is because the tokens lexed are not null terminated.
keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1); keymap[index] = crc32( enum_str.Ptr, enum_str.Len);
} }
do_once_end do_once_end
@ -508,7 +505,7 @@ CodeBody gen_ast_inlines()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
log_failure( "Attempt to dereference a nullptr!" ); log_failure( "Attempt to dereference a nullptr!\n" );
return nullptr; return nullptr;
} }
return ast; return ast;
@ -518,59 +515,59 @@ CodeBody gen_ast_inlines()
#pragma pop_macro("GEN_NS") #pragma pop_macro("GEN_NS")
#pragma pop_macro("CodeInvalid") #pragma pop_macro("CodeInvalid")
CodeBody impl_code = parse_global_body( token_fmt( "typename", StrC name(Code), code_impl_tmpl )); CodeBody impl_code = parse_global_body( token_fmt( "typename", Str name(Code), code_impl_tmpl ));
CodeBody impl_code_body = parse_global_body( token_fmt( "typename", StrC name(CodeBody), code_impl_tmpl )); CodeBody impl_code_body = parse_global_body( token_fmt( "typename", Str name(CodeBody), code_impl_tmpl ));
CodeBody impl_code_attr = parse_global_body( token_fmt( "typename", StrC name(CodeAttributes), code_impl_tmpl )); CodeBody impl_code_attr = parse_global_body( token_fmt( "typename", Str name(CodeAttributes), code_impl_tmpl ));
CodeBody impl_code_cmt = parse_global_body( token_fmt( "typename", StrC name(CodeComment), code_impl_tmpl )); CodeBody impl_code_cmt = parse_global_body( token_fmt( "typename", Str name(CodeComment), code_impl_tmpl ));
CodeBody impl_code_constr = parse_global_body( token_fmt( "typename", StrC name(CodeConstructor), code_impl_tmpl )); CodeBody impl_code_constr = parse_global_body( token_fmt( "typename", Str name(CodeConstructor), code_impl_tmpl ));
CodeBody impl_code_class = parse_global_body( token_fmt( "typename", StrC name(CodeClass), code_impl_tmpl )); CodeBody impl_code_class = parse_global_body( token_fmt( "typename", Str name(CodeClass), code_impl_tmpl ));
CodeBody impl_code_define = parse_global_body( token_fmt( "typename", StrC name(CodeDefine), code_impl_tmpl )); CodeBody impl_code_define = parse_global_body( token_fmt( "typename", Str name(CodeDefine), code_impl_tmpl ));
CodeBody impl_code_destruct = parse_global_body( token_fmt( "typename", StrC name(CodeDestructor), code_impl_tmpl )); CodeBody impl_code_destruct = parse_global_body( token_fmt( "typename", Str name(CodeDestructor), code_impl_tmpl ));
CodeBody impl_code_enum = parse_global_body( token_fmt( "typename", StrC name(CodeEnum), code_impl_tmpl )); CodeBody impl_code_enum = parse_global_body( token_fmt( "typename", Str name(CodeEnum), code_impl_tmpl ));
CodeBody impl_code_exec = parse_global_body( token_fmt( "typename", StrC name(CodeExec), code_impl_tmpl )); CodeBody impl_code_exec = parse_global_body( token_fmt( "typename", Str name(CodeExec), code_impl_tmpl ));
CodeBody impl_code_extern = parse_global_body( token_fmt( "typename", StrC name(CodeExtern), code_impl_tmpl )); CodeBody impl_code_extern = parse_global_body( token_fmt( "typename", Str name(CodeExtern), code_impl_tmpl ));
CodeBody impl_code_include = parse_global_body( token_fmt( "typename", StrC name(CodeInclude), code_impl_tmpl )); CodeBody impl_code_include = parse_global_body( token_fmt( "typename", Str name(CodeInclude), code_impl_tmpl ));
CodeBody impl_code_friend = parse_global_body( token_fmt( "typename", StrC name(CodeFriend), code_impl_tmpl )); CodeBody impl_code_friend = parse_global_body( token_fmt( "typename", Str name(CodeFriend), code_impl_tmpl ));
CodeBody impl_code_fn = parse_global_body( token_fmt( "typename", StrC name(CodeFn), code_impl_tmpl )); CodeBody impl_code_fn = parse_global_body( token_fmt( "typename", Str name(CodeFn), code_impl_tmpl ));
CodeBody impl_code_module = parse_global_body( token_fmt( "typename", StrC name(CodeModule), code_impl_tmpl )); CodeBody impl_code_module = parse_global_body( token_fmt( "typename", Str name(CodeModule), code_impl_tmpl ));
CodeBody impl_code_ns = parse_global_body( token_fmt( "typename", StrC name(CodeNS), code_impl_tmpl )); CodeBody impl_code_ns = parse_global_body( token_fmt( "typename", Str name(CodeNS), code_impl_tmpl ));
CodeBody impl_code_op = parse_global_body( token_fmt( "typename", StrC name(CodeOperator), code_impl_tmpl )); CodeBody impl_code_op = parse_global_body( token_fmt( "typename", Str name(CodeOperator), code_impl_tmpl ));
CodeBody impl_code_opcast = parse_global_body( token_fmt( "typename", StrC name(CodeOpCast), code_impl_tmpl )); CodeBody impl_code_opcast = parse_global_body( token_fmt( "typename", Str name(CodeOpCast), code_impl_tmpl ));
CodeBody impl_code_param = parse_global_body( token_fmt( "typename", StrC name(CodeParam), code_impl_tmpl )); CodeBody impl_code_params = parse_global_body( token_fmt( "typename", Str name(CodeParams), code_impl_tmpl ));
CodeBody impl_code_pragma = parse_global_body( token_fmt( "typename", StrC name(CodePragma), code_impl_tmpl )); CodeBody impl_code_pragma = parse_global_body( token_fmt( "typename", Str name(CodePragma), code_impl_tmpl ));
CodeBody impl_code_precond = parse_global_body( token_fmt( "typename", StrC name(CodePreprocessCond), code_impl_tmpl )); CodeBody impl_code_precond = parse_global_body( token_fmt( "typename", Str name(CodePreprocessCond), code_impl_tmpl ));
CodeBody impl_code_specs = parse_global_body( token_fmt( "typename", StrC name(CodeSpecifiers), code_impl_tmpl )); CodeBody impl_code_specs = parse_global_body( token_fmt( "typename", Str name(CodeSpecifiers), code_impl_tmpl ));
CodeBody impl_code_struct = parse_global_body( token_fmt( "typename", StrC name(CodeStruct), code_impl_tmpl )); CodeBody impl_code_struct = parse_global_body( token_fmt( "typename", Str name(CodeStruct), code_impl_tmpl ));
CodeBody impl_code_tmpl = parse_global_body( token_fmt( "typename", StrC name(CodeTemplate), code_impl_tmpl )); CodeBody impl_code_tmpl = parse_global_body( token_fmt( "typename", Str name(CodeTemplate), code_impl_tmpl ));
CodeBody impl_code_type = parse_global_body( token_fmt( "typename", StrC name(CodeTypename), code_impl_tmpl )); CodeBody impl_code_type = parse_global_body( token_fmt( "typename", Str name(CodeTypename), code_impl_tmpl ));
CodeBody impl_code_typedef = parse_global_body( token_fmt( "typename", StrC name(CodeTypedef), code_impl_tmpl )); CodeBody impl_code_typedef = parse_global_body( token_fmt( "typename", Str name(CodeTypedef), code_impl_tmpl ));
CodeBody impl_code_union = parse_global_body( token_fmt( "typename", StrC name(CodeUnion), code_impl_tmpl )); CodeBody impl_code_union = parse_global_body( token_fmt( "typename", Str name(CodeUnion), code_impl_tmpl ));
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", Str 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", Str name(CodeVar), code_impl_tmpl ));
body_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", Str name(Attributes), codetype_impl_tmpl )));
body_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", Str name(Comment), codetype_impl_tmpl )));
body_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", Str name(Constructor), codetype_impl_tmpl )));
body_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", Str name(Define), codetype_impl_tmpl )));
body_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", Str name(Destructor), codetype_impl_tmpl )));
body_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", Str name(Enum), codetype_impl_tmpl )));
body_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", Str name(Exec), codetype_impl_tmpl )));
body_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", Str name(Extern), codetype_impl_tmpl )));
body_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", Str name(Include), codetype_impl_tmpl )));
body_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", Str name(Friend), codetype_impl_tmpl )));
body_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", Str name(Fn), codetype_impl_tmpl )));
body_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", Str name(Module), codetype_impl_tmpl )));
body_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", Str name(NS), codetype_impl_tmpl )));
body_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", Str name(Operator), codetype_impl_tmpl )));
body_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", Str name(OpCast), codetype_impl_tmpl )));
body_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", Str name(Pragma), codetype_impl_tmpl )));
body_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", Str name(PreprocessCond), codetype_impl_tmpl )));
body_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", Str name(Template), codetype_impl_tmpl )));
body_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", Str name(Typename), codetype_impl_tmpl )));
body_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", Str name(Typedef), codetype_impl_tmpl )));
body_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", Str name(Union), codetype_impl_tmpl )));
body_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", Str name(Using), codetype_impl_tmpl )));
body_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", Str name(Var), codetype_impl_tmpl )));
#pragma push_macro("forceinline") #pragma push_macro("forceinline")
#undef forceinline #undef forceinline
@ -582,34 +579,34 @@ CodeBody gen_ast_inlines()
); );
#pragma pop_macro("forceinline") #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", Str 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", Str name(Attributes), cast_tmpl ));
CodeBody impl_cast_cmt = parse_global_body( token_fmt( "typename", StrC name(Comment), cast_tmpl )); CodeBody impl_cast_cmt = parse_global_body( token_fmt( "typename", Str name(Comment), cast_tmpl ));
CodeBody impl_cast_constr = parse_global_body( token_fmt( "typename", StrC name(Constructor), cast_tmpl )); CodeBody impl_cast_constr = parse_global_body( token_fmt( "typename", Str name(Constructor), cast_tmpl ));
CodeBody impl_cast_class = parse_global_body( token_fmt( "typename", StrC name(Class), cast_tmpl )); CodeBody impl_cast_class = parse_global_body( token_fmt( "typename", Str name(Class), cast_tmpl ));
CodeBody impl_cast_define = parse_global_body( token_fmt( "typename", StrC name(Define), cast_tmpl )); CodeBody impl_cast_define = parse_global_body( token_fmt( "typename", Str name(Define), cast_tmpl ));
CodeBody impl_cast_destruct = parse_global_body( token_fmt( "typename", StrC name(Destructor), cast_tmpl )); CodeBody impl_cast_destruct = parse_global_body( token_fmt( "typename", Str name(Destructor), cast_tmpl ));
CodeBody impl_cast_enum = parse_global_body( token_fmt( "typename", StrC name(Enum), cast_tmpl )); CodeBody impl_cast_enum = parse_global_body( token_fmt( "typename", Str name(Enum), cast_tmpl ));
CodeBody impl_cast_exec = parse_global_body( token_fmt( "typename", StrC name(Exec), cast_tmpl )); CodeBody impl_cast_exec = parse_global_body( token_fmt( "typename", Str name(Exec), cast_tmpl ));
CodeBody impl_cast_extern = parse_global_body( token_fmt( "typename", StrC name(Extern), cast_tmpl )); CodeBody impl_cast_extern = parse_global_body( token_fmt( "typename", Str name(Extern), cast_tmpl ));
CodeBody impl_cast_friend = parse_global_body( token_fmt( "typename", StrC name(Friend), cast_tmpl )); CodeBody impl_cast_friend = parse_global_body( token_fmt( "typename", Str name(Friend), cast_tmpl ));
CodeBody impl_cast_fn = parse_global_body( token_fmt( "typename", StrC name(Fn), cast_tmpl )); CodeBody impl_cast_fn = parse_global_body( token_fmt( "typename", Str name(Fn), cast_tmpl ));
CodeBody impl_cast_include = parse_global_body( token_fmt( "typename", StrC name(Include), cast_tmpl )); CodeBody impl_cast_include = parse_global_body( token_fmt( "typename", Str name(Include), cast_tmpl ));
CodeBody impl_cast_module = parse_global_body( token_fmt( "typename", StrC name(Module), cast_tmpl )); CodeBody impl_cast_module = parse_global_body( token_fmt( "typename", Str name(Module), cast_tmpl ));
CodeBody impl_cast_ns = parse_global_body( token_fmt( "typename", StrC name(NS), cast_tmpl )); CodeBody impl_cast_ns = parse_global_body( token_fmt( "typename", Str name(NS), cast_tmpl ));
CodeBody impl_cast_op = parse_global_body( token_fmt( "typename", StrC name(Operator), cast_tmpl )); CodeBody impl_cast_op = parse_global_body( token_fmt( "typename", Str name(Operator), cast_tmpl ));
CodeBody impl_cast_opcast = parse_global_body( token_fmt( "typename", StrC name(OpCast), cast_tmpl )); CodeBody impl_cast_opcast = parse_global_body( token_fmt( "typename", Str name(OpCast), cast_tmpl ));
CodeBody impl_cast_param = parse_global_body( token_fmt( "typename", StrC name(Param), cast_tmpl )); CodeBody impl_cast_params = parse_global_body( token_fmt( "typename", Str name(Params), cast_tmpl ));
CodeBody impl_cast_pragma = parse_global_body( token_fmt( "typename", StrC name(Pragma), cast_tmpl )); CodeBody impl_cast_pragma = parse_global_body( token_fmt( "typename", Str name(Pragma), cast_tmpl ));
CodeBody impl_cast_precond = parse_global_body( token_fmt( "typename", StrC name(PreprocessCond), cast_tmpl )); CodeBody impl_cast_precond = parse_global_body( token_fmt( "typename", Str name(PreprocessCond), cast_tmpl ));
CodeBody impl_cast_specs = parse_global_body( token_fmt( "typename", StrC name(Specifiers), cast_tmpl )); CodeBody impl_cast_specs = parse_global_body( token_fmt( "typename", Str name(Specifiers), cast_tmpl ));
CodeBody impl_cast_struct = parse_global_body( token_fmt( "typename", StrC name(Struct), cast_tmpl )); CodeBody impl_cast_struct = parse_global_body( token_fmt( "typename", Str name(Struct), cast_tmpl ));
CodeBody impl_cast_tmpl = parse_global_body( token_fmt( "typename", StrC name(Template), cast_tmpl )); CodeBody impl_cast_tmpl = parse_global_body( token_fmt( "typename", Str name(Template), cast_tmpl ));
CodeBody impl_cast_type = parse_global_body( token_fmt( "typename", StrC name(Typename), cast_tmpl )); CodeBody impl_cast_type = parse_global_body( token_fmt( "typename", Str name(Typename), cast_tmpl ));
CodeBody impl_cast_typedef = parse_global_body( token_fmt( "typename", StrC name(Typedef), cast_tmpl )); CodeBody impl_cast_typedef = parse_global_body( token_fmt( "typename", Str name(Typedef), cast_tmpl ));
CodeBody impl_cast_union = parse_global_body( token_fmt( "typename", StrC name(Union), cast_tmpl )); CodeBody impl_cast_union = parse_global_body( token_fmt( "typename", Str name(Union), cast_tmpl ));
CodeBody impl_cast_using = parse_global_body( token_fmt( "typename", StrC name(Using), cast_tmpl )); CodeBody impl_cast_using = parse_global_body( token_fmt( "typename", Str name(Using), cast_tmpl ));
CodeBody impl_cast_var = parse_global_body( token_fmt( "typename", StrC name(Var), cast_tmpl )); CodeBody impl_cast_var = parse_global_body( token_fmt( "typename", Str name(Var), cast_tmpl ));
CodeBody result = def_global_body( args( CodeBody result = def_global_body( args(
def_pragma( txt("region generated code inline implementation")), def_pragma( txt("region generated code inline implementation")),
@ -632,7 +629,7 @@ CodeBody gen_ast_inlines()
impl_code_ns, impl_code_ns,
impl_code_op, impl_code_op,
impl_code_opcast, impl_code_opcast,
impl_code_param, impl_code_params,
impl_code_pragma, impl_code_pragma,
impl_code_precond, impl_code_precond,
impl_code_specs, impl_code_specs,
@ -666,7 +663,7 @@ CodeBody gen_ast_inlines()
impl_cast_ns, impl_cast_ns,
impl_cast_op, impl_cast_op,
impl_cast_opcast, impl_cast_opcast,
impl_cast_param, impl_cast_params,
impl_cast_pragma, impl_cast_pragma,
impl_cast_precond, impl_cast_precond,
impl_cast_specs, impl_cast_specs,

View File

@ -21,22 +21,22 @@ using namespace gen;
void clang_format_file( char const* path, char const* style_path ) void clang_format_file( char const* path, char const* style_path )
{ {
GEN_ASSERT_NOT_NULL(path); GEN_ASSERT_NOT_NULL(path);
String resolved_path = string_make_strc(GlobalAllocator, to_strc_from_c_str(path)); StrBuilder resolved_path = strbuilder_make_str(GlobalAllocator, to_str_from_c_str(path));
String style_arg; StrBuilder style_arg;
if (style_path) { if (style_path) {
style_arg = string_make_strc(GlobalAllocator, txt("-style=file:")); style_arg = strbuilder_make_str(GlobalAllocator, txt("-style=file:"));
string_append_fmt( & style_arg, "%s ", style_path ); strbuilder_append_fmt( & style_arg, "%s ", style_path );
} }
StrC clang_format = txt("clang-format "); Str clang_format = txt("clang-format ");
StrC cf_format_inplace = txt("-i "); Str cf_format_inplace = txt("-i ");
StrC cf_verbose = txt("-verbose "); Str cf_verbose = txt("-verbose ");
String command = string_make_strc( GlobalAllocator, clang_format ); StrBuilder command = strbuilder_make_str( GlobalAllocator, clang_format );
string_append_strc( & command, cf_format_inplace ); strbuilder_append_str( & command, cf_format_inplace );
string_append_strc( & command, cf_verbose ); strbuilder_append_str( & command, cf_verbose );
string_append_string( & command, style_arg ); strbuilder_append_string( & command, style_arg );
string_append_string( & command, resolved_path ); strbuilder_append_string( & command, resolved_path );
system( command ); system( command );
} }
@ -48,11 +48,11 @@ void refactor_file( char const* path, char const* refactor_script )
GEN_ASSERT_NOT_NULL(path); GEN_ASSERT_NOT_NULL(path);
GEN_ASSERT_NOT_NULL(refactor_script); GEN_ASSERT_NOT_NULL(refactor_script);
String command = string_make_strc(GlobalAllocator, txt("refactor ")); StrBuilder command = strbuilder_make_str(GlobalAllocator, txt("refactor "));
// string_append_strc( & command, txt("-debug ") ); // strbuilder_append_str( & command, txt("-debug ") );
string_append_strc( & command, txt("-num=1 ") ); strbuilder_append_str( & command, txt("-num=1 ") );
string_append_fmt( & command, "-src=%s ", path ); strbuilder_append_fmt( & command, "-src=%s ", path );
string_append_fmt( & command,"-spec=%s ", refactor_script ); strbuilder_append_fmt( & command,"-spec=%s ", refactor_script );
system(command); system(command);
log_fmt("\n"); log_fmt("\n");
} }

View File

@ -1,5 +1,5 @@
#if GEN_TIME // This undefines the macros used by the gen library
// This undefines the macros used by the gen library but are not necessary for the user. #undef GEN_TIME
#undef GEN_ARCH_64_BIT #undef GEN_ARCH_64_BIT
#undef GEN_ARCH_32_BIT #undef GEN_ARCH_32_BIT
@ -18,21 +18,116 @@
#undef GEN_COMPILER_CLANG #undef GEN_COMPILER_CLANG
#undef GEN_COMPILER_GCC #undef GEN_COMPILER_GCC
#undef GEN_COMPILER_MINGW
#undef GEN_COMPILER_MSVC #undef GEN_COMPILER_MSVC
#undef forceinline #undef GEN_HAS_ATTRIBUTE
#undef neverinline
#undef GEN_COMPILER_C
#undef GEN_COMPILER_CPP
#undef GEN_DONT_USE_NAMESPACE
#undef GEN_NS_PARSER_BEGIN
#undef GEN_NS_PARSER_END
#undef GEN_USING_NS_PARSER
#undef GEN_NS_PARSER
#undef GEN_NS
#undef GEN_NS_BEGIN
#undef GEN_NS_END
#undef GEN_C_LIKE_CPP
#undef global #undef global
#undef internal #undef internal
#undef local_persist #undef local_persist
#undef bit
#undef bitfield_is_equal
#undef cast
#undef ccast
#undef scast
#undef rcast
#undef pcast
#undef stringize
#undef do_once
#undef do_once_start
#undef do_once_end
#undef labeled_scope_start
#undef labeled_scope_end
#undef compiler_decorated_func_name
#undef num_args_impl
#undef num_args
#undef clamp
#undef count_of
#undef is_between
#undef size_of
#undef max
#undef min
#undef offset_of
#undef forceinline
#undef neverinline
#undef static_assert
#undef thread_local
#undef typeof
#undef GEN_API_C_BEGIN
#undef GEN_API_C_END
#undef enum_underlying
#undef nullptr
#undef GEN_PARAM_DEFAULT
#undef struct_init
#undef GEN_OPTIMIZE_MAPPINGS_BEGIN
#undef GEN_OPITMIZE_MAPPINGS_END
#undef GEN_U8_MIN
#undef GEN_U8_MAX
#undef GEN_I8_MIN
#undef GEN_I8_MAX
#undef GEN_U16_MIN
#undef GEN_U16_MAX
#undef GEN_I16_MIN
#undef GEN_I16_MAX
#undef GEN_U32_MIN
#undef GEN_U32_MAX
#undef GEN_I32_MIN
#undef GEN_I32_MAX
#undef GEN_U64_MIN
#undef GEN_U64_MAX
#undef GEN_I64_MIN
#undef GEN_I64_MAX
#undef GEN_USIZE_MIN
#undef GEN_USIZE_MAX
#undef GEN_ISIZE_MIN
#undef GEN_ISIZE_MAX
#undef GEN_USIZE_MIN
#undef GEN_USIZE_MAX
#undef GEN_ISIZE_MIN
#undef GEN_ISIZE_MAX
#undef GEN_F32_MIN
#undef GEN_F32_MAX
#undef GEN_F64_MIN
#undef GEN_F64_MAX
#undef to_uptr
#undef to_sptr
#undef to_mem_ptr
#undef to_mem_ptr_const
#undef kilobytes #undef kilobytes
#undef megabytes #undef megabytes
#undef gigabytes #undef gigabytes
#undef terabytes #undef terabytes
#undef GEN__ONES
#undef GEN__HIGHS
#undef GEN__HAS_ZERO
#undef GEN_DEFAULT_MEMORY_ALIGNMENT
#undef GEN_DEFAULT_ALLOCATOR_FLAGS
#undef zero_item #undef zero_item
#undef zero_array #undef zero_array
@ -42,37 +137,67 @@
#undef malloc #undef malloc
#undef mfree #undef mfree
#undef count_of #undef GEN_DEBUG_TRAP
#undef is_between #undef GEN_ASSERT
#undef min #undef GEN_ASSERT_MSG
#undef size_of #undef GEN_ASSERT_NOT_NULL
#undef swap #undef GEN_PANIC
#undef GEN_FATAL
#undef GEN_FILE_OPEN_PROC
#undef GEN_FILE_READ_AT_PROC
#undef GEN_FILE_WRITE_AT_PROC
#undef GEN_FILE_SEEK_PROC
#undef GEN_FILE_CLOSE_PROC
#undef GEN_PRINTF_MAXLEN
#undef _strlen
#undef _printf_err
#undef _printf_err_va
#undef _strlen
#undef _printf_err
#undef _printf_err_va
#undef Array
#undef get_array_underlying_type
#undef HashTable
#undef get_hashtable_underlying_type
#undef bit
#undef bitfield_is_equal
#undef ccast
#undef scast
#undef rcast
#undef pcast
#undef do_once
#undef do_once_start
#undef do_once_end
#undef num_args
#undef num_args_impl
#undef stringize
#undef stringize
#undef stringize_va
#undef txt #undef txt
#undef GEN_TIME #undef NOMINMAX
#undef VC_EXTRALEAN
#undef WIN32_LEAN_AND_MEAN
#undef WIN32_MEAN_AND_LEAN
#undef GEN_DEFINE_ATTRIBUTE_TOKENS
#undef GEN_AST_BODY_CLASS_UNALLOWED_TYPES
#undef GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES
#undef GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES
#undef GEN_AST_BODY_EXPORT_UNALLOWED_TYPES
#undef GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES
#undef GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES
#undef GEN_GLOBAL_BUCKET_SIZE
#undef GEN_CODEPOOL_NUM_BLOCKS
#undef GEN_SIZE_PER_STRING_ARENA
#undef GEN_MAX_COMMENT_LINE_LENGTH
#undef GEN_MAX_NAME_LENGTH
#undef GEN_MAX_UNTYPED_STR_LENGTH
#undef TokenMap_FixedArena
#undef GEN_LEX_ALLOCATOR_SIZE
#undef GEN_BUILDER_STR_BUFFER_RESERVE
#undef log_failure
#undef gen_main #undef gen_main
#undef __
#undef name #undef name
#undef code #undef code
#undef args #undef args
#undef code_str #undef code_str
#undef code_fmt #undef code_fmt
#undef token_fmt #undef token_fmt
#undef parse_fmt
// GEN_TIME #undef token_fmt
#endif

View File

@ -37,22 +37,22 @@ The full definitions of all asts are within:
* [`ast.hpp`](../base/components/ast.hpp) * [`ast.hpp`](../base/components/ast.hpp)
* [`ast_types.hpp`](../base/components/ast_types.hpp) * [`ast_types.hpp`](../base/components/ast_types.hpp)
* [`code_types.hpp`](../base/components/ast_types.hpp) * [`code_types.hpp`](../base/components/code_types.hpp)
The C/C++ interface procedures are located with `ast.hpp` (for the Code type), and `code_types.hpp` for all others.
## Serialization ## Serialization
All code types can either serialize using a function of the pattern: All code types can either serialize using a function of the pattern:
```c ```c
String <prefix>_to_string(Code code); StrBuilder <prefix>_to_strbuilder(Code code);
// or // or
<prefix>_to_string(Code code, String& result); <prefix>_to_strbuilder(Code code, StrBuilder& result);
``` ```
Where the first generates strings allocated using Allocator_StringArena and the other appends an existing strings with their backed allocator. Where the first generates strings allocated using Allocator_StringArena and the other appends an existing strings with their backed allocator.
Serialization of for the AST is defined for `Code` in [`ast.chpp`](../base/components/ast.cpp) with `code_to_string_ptr` & `code_to_string`. Serialization of for the AST is defined for `Code` in [`ast.chpp`](../base/components/ast.cpp) with `code_to_strbuilder_ptr` & `code_to_strbuilder`.
Serializtion for the rest of the code types is within [`code_serialization.cpp`](../base/components/code_serialization.cpp).
Serializtion for the rest of the code types is within [`code_serialization.cpp`](../base/components/code_serialization.cpp). Gencpp's serialization does not provide coherent formatting of the code. The user should use a formatter after serializing.
gencpp's serialization does not provide coherent formatting of the code. The user should use a formatter after.

View File

@ -25,11 +25,11 @@ These are containers representing a scope body of a definition that can be of th
Fields: Fields:
```cpp ```cpp
StringCached Name;
Code Front; Code Front;
Code Back; Code Back;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
s32 NumEntries; s32 NumEntries;
``` ```
@ -37,14 +37,15 @@ s32 NumEntries;
The `Front` member represents the start of the link list and `Back` the end. The `Front` member represents the start of the link list and `Back` the end.
NumEntries is the number of entries in the body. NumEntries is the number of entries in the body.
Parent should have a compatible ECode type for the type of defintion used. Parent should have a compatible CodeType type for the type of defintion used.
Serialization: Serialization:
Will output only the entries, the braces are handled by the parent. Will output only the entries, the braces are handled by the parent.
```cpp ```cpp
<Front>... <Front>
...
<Back> <Back>
``` ```
@ -56,11 +57,11 @@ Fields:
```cpp ```cpp
StringCached Content; StringCached Content;
StringCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
``` ```
@ -80,11 +81,11 @@ Fields:
```cpp ```cpp
StringCached Content; StringCached Content;
StringCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
``` ```
@ -108,11 +109,11 @@ CodeComment InlineCmt; // Only supported by forward declarations
CodeAttributes Attributes; CodeAttributes Attributes;
CodeType ParentType; CodeType ParentType;
CodeBody Body; CodeBody Body;
CodeType Prev; // Used to store references to interfaces
CodeType Next; // Used to store references to interfaces
parser::Token* Tok;
Code Parent;
StringCached Name; StringCached Name;
CodeType Prev;
CodeType Next;
Token* Tok;
Code Parent;
CodeT Type; CodeT Type;
ModuleFlag ModuleFlags; ModuleFlag ModuleFlags;
AccessSpec ParentAccess; AccessSpec ParentAccess;
@ -131,7 +132,7 @@ Serialization:
}; };
``` ```
You'll notice that only one parent type is supported only with parent access. This library only supports single inheritance, the rest must be done through interfaces. You'll notice that only one parent type is supported only with parent access. This library only supports single inheritance, the rest are assumed to be interfaces and are given public acess specifiers.
## Constructor ## Constructor
@ -140,13 +141,13 @@ Fields:
```cpp ```cpp
CodeComment InlineCmt; // Only supported by forward declarations CodeComment InlineCmt; // Only supported by forward declarations
Code InitializerList; Code InitializerList;
CodeParam Params; CodeParams Params;
Code Body; Code Body;
StringCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
``` ```
@ -178,11 +179,11 @@ Fields:
```cpp ```cpp
StringCached Content; StringCached Content;
StringCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
``` ```
@ -200,11 +201,11 @@ Fields:
CodeComment InlineCmt; CodeComment InlineCmt;
CodeSpecifiers Specs; CodeSpecifiers Specs;
Code Body; Code Body;
StringCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
``` ```
@ -235,24 +236,28 @@ Fields:
CodeComment InlineCmt; CodeComment InlineCmt;
CodeAttributes Attributes; CodeAttributes Attributes;
CodeType UnderlyingType; CodeType UnderlyingType;
Code UnderlyingTypeMacro;
CodeBody Body; CodeBody Body;
Code Prev; Code Prev;
Code Next; Code Next;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name; StringCached Name;
CodeT Type; CodeT Type;
ModuleFlag ModuleFlags; ModuleFlag ModuleFlags;
``` ```
UnderlyingTypeMacro is a macro the library natively supports: `enum_underlying(type)` that is meant to behave as a wrapper for underlying type assignment.
The `enum_underlying_sig` is a `Str` global var that can be set which will be defined within `PreprocessorDefines` and used in `parser_parse_enum` to identify a valid macro.
Serialization: Serialization:
```cpp ```cpp
// Enum_Fwd // Enum_Fwd
<ModuleFlags> enum class <Name> : <UnderlyingType>; <InlineCmt> <ModuleFlags> enum class <Name> : <UnderlyingType> or <UnderlyingTypeMacro> ; <InlineCmt>
// Enum // Enum
<ModuleFlags> <enum or enum class> <Name> : <UnderlyingType> <ModuleFlags> <enum or enum class> <Name> : <UnderlyingType> or <UnderlyingTypeMacro>
{ {
<Body> <Body>
}; };
@ -267,11 +272,11 @@ Fields:
```cpp ```cpp
StringCached Content; StringCached Content;
StringCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
``` ```
@ -287,11 +292,11 @@ Fields:
```cpp ```cpp
CodeBody Body; CodeBody Body;
StringCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
``` ```
@ -310,11 +315,11 @@ Fields:
```cpp ```cpp
StringCached Content; StringCached Content;
StringCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
Code Parent; Code Parent;
parser::Token* Tok; Token* Tok;
StringCached Name;
CodeT Type; CodeT Type;
``` ```
@ -333,11 +338,11 @@ Fields:
```cpp ```cpp
CodeComment InlineCmt; CodeComment InlineCmt;
Code Declaration; Code Declaration;
StringCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
``` ```
@ -356,13 +361,13 @@ CodeComment InlineCmt;
CodeAttributes Attributes; CodeAttributes Attributes;
CodeSpecifiers Specs; CodeSpecifiers Specs;
CodeType ReturnType; CodeType ReturnType;
CodeParam Params; CodeParams Params;
CodeBody Body; CodeBody Body;
StringCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
ModuleFlag ModuleFlags; ModuleFlag ModuleFlags;
``` ```
@ -385,11 +390,11 @@ Serialization:
Fields: Fields:
```cpp ```cpp
StringCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
ModuleFlag ModuleFlags; ModuleFlag ModuleFlags;
``` ```
@ -406,11 +411,11 @@ Fields:
```cpp ```cpp
CodeBody Body; CodeBody Body;
StringCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
ModuleFlag ModuleFlags; ModuleFlag ModuleFlags;
``` ```
@ -424,7 +429,7 @@ Serialization:
} }
``` ```
## Operator Overload ## Operator Overload (Operator)
Fields: Fields:
@ -433,13 +438,13 @@ CodeComment InlineCmt;
CodeAttributes Attributes; CodeAttributes Attributes;
CodeSpecifiers Specs; CodeSpecifiers Specs;
CodeType ReturnType; CodeType ReturnType;
CodeParam Params; CodeParams Params;
CodeBody Body; CodeBody Body;
StringCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
ModuleFlag ModuleFlags; ModuleFlag ModuleFlags;
OperatorT Op; OperatorT Op;
@ -458,7 +463,7 @@ Serialization:
} }
``` ```
## Operator Cast Overload ( User-Defined Type Conversion ) ## Operator Cast Overload ( User-Defined Type Conversion, OpCast )
Fields: Fields:
@ -467,11 +472,11 @@ CodeComment InlineCmt;
CodeSpecifiers Specs; CodeSpecifiers Specs;
CodeType ValueType; CodeType ValueType;
CodeBody Body; CodeBody Body;
StringCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
``` ```
@ -488,7 +493,7 @@ Serialization:
} }
``` ```
## Parameters (AST_Param) ## Parameters (AST_Params)
Fields: Fields:
@ -496,11 +501,12 @@ Fields:
CodeType ValueType; CodeType ValueType;
Code Macro; Code Macro;
Code Value; Code Value;
CodeParam Last; Code PostNameMacro;
CodeParam Next;
parser::Token* Tok;
Code Parent;
StringCached Name; StringCached Name;
CodeParams Last;
CodeParams Next;
Token* Tok;
Code Parent;
CodeT Type; CodeT Type;
s32 NumEntries; s32 NumEntries;
``` ```
@ -510,7 +516,7 @@ Serialization:
```cpp ```cpp
<Macro>, <Next> ... <Last> <Macro>, <Next> ... <Last>
<Macro> <ValueType> <Name>, <Next>... <Last> <Macro> <ValueType> <Name> <PostNameMacro> = <Value>, <Next>... <Last>
``` ```
## Pragma ## Pragma
@ -519,11 +525,11 @@ Fields:
```cpp ```cpp
StringCached Content; StringCached Content;
StringCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
``` ```
@ -539,11 +545,11 @@ Fields:
```cpp ```cpp
StringCached Content; StringCached Content;
StringCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
paser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
``` ```
@ -560,11 +566,11 @@ Fields:
```cpp ```cpp
SpecifierT ArrSpecs[ AST_ArrSpecs_Cap ]; SpecifierT ArrSpecs[ AST_ArrSpecs_Cap ];
CodeSpecifiers NextSpecs; CodeSpecifiers NextSpecs;
StringCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
s32 NumEntries; s32 NumEntries;
``` ```
@ -580,13 +586,13 @@ Serialization:
Fields: Fields:
```cpp ```cpp
CodeParam Params; CodeParams Params;
Code Declaration; Code Declaration;
StringCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
ModuleFlag ModuleFlags; ModuleFlag ModuleFlags;
``` ```
@ -609,23 +615,30 @@ Fields:
CodeAttributes Attributes; CodeAttributes Attributes;
CodeSpecifiers Specs; CodeSpecifiers Specs;
CodeReturnType ReturnType; CodeReturnType ReturnType;
CodeParam Params; CodeParams Params;
Code ArrExpr; Code ArrExpr;
Code Prev; Code Prev;
Code Next; Code Next;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name; StringCached Name;
CodeT Type; CodeT Type;
b32 IsParamPack; b32 IsParamPack;
ETypenameTag TypeTag;
``` ```
Serialization: Serialization:
```cpp ```cpp
<Attributes> <Name> <Specs> <IsParamPack ?: ...> <Attributes> <TypeTag> <Name> <Specs> <IsParamPack ?: ...>
// Function
<Attributes> <ReturnType> <Name> <Params> <Specs>
``` ```
`<Name>` currently has the full serialization of anything with
*Note: ArrExpr is not used in serialization by `typename_to_strbuilder_ref` its instead handled by a parent AST's serailization (variable, typedef, using).*
## Typedef ## Typedef
Behave as usual except function or macro typedefs. Behave as usual except function or macro typedefs.
@ -636,11 +649,11 @@ Fields:
```cpp ```cpp
CodeComment InlineCmt; CodeComment InlineCmt;
Code UnderlyingType; Code UnderlyingType;
StringCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
parse::Token* Tok Token* Tok
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
ModuleFlag ModuleFlags; ModuleFlag ModuleFlags;
b32 IsFunction; b32 IsFunction;
@ -650,11 +663,16 @@ Serialization:
```cpp ```cpp
// Regular // Regular
<ModuleFlags> typedef <UnderlyingType> <Name>; <InlineCmt> <ModuleFlags> typedef <UnderlyingType> <Name> <UnderlyingType-ArrExpr>; <InlineCmt>
// Functions // Functions
<ModuleFlags> typedef <ReturnType> <Name>( <Parameters> ); <InlineCmt>
<ModuleFlags> typedef <ReturnType> ( <Expression that yeilds an Identifier signature> )( <Parameters> ); <InlineCmt> // Currently:
<ModuleFlags> typedef <UnderlyingType (Serialized expression)>; <InlineCmt>
// Desired: Not handled yet
<ModuleFlags> typedef <UnderlyingType->ReturnType> UnderlyingType->Name> <UnderlyingType-ArrExpr> ( <UnderlyingType->Parameters> ); <InlineCmt>
<ModuleFlags> typedef <UnderlyingType->ReturnType> ( <Name->Namespace> for<Specs->has(Spec_Ptr) ?: *> <UnderlyingType->Name> <UnderlyingType-ArrExpr> ) ( <UnderlyingType->Parameters> ); <InlineCmt>
``` ```
## Union ## Union
@ -664,11 +682,11 @@ Fields:
```cpp ```cpp
CodeAttributes Attributes; CodeAttributes Attributes;
CodeBody Body; CodeBody Body;
StringCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
ModuleFlag ModuleFlags; ModuleFlag ModuleFlags;
``` ```
@ -690,11 +708,11 @@ Fields:
CodeComment InlineCmt; CodeComment InlineCmt;
CodeAttributes Attributes; CodeAttributes Attributes;
CodeType UnderlyingType; CodeType UnderlyingType;
StringCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
ModuleFlag ModuleFlags; ModuleFlag ModuleFlags;
``` ```
@ -722,14 +740,15 @@ CodeSpecifiers Specs;
CodeType ValueType; CodeType ValueType;
Code BitfieldSize; Code BitfieldSize;
Code Value; Code Value;
StringCached Name;
CodeVar NextVar; CodeVar NextVar;
Code Prev; Code Prev;
Code Next; Code Next;
parser::Token* Tok; Token* Tok;
Code Parent; Code Parent;
StringCached Name;
CodeT Type; CodeT Type;
ModuleFlag ModuleFlags; ModuleFlag ModuleFlags;
s32 VarParenthesizedInit;
``` ```
Serialization: Serialization:
@ -740,4 +759,7 @@ Serialization:
// Bitfield // Bitfield
<ModuleFlags> <Attributes> <Specs> <ValueType> <Name> : <BitfieldSize> = <Value>, NextVar ...; <InlineCmt> <ModuleFlags> <Attributes> <Specs> <ValueType> <Name> : <BitfieldSize> = <Value>, NextVar ...; <InlineCmt>
// VarParenthesizedInit
<Attributes> <Specs> <ValueType> <Name>( <Value>, NextVar ... ); <InlineCmt>
``` ```

View File

@ -12,8 +12,8 @@ gencpp uses a hand-written recursive descent parser. Both the lexer and parser c
### Lexer ### Lexer
The lex procedure does the lexical pass of content provided as a `StrC` type. The lex procedure does the lexical pass of content provided as a `Str` type.
The tokens are stored (for now) in `gen::parser::Lexer_Tokens`. The tokens are stored (for now) in `Lexer_Tokens`.
Fields: Fields:
@ -75,7 +75,7 @@ The parser has a limited user interface, only specific types of definitions or s
Each public user interface procedure has the following format: Each public user interface procedure has the following format:
```cpp ```cpp
<code type> parse_<definition type>( StrC def ) <code type> parse_<definition type>( Str def )
{ {
check_parse_args( def ); check_parse_args( def );
using namespace Parser; using namespace Parser;
@ -287,7 +287,7 @@ In the future statements and expressions will be parsed.
1. Attributes ( Standard, GNU, MSVC, Macro ) : `parse_attributes` 1. Attributes ( Standard, GNU, MSVC, Macro ) : `parse_attributes`
2. Specifiers ( consteval, constexpr, constinit, extern, forceinline, global, inline, internal_linkage, neverinline, static ) 2. Specifiers ( consteval, constexpr, constinit, extern, forceinline, global, inline, internal_linkage, neverinline, static )
3. Is either ( identifier, const specifier, long, short, signed, unsigned, bool, char, double, int) 3. Is either ( identifier, const specifier, long, short, signed, unsigned, bool, char, double, int)
1. Attempt to parse as constrcutor or destructor : `parse_global_nspace_constructor_destructor` 1. Attempt to parse as construtor or destructor : `parse_global_nspace_constructor_destructor`
2. If its an operator cast (definition outside class) : `parse_operator_cast` 2. If its an operator cast (definition outside class) : `parse_operator_cast`
3. Its an operator, function, or varaible : `parse_operator_function_or_varaible` 3. Its an operator, function, or varaible : `parse_operator_function_or_varaible`
4. If its not a global body, consume the closing curly brace 4. If its not a global body, consume the closing curly brace

View File

@ -8,32 +8,32 @@
The library features a naive single-pass parser tailored for only what the library needs to construct the supported syntax of C++ into its AST for *"front-end"* meta-programming purposes. The library features a naive single-pass parser tailored for only what the library needs to construct the supported syntax of C++ into its AST for *"front-end"* meta-programming purposes.
This parser does not, and should not do the compiler's job. By only supporting this minimal set of features, the parser is kept (so far) around ~5600 loc. I hope to keep it under 10k loc worst case. This parser does not, and should not do the compiler's job. By only supporting this minimal set of features, the parser is kept (so far) around ~7000 loc. I hope to keep it under 10k loc worst case.
You can think of this parser as *frontend parser* vs a *semantic parser*. Its intuitively similar to WYSIWYG. What you ***precerive*** as the syntax from the user-side before the compiler gets a hold of it, is what you get. You can think of this parser as *frontend parser* vs a *semantic parser*. Its intuitively similar to WYSIWYG. What you ***precerive*** as the syntax from the user-side before the compiler gets a hold of it, is what you get.
User exposed interface: User exposed interface:
```cpp ```cpp
CodeClass parse_class ( StrC class_def ); CodeClass parse_class ( Str class_def );
CodeConstructor parse_constructor ( StrC constructor_def ); CodeConstructor parse_constructor ( Str constructor_def );
CodeDestructor parse_destructor ( StrC destructor_def ); CodeDestructor parse_destructor ( Str destructor_def );
CodeEnum parse_enum ( StrC enum_def ); CodeEnum parse_enum ( Str enum_def );
CodeBody parse_export_body ( StrC export_def ); CodeBody parse_export_body ( Str export_def );
CodeExtern parse_extern_link ( StrC exten_link_def ); CodeExtern parse_extern_link ( Str exten_link_def );
CodeFriend parse_friend ( StrC friend_def ); CodeFriend parse_friend ( Str friend_def );
CodeFn parse_function ( StrC fn_def ); CodeFn parse_function ( Str fn_def );
CodeBody parse_global_body ( StrC body_def ); CodeBody parse_global_body ( Str body_def );
CodeNS parse_namespace ( StrC namespace_def ); CodeNS parse_namespace ( Str namespace_def );
CodeOperator parse_operator ( StrC operator_def ); CodeOperator parse_operator ( Str operator_def );
CodeOpCast parse_operator_cast( StrC operator_def ); CodeOpCast parse_operator_cast( Str operator_def );
CodeStruct parse_struct ( StrC struct_def ); CodeStruct parse_struct ( Str struct_def );
CodeTemplate parse_template ( StrC template_def ); CodeTemplate parse_template ( Str template_def );
CodeType parse_type ( StrC type_def ); CodeType parse_type ( Str type_def );
CodeTypedef parse_typedef ( StrC typedef_def ); CodeTypedef parse_typedef ( Str typedef_def );
CodeUnion parse_union ( StrC union_def ); CodeUnion parse_union ( Str union_def );
CodeUsing parse_using ( StrC using_def ); CodeUsing parse_using ( Str using_def );
CodeVar parse_variable ( StrC var_def ); CodeVar parse_variable ( Str var_def );
``` ```
To parse file buffers, use the `parse_global_body` function. To parse file buffers, use the `parse_global_body` function.

View File

@ -4,7 +4,7 @@
Contains: Contains:
* [AST_Design](./AST_Design.md): Overvie of ASTs * [AST_Design](./AST_Design.md): Overview of ASTs
* [AST Types](./AST_Types.md): Listing of all AST types along with their Code type interface. * [AST Types](./AST_Types.md): Listing of all AST types along with their Code type interface.
* [Parsing](./Parsing.md): Overview of the parsing interface. * [Parsing](./Parsing.md): Overview of the parsing interface.
* [Parser Algo](./Parser_Algo.md): In-depth breakdown of the parser's implementation. * [Parser Algo](./Parser_Algo.md): In-depth breakdown of the parser's implementation.
@ -49,10 +49,10 @@ However, the user may specifiy memory configuration.
https://github.com/Ed94/gencpp/blob/eea4ebf5c40d5d87baa465abfb1be30845b2377e/base/components/ast.hpp#L396-L461 https://github.com/Ed94/gencpp/blob/eea4ebf5c40d5d87baa465abfb1be30845b2377e/base/components/ast.hpp#L396-L461
*`StringCahced` is a typedef for `Str` (a string slice), to denote it is an interned string*
*`CodeType` is enum taggin the type of code. Has an underlying type of `u32`* *`CodeType` is enum taggin the type of code. Has an underlying type of `u32`*
*`OperatorT` is a typedef for `EOperator::Type` which has an underlying type of `u32`* *`OperatorT` is a typedef for `EOperator::Type` which has an underlying type of `u32`*
*`StringCahced` is a typedef for `String const`, to denote it is an interned string* *`StrBuilder` is the dynamically allocated string type for the library*
*`String` is the dynamically allocated string type for the library*
AST widths are setup to be AST_POD_Size. AST widths are setup to be AST_POD_Size.
The width dictates how much the static array can hold before it must give way to using an allocated array: The width dictates how much the static array can hold before it must give way to using an allocated array:
@ -79,7 +79,7 @@ int AST_ArrSpecs_Cap =
Data Notes: Data Notes:
* The allocator definitions used are exposed to the user incase they want to dictate memory usage * The allocator definitions used are exposed to the user incase they want to dictate memory usage
* You'll find the memory handling in `init`, `deinit`, `reset`, `gen_string_allocator`, `get_cached_string`, `make_code`. * You'll find the memory handling in `init`, `deinit`, `reset`, `gen_strbuilder_allocator`, `get_cached_string`, `make_code`.
* Allocators are defined with the `AllocatorInfo` structure found in [`memory.hpp`](../base/dependencies/memory.hpp) * Allocators are defined with the `AllocatorInfo` structure found in [`memory.hpp`](../base/dependencies/memory.hpp)
* Most of the work is just defining the allocation procedure: * Most of the work is just defining the allocation procedure:
@ -128,7 +128,7 @@ The following CodeTypes are used which the user may optionally use strong typing
* CodeNS * CodeNS
* CodeOperator * CodeOperator
* CodeOpCast * CodeOpCast
* CodeParam : Has support for `for : range` iterating across parameters. * CodeParams : Has support for `for : range` iterating across parameters.
* CodePreprocessCond * CodePreprocessCond
* CodePragma * CodePragma
* CodeSpecifiers : Has support for `for : range` iterating across specifiers. * CodeSpecifiers : Has support for `for : range` iterating across specifiers.
@ -308,7 +308,7 @@ Code <name> = code_str( <some code without "" quotes > )
Template metaprogramming in the traditional sense becomes possible with the use of `token_fmt` and parse constructors: Template metaprogramming in the traditional sense becomes possible with the use of `token_fmt` and parse constructors:
```cpp ```cpp
StrC value = txt("Something"); Str value = txt("Something");
char const* template_str = txt( char const* template_str = txt(
Code with <key> to replace with token_values Code with <key> to replace with token_values
@ -403,7 +403,7 @@ There are two provided auxillary interfaces:
* Builder * Builder
* Scanner * Scanner
### Builder is a similar object to the jai language's string_builder ### Builder is a similar object to the jai language's strbuilder_builder
* The purpose of it is to generate a file. * The purpose of it is to generate a file.
* A file is specified and opened for writing using the open( file_path) function. * A file is specified and opened for writing using the open( file_path) function.
@ -412,4 +412,8 @@ There are two provided auxillary interfaces:
### Scanner Auxillary Interface ### Scanner Auxillary Interface
* The purpose is to scan or parse files
* Some with two basic functions to convert a fil to code: `scan_file` and `parse_file`
* `scan_file`: Merely grabs the file and stores it in an untyped Code.
* `parse_file`: Will parse the file using `parse_global_body` and return a `CodeBody`.
* Two basic functions for grabbing columns from a CSV: `parse_csv_one_column` and `parse_csv_two_columns`

View File

@ -24,24 +24,24 @@ constexpr char const* generation_notice =
"// This file was generated automatially by gencpp's c_library.cpp " "// This file was generated automatially by gencpp's c_library.cpp "
"(See: https://github.com/Ed94/gencpp)\n\n"; "(See: https://github.com/Ed94/gencpp)\n\n";
constexpr StrC roll_own_dependencies_guard_start = txt(R"( constexpr Str roll_own_dependencies_guard_start = txt(R"(
//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file. //! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file.
// Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl // Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
#ifndef GEN_ROLL_OWN_DEPENDENCIES #ifndef GEN_ROLL_OWN_DEPENDENCIES
)"); )");
constexpr StrC roll_own_dependencies_guard_end = txt(R"( constexpr Str roll_own_dependencies_guard_end = txt(R"(
// GEN_ROLL_OWN_DEPENDENCIES // GEN_ROLL_OWN_DEPENDENCIES
#endif #endif
)"); )");
constexpr StrC implementation_guard_start = txt(R"( constexpr Str implementation_guard_start = txt(R"(
#pragma region GENCPP IMPLEMENTATION GUARD #pragma region GENCPP IMPLEMENTATION GUARD
#if defined(GEN_IMPLEMENTATION) && ! defined(GEN_IMPLEMENTED) #if defined(GEN_IMPLEMENTATION) && ! defined(GEN_IMPLEMENTED)
# define GEN_IMPLEMENTED # define GEN_IMPLEMENTED
)"); )");
constexpr StrC implementation_guard_end = txt(R"( constexpr Str implementation_guard_end = txt(R"(
#endif #endif
#pragma endregion GENCPP IMPLEMENTATION GUARD #pragma endregion GENCPP IMPLEMENTATION GUARD
)"); )");
@ -85,13 +85,14 @@ int gen_main()
// Header Content: Reflection and Generation // Header Content: Reflection and Generation
#pragma region Resolve Dependencies #pragma region Resolve Dependencies
Code header_platform = scan_file( path_base "dependencies/platform.hpp" ); Code header_platform = scan_file( path_base "dependencies/platform.hpp" );
Code header_macros = scan_file( path_base "dependencies/macros.hpp" ); Code header_macros = scan_file( path_base "dependencies/macros.hpp" );
Code header_basic_types = scan_file( path_base "dependencies/basic_types.hpp" ); Code header_generic_macros = scan_file( "components/generic_macros.h" );
Code header_debug = scan_file( path_base "dependencies/debug.hpp" ); Code header_basic_types = scan_file( path_base "dependencies/basic_types.hpp" );
Code header_string_ops = scan_file( path_base "dependencies/string_ops.hpp" ); Code header_debug = scan_file( path_base "dependencies/debug.hpp" );
Code header_hashing = scan_file( path_base "dependencies/hashing.hpp" ); Code header_string_ops = scan_file( path_base "dependencies/string_ops.hpp" );
Code header_timing = scan_file( path_base "dependencies/timing.hpp" ); Code header_hashing = scan_file( path_base "dependencies/hashing.hpp" );
Code header_timing = scan_file( path_base "dependencies/timing.hpp" );
CodeBody parsed_header_memory = parse_file( path_base "dependencies/memory.hpp" ); CodeBody parsed_header_memory = parse_file( path_base "dependencies/memory.hpp" );
CodeBody header_memory = def_body(CT_Global_Body); CodeBody header_memory = def_body(CT_Global_Body);
@ -99,7 +100,7 @@ int gen_main()
{ {
case CT_Using: case CT_Using:
{ {
log_fmt("REPLACE THIS MANUALLY: %SC\n", entry->Name); log_fmt("REPLACE THIS MANUALLY: %S\n", entry->Name);
CodeUsing using_ver = cast(CodeUsing, entry); CodeUsing using_ver = cast(CodeUsing, entry);
CodeTypedef typedef_ver = def_typedef(using_ver->Name, using_ver->UnderlyingType); CodeTypedef typedef_ver = def_typedef(using_ver->Name, using_ver->UnderlyingType);
@ -125,7 +126,7 @@ int gen_main()
if (fn->Specs) { if (fn->Specs) {
s32 constexpr_found = fn->Specs.remove( Spec_Constexpr ); s32 constexpr_found = fn->Specs.remove( Spec_Constexpr );
if (constexpr_found > -1) { if (constexpr_found > -1) {
//log_fmt("Found constexpr: %S\n", entry.to_string()); //log_fmt("Found constexpr: %SB\n", entry.to_strbuilder());
fn->Specs.append(Spec_Inline); fn->Specs.append(Spec_Inline);
} }
} }
@ -237,7 +238,7 @@ do \
break; break;
case CT_Variable: case CT_Variable:
{ {
if ( strc_contains(entry->Name, txt("Msg_Invalid_Value"))) if ( str_contains(entry->Name, txt("Msg_Invalid_Value")))
{ {
CodeDefine define = def_define(entry->Name, entry->Value->Content); CodeDefine define = def_define(entry->Name, entry->Value->Content);
header_printing.append(define); header_printing.append(define);
@ -291,16 +292,16 @@ do \
case CT_Preprocess_IfNotDef: case CT_Preprocess_IfNotDef:
{ {
//log_fmt("\nIFNDEF: %SC\n", entry->Content); //log_fmt("\nIFNDEF: %S\n", entry->Content);
header_strings.append(entry); header_strings.append(entry);
} }
break; break;
case CT_Struct_Fwd: case CT_Struct_Fwd:
{ {
if ( entry->Name.is_equal(txt("String")) ) if ( entry->Name.is_equal(txt("StrBuilder")) )
{ {
CodeTypedef c_def = parse_typedef(code( typedef char* String; )); CodeTypedef c_def = parse_typedef(code( typedef char* StrBuilder; ));
header_strings.append(c_def); header_strings.append(c_def);
header_strings.append(fmt_newline); header_strings.append(fmt_newline);
++ entry; ++ entry;
@ -340,12 +341,12 @@ do \
case CT_Typedef: case CT_Typedef:
{ {
StrC name_string_table = txt("StringTable"); Str name_string_table = txt("StringTable");
CodeTypedef td = cast(CodeTypedef, entry); CodeTypedef td = cast(CodeTypedef, entry);
if (td->Name.contains(name_string_table)) if (td->Name.contains(name_string_table))
{ {
CodeBody ht = gen_hashtable(txt("gen_StrC"), name_string_table); CodeBody ht = gen_hashtable(txt("gen_Str"), name_string_table);
header_strings.append(ht); header_strings.append(ht);
break; break;
} }
@ -387,8 +388,8 @@ do \
case CT_Union: case CT_Union:
case CT_Union_Fwd: case CT_Union_Fwd:
{ {
StrC type_str = codetype_to_keyword_str(entry->Type); Str type_str = codetype_to_keyword_str(entry->Type);
StrC formated_tmpl = token_fmt_impl( 3, Str formated_tmpl = token_fmt_impl( 3,
"type", type_str "type", type_str
, "name", entry->Name, , "name", entry->Name,
stringize( stringize(
@ -489,8 +490,8 @@ do \
continue; continue;
} }
StrC type_str = codetype_to_keyword_str(entry->Type); Str type_str = codetype_to_keyword_str(entry->Type);
StrC formated_tmpl = token_fmt_impl( 3, Str formated_tmpl = token_fmt_impl( 3,
"type", type_str "type", type_str
, "name", entry->Name, , "name", entry->Name,
stringize( stringize(
@ -548,9 +549,9 @@ do \
{ {
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_strbuilder(type->ReturnType).to_str()
, "Name" , using_ver->Name , "Name" , using_ver->Name
, "Parameters", to_string(type->Params).to_strc() , "Parameters", to_strbuilder(type->Params).to_str()
, stringize( , stringize(
typedef <ReturnType>( * <Name>)(<Parameters>); typedef <ReturnType>( * <Name>)(<Parameters>);
))); )));
@ -577,7 +578,7 @@ do \
types.append(entry_td); types.append(entry_td);
continue; continue;
} }
//log_fmt("Detected ENUM: %S", entry->Name); //log_fmt("Detected ENUM: %SB", entry->Name);
convert_cpp_enum_to_c(cast(CodeEnum, entry), types); convert_cpp_enum_to_c(cast(CodeEnum, entry), types);
} }
break; break;
@ -644,9 +645,9 @@ do \
CodeFn fn = cast(CodeFn, entry); CodeFn fn = cast(CodeFn, entry);
if (fn->Name.starts_with(txt("code_"))) if (fn->Name.starts_with(txt("code_")))
{ {
StrC old_prefix = txt("code_"); Str old_prefix = txt("code_");
StrC actual_name = { fn->Name.Len - old_prefix.Len, fn->Name.Ptr + old_prefix.Len }; Str actual_name = { fn->Name.Ptr + old_prefix.Len, fn->Name.Len - old_prefix.Len };
String new_name = String::fmt_buf(GlobalAllocator, "code__%SC", actual_name ); StrBuilder new_name = StrBuilder::fmt_buf(GlobalAllocator, "code__%S", actual_name );
fn->Name = get_cached_string(new_name); fn->Name = get_cached_string(new_name);
code_c_interface.append(fn); code_c_interface.append(fn);
@ -693,21 +694,21 @@ do \
s32 constexpr_found = var->Specs ? var->Specs.remove( Spec_Constexpr ) : - 1; 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: %SB\n", entry.to_strbuilder());
if (var->Name.contains(txt("AST_ArrSpecs_Cap"))) if (var->Name.contains(txt("AST_ArrSpecs_Cap")))
{ {
Code def = untyped_str(txt( Code def = untyped_str(txt(
R"(#define AST_ArrSpecs_Cap \ R"(#define AST_ArrSpecs_Cap \
( \ ( \
AST_POD_Size \ AST_POD_Size \
- sizeof(Code) \ - sizeof(Code) \
- sizeof(StringCached) \ - sizeof(StringCached) \
- sizeof(Code) * 2 \ - sizeof(Code) * 2 \
- sizeof(Token*) \ - sizeof(Token*) \
- sizeof(Code) \ - sizeof(Code) \
- sizeof(CodeType) \ - sizeof(CodeType) \
- sizeof(ModuleFlag) \ - sizeof(ModuleFlag) \
- sizeof(u32) \ - sizeof(u32) \
) \ ) \
/ sizeof(Specifier) - 1 / sizeof(Specifier) - 1
)" )"
@ -715,7 +716,7 @@ R"(#define AST_ArrSpecs_Cap \
ast.append(def); ast.append(def);
break; break;
} }
CodeDefine def = def_define(var->Name, var->Value.to_string()); CodeDefine def = def_define(var->Name, var->Value.to_strbuilder());
ast.append(def); ast.append(def);
break; break;
} }
@ -728,7 +729,7 @@ R"(#define AST_ArrSpecs_Cap \
break; break;
} }
StrC code_typenames[] = { Str code_typenames[] = {
txt("Code"), txt("Code"),
txt("CodeBody"), txt("CodeBody"),
txt("CodeAttributes"), txt("CodeAttributes"),
@ -748,9 +749,10 @@ R"(#define AST_ArrSpecs_Cap \
txt("CodeOperator"), txt("CodeOperator"),
txt("CodeOpCast"), txt("CodeOpCast"),
txt("CodePragma"), txt("CodePragma"),
txt("CodeParam"), txt("CodeParams"),
txt("CodePreprocessCond"), txt("CodePreprocessCond"),
txt("CodeSpecifiers"), txt("CodeSpecifiers"),
txt("CodeStruct"),
txt("CodeTemplate"), txt("CodeTemplate"),
txt("CodeTypename"), txt("CodeTypename"),
txt("CodeTypedef"), txt("CodeTypedef"),
@ -789,24 +791,24 @@ R"(#define AST_ArrSpecs_Cap \
default: gen_generic_selection (Fail case) \ default: gen_generic_selection (Fail case) \
) GEN_RESOLVED_FUNCTION_CALL( code, ... ) \ ) GEN_RESOLVED_FUNCTION_CALL( code, ... ) \
*/ */
String generic_selector = String::make_reserve(GlobalAllocator, kilobytes(2)); StrBuilder generic_selector = StrBuilder::make_reserve(GlobalAllocator, kilobytes(2));
for ( CodeFn fn : code_c_interface ) for ( CodeFn fn : code_c_interface )
{ {
generic_selector.clear(); generic_selector.clear();
StrC private_prefix = txt("code__"); Str private_prefix = txt("code__");
StrC actual_name = { fn->Name.Len - private_prefix.Len, fn->Name.Ptr + private_prefix.Len }; Str actual_name = { fn->Name.Ptr + private_prefix.Len, fn->Name.Len - private_prefix.Len };
String interface_name = String::fmt_buf(GlobalAllocator, "code_%SC", actual_name ); StrBuilder interface_name = StrBuilder::fmt_buf(GlobalAllocator, "code_%S", actual_name );
// Resolve generic's arguments // Resolve generic's arguments
b32 has_args = fn->Params->NumEntries > 1; b32 has_args = fn->Params->NumEntries > 1;
String params_str = String::make_reserve(GlobalAllocator, 32); StrBuilder params_str = StrBuilder::make_reserve(GlobalAllocator, 32);
for (CodeParam param = fn->Params->Next; param != fn->Params.end(); ++ param) { for (CodeParams param = fn->Params->Next; param != fn->Params.end(); ++ param) {
// We skip the first parameter as its always going to be the code for selection // We skip the first parameter as its always going to be the code for selection
if (param->Next == nullptr) { if (param->Next == nullptr) {
params_str.append_fmt( "%SC", param->Name ); params_str.append_fmt( "%S", param->Name );
continue; continue;
} }
params_str.append_fmt( "%SC, ", param->Name ); params_str.append_fmt( "%S, ", param->Name );
} }
char const* tmpl_def_start = nullptr; char const* tmpl_def_start = nullptr;
@ -822,14 +824,14 @@ R"(#define <interface_name>( code ) _Generic( (code), \
} }
// Definition start // Definition start
generic_selector.append( token_fmt( generic_selector.append( token_fmt(
"interface_name", interface_name.to_strc() "interface_name", interface_name.to_str()
, "params", params_str.to_strc() // Only used if has_args , "params", params_str.to_str() // Only used if has_args
, tmpl_def_start , tmpl_def_start
)); ));
// Append slots // Append slots
for(StrC type : code_typenames ) { for(Str type : code_typenames ) {
generic_selector.append_fmt("%SC : %SC,\\\n", type, fn->Name ); generic_selector.append_fmt("%S : %S,\\\n", type, fn->Name );
} }
generic_selector.append(txt("default: gen_generic_selection_fail \\\n")); generic_selector.append(txt("default: gen_generic_selection_fail \\\n"));
@ -842,7 +844,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
} }
// Definition end // Definition end
generic_selector.append( token_fmt( generic_selector.append( token_fmt(
"params", params_str.to_strc() "params", params_str.to_str()
, "type", fn->Params->ValueType->Name , "type", fn->Params->ValueType->Name
, tmpl_def_end ) ); , tmpl_def_end ) );
@ -888,8 +890,8 @@ R"(#define <interface_name>( code ) _Generic( (code), \
char conversion_buf[32] = {}; char conversion_buf[32] = {};
u64_to_str(size_of(AST_Body::_PAD_), conversion_buf, 10); u64_to_str(size_of(AST_Body::_PAD_), conversion_buf, 10);
StrC arr_exp = union_entry->ValueType->ArrExpr->Content; Str arr_exp = union_entry->ValueType->ArrExpr->Content;
StrC cpp_size = to_strc_from_c_str(conversion_buf); Str cpp_size = to_str_from_c_str(conversion_buf);
union_entry->ValueType->ArrExpr = untyped_str( cpp_size ); union_entry->ValueType->ArrExpr = untyped_str( cpp_size );
union_entry->InlineCmt = untyped_str(token_fmt("arr_exp", arr_exp, union_entry->InlineCmt = untyped_str(token_fmt("arr_exp", arr_exp,
"// Had to hardcode _PAD_ because (<arr_exp>) was 67 bytes in C\n" "// Had to hardcode _PAD_ because (<arr_exp>) was 67 bytes in C\n"
@ -929,29 +931,29 @@ R"(#define <interface_name>( code ) _Generic( (code), \
if (prev && prev->Name.is_equal(entry->Name)) { if (prev && prev->Name.is_equal(entry->Name)) {
// rename second definition so there isn't a symbol conflict // rename second definition so there isn't a symbol conflict
String postfix_arr = String::fmt_buf(GlobalAllocator, "%SC_arr", entry->Name); StrBuilder postfix_arr = StrBuilder::fmt_buf(GlobalAllocator, "%S_arr", entry->Name);
entry->Name = get_cached_string(postfix_arr.to_strc()); entry->Name = get_cached_string(postfix_arr.to_str());
postfix_arr.free(); postfix_arr.free();
} }
b32 handled= false; b32 handled= false;
for ( CodeParam opt_param : fn->Params ) if (opt_param->ValueType->Name.starts_with(txt("Opts_"))) for ( CodeParams opt_param : fn->Params ) if (opt_param->ValueType->Name.starts_with(txt("Opts_")))
{ {
// Convert the definition to use a default struct: https://vxtwitter.com/vkrajacic/status/1749816169736073295 // Convert the definition to use a default struct: https://vxtwitter.com/vkrajacic/status/1749816169736073295
StrC prefix = txt("def_"); Str prefix = txt("def_");
StrC actual_name = { fn->Name.Len - prefix.Len, fn->Name.Ptr + prefix.Len }; Str actual_name = { fn->Name.Ptr + prefix.Len, fn->Name.Len - prefix.Len };
StrC new_name = String::fmt_buf(GlobalAllocator, "def__%SC", actual_name ).to_strc(); Str new_name = StrBuilder::fmt_buf(GlobalAllocator, "def__%S", actual_name ).to_str();
// Resolve define's arguments // Resolve define's arguments
b32 has_args = fn->Params->NumEntries > 1; b32 has_args = fn->Params->NumEntries > 1;
String params_str = String::make_reserve(GlobalAllocator, 32); StrBuilder params_str = StrBuilder::make_reserve(GlobalAllocator, 32);
for (CodeParam other_param = fn->Params; other_param != opt_param; ++ other_param) { for (CodeParams other_param = fn->Params; other_param != opt_param; ++ other_param) {
if ( other_param == opt_param ) { if ( other_param == opt_param ) {
params_str.append_fmt( "%SC", other_param->Name ); params_str.append_fmt( "%S", other_param->Name );
break; break;
} }
// If there are arguments before the optional, prepare them here. // If there are arguments before the optional, prepare them here.
params_str.append_fmt( "%SC, ", other_param->Name ); params_str.append_fmt( "%S, ", other_param->Name );
} }
char const* tmpl_fn_macro = nullptr; char const* tmpl_fn_macro = nullptr;
if (params_str.length() > 0 ) { if (params_str.length() > 0 ) {
@ -963,7 +965,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
Code fn_macro = untyped_str(token_fmt( Code fn_macro = untyped_str(token_fmt(
"def_name", fn->Name "def_name", fn->Name
, "def__name", new_name , "def__name", new_name
, "params", params_str.to_strc() , "params", params_str.to_str()
, "opts_type", opt_param->ValueType->Name , "opts_type", opt_param->ValueType->Name
, tmpl_fn_macro , tmpl_fn_macro
)); ));
@ -1017,9 +1019,9 @@ R"(#define <interface_name>( code ) _Generic( (code), \
CodeFn fn = cast(CodeFn, entry); CodeFn fn = cast(CodeFn, entry);
if (fn->Name.starts_with(txt("code_"))) if (fn->Name.starts_with(txt("code_")))
{ {
StrC old_prefix = txt("code_"); Str old_prefix = txt("code_");
StrC actual_name = { fn->Name.Len - old_prefix.Len, fn->Name.Ptr + old_prefix.Len }; Str actual_name = { fn->Name.Ptr + old_prefix.Len, fn->Name.Len - old_prefix.Len };
String new_name = String::fmt_buf(GlobalAllocator, "code__%SC", actual_name ); StrBuilder new_name = StrBuilder::fmt_buf(GlobalAllocator, "code__%S", actual_name );
fn->Name = get_cached_string(new_name); fn->Name = get_cached_string(new_name);
} }
@ -1172,9 +1174,9 @@ R"(#define <interface_name>( code ) _Generic( (code), \
CodeFn fn = cast(CodeFn, entry); CodeFn fn = cast(CodeFn, entry);
if (fn->Name.starts_with(txt("code_"))) if (fn->Name.starts_with(txt("code_")))
{ {
StrC old_prefix = txt("code_"); Str old_prefix = txt("code_");
StrC actual_name = { fn->Name.Len - old_prefix.Len, fn->Name.Ptr + old_prefix.Len }; Str actual_name = { fn->Name.Ptr + old_prefix.Len, fn->Name.Len - old_prefix.Len };
String new_name = String::fmt_buf(GlobalAllocator, "code__%SC", actual_name ); StrBuilder new_name = StrBuilder::fmt_buf(GlobalAllocator, "code__%S", actual_name );
fn->Name = get_cached_string(new_name); fn->Name = get_cached_string(new_name);
} }
@ -1210,23 +1212,23 @@ R"(#define <interface_name>( code ) _Generic( (code), \
CodeFn fn = cast(CodeFn, entry); CodeFn fn = cast(CodeFn, entry);
Code prev = entry->Prev; Code prev = entry->Prev;
for ( CodeParam arr_param : fn->Params ) for ( CodeParams arr_param : fn->Params )
if ( fn->Name.starts_with(txt("def_")) if ( fn->Name.starts_with(txt("def_"))
&& ( (arr_param->ValueType->Name.starts_with(txt("Specifier")) && fn->Params->NumEntries > 1) && ( (arr_param->ValueType->Name.starts_with(txt("Specifier")) && fn->Params->NumEntries > 1)
|| arr_param->ValueType->Name.starts_with(txt("Code")) ) || arr_param->ValueType->Name.starts_with(txt("Code")) )
) )
{ {
// rename second definition so there isn't a symbol conflict // rename second definition so there isn't a symbol conflict
String postfix_arr = String::fmt_buf(GlobalAllocator, "%SC_arr", fn->Name); StrBuilder postfix_arr = StrBuilder::fmt_buf(GlobalAllocator, "%S_arr", fn->Name);
fn->Name = get_cached_string(postfix_arr.to_strc()); fn->Name = get_cached_string(postfix_arr.to_str());
postfix_arr.free(); postfix_arr.free();
} }
for ( CodeParam opt_param : fn->Params ) if (opt_param->ValueType->Name.starts_with(txt("Opts_"))) for ( CodeParams opt_param : fn->Params ) if (opt_param->ValueType->Name.starts_with(txt("Opts_")))
{ {
StrC prefix = txt("def_"); Str prefix = txt("def_");
StrC actual_name = { fn->Name.Len - prefix.Len, fn->Name.Ptr + prefix.Len }; Str actual_name = { fn->Name.Ptr + prefix.Len, fn->Name.Len - prefix.Len };
StrC new_name = String::fmt_buf(GlobalAllocator, "def__%SC", actual_name ).to_strc(); Str new_name = StrBuilder::fmt_buf(GlobalAllocator, "def__%S", actual_name ).to_str();
fn->Name = get_cached_string(new_name); fn->Name = get_cached_string(new_name);
} }
@ -1317,7 +1319,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
Code define_ver = untyped_str(token_fmt( Code define_ver = untyped_str(token_fmt(
"name", var->Name "name", var->Name
, "value", var->Value->Content , "value", var->Value->Content
, "type", var->ValueType.to_string().to_strc() , "type", var->ValueType.to_strbuilder().to_str()
, "#define <name> (<type>) <value>\n" , "#define <name> (<type>) <value>\n"
)); ));
src_lexer.append(define_ver); src_lexer.append(define_ver);
@ -1362,7 +1364,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
Code define_ver = untyped_str(token_fmt( Code define_ver = untyped_str(token_fmt(
"name", var->Name "name", var->Name
, "value", var->Value->Content , "value", var->Value->Content
, "type", var->ValueType.to_string().to_strc() , "type", var->ValueType.to_strbuilder().to_str()
, "#define <name> (<type>) <value>\n" , "#define <name> (<type>) <value>\n"
)); ));
src_parser.append(define_ver); src_parser.append(define_ver);
@ -1456,7 +1458,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
Code rf_src_parser = refactor_and_format(src_parser); Code rf_src_parser = refactor_and_format(src_parser);
Code r_src_parsing = refactor(src_parsing_interface); Code r_src_parsing = refactor(src_parsing_interface);
Code r_src_untyped = refactor(src_untyped); Code r_src_untyped = refactor(src_untyped);
CodeBody etoktype = gen_etoktype( path_base "enums/ETokType.csv", path_base "enums/AttributeTokens.csv", helper_use_c_definition ); CodeBody etoktype = gen_etoktype( path_base "enums/ETokType.csv", path_base "enums/AttributeTokens.csv", helper_use_c_definition );
Code rf_etoktype = refactor_and_format(etoktype); Code rf_etoktype = refactor_and_format(etoktype);
@ -1479,8 +1481,10 @@ R"(#define <interface_name>( code ) _Generic( (code), \
header.print_fmt( roll_own_dependencies_guard_start ); header.print_fmt( roll_own_dependencies_guard_start );
header.print( r_header_platform ); header.print( r_header_platform );
header.print_fmt( "\nGEN_NS_BEGIN\n" ); header.print_fmt( "\nGEN_NS_BEGIN\n" );
header.print_fmt( "GEN_API_C_BEGIN\n" );
header.print( r_header_macros ); header.print( r_header_macros );
header.print( header_generic_macros );
header.print( r_header_basic_types ); header.print( r_header_basic_types );
header.print( r_header_debug ); header.print( r_header_debug );
header.print( rf_header_memory ); header.print( rf_header_memory );
@ -1494,7 +1498,8 @@ R"(#define <interface_name>( code ) _Generic( (code), \
header.print( r_header_timing ); header.print( r_header_timing );
header.print(rf_header_parsing ); header.print(rf_header_parsing );
header.print_fmt( "\nGEN_NS_END\n" ); header.print_fmt( "\nGEN_API_C_END\n" );
header.print_fmt( "GEN_NS_END\n" );
header.print_fmt( roll_own_dependencies_guard_end ); header.print_fmt( roll_own_dependencies_guard_end );
#pragma endregion Print Dependencies #pragma endregion Print Dependencies
@ -1545,7 +1550,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
#pragma region Print Dependencies #pragma region Print Dependencies
header.print_fmt( roll_own_dependencies_guard_start ); header.print_fmt( roll_own_dependencies_guard_start );
header.print_fmt( "GEN_NS_BEGIN\n"); header.print_fmt( "\nGEN_NS_BEGIN\n");
header.print_fmt( "GEN_API_C_BEGIN\n" ); header.print_fmt( "GEN_API_C_BEGIN\n" );
header.print( r_src_dep_start ); header.print( r_src_dep_start );
@ -1559,12 +1564,14 @@ R"(#define <interface_name>( code ) _Generic( (code), \
header.print( r_src_timing ); header.print( r_src_timing );
header.print( rf_src_parsing ); header.print( rf_src_parsing );
header.print_fmt( "\nGEN_API_C_END\n" );
header.print_fmt( "GEN_NS_END\n"); header.print_fmt( "GEN_NS_END\n");
header.print_fmt( roll_own_dependencies_guard_end ); header.print_fmt( roll_own_dependencies_guard_end );
#pragma endregion Print Dependencies #pragma endregion Print Dependencies
#pragma region Print Components #pragma region Print Components
header.print_fmt( "\nGEN_NS_BEGIN\n"); header.print_fmt( "\nGEN_NS_BEGIN\n");
header.print_fmt( "GEN_API_C_BEGIN\n" );
header.print( fmt_newline); header.print( fmt_newline);
header.print( rf_array_arena ); header.print( rf_array_arena );
@ -1593,12 +1600,13 @@ R"(#define <interface_name>( code ) _Generic( (code), \
header.print( r_src_parsing ); header.print( r_src_parsing );
header.print_fmt( "\n#pragma endregion Parsing\n" ); header.print_fmt( "\n#pragma endregion Parsing\n" );
header.print( r_src_untyped ); header.print( r_src_untyped );
header.print_fmt( "\n#pragma endregion Interface\n\n"); header.print_fmt( "\n#pragma endregion Interface\n");
header.print( rf_src_builder ); header.print( rf_src_builder );
header.print( rf_src_scanner ); header.print( rf_src_scanner );
header.print_fmt( "GEN_API_C_END\n" ); header.print_fmt( "\nGEN_API_C_END\n" );
header.print_fmt( "GEN_NS_END\n");
#pragma endregion Print Components #pragma endregion Print Components
header.print_fmt( implementation_guard_end ); header.print_fmt( implementation_guard_end );
@ -1617,6 +1625,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
header.print_fmt( "\nGEN_NS_BEGIN\n" ); header.print_fmt( "\nGEN_NS_BEGIN\n" );
header.print( r_header_macros ); header.print( r_header_macros );
header.print( header_generic_macros );
header.print( r_header_basic_types ); header.print( r_header_basic_types );
header.print( r_header_debug ); header.print( r_header_debug );
header.print( rf_header_memory ); header.print( rf_header_memory );

View File

@ -167,7 +167,7 @@ namespace pool_, gen_pool_
// Printing // Printing
namespace str_, gen_str_ namespace c_str_, gen_c_str_
word PrintF_Buffer, gen_PrintF_Buffer word PrintF_Buffer, gen_PrintF_Buffer
word Msg_Invalid_Value, gen_Msg_Invalid_Value word Msg_Invalid_Value, gen_Msg_Invalid_Value
@ -211,18 +211,18 @@ word crc64, gen_crc64
// Strings // Strings
word StrC, gen_StrC word Str, gen_Str
word to_strc_from_c_str, gen_to_strc_from_c_str word to_str_from_c_str, gen_to_str_from_c_str
namespace strc_, gen_strc_ namespace str_, gen_str_
word cast_to_strc, gen_cast_to_strc word cast_to_str, gen_cast_to_str
word StringHeader, gen_StringHeader word StrBuilderHeader, gen_StrBuilderHeader
word String, gen_String word StrBuilder, gen_StrBuilder
namespace string_, gen_string_ namespace strbuilder_, gen_strbuilder_
word StringCached, gen_StringCached word StringCached, gen_StringCached
@ -308,7 +308,7 @@ word operator_to_str, gen_operator_to_str
word Specifier, gen_Specifier word Specifier, gen_Specifier
word spec_to_str, gen_spec_to_str word spec_to_str, gen_spec_to_str
word spec_is_trailing, gen_spec_is_trailing word spec_is_trailing, gen_spec_is_trailing
// word strc_to_specifier, gen_strc_to_specifier // word str_to_specifier, gen_str_to_specifier
// AST // AST
@ -319,33 +319,34 @@ namespace AST_, gen_AST_
word Code, gen_Code word Code, gen_Code
word Token, gen_Token word Token, gen_Token
word CodeBody, gen_CodeBody word CodeBody, gen_CodeBody
word CodeAttributes, gen_CodeAttributes word CodeAttributes, gen_CodeAttributes
word CodeComment, gen_CodeComment word CodeComment, gen_CodeComment
word CodeClass, gen_CodeClass word CodeClass, gen_CodeClass
word CodeConstructor, gen_CodeConstructor word CodeConstructor, gen_CodeConstructor
word CodeDefine, gen_CodeDefine word CodeDefine, gen_CodeDefine
word CodeDestructor, gen_CodeDestructor word CodeDestructor, gen_CodeDestructor
word CodeEnum, gen_CodeEnum word CodeEnum, gen_CodeEnum
word CodeExec, gen_CodeExec word CodeExec, gen_CodeExec
word CodeExtern, gen_CodeExtern word CodeExtern, gen_CodeExtern
word CodeInclude, gen_CodeInclude word CodeInclude, gen_CodeInclude
word CodeFriend, gen_CodeFriend word CodeFriend, gen_CodeFriend
word CodeFn, gen_CodeFn word CodeFn, gen_CodeFn
word CodeModule, gen_CodeModule word CodeModule, gen_CodeModule
word CodeNS, gen_CodeNS word CodeNS, gen_CodeNS
word CodeOperator, gen_CodeOperator word CodeOperator, gen_CodeOperator
word CodeOpCast, gen_CodeOpCast word CodeOpCast, gen_CodeOpCast
word CodePragma, gen_CodePragma word CodePragma, gen_CodePragma
word CodeParam, gen_CodeParam word CodeParams, gen_CodeParams
word CodePreprocessCo, gen_CodePreprocessCo word CodePreprocessCond, gen_CodePreprocessCond
word CodeSpecifiers, gen_CodeSpecifiers word CodeSpecifiers, gen_CodeSpecifiers
word CodeTemplate, gen_CodeTemplate word CodeStruct, gen_CodeStruct
word CodeTypename, gen_CodeTypename word CodeTemplate, gen_CodeTemplate
word CodeTypedef, gen_CodeTypedef word CodeTypename, gen_CodeTypename
word CodeUnion, gen_CodeUnion word CodeTypedef, gen_CodeTypedef
word CodeUsing, gen_CodeUsing word CodeUnion, gen_CodeUnion
word CodeVar, gen_CodeVar word CodeUsing, gen_CodeUsing
word CodeVar, gen_CodeVar
// Code Interface // Code Interface
@ -467,6 +468,10 @@ word Allocator_TypeTable, gen_Allocator_TypeTable
word Builder, gen_Builder word Builder, gen_Builder
namespace builder_, gen_builder_ namespace builder_, gen_builder_
// Scanner
word scan_file, gen_scan_file
// Implementation (prviate) // Implementation (prviate)
word _format_info, gen__format_info word _format_info, gen__format_info
@ -522,7 +527,7 @@ word parser_deinit, gen_parser_deinit
word TokType, gen_TokType word TokType, gen_TokType
word toktype_to_str, gen_toktype_to_str word toktype_to_str, gen_toktype_to_str
// word strc_to_toktype, gen_strc_to_toktype // word str_to_toktype, gen_str_to_toktype
word NullToken, gen_NullToken word NullToken, gen_NullToken
namespace tok_, gen_tok_ namespace tok_, gen_tok_

View File

@ -40,11 +40,11 @@ CodeBody gen_array_base()
)); ));
}; };
CodeBody gen_array( StrC type, StrC array_name ) CodeBody gen_array( Str type, Str array_name )
{ {
String array_type = String::fmt_buf( GlobalAllocator, "%.*s", array_name.Len, array_name.Ptr ); StrBuilder array_type = StrBuilder::fmt_buf( GlobalAllocator, "%.*s", array_name.Len, array_name.Ptr );
String fn = String::fmt_buf( GlobalAllocator, "%.*s", array_name.Len, array_name.Ptr ); StrBuilder fn = StrBuilder::fmt_buf( GlobalAllocator, "%.*s", array_name.Len, array_name.Ptr );
// str_to_lower(fn.Data); // c_str_to_lower(fn.Data);
#pragma push_macro( "GEN_ASSERT" ) #pragma push_macro( "GEN_ASSERT" )
#pragma push_macro( "rcast" ) #pragma push_macro( "rcast" )
@ -56,7 +56,7 @@ CodeBody gen_array( StrC type, StrC array_name )
#undef cast #undef cast
#undef typeof #undef typeof
#undef forceinline #undef forceinline
CodeBody result = parse_global_body( token_fmt( "array_type", (StrC)array_type, "fn", (StrC)fn, "type", (StrC)type CodeBody result = parse_global_body( token_fmt( "array_type", (Str)array_type, "fn", (Str)fn, "type", (Str)type
, stringize( , stringize(
typedef <type>* <array_type>; typedef <type>* <array_type>;
@ -375,9 +375,9 @@ CodeBody gen_array( StrC type, StrC array_name )
#pragma pop_macro( "forceinline" ) #pragma pop_macro( "forceinline" )
++ Array_DefinitionCounter; ++ Array_DefinitionCounter;
StrC slot_str = String::fmt_buf(GlobalAllocator, "%d", Array_DefinitionCounter).to_strc(); Str slot_str = StrBuilder::fmt_buf(GlobalAllocator, "%d", Array_DefinitionCounter).to_str();
Code generic_interface_slot = untyped_str(token_fmt( "type", type, "array_type", (StrC)array_type, "slot", (StrC)slot_str, Code generic_interface_slot = untyped_str(token_fmt( "type", type, "array_type", (Str)array_type, "slot", (Str)slot_str,
R"(#define GENERIC_SLOT_<slot>__array_init <type>, <array_type>_init R"(#define GENERIC_SLOT_<slot>__array_init <type>, <array_type>_init
#define GENERIC_SLOT_<slot>__array_init_reserve <type>, <array_type>_init_reserve #define GENERIC_SLOT_<slot>__array_init_reserve <type>, <array_type>_init_reserve
#define GENERIC_SLOT_<slot>__array_append <array_type>, <array_type>_append #define GENERIC_SLOT_<slot>__array_append <array_type>, <array_type>_append
@ -399,13 +399,13 @@ R"(#define GENERIC_SLOT_<slot>__array_init <type>, <array_type>_i
)); ));
return def_global_body( args( return def_global_body( args(
def_pragma( string_to_strc( string_fmt_buf( GlobalAllocator, "region %S", array_type ))), def_pragma( strbuilder_to_str( strbuilder_fmt_buf( GlobalAllocator, "region %SB", array_type ))),
fmt_newline, fmt_newline,
generic_interface_slot, generic_interface_slot,
fmt_newline, fmt_newline,
result, result,
fmt_newline, fmt_newline,
def_pragma( string_to_strc(string_fmt_buf( GlobalAllocator, "endregion %S", array_type ))), def_pragma( strbuilder_to_str(strbuilder_fmt_buf( GlobalAllocator, "endregion %SB", array_type ))),
fmt_newline fmt_newline
)); ));
}; };

View File

@ -27,24 +27,24 @@ R"(#define HashTable(_type) struct _type
return def_global_body(args(struct_def, define_type, define_critical_load_scale)); return def_global_body(args(struct_def, define_type, define_critical_load_scale));
} }
CodeBody gen_hashtable( StrC type, StrC hashtable_name ) CodeBody gen_hashtable( Str type, Str hashtable_name )
{ {
String tbl_type = {(char*) hashtable_name.duplicate(GlobalAllocator).Ptr}; StrBuilder tbl_type = {(char*) hashtable_name.duplicate(GlobalAllocator).Ptr};
String fn = tbl_type.duplicate(GlobalAllocator); StrBuilder fn = tbl_type.duplicate(GlobalAllocator);
// str_to_lower(fn.Data); // c_str_to_lower(fn.Data);
String name_lower = String::make( GlobalAllocator, hashtable_name ); StrBuilder name_lower = StrBuilder::make( GlobalAllocator, hashtable_name );
// str_to_lower( name_lower.Data ); // c_str_to_lower( name_lower.Data );
String hashtable_entry = String::fmt_buf( GlobalAllocator, "HTE_%.*s", hashtable_name.Len, hashtable_name.Ptr ); StrBuilder hashtable_entry = StrBuilder::fmt_buf( GlobalAllocator, "HTE_%.*s", hashtable_name.Len, hashtable_name.Ptr );
String entry_array_name = String::fmt_buf( GlobalAllocator, "Arr_HTE_%.*s", hashtable_name.Len, hashtable_name.Ptr ); StrBuilder entry_array_name = StrBuilder::fmt_buf( GlobalAllocator, "Arr_HTE_%.*s", hashtable_name.Len, hashtable_name.Ptr );
String entry_array_fn_ns = String::fmt_buf( GlobalAllocator, "arr_hte_%.*s", name_lower.length(), name_lower.Data ); StrBuilder entry_array_fn_ns = StrBuilder::fmt_buf( GlobalAllocator, "arr_hte_%.*s", name_lower.length(), name_lower.Data );
CodeBody hashtable_types = parse_global_body( token_fmt( CodeBody hashtable_types = parse_global_body( token_fmt(
"type", (StrC) type, "type", (Str) type,
"tbl_name", (StrC) hashtable_name, "tbl_name", (Str) hashtable_name,
"tbl_type", (StrC) tbl_type, "tbl_type", (Str) tbl_type,
stringize( stringize(
typedef struct HashTable_<type> <tbl_type>; typedef struct HashTable_<type> <tbl_type>;
typedef struct HTE_<tbl_name> HTE_<tbl_name>; typedef struct HTE_<tbl_name> HTE_<tbl_name>;
@ -74,13 +74,13 @@ CodeBody gen_hashtable( StrC type, StrC hashtable_name )
#undef typeof #undef typeof
#undef forceinline #undef forceinline
CodeBody hashtable_def = parse_global_body( token_fmt( CodeBody hashtable_def = parse_global_body( token_fmt(
"type", (StrC) type, "type", (Str) type,
"tbl_name", (StrC) hashtable_name, "tbl_name", (Str) hashtable_name,
"tbl_type", (StrC) tbl_type, "tbl_type", (Str) tbl_type,
"fn", (StrC) fn, "fn", (Str) fn,
"entry_type", (StrC) hashtable_entry, "entry_type", (Str) hashtable_entry,
"array_entry", (StrC) entry_array_name, "array_entry", (Str) entry_array_name,
"fn_array", (StrC) entry_array_fn_ns, "fn_array", (Str) entry_array_fn_ns,
stringize( stringize(
struct HashTable_<type> { struct HashTable_<type> {
Array_ssize Hashes; Array_ssize Hashes;
@ -372,9 +372,9 @@ CodeBody gen_hashtable( StrC type, StrC hashtable_name )
#pragma pop_macro( "forceinline" ) #pragma pop_macro( "forceinline" )
++ HashTable_DefinitionCounter; ++ HashTable_DefinitionCounter;
StrC slot_str = String::fmt_buf(GlobalAllocator, "%d", HashTable_DefinitionCounter).to_strc(); Str slot_str = StrBuilder::fmt_buf(GlobalAllocator, "%d", HashTable_DefinitionCounter).to_str();
Code generic_interface_slot = untyped_str(token_fmt( "type", type, "tbl_type", (StrC)tbl_type, "slot", (StrC)slot_str, Code generic_interface_slot = untyped_str(token_fmt( "type", type, "tbl_type", (Str)tbl_type, "slot", (Str)slot_str,
R"(#define GENERIC_SLOT_<slot>__hashtable_init <type>, <tbl_type>_init R"(#define GENERIC_SLOT_<slot>__hashtable_init <type>, <tbl_type>_init
#define GENERIC_SLOT_<slot>__hashtable_init_reserve <type>, <tbl_type>_init_reserve #define GENERIC_SLOT_<slot>__hashtable_init_reserve <type>, <tbl_type>_init_reserve
#define GENERIC_SLOT_<slot>__hashtable_clear <tbl_type>, <tbl_type>_clear #define GENERIC_SLOT_<slot>__hashtable_clear <tbl_type>, <tbl_type>_clear
@ -395,12 +395,12 @@ R"(#define GENERIC_SLOT_<slot>__hashtable_init <type>, <tbl_type>_
)" )"
)); ));
char const* cmt_str = str_fmt_buf( "Name: %.*s Type: %.*s" char const* cmt_str = c_str_fmt_buf( "Name: %.*s Type: %.*s"
, tbl_type.length(), tbl_type.Data , tbl_type.length(), tbl_type.Data
, type.Len, type.Ptr ); , type.Len, type.Ptr );
return def_global_body(args( return def_global_body(args(
def_pragma( string_to_strc( string_fmt_buf( GlobalAllocator, "region %S", tbl_type ))), def_pragma( strbuilder_to_str( strbuilder_fmt_buf( GlobalAllocator, "region %SB", tbl_type ))),
fmt_newline, fmt_newline,
generic_interface_slot, generic_interface_slot,
fmt_newline, fmt_newline,
@ -409,7 +409,7 @@ R"(#define GENERIC_SLOT_<slot>__hashtable_init <type>, <tbl_type>_
entry_array, entry_array,
hashtable_def, hashtable_def,
fmt_newline, fmt_newline,
def_pragma( string_to_strc( string_fmt_buf( GlobalAllocator, "endregion %S", tbl_type ))), def_pragma( strbuilder_to_str( strbuilder_fmt_buf( GlobalAllocator, "endregion %SB", tbl_type ))),
fmt_newline fmt_newline
)); ));
} }

View File

@ -0,0 +1,116 @@
#pragma region _Generic Macros
// ____ _ ______ _ _ ____ _ __ _
// / ___} (_) | ____} | | (_) / __ \ | | | |(_)
// | | ___ ___ _ __ ___ _ __ _ ___ | |__ _ _ _ __ ___| |_ _ ___ _ __ | | | |_ _____ _ __ | | ___ __ _ __| | _ _ __ __ _
// | |{__ |/ _ \ '_ \ / _ \ '__} |/ __| | __} | | | '_ \ / __} __} |/ _ \| '_ \ | | | \ \ / / _ \ '_ }| |/ _ \ / _` |/ _` || | '_ \ / _` |
// | |__j | __/ | | | __/ | | | (__ | | | |_| | | | | (__| l_| | (_) | | | | | l__| |\ V / __/ | | | (_) | (_| | (_| || | | | | (_| |
// \____/ \___}_l l_l\___}_l l_l\___| l_l \__,_l_l l_l\___}\__}_l\___/l_l l_l \____/ \_/ \___}_l l_l\___/ \__,_l\__,_l|_|_| |_|\__, |
// This implemnents macros for utilizing "The Naive Extendible _Generic Macro" explained in: __| |
// https://github.com/JacksonAllan/CC/blob/main/articles/Better_C_Generics_Part_1_The_Extendible_Generic.md {___/
// Since gencpp is used to generate the c-library, it was choosen over the more novel implementations to keep the macros as easy to understand and unobfuscated as possible.
#define GEN_COMMA_OPERATOR , // The comma operator is used by preprocessor macros to delimit arguments, so we have to represent it via a macro to prevent parsing incorrectly.
// Helper macros for argument selection
#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_3( _1, _2, _3, ... ) _3 // etc..
#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_COMMA_DELIMITER GEN_SELECT_ARG_3 // Use the arg expansion macro to select arg 3 which should have the comma delimiter ','.
#define GEN_RESOLVED_FUNCTION_CALL // Just used to indicate where the call "occurs"
// ----------------------------------------------------------------------------------------------------------------------------------
// GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( macro ) includes a _Generic slot only if the specified macro is defined (as type, function_name).
// It takes advantage of the fact that if the macro is defined, then the expanded text will contain a comma.
// Expands to ',' if it can find (type): (function) <comma_operator: ',' >
// 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, , )
// ^ Selects the comma ^ is the type ^ is the function ^ Insert a comma
// The slot won't exist if that comma is not found.
// For the occastion where an expression didn't resolve to a selection option the "default: <value>" will be set to:
typedef struct GENCPP_NO_RESOLVED_GENERIC_SELECTION GENCPP_NO_RESOLVED_GENERIC_SELECTION;
struct GENCPP_NO_RESOLVED_GENERIC_SELECTION {
void* _THE_VOID_SLOT_;
};
GENCPP_NO_RESOLVED_GENERIC_SELECTION const gen_generic_selection_fail = {0};
// Which will provide the message: error: called object type 'struct NO_RESOLVED_GENERIC_SELECTION' is not a function or function pointer
// ----------------------------------------------------------------------------------------------------------------------------------
// Below are generated on demand for an overlaod depdendent on a type:
// ----------------------------------------------------------------------------------------------------------------------------------
#define GEN_FUNCTION_GENERIC_EXAMPLE( selector_arg ) _Generic( \
(selector_arg), /* Select Via Expression*/ \
/* Extendibility slots: */ \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_1__function_sig ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_2__function_sig ) \
default: gen_generic_selection_fail \
) GEN_RESOLVED_FUNCTION_CALL( selector_arg )
// ----------------------------------------------------------------------------------------------------------------------------------
// Then each definiton of a function has an associated define:
#// #define GENERIC_SLOT_<#>_<generic identifier> <typename>, <function_to_resolve>
// Then somehwere later on
// <etc> <return_type> <function_id> ( <arguments> ) { <implementation> }
// Concrete example:
// To add support for long:
#define GENERIC_SLOT_1_gen_example_hash long, gen_example_hash__P_long
size_t gen_example_hash__P_long( long val ) { return val * 2654435761ull; }
// To add support for long long:
#define GENERIC_SLOT_2_gen_example_hash long long, gen_example_hash__P_long_long
size_t gen_example_hash__P_long_long( long long val ) { return val * 2654435761ull; }
// If using an Editor with support for syntax hightlighting macros:
// GENERIC_SLOT_1_gen_example_hash and GENERIC_SLOT_2_gen_example_hash should show color highlighting indicating the slot is enabled,
// or, "defined" for usage during the compilation pass that handles the _Generic instrinsic.
#define gen_hash_example( function_arguments ) _Generic( \
(function_arguments), /* Select Via Expression*/ \
/* Extendibility slots: */ \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_1_gen_example_hash ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_2_gen_example_hash ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_3_gen_example_hash ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_4_gen_example_hash ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_5_gen_example_hash ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_6_gen_example_hash ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_7_gen_example_hash ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_8_gen_example_hash ) \
default: gen_generic_selection_fail \
) GEN_RESOLVED_FUNCTION_CALL( function_arguments )
// Additional Variations:
// If the function takes more than one argument the following is used:
#define GEN_FUNCTION_GENERIC_EXAMPLE_VARADIC( selector_arg, ... ) _Generic( \
(selector_arg), \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_1__function_sig ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_2__function_sig ) \
/* ... */ \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT(GENERIC_SLOT_N__function_sig ) \
default: gen_generic_selection_fail \
) GEN_RESOLVED_FUNCTION_CALL( selector_arg, __VA_ARG__ )
// If the function does not take the arugment as a parameter:
#define GEN_FUNCTION_GENERIC_EXAMPLE_DIRECT_TYPE( selector_arg ) _Generic( \
( GEN_TYPE_TO_EXP(selector_arg) ), \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_1__function_sig ) \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_2__function_sig ) \
/* ... */ \
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT(GENERIC_SLOT_N__function_sig ) \
default: gen_generic_selection_fail \
) GEN_RESOLVED_FUNCTION_CALL()
// Used to keep the _Generic keyword happy as bare types are not considered "expressions"
#define GEN_TYPE_TO_EXP(type) (* (type*)NULL)
// Instead of using this macro, you'll see it directly expanded by the code generation.
// typedef void* GEN_GenericExampleType;
// GEN_FUNCTION_GENERIC_EXAMPLE_DIRECT_TYPE( GEN_GenericExampleType );
#pragma endregion _Generic Macros

View File

@ -18,13 +18,13 @@ void convert_cpp_enum_to_c( CodeEnum to_convert, CodeBody to_append )
#pragma pop_macro("enum_underlying") #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( Str 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.is_equal(cond_sig) ) if ( cond->Content.is_equal(cond_sig) )
{ {
//log_fmt("Preprocess cond found: %SC\n", cond->Content); //log_fmt("Preprocess cond found: %S\n", cond->Content);
found = true; found = true;
s32 depth = 1; s32 depth = 1;
@ -72,7 +72,7 @@ b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& par
constexpr bool GenericSel_One_Arg = true; constexpr bool GenericSel_One_Arg = true;
enum GenericSelectionOpts : u32 { GenericSel_Default, GenericSel_By_Ref, GenericSel_Direct_Type }; enum GenericSelectionOpts : u32 { GenericSel_Default, GenericSel_By_Ref, GenericSel_Direct_Type };
Code gen_generic_selection_function_macro( s32 num_slots, StrC macro_name, GenericSelectionOpts opts = GenericSel_Default, bool one_arg = false ) Code gen_generic_selection_function_macro( s32 num_slots, Str macro_name, GenericSelectionOpts opts = GenericSel_Default, bool one_arg = false )
{ {
/* Implements: /* Implements:
#define GEN_FUNCTION_GENERIC_EXAMPLE( selector_arg, ... ) _Generic( \ #define GEN_FUNCTION_GENERIC_EXAMPLE( selector_arg, ... ) _Generic( \
@ -84,18 +84,18 @@ Code gen_generic_selection_function_macro( s32 num_slots, StrC macro_name, Gener
) GEN_RESOLVED_FUNCTION_CALL( selector_arg ) ) GEN_RESOLVED_FUNCTION_CALL( selector_arg )
*/ */
local_persist local_persist
String define_builder = String::make_reserve(GlobalAllocator, kilobytes(64)); StrBuilder define_builder = StrBuilder::make_reserve(GlobalAllocator, kilobytes(64));
define_builder.clear(); define_builder.clear();
StrC macro_begin; Str macro_begin;
if (opts == GenericSel_Direct_Type) { if (opts == GenericSel_Direct_Type) {
macro_begin = token_fmt( "macro_name", (StrC)macro_name, macro_begin = token_fmt( "macro_name", (Str)macro_name,
R"(#define <macro_name>(selector_arg, ...) _Generic( (*(selector_arg*)NULL ), \ R"(#define <macro_name>(selector_arg, ...) _Generic( (*(selector_arg*)NULL ), \
)" )"
); );
} }
else { else {
macro_begin = token_fmt( "macro_name", (StrC)macro_name, macro_begin = token_fmt( "macro_name", (Str)macro_name,
R"(#define <macro_name>(selector_arg, ...) _Generic( (selector_arg), \ R"(#define <macro_name>(selector_arg, ...) _Generic( (selector_arg), \
)" )"
); );
@ -104,7 +104,7 @@ R"(#define <macro_name>(selector_arg, ...) _Generic( (selector_arg), \
for ( s32 slot = 1; slot <= num_slots; ++ slot ) for ( s32 slot = 1; slot <= num_slots; ++ slot )
{ {
StrC slot_str = String::fmt_buf(GlobalAllocator, "%d", slot).to_strc(); Str slot_str = StrBuilder::fmt_buf(GlobalAllocator, "%d", slot).to_str();
if (slot == num_slots && false) if (slot == num_slots && false)
{ {
define_builder.append( token_fmt( "macro_name", macro_name, "slot", slot_str, define_builder.append( token_fmt( "macro_name", macro_name, "slot", slot_str,
@ -152,29 +152,29 @@ R"( GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_<slot>__<macro_name> )
// Add gap for next definition // Add gap for next definition
define_builder.append(txt("\n\n")); define_builder.append(txt("\n\n"));
Code macro = untyped_str(define_builder.to_strc()); Code macro = untyped_str(define_builder.to_str());
return macro; return macro;
} }
CodeFn rename_function_to_unique_symbol(CodeFn fn, StrC optional_prefix = txt("")) CodeFn rename_function_to_unique_symbol(CodeFn fn, Str optional_prefix = txt(""))
{ {
// Get basic components for the name // Get basic components for the name
StrC old_name = fn->Name; Str old_name = fn->Name;
String new_name; StrBuilder new_name;
// Add prefix if provided // Add prefix if provided
if (optional_prefix.Len) if (optional_prefix.Len)
new_name = string_fmt_buf(GlobalAllocator, "%SC_%SC_", optional_prefix, old_name); new_name = strbuilder_fmt_buf(GlobalAllocator, "%S_%S_", optional_prefix, old_name);
else else
new_name = string_fmt_buf(GlobalAllocator, "%SC_", old_name); new_name = strbuilder_fmt_buf(GlobalAllocator, "%S_", old_name);
// Add return type to the signature // Add return type to the signature
if (fn->ReturnType) if (fn->ReturnType)
new_name.append_fmt("_%SC", fn->ReturnType->Name); new_name.append_fmt("_%S", fn->ReturnType->Name);
// Add parameter types to create a unique signature // Add parameter types to create a unique signature
bool first_param = true; bool first_param = true;
for (CodeParam param = fn->Params; param.ast; param = param->Next) for (CodeParams param = fn->Params; param.ast; param = param->Next)
{ {
if (param->ValueType) if (param->ValueType)
{ {
@ -198,11 +198,11 @@ CodeFn rename_function_to_unique_symbol(CodeFn fn, StrC optional_prefix = txt(""
continue; continue;
} }
new_name.append_fmt("%SC_", spec_to_str(spec)); new_name.append_fmt("%S_", spec_to_str(spec));
} }
} }
new_name.append_fmt("%SC", param->ValueType->Name); new_name.append_fmt("%S", param->ValueType->Name);
} }
} }
@ -214,7 +214,7 @@ CodeFn rename_function_to_unique_symbol(CodeFn fn, StrC optional_prefix = txt(""
spec != end(fn->Specs); spec != end(fn->Specs);
++spec) ++spec)
{ {
new_name.append_fmt("%SC_", spec_to_str(*spec)); new_name.append_fmt("%S_", spec_to_str(*spec));
} }
} }
@ -223,13 +223,13 @@ CodeFn rename_function_to_unique_symbol(CodeFn fn, StrC optional_prefix = txt(""
} }
using SwapContentProc = CodeBody(void); using SwapContentProc = CodeBody(void);
bool swap_pragma_region_implementation( StrC region_name, SwapContentProc* swap_content, Code& entry_iter, CodeBody& body ) bool swap_pragma_region_implementation( Str region_name, SwapContentProc* swap_content, Code& entry_iter, CodeBody& body )
{ {
bool found = false; bool found = false;
CodePragma possible_region = cast(CodePragma, entry_iter); CodePragma possible_region = cast(CodePragma, entry_iter);
String region_sig = string_fmt_buf(GlobalAllocator, "region %s", region_name.Ptr); StrBuilder region_sig = strbuilder_fmt_buf(GlobalAllocator, "region %s", region_name.Ptr);
String endregion_sig = string_fmt_buf(GlobalAllocator, "endregion %s", region_name.Ptr); StrBuilder endregion_sig = strbuilder_fmt_buf(GlobalAllocator, "endregion %s", region_name.Ptr);
if ( possible_region->Content.contains(region_sig)) if ( possible_region->Content.contains(region_sig))
{ {
found = true; found = true;

View File

@ -117,7 +117,7 @@ int gen_main()
def_include(txt("components/types.hpp")), def_include(txt("components/types.hpp")),
preprocess_endif, preprocess_endif,
fmt_newline, fmt_newline,
untyped_str( to_strc_from_c_str(generation_notice) ) untyped_str( to_str_from_c_str(generation_notice) )
)); ));
// gen.hpp // gen.hpp
@ -171,7 +171,7 @@ int gen_main()
builder_print_fmt( header, "#pragma endregion Inlines\n" ); builder_print_fmt( header, "#pragma endregion Inlines\n" );
builder_print( header, header_end ); builder_print( header, header_end );
builder_print_fmt( header, "GEN_NS_END\n\n" ); builder_print_fmt( header, "\nGEN_NS_END\n\n" );
builder_print( header, pop_ignores ); builder_print( header, pop_ignores );
builder_write(header); builder_write(header);
} }
@ -238,7 +238,7 @@ int gen_main()
builder_print( & header, def_include( txt("gen.hpp") )); builder_print( & header, def_include( txt("gen.hpp") ));
builder_print_fmt( & header, "\nGEN_NS_BEGIN\n" ); builder_print_fmt( & header, "\nGEN_NS_BEGIN\n" );
builder_print( & header, builder ); builder_print( & header, builder );
builder_print_fmt( & header, "GEN_NS_END\n" ); builder_print_fmt( & header, "\nGEN_NS_END\n" );
builder_write( & header); builder_write( & header);
} }
@ -278,7 +278,7 @@ int gen_main()
builder_print( & src, def_include( txt("gen.scanner.hpp") ) ); builder_print( & src, def_include( txt("gen.scanner.hpp") ) );
builder_print_fmt( & src, "\nGEN_NS_BEGIN\n" ); builder_print_fmt( & src, "\nGEN_NS_BEGIN\n" );
builder_print( & src, scanner ); builder_print( & src, scanner );
builder_print_fmt( & src, "GEN_NS_END\n" ); builder_print_fmt( & src, "\nGEN_NS_END\n" );
builder_write( & src); builder_write( & src);
} }

View File

@ -15,4 +15,4 @@ If using the library's provided build scripts:
```ps1 ```ps1
.\build.ps1 <compiler> <debug or omit> singleheader .\build.ps1 <compiler> <debug or omit> singleheader
``` ```

View File

@ -17,24 +17,24 @@ constexpr char const* generation_notice =
"// This file was generated automatially by gencpp's singleheader.cpp" "// This file was generated automatially by gencpp's singleheader.cpp"
"(See: https://github.com/Ed94/gencpp)\n\n"; "(See: https://github.com/Ed94/gencpp)\n\n";
constexpr StrC implementation_guard_start = txt(R"( constexpr Str implementation_guard_start = txt(R"(
#pragma region GENCPP IMPLEMENTATION GUARD #pragma region GENCPP IMPLEMENTATION GUARD
#if defined(GEN_IMPLEMENTATION) && ! defined(GEN_IMPLEMENTED) #if defined(GEN_IMPLEMENTATION) && ! defined(GEN_IMPLEMENTED)
# define GEN_IMPLEMENTED # define GEN_IMPLEMENTED
)"); )");
constexpr StrC implementation_guard_end = txt(R"( constexpr Str implementation_guard_end = txt(R"(
#endif #endif
#pragma endregion GENCPP IMPLEMENTATION GUARD #pragma endregion GENCPP IMPLEMENTATION GUARD
)"); )");
constexpr StrC roll_own_dependencies_guard_start = txt(R"( constexpr Str roll_own_dependencies_guard_start = txt(R"(
//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file. //! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file.
// Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl // Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
#ifndef GEN_ROLL_OWN_DEPENDENCIES #ifndef GEN_ROLL_OWN_DEPENDENCIES
)"); )");
constexpr StrC roll_own_dependencies_guard_end = txt(R"( constexpr Str roll_own_dependencies_guard_end = txt(R"(
// GEN_ROLL_OWN_DEPENDENCIES // GEN_ROLL_OWN_DEPENDENCIES
#endif #endif
)"); )");
@ -77,7 +77,7 @@ int gen_main()
Code basic_types = scan_file( path_base "dependencies/basic_types.hpp" ); Code basic_types = scan_file( path_base "dependencies/basic_types.hpp" );
Code debug = scan_file( path_base "dependencies/debug.hpp" ); Code debug = scan_file( path_base "dependencies/debug.hpp" );
Code memory = scan_file( path_base "dependencies/memory.hpp" ); Code memory = scan_file( path_base "dependencies/memory.hpp" );
Code string_ops = scan_file( path_base "dependencies/string_ops.hpp" ); Code stirng_ops = scan_file( path_base "dependencies/string_ops.hpp" );
Code printing = scan_file( path_base "dependencies/printing.hpp" ); Code printing = scan_file( path_base "dependencies/printing.hpp" );
Code containers = scan_file( path_base "dependencies/containers.hpp" ); Code containers = scan_file( path_base "dependencies/containers.hpp" );
Code hashing = scan_file( path_base "dependencies/hashing.hpp" ); Code hashing = scan_file( path_base "dependencies/hashing.hpp" );
@ -93,7 +93,7 @@ int gen_main()
header.print( basic_types ); header.print( basic_types );
header.print( debug ); header.print( debug );
header.print( memory ); header.print( memory );
header.print( string_ops ); header.print( stirng_ops );
header.print( printing ); header.print( printing );
header.print( containers ); header.print( containers );
header.print( hashing ); header.print( hashing );
@ -105,6 +105,7 @@ int gen_main()
header.print( scan_file( path_base "dependencies/parsing.hpp" ) ); header.print( scan_file( path_base "dependencies/parsing.hpp" ) );
} }
header.print(fmt_newline);
header.print_fmt( "GEN_NS_END\n" ); header.print_fmt( "GEN_NS_END\n" );
header.print_fmt( roll_own_dependencies_guard_end ); header.print_fmt( roll_own_dependencies_guard_end );
header.print( fmt_newline ); header.print( fmt_newline );
@ -155,7 +156,11 @@ int gen_main()
if ( generate_builder ) { if ( generate_builder ) {
header.print( scan_file( path_base "auxillary/builder.hpp" ) ); header.print( scan_file( path_base "auxillary/builder.hpp" ) );
} }
if ( generate_scanner ) {
header.print( scan_file( path_base "auxillary/scanner.hpp" ) );
}
header.print(fmt_newline);
header.print_fmt( "GEN_NS_END\n" ); header.print_fmt( "GEN_NS_END\n" );
} }
@ -176,9 +181,10 @@ int gen_main()
Code timing = scan_file( path_base "dependencies/timing.cpp" ); Code timing = scan_file( path_base "dependencies/timing.cpp" );
header.print_fmt( roll_own_dependencies_guard_start ); header.print_fmt( roll_own_dependencies_guard_start );
header.print_fmt( "GEN_NS_BEGIN\n\n");
header.print( impl_start ); header.print( impl_start );
header.print( fmt_newline );
header.print_fmt( "GEN_NS_BEGIN\n");
header.print( debug ); header.print( debug );
header.print( string_ops ); header.print( string_ops );
header.print( printing ); header.print( printing );
@ -209,8 +215,7 @@ int gen_main()
Code parsing_interface = scan_file( path_base "components/interface.parsing.cpp" ); Code parsing_interface = scan_file( path_base "components/interface.parsing.cpp" );
Code untyped = scan_file( path_base "components/interface.untyped.cpp" ); Code untyped = scan_file( path_base "components/interface.untyped.cpp" );
CodeBody etoktype = gen_etoktype( path_base "enums/ETokType.csv", path_base "enums/AttributeTokens.csv" ); CodeBody etoktype = gen_etoktype( path_base "enums/ETokType.csv", path_base "enums/AttributeTokens.csv" );
CodeNS parser_nspace = def_namespace( name(parser), def_namespace_body( args(etoktype)) );
header.print_fmt( "\nGEN_NS_BEGIN\n"); header.print_fmt( "\nGEN_NS_BEGIN\n");
header.print( static_data ); header.print( static_data );
@ -225,27 +230,23 @@ int gen_main()
header.print( interface ); header.print( interface );
header.print( upfront ); header.print( upfront );
header.print_fmt( "\n#pragma region Parsing\n\n" ); header.print_fmt( "\n#pragma region Parsing\n\n" );
header.print( format(parser_nspace) ); header.print( format(etoktype) );
header.print( lexer ); header.print( lexer );
header.print( parser ); header.print( parser );
header.print( parsing_interface ); header.print( parsing_interface );
header.print_fmt( "\n#pragma endregion Parsing\n" ); header.print_fmt( "\n#pragma endregion Parsing\n" );
header.print( untyped ); header.print( untyped );
header.print_fmt( "\n#pragma endregion Interface\n\n"); header.print_fmt( "\n#pragma endregion Interface\n");
if ( generate_builder ) { if ( generate_builder ) {
header.print( scan_file( path_base "auxillary/builder.cpp" ) ); header.print( scan_file( path_base "auxillary/builder.cpp" ) );
} }
// Scanner header depends on implementation
if ( generate_scanner ) {
header.print( scan_file( path_base "auxillary/scanner.hpp" ) );
}
if ( generate_scanner ) { if ( generate_scanner ) {
header.print( scan_file( path_base "auxillary/scanner.cpp" ) ); header.print( scan_file( path_base "auxillary/scanner.cpp" ) );
} }
header.print( fmt_newline);
header.print_fmt( "GEN_NS_END\n"); header.print_fmt( "GEN_NS_END\n");
header.print_fmt( "%s\n", (char const*) implementation_guard_end ); header.print_fmt( "%s\n", (char const*) implementation_guard_end );

View File

@ -17,25 +17,25 @@ constexpr char const* generation_notice =
"// This file was generated automatially by gencpp's unreal.cpp " "// This file was generated automatially by gencpp's unreal.cpp "
"(See: https://github.com/Ed94/gencpp)\n\n"; "(See: https://github.com/Ed94/gencpp)\n\n";
constexpr StrC implementation_guard_start = txt(R"( constexpr Str implementation_guard_start = txt(R"(
#pragma region GENCPP IMPLEMENTATION GUARD #pragma region GENCPP IMPLEMENTATION GUARD
#if defined(GEN_IMPLEMENTATION) && ! defined(GEN_IMPLEMENTED) #if defined(GEN_IMPLEMENTATION) && ! defined(GEN_IMPLEMENTED)
# define GEN_IMPLEMENTED # define GEN_IMPLEMENTED
)"); )");
constexpr StrC implementation_guard_end = txt(R"( constexpr Str implementation_guard_end = txt(R"(
#endif #endif
#pragma endregion GENCPP IMPLEMENTATION GUARD #pragma endregion GENCPP IMPLEMENTATION GUARD
)"); )");
constexpr StrC roll_own_dependencies_guard_start = txt(R"( constexpr Str roll_own_dependencies_guard_start = txt(R"(
//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file. //! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file.
// Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl // Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
#ifndef GEN_ROLL_OWN_DEPENDENCIES #ifndef GEN_ROLL_OWN_DEPENDENCIES
)"); )");
constexpr StrC roll_own_dependencies_guard_end = txt(R"( constexpr Str roll_own_dependencies_guard_end = txt(R"(
// GEN_ROLL_OWN_DEPENDENCIES // GEN_ROLL_OWN_DEPENDENCIES
#endif #endif
)"); )");
@ -68,7 +68,7 @@ int gen_main()
CodeBody macros = def_body( CT_Global_Body ); CodeBody macros = def_body( CT_Global_Body );
{ {
FileContents content = file_read_contents( GlobalAllocator, true, path_base "dependencies/macros.hpp" ); FileContents content = file_read_contents( GlobalAllocator, true, path_base "dependencies/macros.hpp" );
CodeBody ori_macros = parse_global_body( StrC { content.size, (char const*)content.data }); CodeBody ori_macros = parse_global_body( Str { (char const*)content.data, content.size });
for (Code code = ori_macros.begin(); for (Code code = ori_macros.begin();
code != ori_macros.end(); code != ori_macros.end();
@ -173,7 +173,7 @@ int gen_main()
// gen.hpp // gen.hpp
{ {
Code header_start = scan_file( "components/header_start.hpp" ); Code header_start = scan_file( "components/header_start.hpp" );
Code types = scan_file( path_base "components/types.hpp" ); Code types = scan_file( path_base "components/types.hpp" );
Code ast = scan_file( path_base "components/ast.hpp" ); Code ast = scan_file( path_base "components/ast.hpp" );
Code ast_types = scan_file( path_base "components/ast_types.hpp" ); Code ast_types = scan_file( path_base "components/ast_types.hpp" );
@ -223,7 +223,7 @@ int gen_main()
header.print_fmt( "#pragma endregion Inlines\n" ); header.print_fmt( "#pragma endregion Inlines\n" );
header.print( header_end ); header.print( header_end );
header.print_fmt( "GEN_NS_END\n\n" ); header.print_fmt( "\nGEN_NS_END\n\n" );
header.print( pop_ignores ); header.print( pop_ignores );
header.write(); header.write();
} }
@ -294,7 +294,7 @@ int gen_main()
header.print( def_include( txt("gen.hpp") )); header.print( def_include( txt("gen.hpp") ));
header.print_fmt( "\nGEN_NS_BEGIN\n" ); header.print_fmt( "\nGEN_NS_BEGIN\n" );
header.print( builder ); header.print( builder );
header.print_fmt( "GEN_NS_END\n" ); header.print_fmt( "\nGEN_NS_END\n" );
header.print( fmt_newline ); header.print( fmt_newline );
header.print( pop_ignores ); header.print( pop_ignores );
header.write(); header.write();
@ -333,7 +333,7 @@ int gen_main()
header.print_fmt( "\nGEN_NS_BEGIN\n" ); header.print_fmt( "\nGEN_NS_BEGIN\n" );
header.print( parsing ); header.print( parsing );
header.print( scanner ); header.print( scanner );
header.print_fmt( "GEN_NS_END\n" ); header.print_fmt( "\nGEN_NS_END\n" );
header.print( fmt_newline ); header.print( fmt_newline );
header.print( pop_ignores ); header.print( pop_ignores );
header.write(); header.write();
@ -353,7 +353,7 @@ int gen_main()
src.print_fmt( "\nGEN_NS_BEGIN\n" ); src.print_fmt( "\nGEN_NS_BEGIN\n" );
src.print( parsing ); src.print( parsing );
// src.print( scanner ); // src.print( scanner );
src.print_fmt( "GEN_NS_END\n" ); src.print_fmt( "\nGEN_NS_END\n" );
src.print( fmt_newline ); src.print( fmt_newline );
src.print( pop_ignores ); src.print( pop_ignores );
src.write(); src.write();

View File

@ -1,3 +1,3 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> <wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=53AF600D_002DC09C_002D4F39_002D83E0_002DE022AA9479F2_002Fd_003Athirdparty_002Ff_003Azpl_002Eh/@EntryIndexedValue">ForceIncluded</s:String> <s:StrBuilder x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=53AF600D_002DC09C_002D4F39_002D83E0_002DE022AA9479F2_002Fd_003Athirdparty_002Ff_003Azpl_002Eh/@EntryIndexedValue">ForceIncluded</s:StrBuilder>
<s:String x:Key="/Default/CodeInspection/Highlighting/SweaWarningsMode/@EntryValue">ShowAndRun</s:String></wpf:ResourceDictionary> <s:StrBuilder x:Key="/Default/CodeInspection/Highlighting/SweaWarningsMode/@EntryValue">ShowAndRun</s:StrBuilder></wpf:ResourceDictionary>

View File

@ -21,10 +21,10 @@
<Action>NoStepInto</Action> <Action>NoStepInto</Action>
</Function> </Function>
<Function> <Function>
<Name>gen::Code.*::to_string</Name> <Name>gen::Code.*::to_strbuilder</Name>
<Action>NoStepInto</Action> <Action>NoStepInto</Action>
</Function> </Function>
<Function> <Function>
<Name>gen::String::operator .*</Name> <Name>gen::StrBuilder::operator .*</Name>
</Function> </Function>
</StepFilter> </StepFilter>

View File

@ -36,11 +36,11 @@
</Expand> </Expand>
</Type> </Type>
<Type Name="gen::StrC"> <Type Name="gen::Str">
<DisplayString>Len:{Len} Ptr:{Ptr, [Len]s}</DisplayString> <DisplayString>Len:{Len} Ptr:{Ptr, [Len]s}</DisplayString>
</Type> </Type>
<Type Name="gen::String"> <Type Name="gen::StrBuilder">
<DisplayString Condition="Data == nullptr">null</DisplayString> <DisplayString Condition="Data == nullptr">null</DisplayString>
<DisplayString>{Data,na}</DisplayString> <DisplayString>{Data,na}</DisplayString>
<Expand> <Expand>
@ -55,7 +55,7 @@
</Expand> </Expand>
</Type> </Type>
<Type Name="gen::String::Header"> <Type Name="gen::StrBuilder::Header">
<DisplayString>Length: {Length}, Capacity: {Capacity}</DisplayString> <DisplayString>Length: {Length}, Capacity: {Capacity}</DisplayString>
<Expand> <Expand>
<Item Name="Allocator">Allocator</Item> <Item Name="Allocator">Allocator</Item>
@ -266,7 +266,7 @@
</Expand> </Expand>
</Type> </Type>
<Type Name="gen::AST_Param"> <Type Name="gen::AST_Params">
<DisplayString>{Name} Type: {Type}</DisplayString> <DisplayString>{Name} Type: {Type}</DisplayString>
<Expand> <Expand>
<Item Name="ValueType">ValueType</Item> <Item Name="ValueType">ValueType</Item>
@ -553,7 +553,7 @@
</Expand> </Expand>
</Type> </Type>
<Type Name="gen::CodeParam"> <Type Name="gen::CodeParams">
<DisplayString Condition="ast == nullptr">Null</DisplayString> <DisplayString Condition="ast == nullptr">Null</DisplayString>
<DisplayString Condition="ast != nullptr">{ast->Name} {ast->Type}</DisplayString> <DisplayString Condition="ast != nullptr">{ast->Name} {ast->Type}</DisplayString>
<Expand> <Expand>

View File

@ -197,11 +197,11 @@ if ( $vendor -match "clang" )
$compiler_args += $flag_no_optimization $compiler_args += $flag_no_optimization
} }
if ( $debug ) { if ( $debug ) {
$compiler_args += ( $flag_define + 'Build_Debug=1' ) $compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=1' )
$compiler_args += $flag_debug, $flag_debug_codeview, $flag_profiling_debug $compiler_args += $flag_debug, $flag_debug_codeview, $flag_profiling_debug
} }
else { else {
$compiler_args += ( $flag_define + 'Build_Debug=0' ) $compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=0' )
} }
$warning_ignores | ForEach-Object { $warning_ignores | ForEach-Object {
@ -277,11 +277,11 @@ if ( $vendor -match "clang" )
$compiler_args += $flag_no_optimization $compiler_args += $flag_no_optimization
} }
if ( $debug ) { if ( $debug ) {
$compiler_args += ( $flag_define + 'Build_Debug=1' ) $compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=1' )
$compiler_args += $flag_debug, $flag_debug_codeview, $flag_profiling_debug $compiler_args += $flag_debug, $flag_debug_codeview, $flag_profiling_debug
} }
else { else {
$compiler_args += ( $flag_define + 'Build_Debug=0' ) $compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=0' )
} }
$warning_ignores | ForEach-Object { $warning_ignores | ForEach-Object {
@ -402,7 +402,7 @@ if ( $vendor -match "msvc" )
if ( $debug ) if ( $debug )
{ {
$compiler_args += $flag_debug $compiler_args += $flag_debug
$compiler_args += ( $flag_define + 'Build_Debug=1' ) $compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=1' )
$compiler_args += ( $flag_path_debug + $path_output + '\' ) $compiler_args += ( $flag_path_debug + $path_output + '\' )
$compiler_args += $flag_link_win_rt_static_debug $compiler_args += $flag_link_win_rt_static_debug
@ -412,7 +412,7 @@ if ( $vendor -match "msvc" )
} }
} }
else { else {
$compiler_args += ( $flag_define + 'Build_Debug=0' ) $compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=0' )
$compiler_args += $flag_link_win_rt_static $compiler_args += $flag_link_win_rt_static
} }
$compiler_args += $includes | ForEach-Object { $flag_include + $_ } $compiler_args += $includes | ForEach-Object { $flag_include + $_ }
@ -489,7 +489,7 @@ if ( $vendor -match "msvc" )
if ( $debug ) if ( $debug )
{ {
$compiler_args += $flag_debug $compiler_args += $flag_debug
$compiler_args += ( $flag_define + 'Build_Debug=1' ) $compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=1' )
$compiler_args += ( $flag_path_debug + $path_output + '\' ) $compiler_args += ( $flag_path_debug + $path_output + '\' )
$compiler_args += $flag_link_win_rt_static_debug $compiler_args += $flag_link_win_rt_static_debug
@ -498,7 +498,7 @@ if ( $vendor -match "msvc" )
} }
} }
else { else {
$compiler_args += ( $flag_define + 'Build_Debug=0' ) $compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=0' )
$compiler_args += $flag_link_win_rt_static $compiler_args += $flag_link_win_rt_static
} }
$compiler_args += $includes | ForEach-Object { $flag_include + $_ } $compiler_args += $includes | ForEach-Object { $flag_include + $_ }

View File

@ -30,15 +30,32 @@ struct AnotherTemplate {
T value; T value;
}; };
typedef decltype(nullptr) (MyClass::*InsaneComplexTypeDef) typedef decltype(nullptr) ( MyClass:: * InsaneComplexTypeDef )
( (
decltype((MyEnum::VAL1 == MyEnum::VAL2) ? 1 : 2.0)(TemplateStruct<decltype(OuterStruct().unionInstance.inner), 5>::*ptr)[5][alignof(double)], decltype( (MyEnum::VAL1 == MyEnum::VAL2) ? 1 : 2.0 )
std::function<void *(TemplateStruct<int, 10>&&, void (MyClass::*memFnPtr)(TemplateStruct<decltype(OuterStruct().unionInstance.inner)>))>, ( TemplateStruct< decltype(OuterStruct().unionInstance.inner), 5> :: * ptr ) [5] [ alignof(double) ],
int (MyClass::*&refToMemFnPtr)(TemplateStruct<int, 10>), std::function<
int (TemplateStruct<int, 10>::*memberPointer)[10], void *
typename std::tuple_element<0, std::tuple<AnotherTemplate<TemplateStruct<decltype(OuterStruct().unionInstance), 3>>>>::type::*complexMember, (
template<typename U> typename AnotherTemplate<U>::*templateMember TemplateStruct<int, 10> &&,
void ( MyClass:: * memFnPtr )(
TemplateStruct<
decltype(OuterStruct().unionInstance.inner)
>
)
)
>,
int ( MyClass :: * & refToMemFnPtr )( TemplateStruct<int, 10> ) ,
int ( TemplateStruct<int, 10>:: * memberPointer) [10],
typename std::tuple_element<
0,
std::tuple<
AnotherTemplate<
TemplateStruct< decltype(OuterStruct().unionInstance), 3 >
>
>
> :: type :: * complexMember,
template<typename U> typename AnotherTemplate<U> :: * templateMember
char&&..., char&&...,
) )
volatile const && noexcept; volatile const && noexcept;