From 2c51a2f9c8ef41254b85fde095b57ecd73a605e1 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Tue, 10 Dec 2024 16:13:14 -0500 Subject: [PATCH] WIP: Restructuring project --- .vscode/c_cpp_properties.json | 2 +- base/Readme.md | 68 +++ {project => base}/auxillary/builder.cpp | 3 + {project => base}/auxillary/builder.hpp | 18 +- {project => base}/auxillary/gen_template.hpp | 14 +- {project => base}/auxillary/scanner.cpp | 0 {project => base}/auxillary/scanner.hpp | 86 ++-- base/base.cpp | 56 ++ {project => base}/components/ast.cpp | 0 {project => base}/components/ast.hpp | 0 .../components/ast_case_macros.cpp | 0 {project => base}/components/ast_types.hpp | 0 .../components/code_serialization.cpp | 0 {project => base}/components/code_types.hpp | 0 .../components/gen/ast_inlines.hpp | 0 {project => base}/components/gen/ecode.hpp | 0 .../components/gen/eoperator.hpp | 0 .../components/gen/especifier.hpp | 0 {project => base}/components/gen/etoktype.cpp | 0 {project => base}/components/header_end.hpp | 0 {project => base}/components/header_start.hpp | 0 {project => base}/components/inlines.hpp | 0 {project => base}/components/interface.cpp | 0 {project => base}/components/interface.hpp | 0 .../components/interface.parsing.cpp | 0 .../components/interface.untyped.cpp | 0 .../components/interface.upfront.cpp | 0 {project => base}/components/lexer.cpp | 0 {project => base}/components/parser.cpp | 0 {project => base}/components/src_start.cpp | 0 {project => base}/components/static_data.cpp | 0 {project => base}/components/types.hpp | 0 .../dependencies/basic_types.hpp | 0 {project => base}/dependencies/containers.hpp | 0 {project => base}/dependencies/debug.cpp | 0 {project => base}/dependencies/debug.hpp | 0 {project => base}/dependencies/filesystem.cpp | 0 {project => base}/dependencies/filesystem.hpp | 0 {project => base}/dependencies/hashing.cpp | 0 {project => base}/dependencies/hashing.hpp | 0 {project => base}/dependencies/macros.hpp | 0 {project => base}/dependencies/memory.cpp | 0 {project => base}/dependencies/memory.hpp | 0 {project => base}/dependencies/parsing.cpp | 0 {project => base}/dependencies/parsing.hpp | 0 {project => base}/dependencies/platform.hpp | 0 {project => base}/dependencies/printing.cpp | 0 {project => base}/dependencies/printing.hpp | 0 {project => base}/dependencies/src_start.cpp | 0 {project => base}/dependencies/string_ops.cpp | 0 {project => base}/dependencies/string_ops.hpp | 0 {project => base}/dependencies/strings.cpp | 0 {project => base}/dependencies/strings.hpp | 0 {project => base}/dependencies/timing.cpp | 0 {project => base}/dependencies/timing.hpp | 0 {project => base}/enums/AttributeTokens.csv | 0 {project => base}/enums/ECodeTypes.csv | 0 .../enums/ECode_ExecutionSupport.csv | 0 {project => base}/enums/EOperator.csv | 0 {project => base}/enums/ESpecifier.csv | 0 {project => base}/enums/ETokType.csv | 0 .../enums/ETokType_ExecutionSupport.csv | 0 {project => base}/gen.cpp | 0 {project => base}/gen.dep.cpp | 0 {project => base}/gen.dep.hpp | 0 {project => base}/gen.hpp | 3 + {project => base}/gencpp.refactor | 0 .../helpers/base_codegen.hpp | 79 +-- base/helpers/misc.hpp | 86 ++++ .../helpers/pop_container_defines.inline.hpp | 0 .../helpers/pop_ignores.inline.hpp | 0 .../helpers/push_container_defines.inline.hpp | 0 .../helpers/push_ignores.inline.hpp | 0 .../helpers/undef.macros.h | 0 gen_c_library/c_library.cpp | 20 +- gen_c_library/c_library.refactor | 12 +- gen_segemented/Readme.md | 15 + .../segemented.cpp | 64 +-- project/Readme.md | 66 --- project/helpers/member_proc_support.hpp | 10 - scripts/build.ci.ps1 | 118 ++--- test/Readme.md | 5 +- test/SOA.cpp | 146 ------ test/Unreal/Readme.md | 25 - test/Unreal/validate.ps1 | 0 test/Unreal/validate.unreal.cpp | 0 test/_old/parsed/Array.Parsed.hpp | 294 ----------- test/_old/parsed/Buffer.Parsed.hpp | 205 -------- test/_old/parsed/HashTable.Parsed.hpp | 359 ------------- test/_old/parsed/Ring.Parsed.hpp | 175 ------- test/_old/parsed/Sanity.Parsed.hpp | 344 ------------- test/_old/parsed/test.parsing.cpp | 75 --- test/_old/upfront/Array.Upfront.hpp | 375 -------------- test/_old/upfront/Buffer.Upfront.hpp | 275 ---------- test/_old/upfront/HashTable.Upfront.hpp | 486 ------------------ test/_old/upfront/Ring.Upfront.hpp | 228 -------- test/_old/upfront/Sanity.Upfront.hpp | 331 ------------ test/_old/upfront/test.upfront.cpp | 49 -- test/parsing.cpp | 0 test/parsing.hpp | 21 - test/sanity.cpp | 95 ---- test/test.cpp | 81 --- test/upfront.cpp | 0 test/upfront.hpp | 21 - test/validate.bootstrap.cpp | 3 - test/validate.original.cpp | 186 ------- test/validate.singleheader.cpp | 86 ---- 107 files changed, 417 insertions(+), 4168 deletions(-) create mode 100644 base/Readme.md rename {project => base}/auxillary/builder.cpp (96%) rename {project => base}/auxillary/builder.hpp (75%) rename {project => base}/auxillary/gen_template.hpp (65%) rename {project => base}/auxillary/scanner.cpp (100%) rename {project => base}/auxillary/scanner.hpp (60%) create mode 100644 base/base.cpp rename {project => base}/components/ast.cpp (100%) rename {project => base}/components/ast.hpp (100%) rename {project => base}/components/ast_case_macros.cpp (100%) rename {project => base}/components/ast_types.hpp (100%) rename {project => base}/components/code_serialization.cpp (100%) rename {project => base}/components/code_types.hpp (100%) rename {project => base}/components/gen/ast_inlines.hpp (100%) rename {project => base}/components/gen/ecode.hpp (100%) rename {project => base}/components/gen/eoperator.hpp (100%) rename {project => base}/components/gen/especifier.hpp (100%) rename {project => base}/components/gen/etoktype.cpp (100%) rename {project => base}/components/header_end.hpp (100%) rename {project => base}/components/header_start.hpp (100%) rename {project => base}/components/inlines.hpp (100%) rename {project => base}/components/interface.cpp (100%) rename {project => base}/components/interface.hpp (100%) rename {project => base}/components/interface.parsing.cpp (100%) rename {project => base}/components/interface.untyped.cpp (100%) rename {project => base}/components/interface.upfront.cpp (100%) rename {project => base}/components/lexer.cpp (100%) rename {project => base}/components/parser.cpp (100%) rename {project => base}/components/src_start.cpp (100%) rename {project => base}/components/static_data.cpp (100%) rename {project => base}/components/types.hpp (100%) rename {project => base}/dependencies/basic_types.hpp (100%) rename {project => base}/dependencies/containers.hpp (100%) rename {project => base}/dependencies/debug.cpp (100%) rename {project => base}/dependencies/debug.hpp (100%) rename {project => base}/dependencies/filesystem.cpp (100%) rename {project => base}/dependencies/filesystem.hpp (100%) rename {project => base}/dependencies/hashing.cpp (100%) rename {project => base}/dependencies/hashing.hpp (100%) rename {project => base}/dependencies/macros.hpp (100%) rename {project => base}/dependencies/memory.cpp (100%) rename {project => base}/dependencies/memory.hpp (100%) rename {project => base}/dependencies/parsing.cpp (100%) rename {project => base}/dependencies/parsing.hpp (100%) rename {project => base}/dependencies/platform.hpp (100%) rename {project => base}/dependencies/printing.cpp (100%) rename {project => base}/dependencies/printing.hpp (100%) rename {project => base}/dependencies/src_start.cpp (100%) rename {project => base}/dependencies/string_ops.cpp (100%) rename {project => base}/dependencies/string_ops.hpp (100%) rename {project => base}/dependencies/strings.cpp (100%) rename {project => base}/dependencies/strings.hpp (100%) rename {project => base}/dependencies/timing.cpp (100%) rename {project => base}/dependencies/timing.hpp (100%) rename {project => base}/enums/AttributeTokens.csv (100%) rename {project => base}/enums/ECodeTypes.csv (100%) rename {project => base}/enums/ECode_ExecutionSupport.csv (100%) rename {project => base}/enums/EOperator.csv (100%) rename {project => base}/enums/ESpecifier.csv (100%) rename {project => base}/enums/ETokType.csv (100%) rename project/enums/ETokType_New.csv => base/enums/ETokType_ExecutionSupport.csv (100%) rename {project => base}/gen.cpp (100%) rename {project => base}/gen.dep.cpp (100%) rename {project => base}/gen.dep.hpp (100%) rename {project => base}/gen.hpp (92%) rename {project => base}/gencpp.refactor (100%) rename project/helpers/helper.hpp => base/helpers/base_codegen.hpp (93%) create mode 100644 base/helpers/misc.hpp rename {project => base}/helpers/pop_container_defines.inline.hpp (100%) rename {project => base}/helpers/pop_ignores.inline.hpp (100%) rename {project => base}/helpers/push_container_defines.inline.hpp (100%) rename {project => base}/helpers/push_ignores.inline.hpp (100%) rename project/helpers/undef.macros.hpp => base/helpers/undef.macros.h (100%) create mode 100644 gen_segemented/Readme.md rename project/bootstrap.cpp => gen_segemented/segemented.cpp (83%) delete mode 100644 project/Readme.md delete mode 100644 project/helpers/member_proc_support.hpp delete mode 100644 test/SOA.cpp delete mode 100644 test/Unreal/Readme.md delete mode 100644 test/Unreal/validate.ps1 delete mode 100644 test/Unreal/validate.unreal.cpp delete mode 100644 test/_old/parsed/Array.Parsed.hpp delete mode 100644 test/_old/parsed/Buffer.Parsed.hpp delete mode 100644 test/_old/parsed/HashTable.Parsed.hpp delete mode 100644 test/_old/parsed/Ring.Parsed.hpp delete mode 100644 test/_old/parsed/Sanity.Parsed.hpp delete mode 100644 test/_old/parsed/test.parsing.cpp delete mode 100644 test/_old/upfront/Array.Upfront.hpp delete mode 100644 test/_old/upfront/Buffer.Upfront.hpp delete mode 100644 test/_old/upfront/HashTable.Upfront.hpp delete mode 100644 test/_old/upfront/Ring.Upfront.hpp delete mode 100644 test/_old/upfront/Sanity.Upfront.hpp delete mode 100644 test/_old/upfront/test.upfront.cpp delete mode 100644 test/parsing.cpp delete mode 100644 test/parsing.hpp delete mode 100644 test/sanity.cpp delete mode 100644 test/test.cpp delete mode 100644 test/upfront.cpp delete mode 100644 test/upfront.hpp delete mode 100644 test/validate.bootstrap.cpp delete mode 100644 test/validate.original.cpp delete mode 100644 test/validate.singleheader.cpp diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 562da8a..8fcd4f7 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -3,7 +3,7 @@ { "name": "Bootstrap", "includePath": [ - "${workspaceFolder}/project/**" + "${workspaceFolder}/base/**" ], "defines": [ "_DEBUG", diff --git a/base/Readme.md b/base/Readme.md new file mode 100644 index 0000000..efd2160 --- /dev/null +++ b/base/Readme.md @@ -0,0 +1,68 @@ +# Documentation + +The library is fragmented into a series of headers and source files meant to be scanned in and then generated to a standard target format, or a user's desires. + +Standard formats: + +* **base**: Files are in granular pieces separated into four directories: + * **dependencies**: Originally from the c-zpl library and modified thereafter. + * **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. + * `base_codegen.hpp`: Helps with self-hosted code generation of enums, and operator overload inlines of the code types. + * `..inline.`: macros that are meant to be injected at specific locations of the library. + * `misc.hpp`: + * `undef.macros.h`: Undefines all macros from library that original were intended to leak into user code. + * **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`). + * **`Scanner`**: Interface to load up `Code` from files two basic funcctions are currently provided. + * `scan_file`: Used mainly by the library format generators to directly scan files into untyped `Code` (raw string content, pre-formatted no AST parsed). + * `parse_file`: Used to read file and then parsed to populate a `CodeBody` AST. +* **gen_segemetned**: Dependencies go into gen.dep.{hpp/cpp} and components into gen.{hpp/cpp} +* **gen_singleheader**: Everything into a single file: gen.hpp +* **gen_unreal_engine**: Like gen_segemented but the library is modified slightly to compile as a thirdparty library within an Unreal Engine plugin or module. +* **gen_c_library**: The library is heavily modifed into C11 compliant code. A segemented and single-header set of variants are generatd. + + +Code not making up the core library is located in `auxiliary/.`. These are optional extensions or tools for the library. + +Feature Macros: + +* `GEN_DEFINE_ATTRIBUTE_TOKENS` : Allows user to define their own attribute macros for use in parsing. + * This is auto-generated if using the bootstrap or single-header generation + * *Note: The user will use the `AttributeTokens.csv` when the library is fully self-hosting.* +* `GEN_DEFINE_LIBRARY_CORE_CONSTANTS` : Optional typename codes as they are non-standard to C/C++ and not necessary to library usage +* `GEN_DONT_ENFORCE_GEN_TIME_GUARD` : By default, the library ( gen.hpp/ gen.cpp ) expects the macro `GEN_TIME` to be defined, this disables that. +* `GEN_ENFORCE_STRONG_CODE_TYPES` : Enforces casts to filtered code types. +* `GEN_EXPOSE_BACKEND` : Will expose symbols meant for internal use only. +* `GEN_ROLL_OWN_DEPENDENCIES` : Optional override so that user may define the dependencies themselves. +* `GEN_DONT_ALLOW_INVALID_CODE` (Not implemented yet) : Will fail when an invalid code is constructed, parsed, or serialized. +* `GEN_C_LIKE_PP` : Will prevent usage of function defnitions using references and structs with member functions. +Structs will still have user-defined operator conversions, for-range support, and other operator overloads + +*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)* + +## 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. + +## Extending the library + +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: + +1. Check name or parameters to make sure they are valid for the construction requested +2. Create a code object using `make_code`. +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). + +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. + +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. + +## A note on compilation and runtime generation speed + +The library is designed to be fast to compile and generate code at runtime as fast as resonable possible on a debug build. +Its recommended that your metaprogam be compiled using a single translation unit (unity build). diff --git a/project/auxillary/builder.cpp b/base/auxillary/builder.cpp similarity index 96% rename from project/auxillary/builder.cpp rename to base/auxillary/builder.cpp index 184c2e7..eb5e931 100644 --- a/project/auxillary/builder.cpp +++ b/base/auxillary/builder.cpp @@ -2,6 +2,8 @@ # include "builder.hpp" #endif +#pragma region Builder + Builder builder_open( char const* path ) { Builder result; @@ -54,3 +56,4 @@ void builder_write(Builder* builder) string_free(& builder->Buffer); } +#pragma endregion Builder diff --git a/project/auxillary/builder.hpp b/base/auxillary/builder.hpp similarity index 75% rename from project/auxillary/builder.hpp rename to base/auxillary/builder.hpp index ef182bb..7d92fda 100644 --- a/project/auxillary/builder.hpp +++ b/base/auxillary/builder.hpp @@ -1,8 +1,22 @@ #ifdef GEN_INTELLISENSE_DIRECTIVES # pragma once -# include "gen.hpp" +# include "helpers/push_ignores.inline.hpp" +# include "components/header_start.hpp" +# include "components/types.hpp" +# include "components/gen/ecode.hpp" +# include "components/gen/eoperator.hpp" +# include "components/gen/especifier.hpp" +# include "components/ast.hpp" +# include "components/code_types.hpp" +# include "components/ast_types.hpp" +# include "components/interface.hpp" +# include "components/inlines.hpp" +# include "components/gen/ast_inlines.hpp" +# include "components/header_end.hpp" #endif +#pragma region Builder + struct Builder; typedef struct Builder Builder; @@ -51,3 +65,5 @@ void builder_print_fmt( Builder& builder, char const* fmt, ...) { va_end( va ); } #endif + +#pragma endregion Builder diff --git a/project/auxillary/gen_template.hpp b/base/auxillary/gen_template.hpp similarity index 65% rename from project/auxillary/gen_template.hpp rename to base/auxillary/gen_template.hpp index 0f1d7b0..101f7de 100644 --- a/project/auxillary/gen_template.hpp +++ b/base/auxillary/gen_template.hpp @@ -1,6 +1,18 @@ #ifdef GEN_INTELLISENSE_DIRECTIVES # pragma once -# include "../gen.hpp" +# include "helpers/push_ignores.inline.hpp" +# include "components/header_start.hpp" +# include "components/types.hpp" +# include "components/gen/ecode.hpp" +# include "components/gen/eoperator.hpp" +# include "components/gen/especifier.hpp" +# include "components/ast.hpp" +# include "components/code_types.hpp" +# include "components/ast_types.hpp" +# include "components/interface.hpp" +# include "components/inlines.hpp" +# include "components/gen/ast_inlines.hpp" +# include "components/header_end.hpp" #endif /* diff --git a/project/auxillary/scanner.cpp b/base/auxillary/scanner.cpp similarity index 100% rename from project/auxillary/scanner.cpp rename to base/auxillary/scanner.cpp diff --git a/project/auxillary/scanner.hpp b/base/auxillary/scanner.hpp similarity index 60% rename from project/auxillary/scanner.hpp rename to base/auxillary/scanner.hpp index f1aaeb6..4ef4222 100644 --- a/project/auxillary/scanner.hpp +++ b/base/auxillary/scanner.hpp @@ -1,8 +1,22 @@ #ifdef GEN_INTELLISENSE_DIRECTIVES # pragma once -# include "gen.hpp" +# include "helpers/push_ignores.inline.hpp" +# include "components/header_start.hpp" +# include "components/types.hpp" +# include "components/gen/ecode.hpp" +# include "components/gen/eoperator.hpp" +# include "components/gen/especifier.hpp" +# include "components/ast.hpp" +# include "components/code_types.hpp" +# include "components/ast_types.hpp" +# include "components/interface.hpp" +# include "components/inlines.hpp" +# include "components/gen/ast_inlines.hpp" +# include "components/header_end.hpp" #endif +#pragma region Scanner + // This is a simple file reader that reads the entire file into memory. // It has an extra option to skip the first few lines for undesired includes. // This is done so that includes can be kept in dependency and component files so that intellisense works. @@ -119,41 +133,53 @@ Code scan_file( char const* path ) return untyped_str( string_to_strc(str) ); } -#if 0 -struct CodeFile +CodeBody parse_file( const char* path ) { - using namespace Parser; + FileContents file = file_read_contents( GlobalAllocator, true, path ); + CodeBody code = parse_global_body( { file.size, (char const*)file.data } ); + log_fmt("\nParsed: %s\n", path); + return code; +} - String FilePath; - TokArray Tokens; - Array ParseFailures; - Code CodeRoot; +// The follow is basic support for light csv parsing (use it as an example) +// Make something robust if its more serious. + +typedef struct CSV_Column CSV_Column; +struct CSV_Column { + CSV_Object Owner; + Array Content; }; -namespace Parser -{ - struct ParseFailure - { - String Reason; - Code Node; - }; -} +typedef struct CSV_Columns2 CSV_Columns2; +struct CSV_Columns2 { + CSV_Object Owner; + Array Col_1; + Array Col_2; +}; -CodeFile scan_file( char const* path ) -{ - using namespace Parser; +CSV_Column parse_csv_one_column(AllocatorInfo allocator, char const* path) { + char scratch_mem[kilobytes(32)]; + Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) ); - CodeFile - result = {}; - result.FilePath = String::make( GlobalAllocator, path ); - - Code code = scan_file( path ); - result.CodeRoot = code; - - ParseContext context = parser_get_last_context(); - result.Tokens = context.Tokens; - result.ParseFailures = context.Failures; + file_read_contents( arena_allocator_info( & scratch), file_zero_terminate, path ); + CSV_Column result; + csv_parse( & result.owner, scratch_mem, allocator, false ); + result.Content = csv_nodes.nodes[0].nodes; return result; } -#endif + +CSV_Columns2 parse_csv_two_columns(AllocatorInfo allocator, char const* path) { + char scratch_mem[kilobytes(32)]; + Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) ); + + file_read_contents( arena_allocator_info( & scratch), file_zero_terminate, path ); + + CSV_Columns2 result; + csv_parse( & result.owner, scratch_mem, allocator, false ); + result.Col_1 = csv_nodes.nodes[0].nodes; + result.Col_2 = csv_nodes.nodes[1].nodes; + return result; +} + +#pragma endregion Scanner diff --git a/base/base.cpp b/base/base.cpp new file mode 100644 index 0000000..35703b6 --- /dev/null +++ b/base/base.cpp @@ -0,0 +1,56 @@ +#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS +#define GEN_ENFORCE_STRONG_CODE_TYPES +#define GEN_EXPOSE_BACKEND +#define GEN_C_LIKE_CPP 1 +#include "../project/gen.cpp" + +#include "helpers/push_ignores.inline.hpp" +#include "helpers/helper.hpp" + +GEN_NS_BEGIN +#include "helpers/push_container_defines.inline.hpp" +#include "dependencies/parsing.cpp" +#include "helpers/pop_container_defines.inline.hpp" +GEN_NS_END + +#include "auxillary/builder.hpp" +#include "auxillary/builder.cpp" +#include "auxillary/scanner.hpp" +#include "auxillary/misc.hpp" + +using namespace gen; + +constexpr char const* path_format_style = "../scripts/.clang-format"; +constexpr char const* scratch_file = "gen/scratch.hpp"; + +Code format( Code code ) { + return code_refactor_and_format(code, scratch_file, nullptr, path_format_style ); +} + +int gen_main() +{ + CodeBody ecode = gen_ecode ( "enums/ECodeTypes.csv" ); + CodeBody eoperator = gen_eoperator ( "enums/EOperator.csv" ); + CodeBody especifier = gen_especifier( "enums/ESpecifier.csv" ); + CodeBody ast_inlines = gen_ast_inlines(); + + Builder header_ecode = builder_open( "components/gen/ecode.hpp" ); + builder_print( & header_ecode, gen_component_header ); + builder_print( & header_ecode, format(ecode) ); + builder_write( & header_ecode); + + Builder header_eoperator = builder_open( "components/gen/eoperator.hpp" ); + builder_print( & header_eoperator, gen_component_header ); + builder_print( & header_eoperator, format(eoperator) ); + builder_write( & header_eoperator ); + + Builder header_especifier = builder_open( "components/gen/especifier.hpp" ); + builder_print( & header_especifier, gen_component_header ); + builder_print( & header_especifier, format(especifier) ); + builder_write( & header_especifier); + + Builder header_ast_inlines = builder_open( "components/gen/ast_inlines.hpp" ); + builder_print( & header_ast_inlines, gen_component_header ); + builder_print( & header_ast_inlines, format(ast_inlines) ); + builder_write( & header_ast_inlines); +} \ No newline at end of file diff --git a/project/components/ast.cpp b/base/components/ast.cpp similarity index 100% rename from project/components/ast.cpp rename to base/components/ast.cpp diff --git a/project/components/ast.hpp b/base/components/ast.hpp similarity index 100% rename from project/components/ast.hpp rename to base/components/ast.hpp diff --git a/project/components/ast_case_macros.cpp b/base/components/ast_case_macros.cpp similarity index 100% rename from project/components/ast_case_macros.cpp rename to base/components/ast_case_macros.cpp diff --git a/project/components/ast_types.hpp b/base/components/ast_types.hpp similarity index 100% rename from project/components/ast_types.hpp rename to base/components/ast_types.hpp diff --git a/project/components/code_serialization.cpp b/base/components/code_serialization.cpp similarity index 100% rename from project/components/code_serialization.cpp rename to base/components/code_serialization.cpp diff --git a/project/components/code_types.hpp b/base/components/code_types.hpp similarity index 100% rename from project/components/code_types.hpp rename to base/components/code_types.hpp diff --git a/project/components/gen/ast_inlines.hpp b/base/components/gen/ast_inlines.hpp similarity index 100% rename from project/components/gen/ast_inlines.hpp rename to base/components/gen/ast_inlines.hpp diff --git a/project/components/gen/ecode.hpp b/base/components/gen/ecode.hpp similarity index 100% rename from project/components/gen/ecode.hpp rename to base/components/gen/ecode.hpp diff --git a/project/components/gen/eoperator.hpp b/base/components/gen/eoperator.hpp similarity index 100% rename from project/components/gen/eoperator.hpp rename to base/components/gen/eoperator.hpp diff --git a/project/components/gen/especifier.hpp b/base/components/gen/especifier.hpp similarity index 100% rename from project/components/gen/especifier.hpp rename to base/components/gen/especifier.hpp diff --git a/project/components/gen/etoktype.cpp b/base/components/gen/etoktype.cpp similarity index 100% rename from project/components/gen/etoktype.cpp rename to base/components/gen/etoktype.cpp diff --git a/project/components/header_end.hpp b/base/components/header_end.hpp similarity index 100% rename from project/components/header_end.hpp rename to base/components/header_end.hpp diff --git a/project/components/header_start.hpp b/base/components/header_start.hpp similarity index 100% rename from project/components/header_start.hpp rename to base/components/header_start.hpp diff --git a/project/components/inlines.hpp b/base/components/inlines.hpp similarity index 100% rename from project/components/inlines.hpp rename to base/components/inlines.hpp diff --git a/project/components/interface.cpp b/base/components/interface.cpp similarity index 100% rename from project/components/interface.cpp rename to base/components/interface.cpp diff --git a/project/components/interface.hpp b/base/components/interface.hpp similarity index 100% rename from project/components/interface.hpp rename to base/components/interface.hpp diff --git a/project/components/interface.parsing.cpp b/base/components/interface.parsing.cpp similarity index 100% rename from project/components/interface.parsing.cpp rename to base/components/interface.parsing.cpp diff --git a/project/components/interface.untyped.cpp b/base/components/interface.untyped.cpp similarity index 100% rename from project/components/interface.untyped.cpp rename to base/components/interface.untyped.cpp diff --git a/project/components/interface.upfront.cpp b/base/components/interface.upfront.cpp similarity index 100% rename from project/components/interface.upfront.cpp rename to base/components/interface.upfront.cpp diff --git a/project/components/lexer.cpp b/base/components/lexer.cpp similarity index 100% rename from project/components/lexer.cpp rename to base/components/lexer.cpp diff --git a/project/components/parser.cpp b/base/components/parser.cpp similarity index 100% rename from project/components/parser.cpp rename to base/components/parser.cpp diff --git a/project/components/src_start.cpp b/base/components/src_start.cpp similarity index 100% rename from project/components/src_start.cpp rename to base/components/src_start.cpp diff --git a/project/components/static_data.cpp b/base/components/static_data.cpp similarity index 100% rename from project/components/static_data.cpp rename to base/components/static_data.cpp diff --git a/project/components/types.hpp b/base/components/types.hpp similarity index 100% rename from project/components/types.hpp rename to base/components/types.hpp diff --git a/project/dependencies/basic_types.hpp b/base/dependencies/basic_types.hpp similarity index 100% rename from project/dependencies/basic_types.hpp rename to base/dependencies/basic_types.hpp diff --git a/project/dependencies/containers.hpp b/base/dependencies/containers.hpp similarity index 100% rename from project/dependencies/containers.hpp rename to base/dependencies/containers.hpp diff --git a/project/dependencies/debug.cpp b/base/dependencies/debug.cpp similarity index 100% rename from project/dependencies/debug.cpp rename to base/dependencies/debug.cpp diff --git a/project/dependencies/debug.hpp b/base/dependencies/debug.hpp similarity index 100% rename from project/dependencies/debug.hpp rename to base/dependencies/debug.hpp diff --git a/project/dependencies/filesystem.cpp b/base/dependencies/filesystem.cpp similarity index 100% rename from project/dependencies/filesystem.cpp rename to base/dependencies/filesystem.cpp diff --git a/project/dependencies/filesystem.hpp b/base/dependencies/filesystem.hpp similarity index 100% rename from project/dependencies/filesystem.hpp rename to base/dependencies/filesystem.hpp diff --git a/project/dependencies/hashing.cpp b/base/dependencies/hashing.cpp similarity index 100% rename from project/dependencies/hashing.cpp rename to base/dependencies/hashing.cpp diff --git a/project/dependencies/hashing.hpp b/base/dependencies/hashing.hpp similarity index 100% rename from project/dependencies/hashing.hpp rename to base/dependencies/hashing.hpp diff --git a/project/dependencies/macros.hpp b/base/dependencies/macros.hpp similarity index 100% rename from project/dependencies/macros.hpp rename to base/dependencies/macros.hpp diff --git a/project/dependencies/memory.cpp b/base/dependencies/memory.cpp similarity index 100% rename from project/dependencies/memory.cpp rename to base/dependencies/memory.cpp diff --git a/project/dependencies/memory.hpp b/base/dependencies/memory.hpp similarity index 100% rename from project/dependencies/memory.hpp rename to base/dependencies/memory.hpp diff --git a/project/dependencies/parsing.cpp b/base/dependencies/parsing.cpp similarity index 100% rename from project/dependencies/parsing.cpp rename to base/dependencies/parsing.cpp diff --git a/project/dependencies/parsing.hpp b/base/dependencies/parsing.hpp similarity index 100% rename from project/dependencies/parsing.hpp rename to base/dependencies/parsing.hpp diff --git a/project/dependencies/platform.hpp b/base/dependencies/platform.hpp similarity index 100% rename from project/dependencies/platform.hpp rename to base/dependencies/platform.hpp diff --git a/project/dependencies/printing.cpp b/base/dependencies/printing.cpp similarity index 100% rename from project/dependencies/printing.cpp rename to base/dependencies/printing.cpp diff --git a/project/dependencies/printing.hpp b/base/dependencies/printing.hpp similarity index 100% rename from project/dependencies/printing.hpp rename to base/dependencies/printing.hpp diff --git a/project/dependencies/src_start.cpp b/base/dependencies/src_start.cpp similarity index 100% rename from project/dependencies/src_start.cpp rename to base/dependencies/src_start.cpp diff --git a/project/dependencies/string_ops.cpp b/base/dependencies/string_ops.cpp similarity index 100% rename from project/dependencies/string_ops.cpp rename to base/dependencies/string_ops.cpp diff --git a/project/dependencies/string_ops.hpp b/base/dependencies/string_ops.hpp similarity index 100% rename from project/dependencies/string_ops.hpp rename to base/dependencies/string_ops.hpp diff --git a/project/dependencies/strings.cpp b/base/dependencies/strings.cpp similarity index 100% rename from project/dependencies/strings.cpp rename to base/dependencies/strings.cpp diff --git a/project/dependencies/strings.hpp b/base/dependencies/strings.hpp similarity index 100% rename from project/dependencies/strings.hpp rename to base/dependencies/strings.hpp diff --git a/project/dependencies/timing.cpp b/base/dependencies/timing.cpp similarity index 100% rename from project/dependencies/timing.cpp rename to base/dependencies/timing.cpp diff --git a/project/dependencies/timing.hpp b/base/dependencies/timing.hpp similarity index 100% rename from project/dependencies/timing.hpp rename to base/dependencies/timing.hpp diff --git a/project/enums/AttributeTokens.csv b/base/enums/AttributeTokens.csv similarity index 100% rename from project/enums/AttributeTokens.csv rename to base/enums/AttributeTokens.csv diff --git a/project/enums/ECodeTypes.csv b/base/enums/ECodeTypes.csv similarity index 100% rename from project/enums/ECodeTypes.csv rename to base/enums/ECodeTypes.csv diff --git a/project/enums/ECode_ExecutionSupport.csv b/base/enums/ECode_ExecutionSupport.csv similarity index 100% rename from project/enums/ECode_ExecutionSupport.csv rename to base/enums/ECode_ExecutionSupport.csv diff --git a/project/enums/EOperator.csv b/base/enums/EOperator.csv similarity index 100% rename from project/enums/EOperator.csv rename to base/enums/EOperator.csv diff --git a/project/enums/ESpecifier.csv b/base/enums/ESpecifier.csv similarity index 100% rename from project/enums/ESpecifier.csv rename to base/enums/ESpecifier.csv diff --git a/project/enums/ETokType.csv b/base/enums/ETokType.csv similarity index 100% rename from project/enums/ETokType.csv rename to base/enums/ETokType.csv diff --git a/project/enums/ETokType_New.csv b/base/enums/ETokType_ExecutionSupport.csv similarity index 100% rename from project/enums/ETokType_New.csv rename to base/enums/ETokType_ExecutionSupport.csv diff --git a/project/gen.cpp b/base/gen.cpp similarity index 100% rename from project/gen.cpp rename to base/gen.cpp diff --git a/project/gen.dep.cpp b/base/gen.dep.cpp similarity index 100% rename from project/gen.dep.cpp rename to base/gen.dep.cpp diff --git a/project/gen.dep.hpp b/base/gen.dep.hpp similarity index 100% rename from project/gen.dep.hpp rename to base/gen.dep.hpp diff --git a/project/gen.hpp b/base/gen.hpp similarity index 92% rename from project/gen.hpp rename to base/gen.hpp index b3a0d05..38bf164 100644 --- a/project/gen.hpp +++ b/base/gen.hpp @@ -31,6 +31,9 @@ GEN_NS_BEGIN #include "components/gen/ast_inlines.hpp" #include "components/header_end.hpp" +#include "auxillary/builder.hpp" +#include "auxillary/scanner.hpp" + GEN_NS_END #include "helpers/pop_container_defines.inline.hpp" diff --git a/project/gencpp.refactor b/base/gencpp.refactor similarity index 100% rename from project/gencpp.refactor rename to base/gencpp.refactor diff --git a/project/helpers/helper.hpp b/base/helpers/base_codegen.hpp similarity index 93% rename from project/helpers/helper.hpp rename to base/helpers/base_codegen.hpp index 522f784..d133cbb 100644 --- a/project/helpers/helper.hpp +++ b/base/helpers/base_codegen.hpp @@ -2,50 +2,35 @@ #include "gen.hpp" -GEN_NS_BEGIN -#include "dependencies/parsing.hpp" -GEN_NS_END - using namespace gen; +#include "dependencies/parsing.hpp" +#include "misc.hpp" + CodeBody gen_ecode( char const* path, bool use_c_definition = false ) { - char scratch_mem[kilobytes(4)]; - Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) ); - - file_read_contents( arena_allocator_info( & scratch), file_zero_terminate, path ); - - CSV_Object csv_nodes; - csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false ); - - Array enum_strs = csv_nodes.nodes[0].nodes; - Array keyword_strs = csv_nodes.nodes[1].nodes; + CSV_Columns2 csv_enum = parse_csv_two_columns(GlobalAllocator, path ); String enum_entries = string_make_reserve( GlobalAllocator, kilobytes(1) ); String to_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) ); String to_keyword_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) ); - for ( ssize idx = 0; idx < array_num(enum_strs); ++ idx ) - { - char const* code = enum_strs [idx].string; - char const* keyword = keyword_strs[idx].string; - + for ( ssize idx = 0; idx < array_num(csv_enum.Col_1); ++ idx ) { + char const* code = csv_enum.Col_1[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. - string_append_fmt( & enum_entries, "CT_%s,\n", code ); string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", code, code ); string_append_fmt( & to_keyword_str_entries, "{ sizeof(\"%s\") - 1, \"%s\" },\n", keyword, keyword ); } CodeEnum enum_code; - 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 CodeType enum_underlying(u32) { 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 CodeType : u32 { CT_NumTypes, CT_UnderlyingType = GEN_U32_MAX };" )); @@ -53,7 +38,7 @@ CodeBody gen_ecode( char const* path, bool use_c_definition = false ) #pragma push_macro("local_persist") #undef local_persist - StrC lookup_size = string_to_strc(string_fmt_buf(GlobalAllocator, "%d", array_num(enum_strs) )); + StrC lookup_size = string_to_strc(string_fmt_buf(GlobalAllocator, "%d", array_num(csv_enum.Col_1) )); CodeBody to_str_fns = parse_global_body( token_fmt( "entries", string_to_strc(to_str_entries) , "keywords", string_to_strc(to_keyword_str_entries) @@ -84,16 +69,14 @@ CodeBody gen_ecode( char const* path, bool use_c_definition = false ) CodeBody result = def_body(CT_Global_Body); body_append(result, enum_code); - if (use_c_definition) - { + if (use_c_definition) { CodeTypedef code_t = parse_typedef(code(typedef enum CodeType CodeType; )); body_append(result, code_t); } body_append(result, to_str_fns); - if (! use_c_definition) - { + if (! use_c_definition) { #pragma push_macro("forceinline") #undef forceinline CodeBody alias_mappings = parse_global_body(code( @@ -108,24 +91,14 @@ CodeBody gen_ecode( char const* path, bool use_c_definition = false ) CodeBody gen_eoperator( char const* path, bool use_c_definition = false ) { - char scratch_mem[kilobytes(4)]; - Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) ); - - file_read_contents( arena_allocator_info(& scratch), file_zero_terminate, path ); - - CSV_Object csv_nodes; - csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false ); - - Array enum_strs = csv_nodes.nodes[0].nodes; - Array str_strs = csv_nodes.nodes[1].nodes; + CSV_Columns2 csv_enum = parse_csv_two_columns(GlobalAllocator, path); String enum_entries = string_make_reserve( GlobalAllocator, kilobytes(1) ); String to_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) ); - for (usize idx = 0; idx < array_num(enum_strs); idx++) - { - char const* enum_str = enum_strs[idx].string; - char const* entry_to_str = str_strs [idx].string; + for (usize idx = 0; idx < array_num(csv_enum.Col_1); idx++) { + char const* enum_str = csv_enum.Col_1[idx].string; + char const* entry_to_str = csv_enum.Col_2[idx].string; string_append_fmt( & enum_entries, "Op_%s,\n", enum_str ); string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); @@ -160,7 +133,7 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false ) #pragma push_macro("local_persist") #undef local_persist - StrC lookup_size = string_to_strc(string_fmt_buf(GlobalAllocator, "%d", array_num(enum_strs) )); + StrC lookup_size = string_to_strc(string_fmt_buf(GlobalAllocator, "%d", array_num(csv_enum.Col_1) )); CodeFn to_str = parse_function(token_fmt( "entries", string_to_strc(to_str_entries) , "num", lookup_size @@ -180,8 +153,7 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false ) CodeBody result = def_body(CT_Global_Body); body_append(result, enum_code); - if ( use_c_definition ) - { + if ( use_c_definition ) { CodeTypedef operator_t = parse_typedef(code( typedef enum Operator Operator; )); body_append(result, operator_t); } @@ -203,21 +175,12 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false ) CodeBody gen_especifier( char const* path, bool use_c_definition = false ) { - char scratch_mem[kilobytes(4)]; - Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) ); - - file_read_contents( arena_allocator_info(& scratch), file_zero_terminate, path ); - - CSV_Object csv_nodes; - csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false ); - - Array enum_strs = csv_nodes.nodes[0].nodes; - Array str_strs = csv_nodes.nodes[1].nodes; + CSV_Columns2 csv_enum = parse_csv_two_columns(GlobalAllocator, path); String enum_entries = string_make_reserve( GlobalAllocator, kilobytes(1) ); String to_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) ); - for (usize idx = 0; idx < array_num(enum_strs); idx++) + for (usize idx = 0; idx < array_num(csv_enum.Col_1); idx++) { char const* enum_str = enum_strs[idx].string; char const* entry_to_str = str_strs [idx].string; @@ -271,7 +234,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false ) #undef do_once_end #undef forceinline #undef neverinline - StrC lookup_size = string_to_strc(string_fmt_buf(GlobalAllocator, "%d", array_num(enum_strs) )); + StrC lookup_size = string_to_strc(string_fmt_buf(GlobalAllocator, "%d", array_num(csv_enum.Col_1) )); CodeFn to_str = parse_function(token_fmt( "entries", string_to_strc(to_str_entries) , "num", lookup_size diff --git a/base/helpers/misc.hpp b/base/helpers/misc.hpp new file mode 100644 index 0000000..9a3dd73 --- /dev/null +++ b/base/helpers/misc.hpp @@ -0,0 +1,86 @@ + +#ifdef GEN_INTELLISENSE_DIRECTIVES +#pragma once +#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS +#define GEN_ENFORCE_STRONG_CODE_TYPES +#define GEN_EXPOSE_BACKEND +#include "../gen.cpp" + +#include "helpers/push_ignores.inline.hpp" +#include "helpers/helper.hpp" + +GEN_NS_BEGIN +#include "helpers/push_container_defines.inline.hpp" +#include "dependencies/parsing.cpp" +#include "helpers/pop_container_defines.inline.hpp" +GEN_NS_END + +#include "auxillary/builder.hpp" +#include "auxillary/builder.cpp" +#include "auxillary/scanner.hpp" +#endif + +// Will format a file with the given style at the provided path. +// Assumes clang-format is defined in an user-exposed or system enviornment PATH. +void clang_format_file( char const* path, char const* style_path ) +{ + GEN_ASSERT_NOT_NULL(path); + String resolved_path = string_make_strc(GlobalAllocator, to_strc_from_c_str(path)); + + String style_arg; + if (style_path) { + stle_arg = string_make_strc(GlobalAllocator, txt("-style=file:")); + string_append_fmt( & style_arg, "%s ", style_path ); + } + + StrC clang_format = txt("clang-format ") + StrC cf_format_inplace = txt("-i ") + StrC cf_verbose = txt("-verbose ") + + String command = string_make_strc( GlobalAllocator, clang_format ); + string_append_strc( & command, cf_format_inplace ); + string_append_strc( & command, cf_verbose ); + string_append_string( & command, style_arg ); + string_append_string( & command, resolved_path ); + + log_fmt("\tRunning clang-format:\n"); + system( command ); + log_fmt("\tclang-format finished formatting.\n"); +} +// Will refactor a file with the given script at the provided path. +// Assumes refactor is defined in an user-exposed or system enviornment PATH. +// (See: ./gencpp/scripts/build.ci.ps1 for how) +void refactor_file( char const* path, char const* refactor_script ) +{ + GEN_ASSERT_NOT_NULL(path, refactor_script); + + #define refactor + + String command = string_make_strc(GlobalAllocator, txt("refactor"))); + + log_fmt("\tBeginning refactor:\n"); + system(command); + log_fmt("\nRefactoring complete.\n"); + + #undef refactor +} + +Code code_refactor_and_format( Code code, char const* scratch_path, char const* refactor_script, char_const* clang_format_sytle_path ) +{ + GEN_ASSERT_NOT_NULL(code); + GEN_ASSERT_NOT_NULL(scratch_path); + Builder scratch_file = builder_open("gen/scratch.hpp"); + builder_print( & scratch_file, code); + builder_write(& scratch_file); + + if (refactor_script) { + refactor_file(scratch_path, refactor_script) + } + if ( clang_format_sytle_path ) { + clang_format_file(scratch_path, clang_format_sytle_path); + } + + Code result = scan_file( scratch_path ); + remove("gen/scratch.hpp"); + return result; +} diff --git a/project/helpers/pop_container_defines.inline.hpp b/base/helpers/pop_container_defines.inline.hpp similarity index 100% rename from project/helpers/pop_container_defines.inline.hpp rename to base/helpers/pop_container_defines.inline.hpp diff --git a/project/helpers/pop_ignores.inline.hpp b/base/helpers/pop_ignores.inline.hpp similarity index 100% rename from project/helpers/pop_ignores.inline.hpp rename to base/helpers/pop_ignores.inline.hpp diff --git a/project/helpers/push_container_defines.inline.hpp b/base/helpers/push_container_defines.inline.hpp similarity index 100% rename from project/helpers/push_container_defines.inline.hpp rename to base/helpers/push_container_defines.inline.hpp diff --git a/project/helpers/push_ignores.inline.hpp b/base/helpers/push_ignores.inline.hpp similarity index 100% rename from project/helpers/push_ignores.inline.hpp rename to base/helpers/push_ignores.inline.hpp diff --git a/project/helpers/undef.macros.hpp b/base/helpers/undef.macros.h similarity index 100% rename from project/helpers/undef.macros.hpp rename to base/helpers/undef.macros.h diff --git a/gen_c_library/c_library.cpp b/gen_c_library/c_library.cpp index fabb70e..9333e6e 100644 --- a/gen_c_library/c_library.cpp +++ b/gen_c_library/c_library.cpp @@ -52,7 +52,7 @@ constexpr StrC implementation_guard_end = txt(R"( #pragma endregion GENCPP IMPLEMENTATION GUARD )"); -void format_file( char const* path ) +void CHANGE_format_file( char const* path ) { String resolved_path = String::make(GlobalAllocator, to_strc_from_c_str(path)); @@ -77,7 +77,7 @@ void format_file( char const* path ) #undef cf_verbse } -Code format_code_to_untyped( Code code ) +Code CHANGE_format_code_to_untyped( Code code ) { Builder ecode_file_temp = Builder::open("gen/scratch.hpp"); ecode_file_temp.print(code); @@ -88,18 +88,8 @@ Code format_code_to_untyped( Code code ) return result; } -CodeBody parse_file( const char* path ) -{ - FileContents file = file_read_contents( GlobalAllocator, true, path ); - CodeBody code = parse_global_body( { file.size, (char const*)file.data } ); - log_fmt("\nParsed: %s\n", path); - return code; -} - constexpr bool helper_use_c_definition = true; -constexpr bool will_refactor_to_gen_namespace = true; - int gen_main() { #define project_dir "../project/" @@ -116,8 +106,8 @@ int gen_main() PreprocessorDefines.append(txt("Using_CodeOps(")); PreprocessorDefines.append(txt("GEN_OPTIMIZE_MAPPINGS_BEGIN")); PreprocessorDefines.append(txt("GEN_OPITMIZE_MAPPINGS_END")); - //PreprocessorDefines.append(txt("GEN_EXECUTION_EXPRESSION_SUPPORT")); PreprocessorDefines.append(txt("GEN_PARAM_DEFAULT")); + //PreprocessorDefines.append(txt("GEN_EXECUTION_EXPRESSION_SUPPORT")); Code push_ignores = scan_file( project_dir "helpers/push_ignores.inline.hpp" ); Code pop_ignores = scan_file( project_dir "helpers/pop_ignores.inline.hpp" ); @@ -1181,10 +1171,10 @@ R"(#define ( code ) _Generic( (code), \ #pragma region Resolve Components CodeBody array_arena = gen_array(txt("gen_Arena"), txt("Array_gen_Arena")); - CodeBody array_pool = gen_array(txt("gen_Pool"), txt("Array_gen_Pool")); + CodeBody array_pool = gen_array(txt("gen_Pool"), txt("Array_gen_Pool")); CodeBody array_token = gen_array(txt("gen_Token"), txt("Array_gen_Token")); - Code src_static_data = scan_file( project_dir "components/static_data.cpp" ); + Code src_static_data = scan_file( project_dir "components/static_data.cpp" ); Code src_ast_case_macros = scan_file( project_dir "components/ast_case_macros.cpp" ); Code src_code_serialization = scan_file( project_dir "components/code_serialization.cpp" ); Code src_interface = scan_file( project_dir "components/interface.cpp" ); diff --git a/gen_c_library/c_library.refactor b/gen_c_library/c_library.refactor index d0d3796..3e6569a 100644 --- a/gen_c_library/c_library.refactor +++ b/gen_c_library/c_library.refactor @@ -1,14 +1,5 @@ __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 @@ -21,6 +12,9 @@ // Gen Macro namespace // namespace GEN_, new_namespace_ +// c_library.refactor +// Used to prefix all exposed identifiers with the gen_namespace by c_library.cpp using ./gencpp/scripts/helpers/refactor.exe + // Macros word global, gen_global diff --git a/gen_segemented/Readme.md b/gen_segemented/Readme.md new file mode 100644 index 0000000..4b18a21 --- /dev/null +++ b/gen_segemented/Readme.md @@ -0,0 +1,15 @@ +# Generate Segemented Library + +The principal (user) files are `gen.hpp` and `gen.cpp`. +They contain includes for its various components: `components/.` + +Dependencies are bundled into `gen.dep.`. They are included in `gen.` before component includes. +Just like the `gen.` they include their components: `dependencies/.` + + +Both libraries use *pre-generated* (self-hosting I guess) version of the library to then generate the latest version of itself. + +They dedicated header and source files. Dependencies included at the top of the file and each header starting with a pragma once. +The output will be in the `project/gen` directory (if the directory does not exist, it will create it). + +Use those to get a general idea of how to make your own tailored version. diff --git a/project/bootstrap.cpp b/gen_segemented/segemented.cpp similarity index 83% rename from project/bootstrap.cpp rename to gen_segemented/segemented.cpp index 3128d6f..cdf68a9 100644 --- a/project/bootstrap.cpp +++ b/gen_segemented/segemented.cpp @@ -16,6 +16,7 @@ GEN_NS_END #include "auxillary/builder.hpp" #include "auxillary/builder.cpp" #include "auxillary/scanner.hpp" +#include "auxillary/misc.hpp" using namespace gen; @@ -25,50 +26,20 @@ constexpr char const* generation_notice = #include // for system() -void format_file( char const* path ) -{ - String resolved_path = string_make_strc(GlobalAllocator, to_strc_from_c_str(path)); +constexpr char const* path_format_style = "../scripts/.clang-format "; +constexpr char const* scratch_file = "gen/scratch.hpp"; +constexpr char const* path_base = "../base/"; - String style_arg = string_make_strc(GlobalAllocator, txt("-style=file:")); - string_append_strc( & style_arg, txt("../scripts/.clang-format ")); - - // Need to execute clang format on the generated file to get it to match the original. - #define clang_format txt("clang-format ") - #define cf_format_inplace txt("-i ") - #define cf_verbose txt("-verbose ") - String command = string_make_strc( GlobalAllocator, clang_format ); - string_append_strc( & command, cf_format_inplace ); - string_append_strc( & command, cf_verbose ); - string_append_string( & command, style_arg ); - string_append_string( & command, resolved_path ); - log_fmt("\tRunning clang-format on file:\n"); - system( command ); - log_fmt("\tclang-format finished reformatting.\n"); - #undef cf_cmd - #undef cf_format_inplace - #undef cf_style - #undef cf_verbse -} - -Code dump_to_scratch_and_retireve( Code code ) -{ - Builder ecode_file_temp = builder_open("gen/scratch.hpp"); - builder_print( & ecode_file_temp, code); - builder_write(& ecode_file_temp); - format_file("gen/scratch.hpp"); - Code result = scan_file( "gen/scratch.hpp" ); - remove("gen/scratch.hpp"); - return result; +Code format( Code code ) { + return code_refactor_and_format(code, scratch_file, nullptr, path_format_style ); } int gen_main() { gen::init(); - // PreprocessorDefines.append("GEN_NS"); - - Code push_ignores = scan_file( "helpers/push_ignores.inline.hpp" ); - Code pop_ignores = scan_file( "helpers/pop_ignores.inline.hpp" ); + Code push_ignores = scan_file( path_base "helpers/push_ignores.inline.hpp" ); + Code pop_ignores = scan_file( path_base "helpers/pop_ignores.inline.hpp" ); // gen_dep.hpp { @@ -176,11 +147,11 @@ int gen_main() builder_print_fmt(header, "#pragma region Types\n" ); builder_print( header, types ); builder_print( header, fmt_newline); - builder_print( header, dump_to_scratch_and_retireve(ecode) ); + builder_print( header, format(ecode) ); builder_print( header, fmt_newline); - builder_print( header, dump_to_scratch_and_retireve(eoperator) ); + builder_print( header, format(eoperator) ); builder_print( header, fmt_newline); - builder_print( header, dump_to_scratch_and_retireve(especifier) ); + builder_print( header, format(especifier) ); builder_print( header, fmt_newline); builder_print_fmt( header, "#pragma endregion Types\n\n" ); @@ -195,7 +166,7 @@ int gen_main() builder_print_fmt( header, "\n#pragma region Inlines\n" ); builder_print( header, inlines ); builder_print( header, fmt_newline ); - builder_print( header, dump_to_scratch_and_retireve(ast_inlines) ); + builder_print( header, format(ast_inlines) ); builder_print( header, fmt_newline ); builder_print_fmt( header, "#pragma endregion Inlines\n" ); @@ -206,22 +177,22 @@ int gen_main() Builder header_ecode = builder_open( "components/gen/ecode.hpp" ); builder_print( & header_ecode, gen_component_header ); - builder_print( & header_ecode, dump_to_scratch_and_retireve(ecode) ); + builder_print( & header_ecode, format(ecode) ); builder_write( & header_ecode); Builder header_eoperator = builder_open( "components/gen/eoperator.hpp" ); builder_print( & header_eoperator, gen_component_header ); - builder_print( & header_eoperator, dump_to_scratch_and_retireve(eoperator) ); + builder_print( & header_eoperator, format(eoperator) ); builder_write( & header_eoperator ); Builder header_especifier = builder_open( "components/gen/especifier.hpp" ); builder_print( & header_especifier, gen_component_header ); - builder_print( & header_especifier, dump_to_scratch_and_retireve(especifier) ); + builder_print( & header_especifier, format(especifier) ); builder_write( & header_especifier); Builder header_ast_inlines = builder_open( "components/gen/ast_inlines.hpp" ); builder_print( & header_ast_inlines, gen_component_header ); - builder_print( & header_ast_inlines, dump_to_scratch_and_retireve(ast_inlines) ); + builder_print( & header_ast_inlines, format(ast_inlines) ); builder_write( & header_ast_inlines); } @@ -240,11 +211,10 @@ int gen_main() Code untyped = scan_file( "components/interface.untyped.cpp" ); CodeBody etoktype = gen_etoktype( "enums/ETokType.csv", "enums/AttributeTokens.csv" ); - //CodeNS nspaced_etoktype = def_namespace( name(parser), def_namespace_body( args(etoktype)) ); CodeBody nspaced_etoktype = def_global_body( args( etoktype )); - Code formatted_toktype = dump_to_scratch_and_retireve(nspaced_etoktype); + Code formatted_toktype = format(nspaced_etoktype); Builder _src = builder_open( "gen/gen.cpp" ); Builder* src = & _src; diff --git a/project/Readme.md b/project/Readme.md deleted file mode 100644 index ecf7c8d..0000000 --- a/project/Readme.md +++ /dev/null @@ -1,66 +0,0 @@ -# Documentation - -The library is fragmented into a series of headers and source files meant to be scanned in and then generated to a tailored format for the target `gen` files. - -The principal (user) files are `gen.hpp` and `gen.cpp`. -They contain includes for its various components: `components/.` - -Dependencies are bundled into `gen.dep.`. -Just like the `gen.` they include their components: `dependencies/.` - -Code not making up the core library is located in `auxiliary/.`. These are optional extensions or tools for the library. - -Both libraries use *pre-generated* (self-hosting I guess) version of the library to then generate the latest version of itself. - -The default `gen.bootstrap.cpp` located in the project folder is meant to be produce a standard segmented library, where the components of the library -have relatively dedicated header and source files. Dependencies included at the top of the file and each header starting with a pragma once. -The output will be in the `project/gen` directory (if the directory does not exist, it will create it). - -Use those to get a general idea of how to make your own tailored version. - -Feature Macros: - -* `GEN_DEFINE_ATTRIBUTE_TOKENS` : Allows user to define their own attribute macros for use in parsing. - * This is auto-generated if using the bootstrap or single-header generation - * *Note: The user will use the `AttributeTokens.csv` when the library is fully self-hosting.* -* `GEN_DEFINE_LIBRARY_CORE_CONSTANTS` : Optional typename codes as they are non-standard to C/C++ and not necessary to library usage -* `GEN_DONT_ENFORCE_GEN_TIME_GUARD` : By default, the library ( gen.hpp/ gen.cpp ) expects the macro `GEN_TIME` to be defined, this disables that. -* `GEN_ENFORCE_STRONG_CODE_TYPES` : Enforces casts to filtered code types. -* `GEN_EXPOSE_BACKEND` : Will expose symbols meant for internal use only. -* `GEN_ROLL_OWN_DEPENDENCIES` : Optional override so that user may define the dependencies themselves. -* `GEN_DONT_ALLOW_INVALID_CODE` (Not implemented yet) : Will fail when an invalid code is constructed, parsed, or serialized. - -By default the base library implementation strictly uses a C-like interface. This is to allow for the generation of a C-variant of the library using [gen_c_library](../gen_c_library/). However, the library was written in C++ and supports some of its features: - -* `GEN_SUPPORT_CPP_REFERENCES` : Will enable support for reference interface on some definitions -* `GEN_SUPPORT_CPP_MEMBER_FEATURES` : Will enable support for definitions to have their interface as members. - -*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)* - -## 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. - -## Extending the library - -This library is relatively very small, and can be extended without much hassle. - -The convention you'll see used throughout the interface of the library is as follows: - -1. Check name or parameters to make sure they are valid for the construction requested -2. Create a code object using `make_code`. -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). - -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 constructor as it has multiple permutations of definitions that could be created that are not trivial to determine if valid. - -The library has its code segmented into component files, use it to help create a derived version without needing to have to rewrite a generated file directly or build on top of the header via composition or inheritance. - -The parser is documented under `docs/Parsing.md` and `docs/Parser_Algo.md`. - -## A note on compilation and runtime generation speed - -The library is designed to be fast to compile and generate code at runtime as fast as resonable possible on a debug build. -Its recommended that your metaprogam be compiled using a single translation unit (unity build). diff --git a/project/helpers/member_proc_support.hpp b/project/helpers/member_proc_support.hpp deleted file mode 100644 index 02a3af2..0000000 --- a/project/helpers/member_proc_support.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include "gen.hpp" - -GEN_NS_BEGIN -#include "dependencies/parsing.hpp" -GEN_NS_END - -using namespace gen; - diff --git a/scripts/build.ci.ps1 b/scripts/build.ci.ps1 index 0bea56a..dcf10ed 100644 --- a/scripts/build.ci.ps1 +++ b/scripts/build.ci.ps1 @@ -40,7 +40,7 @@ Push-Location $path_root $vendor = $null $release = $null $verbose = $false -[bool] $bootstrap = $false +[bool] $segemented = $false [bool] $singleheader = $false [bool] $c_library = $false [bool] $unreal = $false @@ -56,7 +56,7 @@ if ( $args ) { $args | ForEach-Object { "verbose" { $verbose = $true } "release" { $release = $true } "debug" { $release = $false } - "bootstrap" { $bootstrap = $true } + "segemented" { $segemented = $true } "singleheader" { $singleheader = $true } "c_library" { $c_library = $true } "unreal" { $unreal = $true } @@ -88,7 +88,7 @@ else { $optimize = $true } -if ( $bootstrap -eq $false -and $singleheader -eq $false -and $c_library -eq $false -and $unreal -eq $false -and $test -eq $false ) { +if ( $segmented -eq $false -and $singleheader -eq $false -and $c_library -eq $false -and $unreal -eq $false -and $test -eq $false ) { throw "No build target specified. One must be specified, this script will not assume one" } @@ -100,25 +100,23 @@ write-host "Build Type: $(if ($release) {"Release"} else {"Debug"} )" #region Building $path_build = Join-Path $path_root build -$path_project = Join-Path $path_root project -$path_scripts = Join-Path $path_root scripts +$path_base = Join-Path $path_root base $path_c_library = join-Path $path_root gen_c_library +$path_segmented = Join-Path $path_root gen_segmented $path_singleheader = Join-Path $path_root gen_singleheader +$path_scripts = Join-Path $path_root scripts $path_unreal = Join-Path $path_root gen_unreal_engine $path_test = Join-Path $path_root test -if ( $bootstrap ) +if ( $base ) { - $path_build = join-path $path_project build - $path_gen = join-path $path_project gen - $path_comp_gen = join-path $path_project components/gen + $path_build = join-path $path_base build + $path_comp = join-path $path_segmented 'components' + $path_comp_gen = join-path $path_comp 'gen' if ( -not(Test-Path($path_build) )) { New-Item -ItemType Directory -Path $path_build } - if ( -not(Test-Path($path_gen) )) { - New-Item -ItemType Directory -Path $path_gen - } if ( -not(Test-Path($path_comp_gen) )) { New-Item -ItemType Directory -Path $path_comp_gen } @@ -131,8 +129,46 @@ if ( $bootstrap ) ) $includes = @( $path_project) - $unit = join-path $path_project "bootstrap.cpp" - $executable = join-path $path_build "bootstrap.exe" + $unit = join-path $path_base "base.cpp" + $executable = join-path $path_build "base.exe" + + $result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable + + Push-Location $path_project + if ( Test-Path( $executable ) ) { + write-host "`nRunning bootstrap" + $time_taken = Measure-Command { & $executable + | ForEach-Object { + write-host `t $_ -ForegroundColor Green + } + } + write-host "`nBootstrap completed in $($time_taken.TotalMilliseconds) ms" + } + Pop-Location +} + +if ( $segmented ) +{ + $path_build = join-path $path_segmented build + $path_gen = join-path $path_segmented gen + + if ( -not(Test-Path($path_build) )) { + New-Item -ItemType Directory -Path $path_build + } + if ( -not(Test-Path($path_gen) )) { + New-Item -ItemType Directory -Path $path_gen + } + + $compiler_args = @() + $compiler_args += ( $flag_define + 'GEN_TIME' ) + + $linker_args = @( + $flag_link_win_subsystem_console + ) + + $includes = @( $path_project) + $unit = join-path $path_segmented "segmented.cpp" + $executable = join-path $path_build "segmented.exe" $result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable @@ -294,7 +330,8 @@ if ( $unreal ) . $refactor_unreal } -if ( $test ) +# TODO(Ed): The unit testing needs a full rewrite +if ( $test -and $false ) { $path_gen = join-path $path_test gen $path_gen_build = join-path $path_gen build @@ -356,55 +393,4 @@ if ( $test ) } #endregion Building -#region Formatting -push-location $path_scripts -if ( $false -and $bootstrap -and (Test-Path (Join-Path $path_project "gen/gen.hpp")) ) -{ - $path_gen = join-path $path_project gen - $include = @( - 'gen.hpp', 'gen.cpp', - 'gen.dep.hpp', 'gen.dep.cpp', - 'gen.builder.hpp', 'gen.builder.cpp' - 'gen.scanner.hpp', 'gen.scanner.cpp' - ) - $exclude = $null - # format-cpp $path_gen $include $exclude - format-cpp $path_comp_gen @( 'ast_inlines.hpp', 'ecode.hpp', 'especifier.hpp', 'eoperator.hpp', 'etoktype.cpp' ) $null -} - -if ( $false -and $singleheader -and (Test-Path (Join-Path $path_singleheader "gen/gen.hpp")) ) -{ - $path_gen = join-path $path_singleheader gen - $include = @( - 'gen.hpp' - ) - $exclude = $null - format-cpp $path_gen $include $exclude -} - -if ( $false -and $unreal -and (Test-Path( Join-Path $path_unreal "gen/gen.hpp")) ) -{ - $path_gen = join-path $path_unreal gen - $include = @( - 'gen.hpp', 'gen.cpp', - 'gen.dep.hpp', 'gen.dep.cpp', - 'gen.builder.hpp', 'gen.builder.cpp' - 'gen.scanner.hpp', 'gen.scanner.cpp' - ) - $exclude = $null - format-cpp $path_gen $include $exclude -} - -if ( $test -and $false ) -{ - $path_gen = join-path $path_test gen - $include = @( - '*.gen.hpp' - ) - $exclude = $null - format-cpp $path_gen $include $exclude -} -pop-location -#endregion Formatting - Pop-Location # $path_root diff --git a/test/Readme.md b/test/Readme.md index 2418ff3..57f6892 100644 --- a/test/Readme.md +++ b/test/Readme.md @@ -1,6 +1,3 @@ # Test -The implementaiton here is not well organized and needs a rewrite.. - -I only do basic sanity and parsing tests for the most part. -The library is getting practical usage tests in [genc](https://github.com/Ed94/genc) and other projects. +The implementaiton here has been gutted and will be rewritten... diff --git a/test/SOA.cpp b/test/SOA.cpp deleted file mode 100644 index 445e022..0000000 --- a/test/SOA.cpp +++ /dev/null @@ -1,146 +0,0 @@ -#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS -#define GEN_ENFORCE_STRONG_CODE_TYPES -#define GEN_EXPOSE_BACKEND -#define GEN_BENCHMARK -#include "gen.hpp" -#include "gen.builder.hpp" -using namespace gen; - -Code gen_SOA( CodeStruct struct_def, s32 num_entries = 0 ) -{ - StringCached name = get_cached_string( token_fmt( "name", (StrC)struct_def->Name, - stringize( SOA_ ) - )); - - Code - soa_entry = { struct_def.duplicate() }; - soa_entry->Name = get_cached_string( name(Entry) ); - - constexpr s32 Num_Vars_Cap = 128; - - local_persist Code var_memory[Num_Vars_Cap]; - local_persist Arena var_arena; - do_once_start - var_arena = Arena::init_from_memory( var_memory, kilobytes(Num_Vars_Cap) ); - do_once_end - - Array vars = Array::init( var_arena );; - - CodeStruct soa = def_struct( name, def_struct_body( args( soa_entry ) )); - { - for ( Code struct_mem : struct_def->Body ) - { - if ( struct_mem->Type == ECode::Variable ) - { - CodeType var_type = struct_mem.cast()->ValueType; - StrC num_entries_str = to_str( str_fmt_buf( "%d", num_entries ) ); - - CodeVar entry_arr = { nullptr }; - if ( ! num_entries) - { - entry_arr = parse_variable( token_fmt( "type", (StrC)var_type->Name, "name", (StrC)struct_mem->Name, - stringize( Array<> ; ) - )); - } - else - { - entry_arr = parse_variable( token_fmt( "type", (StrC)var_type->Name, "name", (StrC)struct_mem->Name, "num", num_entries_str, - stringize( []; ) - )); - } - - vars.append( entry_arr ); - soa->Body.append( entry_arr ); - } - } - } - - CodeFn make; - { - make = parse_function( token_fmt("SOA_Type", (StrC)name, - stringize( - static - make( AllocatorInfo allocator ) - { - soa = {}; - } - ) - )); - - if ( ! num_entries ) - { - for ( CodeVar member : vars ) - { - Code arr_init = def_execution( token_fmt( "var_name", (StrC)member->Name, "var_type", (StrC)member->ValueType->Name, - stringize( soa. = ::init( allocator ); ) - )); - - make->Body.append( arr_init ); - } - } - - make->Body.append( def_execution( code( return soa; ) )); - } - - CodeFn get; - { - get = parse_function( code( - Entry get( s32 idx ) - { - } - )); - - String content = String::make( GlobalAllocator, "return\n{\n" ); - - for ( CodeVar member : vars ) - { - content.append_fmt( token_fmt( "var_name", (StrC)member->Name, - "[idx]," - )); - } - - content.append( "};" ); - - CodeExec ret = def_execution( content ); - - get->Body.append( ret ); - } - - soa->Body.append( make ); - soa->Body.append( get ); - soa->Body.raw()->validate_body(); - vars.free(); - - return soa; -} - -void check_SOA() -{ - log_fmt("\ncheck_SOA:"); - gen::init(); - - Builder soa_test = Builder::open( "SOA.gen.hpp" ); - - soa_test.print( parse_using( code( - using u16 = unsigned short; - ))); - soa_test.print( def_include( txt("gen.hpp"))); - soa_test.print( def_using_namespace( name(gen) ) ); - - soa_test.print( gen_SOA( - parse_struct( code( - struct TestStruct - { - u8 A; - u16 B; - u32 C; - u64 D; - }; - )) - , 100 - )); - - soa_test.write(); - gen::deinit(); - log_fmt(" passed!\n"); -} diff --git a/test/Unreal/Readme.md b/test/Unreal/Readme.md deleted file mode 100644 index 882f0ef..0000000 --- a/test/Unreal/Readme.md +++ /dev/null @@ -1,25 +0,0 @@ -# Unreal Header & Source reconstruction tests - -***Note: This validation test has not been implemented yet.*** - -Will test the following modules + plugins: - -* Kismet -* Slate -* RTTI Bases -* Gameframework -* Actor & Component Bases -* Lyra - -In the future I could attempt to do a similar test to that of the godot engine full compilation test. - -For now it just does the following: - -* Download the Unreal source code -* For each module - 1. Grab all header and source file paths - 2. Generate an ast for each file and serialize it to a file called `.gen.` - 3. Reconstruct the ast from the generated file - 4. Compare the original ast to the reconstructed ast - -This wil most likely be the most difficult test along-side godot's full compilation test. diff --git a/test/Unreal/validate.ps1 b/test/Unreal/validate.ps1 deleted file mode 100644 index e69de29..0000000 diff --git a/test/Unreal/validate.unreal.cpp b/test/Unreal/validate.unreal.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/test/_old/parsed/Array.Parsed.hpp b/test/_old/parsed/Array.Parsed.hpp deleted file mode 100644 index 6c31354..0000000 --- a/test/_old/parsed/Array.Parsed.hpp +++ /dev/null @@ -1,294 +0,0 @@ -#pragma once - -#if GEN_TIME -#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS -#define GEN_ENFORCE_STRONG_CODE_TYPES -#define GEN_EXPOSE_BACKEND -#define GEN_BENCHMARK -#include "gen.hpp" - -using namespace gen; - -Code gen__array_base() -{ - return parse_global_body( code( - struct ArrayHeader - { - AllocatorInfo Allocator; - usize Capacity; - usize Num; - }; - - static inline usize array_grow_formula( usize value ) - { - return 2 * value * 8; - } - )); -} - -Code gen__array( StrC type ) -{ - StrC name; - { - char const* name_str = str_fmt_buf( "Array_%s\0", type.Ptr ); - s32 name_len = str_len( name_str ); - - name = { name_len, name_str }; - }; - - CodeStruct array = parse_struct( token_fmt( "ArrayType", name, "type", type, - stringize( - struct - { - using Header = ArrayHeader; - using Type = ; - - static constexpr auto grow_formula = &array_grow_formula; - - static - init( AllocatorInfo allocator ) - { - return init_reserve( allocator, grow_formula(0) ); - } - - static - init_reserve( AllocatorInfo allocator, ssize capacity ) - { - Header* header = rcast( Header*, alloc( allocator, sizeof(Header) + sizeof(Type) )); - - if ( header == nullptr ) - return { nullptr }; - - header->Allocator = allocator; - header->Capacity = capacity; - header->Num = 0; - - return { rcast( Type*, header + 1) }; - } - - bool append( Type value ) - { - Header& header = get_header(); - - if ( header.Num == header.Capacity ) - { - if ( ! grow( header.Capacity )) - return false; - } - - Data[ header.Num ] = value; - header.Num++; - - return true; - } - - Type& back( void ) - { - Header& header = get_header(); - return Data[ header.Num - 1 ]; - } - - void clear( void ) - { - Header& header = get_header(); - header.Num = 0; - } - - bool fill( usize begin, usize end, Type value ) - { - Header& header = get_header(); - - if ( begin < 0 || end >= header.Num ) - return false; - - for ( ssize idx = begin; idx < end; idx++ ) - { - Data[ idx ] = value; - } - - return true; - } - - void free( void ) - { - Header& header = get_header(); - gen::free( header.Allocator, &header ); - } - - Header& get_header( void ) - { - return *( reinterpret_cast< Header* >( Data ) - 1 ); - } - - bool grow( usize min_capacity ) - { - Header& header = get_header(); - usize new_capacity = grow_formula( header.Capacity ); - - if ( new_capacity < min_capacity ) - new_capacity = 8; - - return set_capacity( new_capacity ); - } - - usize num( void ) - { - return get_header().Num; - } - - bool pop( void ) - { - Header& header = get_header(); - - GEN_ASSERT( header.Num > 0 ); - header.Num--; - } - - void remove_at( usize idx ) - { - Header* header = &get_header(); - GEN_ASSERT( idx < header->Num ); - - mem_move( header + idx, header + idx + 1, sizeof( Type ) * ( header->Num - idx - 1 ) ); - header->Num--; - } - - bool reserve( usize new_capacity ) - { - Header& header = get_header(); - - if ( header.Capacity < new_capacity ) - return set_capacity( new_capacity ); - - return true; - } - - bool resize( usize num ) - { - Header& header = get_header(); - - if ( num > header.Capacity ) - { - if ( ! grow( header.Capacity ) ) - return false; - } - - header.Num = num; - return true; - } - - bool set_capacity( usize new_capacity ) - { - Header& header = get_header(); - - if ( new_capacity == header.Capacity ) - return true; - - if ( new_capacity < header.Num ) - header.Num = new_capacity; - - ssize size = sizeof( Header ) + sizeof( Type ) * new_capacity; - Header* new_header = rcast( Header*, alloc( header.Allocator, size ) ); - - if ( new_header == nullptr ) - return false; - - mem_move( new_header, &header, sizeof( Header ) + sizeof( Type ) * header.Num ); - - new_header->Allocator = header.Allocator; - new_header->Num = header.Num; - new_header->Capacity = new_capacity; - - gen::free( header.Allocator, &header ); - - Data = ( Type* )new_header + 1; - return true; - } - - Type* Data; - - operator Type*() - { - return Data; - } - }; - ) - )); - - return array; -} - - -struct GenArrayRequest -{ - StrC Dependency; - StrC Type; -}; -Array GenArrayRequests; - -void gen__array_request( StrC type, StrC dep = {} ) -{ - do_once_start - GenArrayRequests = Array::init( GlobalAllocator ); - do_once_end - - // Make sure we don't already have a request for the type. - for ( ssize idx = 0; idx < GenArrayRequests.num(); ++idx ) - { - StrC const reqest_type = GenArrayRequests[ idx ].Type; - - if ( reqest_type.Len != type.Len ) - continue; - - if ( str_compare( reqest_type.Ptr, type.Ptr, reqest_type.Len ) == 0 ) - return; - } - - GenArrayRequest request = { dep, type }; - GenArrayRequests.append( request ); -} -#define gen_array( type ) gen__array_request( code(type) ) - -u32 gen_array_file() -{ - Builder - gen_array_file; - gen_array_file.open( "array.Parsed.gen.hpp" ); - - Code include_gen = def_include( txt("gen.hpp") ); - gen_array_file.print( include_gen ); - - gen_array_file.print( def_using_namespace( name(gen))); - - Code array_base = gen__array_base(); - gen_array_file.print( array_base ); - - GenArrayRequest* current = GenArrayRequests; - s32 left = GenArrayRequests.num(); - while (left--) - { - GenArrayRequest const& request = * current; - - Code generated_array = gen__array( request.Type ); - - if ( request.Dependency ) - { - char const* cmt_str = str_fmt_buf( "// Dependency for %s type", request.Type ); - s32 cmt_len = str_len( cmt_str ); - - Code cmt = def_comment( { cmt_len, cmt_str } ); - Code include = def_include( request.Dependency ); - - gen_array_file.print( cmt ); - gen_array_file.print( include ); - } - - gen_array_file.print( generated_array ); - current++; - } - - gen_array_file.write(); - return 0; -} - -#endif diff --git a/test/_old/parsed/Buffer.Parsed.hpp b/test/_old/parsed/Buffer.Parsed.hpp deleted file mode 100644 index b922bb5..0000000 --- a/test/_old/parsed/Buffer.Parsed.hpp +++ /dev/null @@ -1,205 +0,0 @@ -#pragma once - -#if GEN_TIME -#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS -#define GEN_ENFORCE_STRONG_CODE_TYPES -#define GEN_EXPOSE_BACKEND -#define GEN_BENCHMARK -#include "gen.hpp" - -using namespace gen; - -Code gen__buffer_base() -{ - return parse_global_body( code( - struct BufferHeader - { - AllocatorInfo Backing; - usize Capacity; - usize Num; - }; - )); -} - -Code gen__buffer( StrC type ) -{ - StrC name; - { - char const* name_str = str_fmt_buf( "Buffer_%s\0", type.Ptr ); - s32 name_len = str_len( name_str ); - - name = { name_len, name_str }; - }; - - Code buffer = parse_struct( token_fmt( "BufferName", name, "type", type, - stringize( - struct - { - using Header = BufferHeader; - using Type = ; - - static init( AllocatorInfo allocator, ssize capacity ) - { - Header* header = rcast( Header*, alloc( allocator, sizeof( Header ) + capacity * sizeof( Type ) ) ); - - if ( header == nullptr ) - return { nullptr }; - - header->Backing = allocator; - header->Capacity = capacity; - header->Num = 0; - - return { rcast( Type*, header + 1 ) }; - } - - init( AllocatorInfo allocator, other ) - { - Header& other_header = other.get_header(); - Header* header = rcast( Header*, alloc( allocator, sizeof( Header ) + other_header.Capacity * sizeof( Type ) ) ); - - if ( header == nullptr ) - return { nullptr }; - - header->Backing = allocator; - header->Capacity = other_header.Capacity; - header->Num = other_header.Num; - - mem_copy( header + 1, other.Data, other_header.Num * sizeof( Type ) ); - - return { rcast( Type*, header + 1 ) }; - } - - void append( Type value ) - { - Header& header = get_header(); - Data[ header.Num ] = value; - header.Num++; - } - - void append( Type* values, ssize num ) - { - Header& header = get_header(); - GEN_ASSERT( header.Num + num <= header.Capacity); - - mem_copy( Data + header.Num, values, num * sizeof( Type ) ); - header.Num += num; - } - - void clear( void ) - { - Header& header = get_header(); - header.Num = 0; - } - - Type& end( void ) - { - Header& header = get_header(); - return Data[ header.Num - 1 ]; - } - - void free( void ) - { - Header& header = get_header(); - gen::free( header.Backing, &header ); - } - - Header& get_header( void ) - { - return *( rcast( Header*, Data ) - 1 ); - } - - ssize num( void ) - { - return get_header().Num; - } - - void wipe( void ) - { - Header& header = get_header(); - header.Num = 0; - mem_set( Data, 0, header.Capacity * sizeof( Type ) ); - } - - operator Type*() - { - return Data; - } - - Type* Data; - }; - ) - )); - - return buffer; -} - -struct GenBufferRequest -{ - StrC Dependency; - StrC Type; -}; -Array GenBufferRequests; - -void gen__buffer_request( StrC type, StrC dep = {} ) -{ - do_once_start - GenBufferRequests = Array::init( GlobalAllocator ); - do_once_end - - // Make sure we don't already have a request for the type. - for ( ssize idx = 0; idx < GenBufferRequests.num(); ++idx ) - { - StrC const reqest_type = GenBufferRequests[ idx ].Type; - - if ( reqest_type.Len != type.Len ) - continue; - - if ( str_compare( reqest_type.Ptr, type.Ptr, reqest_type.Len ) == 0 ) - return; - } - - GenBufferRequest request = { dep, type }; - GenBufferRequests.append( request ); -} -#define gen_buffer( type ) gen__buffer_request( code(type) ) - -u32 gen_buffer_file() -{ - Builder - gen_buffer_file; - gen_buffer_file.open( "buffer.Parsed.gen.hpp" ); - - gen_buffer_file.print( def_include( txt("gen.hpp")) ); - gen_buffer_file.print( def_using_namespace( name(gen))); - - gen_buffer_file.print( gen__buffer_base() ); - - GenBufferRequest* current = GenBufferRequests; - s32 left = GenBufferRequests.num(); - while (left--) - { - GenBufferRequest const& request = * current; - - Code generated_buffer = gen__buffer( current->Type ); - - if ( request.Dependency ) - { - char const* cmt_str = str_fmt_buf( "// Dependency for %s type", request.Type ); - s32 cmt_len = str_len( cmt_str ); - - Code cmt = def_comment( { cmt_len, cmt_str } ); - Code include = def_include( request.Dependency ); - - gen_buffer_file.print( cmt ); - gen_buffer_file.print( include ); - } - - gen_buffer_file.print( generated_buffer ); - current++; - } - - gen_buffer_file.write(); - return 0; -} - -#endif // GEN_TIME diff --git a/test/_old/parsed/HashTable.Parsed.hpp b/test/_old/parsed/HashTable.Parsed.hpp deleted file mode 100644 index af10723..0000000 --- a/test/_old/parsed/HashTable.Parsed.hpp +++ /dev/null @@ -1,359 +0,0 @@ -#pragma once - -#if GEN_TIME -#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS -#define GEN_ENFORCE_STRONG_CODE_TYPES -#define GEN_EXPOSE_BACKEND -#define GEN_BENCHMARK -#include "gen.hpp" -#include "Array.Parsed.hpp" - -using namespace gen; - -Code gen__hashtable_base() -{ - return parse_global_body( code( - struct HashTable_FindResult - { - ssize HashIndex; - ssize PrevIndex; - ssize EntryIndex; - }; - )); -} - -Code gen__hashtable( StrC type ) -{ - StringCached name; - { - char const* name_str = str_fmt_buf( "HashTable_%s", type.Ptr ); - s32 len = str_len( name_str ); - - name = get_cached_string({ len, name_str }); - } - - Code ht_entry = parse_struct( token_fmt( "HashTableName", (StrC)name, "type", type, - stringize( - struct _Entry - { - u64 Key; - ssize Next; - Value; - }; - ) - )); - - StringCached ht_entry_name = get_cached_string( token_fmt( "HashTableName", (StrC)name, "_Entry" )); - - Code array_ht_entry = gen__array( ht_entry_name ); - - Code hashtable = parse_struct( token_fmt( "HashTableName", (StrC)name, "type", type, - stringize( - struct - { - using Type = ; - using Entry = _Entry; - using Array_Entry = Array__Entry; - using FindResult = HashTable_FindResult; - using MapProc = void ( * )( u64 key, Type value ); - using MapMutProc = void ( * )( u64 key, Type* value ); - - static - init( AllocatorInfo allocator ) - { - - result = { 0 }; - result.Hashes = Array_sw ::init( allocator ); - result.Entries = Array_Entry::init( allocator ); - return result; - } - - void clear( void ) - { - for ( s32 idx = 0; idx < Hashes.num(); idx++ ) - Hashes[ idx ] = -1; - - Entries.clear(); - } - - void destroy( void ) - { - if ( Hashes ) - Hashes.free(); - if ( Entries ) - Entries.free(); - } - - Type* get( u64 key ) - { - ssize idx = find( key ).EntryIndex; - - if ( idx > 0 ) - return &Entries[ idx ].Value; - - return nullptr; - } - - void grow( void ) - { - ssize new_num = array_grow_formula( Entries.num() ); - - rehash( new_num ); - } - - void map( MapProc map_proc ) - { - GEN_ASSERT_NOT_NULL( map_proc ); - - for ( ssize idx = 0; idx < Entries.num(); idx++ ) - { - map_proc( Entries[ idx ].Key, Entries[ idx ].Value ); - } - } - - void map_mut( MapMutProc map_proc ) - { - GEN_ASSERT_NOT_NULL( map_proc ); - - for ( ssize idx = 0; idx < Entries.num(); idx++ ) - { - map_proc( Entries[ idx ].Key, &Entries[ idx ].Value ); - } - } - - void rehash( ssize new_num ) - { - ssize idx; - ssize last_added_index; - HashTable_u32 new_ht = HashTable_u32::init( Hashes.get_header().Allocator ); - - new_ht.Hashes.resize( new_num ); - new_ht.Entries.reserve( new_ht.Hashes.num() ); - - for ( idx = 0; idx < new_ht.Hashes.num(); ++idx ) - new_ht.Hashes[ idx ] = -1; - - for ( idx = 0; idx < Entries.num(); ++idx ) - { - Entry& entry = Entries[ idx ]; - FindResult find_result; - - if ( new_ht.Hashes.num() == 0 ) - new_ht.grow(); - - entry = Entries[ idx ]; - find_result = new_ht.find( entry.Key ); - last_added_index = new_ht.add_entry( entry.Key ); - - if ( find_result.PrevIndex < 0 ) - new_ht.Hashes[ find_result.HashIndex ] = last_added_index; - - else - new_ht.Entries[ find_result.PrevIndex ].Next = last_added_index; - - new_ht.Entries[ last_added_index ].Next = find_result.EntryIndex; - new_ht.Entries[ last_added_index ].Value = entry.Value; - } - - destroy(); - - Hashes = new_ht.Hashes; - Entries = new_ht.Entries; - } - - void rehash_fast( void ) - { - ssize idx; - - for ( idx = 0; idx < Entries.num(); idx++ ) - Entries[ idx ].Next = -1; - - for ( idx = 0; idx < Hashes.num(); idx++ ) - Hashes[ idx ] = -1; - - for ( idx = 0; idx < Entries.num(); idx++ ) - { - Entry* entry; - FindResult find_result; - } - } - - void remove( u64 key ) - { - FindResult find_result = find( key ); - - if ( find_result.EntryIndex >= 0 ) - { - Entries.remove_at( find_result.EntryIndex ); - rehash_fast(); - } - } - - void remove_entry( ssize idx ) - { - Entries.remove_at( idx ); - } - - void set( u64 key, Type value ) - { - ssize idx; - FindResult find_result; - - if ( Hashes.num() == 0 ) - grow(); - - find_result = find( key ); - - if ( find_result.EntryIndex >= 0 ) - { - idx = find_result.EntryIndex; - } - else - { - idx = add_entry( key ); - - if ( find_result.PrevIndex >= 0 ) - { - Entries[ find_result.PrevIndex ].Next = idx; - } - else - { - Hashes[ find_result.HashIndex ] = idx; - } - } - - Entries[ idx ].Value = value; - - if ( full() ) - grow(); - } - - ssize slot( u64 key ) - { - for ( ssize idx = 0; idx < Hashes.num(); ++idx ) - if ( Hashes[ idx ] == key ) - return idx; - - return -1; - } - - Array_sw Hashes; - Array_Entry Entries; - - protected: - - ssize add_entry( u64 key ) - { - ssize idx; - Entry entry = { key, -1 }; - idx = Entries.num(); - Entries.append( entry ); - return idx; - } - - HashTable_FindResult find( u64 key ) - { - FindResult result = { -1, -1, -1 }; - if ( Hashes.num() > 0 ) - { - result.HashIndex = key % Hashes.num(); - result.EntryIndex = Hashes[ result.HashIndex ]; - - while ( result.EntryIndex >= 0 ) - { - if ( Entries[ result.EntryIndex ].Key == key ) - break; - - result.PrevIndex = result.EntryIndex; - result.EntryIndex = Entries[ result.EntryIndex ].Next; - } - } - return result; - } - - b32 full( void ) - { - return 0.75f * Hashes.num() < Entries.num(); - } - }; - ) - )); - - return def_global_body( args( ht_entry, array_ht_entry, hashtable )); -} - -struct GenHashTableRequest -{ - StrC Dependency; - StrC Type; -}; -Array GenHashTableRequests; - -void gen__hashtable_request( StrC type, StrC dep = {} ) -{ - do_once_start - GenHashTableRequests = Array::init( GlobalAllocator ); - - gen_array( ssize ); - do_once_end - - // Make sure we don't already have a request for the type. - for ( ssize idx = 0; idx < GenHashTableRequests.num(); ++idx ) - { - StrC const reqest_type = GenHashTableRequests[ idx ].Type; - - if ( reqest_type.Len != type.Len ) - continue; - - if ( str_compare( reqest_type.Ptr, type.Ptr, reqest_type.Len ) == 0 ) - return; - } - - GenHashTableRequest request = { dep, type }; - GenHashTableRequests.append( request ); -} -#define gen_hashtable( type ) gen__hashtable_request( code(type) ) - -u32 gen_hashtable_file() -{ - Builder - gen_hashtable_file; - gen_hashtable_file.open( "hashtable.Parsed.gen.hpp" ); - - gen_hashtable_file.print( def_include( txt("gen.hpp")) ); - gen_hashtable_file.print( def_include( txt("Array.Parsed.hpp")) ); - gen_hashtable_file.print( def_include( txt("array.Parsed.gen.hpp")) ); - - gen_hashtable_file.print( def_using_namespace( name(gen))); - - gen_hashtable_file.print( gen__hashtable_base()); - - GenHashTableRequest* current = GenHashTableRequests; - s32 left = GenHashTableRequests.num(); - while (left--) - { - GenHashTableRequest const& request = * current; - - Code generated_buffer = gen__hashtable( current->Type ); - - if ( request.Dependency ) - { - char const* cmt_str = str_fmt_buf( "// Dependency for %s type", request.Type ); - s32 cmt_len = str_len( cmt_str ); - - Code cmt = def_comment( { cmt_len, cmt_str } ); - Code include = def_include( request.Dependency ); - - gen_hashtable_file.print( cmt ); - gen_hashtable_file.print( include ); - } - - gen_hashtable_file.print( generated_buffer ); - current++; - } - - gen_hashtable_file.write(); - return 0; -} - -#endif // GEN_TIME diff --git a/test/_old/parsed/Ring.Parsed.hpp b/test/_old/parsed/Ring.Parsed.hpp deleted file mode 100644 index 9177776..0000000 --- a/test/_old/parsed/Ring.Parsed.hpp +++ /dev/null @@ -1,175 +0,0 @@ -#pragma once - -#if GEN_TIME -#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS -#define GEN_ENFORCE_STRONG_CODE_TYPES -#define GEN_EXPOSE_BACKEND -#define GEN_BENCHMARK -#include "gen.hpp" -#include "Buffer.Parsed.hpp" - -using namespace gen; - -Code gen__ring( StrC type ) -{ - static Code t_allocator_info = def_type( name(AllocatorInfo) ); - - StringCached name; - { - char const* name_str = str_fmt_buf( "Ring_%s\0", type.Ptr ); - s32 name_len = str_len( name_str ); - - name = get_cached_string({ name_len, name_str }); - }; - - StrC buffer_name = to_str( str_fmt_buf( "Buffer_%s", type.Ptr )); - - Code ring = parse_struct( token_fmt( "RingName", (StrC)name, "type", type, "BufferName", buffer_name, - stringize( - struct - { - using Type = ; - - static init( AllocatorInfo allocator, usize max_size ) - { - result = { 0 }; - - result.Backing = allocator; - result.Buffer = ::init( allocator, max_size + 1 ); - - if ( result.Buffer == nullptr ) - return { nullptr }; - - result.Capacity = max_size + 1; - return result; - } - - void append( s16 value ) - { - Buffer[ Head ] = value; - Head = ( Head + 1 ) % Capacity; - if ( Head == Tail ) - Tail = ( Tail + 1 ) % Capacity; - } - - inline void append( Type* values, ssize num ) - { - for ( ssize idx = 0; idx < num; idx++ ) - append( values[ idx ] ); - } - - bool empty( void ) - { - return Head == Tail; - } - - void free( void ) - { - Buffer.free(); - } - - bool full( void ) - { - return ( Head + 1 ) % Capacity == Tail; - } - - Type& get( void ) - { - Type& data = Buffer[ Tail ]; - Tail = ( Tail + 1 ) % Capacity; - return data; - } - - void wipe( void ) - { - Head = 0; - Tail = 0; - Buffer.wipe(); - } - - AllocatorInfo Backing; - usize Capacity; - usize Head; - usize Tail; - Buffer; - }; - ) - )); - - return ring; -} - -struct GenRingRequest -{ - StrC Dependency; - StrC Type; -}; -Array GenRingRequests; - -void gen__ring_request( StrC type, StrC dep = {} ) -{ - do_once_start - GenRingRequests = Array::init( GlobalAllocator ); - do_once_end - - // Make sure we don't already have a request for the type. - for ( ssize idx = 0; idx < GenRingRequests.num(); ++idx ) - { - StrC const reqest_type = GenRingRequests[ idx ].Type; - - if ( reqest_type.Len != type.Len ) - continue; - - if ( str_compare( reqest_type.Ptr, type.Ptr, reqest_type.Len ) == 0 ) - return; - } - - // Ring definition depends on a array and buffer definition. - gen__buffer_request( type, dep ); - - GenRingRequest request = { dep, type }; - GenRingRequests.append( request ); -} -#define gen_ring( type ) gen__ring_request( code(type) ) - -u32 gen_ring_file() -{ - Builder - gen_ring_file; - gen_ring_file.open( "ring.Parsed.gen.hpp" ); - - gen_ring_file.print( def_include( txt("gen.hpp")) ); - gen_ring_file.print( def_include( txt("buffer.Parsed.gen.hpp")) ); - // gen_ring_file.print( gen__ring_base() ); - - gen_ring_file.print( def_using_namespace( name(gen))); - - GenRingRequest* current = GenRingRequests; - s32 left = GenRingRequests.num(); - while (left--) - { - GenRingRequest const& request = * current; - - Code generated_ring = gen__ring( current->Type ); - - if ( request.Dependency ) - { - char const* cmt_str = str_fmt_buf( "// Dependency for %s type", request.Type ); - s32 cmt_len = str_len( cmt_str ); - - Code cmt = def_comment( { cmt_len, cmt_str } ); - Code include = def_include( request.Dependency ); - - gen_ring_file.print( cmt ); - gen_ring_file.print( include ); - } - - gen_ring_file.print( generated_ring ); - current++; - } - - gen_ring_file.write(); - return 0; -} - -#endif // GEN_TIME diff --git a/test/_old/parsed/Sanity.Parsed.hpp b/test/_old/parsed/Sanity.Parsed.hpp deleted file mode 100644 index 6a8d4f6..0000000 --- a/test/_old/parsed/Sanity.Parsed.hpp +++ /dev/null @@ -1,344 +0,0 @@ -#pragma once -#ifdef GEN_TIME -#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS -#define GEN_ENFORCE_STRONG_CODE_TYPES -#define GEN_EXPOSE_BACKEND -#define GEN_BENCHMARK -#include "gen.hpp" - -using namespace gen; - -u32 gen_sanity() -{ - Builder - gen_sanity_file; - gen_sanity_file.open("./sanity.Parsed.gen.hpp"); - - gen_sanity_file.print( def_comment( txt( - "The following will show a series of base cases for the gen parsed api.\n" - ))); - - // Typedef - { - CodeTypedef u8_typedef = parse_typedef( code( - typedef unsigned char u8; - )); - - gen_sanity_file.print(u8_typedef); - } - - gen_sanity_file.print_fmt("\n"); - - // Class - { - CodeClass fwd = parse_class( code( - class TestEmptyClass; - )); - - CodeClass empty_body = parse_class( code( - class TestEmptyClass - {}; - )); - - empty_body->Body.append( def_comment( txt("Empty class body") ) ); - - gen_sanity_file.print(fwd); - gen_sanity_file.print(empty_body); - } - - gen_sanity_file.print_fmt("\n"); - - // Enum - { - CodeEnum fwd = parse_enum( code( - enum ETestEnum : u8; - )); - - CodeEnum def = parse_enum( code( - enum ETestEnum : u8 - { - A, - B, - C - }; - )); - - CodeEnum fwd_enum_class = parse_enum( code( - enum class ETestEnumClass : u8; - )); - - gen_sanity_file.print(fwd); - gen_sanity_file.print(def); - gen_sanity_file.print(fwd_enum_class); - } - - gen_sanity_file.print_fmt("\n"); - - // External Linkage - { - CodeComment empty_comment = def_comment( txt("Empty external linkage") ); - - CodeExtern c_extern = parse_extern_link( code( - extern "C" - { - }; - )); - - c_extern->Body.append( empty_comment ); - - gen_sanity_file.print(c_extern); - } - - gen_sanity_file.print_fmt("\n"); - - // Friend - { - CodeClass fwd = parse_class( code( - class TestFriendClass; - )); - - CodeClass def = parse_class( code( - class TestFriend - { - friend class TestFriendClass; - }; - )); - - gen_sanity_file.print(fwd); - gen_sanity_file.print(def); - } - - gen_sanity_file.print_fmt("\n"); - - // Function - { - CodeFn fwd = parse_function( code( - void test_function(); - )); - - CodeFn def = parse_function( code( - void test_function() - { - } - )); - - def->Body.append( def_comment( txt("Empty function body") ) ); - - gen_sanity_file.print(fwd); - gen_sanity_file.print(def); - } - - gen_sanity_file.print_fmt("\n"); - - // Namespace - { - CodeNS def = parse_namespace( code( - namespace TestNamespace - { - } - )); - - def->Body.append( def_comment( txt("Empty namespace body") ) ); - - gen_sanity_file.print(def); - } - - gen_sanity_file.print_fmt("\n"); - - // Operator - { - CodeEnum bitflagtest = parse_enum( code( - enum class EBitFlagTest : u8 - { - A = 1 << 0, - B = 1 << 1, - C = 1 << 2 - }; - )); - - CodeOperator op_fwd = parse_operator( code( - EBitFlagTest operator | ( EBitFlagTest a, EBitFlagTest b ); - )); - - CodeOperator op_or = parse_operator( code( - EBitFlagTest operator | ( EBitFlagTest a, EBitFlagTest b ) - { - return EBitFlagTest( (u8)a | (u8)b ); - } - )); - - gen_sanity_file.print(bitflagtest); - gen_sanity_file.print(op_fwd); - gen_sanity_file.print(op_or); - } - - gen_sanity_file.print_fmt("\n"); - - // Operator cast - { - CodeOpCast op_ptr = parse_operator_cast( code( - operator u8* (); - )); - - CodeClass class_def = parse_class( code( - class TestClass - { - }; - )); - - class_def->Body.append( op_ptr ); - - gen_sanity_file.print(class_def); - } - - gen_sanity_file.print_fmt("\n"); - - // Parameters - { - CodeFn fwd = parse_function( code( - void test_function_param( int a ); - )); - - CodeFn def = parse_function( code( - void test_function_param2( int a, int b ) - { - } - )); - - def->Body.append( def_comment( txt("Empty function body") ) ); - - gen_sanity_file.print(fwd); - gen_sanity_file.print(def); - } - - gen_sanity_file.print_fmt("\n"); - - // Specifiers - { - CodeFn fwd_fn = parse_function( code( - inline - void test_function_specifiers(); - )); - - CodeTypedef typedef_u8_ptr = parse_typedef( code( - typedef u8* u8_ptr; - )); - - gen_sanity_file.print(fwd_fn); - gen_sanity_file.print(typedef_u8_ptr); - } - - gen_sanity_file.print_fmt("\n"); - - // Struct - { - CodeStruct fwd = parse_struct( code( - struct TestEmptyStruct; - )); - - CodeStruct empty_body = parse_struct( code( - struct TestEmptyStruct - {}; - )); - - empty_body->Body.append( def_comment( txt("Empty struct body") ) ); - - gen_sanity_file.print(fwd); - gen_sanity_file.print(empty_body); - } - - gen_sanity_file.print_fmt("\n"); - - // Union - { - CodeUnion empty = parse_union( code( - union TestEmptyUnion - { - }; - )); - - empty->Body.append( def_comment( txt("Empty union body") ) ); - - gen_sanity_file.print( parse_typedef( code( typedef unsigned short u16; )) ); - gen_sanity_file.print( parse_typedef( code( typedef unsigned long u32; )) ); - - CodeUnion def = parse_union( code( - union TestUnion - { - u8 a; - u16 b; - u32 c; - }; - )); - - gen_sanity_file.print(empty); - gen_sanity_file.print(def); - } - - gen_sanity_file.print_fmt("\n"); - - // Using - { - CodeUsing reg = (CodeUsing) parse_using( code( - using TestUsing = u8; - )); - - CodeNS nspace = parse_namespace( code( - namespace TestNamespace - { - }; - - )); - - CodeUsing npspace_using = parse_using( code( - using namespace TestNamespace; - )); - - gen_sanity_file.print(reg); - gen_sanity_file.print(nspace); - gen_sanity_file.print(npspace_using); - } - - gen_sanity_file.print_fmt("\n"); - - // Variable - { - CodeVar bss = parse_variable( code( - u8 test_variable; - )); - - CodeVar data = parse_variable( code( - u8 test_variable = 0x12; - )); - - gen_sanity_file.print(bss); - gen_sanity_file.print(data); - } - - gen_sanity_file.print_fmt("\n"); - - // template - { - #pragma push_macro("template") - #undef template - CodeTemplate tmpl = parse_template( code( - template< typename Type > - void test_template( Type a ) - { - } - )); - #pragma pop_macro("template") - - gen_sanity_file.print(tmpl); - } - - gen_sanity_file.print_fmt("\n"); - - gen_sanity_file.print( def_comment( txt( - "End of base case tests\n" - ))); - - gen_sanity_file.write(); - return 0; -} -#endif diff --git a/test/_old/parsed/test.parsing.cpp b/test/_old/parsed/test.parsing.cpp deleted file mode 100644 index 52e010a..0000000 --- a/test/_old/parsed/test.parsing.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#ifdef GEN_TIME -#define GEN_FEATURE_PARSING -#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS -#define GEN_ENFORCE_STRONG_CODE_TYPES -#define GEN_EXPOSE_BACKEND -#define GEN_BENCHMARK -#include "Array.Parsed.hpp" -#include "Buffer.Parsed.hpp" -#include "HashTable.Parsed.hpp" -#include "Ring.Parsed.hpp" -#include "Sanity.Parsed.hpp" -#include "SOA.cpp" -#include "gen.cpp" - -using namespace gen; - -// TODO : Need to make a more robust test suite - -int gen_main() -{ - gen::init(); - - gen_sanity(); - - gen_array( u8 ); - gen_array( ssize ); - - gen_buffer( u8 ); - - gen_hashtable( u32 ); - - gen_ring( s16 ); - gen_ring( usize ); - - gen_array_file(); - gen_buffer_file(); - gen_hashtable_file(); - gen_ring_file(); - - Builder soa_test; soa_test.open( "SOA.gen.hpp" ); - - soa_test.print( parse_using( code( - using u16 = unsigned short; - ))); - - soa_test.print( def_include( txt("gen.hpp"))); - - soa_test.print( def_using_namespace( name(gen) ) ); - - soa_test.print( gen_SOA( - parse_struct( code( - struct TestStruct - { - u8 A; - u16 B; - u32 C; - u64 D; - }; - )) - )); - - soa_test.write(); - - gen::deinit(); - return 0; -} -#endif - - -#ifdef runtime -int main() -{ - return 0; -} -#endif diff --git a/test/_old/upfront/Array.Upfront.hpp b/test/_old/upfront/Array.Upfront.hpp deleted file mode 100644 index 389dfdd..0000000 --- a/test/_old/upfront/Array.Upfront.hpp +++ /dev/null @@ -1,375 +0,0 @@ -#pragma once - - - -#if GEN_TIME -#include "gen.hpp" - -using namespace gen; - -Code gen__array_base() -{ - CodeType t_allocator_info = def_type( name(AllocatorInfo) ); - - CodeStruct header = def_struct( name(ArrayHeader), - def_struct_body( args( - def_variable( t_allocator_info, name(Allocator) ) - , def_variable( t_uw, name(Capacity) ) - , def_variable( t_uw, name(Num) ) - ))); - - CodeFn grow_formula = def_function( name(array_grow_formula), def_param( t_uw, name(value)), t_uw - , def_execution( code( return 2 * value * 8; ) ) - , def_specifiers( args( ESpecifier::Static, ESpecifier::Inline ) ) - ); - - return def_global_body( args( header, grow_formula ) ); -} - -Code gen__array( StrC type ) -{ - static CodeType t_allocator_info = def_type( name(AllocatorInfo) ); - static Code v_nullptr = code_str(nullptr); - - static CodeSpecifiers spec_ct_member = def_specifiers( 2, ESpecifier::Constexpr, ESpecifier::Static ); - static CodeSpecifiers spec_static_inline = def_specifiers( 2, ESpecifier::Static, ESpecifier::Inline ); - static CodeSpecifiers spec_static = def_specifier( ESpecifier::Static ); - - static CodeUsing using_header = def_using( name(Header), def_type( name(ArrayHeader) ) ); - static CodeVar ct_grow_formula = def_variable( t_auto, name(grow_formula), untyped_str( code( & array_grow_formula )), spec_ct_member ); - - StrC name; - { - char const* name_str = str_fmt_buf( "Array_%s\0", type.Ptr ); - s32 name_len = str_len( name_str ); - - name = { name_len, name_str }; - }; - - CodeType t_array_type = def_type( name ); - - CodeType t_type = def_type( type ); - CodeType t_type_ptr = def_type( type, __, spec_ptr ); - CodeType t_type_ref = def_type( type, __, spec_ref ); - - CodeType t_alias = def_type( name(Type) ); - CodeType t_alias_ptr = def_type( name(Type), __, spec_ptr ); - CodeType t_alias_ref = def_type( name(Type), __, spec_ref ); - - CodeType t_header = def_type( name(Header) ); - CodeType t_header_ptr = def_type( name(Header), __, spec_ptr ); - CodeType t_header_ref = def_type( name(Header), __, spec_ref ); - - CodeStruct array = {0}; - { - CodeUsing using_type = def_using( name(Type), t_type ); - CodeVar data = def_variable( t_alias_ptr, name(Data) ); - - CodeFn init = def_function( name(init), def_param( t_allocator_info, name(allocator) ), t_array_type - , def_execution( code( - return init_reserve( allocator, grow_formula(0) ); - )) - , spec_static - ); - - CodeFn init_reserve; - { - CodeParam params = def_params( args( - def_param( t_allocator_info, name(allocator) ) - , def_param( t_sw, name(capacity) ) - )); - - Code body = def_execution( code( - Header* header = rcast( Header*, alloc( allocator, sizeof(Header) + sizeof(Type) )); - - if ( header == nullptr ) - return { nullptr }; - - header->Allocator = allocator; - header->Capacity = capacity; - header->Num = 0; - - return { rcast( Type*, header + 1) }; - )); - - init_reserve = def_function( name(init_reserve), params, t_array_type, body, spec_static ); - } - - CodeFn append = def_function( name(append), def_param(t_alias, name(value)), t_bool - , def_execution( code( - Header* header = get_header(); - - if ( header->Num == header->Capacity ) - { - if ( ! grow( header->Capacity )) - return false; - - header = get_header(); - } - - Data[ header->Num ] = value; - header->Num++; - - return true; - )) - ); - - CodeFn back = def_function( name(back), __, t_alias_ref - , def_execution( code( - Header& header = * get_header(); - return Data[ header.Num - 1 ]; - )) - ); - - CodeFn clear = def_function( name(clear), __, t_void - , def_execution( code( - Header& header = * get_header(); - header.Num = 0; - )) - ); - - CodeFn fill; - { - CodeParam params = def_params( args( - def_param( t_uw, name(begin) ) - , def_param( t_uw, name(end) ) - , def_param( t_alias, name(value) ) - )); - - Code body = untyped_str( code( - Header& header = * get_header(); - - if ( begin < 0 || end >= header.Num ) - return false; - - for ( ssize idx = begin; idx < end; idx++ ) - { - Data[ idx ] = value; - } - - return true; - )); - - fill = def_function( name(fill), params, t_bool, body ); - } - - CodeFn free = def_function( name(free), __, t_void - , def_execution( code( - Header* header = get_header(); - gen::free( header->Allocator, header ); - )) - ); - - CodeFn get_header = def_function( name(get_header), __, t_header_ptr - , def_execution( code( - return rcast( Header*, Data ) - 1; - )) - ); - - CodeFn grow = def_function( name(grow), def_param( t_uw, name(min_capacity)), t_bool - , def_execution( code( - Header& header = * get_header(); - - usize new_capacity = grow_formula( header.Capacity ); - - if ( new_capacity < min_capacity ) - new_capacity = 8; - - return set_capacity( new_capacity ); - )) - ); - - CodeFn num = def_function( name(num), __, t_uw - , def_execution( code( - return get_header()->Num; - )) - ); - - CodeFn pop = def_function( name(pop), __, t_bool - , def_execution( code( - Header& header = * get_header(); - - GEN_ASSERT( header.Num > 0 ); - header.Num--; - )) - ); - - CodeFn remove_at = def_function( name(remove_at), def_param( t_uw, name(idx)), t_void - , def_execution( code( - Header* header = get_header(); - GEN_ASSERT( idx < header->Num ); - - mem_move( header + idx, header + idx + 1, sizeof( Type ) * ( header->Num - idx - 1 ) ); - header->Num--; - )) - ); - - CodeFn reserve = def_function( name(reserve), def_param( t_uw, name(new_capacity)), t_bool - , def_execution( code( - Header& header = * get_header(); - - if ( header.Capacity < new_capacity ) - return set_capacity( new_capacity ); - - return true; - )) - ); - - CodeFn resize = def_function( name(resize), def_param( t_uw, name(num)), t_bool - , def_execution( code( - Header* header = get_header(); - - if ( num > header->Capacity ) - { - if ( ! grow( header->Capacity )) - return false; - - header = get_header(); - } - - header->Num = num; - return true; - )) - ); - - CodeFn set_capacity; - { - Code body = def_execution( code( - Header& header = * get_header(); - - if ( new_capacity == header.Capacity ) - return true; - - if ( new_capacity < header.Num ) - header.Num = new_capacity; - - ssize size = sizeof(Header) + sizeof(Type) * new_capacity; - Header* new_header = rcast( Header*, alloc( header.Allocator, size )); - - if ( new_header == nullptr ) - return false; - - mem_move( new_header, & header, sizeof( Header ) + sizeof(Type) * header.Num ); - - new_header->Capacity = new_capacity; - - gen::free( header.Allocator, & header ); - - Data = rcast( Type*, new_header + 1); - - return true; - )); - - set_capacity = def_function( name(set_capacity), def_param( t_uw, name(new_capacity)), t_bool, body ); - } - - CodeOpCast op_ptr = def_operator_cast( t_type_ptr, def_execution( code( - return Data; - ))); - - CodeBody body = def_struct_body( args( - using_header - , using_type - , ct_grow_formula - - , init - , init_reserve - - , append - , back - , clear - , fill - , free - , get_header - , grow - , num - , pop - , remove_at - , reserve - , resize - , set_capacity - - , op_ptr - - , data - )); - array = def_struct( name, body ); - } - - return array; -} - - -struct GenArrayRequest -{ - StrC Dependency; - StrC Type; -}; -Array GenArrayRequests; - -void gen__array_request( StrC type, StrC dep = {} ) -{ - do_once_start - GenArrayRequests = Array::init( GlobalAllocator ); - do_once_end - - // Make sure we don't already have a request for the type. - for ( ssize idx = 0; idx < GenArrayRequests.num(); ++idx ) - { - StrC const reqest_type = GenArrayRequests[ idx ].Type; - - if ( reqest_type.Len != type.Len ) - continue; - - if ( str_compare( reqest_type.Ptr, type.Ptr, reqest_type.Len ) == 0 ) - return; - } - - GenArrayRequest request = { dep, type }; - GenArrayRequests.append( request ); -} -#define gen_array( type ) gen__array_request( code(type) ) - -u32 gen_array_file() -{ - Builder - gen_array_file; - gen_array_file.open( "array.Upfront.gen.hpp" ); - - CodeInclude include_gen = def_include( txt("gen.hpp") ); - gen_array_file.print( include_gen ); - - gen_array_file.print( def_using_namespace( name(gen))); - - Code array_base = gen__array_base(); - gen_array_file.print( array_base ); - - GenArrayRequest* current = GenArrayRequests; - s32 left = GenArrayRequests.num(); - while (left--) - { - GenArrayRequest const& request = * current; - - Code generated_array = gen__array( request.Type ); - - if ( request.Dependency ) - { - char const* cmt_str = str_fmt_buf( "// Dependency for %s type", request.Type ); - s32 cmt_len = str_len( cmt_str ); - - CodeComment cmt = def_comment( { cmt_len, cmt_str } ); - CodeInclude include = def_include( request.Dependency ); - - gen_array_file.print( cmt ); - gen_array_file.print( include ); - } - - gen_array_file.print( generated_array ); - current++; - } - - gen_array_file.write(); - return 0; -} - -#endif diff --git a/test/_old/upfront/Buffer.Upfront.hpp b/test/_old/upfront/Buffer.Upfront.hpp deleted file mode 100644 index 2821394..0000000 --- a/test/_old/upfront/Buffer.Upfront.hpp +++ /dev/null @@ -1,275 +0,0 @@ -#pragma once - -#if GEN_TIME -#include "gen.hpp" - -using namespace gen; - -Code gen__buffer_base() -{ - CodeType t_allocator_info = def_type( name(AllocatorInfo) ); - - Code header = def_struct( name(BufferHeader), - def_struct_body( args( - def_variable( t_allocator_info, name(Backing) ) - , def_variable( t_uw, name(Capacity) ) - , def_variable( t_uw, name(Num) ) - ))); - - return def_global_body( 1, header ); -} - -Code gen__buffer( StrC type, ssize type_size ) -{ - static CodeType t_allocator_info = def_type( name(AllocatorInfo)); - - static CodeUsing using_header = def_using( name(Header), def_type( name(BufferHeader) ) ); - - StrC name; - { - char const* name_str = str_fmt_buf( "Buffer_%s\0", type.Ptr ); - s32 name_len = str_len( name_str ); - - name = { name_len, name_str }; - }; - - CodeType t_buffer_type = def_type( name ); - - CodeType t_type = def_type( type ); - CodeType t_type_ptr = def_type( type, __, spec_ptr ); - CodeType t_type_ref = def_type( type, __, spec_ref ); - - CodeType t_header = def_type( name(Header) ); - CodeType t_header_ptr = def_type( name(Header), __, spec_ptr ); - CodeType t_header_ref = def_type( name(Header), __, spec_ref ); - - CodeStruct buffer = {0}; - { - CodeUsing using_type = def_using( name(Type), t_type ); - CodeVar data = def_variable( t_type_ptr, name(Data) ); - - CodeFn init; - { - CodeParam params = def_params( args( - def_param( t_allocator_info, name(allocator)) - , def_param( t_sw, name(capacity)) - )); - - Code body = def_execution( code( - Header* header = rcast( Header*, alloc( allocator, sizeof(Header) + capacity * sizeof(Type) ) ); - - if ( header == nullptr ) - return { nullptr }; - - header->Backing = allocator; - header->Capacity = capacity; - header->Num = 0; - - return { rcast( Type*, header + 1) }; - )); - - init = def_function( name(init), params, t_buffer_type, body, spec_static_member ); - } - - CodeFn init_copy; - { - CodeParam params = def_params( args( - def_param( t_allocator_info, name(allocator)) - , def_param( t_buffer_type, name(other)) - )); - - init_copy = def_function( name(init), params, t_buffer_type - , def_execution( code( - Header& other_header = other.get_header(); - Header* header = rcast( Header*, alloc( allocator, sizeof(Header) + other_header.Capacity * sizeof(Type) ) ); - - if ( header == nullptr ) - return { nullptr }; - - header->Backing = allocator; - header->Capacity = other_header.Capacity; - header->Num = other_header.Num; - - mem_copy( header + 1, other.Data, other_header.Num * sizeof(Type) ); - return { rcast( Type*, header + 1) }; - )) - ); - } - - CodeFn append = def_function( name(append), def_param( t_type, name(value)), t_void - , def_execution( code( - Header& header = get_header(); - Data[ header.Num ] = value; - header.Num++; - )) - ); - - CodeFn appendv; - { - CodeParam params = def_params( args( - def_param( t_type_ptr, name( values)) - , def_param( t_sw, name( num)) - )); - - appendv = def_function( name(append), params, t_void - , def_execution( code( - Header& header = get_header(); - - GEN_ASSERT( header.Num + num <= header.Capacity); - - mem_copy( Data + header.Num, values, num * sizeof( Type ) ); - - header.Num += num; - )) - ); - } - - CodeFn clear = def_function( name(clear), __, t_void - , def_execution( code( - Header& header = get_header(); - header.Num = 0; - )) - ); - - CodeFn end = def_function( name(end), __, t_type_ref - , def_execution( code( - Header& header = get_header(); - return Data[ header.Num - 1 ]; - )) - ); - - CodeFn free = def_function( name(free), __, t_void - , def_execution( code( - Header& header = get_header(); - gen::free( header.Backing, & header ); - )) - ); - - CodeFn get_header = def_function( name(get_header), __, t_header_ref - , def_execution( code( - return * ( rcast( Header*, Data ) - 1 ); - )) - ); - - CodeFn num = def_function( name(num), __, t_sw - , def_execution( code( - return get_header().Num; - )) - ); - - CodeFn pop = def_function( name(pop), __, t_type - , def_execution( code( - Header& header = get_header(); - header.Num--; - return Data[ header.Num ]; - )) - ); - - CodeFn wipe = def_function( name(wipe), __, t_void - , def_execution( code( - Header& header = get_header(); - header.Num = 0; - mem_set( Data, 0, header.Capacity * sizeof( Type ) ); - )) - ); - - CodeOpCast op_type_ptr = def_operator_cast( t_type_ptr, def_execution( code( - return Data; - ))); - - buffer = def_struct( name, def_struct_body( args( - using_header - , using_type - - , init - , init_copy - , append - , appendv - , clear - , end - , free - , get_header - , num - , pop - , wipe - - , op_type_ptr - - , data - ))); - } - - return buffer; -} - -struct GenBufferRequest -{ - StrC Dependency; - StrC Type; - ssize TypeSize; -}; -Array GenBufferRequests; - -void gen__buffer_request( StrC type, StrC dep = {} ) -{ - do_once_start - GenBufferRequests = Array::init( GlobalAllocator ); - do_once_end - - // Make sure we don't already have a request for the type. - for ( ssize idx = 0; idx < GenBufferRequests.num(); ++idx ) - { - StrC const reqest_type = GenBufferRequests[ idx ].Type; - - if ( reqest_type.Len != type.Len ) - continue; - - if ( str_compare( reqest_type.Ptr, type.Ptr, reqest_type.Len ) == 0 ) - return; - } - - GenBufferRequest request = { dep, type}; - GenBufferRequests.append( request ); -} -#define gen_buffer( type ) gen__buffer_request( code(type)) - -u32 gen_buffer_file() -{ - Builder - gen_buffer_file; - gen_buffer_file.open( "buffer.Upfront.gen.hpp" ); - - gen_buffer_file.print( def_include( txt("gen.hpp")) ); - gen_buffer_file.print( def_using_namespace( name(gen)) ); - - gen_buffer_file.print( gen__buffer_base() ); - - GenBufferRequest* current = GenBufferRequests; - s32 left = GenBufferRequests.num(); - while (left--) - { - GenBufferRequest const& request = * current; - - Code generated_buffer = gen__buffer( current->Type, current->TypeSize ); - - if ( request.Dependency ) - { - char const* cmt_str = str_fmt_buf( "// Dependency for %s type", request.Type ); - s32 cmt_len = str_len( cmt_str ); - - Code cmt = def_comment( { cmt_len, cmt_str } ); - Code include = def_include( request.Dependency ); - - gen_buffer_file.print( cmt ); - gen_buffer_file.print( include ); - } - - gen_buffer_file.print( generated_buffer ); - current++; - } - - gen_buffer_file.write(); - return 0; -} - -#endif // GEN_TIME diff --git a/test/_old/upfront/HashTable.Upfront.hpp b/test/_old/upfront/HashTable.Upfront.hpp deleted file mode 100644 index ed04f5d..0000000 --- a/test/_old/upfront/HashTable.Upfront.hpp +++ /dev/null @@ -1,486 +0,0 @@ -#pragma once - -#if GEN_TIME -#include "gen.hpp" -#include "Array.Upfront.hpp" - -using namespace gen; - -Code gen__hashtable_base() -{ - CodeVar hashIndex = def_variable( t_sw, name(HashIndex) ); - CodeVar entry_prev = def_variable( t_sw, name(PrevIndex) ); - CodeVar entry_index = def_variable( t_sw, name(EntryIndex) ); - - CodeStruct find_result = def_struct( name(HashTable_FindResult), def_struct_body( 3 - , hashIndex - , entry_prev - , entry_index - )); - - return find_result; -} - -Code gen__hashtable( StrC type ) -{ - static CodeType t_allocator_info = def_type( name(AllocatorInfo) ); - - CodeType t_find_result = def_type( name(HashTable_FindResult) ); - - StringCached name; - { - char const* name_str = str_fmt_buf( "HashTable_%s", type.Ptr ); - s32 len = str_len( name_str ); - - name = get_cached_string({ len, name_str }); - } - - CodeType t_ht_type = def_type( name ); - - CodeType t_type = def_type( type ); - CodeType t_type_ptr = def_type( type, __, spec_ptr ); - CodeType t_type_ref = def_type( type, __, spec_ref ); - - // Hash table depends on array container for its entry structure. - CodeType t_ht_entry, t_array_ht_entry; - CodeStruct ht_entry, array_ht_entry; - { - char const* name_str = str_fmt_buf( "HashTable_%s_Entry", type.Ptr ); - s32 len = str_len( name_str ); - - StringCached ht_entry_name = get_cached_string({ len, name_str }); - - t_ht_entry = def_type( ht_entry_name ); - ht_entry = def_struct( ht_entry_name, def_struct_body( args( - def_variable( t_u64, name(Key)) - , def_variable( t_sw, name(Next)) - , def_variable( t_type, name(Value)) - ))); - - array_ht_entry = gen__array( ht_entry_name ); - t_array_ht_entry = def_type( array_ht_entry->Name ); - } - - CodeStruct hashtable = {0}; - { - CodeUsing using_entry = def_using( name(Entry), t_ht_entry ); - CodeUsing using_array_entry = def_using( name(Array_Entry), t_array_ht_entry ); - CodeUsing using_find_result = def_using( name(FindResult), t_find_result ); - - CodeType t_array_sw = def_type( name(Array_sw) ); - CodeType t_array_entry = def_type( name(Array_Entry) ); - - CodeVar hashes = def_variable( t_array_sw, name(Hashes) ); - CodeVar entries = def_variable( t_array_entry, name(Entries)); - - CodeFn init; - { - char const* tmpl = stringize( - result = { 0 }; - - result.Hashes = Array_sw ::init( allocator ); - result.Entries = Array_Entry::init( allocator ); - - return result; - ); - Code body = def_execution( token_fmt( "type", (StrC)name, tmpl ) ); - - init = def_function( name(init), def_param( t_allocator_info, name(allocator)), t_ht_type, body, spec_static_member ); - } - - - CodeFn init_reserve; - { - char const* tmpl = stringize( - result = { { nullptr }, { nullptr } }; - - result.Hashes = Array_sw::init_reserve( allocator, num ); - result.Hashes.get_header()->Num = num; - - result.Entries = Array_Entry::init_reserve( allocator, num ); - - return result; - ); - Code body = def_execution( token_fmt( "type", (StrC)name, tmpl ) ); - - CodeParam params = def_params( args( def_param( t_allocator_info, name(allocator)), def_param( t_sw, name(num)))); - - init_reserve = def_function( name(init_reserve), params, t_ht_type, body, spec_static_member ); - } - - CodeFn clear = def_function( name(clear), __, t_void - , def_execution( code( - for ( s32 idx = 0; idx < Hashes.num(); idx++ ) - Hashes[ idx ] = -1; - - Entries.clear(); - )) - ); - - CodeFn destroy = def_function( name(destroy), __, t_void - , def_execution( code( - if ( Hashes && Hashes.get_header()->Capacity ) - Hashes.free(); - if ( Entries && Hashes.get_header()->Capacity ) - Entries.free(); - )) - ); - - CodeFn get = def_function( name(get), def_param( t_u64, name(key)), t_type_ptr - , def_execution( code( - ssize idx = find( key ).EntryIndex; - if ( idx >= 0 ) - return & Entries[ idx ].Value; - - return nullptr; - )) - ); - - CodeUsing using_map_proc; - { - char const* tmpl = stringize( - void (*) ( u64 key, value ) - ); - CodeType value = def_type( token_fmt( "type", (StrC)t_type.to_string(), tmpl ) ); - - using_map_proc = def_using ( name(MapProc), value); - } - - CodeFn map; - { - CodeType t_map_proc = def_type( name(MapProc) ); - - Code body = def_execution( code( - GEN_ASSERT_NOT_NULL( map_proc ); - - for ( ssize idx = 0; idx < Entries.num(); idx++ ) - { - map_proc( Entries[ idx ].Key, Entries[ idx ].Value ); - } - )); - - map = def_function( name(map), def_param( t_map_proc, name(map_proc) ), t_void, body ); - } - - CodeUsing using_map_mut_proc; - { - char const* tmpl = stringize( - void (*) ( u64 key, value ) - ); - CodeType value = def_type( token_fmt( "type", (StrC)t_type_ptr.to_string(), tmpl ) ); - - using_map_mut_proc = def_using ( name(MapMutProc), value); - } - - CodeFn map_mut; - { - CodeType t_map_mut_proc = def_type( name(MapMutProc)); - - Code body = def_execution( code( - GEN_ASSERT_NOT_NULL( map_proc ); - - for ( ssize idx = 0; idx < Entries.num(); idx++ ) - { - map_proc( Entries[ idx ].Key, & Entries[ idx ].Value ); - } - )); - - map_mut = def_function( name(map_mut), def_param( t_map_mut_proc, name(map_proc)), t_void, body ); - } - - CodeFn grow = def_function( name(grow), __, t_void - , def_execution( code( - ssize new_num = array_grow_formula( Entries.num() ); - rehash( new_num ); - )) - ); - - CodeFn rehash; - { - char const* tmpl = stringize( - ssize idx; - ssize last_added_index; - - new_ht = init_reserve( Hashes.get_header()->Allocator, new_num ); - - Array_sw::Header* hash_header = new_ht.Hashes.get_header(); - - for ( idx = 0; idx < new_ht.Hashes.num(); ++idx ) - new_ht.Hashes[ idx ] = -1; - - for ( idx = 0; idx < Entries.num(); ++idx ) - { - Entry& entry = Entries[ idx ]; - - FindResult find_result; - - if ( new_ht.Hashes.num() == 0 ) - new_ht.grow(); - - entry = Entries[ idx ]; - find_result = new_ht.find( entry.Key ); - last_added_index = new_ht.add_entry( entry.Key ); - - if ( find_result.PrevIndex < 0 ) - new_ht.Hashes[ find_result.HashIndex ] = last_added_index; - - else - new_ht.Entries[ find_result.PrevIndex ].Next = last_added_index; - - new_ht.Entries[ last_added_index ].Next = find_result.EntryIndex; - new_ht.Entries[ last_added_index ].Value = entry.Value; - } - - destroy(); - *this = new_ht; - ); - Code body = def_execution( token_fmt( "type", (StrC)name, tmpl ) ); - - rehash = def_function( name(rehash), def_param( t_sw, name(new_num)), t_void, body ); - } - - CodeFn rehash_fast; - { - char const* tmpl = stringize( - ssize idx; - - for ( idx = 0; idx < Entries.num(); idx++ ) - Entries[ idx ].Next = -1; - - for ( idx = 0; idx < Hashes.num(); idx++ ) - Hashes[ idx ] = -1; - - for ( idx = 0; idx < Entries.num(); idx++ ) - { - Entry* entry; - - FindResult find_result; - } - ); - Code body = def_execution( token_fmt( "type", name, tmpl ) ); - - rehash_fast = def_function( name(rehash_fast), __, t_void, body ); - } - - CodeFn remove = def_function( name(remove), def_param( t_u64, name(key)), t_void - , def_execution( code( - FindResult find_result = find( key); - - if ( find_result.EntryIndex >= 0 ) - { - Entries.remove_at( find_result.EntryIndex ); - rehash_fast(); - } - )) - ); - - CodeFn remove_entry = def_function( name(remove_entry), def_param( t_sw, name(idx)), t_void - , def_execution( code( - Entries.remove_at( idx ); - )) - ); - - CodeFn set; - { - CodeParam params = def_params( args( - def_param( t_u64, name(key)) - , def_param( t_type, name(value)) - )); - - Code body = def_execution( code( - ssize idx; - FindResult find_result; - - if ( Hashes.num() == 0 ) - grow(); - - find_result = find( key ); - - if ( find_result.EntryIndex >= 0 ) - { - idx = find_result.EntryIndex; - } - else - { - idx = add_entry( key ); - - if ( find_result.PrevIndex >= 0 ) - { - Entries[ find_result.PrevIndex ].Next = idx; - } - else - { - Hashes[ find_result.HashIndex ] = idx; - } - } - - Entries[ idx ].Value = value; - - if ( full() ) - grow(); - )); - - set = def_function( name(set), params, t_void, body ); - } - - CodeFn slot = def_function( name(slot), def_param( t_u64, name(key)), t_sw - , def_execution( code( - for ( ssize idx = 0; idx < Hashes.num(); ++idx ) - if ( Hashes[ idx ] == key ) - return idx; - - return -1; - )) - ); - - CodeFn add_entry = def_function( name(add_entry), def_param( t_u64, name(key)), t_sw - , def_execution( code( - ssize idx; - Entry entry = { key, -1 }; - - idx = Entries.num(); - Entries.append( entry ); - return idx; - )) - ); - - CodeFn find = def_function( name(find), def_param( t_u64, name(key)), t_find_result - , def_execution( code( - FindResult result = { -1, -1, -1 }; - - if ( Hashes.num() > 0 ) - { - result.HashIndex = key % Hashes.num(); - result.EntryIndex = Hashes[ result.HashIndex ]; - - while ( result.EntryIndex >= 0 ) - { - if ( Entries[ result.EntryIndex ].Key == key ) - break; - - result.PrevIndex = result.EntryIndex; - result.EntryIndex = Entries[ result.EntryIndex ].Next; - } - } - - return result; - )) - ); - - CodeFn full = def_function( name(full), __, t_b32 - , def_execution( code( - return 0.75f * Hashes.num() < Entries.num(); - )) - ); - - hashtable = def_struct( name, def_struct_body( args( - using_entry - , using_array_entry - , using_find_result - , using_map_proc - , using_map_mut_proc - - , init - , init_reserve - - , clear - , destroy - , get - , grow - , map - , map_mut - , rehash - , rehash_fast - , remove - , remove_entry - , set - , slot - - , hashes - , entries - - , access_protected - , add_entry - , find - , full - ))); - } - - return def_global_body( args( ht_entry, array_ht_entry, hashtable )); -} - -struct GenHashTableRequest -{ - StrC Dependency; - StrC Type; -}; -Array GenHashTableRequests; - -void gen__hashtable_request( StrC type, StrC dep = {} ) -{ - do_once_start - GenHashTableRequests = Array::init( GlobalAllocator ); - - gen_array( ssize ); - do_once_end - - // Make sure we don't already have a request for the type. - for ( ssize idx = 0; idx < GenHashTableRequests.num(); ++idx ) - { - StrC const reqest_type = GenHashTableRequests[ idx ].Type; - - if ( reqest_type.Len != type.Len ) - continue; - - if ( str_compare( reqest_type.Ptr, type.Ptr, reqest_type.Len ) == 0 ) - return; - } - - GenHashTableRequest request = { dep, type }; - GenHashTableRequests.append( request ); -} -#define gen_hashtable( type ) gen__hashtable_request( code(type)) - -u32 gen_hashtable_file() -{ - Builder - gen_hashtable_file; - gen_hashtable_file.open( "hashtable.Upfront.gen.hpp" ); - - gen_hashtable_file.print( def_include( txt("gen.hpp")) ); - gen_hashtable_file.print( def_include( txt("Array.Upfront.hpp")) ); - gen_hashtable_file.print( def_include( txt("array.Upfront.gen.hpp")) ); - - gen_hashtable_file.print( def_using_namespace( name(gen))); - - gen_hashtable_file.print( gen__hashtable_base()); - - GenHashTableRequest* current = GenHashTableRequests; - s32 left = GenHashTableRequests.num(); - while (left--) - { - GenHashTableRequest const& request = * current; - - Code generated_buffer = gen__hashtable( current->Type ); - - if ( request.Dependency ) - { - char const* cmt_str = str_fmt_buf( "// Dependency for %s type", request.Type ); - s32 cmt_len = str_len( cmt_str ); - - Code cmt = def_comment( { cmt_len, cmt_str } ); - Code include = def_include( request.Dependency ); - - gen_hashtable_file.print( cmt ); - gen_hashtable_file.print( include ); - } - - gen_hashtable_file.print( generated_buffer ); - current++; - } - - gen_hashtable_file.write(); - return 0; -} - -#endif // GEN_TIME diff --git a/test/_old/upfront/Ring.Upfront.hpp b/test/_old/upfront/Ring.Upfront.hpp deleted file mode 100644 index 69c488b..0000000 --- a/test/_old/upfront/Ring.Upfront.hpp +++ /dev/null @@ -1,228 +0,0 @@ -#pragma once - -#if GEN_TIME -#include "gen.hpp" -#include "Buffer.Upfront.hpp" - -using namespace gen; - -Code gen__ring( StrC type ) -{ - static CodeType t_allocator_info = def_type( name(AllocatorInfo) ); - - String name; - { - char const* name_str = str_fmt_buf( "Ring_%s\0", type.Ptr ); - s32 name_len = str_len( name_str ); - - name = get_cached_string({ name_len, name_str }); - }; - - CodeType t_ring_type = def_type( name ); - CodeType t_ring_type_ptr = def_type( name, __, spec_ptr ); - - CodeType t_type = def_type( type ); - CodeType t_type_ptr = def_type( type, __, spec_ptr ); - CodeType t_type_ref = def_type( type, __, spec_ref ); - - CodeType t_buffer_type; - { - char const* name_str = str_fmt_buf( "Buffer_%s\0", type.Ptr ); - s32 len = str_len( name_str ); - - t_buffer_type = def_type( { len, name_str } ); - } - - CodeStruct ring = {0}; - { - CodeUsing using_type = def_using( name(Type), t_type ); - - CodeVar backing = def_variable( t_allocator_info, name(Backing) ); - CodeVar capacity = def_variable( t_uw, name(Capacity) ); - CodeVar head = def_variable( t_uw, name(Head) ); - CodeVar tail = def_variable( t_uw, name(Tail) ); - CodeVar buffer = def_variable( t_buffer_type, name(Buffer) ); - - CodeFn init; - { - CodeParam params = def_params( args( - def_param( t_allocator_info, name(allocator) ) - , def_param( t_uw, name(max_size) ) - )); - - char const* tmpl = stringize( - result = { 0 }; - - result.Backing = allocator; - - result.Buffer = Buffer_::init( allocator, max_size + 1 ); - - if ( result.Buffer == nullptr ) - return { nullptr }; - - result.Capacity = max_size + 1; - - return result; - ); - Code body = def_execution( token_fmt( "type", (StrC)name, "data_type", type, tmpl )); - - init = def_function( name(init), params, t_ring_type, body, spec_static_member ); - } - - CodeFn append = def_function( name(append), def_param( t_type, name(value)), t_void - , def_execution( code( - Buffer[ Head ] = value; - Head = ( Head + 1 ) % Capacity; - - if ( Head == Tail ) - Tail = ( Tail + 1 ) % Capacity; - )) - ); - - CodeFn appendv; - { - CodeParam params = def_params( 2 - , def_param( t_type_ptr, name(values)) - , def_param( t_sw, name(num)) - ); - - Code body = def_execution( code( - for ( ssize idx = 0; idx < num; idx++ ) - append( values[ idx ] ); - )); - - appendv = def_function( name(append), params, t_void, body, spec_inline ); - } - - CodeFn empty = def_function( name(empty), __, t_bool - , def_execution( code( - return Head == Tail; - )) - ); - - CodeFn free = def_function( name(free), __, t_void - , def_execution( code( - Buffer.free(); - )) - ); - - CodeFn full = def_function( name(full), __, t_bool - , def_execution( code( - return (Head + 1) % Capacity == Tail; - )) - ); - - CodeFn get = def_function( name(get), __, t_type_ref - , def_execution( code( - Type& data = Buffer[ Tail ]; - Tail = ( Tail + 1 ) % Capacity; - - return data; - )) - ); - - CodeFn wipe = def_function( name(wipe), __, t_void - , def_execution( code( - Head = 0; - Tail = 0; - Buffer.wipe(); - )) - ); - - ring = def_struct( name, def_struct_body( args( - using_type, - - init, - - append, - appendv, - empty, - free, - full, - get, - wipe, - - backing, - capacity, - head, - tail, - buffer - ))); - } - - return ring; -} - -struct GenRingRequest -{ - StrC Dependency; - StrC Type; -}; -Array GenRingRequests; - -void gen__ring_request( StrC type, StrC dep = {} ) -{ - do_once_start - GenRingRequests = Array::init( GlobalAllocator ); - do_once_end - - // Make sure we don't already have a request for the type. - for ( ssize idx = 0; idx < GenRingRequests.num(); ++idx ) - { - StrC const reqest_type = GenRingRequests[ idx ].Type; - - if ( reqest_type.Len != type.Len ) - continue; - - if ( str_compare( reqest_type.Ptr, type.Ptr, reqest_type.Len ) == 0 ) - return; - } - - // Ring definition depends on a array and buffer definition. - gen__buffer_request( type, dep ); - - GenRingRequest request = { dep, type }; - GenRingRequests.append( request ); -} -#define gen_ring( type ) gen__ring_request( code(type) ) - -u32 gen_ring_file() -{ - Builder - gen_ring_file; - gen_ring_file.open( "ring.Upfront.gen.hpp" ); - - gen_ring_file.print( def_include( txt("gen.hpp")) ); - gen_ring_file.print( def_include( txt("buffer.Upfront.gen.hpp")) ); - - gen_ring_file.print( def_using_namespace( name(gen))); - - GenRingRequest* current = GenRingRequests; - s32 left = GenRingRequests.num(); - while (left--) - { - GenRingRequest const& request = * current; - - Code generated_ring = gen__ring( current->Type ); - - if ( request.Dependency ) - { - char const* cmt_str = str_fmt_buf( "// Dependency for %s type", request.Type ); - s32 cmt_len = str_len( cmt_str ); - - Code cmt = def_comment( { cmt_len, cmt_str } ); - Code include = def_include( request.Dependency ); - - gen_ring_file.print( cmt ); - gen_ring_file.print( include ); - } - - gen_ring_file.print( generated_ring ); - current++; - } - - gen_ring_file.write(); - return 0; -} - -#endif // GEN_TIME diff --git a/test/_old/upfront/Sanity.Upfront.hpp b/test/_old/upfront/Sanity.Upfront.hpp deleted file mode 100644 index b716342..0000000 --- a/test/_old/upfront/Sanity.Upfront.hpp +++ /dev/null @@ -1,331 +0,0 @@ -#ifdef GEN_TIME -#include "gen.hpp" - -using namespace gen; - -u32 gen_sanity_upfront() -{ - Builder - gen_sanity_file; - gen_sanity_file.open("./sanity.Upfront.gen.hpp"); - - // Comment - { - CodeComment comment_test = def_comment( txt("Sanity check: def_comment test") ); - - gen_sanity_file.print(comment_test); - } - - gen_sanity_file.print_fmt("\n"); - gen_sanity_file.print( def_comment( txt( - "The following will show a series of base cases for the gen api.\n" - ))); - - // Class - { - CodeClass fwd = def_class( name(TestEmptyClass) ); - CodeClass empty_body; - { - CodeComment cmt = def_comment( txt("Empty class body") ); - CodeBody body = def_class_body( args( cmt ) ); - - empty_body = def_class( name(TestEmptyClass), body ); - } - - gen_sanity_file.print(fwd); - gen_sanity_file.print(empty_body); - } - - gen_sanity_file.print_fmt("\n"); - - // Typedef - { - CodeType t_unsigned_char = def_type( name(unsigned char) ); - CodeTypedef u8_typedef = def_typedef( name(u8), t_unsigned_char ); - - gen_sanity_file.print(u8_typedef); - } - - gen_sanity_file.print_fmt("\n"); - - // Enum - { - CodeEnum fwd = def_enum( name(ETestEnum), NullCode, t_u8 ); - CodeEnum def; - { - Code body = untyped_str( code( - A, - B, - C - )); - - def = def_enum( name(ETestEnum), body, t_u8 ); - } - - CodeEnum fwd_enum_class = def_enum( name(ETestEnumClass), NullCode, t_u8, EnumClass ); - - gen_sanity_file.print(fwd); - gen_sanity_file.print(def); - gen_sanity_file.print(fwd_enum_class); - } - - gen_sanity_file.print_fmt("\n"); - - // External Linkage - { - CodeBody body = def_extern_link_body( 1 - , def_comment( txt("Empty extern body") ) - ); - - CodeExtern c_extern = def_extern_link( name(C), body ); - - gen_sanity_file.print(c_extern); - } - - gen_sanity_file.print_fmt("\n"); - - // Friend - { - CodeClass fwd = def_class( name(TestFriendFwd)); - CodeBody body = def_class_body( args( def_friend( fwd ) ) ); - - gen_sanity_file.print( def_class( name(TestFriend), body ) ); - } - - gen_sanity_file.print_fmt("\n"); - - // Function - { - CodeFn fwd = def_function( name(test_function) ); - CodeFn def; - { - CodeBody body = def_function_body( 1 - , def_comment( txt("Empty function body") ) - ); - - def = def_function( name(test_function), __, __, body ); - } - - gen_sanity_file.print(fwd); - gen_sanity_file.print(def); - } - - gen_sanity_file.print_fmt("\n"); - - // Include - { - CodeInclude include = def_include( txt("../DummyInclude.hpp") ); - - gen_sanity_file.print(include); - } - - gen_sanity_file.print_fmt("\n"); - - // Module - if (0) - { - CodeModule module_export = def_module( name(TestModule), ModuleFlag::Export ); - CodeModule module_import = def_module( name(TestModule), ModuleFlag::Import ); - CodeModule module_both = def_module( name(TestModule), ModuleFlag::Export | ModuleFlag::Import ); - - gen_sanity_file.print(module_global_fragment); - gen_sanity_file.print(module_private_fragment); - gen_sanity_file.print(module_export); - gen_sanity_file.print(module_import); - gen_sanity_file.print(module_both); - } - - gen_sanity_file.print_fmt("\n"); - - // Namespace - { - CodeNS namespace_def; - { - CodeBody body = def_namespace_body( 1 - , def_comment( txt("Empty namespace body") ) - ); - - namespace_def = def_namespace( name(TestNamespace), body ); - } - - gen_sanity_file.print(namespace_def); - } - - gen_sanity_file.print_fmt("\n"); - - // Operator - { - // Going to make a bit flag set of overloads for this. - - CodeEnum bitflagtest; - { - CodeBody body = def_enum_body( 1, untyped_str( code( - A = 1 << 0, - B = 1 << 1, - C = 1 << 2 - ))); - bitflagtest = def_enum( name(EBitFlagtest), body, t_u8, EnumClass ); - } - CodeType t_bitflag = def_type( name(EBitFlagtest) ); - - CodeOperator op_fwd, op_or; - { - CodeParam params = def_params( args( - def_param( t_bitflag, name(a) ), - def_param( t_bitflag, name(b) ) - )); - - op_fwd = def_operator( EOperator::BOr, params, t_bitflag ); - op_or = def_operator( EOperator::BOr, params, t_bitflag, untyped_str( code( - return EBitFlagtest( (u8)a | (u8)b ); - ))); - } - - gen_sanity_file.print(bitflagtest); - gen_sanity_file.print(op_fwd); - gen_sanity_file.print(op_or); - } - - gen_sanity_file.print_fmt("\n"); - - // Operator cast - { - CodeType t_u8_ptr = def_type( name(u8), __, spec_ptr ); - - CodeOpCast op_ptr = def_operator_cast( t_u8_ptr, __ ); - - CodeClass op_class = def_class( name(TestOperatorCast), def_class_body( args( op_ptr) ) ); - - gen_sanity_file.print(op_class); - } - - gen_sanity_file.print_fmt("\n"); - - // Parameters - { - CodeFn fwd; - { - CodeParam params = def_param( t_u8, name(a) ); - - fwd = def_function( name(test_function_wparam), params ); - } - - CodeFn def, def2; - { - CodeBody body = def_function_body( 1 - , def_comment( txt("Empty function body") ) - ); - - CodeParam params = def_params( args( - def_param( t_u8, name(a) ) - , def_param( t_u8, name(b) ) - )); - - def = def_function( name(test_function_wparams), params, __, body ); - - CodeParam param_a = def_param( t_u8, name(a)); - CodeParam param_b = def_param( t_u8, name(b)); - CodeParam params_arr[2] = { param_a, param_b }; - - CodeParam params2 = def_params( 2, params_arr ); - - def2 = def_function( name(test_function_wparams2), params2, __, body ); - } - - gen_sanity_file.print(fwd); - gen_sanity_file.print(def); - gen_sanity_file.print(def2); - } - - gen_sanity_file.print_fmt("\n"); - - // Specifiers - { - CodeFn fwd_fn = def_function( name(test_function_specifiers), __, __, __, spec_inline ); - - // TODO : Need an op overload here - - CodeType u8_ptr = def_type( name(u8), __, spec_ptr ); - CodeTypedef typedef_u8_ptr = def_typedef( name(ConstExprTest), u8_ptr ); - - gen_sanity_file.print(fwd_fn); - gen_sanity_file.print(typedef_u8_ptr); - } - - gen_sanity_file.print_fmt("\n"); - - // Struct - { - CodeClass fwd = def_class( name(TestEmptyStruct) ); - CodeClass empty_body; - { - CodeComment cmt = def_comment( txt("Empty struct body") ); - CodeBody body = def_class_body( args( cmt ) ); - - empty_body = def_class( name(TestEmptyStruct), body ); - } - - gen_sanity_file.print(fwd); - gen_sanity_file.print(empty_body); - } - - gen_sanity_file.print_fmt("\n"); - - // Union - { - CodeBody body = def_union_body( 1 - , def_comment( txt("Empty union body") ) - ); - - CodeUnion def = def_union( name(TestEmptyUnion), body ); - - gen_sanity_file.print(def); - } - - gen_sanity_file.print_fmt("\n"); - - // Using - { - CodeUsing reg = def_using( name(TestUsing), t_u8 ); - CodeUsing nspace = def_using_namespace( name(TestNamespace) ); - - gen_sanity_file.print(reg); - gen_sanity_file.print(nspace); - } - - gen_sanity_file.print_fmt("\n"); - - // Variable - { - CodeVar bss = def_variable( t_u8, name(test_variable) ); - CodeVar data = def_variable( t_u8, name(test_variable2), untyped_str( code( 0x12 )) ); - - gen_sanity_file.print(bss); - gen_sanity_file.print(data); - } - - gen_sanity_file.print_fmt("\n"); - - // Template - { - CodeType t_Type = def_type( name(Type) ); - - CodeTemplate tmpl = def_template( def_param( t_class, name(Type) ) - , def_function( name(test_template), def_param( t_Type, name(a) ), __ - , def_function_body(1, def_comment( txt("Empty template function body"))) - ) - ); - - gen_sanity_file.print(tmpl); - } - - gen_sanity_file.print_fmt("\n"); - - gen_sanity_file.print( def_comment( txt( - "End of base case tests.\n" - ))); - - gen_sanity_file.write(); - return 0; -} -#endif diff --git a/test/_old/upfront/test.upfront.cpp b/test/_old/upfront/test.upfront.cpp deleted file mode 100644 index f3edb85..0000000 --- a/test/_old/upfront/test.upfront.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#ifdef GEN_TIME -#define GEN_FEATURE_PARSING -#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS -#define GEN_ENFORCE_STRONG_CODE_TYPES -#define GEN_EXPOSE_BACKEND -#define GEN_BENCHMARK -#include "gen.cpp" -#include "Array.Upfront.hpp" -#include "Buffer.Upfront.hpp" -#include "HashTable.Upfront.hpp" -#include "Ring.Upfront.hpp" -#include "Sanity.Upfront.hpp" - - -using namespace gen; - - -int gen_main() -{ - gen::init(); - - gen_sanity_upfront(); - - gen_array( u8 ); - gen_array( ssize ); - - gen_buffer( u8 ); - - gen_hashtable( u32 ); - - gen_ring( s16 ); - - gen_array_file(); - gen_buffer_file(); - gen_hashtable_file(); - gen_ring_file(); - - gen::deinit(); - return 0; -} -#endif - - -#ifdef runtime -int main() -{ - return 0; -} -#endif diff --git a/test/parsing.cpp b/test/parsing.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/test/parsing.hpp b/test/parsing.hpp deleted file mode 100644 index 671f058..0000000 --- a/test/parsing.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifdef GEN_TIME -#define GEN_FEATURE_PARSING -#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS -#define GEN_ENFORCE_STRONG_CODE_TYPES -#define GEN_EXPOSE_BACKEND -#define GEN_BENCHMARK -#include "gen.hpp" - -void check_parsing() -{ - using namespace gen; - log_fmt("\nupfront: "); - gen::init(); - - // TODO - - gen::deinit(); - log_fmt("Passed!\n"); -} - -#endif \ No newline at end of file diff --git a/test/sanity.cpp b/test/sanity.cpp deleted file mode 100644 index aee4483..0000000 --- a/test/sanity.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// Testing to make sure backend of library is operating properly. - -#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS -#define GEN_ENFORCE_STRONG_CODE_TYPES -#define GEN_EXPOSE_BACKEND -#define GEN_BENCHMARK - -#define GEN_GLOBAL_BUCKET_SIZE megabytes(10) -#define GEN_CODE_POOL_BLOCK_SIZE megabytes(32) -#define GEN_STRING_ARENA_SIZE megabytes(1) - -#include "gen.hpp" -#include "gen.builder.hpp" - -void check_sanity() -{ - using namespace gen; - gen::init(); - log_fmt("\ncheck_sanity:\n"); - - // Test string caching: - CodeType t_int_dupe = def_type( name(int) ); - - if ( t_int_dupe->Name != t_int->Name ) - GEN_FATAL("check_sanity: String caching failed!"); - - - // Purposefully uses an excessive amount of memory to make sure the the memory backend doesn't break. - // This has been tested with num_iterations set to 15000000 (generates 15 million lines of code), the Global_BlockSize, along with CodePool_NumBlocks, and SizePer_StringArena - // must be adjusted to gigabytes(2), kilobytes(512), and gigabyte(1) for good performance without crashing. - /* - Typical usage (megabytes(10), kilobytes(4), megabytes(1), for 650000 (the limit of 10 meg partition buckets in global arena) ) - Memory after builder: - Num Global Arenas : 14 TotalSize: 146800640 ! - Num Code Pools : 794 TotalSize: 416284672 ! - Num String Cache Arenas : 60 TotalSize: 62914560 ! - Num String Cache : 1300007 - - Memory usage to expect at 15 mil file: - Num Global Arenas : 2 TotalSize: 4294967296 ! - Num Code Pools : 144 TotalSize: 9663676416 ! - Num String Cache Arenas : 2 TotalSize: 2147483648 ! - Num String Cache : 30000025 - */ - constexpr - s32 num_iterations = 325000; - - Array typedefs = Array::init_reserve( GlobalAllocator, num_iterations * 2 ); - - s32 idx = num_iterations; - while( --idx ) - { - // Stress testing string allocation - String type_name = String::fmt_buf( GlobalAllocator, "type_%ld", idx ); - String typedef_name = String::fmt_buf(GlobalAllocator, "typedef_%ld", idx ); - - CodeTypedef type_as_int = def_typedef( type_name, t_int ); - CodeType type = def_type( type_name ); - CodeTypedef type_def = def_typedef( typedef_name, type ); - - typedefs.append( type_as_int ); - typedefs.append( type_def ); - } - - log_fmt("\nMemory before builder:\n"); - log_fmt("Num Global Arenas : %llu TotalSize: %llu !\n", Global_AllocatorBuckets.num(), Global_AllocatorBuckets.num() * Global_BucketSize); - log_fmt("Num Code Pools : %llu TotalSize: %llu !\n", CodePools.num(), CodePools.num() * CodePool_NumBlocks * CodePools.back().BlockSize); - log_fmt("Num String Cache Arenas : %llu TotalSize: %llu !\n", StringArenas.num(), StringArenas.num() * SizePer_StringArena); - log_fmt("Num String Cache : %llu\n", StringCache.Entries.num(), StringCache); - - Builder builder = Builder::open( "./gen/sanity.gen.hpp" ); - - idx = typedefs.num(); -#ifdef GEN_BENCHMARK - u64 time_start = time_rel_ms(); -#endif - while( --idx ) - { - builder.print( typedefs[idx] ); - } - - builder.write(); -#ifdef GEN_BENCHMARK - log_fmt("\n\nBuilder finished writting. Time taken: %llu ms\n", time_rel_ms() - time_start); -#endif - - log_fmt("\nMemory after builder:\n"); - log_fmt("Num Global Arenas : %llu TotalSize: %llu !\n", Global_AllocatorBuckets.num(), Global_AllocatorBuckets.num() * Global_BucketSize); - log_fmt("Num Code Pools : %llu TotalSize: %llu !\n", CodePools.num(), CodePools.num() * CodePool_NumBlocks * CodePools.back().BlockSize); - log_fmt("Num String Cache Arenas : %llu TotalSize: %llu !\n", StringArenas.num(), StringArenas.num() * SizePer_StringArena); - log_fmt("Num String Cache : %llu\n", StringCache.Entries.num(), StringCache); - - gen::deinit(); - log_fmt("\nSanity passed!\n"); -} diff --git a/test/test.cpp b/test/test.cpp deleted file mode 100644 index c28418c..0000000 --- a/test/test.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#if GEN_TIME -#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS -#define GEN_ENFORCE_STRONG_CODE_TYPES -#define GEN_EXPOSE_BACKEND -#define GEN_BENCHMARK -#include "gen.cpp" -#include "gen.builder.cpp" -#include "gen.scanner.cpp" -#include "sanity.cpp" -#include "SOA.cpp" - -#ifdef GEN_SYSTEM_WINDOWS - #include -#endif - -using namespace gen; - -void format_file( char const* path ) -{ - String resolved_path = String::make(GlobalAllocator, to_str(path)); - - String style_arg = String::make(GlobalAllocator, txt("-style=file:")); - style_arg.append("../scripts/.clang-format "); - - // Need to execute clang format on the generated file to get it to match the original. - #define clang_format "clang-format " - #define cf_format_inplace "-i " - #define cf_verbose "-verbose " - String command = String::make( GlobalAllocator, clang_format ); - command.append( cf_format_inplace ); - command.append( cf_verbose ); - command.append( style_arg ); - command.append( resolved_path ); - log_fmt("\tRunning clang-format on file:\n"); - system( command ); - log_fmt("\tclang-format finished reformatting.\n"); - #undef cf_cmd - #undef cf_format_inplace - #undef cf_style - #undef cf_verbse -} - -Code dump_to_scratch_and_retireve( Code code ) -{ - Builder ecode_file_temp = Builder::open("gen/scratch.hpp"); - ecode_file_temp.print(code); - ecode_file_temp.write(); - format_file("gen/scratch.hpp"); - Code result = scan_file( "gen/scratch.hpp" ); - remove("gen/scratch.hpp"); - return result; -} - -#include "validate.original.cpp" -#include "validate.singleheader.cpp" - -int gen_main() -{ - log_fmt("\ngen_time:"); - - // check_sanity(); - - // check_SOA(); - - // validate_original_files_ast(); - validate_singleheader_ast(); - - return 0; -} -#endif - - -// This only has to be done if symbol conflicts occur. -#ifndef GEN_TIME -int main() -{ - - - return 0; -} -#endif diff --git a/test/upfront.cpp b/test/upfront.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/test/upfront.hpp b/test/upfront.hpp deleted file mode 100644 index 9220752..0000000 --- a/test/upfront.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifdef GEN_TIME -#define GEN_FEATURE_PARSING -#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS -#define GEN_ENFORCE_STRONG_CODE_TYPES -#define GEN_EXPOSE_BACKEND -#define GEN_BENCHMARK -#include "gen.hpp" - -void check_upfront() -{ - using namespace gen; - log_fmt("\nupfront: "); - gen::init(); - - // TODO - - gen::deinit(); - log_fmt("Passed!\n"); -} - -#endif \ No newline at end of file diff --git a/test/validate.bootstrap.cpp b/test/validate.bootstrap.cpp deleted file mode 100644 index 32280b3..0000000 --- a/test/validate.bootstrap.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// Constructs an AST from the bootstrap generated gen files, then serializes it to a set of files. -// Using the new set of serialized files, reconstructs the AST and then serializes it again. -// The two sets of serialized files should be identical. (Verified by comparing the file hashes) diff --git a/test/validate.original.cpp b/test/validate.original.cpp deleted file mode 100644 index 7bc7018..0000000 --- a/test/validate.original.cpp +++ /dev/null @@ -1,186 +0,0 @@ - -#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS -#define GEN_ENFORCE_STRONG_CODE_TYPES -#define GEN_EXPOSE_BACKEND -#define GEN_BENCHMARK -#include "gen.hpp" -#include "gen.builder.hpp" -#include "gen.scanner.hpp" -using namespace gen; - -#define path_root "../" -#define path_project path_root "project/" -#define path_scripts path_root "scripts/" -#define path_components path_project "components/" -#define path_generated path_components "gen/" -#define path_dependencies path_project "dependencies/" -#define path_helpers path_project "helpers/" - -void validate_file_ast( char const* path, char const* path_gen ) -{ - log_fmt( "\nValidating: %s", path ); - - String path_temp = String::make_length( GlobalAllocator, path_gen, str_len( path_gen ) ); - - // Sleep(100); - FileContents file = file_read_contents( GlobalAllocator, true, path ); - - // Duplicate and format - { - // Sleep(100); - FileInfo scratch; - FileError error = file_open_mode( & scratch, EFileMode_WRITE, "gen/scratch.cpp" ); - if ( error != EFileError_NONE ) { - log_failure( "gen::File::open - Could not open file: %s", "gen/scratch.cpp"); - return; - } - // Sleep(100); - b32 result = file_write( & scratch, file.data, file.size ); - if ( result == false ) { - log_failure("gen::File::write - Failed to write to file: %s\n", file_name( & scratch ) ); - file_close( & scratch ); - return; - } - file_close( & scratch ); - // Sleep(100); - format_file( "gen/scratch.cpp" ); - // Sleep(100); - - file = file_read_contents( GlobalAllocator, true, "gen/scratch.cpp" ); - } - - u64 time_start = time_rel_ms(); - CodeBody ast = parse_global_body( { file.size, (char const*)file.data } ); - log_fmt("\n\tAst generated. Time taken: %llu ms", time_rel_ms() - time_start); - - log_fmt("\n\tSerializng ast:\n"); - time_start = time_rel_ms(); - Builder - builder = Builder::open( path_gen ); - builder.print( ast ); - builder.write(); - log_fmt("\tSerialized. Time taken: %llu ms", time_rel_ms() - time_start); - - // Need to execute clang format on the generated file to get it to match the original. - #define clang_format "clang-format " - #define cf_format_inplace "-i " - #define cf_style "-style=file:" "C:/projects/gencpp/scripts/.clang-format " - #define cf_verbose "-verbose " - String command = String::make( GlobalAllocator, clang_format ); - command.append( cf_format_inplace ); - command.append( cf_style ); - command.append( cf_verbose ); - command.append( path_gen ); - log_fmt("\n\tRunning clang-format on generated file:\n"); - system( command ); - log_fmt("\tclang-format finished reformatting."); - #undef cf_cmd - #undef cf_format_inplace - #undef cf_style - #undef cf_verbse - - FileContents file_gen = file_read_contents( GlobalAllocator, true, path_gen ); - log_fmt("\n\tReconstructing from generated file:"); - time_start = time_rel_ms(); - CodeBody ast_gen = parse_global_body( { file_gen.size, (char const*)file_gen.data } ); - log_fmt("\n\tAst generated. Time taken: %llu ms", time_rel_ms() - time_start); - - time_start = time_rel_ms(); - - if ( ast.is_equal( ast_gen ) ) - log_fmt( "\n\tPassed!: AST passed validation! " ); - else - log_fmt( "\nFailed: AST did not pass validation " ); - - log_fmt( "Time taken: %llu ms\n", time_rel_ms() - time_start ); -} - -void validate_original_files_ast() -{ - gen::init(); - log_fmt("\nvalidate_original_files_ast:\n"); - - PreprocessorDefines.append( get_cached_string( txt("GEN_FILE_SEEK_PROC("))); - PreprocessorDefines.append( get_cached_string( txt("GEN_FILE_READ_AT_PROC("))); - PreprocessorDefines.append( get_cached_string( txt("GEN_FILE_WRITE_AT_PROC("))); - PreprocessorDefines.append( get_cached_string( txt("GEN_FILE_CLOSE_PROC("))); - PreprocessorDefines.append( get_cached_string( txt("GEN_FILE_OPEN_PROC("))); - - // Helpers - { - #define validate( path ) validate_file_ast( path_helpers path, "gen/original/helpers/" path ); - validate( "push_ignores.inline.hpp" ); - validate( "pop_ignores.inline.hpp" ); - #undef validate - } - - // Dependencies - { - #define validate( path ) validate_file_ast( path_dependencies path, "gen/original/dependencies/" path ) - validate( "platform.hpp" ); - validate( "macros.hpp" ); - validate( "basic_types.hpp" ); - validate( "debug.hpp" ); - validate( "memory.hpp" ); - validate( "string_ops.hpp" ); - validate( "printing.hpp" ); - validate( "containers.hpp" ); - validate( "hashing.hpp" ); - validate( "strings.hpp" ); - validate( "filesystem.hpp" ); - validate( "timing.hpp" ); - - validate( "src_start.cpp" ); - validate( "debug.cpp" ); - validate( "string_ops.cpp" ); - validate( "printing.cpp" ); - validate( "memory.cpp" ); - validate( "hashing.cpp" ); - validate( "strings.cpp" ); - validate( "filesystem.cpp" ); - validate( "timing.cpp" ); - - validate( "parsing.cpp" ); - validate( "parisng.hpp" ); - #undef validate - } - - // Components - { - #define validate( path ) validate_file_ast( path_components path, "gen/original/components/" path ) - validate( "header_start.hpp" ); - validate( "types.hpp" ); - validate( "gen/ecode.hpp" ); - validate( "gen/eoperator.hpp" ); - validate( "gen/especifier.hpp" ); - validate( "ast.hpp" ); - validate( "code_types.hpp" ); - validate( "ast_types.hpp" ); - validate( "interface.hpp" ); - validate( "inlines.hpp" ); - validate( "gen/ast_inlines.hpp" ); - validate( "header_end.hpp" ); - - validate( "static_data.cpp" ); - validate( "ast_case_macros.cpp" ); - validate( "ast.cpp" ); - validate( "code_serialization.cpp" ); - validate( "interface.cpp" ); - validate( "interface.upfront.cpp" ); - validate( "gen/etoktype.cpp" ); - validate( "lexer.cpp" ); - validate( "parser.cpp" ); - validate( "interface.parsing.cpp" ); - validate( "interface.untyped.cpp" ); - #undef validate - } - - gen::deinit(); -} - -#undef path_root -#undef path_project -#undef path_scripts -#undef path_components -#undef path_generated -#undef path_dependencies diff --git a/test/validate.singleheader.cpp b/test/validate.singleheader.cpp deleted file mode 100644 index 069fffd..0000000 --- a/test/validate.singleheader.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS -#define GEN_ENFORCE_STRONG_CODE_TYPES -#define GEN_EXPOSE_BACKEND -#define GEN_BENCHMARK -#include "gen.hpp" -#include "gen.builder.hpp" -#include "gen.scanner.hpp" -using namespace gen; - -void validate_singleheader_ast() -{ - #define root_dir "../" - gen::init(); - log_fmt("\nvalidate_singleheader_ast:\n"); - - FileContents file = file_read_contents( GlobalAllocator, true, root_dir "singleheader/gen/gen.hpp" ); - - // Duplicate and format - { - // Sleep(100); - FileInfo scratch; - FileError error = file_open_mode( & scratch, EFileMode_WRITE, "gen/scratch.cpp" ); - if ( error != EFileError_NONE ) { - log_failure( "gen::File::open - Could not open file: %s", "gen/scratch.cpp"); - return; - } - // Sleep(100); - b32 result = file_write( & scratch, file.data, file.size ); - if ( result == false ) { - log_failure("gen::File::write - Failed to write to file: %s\n", file_name( & scratch ) ); - file_close( & scratch ); - return; - } - file_close( & scratch ); - // Sleep(100); - format_file( "gen/scratch.cpp" ); - // Sleep(100); - - file = file_read_contents( GlobalAllocator, true, "gen/scratch.cpp" ); - } - - u64 time_start = time_rel_ms(); - CodeBody ast = parse_global_body( { file.size, (char const*)file.data } ); - log_fmt("\nAst generated. Time taken: %llu ms\n", time_rel_ms() - time_start); - - log_fmt("\nSerializng ast:\n"); - time_start = time_rel_ms(); - Builder - builder = Builder::open( "gen/singleheader_copy.gen.hpp" ); - builder.print( ast ); - builder.write(); - log_fmt("Serialized. Time taken: %llu ms\n", time_rel_ms() - time_start); - - // Need to execute clang format on the generated file to get it to match the original. - #define script_path root_dir "scripts/" - #define clang_format "clang-format " - #define cf_format_inplace "-i " - #define cf_style "-style=file:" "C:/projects/gencpp/scripts/.clang-format " - #define cf_verbose "-verbose " - - log_fmt("\nRunning clang-format on generated file:\n"); - system( clang_format cf_format_inplace cf_style cf_verbose "gen/singleheader_copy.gen.hpp" ); - log_fmt("clang-format finished reformatting.\n"); - #undef script_path - #undef cf_cmd - #undef cf_format_inplace - #undef cf_style - #undef cf_verbse - - FileContents file_gen = file_read_contents( GlobalAllocator, true, "gen/singleheader_copy.gen.hpp" ); - log_fmt("\nReconstructing from generated file:\n"); - time_start = time_rel_ms(); - CodeBody ast_gen = parse_global_body( { file_gen.size, (char const*)file_gen.data } ); - log_fmt("\nAst generated. Time taken: %llu ms\n\n", time_rel_ms() - time_start); - - time_start = time_rel_ms(); - - if ( ast.is_equal( ast_gen ) ) - log_fmt( "\nPassed!: AST passed validation!\n" ); - else - log_fmt( "\nFailed: AST did not pass validation\n" ); - - log_fmt( "Time taken: %llu ms\n", time_rel_ms() - time_start ); - - gen::deinit(); -}