mirror of
https://github.com/Ed94/gencpp.git
synced 2025-07-01 11:21:04 -07:00
Compare commits
79 Commits
v0.18-Alph
...
cae1555b11
Author | SHA1 | Date | |
---|---|---|---|
cae1555b11 | |||
f7709bb64e | |||
3a55af9ce4 | |||
6081834687 | |||
a3548a5bd3 | |||
d686831a7c | |||
ba1dd1894a | |||
e00b2f8afb | |||
72d088c566 | |||
c6fba23173 | |||
d45908fb32 | |||
a7c9dad9fd | |||
63ebd0d094 | |||
f28ae57f16 | |||
2fe708e4be | |||
69a9abcd59 | |||
defe42c15c | |||
05e65aa464 | |||
8f47f3b30f | |||
0bad61fda6 | |||
ea18792373 | |||
16b8a3a164 | |||
5b0079fb0c | |||
9321a04ebc | |||
9b68791e38 | |||
2dcc968c39 | |||
c38b077c37 | |||
f9b5029e64 | |||
2b24511f7d | |||
5cd69e1742 | |||
007bfa0cb0 | |||
37c33ffb3e | |||
937235b776 | |||
f9c21ebc04 | |||
fec709cc76 | |||
80cb3f4eca | |||
9e88cb8724 | |||
f61c1c560d | |||
8ef982003a | |||
31691b1466 | |||
ed0c0422ad | |||
e5acac1d18 | |||
c7b072266f | |||
a96d03eaed | |||
0b4ccac8f9 | |||
31a3609b28 | |||
fbdb870986 | |||
6d04165b96 | |||
cc245cc263 | |||
06deb1e836 | |||
5527a27f7b | |||
a67fdef20a | |||
056a5863b8 | |||
79eb5f1f76 | |||
c6cb583518 | |||
34eec66f35 | |||
4137ebfbd8 | |||
5958dd2055 | |||
163ad0a511 | |||
e3c2a577ba | |||
81a0376c99 | |||
1417a68757 | |||
1e4d5ce630 | |||
0f2763a115 | |||
420f452d35 | |||
908c385de5 | |||
c1878265c8 | |||
23742868c4 | |||
2e5e31ed3b | |||
00df336610 | |||
d89c9a6072 | |||
6aa99ac1d5 | |||
3989f5fa83 | |||
f90c0a59b6 | |||
33f992ef56 | |||
0542204b35 | |||
e5616c5879 | |||
40a256f6c3 | |||
b8e1aa6eb7 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -29,3 +29,6 @@ release/**
|
||||
! **/Unreal/validate.unreal.cpp
|
||||
project/auxillary/vis_ast/dependencies/temp
|
||||
test/gen/original
|
||||
singleheader/gen/scratch.hpp
|
||||
test/gen/scratch.cpp
|
||||
gen_c_library/gen
|
||||
|
9
.vscode/launch.json
vendored
9
.vscode/launch.json
vendored
@ -41,6 +41,15 @@
|
||||
"cwd": "${workspaceFolder}/singleheader/",
|
||||
"visualizerFile": "${workspaceFolder}/scripts/gencpp.natvis"
|
||||
},
|
||||
{
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"name": "Debug unreal vsdbg",
|
||||
"program": "${workspaceFolder}/unreal_engine/build/unreal.exe",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}/unreal_engine/",
|
||||
"visualizerFile": "${workspaceFolder}/scripts/gencpp.natvis"
|
||||
},
|
||||
{
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
|
21
.vscode/settings.json
vendored
21
.vscode/settings.json
vendored
@ -37,7 +37,26 @@
|
||||
"propidl.h": "c",
|
||||
"android_native_app_glue.h": "c",
|
||||
"raylib.h": "c",
|
||||
"*.m": "cpp"
|
||||
"*.m": "cpp",
|
||||
"atomic": "cpp",
|
||||
"gen.h": "c",
|
||||
"string_ops.hpp": "c",
|
||||
"assert.h": "c",
|
||||
"intrin.h": "c",
|
||||
"bit": "cpp",
|
||||
"cmath": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"new": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"xstddef": "cpp"
|
||||
},
|
||||
"C_Cpp.intelliSenseEngineFallback": "disabled",
|
||||
"mesonbuild.configureOnOpen": true,
|
||||
|
14
Readme.md
14
Readme.md
@ -67,7 +67,7 @@ Example using each construction interface:
|
||||
Validation and construction through a functional interface.
|
||||
|
||||
```cpp
|
||||
Code t_uw = def_type( name(uw) );
|
||||
Code t_uw = def_type( name(usize) );
|
||||
Code t_allocator = def_type( name(allocator) );
|
||||
Code t_string_const = def_type( name(char), def_specifiers( args( ESpecifier::Const, ESpecifier::Ptr ) ));
|
||||
|
||||
@ -90,8 +90,8 @@ Validation through ast construction.
|
||||
Code header = parse_struct( code(
|
||||
struct ArrayHeader
|
||||
{
|
||||
uw Num;
|
||||
uw Capacity;
|
||||
usize Num;
|
||||
usize Capacity;
|
||||
allocator Allocator;
|
||||
};
|
||||
));
|
||||
@ -106,8 +106,8 @@ No validation, just glorified text injection.
|
||||
Code header = code_str(
|
||||
struct ArrayHeader
|
||||
{
|
||||
uw Num;
|
||||
uw Capacity;
|
||||
usize Num;
|
||||
usize Capacity;
|
||||
allocator Allocator;
|
||||
};
|
||||
);
|
||||
@ -123,8 +123,8 @@ All three constrcuton interfaces will generate the following C code:
|
||||
```cpp
|
||||
struct ArrayHeader
|
||||
{
|
||||
uw Num;
|
||||
uw Capacity;
|
||||
usize Num;
|
||||
usize Capacity;
|
||||
allocator Allocator;
|
||||
};
|
||||
```
|
||||
|
@ -552,7 +552,7 @@ Serialization:
|
||||
Fields:
|
||||
|
||||
```cpp
|
||||
SpecifierT ArrSpecs[ AST::ArrSpecs_Cap ];
|
||||
SpecifierT ArrSpecs[ AST_ArrSpecs_Cap ];
|
||||
CodeSpecifiers NextSpecs;
|
||||
Code Prev;
|
||||
Code Next;
|
||||
|
@ -25,6 +25,8 @@ This library was written in a subset of C++ where the following are not used at
|
||||
* Exceptions
|
||||
|
||||
Polymorphic & Member-functions are used as an ergonomic choice, along with a conserative use of operator overloads.
|
||||
The base library itself does not use anything but C-like features to allow for generating a derviative compatiable with C (WIP).
|
||||
|
||||
There are only 4 template definitions in the entire library. (`Array<Type>`, `Hashtable<Type>`, `swap<Type>`, and `AST/Code::cast<Type>`)
|
||||
|
||||
Two generic templated containers are used throughout the library:
|
||||
@ -99,7 +101,7 @@ union {
|
||||
};
|
||||
StringCached Content; // Attributes, Comment, Execution, Include
|
||||
struct {
|
||||
SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers
|
||||
SpecifierT ArrSpecs[AST_ArrSpecs_Cap]; // Specifiers
|
||||
AST* NextSpecs; // Specifiers
|
||||
};
|
||||
};
|
||||
@ -136,7 +138,7 @@ The width dictates how much the static array can hold before it must give way to
|
||||
|
||||
```cpp
|
||||
constexpr static
|
||||
uw ArrSpecs_Cap =
|
||||
usize ArrSpecs_Cap =
|
||||
(
|
||||
AST_POD_Size
|
||||
- sizeof(AST*) * 3
|
||||
@ -158,7 +160,7 @@ Data Notes:
|
||||
* Most of the work is just defining the allocation procedure:
|
||||
|
||||
```cpp
|
||||
void* ( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags );
|
||||
void* ( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
|
||||
```
|
||||
|
||||
* ASTs are wrapped for the user in a Code struct which is a wrapper for a AST* type.
|
||||
|
446
gen_c_library/c_library.cpp
Normal file
446
gen_c_library/c_library.cpp
Normal file
@ -0,0 +1,446 @@
|
||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
||||
#define GEN_EXPOSE_BACKEND
|
||||
#define GEN_SUPPORT_CPP_MEMBER_FEATURES 1
|
||||
#define GEN_SUPPORT_CPP_REFERENCES 1
|
||||
#include "../project/gen.cpp"
|
||||
|
||||
#include "helpers/push_ignores.inline.hpp"
|
||||
#include "helpers/helper.hpp"
|
||||
|
||||
GEN_NS_BEGIN
|
||||
#include "dependencies/parsing.cpp"
|
||||
GEN_NS_END
|
||||
|
||||
#include "auxillary/builder.hpp"
|
||||
#include "auxillary/builder.cpp"
|
||||
#include "auxillary/scanner.hpp"
|
||||
|
||||
#include <cstdlib> // for system()
|
||||
|
||||
#include "components/memory.fixed_arena.hpp"
|
||||
#include "components/misc.hpp"
|
||||
#include "components/containers.array.hpp"
|
||||
#include "components/containers.hashtable.hpp"
|
||||
|
||||
using namespace gen;
|
||||
|
||||
constexpr char const* generation_notice =
|
||||
"// This file was generated automatially by gencpp's c_library.cpp"
|
||||
"(See: https://github.com/Ed94/gencpp)\n\n";
|
||||
|
||||
constexpr StrC roll_own_dependencies_guard_start = txt(R"(
|
||||
//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file.
|
||||
// Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
|
||||
#ifndef GEN_ROLL_OWN_DEPENDENCIES
|
||||
)");
|
||||
|
||||
constexpr StrC roll_own_dependencies_guard_end = txt(R"(
|
||||
// GEN_ROLL_OWN_DEPENDENCIES
|
||||
#endif
|
||||
)");
|
||||
|
||||
constexpr StrC implementation_guard_start = txt(R"(
|
||||
#pragma region GENCPP IMPLEMENTATION GUARD
|
||||
#if defined(GEN_IMPLEMENTATION) && ! defined(GEN_IMPLEMENTED)
|
||||
# define GEN_IMPLEMENTED
|
||||
)");
|
||||
|
||||
constexpr StrC implementation_guard_end = txt(R"(
|
||||
#endif
|
||||
#pragma endregion GENCPP IMPLEMENTATION GUARD
|
||||
)");
|
||||
|
||||
void format_file( char const* path )
|
||||
{
|
||||
String resolved_path = String::make(GlobalAllocator, to_strc_from_c_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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int gen_main()
|
||||
{
|
||||
#define project_dir "../project/"
|
||||
gen::init();
|
||||
|
||||
PreprocessorDefines.append(txt("GEN_API_C_BEGIN"));
|
||||
PreprocessorDefines.append(txt("GEN_API_C_END"));
|
||||
|
||||
Code push_ignores = scan_file( project_dir "helpers/push_ignores.inline.hpp" );
|
||||
Code pop_ignores = scan_file( project_dir "helpers/pop_ignores.inline.hpp" );
|
||||
Code c_library_header_start = scan_file( "components/header_start.hpp" );
|
||||
|
||||
Builder
|
||||
header = Builder::open( "gen/gen.h" );
|
||||
header.print_fmt( generation_notice );
|
||||
header.print_fmt("#pragma once\n\n");
|
||||
header.print( push_ignores );
|
||||
|
||||
// Headers
|
||||
{
|
||||
header.print( c_library_header_start );
|
||||
|
||||
Code platform = scan_file( project_dir "dependencies/platform.hpp" );
|
||||
Code macros = scan_file( project_dir "dependencies/macros.hpp" );
|
||||
Code basic_types = scan_file( project_dir "dependencies/basic_types.hpp" );
|
||||
Code debug = scan_file( project_dir "dependencies/debug.hpp" );
|
||||
|
||||
header.print_fmt( roll_own_dependencies_guard_start );
|
||||
header.print( platform );
|
||||
header.print_fmt( "\nGEN_NS_BEGIN\n" );
|
||||
|
||||
header.print( macros );
|
||||
header.print( basic_types );
|
||||
header.print( debug );
|
||||
|
||||
// Array(StrC) to_rename = array_init_reserve(StrC, GlobalAllocator, 128);
|
||||
// to_rename.append(txt("align_forward"));
|
||||
// to_rename.append(txt("pointer_add"));
|
||||
// to_rename.append(txt("allocator_info"));
|
||||
// to_rename.append(txt("size_remaining"));
|
||||
// to_rename.append(txt("free"));
|
||||
// to_rename.append(txt("clear"));
|
||||
// to_rename.append(txt("init_sub"));
|
||||
// to_rename.append(txt("check"));
|
||||
|
||||
// NeedsSelectors needs_selectors;
|
||||
// needs_selectors.table = hashtable_init_reserve(Array(CodeFn), GlobalAllocator, 1024);
|
||||
// for ( StrC id : to_rename ) {
|
||||
// needs_selectors.set(id, array_init_reserve(CodeFn, GlobalAllocator, 128));
|
||||
// }
|
||||
|
||||
CodeBody parsed_memory = parse_file( project_dir "dependencies/memory.hpp" );
|
||||
CodeBody memory = def_body(CT_Global_Body);
|
||||
|
||||
for ( Code entry = parsed_memory.begin(); entry != parsed_memory.end(); ++ entry )
|
||||
{
|
||||
switch (entry->Type)
|
||||
{
|
||||
case CT_Using:
|
||||
{
|
||||
log_fmt("REPLACE THIS MANUALLY: %SC\n", entry->Name);
|
||||
CodeUsing using_ver = cast(CodeUsing, entry);
|
||||
CodeTypedef typedef_ver = def_typedef(using_ver->Name, using_ver->UnderlyingType);
|
||||
|
||||
memory.append(typedef_ver);
|
||||
}
|
||||
break;
|
||||
case CT_Function_Fwd:
|
||||
{
|
||||
CodeFn fn = cast(CodeFn, entry);
|
||||
// for ( StrC id : to_rename ) if (fn->Name.is_equal(id)) {
|
||||
// rename_function_to_unique_symbol(fn);
|
||||
// }
|
||||
memory.append(fn);
|
||||
}
|
||||
break;
|
||||
case CT_Function:
|
||||
{
|
||||
CodeFn fn = cast(CodeFn, entry);
|
||||
s32 constexpr_found = fn->Specs.remove( Spec_Constexpr );
|
||||
if (constexpr_found > -1) {
|
||||
log_fmt("Found constexpr: %S\n", entry.to_string());
|
||||
fn->Specs.append(Spec_Inline);
|
||||
}
|
||||
// for ( StrC id : to_rename ) if (fn->Name.is_equal(id)) {
|
||||
// Array(CodeFn) list = * needs_selectors.get(id);
|
||||
// list.append(rename_function_to_unique_symbol(fn));
|
||||
// }
|
||||
memory.append(fn);
|
||||
}
|
||||
break;
|
||||
case CT_Template:
|
||||
{
|
||||
CodeTemplate tmpl = cast(CodeTemplate, entry);
|
||||
if ( tmpl->Declaration->Name.contains(txt("swap")))
|
||||
{
|
||||
CodeBody macro_swap = parse_global_body( txt(R"(
|
||||
#define swap( a, b ) \
|
||||
do \
|
||||
{ \
|
||||
typeof( a ) temp = ( a ); \
|
||||
( a ) = ( b ); \
|
||||
( b ) = temp; \
|
||||
} while ( 0 )
|
||||
)"
|
||||
));
|
||||
memory.append(macro_swap);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CT_Class:
|
||||
case CT_Struct:
|
||||
{
|
||||
CodeBody body = cast(CodeBody, entry->Body);
|
||||
CodeBody new_body = def_body( entry->Body->Type );
|
||||
for ( Code body_entry = body.begin(); body_entry != body.end(); ++ body_entry ) switch
|
||||
(body_entry->Type) {
|
||||
case CT_Preprocess_If:
|
||||
{
|
||||
ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_MEMBER_FEATURES"), body_entry, body );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
new_body.append(body_entry);
|
||||
break;
|
||||
}
|
||||
|
||||
entry->Body = new_body;
|
||||
memory.append(entry);
|
||||
}
|
||||
break;
|
||||
case CT_Preprocess_If:
|
||||
{
|
||||
b32 found = ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_MEMBER_FEATURES"), entry, parsed_memory );
|
||||
if (found) break;
|
||||
|
||||
found = ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_REFERENCES"), entry, parsed_memory );
|
||||
if (found) break;
|
||||
|
||||
memory.append(entry);
|
||||
}
|
||||
break;
|
||||
case CT_Preprocess_IfDef:
|
||||
{
|
||||
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_memory );
|
||||
if (found) break;
|
||||
|
||||
memory.append(entry);
|
||||
}
|
||||
break;
|
||||
case CT_Preprocess_Pragma:
|
||||
{
|
||||
CodePragma pragma = cast(CodePragma, entry);
|
||||
// if (pragma->Content.starts_with(txt("region Memory"))) {
|
||||
// memory.append(generic_test);
|
||||
// break;
|
||||
// }
|
||||
|
||||
b32 found = swap_pragma_region_implementation( txt("FixedArena"), gen_fixed_arenas, entry, memory);
|
||||
if (found) break;
|
||||
|
||||
memory.append(entry);
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
memory.append(entry);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// CodeBody selectors = generate_generic_selectors(needs_selectors);
|
||||
// memory.append_at(selectors, 0)
|
||||
// memory.append(fmt_newline);
|
||||
|
||||
header.print( dump_to_scratch_and_retireve(memory) );
|
||||
|
||||
Code string_ops = scan_file( project_dir "dependencies/string_ops.hpp" );
|
||||
// header.print( string_ops );
|
||||
|
||||
CodeBody printing_parsed = parse_file( project_dir "dependencies/printing.hpp" );
|
||||
CodeBody printing = def_body(CT_Global_Body);
|
||||
for ( Code entry = printing_parsed.begin(); entry != printing_parsed.end(); ++ entry )
|
||||
{
|
||||
switch (entry->Type)
|
||||
{
|
||||
case CT_Preprocess_IfDef:
|
||||
{
|
||||
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, printing_parsed );
|
||||
if (found) break;
|
||||
|
||||
printing.append(entry);
|
||||
}
|
||||
break;
|
||||
case CT_Variable:
|
||||
{
|
||||
if ( strc_contains(entry->Name, txt("Msg_Invalid_Value")))
|
||||
{
|
||||
CodeDefine define = def_define(entry->Name, entry->Value->Content);
|
||||
printing.append(define);
|
||||
continue;
|
||||
}
|
||||
printing.append(entry);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printing.append(entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// header.print(dump_to_scratch_and_retireve(printing));
|
||||
|
||||
CodeBody containers = def_body(CT_Global_Body);
|
||||
{
|
||||
containers.append( def_pragma(code(region Containers)));
|
||||
|
||||
containers.append( gen_array_base() );
|
||||
containers.append( gen_hashtable_base() );
|
||||
|
||||
containers.append( def_pragma(code(endregion Containers)));
|
||||
}
|
||||
header.print(fmt_newline);
|
||||
// header.print(dump_to_scratch_and_retireve(containers));
|
||||
|
||||
Code hashing = scan_file( project_dir "dependencies/hashing.hpp" );
|
||||
// header.print( hashing );
|
||||
|
||||
CodeBody parsed_strings = parse_file( project_dir "dependencies/strings.hpp" );
|
||||
CodeBody strings = def_body(CT_Global_Body);
|
||||
for ( Code entry = parsed_strings.begin(); entry != parsed_strings.end(); ++ entry )
|
||||
{
|
||||
switch (entry->Type)
|
||||
{
|
||||
case CT_Preprocess_If:
|
||||
{
|
||||
CodePreprocessCond cond = cast(CodePreprocessCond, entry);
|
||||
if (cond->Content.starts_with(txt("GEN_COMPILER_C || ! GEN_SUPPORT_CPP_MEMBER_FEATURES")))
|
||||
{
|
||||
++ entry;
|
||||
strings.append(entry); // typedef
|
||||
strings.append(fmt_newline);
|
||||
|
||||
for (; entry != end(parsed_strings) && entry->Type != CT_Preprocess_EndIf; ++ entry) {}
|
||||
++ entry;
|
||||
break;
|
||||
}
|
||||
|
||||
bool found = ignore_preprocess_cond_block(txt("! GEN_COMPILER_C"), entry, parsed_strings);
|
||||
if (found) break;
|
||||
|
||||
found = ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_REFERENCES"), entry, parsed_strings);
|
||||
}
|
||||
break;
|
||||
|
||||
case CT_Preprocess_IfDef:
|
||||
{
|
||||
ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_strings );
|
||||
}
|
||||
break;
|
||||
|
||||
case CT_Struct_Fwd:
|
||||
{
|
||||
if ( entry->Name.is_equal(txt("String")) )
|
||||
{
|
||||
CodeTypedef c_def = parse_typedef(code( typedef char* String; ));
|
||||
strings.append(c_def);
|
||||
strings.append(fmt_newline);
|
||||
++ entry;
|
||||
continue;
|
||||
}
|
||||
strings.append(entry);
|
||||
}
|
||||
break;
|
||||
|
||||
case CT_Struct:
|
||||
{
|
||||
CodeBody body = cast(CodeBody, entry->Body);
|
||||
CodeBody new_body = def_body( entry->Body->Type );
|
||||
for ( Code body_entry = body.begin(); body_entry != body.end(); ++ body_entry ) switch
|
||||
(body_entry->Type) {
|
||||
case CT_Preprocess_If:
|
||||
{
|
||||
b32 found = ignore_preprocess_cond_block(txt("! GEN_COMPILER_C"), body_entry, body );
|
||||
if (found) break;
|
||||
|
||||
new_body.append(body_entry);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
new_body.append(body_entry);
|
||||
break;
|
||||
}
|
||||
entry->Body = new_body;
|
||||
strings.append(entry);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
strings.append(entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// header.print(dump_to_scratch_and_retireve(strings));
|
||||
|
||||
Code filesystem = scan_file( project_dir "dependencies/filesystem.hpp" );
|
||||
Code timing = scan_file( project_dir "dependencies/timing.hpp" );
|
||||
// header.print( filesystem );
|
||||
// header.print( timing );
|
||||
|
||||
header.print_fmt( "\nGEN_NS_END\n" );
|
||||
header.print_fmt( roll_own_dependencies_guard_end );
|
||||
|
||||
Code types = scan_file( project_dir "components/types.hpp" );
|
||||
Code ast = scan_file( project_dir "components/ast.hpp" );
|
||||
Code ast_types = scan_file( project_dir "components/ast_types.hpp" );
|
||||
Code code_types = scan_file( project_dir "components/code_types.hpp" );
|
||||
Code interface = scan_file( project_dir "components/interface.hpp" );
|
||||
Code inlines = scan_file( project_dir "components/inlines.hpp" );
|
||||
Code header_end = scan_file( project_dir "components/header_end.hpp" );
|
||||
|
||||
CodeBody ecode = gen_ecode ( project_dir "enums/ECode.csv" );
|
||||
CodeBody eoperator = gen_eoperator ( project_dir "enums/EOperator.csv" );
|
||||
CodeBody especifier = gen_especifier( project_dir "enums/ESpecifier.csv" );
|
||||
CodeBody ast_inlines = gen_ast_inlines();
|
||||
|
||||
#if 0
|
||||
header.print_fmt("#pragma region Types\n");
|
||||
header.print( types );
|
||||
header.print( fmt_newline );
|
||||
header.print( dump_to_scratch_and_retireve( ecode ));
|
||||
header.print( fmt_newline );
|
||||
header.print( dump_to_scratch_and_retireve( eoperator ));
|
||||
header.print( fmt_newline );
|
||||
header.print( dump_to_scratch_and_retireve( especifier ));
|
||||
header.print( fmt_newline );
|
||||
header.print_fmt("#pragma endregion Types\n\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
header.print( pop_ignores );
|
||||
header.write();
|
||||
|
||||
// format_file( "gen/gen.h" );
|
||||
|
||||
gen::deinit();
|
||||
return 0;
|
||||
#undef project_dir
|
||||
}
|
295
gen_c_library/components/containers.array.hpp
Normal file
295
gen_c_library/components/containers.array.hpp
Normal file
@ -0,0 +1,295 @@
|
||||
#pragma once
|
||||
|
||||
#include "../project/gen.hpp"
|
||||
|
||||
using namespace gen;
|
||||
|
||||
CodeBody gen_array_base()
|
||||
{
|
||||
CodeTypedef td_header = parse_typedef( code( typedef struct ArrayHeader ArrayHeader; ));
|
||||
CodeStruct header = parse_struct( code(
|
||||
struct ArrayHeader
|
||||
{
|
||||
AllocatorInfo Allocator;
|
||||
usize Capacity;
|
||||
usize Num;
|
||||
};
|
||||
));
|
||||
|
||||
// Code grow_formula = untyped_str( txt( "#define gen_array_grow_formula( value ) ( 2 * value + 8 )\n" ));
|
||||
Code get_header = untyped_str( txt( "#define array_get_header( Type, self ) ( (ArrayHeader*)( self ) - 1)\n" ));
|
||||
|
||||
return def_global_body( args( fmt_newline, td_header, header, get_header, fmt_newline ) );
|
||||
};
|
||||
|
||||
CodeBody gen_array( StrC type, StrC array_name )
|
||||
{
|
||||
String array_type = String::fmt_buf( GlobalAllocator, "%.*s", array_name.Len, array_name.Ptr );
|
||||
String fn = String::fmt_buf( GlobalAllocator, "%.*s", array_name.Len, array_name.Ptr );
|
||||
str_to_lower(fn.Data);
|
||||
|
||||
#pragma push_macro( "GEN_ASSERT" )
|
||||
#undef GEN_ASSERT
|
||||
CodeBody result = parse_global_body( token_fmt( "array_type", (StrC)array_type, "fn", (StrC)fn, "type", (StrC)type
|
||||
, stringize(
|
||||
typedef <type>* <array_type>;
|
||||
|
||||
<array_type> <fn>_init ( AllocatorInfo allocator );
|
||||
<array_type> <fn>_init_reserve ( AllocatorInfo allocator, usize capacity );
|
||||
bool <fn>_append ( <array_type>* self, <type> value );
|
||||
bool <fn>_append_items ( <array_type>* self, <type>* items, usize item_num );
|
||||
bool <fn>_append_at ( <array_type>* self, <type> item, usize idx );
|
||||
bool <fn>_append_items_at( <array_type>* self, <type>* items, usize item_num, usize idx );
|
||||
<type>* <fn>_back ( <array_type> self );
|
||||
void <fn>_clear ( <array_type> self );
|
||||
bool <fn>_fill ( <array_type> self, usize begin, usize end, <type> value );
|
||||
void <fn>_free ( <array_type> self );
|
||||
bool <fn>_grow ( <array_type>* self, usize min_capacity );
|
||||
usize <fn>_num ( <array_type> self );
|
||||
<type> <fn>_pop ( <array_type> self );
|
||||
bool <fn>_reserve ( <array_type>* self, usize new_capacity );
|
||||
bool <fn>_resize ( <array_type>* self, usize num );
|
||||
bool <fn>_set_capacity ( <array_type>* self, usize new_capacity );
|
||||
|
||||
<array_type> <fn>_init( AllocatorInfo allocator )
|
||||
{
|
||||
return <fn>_init_reserve( allocator, array_grow_formula( 0 ) );
|
||||
}
|
||||
|
||||
<array_type> <fn>_init_reserve( AllocatorInfo allocator, usize capacity )
|
||||
{
|
||||
ArrayHeader* header = cast(ArrayHeader*, alloc( allocator, sizeof(ArrayHeader) + sizeof(<type>) * capacity ) );
|
||||
|
||||
if ( header == NULL )
|
||||
return NULL;
|
||||
|
||||
header->Allocator = allocator;
|
||||
header->Capacity = capacity;
|
||||
header->Num = 0;
|
||||
|
||||
return cast( <type>*, header + 1 );
|
||||
}
|
||||
|
||||
bool <fn>_append( <array_type>* self, <type> value )
|
||||
{
|
||||
ArrayHeader* header = get_header( * self );
|
||||
|
||||
if ( header->Num == header->Capacity )
|
||||
{
|
||||
if ( ! <fn>_grow( self, header->Capacity))
|
||||
return false;
|
||||
|
||||
header = get_header( * self );
|
||||
}
|
||||
|
||||
(* self)[ header->Num ] = value;
|
||||
header->Num++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool <fn>_append_items( <array_type>* self, <type>* items, usize item_num )
|
||||
{
|
||||
ArrayHeader* header = get_header( * self );
|
||||
|
||||
if ( header->Num + item_num > header->Capacity )
|
||||
{
|
||||
if ( ! <fn>_grow( self, header->Capacity + item_num ))
|
||||
return false;
|
||||
|
||||
header = get_header( * self );
|
||||
}
|
||||
|
||||
mem_copy( (* self) + header->Num, items, sizeof(<type>) * item_num );
|
||||
header->Num += item_num;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool <fn>_append_at( <array_type>* self, <type> item, usize idx )
|
||||
{
|
||||
ArrayHeader* header = get_header( * self );
|
||||
|
||||
if ( idx >= header->Num )
|
||||
idx = header->Num - 1;
|
||||
|
||||
if ( idx < 0 )
|
||||
idx = 0;
|
||||
|
||||
if ( header->Capacity < header->Num + 1 )
|
||||
{
|
||||
if ( ! <fn>_grow( self, header->Capacity + 1 ) )
|
||||
return false;
|
||||
|
||||
header = get_header( * self );
|
||||
}
|
||||
|
||||
<array_type> target = (* self) + idx;
|
||||
|
||||
mem_move( target + 1, target, (header->Num - idx) * sizeof(<type>) );
|
||||
header->Num++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool <fn>_append_items_at( <array_type>* self, <type>* items, usize item_num, usize idx )
|
||||
{
|
||||
ArrayHeader* header = get_header( * self );
|
||||
|
||||
if ( idx >= header->Num )
|
||||
{
|
||||
return <fn>_append_items( self, items, item_num );
|
||||
}
|
||||
|
||||
if ( item_num > header->Capacity )
|
||||
{
|
||||
if ( ! <fn>_grow( self, item_num + header->Capacity ) )
|
||||
return false;
|
||||
|
||||
header = get_header( * self );
|
||||
}
|
||||
|
||||
<type>* target = (* self) + idx + item_num;
|
||||
<type>* src = (* self) + idx;
|
||||
|
||||
mem_move( target, src, (header->Num - idx) * sizeof(<type>) );
|
||||
mem_copy( src, items, item_num * sizeof(<type>) );
|
||||
header->Num += item_num;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
<type>* <fn>_back( <array_type> self )
|
||||
{
|
||||
ArrayHeader* header = get_header( self );
|
||||
|
||||
if ( header->Num == 0 )
|
||||
return NULL;
|
||||
|
||||
return self + header->Num - 1;
|
||||
}
|
||||
|
||||
void <fn>_clear( <array_type> self )
|
||||
{
|
||||
ArrayHeader* header = get_header( self );
|
||||
header->Num = 0;
|
||||
}
|
||||
|
||||
bool <fn>_fill( <array_type> self, usize begin, usize end, <type> value )
|
||||
{
|
||||
ArrayHeader* header = get_header( self );
|
||||
|
||||
if ( begin < 0 || end >= header->Num )
|
||||
return false;
|
||||
|
||||
for ( ssize idx = begin; idx < end; idx ++ )
|
||||
self[ idx ] = value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void <fn>_free( <array_type> self )
|
||||
{
|
||||
ArrayHeader* header = get_header( self );
|
||||
free( header->Allocator, header );
|
||||
self = NULL;
|
||||
}
|
||||
|
||||
bool <fn>_grow( <array_type>* self, usize min_capacity )
|
||||
{
|
||||
ArrayHeader* header = get_header( *self );
|
||||
usize new_capacity = array_grow_formula( header->Capacity );
|
||||
|
||||
if ( new_capacity < min_capacity )
|
||||
new_capacity = min_capacity;
|
||||
|
||||
return <fn>_set_capacity( self, new_capacity );
|
||||
}
|
||||
|
||||
usize <fn>_num( <array_type> self )
|
||||
{
|
||||
return get_header(self)->Num;
|
||||
}
|
||||
|
||||
<type> <fn>_pop( <array_type> self )
|
||||
{
|
||||
ArrayHeader* header = get_header( self );
|
||||
GEN_ASSERT( header->Num > 0 );
|
||||
|
||||
<type> result = self[ header->Num - 1 ];
|
||||
header->Num--;
|
||||
return result;
|
||||
}
|
||||
|
||||
void <fn>_remove_at( <array_type> self, usize idx )
|
||||
{
|
||||
ArrayHeader* header = get_header( self );
|
||||
GEN_ASSERT( idx < header->Num );
|
||||
|
||||
mem_move( self + idx, self + idx + 1, sizeof( <type> ) * ( header->Num - idx - 1 ) );
|
||||
header->Num--;
|
||||
}
|
||||
|
||||
bool <fn>_reserve( <array_type>* self, usize new_capacity )
|
||||
{
|
||||
ArrayHeader* header = get_header( * self );
|
||||
|
||||
if ( header->Capacity < new_capacity )
|
||||
return <fn>_set_capacity( self, new_capacity );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool <fn>_resize( <array_type>* self, usize num )
|
||||
{
|
||||
ArrayHeader* header = get_header( * self );
|
||||
|
||||
if ( header->Capacity < num )
|
||||
{
|
||||
if ( ! <fn>_grow( self, num ) )
|
||||
return false;
|
||||
|
||||
header = get_header( * self );
|
||||
}
|
||||
|
||||
header->Num = num;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool <fn>_set_capacity( <array_type>* self, usize new_capacity )
|
||||
{
|
||||
ArrayHeader* header = get_header( * self );
|
||||
|
||||
if ( new_capacity == header->Capacity )
|
||||
return true;
|
||||
|
||||
if ( new_capacity < header->Num )
|
||||
header->Num = new_capacity;
|
||||
|
||||
usize size = sizeof( ArrayHeader ) + sizeof( <type> ) * new_capacity;
|
||||
ArrayHeader* new_header = cast( ArrayHeader*, alloc( header->Allocator, size ));
|
||||
|
||||
if ( new_header == NULL )
|
||||
return false;
|
||||
|
||||
mem_move( new_header, header, sizeof( ArrayHeader ) + sizeof( <type> ) * header->Num );
|
||||
free( header->Allocator, & header );
|
||||
|
||||
new_header->Capacity = new_capacity;
|
||||
* self = cast( <type>*, new_header + 1 );
|
||||
return true;
|
||||
}
|
||||
)));
|
||||
#pragma pop_macro( "GEN_ASSERT" )
|
||||
|
||||
return def_global_body( args(
|
||||
def_pragma( string_to_strc( string_fmt_buf( GlobalAllocator, "region %S", array_type ))),
|
||||
fmt_newline,
|
||||
result,
|
||||
fmt_newline,
|
||||
def_pragma( string_to_strc(string_fmt_buf( GlobalAllocator, "endregion %S", array_type ))),
|
||||
fmt_newline
|
||||
));
|
||||
};
|
||||
|
||||
// CodeBody gen_
|
354
gen_c_library/components/containers.hashtable.hpp
Normal file
354
gen_c_library/components/containers.hashtable.hpp
Normal file
@ -0,0 +1,354 @@
|
||||
#pragma once
|
||||
|
||||
#include "../project/gen.hpp"
|
||||
#include "containers.array.hpp"
|
||||
|
||||
using namespace gen;
|
||||
|
||||
CodeBody gen_hashtable_base()
|
||||
{
|
||||
return parse_global_body( code(
|
||||
typedef struct HT_FindResult HT_FindResult;
|
||||
struct HT_FindResult
|
||||
{
|
||||
ssize HashIndex;
|
||||
ssize PrevIndex;
|
||||
ssize EntryIndex;
|
||||
};
|
||||
));
|
||||
}
|
||||
|
||||
CodeBody gen_hashtable( StrC type, StrC hashtable_name )
|
||||
{
|
||||
String
|
||||
fn = String::make_reserve( GlobalAllocator, hashtable_name.Len + sizeof("gen") );
|
||||
fn.append_fmt( "%.*s", hashtable_name.Len, hashtable_name.Ptr );
|
||||
str_to_lower(fn.Data);
|
||||
|
||||
String
|
||||
tbl_type = String::make_reserve( GlobalAllocator, hashtable_name.Len + sizeof("gen") );
|
||||
tbl_type.append_fmt( "%.*s", hashtable_name.Len, hashtable_name.Ptr );
|
||||
|
||||
String name_lower = String::make( GlobalAllocator, hashtable_name );
|
||||
str_to_lower( name_lower.Data );
|
||||
|
||||
String hashtable_entry = String::fmt_buf( GlobalAllocator, "HTE_%.*s", hashtable_name.Len, hashtable_name.Ptr );
|
||||
String entry_array_name = String::fmt_buf( GlobalAllocator, "Arr_HTE_%.*s", hashtable_name.Len, hashtable_name.Ptr );
|
||||
String entry_array_fn_ns = String::fmt_buf( GlobalAllocator, "arr_hte_%.*s", name_lower.length(), name_lower.Data );
|
||||
|
||||
CodeBody hashtable_types = parse_global_body( token_fmt(
|
||||
"type", (StrC) type,
|
||||
"tbl_name", (StrC) hashtable_name,
|
||||
"tbl_type", (StrC) tbl_type,
|
||||
stringize(
|
||||
typedef struct HTE_<tbl_name> HTE_<tbl_name>;
|
||||
struct HTE_<tbl_name>
|
||||
{
|
||||
u64 Key;
|
||||
ssize Next;
|
||||
<type> Value;
|
||||
};
|
||||
|
||||
typedef void (* <tbl_type>_MapProc) ( <tbl_type> self, u64 key, <type> value );
|
||||
typedef void (* <tbl_type>_MapMutProc) ( <tbl_type> self, u64 key, <type>* value );
|
||||
)));
|
||||
|
||||
CodeBody entry_array = gen_array( hashtable_entry, entry_array_name );
|
||||
|
||||
#pragma push_macro( "GEN_ASSERT" )
|
||||
#pragma push_macro( "GEN_ASSERT_NOT_NULL" )
|
||||
#undef GEN_ASSERT
|
||||
#undef GEN_ASSERT_NOT_NULL
|
||||
CodeBody hashtable_def = parse_global_body( token_fmt(
|
||||
"type", (StrC) type,
|
||||
"tbl_name", (StrC) hashtable_name,
|
||||
"tbl_type", (StrC) tbl_type,
|
||||
"fn", (StrC) fn,
|
||||
"entry_type", (StrC) hashtable_entry,
|
||||
"array_entry", (StrC) entry_array_name,
|
||||
"fn_array", (StrC) entry_array_fn_ns,
|
||||
stringize(
|
||||
typedef struct <tbl_type> <tbl_type>;
|
||||
struct <tbl_type>
|
||||
{
|
||||
Array_ssize Hashes;
|
||||
<array_entry> Entries;
|
||||
};
|
||||
|
||||
<tbl_type> <fn>_make ( AllocatorInfo allocator );
|
||||
<tbl_type> <fn>_make_reserve( AllocatorInfo allocator, ssize num );
|
||||
void <fn>_clear ( <tbl_type> self );
|
||||
void <fn>_destroy ( <tbl_type> self );
|
||||
<type>* <fn>_get ( <tbl_type> self, u64 key );
|
||||
void <fn>_map ( <tbl_type> self, <tbl_type>_MapProc map_proc );
|
||||
void <fn>_map_mut ( <tbl_type> self, <tbl_type>_MapMutProc map_proc );
|
||||
void <fn>_grow ( <tbl_type>* self );
|
||||
void <fn>_rehash ( <tbl_type>* self, ssize new_num );
|
||||
void <fn>_rehash_fast ( <tbl_type> self );
|
||||
void <fn>_remove ( <tbl_type> self, u64 key );
|
||||
void <fn>_remove_entry( <tbl_type> self, ssize idx );
|
||||
void <fn>_set ( <tbl_type>* self, u64 key, <type> value );
|
||||
ssize <fn>_slot ( <tbl_type> self, u64 key );
|
||||
|
||||
ssize <fn>__add_entry( <tbl_type> self, u64 key );
|
||||
HT_FindResult <fn>__find ( <tbl_type> self, u64 key );
|
||||
b32 <fn>__full ( <tbl_type> self );
|
||||
|
||||
<tbl_type> <fn>_make( AllocatorInfo allocator )
|
||||
{
|
||||
<tbl_type>
|
||||
result = { NULL, NULL };
|
||||
result.Hashes = array_ssize_make( allocator );
|
||||
result.Entries = <fn_array>_make( allocator );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
<tbl_type> <fn>_make_reserve( AllocatorInfo allocator, ssize num )
|
||||
{
|
||||
<tbl_type>
|
||||
result = { NULL, NULL };
|
||||
result.Hashes = array_ssize_make_reserve( allocator, num );
|
||||
result.Entries = <fn_array>_make_reserve( allocator, num );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void <fn>_clear( <tbl_type> self )
|
||||
{
|
||||
for ( ssize idx = 0; idx < array_header( self.Hashes )->Num; idx++ )
|
||||
self.Hashes[idx] = -1;
|
||||
|
||||
array_ssize_clear( self.Hashes );
|
||||
<fn_array>_clear( self.Entries );
|
||||
}
|
||||
|
||||
void <fn>_destroy( <tbl_type> self )
|
||||
{
|
||||
if ( self.Hashes && self.Entries )
|
||||
{
|
||||
array_ssize_free( self.Hashes );
|
||||
<fn_array>_free( self.Entries );
|
||||
}
|
||||
}
|
||||
|
||||
<type>* <fn>_get( <tbl_type> self, u64 key )
|
||||
{
|
||||
ssize idx = <fn>__find( self, key ).EntryIndex;
|
||||
if ( idx > 0 )
|
||||
return & self.Entries[idx].Value;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void <fn>_map( <tbl_type> self, <tbl_type>_MapProc map_proc )
|
||||
{
|
||||
GEN_ASSERT_NOT_NULL( map_proc );
|
||||
|
||||
for ( ssize idx = 0; idx < array_header( self.Entries )->Num; idx++ )
|
||||
{
|
||||
map_proc( self, self.Entries[idx].Key, self.Entries[idx].Value );
|
||||
}
|
||||
}
|
||||
|
||||
void <fn>_map_mut( <tbl_type> self, <tbl_type>_MapMutProc map_proc )
|
||||
{
|
||||
GEN_ASSERT_NOT_NULL( map_proc );
|
||||
|
||||
for ( ssize idx = 0; idx < array_header( self.Entries )->Num; idx++ )
|
||||
{
|
||||
map_proc( self, self.Entries[idx].Key, & self.Entries[idx].Value );
|
||||
}
|
||||
}
|
||||
|
||||
void <fn>_grow( <tbl_type>* self )
|
||||
{
|
||||
ssize new_num = array_grow_formula( array_header( self->Entries )->Num );
|
||||
<fn>_rehash( self, new_num );
|
||||
}
|
||||
|
||||
void <fn>_rehash( <tbl_type>* self, ssize new_num )
|
||||
{
|
||||
ssize idx;
|
||||
ssize last_added_index;
|
||||
|
||||
ArrayHeader* old_hash_header = array_header( self->Hashes );
|
||||
ArrayHeader* old_entries_header = array_header( self->Entries );
|
||||
|
||||
<tbl_type> new_tbl = <fn>_make_reserve( old_hash_header->Allocator, old_hash_header->Num );
|
||||
|
||||
ArrayHeader* new_hash_header = array_header( new_tbl.Hashes );
|
||||
|
||||
for ( idx = 0; idx < new_hash_header->Num; idx++ )
|
||||
new_tbl.Hashes[idx] = -1;
|
||||
|
||||
for ( idx = 0; idx < old_entries_header->Num; idx++ )
|
||||
{
|
||||
<entry_type>* entry;
|
||||
HT_FindResult find_result;
|
||||
|
||||
if ( new_hash_header->Num == 0 )
|
||||
<fn>_grow( & new_tbl );
|
||||
|
||||
entry = & self->Entries[ idx ];
|
||||
find_result = <fn>__find( new_tbl, entry->Key );
|
||||
last_added_index = <fn>__add_entry( new_tbl, entry->Key );
|
||||
|
||||
if ( find_result.PrevIndex < 0 )
|
||||
new_tbl.Hashes[ find_result.HashIndex ] = last_added_index;
|
||||
else
|
||||
new_tbl.Entries[ find_result.PrevIndex ].Next = last_added_index;
|
||||
|
||||
new_tbl.Entries[ last_added_index ].Next = find_result.EntryIndex;
|
||||
new_tbl.Entries[ last_added_index ].Value = entry->Value;
|
||||
}
|
||||
|
||||
<fn>_destroy( *self );
|
||||
* self = new_tbl;
|
||||
}
|
||||
|
||||
void <fn>_rehash_fast( <tbl_type> self )
|
||||
{
|
||||
ssize idx;
|
||||
|
||||
for ( idx = 0; idx < array_header( self.Entries )->Num; idx++ )
|
||||
self.Entries[ idx ].Next = -1;
|
||||
|
||||
for ( idx = 0; idx < array_header( self.Hashes )->Num; idx++ )
|
||||
self.Hashes[ idx ] = -1;
|
||||
|
||||
for ( idx = 0; idx < array_header( self.Entries )->Num; idx++ )
|
||||
{
|
||||
<entry_type>* entry;
|
||||
HT_FindResult find_result;
|
||||
|
||||
entry = & self.Entries[ idx ];
|
||||
find_result = <fn>__find( self, entry->Key );
|
||||
|
||||
if ( find_result.PrevIndex < 0 )
|
||||
self.Hashes[ find_result.HashIndex ] = idx;
|
||||
else
|
||||
self.Entries[ find_result.PrevIndex ].Next = idx;
|
||||
}
|
||||
}
|
||||
|
||||
void <fn>_remove( <tbl_type> self, u64 key )
|
||||
{
|
||||
HT_FindResult find_result = <fn>__find( self, key );
|
||||
|
||||
if ( find_result.EntryIndex >= 0 )
|
||||
{
|
||||
<fn_array>_remove_at( self.Entries, find_result.EntryIndex );
|
||||
<fn>_rehash_fast( self );
|
||||
}
|
||||
}
|
||||
|
||||
void <fn>_remove_entry( <tbl_type> self, ssize idx )
|
||||
{
|
||||
<fn_array>_remove_at( self.Entries, idx );
|
||||
}
|
||||
|
||||
void <fn>_set( <tbl_type>* self, u64 key, <type> value )
|
||||
{
|
||||
ssize idx;
|
||||
HT_FindResult find_result;
|
||||
|
||||
if ( array_header( self->Hashes )->Num == 0 )
|
||||
<fn>_grow( self );
|
||||
|
||||
find_result = <fn>__find( * self, key );
|
||||
|
||||
if ( find_result.EntryIndex >= 0 )
|
||||
{
|
||||
idx = find_result.EntryIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
idx = <fn>__add_entry( * self, key );
|
||||
|
||||
if ( find_result.PrevIndex >= 0 )
|
||||
{
|
||||
self->Entries[ find_result.PrevIndex ].Next = idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->Hashes[ find_result.HashIndex ] = idx;
|
||||
}
|
||||
}
|
||||
|
||||
self->Entries[ idx ].Value = value;
|
||||
|
||||
if ( <fn>__full( * self ) )
|
||||
<fn>_grow( self );
|
||||
}
|
||||
|
||||
ssize <fn>_slot( <tbl_type> self, u64 key )
|
||||
{
|
||||
for ( ssize idx = 0; idx < array_header( self.Hashes )->Num; ++idx )
|
||||
if ( self.Hashes[ idx ] == key )
|
||||
return idx;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize <fn>__add_entry( <tbl_type> self, u64 key )
|
||||
{
|
||||
ssize idx;
|
||||
<entry_type> entry = { key, -1 };
|
||||
|
||||
idx = array_header( self.Entries )->Num;
|
||||
<fn_array>_append( & self.Entries, entry );
|
||||
return idx;
|
||||
}
|
||||
|
||||
HT_FindResult <fn>__find( <tbl_type> self, u64 key )
|
||||
{
|
||||
HT_FindResult result = { -1, -1, -1 };
|
||||
|
||||
ArrayHeader* hash_header = array_header( self.Hashes );
|
||||
|
||||
if ( hash_header->Num > 0 )
|
||||
{
|
||||
result.HashIndex = key % hash_header->Num;
|
||||
result.EntryIndex = self.Hashes[ result.HashIndex ];
|
||||
|
||||
while ( result.EntryIndex >= 0 )
|
||||
{
|
||||
if ( self.Entries[ result.EntryIndex ].Key == key )
|
||||
break;
|
||||
|
||||
result.PrevIndex = result.EntryIndex;
|
||||
result.EntryIndex = self.Entries[ result.EntryIndex ].Next;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
b32 <fn>__full( <tbl_type> self )
|
||||
{
|
||||
ArrayHeader* hash_header = array_header( self.Hashes );
|
||||
ArrayHeader* entries_header = array_header( self.Entries );
|
||||
|
||||
return 0.75f * hash_header->Num < entries_header->Num;
|
||||
}
|
||||
)));
|
||||
#pragma pop_macro( "GEN_ASSERT" )
|
||||
#pragma pop_macro( "GEN_ASSERT_NOT_NULL" )
|
||||
|
||||
char const* cmt_str = str_fmt_buf( "Name: %.*s Type: %.*s"
|
||||
, tbl_type.length(), tbl_type.Data
|
||||
, type.Len, type.Ptr );
|
||||
|
||||
return def_global_body(args(
|
||||
def_pragma( string_to_strc( string_fmt_buf( GlobalAllocator, "region %S", tbl_type ))),
|
||||
fmt_newline,
|
||||
hashtable_types,
|
||||
fmt_newline,
|
||||
entry_array,
|
||||
hashtable_def,
|
||||
fmt_newline,
|
||||
def_pragma( string_to_strc( string_fmt_buf( GlobalAllocator, "endregion %S", tbl_type ))),
|
||||
fmt_newline
|
||||
));
|
||||
}
|
14
gen_c_library/components/header_start.hpp
Normal file
14
gen_c_library/components/header_start.hpp
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
gencpp: An attempt at "simple" staged metaprogramming for c/c++.
|
||||
|
||||
See Readme.md for more information from the project repository.
|
||||
|
||||
Public Address:
|
||||
https://github.com/Ed94/gencpp
|
||||
|
||||
This is a single header C-Library variant.
|
||||
Define GEN_IMPLEMENTATION before including this file in a single compilation unit.
|
||||
*/
|
||||
#if ! defined(GEN_DONT_ENFORCE_GEN_TIME_GUARD) && ! defined(GEN_TIME)
|
||||
# error Gen.hpp : GEN_TIME not defined
|
||||
#endif
|
122
gen_c_library/components/memory.fixed_arena.hpp
Normal file
122
gen_c_library/components/memory.fixed_arena.hpp
Normal file
@ -0,0 +1,122 @@
|
||||
#pragma once
|
||||
#include "../project/gen.hpp"
|
||||
|
||||
using namespace gen;
|
||||
|
||||
CodeBody gen_fixed_arenas()
|
||||
{
|
||||
CodeBody result = def_body(CT_Global_Body);
|
||||
result.append(def_pragma(txt("region FixedArena")));
|
||||
|
||||
char const* template_struct = stringize(
|
||||
struct FixedArena_<Name>
|
||||
{
|
||||
char memory[<Size>];
|
||||
Arena arena;
|
||||
};
|
||||
);
|
||||
|
||||
char const* template_interface = stringize(
|
||||
inline
|
||||
void fixed_arena_init_<Name>(FixedArena_<Name>* result) {
|
||||
zero_size(& result->memory[0], <Size>);
|
||||
result->arena = arena_init_from_memory(& result->memory[0], <Size>);
|
||||
}
|
||||
|
||||
inline
|
||||
ssize fixed_arena_size_remaining_<Name>(FixedArena_<Name>* fixed_arena, ssize alignment) {
|
||||
return size_remaining(fixed_arena->arena, alignment);
|
||||
}
|
||||
);
|
||||
|
||||
CodeStruct arena_struct_1kb = parse_struct( token_fmt_impl( 3, "Name", txt("1KB"), "Size", txt("kilobytes(1)"), template_struct ));
|
||||
CodeStruct arena_struct_4kb = parse_struct( token_fmt_impl( 3, "Name", txt("4KB"), "Size", txt("kilobytes(4)"), template_struct ));
|
||||
CodeStruct arena_struct_8kb = parse_struct( token_fmt_impl( 3, "Name", txt("8KB"), "Size", txt("kilobytes(8)"), template_struct ));
|
||||
CodeStruct arena_struct_16kb = parse_struct( token_fmt_impl( 3, "Name", txt("16KB"), "Size", txt("kilobytes(16)"), template_struct ));
|
||||
CodeStruct arena_struct_32kb = parse_struct( token_fmt_impl( 3, "Name", txt("32KB"), "Size", txt("kilobytes(32)"), template_struct ));
|
||||
CodeStruct arena_struct_64kb = parse_struct( token_fmt_impl( 3, "Name", txt("64KB"), "Size", txt("kilobytes(64)"), template_struct ));
|
||||
CodeStruct arena_struct_128kb = parse_struct( token_fmt_impl( 3, "Name", txt("128KB"), "Size", txt("kilobytes(128)"), template_struct ));
|
||||
CodeStruct arena_struct_256kb = parse_struct( token_fmt_impl( 3, "Name", txt("256KB"), "Size", txt("kilobytes(256)"), template_struct ));
|
||||
CodeStruct arena_struct_512kb = parse_struct( token_fmt_impl( 3, "Name", txt("512KB"), "Size", txt("kilobytes(512)"), template_struct ));
|
||||
CodeStruct arena_struct_1mb = parse_struct( token_fmt_impl( 3, "Name", txt("1MB"), "Size", txt("megabytes(1)"), template_struct ));
|
||||
CodeStruct arena_struct_2mb = parse_struct( token_fmt_impl( 3, "Name", txt("2MB"), "Size", txt("megabytes(2)"), template_struct ));
|
||||
CodeStruct arena_struct_4mb = parse_struct( token_fmt_impl( 3, "Name", txt("4MB"), "Size", txt("megabytes(4)"), template_struct ));
|
||||
|
||||
|
||||
CodeBody arena_interface_1kb = parse_global_body( token_fmt_impl( 3, "Name", txt("1KB"), "Size", txt("kilobytes(1)"), template_interface ));
|
||||
CodeBody arena_interface_4kb = parse_global_body( token_fmt_impl( 3, "Name", txt("4KB"), "Size", txt("kilobytes(4)"), template_interface ));
|
||||
CodeBody arena_interface_8kb = parse_global_body( token_fmt_impl( 3, "Name", txt("8KB"), "Size", txt("kilobytes(8)"), template_interface ));
|
||||
CodeBody arena_interface_16kb = parse_global_body( token_fmt_impl( 3, "Name", txt("16KB"), "Size", txt("kilobytes(16)"), template_interface ));
|
||||
CodeBody arena_interface_32kb = parse_global_body( token_fmt_impl( 3, "Name", txt("32KB"), "Size", txt("kilobytes(32)"), template_interface ));
|
||||
CodeBody arena_interface_64kb = parse_global_body( token_fmt_impl( 3, "Name", txt("64KB"), "Size", txt("kilobytes(64)"), template_interface ));
|
||||
CodeBody arena_interface_128kb = parse_global_body( token_fmt_impl( 3, "Name", txt("128KB"), "Size", txt("kilobytes(128)"), template_interface ));
|
||||
CodeBody arena_interface_256kb = parse_global_body( token_fmt_impl( 3, "Name", txt("256KB"), "Size", txt("kilobytes(256)"), template_interface ));
|
||||
CodeBody arena_interface_512kb = parse_global_body( token_fmt_impl( 3, "Name", txt("512KB"), "Size", txt("kilobytes(512)"), template_interface ));
|
||||
CodeBody arena_interface_1mb = parse_global_body( token_fmt_impl( 3, "Name", txt("1MB"), "Size", txt("megabytes(1)"), template_interface ));
|
||||
CodeBody arena_interface_2mb = parse_global_body( token_fmt_impl( 3, "Name", txt("2MB"), "Size", txt("megabytes(2)"), template_interface ));
|
||||
CodeBody arena_interface_4mb = parse_global_body( token_fmt_impl( 3, "Name", txt("4MB"), "Size", txt("megabytes(4)"), template_interface ));
|
||||
|
||||
result.append(arena_struct_1kb);
|
||||
result.append(arena_struct_4kb);
|
||||
result.append(arena_struct_8kb);
|
||||
result.append(arena_struct_16kb);
|
||||
result.append(arena_struct_32kb);
|
||||
result.append(arena_struct_128kb);
|
||||
result.append(arena_struct_256kb);
|
||||
result.append(arena_struct_512kb);
|
||||
result.append(arena_struct_1mb);
|
||||
result.append(arena_struct_2mb);
|
||||
result.append(arena_struct_4mb);
|
||||
|
||||
result.append(arena_interface_1kb);
|
||||
result.append(arena_interface_4kb);
|
||||
result.append(arena_interface_8kb);
|
||||
result.append(arena_interface_16kb);
|
||||
result.append(arena_interface_32kb);
|
||||
result.append(arena_interface_128kb);
|
||||
result.append(arena_interface_256kb);
|
||||
result.append(arena_interface_512kb);
|
||||
result.append(arena_interface_1mb);
|
||||
result.append(arena_interface_2mb);
|
||||
result.append(arena_interface_4mb);
|
||||
|
||||
CodeDefine def = def_define(txt("fixed_arena_allocator_info(fixed_arena)"), code({ arena_allocator_proc, & fixed_arena.arena }) );
|
||||
result.append(def);
|
||||
|
||||
result.append(parse_global_body(txt(R"(
|
||||
#define fixed_arena_init(expr) _Generic((expr), \
|
||||
FixedArena_1KB* : fixed_arena_init_1KB, \
|
||||
FixedArena_4KB* : fixed_arena_init_4KB, \
|
||||
FixedArena_8KB* : fixed_arena_init_8KB, \
|
||||
FixedArena_16KB* : fixed_arena_init_16KB, \
|
||||
FixedArena_32KB* : fixed_arena_init_32KB, \
|
||||
FixedArena_64KB* : fixed_arena_init_64KB, \
|
||||
FixedArena_128KB* : fixed_arena_init_128KB, \
|
||||
FixedArena_256KB* : fixed_arena_init_256KB, \
|
||||
FixedArena_512KB* : fixed_arena_init_512KB, \
|
||||
FixedArena_1MB* : fixed_arena_init_1MB, \
|
||||
FixedArena_2MB* : fixed_arena_init_2MB, \
|
||||
FixedArena_4MB* : fixed_arena_init_4MB \
|
||||
)(expr)
|
||||
|
||||
#define fixed_arena_size_remaining(expr, alignment) _Generic((expr), \
|
||||
FixedArena_1KB* : fixed_arena_size_remaining_1KB, \
|
||||
FixedArena_4KB* : fixed_arena_size_remaining_4KB, \
|
||||
FixedArena_8KB* : fixed_arena_size_remaining_8KB, \
|
||||
FixedArena_16KB* : fixed_arena_size_remaining_16KB, \
|
||||
FixedArena_32KB* : fixed_arena_size_remaining_32KB, \
|
||||
FixedArena_64KB* : fixed_arena_size_remaining_64KB, \
|
||||
FixedArena_128KB* : fixed_arena_size_remaining_128KB, \
|
||||
FixedArena_256KB* : fixed_arena_size_remaining_256KB, \
|
||||
FixedArena_512KB* : fixed_arena_size_remaining_512KB, \
|
||||
FixedArena_1MB* : fixed_arena_size_remaining_1MB, \
|
||||
FixedArena_2MB* : fixed_arena_size_remaining_2MB, \
|
||||
FixedArena_4MB* : fixed_arena_size_remaining_4MB \
|
||||
)(expr, alignment)
|
||||
)"
|
||||
)));
|
||||
|
||||
result.append(def_pragma(txt("endregion FixedArena")));
|
||||
|
||||
return result;
|
||||
}
|
185
gen_c_library/components/misc.hpp
Normal file
185
gen_c_library/components/misc.hpp
Normal file
@ -0,0 +1,185 @@
|
||||
// #pragma once
|
||||
// #include "../project/gen.hpp"
|
||||
|
||||
// using namespace gen;
|
||||
|
||||
using SwapContentProc = CodeBody(void);
|
||||
|
||||
|
||||
struct NeedsSelectors {
|
||||
HashTable(Array(CodeFn)) table;
|
||||
|
||||
void set(StrC sig, Array(CodeFn) list) {
|
||||
u32 key = crc32(sig.Ptr, sig.Len);
|
||||
table.set(key, list);
|
||||
}
|
||||
Array(CodeFn)* get(StrC sig) {
|
||||
u32 key = crc32(sig.Ptr, sig.Len);
|
||||
return table.get(key);
|
||||
}
|
||||
};
|
||||
CodeBody generate_generic_selectors(Array(Array(CodeFn)) listing)
|
||||
{
|
||||
constexpr char const* tmpl_selector =
|
||||
R"( #define <base_name>(<params>) \
|
||||
_Generic((
|
||||
))
|
||||
);
|
||||
)";
|
||||
|
||||
CodeBody result = def_body(CT_Global_Body);
|
||||
for (Array(CodeFn) functions : listing)
|
||||
{
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& body )
|
||||
{
|
||||
b32 found = false;
|
||||
CodePreprocessCond cond = cast(CodePreprocessCond, entry_iter);
|
||||
if ( cond->Content.contains(cond_sig) )
|
||||
{
|
||||
log_fmt("Preprocess cond found: %SC\n", cond->Content);
|
||||
found = true;
|
||||
|
||||
s32 depth = 1;
|
||||
++ entry_iter;
|
||||
for(b32 continue_for = true; continue_for && entry_iter != body.end(); ) switch
|
||||
(entry_iter->Type) {
|
||||
case CT_Preprocess_If:
|
||||
case CT_Preprocess_IfDef:
|
||||
case CT_Preprocess_IfNotDef:
|
||||
++ depth;
|
||||
++ entry_iter;
|
||||
break;
|
||||
|
||||
case CT_Preprocess_Else:
|
||||
++ entry_iter;
|
||||
for(; continue_for && entry_iter != body.end(); ++ entry_iter)
|
||||
{
|
||||
if (entry_iter->Type == CT_Preprocess_EndIf)
|
||||
{
|
||||
continue_for = false;
|
||||
break;
|
||||
}
|
||||
body.append(entry_iter);
|
||||
}
|
||||
break;
|
||||
|
||||
case CT_Preprocess_EndIf:
|
||||
{
|
||||
depth --;
|
||||
if (depth == 0) {
|
||||
continue_for = false;
|
||||
break;
|
||||
}
|
||||
++ entry_iter;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
++ entry_iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
CodeFn rename_function_to_unique_symbol(CodeFn fn, StrC optional_prefix = txt(""))
|
||||
{
|
||||
// Get basic components for the name
|
||||
StrC old_name = fn->Name;
|
||||
String new_name;
|
||||
|
||||
// Add prefix if provided
|
||||
if (optional_prefix.Len)
|
||||
new_name = string_fmt_buf(GlobalAllocator, "%SC_%SC_", optional_prefix, old_name);
|
||||
else
|
||||
new_name = string_fmt_buf(GlobalAllocator, "%SC_", old_name);
|
||||
|
||||
// Add return type to the signature
|
||||
if (fn->ReturnType)
|
||||
new_name.append_fmt("_%SC", fn->ReturnType->Name);
|
||||
|
||||
// Add parameter types to create a unique signature
|
||||
bool first_param = true;
|
||||
for (CodeParam param = fn->Params; param.ast; param = param->Next)
|
||||
{
|
||||
if (param->ValueType)
|
||||
{
|
||||
// Add separator for readability
|
||||
if (first_param)
|
||||
{
|
||||
new_name.append("_P_");
|
||||
first_param = false;
|
||||
}
|
||||
else
|
||||
new_name.append("_");
|
||||
|
||||
// Add parameter type, handle any specifiers
|
||||
if (param->ValueType->Specs && param->ValueType->Specs->NumEntries > 0)
|
||||
{
|
||||
// Add specifiers (const, volatile, etc)
|
||||
for (Specifier spec : param->ValueType->Specs)
|
||||
{
|
||||
if (spec == Spec_Ptr) {
|
||||
new_name.append("ptr_");
|
||||
continue;
|
||||
}
|
||||
|
||||
new_name.append_fmt("%SC_", to_str(spec));
|
||||
}
|
||||
}
|
||||
|
||||
new_name.append_fmt("%SC", param->ValueType->Name);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle function specifiers if present
|
||||
if (fn->Specs && fn->Specs->NumEntries > 0)
|
||||
{
|
||||
new_name.append("_S_");
|
||||
for (Specifier* spec = begin(fn->Specs);
|
||||
spec != end(fn->Specs);
|
||||
++spec)
|
||||
{
|
||||
new_name.append_fmt("%SC_", to_str(*spec));
|
||||
}
|
||||
}
|
||||
|
||||
fn->Name = new_name;
|
||||
return fn;
|
||||
}
|
||||
|
||||
bool swap_pragma_region_implementation( StrC region_name, SwapContentProc* swap_content, Code& entry_iter, CodeBody& body )
|
||||
{
|
||||
bool found = false;
|
||||
CodePragma possible_region = cast(CodePragma, entry_iter);
|
||||
|
||||
String region_sig = string_fmt_buf(GlobalAllocator, "region %s", region_name.Ptr);
|
||||
String endregion_sig = string_fmt_buf(GlobalAllocator, "endregion %s", region_name.Ptr);
|
||||
if ( possible_region->Content.contains(region_sig))
|
||||
{
|
||||
found = true;
|
||||
// body.append(possible_region);
|
||||
body.append(swap_content());
|
||||
|
||||
++ entry_iter;
|
||||
for(b32 continue_for = true; continue_for; ++entry_iter) switch
|
||||
(entry_iter->Type) {
|
||||
case CT_Preprocess_Pragma:
|
||||
{
|
||||
CodePragma possible_end_region = cast(CodePragma, entry_iter);
|
||||
if ( possible_end_region->Content.contains(endregion_sig) ) {
|
||||
// body.append(possible_end_region);
|
||||
continue_for = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
body.append(entry_iter);
|
||||
}
|
||||
return found;
|
||||
}
|
7
gen_c_library/gen.c
Normal file
7
gen_c_library/gen.c
Normal file
@ -0,0 +1,7 @@
|
||||
#define GEN_IMPLEMENTATION
|
||||
#include "gen/gen.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
// init();
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
# Singleheader
|
||||
|
||||
Creates a single header file version of the library using `gen.singleheader.cpp`.
|
||||
Creates a single header file version of the library using `singleheader.cpp`.
|
||||
Follows the same convention seen in the gb, stb, and zpl libraries.
|
@ -12,12 +12,3 @@
|
||||
#if ! defined(GEN_DONT_ENFORCE_GEN_TIME_GUARD) && ! defined(GEN_TIME)
|
||||
# error Gen.hpp : GEN_TIME not defined
|
||||
#endif
|
||||
|
||||
#ifdef GEN_DONT_USE_NAMESPACE
|
||||
# define GEN_NS_BEGIN
|
||||
# define GEN_NS_END
|
||||
#else
|
||||
# define GEN_NS_BEGIN namespace gen {
|
||||
# define GEN_NS_END }
|
||||
#endif
|
||||
|
@ -1,6 +1,8 @@
|
||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
||||
#define GEN_EXPOSE_BACKEND
|
||||
#define GEN_SUPPORT_CPP_MEMBER_FEATURES 1
|
||||
#define GEN_SUPPORT_CPP_REFERENCES 0
|
||||
#include "gen.cpp"
|
||||
|
||||
#include "helpers/push_ignores.inline.hpp"
|
||||
@ -14,6 +16,8 @@ GEN_NS_END
|
||||
#include "auxillary/builder.cpp"
|
||||
#include "auxillary/scanner.hpp"
|
||||
|
||||
#include <cstdlib> // for system()
|
||||
|
||||
using namespace gen;
|
||||
|
||||
constexpr char const* generation_notice =
|
||||
@ -35,7 +39,6 @@ constexpr StrC roll_own_dependencies_guard_start = txt(R"(
|
||||
//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file.
|
||||
// Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
|
||||
#ifndef GEN_ROLL_OWN_DEPENDENCIES
|
||||
|
||||
)");
|
||||
|
||||
constexpr StrC roll_own_dependencies_guard_end = txt(R"(
|
||||
@ -48,6 +51,42 @@ global bool generate_builder = true;
|
||||
global bool generate_editor = true;
|
||||
global bool generate_scanner = true;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int gen_main()
|
||||
{
|
||||
#define project_dir "../project/"
|
||||
@ -69,7 +108,7 @@ int gen_main()
|
||||
|
||||
if ( generate_gen_dep )
|
||||
{
|
||||
Code header_start = scan_file( project_dir "dependencies/header_start.hpp" );
|
||||
Code platform = scan_file( project_dir "dependencies/platform.hpp" );
|
||||
Code macros = scan_file( project_dir "dependencies/macros.hpp" );
|
||||
Code basic_types = scan_file( project_dir "dependencies/basic_types.hpp" );
|
||||
Code debug = scan_file( project_dir "dependencies/debug.hpp" );
|
||||
@ -83,7 +122,7 @@ int gen_main()
|
||||
Code timing = scan_file( project_dir "dependencies/timing.hpp" );
|
||||
|
||||
header.print_fmt( roll_own_dependencies_guard_start );
|
||||
header.print( header_start );
|
||||
header.print( platform );
|
||||
header.print_fmt( "\nGEN_NS_BEGIN\n" );
|
||||
|
||||
header.print( macros );
|
||||
@ -127,9 +166,13 @@ int gen_main()
|
||||
|
||||
header.print_fmt("#pragma region Types\n");
|
||||
header.print( types );
|
||||
header.print( ecode );
|
||||
header.print( eoperator );
|
||||
header.print( especifier );
|
||||
header.print( fmt_newline );
|
||||
header.print( dump_to_scratch_and_retireve( ecode ));
|
||||
header.print( fmt_newline );
|
||||
header.print( dump_to_scratch_and_retireve( eoperator ));
|
||||
header.print( fmt_newline );
|
||||
header.print( dump_to_scratch_and_retireve( especifier ));
|
||||
header.print( fmt_newline );
|
||||
header.print_fmt("#pragma endregion Types\n\n");
|
||||
|
||||
header.print_fmt("#pragma region AST\n");
|
||||
@ -142,7 +185,8 @@ int gen_main()
|
||||
|
||||
header.print_fmt( "\n#pragma region Inlines\n" );
|
||||
header.print( inlines );
|
||||
header.print( ast_inlines );
|
||||
header.print( dump_to_scratch_and_retireve( ast_inlines ));
|
||||
header.print( fmt_newline );
|
||||
header.print_fmt( "#pragma endregion Inlines\n" );
|
||||
|
||||
header.print( header_end );
|
||||
@ -209,7 +253,7 @@ int gen_main()
|
||||
Code untyped = scan_file( project_dir "components/interface.untyped.cpp" );
|
||||
|
||||
CodeBody etoktype = gen_etoktype( project_dir "enums/ETokType.csv", project_dir "enums/AttributeTokens.csv" );
|
||||
CodeNS parser_nspace = def_namespace( name(Parser), def_namespace_body( args(etoktype)) );
|
||||
CodeNS parser_nspace = def_namespace( name(parser), def_namespace_body( args(etoktype)) );
|
||||
|
||||
header.print_fmt( "\nGEN_NS_BEGIN\n");
|
||||
header.print( static_data );
|
||||
@ -224,7 +268,7 @@ int gen_main()
|
||||
header.print( interface );
|
||||
header.print( upfront );
|
||||
header.print_fmt( "\n#pragma region Parsing\n\n" );
|
||||
header.print( parser_nspace );
|
||||
header.print( dump_to_scratch_and_retireve(parser_nspace) );
|
||||
header.print( lexer );
|
||||
header.print( parser );
|
||||
header.print( parsing_interface );
|
3
gen_unreal_engine/Readme.md
Normal file
3
gen_unreal_engine/Readme.md
Normal file
@ -0,0 +1,3 @@
|
||||
# Unreal Engine Version Generator
|
||||
|
||||
This generates a variant of gencpp thats compatiable with use as a thirdparty module within a plugin or module of an Unreal Project or the Engine itself.
|
31
gen_unreal_engine/components/header_start.hpp
Normal file
31
gen_unreal_engine/components/header_start.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
gencpp: An attempt at "simple" staged metaprogramming for c/c++.
|
||||
|
||||
See Readme.md for more information from the project repository.
|
||||
|
||||
Public Address:
|
||||
https://github.com/Ed94/gencpp
|
||||
|
||||
This is a variant intended for use with Unreal Engine 5
|
||||
*/
|
||||
#if ! defined(GEN_DONT_ENFORCE_GEN_TIME_GUARD) && ! defined(GEN_TIME)
|
||||
# error Gen.hpp : GEN_TIME not defined
|
||||
#endif
|
||||
|
||||
//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file.
|
||||
// Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
|
||||
#ifndef GEN_ROLL_OWN_DEPENDENCIES
|
||||
# include "gen.dep.hpp"
|
||||
#endif
|
||||
|
||||
#ifndef GEN_NS_BEGIN
|
||||
# ifdef GEN_DONT_USE_NAMESPACE
|
||||
# define GEN_NS
|
||||
# define GEN_NS_BEGIN
|
||||
# define GEN_NS_END
|
||||
# else
|
||||
# define GEN_NS gen::
|
||||
# define GEN_NS_BEGIN namespace gen {
|
||||
# define GEN_NS_END }
|
||||
# endif
|
||||
#endif
|
5
gen_unreal_engine/components/src_start.cpp
Normal file
5
gen_unreal_engine/components/src_start.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#if ! defined(GEN_DONT_ENFORCE_GEN_TIME_GUARD) && ! defined(GEN_TIME)
|
||||
# error Gen.hpp : GEN_TIME not defined
|
||||
#endif
|
||||
|
||||
#include "gen.hpp"
|
7
gen_unreal_engine/enums/AttributeTokens.csv
Normal file
7
gen_unreal_engine/enums/AttributeTokens.csv
Normal file
@ -0,0 +1,7 @@
|
||||
API_Export, GEN_API_Export_Code
|
||||
API_Import, GEN_API_Import_Code
|
||||
COREUOBJECT_API, COREUOBJECT_API
|
||||
ENGINE_API, ENGINE_API
|
||||
GAMEPLAYABILITIES_API, GAMEPLAYABILITIES_API
|
||||
UMG_API, UMG_API
|
||||
UE_DEPRECATED, UE_DEPRECATED
|
|
397
gen_unreal_engine/unreal.cpp
Normal file
397
gen_unreal_engine/unreal.cpp
Normal file
@ -0,0 +1,397 @@
|
||||
#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 "dependencies/parsing.cpp"
|
||||
GEN_NS_END
|
||||
|
||||
#include "auxillary/builder.hpp"
|
||||
#include "auxillary/builder.cpp"
|
||||
#include "auxillary/scanner.hpp"
|
||||
|
||||
#include <cstdlib> // for system()
|
||||
|
||||
using namespace gen;
|
||||
|
||||
constexpr char const* generation_notice =
|
||||
"// This file was generated automatially by gencpp's unreal.cpp "
|
||||
"(See: https://github.com/Ed94/gencpp)\n\n";
|
||||
|
||||
constexpr StrC implementation_guard_start = txt(R"(
|
||||
#pragma region GENCPP IMPLEMENTATION GUARD
|
||||
#if defined(GEN_IMPLEMENTATION) && ! defined(GEN_IMPLEMENTED)
|
||||
# define GEN_IMPLEMENTED
|
||||
)");
|
||||
|
||||
constexpr StrC implementation_guard_end = txt(R"(
|
||||
#endif
|
||||
#pragma endregion GENCPP IMPLEMENTATION GUARD
|
||||
)");
|
||||
|
||||
constexpr StrC roll_own_dependencies_guard_start = txt(R"(
|
||||
//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file.
|
||||
// Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
|
||||
#ifndef GEN_ROLL_OWN_DEPENDENCIES
|
||||
|
||||
)");
|
||||
|
||||
constexpr StrC roll_own_dependencies_guard_end = txt(R"(
|
||||
// GEN_ROLL_OWN_DEPENDENCIES
|
||||
#endif
|
||||
)");
|
||||
|
||||
global bool generate_gen_dep = true;
|
||||
global bool generate_builder = true;
|
||||
global bool generate_editor = true;
|
||||
global bool generate_scanner = true;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int gen_main()
|
||||
{
|
||||
#define project_dir "../project/"
|
||||
gen::init();
|
||||
|
||||
Code push_ignores = scan_file( project_dir "helpers/push_ignores.inline.hpp" );
|
||||
Code pop_ignores = scan_file( project_dir "helpers/pop_ignores.inline.hpp" );
|
||||
|
||||
Code ue_forceinline = code_str(FORCEINLINE);
|
||||
// Code
|
||||
|
||||
// gen_dep.hpp
|
||||
{
|
||||
CodeBody macros = def_body( CodeT::Global_Body );
|
||||
{
|
||||
FileContents content = file_read_contents( GlobalAllocator, true, project_dir "dependencies/macros.hpp" );
|
||||
CodeBody ori_macros = parse_global_body( StrC { content.size, (char const*)content.data });
|
||||
|
||||
for (Code code = ori_macros.begin();
|
||||
code != ori_macros.end();
|
||||
++ code )
|
||||
{
|
||||
switch (code->Type)
|
||||
{
|
||||
using namespace ECode;
|
||||
case Preprocess_Define:
|
||||
{
|
||||
CodeDefine define = code.cast<CodeDefine>();
|
||||
if ( define->Name.starts_with(txt("global")) )
|
||||
{
|
||||
macros.append(parse_global_body(txt("#define global // Global variables")));
|
||||
continue;
|
||||
}
|
||||
|
||||
macros.append(define);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
macros.append(code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Code platform = scan_file( project_dir "dependencies/platform.hpp" );
|
||||
Code basic_types = scan_file( project_dir "dependencies/basic_types.hpp" );
|
||||
Code debug = scan_file( project_dir "dependencies/debug.hpp" );
|
||||
Code memory = scan_file( project_dir "dependencies/memory.hpp" );
|
||||
Code string_ops = scan_file( project_dir "dependencies/string_ops.hpp" );
|
||||
Code printing = scan_file( project_dir "dependencies/printing.hpp" );
|
||||
Code containers = scan_file( project_dir "dependencies/containers.hpp" );
|
||||
Code hashing = scan_file( project_dir "dependencies/hashing.hpp" );
|
||||
Code strings = scan_file( project_dir "dependencies/strings.hpp" );
|
||||
Code filesystem = scan_file( project_dir "dependencies/filesystem.hpp" );
|
||||
Code timing = scan_file( project_dir "dependencies/timing.hpp" );
|
||||
|
||||
Builder
|
||||
header = Builder::open("gen/gen.dep.hpp");
|
||||
header.print_fmt( generation_notice );
|
||||
header.print( pragma_once );
|
||||
header.print( push_ignores );
|
||||
header.print( platform );
|
||||
header.print_fmt( "\nGEN_NS_BEGIN\n" );
|
||||
|
||||
header.print( fmt_newline);
|
||||
header.print( dump_to_scratch_and_retireve(macros) );
|
||||
header.print( basic_types );
|
||||
header.print( debug );
|
||||
header.print( memory );
|
||||
header.print( string_ops );
|
||||
header.print( printing );
|
||||
header.print( containers );
|
||||
header.print( hashing );
|
||||
header.print( strings );
|
||||
header.print( filesystem );
|
||||
header.print( timing );
|
||||
|
||||
header.print_fmt( "\nGEN_NS_END\n" );
|
||||
header.print( fmt_newline );
|
||||
header.print( pop_ignores );
|
||||
header.write();
|
||||
}
|
||||
|
||||
// gen_dep.cpp
|
||||
{
|
||||
Code src_start = scan_file( project_dir "dependencies/src_start.cpp" );
|
||||
Code debug = scan_file( project_dir "dependencies/debug.cpp" );
|
||||
Code string_ops = scan_file( project_dir "dependencies/string_ops.cpp" );
|
||||
Code printing = scan_file( project_dir "dependencies/printing.cpp" );
|
||||
Code memory = scan_file( project_dir "dependencies/memory.cpp" );
|
||||
Code hashing = scan_file( project_dir "dependencies/hashing.cpp" );
|
||||
Code strings = scan_file( project_dir "dependencies/strings.cpp" );
|
||||
Code filesystem = scan_file( project_dir "dependencies/filesystem.cpp" );
|
||||
Code timing = scan_file( project_dir "dependencies/timing.cpp" );
|
||||
|
||||
Builder
|
||||
src = Builder::open( "gen/gen.dep.cpp" );
|
||||
src.print_fmt( generation_notice );
|
||||
src.print( def_include(txt("gen.dep.hpp")));
|
||||
src.print( fmt_newline );
|
||||
src.print( push_ignores );
|
||||
src.print( src_start );
|
||||
src.print_fmt( "\nGEN_NS_BEGIN\n" );
|
||||
|
||||
src.print( debug );
|
||||
src.print( string_ops );
|
||||
src.print( printing );
|
||||
src.print( hashing );
|
||||
src.print( memory );
|
||||
src.print( strings );
|
||||
src.print( filesystem );
|
||||
src.print( timing );
|
||||
|
||||
src.print_fmt( "\nGEN_NS_END\n" );
|
||||
src.print( fmt_newline );
|
||||
src.print( pop_ignores );
|
||||
src.write();
|
||||
}
|
||||
|
||||
// gen.hpp
|
||||
{
|
||||
Code header_start = scan_file( "components/header_start.hpp" );
|
||||
Code types = scan_file( project_dir "components/types.hpp" );
|
||||
Code ast = scan_file( project_dir "components/ast.hpp" );
|
||||
Code ast_types = scan_file( project_dir "components/ast_types.hpp" );
|
||||
Code code_types = scan_file( project_dir "components/code_types.hpp" );
|
||||
Code interface = scan_file( project_dir "components/interface.hpp" );
|
||||
Code inlines = scan_file( project_dir "components/inlines.hpp" );
|
||||
Code header_end = scan_file( project_dir "components/header_end.hpp" );
|
||||
|
||||
CodeBody ecode = gen_ecode ( project_dir "enums/ECode.csv" );
|
||||
CodeBody eoperator = gen_eoperator ( project_dir "enums/EOperator.csv" );
|
||||
CodeBody especifier = gen_especifier( project_dir "enums/ESpecifier.csv" );
|
||||
CodeBody ast_inlines = gen_ast_inlines();
|
||||
|
||||
Builder
|
||||
header = Builder::open( "gen/gen.hpp" );
|
||||
header.print_fmt( generation_notice );
|
||||
header.print_fmt( "#pragma once\n\n" );
|
||||
header.print( push_ignores );
|
||||
header.print( fmt_newline );
|
||||
header.print( header_start );
|
||||
header.print_fmt( "\nGEN_NS_BEGIN\n\n" );
|
||||
|
||||
header.print_fmt( "#pragma region Types\n" );
|
||||
header.print( types );
|
||||
header.print( fmt_newline );
|
||||
header.print( dump_to_scratch_and_retireve(ecode) );
|
||||
header.print( fmt_newline );
|
||||
header.print( dump_to_scratch_and_retireve(eoperator) );
|
||||
header.print( fmt_newline );
|
||||
header.print( dump_to_scratch_and_retireve(especifier) );
|
||||
header.print( fmt_newline );
|
||||
header.print_fmt( "#pragma endregion Types\n\n" );
|
||||
|
||||
header.print_fmt( "#pragma region AST\n" );
|
||||
header.print( ast );
|
||||
header.print( code_types );
|
||||
header.print( ast_types );
|
||||
header.print_fmt( "\n#pragma endregion AST\n" );
|
||||
|
||||
header.print( interface );
|
||||
|
||||
header.print_fmt( "\n#pragma region Inlines\n" );
|
||||
header.print( inlines );
|
||||
header.print( fmt_newline );
|
||||
header.print( dump_to_scratch_and_retireve(ast_inlines) );
|
||||
header.print( fmt_newline );
|
||||
header.print_fmt( "#pragma endregion Inlines\n" );
|
||||
|
||||
header.print( header_end );
|
||||
header.print_fmt( "GEN_NS_END\n\n" );
|
||||
header.print( pop_ignores );
|
||||
header.write();
|
||||
}
|
||||
|
||||
// gen.cpp
|
||||
{
|
||||
Code src_start = scan_file( "components/src_start.cpp" );
|
||||
Code static_data = scan_file( project_dir "components/static_data.cpp" );
|
||||
Code ast_case_macros = scan_file( project_dir "components/ast_case_macros.cpp" );
|
||||
Code ast = scan_file( project_dir "components/ast.cpp" );
|
||||
Code code_serialization = scan_file( project_dir "components/code_serialization.cpp" );
|
||||
Code interface = scan_file( project_dir "components/interface.cpp" );
|
||||
Code upfront = scan_file( project_dir "components/interface.upfront.cpp" );
|
||||
Code lexer = scan_file( project_dir "components/lexer.cpp" );
|
||||
Code parser = scan_file( project_dir "components/parser.cpp" );
|
||||
Code parsing_interface = scan_file( project_dir "components/interface.parsing.cpp" );
|
||||
Code untyped = scan_file( project_dir "components/interface.untyped.cpp" );
|
||||
|
||||
// Note(Ed): The Attribute tokens need to be expanded and regenerated on a per-project/installation of this library for a specific codebase of Unreal.
|
||||
// We can support an arbitrary set of modules or plugin apis for parsing
|
||||
// but its up to the user to define them all (This will just provide whats I've used up till now).
|
||||
CodeBody etoktype = gen_etoktype( project_dir "enums/ETokType.csv", "enums/AttributeTokens.csv" );
|
||||
CodeNS nspaced_etoktype = def_namespace( name(parser), def_namespace_body( args(etoktype)) );
|
||||
|
||||
Builder
|
||||
src = Builder::open( "gen/gen.cpp" );
|
||||
src.print_fmt( generation_notice );
|
||||
src.print( push_ignores );
|
||||
src.print( fmt_newline );
|
||||
src.print( src_start );
|
||||
src.print( fmt_newline );
|
||||
src.print_fmt( "GEN_NS_BEGIN\n");
|
||||
|
||||
src.print( static_data );
|
||||
|
||||
src.print_fmt( "\n#pragma region AST\n\n" );
|
||||
src.print( ast_case_macros );
|
||||
src.print( ast );
|
||||
src.print( code_serialization );
|
||||
src.print_fmt( "\n#pragma endregion AST\n" );
|
||||
|
||||
src.print_fmt( "\n#pragma region Interface\n" );
|
||||
src.print( interface );
|
||||
src.print( upfront );
|
||||
src.print_fmt( "\n#pragma region Parsing\n\n" );
|
||||
src.print( dump_to_scratch_and_retireve(nspaced_etoktype) );
|
||||
src.print( lexer );
|
||||
src.print( parser );
|
||||
src.print( parsing_interface );
|
||||
src.print( untyped );
|
||||
src.print_fmt( "\n#pragma endregion Parsing\n\n" );
|
||||
src.print_fmt( "#pragma endregion Interface\n\n" );
|
||||
|
||||
src.print_fmt( "GEN_NS_END\n\n");
|
||||
src.print( pop_ignores );
|
||||
src.write();
|
||||
}
|
||||
|
||||
// gen_builder.hpp
|
||||
{
|
||||
Code builder = scan_file( project_dir "auxillary/builder.hpp" );
|
||||
|
||||
Builder
|
||||
header = Builder::open( "gen/gen.builder.hpp" );
|
||||
header.print_fmt( generation_notice );
|
||||
header.print( push_ignores );
|
||||
header.print( fmt_newline );
|
||||
header.print_fmt( "#pragma once\n\n" );
|
||||
header.print( def_include( txt("gen.hpp") ));
|
||||
header.print_fmt( "\nGEN_NS_BEGIN\n" );
|
||||
header.print( builder );
|
||||
header.print_fmt( "GEN_NS_END\n" );
|
||||
header.print( fmt_newline );
|
||||
header.print( pop_ignores );
|
||||
header.write();
|
||||
}
|
||||
|
||||
// gen_builder.cpp
|
||||
{
|
||||
Code builder = scan_file( project_dir "auxillary/builder.cpp" );
|
||||
|
||||
Builder
|
||||
src = Builder::open( "gen/gen.builder.cpp" );
|
||||
src.print_fmt( generation_notice );
|
||||
src.print( push_ignores );
|
||||
src.print( fmt_newline );
|
||||
src.print( def_include( txt("gen.builder.hpp") ) );
|
||||
src.print_fmt( "\nGEN_NS_BEGIN\n" );
|
||||
src.print( builder );
|
||||
src.print_fmt( "\nGEN_NS_END\n" );
|
||||
src.print( fmt_newline );
|
||||
src.print( pop_ignores );
|
||||
src.write();
|
||||
}
|
||||
|
||||
// gen_scanner.hpp
|
||||
{
|
||||
Code parsing = scan_file( project_dir "dependencies/parsing.hpp" );
|
||||
Code scanner = scan_file( project_dir "auxillary/scanner.hpp" );
|
||||
|
||||
Builder
|
||||
header = Builder::open( "gen/gen.scanner.hpp" );
|
||||
header.print_fmt( generation_notice );
|
||||
header.print_fmt( "#pragma once\n\n" );
|
||||
header.print( push_ignores );
|
||||
header.print( fmt_newline );
|
||||
header.print( def_include( txt("gen.hpp") ) );
|
||||
header.print_fmt( "\nGEN_NS_BEGIN\n" );
|
||||
header.print( parsing );
|
||||
header.print( scanner );
|
||||
header.print_fmt( "GEN_NS_END\n" );
|
||||
header.print( fmt_newline );
|
||||
header.print( pop_ignores );
|
||||
header.write();
|
||||
}
|
||||
|
||||
// gen.scanner.cpp
|
||||
{
|
||||
Code parsing = scan_file( project_dir "dependencies/parsing.cpp" );
|
||||
Code scanner = scan_file( project_dir "auxillary/scanner.cpp" );
|
||||
|
||||
Builder
|
||||
src = Builder::open( "gen/gen.scanner.cpp" );
|
||||
src.print_fmt( generation_notice );
|
||||
src.print( push_ignores );
|
||||
src.print( fmt_newline );
|
||||
src.print( def_include( txt("gen.scanner.hpp") ) );
|
||||
src.print_fmt( "\nGEN_NS_BEGIN\n" );
|
||||
src.print( parsing );
|
||||
// src.print( scanner );
|
||||
src.print_fmt( "GEN_NS_END\n" );
|
||||
src.print( fmt_newline );
|
||||
src.print( pop_ignores );
|
||||
src.write();
|
||||
}
|
||||
}
|
10
gencpp.10x
10
gencpp.10x
@ -6,6 +6,7 @@
|
||||
<SyncFiles>true</SyncFiles>
|
||||
<Recursive>true</Recursive>
|
||||
<ShowEmptyFolders>true</ShowEmptyFolders>
|
||||
<IncludeFilesWithoutExt>false</IncludeFilesWithoutExt>
|
||||
<IsVirtual>false</IsVirtual>
|
||||
<IsFolder>false</IsFolder>
|
||||
<BuildCommand>pwsh ./scripts/build.ps1 msvc debug bootstrap</BuildCommand>
|
||||
@ -14,12 +15,13 @@
|
||||
<CleanCommand>pwsh ./scripts/clean.ps1</CleanCommand>
|
||||
<BuildWorkingDirectory></BuildWorkingDirectory>
|
||||
<CancelBuild></CancelBuild>
|
||||
<RunCommand>./test/gen/build/gencpp.exe</RunCommand>
|
||||
<RunCommandWorkingDirectory></RunCommandWorkingDirectory>
|
||||
<Exe>./test/gen/build/gencpp.exe</Exe>
|
||||
<Args></Args>
|
||||
<WorkingDirectory></WorkingDirectory>
|
||||
<DebugCommand>pwsh ./scripts/build.ps1</DebugCommand>
|
||||
<ExePathCommand>./test/gen/build/gencpp.exe</ExePathCommand>
|
||||
<DebugSln></DebugSln>
|
||||
<UseVisualStudioEnvBat>true</UseVisualStudioEnvBat>
|
||||
<CaptureExeOutput>false</CaptureExeOutput>
|
||||
<Configurations>
|
||||
<Configuration>Debug</Configuration>
|
||||
<Configuration>Release</Configuration>
|
||||
@ -44,6 +46,8 @@
|
||||
<Define>GEN_SYSTEM_WINDOWS</Define>
|
||||
<Define>GEN_INTELLISENSE_DIRECTIVES</Define>
|
||||
<Define>GEN_EXECUTION_EXPRESSION_SUPPORT</Define>
|
||||
<Define>GEN_BENCHMARK</Define>
|
||||
<Define>GEN_COMPILER_MSVC</Define>
|
||||
</Defines>
|
||||
<ConfigProperties>
|
||||
<ConfigAndPlatform>
|
||||
|
@ -30,6 +30,13 @@ Feature Macros:
|
||||
* `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.
|
||||
|
@ -5,7 +5,7 @@
|
||||
Builder Builder::open( char const* path )
|
||||
{
|
||||
Builder result;
|
||||
|
||||
|
||||
FileError error = file_open_mode( & result.File, EFileMode_WRITE, path );
|
||||
if ( error != EFileError_NONE )
|
||||
{
|
||||
@ -13,7 +13,7 @@ Builder Builder::open( char const* path )
|
||||
return result;
|
||||
}
|
||||
|
||||
result.Buffer = String::make_reserve( GlobalAllocator, Builder_StrBufferReserve );
|
||||
result.Buffer = string_make_reserve( GlobalAllocator, Builder_StrBufferReserve );
|
||||
|
||||
// log_fmt("$Builder - Opened file: %s\n", result.File.filename );
|
||||
return result;
|
||||
@ -21,20 +21,20 @@ Builder Builder::open( char const* path )
|
||||
|
||||
void Builder::pad_lines( s32 num )
|
||||
{
|
||||
Buffer.append( "\n" );
|
||||
string_append_strc( & Buffer, txt("\n") );
|
||||
}
|
||||
|
||||
void Builder::print( Code code )
|
||||
{
|
||||
String str = code->to_string();
|
||||
// const sw len = str.length();
|
||||
String str = to_string(code);
|
||||
// const ssize len = str.length();
|
||||
// log_fmt( "%s - print: %.*s\n", File.filename, len > 80 ? 80 : len, str.Data );
|
||||
Buffer.append( str );
|
||||
string_append_string( & Buffer, str );
|
||||
}
|
||||
|
||||
void Builder::print_fmt( char const* fmt, ... )
|
||||
{
|
||||
sw res;
|
||||
ssize res;
|
||||
char buf[ GEN_PRINTF_MAXLEN ] = { 0 };
|
||||
|
||||
va_list va;
|
||||
@ -43,17 +43,17 @@ void Builder::print_fmt( char const* fmt, ... )
|
||||
va_end( va );
|
||||
|
||||
// log_fmt( "$%s - print_fmt: %.*s\n", File.filename, res > 80 ? 80 : res, buf );
|
||||
Buffer.append( buf, res );
|
||||
string_append_c_str_len( (String*) & Buffer, (char const*)buf, res );
|
||||
}
|
||||
|
||||
void Builder::write()
|
||||
{
|
||||
bool result = file_write( & File, Buffer, Buffer.length() );
|
||||
b32 result = file_write( & File, Buffer, string_length(Buffer) );
|
||||
|
||||
if ( result == false )
|
||||
log_failure("gen::File::write - Failed to write to file: %s\n", file_name( & File ) );
|
||||
|
||||
log_fmt( "Generated: %s\n", File.filename );
|
||||
file_close( & File );
|
||||
Buffer.free();
|
||||
string_free(& Buffer);
|
||||
}
|
||||
|
23
project/auxillary/gen_template.hpp
Normal file
23
project/auxillary/gen_template.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "../gen.hpp"
|
||||
#endif
|
||||
|
||||
/*
|
||||
Explicitly generates a resolved definition of a cpp template definition.
|
||||
|
||||
TODO(Ed): Needs implementing for the C-library variant.
|
||||
TODO(Ed): We need a non <token> syntax subst implemtnation for Strings for this to work. It must subst keywords directly based on template parameter names.
|
||||
|
||||
This is only meant to be used on relatively trivial templates, where the type or numeric is mostly a 'duck' type.
|
||||
It cannot parse complex template parameters.
|
||||
|
||||
The varadic args should correspond 1:1 with the type of objects the generator expects from the template's parameters.alignas.
|
||||
*/
|
||||
|
||||
CodeOperator gen_operator_template( CodeTemplate template, ... );
|
||||
CodeFn gen_func_template( CodeTemplate template, ... );
|
||||
Code gen_class_struct_template( CodeTemplate template, ... );
|
||||
|
||||
Code gen_template( CodeTemplate template, ... );
|
||||
Code gen_template( StrC template, StrC instantiation );
|
@ -1,3 +1,5 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
# include "scanner.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
// 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.
|
||||
inline
|
||||
Code scan_file( char const* path )
|
||||
{
|
||||
FileInfo file;
|
||||
@ -16,15 +17,15 @@ Code scan_file( char const* path )
|
||||
GEN_FATAL( "scan_file: Could not open: %s", path );
|
||||
}
|
||||
|
||||
sw fsize = file_size( & file );
|
||||
ssize fsize = file_size( & file );
|
||||
if ( fsize <= 0 )
|
||||
{
|
||||
GEN_FATAL("scan_file: %s is empty", path );
|
||||
}
|
||||
|
||||
String str = String::make_reserve( GlobalAllocator, fsize );
|
||||
String str = string_make_reserve( GlobalAllocator, fsize );
|
||||
file_read( & file, str, fsize );
|
||||
str.get_header().Length = fsize;
|
||||
string_get_header(str)->Length = fsize;
|
||||
|
||||
// Skip GEN_INTELLISENSE_DIRECTIVES preprocessor blocks
|
||||
// Its designed so that the directive should be the first thing in the file.
|
||||
@ -38,7 +39,7 @@ Code scan_file( char const* path )
|
||||
const StrC def_intellisense = txt("GEN_INTELLISENSE_DIRECTIVES" );
|
||||
|
||||
bool found_directive = false;
|
||||
char const* scanner = str.Data;
|
||||
char const* scanner = (char const*)str;
|
||||
s32 left = fsize;
|
||||
while ( left )
|
||||
{
|
||||
@ -51,7 +52,7 @@ Code scan_file( char const* path )
|
||||
|
||||
if ( ! found_directive )
|
||||
{
|
||||
if ( left && str_compare( scanner, directive_start.Ptr, directive_start.Len ) == matched )
|
||||
if ( left && str_compare_len( scanner, directive_start.Ptr, directive_start.Len ) == matched )
|
||||
{
|
||||
scanner += directive_start.Len;
|
||||
left -= directive_start.Len;
|
||||
@ -59,7 +60,7 @@ Code scan_file( char const* path )
|
||||
while ( left && char_is_space( current ) )
|
||||
move_fwd();
|
||||
|
||||
if ( left && str_compare( scanner, def_intellisense.Ptr, def_intellisense.Len ) == matched )
|
||||
if ( left && str_compare_len( scanner, def_intellisense.Ptr, def_intellisense.Len ) == matched )
|
||||
{
|
||||
scanner += def_intellisense.Len;
|
||||
left -= def_intellisense.Len;
|
||||
@ -79,7 +80,7 @@ Code scan_file( char const* path )
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( left && str_compare( scanner, directive_end.Ptr, directive_end.Len ) == matched )
|
||||
if ( left && str_compare_len( scanner, directive_end.Ptr, directive_end.Len ) == matched )
|
||||
{
|
||||
scanner += directive_end.Len;
|
||||
left -= directive_end.Len;
|
||||
@ -93,19 +94,18 @@ Code scan_file( char const* path )
|
||||
move_fwd();
|
||||
|
||||
// sptr skip_size = fsize - left;
|
||||
if ( (scanner + 2) >= ( str.Data + fsize ) )
|
||||
if ( (scanner + 2) >= ( (char const*) str + fsize ) )
|
||||
{
|
||||
mem_move( str, scanner, left );
|
||||
str.get_header().Length = left;
|
||||
string_get_header(str)->Length = left;
|
||||
break;
|
||||
}
|
||||
|
||||
mem_move( str, scanner, left );
|
||||
str.get_header().Length = left;
|
||||
string_get_header(str)->Length = left;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
move_fwd();
|
||||
@ -116,7 +116,7 @@ Code scan_file( char const* path )
|
||||
}
|
||||
|
||||
file_close( & file );
|
||||
return untyped_str( str );
|
||||
return untyped_str( string_to_strc(str) );
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -1,126 +0,0 @@
|
||||
Clear-Host
|
||||
|
||||
$path_root = git rev-parse --show-toplevel
|
||||
$path_scripts = Join-Path $path_root 'scripts'
|
||||
|
||||
$target_arch = Join-Path $path_scripts 'helpers/target_arch.psm1'
|
||||
$devshell = Join-Path $path_scripts 'helpers/devshell.ps1'
|
||||
$format_cpp = Join-Path $path_scripts 'helpers/format_cpp.psm1'
|
||||
$incremental_checks = Join-Path $path_scripts 'helpers/incremental_checks.ps1'
|
||||
$vendor_toolchain = Join-Path $path_scripts 'helpers/vendor_toolchain.ps1'
|
||||
|
||||
$path_project = Join-Path $path_root 'project'
|
||||
$path_aux = Join-Path $path_project 'auxillary'
|
||||
$path_vis_root = Join-Path $path_aux 'vis_ast'
|
||||
$path_binaries = Join-Path $path_vis_root 'binaries'
|
||||
$path_build = Join-Path $path_vis_root 'build'
|
||||
$path_code = Join-Path $path_vis_root 'code'
|
||||
$path_deps = Join-Path $path_vis_root 'dependencies'
|
||||
$path_win32 = Join-Path $path_code 'win32'
|
||||
|
||||
Import-Module $target_arch
|
||||
Import-Module $format_cpp
|
||||
|
||||
#region Arguments
|
||||
$vendor = $null
|
||||
$optimize = $null
|
||||
$debug = $null
|
||||
$analysis = $false
|
||||
$dev = $false
|
||||
$verbose = $null
|
||||
$platform = $null
|
||||
$module_specified = $false
|
||||
|
||||
[array] $vendors = @( "clang", "msvc" )
|
||||
|
||||
# This is a really lazy way of parsing the args, could use actual params down the line...
|
||||
|
||||
if ( $args ) { $args | ForEach-Object {
|
||||
switch ($_){
|
||||
{ $_ -in $vendors } { $vendor = $_; break }
|
||||
"optimize" { $optimize = $true }
|
||||
"debug" { $debug = $true }
|
||||
"analysis" { $analysis = $true }
|
||||
"dev" { $dev = $true }
|
||||
"verbose" { $verbose = $true }
|
||||
"platform" { $platform = $true; $module_specified = $true }
|
||||
}
|
||||
}}
|
||||
#endregion Argument
|
||||
|
||||
if ( -not $module_specified )
|
||||
{
|
||||
$platform = $true
|
||||
}
|
||||
|
||||
# Load up toolchain configuraion
|
||||
. $vendor_toolchain
|
||||
. $incremental_checks
|
||||
|
||||
write-host "Building Vis AST with $vendor"
|
||||
|
||||
if ( (Test-Path $path_build) -eq $false ) {
|
||||
New-Item $path_build -ItemType Directory
|
||||
}
|
||||
|
||||
if ( (Test-Path $path_binaries) -eq $false ) {
|
||||
New-Item $path_binaries -ItemType Directory
|
||||
}
|
||||
|
||||
$path_raylib = join-path $path_deps 'raylib'
|
||||
$path_raylib_inc = join-path $path_raylib 'include'
|
||||
$path_raylib_lib = join-path $path_raylib 'lib'
|
||||
|
||||
$path_raylib_dll = join-path $path_raylib_lib 'raylib.dll'
|
||||
$path_raylib_dll_bin = join-path $path_binaries 'raylib.dll'
|
||||
|
||||
Copy-Item $path_raylib_dll $path_raylib_dll_bin -Force
|
||||
|
||||
$includes = @(
|
||||
$path_code,
|
||||
$path_deps
|
||||
)
|
||||
|
||||
write-host $path_code
|
||||
|
||||
foreach ( $include in $includes ) {
|
||||
Write-Host 'include: ' $include
|
||||
}
|
||||
|
||||
# Microsoft
|
||||
$lib_gdi32 = 'Gdi32.lib'
|
||||
$lib_xinput = 'Xinput.lib'
|
||||
$lib_user32 = 'User32.lib'
|
||||
$lib_winmm = 'Winmm.lib'
|
||||
|
||||
$stack_size = 1024 * 1024 * 4
|
||||
|
||||
$compiler_args = @(
|
||||
( $flag_define + 'UNICODE'),
|
||||
( $flag_define + '_UNICODE')
|
||||
( $flag_define + 'INTELLISENSE_DIRECTIVES=0'),
|
||||
( $flag_define + 'RL_USE_LIBTYPE_SHARED')
|
||||
# ($flag_set_stack_size + $stack_size)
|
||||
$flag_wall
|
||||
$flag_warnings_as_errors
|
||||
$flag_optimize_intrinsics
|
||||
)
|
||||
|
||||
if ( $dev ) {
|
||||
$compiler_args += ( $flag_define + 'Build_Development=1' )
|
||||
}
|
||||
else {
|
||||
$compiler_args += ( $flag_define + 'Build_Development=0' )
|
||||
}
|
||||
|
||||
$linker_args = @(
|
||||
$flag_link_win_subsystem_windows,
|
||||
$flag_link_optiiize_references,
|
||||
|
||||
( join-path $path_raylib_lib 'raylib.lib' )
|
||||
)
|
||||
|
||||
$unit = join-path $path_code 'vis_ast_windows.cpp'
|
||||
$executable = join-path $path_binaries 'vis_ast.exe'
|
||||
|
||||
$build_result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable
|
@ -1,22 +0,0 @@
|
||||
$path_root = git rev-parse --show-toplevel
|
||||
$path_scripts = Join-Path $path_root 'scripts'
|
||||
|
||||
$target_arch = Join-Path $path_scripts 'helpers/target_arch.psm1'
|
||||
$devshell = Join-Path $path_scripts 'helpers/devshell.ps1'
|
||||
$format_cpp = Join-Path $path_scripts 'helpers/format_cpp.psm1'
|
||||
$incremental_checks = Join-Path $path_scripts 'helpers/incremental_checks.ps1'
|
||||
$vendor_toolchain = Join-Path $path_scripts 'helpers/vendor_toolchain.ps1'
|
||||
|
||||
$path_project = Join-Path $path_root 'project'
|
||||
$path_aux = Join-Path $path_project 'auxillary'
|
||||
$path_vis_root = Join-Path $path_aux 'vis_ast'
|
||||
$path_binaries = Join-Path $path_vis_root 'binaries'
|
||||
$path_build = Join-Path $path_vis_root 'build'
|
||||
|
||||
if ( test-path $path_build ) {
|
||||
remove-item $path_build -Recurse
|
||||
}
|
||||
|
||||
if ( test-path $path_binaries ) {
|
||||
remove-item $path_binaries -recurse
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
#if INTELLISENSE_DIRECTIVES
|
||||
#include "vendor/compiler.hpp"
|
||||
#endif
|
||||
|
||||
#define global static // Global variables
|
||||
#define internal static // Internal linkage
|
||||
#define local_persist static // Local Persisting variables
|
||||
|
||||
#define api_c extern "C"
|
||||
|
||||
#define ccast( type, value ) ( const_cast< type >( (value) ) )
|
||||
#define pcast( type, value ) ( * reinterpret_cast< type* >( & ( value ) ) )
|
||||
#define rcast( type, value ) reinterpret_cast< type >( value )
|
||||
#define scast( type, value ) static_cast< type >( value )
|
||||
|
||||
#define do_once() for ( local_persist b32 once = true; once; once = false )
|
||||
#define stmt( ... ) do { __VA_ARGS__; } while ( 0 )
|
||||
|
||||
#define array_count( array ) ( sizeof( array ) / sizeof( ( array )[0] ) )
|
||||
|
||||
#define kilobytes( x ) ( ( x ) * ( s64 )( 1024 ) )
|
||||
#define megabytes( x ) ( kilobytes( x ) * ( s64 )( 1024 ) )
|
||||
#define gigabytes( x ) ( megabytes( x ) * ( s64 )( 1024 ) )
|
||||
#define terabytes( x ) ( gigabytes( x ) * ( s64 )( 1024 ) )
|
@ -1,10 +0,0 @@
|
||||
// Platform architecture
|
||||
#pragma once
|
||||
|
||||
#if defined( _WIN64 ) || defined( __x86_64__ ) || defined( _M_X64 ) || defined( __64BIT__ ) || defined( __powerpc64__ ) || defined( __ppc64__ ) || defined( __aarch64__ )
|
||||
# ifndef ARCH_64_BIT
|
||||
# define ARCH_64_BIT 1
|
||||
# endif
|
||||
#else
|
||||
# error A 32-bit architecture is not supported
|
||||
#endif
|
@ -1,22 +0,0 @@
|
||||
// Platform compiler
|
||||
#pragma once
|
||||
|
||||
#if defined( _MSC_VER )
|
||||
# define Compiler_MSVC 1
|
||||
#elif defined( __clang__ )
|
||||
# define Compiler_Clang 1
|
||||
#else
|
||||
# error "Unknown compiler"
|
||||
#endif
|
||||
|
||||
#if defined( __has_attribute )
|
||||
# define HAS_ATTRIBUTE( attribute ) __has_attribute( attribute )
|
||||
#else
|
||||
# define HAS_ATTRIBUTE( attribute ) ( 0 )
|
||||
#endif
|
||||
|
||||
#ifdef Compiler_Clang
|
||||
# define compiler_decorated_func_name __PRETTY_NAME__
|
||||
#elif defined(Compiler_MSVC)
|
||||
# define compiler_decorated_func_name __FUNCDNAME__
|
||||
#endif
|
@ -1,34 +0,0 @@
|
||||
#pragma once
|
||||
#if INTELLISENSE_DIRECTIVES
|
||||
#include "compiler.hpp"
|
||||
#endif
|
||||
|
||||
#ifdef Compiler_MSVC
|
||||
#pragma warning( disable: 4201 ) // Support for non-standard nameless struct or union extesnion
|
||||
#pragma warning( disable: 4100 ) // Support for unreferenced formal parameters
|
||||
#pragma warning( disable: 4800 ) // Support implicit conversion to bools
|
||||
#pragma warning( disable: 4365 ) // Support for signed/unsigned mismatch auto-conversion
|
||||
#pragma warning( disable: 4189 ) // Support for unused variables
|
||||
#pragma warning( disable: 4514 ) // Support for unused inline functions
|
||||
#pragma warning( disable: 4505 ) // Support for unused static functions
|
||||
#pragma warning( disable: 5045 ) // Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
|
||||
#pragma warning( disable: 5264 ) // Support for 'const' variables unused
|
||||
#pragma warning( disable: 4820 ) // Support auto-adding padding to structs
|
||||
#pragma warning( disable: 4711 ) // Support automatic inline expansion
|
||||
#pragma warning( disable: 4710 ) // Support automatic inline expansion
|
||||
#pragma warning( disable: 4805 ) // Support comparisons of s32 to bool.
|
||||
#pragma warning( disable: 5246 ) // Support for initialization of subobject without braces.
|
||||
#endif
|
||||
|
||||
#ifdef Compiler_Clang
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-const-variable"
|
||||
#pragma clang diagnostic ignored "-Wswitch"
|
||||
#pragma clang diagnostic ignored "-Wunused-variable"
|
||||
#pragma clang diagnostic ignored "-Wunused-local-typedef"
|
||||
#pragma clang diagnostic ignored "-Wunknown-pragmas"
|
||||
#pragma clang diagnostic ignored "-Wvarargs"
|
||||
#pragma clang diagnostic ignored "-Wunused-function"
|
||||
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
|
||||
#pragma clang diagnostic ignored "-Wmissing-braces"
|
||||
#endif
|
@ -1,22 +0,0 @@
|
||||
// Platform OS detection
|
||||
#pragma once
|
||||
|
||||
#if defined( _WIN32 ) || defined( _WIN64 )
|
||||
# ifndef System_Windows
|
||||
# define System_Windows 1
|
||||
# endif
|
||||
#elif defined( __APPLE__ ) && defined( __MACH__ )
|
||||
# ifndef System_MacOS
|
||||
# define System_MacOS 1
|
||||
# endif
|
||||
#elif defined( __unix__ )
|
||||
# if defined( __linux__ )
|
||||
# ifndef System_Linux
|
||||
# define System_linux 1
|
||||
# endif
|
||||
# else
|
||||
# error This UNIX operating system is not supported
|
||||
# endif
|
||||
#else
|
||||
# error This operating system is not supported
|
||||
#endif
|
@ -1,45 +0,0 @@
|
||||
#if INTELLISENSE_DIRECTIVES
|
||||
#include "win32.hpp"
|
||||
#include "raylib/include/raylib.h"
|
||||
#endif
|
||||
|
||||
int __stdcall WinMain( HINSTANCE instance, HINSTANCE prev_instance, char* commandline, int num_cmd_show)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
rl::init_window(screenWidth, screenHeight, "raylib [core] example - basic window");
|
||||
|
||||
rl::set_target_fps(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!rl::window_should_close()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update your variables here
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
rl::begin_drawing();
|
||||
|
||||
rl::clear_background(RL_RAYWHITE);
|
||||
|
||||
rl::draw_text("Congrats! You created your first window!", 190, 200, 20, RL_LIGHTGRAY);
|
||||
|
||||
rl::end_drawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
rl::close_window(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,3 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
using HINSTANCE = void*;
|
@ -1,14 +0,0 @@
|
||||
|
||||
|
||||
#include "platform/vendor/arch.hpp"
|
||||
#include "platform/vendor/compiler.hpp"
|
||||
#include "platform/vendor/compiler_ignores.hpp"
|
||||
#include "platform/vendor/os.hpp"
|
||||
|
||||
#include "platform/macros.hpp"
|
||||
|
||||
#include "platform/win32/types.hpp"
|
||||
|
||||
#include "raylib/include/raylib.h"
|
||||
|
||||
#include "platform/win32/launch.cpp"
|
@ -1,285 +0,0 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib configuration flags
|
||||
*
|
||||
* This file defines all the configuration flags for the different raylib modules
|
||||
*
|
||||
* LICENSE: zlib/libpng
|
||||
*
|
||||
* Copyright (c) 2018-2023 Ahmad Fatoum & Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose, including commercial
|
||||
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim that you
|
||||
* wrote the original software. If you use this software in a product, an acknowledgment
|
||||
* in the product documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
||||
* as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module selection - Some modules could be avoided
|
||||
// Mandatory modules: rcore, rlgl, utils
|
||||
//------------------------------------------------------------------------------------
|
||||
#define RL_SUPPORT_MODULE_RSHAPES 1
|
||||
#define RL_SUPPORT_MODULE_RTEXTURES 1
|
||||
#define RL_SUPPORT_MODULE_RTEXT 1 // WARNING: It requires RL_SUPPORT_MODULE_RTEXTURES to load sprite font textures
|
||||
#define RL_SUPPORT_MODULE_RMODELS 1
|
||||
#define RL_SUPPORT_MODULE_RAUDIO 1
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module: rcore - Configuration Flags
|
||||
//------------------------------------------------------------------------------------
|
||||
// Camera module is included (rcamera.h) and multiple predefined cameras are available: free, 1st/3rd person, orbital
|
||||
#define RL_SUPPORT_CAMERA_SYSTEM 1
|
||||
// Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag
|
||||
#define RL_SUPPORT_GESTURES_SYSTEM 1
|
||||
// Include pseudo-random numbers generator (rprand.h), based on Xoshiro128** and SplitMix64
|
||||
#define RL_SUPPORT_RPRAND_GENERATOR 1
|
||||
// Mouse gestures are directly mapped like touches and processed by gestures system
|
||||
#define RL_SUPPORT_MOUSE_GESTURES 1
|
||||
// Reconfigure standard input to receive key inputs, works with SSH connection.
|
||||
#define RL_SUPPORT_SSH_KEYBOARD_RPI 1
|
||||
// Setting a higher resolution can improve the accuracy of time-out intervals in wait functions.
|
||||
// However, it can also reduce overall system performance, because the thread scheduler switches tasks more often.
|
||||
#define RL_SUPPORT_WINMM_HIGHRES_TIMER 1
|
||||
// Use busy wait loop for timing sync, if not defined, a high-resolution timer is set up and used
|
||||
//#define RL_SUPPORT_BUSY_WAIT_LOOP 1
|
||||
// Use a partial-busy wait loop, in this case frame sleeps for most of the time, but then runs a busy loop at the end for accuracy
|
||||
#define RL_SUPPORT_PARTIALBUSY_WAIT_LOOP 1
|
||||
// Allow automatic screen capture of current screen pressing F12, defined in KeyCallback()
|
||||
#define RL_SUPPORT_SCREEN_CAPTURE 1
|
||||
// Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback()
|
||||
#define RL_SUPPORT_GIF_RECORDING 1
|
||||
// Support CompressData() and DecompressData() functions
|
||||
#define RL_SUPPORT_COMPRESSION_API 1
|
||||
// Support automatic generated events, loading and recording of those events when required
|
||||
#define RL_SUPPORT_AUTOMATION_EVENTS 1
|
||||
// Support custom frame control, only for advance users
|
||||
// By default end_drawing() does this job: draws everything + swap_screen_buffer() + manage frame timing + poll_input_events()
|
||||
// Enabling this flag allows manual control of the frame processes, use at your own risk
|
||||
//#define RL_SUPPORT_CUSTOM_FRAME_CONTROL 1
|
||||
|
||||
// rcore: Configuration values
|
||||
//------------------------------------------------------------------------------------
|
||||
#define RL_MAX_FILEPATH_CAPACITY 8192 // Maximum file paths capacity
|
||||
#define RL_MAX_FILEPATH_LENGTH 4096 // Maximum length for filepaths (Linux PATH_MAX default value)
|
||||
|
||||
#define RL_MAX_KEYBOARD_KEYS 512 // Maximum number of keyboard keys supported
|
||||
#define RL_MAX_MOUSE_BUTTONS 8 // Maximum number of mouse buttons supported
|
||||
#define RL_MAX_GAMEPADS 4 // Maximum number of gamepads supported
|
||||
#define RL_MAX_GAMEPAD_AXIS 8 // Maximum number of axis supported (per gamepad)
|
||||
#define RL_MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad)
|
||||
#define RL_MAX_TOUCH_POINTS 8 // Maximum number of touch points supported
|
||||
#define RL_MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue
|
||||
#define RL_MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue
|
||||
|
||||
#define RL_MAX_DECOMPRESSION_SIZE 64 // Max size allocated for decompression in MB
|
||||
|
||||
#define RL_MAX_AUTOMATION_EVENTS 16384 // Maximum number of automation events to record
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module: rlgl - Configuration values
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
// Enable OpenGL Debug Context (only available on OpenGL 4.3)
|
||||
//#define RLGL_ENABLE_OPENGL_DEBUG_CONTEXT 1
|
||||
|
||||
// Show OpenGL extensions and capabilities detailed logs on init
|
||||
//#define RLGL_SHOW_GL_DETAILS_INFO 1
|
||||
|
||||
//#define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 4096 // Default internal render batch elements limits
|
||||
#define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering)
|
||||
#define RL_DEFAULT_BATCH_DRAWCALLS 256 // Default number of batch draw calls (by state changes: mode, texture)
|
||||
#define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS 4 // Maximum number of textures units that can be activated on batch drawing (set_shader_value_texture())
|
||||
|
||||
#define RL_MAX_MATRIX_STACK_SIZE 32 // Maximum size of internal Matrix stack
|
||||
|
||||
#define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported
|
||||
|
||||
#define RL_CULL_DISTANCE_NEAR 0.01 // Default projection matrix near cull distance
|
||||
#define RL_CULL_DISTANCE_FAR 1000.0 // Default projection matrix far cull distance
|
||||
|
||||
// Default shader vertex attribute names to set location points
|
||||
// NOTE: When a new shader is loaded, the following locations are tried to be set for convenience
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: 0
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: 1
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: 2
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: 3
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: 4
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: 5
|
||||
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView))
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color)
|
||||
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0)
|
||||
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1)
|
||||
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2)
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module: rshapes - Configuration Flags
|
||||
//------------------------------------------------------------------------------------
|
||||
// Use QUADS instead of TRIANGLES for drawing when possible
|
||||
// Some lines-based shapes could still use lines
|
||||
#define RL_SUPPORT_QUADS_DRAW_MODE 1
|
||||
|
||||
// rshapes: Configuration values
|
||||
//------------------------------------------------------------------------------------
|
||||
#define SPLINE_SEGMENT_DIVISIONS 24 // Spline segments subdivisions
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module: rtextures - Configuration Flags
|
||||
//------------------------------------------------------------------------------------
|
||||
// Selecte desired fileformats to be supported for image data loading
|
||||
#define RL_SUPPORT_FILEFORMAT_PNG 1
|
||||
//#define RL_SUPPORT_FILEFORMAT_BMP 1
|
||||
//#define RL_SUPPORT_FILEFORMAT_TGA 1
|
||||
//#define RL_SUPPORT_FILEFORMAT_JPG 1
|
||||
#define RL_SUPPORT_FILEFORMAT_GIF 1
|
||||
#define RL_SUPPORT_FILEFORMAT_QOI 1
|
||||
//#define RL_SUPPORT_FILEFORMAT_PSD 1
|
||||
#define RL_SUPPORT_FILEFORMAT_DDS 1
|
||||
//#define RL_SUPPORT_FILEFORMAT_HDR 1
|
||||
//#define RL_SUPPORT_FILEFORMAT_PIC 1
|
||||
//#define RL_SUPPORT_FILEFORMAT_KTX 1
|
||||
//#define RL_SUPPORT_FILEFORMAT_ASTC 1
|
||||
//#define RL_SUPPORT_FILEFORMAT_PKM 1
|
||||
//#define RL_SUPPORT_FILEFORMAT_PVR 1
|
||||
//#define RL_SUPPORT_FILEFORMAT_SVG 1
|
||||
|
||||
// Support image export functionality (.png, .bmp, .tga, .jpg, .qoi)
|
||||
#define RL_SUPPORT_IMAGE_EXPORT 1
|
||||
// Support procedural image generation functionality (gradient, spot, perlin-noise, cellular)
|
||||
#define RL_SUPPORT_IMAGE_GENERATION 1
|
||||
// Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop...
|
||||
// If not defined, still some functions are supported: image_format(), image_crop(), image_to_pot()
|
||||
#define RL_SUPPORT_IMAGE_MANIPULATION 1
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module: rtext - Configuration Flags
|
||||
//------------------------------------------------------------------------------------
|
||||
// Default font is loaded on window initialization to be available for the user to render simple text
|
||||
// NOTE: If enabled, uses external module functions to load default raylib font
|
||||
#define RL_SUPPORT_DEFAULT_FONT 1
|
||||
// Selected desired font fileformats to be supported for loading
|
||||
#define RL_SUPPORT_FILEFORMAT_FNT 1
|
||||
#define RL_SUPPORT_FILEFORMAT_TTF 1
|
||||
|
||||
// Support text management functions
|
||||
// If not defined, still some functions are supported: text_length(), TextFormat()
|
||||
#define RL_SUPPORT_TEXT_MANIPULATION 1
|
||||
|
||||
// On font atlas image generation [gen_image_font_atlas()], add a 3x3 pixels white rectangle
|
||||
// at the bottom-right corner of the atlas. It can be useful to for shapes drawing, to allow
|
||||
// drawing text and shapes with a single draw call [set_shapes_texture()].
|
||||
#define RL_SUPPORT_FONT_ATLAS_WHITE_REC 1
|
||||
|
||||
// rtext: Configuration values
|
||||
//------------------------------------------------------------------------------------
|
||||
#define RL_MAX_TEXT_BUFFER_LENGTH 1024 // Size of internal static buffers used on some functions:
|
||||
// TextFormat(), TextSubtext(), TextToUpper(), TextToLower(), TextToPascal(), TextSplit()
|
||||
#define RL_MAX_TEXTSPLIT_COUNT 128 // Maximum number of substrings to split: TextSplit()
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module: rmodels - Configuration Flags
|
||||
//------------------------------------------------------------------------------------
|
||||
// Selected desired model fileformats to be supported for loading
|
||||
#define RL_SUPPORT_FILEFORMAT_OBJ 1
|
||||
#define RL_SUPPORT_FILEFORMAT_MTL 1
|
||||
#define RL_SUPPORT_FILEFORMAT_IQM 1
|
||||
#define RL_SUPPORT_FILEFORMAT_GLTF 1
|
||||
#define RL_SUPPORT_FILEFORMAT_VOX 1
|
||||
#define RL_SUPPORT_FILEFORMAT_M3D 1
|
||||
// Support procedural mesh generation functions, uses external par_shapes.h library
|
||||
// NOTE: Some generated meshes DO NOT include generated texture coordinates
|
||||
#define RL_SUPPORT_MESH_GENERATION 1
|
||||
|
||||
// rmodels: Configuration values
|
||||
//------------------------------------------------------------------------------------
|
||||
#define RL_MAX_MATERIAL_MAPS 12 // Maximum number of shader maps supported
|
||||
#define RL_MAX_MESH_VERTEX_BUFFERS 7 // Maximum vertex buffers (VBO) per mesh
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module: raudio - Configuration Flags
|
||||
//------------------------------------------------------------------------------------
|
||||
// Desired audio fileformats to be supported for loading
|
||||
#define RL_SUPPORT_FILEFORMAT_WAV 1
|
||||
#define RL_SUPPORT_FILEFORMAT_OGG 1
|
||||
#define RL_SUPPORT_FILEFORMAT_MP3 1
|
||||
#define RL_SUPPORT_FILEFORMAT_QOA 1
|
||||
//#define RL_SUPPORT_FILEFORMAT_FLAC 1
|
||||
#define RL_SUPPORT_FILEFORMAT_XM 1
|
||||
#define RL_SUPPORT_FILEFORMAT_MOD 1
|
||||
|
||||
// raudio: Configuration values
|
||||
//------------------------------------------------------------------------------------
|
||||
#define RL_AUDIO_DEVICE_FORMAT ma_format_f32 // Device output format (miniaudio: float-32bit)
|
||||
#define RL_AUDIO_DEVICE_CHANNELS 2 // Device output channels: stereo
|
||||
#define RL_AUDIO_DEVICE_SAMPLE_RATE 0 // Device sample rate (device default)
|
||||
|
||||
#define RL_MAX_AUDIO_BUFFER_POOL_CHANNELS 16 // Maximum number of audio pool channels
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module: utils - Configuration Flags
|
||||
//------------------------------------------------------------------------------------
|
||||
// Standard file io library (stdio.h) included
|
||||
#define RL_SUPPORT_STANDARD_FILEIO 1
|
||||
// Show RL_TRACELOG() output messages
|
||||
// NOTE: By default LOG_DEBUG traces not shown
|
||||
#define RL_SUPPORT_TRACELOG 1
|
||||
//#define RL_SUPPORT_TRACELOG_DEBUG 1
|
||||
|
||||
// utils: Configuration values
|
||||
//------------------------------------------------------------------------------------
|
||||
#define RL_MAX_TRACELOG_MSG_LENGTH 256 // Max length of one trace-log message
|
||||
|
||||
#endif // CONFIG_H
|
||||
|
||||
// Indicates of raylib has been refactored
|
||||
#ifndef RL_REFACTORED_CPP
|
||||
#define RL_REFACTORED_CPP
|
||||
#endif
|
||||
|
||||
#define RL_USE_CPP_NAMESPACE 1
|
||||
#define RL_USE_CPP_MANGLING 1
|
||||
|
||||
#if RL_USE_CPP_NAMESPACE && defined(__cplusplus)
|
||||
#pragma message("USING CPP NAMESPACE")
|
||||
#define RL_NS_BEGIN namespace rl {
|
||||
#define RL_NS_END }
|
||||
#else
|
||||
#define RL_NS_BEGIN
|
||||
#define RL_NS_END
|
||||
#endif
|
||||
|
||||
#if RL_USE_CPP_MANGLING && defined(__cplusplus)
|
||||
#pragma message("USING CPP MANGLING")
|
||||
#define RL_EXTERN_C_BEGIN
|
||||
#define RL_EXTERN_C_END
|
||||
#else
|
||||
#ifdef __cplusplus
|
||||
#define RL_EXTERN_C_BEGIN extern "C" {
|
||||
#define RL_EXTERN_C_END }
|
||||
#else
|
||||
#define RL_EXTERN_C_BEGIN
|
||||
#define RL_EXTERN_C_END
|
||||
#endif
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,562 +0,0 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* rcamera - Basic camera system with support for multiple camera modes
|
||||
*
|
||||
* CONFIGURATION:
|
||||
* #define RCAMERA_IMPLEMENTATION
|
||||
* Generates the implementation of the library into the included file.
|
||||
* If not defined, the library is in header only mode and can be included in other headers
|
||||
* or source files without problems. But only ONE file should hold the implementation.
|
||||
*
|
||||
* #define RCAMERA_STANDALONE
|
||||
* If defined, the library can be used as standalone as a camera system but some
|
||||
* functions must be redefined to manage inputs accordingly.
|
||||
*
|
||||
* CONTRIBUTORS:
|
||||
* Ramon Santamaria: Supervision, review, update and maintenance
|
||||
* Christoph Wagner: Complete redesign, using raymath (2022)
|
||||
* Marc Palau: Initial implementation (2014)
|
||||
*
|
||||
*
|
||||
* LICENSE: zlib/libpng
|
||||
*
|
||||
* Copyright (c) 2022-2023 Christoph Wagner (@Crydsch) & Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose, including commercial
|
||||
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim that you
|
||||
* wrote the original software. If you use this software in a product, an acknowledgment
|
||||
* in the product documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
||||
* as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#ifndef RCAMERA_H
|
||||
#define RCAMERA_H
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
// Function specifiers definition
|
||||
|
||||
// Function specifiers in case library is build/used as a shared library (Windows)
|
||||
// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
|
||||
#if defined(_WIN32)
|
||||
#if defined(RL_BUILD_LIBTYPE_SHARED)
|
||||
#if defined(__TINYC__)
|
||||
#define __declspec(x) __attribute__((x))
|
||||
#endif
|
||||
#define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll)
|
||||
#elif defined(RL_USE_LIBTYPE_SHARED)
|
||||
#define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef RLAPI
|
||||
#define RLAPI // Functions defined as 'extern' by default (implicit specifiers)
|
||||
#endif
|
||||
|
||||
#if defined(RCAMERA_STANDALONE)
|
||||
#define RL_CAMERA_CULL_DISTANCE_NEAR 0.01
|
||||
#define RL_CAMERA_CULL_DISTANCE_FAR 1000.0
|
||||
#else
|
||||
#define RL_CAMERA_CULL_DISTANCE_NEAR RL_CULL_DISTANCE_NEAR
|
||||
#define RL_CAMERA_CULL_DISTANCE_FAR RL_CULL_DISTANCE_FAR
|
||||
#endif
|
||||
|
||||
RL_NS_BEGIN
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
// NOTE: Below types are required for standalone usage
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(RCAMERA_STANDALONE)
|
||||
// Vector2, 2 components
|
||||
typedef struct Vector2 {
|
||||
float x; // Vector x component
|
||||
float y; // Vector y component
|
||||
} Vector2;
|
||||
|
||||
// Vector3, 3 components
|
||||
typedef struct Vector3 {
|
||||
float x; // Vector x component
|
||||
float y; // Vector y component
|
||||
float z; // Vector z component
|
||||
} Vector3;
|
||||
|
||||
// Matrix, 4x4 components, column major, OpenGL style, right-handed
|
||||
typedef struct Matrix {
|
||||
float m0, m4, m8, m12; // Matrix first row (4 components)
|
||||
float m1, m5, m9, m13; // Matrix second row (4 components)
|
||||
float m2, m6, m10, m14; // Matrix third row (4 components)
|
||||
float m3, m7, m11, m15; // Matrix fourth row (4 components)
|
||||
} Matrix;
|
||||
|
||||
// Camera type, defines a camera position/orientation in 3d space
|
||||
typedef struct Camera3D {
|
||||
Vector3 position; // Camera position
|
||||
Vector3 target; // Camera target it looks-at
|
||||
Vector3 up; // Camera up vector (rotation over its axis)
|
||||
float fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic
|
||||
int projection; // Camera projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC
|
||||
} Camera3D;
|
||||
|
||||
typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D
|
||||
|
||||
// Camera projection
|
||||
typedef enum {
|
||||
CAMERA_PERSPECTIVE = 0, // Perspective projection
|
||||
CAMERA_ORTHOGRAPHIC // Orthographic projection
|
||||
} CameraProjection;
|
||||
|
||||
// Camera system modes
|
||||
typedef enum {
|
||||
CAMERA_CUSTOM = 0, // Camera custom, controlled by user (update_camera() does nothing)
|
||||
CAMERA_FREE, // Camera free mode
|
||||
CAMERA_ORBITAL, // Camera orbital, around target, zoom supported
|
||||
CAMERA_FIRST_PERSON, // Camera first person
|
||||
CAMERA_THIRD_PERSON // Camera third person
|
||||
} CameraMode;
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
//...
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
RL_EXTERN_C_BEGIN
|
||||
|
||||
RLAPI Vector3 get_camera_forward(Camera *camera);
|
||||
RLAPI Vector3 get_camera_up(Camera *camera);
|
||||
RLAPI Vector3 get_camera_right(Camera *camera);
|
||||
|
||||
// Camera movement
|
||||
RLAPI void camera_move_forward(Camera *camera, float distance, bool moveInWorldPlane);
|
||||
RLAPI void camera_move_up(Camera *camera, float distance);
|
||||
RLAPI void camera_move_right(Camera *camera, float distance, bool moveInWorldPlane);
|
||||
RLAPI void camera_move_to_target(Camera *camera, float delta);
|
||||
|
||||
// Camera rotation
|
||||
RLAPI void camera_yaw(Camera *camera, float angle, bool rotateAroundTarget);
|
||||
RLAPI void camera_pitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp);
|
||||
RLAPI void camera_roll(Camera *camera, float angle);
|
||||
|
||||
RLAPI Matrix get_camera_view_matrix(Camera *camera);
|
||||
RLAPI Matrix get_camera_projection_matrix(Camera* camera, float aspect);
|
||||
|
||||
RL_EXTERN_C_END
|
||||
|
||||
RL_NS_END
|
||||
|
||||
#endif // RCAMERA_H
|
||||
|
||||
|
||||
/***********************************************************************************
|
||||
*
|
||||
* CAMERA IMPLEMENTATION
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(RCAMERA_IMPLEMENTATION)
|
||||
|
||||
#include "raymath.h" // Required for vector maths:
|
||||
// vector3_add()
|
||||
// vector3_subtract()
|
||||
// vector3_scale()
|
||||
// vector3_normalize()
|
||||
// vector3_distance()
|
||||
// vector3_cross_product()
|
||||
// vector3_rotate_by_axis_angle()
|
||||
// vector3_angle()
|
||||
// vector3_negate()
|
||||
// matrix_look_at()
|
||||
// matrix_perspective()
|
||||
// matrix_ortho()
|
||||
// matrix_identity()
|
||||
|
||||
// raylib required functionality:
|
||||
// get_mouse_delta()
|
||||
// get_mouse_wheel_move()
|
||||
// is_key_down()
|
||||
// is_key_pressed()
|
||||
// get_frame_time()
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
#define CAMERA_MOVE_SPEED 0.09f
|
||||
#define CAMERA_ROTATION_SPEED 0.03f
|
||||
#define CAMERA_PAN_SPEED 0.2f
|
||||
|
||||
// Camera mouse movement sensitivity
|
||||
#define CAMERA_MOUSE_MOVE_SENSITIVITY 0.003f // TODO: it should be independant of framerate
|
||||
#define CAMERA_MOUSE_SCROLL_SENSITIVITY 1.5f
|
||||
|
||||
#define CAMERA_ORBITAL_SPEED 0.5f // Radians per second
|
||||
|
||||
|
||||
#define CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER 8.0f
|
||||
#define CAMERA_FIRST_PERSON_STEP_DIVIDER 30.0f
|
||||
#define CAMERA_FIRST_PERSON_WAVING_DIVIDER 200.0f
|
||||
|
||||
// PLAYER (used by camera)
|
||||
#define PLAYER_MOVEMENT_SENSITIVITY 20.0f
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
//...
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
//...
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
//...
|
||||
|
||||
RL_NS_BEGIN
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
// Returns the cameras forward vector (normalized)
|
||||
Vector3 get_camera_forward(Camera *camera)
|
||||
{
|
||||
return vector3_normalize(vector3_subtract(camera->target, camera->position));
|
||||
}
|
||||
|
||||
// Returns the cameras up vector (normalized)
|
||||
// Note: The up vector might not be perpendicular to the forward vector
|
||||
Vector3 get_camera_up(Camera *camera)
|
||||
{
|
||||
return vector3_normalize(camera->up);
|
||||
}
|
||||
|
||||
// Returns the cameras right vector (normalized)
|
||||
Vector3 get_camera_right(Camera *camera)
|
||||
{
|
||||
Vector3 forward = get_camera_forward(camera);
|
||||
Vector3 up = get_camera_up(camera);
|
||||
|
||||
return vector3_cross_product(forward, up);
|
||||
}
|
||||
|
||||
// Moves the camera in its forward direction
|
||||
void camera_move_forward(Camera *camera, float distance, bool moveInWorldPlane)
|
||||
{
|
||||
Vector3 forward = get_camera_forward(camera);
|
||||
|
||||
if (moveInWorldPlane)
|
||||
{
|
||||
// Project vector onto world plane
|
||||
forward.y = 0;
|
||||
forward = vector3_normalize(forward);
|
||||
}
|
||||
|
||||
// Scale by distance
|
||||
forward = vector3_scale(forward, distance);
|
||||
|
||||
// Move position and target
|
||||
camera->position = vector3_add(camera->position, forward);
|
||||
camera->target = vector3_add(camera->target, forward);
|
||||
}
|
||||
|
||||
// Moves the camera in its up direction
|
||||
void camera_move_up(Camera *camera, float distance)
|
||||
{
|
||||
Vector3 up = get_camera_up(camera);
|
||||
|
||||
// Scale by distance
|
||||
up = vector3_scale(up, distance);
|
||||
|
||||
// Move position and target
|
||||
camera->position = vector3_add(camera->position, up);
|
||||
camera->target = vector3_add(camera->target, up);
|
||||
}
|
||||
|
||||
// Moves the camera target in its current right direction
|
||||
void camera_move_right(Camera *camera, float distance, bool moveInWorldPlane)
|
||||
{
|
||||
Vector3 right = get_camera_right(camera);
|
||||
|
||||
if (moveInWorldPlane)
|
||||
{
|
||||
// Project vector onto world plane
|
||||
right.y = 0;
|
||||
right = vector3_normalize(right);
|
||||
}
|
||||
|
||||
// Scale by distance
|
||||
right = vector3_scale(right, distance);
|
||||
|
||||
// Move position and target
|
||||
camera->position = vector3_add(camera->position, right);
|
||||
camera->target = vector3_add(camera->target, right);
|
||||
}
|
||||
|
||||
// Moves the camera position closer/farther to/from the camera target
|
||||
void camera_move_to_target(Camera *camera, float delta)
|
||||
{
|
||||
float distance = vector3_distance(camera->position, camera->target);
|
||||
|
||||
// Apply delta
|
||||
distance += delta;
|
||||
|
||||
// Distance must be greater than 0
|
||||
if (distance <= 0) distance = 0.001f;
|
||||
|
||||
// Set new distance by moving the position along the forward vector
|
||||
Vector3 forward = get_camera_forward(camera);
|
||||
camera->position = vector3_add(camera->target, vector3_scale(forward, -distance));
|
||||
}
|
||||
|
||||
// Rotates the camera around its up vector
|
||||
// Yaw is "looking left and right"
|
||||
// If rotateAroundTarget is false, the camera rotates around its position
|
||||
// Note: angle must be provided in radians
|
||||
void camera_yaw(Camera *camera, float angle, bool rotateAroundTarget)
|
||||
{
|
||||
// Rotation axis
|
||||
Vector3 up = get_camera_up(camera);
|
||||
|
||||
// View vector
|
||||
Vector3 targetPosition = vector3_subtract(camera->target, camera->position);
|
||||
|
||||
// Rotate view vector around up axis
|
||||
targetPosition = vector3_rotate_by_axis_angle(targetPosition, up, angle);
|
||||
|
||||
if (rotateAroundTarget)
|
||||
{
|
||||
// Move position relative to target
|
||||
camera->position = vector3_subtract(camera->target, targetPosition);
|
||||
}
|
||||
else // rotate around camera.position
|
||||
{
|
||||
// Move target relative to position
|
||||
camera->target = vector3_add(camera->position, targetPosition);
|
||||
}
|
||||
}
|
||||
|
||||
// Rotates the camera around its right vector, pitch is "looking up and down"
|
||||
// - lockView prevents camera overrotation (aka "somersaults")
|
||||
// - rotateAroundTarget defines if rotation is around target or around its position
|
||||
// - rotateUp rotates the up direction as well (typically only usefull in CAMERA_FREE)
|
||||
// NOTE: angle must be provided in radians
|
||||
void camera_pitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp)
|
||||
{
|
||||
// Up direction
|
||||
Vector3 up = get_camera_up(camera);
|
||||
|
||||
// View vector
|
||||
Vector3 targetPosition = vector3_subtract(camera->target, camera->position);
|
||||
|
||||
if (lockView)
|
||||
{
|
||||
// In these camera modes we clamp the Pitch angle
|
||||
// to allow only viewing straight up or down.
|
||||
|
||||
// clamp view up
|
||||
float maxAngleUp = vector3_angle(up, targetPosition);
|
||||
maxAngleUp -= 0.001f; // avoid numerical errors
|
||||
if (angle > maxAngleUp) angle = maxAngleUp;
|
||||
|
||||
// clamp view down
|
||||
float maxAngleDown = vector3_angle(vector3_negate(up), targetPosition);
|
||||
maxAngleDown *= -1.0f; // downwards angle is negative
|
||||
maxAngleDown += 0.001f; // avoid numerical errors
|
||||
if (angle < maxAngleDown) angle = maxAngleDown;
|
||||
}
|
||||
|
||||
// Rotation axis
|
||||
Vector3 right = get_camera_right(camera);
|
||||
|
||||
// Rotate view vector around right axis
|
||||
targetPosition = vector3_rotate_by_axis_angle(targetPosition, right, angle);
|
||||
|
||||
if (rotateAroundTarget)
|
||||
{
|
||||
// Move position relative to target
|
||||
camera->position = vector3_subtract(camera->target, targetPosition);
|
||||
}
|
||||
else // rotate around camera.position
|
||||
{
|
||||
// Move target relative to position
|
||||
camera->target = vector3_add(camera->position, targetPosition);
|
||||
}
|
||||
|
||||
if (rotateUp)
|
||||
{
|
||||
// Rotate up direction around right axis
|
||||
camera->up = vector3_rotate_by_axis_angle(camera->up, right, angle);
|
||||
}
|
||||
}
|
||||
|
||||
// Rotates the camera around its forward vector
|
||||
// Roll is "turning your head sideways to the left or right"
|
||||
// Note: angle must be provided in radians
|
||||
void camera_roll(Camera *camera, float angle)
|
||||
{
|
||||
// Rotation axis
|
||||
Vector3 forward = get_camera_forward(camera);
|
||||
|
||||
// Rotate up direction around forward axis
|
||||
camera->up = vector3_rotate_by_axis_angle(camera->up, forward, angle);
|
||||
}
|
||||
|
||||
// Returns the camera view matrix
|
||||
Matrix get_camera_view_matrix(Camera *camera)
|
||||
{
|
||||
return matrix_look_at(camera->position, camera->target, camera->up);
|
||||
}
|
||||
|
||||
// Returns the camera projection matrix
|
||||
Matrix get_camera_projection_matrix(Camera *camera, float aspect)
|
||||
{
|
||||
if (camera->projection == CAMERA_PERSPECTIVE)
|
||||
{
|
||||
return matrix_perspective(camera->fovy*RL_DEG2RAD, aspect, RL_CAMERA_CULL_DISTANCE_NEAR, RL_CAMERA_CULL_DISTANCE_FAR);
|
||||
}
|
||||
else if (camera->projection == CAMERA_ORTHOGRAPHIC)
|
||||
{
|
||||
double top = camera->fovy/2.0;
|
||||
double right = top*aspect;
|
||||
|
||||
return matrix_ortho(-right, right, -top, top, RL_CAMERA_CULL_DISTANCE_NEAR, RL_CAMERA_CULL_DISTANCE_FAR);
|
||||
}
|
||||
|
||||
return matrix_identity();
|
||||
}
|
||||
|
||||
#if !defined(RCAMERA_STANDALONE)
|
||||
// Update camera position for selected mode
|
||||
// Camera mode: CAMERA_FREE, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON, CAMERA_ORBITAL or CUSTOM
|
||||
void update_camera(Camera *camera, int mode)
|
||||
{
|
||||
Vector2 mousePositionDelta = get_mouse_delta();
|
||||
|
||||
bool moveInWorldPlane = ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON));
|
||||
bool rotateAroundTarget = ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL));
|
||||
bool lockView = ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL));
|
||||
bool rotateUp = false;
|
||||
|
||||
if (mode == CAMERA_ORBITAL)
|
||||
{
|
||||
// Orbital can just orbit
|
||||
Matrix rotation = matrix_rotate(get_camera_up(camera), CAMERA_ORBITAL_SPEED*get_frame_time());
|
||||
Vector3 view = vector3_subtract(camera->position, camera->target);
|
||||
view = vector3_transform(view, rotation);
|
||||
camera->position = vector3_add(camera->target, view);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Camera rotation
|
||||
if (is_key_down(KEY_DOWN)) camera_pitch(camera, -CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp);
|
||||
if (is_key_down(KEY_UP)) camera_pitch(camera, CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp);
|
||||
if (is_key_down(KEY_RIGHT)) camera_yaw(camera, -CAMERA_ROTATION_SPEED, rotateAroundTarget);
|
||||
if (is_key_down(KEY_LEFT)) camera_yaw(camera, CAMERA_ROTATION_SPEED, rotateAroundTarget);
|
||||
if (is_key_down(KEY_Q)) camera_roll(camera, -CAMERA_ROTATION_SPEED);
|
||||
if (is_key_down(KEY_E)) camera_roll(camera, CAMERA_ROTATION_SPEED);
|
||||
|
||||
// Camera movement
|
||||
if (!is_gamepad_available(0))
|
||||
{
|
||||
// Camera pan (for CAMERA_FREE)
|
||||
if ((mode == CAMERA_FREE) && (is_mouse_button_down(MOUSE_BUTTON_MIDDLE)))
|
||||
{
|
||||
const Vector2 mouseDelta = get_mouse_delta();
|
||||
if (mouseDelta.x > 0.0f) camera_move_right(camera, CAMERA_PAN_SPEED, moveInWorldPlane);
|
||||
if (mouseDelta.x < 0.0f) camera_move_right(camera, -CAMERA_PAN_SPEED, moveInWorldPlane);
|
||||
if (mouseDelta.y > 0.0f) camera_move_up(camera, -CAMERA_PAN_SPEED);
|
||||
if (mouseDelta.y < 0.0f) camera_move_up(camera, CAMERA_PAN_SPEED);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Mouse support
|
||||
camera_yaw(camera, -mousePositionDelta.x*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget);
|
||||
camera_pitch(camera, -mousePositionDelta.y*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp);
|
||||
}
|
||||
|
||||
// Keyboard support
|
||||
if (is_key_down(KEY_W)) camera_move_forward(camera, CAMERA_MOVE_SPEED, moveInWorldPlane);
|
||||
if (is_key_down(KEY_A)) camera_move_right(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane);
|
||||
if (is_key_down(KEY_S)) camera_move_forward(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane);
|
||||
if (is_key_down(KEY_D)) camera_move_right(camera, CAMERA_MOVE_SPEED, moveInWorldPlane);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Gamepad controller support
|
||||
camera_yaw(camera, -(get_gamepad_axis_movement(0, GAMEPAD_AXIS_RIGHT_X) * 2)*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget);
|
||||
camera_pitch(camera, -(get_gamepad_axis_movement(0, GAMEPAD_AXIS_RIGHT_Y) * 2)*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp);
|
||||
|
||||
if (get_gamepad_axis_movement(0, GAMEPAD_AXIS_LEFT_Y) <= -0.25f) camera_move_forward(camera, CAMERA_MOVE_SPEED, moveInWorldPlane);
|
||||
if (get_gamepad_axis_movement(0, GAMEPAD_AXIS_LEFT_X) <= -0.25f) camera_move_right(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane);
|
||||
if (get_gamepad_axis_movement(0, GAMEPAD_AXIS_LEFT_Y) >= 0.25f) camera_move_forward(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane);
|
||||
if (get_gamepad_axis_movement(0, GAMEPAD_AXIS_LEFT_X) >= 0.25f) camera_move_right(camera, CAMERA_MOVE_SPEED, moveInWorldPlane);
|
||||
}
|
||||
|
||||
if (mode == CAMERA_FREE)
|
||||
{
|
||||
if (is_key_down(KEY_SPACE)) camera_move_up(camera, CAMERA_MOVE_SPEED);
|
||||
if (is_key_down(KEY_LEFT_CONTROL)) camera_move_up(camera, -CAMERA_MOVE_SPEED);
|
||||
}
|
||||
}
|
||||
|
||||
if ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL) || (mode == CAMERA_FREE))
|
||||
{
|
||||
// Zoom target distance
|
||||
camera_move_to_target(camera, -get_mouse_wheel_move());
|
||||
if (is_key_pressed(KEY_KP_SUBTRACT)) camera_move_to_target(camera, 2.0f);
|
||||
if (is_key_pressed(KEY_KP_ADD)) camera_move_to_target(camera, -2.0f);
|
||||
}
|
||||
}
|
||||
#endif // !RCAMERA_STANDALONE
|
||||
|
||||
// Update camera movement, movement/rotation values should be provided by user
|
||||
void update_camera_pro(Camera *camera, Vector3 movement, Vector3 rotation, float zoom)
|
||||
{
|
||||
// Required values
|
||||
// movement.x - Move forward/backward
|
||||
// movement.y - Move right/left
|
||||
// movement.z - Move up/down
|
||||
// rotation.x - yaw
|
||||
// rotation.y - pitch
|
||||
// rotation.z - roll
|
||||
// zoom - Move towards target
|
||||
|
||||
bool lockView = true;
|
||||
bool rotateAroundTarget = false;
|
||||
bool rotateUp = false;
|
||||
bool moveInWorldPlane = true;
|
||||
|
||||
// Camera rotation
|
||||
camera_pitch(camera, -rotation.y*RL_DEG2RAD, lockView, rotateAroundTarget, rotateUp);
|
||||
camera_yaw(camera, -rotation.x*RL_DEG2RAD, rotateAroundTarget);
|
||||
camera_roll(camera, rotation.z*RL_DEG2RAD);
|
||||
|
||||
// Camera movement
|
||||
camera_move_forward(camera, movement.x, moveInWorldPlane);
|
||||
camera_move_right(camera, movement.y, moveInWorldPlane);
|
||||
camera_move_up(camera, movement.z);
|
||||
|
||||
// Zoom target distance
|
||||
camera_move_to_target(camera, zoom);
|
||||
}
|
||||
|
||||
RL_NS_END
|
||||
|
||||
#endif // RCAMERA_IMPLEMENTATION
|
@ -1,579 +0,0 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* rgestures - Gestures system, gestures processing based on input events (touch/mouse)
|
||||
*
|
||||
* CONFIGURATION:
|
||||
* #define RGESTURES_IMPLEMENTATION
|
||||
* Generates the implementation of the library into the included file.
|
||||
* If not defined, the library is in header only mode and can be included in other headers
|
||||
* or source files without problems. But only ONE file should hold the implementation.
|
||||
*
|
||||
* #define RGESTURES_STANDALONE
|
||||
* If defined, the library can be used as standalone to process gesture events with
|
||||
* no external dependencies.
|
||||
*
|
||||
* CONTRIBUTORS:
|
||||
* Marc Palau: Initial implementation (2014)
|
||||
* Albert Martos: Complete redesign and testing (2015)
|
||||
* Ian Eito: Complete redesign and testing (2015)
|
||||
* Ramon Santamaria: Supervision, review, update and maintenance
|
||||
*
|
||||
*
|
||||
* LICENSE: zlib/libpng
|
||||
*
|
||||
* Copyright (c) 2014-2023 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose, including commercial
|
||||
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim that you
|
||||
* wrote the original software. If you use this software in a product, an acknowledgment
|
||||
* in the product documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
||||
* as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#ifndef RGESTURES_H
|
||||
#define RGESTURES_H
|
||||
|
||||
#ifndef RL_PI
|
||||
#define RL_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
#ifndef RL_MAX_TOUCH_POINTS
|
||||
#define RL_MAX_TOUCH_POINTS 8 // Maximum number of touch points supported
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
// NOTE: Below types are required for standalone usage
|
||||
//----------------------------------------------------------------------------------
|
||||
// Boolean type
|
||||
#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
|
||||
#include <stdbool.h>
|
||||
#elif !defined(__cplusplus) && !defined(bool) && !defined(RL_BOOL_TYPE)
|
||||
typedef enum bool { false = 0, true = !false } bool;
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
|
||||
RL_NS_BEGIN
|
||||
|
||||
#if !defined(RL_VECTOR2_TYPE)
|
||||
// Vector2 type
|
||||
typedef struct Vector2 {
|
||||
float x;
|
||||
float y;
|
||||
} Vector2;
|
||||
#endif
|
||||
|
||||
#if defined(RGESTURES_STANDALONE)
|
||||
// Gestures type
|
||||
// NOTE: It could be used as flags to enable only some gestures
|
||||
typedef enum {
|
||||
GESTURE_NONE = 0,
|
||||
GESTURE_TAP = 1,
|
||||
GESTURE_DOUBLETAP = 2,
|
||||
GESTURE_HOLD = 4,
|
||||
GESTURE_DRAG = 8,
|
||||
GESTURE_SWIPE_RIGHT = 16,
|
||||
GESTURE_SWIPE_LEFT = 32,
|
||||
GESTURE_SWIPE_UP = 64,
|
||||
GESTURE_SWIPE_DOWN = 128,
|
||||
GESTURE_PINCH_IN = 256,
|
||||
GESTURE_PINCH_OUT = 512
|
||||
} Gesture;
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
TOUCH_ACTION_UP = 0,
|
||||
TOUCH_ACTION_DOWN,
|
||||
TOUCH_ACTION_MOVE,
|
||||
TOUCH_ACTION_CANCEL
|
||||
} TouchAction;
|
||||
|
||||
// Gesture event
|
||||
typedef struct {
|
||||
int touchAction;
|
||||
int pointCount;
|
||||
int pointId[RL_MAX_TOUCH_POINTS];
|
||||
Vector2 position[RL_MAX_TOUCH_POINTS];
|
||||
} GestureEvent;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
//...
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
RL_EXTERN_C_BEGIN
|
||||
|
||||
void process_gesture_event(GestureEvent event); // Process gesture event and translate it into gestures
|
||||
void update_gestures(void); // Update gestures detected (must be called every frame)
|
||||
|
||||
#if defined(RGESTURES_STANDALONE)
|
||||
void set_gestures_enabled(unsigned int flags); // Enable a set of gestures using flags
|
||||
bool is_gesture_detected(int gesture); // Check if a gesture have been detected
|
||||
int get_gesture_detected(void); // Get latest detected gesture
|
||||
|
||||
float get_gesture_hold_duration(void); // Get gesture hold time in seconds
|
||||
Vector2 get_gesture_drag_vector(void); // Get gesture drag vector
|
||||
float get_gesture_drag_angle(void); // Get gesture drag angle
|
||||
Vector2 get_gesture_pinch_vector(void); // Get gesture pinch delta
|
||||
float get_gesture_pinch_angle(void); // Get gesture pinch angle
|
||||
#endif
|
||||
|
||||
RL_EXTERN_C_END
|
||||
|
||||
RL_NS_END
|
||||
|
||||
#endif // RGESTURES_H
|
||||
|
||||
/***********************************************************************************
|
||||
*
|
||||
* RGESTURES IMPLEMENTATION
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(RGESTURES_IMPLEMENTATION)
|
||||
|
||||
#if defined(RGESTURES_STANDALONE)
|
||||
#if defined(_WIN32)
|
||||
#if defined(__cplusplus)
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
// Functions required to query time on Windows
|
||||
int __stdcall query_performance_counter(unsigned long long int *lpPerformanceCount);
|
||||
int __stdcall query_performance_frequency(unsigned long long int *lpFrequency);
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#elif defined(__linux__)
|
||||
#if _POSIX_C_SOURCE < 199309L
|
||||
#undef _POSIX_C_SOURCE
|
||||
#define _POSIX_C_SOURCE 199309L // Required for CLOCK_MONOTONIC if compiled with c99 without gnu ext.
|
||||
#endif
|
||||
#include <sys/time.h> // Required for: timespec
|
||||
#include <time.h> // Required for: clock_gettime()
|
||||
|
||||
#include <math.h> // Required for: sqrtf(), atan2f()
|
||||
#endif
|
||||
#if defined(__APPLE__) // macOS also defines __MACH__
|
||||
#include <mach/clock.h> // Required for: clock_get_time()
|
||||
#include <mach/mach.h> // Required for: mach_timespec_t
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
#define RL_FORCE_TO_SWIPE 0.2f // Swipe force, measured in normalized screen units/time
|
||||
#define RL_MINIMUM_DRAG 0.015f // Drag minimum force, measured in normalized screen units (0.0f to 1.0f)
|
||||
#define RL_DRAG_TIMEOUT 0.3f // Drag minimum time for web, measured in seconds
|
||||
#define RL_MINIMUM_PINCH 0.005f // Pinch minimum force, measured in normalized screen units (0.0f to 1.0f)
|
||||
#define RL_TAP_TIMEOUT 0.3f // Tap minimum time, measured in seconds
|
||||
#define RL_PINCH_TIMEOUT 0.3f // Pinch minimum time, measured in seconds
|
||||
#define RL_DOUBLETAP_RANGE 0.03f // DoubleTap range, measured in normalized screen units (0.0f to 1.0f)
|
||||
|
||||
RL_NS_BEGIN
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Gestures module state context [136 bytes]
|
||||
typedef struct {
|
||||
unsigned int current; // Current detected gesture
|
||||
unsigned int enabledFlags; // Enabled gestures flags
|
||||
struct {
|
||||
int firstId; // Touch id for first touch point
|
||||
int pointCount; // Touch points counter
|
||||
double eventTime; // Time stamp when an event happened
|
||||
Vector2 upPosition; // Touch up position
|
||||
Vector2 downPositionA; // First touch down position
|
||||
Vector2 downPositionB; // Second touch down position
|
||||
Vector2 downDragPosition; // Touch drag position
|
||||
Vector2 moveDownPositionA; // First touch down position on move
|
||||
Vector2 moveDownPositionB; // Second touch down position on move
|
||||
Vector2 previousPositionA; // Previous position A to compare for pinch gestures
|
||||
Vector2 previousPositionB; // Previous position B to compare for pinch gestures
|
||||
int tapCounter; // TAP counter (one tap implies TOUCH_ACTION_DOWN and TOUCH_ACTION_UP actions)
|
||||
} Touch;
|
||||
struct {
|
||||
bool resetRequired; // HOLD reset to get first touch point again
|
||||
double timeDuration; // HOLD duration in seconds
|
||||
} Hold;
|
||||
struct {
|
||||
Vector2 vector; // DRAG vector (between initial and current position)
|
||||
float angle; // DRAG angle (relative to x-axis)
|
||||
float distance; // DRAG distance (from initial touch point to final) (normalized [0..1])
|
||||
float intensity; // DRAG intensity, how far why did the DRAG (pixels per frame)
|
||||
} Drag;
|
||||
struct {
|
||||
double startTime; // SWIPE start time to calculate drag intensity
|
||||
} Swipe;
|
||||
struct {
|
||||
Vector2 vector; // PINCH vector (between first and second touch points)
|
||||
float angle; // PINCH angle (relative to x-axis)
|
||||
float distance; // PINCH displacement distance (normalized [0..1])
|
||||
} Pinch;
|
||||
} GesturesData;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
static GesturesData GESTURES = {
|
||||
#ifdef __cplusplus
|
||||
(unsigned int)-1,
|
||||
GESTURE_NONE,
|
||||
0b0000001111111111
|
||||
#else
|
||||
.Touch.firstId = -1,
|
||||
.current = GESTURE_NONE, // No current gesture detected
|
||||
.enabledFlags = 0b0000001111111111 // All gestures supported by default
|
||||
#endif
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
static float rg_vector2_angle(Vector2 initialPosition, Vector2 finalPosition);
|
||||
static float rg_vector2_distance(Vector2 v1, Vector2 v2);
|
||||
static double rg_get_current_time(void);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Enable only desired gestures to be detected
|
||||
void set_gestures_enabled(unsigned int flags)
|
||||
{
|
||||
GESTURES.enabledFlags = flags;
|
||||
}
|
||||
|
||||
// Check if a gesture have been detected
|
||||
bool is_gesture_detected(unsigned int gesture)
|
||||
{
|
||||
if ((GESTURES.enabledFlags & GESTURES.current) == gesture) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
// Process gesture event and translate it into gestures
|
||||
void process_gesture_event(GestureEvent event)
|
||||
{
|
||||
// Reset required variables
|
||||
GESTURES.Touch.pointCount = event.pointCount; // Required on update_gestures()
|
||||
|
||||
if (GESTURES.Touch.pointCount == 1) // One touch point
|
||||
{
|
||||
if (event.touchAction == TOUCH_ACTION_DOWN)
|
||||
{
|
||||
GESTURES.Touch.tapCounter++; // Tap counter
|
||||
|
||||
// Detect GESTURE_DOUBLE_TAP
|
||||
if ((GESTURES.current == GESTURE_NONE) && (GESTURES.Touch.tapCounter >= 2) && ((rg_get_current_time() - GESTURES.Touch.eventTime) < RL_TAP_TIMEOUT) && (rg_vector2_distance(GESTURES.Touch.downPositionA, event.position[0]) < RL_DOUBLETAP_RANGE))
|
||||
{
|
||||
GESTURES.current = GESTURE_DOUBLETAP;
|
||||
GESTURES.Touch.tapCounter = 0;
|
||||
}
|
||||
else // Detect GESTURE_TAP
|
||||
{
|
||||
GESTURES.Touch.tapCounter = 1;
|
||||
GESTURES.current = GESTURE_TAP;
|
||||
}
|
||||
|
||||
GESTURES.Touch.downPositionA = event.position[0];
|
||||
GESTURES.Touch.downDragPosition = event.position[0];
|
||||
|
||||
GESTURES.Touch.upPosition = GESTURES.Touch.downPositionA;
|
||||
GESTURES.Touch.eventTime = rg_get_current_time();
|
||||
|
||||
GESTURES.Swipe.startTime = rg_get_current_time();
|
||||
|
||||
#ifdef __cplusplus
|
||||
GESTURES.Drag.vector = Vector2{ 0.0f, 0.0f };
|
||||
#else
|
||||
GESTURES.Drag.vector = (Vector2){ 0.0f, 0.0f };
|
||||
#endif
|
||||
}
|
||||
else if (event.touchAction == TOUCH_ACTION_UP)
|
||||
{
|
||||
// A swipe can happen while the current gesture is drag, but (specially for web) also hold, so set upPosition for both cases
|
||||
if (GESTURES.current == GESTURE_DRAG || GESTURES.current == GESTURE_HOLD) GESTURES.Touch.upPosition = event.position[0];
|
||||
|
||||
// NOTE: GESTURES.Drag.intensity dependent on the resolution of the screen
|
||||
GESTURES.Drag.distance = rg_vector2_distance(GESTURES.Touch.downPositionA, GESTURES.Touch.upPosition);
|
||||
GESTURES.Drag.intensity = GESTURES.Drag.distance/(float)((rg_get_current_time() - GESTURES.Swipe.startTime));
|
||||
|
||||
// Detect GESTURE_SWIPE
|
||||
if ((GESTURES.Drag.intensity > RL_FORCE_TO_SWIPE) && (GESTURES.current != GESTURE_DRAG))
|
||||
{
|
||||
// NOTE: Angle should be inverted in Y
|
||||
GESTURES.Drag.angle = 360.0f - rg_vector2_angle(GESTURES.Touch.downPositionA, GESTURES.Touch.upPosition);
|
||||
|
||||
if ((GESTURES.Drag.angle < 30) || (GESTURES.Drag.angle > 330)) GESTURES.current = GESTURE_SWIPE_RIGHT; // Right
|
||||
else if ((GESTURES.Drag.angle >= 30) && (GESTURES.Drag.angle <= 150)) GESTURES.current = GESTURE_SWIPE_UP; // Up
|
||||
else if ((GESTURES.Drag.angle > 150) && (GESTURES.Drag.angle < 210)) GESTURES.current = GESTURE_SWIPE_LEFT; // Left
|
||||
else if ((GESTURES.Drag.angle >= 210) && (GESTURES.Drag.angle <= 330)) GESTURES.current = GESTURE_SWIPE_DOWN; // Down
|
||||
else GESTURES.current = GESTURE_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
GESTURES.Drag.distance = 0.0f;
|
||||
GESTURES.Drag.intensity = 0.0f;
|
||||
GESTURES.Drag.angle = 0.0f;
|
||||
|
||||
GESTURES.current = GESTURE_NONE;
|
||||
}
|
||||
|
||||
#if __cplusplus
|
||||
GESTURES.Touch.downDragPosition = Vector2{ 0.0f, 0.0f };
|
||||
#else
|
||||
GESTURES.Touch.downDragPosition = (Vector2){ 0.0f, 0.0f };
|
||||
#endif
|
||||
GESTURES.Touch.pointCount = 0;
|
||||
}
|
||||
else if (event.touchAction == TOUCH_ACTION_MOVE)
|
||||
{
|
||||
GESTURES.Touch.moveDownPositionA = event.position[0];
|
||||
|
||||
if (GESTURES.current == GESTURE_HOLD)
|
||||
{
|
||||
if (GESTURES.Hold.resetRequired) GESTURES.Touch.downPositionA = event.position[0];
|
||||
|
||||
GESTURES.Hold.resetRequired = false;
|
||||
|
||||
// Detect GESTURE_DRAG
|
||||
if ((rg_get_current_time() - GESTURES.Touch.eventTime) > RL_DRAG_TIMEOUT)
|
||||
{
|
||||
GESTURES.Touch.eventTime = rg_get_current_time();
|
||||
GESTURES.current = GESTURE_DRAG;
|
||||
}
|
||||
}
|
||||
|
||||
GESTURES.Drag.vector.x = GESTURES.Touch.moveDownPositionA.x - GESTURES.Touch.downDragPosition.x;
|
||||
GESTURES.Drag.vector.y = GESTURES.Touch.moveDownPositionA.y - GESTURES.Touch.downDragPosition.y;
|
||||
}
|
||||
}
|
||||
else if (GESTURES.Touch.pointCount == 2) // Two touch points
|
||||
{
|
||||
if (event.touchAction == TOUCH_ACTION_DOWN)
|
||||
{
|
||||
GESTURES.Touch.downPositionA = event.position[0];
|
||||
GESTURES.Touch.downPositionB = event.position[1];
|
||||
|
||||
GESTURES.Touch.previousPositionA = GESTURES.Touch.downPositionA;
|
||||
GESTURES.Touch.previousPositionB = GESTURES.Touch.downPositionB;
|
||||
|
||||
//GESTURES.Pinch.distance = rg_vector2_distance(GESTURES.Touch.downPositionA, GESTURES.Touch.downPositionB);
|
||||
|
||||
GESTURES.Pinch.vector.x = GESTURES.Touch.downPositionB.x - GESTURES.Touch.downPositionA.x;
|
||||
GESTURES.Pinch.vector.y = GESTURES.Touch.downPositionB.y - GESTURES.Touch.downPositionA.y;
|
||||
|
||||
GESTURES.current = GESTURE_HOLD;
|
||||
GESTURES.Hold.timeDuration = rg_get_current_time();
|
||||
}
|
||||
else if (event.touchAction == TOUCH_ACTION_MOVE)
|
||||
{
|
||||
GESTURES.Pinch.distance = rg_vector2_distance(GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB);
|
||||
|
||||
GESTURES.Touch.moveDownPositionA = event.position[0];
|
||||
GESTURES.Touch.moveDownPositionB = event.position[1];
|
||||
|
||||
GESTURES.Pinch.vector.x = GESTURES.Touch.moveDownPositionB.x - GESTURES.Touch.moveDownPositionA.x;
|
||||
GESTURES.Pinch.vector.y = GESTURES.Touch.moveDownPositionB.y - GESTURES.Touch.moveDownPositionA.y;
|
||||
|
||||
if ((rg_vector2_distance(GESTURES.Touch.previousPositionA, GESTURES.Touch.moveDownPositionA) >= RL_MINIMUM_PINCH) || (rg_vector2_distance(GESTURES.Touch.previousPositionB, GESTURES.Touch.moveDownPositionB) >= RL_MINIMUM_PINCH))
|
||||
{
|
||||
if ( rg_vector2_distance(GESTURES.Touch.previousPositionA, GESTURES.Touch.previousPositionB) > rg_vector2_distance(GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB) ) GESTURES.current = GESTURE_PINCH_IN;
|
||||
else GESTURES.current = GESTURE_PINCH_OUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
GESTURES.current = GESTURE_HOLD;
|
||||
GESTURES.Hold.timeDuration = rg_get_current_time();
|
||||
}
|
||||
|
||||
// NOTE: Angle should be inverted in Y
|
||||
GESTURES.Pinch.angle = 360.0f - rg_vector2_angle(GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB);
|
||||
}
|
||||
else if (event.touchAction == TOUCH_ACTION_UP)
|
||||
{
|
||||
GESTURES.Pinch.distance = 0.0f;
|
||||
GESTURES.Pinch.angle = 0.0f;
|
||||
#if __cplusplus
|
||||
GESTURES.Pinch.vector = Vector2{ 0.0f, 0.0f };
|
||||
#else
|
||||
GESTURES.Pinch.vector = (Vector2){ 0.0f, 0.0f };
|
||||
#endif
|
||||
GESTURES.Touch.pointCount = 0;
|
||||
|
||||
GESTURES.current = GESTURE_NONE;
|
||||
}
|
||||
}
|
||||
else if (GESTURES.Touch.pointCount > 2) // More than two touch points
|
||||
{
|
||||
// TODO: Process gesture events for more than two points
|
||||
}
|
||||
}
|
||||
|
||||
// Update gestures detected (must be called every frame)
|
||||
void update_gestures(void)
|
||||
{
|
||||
// NOTE: Gestures are processed through system callbacks on touch events
|
||||
|
||||
// Detect GESTURE_HOLD
|
||||
if (((GESTURES.current == GESTURE_TAP) || (GESTURES.current == GESTURE_DOUBLETAP)) && (GESTURES.Touch.pointCount < 2))
|
||||
{
|
||||
GESTURES.current = GESTURE_HOLD;
|
||||
GESTURES.Hold.timeDuration = rg_get_current_time();
|
||||
}
|
||||
|
||||
// Detect GESTURE_NONE
|
||||
if ((GESTURES.current == GESTURE_SWIPE_RIGHT) || (GESTURES.current == GESTURE_SWIPE_UP) || (GESTURES.current == GESTURE_SWIPE_LEFT) || (GESTURES.current == GESTURE_SWIPE_DOWN))
|
||||
{
|
||||
GESTURES.current = GESTURE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
// Get latest detected gesture
|
||||
int get_gesture_detected(void)
|
||||
{
|
||||
// Get current gesture only if enabled
|
||||
return (GESTURES.enabledFlags & GESTURES.current);
|
||||
}
|
||||
|
||||
// Hold time measured in ms
|
||||
float get_gesture_hold_duration(void)
|
||||
{
|
||||
// NOTE: time is calculated on current gesture HOLD
|
||||
|
||||
double time = 0.0;
|
||||
|
||||
if (GESTURES.current == GESTURE_HOLD) time = rg_get_current_time() - GESTURES.Hold.timeDuration;
|
||||
|
||||
return (float)time;
|
||||
}
|
||||
|
||||
// Get drag vector (between initial touch point to current)
|
||||
Vector2 get_gesture_drag_vector(void)
|
||||
{
|
||||
// NOTE: drag vector is calculated on one touch points TOUCH_ACTION_MOVE
|
||||
|
||||
return GESTURES.Drag.vector;
|
||||
}
|
||||
|
||||
// Get drag angle
|
||||
// NOTE: Angle in degrees, horizontal-right is 0, counterclockwise
|
||||
float get_gesture_drag_angle(void)
|
||||
{
|
||||
// NOTE: drag angle is calculated on one touch points TOUCH_ACTION_UP
|
||||
|
||||
return GESTURES.Drag.angle;
|
||||
}
|
||||
|
||||
// Get distance between two pinch points
|
||||
Vector2 get_gesture_pinch_vector(void)
|
||||
{
|
||||
// NOTE: Pinch distance is calculated on two touch points TOUCH_ACTION_MOVE
|
||||
|
||||
return GESTURES.Pinch.vector;
|
||||
}
|
||||
|
||||
// Get angle between two pinch points
|
||||
// NOTE: Angle in degrees, horizontal-right is 0, counterclockwise
|
||||
float get_gesture_pinch_angle(void)
|
||||
{
|
||||
// NOTE: pinch angle is calculated on two touch points TOUCH_ACTION_MOVE
|
||||
|
||||
return GESTURES.Pinch.angle;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
// Get angle from two-points vector with X-axis
|
||||
static float rg_vector2_angle(Vector2 v1, Vector2 v2)
|
||||
{
|
||||
float angle = atan2f(v2.y - v1.y, v2.x - v1.x)*(180.0f/RL_PI);
|
||||
|
||||
if (angle < 0) angle += 360.0f;
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
// Calculate distance between two Vector2
|
||||
static float rg_vector2_distance(Vector2 v1, Vector2 v2)
|
||||
{
|
||||
float result;
|
||||
|
||||
float dx = v2.x - v1.x;
|
||||
float dy = v2.y - v1.y;
|
||||
|
||||
result = (float)sqrt(dx*dx + dy*dy);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Time measure returned are seconds
|
||||
static double rg_get_current_time(void)
|
||||
{
|
||||
double time = 0;
|
||||
|
||||
#if !defined(RGESTURES_STANDALONE)
|
||||
time = get_time();
|
||||
#else
|
||||
#if defined(_WIN32)
|
||||
unsigned long long int clockFrequency, currentTime;
|
||||
|
||||
query_performance_frequency(&clockFrequency); // BE CAREFUL: Costly operation!
|
||||
query_performance_counter(¤tTime);
|
||||
|
||||
time = (double)currentTime/clockFrequency; // Time in seconds
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
// NOTE: Only for Linux-based systems
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
unsigned long long int nowTime = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec; // Time in nanoseconds
|
||||
|
||||
time = ((double)nowTime*1e-9); // Time in seconds
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
//#define CLOCK_REALTIME CALENDAR_CLOCK // returns UTC time since 1970-01-01
|
||||
//#define CLOCK_MONOTONIC SYSTEM_CLOCK // returns the time since boot time
|
||||
|
||||
clock_serv_t cclock;
|
||||
mach_timespec_t now;
|
||||
host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
|
||||
|
||||
// NOTE: OS X does not have clock_gettime(), using clock_get_time()
|
||||
clock_get_time(cclock, &now);
|
||||
mach_port_deallocate(mach_task_self(), cclock);
|
||||
unsigned long long int nowTime = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec; // Time in nanoseconds
|
||||
|
||||
time = ((double)nowTime*1e-9); // Time in seconds
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
RL_NS_END
|
||||
|
||||
#endif // RGESTURES_IMPLEMENTATION
|
File diff suppressed because it is too large
Load Diff
@ -1,81 +0,0 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib.utils - Some common utility functions
|
||||
*
|
||||
*
|
||||
* LICENSE: zlib/libpng
|
||||
*
|
||||
* Copyright (c) 2014-2023 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose, including commercial
|
||||
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim that you
|
||||
* wrote the original software. If you use this software in a product, an acknowledgment
|
||||
* in the product documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
||||
* as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
#include <stdio.h> // Required for: FILE
|
||||
#include <android/asset_manager.h> // Required for: AAssetManager
|
||||
#endif
|
||||
|
||||
#if defined(RL_SUPPORT_TRACELOG)
|
||||
#define RL_TRACELOG(level, ...) RL_NS(trace_log)(level, __VA_ARGS__)
|
||||
|
||||
#if defined(RL_SUPPORT_TRACELOG_DEBUG)
|
||||
#define TRACELOGD(...) RL_NS(trace_log)(LOG_DEBUG, __VA_ARGS__)
|
||||
#else
|
||||
#define TRACELOGD(...) (void)0
|
||||
#endif
|
||||
#else
|
||||
#define RL_TRACELOG(level, ...) (void)0
|
||||
#define TRACELOGD(...) (void)0
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Some basic Defines
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
#define fopen(name, mode) android_fopen(name, mode)
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
//...
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
// Nop...
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(__cplusplus)
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
void init_asset_manager(AAssetManager *manager, const char *dataPath); // Initialize asset manager from android app
|
||||
FILE *android_fopen(const char *fileName, const char *mode); // Replacement for fopen() -> Read-only!
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // UTILS_H
|
Binary file not shown.
@ -1,8 +0,0 @@
|
||||
#include "raudio.c"
|
||||
#include "rcore.c"
|
||||
#include "rglfw.c"
|
||||
#include "rmodels.c"
|
||||
#include "rshapes.c"
|
||||
#include "rtext.c"
|
||||
#include "rtextures.c"
|
||||
#include "rutils.c"
|
File diff suppressed because it is too large
Load Diff
@ -1,242 +0,0 @@
|
||||
// rlgl.h
|
||||
|
||||
word RL_NOT_REFACTORED, RL_REFACTORED_CPP
|
||||
|
||||
namespace rl_,
|
||||
namespace rl,
|
||||
namespace rlgl,
|
||||
not word rl
|
||||
not word rlgl
|
||||
|
||||
namespace RL_LOG_, LOG_
|
||||
namespace RL_PIXELFORMAT_, PIXELFORMAT_
|
||||
namespace RL_TEXTURE_, TEXTURE_
|
||||
namespace RL_SHADER_, SHADER_
|
||||
namespace RL_BLEND_, BLEND_
|
||||
namespace RL_ATTACHMENT_, ATTACHMENT_
|
||||
namespace RL_CULL_, CULL_
|
||||
|
||||
not include rlgl.h
|
||||
|
||||
word TRACELOG, RL_TRACELOG
|
||||
|
||||
word RLGL, GLOBAL_DATA
|
||||
|
||||
word Vector2, Vector2
|
||||
word Vector3, Vector3
|
||||
word Vector4, Vector4
|
||||
word Quaternion, Quaternion
|
||||
word Matrix, Matrix
|
||||
word Color, Color
|
||||
word Rectangle, Rectangle
|
||||
word Image, Image
|
||||
word Texture, Texture
|
||||
word Texture2D, Texture2d
|
||||
word TextureCubemap, Texture_Cubemap
|
||||
word RenderTexture, Render_Texture
|
||||
word RenderTexture2D, Render_Texture2D
|
||||
word NPatchInfo, N_Patch_Info
|
||||
word GlyphInfo, Glyph_Info
|
||||
word Font, Font
|
||||
word Camera3D, Camera3D
|
||||
word Camera, Camera
|
||||
word Camera2D, Camera2D
|
||||
word Mesh, Mesh
|
||||
word Shader, Shader
|
||||
word MaterialMap, Material_Map
|
||||
word Material, Material
|
||||
word Transform, Transform
|
||||
word BoneInfo, Bone_Info
|
||||
word Model, Model
|
||||
word ModelAnimation, Model_Animation
|
||||
word Ray, Ray
|
||||
word RayCollision, Ray_Collision
|
||||
word BoundingBox, Bounding_box
|
||||
word Wave, Wave
|
||||
word rAudioBuffer, Audio_Buffer
|
||||
word rAudioProcessor, Audio_Processor
|
||||
word AudioStream, Audio_Stream
|
||||
word Sound, Sound
|
||||
word Music, Music
|
||||
word VrDeviceInfo, VR_Device_Info
|
||||
word VrStereoConfig, VR_Stereo_Config
|
||||
word FilePathList, File_Path_List
|
||||
word AutomationEvent, Automation_Event
|
||||
word AutomationEventList, Automation_Event_List
|
||||
word Matrix, Matrix
|
||||
|
||||
word rlVertexBuffer, vertex_buffer
|
||||
word rlDrawCall, draw_call
|
||||
word rlRenderBatch, render_batch
|
||||
word rlGlVersion, gl_version
|
||||
word rlTraceLogLevel, trace_log_level
|
||||
word rlPixelFormat, pixel_format
|
||||
word rlTextureFilter, texture_filter
|
||||
word rlShaderLocationIndex, shader_location_index
|
||||
word rlShaderUniformDataType, shader_uniform_data_type
|
||||
word rlShaderAttributeDataType, shader_attribute_data_type
|
||||
word rlBlendMode, blend_mode
|
||||
word rlFramebufferAttachType, framebuffer_attach_type
|
||||
word rlFramebufferAttachTextureType, framebuffer_attach_texture_type
|
||||
word rlCullMode, cull_mode
|
||||
|
||||
word get_pixel_data_size, gpu_get_pixel_data_size
|
||||
|
||||
word rlMatrixMode, matrix_mode
|
||||
word rlPushMatrix, push_matrix
|
||||
word rlPopMatrix, pop_matrix
|
||||
word rlLoadIdentity, load_identity
|
||||
word rlTranslatef, translatef
|
||||
word rlRotatef, rotatef
|
||||
word rlScalef, scalef
|
||||
word rlMultMatrixf, mult_matrixf
|
||||
word rlFrustum, frustum
|
||||
word rlOrtho, ortho
|
||||
word rlViewport, viewport
|
||||
word rlBegin, begin
|
||||
word rlEnd, end
|
||||
word rlVertex2i, vertex2i
|
||||
word rlVertex2f, vertex2f
|
||||
word rlVertex3f, vertex3f
|
||||
word rlTexCoord2f, tex_coord2f
|
||||
word rlNormal3f, normal3f
|
||||
word rlColor4ub, color4ub
|
||||
word rlColor3f, color3f
|
||||
word rlColor4f, color4f
|
||||
word rlEnableVertexArray, enable_vertex_array
|
||||
word rlDisableVertexArray, disable_vertex_array
|
||||
word rlEnableVertexBuffer, enable_vertex_buffer
|
||||
word rlDisableVertexBuffer, disable_vertex_buffer
|
||||
word rlEnableVertexBufferElement, enable_vertex_buffer_element
|
||||
word rlDisableVertexBufferElement, disable_vertex_buffer_element
|
||||
word rlEnableVertexAttribute, enable_vertex_attribute
|
||||
word rlDisableVertexAttribute, disable_vertex_attribute
|
||||
word rlEnableStatePointer, enable_state_pointer
|
||||
word rlDisableStatePointer, disable_state_pointer
|
||||
word rlActiveTextureSlot, active_texture_slot
|
||||
word rlEnableTexture, enable_texture
|
||||
word rlDisableTexture, disable_texture
|
||||
word rlEnableTextureCubemap, enable_texture_cubemap
|
||||
word rlDisableTextureCubemap, disable_texture_cubemap
|
||||
word rlTextureParameters, texture_parameters
|
||||
word rlCubemapParameters, cubemap_parameters
|
||||
word rlEnableShader, enable_shader
|
||||
word rlDisableShader, disable_shader
|
||||
word rlEnableFramebuffer, enable_framebuffer
|
||||
word rlDisableFramebuffer, disable_framebuffer
|
||||
word rlActiveDrawBuffers, active_draw_buffers
|
||||
word rlBlitFramebuffer, blit_framebuffer
|
||||
word rlEnableColorBlend, enable_color_blend
|
||||
word rlDisableColorBlend, disable_color_blend
|
||||
word rlEnableDepthTest, enable_depth_test
|
||||
word rlDisableDepthTest, disable_depth_test
|
||||
word rlEnableDepthMask, enable_depth_mask
|
||||
word rlDisableDepthMask, disable_depth_mask
|
||||
word rlEnableBackfaceCulling, enable_backface_culling
|
||||
word rlDisableBackfaceCulling, disable_backface_culling
|
||||
word rlSetCullFace, set_cull_face
|
||||
word rlEnableScissorTest, enable_scissor_test
|
||||
word rlDisableScissorTest, disable_scissor_test
|
||||
word rlScissor, scissor
|
||||
word rlEnableWireMode, enable_wire_mode
|
||||
word rlEnablePointMode, enable_point_mode
|
||||
word rlDisableWireMode, disable_wire_mode
|
||||
word rlSetLineWidth, set_line_width
|
||||
word rlGetLineWidth, get_line_width
|
||||
word rlEnableSmoothLines, enable_smooth_lines
|
||||
word rlDisableSmoothLines, disable_smooth_lines
|
||||
word rlEnableStereoRender, enable_stereo_render
|
||||
word rlDisableStereoRender, disable_stereo_render
|
||||
word rlIsStereoRenderEnabled, is_stereo_render_enabled
|
||||
word rlClearColor, clear_color
|
||||
word rlClearScreenBuffers, clear_screen_buffers
|
||||
word rlCheckErrors, check_errors
|
||||
word rlSetBlendMode, set_blend_mode
|
||||
word rlSetBlendFactors, set_blend_factors
|
||||
word rlSetBlendFactorsSeparate, set_blend_factors_separate
|
||||
word rlglInit, init
|
||||
word rlglClose, close
|
||||
word rlLoadExtensions, load_extensions
|
||||
word rlGetVersion, get_version
|
||||
word rlSetFramebufferWidth, set_framebuffer_width
|
||||
word rlGetFramebufferWidth, get_framebuffer_width
|
||||
word rlSetFramebufferHeight, set_framebuffer_height
|
||||
word rlGetFramebufferHeight, get_framebuffer_height
|
||||
word rlGetTextureIdDefault, get_texture_id_default
|
||||
word rlGetShaderIdDefault, get_shader_id_default
|
||||
word rlLoadRenderBatch, load_render_batch
|
||||
word rlUnloadRenderBatch, unload_render_batch
|
||||
word rlDrawRenderBatch, draw_render_batch
|
||||
word rlSetRenderBatchActive, set_render_batch_active
|
||||
word rlDrawRenderBatchActive, draw_render_batch_active
|
||||
word rlCheckRenderBatchLimit, check_render_batch_limit
|
||||
word rlSetTexture, set_texture
|
||||
word rlLoadVertexArray, load_vertex_array
|
||||
word rlLoadVertexBuffer, load_vertex_buffer
|
||||
word rlLoadVertexBufferElement, load_vertex_buffer_element
|
||||
word rlUpdateVertexBuffer, update_vertex_buffer
|
||||
word rlUpdateVertexBufferElements, update_vertex_buffer_elements
|
||||
word rlUnloadVertexArray, unload_vertex_array
|
||||
word rlUnloadVertexBuffer, unload_vertex_buffer
|
||||
word rlSetVertexAttribute, set_vertex_attribute
|
||||
word rlSetVertexAttributeDivisor, set_vertex_attribute_divisor
|
||||
word rlSetVertexAttributeDefault, set_vertex_attribute_default
|
||||
word rlDrawVertexArray, draw_vertex_array
|
||||
word rlDrawVertexArrayElements, draw_vertex_array_elements
|
||||
word rlDrawVertexArrayInstanced, draw_vertex_array_instanced
|
||||
word rlDrawVertexArrayElementsInstanced, draw_vertex_array_elements_instanced
|
||||
word rlLoadTexture, load_texture
|
||||
word rlLoadTextureDepth, load_texture_depth
|
||||
word rlLoadTextureCubemap, load_texture_cubemap
|
||||
word rlUpdateTexture, update_texture
|
||||
word rlGetGlTextureFormats, get_gl_texture_formats
|
||||
word rlUnloadTexture, unload_texture
|
||||
word rlGenTextureMipmaps, gen_texture_mipmaps
|
||||
word rlLoadFramebuffer, load_framebuffer
|
||||
word rlFramebufferAttach, framebuffer_attach
|
||||
word rlFramebufferComplete, framebuffer_complete
|
||||
word rlUnloadFramebuffer, unload_framebuffer
|
||||
word rlLoadShaderCode, load_shader_code
|
||||
word rlCompileShader, compile_shader
|
||||
word rlLoadShaderProgram, load_shader_program
|
||||
word rlUnloadShaderProgram, unload_shader_program
|
||||
word rlGetLocationUniform, get_location_uniform
|
||||
word rlGetLocationAttrib, get_location_attrib
|
||||
word rlSetUniform, set_uniform
|
||||
word rlSetUniformMatrix, set_uniform_matrix
|
||||
word rlSetUniformSampler, set_uniform_sampler
|
||||
word rlSetShader, set_shader
|
||||
word rlLoadComputeShaderProgram, load_compute_shader_program
|
||||
word rlComputeShaderDispatch, compute_shader_dispatch
|
||||
word rlLoadShaderBuffer, load_shader_buffer
|
||||
word rlUnloadShaderBuffer, unload_shader_buffer
|
||||
word rlUpdateShaderBuffer, update_shader_buffer
|
||||
word rlBindShaderBuffer, bind_shader_buffer
|
||||
word rlReadShaderBuffer, read_shader_buffer
|
||||
word rlCopyShaderBuffer, copy_shader_buffer
|
||||
word rlGetShaderBufferSize, get_shader_buffer_size
|
||||
word rlBindImageTexture, bind_image_texture
|
||||
word rlGetMatrixModelview, get_matrix_modelview
|
||||
word rlGetMatrixProjection, get_matrix_projection
|
||||
word rlGetMatrixTransform, get_matrix_transform
|
||||
word rlGetMatrixProjectionStereo, get_matrix_projection_stereo
|
||||
word rlGetMatrixViewOffsetStereo, get_matrix_view_offset_stereo
|
||||
word rlSetMatrixProjection, set_matrix_projection
|
||||
word rlSetMatrixModelview, set_matrix_modelview
|
||||
word rlSetMatrixProjectionStereo, set_matrix_projection_stereo
|
||||
word rlSetMatrixViewOffsetStereo, set_matrix_view_offset_stereo
|
||||
word rlLoadDrawCube, load_draw_cube
|
||||
word rlLoadDrawQuad, load_draw_quad
|
||||
word rlLoadShaderDefault, load_shader_default
|
||||
word rlUnloadShaderDefault, unload_shader_default
|
||||
word rlGetPixelDataSize, internal_get_pixel_data_size
|
||||
word rlMatrixIdentity, internal_matrix_identity
|
||||
word rlMatrixMultiply, internal_matrix_multiply
|
||||
word rlCheckRenderBatchLimit, check_render_batch_limit
|
||||
word rlLoadShaderDefault, load_shader_default
|
||||
word rlSetMatrixProjection, set_matrix_projection
|
||||
word rlUnloadFramebuffer, unload_framebuffer
|
||||
word rlReadScreenPixels, read_screen_pixels
|
||||
word rlReadTexturePixels, read_texture_pixels
|
||||
word rlGetShaderLocsDefault, get_shader_locs_default
|
||||
word rlGetPixelFormatName, get_pixel_format_name
|
@ -1,322 +0,0 @@
|
||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||
#define GEN_BENCHMARK
|
||||
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
||||
// #define GEN_IMPLEMENTATION
|
||||
#include "gen.cpp"
|
||||
#include "gen.builder.cpp"
|
||||
|
||||
|
||||
constexpr char const* path_config_h = "config.h";
|
||||
constexpr char const* path_raylib_h = "raylib.h";
|
||||
constexpr char const* path_raymath_h = "raymath.h";
|
||||
constexpr char const* path_rcamera_h = "rcamera.h";
|
||||
constexpr char const* path_rcore_h = "rcore.h";
|
||||
constexpr char const* path_rgestures_h = "rgestures.h";
|
||||
constexpr char const* path_rgl_h = "rgl.h";
|
||||
constexpr char const* path_rtext_h = "rtext.h";
|
||||
|
||||
constexpr char const* path_rcore_desktop_c = "rcore_desktop.c";
|
||||
|
||||
constexpr char const* path_raudio_c = "raudio.c";
|
||||
constexpr char const* path_rcore_c = "rcore.c";
|
||||
constexpr char const* path_rglfw_c = "rglfw.c";
|
||||
constexpr char const* path_rmodels_c = "rmodels.c";
|
||||
constexpr char const* path_rtext_c = "rtext.c";
|
||||
constexpr char const* path_rtextures_c = "rtextures.c";
|
||||
constexpr char const* path_rutils_c = "rutils.c";
|
||||
|
||||
using namespace gen;
|
||||
|
||||
StringCached upper_snake_to_mixed_snake(StringCached str)
|
||||
{
|
||||
local_persist String scratch = String::make_reserve(GlobalAllocator, kilobytes(1));
|
||||
scratch.clear();
|
||||
|
||||
bool capitalizeNext = true;
|
||||
|
||||
for (s32 index = 0; index < str.length(); ++index)
|
||||
{
|
||||
char c = str[index];
|
||||
|
||||
if (c == '_')
|
||||
{
|
||||
scratch.append(c);
|
||||
capitalizeNext = true;
|
||||
}
|
||||
else if (capitalizeNext)
|
||||
{
|
||||
if (c >= 'a' && c <= 'z')
|
||||
{
|
||||
scratch.append(c - 32); // Convert to uppercase
|
||||
}
|
||||
else
|
||||
{
|
||||
scratch.append(c);
|
||||
}
|
||||
capitalizeNext = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
{
|
||||
scratch.append(c + 32); // Convert to lowercase
|
||||
}
|
||||
else
|
||||
{
|
||||
scratch.append(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StringCached result = get_cached_string(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
StringCached pascal_to_lower_snake(StringCached str)
|
||||
{
|
||||
local_persist String scratch = String::make_reserve(GlobalAllocator, kilobytes(1));
|
||||
scratch.clear();
|
||||
|
||||
for (s32 index = 0; index < str.length(); ++index)
|
||||
{
|
||||
char c = str[index];
|
||||
char next = (index + 1 < str.length()) ? str[index + 1] : '\0'; // Ensure we don't go out of bounds
|
||||
|
||||
// Whitelist check for "2D" and "3D"
|
||||
if ((c == '2' || c == '3' | c == '4') && (next == 'D' || next == 'd'))
|
||||
{
|
||||
if (index > 0) // If it's not the start of the string, append an underscore
|
||||
{
|
||||
char* prev = str.Data + index - 1;
|
||||
if (*prev != '_') // Avoid double underscores
|
||||
{
|
||||
scratch.append('_');
|
||||
}
|
||||
}
|
||||
scratch.append(c);
|
||||
scratch.append('d'); // Convert to lowercase
|
||||
index++; // Skip the next character since we've already processed it
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
{
|
||||
char* prev = (index > 0) ? str.Data + index - 1 : nullptr;
|
||||
|
||||
if ((index > 0 && prev && *prev >= 'a' && *prev <= 'z') ||
|
||||
(prev && char_is_digit(*prev) && (next >= 'A' && next <= 'Z')))
|
||||
{
|
||||
scratch.append('_');
|
||||
}
|
||||
|
||||
scratch.append(c + 32);
|
||||
}
|
||||
else if (char_is_digit(c) && (next >= 'A' && next <= 'Z')) // Check for a number followed by an uppercase letter
|
||||
{
|
||||
scratch.append(c);
|
||||
scratch.append('_');
|
||||
}
|
||||
else
|
||||
{
|
||||
scratch.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
StringCached result = get_cached_string(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
void refactor_define( CodeDefine& code )
|
||||
{
|
||||
local_persist String name_scratch = String::make_reserve( GlobalAllocator, kilobytes(1) );
|
||||
|
||||
if ( str_compare( elem->Name, txt("RL"), 2 ) == 0 || str_compare( elem->Name, txt("RAYLIB"), 6 ) == 0 )
|
||||
continue;
|
||||
|
||||
name_scratch.append_fmt( "%RL_%S", elem->Name );
|
||||
elem->Name = get_cached_string( name_scratch );
|
||||
name_scratch.clear();
|
||||
}
|
||||
|
||||
void refactor_enum( CodeEnum& code )
|
||||
{
|
||||
for ( Code elem : code->Body )
|
||||
{
|
||||
if ( elem->Type == ECode::Untyped )
|
||||
{
|
||||
elem->Content = upper_snake_to_mixed_snake( elem->Content );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void refactor_typename( CodeType& type )
|
||||
{
|
||||
local_persist CodeType t_unsigned_char = parse_type( code(unsigned char) );
|
||||
local_persist CodeType t_unsigned_char_ptr = parse_type( code(unsigned char*) );
|
||||
local_persist CodeType t_unsigned_short_ptr = parse_type( code(unsigned short*) );
|
||||
local_persist CodeType t_int = parse_type( code(int) );
|
||||
local_persist CodeType t_int_ptr = parse_type( code(int*) );
|
||||
local_persist CodeType t_unsigned_int = parse_type( code(unsigned int) );
|
||||
local_persist CodeType t_float = parse_type( code(float) );
|
||||
local_persist CodeType t_float_ptr = parse_type( code(float*) );
|
||||
|
||||
local_persist CodeType t_f32_ptr = parse_type( code(f32*) );
|
||||
local_persist CodeType t_u8_ptr = parse_type( code(u8*) );
|
||||
local_persist CodeType t_s32_ptr = parse_type( code(s32*) );
|
||||
|
||||
String type_str = type.to_string();
|
||||
|
||||
if ( str_compare( type_str, t_unsigned_char.to_string() ) == 0 )
|
||||
{
|
||||
type.ast = t_u8.ast;
|
||||
}
|
||||
if ( str_compare( type_str, t_unsigned_char_ptr.to_string() ) == 0 )
|
||||
{
|
||||
type.ast = t_u8_ptr.ast;
|
||||
}
|
||||
if ( str_compare( type_str, t_unsigned_short_ptr.to_string() ) == 0 )
|
||||
{
|
||||
type.ast = t_u8_ptr.ast;
|
||||
}
|
||||
if ( str_compare( type_str, t_int.to_string() ) == 0 )
|
||||
{
|
||||
type.ast = t_s32.ast;
|
||||
}
|
||||
if ( str_compare( type_str, t_int_ptr.to_string() ) == 0 )
|
||||
{
|
||||
type.ast = t_s32_ptr.ast;
|
||||
}
|
||||
if ( str_compare( type_str, t_unsigned_int.to_string() ) == 0 )
|
||||
{
|
||||
type.ast = t_u32.ast;
|
||||
}
|
||||
if ( str_compare( type_str, t_float.to_string() ) == 0 )
|
||||
{
|
||||
type.ast = t_f32.ast;
|
||||
}
|
||||
if ( str_compare( type_str, t_float_ptr.to_string() ) == 0 )
|
||||
{
|
||||
type.ast = t_f32_ptr.ast;
|
||||
}
|
||||
}
|
||||
|
||||
void refactor_fn( CodeFn& fn )
|
||||
{
|
||||
StringCached original_name = fn->Name;
|
||||
fn->Name = pascal_to_lower_snake( fn->Name );
|
||||
|
||||
log_fmt( "%S", "Proc ID: %S -> %S", original_name, fn->Name );
|
||||
|
||||
for ( CodeParam param : fn->Params )
|
||||
{
|
||||
refactor_typename( param->ValueType );
|
||||
}
|
||||
}
|
||||
|
||||
void refactor_struct( CodeStruct& code )
|
||||
{
|
||||
for ( Code field : code->Body )
|
||||
{
|
||||
if ( field->Type == ECode::Variable )
|
||||
{
|
||||
CodeVar var = field.cast<CodeVar>();
|
||||
refactor_typename( var->ValueType );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void refactor_file( char const* path )
|
||||
{
|
||||
FileContents contents = file_read_contents( GlobalAllocator, true, path );
|
||||
CodeBody code = parse_global_body( { contents.size, rcast(char const*, contents.data) } );
|
||||
|
||||
local_perist String name_scratch = String::make_reserve( GlobalAllocator, kilobytes(1) );
|
||||
|
||||
// CodeBody includes
|
||||
// CodeBody nspace_body = def_body( ECode::Namespace );
|
||||
CodeBody new_code = def_body( ECode::Global_Body );
|
||||
|
||||
for ( Code elem : code )
|
||||
{
|
||||
if ( elem->Type == ECode::Preprocess_Define )
|
||||
{
|
||||
refactor_define( elem.cast<CodeDefine>() );
|
||||
}
|
||||
|
||||
if ( elem->Type == ECode::Enum )
|
||||
{
|
||||
refactor_enum( elem.cast<CodeEnum>() );
|
||||
}
|
||||
|
||||
if ( elem->Type == ECode::Typedef )
|
||||
{
|
||||
CodeTypedef td = elem.cast<CodeTypedef>();
|
||||
if ( td->UnderlyingType->Type == ECode::Enum )
|
||||
{
|
||||
CodeEnum code = td->UnderlyingType.cast<CodeEnum>();
|
||||
refactor_enum( code );
|
||||
}
|
||||
if ( td->UnderlyingType->Type == ECode::Struct )
|
||||
{
|
||||
CodeStruct code = td->UnderlyingType.cast<CodeStruct>();
|
||||
refactor_struct( code );
|
||||
}
|
||||
}
|
||||
|
||||
if ( elem->Type == ECode::Struct )
|
||||
{
|
||||
refactor_struct( elem.cast<CodeStruct>() );
|
||||
}
|
||||
|
||||
if ( elem->Type == ECode::Function || elem->Type == ECode::Function_Fwd )
|
||||
{
|
||||
refactor_fn( elem.cast<CodeFn>() );
|
||||
}
|
||||
|
||||
if ( elem->Type == ECode::Extern_Linkage )
|
||||
{
|
||||
CodeBody body = elem.cast<CodeExtern>()->Body;
|
||||
for ( Code elem : body )
|
||||
{
|
||||
if ( elem->Type == ECode::Function || elem->Type == ECode::Function_Fwd )
|
||||
{
|
||||
refactor_fn( elem.cast<CodeFn>() );
|
||||
}
|
||||
}
|
||||
|
||||
Code nspace = def_namespace( txt("raylib"), def_namespace_body( args(elem) ) );
|
||||
elem = nspace;
|
||||
}
|
||||
|
||||
new_code.append( elem );
|
||||
}
|
||||
|
||||
Builder builder = Builder::open( path );
|
||||
builder.print( new_code );
|
||||
builder.write();
|
||||
|
||||
name_scratch.clear();
|
||||
}
|
||||
|
||||
int gen_main()
|
||||
{
|
||||
gen::init();
|
||||
|
||||
refactor_file( path_config_h );
|
||||
refactor_file( path_raylib_h );
|
||||
refactor_file( path_rcamera_h );
|
||||
refactor_file( path_raymath_h );
|
||||
refactor_file( path_rcore_h );
|
||||
refactor_file( path_rgl_h );
|
||||
refactor_file( path_rtext_h );
|
||||
|
||||
refactor_file( path_rcore_desktop_c );
|
||||
refactor_file( path_raudio_c );
|
||||
refactor_file( path_rcore_c );
|
||||
refactor_file( path_rglfw_c );
|
||||
refactor_file( path_rmodels_c );
|
||||
refactor_file( path_rtext_c );
|
||||
refactor_file( path_rutils_c );
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
# Vis AST
|
||||
|
||||
AST visualizer for gencpp
|
||||
|
||||
This is a early start to creating frontend tooling for c/c++ using gencpp as a core component.
|
||||
I'll be exploring creating an AST explorer for this library with raylib as the graphical & general platform vendor for dependencies that go beyond the scope of gencpp.
|
||||
|
||||
For now I'll have its build script in this file, however it will heavily rely on gencpp's helper scripts.
|
||||
|
||||
Whatever sort of UX tooling I setup for this will be reused for the other tools I'll be creating for gencpp.
|
@ -1,256 +0,0 @@
|
||||
Clear-Host
|
||||
|
||||
$path_root = git rev-parse --show-toplevel
|
||||
$path_scripts = Join-Path $path_root 'scripts'
|
||||
|
||||
$target_arch = Join-Path $path_scripts 'helpers/target_arch.psm1'
|
||||
$devshell = Join-Path $path_scripts 'helpers/devshell.ps1'
|
||||
$format_cpp = Join-Path $path_scripts 'helpers/format_cpp.psm1'
|
||||
$incremental_checks = Join-Path $path_scripts 'helpers/incremental_checks.ps1'
|
||||
$vendor_toolchain = Join-Path $path_scripts 'helpers/vendor_toolchain.ps1'
|
||||
|
||||
$path_project = Join-Path $path_root 'project'
|
||||
$path_aux = Join-Path $path_project 'auxillary'
|
||||
$path_vis_root = Join-Path $path_aux 'vis_ast'
|
||||
$path_binaries = Join-Path $path_vis_root 'binaries'
|
||||
|
||||
$path_deps = Join-Path $path_vis_root 'dependencies'
|
||||
$path_temp = Join-Path $path_deps 'temp'
|
||||
|
||||
Import-Module $target_arch
|
||||
Import-Module $format_cpp
|
||||
|
||||
#region Arguments
|
||||
$vendor = $null
|
||||
$optimize = $null
|
||||
$debug = $null
|
||||
$analysis = $false
|
||||
$dev = $false
|
||||
$verbose = $null
|
||||
|
||||
[array] $vendors = @( "clang", "msvc" )
|
||||
|
||||
# This is a really lazy way of parsing the args, could use actual params down the line...
|
||||
|
||||
if ( $args ) { $args | ForEach-Object {
|
||||
switch ($_){
|
||||
{ $_ -in $vendors } { $vendor = $_; break }
|
||||
"optimize" { $optimize = $true }
|
||||
"debug" { $debug = $true }
|
||||
"analysis" { $analysis = $true }
|
||||
"dev" { $dev = $true }
|
||||
"verbose" { $verbose = $true }
|
||||
}
|
||||
}}
|
||||
#endregion Argument
|
||||
|
||||
# Load up toolchain configuraion
|
||||
. $vendor_toolchain
|
||||
. $incremental_checks
|
||||
|
||||
# Clear out the current content first
|
||||
if ( test-path $path_temp) {
|
||||
remove-item $path_temp -Recurse
|
||||
}
|
||||
New-Item -ItemType Directory -Path $path_temp
|
||||
|
||||
if ( -not (Test-Path $path_binaries) ) {
|
||||
New-Item -ItemType Directory -Path $path_binaries
|
||||
}
|
||||
|
||||
function setup-raylib {
|
||||
$path_raylib = join-path $path_deps 'raylib'
|
||||
$path_raylib_inc = join-path $path_raylib 'include'
|
||||
$path_raylib_lib = join-path $path_raylib 'lib'
|
||||
if ( test-path $path_raylib_inc ) {
|
||||
remove-item $path_raylib_inc -recurse
|
||||
remove-item $path_raylib_lib -recurse
|
||||
}
|
||||
new-item -path $path_raylib_inc -ItemType Directory
|
||||
new-item -path $path_raylib_lib -ItemType Directory
|
||||
|
||||
$url_raylib_zip = 'https://github.com/Ed94/raylib_refactored/archive/refs/heads/refactor-support.zip'
|
||||
$path_raylib_zip = join-path $path_temp 'raylib.zip'
|
||||
|
||||
$path_raylib_master = join-path $path_temp 'raylib_refactored-refactor-support'
|
||||
$path_raylib_src = join-path $path_raylib_master 'src'
|
||||
$path_raylib_platforms = join-path $path_raylib_src 'platforms'
|
||||
$path_raylib_glfw_inc = join-path $path_raylib_src 'external/glfw/include'
|
||||
$path_raylib_gputex = join-path $path_raylib_src 'external/rl_gputex.h'
|
||||
|
||||
if ( test-path $path_raylib_master ) {
|
||||
remove-item $path_raylib_master -Recurse
|
||||
}
|
||||
invoke-webrequest -uri $url_raylib_zip -outfile $path_raylib_zip
|
||||
expand-archive -path $path_raylib_zip -destinationpath $path_temp
|
||||
|
||||
write-host "Building raylib with $vendor"
|
||||
|
||||
$path_build = Join-Path $path_raylib 'build'
|
||||
if ( (Test-Path $path_build) -eq $false ) {
|
||||
New-Item $path_build -ItemType Directory
|
||||
}
|
||||
|
||||
$raylib_headers = Get-ChildItem -Path $path_raylib_src -Filter '*.h' -File
|
||||
$raylib_modules = get-childitem -path $path_raylib_src -filter '*.c' -file
|
||||
|
||||
# Refactor with refactor.exe
|
||||
if ( $true ) {
|
||||
$path_refactor = join-path $path_raylib 'raylib_cpp.refactor'
|
||||
$path_refactor_rlgl = join-path $path_raylib 'raylib_cpp_gl.refactor'
|
||||
|
||||
$files = @()
|
||||
foreach ( $header in $raylib_headers ) {
|
||||
$file_name = split-path $header -leaf
|
||||
|
||||
if ( -not $file_name.Equals('rlgl.h' ) ) {
|
||||
$files += "$header"
|
||||
}
|
||||
}
|
||||
foreach ( $module in $raylib_modules ) {
|
||||
$files += "$module"
|
||||
}
|
||||
|
||||
$files += "$path_raylib_gputex"
|
||||
|
||||
$platform_modules = @()
|
||||
foreach ( $module in (get-childitem -path $path_raylib_platforms -filter '*.c' -file) ) {
|
||||
$platform_modules += "$module"
|
||||
}
|
||||
|
||||
$path_rlgl = join-path $path_raylib_src 'rlgl.h'
|
||||
|
||||
Push-Location $path_raylib_src
|
||||
write-host "Beginning refactor...`n"
|
||||
$refactors = @(@())
|
||||
$refactorParams = @(
|
||||
# "-debug",
|
||||
"-num=$($files.Count)"
|
||||
"-src=$($files)",
|
||||
"-spec=$($path_refactor)"
|
||||
)
|
||||
& refactor $refactorParams
|
||||
Write-Host "`nRefactoring complete`n`n"
|
||||
Pop-Location
|
||||
|
||||
Push-Location $path_raylib_platforms
|
||||
write-host "Beginning refactor...`n"
|
||||
$refactors = @(@())
|
||||
$refactorParams = @(
|
||||
# "-debug",
|
||||
"-num=$($platform_modules.Count)"
|
||||
"-src=$($platform_modules)",
|
||||
"-spec=$($path_refactor)"
|
||||
)
|
||||
& refactor $refactorParams
|
||||
Write-Host "`nRefactoring complete`n`n"
|
||||
Pop-Location
|
||||
|
||||
Push-Location $path_raylib_src
|
||||
$gl_modules = @( "$path_rlgl", "$path_raylib_gputex" )
|
||||
|
||||
write-host "Beginning refactor just for rlgl.h...`n"
|
||||
$refactors = @(@())
|
||||
$refactorParams = @(
|
||||
# "-debug",
|
||||
"-num=$($gl_modules.Count)"
|
||||
"-src=$($gl_modules)",
|
||||
"-spec=$($path_refactor_rlgl)"
|
||||
)
|
||||
& refactor $refactorParams
|
||||
Write-Host "`nRefactoring complete`n`n"
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
# Refactor raylib with gencpp
|
||||
if ( $false ) {
|
||||
# if ( $false ) {
|
||||
$path_gencpp = join-path $path_root 'project/gen'
|
||||
|
||||
$includes = @(
|
||||
$path_gencpp
|
||||
)
|
||||
|
||||
$compiler_args = @(
|
||||
($flag_define + 'GEN_TIME')
|
||||
)
|
||||
|
||||
$linker_args = @(
|
||||
|
||||
)
|
||||
|
||||
$unit = join-path $path_raylib 'raylib_refactor.cpp'
|
||||
$executable = join-path $path_build 'raylib_refactor.exe'
|
||||
|
||||
$build_result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable
|
||||
Push-Location $path_raylib_src
|
||||
if ( Test-Path( $executable ) ) {
|
||||
Measure-Command { & $executable
|
||||
| ForEach-Object {
|
||||
write-host `t $_ -ForegroundColor Green
|
||||
}
|
||||
}
|
||||
}
|
||||
Pop-Location
|
||||
|
||||
push-location $path_scripts
|
||||
# Time to format
|
||||
$fmt_includes = @()
|
||||
foreach ( $header in $raylib_headers ) {
|
||||
$fmt_includes += split-path $header -leaf
|
||||
}
|
||||
foreach ( $module in $raylib_modules ) {
|
||||
$fmt_includes += split-path $module -leaf
|
||||
}
|
||||
format-cpp $path_raylib_src $fmt_includes $null
|
||||
pop-location
|
||||
}
|
||||
|
||||
# Build raylib
|
||||
if ( $true ) {
|
||||
# Microsoft
|
||||
$lib_gdi32 = 'Gdi32.lib'
|
||||
$lib_shell32 = 'Shell32.lib'
|
||||
$lib_xinput = 'Xinput.lib'
|
||||
$lib_user32 = 'User32.lib'
|
||||
$lib_winmm = 'Winmm.lib'
|
||||
|
||||
$includes = @(
|
||||
$path_raylib_src,
|
||||
$path_raylib_glfw_inc
|
||||
)
|
||||
foreach ($include in $includes) {
|
||||
write-host $include
|
||||
}
|
||||
|
||||
$compiler_args = @(
|
||||
($flag_define + 'PLATFORM_DESKTOP'),
|
||||
($flag_define + 'RL_BUILD_LIBTYPE_SHARED'),
|
||||
$flag_all_cpp
|
||||
)
|
||||
$linker_args = @(
|
||||
$flag_link_dll,
|
||||
|
||||
# $lib_xinput,
|
||||
$lib_gdi32,
|
||||
$lib_shell32,
|
||||
$lib_user32,
|
||||
$lib_winmm
|
||||
)
|
||||
|
||||
# $unit = join-path $path_raylib 'raylib.c'
|
||||
$dll = join-path $path_raylib_lib 'raylib.dll'
|
||||
# $build_result = build-simple $path_build $includes $compiler_args $linker_args $unit $dll
|
||||
|
||||
$build_result = build $path_build $includes $compiler_args $linker_args $raylib_modules $dll
|
||||
}
|
||||
|
||||
# Move headers to used include
|
||||
foreach ($header in $raylib_headers) {
|
||||
Copy-Item -Path $header -Destination (join-path $path_raylib_inc (split-path $header -Leaf))
|
||||
}
|
||||
|
||||
# Don't want to remove as it hampers debugging.
|
||||
# remove-item -path $path_temp -Recurse
|
||||
}
|
||||
setup-raylib
|
@ -1,6 +1,8 @@
|
||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
||||
#define GEN_EXPOSE_BACKEND
|
||||
#define GEN_SUPPORT_CPP_MEMBER_FEATURES 0
|
||||
#define GEN_SUPPORT_CPP_REFERENCES 0
|
||||
#include "gen.cpp"
|
||||
|
||||
#include "helpers/push_ignores.inline.hpp"
|
||||
@ -20,16 +22,56 @@ constexpr char const* generation_notice =
|
||||
"// This file was generated automatially by gencpp's bootstrap.cpp "
|
||||
"(See: https://github.com/Ed94/gencpp)\n\n";
|
||||
|
||||
#include <cstdlib> // for system()
|
||||
|
||||
void format_file( char const* path )
|
||||
{
|
||||
String resolved_path = string_make_strc(GlobalAllocator, to_strc_from_c_str(path));
|
||||
|
||||
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");
|
||||
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;
|
||||
}
|
||||
|
||||
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" );
|
||||
|
||||
// gen_dep.hpp
|
||||
{
|
||||
Code header_start = scan_file( "dependencies/header_start.hpp" );
|
||||
Code platform = scan_file( "dependencies/platform.hpp" );
|
||||
Code macros = scan_file( "dependencies/macros.hpp" );
|
||||
Code basic_types = scan_file( "dependencies/basic_types.hpp" );
|
||||
Code debug = scan_file( "dependencies/debug.hpp" );
|
||||
@ -45,8 +87,8 @@ int gen_main()
|
||||
Builder
|
||||
header = Builder::open("gen/gen.dep.hpp");
|
||||
header.print_fmt( generation_notice );
|
||||
header.print_fmt( "// This file is intended to be included within gen.hpp (There is no pragma diagnostic ignores)\n\n" );
|
||||
header.print( header_start );
|
||||
header.print_fmt( "// This file is intended to be included within gen.hpp (There is no pragma diagnostic ignores)\n" );
|
||||
header.print( platform );
|
||||
header.print_fmt( "\nGEN_NS_BEGIN\n" );
|
||||
|
||||
header.print( macros );
|
||||
@ -80,7 +122,7 @@ int gen_main()
|
||||
Builder
|
||||
src = Builder::open( "gen/gen.dep.cpp" );
|
||||
src.print_fmt( generation_notice );
|
||||
src.print_fmt( "// This file is intended to be included within gen.cpp (There is no pragma diagnostic ignores)\n\n" );
|
||||
src.print_fmt( "// This file is intended to be included within gen.cpp (There is no pragma diagnostic ignores)\n" );
|
||||
src.print( src_start );
|
||||
src.print_fmt( "\nGEN_NS_BEGIN\n" );
|
||||
|
||||
@ -103,7 +145,7 @@ int gen_main()
|
||||
def_include(txt("components/types.hpp")),
|
||||
preprocess_endif,
|
||||
fmt_newline,
|
||||
untyped_str( to_str(generation_notice) )
|
||||
untyped_str( to_strc_from_c_str(generation_notice) )
|
||||
));
|
||||
|
||||
// gen.hpp
|
||||
@ -132,9 +174,13 @@ int gen_main()
|
||||
|
||||
header.print_fmt( "#pragma region Types\n" );
|
||||
header.print( types );
|
||||
header.print( ecode );
|
||||
header.print( eoperator );
|
||||
header.print( especifier );
|
||||
header.print( fmt_newline);
|
||||
header.print( dump_to_scratch_and_retireve(ecode) );
|
||||
header.print( fmt_newline);
|
||||
header.print( dump_to_scratch_and_retireve(eoperator) );
|
||||
header.print( fmt_newline);
|
||||
header.print( dump_to_scratch_and_retireve(especifier) );
|
||||
header.print( fmt_newline);
|
||||
header.print_fmt( "#pragma endregion Types\n\n" );
|
||||
|
||||
header.print_fmt( "#pragma region AST\n" );
|
||||
@ -148,7 +194,8 @@ int gen_main()
|
||||
header.print_fmt( "\n#pragma region Inlines\n" );
|
||||
header.print( inlines );
|
||||
header.print( fmt_newline );
|
||||
header.print( ast_inlines );
|
||||
header.print( dump_to_scratch_and_retireve(ast_inlines) );
|
||||
header.print( fmt_newline );
|
||||
header.print_fmt( "#pragma endregion Inlines\n" );
|
||||
|
||||
header.print( header_end );
|
||||
@ -196,14 +243,19 @@ 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)) );
|
||||
//CodeNS nspaced_etoktype = def_namespace( name(parser), def_namespace_body( args(etoktype)) );
|
||||
CodeBody nspaced_etoktype = def_global_body( args(
|
||||
untyped_str(txt("GEN_NS_PARSER_BEGIN\n")),
|
||||
etoktype,
|
||||
untyped_str(txt("GEN_NS_PARSER_END\n"))
|
||||
));
|
||||
|
||||
Builder
|
||||
src = Builder::open( "gen/gen.cpp" );
|
||||
src.print_fmt( generation_notice );
|
||||
src.print( push_ignores );
|
||||
src.print( src_start );
|
||||
src.print_fmt( "GEN_NS_BEGIN\n");
|
||||
src.print_fmt( "\nGEN_NS_BEGIN\n");
|
||||
|
||||
src.print( static_data );
|
||||
|
||||
@ -217,7 +269,7 @@ int gen_main()
|
||||
src.print( interface );
|
||||
src.print( upfront );
|
||||
src.print_fmt( "\n#pragma region Parsing\n\n" );
|
||||
src.print( nspaced_etoktype );
|
||||
src.print( dump_to_scratch_and_retireve(nspaced_etoktype) );
|
||||
src.print( lexer );
|
||||
src.print( parser );
|
||||
src.print( parsing_interface );
|
||||
@ -278,7 +330,7 @@ int gen_main()
|
||||
header.print_fmt( "\nGEN_NS_BEGIN\n" );
|
||||
header.print( parsing );
|
||||
header.print( scanner );
|
||||
header.print_fmt( "GEN_NS_END\n" );
|
||||
header.print_fmt( "\nGEN_NS_END\n" );
|
||||
header.write();
|
||||
}
|
||||
|
||||
@ -293,7 +345,7 @@ int gen_main()
|
||||
src.print( def_include( txt("gen.scanner.hpp") ) );
|
||||
src.print_fmt( "\nGEN_NS_BEGIN\n" );
|
||||
src.print( parsing );
|
||||
src.print( scanner );
|
||||
// src.print( scanner );
|
||||
src.print_fmt( "GEN_NS_END\n" );
|
||||
src.write();
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -67,85 +67,116 @@ struct AST_Stmt_While;
|
||||
|
||||
struct AST_Struct;
|
||||
struct AST_Template;
|
||||
struct AST_Type;
|
||||
struct AST_Typename;
|
||||
struct AST_Typedef;
|
||||
struct AST_Union;
|
||||
struct AST_Using;
|
||||
struct AST_Var;
|
||||
|
||||
struct Code;
|
||||
struct CodeBody;
|
||||
// These are to offer ease of use and optionally strong type safety for the AST.
|
||||
struct CodeAttributes;
|
||||
// struct CodeBaseClass;
|
||||
struct CodeComment;
|
||||
struct CodeClass;
|
||||
struct CodeConstructor;
|
||||
struct CodeDefine;
|
||||
struct CodeDestructor;
|
||||
struct CodeEnum;
|
||||
struct CodeExec;
|
||||
struct CodeExtern;
|
||||
struct CodeInclude;
|
||||
struct CodeFriend;
|
||||
struct CodeFn;
|
||||
struct CodeModule;
|
||||
struct CodeNS;
|
||||
struct CodeOperator;
|
||||
struct CodeOpCast;
|
||||
struct CodeParam;
|
||||
struct CodePreprocessCond;
|
||||
struct CodePragma;
|
||||
struct CodeSpecifiers;
|
||||
|
||||
#if GEN_EXECUTION_EXPRESSION_SUPPORT
|
||||
struct CodeExpr;
|
||||
struct CodeExpr_Assign;
|
||||
struct CodeExpr_Alignof;
|
||||
struct CodeExpr_Binary;
|
||||
struct CodeExpr_CStyleCast;
|
||||
struct CodeExpr_FunctionalCast;
|
||||
struct CodeExpr_CppCast;
|
||||
struct CodeExpr_Element;
|
||||
struct CodeExpr_ProcCall;
|
||||
struct CodeExpr_Decltype;
|
||||
struct CodeExpr_Comma;
|
||||
struct CodeExpr_AMS; // Access Member Symbol
|
||||
struct CodeExpr_Sizeof;
|
||||
struct CodeExpr_Subscript;
|
||||
struct CodeExpr_Ternary;
|
||||
struct CodeExpr_UnaryPrefix;
|
||||
struct CodeExpr_UnaryPostfix;
|
||||
|
||||
struct CodeStmt;
|
||||
struct CodeStmt_Break;
|
||||
struct CodeStmt_Case;
|
||||
struct CodeStmt_Continue;
|
||||
struct CodeStmt_Decl;
|
||||
struct CodeStmt_Do;
|
||||
struct CodeStmt_Expr;
|
||||
struct CodeStmt_Else;
|
||||
struct CodeStmt_If;
|
||||
struct CodeStmt_For;
|
||||
struct CodeStmt_Goto;
|
||||
struct CodeStmt_Label;
|
||||
struct CodeStmt_Switch;
|
||||
struct CodeStmt_While;
|
||||
#if GEN_COMPILER_C
|
||||
#define Define_Code(Type) typedef AST_##Type* Code##Type
|
||||
#else
|
||||
#define Define_Code(Type) struct Code##Type
|
||||
#endif
|
||||
|
||||
struct CodeStruct;
|
||||
struct CodeTemplate;
|
||||
struct CodeType;
|
||||
struct CodeTypedef;
|
||||
struct CodeUnion;
|
||||
struct CodeUsing;
|
||||
struct CodeVar;
|
||||
#if GEN_COMPILER_C
|
||||
typedef AST* code;
|
||||
#else
|
||||
struct Code;
|
||||
#endif
|
||||
Define_Code(Body);
|
||||
// These are to offer ease of use and optionally strong type safety for the AST.
|
||||
Define_Code(Attributes);
|
||||
// struct CodeBaseClass;
|
||||
Define_Code(Comment);
|
||||
Define_Code(Class);
|
||||
Define_Code(Constructor);
|
||||
Define_Code(Define);
|
||||
Define_Code(Destructor);
|
||||
Define_Code(Enum);
|
||||
Define_Code(Exec);
|
||||
Define_Code(Extern);
|
||||
Define_Code(Include);
|
||||
Define_Code(Friend);
|
||||
Define_Code(Fn);
|
||||
Define_Code(Module);
|
||||
Define_Code(NS);
|
||||
Define_Code(Operator);
|
||||
Define_Code(OpCast);
|
||||
Define_Code(Param);
|
||||
Define_Code(PreprocessCond);
|
||||
Define_Code(Pragma);
|
||||
Define_Code(Specifiers);
|
||||
|
||||
namespace parser
|
||||
{
|
||||
struct Token;
|
||||
}
|
||||
#if GEN_EXECUTION_EXPRESSION_SUPPORT
|
||||
Define_Code(Expr);
|
||||
Define_Code(Expr_Assign);
|
||||
Define_Code(Expr_Alignof);
|
||||
Define_Code(Expr_Binary);
|
||||
Define_Code(Expr_CStyleCast);
|
||||
Define_Code(Expr_FunctionalCast);
|
||||
Define_Code(Expr_CppCast);
|
||||
Define_Code(Expr_Element);
|
||||
Define_Code(Expr_ProcCall);
|
||||
Define_Code(Expr_Decltype);
|
||||
Define_Code(Expr_Comma);
|
||||
Define_Code(Expr_AMS); // Access Member Symbol
|
||||
Define_Code(Expr_Sizeof);
|
||||
Define_Code(Expr_Subscript);
|
||||
Define_Code(Expr_Ternary);
|
||||
Define_Code(Expr_UnaryPrefix);
|
||||
Define_Code(Expr_UnaryPostfix);
|
||||
|
||||
Define_Code(Stmt);
|
||||
Define_Code(Stmt_Break);
|
||||
Define_Code(Stmt_Case);
|
||||
Define_Code(Stmt_Continue);
|
||||
Define_Code(Stmt_Decl);
|
||||
Define_Code(Stmt_Do);
|
||||
Define_Code(Stmt_Expr);
|
||||
Define_Code(Stmt_Else);
|
||||
Define_Code(Stmt_If);
|
||||
Define_Code(Stmt_For);
|
||||
Define_Code(Stmt_Goto);
|
||||
Define_Code(Stmt_Label);
|
||||
Define_Code(Stmt_Switch);
|
||||
Define_Code(Stmt_While);
|
||||
#endif
|
||||
|
||||
Define_Code(Struct);
|
||||
Define_Code(Template);
|
||||
Define_Code(Typename);
|
||||
Define_Code(Typedef);
|
||||
Define_Code(Union);
|
||||
Define_Code(Using);
|
||||
Define_Code(Var);
|
||||
#undef Define_Code
|
||||
|
||||
GEN_NS_PARSER_BEGIN
|
||||
struct Token;
|
||||
GEN_NS_PARSER_END
|
||||
|
||||
#if ! GEN_COMPILER_C
|
||||
template< class Type> forceinline Type tmpl_cast( Code self ) { return * rcast( Type*, & self ); }
|
||||
#endif
|
||||
|
||||
#pragma region Code Interface
|
||||
void append (Code code, Code other );
|
||||
char const* debug_str (Code code);
|
||||
Code duplicate (Code code);
|
||||
Code* entry (Code code, u32 idx );
|
||||
bool has_entries (Code code);
|
||||
bool is_body (Code code);
|
||||
bool is_equal (Code code, Code other);
|
||||
bool is_valid (Code code);
|
||||
void set_global (Code code);
|
||||
String to_string (Code self );
|
||||
void to_string (Code self, String* result );
|
||||
char const* type_str (Code self );
|
||||
bool validate_body(Code self );
|
||||
#pragma endregion Code Interface
|
||||
|
||||
#if ! GEN_COMPILER_C
|
||||
/*
|
||||
AST* wrapper
|
||||
- Not constantly have to append the '*' as this is written often..
|
||||
@ -153,39 +184,36 @@ namespace parser
|
||||
*/
|
||||
struct Code
|
||||
{
|
||||
# pragma region Statics
|
||||
// Used to identify ASTs that should always be duplicated. (Global constant ASTs)
|
||||
static Code Global;
|
||||
AST* ast;
|
||||
|
||||
// Used to identify invalid generated code.
|
||||
static Code Invalid;
|
||||
# pragma endregion Statics
|
||||
# define Using_Code( Typename ) \
|
||||
char const* debug_str() { return GEN_NS debug_str(* this); } \
|
||||
Code duplicate() { return GEN_NS duplicate(* this); } \
|
||||
bool is_equal( Code other ) { return GEN_NS is_equal(* this, other); } \
|
||||
bool is_body() { return GEN_NS is_body(* this); } \
|
||||
bool is_valid() { return GEN_NS is_valid(* this); } \
|
||||
void set_global() { return GEN_NS set_global(* this); }
|
||||
|
||||
# define Using_Code( Typename ) \
|
||||
char const* debug_str(); \
|
||||
Code duplicate(); \
|
||||
bool is_equal( Code other ); \
|
||||
bool is_valid(); \
|
||||
void set_global(); \
|
||||
String to_string(); \
|
||||
Typename& operator = ( AST* other ); \
|
||||
Typename& operator = ( Code other ); \
|
||||
bool operator ==( Code other ); \
|
||||
bool operator !=( Code other ); \
|
||||
# define Using_CodeOps( Typename ) \
|
||||
Typename& operator = ( Code other ); \
|
||||
bool operator ==( Code other ) { return (AST*)ast == other.ast; } \
|
||||
bool operator !=( Code other ) { return (AST*)ast != other.ast; } \
|
||||
operator bool();
|
||||
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( Code );
|
||||
void append(Code other) { return GEN_NS append(* this, other); }
|
||||
Code* entry(u32 idx) { return GEN_NS entry(* this, idx); }
|
||||
bool has_entries() { return GEN_NS has_entries(* this); }
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
void to_string(String& result) { return GEN_NS to_string(* this, & result); }
|
||||
char const* type_str() { return GEN_NS type_str(* this); }
|
||||
bool validate_body() { return GEN_NS validate_body(*this); }
|
||||
#endif
|
||||
|
||||
template< class Type >
|
||||
forceinline Type cast()
|
||||
{
|
||||
return * rcast( Type*, this );
|
||||
}
|
||||
Using_CodeOps( Code );
|
||||
|
||||
AST* operator ->()
|
||||
{
|
||||
return ast;
|
||||
}
|
||||
AST* operator ->() { return ast; }
|
||||
Code& operator ++();
|
||||
|
||||
// TODO(Ed) : Remove this overload.
|
||||
@ -200,7 +228,10 @@ struct Code
|
||||
return *this;
|
||||
}
|
||||
|
||||
AST* ast;
|
||||
bool operator==(std::nullptr_t) const { return ast == nullptr; }
|
||||
bool operator!=(std::nullptr_t) const { return ast != nullptr; }
|
||||
friend bool operator==(std::nullptr_t, const Code code) { return code.ast == nullptr; }
|
||||
friend bool operator!=(std::nullptr_t, const Code code) { return code.ast != nullptr; }
|
||||
|
||||
#ifdef GEN_ENFORCE_STRONG_CODE_TYPES
|
||||
# define operator explicit operator
|
||||
@ -229,228 +260,122 @@ struct Code
|
||||
operator CodeSpecifiers() const;
|
||||
operator CodeStruct() const;
|
||||
operator CodeTemplate() const;
|
||||
operator CodeType() const;
|
||||
operator CodeTypename() const;
|
||||
operator CodeTypedef() const;
|
||||
operator CodeUnion() const;
|
||||
operator CodeUsing() const;
|
||||
operator CodeVar() const;
|
||||
#undef operator
|
||||
};
|
||||
#endif
|
||||
|
||||
#pragma region Statics
|
||||
// Used to identify ASTs that should always be duplicated. (Global constant ASTs)
|
||||
extern Code Code_Global;
|
||||
|
||||
// Used to identify invalid generated code.
|
||||
extern Code Code_Invalid;
|
||||
#pragma endregion Statics
|
||||
|
||||
struct Code_POD
|
||||
{
|
||||
AST* ast;
|
||||
};
|
||||
|
||||
static_assert( sizeof(Code) == sizeof(Code_POD), "ERROR: Code is not POD" );
|
||||
|
||||
// Desired width of the AST data structure.
|
||||
constexpr int const AST_POD_Size = 128;
|
||||
|
||||
constexpr static
|
||||
int AST_ArrSpecs_Cap =
|
||||
(
|
||||
AST_POD_Size
|
||||
- sizeof(AST*) * 3
|
||||
- sizeof(parser::Token*)
|
||||
- sizeof(AST*)
|
||||
- sizeof(StringCached)
|
||||
- sizeof(CodeType)
|
||||
- sizeof(ModuleFlag)
|
||||
- sizeof(int)
|
||||
)
|
||||
/ sizeof(int) - 1; // -1 for 4 extra bytes
|
||||
|
||||
/*
|
||||
Simple AST POD with functionality to seralize into C++ syntax.
|
||||
*/
|
||||
struct AST
|
||||
{
|
||||
# pragma region Member Functions
|
||||
void append ( AST* other );
|
||||
char const* debug_str ();
|
||||
AST* duplicate ();
|
||||
Code& entry ( u32 idx );
|
||||
bool has_entries();
|
||||
bool is_equal ( AST* other );
|
||||
char const* type_str();
|
||||
bool validate_body();
|
||||
|
||||
String to_string();
|
||||
|
||||
neverinline
|
||||
void to_string( String& result );
|
||||
|
||||
template< class Type >
|
||||
forceinline Type cast()
|
||||
{
|
||||
return * this;
|
||||
}
|
||||
|
||||
operator Code();
|
||||
operator CodeBody();
|
||||
operator CodeAttributes();
|
||||
// operator CodeBaseClass();
|
||||
operator CodeComment();
|
||||
operator CodeConstructor();
|
||||
operator CodeDestructor();
|
||||
operator CodeClass();
|
||||
operator CodeDefine();
|
||||
operator CodeEnum();
|
||||
operator CodeExec();
|
||||
operator CodeExtern();
|
||||
operator CodeInclude();
|
||||
operator CodeFriend();
|
||||
operator CodeFn();
|
||||
operator CodeModule();
|
||||
operator CodeNS();
|
||||
operator CodeOperator();
|
||||
operator CodeOpCast();
|
||||
operator CodeParam();
|
||||
operator CodePragma();
|
||||
operator CodePreprocessCond();
|
||||
operator CodeSpecifiers();
|
||||
operator CodeStruct();
|
||||
operator CodeTemplate();
|
||||
operator CodeType();
|
||||
operator CodeTypedef();
|
||||
operator CodeUnion();
|
||||
operator CodeUsing();
|
||||
operator CodeVar();
|
||||
# pragma endregion Member Functions
|
||||
|
||||
constexpr static
|
||||
int ArrSpecs_Cap =
|
||||
(
|
||||
AST_POD_Size
|
||||
- sizeof(AST*) * 3
|
||||
- sizeof(parser::Token*)
|
||||
- sizeof(AST*)
|
||||
- sizeof(StringCached)
|
||||
- sizeof(CodeT)
|
||||
- sizeof(ModuleFlag)
|
||||
- sizeof(int)
|
||||
)
|
||||
/ sizeof(int) - 1; // -1 for 4 extra bytes
|
||||
|
||||
union {
|
||||
struct
|
||||
{
|
||||
AST* InlineCmt; // Class, Constructor, Destructor, Enum, Friend, Functon, Operator, OpCast, Struct, Typedef, Using, Variable
|
||||
AST* Attributes; // Class, Enum, Function, Struct, Typedef, Union, Using, Variable
|
||||
AST* Specs; // Destructor, Function, Operator, Typename, Variable
|
||||
Code InlineCmt; // Class, Constructor, Destructor, Enum, Friend, Functon, Operator, OpCast, Struct, Typedef, Using, Variable
|
||||
Code Attributes; // Class, Enum, Function, Struct, Typedef, Union, Using, Variable
|
||||
Code Specs; // Destructor, Function, Operator, Typename, Variable
|
||||
union {
|
||||
AST* InitializerList; // Constructor
|
||||
AST* ParentType; // Class, Struct, ParentType->Next has a possible list of interfaces.
|
||||
AST* ReturnType; // Function, Operator, Typename
|
||||
AST* UnderlyingType; // Enum, Typedef
|
||||
AST* ValueType; // Parameter, Variable
|
||||
Code InitializerList; // Constructor
|
||||
Code ParentType; // Class, Struct, ParentType->Next has a possible list of interfaces.
|
||||
Code ReturnType; // Function, Operator, Typename
|
||||
Code UnderlyingType; // Enum, Typedef
|
||||
Code ValueType; // Parameter, Variable
|
||||
};
|
||||
union {
|
||||
AST* Macro; // Parameter
|
||||
AST* BitfieldSize; // Variable (Class/Struct Data Member)
|
||||
AST* Params; // Constructor, Function, Operator, Template, Typename
|
||||
Code Macro; // Parameter
|
||||
Code BitfieldSize; // Variable (Class/Struct Data Member)
|
||||
Code Params; // Constructor, Function, Operator, Template, Typename
|
||||
};
|
||||
union {
|
||||
AST* ArrExpr; // Typename
|
||||
AST* Body; // Class, Constructr, Destructor, Enum, Friend, Function, Namespace, Struct, Union
|
||||
AST* Declaration; // Friend, Template
|
||||
AST* Value; // Parameter, Variable
|
||||
Code ArrExpr; // Typename
|
||||
Code Body; // Class, Constructor, Destructor, Enum, Friend, Function, Namespace, Struct, Union
|
||||
Code Declaration; // Friend, Template
|
||||
Code Value; // Parameter, Variable
|
||||
};
|
||||
union {
|
||||
AST* NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value )
|
||||
AST* SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed )
|
||||
Code NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value )
|
||||
Code SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed )
|
||||
Code PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal)
|
||||
};
|
||||
};
|
||||
StringCached Content; // Attributes, Comment, Execution, Include
|
||||
struct {
|
||||
SpecifierT ArrSpecs[ArrSpecs_Cap]; // Specifiers
|
||||
AST* NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used.
|
||||
Specifier ArrSpecs[AST_ArrSpecs_Cap]; // Specifiers
|
||||
Code NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used.
|
||||
};
|
||||
};
|
||||
union {
|
||||
AST* Prev;
|
||||
AST* Front;
|
||||
AST* Last;
|
||||
Code Prev;
|
||||
Code Front;
|
||||
Code Last;
|
||||
};
|
||||
union {
|
||||
AST* Next;
|
||||
AST* Back;
|
||||
Code Next;
|
||||
Code Back;
|
||||
};
|
||||
parser::Token* Token; // Reference to starting token, only avaialble if it was derived from parsing.
|
||||
AST* Parent;
|
||||
Code Parent;
|
||||
StringCached Name;
|
||||
CodeT Type;
|
||||
CodeType Type;
|
||||
// CodeFlag CodeFlags;
|
||||
ModuleFlag ModuleFlags;
|
||||
union {
|
||||
b32 IsFunction; // Used by typedef to not serialize the name field.
|
||||
b32 IsParamPack; // Used by typename to know if type should be considered a parameter pack.
|
||||
OperatorT Op;
|
||||
Operator Op;
|
||||
AccessSpec ParentAccess;
|
||||
s32 NumEntries;
|
||||
s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression.
|
||||
b32 EnumUnderlyingMacro; // Used by enums incase the user wants to wrap underlying type specification in a macro
|
||||
};
|
||||
};
|
||||
static_assert( sizeof(AST) == AST_POD_Size, "ERROR: AST POD is not size of AST_POD_Size" );
|
||||
|
||||
struct AST_POD
|
||||
{
|
||||
union {
|
||||
struct
|
||||
{
|
||||
AST* InlineCmt; // Class, Constructor, Destructor, Enum, Friend, Functon, Operator, OpCast, Struct, Typedef, Using, Variable
|
||||
AST* Attributes; // Class, Enum, Function, Struct, Typedef, Union, Using, Variable
|
||||
AST* Specs; // Destructor, Function, Operator, Typename, Variable
|
||||
union {
|
||||
AST* InitializerList; // Constructor
|
||||
AST* ParentType; // Class, Struct, ParentType->Next has a possible list of interfaces.
|
||||
AST* ReturnType; // Function, Operator, Typename
|
||||
AST* UnderlyingType; // Enum, Typedef
|
||||
AST* ValueType; // Parameter, Variable
|
||||
};
|
||||
union {
|
||||
AST* Macro; // Parameter
|
||||
AST* BitfieldSize; // Variable (Class/Struct Data Member)
|
||||
AST* Params; // Constructor, Function, Operator, Template, Typename
|
||||
};
|
||||
union {
|
||||
AST* ArrExpr; // Typename
|
||||
AST* Body; // Class, Constructr, Destructor, Enum, Friend, Function, Namespace, Struct, Union
|
||||
AST* Declaration; // Friend, Template
|
||||
AST* Value; // Parameter, Variable
|
||||
};
|
||||
union {
|
||||
AST* NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value )
|
||||
AST* SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed )
|
||||
};
|
||||
};
|
||||
StringCached Content; // Attributes, Comment, Execution, Include
|
||||
struct {
|
||||
SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers
|
||||
AST* NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used.
|
||||
};
|
||||
};
|
||||
union {
|
||||
AST* Prev;
|
||||
AST* Front;
|
||||
AST* Last;
|
||||
};
|
||||
union {
|
||||
AST* Next;
|
||||
AST* Back;
|
||||
};
|
||||
parser::Token* Token; // Reference to starting token, only avaialble if it was derived from parsing.
|
||||
AST* Parent;
|
||||
StringCached Name;
|
||||
CodeT Type;
|
||||
CodeFlag CodeFlags;
|
||||
ModuleFlag ModuleFlags;
|
||||
union {
|
||||
b32 IsFunction; // Used by typedef to not serialize the name field.
|
||||
b32 IsParamPack; // Used by typename to know if type should be considered a parameter pack.
|
||||
OperatorT Op;
|
||||
AccessSpec ParentAccess;
|
||||
s32 NumEntries;
|
||||
};
|
||||
};
|
||||
|
||||
struct test {
|
||||
SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers
|
||||
AST* NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used.
|
||||
};
|
||||
|
||||
constexpr int pls = sizeof(test);
|
||||
|
||||
// Its intended for the AST to have equivalent size to its POD.
|
||||
// All extra functionality within the AST namespace should just be syntatic sugar.
|
||||
static_assert( sizeof(AST) == sizeof(AST_POD), "ERROR: AST IS NOT POD" );
|
||||
static_assert( sizeof(AST_POD) == AST_POD_Size, "ERROR: AST POD is not size of AST_POD_Size" );
|
||||
#if ! GEN_COMPILER_C
|
||||
// Uses an implicitly overloaded cast from the AST to the desired code type.
|
||||
// Necessary if the user wants GEN_ENFORCE_STRONG_CODE_TYPES
|
||||
struct InvalidCode_ImplictCaster;
|
||||
#define InvalidCode (InvalidCode_ImplictCaster{})
|
||||
#else
|
||||
#define InvalidCode Code_Invalid
|
||||
#endif
|
||||
|
||||
// Used when the its desired when omission is allowed in a definition.
|
||||
#define NoCode { nullptr }
|
||||
#define CodeInvalid (* Code::Invalid.ast) // Uses an implicitly overloaded cast from the AST to the desired code type.
|
||||
#define NullCode { nullptr }
|
||||
|
@ -1,78 +1,78 @@
|
||||
# define GEN_AST_BODY_CLASS_UNALLOWED_TYPES \
|
||||
case PlatformAttributes: \
|
||||
case Class_Body: \
|
||||
case Enum_Body: \
|
||||
case Extern_Linkage: \
|
||||
case Function_Body: \
|
||||
case Function_Fwd: \
|
||||
case Global_Body: \
|
||||
case Namespace: \
|
||||
case Namespace_Body: \
|
||||
case Operator: \
|
||||
case Operator_Fwd: \
|
||||
case Parameters: \
|
||||
case Specifiers: \
|
||||
case Struct_Body: \
|
||||
case Typename:
|
||||
case CT_PlatformAttributes: \
|
||||
case CT_Class_Body: \
|
||||
case CT_Enum_Body: \
|
||||
case CT_Extern_Linkage: \
|
||||
case CT_Function_Body: \
|
||||
case CT_Function_Fwd: \
|
||||
case CT_Global_Body: \
|
||||
case CT_Namespace: \
|
||||
case CT_Namespace_Body: \
|
||||
case CT_Operator: \
|
||||
case CT_Operator_Fwd: \
|
||||
case CT_Parameters: \
|
||||
case CT_Specifiers: \
|
||||
case CT_Struct_Body: \
|
||||
case CT_Typename:
|
||||
# define GEN_AST_BODY_STRUCT_UNALLOWED_TYPES GEN_AST_BODY_CLASS_UNALLOWED_TYPES
|
||||
|
||||
# define GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES \
|
||||
case Access_Public: \
|
||||
case Access_Protected: \
|
||||
case Access_Private: \
|
||||
case PlatformAttributes: \
|
||||
case Class_Body: \
|
||||
case Enum_Body: \
|
||||
case Extern_Linkage: \
|
||||
case Friend: \
|
||||
case Function_Body: \
|
||||
case Function_Fwd: \
|
||||
case Global_Body: \
|
||||
case Namespace: \
|
||||
case Namespace_Body: \
|
||||
case Operator: \
|
||||
case Operator_Fwd: \
|
||||
case Operator_Member: \
|
||||
case Operator_Member_Fwd: \
|
||||
case Parameters: \
|
||||
case Specifiers: \
|
||||
case Struct_Body: \
|
||||
case Typename:
|
||||
case CT_Access_Public: \
|
||||
case CT_Access_Protected: \
|
||||
case CT_Access_Private: \
|
||||
case CT_PlatformAttributes: \
|
||||
case CT_Class_Body: \
|
||||
case CT_Enum_Body: \
|
||||
case CT_Extern_Linkage: \
|
||||
case CT_Friend: \
|
||||
case CT_Function_Body: \
|
||||
case CT_Function_Fwd: \
|
||||
case CT_Global_Body: \
|
||||
case CT_Namespace: \
|
||||
case CT_Namespace_Body: \
|
||||
case CT_Operator: \
|
||||
case CT_Operator_Fwd: \
|
||||
case CT_Operator_Member: \
|
||||
case CT_Operator_Member_Fwd: \
|
||||
case CT_Parameters: \
|
||||
case CT_Specifiers: \
|
||||
case CT_Struct_Body: \
|
||||
case CT_Typename:
|
||||
|
||||
# define GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES \
|
||||
case Access_Public: \
|
||||
case Access_Protected: \
|
||||
case Access_Private: \
|
||||
case PlatformAttributes: \
|
||||
case Class_Body: \
|
||||
case Enum_Body: \
|
||||
case Execution: \
|
||||
case Friend: \
|
||||
case Function_Body: \
|
||||
case Namespace_Body: \
|
||||
case Operator_Member: \
|
||||
case Operator_Member_Fwd: \
|
||||
case Parameters: \
|
||||
case Specifiers: \
|
||||
case Struct_Body: \
|
||||
case Typename:
|
||||
# define GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES \
|
||||
case CT_Access_Public: \
|
||||
case CT_Access_Protected: \
|
||||
case CT_Access_Private: \
|
||||
case CT_PlatformAttributes: \
|
||||
case CT_Class_Body: \
|
||||
case CT_Enum_Body: \
|
||||
case CT_Execution: \
|
||||
case CT_Friend: \
|
||||
case CT_Function_Body: \
|
||||
case CT_Namespace_Body: \
|
||||
case CT_Operator_Member: \
|
||||
case CT_Operator_Member_Fwd: \
|
||||
case CT_Parameters: \
|
||||
case CT_Specifiers: \
|
||||
case CT_Struct_Body: \
|
||||
case CT_Typename:
|
||||
# define GEN_AST_BODY_EXPORT_UNALLOWED_TYPES GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES
|
||||
# define GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES
|
||||
|
||||
# define GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES \
|
||||
case Access_Public: \
|
||||
case Access_Protected: \
|
||||
case Access_Private: \
|
||||
case PlatformAttributes: \
|
||||
case Class_Body: \
|
||||
case Enum_Body: \
|
||||
case Execution: \
|
||||
case Friend: \
|
||||
case Function_Body: \
|
||||
case Namespace_Body: \
|
||||
case Operator_Member: \
|
||||
case Operator_Member_Fwd: \
|
||||
case Parameters: \
|
||||
case Specifiers: \
|
||||
case Struct_Body: \
|
||||
case Typename:
|
||||
case CT_Access_Public: \
|
||||
case CT_Access_Protected: \
|
||||
case CT_Access_Private: \
|
||||
case CT_PlatformAttributes: \
|
||||
case CT_Class_Body: \
|
||||
case CT_Enum_Body: \
|
||||
case CT_Execution: \
|
||||
case CT_Friend: \
|
||||
case CT_Function_Body: \
|
||||
case CT_Namespace_Body: \
|
||||
case CT_Operator_Member: \
|
||||
case CT_Operator_Member_Fwd: \
|
||||
case CT_Parameters: \
|
||||
case CT_Specifiers: \
|
||||
case CT_Struct_Body: \
|
||||
case CT_Typename:
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -3,75 +3,168 @@
|
||||
#include "ast.hpp"
|
||||
#endif
|
||||
|
||||
#pragma region Code Type Interface
|
||||
void append ( CodeBody body, Code other );
|
||||
void append ( CodeBody body, CodeBody other );
|
||||
String to_string ( CodeBody body );
|
||||
void to_string ( CodeBody body, String* result );
|
||||
void to_string_export ( CodeBody body, String* result );
|
||||
|
||||
Code begin( CodeBody body);
|
||||
Code end ( CodeBody body );
|
||||
|
||||
void add_interface( CodeClass self, CodeType interface );
|
||||
String to_string ( CodeClass self );
|
||||
void to_string_def( CodeClass self, String* result );
|
||||
void to_string_fwd( CodeClass self, String* result );
|
||||
|
||||
void append (CodeParam params, CodeParam param );
|
||||
CodeParam get (CodeParam params, s32 idx);
|
||||
bool has_entries(CodeParam params );
|
||||
String to_string (CodeParam params );
|
||||
void to_string (CodeParam params, String* result );
|
||||
|
||||
CodeParam begin(CodeParam params);
|
||||
CodeParam end (CodeParam params);
|
||||
|
||||
bool append (CodeSpecifiers specifiers, Specifier spec);
|
||||
s32 has (CodeSpecifiers specifiers, Specifier spec);
|
||||
s32 remove (CodeSpecifiers specifiers, Specifier to_remove );
|
||||
String to_string(CodeSpecifiers specifiers);
|
||||
void to_string(CodeSpecifiers specifiers, String* result);
|
||||
|
||||
Specifier* begin(CodeSpecifiers specifiers );
|
||||
Specifier* end (CodeSpecifiers specifiers);
|
||||
|
||||
void add_interface(CodeStruct self, CodeType interface);
|
||||
String to_string (CodeStruct self);
|
||||
void to_string_fwd(CodeStruct self, String* result);
|
||||
void to_string_def(CodeStruct self, String* result);
|
||||
|
||||
String to_string(CodeAttributes attributes);
|
||||
String to_string(CodeComment comment );
|
||||
|
||||
String to_string (CodeConstructor constructor);
|
||||
void to_string_def(CodeConstructor constructor, String* result );
|
||||
void to_string_fwd(CodeConstructor constructor, String* result );
|
||||
|
||||
String to_string(CodeDefine define);
|
||||
void to_string(CodeDefine define, String* result);
|
||||
|
||||
String to_string (CodeDestructor destructor);
|
||||
void to_string_def(CodeDestructor destructor, String* result );
|
||||
void to_string_fwd(CodeDestructor destructor, String* result );
|
||||
|
||||
String to_string (CodeEnum self);
|
||||
void to_string_def (CodeEnum self, String* result );
|
||||
void to_string_fwd (CodeEnum self, String* result );
|
||||
void to_string_class_def(CodeEnum self, String* result );
|
||||
void to_string_class_fwd(CodeEnum self, String* result );
|
||||
|
||||
String to_string(CodeExec exec);
|
||||
|
||||
void to_string(CodeExtern self, String* result);
|
||||
|
||||
String to_string(CodeInclude include);
|
||||
void to_string(CodeInclude include, String* result);
|
||||
|
||||
String to_string(CodeFriend self);
|
||||
void to_string(CodeFriend self, String* result);
|
||||
|
||||
String to_string (CodeFn self);
|
||||
void to_string_def(CodeFn self, String* result);
|
||||
void to_string_fwd(CodeFn self, String* result);
|
||||
|
||||
String to_string(CodeModule self);
|
||||
void to_string(CodeModule self, String* result);
|
||||
|
||||
String to_string(CodeNS self);
|
||||
void to_string(CodeNS self, String* result);
|
||||
|
||||
String to_string (CodeOperator self);
|
||||
void to_string_fwd(CodeOperator self, String* result );
|
||||
void to_string_def(CodeOperator self, String* result );
|
||||
|
||||
String to_string (CodeOpCast op_cast );
|
||||
void to_string_def(CodeOpCast op_cast, String* result );
|
||||
void to_string_fwd(CodeOpCast op_cast, String* result );
|
||||
|
||||
String to_string(CodePragma self);
|
||||
void to_string(CodePragma self, String* result);
|
||||
|
||||
String to_string (CodePreprocessCond cond);
|
||||
void to_string_if (CodePreprocessCond cond, String* result );
|
||||
void to_string_ifdef (CodePreprocessCond cond, String* result );
|
||||
void to_string_ifndef(CodePreprocessCond cond, String* result );
|
||||
void to_string_elif (CodePreprocessCond cond, String* result );
|
||||
void to_string_else (CodePreprocessCond cond, String* result );
|
||||
void to_string_endif (CodePreprocessCond cond, String* result );
|
||||
|
||||
String to_string(CodeTemplate self);
|
||||
void to_string(CodeTemplate self, String* result);
|
||||
|
||||
String to_string(CodeTypename self);
|
||||
void to_string(CodeTypename self, String* result);
|
||||
|
||||
String to_string(CodeTypedef self);
|
||||
void to_string(CodeTypedef self, String* result);
|
||||
|
||||
String to_string(CodeUnion self);
|
||||
void to_string(CodeUnion self, String* result);
|
||||
|
||||
String to_string (CodeUsing op_cast );
|
||||
void to_string (CodeUsing op_cast, String* result );
|
||||
void to_string_ns(CodeUsing op_cast, String* result );
|
||||
|
||||
String to_string(CodeVar self);
|
||||
void to_string(CodeVar self, String* result);
|
||||
#pragma endregion Code Type Interface
|
||||
|
||||
#pragma region Code Types
|
||||
// These structs are not used at all by the C vairant.
|
||||
#if ! GEN_COMPILER_C
|
||||
// stati_assert( GEN_COMPILER_C, "This should not be compiled with the C-library" );
|
||||
|
||||
#define Verify_POD(Type) static_assert(size_of(Code##Type) == size_of(AST_##Type), "ERROR: Code##Type is not a POD")
|
||||
|
||||
struct CodeBody
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeBody );
|
||||
|
||||
void append( Code other )
|
||||
{
|
||||
raw()->append( other.ast );
|
||||
}
|
||||
void append( CodeBody body )
|
||||
{
|
||||
for ( Code entry : body )
|
||||
{
|
||||
append( entry );
|
||||
}
|
||||
}
|
||||
bool has_entries()
|
||||
{
|
||||
return rcast( AST*, ast )->has_entries();
|
||||
}
|
||||
void to_string( String& result );
|
||||
void to_string_export( String& result );
|
||||
AST* raw()
|
||||
{
|
||||
return rcast( AST*, ast );
|
||||
}
|
||||
AST_Body* operator->()
|
||||
{
|
||||
return ast;
|
||||
}
|
||||
operator Code()
|
||||
{
|
||||
return * rcast( Code*, this );
|
||||
}
|
||||
#pragma region Iterator
|
||||
Code begin()
|
||||
{
|
||||
if ( ast )
|
||||
return { rcast( AST*, ast)->Front };
|
||||
void append( Code other ) { return GEN_NS append( *this, other ); }
|
||||
void append( CodeBody body ) { return GEN_NS append(*this, body); }
|
||||
bool has_entries() { return GEN_NS has_entries(* this); }
|
||||
|
||||
return { nullptr };
|
||||
}
|
||||
Code end()
|
||||
{
|
||||
return { rcast(AST*, ast)->Back->Next };
|
||||
}
|
||||
#pragma endregion Iterator
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
void to_string( String& result ) { return GEN_NS to_string(* this, & result ); }
|
||||
void to_string_export( String& result ) { return GEN_NS to_string_export(* this, & result); }
|
||||
|
||||
Code begin() { return GEN_NS begin(* this); }
|
||||
Code end() { return GEN_NS end(* this); }
|
||||
#endif
|
||||
|
||||
Using_CodeOps( CodeBody );
|
||||
operator Code() { return * rcast( Code*, this ); }
|
||||
AST_Body* operator->() { return ast; }
|
||||
|
||||
AST_Body* ast;
|
||||
};
|
||||
|
||||
struct CodeClass
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeClass );
|
||||
|
||||
void add_interface( CodeType interface );
|
||||
|
||||
void to_string_def( String& result );
|
||||
void to_string_fwd( String& result );
|
||||
String to_string();
|
||||
void to_string_def( String& result );
|
||||
void to_string_fwd( String& result );
|
||||
#endif
|
||||
|
||||
AST* raw()
|
||||
{
|
||||
return rcast( AST*, ast );
|
||||
}
|
||||
operator Code()
|
||||
{
|
||||
return * rcast( Code*, this );
|
||||
}
|
||||
Using_CodeOps( CodeClass );
|
||||
operator Code() { return * rcast( Code*, this ); }
|
||||
AST_Class* operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
@ -86,17 +179,17 @@ struct CodeClass
|
||||
|
||||
struct CodeParam
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeParam );
|
||||
|
||||
void append( CodeParam other );
|
||||
|
||||
void append( CodeParam other );
|
||||
CodeParam get( s32 idx );
|
||||
bool has_entries();
|
||||
void to_string( String& result );
|
||||
AST* raw()
|
||||
{
|
||||
return rcast( AST*, ast );
|
||||
}
|
||||
bool has_entries();
|
||||
String to_string();
|
||||
void to_string( String& result );
|
||||
#endif
|
||||
|
||||
Using_CodeOps( CodeParam );
|
||||
AST_Param* operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
@ -106,70 +199,27 @@ struct CodeParam
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
operator Code()
|
||||
{
|
||||
return { (AST*)ast };
|
||||
}
|
||||
#pragma region Iterator
|
||||
CodeParam begin()
|
||||
{
|
||||
if ( ast )
|
||||
return { ast };
|
||||
|
||||
return { nullptr };
|
||||
}
|
||||
CodeParam end()
|
||||
{
|
||||
// return { (AST_Param*) rcast( AST*, ast)->Last };
|
||||
return { nullptr };
|
||||
}
|
||||
operator Code() { return { (AST*)ast }; }
|
||||
CodeParam operator*() { return * this; }
|
||||
CodeParam& operator++();
|
||||
CodeParam operator*()
|
||||
{
|
||||
return * this;
|
||||
}
|
||||
#pragma endregion Iterator
|
||||
|
||||
AST_Param* ast;
|
||||
};
|
||||
|
||||
struct CodeSpecifiers
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeSpecifiers );
|
||||
|
||||
bool append( SpecifierT spec )
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure("CodeSpecifiers: Attempted to append to a null specifiers AST!");
|
||||
return false;
|
||||
}
|
||||
bool append( Specifier spec ) { return GEN_NS append(* this, spec); }
|
||||
s32 has( Specifier spec ) { return GEN_NS has(* this, spec); }
|
||||
s32 remove( Specifier to_remove ) { return GEN_NS remove(* this, to_remove); }
|
||||
String to_string() { return GEN_NS to_string(* this ); }
|
||||
void to_string( String& result ) { return GEN_NS to_string(* this, & result); }
|
||||
#endif
|
||||
|
||||
if ( raw()->NumEntries == AST::ArrSpecs_Cap )
|
||||
{
|
||||
log_failure("CodeSpecifiers: Attempted to append over %d specifiers to a specifiers AST!", AST::ArrSpecs_Cap );
|
||||
return false;
|
||||
}
|
||||
|
||||
raw()->ArrSpecs[ raw()->NumEntries ] = spec;
|
||||
raw()->NumEntries++;
|
||||
return true;
|
||||
}
|
||||
s32 has( SpecifierT spec )
|
||||
{
|
||||
for ( s32 idx = 0; idx < raw()->NumEntries; idx++ )
|
||||
{
|
||||
if ( raw()->ArrSpecs[ idx ] == spec )
|
||||
return idx;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
void to_string( String& result );
|
||||
AST* raw()
|
||||
{
|
||||
return rcast( AST*, ast );
|
||||
}
|
||||
Using_CodeOps(CodeSpecifiers);
|
||||
operator Code() { return { (AST*) ast }; }
|
||||
AST_Specifiers* operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
@ -179,44 +229,24 @@ struct CodeSpecifiers
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
operator Code()
|
||||
{
|
||||
return { (AST*) ast };
|
||||
}
|
||||
#pragma region Iterator
|
||||
SpecifierT* begin()
|
||||
{
|
||||
if ( ast )
|
||||
return & raw()->ArrSpecs[0];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
SpecifierT* end()
|
||||
{
|
||||
return raw()->ArrSpecs + raw()->NumEntries;
|
||||
}
|
||||
#pragma endregion Iterator
|
||||
|
||||
AST_Specifiers* ast;
|
||||
};
|
||||
|
||||
struct CodeStruct
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeStruct );
|
||||
|
||||
void add_interface( CodeType interface );
|
||||
|
||||
void to_string_def( String& result );
|
||||
void to_string_fwd( String& result );
|
||||
String to_string();
|
||||
void to_string_fwd( String& result );
|
||||
void to_string_def( String& result );
|
||||
#endif
|
||||
|
||||
AST* raw()
|
||||
{
|
||||
return rcast( AST*, ast );
|
||||
}
|
||||
operator Code()
|
||||
{
|
||||
return * rcast( Code*, this );
|
||||
}
|
||||
Using_CodeOps( CodeStruct );
|
||||
operator Code() { return * rcast( Code*, this ); }
|
||||
AST_Struct* operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
@ -229,28 +259,45 @@ struct CodeStruct
|
||||
AST_Struct* ast;
|
||||
};
|
||||
|
||||
#define Define_CodeType( Typename ) \
|
||||
struct Code##Typename \
|
||||
{ \
|
||||
Using_Code( Code ## Typename ); \
|
||||
AST* raw(); \
|
||||
operator Code(); \
|
||||
AST_##Typename* operator->(); \
|
||||
AST_##Typename* ast; \
|
||||
}
|
||||
struct CodeAttributes
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code(CodeAttributes);
|
||||
String to_string();
|
||||
#endif
|
||||
|
||||
Using_CodeOps(CodeAttributes);
|
||||
operator Code();
|
||||
AST_Attributes *operator->();
|
||||
AST_Attributes *ast;
|
||||
};
|
||||
|
||||
Define_CodeType( Attributes );
|
||||
// Define_CodeType( BaseClass );
|
||||
Define_CodeType( Comment );
|
||||
|
||||
struct CodeComment
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code(CodeComment);
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
#endif
|
||||
|
||||
Using_CodeOps(CodeComment);
|
||||
operator Code();
|
||||
AST_Comment *operator->();
|
||||
AST_Comment *ast;
|
||||
};
|
||||
|
||||
struct CodeConstructor
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeConstructor );
|
||||
|
||||
void to_string_def( String& result );
|
||||
void to_string_fwd( String& result );
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
void to_string_def( String& result ) { return GEN_NS to_string_def(* this, & result); }
|
||||
void to_string_fwd( String& result ) { return GEN_NS to_string_fwd(* this, & result); }
|
||||
#endif
|
||||
|
||||
AST* raw();
|
||||
Using_CodeOps(CodeConstructor);
|
||||
operator Code();
|
||||
AST_Constructor* operator->();
|
||||
AST_Constructor* ast;
|
||||
@ -258,11 +305,14 @@ struct CodeConstructor
|
||||
|
||||
struct CodeDefine
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeDefine );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
void to_string( String& result ) { return GEN_NS to_string(* this, & result); }
|
||||
#endif
|
||||
|
||||
AST* raw();
|
||||
Using_CodeOps(CodeDefine);
|
||||
operator Code();
|
||||
AST_Define* operator->();
|
||||
AST_Define* ast;
|
||||
@ -270,12 +320,15 @@ struct CodeDefine
|
||||
|
||||
struct CodeDestructor
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeDestructor );
|
||||
|
||||
void to_string_def( String& result );
|
||||
void to_string_fwd( String& result );
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
void to_string_def( String& result ) { return GEN_NS to_string_def(* this, & result); }
|
||||
void to_string_fwd( String& result ) { return GEN_NS to_string_fwd(* this, & result); }
|
||||
#endif
|
||||
|
||||
AST* raw();
|
||||
Using_CodeOps(CodeDestructor);
|
||||
operator Code();
|
||||
AST_Destructor* operator->();
|
||||
AST_Destructor* ast;
|
||||
@ -283,20 +336,34 @@ struct CodeDestructor
|
||||
|
||||
struct CodeEnum
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeEnum );
|
||||
|
||||
void to_string_def( String& result );
|
||||
void to_string_fwd( String& result );
|
||||
void to_string_class_def( String& result );
|
||||
void to_string_class_fwd( String& result );
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
void to_string_def( String& result ) { return GEN_NS to_string_def(* this, & result); }
|
||||
void to_string_fwd( String& result ) { return GEN_NS to_string_fwd(* this, & result); }
|
||||
void to_string_class_def( String& result ) { return GEN_NS to_string_class_def(* this, & result); }
|
||||
void to_string_class_fwd( String& result ) { return GEN_NS to_string_class_fwd(* this, & result); }
|
||||
#endif
|
||||
|
||||
AST* raw();
|
||||
Using_CodeOps(CodeEnum);
|
||||
operator Code();
|
||||
AST_Enum* operator->();
|
||||
AST_Enum* ast;
|
||||
};
|
||||
|
||||
Define_CodeType( Exec );
|
||||
struct CodeExec
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code(CodeExec);
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
#endif
|
||||
|
||||
Using_CodeOps(CodeExec);
|
||||
operator Code();
|
||||
AST_Exec *operator->();
|
||||
AST_Exec *ast;
|
||||
};
|
||||
|
||||
#if GEN_EXECUTION_EXPRESSION_SUPPORT
|
||||
struct CodeExpr
|
||||
@ -506,11 +573,13 @@ struct CodeExpr_UnaryPostfix
|
||||
|
||||
struct CodeExtern
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeExtern );
|
||||
|
||||
void to_string( String& result );
|
||||
void to_string( String& result ) { return GEN_NS to_string(* this, & result); }
|
||||
#endif
|
||||
|
||||
AST* raw();
|
||||
Using_CodeOps(CodeExtern);
|
||||
operator Code();
|
||||
AST_Extern* operator->();
|
||||
AST_Extern* ast;
|
||||
@ -518,11 +587,14 @@ struct CodeExtern
|
||||
|
||||
struct CodeInclude
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeInclude );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
void to_string( String& result ) { return GEN_NS to_string(* this, & result); }
|
||||
#endif
|
||||
|
||||
AST* raw();
|
||||
Using_CodeOps(CodeInclude);
|
||||
operator Code();
|
||||
AST_Include* operator->();
|
||||
AST_Include* ast;
|
||||
@ -530,11 +602,14 @@ struct CodeInclude
|
||||
|
||||
struct CodeFriend
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeFriend );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
void to_string( String& result ) { return GEN_NS to_string(* this, & result); }
|
||||
#endif
|
||||
|
||||
AST* raw();
|
||||
Using_CodeOps(CodeFriend);
|
||||
operator Code();
|
||||
AST_Friend* operator->();
|
||||
AST_Friend* ast;
|
||||
@ -542,12 +617,15 @@ struct CodeFriend
|
||||
|
||||
struct CodeFn
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeFn );
|
||||
|
||||
void to_string_def( String& result );
|
||||
void to_string_fwd( String& result );
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
void to_string_def( String& result ) { return GEN_NS to_string_def(* this, & result); }
|
||||
void to_string_fwd( String& result ) { return GEN_NS to_string_fwd(* this, & result); }
|
||||
#endif
|
||||
|
||||
AST* raw();
|
||||
Using_CodeOps(CodeFn);
|
||||
operator Code();
|
||||
AST_Fn* operator->();
|
||||
AST_Fn* ast;
|
||||
@ -555,11 +633,14 @@ struct CodeFn
|
||||
|
||||
struct CodeModule
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeModule );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
void to_string( String& result ) { return GEN_NS to_string(* this, & result); }
|
||||
#endif
|
||||
|
||||
AST* raw();
|
||||
Using_CodeOps(CodeModule);
|
||||
operator Code();
|
||||
AST_Module* operator->();
|
||||
AST_Module* ast;
|
||||
@ -567,11 +648,14 @@ struct CodeModule
|
||||
|
||||
struct CodeNS
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeNS );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
void to_string( String& result ) { return GEN_NS to_string(* this, & result); }
|
||||
#endif
|
||||
|
||||
AST* raw();
|
||||
Using_CodeOps(CodeNS);
|
||||
operator Code();
|
||||
AST_NS* operator->();
|
||||
AST_NS* ast;
|
||||
@ -579,12 +663,15 @@ struct CodeNS
|
||||
|
||||
struct CodeOperator
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeOperator );
|
||||
|
||||
void to_string_def( String& result );
|
||||
void to_string_fwd( String& result );
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
void to_string_def( String& result ) { return GEN_NS to_string_def(* this, & result); }
|
||||
void to_string_fwd( String& result ) { return GEN_NS to_string_fwd(* this, & result); }
|
||||
#endif
|
||||
|
||||
AST* raw();
|
||||
Using_CodeOps(CodeOperator);
|
||||
operator Code();
|
||||
AST_Operator* operator->();
|
||||
AST_Operator* ast;
|
||||
@ -592,12 +679,15 @@ struct CodeOperator
|
||||
|
||||
struct CodeOpCast
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeOpCast );
|
||||
|
||||
void to_string_def( String& result );
|
||||
void to_string_fwd( String& result );
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
void to_string_def( String& result ) { return GEN_NS to_string_def(* this, & result); }
|
||||
void to_string_fwd( String& result ) { return GEN_NS to_string_fwd(* this, & result); }
|
||||
#endif
|
||||
|
||||
AST* raw();
|
||||
Using_CodeOps(CodeOpCast);
|
||||
operator Code();
|
||||
AST_OpCast* operator->();
|
||||
AST_OpCast* ast;
|
||||
@ -605,11 +695,14 @@ struct CodeOpCast
|
||||
|
||||
struct CodePragma
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES || 1
|
||||
Using_Code( CodePragma );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
void to_string( String& result ) { return GEN_NS to_string(* this, & result); }
|
||||
#endif
|
||||
|
||||
AST* raw();
|
||||
Using_CodeOps( CodePragma );
|
||||
operator Code();
|
||||
AST_Pragma* operator->();
|
||||
AST_Pragma* ast;
|
||||
@ -617,16 +710,19 @@ struct CodePragma
|
||||
|
||||
struct CodePreprocessCond
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodePreprocessCond );
|
||||
|
||||
void to_string_if( String& result );
|
||||
void to_string_ifdef( String& result );
|
||||
void to_string_ifndef( String& result );
|
||||
void to_string_elif( String& result );
|
||||
void to_string_else( String& result );
|
||||
void to_string_endif( String& result );
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
void to_string_if( String& result ) { return GEN_NS to_string_if(* this, & result); }
|
||||
void to_string_ifdef( String& result ) { return GEN_NS to_string_ifdef(* this, & result); }
|
||||
void to_string_ifndef( String& result ) { return GEN_NS to_string_ifndef(* this, & result); }
|
||||
void to_string_elif( String& result ) { return GEN_NS to_string_elif(* this, & result); }
|
||||
void to_string_else( String& result ) { return GEN_NS to_string_else(* this, & result); }
|
||||
void to_string_endif( String& result ) { return GEN_NS to_string_endif(* this, & result); }
|
||||
#endif
|
||||
|
||||
AST* raw();
|
||||
Using_CodeOps( CodePreprocessCond );
|
||||
operator Code();
|
||||
AST_PreprocessCond* operator->();
|
||||
AST_PreprocessCond* ast;
|
||||
@ -637,7 +733,8 @@ struct CodeStmt
|
||||
{
|
||||
Using_Code( CodeStmt );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string();
|
||||
void to_string( String& result );
|
||||
|
||||
AST* raw();
|
||||
operator Code();
|
||||
@ -649,7 +746,8 @@ struct CodeStmt_Break
|
||||
{
|
||||
Using_Code( CodeStmt_Break );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string();
|
||||
void to_string( String& result );
|
||||
|
||||
AST* raw();
|
||||
operator Code();
|
||||
@ -661,7 +759,8 @@ struct CodeStmt_Case
|
||||
{
|
||||
Using_Code( CodeStmt_Case );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string();
|
||||
void to_string( String& result );
|
||||
|
||||
AST* raw();
|
||||
operator Code();
|
||||
@ -673,7 +772,8 @@ struct CodeStmt_Continue
|
||||
{
|
||||
Using_Code( CodeStmt_Continue );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string();
|
||||
void to_string( String& result );
|
||||
|
||||
AST* raw();
|
||||
operator Code();
|
||||
@ -685,7 +785,8 @@ struct CodeStmt_Decl
|
||||
{
|
||||
Using_Code( CodeStmt_Decl );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string();
|
||||
void to_string( String& result );
|
||||
|
||||
AST* raw();
|
||||
operator Code();
|
||||
@ -697,7 +798,8 @@ struct CodeStmt_Do
|
||||
{
|
||||
Using_Code( CodeStmt_Do );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string();
|
||||
void to_string( String& result );
|
||||
|
||||
AST* raw();
|
||||
operator Code();
|
||||
@ -709,7 +811,8 @@ struct CodeStmt_Expr
|
||||
{
|
||||
Using_Code( CodeStmt_Expr );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string();
|
||||
void to_string( String& result );
|
||||
|
||||
AST* raw();
|
||||
operator Code();
|
||||
@ -721,7 +824,8 @@ struct CodeStmt_Else
|
||||
{
|
||||
Using_Code( CodeStmt_Else );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string();
|
||||
void to_string( String& result );
|
||||
|
||||
AST* raw();
|
||||
operator Code();
|
||||
@ -733,7 +837,8 @@ struct CodeStmt_If
|
||||
{
|
||||
Using_Code( CodeStmt_If );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string();
|
||||
void to_string( String& result );
|
||||
|
||||
AST* raw();
|
||||
operator Code();
|
||||
@ -745,7 +850,8 @@ struct CodeStmt_For
|
||||
{
|
||||
Using_Code( CodeStmt_For );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string();
|
||||
void to_string( String& result );
|
||||
|
||||
AST* raw();
|
||||
operator Code();
|
||||
@ -757,7 +863,8 @@ struct CodeStmt_Goto
|
||||
{
|
||||
Using_Code( CodeStmt_Goto );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string();
|
||||
void to_string( String& result );
|
||||
|
||||
AST* raw();
|
||||
operator Code();
|
||||
@ -769,7 +876,8 @@ struct CodeStmt_Label
|
||||
{
|
||||
Using_Code( CodeStmt_Label );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string();
|
||||
void to_string( String& result );
|
||||
|
||||
AST* raw();
|
||||
operator Code();
|
||||
@ -781,7 +889,8 @@ struct CodeStmt_Switch
|
||||
{
|
||||
Using_Code( CodeStmt_Switch );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string();
|
||||
void to_string( String& result );
|
||||
|
||||
AST* raw();
|
||||
operator Code();
|
||||
@ -793,7 +902,8 @@ struct CodeStmt_While
|
||||
{
|
||||
Using_Code( CodeStmt_While );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string();
|
||||
void to_string( String& result );
|
||||
|
||||
AST* raw();
|
||||
operator Code();
|
||||
@ -804,35 +914,44 @@ struct CodeStmt_While
|
||||
|
||||
struct CodeTemplate
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeTemplate );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
void to_string( String& result ) { return GEN_NS to_string(* this, & result); }
|
||||
#endif
|
||||
|
||||
AST* raw();
|
||||
Using_CodeOps( CodeTemplate );
|
||||
operator Code();
|
||||
AST_Template* operator->();
|
||||
AST_Template* ast;
|
||||
};
|
||||
|
||||
struct CodeType
|
||||
struct CodeTypename
|
||||
{
|
||||
Using_Code( CodeType );
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeTypename );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
void to_string( String& result ) { return GEN_NS to_string(* this, & result); }
|
||||
#endif
|
||||
|
||||
AST* raw();
|
||||
operator Code();
|
||||
AST_Type* operator->();
|
||||
AST_Type* ast;
|
||||
Using_CodeOps( CodeTypename );
|
||||
operator Code();
|
||||
AST_Typename* operator->();
|
||||
AST_Typename* ast;
|
||||
};
|
||||
|
||||
struct CodeTypedef
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeTypedef );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
void to_string( String& result ) { return GEN_NS to_string(* this, & result); }
|
||||
#endif
|
||||
|
||||
AST* raw();
|
||||
Using_CodeOps( CodeTypedef );
|
||||
operator Code();
|
||||
AST_Typedef* operator->();
|
||||
AST_Typedef* ast;
|
||||
@ -840,11 +959,14 @@ struct CodeTypedef
|
||||
|
||||
struct CodeUnion
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeUnion );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
void to_string( String& result ) { return GEN_NS to_string(* this, & result); }
|
||||
#endif
|
||||
|
||||
AST* raw();
|
||||
Using_CodeOps(CodeUnion);
|
||||
operator Code();
|
||||
AST_Union* operator->();
|
||||
AST_Union* ast;
|
||||
@ -852,12 +974,15 @@ struct CodeUnion
|
||||
|
||||
struct CodeUsing
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeUsing );
|
||||
|
||||
void to_string( String& result );
|
||||
void to_string_ns( String& result );
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
void to_string( String& result ) { return GEN_NS to_string(* this, & result); }
|
||||
void to_string_ns( String& result ) { return GEN_NS to_string_ns(* this, & result); }
|
||||
#endif
|
||||
|
||||
AST* raw();
|
||||
Using_CodeOps(CodeUsing);
|
||||
operator Code();
|
||||
AST_Using* operator->();
|
||||
AST_Using* ast;
|
||||
@ -865,11 +990,14 @@ struct CodeUsing
|
||||
|
||||
struct CodeVar
|
||||
{
|
||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
Using_Code( CodeVar );
|
||||
|
||||
void to_string( String& result );
|
||||
String to_string() { return GEN_NS to_string(* this); }
|
||||
void to_string( String& result ) { return GEN_NS to_string(* this, & result); }
|
||||
#endif
|
||||
|
||||
AST* raw();
|
||||
Using_CodeOps(CodeVar);
|
||||
operator Code();
|
||||
AST_Var* operator->();
|
||||
AST_Var* ast;
|
||||
@ -877,5 +1005,48 @@ struct CodeVar
|
||||
|
||||
#undef Define_CodeType
|
||||
#undef Using_Code
|
||||
#undef Using_CodeOps
|
||||
|
||||
#if GEN_SUPPORT_CPP_REFERENCES
|
||||
void to_string_export( CodeBody body, String& result ) { return to_string_export(body, & result); };
|
||||
#endif
|
||||
|
||||
#undef Verify_POD
|
||||
|
||||
struct InvalidCode_ImplictCaster
|
||||
{
|
||||
// operator CodeBaseClass() const;
|
||||
operator Code () const { return Code_Invalid; }
|
||||
operator CodeBody () const { return cast(CodeBody, Code_Invalid); }
|
||||
operator CodeAttributes () const { return cast(CodeAttributes, Code_Invalid); }
|
||||
operator CodeComment () const { return cast(CodeComment, Code_Invalid); }
|
||||
operator CodeClass () const { return cast(CodeClass, Code_Invalid); }
|
||||
operator CodeConstructor () const { return cast(CodeConstructor, Code_Invalid); }
|
||||
operator CodeDefine () const { return cast(CodeDefine, Code_Invalid); }
|
||||
operator CodeDestructor () const { return cast(CodeDestructor, Code_Invalid); }
|
||||
operator CodeExec () const { return cast(CodeExec, Code_Invalid); }
|
||||
operator CodeEnum () const { return cast(CodeEnum, Code_Invalid); }
|
||||
operator CodeExtern () const { return cast(CodeExtern, Code_Invalid); }
|
||||
operator CodeInclude () const { return cast(CodeInclude, Code_Invalid); }
|
||||
operator CodeFriend () const { return cast(CodeFriend, Code_Invalid); }
|
||||
operator CodeFn () const { return cast(CodeFn, Code_Invalid); }
|
||||
operator CodeModule () const { return cast(CodeModule, Code_Invalid); }
|
||||
operator CodeNS () const { return cast(CodeNS, Code_Invalid); }
|
||||
operator CodeOperator () const { return cast(CodeOperator, Code_Invalid); }
|
||||
operator CodeOpCast () const { return cast(CodeOpCast, Code_Invalid); }
|
||||
operator CodeParam () const { return cast(CodeParam, Code_Invalid); }
|
||||
operator CodePragma () const { return cast(CodePragma, Code_Invalid); }
|
||||
operator CodePreprocessCond() const { return cast(CodePreprocessCond, Code_Invalid); }
|
||||
operator CodeSpecifiers () const { return cast(CodeSpecifiers, Code_Invalid); }
|
||||
operator CodeStruct () const { return cast(CodeStruct, Code_Invalid); }
|
||||
operator CodeTemplate () const { return cast(CodeTemplate, Code_Invalid); }
|
||||
operator CodeTypename () const { return cast(CodeTypename, Code_Invalid); }
|
||||
operator CodeTypedef () const { return cast(CodeTypedef, Code_Invalid); }
|
||||
operator CodeUnion () const { return cast(CodeUnion, Code_Invalid); }
|
||||
operator CodeUsing () const { return cast(CodeUsing, Code_Invalid); }
|
||||
operator CodeVar () const { return cast(CodeVar, Code_Invalid); }
|
||||
};
|
||||
|
||||
#endif //if ! GEN_COMPILER_C
|
||||
|
||||
#pragma endregion Code Types
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -5,140 +5,135 @@
|
||||
|
||||
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
|
||||
|
||||
namespace ECode
|
||||
enum CodeType_Def : u32
|
||||
{
|
||||
enum Type : u32
|
||||
{
|
||||
Invalid,
|
||||
Untyped,
|
||||
NewLine,
|
||||
Comment,
|
||||
Access_Private,
|
||||
Access_Protected,
|
||||
Access_Public,
|
||||
PlatformAttributes,
|
||||
Class,
|
||||
Class_Fwd,
|
||||
Class_Body,
|
||||
Constructor,
|
||||
Constructor_Fwd,
|
||||
Destructor,
|
||||
Destructor_Fwd,
|
||||
Enum,
|
||||
Enum_Fwd,
|
||||
Enum_Body,
|
||||
Enum_Class,
|
||||
Enum_Class_Fwd,
|
||||
Execution,
|
||||
Export_Body,
|
||||
Extern_Linkage,
|
||||
Extern_Linkage_Body,
|
||||
Friend,
|
||||
Function,
|
||||
Function_Fwd,
|
||||
Function_Body,
|
||||
Global_Body,
|
||||
Module,
|
||||
Namespace,
|
||||
Namespace_Body,
|
||||
Operator,
|
||||
Operator_Fwd,
|
||||
Operator_Member,
|
||||
Operator_Member_Fwd,
|
||||
Operator_Cast,
|
||||
Operator_Cast_Fwd,
|
||||
Parameters,
|
||||
Preprocess_Define,
|
||||
Preprocess_Include,
|
||||
Preprocess_If,
|
||||
Preprocess_IfDef,
|
||||
Preprocess_IfNotDef,
|
||||
Preprocess_ElIf,
|
||||
Preprocess_Else,
|
||||
Preprocess_EndIf,
|
||||
Preprocess_Pragma,
|
||||
Specifiers,
|
||||
Struct,
|
||||
Struct_Fwd,
|
||||
Struct_Body,
|
||||
Template,
|
||||
Typedef,
|
||||
Typename,
|
||||
Union,
|
||||
Union_Body,
|
||||
Using,
|
||||
Using_Namespace,
|
||||
Variable,
|
||||
NumTypes
|
||||
CT_Invalid,
|
||||
CT_Untyped,
|
||||
CT_NewLine,
|
||||
CT_Comment,
|
||||
CT_Access_Private,
|
||||
CT_Access_Protected,
|
||||
CT_Access_Public,
|
||||
CT_PlatformAttributes,
|
||||
CT_Class,
|
||||
CT_Class_Fwd,
|
||||
CT_Class_Body,
|
||||
CT_Constructor,
|
||||
CT_Constructor_Fwd,
|
||||
CT_Destructor,
|
||||
CT_Destructor_Fwd,
|
||||
CT_Enum,
|
||||
CT_Enum_Fwd,
|
||||
CT_Enum_Body,
|
||||
CT_Enum_Class,
|
||||
CT_Enum_Class_Fwd,
|
||||
CT_Execution,
|
||||
CT_Export_Body,
|
||||
CT_Extern_Linkage,
|
||||
CT_Extern_Linkage_Body,
|
||||
CT_Friend,
|
||||
CT_Function,
|
||||
CT_Function_Fwd,
|
||||
CT_Function_Body,
|
||||
CT_Global_Body,
|
||||
CT_Module,
|
||||
CT_Namespace,
|
||||
CT_Namespace_Body,
|
||||
CT_Operator,
|
||||
CT_Operator_Fwd,
|
||||
CT_Operator_Member,
|
||||
CT_Operator_Member_Fwd,
|
||||
CT_Operator_Cast,
|
||||
CT_Operator_Cast_Fwd,
|
||||
CT_Parameters,
|
||||
CT_Preprocess_Define,
|
||||
CT_Preprocess_Include,
|
||||
CT_Preprocess_If,
|
||||
CT_Preprocess_IfDef,
|
||||
CT_Preprocess_IfNotDef,
|
||||
CT_Preprocess_ElIf,
|
||||
CT_Preprocess_Else,
|
||||
CT_Preprocess_EndIf,
|
||||
CT_Preprocess_Pragma,
|
||||
CT_Specifiers,
|
||||
CT_Struct,
|
||||
CT_Struct_Fwd,
|
||||
CT_Struct_Body,
|
||||
CT_Template,
|
||||
CT_Typedef,
|
||||
CT_Typename,
|
||||
CT_Union,
|
||||
CT_Union_Body,
|
||||
CT_Using,
|
||||
CT_Using_Namespace,
|
||||
CT_Variable,
|
||||
CT_NumTypes
|
||||
};
|
||||
typedef enum CodeType_Def CodeType;
|
||||
|
||||
inline StrC to_str( CodeType type )
|
||||
{
|
||||
local_persist StrC lookup[] {
|
||||
{ sizeof( "Invalid" ), "Invalid" },
|
||||
{ sizeof( "Untyped" ), "Untyped" },
|
||||
{ sizeof( "NewLine" ), "NewLine" },
|
||||
{ sizeof( "Comment" ), "Comment" },
|
||||
{ sizeof( "Access_Private" ), "Access_Private" },
|
||||
{ sizeof( "Access_Protected" ), "Access_Protected" },
|
||||
{ sizeof( "Access_Public" ), "Access_Public" },
|
||||
{ sizeof( "PlatformAttributes" ), "PlatformAttributes" },
|
||||
{ sizeof( "Class" ), "Class" },
|
||||
{ sizeof( "Class_Fwd" ), "Class_Fwd" },
|
||||
{ sizeof( "Class_Body" ), "Class_Body" },
|
||||
{ sizeof( "Constructor" ), "Constructor" },
|
||||
{ sizeof( "Constructor_Fwd" ), "Constructor_Fwd" },
|
||||
{ sizeof( "Destructor" ), "Destructor" },
|
||||
{ sizeof( "Destructor_Fwd" ), "Destructor_Fwd" },
|
||||
{ sizeof( "Enum" ), "Enum" },
|
||||
{ sizeof( "Enum_Fwd" ), "Enum_Fwd" },
|
||||
{ sizeof( "Enum_Body" ), "Enum_Body" },
|
||||
{ sizeof( "Enum_Class" ), "Enum_Class" },
|
||||
{ sizeof( "Enum_Class_Fwd" ), "Enum_Class_Fwd" },
|
||||
{ sizeof( "Execution" ), "Execution" },
|
||||
{ sizeof( "Export_Body" ), "Export_Body" },
|
||||
{ sizeof( "Extern_Linkage" ), "Extern_Linkage" },
|
||||
{ sizeof( "Extern_Linkage_Body" ), "Extern_Linkage_Body" },
|
||||
{ sizeof( "Friend" ), "Friend" },
|
||||
{ sizeof( "Function" ), "Function" },
|
||||
{ sizeof( "Function_Fwd" ), "Function_Fwd" },
|
||||
{ sizeof( "Function_Body" ), "Function_Body" },
|
||||
{ sizeof( "Global_Body" ), "Global_Body" },
|
||||
{ sizeof( "Module" ), "Module" },
|
||||
{ sizeof( "Namespace" ), "Namespace" },
|
||||
{ sizeof( "Namespace_Body" ), "Namespace_Body" },
|
||||
{ sizeof( "Operator" ), "Operator" },
|
||||
{ sizeof( "Operator_Fwd" ), "Operator_Fwd" },
|
||||
{ sizeof( "Operator_Member" ), "Operator_Member" },
|
||||
{ sizeof( "Operator_Member_Fwd" ), "Operator_Member_Fwd" },
|
||||
{ sizeof( "Operator_Cast" ), "Operator_Cast" },
|
||||
{ sizeof( "Operator_Cast_Fwd" ), "Operator_Cast_Fwd" },
|
||||
{ sizeof( "Parameters" ), "Parameters" },
|
||||
{ sizeof( "Preprocess_Define" ), "Preprocess_Define" },
|
||||
{ sizeof( "Preprocess_Include" ), "Preprocess_Include" },
|
||||
{ sizeof( "Preprocess_If" ), "Preprocess_If" },
|
||||
{ sizeof( "Preprocess_IfDef" ), "Preprocess_IfDef" },
|
||||
{ sizeof( "Preprocess_IfNotDef" ), "Preprocess_IfNotDef" },
|
||||
{ sizeof( "Preprocess_ElIf" ), "Preprocess_ElIf" },
|
||||
{ sizeof( "Preprocess_Else" ), "Preprocess_Else" },
|
||||
{ sizeof( "Preprocess_EndIf" ), "Preprocess_EndIf" },
|
||||
{ sizeof( "Preprocess_Pragma" ), "Preprocess_Pragma" },
|
||||
{ sizeof( "Specifiers" ), "Specifiers" },
|
||||
{ sizeof( "Struct" ), "Struct" },
|
||||
{ sizeof( "Struct_Fwd" ), "Struct_Fwd" },
|
||||
{ sizeof( "Struct_Body" ), "Struct_Body" },
|
||||
{ sizeof( "Template" ), "Template" },
|
||||
{ sizeof( "Typedef" ), "Typedef" },
|
||||
{ sizeof( "Typename" ), "Typename" },
|
||||
{ sizeof( "Union" ), "Union" },
|
||||
{ sizeof( "Union_Body" ), "Union_Body" },
|
||||
{ sizeof( "Using" ), "Using" },
|
||||
{ sizeof( "Using_Namespace" ), "Using_Namespace" },
|
||||
{ sizeof( "Variable" ), "Variable" },
|
||||
};
|
||||
|
||||
StrC to_str( Type type )
|
||||
{
|
||||
local_persist StrC lookup[] {
|
||||
{ sizeof( "Invalid" ), "Invalid" },
|
||||
{ sizeof( "Untyped" ), "Untyped" },
|
||||
{ sizeof( "NewLine" ), "NewLine" },
|
||||
{ sizeof( "Comment" ), "Comment" },
|
||||
{ sizeof( "Access_Private" ), "Access_Private" },
|
||||
{ sizeof( "Access_Protected" ), "Access_Protected" },
|
||||
{ sizeof( "Access_Public" ), "Access_Public" },
|
||||
{ sizeof( "PlatformAttributes" ), "PlatformAttributes" },
|
||||
{ sizeof( "Class" ), "Class" },
|
||||
{ sizeof( "Class_Fwd" ), "Class_Fwd" },
|
||||
{ sizeof( "Class_Body" ), "Class_Body" },
|
||||
{ sizeof( "Constructor" ), "Constructor" },
|
||||
{ sizeof( "Constructor_Fwd" ), "Constructor_Fwd" },
|
||||
{ sizeof( "Destructor" ), "Destructor" },
|
||||
{ sizeof( "Destructor_Fwd" ), "Destructor_Fwd" },
|
||||
{ sizeof( "Enum" ), "Enum" },
|
||||
{ sizeof( "Enum_Fwd" ), "Enum_Fwd" },
|
||||
{ sizeof( "Enum_Body" ), "Enum_Body" },
|
||||
{ sizeof( "Enum_Class" ), "Enum_Class" },
|
||||
{ sizeof( "Enum_Class_Fwd" ), "Enum_Class_Fwd" },
|
||||
{ sizeof( "Execution" ), "Execution" },
|
||||
{ sizeof( "Export_Body" ), "Export_Body" },
|
||||
{ sizeof( "Extern_Linkage" ), "Extern_Linkage" },
|
||||
{ sizeof( "Extern_Linkage_Body" ), "Extern_Linkage_Body" },
|
||||
{ sizeof( "Friend" ), "Friend" },
|
||||
{ sizeof( "Function" ), "Function" },
|
||||
{ sizeof( "Function_Fwd" ), "Function_Fwd" },
|
||||
{ sizeof( "Function_Body" ), "Function_Body" },
|
||||
{ sizeof( "Global_Body" ), "Global_Body" },
|
||||
{ sizeof( "Module" ), "Module" },
|
||||
{ sizeof( "Namespace" ), "Namespace" },
|
||||
{ sizeof( "Namespace_Body" ), "Namespace_Body" },
|
||||
{ sizeof( "Operator" ), "Operator" },
|
||||
{ sizeof( "Operator_Fwd" ), "Operator_Fwd" },
|
||||
{ sizeof( "Operator_Member" ), "Operator_Member" },
|
||||
{ sizeof( "Operator_Member_Fwd" ), "Operator_Member_Fwd" },
|
||||
{ sizeof( "Operator_Cast" ), "Operator_Cast" },
|
||||
{ sizeof( "Operator_Cast_Fwd" ), "Operator_Cast_Fwd" },
|
||||
{ sizeof( "Parameters" ), "Parameters" },
|
||||
{ sizeof( "Preprocess_Define" ), "Preprocess_Define" },
|
||||
{ sizeof( "Preprocess_Include" ), "Preprocess_Include" },
|
||||
{ sizeof( "Preprocess_If" ), "Preprocess_If" },
|
||||
{ sizeof( "Preprocess_IfDef" ), "Preprocess_IfDef" },
|
||||
{ sizeof( "Preprocess_IfNotDef" ), "Preprocess_IfNotDef" },
|
||||
{ sizeof( "Preprocess_ElIf" ), "Preprocess_ElIf" },
|
||||
{ sizeof( "Preprocess_Else" ), "Preprocess_Else" },
|
||||
{ sizeof( "Preprocess_EndIf" ), "Preprocess_EndIf" },
|
||||
{ sizeof( "Preprocess_Pragma" ), "Preprocess_Pragma" },
|
||||
{ sizeof( "Specifiers" ), "Specifiers" },
|
||||
{ sizeof( "Struct" ), "Struct" },
|
||||
{ sizeof( "Struct_Fwd" ), "Struct_Fwd" },
|
||||
{ sizeof( "Struct_Body" ), "Struct_Body" },
|
||||
{ sizeof( "Template" ), "Template" },
|
||||
{ sizeof( "Typedef" ), "Typedef" },
|
||||
{ sizeof( "Typename" ), "Typename" },
|
||||
{ sizeof( "Union" ), "Union" },
|
||||
{ sizeof( "Union_Body" ), "Union_Body" },
|
||||
{ sizeof( "Using" ), "Using" },
|
||||
{ sizeof( "Using_Namespace" ), "Using_Namespace" },
|
||||
{ sizeof( "Variable" ), "Variable" },
|
||||
};
|
||||
return lookup[type];
|
||||
}
|
||||
|
||||
} // namespace ECode
|
||||
|
||||
using CodeT = ECode::Type;
|
||||
return lookup[type];
|
||||
}
|
||||
|
@ -5,114 +5,109 @@
|
||||
|
||||
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
|
||||
|
||||
namespace EOperator
|
||||
enum Operator_Def : u32
|
||||
{
|
||||
enum Type : u32
|
||||
{
|
||||
Invalid,
|
||||
Assign,
|
||||
Assign_Add,
|
||||
Assign_Subtract,
|
||||
Assign_Multiply,
|
||||
Assign_Divide,
|
||||
Assign_Modulo,
|
||||
Assign_BAnd,
|
||||
Assign_BOr,
|
||||
Assign_BXOr,
|
||||
Assign_LShift,
|
||||
Assign_RShift,
|
||||
Increment,
|
||||
Decrement,
|
||||
Unary_Plus,
|
||||
Unary_Minus,
|
||||
UnaryNot,
|
||||
Add,
|
||||
Subtract,
|
||||
Multiply,
|
||||
Divide,
|
||||
Modulo,
|
||||
BNot,
|
||||
BAnd,
|
||||
BOr,
|
||||
BXOr,
|
||||
LShift,
|
||||
RShift,
|
||||
LAnd,
|
||||
LOr,
|
||||
LEqual,
|
||||
LNot,
|
||||
Lesser,
|
||||
Greater,
|
||||
LesserEqual,
|
||||
GreaterEqual,
|
||||
Subscript,
|
||||
Indirection,
|
||||
AddressOf,
|
||||
MemberOfPointer,
|
||||
PtrToMemOfPtr,
|
||||
FunctionCall,
|
||||
Comma,
|
||||
New,
|
||||
NewArray,
|
||||
Delete,
|
||||
DeleteArray,
|
||||
NumOps
|
||||
Op_Invalid,
|
||||
Op_Assign,
|
||||
Op_Assign_Add,
|
||||
Op_Assign_Subtract,
|
||||
Op_Assign_Multiply,
|
||||
Op_Assign_Divide,
|
||||
Op_Assign_Modulo,
|
||||
Op_Assign_BAnd,
|
||||
Op_Assign_BOr,
|
||||
Op_Assign_BXOr,
|
||||
Op_Assign_LShift,
|
||||
Op_Assign_RShift,
|
||||
Op_Increment,
|
||||
Op_Decrement,
|
||||
Op_Unary_Plus,
|
||||
Op_Unary_Minus,
|
||||
Op_UnaryNot,
|
||||
Op_Add,
|
||||
Op_Subtract,
|
||||
Op_Multiply,
|
||||
Op_Divide,
|
||||
Op_Modulo,
|
||||
Op_BNot,
|
||||
Op_BAnd,
|
||||
Op_BOr,
|
||||
Op_BXOr,
|
||||
Op_LShift,
|
||||
Op_RShift,
|
||||
Op_LAnd,
|
||||
Op_LOr,
|
||||
Op_LEqual,
|
||||
Op_LNot,
|
||||
Op_Lesser,
|
||||
Op_Greater,
|
||||
Op_LesserEqual,
|
||||
Op_GreaterEqual,
|
||||
Op_Subscript,
|
||||
Op_Indirection,
|
||||
Op_AddressOf,
|
||||
Op_MemberOfPointer,
|
||||
Op_PtrToMemOfPtr,
|
||||
Op_FunctionCall,
|
||||
Op_Comma,
|
||||
Op_New,
|
||||
Op_NewArray,
|
||||
Op_Delete,
|
||||
Op_DeleteArray,
|
||||
NumOps
|
||||
};
|
||||
typedef enum Operator_Def Operator;
|
||||
|
||||
inline StrC to_str( Operator op )
|
||||
{
|
||||
local_persist StrC lookup[] {
|
||||
{ sizeof( "INVALID" ), "INVALID" },
|
||||
{ sizeof( "=" ), "=" },
|
||||
{ sizeof( "+=" ), "+=" },
|
||||
{ sizeof( "-=" ), "-=" },
|
||||
{ sizeof( "*=" ), "*=" },
|
||||
{ sizeof( "/=" ), "/=" },
|
||||
{ sizeof( "%=" ), "%=" },
|
||||
{ sizeof( "&=" ), "&=" },
|
||||
{ sizeof( "|=" ), "|=" },
|
||||
{ sizeof( "^=" ), "^=" },
|
||||
{ sizeof( "<<=" ), "<<=" },
|
||||
{ sizeof( ">>=" ), ">>=" },
|
||||
{ sizeof( "++" ), "++" },
|
||||
{ sizeof( "--" ), "--" },
|
||||
{ sizeof( "+" ), "+" },
|
||||
{ sizeof( "-" ), "-" },
|
||||
{ sizeof( "!" ), "!" },
|
||||
{ sizeof( "+" ), "+" },
|
||||
{ sizeof( "-" ), "-" },
|
||||
{ sizeof( "*" ), "*" },
|
||||
{ sizeof( "/" ), "/" },
|
||||
{ sizeof( "%" ), "%" },
|
||||
{ sizeof( "~" ), "~" },
|
||||
{ sizeof( "&" ), "&" },
|
||||
{ sizeof( "|" ), "|" },
|
||||
{ sizeof( "^" ), "^" },
|
||||
{ sizeof( "<<" ), "<<" },
|
||||
{ sizeof( ">>" ), ">>" },
|
||||
{ sizeof( "&&" ), "&&" },
|
||||
{ sizeof( "||" ), "||" },
|
||||
{ sizeof( "==" ), "==" },
|
||||
{ sizeof( "!=" ), "!=" },
|
||||
{ sizeof( "<" ), "<" },
|
||||
{ sizeof( ">" ), ">" },
|
||||
{ sizeof( "<=" ), "<=" },
|
||||
{ sizeof( ">=" ), ">=" },
|
||||
{ sizeof( "[]" ), "[]" },
|
||||
{ sizeof( "*" ), "*" },
|
||||
{ sizeof( "&" ), "&" },
|
||||
{ sizeof( "->" ), "->" },
|
||||
{ sizeof( "->*" ), "->*" },
|
||||
{ sizeof( "()" ), "()" },
|
||||
{ sizeof( "," ), "," },
|
||||
{ sizeof( "new" ), "new" },
|
||||
{ sizeof( "new[]" ), "new[]" },
|
||||
{ sizeof( "delete" ), "delete" },
|
||||
{ sizeof( "delete[]" ), "delete[]" },
|
||||
};
|
||||
|
||||
StrC to_str( Type op )
|
||||
{
|
||||
local_persist StrC lookup[] {
|
||||
{ sizeof( "INVALID" ), "INVALID" },
|
||||
{ sizeof( "=" ), "=" },
|
||||
{ sizeof( "+=" ), "+=" },
|
||||
{ sizeof( "-=" ), "-=" },
|
||||
{ sizeof( "*=" ), "*=" },
|
||||
{ sizeof( "/=" ), "/=" },
|
||||
{ sizeof( "%=" ), "%=" },
|
||||
{ sizeof( "&=" ), "&=" },
|
||||
{ sizeof( "|=" ), "|=" },
|
||||
{ sizeof( "^=" ), "^=" },
|
||||
{ sizeof( "<<=" ), "<<=" },
|
||||
{ sizeof( ">>=" ), ">>=" },
|
||||
{ sizeof( "++" ), "++" },
|
||||
{ sizeof( "--" ), "--" },
|
||||
{ sizeof( "+" ), "+" },
|
||||
{ sizeof( "-" ), "-" },
|
||||
{ sizeof( "!" ), "!" },
|
||||
{ sizeof( "+" ), "+" },
|
||||
{ sizeof( "-" ), "-" },
|
||||
{ sizeof( "*" ), "*" },
|
||||
{ sizeof( "/" ), "/" },
|
||||
{ sizeof( "%" ), "%" },
|
||||
{ sizeof( "~" ), "~" },
|
||||
{ sizeof( "&" ), "&" },
|
||||
{ sizeof( "|" ), "|" },
|
||||
{ sizeof( "^" ), "^" },
|
||||
{ sizeof( "<<" ), "<<" },
|
||||
{ sizeof( ">>" ), ">>" },
|
||||
{ sizeof( "&&" ), "&&" },
|
||||
{ sizeof( "||" ), "||" },
|
||||
{ sizeof( "==" ), "==" },
|
||||
{ sizeof( "!=" ), "!=" },
|
||||
{ sizeof( "<" ), "<" },
|
||||
{ sizeof( ">" ), ">" },
|
||||
{ sizeof( "<=" ), "<=" },
|
||||
{ sizeof( ">=" ), ">=" },
|
||||
{ sizeof( "[]" ), "[]" },
|
||||
{ sizeof( "*" ), "*" },
|
||||
{ sizeof( "&" ), "&" },
|
||||
{ sizeof( "->" ), "->" },
|
||||
{ sizeof( "->*" ), "->*" },
|
||||
{ sizeof( "()" ), "()" },
|
||||
{ sizeof( "," ), "," },
|
||||
{ sizeof( "new" ), "new" },
|
||||
{ sizeof( "new[]" ), "new[]" },
|
||||
{ sizeof( "delete" ), "delete" },
|
||||
{ sizeof( "delete[]" ), "delete[]" },
|
||||
};
|
||||
return lookup[op];
|
||||
}
|
||||
|
||||
} // namespace EOperator
|
||||
|
||||
using OperatorT = EOperator::Type;
|
||||
return lookup[op];
|
||||
}
|
||||
|
@ -5,94 +5,89 @@
|
||||
|
||||
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
|
||||
|
||||
namespace ESpecifier
|
||||
enum Specifier_Def : u32
|
||||
{
|
||||
enum Type : u32
|
||||
{
|
||||
Invalid,
|
||||
Consteval,
|
||||
Constexpr,
|
||||
Constinit,
|
||||
Explicit,
|
||||
External_Linkage,
|
||||
ForceInline,
|
||||
Global,
|
||||
Inline,
|
||||
Internal_Linkage,
|
||||
Local_Persist,
|
||||
Mutable,
|
||||
NeverInline,
|
||||
Ptr,
|
||||
Ref,
|
||||
Register,
|
||||
RValue,
|
||||
Static,
|
||||
Thread_Local,
|
||||
Virtual,
|
||||
Const,
|
||||
Final,
|
||||
NoExceptions,
|
||||
Override,
|
||||
Pure,
|
||||
Volatile,
|
||||
NumSpecifiers
|
||||
Spec_Invalid,
|
||||
Spec_Consteval,
|
||||
Spec_Constexpr,
|
||||
Spec_Constinit,
|
||||
Spec_Explicit,
|
||||
Spec_External_Linkage,
|
||||
Spec_ForceInline,
|
||||
Spec_Global,
|
||||
Spec_Inline,
|
||||
Spec_Internal_Linkage,
|
||||
Spec_Local_Persist,
|
||||
Spec_Mutable,
|
||||
Spec_NeverInline,
|
||||
Spec_Ptr,
|
||||
Spec_Ref,
|
||||
Spec_Register,
|
||||
Spec_RValue,
|
||||
Spec_Static,
|
||||
Spec_Thread_Local,
|
||||
Spec_Virtual,
|
||||
Spec_Const,
|
||||
Spec_Final,
|
||||
Spec_NoExceptions,
|
||||
Spec_Override,
|
||||
Spec_Pure,
|
||||
Spec_Volatile,
|
||||
Spec_NumSpecifiers
|
||||
};
|
||||
typedef enum Specifier_Def Specifier;
|
||||
|
||||
inline bool is_trailing( Specifier specifier )
|
||||
{
|
||||
return specifier > Spec_Virtual;
|
||||
}
|
||||
|
||||
inline StrC to_str( Specifier type )
|
||||
{
|
||||
local_persist StrC lookup[] {
|
||||
{ sizeof( "INVALID" ), "INVALID" },
|
||||
{ sizeof( "consteval" ), "consteval" },
|
||||
{ sizeof( "constexpr" ), "constexpr" },
|
||||
{ sizeof( "constinit" ), "constinit" },
|
||||
{ sizeof( "explicit" ), "explicit" },
|
||||
{ sizeof( "extern" ), "extern" },
|
||||
{ sizeof( "forceinline" ), "forceinline" },
|
||||
{ sizeof( "global" ), "global" },
|
||||
{ sizeof( "inline" ), "inline" },
|
||||
{ sizeof( "internal" ), "internal" },
|
||||
{ sizeof( "local_persist" ), "local_persist" },
|
||||
{ sizeof( "mutable" ), "mutable" },
|
||||
{ sizeof( "neverinline" ), "neverinline" },
|
||||
{ sizeof( "*" ), "*" },
|
||||
{ sizeof( "&" ), "&" },
|
||||
{ sizeof( "register" ), "register" },
|
||||
{ sizeof( "&&" ), "&&" },
|
||||
{ sizeof( "static" ), "static" },
|
||||
{ sizeof( "thread_local" ), "thread_local" },
|
||||
{ sizeof( "virtual" ), "virtual" },
|
||||
{ sizeof( "const" ), "const" },
|
||||
{ sizeof( "final" ), "final" },
|
||||
{ sizeof( "noexcept" ), "noexcept" },
|
||||
{ sizeof( "override" ), "override" },
|
||||
{ sizeof( "= 0" ), "= 0" },
|
||||
{ sizeof( "volatile" ), "volatile" },
|
||||
};
|
||||
return lookup[type];
|
||||
}
|
||||
|
||||
bool is_trailing( Type specifier )
|
||||
inline Specifier to_specifier( StrC str )
|
||||
{
|
||||
local_persist u32 keymap[Spec_NumSpecifiers];
|
||||
do_once_start for ( u32 index = 0; index < Spec_NumSpecifiers; index++ )
|
||||
{
|
||||
return specifier > Virtual;
|
||||
StrC enum_str = to_str( (Specifier)index );
|
||||
keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1 );
|
||||
}
|
||||
|
||||
StrC to_str( Type type )
|
||||
do_once_end u32 hash = crc32( str.Ptr, str.Len );
|
||||
for ( u32 index = 0; index < Spec_NumSpecifiers; index++ )
|
||||
{
|
||||
local_persist StrC lookup[] {
|
||||
{ sizeof( "INVALID" ), "INVALID" },
|
||||
{ sizeof( "consteval" ), "consteval" },
|
||||
{ sizeof( "constexpr" ), "constexpr" },
|
||||
{ sizeof( "constinit" ), "constinit" },
|
||||
{ sizeof( "explicit" ), "explicit" },
|
||||
{ sizeof( "extern" ), "extern" },
|
||||
{ sizeof( "forceinline" ), "forceinline" },
|
||||
{ sizeof( "global" ), "global" },
|
||||
{ sizeof( "inline" ), "inline" },
|
||||
{ sizeof( "internal" ), "internal" },
|
||||
{ sizeof( "local_persist" ), "local_persist" },
|
||||
{ sizeof( "mutable" ), "mutable" },
|
||||
{ sizeof( "neverinline" ), "neverinline" },
|
||||
{ sizeof( "*" ), "*" },
|
||||
{ sizeof( "&" ), "&" },
|
||||
{ sizeof( "register" ), "register" },
|
||||
{ sizeof( "&&" ), "&&" },
|
||||
{ sizeof( "static" ), "static" },
|
||||
{ sizeof( "thread_local" ), "thread_local" },
|
||||
{ sizeof( "virtual" ), "virtual" },
|
||||
{ sizeof( "const" ), "const" },
|
||||
{ sizeof( "final" ), "final" },
|
||||
{ sizeof( "noexcept" ), "noexcept" },
|
||||
{ sizeof( "override" ), "override" },
|
||||
{ sizeof( "= 0" ), "= 0" },
|
||||
{ sizeof( "volatile" ), "volatile" },
|
||||
};
|
||||
return lookup[type];
|
||||
if ( keymap[index] == hash )
|
||||
return (Specifier)index;
|
||||
}
|
||||
|
||||
Type to_type( StrC str )
|
||||
{
|
||||
local_persist u32 keymap[NumSpecifiers];
|
||||
do_once_start for ( u32 index = 0; index < NumSpecifiers; index++ )
|
||||
{
|
||||
StrC enum_str = to_str( (Type)index );
|
||||
keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1 );
|
||||
}
|
||||
do_once_end u32 hash = crc32( str.Ptr, str.Len );
|
||||
for ( u32 index = 0; index < NumSpecifiers; index++ )
|
||||
{
|
||||
if ( keymap[index] == hash )
|
||||
return (Type)index;
|
||||
}
|
||||
return Invalid;
|
||||
}
|
||||
|
||||
} // namespace ESpecifier
|
||||
|
||||
using SpecifierT = ESpecifier::Type;
|
||||
return Spec_Invalid;
|
||||
}
|
||||
|
@ -5,237 +5,231 @@
|
||||
|
||||
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
|
||||
|
||||
namespace parser
|
||||
GEN_NS_PARSER_BEGIN
|
||||
#define GEN_DEFINE_ATTRIBUTE_TOKENS Entry( Tok_Attribute_API_Export, "GEN_API_Export_Code" ) Entry( Tok_Attribute_API_Import, "GEN_API_Import_Code" )
|
||||
|
||||
enum TokType_Def : u32
|
||||
{
|
||||
namespace ETokType
|
||||
Tok_Invalid,
|
||||
Tok_Access_Private,
|
||||
Tok_Access_Protected,
|
||||
Tok_Access_Public,
|
||||
Tok_Access_MemberSymbol,
|
||||
Tok_Access_StaticSymbol,
|
||||
Tok_Ampersand,
|
||||
Tok_Ampersand_DBL,
|
||||
Tok_Assign_Classifer,
|
||||
Tok_Attribute_Open,
|
||||
Tok_Attribute_Close,
|
||||
Tok_BraceCurly_Open,
|
||||
Tok_BraceCurly_Close,
|
||||
Tok_BraceSquare_Open,
|
||||
Tok_BraceSquare_Close,
|
||||
Tok_Capture_Start,
|
||||
Tok_Capture_End,
|
||||
Tok_Comment,
|
||||
Tok_Comment_End,
|
||||
Tok_Comment_Start,
|
||||
Tok_Char,
|
||||
Tok_Comma,
|
||||
Tok_Decl_Class,
|
||||
Tok_Decl_GNU_Attribute,
|
||||
Tok_Decl_MSVC_Attribute,
|
||||
Tok_Decl_Enum,
|
||||
Tok_Decl_Extern_Linkage,
|
||||
Tok_Decl_Friend,
|
||||
Tok_Decl_Module,
|
||||
Tok_Decl_Namespace,
|
||||
Tok_Decl_Operator,
|
||||
Tok_Decl_Struct,
|
||||
Tok_Decl_Template,
|
||||
Tok_Decl_Typedef,
|
||||
Tok_Decl_Using,
|
||||
Tok_Decl_Union,
|
||||
Tok_Identifier,
|
||||
Tok_Module_Import,
|
||||
Tok_Module_Export,
|
||||
Tok_NewLine,
|
||||
Tok_Number,
|
||||
Tok_Operator,
|
||||
Tok_Preprocess_Hash,
|
||||
Tok_Preprocess_Define,
|
||||
Tok_Preprocess_If,
|
||||
Tok_Preprocess_IfDef,
|
||||
Tok_Preprocess_IfNotDef,
|
||||
Tok_Preprocess_ElIf,
|
||||
Tok_Preprocess_Else,
|
||||
Tok_Preprocess_EndIf,
|
||||
Tok_Preprocess_Include,
|
||||
Tok_Preprocess_Pragma,
|
||||
Tok_Preprocess_Content,
|
||||
Tok_Preprocess_Macro,
|
||||
Tok_Preprocess_Unsupported,
|
||||
Tok_Spec_Alignas,
|
||||
Tok_Spec_Const,
|
||||
Tok_Spec_Consteval,
|
||||
Tok_Spec_Constexpr,
|
||||
Tok_Spec_Constinit,
|
||||
Tok_Spec_Explicit,
|
||||
Tok_Spec_Extern,
|
||||
Tok_Spec_Final,
|
||||
Tok_Spec_ForceInline,
|
||||
Tok_Spec_Global,
|
||||
Tok_Spec_Inline,
|
||||
Tok_Spec_Internal_Linkage,
|
||||
Tok_Spec_LocalPersist,
|
||||
Tok_Spec_Mutable,
|
||||
Tok_Spec_NeverInline,
|
||||
Tok_Spec_Override,
|
||||
Tok_Spec_Static,
|
||||
Tok_Spec_ThreadLocal,
|
||||
Tok_Spec_Volatile,
|
||||
Tok_Spec_Virtual,
|
||||
Tok_Star,
|
||||
Tok_Statement_End,
|
||||
Tok_StaticAssert,
|
||||
Tok_String,
|
||||
Tok_Type_Typename,
|
||||
Tok_Type_Unsigned,
|
||||
Tok_Type_Signed,
|
||||
Tok_Type_Short,
|
||||
Tok_Type_Long,
|
||||
Tok_Type_bool,
|
||||
Tok_Type_char,
|
||||
Tok_Type_int,
|
||||
Tok_Type_double,
|
||||
Tok_Type_MS_int8,
|
||||
Tok_Type_MS_int16,
|
||||
Tok_Type_MS_int32,
|
||||
Tok_Type_MS_int64,
|
||||
Tok_Type_MS_W64,
|
||||
Tok_Varadic_Argument,
|
||||
Tok___Attributes_Start,
|
||||
Tok_Attribute_API_Export,
|
||||
Tok_Attribute_API_Import,
|
||||
Tok_NumTokens
|
||||
};
|
||||
typedef enum TokType_Def TokType;
|
||||
|
||||
inline StrC to_str( TokType type )
|
||||
{
|
||||
local_persist StrC lookup[] {
|
||||
{ sizeof( "__invalid__" ), "__invalid__" },
|
||||
{ sizeof( "private" ), "private" },
|
||||
{ sizeof( "protected" ), "protected" },
|
||||
{ sizeof( "public" ), "public" },
|
||||
{ sizeof( "." ), "." },
|
||||
{ sizeof( "::" ), "::" },
|
||||
{ sizeof( "&" ), "&" },
|
||||
{ sizeof( "&&" ), "&&" },
|
||||
{ sizeof( ":" ), ":" },
|
||||
{ sizeof( "[[" ), "[[" },
|
||||
{ sizeof( "]]" ), "]]" },
|
||||
{ sizeof( "{" ), "{" },
|
||||
{ sizeof( "}" ), "}" },
|
||||
{ sizeof( "[" ), "[" },
|
||||
{ sizeof( "]" ), "]" },
|
||||
{ sizeof( "(" ), "(" },
|
||||
{ sizeof( ")" ), ")" },
|
||||
{ sizeof( "__comment__" ), "__comment__" },
|
||||
{ sizeof( "__comment_end__" ), "__comment_end__" },
|
||||
{ sizeof( "__comment_start__" ), "__comment_start__" },
|
||||
{ sizeof( "__character__" ), "__character__" },
|
||||
{ sizeof( "," ), "," },
|
||||
{ sizeof( "class" ), "class" },
|
||||
{ sizeof( "__attribute__" ), "__attribute__" },
|
||||
{ sizeof( "__declspec" ), "__declspec" },
|
||||
{ sizeof( "enum" ), "enum" },
|
||||
{ sizeof( "extern" ), "extern" },
|
||||
{ sizeof( "friend" ), "friend" },
|
||||
{ sizeof( "module" ), "module" },
|
||||
{ sizeof( "namespace" ), "namespace" },
|
||||
{ sizeof( "operator" ), "operator" },
|
||||
{ sizeof( "struct" ), "struct" },
|
||||
{ sizeof( "template" ), "template" },
|
||||
{ sizeof( "typedef" ), "typedef" },
|
||||
{ sizeof( "using" ), "using" },
|
||||
{ sizeof( "union" ), "union" },
|
||||
{ sizeof( "__identifier__" ), "__identifier__" },
|
||||
{ sizeof( "import" ), "import" },
|
||||
{ sizeof( "export" ), "export" },
|
||||
{ sizeof( "__new_line__" ), "__new_line__" },
|
||||
{ sizeof( "__number__" ), "__number__" },
|
||||
{ sizeof( "__operator__" ), "__operator__" },
|
||||
{ sizeof( "#" ), "#" },
|
||||
{ sizeof( "define" ), "define" },
|
||||
{ sizeof( "if" ), "if" },
|
||||
{ sizeof( "ifdef" ), "ifdef" },
|
||||
{ sizeof( "ifndef" ), "ifndef" },
|
||||
{ sizeof( "elif" ), "elif" },
|
||||
{ sizeof( "else" ), "else" },
|
||||
{ sizeof( "endif" ), "endif" },
|
||||
{ sizeof( "include" ), "include" },
|
||||
{ sizeof( "pragma" ), "pragma" },
|
||||
{ sizeof( "__macro_content__" ), "__macro_content__" },
|
||||
{ sizeof( "__macro__" ), "__macro__" },
|
||||
{ sizeof( "__unsupported__" ), "__unsupported__" },
|
||||
{ sizeof( "alignas" ), "alignas" },
|
||||
{ sizeof( "const" ), "const" },
|
||||
{ sizeof( "consteval" ), "consteval" },
|
||||
{ sizeof( "constexpr" ), "constexpr" },
|
||||
{ sizeof( "constinit" ), "constinit" },
|
||||
{ sizeof( "explicit" ), "explicit" },
|
||||
{ sizeof( "extern" ), "extern" },
|
||||
{ sizeof( "final" ), "final" },
|
||||
{ sizeof( "forceinline" ), "forceinline" },
|
||||
{ sizeof( "global" ), "global" },
|
||||
{ sizeof( "inline" ), "inline" },
|
||||
{ sizeof( "internal" ), "internal" },
|
||||
{ sizeof( "local_persist" ), "local_persist" },
|
||||
{ sizeof( "mutable" ), "mutable" },
|
||||
{ sizeof( "neverinline" ), "neverinline" },
|
||||
{ sizeof( "override" ), "override" },
|
||||
{ sizeof( "static" ), "static" },
|
||||
{ sizeof( "thread_local" ), "thread_local" },
|
||||
{ sizeof( "volatile" ), "volatile" },
|
||||
{ sizeof( "virtual" ), "virtual" },
|
||||
{ sizeof( "*" ), "*" },
|
||||
{ sizeof( ";" ), ";" },
|
||||
{ sizeof( "static_assert" ), "static_assert" },
|
||||
{ sizeof( "__string__" ), "__string__" },
|
||||
{ sizeof( "typename" ), "typename" },
|
||||
{ sizeof( "unsigned" ), "unsigned" },
|
||||
{ sizeof( "signed" ), "signed" },
|
||||
{ sizeof( "short" ), "short" },
|
||||
{ sizeof( "long" ), "long" },
|
||||
{ sizeof( "bool" ), "bool" },
|
||||
{ sizeof( "char" ), "char" },
|
||||
{ sizeof( "int" ), "int" },
|
||||
{ sizeof( "double" ), "double" },
|
||||
{ sizeof( "__int8" ), "__int8" },
|
||||
{ sizeof( "__int16" ), "__int16" },
|
||||
{ sizeof( "__int32" ), "__int32" },
|
||||
{ sizeof( "__int64" ), "__int64" },
|
||||
{ sizeof( "_W64" ), "_W64" },
|
||||
{ sizeof( "..." ), "..." },
|
||||
{ sizeof( "__attrib_start__" ), "__attrib_start__" },
|
||||
{ sizeof( "GEN_API_Export_Code" ), "GEN_API_Export_Code" },
|
||||
{ sizeof( "GEN_API_Import_Code" ), "GEN_API_Import_Code" },
|
||||
};
|
||||
return lookup[type];
|
||||
}
|
||||
|
||||
inline TokType to_toktype( StrC str )
|
||||
{
|
||||
local_persist u32 keymap[Tok_NumTokens];
|
||||
do_once_start for ( u32 index = 0; index < Tok_NumTokens; index++ )
|
||||
{
|
||||
#define GEN_DEFINE_ATTRIBUTE_TOKENS Entry( Attribute_API_Export, "GEN_API_Export_Code" ) Entry( Attribute_API_Import, "GEN_API_Import_Code" )
|
||||
StrC enum_str = to_str( (TokType)index );
|
||||
keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1 );
|
||||
}
|
||||
do_once_end u32 hash = crc32( str.Ptr, str.Len );
|
||||
for ( u32 index = 0; index < Tok_NumTokens; index++ )
|
||||
{
|
||||
if ( keymap[index] == hash )
|
||||
return (TokType)index;
|
||||
}
|
||||
return Tok_Invalid;
|
||||
}
|
||||
|
||||
enum Type : u32
|
||||
{
|
||||
Invalid,
|
||||
Access_Private,
|
||||
Access_Protected,
|
||||
Access_Public,
|
||||
Access_MemberSymbol,
|
||||
Access_StaticSymbol,
|
||||
Ampersand,
|
||||
Ampersand_DBL,
|
||||
Assign_Classifer,
|
||||
Attribute_Open,
|
||||
Attribute_Close,
|
||||
BraceCurly_Open,
|
||||
BraceCurly_Close,
|
||||
BraceSquare_Open,
|
||||
BraceSquare_Close,
|
||||
Capture_Start,
|
||||
Capture_End,
|
||||
Comment,
|
||||
Comment_End,
|
||||
Comment_Start,
|
||||
Char,
|
||||
Comma,
|
||||
Decl_Class,
|
||||
Decl_GNU_Attribute,
|
||||
Decl_MSVC_Attribute,
|
||||
Decl_Enum,
|
||||
Decl_Extern_Linkage,
|
||||
Decl_Friend,
|
||||
Decl_Module,
|
||||
Decl_Namespace,
|
||||
Decl_Operator,
|
||||
Decl_Struct,
|
||||
Decl_Template,
|
||||
Decl_Typedef,
|
||||
Decl_Using,
|
||||
Decl_Union,
|
||||
Identifier,
|
||||
Module_Import,
|
||||
Module_Export,
|
||||
NewLine,
|
||||
Number,
|
||||
Operator,
|
||||
Preprocess_Hash,
|
||||
Preprocess_Define,
|
||||
Preprocess_If,
|
||||
Preprocess_IfDef,
|
||||
Preprocess_IfNotDef,
|
||||
Preprocess_ElIf,
|
||||
Preprocess_Else,
|
||||
Preprocess_EndIf,
|
||||
Preprocess_Include,
|
||||
Preprocess_Pragma,
|
||||
Preprocess_Content,
|
||||
Preprocess_Macro,
|
||||
Preprocess_Unsupported,
|
||||
Spec_Alignas,
|
||||
Spec_Const,
|
||||
Spec_Consteval,
|
||||
Spec_Constexpr,
|
||||
Spec_Constinit,
|
||||
Spec_Explicit,
|
||||
Spec_Extern,
|
||||
Spec_Final,
|
||||
Spec_ForceInline,
|
||||
Spec_Global,
|
||||
Spec_Inline,
|
||||
Spec_Internal_Linkage,
|
||||
Spec_LocalPersist,
|
||||
Spec_Mutable,
|
||||
Spec_NeverInline,
|
||||
Spec_Override,
|
||||
Spec_Static,
|
||||
Spec_ThreadLocal,
|
||||
Spec_Volatile,
|
||||
Spec_Virtual,
|
||||
Star,
|
||||
Statement_End,
|
||||
StaticAssert,
|
||||
String,
|
||||
Type_Typename,
|
||||
Type_Unsigned,
|
||||
Type_Signed,
|
||||
Type_Short,
|
||||
Type_Long,
|
||||
Type_bool,
|
||||
Type_char,
|
||||
Type_int,
|
||||
Type_double,
|
||||
Type_MS_int8,
|
||||
Type_MS_int16,
|
||||
Type_MS_int32,
|
||||
Type_MS_int64,
|
||||
Type_MS_W64,
|
||||
Varadic_Argument,
|
||||
__Attributes_Start,
|
||||
Attribute_API_Export,
|
||||
Attribute_API_Import,
|
||||
NumTokens
|
||||
};
|
||||
|
||||
StrC to_str( Type type )
|
||||
{
|
||||
local_persist StrC lookup[] {
|
||||
{ sizeof( "__invalid__" ), "__invalid__" },
|
||||
{ sizeof( "private" ), "private" },
|
||||
{ sizeof( "protected" ), "protected" },
|
||||
{ sizeof( "public" ), "public" },
|
||||
{ sizeof( "." ), "." },
|
||||
{ sizeof( "::" ), "::" },
|
||||
{ sizeof( "&" ), "&" },
|
||||
{ sizeof( "&&" ), "&&" },
|
||||
{ sizeof( ":" ), ":" },
|
||||
{ sizeof( "[[" ), "[[" },
|
||||
{ sizeof( "]]" ), "]]" },
|
||||
{ sizeof( "{" ), "{" },
|
||||
{ sizeof( "}" ), "}" },
|
||||
{ sizeof( "[" ), "[" },
|
||||
{ sizeof( "]" ), "]" },
|
||||
{ sizeof( "(" ), "(" },
|
||||
{ sizeof( ")" ), ")" },
|
||||
{ sizeof( "__comment__" ), "__comment__" },
|
||||
{ sizeof( "__comment_end__" ), "__comment_end__" },
|
||||
{ sizeof( "__comment_start__" ), "__comment_start__" },
|
||||
{ sizeof( "__character__" ), "__character__" },
|
||||
{ sizeof( "," ), "," },
|
||||
{ sizeof( "class" ), "class" },
|
||||
{ sizeof( "__attribute__" ), "__attribute__" },
|
||||
{ sizeof( "__declspec" ), "__declspec" },
|
||||
{ sizeof( "enum" ), "enum" },
|
||||
{ sizeof( "extern" ), "extern" },
|
||||
{ sizeof( "friend" ), "friend" },
|
||||
{ sizeof( "module" ), "module" },
|
||||
{ sizeof( "namespace" ), "namespace" },
|
||||
{ sizeof( "operator" ), "operator" },
|
||||
{ sizeof( "struct" ), "struct" },
|
||||
{ sizeof( "template" ), "template" },
|
||||
{ sizeof( "typedef" ), "typedef" },
|
||||
{ sizeof( "using" ), "using" },
|
||||
{ sizeof( "union" ), "union" },
|
||||
{ sizeof( "__identifier__" ), "__identifier__" },
|
||||
{ sizeof( "import" ), "import" },
|
||||
{ sizeof( "export" ), "export" },
|
||||
{ sizeof( "__new_line__" ), "__new_line__" },
|
||||
{ sizeof( "__number__" ), "__number__" },
|
||||
{ sizeof( "__operator__" ), "__operator__" },
|
||||
{ sizeof( "#" ), "#" },
|
||||
{ sizeof( "define" ), "define" },
|
||||
{ sizeof( "if" ), "if" },
|
||||
{ sizeof( "ifdef" ), "ifdef" },
|
||||
{ sizeof( "ifndef" ), "ifndef" },
|
||||
{ sizeof( "elif" ), "elif" },
|
||||
{ sizeof( "else" ), "else" },
|
||||
{ sizeof( "endif" ), "endif" },
|
||||
{ sizeof( "include" ), "include" },
|
||||
{ sizeof( "pragma" ), "pragma" },
|
||||
{ sizeof( "__macro_content__" ), "__macro_content__" },
|
||||
{ sizeof( "__macro__" ), "__macro__" },
|
||||
{ sizeof( "__unsupported__" ), "__unsupported__" },
|
||||
{ sizeof( "alignas" ), "alignas" },
|
||||
{ sizeof( "const" ), "const" },
|
||||
{ sizeof( "consteval" ), "consteval" },
|
||||
{ sizeof( "constexpr" ), "constexpr" },
|
||||
{ sizeof( "constinit" ), "constinit" },
|
||||
{ sizeof( "explicit" ), "explicit" },
|
||||
{ sizeof( "extern" ), "extern" },
|
||||
{ sizeof( "final" ), "final" },
|
||||
{ sizeof( "forceinline" ), "forceinline" },
|
||||
{ sizeof( "global" ), "global" },
|
||||
{ sizeof( "inline" ), "inline" },
|
||||
{ sizeof( "internal" ), "internal" },
|
||||
{ sizeof( "local_persist" ), "local_persist" },
|
||||
{ sizeof( "mutable" ), "mutable" },
|
||||
{ sizeof( "neverinline" ), "neverinline" },
|
||||
{ sizeof( "override" ), "override" },
|
||||
{ sizeof( "static" ), "static" },
|
||||
{ sizeof( "thread_local" ), "thread_local" },
|
||||
{ sizeof( "volatile" ), "volatile" },
|
||||
{ sizeof( "virtual" ), "virtual" },
|
||||
{ sizeof( "*" ), "*" },
|
||||
{ sizeof( ";" ), ";" },
|
||||
{ sizeof( "static_assert" ), "static_assert" },
|
||||
{ sizeof( "__string__" ), "__string__" },
|
||||
{ sizeof( "typename" ), "typename" },
|
||||
{ sizeof( "unsigned" ), "unsigned" },
|
||||
{ sizeof( "signed" ), "signed" },
|
||||
{ sizeof( "short" ), "short" },
|
||||
{ sizeof( "long" ), "long" },
|
||||
{ sizeof( "bool" ), "bool" },
|
||||
{ sizeof( "char" ), "char" },
|
||||
{ sizeof( "int" ), "int" },
|
||||
{ sizeof( "double" ), "double" },
|
||||
{ sizeof( "__int8" ), "__int8" },
|
||||
{ sizeof( "__int16" ), "__int16" },
|
||||
{ sizeof( "__int32" ), "__int32" },
|
||||
{ sizeof( "__int64" ), "__int64" },
|
||||
{ sizeof( "_W64" ), "_W64" },
|
||||
{ sizeof( "..." ), "..." },
|
||||
{ sizeof( "__attrib_start__" ), "__attrib_start__" },
|
||||
{ sizeof( "GEN_API_Export_Code" ), "GEN_API_Export_Code" },
|
||||
{ sizeof( "GEN_API_Import_Code" ), "GEN_API_Import_Code" },
|
||||
};
|
||||
return lookup[type];
|
||||
}
|
||||
|
||||
Type to_type( StrC str )
|
||||
{
|
||||
local_persist u32 keymap[NumTokens];
|
||||
do_once_start for ( u32 index = 0; index < NumTokens; index++ )
|
||||
{
|
||||
StrC enum_str = to_str( (Type)index );
|
||||
keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1 );
|
||||
}
|
||||
do_once_end u32 hash = crc32( str.Ptr, str.Len );
|
||||
for ( u32 index = 0; index < NumTokens; index++ )
|
||||
{
|
||||
if ( keymap[index] == hash )
|
||||
return (Type)index;
|
||||
}
|
||||
return Invalid;
|
||||
}
|
||||
|
||||
} // namespace ETokType
|
||||
|
||||
using TokType = ETokType::Type;
|
||||
|
||||
} // namespace parser
|
||||
GEN_NS_PARSER_END
|
||||
|
@ -42,7 +42,7 @@ constexpr s32 InitSize_DataArrays = 16;
|
||||
|
||||
// NOTE: This limits the maximum size of an allocation
|
||||
// If you are generating a string larger than this, increase the size of the bucket here.
|
||||
constexpr uw Global_BucketSize = GEN_GLOBAL_BUCKET_SIZE;
|
||||
constexpr usize Global_BucketSize = GEN_GLOBAL_BUCKET_SIZE;
|
||||
constexpr s32 CodePool_NumBlocks = GEN_CODEPOOL_NUM_BLOCKS;
|
||||
constexpr s32 SizePer_StringArena = GEN_SIZE_PER_STRING_ARENA;
|
||||
|
||||
@ -63,7 +63,6 @@ extern CodeAttributes attrib_api_import;
|
||||
extern Code module_global_fragment;
|
||||
extern Code module_private_fragment;
|
||||
|
||||
// Exposed, but this is really used for parsing.
|
||||
extern Code fmt_newline;
|
||||
|
||||
extern CodePragma pragma_once;
|
||||
@ -98,45 +97,46 @@ extern CodeSpecifiers spec_thread_local;
|
||||
extern CodeSpecifiers spec_virtual;
|
||||
extern CodeSpecifiers spec_volatile;
|
||||
|
||||
extern CodeType t_empty; // Used with varaidc parameters. (Exposing just in case its useful for another circumstance)
|
||||
extern CodeType t_auto;
|
||||
extern CodeType t_void;
|
||||
extern CodeType t_int;
|
||||
extern CodeType t_bool;
|
||||
extern CodeType t_char;
|
||||
extern CodeType t_wchar_t;
|
||||
extern CodeType t_class;
|
||||
extern CodeType t_typename;
|
||||
extern CodeTypename t_empty; // Used with varaidc parameters. (Exposing just in case its useful for another circumstance)
|
||||
extern CodeTypename t_auto;
|
||||
extern CodeTypename t_void;
|
||||
extern CodeTypename t_int;
|
||||
extern CodeTypename t_bool;
|
||||
extern CodeTypename t_char;
|
||||
extern CodeTypename t_wchar_t;
|
||||
extern CodeTypename t_class;
|
||||
extern CodeTypename t_typename;
|
||||
|
||||
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||
// Predefined typename codes. Are set to readonly and are setup during gen::init()
|
||||
|
||||
extern CodeType t_b32;
|
||||
extern CodeTypename t_b32;
|
||||
|
||||
extern CodeType t_s8;
|
||||
extern CodeType t_s16;
|
||||
extern CodeType t_s32;
|
||||
extern CodeType t_s64;
|
||||
extern CodeTypename t_s8;
|
||||
extern CodeTypename t_s16;
|
||||
extern CodeTypename t_s32;
|
||||
extern CodeTypename t_s64;
|
||||
|
||||
extern CodeType t_u8;
|
||||
extern CodeType t_u16;
|
||||
extern CodeType t_u32;
|
||||
extern CodeType t_u64;
|
||||
extern CodeTypename t_u8;
|
||||
extern CodeTypename t_u16;
|
||||
extern CodeTypename t_u32;
|
||||
extern CodeTypename t_u64;
|
||||
|
||||
extern CodeType t_sw;
|
||||
extern CodeType t_uw;
|
||||
extern CodeTypename t_ssize;
|
||||
extern CodeTypename t_usize;
|
||||
|
||||
extern CodeType t_f32;
|
||||
extern CodeType t_f64;
|
||||
extern CodeTypename t_f32;
|
||||
extern CodeTypename t_f64;
|
||||
#endif
|
||||
|
||||
#pragma endregion Constants
|
||||
|
||||
#pragma region Macros
|
||||
|
||||
#ifndef token_fmt
|
||||
# define gen_main main
|
||||
|
||||
# define __ NoCode
|
||||
# define __ NullCode
|
||||
|
||||
// Convienence for defining any name used with the gen api.
|
||||
// Lets you provide the length and string literal to the functions without the need for the DSL.
|
||||
@ -152,22 +152,23 @@ extern CodeType t_typename;
|
||||
|
||||
// Takes a format string (char const*) and a list of tokens (StrC) and returns a StrC of the formatted string.
|
||||
# define token_fmt( ... ) GEN_NS token_fmt_impl( (num_args( __VA_ARGS__ ) + 1) / 2, __VA_ARGS__ )
|
||||
#endif
|
||||
|
||||
#pragma endregion Macros
|
||||
|
||||
// Used by the lexer to persistently treat all these identifiers as preprocessor defines.
|
||||
// Populate with strings via gen::get_cached_string.
|
||||
// Functional defines must have format: id( ;at minimum to indicate that the define is only valid with arguments.
|
||||
extern Array< StringCached > PreprocessorDefines;
|
||||
extern Array(StringCached) PreprocessorDefines;
|
||||
|
||||
#ifdef GEN_EXPOSE_BACKEND
|
||||
|
||||
// Global allocator used for data with process lifetime.
|
||||
extern AllocatorInfo GlobalAllocator;
|
||||
extern Array< Arena > Global_AllocatorBuckets;
|
||||
extern Array(Arena) Global_AllocatorBuckets;
|
||||
|
||||
extern Array< Pool > CodePools;
|
||||
extern Array< Arena > StringArenas;
|
||||
extern Array(Pool) CodePools;
|
||||
extern Array(Arena) StringArenas;
|
||||
|
||||
extern StringTable StringCache;
|
||||
|
||||
|
@ -17,15 +17,3 @@
|
||||
#ifndef GEN_ROLL_OWN_DEPENDENCIES
|
||||
# include "gen.dep.hpp"
|
||||
#endif
|
||||
|
||||
#ifndef GEN_NS_BEGIN
|
||||
# ifdef GEN_DONT_USE_NAMESPACE
|
||||
# define GEN_NS
|
||||
# define GEN_NS_BEGIN
|
||||
# define GEN_NS_END
|
||||
# else
|
||||
# define GEN_NS gen::
|
||||
# define GEN_NS_BEGIN namespace gen {
|
||||
# define GEN_NS_END }
|
||||
# endif
|
||||
#endif
|
||||
|
@ -3,94 +3,174 @@
|
||||
#include "interface.hpp"
|
||||
#endif
|
||||
|
||||
void AST::append( AST* other )
|
||||
#pragma region Code
|
||||
inline
|
||||
void append( Code self, Code other )
|
||||
{
|
||||
GEN_ASSERT(self.ast != nullptr);
|
||||
GEN_ASSERT(other.ast != nullptr);
|
||||
|
||||
if ( other->Parent )
|
||||
other = other->duplicate();
|
||||
other = duplicate(other);
|
||||
|
||||
other->Parent = this;
|
||||
other->Parent = self;
|
||||
|
||||
if ( Front == nullptr )
|
||||
if ( self->Front == nullptr )
|
||||
{
|
||||
Front = other;
|
||||
Back = other;
|
||||
self->Front = other;
|
||||
self->Back = other;
|
||||
|
||||
NumEntries++;
|
||||
self->NumEntries++;
|
||||
return;
|
||||
}
|
||||
|
||||
AST*
|
||||
Current = Back;
|
||||
Code
|
||||
Current = self->Back;
|
||||
Current->Next = other;
|
||||
other->Prev = Current;
|
||||
Back = other;
|
||||
NumEntries++;
|
||||
self->Back = other;
|
||||
self->NumEntries++;
|
||||
}
|
||||
|
||||
Code& AST::entry( u32 idx )
|
||||
inline
|
||||
bool is_body(Code self)
|
||||
{
|
||||
AST** current = & Front;
|
||||
GEN_ASSERT(self != nullptr);
|
||||
switch (self->Type)
|
||||
{
|
||||
case CT_Enum_Body:
|
||||
case CT_Class_Body:
|
||||
case CT_Union_Body:
|
||||
case CT_Export_Body:
|
||||
case CT_Global_Body:
|
||||
case CT_Struct_Body:
|
||||
case CT_Function_Body:
|
||||
case CT_Namespace_Body:
|
||||
case CT_Extern_Linkage_Body:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
inline
|
||||
Code* entry( Code self, u32 idx )
|
||||
{
|
||||
GEN_ASSERT(self.ast != nullptr);
|
||||
Code* current = & self->Front;
|
||||
while ( idx >= 0 && current != nullptr )
|
||||
{
|
||||
if ( idx == 0 )
|
||||
return * rcast( Code*, current);
|
||||
return rcast( Code*, current);
|
||||
|
||||
current = & ( * current )->Next;
|
||||
idx--;
|
||||
}
|
||||
|
||||
return * rcast( Code*, current);
|
||||
return rcast( Code*, current);
|
||||
}
|
||||
|
||||
bool AST::has_entries()
|
||||
inline
|
||||
bool is_valid(Code self)
|
||||
{
|
||||
return NumEntries;
|
||||
return self.ast != nullptr && self.ast->Type != CT_Invalid;
|
||||
}
|
||||
|
||||
char const* AST::type_str()
|
||||
inline
|
||||
bool has_entries(AST* self)
|
||||
{
|
||||
return ECode::to_str( Type );
|
||||
GEN_ASSERT(self != nullptr);
|
||||
return self->NumEntries > 0;
|
||||
}
|
||||
|
||||
AST::operator Code()
|
||||
inline
|
||||
void set_global(Code self)
|
||||
{
|
||||
return { this };
|
||||
}
|
||||
if ( self.ast == nullptr )
|
||||
{
|
||||
log_failure("Code::set_global: Cannot set code as global, AST is null!");
|
||||
return;
|
||||
}
|
||||
|
||||
self->Parent.ast = Code_Global.ast;
|
||||
}
|
||||
inline
|
||||
Code& Code::operator ++()
|
||||
{
|
||||
if ( ast )
|
||||
ast = ast->Next;
|
||||
ast = ast->Next.ast;
|
||||
|
||||
return *this;
|
||||
return * this;
|
||||
}
|
||||
|
||||
void CodeClass::add_interface( CodeType type )
|
||||
inline
|
||||
char const* type_str(Code self)
|
||||
{
|
||||
CodeType possible_slot = ast->ParentType;
|
||||
GEN_ASSERT(self != nullptr);
|
||||
return to_str( self->Type );
|
||||
}
|
||||
#pragma endregion Code
|
||||
|
||||
#pragma region CodeBody
|
||||
inline
|
||||
void append( CodeBody self, Code other )
|
||||
{
|
||||
GEN_ASSERT(other.ast != nullptr);
|
||||
|
||||
if (is_body(other)) {
|
||||
append( self, cast(CodeBody, other) );
|
||||
return;
|
||||
}
|
||||
|
||||
append( cast(Code, self), other );
|
||||
}
|
||||
inline
|
||||
void append( CodeBody self, CodeBody body )
|
||||
{
|
||||
GEN_ASSERT(self.ast != nullptr);
|
||||
|
||||
for ( Code entry : body ) {
|
||||
append( self, entry );
|
||||
}
|
||||
}
|
||||
inline
|
||||
Code begin( CodeBody body) {
|
||||
if ( body.ast )
|
||||
return { rcast( AST*, body.ast)->Front };
|
||||
return { nullptr };
|
||||
}
|
||||
inline
|
||||
Code end(CodeBody body ){
|
||||
return { rcast(AST*, body.ast)->Back->Next };
|
||||
}
|
||||
#pragma endregion CodeBody
|
||||
|
||||
#pragma region CodeClass
|
||||
inline
|
||||
void add_interface( CodeClass self, CodeTypename type )
|
||||
{
|
||||
GEN_ASSERT(self.ast !=nullptr);
|
||||
CodeTypename possible_slot = self->ParentType;
|
||||
if ( possible_slot.ast )
|
||||
{
|
||||
// Were adding an interface to parent type, so we need to make sure the parent type is public.
|
||||
ast->ParentAccess = AccessSpec::Public;
|
||||
self->ParentAccess = AccessSpec_Public;
|
||||
// If your planning on adding a proper parent,
|
||||
// then you'll need to move this over to ParentType->next and update ParentAccess accordingly.
|
||||
}
|
||||
|
||||
while ( possible_slot.ast != nullptr )
|
||||
{
|
||||
possible_slot.ast = (AST_Type*) possible_slot->Next.ast;
|
||||
possible_slot.ast = (AST_Typename*) possible_slot->Next.ast;
|
||||
}
|
||||
|
||||
possible_slot.ast = type.ast;
|
||||
}
|
||||
#pragma endregion CodeClass
|
||||
|
||||
void CodeParam::append( CodeParam other )
|
||||
#pragma region CodeParam
|
||||
inline
|
||||
void append( CodeParam appendee, CodeParam other )
|
||||
{
|
||||
AST* self = (AST*) ast;
|
||||
AST* entry = (AST*) other.ast;
|
||||
GEN_ASSERT(appendee.ast != nullptr);
|
||||
Code self = cast(Code, appendee);
|
||||
Code entry = cast(Code, other);
|
||||
|
||||
if ( entry->Parent )
|
||||
entry = entry->duplicate();
|
||||
entry = GEN_NS duplicate( entry );
|
||||
|
||||
entry->Parent = self;
|
||||
|
||||
@ -106,71 +186,177 @@ void CodeParam::append( CodeParam other )
|
||||
self->Last = entry;
|
||||
self->NumEntries++;
|
||||
}
|
||||
|
||||
CodeParam CodeParam::get( s32 idx )
|
||||
inline
|
||||
CodeParam get(CodeParam self, s32 idx )
|
||||
{
|
||||
CodeParam param = *this;
|
||||
GEN_ASSERT(self.ast != nullptr);
|
||||
CodeParam param = * self;
|
||||
do
|
||||
{
|
||||
if ( ! ++ param )
|
||||
return { nullptr };
|
||||
|
||||
return { (AST_Param*) param.raw()->Next };
|
||||
param = cast(Code, param)->Next;
|
||||
}
|
||||
while ( --idx );
|
||||
|
||||
return { nullptr };
|
||||
return param;
|
||||
}
|
||||
|
||||
bool CodeParam::has_entries()
|
||||
inline
|
||||
bool has_entries(CodeParam self)
|
||||
{
|
||||
return ast->NumEntries > 0;
|
||||
GEN_ASSERT(self.ast != nullptr);
|
||||
return self->NumEntries > 0;
|
||||
}
|
||||
|
||||
inline
|
||||
CodeParam& CodeParam::operator ++()
|
||||
{
|
||||
ast = ast->Next.ast;
|
||||
return * this;
|
||||
}
|
||||
|
||||
void CodeStruct::add_interface( CodeType type )
|
||||
inline
|
||||
CodeParam begin(CodeParam params)
|
||||
{
|
||||
CodeType possible_slot = ast->ParentType;
|
||||
if ( params.ast )
|
||||
return { params.ast };
|
||||
|
||||
return { nullptr };
|
||||
}
|
||||
inline
|
||||
CodeParam end(CodeParam params)
|
||||
{
|
||||
// return { (AST_Param*) rcast( AST*, ast)->Last };
|
||||
return { nullptr };
|
||||
}
|
||||
#pragma endregion CodeParam
|
||||
|
||||
#pragma region CodeSpecifiers
|
||||
inline
|
||||
bool append(CodeSpecifiers self, Specifier spec )
|
||||
{
|
||||
if ( self.ast == nullptr )
|
||||
{
|
||||
log_failure("CodeSpecifiers: Attempted to append to a null specifiers AST!");
|
||||
return false;
|
||||
}
|
||||
if ( self->NumEntries == AST_ArrSpecs_Cap )
|
||||
{
|
||||
log_failure("CodeSpecifiers: Attempted to append over %d specifiers to a specifiers AST!", AST_ArrSpecs_Cap );
|
||||
return false;
|
||||
}
|
||||
|
||||
self->ArrSpecs[ self->NumEntries ] = spec;
|
||||
self->NumEntries++;
|
||||
return true;
|
||||
}
|
||||
inline
|
||||
s32 has(CodeSpecifiers self, Specifier spec)
|
||||
{
|
||||
GEN_ASSERT(self.ast != nullptr);
|
||||
for ( s32 idx = 0; idx < self->NumEntries; idx++ ) {
|
||||
if ( self->ArrSpecs[ idx ] == spec )
|
||||
return idx;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
inline
|
||||
s32 remove( CodeSpecifiers self, Specifier to_remove )
|
||||
{
|
||||
AST_Specifiers* ast = self.ast;
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure("CodeSpecifiers: Attempted to append to a null specifiers AST!");
|
||||
return -1;
|
||||
}
|
||||
if ( self->NumEntries == AST_ArrSpecs_Cap )
|
||||
{
|
||||
log_failure("CodeSpecifiers: Attempted to append over %d specifiers to a specifiers AST!", AST_ArrSpecs_Cap );
|
||||
return -1;
|
||||
}
|
||||
|
||||
s32 result = -1;
|
||||
|
||||
s32 curr = 0;
|
||||
s32 next = 0;
|
||||
for(; next < self->NumEntries; ++ curr, ++ next)
|
||||
{
|
||||
Specifier spec = self->ArrSpecs[next];
|
||||
if (spec == to_remove)
|
||||
{
|
||||
result = next;
|
||||
|
||||
next ++;
|
||||
if (next >= self->NumEntries)
|
||||
break;
|
||||
|
||||
spec = self->ArrSpecs[next];
|
||||
}
|
||||
|
||||
self->ArrSpecs[ curr ] = spec;
|
||||
}
|
||||
|
||||
if (result > -1) {
|
||||
self->NumEntries --;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
inline
|
||||
Specifier* begin(CodeSpecifiers self)
|
||||
{
|
||||
if ( self.ast )
|
||||
return & self->ArrSpecs[0];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
inline
|
||||
Specifier* end(CodeSpecifiers self)
|
||||
{
|
||||
return self->ArrSpecs + self->NumEntries;
|
||||
}
|
||||
#pragma endregion CodeSpecifiers
|
||||
|
||||
#pragma region CodeStruct
|
||||
inline
|
||||
void add_interface(CodeStruct self, CodeTypename type )
|
||||
{
|
||||
CodeTypename possible_slot = self->ParentType;
|
||||
if ( possible_slot.ast )
|
||||
{
|
||||
// Were adding an interface to parent type, so we need to make sure the parent type is public.
|
||||
ast->ParentAccess = AccessSpec::Public;
|
||||
self->ParentAccess = AccessSpec_Public;
|
||||
// If your planning on adding a proper parent,
|
||||
// then you'll need to move this over to ParentType->next and update ParentAccess accordingly.
|
||||
}
|
||||
|
||||
while ( possible_slot.ast != nullptr )
|
||||
{
|
||||
possible_slot.ast = (AST_Type*) possible_slot->Next.ast;
|
||||
possible_slot.ast = (AST_Typename*) possible_slot->Next.ast;
|
||||
}
|
||||
|
||||
possible_slot.ast = type.ast;
|
||||
}
|
||||
#pragma endregion Code
|
||||
|
||||
CodeBody def_body( CodeT type )
|
||||
#pragma region Interface
|
||||
inline
|
||||
CodeBody def_body( CodeType type )
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
using namespace ECode;
|
||||
case Class_Body:
|
||||
case Enum_Body:
|
||||
case Export_Body:
|
||||
case Extern_Linkage:
|
||||
case Function_Body:
|
||||
case Global_Body:
|
||||
case Namespace_Body:
|
||||
case Struct_Body:
|
||||
case Union_Body:
|
||||
case CT_Class_Body:
|
||||
case CT_Enum_Body:
|
||||
case CT_Export_Body:
|
||||
case CT_Extern_Linkage:
|
||||
case CT_Function_Body:
|
||||
case CT_Global_Body:
|
||||
case CT_Namespace_Body:
|
||||
case CT_Struct_Body:
|
||||
case CT_Union_Body:
|
||||
break;
|
||||
|
||||
default:
|
||||
log_failure( "def_body: Invalid type %s", (char const*)ECode::to_str(type) );
|
||||
return (CodeBody)Code::Invalid;
|
||||
log_failure( "def_body: Invalid type %s", (char const*)to_str(type) );
|
||||
return (CodeBody)Code_Invalid;
|
||||
}
|
||||
|
||||
Code
|
||||
@ -179,7 +365,8 @@ CodeBody def_body( CodeT type )
|
||||
return (CodeBody)result;
|
||||
}
|
||||
|
||||
StrC token_fmt_impl( sw num, ... )
|
||||
inline
|
||||
StrC token_fmt_impl( ssize num, ... )
|
||||
{
|
||||
local_persist thread_local
|
||||
char buf[GEN_PRINTF_MAXLEN] = { 0 };
|
||||
@ -187,8 +374,9 @@ StrC token_fmt_impl( sw num, ... )
|
||||
|
||||
va_list va;
|
||||
va_start(va, num );
|
||||
sw result = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num, va);
|
||||
ssize result = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num, va);
|
||||
va_end(va);
|
||||
|
||||
return { result, buf };
|
||||
}
|
||||
#pragma endregion Interface
|
||||
|
@ -9,9 +9,9 @@ internal void deinit();
|
||||
}
|
||||
|
||||
internal
|
||||
void* Global_Allocator_Proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags )
|
||||
void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
|
||||
{
|
||||
Arena* last = & Global_AllocatorBuckets.back();
|
||||
Arena* last = array_back(& Global_AllocatorBuckets);
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
@ -19,18 +19,18 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, sw size, sw a
|
||||
{
|
||||
if ( ( last->TotalUsed + size ) > last->TotalSize )
|
||||
{
|
||||
Arena bucket = Arena::init_from_allocator( heap(), Global_BucketSize );
|
||||
Arena bucket = arena_init_from_allocator( heap(), Global_BucketSize );
|
||||
|
||||
if ( bucket.PhysicalStart == nullptr )
|
||||
GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets");
|
||||
|
||||
if ( ! Global_AllocatorBuckets.append( bucket ) )
|
||||
if ( ! array_append( & Global_AllocatorBuckets, bucket ) )
|
||||
GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets");
|
||||
|
||||
last = & Global_AllocatorBuckets.back();
|
||||
last = array_back(& Global_AllocatorBuckets);
|
||||
}
|
||||
|
||||
return alloc_align( * last, size, alignment );
|
||||
return alloc_align( arena_allocator_info(last), size, alignment );
|
||||
}
|
||||
case EAllocation_FREE:
|
||||
{
|
||||
@ -46,15 +46,15 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, sw size, sw a
|
||||
{
|
||||
if ( last->TotalUsed + size > last->TotalSize )
|
||||
{
|
||||
Arena bucket = Arena::init_from_allocator( heap(), Global_BucketSize );
|
||||
Arena bucket = arena_init_from_allocator( heap(), Global_BucketSize );
|
||||
|
||||
if ( bucket.PhysicalStart == nullptr )
|
||||
GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets");
|
||||
|
||||
if ( ! Global_AllocatorBuckets.append( bucket ) )
|
||||
if ( ! array_append( & Global_AllocatorBuckets, bucket ) )
|
||||
GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets");
|
||||
|
||||
last = & Global_AllocatorBuckets.back();
|
||||
last = array_back(& Global_AllocatorBuckets);
|
||||
}
|
||||
|
||||
void* result = alloc_align( last->Backing, size, alignment );
|
||||
@ -74,78 +74,78 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, sw size, sw a
|
||||
internal
|
||||
void define_constants()
|
||||
{
|
||||
Code::Global = make_code();
|
||||
Code::Global->Name = get_cached_string( txt("Global Code") );
|
||||
Code::Global->Content = Code::Global->Name;
|
||||
Code_Global = make_code();
|
||||
Code_Global->Name = get_cached_string( txt("Global Code") );
|
||||
Code_Global->Content = Code_Global->Name;
|
||||
|
||||
Code::Invalid = make_code();
|
||||
Code::Invalid.set_global();
|
||||
Code_Invalid = make_code();
|
||||
set_global(Code_Invalid);
|
||||
|
||||
t_empty = (CodeType) make_code();
|
||||
t_empty->Type = ECode::Typename;
|
||||
t_empty->Name = get_cached_string( txt("") );
|
||||
t_empty.set_global();
|
||||
t_empty = (CodeTypename) make_code();
|
||||
t_empty->Type = CT_Typename;
|
||||
t_empty->Name = get_cached_string( txt("") );
|
||||
set_global(t_empty);
|
||||
|
||||
access_private = make_code();
|
||||
access_private->Type = ECode::Access_Private;
|
||||
access_private->Type = CT_Access_Private;
|
||||
access_private->Name = get_cached_string( txt("private:\n") );
|
||||
access_private.set_global();
|
||||
set_global(access_private);
|
||||
|
||||
access_protected = make_code();
|
||||
access_protected->Type = ECode::Access_Protected;
|
||||
access_protected->Type = CT_Access_Protected;
|
||||
access_protected->Name = get_cached_string( txt("protected:\n") );
|
||||
access_protected.set_global();
|
||||
set_global(access_protected);
|
||||
|
||||
access_public = make_code();
|
||||
access_public->Type = ECode::Access_Public;
|
||||
access_public->Type = CT_Access_Public;
|
||||
access_public->Name = get_cached_string( txt("public:\n") );
|
||||
access_public.set_global();
|
||||
set_global(access_public);
|
||||
|
||||
attrib_api_export = def_attributes( code(GEN_API_Export_Code));
|
||||
attrib_api_export.set_global();
|
||||
set_global(attrib_api_export);
|
||||
|
||||
attrib_api_import = def_attributes( code(GEN_API_Import_Code));
|
||||
attrib_api_import.set_global();
|
||||
set_global(attrib_api_import);
|
||||
|
||||
module_global_fragment = make_code();
|
||||
module_global_fragment->Type = ECode::Untyped;
|
||||
module_global_fragment->Type = CT_Untyped;
|
||||
module_global_fragment->Name = get_cached_string( txt("module;") );
|
||||
module_global_fragment->Content = module_global_fragment->Name;
|
||||
module_global_fragment.set_global();
|
||||
set_global(module_global_fragment);
|
||||
|
||||
module_private_fragment = make_code();
|
||||
module_private_fragment->Type = ECode::Untyped;
|
||||
module_private_fragment->Type = CT_Untyped;
|
||||
module_private_fragment->Name = get_cached_string( txt("module : private;") );
|
||||
module_private_fragment->Content = module_private_fragment->Name;
|
||||
module_private_fragment.set_global();
|
||||
set_global(module_private_fragment);
|
||||
|
||||
fmt_newline = make_code();
|
||||
fmt_newline->Type = ECode::NewLine;
|
||||
fmt_newline.set_global();
|
||||
fmt_newline->Type = CT_NewLine;
|
||||
set_global(fmt_newline);
|
||||
|
||||
pragma_once = (CodePragma) make_code();
|
||||
pragma_once->Type = ECode::Preprocess_Pragma;
|
||||
pragma_once->Type = CT_Preprocess_Pragma;
|
||||
pragma_once->Name = get_cached_string( txt("once") );
|
||||
pragma_once->Content = pragma_once->Name;
|
||||
pragma_once.set_global();
|
||||
set_global(pragma_once);
|
||||
|
||||
param_varadic = (CodeType) make_code();
|
||||
param_varadic->Type = ECode::Parameters;
|
||||
param_varadic = (CodeTypename) make_code();
|
||||
param_varadic->Type = CT_Parameters;
|
||||
param_varadic->Name = get_cached_string( txt("...") );
|
||||
param_varadic->ValueType = t_empty;
|
||||
param_varadic.set_global();
|
||||
set_global(param_varadic);
|
||||
|
||||
preprocess_else = (CodePreprocessCond) make_code();
|
||||
preprocess_else->Type = ECode::Preprocess_Else;
|
||||
preprocess_else.set_global();
|
||||
preprocess_else->Type = CT_Preprocess_Else;
|
||||
set_global(preprocess_else);
|
||||
|
||||
preprocess_endif = (CodePreprocessCond) make_code();
|
||||
preprocess_endif->Type = ECode::Preprocess_EndIf;
|
||||
preprocess_endif.set_global();
|
||||
preprocess_endif->Type = CT_Preprocess_EndIf;
|
||||
set_global(preprocess_endif);
|
||||
|
||||
# define def_constant_code_type( Type_ ) \
|
||||
t_##Type_ = def_type( name(Type_) ); \
|
||||
t_##Type_.set_global();
|
||||
set_global(t_##Type_);
|
||||
|
||||
def_constant_code_type( auto );
|
||||
def_constant_code_type( void );
|
||||
@ -169,8 +169,8 @@ void define_constants()
|
||||
def_constant_code_type( u32 );
|
||||
def_constant_code_type( u64 );
|
||||
|
||||
def_constant_code_type( sw );
|
||||
def_constant_code_type( uw );
|
||||
def_constant_code_type( ssize );
|
||||
def_constant_code_type( usize );
|
||||
|
||||
def_constant_code_type( f32 );
|
||||
def_constant_code_type( f64 );
|
||||
@ -180,7 +180,7 @@ void define_constants()
|
||||
|
||||
# define def_constant_spec( Type_, ... ) \
|
||||
spec_##Type_ = def_specifiers( num_args(__VA_ARGS__), __VA_ARGS__); \
|
||||
spec_##Type_.set_global();
|
||||
set_global(spec_##Type_);
|
||||
|
||||
# pragma push_macro("forceinline")
|
||||
# pragma push_macro("global")
|
||||
@ -192,33 +192,33 @@ void define_constants()
|
||||
# undef internal
|
||||
# undef local_persist
|
||||
# undef neverinline
|
||||
def_constant_spec( const, ESpecifier::Const );
|
||||
def_constant_spec( consteval, ESpecifier::Consteval );
|
||||
def_constant_spec( constexpr, ESpecifier::Constexpr );
|
||||
def_constant_spec( constinit, ESpecifier::Constinit );
|
||||
def_constant_spec( extern_linkage, ESpecifier::External_Linkage );
|
||||
def_constant_spec( final, ESpecifier::Final );
|
||||
def_constant_spec( forceinline, ESpecifier::ForceInline );
|
||||
def_constant_spec( global, ESpecifier::Global );
|
||||
def_constant_spec( inline, ESpecifier::Inline );
|
||||
def_constant_spec( internal_linkage, ESpecifier::Internal_Linkage );
|
||||
def_constant_spec( local_persist, ESpecifier::Local_Persist );
|
||||
def_constant_spec( mutable, ESpecifier::Mutable );
|
||||
def_constant_spec( neverinline, ESpecifier::NeverInline );
|
||||
def_constant_spec( noexcept, ESpecifier::NoExceptions );
|
||||
def_constant_spec( override, ESpecifier::Override );
|
||||
def_constant_spec( ptr, ESpecifier::Ptr );
|
||||
def_constant_spec( pure, ESpecifier::Pure )
|
||||
def_constant_spec( ref, ESpecifier::Ref );
|
||||
def_constant_spec( register, ESpecifier::Register );
|
||||
def_constant_spec( rvalue, ESpecifier::RValue );
|
||||
def_constant_spec( static_member, ESpecifier::Static );
|
||||
def_constant_spec( thread_local, ESpecifier::Thread_Local );
|
||||
def_constant_spec( virtual, ESpecifier::Virtual );
|
||||
def_constant_spec( volatile, ESpecifier::Volatile)
|
||||
def_constant_spec( const, Spec_Const );
|
||||
def_constant_spec( consteval, Spec_Consteval );
|
||||
def_constant_spec( constexpr, Spec_Constexpr );
|
||||
def_constant_spec( constinit, Spec_Constinit );
|
||||
def_constant_spec( extern_linkage, Spec_External_Linkage );
|
||||
def_constant_spec( final, Spec_Final );
|
||||
def_constant_spec( forceinline, Spec_ForceInline );
|
||||
def_constant_spec( global, Spec_Global );
|
||||
def_constant_spec( inline, Spec_Inline );
|
||||
def_constant_spec( internal_linkage, Spec_Internal_Linkage );
|
||||
def_constant_spec( local_persist, Spec_Local_Persist );
|
||||
def_constant_spec( mutable, Spec_Mutable );
|
||||
def_constant_spec( neverinline, Spec_NeverInline );
|
||||
def_constant_spec( noexcept, Spec_NoExceptions );
|
||||
def_constant_spec( override, Spec_Override );
|
||||
def_constant_spec( ptr, Spec_Ptr );
|
||||
def_constant_spec( pure, Spec_Pure )
|
||||
def_constant_spec( ref, Spec_Ref );
|
||||
def_constant_spec( register, Spec_Register );
|
||||
def_constant_spec( rvalue, Spec_RValue );
|
||||
def_constant_spec( static_member, Spec_Static );
|
||||
def_constant_spec( thread_local, Spec_Thread_Local );
|
||||
def_constant_spec( virtual, Spec_Virtual );
|
||||
def_constant_spec( volatile, Spec_Volatile)
|
||||
|
||||
spec_local_persist = def_specifiers( 1, ESpecifier::Local_Persist );
|
||||
spec_local_persist.set_global();
|
||||
spec_local_persist = def_specifiers( 1, Spec_Local_Persist );
|
||||
set_global(spec_local_persist);
|
||||
|
||||
# pragma pop_macro("forceinline")
|
||||
# pragma pop_macro("global")
|
||||
@ -226,6 +226,10 @@ void define_constants()
|
||||
# pragma pop_macro("local_persist")
|
||||
# pragma pop_macro("neverinline")
|
||||
|
||||
# pragma push_macro("enum_underlying")
|
||||
|
||||
# pragma pop_macro("enum_underlying")
|
||||
|
||||
# undef def_constant_spec
|
||||
}
|
||||
|
||||
@ -235,28 +239,27 @@ void init()
|
||||
{
|
||||
GlobalAllocator = AllocatorInfo { & Global_Allocator_Proc, nullptr };
|
||||
|
||||
Global_AllocatorBuckets = Array<Arena>::init_reserve( heap(), 128 );
|
||||
Global_AllocatorBuckets = array_init_reserve<Arena>( heap(), 128 );
|
||||
|
||||
if ( Global_AllocatorBuckets == nullptr )
|
||||
GEN_FATAL( "Failed to reserve memory for Global_AllocatorBuckets");
|
||||
|
||||
Arena bucket = Arena::init_from_allocator( heap(), Global_BucketSize );
|
||||
Arena bucket = arena_init_from_allocator( heap(), Global_BucketSize );
|
||||
|
||||
if ( bucket.PhysicalStart == nullptr )
|
||||
GEN_FATAL( "Failed to create first bucket for Global_AllocatorBuckets");
|
||||
|
||||
Global_AllocatorBuckets.append( bucket );
|
||||
|
||||
array_append( & Global_AllocatorBuckets, bucket );
|
||||
}
|
||||
|
||||
// Setup the arrays
|
||||
{
|
||||
CodePools = Array<Pool>::init_reserve( Allocator_DataArrays, InitSize_DataArrays );
|
||||
CodePools = array_init_reserve<Pool>( Allocator_DataArrays, InitSize_DataArrays );
|
||||
|
||||
if ( CodePools == nullptr )
|
||||
GEN_FATAL( "gen::init: Failed to initialize the CodePools array" );
|
||||
|
||||
StringArenas = Array<Arena>::init_reserve( Allocator_DataArrays, InitSize_DataArrays );
|
||||
StringArenas = array_init_reserve<Arena>( Allocator_DataArrays, InitSize_DataArrays );
|
||||
|
||||
if ( StringArenas == nullptr )
|
||||
GEN_FATAL( "gen::init: Failed to initialize the StringArenas array" );
|
||||
@ -264,33 +267,33 @@ void init()
|
||||
|
||||
// Setup the code pool and code entries arena.
|
||||
{
|
||||
Pool code_pool = Pool::init( Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) );
|
||||
Pool code_pool = pool_init( Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) );
|
||||
|
||||
if ( code_pool.PhysicalStart == nullptr )
|
||||
GEN_FATAL( "gen::init: Failed to initialize the code pool" );
|
||||
|
||||
CodePools.append( code_pool );
|
||||
array_append( & CodePools, code_pool );
|
||||
|
||||
LexArena = Arena::init_from_allocator( Allocator_Lexer, LexAllocator_Size );
|
||||
LexArena = arena_init_from_allocator( Allocator_Lexer, LexAllocator_Size );
|
||||
|
||||
Arena string_arena = Arena::init_from_allocator( Allocator_StringArena, SizePer_StringArena );
|
||||
Arena string_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena );
|
||||
|
||||
if ( string_arena.PhysicalStart == nullptr )
|
||||
GEN_FATAL( "gen::init: Failed to initialize the string arena" );
|
||||
|
||||
StringArenas.append( string_arena );
|
||||
array_append( & StringArenas, string_arena );
|
||||
}
|
||||
|
||||
// Setup the hash tables
|
||||
{
|
||||
StringCache = StringTable::init( Allocator_StringTable );
|
||||
StringCache = hashtable_init<StringCached>(Allocator_StringTable);
|
||||
|
||||
if ( StringCache.Entries == nullptr )
|
||||
GEN_FATAL( "gen::init: Failed to initialize the StringCache");
|
||||
}
|
||||
|
||||
// Preprocessor Defines
|
||||
PreprocessorDefines = Array<StringCached>::init_reserve( GlobalAllocator, kilobytes(1) );
|
||||
PreprocessorDefines = array_init_reserve<StringCached>( GlobalAllocator, kilobytes(1) );
|
||||
|
||||
define_constants();
|
||||
parser::init();
|
||||
@ -298,63 +301,63 @@ void init()
|
||||
|
||||
void deinit()
|
||||
{
|
||||
uw index = 0;
|
||||
uw left = CodePools.num();
|
||||
usize index = 0;
|
||||
usize left = array_num(CodePools);
|
||||
do
|
||||
{
|
||||
Pool* code_pool = & CodePools[index];
|
||||
code_pool->free();
|
||||
pool_free(code_pool);
|
||||
index++;
|
||||
}
|
||||
while ( left--, left );
|
||||
|
||||
index = 0;
|
||||
left = StringArenas.num();
|
||||
left = array_num(StringArenas);
|
||||
do
|
||||
{
|
||||
Arena* string_arena = & StringArenas[index];
|
||||
string_arena->free();
|
||||
arena_free(string_arena);
|
||||
index++;
|
||||
}
|
||||
while ( left--, left );
|
||||
|
||||
StringCache.destroy();
|
||||
destroy(& StringCache);
|
||||
|
||||
CodePools.free();
|
||||
StringArenas.free();
|
||||
array_free( & CodePools);
|
||||
array_free( & StringArenas);
|
||||
|
||||
LexArena.free();
|
||||
arena_free(& LexArena);
|
||||
|
||||
PreprocessorDefines.free();
|
||||
array_free(& PreprocessorDefines);
|
||||
|
||||
index = 0;
|
||||
left = Global_AllocatorBuckets.num();
|
||||
left = array_num(Global_AllocatorBuckets);
|
||||
do
|
||||
{
|
||||
Arena* bucket = & Global_AllocatorBuckets[ index ];
|
||||
bucket->free();
|
||||
arena_free(bucket);
|
||||
index++;
|
||||
}
|
||||
while ( left--, left );
|
||||
|
||||
Global_AllocatorBuckets.free();
|
||||
array_free(& Global_AllocatorBuckets);
|
||||
parser::deinit();
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
s32 index = 0;
|
||||
s32 left = CodePools.num();
|
||||
s32 left = array_num(CodePools);
|
||||
do
|
||||
{
|
||||
Pool* code_pool = & CodePools[index];
|
||||
code_pool->clear();
|
||||
pool_clear(code_pool);
|
||||
index++;
|
||||
}
|
||||
while ( left--, left );
|
||||
|
||||
index = 0;
|
||||
left = StringArenas.num();
|
||||
left = array_num(StringArenas);
|
||||
do
|
||||
{
|
||||
Arena* string_arena = & StringArenas[index];
|
||||
@ -363,28 +366,28 @@ void reset()
|
||||
}
|
||||
while ( left--, left );
|
||||
|
||||
StringCache.clear();
|
||||
clear(StringCache);
|
||||
|
||||
define_constants();
|
||||
}
|
||||
|
||||
AllocatorInfo get_string_allocator( s32 str_length )
|
||||
{
|
||||
Arena* last = & StringArenas.back();
|
||||
Arena* last = array_back(& StringArenas);
|
||||
|
||||
uw size_req = str_length + sizeof(String::Header) + sizeof(char*);
|
||||
usize size_req = str_length + sizeof(StringHeader) + sizeof(char*);
|
||||
|
||||
if ( last->TotalUsed + size_req > last->TotalSize )
|
||||
if ( last->TotalUsed + ssize(size_req) > last->TotalSize )
|
||||
{
|
||||
Arena new_arena = Arena::init_from_allocator( Allocator_StringArena, SizePer_StringArena );
|
||||
Arena new_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena );
|
||||
|
||||
if ( ! StringArenas.append( new_arena ) )
|
||||
if ( ! array_append( & StringArenas, new_arena ) )
|
||||
GEN_FATAL( "gen::get_string_allocator: Failed to allocate a new string arena" );
|
||||
|
||||
last = & StringArenas.back();
|
||||
last = array_back(& StringArenas);
|
||||
}
|
||||
|
||||
return * last;
|
||||
return arena_allocator_info(last);
|
||||
}
|
||||
|
||||
// Will either make or retrive a code string.
|
||||
@ -393,36 +396,36 @@ StringCached get_cached_string( StrC str )
|
||||
s32 hash_length = str.Len > kilobytes(1) ? kilobytes(1) : str.Len;
|
||||
u64 key = crc32( str.Ptr, hash_length );
|
||||
{
|
||||
StringCached* result = StringCache.get( key );
|
||||
StringCached* result = get(StringCache, key );
|
||||
|
||||
if ( result )
|
||||
return * result;
|
||||
}
|
||||
|
||||
String result = String::make( get_string_allocator( str.Len ), str );
|
||||
StringCache.set( key, result );
|
||||
String result = string_make_strc( get_string_allocator( str.Len ), str );
|
||||
set(& StringCache, key, { str.Len, result } );
|
||||
|
||||
return result;
|
||||
return { str.Len, result };
|
||||
}
|
||||
|
||||
// Used internally to retireve a Code object form the CodePool.
|
||||
Code make_code()
|
||||
{
|
||||
Pool* allocator = & CodePools.back();
|
||||
Pool* allocator = array_back( & CodePools);
|
||||
if ( allocator->FreeList == nullptr )
|
||||
{
|
||||
Pool code_pool = Pool::init( Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) );
|
||||
Pool code_pool = pool_init( Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) );
|
||||
|
||||
if ( code_pool.PhysicalStart == nullptr )
|
||||
GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePool allcoator returned nullptr." );
|
||||
|
||||
if ( ! CodePools.append( code_pool ) )
|
||||
if ( ! array_append( & CodePools, code_pool ) )
|
||||
GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePools failed to append new pool." );
|
||||
|
||||
allocator = & CodePools.back();
|
||||
allocator = array_back( & CodePools);
|
||||
}
|
||||
|
||||
Code result { rcast( AST*, alloc( * allocator, sizeof(AST) )) };
|
||||
Code result { rcast( AST*, alloc( pool_allocator_info(allocator), sizeof(AST) )) };
|
||||
mem_set( result.ast, 0, sizeof(AST) );
|
||||
// result->Type = ECode::Invalid;
|
||||
|
||||
|
@ -42,77 +42,129 @@ void set_allocator_type_table ( AllocatorInfo type_reg_allocator );
|
||||
CodeAttributes def_attributes( StrC content );
|
||||
CodeComment def_comment ( StrC content );
|
||||
|
||||
CodeClass def_class( StrC name
|
||||
, Code body = NoCode
|
||||
, CodeType parent = NoCode, AccessSpec access = AccessSpec::Default
|
||||
, CodeAttributes attributes = NoCode
|
||||
, ModuleFlag mflags = ModuleFlag::None
|
||||
, CodeType* interfaces = nullptr, s32 num_interfaces = 0 );
|
||||
struct Opts_def_struct {
|
||||
Code body;
|
||||
CodeTypename parent;
|
||||
AccessSpec parent_access;
|
||||
CodeAttributes attributes;
|
||||
ModuleFlag mflags;
|
||||
CodeTypename* interfaces;
|
||||
s32 num_interfaces;
|
||||
};
|
||||
CodeClass def_class( StrC name, Opts_def_struct otps GEN_PARAM_DEFAULT );
|
||||
|
||||
CodeConstructor def_constructor( CodeParam params = NoCode, Code initializer_list = NoCode, Code body = NoCode );
|
||||
struct Opts_def_constructor {
|
||||
CodeParam params;
|
||||
Code initializer_list;
|
||||
Code body;
|
||||
};
|
||||
CodeConstructor def_constructor( Opts_def_constructor opts GEN_PARAM_DEFAULT );
|
||||
|
||||
CodeDefine def_define( StrC name, StrC content );
|
||||
|
||||
CodeDestructor def_destructor( Code body = NoCode, CodeSpecifiers specifiers = NoCode );
|
||||
struct Opts_def_destructor {
|
||||
Code body;
|
||||
CodeSpecifiers specifiers;
|
||||
};
|
||||
CodeDestructor def_destructor( Opts_def_destructor opts GEN_PARAM_DEFAULT );
|
||||
|
||||
CodeEnum def_enum( StrC name
|
||||
, Code body = NoCode, CodeType type = NoCode
|
||||
, EnumT specifier = EnumRegular, CodeAttributes attributes = NoCode
|
||||
, ModuleFlag mflags = ModuleFlag::None );
|
||||
struct Opts_def_enum {
|
||||
Code body;
|
||||
CodeTypename type;
|
||||
EnumT specifier;
|
||||
CodeAttributes attributes;
|
||||
ModuleFlag mflags;
|
||||
};
|
||||
CodeEnum def_enum( StrC name, Opts_def_enum opts GEN_PARAM_DEFAULT );
|
||||
|
||||
CodeExec def_execution ( StrC content );
|
||||
CodeExtern def_extern_link( StrC name, Code body );
|
||||
CodeFriend def_friend ( Code symbol );
|
||||
|
||||
CodeFn def_function( StrC name
|
||||
, CodeParam params = NoCode, CodeType ret_type = NoCode, Code body = NoCode
|
||||
, CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode
|
||||
, ModuleFlag mflags = ModuleFlag::None );
|
||||
struct Opts_def_function {
|
||||
CodeParam params;
|
||||
CodeTypename ret_type;
|
||||
Code body;
|
||||
CodeSpecifiers specs;
|
||||
CodeAttributes attrs;
|
||||
ModuleFlag mflags;
|
||||
};
|
||||
CodeFn def_function( StrC name, Opts_def_function opts GEN_PARAM_DEFAULT );
|
||||
|
||||
CodeInclude def_include ( StrC content, bool foreign = false );
|
||||
CodeModule def_module ( StrC name, ModuleFlag mflags = ModuleFlag::None );
|
||||
CodeNS def_namespace( StrC name, Code body, ModuleFlag mflags = ModuleFlag::None );
|
||||
struct Opts_def_include { b32 foreign; };
|
||||
struct Opts_def_module { ModuleFlag mflags; };
|
||||
struct Opts_def_namespace { ModuleFlag mflags; };
|
||||
CodeInclude def_include ( StrC content, Opts_def_include opts GEN_PARAM_DEFAULT );
|
||||
CodeModule def_module ( StrC name, Opts_def_module opts GEN_PARAM_DEFAULT );
|
||||
CodeNS def_namespace( StrC name, Code body, Opts_def_namespace opts GEN_PARAM_DEFAULT );
|
||||
|
||||
CodeOperator def_operator( OperatorT op, StrC nspace
|
||||
, CodeParam params = NoCode, CodeType ret_type = NoCode, Code body = NoCode
|
||||
, CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode
|
||||
, ModuleFlag mflags = ModuleFlag::None );
|
||||
struct Opts_def_operator {
|
||||
CodeParam params;
|
||||
CodeTypename ret_type;
|
||||
Code body;
|
||||
CodeSpecifiers specifiers;
|
||||
CodeAttributes attributes;
|
||||
ModuleFlag mflags;
|
||||
};
|
||||
CodeOperator def_operator( Operator op, StrC nspace, Opts_def_operator opts GEN_PARAM_DEFAULT );
|
||||
|
||||
CodeOpCast def_operator_cast( CodeType type, Code body = NoCode, CodeSpecifiers specs = NoCode );
|
||||
struct Opts_def_operator_cast {
|
||||
Code body;
|
||||
CodeSpecifiers specs;
|
||||
};
|
||||
CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast opts GEN_PARAM_DEFAULT );
|
||||
|
||||
CodeParam def_param ( CodeType type, StrC name, Code value = NoCode );
|
||||
struct Opts_def_param { Code value; };
|
||||
CodeParam def_param ( CodeTypename type, StrC name, Opts_def_param opts GEN_PARAM_DEFAULT );
|
||||
CodePragma def_pragma( StrC directive );
|
||||
|
||||
CodePreprocessCond def_preprocess_cond( EPreprocessCond type, StrC content );
|
||||
|
||||
CodeSpecifiers def_specifier( SpecifierT specifier );
|
||||
CodeSpecifiers def_specifier( Specifier specifier );
|
||||
|
||||
CodeStruct def_struct( StrC name
|
||||
, Code body = NoCode
|
||||
, CodeType parent = NoCode, AccessSpec access = AccessSpec::Default
|
||||
, CodeAttributes attributes = NoCode
|
||||
, ModuleFlag mflags = ModuleFlag::None
|
||||
, CodeType* interfaces = nullptr, s32 num_interfaces = 0 );
|
||||
CodeStruct def_struct( StrC name, Opts_def_struct opts GEN_PARAM_DEFAULT );
|
||||
|
||||
CodeTemplate def_template( CodeParam params, Code definition, ModuleFlag mflags = ModuleFlag::None );
|
||||
struct Opts_def_template { ModuleFlag mflags; };
|
||||
CodeTemplate def_template( CodeParam params, Code definition, Opts_def_template opts GEN_PARAM_DEFAULT );
|
||||
|
||||
CodeType def_type ( StrC name, Code arrayexpr = NoCode, CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode );
|
||||
CodeTypedef def_typedef( StrC name, Code type, CodeAttributes attributes = NoCode, ModuleFlag mflags = ModuleFlag::None );
|
||||
struct Opts_def_type {
|
||||
Code arrayexpr;
|
||||
CodeSpecifiers specifiers;
|
||||
CodeAttributes attributes;
|
||||
};
|
||||
CodeTypename def_type( StrC name, Opts_def_type opts GEN_PARAM_DEFAULT );
|
||||
|
||||
CodeUnion def_union( StrC name, Code body, CodeAttributes attributes = NoCode, ModuleFlag mflags = ModuleFlag::None );
|
||||
struct Opts_def_typedef {
|
||||
CodeAttributes attributes;
|
||||
ModuleFlag mflags;
|
||||
};
|
||||
CodeTypedef def_typedef( StrC name, Code type, Opts_def_typedef opts GEN_PARAM_DEFAULT );
|
||||
|
||||
CodeUsing def_using( StrC name, CodeType type = NoCode
|
||||
, CodeAttributes attributess = NoCode
|
||||
, ModuleFlag mflags = ModuleFlag::None );
|
||||
struct Opts_def_union {
|
||||
CodeAttributes attributes;
|
||||
ModuleFlag mflags;
|
||||
};
|
||||
CodeUnion def_union( StrC name, Code body, Opts_def_union opts GEN_PARAM_DEFAULT );
|
||||
|
||||
struct Opts_def_using {
|
||||
CodeAttributes attributes;
|
||||
ModuleFlag mflags;
|
||||
};
|
||||
CodeUsing def_using( StrC name, Code type, Opts_def_using opts GEN_PARAM_DEFAULT );
|
||||
|
||||
CodeUsing def_using_namespace( StrC name );
|
||||
|
||||
CodeVar def_variable( CodeType type, StrC name, Code value = NoCode
|
||||
, CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode
|
||||
, ModuleFlag mflags = ModuleFlag::None );
|
||||
struct Opts_def_variable
|
||||
{
|
||||
Code value;
|
||||
CodeSpecifiers specifiers;
|
||||
CodeAttributes attributes;
|
||||
ModuleFlag mflags;
|
||||
};
|
||||
CodeVar def_variable( CodeTypename type, StrC name, Opts_def_variable opts GEN_PARAM_DEFAULT );
|
||||
|
||||
// Constructs an empty body. Use AST::validate_body() to check if the body is was has valid entries.
|
||||
CodeBody def_body( CodeT type );
|
||||
CodeBody def_body( CodeTypename type );
|
||||
|
||||
// There are two options for defining a struct body, either varadically provided with the args macro to auto-deduce the arg num,
|
||||
/// or provide as an array of Code objects.
|
||||
@ -134,7 +186,7 @@ CodeBody def_namespace_body ( s32 num, Code* codes );
|
||||
CodeParam def_params ( s32 num, ... );
|
||||
CodeParam def_params ( s32 num, CodeParam* params );
|
||||
CodeSpecifiers def_specifiers ( s32 num, ... );
|
||||
CodeSpecifiers def_specifiers ( s32 num, SpecifierT* specs );
|
||||
CodeSpecifiers def_specifiers ( s32 num, Specifier* specs );
|
||||
CodeBody def_struct_body ( s32 num, ... );
|
||||
CodeBody def_struct_body ( s32 num, Code* codes );
|
||||
CodeBody def_union_body ( s32 num, ... );
|
||||
@ -166,7 +218,7 @@ namespace parser {
|
||||
}
|
||||
|
||||
struct ParseInfo
|
||||
|
||||
{
|
||||
Arena FileMem;
|
||||
Arena TokMem;
|
||||
Arena CodeMem;
|
||||
@ -175,7 +227,7 @@ struct ParseInfo
|
||||
Array<parser::Token> Tokens;
|
||||
Array<parser::Error> Errors;
|
||||
// Errors are allocated to a dedicated general arena.
|
||||
;
|
||||
};
|
||||
|
||||
CodeBody parse_file( StrC path );
|
||||
#endif
|
||||
@ -194,7 +246,7 @@ CodeOperator parse_operator ( StrC operator_def );
|
||||
CodeOpCast parse_operator_cast( StrC operator_def );
|
||||
CodeStruct parse_struct ( StrC struct_def );
|
||||
CodeTemplate parse_template ( StrC template_def );
|
||||
CodeType parse_type ( StrC type_def );
|
||||
CodeTypename parse_type ( StrC type_def );
|
||||
CodeTypedef parse_typedef ( StrC typedef_def );
|
||||
CodeUnion parse_union ( StrC union_def );
|
||||
CodeUsing parse_using ( StrC using_def );
|
||||
@ -204,9 +256,9 @@ CodeVar parse_variable ( StrC var_def );
|
||||
|
||||
#pragma region Untyped text
|
||||
|
||||
sw token_fmt_va( char* buf, uw buf_size, s32 num_tokens, va_list va );
|
||||
ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va );
|
||||
//! Do not use directly. Use the token_fmt macro instead.
|
||||
StrC token_fmt_impl( sw, ... );
|
||||
StrC token_fmt_impl( ssize, ... );
|
||||
|
||||
Code untyped_str ( StrC content);
|
||||
Code untyped_fmt ( char const* fmt, ... );
|
||||
|
@ -10,58 +10,58 @@
|
||||
|
||||
CodeClass parse_class( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
using namespace parser;
|
||||
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
push_scope();
|
||||
CodeClass result = (CodeClass) parse_class_struct( TokType::Decl_Class );
|
||||
Context.pop();
|
||||
CodeClass result = (CodeClass) parse_class_struct( Tok_Decl_Class );
|
||||
pop(& Context);
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeConstructor parse_constructor( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
using namespace parser;
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
|
||||
// TODO(Ed): Constructors can have prefix attributes
|
||||
|
||||
CodeSpecifiers specifiers;
|
||||
SpecifierT specs_found[ 16 ] { ESpecifier::NumSpecifiers };
|
||||
Specifier specs_found[ 16 ] { Spec_NumSpecifiers };
|
||||
s32 NumSpecifiers = 0;
|
||||
|
||||
while ( left && currtok.is_specifier() )
|
||||
while ( left && is_specifier(currtok) )
|
||||
{
|
||||
SpecifierT spec = ESpecifier::to_type( currtok );
|
||||
Specifier spec = to_specifier( to_str(currtok) );
|
||||
|
||||
b32 ignore_spec = false;
|
||||
|
||||
switch ( spec )
|
||||
{
|
||||
case ESpecifier::Constexpr :
|
||||
case ESpecifier::Explicit:
|
||||
case ESpecifier::Inline :
|
||||
case ESpecifier::ForceInline :
|
||||
case ESpecifier::NeverInline :
|
||||
case Spec_Constexpr :
|
||||
case Spec_Explicit:
|
||||
case Spec_Inline :
|
||||
case Spec_ForceInline :
|
||||
case Spec_NeverInline :
|
||||
break;
|
||||
|
||||
case ESpecifier::Const :
|
||||
case Spec_Const :
|
||||
ignore_spec = true;
|
||||
break;
|
||||
|
||||
default :
|
||||
log_failure( "Invalid specifier %s for variable\n%s", ESpecifier::to_str( spec ), Context.to_string() );
|
||||
Context.pop();
|
||||
return CodeInvalid;
|
||||
log_failure( "Invalid specifier %s for variable\n%s", to_str( spec ), to_string(Context) );
|
||||
pop(& Context);
|
||||
return InvalidCode;
|
||||
}
|
||||
|
||||
// Every specifier after would be considered part of the type type signature
|
||||
@ -86,12 +86,12 @@ CodeConstructor parse_constructor( StrC def )
|
||||
|
||||
CodeDestructor parse_destructor( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
using namespace parser;
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
|
||||
// TODO(Ed): Destructors can have prefix attributes
|
||||
// TODO(Ed): Destructors can have virtual
|
||||
@ -103,14 +103,14 @@ CodeDestructor parse_destructor( StrC def )
|
||||
|
||||
CodeEnum parse_enum( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
using namespace parser;
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
{
|
||||
Context.pop();
|
||||
return CodeInvalid;
|
||||
pop(& Context);
|
||||
return InvalidCode;
|
||||
}
|
||||
|
||||
Context.Tokens = toks;
|
||||
@ -119,12 +119,12 @@ CodeEnum parse_enum( StrC def )
|
||||
|
||||
CodeBody parse_export_body( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
using namespace parser;
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parse_export_body();
|
||||
@ -132,12 +132,12 @@ CodeBody parse_export_body( StrC def )
|
||||
|
||||
CodeExtern parse_extern_link( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
using namespace parser;
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parse_extern_link();
|
||||
@ -145,12 +145,12 @@ CodeExtern parse_extern_link( StrC def )
|
||||
|
||||
CodeFriend parse_friend( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
using namespace parser;
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parse_friend();
|
||||
@ -158,12 +158,12 @@ CodeFriend parse_friend( StrC def )
|
||||
|
||||
CodeFn parse_function( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
using namespace parser;
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return (CodeFn) parse_function();
|
||||
@ -171,28 +171,28 @@ CodeFn parse_function( StrC def )
|
||||
|
||||
CodeBody parse_global_body( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
using namespace parser;
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
push_scope();
|
||||
CodeBody result = parse_global_nspace( ECode::Global_Body );
|
||||
Context.pop();
|
||||
CodeBody result = parse_global_nspace( CT_Global_Body );
|
||||
pop(& Context);
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeNS parse_namespace( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
using namespace parser;
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parse_namespace();
|
||||
@ -200,12 +200,12 @@ CodeNS parse_namespace( StrC def )
|
||||
|
||||
CodeOperator parse_operator( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
using namespace parser;
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return (CodeOperator) parse_operator();
|
||||
@ -213,12 +213,12 @@ CodeOperator parse_operator( StrC def )
|
||||
|
||||
CodeOpCast parse_operator_cast( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
using namespace parser;
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parse_operator_cast();
|
||||
@ -226,41 +226,41 @@ CodeOpCast parse_operator_cast( StrC def )
|
||||
|
||||
CodeStruct parse_struct( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
using namespace parser;
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
push_scope();
|
||||
CodeStruct result = (CodeStruct) parse_class_struct( TokType::Decl_Struct );
|
||||
Context.pop();
|
||||
CodeStruct result = (CodeStruct) parse_class_struct( Tok_Decl_Struct );
|
||||
pop(& Context);
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeTemplate parse_template( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
using namespace parser;
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parse_template();
|
||||
}
|
||||
|
||||
CodeType parse_type( StrC def )
|
||||
CodeTypename parse_type( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
using namespace parser;
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parse_type();
|
||||
@ -268,12 +268,12 @@ CodeType parse_type( StrC def )
|
||||
|
||||
CodeTypedef parse_typedef( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
using namespace parser;
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parse_typedef();
|
||||
@ -281,12 +281,12 @@ CodeTypedef parse_typedef( StrC def )
|
||||
|
||||
CodeUnion parse_union( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
using namespace parser;
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parse_union();
|
||||
@ -294,12 +294,12 @@ CodeUnion parse_union( StrC def )
|
||||
|
||||
CodeUsing parse_using( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
using namespace parser;
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parse_using();
|
||||
@ -307,12 +307,12 @@ CodeUsing parse_using( StrC def )
|
||||
|
||||
CodeVar parse_variable( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
using namespace parser;
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parse_variable();
|
||||
|
@ -3,21 +3,21 @@
|
||||
#include "interface.parsing.cpp"
|
||||
#endif
|
||||
|
||||
sw token_fmt_va( char* buf, uw buf_size, s32 num_tokens, va_list va )
|
||||
ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
|
||||
{
|
||||
char const* buf_begin = buf;
|
||||
sw remaining = buf_size;
|
||||
ssize remaining = buf_size;
|
||||
|
||||
local_persist
|
||||
Arena tok_map_arena;
|
||||
|
||||
HashTable<StrC> tok_map;
|
||||
HashTable(StrC) tok_map;
|
||||
{
|
||||
local_persist
|
||||
char tok_map_mem[ TokenFmt_TokenMap_MemSize ];
|
||||
|
||||
tok_map_arena = Arena::init_from_memory( tok_map_mem, sizeof(tok_map_mem) );
|
||||
tok_map = HashTable<StrC>::init( tok_map_arena );
|
||||
tok_map_arena = arena_init_from_memory( tok_map_mem, sizeof(tok_map_mem) );
|
||||
tok_map = hashtable_init(StrC, arena_allocator_info(& tok_map_arena) );
|
||||
|
||||
s32 left = num_tokens - 1;
|
||||
|
||||
@ -27,8 +27,7 @@ sw token_fmt_va( char* buf, uw buf_size, s32 num_tokens, va_list va )
|
||||
StrC value = va_arg( va, StrC );
|
||||
|
||||
u32 key = crc32( token, str_len(token) );
|
||||
|
||||
tok_map.set( key, value );
|
||||
set(& tok_map, key, value );
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,7 +36,7 @@ sw token_fmt_va( char* buf, uw buf_size, s32 num_tokens, va_list va )
|
||||
|
||||
while ( current )
|
||||
{
|
||||
sw len = 0;
|
||||
ssize len = 0;
|
||||
|
||||
while ( current && current != '<' && remaining )
|
||||
{
|
||||
@ -64,11 +63,11 @@ sw token_fmt_va( char* buf, uw buf_size, s32 num_tokens, va_list va )
|
||||
char const* token = fmt + 1;
|
||||
|
||||
u32 key = crc32( token, tok_len );
|
||||
StrC* value = tok_map.get( key );
|
||||
StrC* value = get(tok_map, key );
|
||||
|
||||
if ( value )
|
||||
{
|
||||
sw left = value->Len;
|
||||
ssize left = value->Len;
|
||||
char const* str = value->Ptr;
|
||||
|
||||
while ( left-- )
|
||||
@ -94,10 +93,10 @@ sw token_fmt_va( char* buf, uw buf_size, s32 num_tokens, va_list va )
|
||||
}
|
||||
}
|
||||
|
||||
tok_map.clear();
|
||||
tok_map_arena.free();
|
||||
clear(tok_map);
|
||||
arena_free(& tok_map_arena);
|
||||
|
||||
sw result = buf_size - remaining;
|
||||
ssize result = buf_size - remaining;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -107,19 +106,19 @@ Code untyped_str( StrC content )
|
||||
if ( content.Len == 0 )
|
||||
{
|
||||
log_failure( "untyped_str: empty string" );
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
}
|
||||
|
||||
Code
|
||||
result = make_code();
|
||||
result->Name = get_cached_string( content );
|
||||
result->Type = ECode::Untyped;
|
||||
result->Type = CT_Untyped;
|
||||
result->Content = result->Name;
|
||||
|
||||
if ( result->Name == nullptr )
|
||||
{
|
||||
log_failure( "untyped_str: could not cache string" );
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -130,7 +129,7 @@ Code untyped_fmt( char const* fmt, ...)
|
||||
if ( fmt == nullptr )
|
||||
{
|
||||
log_failure( "untyped_fmt: null format string" );
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
}
|
||||
|
||||
local_persist thread_local
|
||||
@ -138,19 +137,19 @@ Code untyped_fmt( char const* fmt, ...)
|
||||
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
sw length = str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va);
|
||||
ssize length = str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va);
|
||||
va_end(va);
|
||||
|
||||
Code
|
||||
result = make_code();
|
||||
result->Name = get_cached_string( { str_len(fmt, MaxNameLength), fmt } );
|
||||
result->Type = ECode::Untyped;
|
||||
result->Name = get_cached_string( { str_len_capped(fmt, MaxNameLength), fmt } );
|
||||
result->Type = CT_Untyped;
|
||||
result->Content = get_cached_string( { length, buf } );
|
||||
|
||||
if ( result->Name == nullptr )
|
||||
{
|
||||
log_failure( "untyped_fmt: could not cache string" );
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -161,7 +160,7 @@ Code untyped_token_fmt( s32 num_tokens, ... )
|
||||
if ( num_tokens == 0 )
|
||||
{
|
||||
log_failure( "untyped_token_fmt: zero tokens" );
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
}
|
||||
|
||||
local_persist thread_local
|
||||
@ -169,19 +168,19 @@ Code untyped_token_fmt( s32 num_tokens, ... )
|
||||
|
||||
va_list va;
|
||||
va_start(va, num_tokens);
|
||||
sw length = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num_tokens, va);
|
||||
ssize length = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num_tokens, va);
|
||||
va_end(va);
|
||||
|
||||
Code
|
||||
result = make_code();
|
||||
result->Name = get_cached_string( { length, buf } );
|
||||
result->Type = ECode::Untyped;
|
||||
result->Type = CT_Untyped;
|
||||
result->Content = result->Name;
|
||||
|
||||
if ( result->Name == nullptr )
|
||||
{
|
||||
log_failure( "untyped_fmt: could not cache string" );
|
||||
return CodeInvalid;
|
||||
return InvalidCode;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -9,4 +9,3 @@
|
||||
#ifndef GEN_ROLL_OWN_DEPENDENCIES
|
||||
# include "gen.dep.cpp"
|
||||
#endif
|
||||
|
||||
|
@ -72,36 +72,36 @@ global CodeSpecifiers spec_thread_local;
|
||||
global CodeSpecifiers spec_virtual;
|
||||
global CodeSpecifiers spec_volatile;
|
||||
|
||||
global CodeType t_empty;
|
||||
global CodeType t_auto;
|
||||
global CodeType t_void;
|
||||
global CodeType t_int;
|
||||
global CodeType t_bool;
|
||||
global CodeType t_char;
|
||||
global CodeType t_wchar_t;
|
||||
global CodeType t_class;
|
||||
global CodeType t_typename;
|
||||
global CodeTypename t_empty;
|
||||
global CodeTypename t_auto;
|
||||
global CodeTypename t_void;
|
||||
global CodeTypename t_int;
|
||||
global CodeTypename t_bool;
|
||||
global CodeTypename t_char;
|
||||
global CodeTypename t_wchar_t;
|
||||
global CodeTypename t_class;
|
||||
global CodeTypename t_typename;
|
||||
|
||||
global Array< StringCached > PreprocessorDefines;
|
||||
global Array(StringCached) PreprocessorDefines;
|
||||
|
||||
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||
global CodeType t_b32;
|
||||
global CodeTypename t_b32;
|
||||
|
||||
global CodeType t_s8;
|
||||
global CodeType t_s16;
|
||||
global CodeType t_s32;
|
||||
global CodeType t_s64;
|
||||
global CodeTypename t_s8;
|
||||
global CodeTypename t_s16;
|
||||
global CodeTypename t_s32;
|
||||
global CodeTypename t_s64;
|
||||
|
||||
global CodeType t_u8;
|
||||
global CodeType t_u16;
|
||||
global CodeType t_u32;
|
||||
global CodeType t_u64;
|
||||
global CodeTypename t_u8;
|
||||
global CodeTypename t_u16;
|
||||
global CodeTypename t_u32;
|
||||
global CodeTypename t_u64;
|
||||
|
||||
global CodeType t_sw;
|
||||
global CodeType t_uw;
|
||||
global CodeTypename t_ssize;
|
||||
global CodeTypename t_usize;
|
||||
|
||||
global CodeType t_f32;
|
||||
global CodeType t_f64;
|
||||
global CodeTypename t_f32;
|
||||
global CodeTypename t_f64;
|
||||
#endif
|
||||
|
||||
#pragma endregion Constants
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "header_start.hpp"
|
||||
#endif
|
||||
|
||||
using LogFailType = sw(*)(char const*, ...);
|
||||
using LogFailType = ssize(*)(char const*, ...);
|
||||
|
||||
// By default this library will either crash or exit if an error is detected while generating codes.
|
||||
// Even if set to not use GEN_FATAL, GEN_FATAL will still be used for memory failures as the library is unusable when they occur.
|
||||
@ -13,64 +13,73 @@ using LogFailType = sw(*)(char const*, ...);
|
||||
#define log_failure GEN_FATAL
|
||||
#endif
|
||||
|
||||
enum class AccessSpec : u32
|
||||
enum AccessSpec enum_underlying(u32)
|
||||
{
|
||||
Default,
|
||||
Private,
|
||||
Protected,
|
||||
Public,
|
||||
AccessSpec_Default,
|
||||
AccessSpec_Private,
|
||||
AccessSpec_Protected,
|
||||
AccessSpec_Public,
|
||||
|
||||
Num_AccessSpec,
|
||||
Invalid,
|
||||
AccessSpec_Num_AccessSpec,
|
||||
AccessSpec_Invalid,
|
||||
|
||||
AccessSpec_SizeDef = GEN_U32_MAX,
|
||||
};
|
||||
static_assert( size_of(AccessSpec) == size_of(u32), "AccessSpec not u32 size" );
|
||||
|
||||
inline
|
||||
char const* to_str( AccessSpec type )
|
||||
{
|
||||
local_persist
|
||||
char const* lookup[ (u32)AccessSpec::Num_AccessSpec ] = {
|
||||
char const* lookup[ (u32)AccessSpec_Num_AccessSpec ] = {
|
||||
"",
|
||||
"private",
|
||||
"protected",
|
||||
"public",
|
||||
};
|
||||
|
||||
if ( type > AccessSpec::Public )
|
||||
if ( type > AccessSpec_Public )
|
||||
return "Invalid";
|
||||
|
||||
return lookup[ (u32)type ];
|
||||
}
|
||||
|
||||
|
||||
enum CodeFlag : u32
|
||||
enum CodeFlag enum_underlying(u32)
|
||||
{
|
||||
None = 0,
|
||||
FunctionType = bit(0),
|
||||
ParamPack = bit(1),
|
||||
Module_Export = bit(2),
|
||||
Module_Import = bit(3),
|
||||
CodeFlag_None = 0,
|
||||
CodeFlag_FunctionType = bit(0),
|
||||
CodeFlag_ParamPack = bit(1),
|
||||
CodeFlag_Module_Export = bit(2),
|
||||
CodeFlag_Module_Import = bit(3),
|
||||
|
||||
CodeFlag_SizeDef = GEN_U32_MAX,
|
||||
};
|
||||
static_assert( size_of(CodeFlag) == size_of(u32), "CodeFlag not u32 size" );
|
||||
|
||||
// Used to indicate if enum definitoin is an enum class or regular enum.
|
||||
enum class EnumT : u8
|
||||
enum EnumDecl enum_underlying(u8)
|
||||
{
|
||||
Regular,
|
||||
Class
|
||||
EnumDecl_Regular,
|
||||
EnumDecl_Class,
|
||||
|
||||
EnumT_SizeDef = GEN_U8_MAX,
|
||||
};
|
||||
typedef u8 EnumT;
|
||||
|
||||
constexpr EnumT EnumClass = EnumT::Class;
|
||||
constexpr EnumT EnumRegular = EnumT::Regular;
|
||||
|
||||
enum class ModuleFlag : u32
|
||||
enum ModuleFlag enum_underlying(u32)
|
||||
{
|
||||
None = 0,
|
||||
Export = bit(0),
|
||||
Import = bit(1),
|
||||
ModuleFlag_None = 0,
|
||||
ModuleFlag_Export = bit(0),
|
||||
ModuleFlag_Import = bit(1),
|
||||
|
||||
Num_ModuleFlags,
|
||||
Invalid,
|
||||
};
|
||||
ModuleFlag_Invalid,
|
||||
|
||||
ModuleFlag_SizeDef = GEN_U32_MAX,
|
||||
};
|
||||
static_assert( size_of(ModuleFlag) == size_of(u32), "ModuleFlag not u32 size" );
|
||||
|
||||
inline
|
||||
StrC to_str( ModuleFlag flag )
|
||||
{
|
||||
local_persist
|
||||
@ -80,26 +89,25 @@ StrC to_str( ModuleFlag flag )
|
||||
{ sizeof("import"), "import" },
|
||||
};
|
||||
|
||||
if ( flag > ModuleFlag::Import )
|
||||
if ( flag > ModuleFlag_Import )
|
||||
return { sizeof("invalid"), "invalid" };
|
||||
|
||||
return lookup[ (u32)flag ];
|
||||
}
|
||||
|
||||
inline
|
||||
ModuleFlag operator|( ModuleFlag A, ModuleFlag B)
|
||||
{
|
||||
return (ModuleFlag)( (u32)A | (u32)B );
|
||||
}
|
||||
|
||||
enum class EPreprocessCond : u32
|
||||
enum EPreprocessCond enum_underlying(u32)
|
||||
{
|
||||
If,
|
||||
IfDef,
|
||||
IfNotDef,
|
||||
ElIf
|
||||
};
|
||||
PreprocessCond_If,
|
||||
PreprocessCond_IfDef,
|
||||
PreprocessCond_IfNotDef,
|
||||
PreprocessCond_ElIf,
|
||||
|
||||
constexpr EPreprocessCond PreprocessCond_If = EPreprocessCond::If;
|
||||
constexpr EPreprocessCond PreprocessCond_IfDef = EPreprocessCond::IfDef;
|
||||
constexpr EPreprocessCond PreprocessCond_IfNotDef = EPreprocessCond::IfNotDef;
|
||||
constexpr EPreprocessCond PreprocessCond_ElIf = EPreprocessCond::ElIf;
|
||||
EPreprocessCond_SizeDef = GEN_U32_MAX,
|
||||
};
|
||||
static_assert( size_of(EPreprocessCond) == size_of(u32), "EPreprocessCond not u32 size" );
|
||||
|
@ -1,5 +1,6 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "platform.hpp"
|
||||
# include "macros.hpp"
|
||||
#endif
|
||||
|
||||
@ -47,21 +48,21 @@
|
||||
#if defined( GEN_COMPILER_MSVC )
|
||||
# if _MSC_VER < 1300
|
||||
typedef unsigned char u8;
|
||||
typedef signed char s8;
|
||||
typedef signed char s8;
|
||||
typedef unsigned short u16;
|
||||
typedef signed short s16;
|
||||
typedef signed short s16;
|
||||
typedef unsigned int u32;
|
||||
typedef signed int s32;
|
||||
typedef signed int s32;
|
||||
# else
|
||||
typedef unsigned __int8 u8;
|
||||
typedef signed __int8 s8;
|
||||
typedef signed __int8 s8;
|
||||
typedef unsigned __int16 u16;
|
||||
typedef signed __int16 s16;
|
||||
typedef signed __int16 s16;
|
||||
typedef unsigned __int32 u32;
|
||||
typedef signed __int32 s32;
|
||||
typedef signed __int32 s32;
|
||||
# endif
|
||||
typedef unsigned __int64 u64;
|
||||
typedef signed __int64 s64;
|
||||
typedef signed __int64 s64;
|
||||
#else
|
||||
# include <stdint.h>
|
||||
|
||||
@ -85,10 +86,10 @@ static_assert( sizeof( u16 ) == 2, "sizeof(u16) != 2" );
|
||||
static_assert( sizeof( u32 ) == 4, "sizeof(u32) != 4" );
|
||||
static_assert( sizeof( u64 ) == 8, "sizeof(u64) != 8" );
|
||||
|
||||
typedef size_t uw;
|
||||
typedef ptrdiff_t sw;
|
||||
typedef size_t usize;
|
||||
typedef ptrdiff_t ssize;
|
||||
|
||||
static_assert( sizeof( uw ) == sizeof( sw ), "sizeof(uw) != sizeof(sw)" );
|
||||
static_assert( sizeof( usize ) == sizeof( ssize ), "sizeof(usize) != sizeof(ssize)" );
|
||||
|
||||
// NOTE: (u)zpl_intptr is only here for semantic reasons really as this library will only support 32/64 bit OSes.
|
||||
#if defined( _WIN64 )
|
||||
@ -122,4 +123,21 @@ typedef s8 b8;
|
||||
typedef s16 b16;
|
||||
typedef s32 b32;
|
||||
|
||||
typedef void* mem_ptr;
|
||||
typedef void const* mem_ptr_const ;
|
||||
|
||||
#if ! GEN_COMPILER_C
|
||||
template<typename Type> uptr to_uptr( Type* ptr ) { return (uptr)ptr; }
|
||||
template<typename Type> sptr to_sptr( Type* ptr ) { return (sptr)ptr; }
|
||||
|
||||
template<typename Type> mem_ptr to_mem_ptr ( Type ptr ) { return (mem_ptr) ptr; }
|
||||
template<typename Type> mem_ptr_const to_mem_ptr_const( Type ptr ) { return (mem_ptr_const)ptr; }
|
||||
#else
|
||||
#define to_utpr( ptr ) ((uptr)(ptr))
|
||||
#define to_stpr( ptr ) ((sptr)(ptr))
|
||||
|
||||
#define to_mem_ptr( ptr) ((mem_ptr)ptr)
|
||||
#define to_mem_ptr_const( ptr) ((mem_ptr)ptr)
|
||||
#endif
|
||||
|
||||
#pragma endregion Basic Types
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -24,7 +24,7 @@
|
||||
{ \
|
||||
if ( ! ( cond ) ) \
|
||||
{ \
|
||||
assert_handler( #cond, __FILE__, zpl_cast( s64 ) __LINE__, msg, ##__VA_ARGS__ ); \
|
||||
assert_handler( #cond, __FILE__, scast( s64, __LINE__ ), msg, ##__VA_ARGS__ ); \
|
||||
GEN_DEBUG_TRAP(); \
|
||||
} \
|
||||
} while ( 0 )
|
||||
@ -34,10 +34,6 @@
|
||||
// NOTE: Things that shouldn't happen with a message!
|
||||
#define GEN_PANIC( msg, ... ) GEN_ASSERT_MSG( 0, msg, ##__VA_ARGS__ )
|
||||
|
||||
void assert_handler( char const* condition, char const* file, s32 line, char const* msg, ... );
|
||||
s32 assert_crash( char const* condition );
|
||||
void process_exit( u32 code );
|
||||
|
||||
#if Build_Debug
|
||||
#define GEN_FATAL( ... ) \
|
||||
do \
|
||||
@ -60,4 +56,10 @@ void process_exit( u32 code );
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
GEN_API_C_BEGIN
|
||||
void assert_handler( char const* condition, char const* file, s32 line, char const* msg, ... );
|
||||
s32 assert_crash( char const* condition );
|
||||
void process_exit( u32 code );
|
||||
GEN_API_C_END
|
||||
|
||||
#pragma endregion Debug
|
||||
|
@ -7,10 +7,11 @@
|
||||
|
||||
#if defined( GEN_SYSTEM_WINDOWS ) || defined( GEN_SYSTEM_CYGWIN )
|
||||
|
||||
internal wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, sw* w_len_ )
|
||||
internal
|
||||
wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, ssize* w_len_ )
|
||||
{
|
||||
wchar_t* w_text = NULL;
|
||||
sw len = 0, w_len = 0, w_len1 = 0;
|
||||
ssize len = 0, w_len = 0, w_len1 = 0;
|
||||
if ( text == NULL )
|
||||
{
|
||||
if ( w_len_ )
|
||||
@ -24,7 +25,7 @@ internal wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, sw* w_
|
||||
*w_len_ = w_len;
|
||||
return NULL;
|
||||
}
|
||||
w_len = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, text, zpl_cast( int ) len, NULL, 0 );
|
||||
w_len = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, text, scast( int, len), NULL, 0 );
|
||||
if ( w_len == 0 )
|
||||
{
|
||||
if ( w_len_ )
|
||||
@ -32,10 +33,10 @@ internal wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, sw* w_
|
||||
return NULL;
|
||||
}
|
||||
w_text = alloc_array( a, wchar_t, w_len + 1 );
|
||||
w_len1 = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, text, zpl_cast( int ) len, w_text, zpl_cast( int ) w_len );
|
||||
w_len1 = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, text, scast( int, len), w_text, scast( int, w_len) );
|
||||
if ( w_len1 == 0 )
|
||||
{
|
||||
free( a, w_text );
|
||||
allocator_free( a, w_text );
|
||||
if ( w_len_ )
|
||||
*w_len_ = 0;
|
||||
return NULL;
|
||||
@ -46,7 +47,8 @@ internal wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, sw* w_
|
||||
return w_text;
|
||||
}
|
||||
|
||||
internal GEN_FILE_SEEK_PROC( _win32_file_seek )
|
||||
internal
|
||||
GEN_FILE_SEEK_PROC( _win32_file_seek )
|
||||
{
|
||||
LARGE_INTEGER li_offset;
|
||||
li_offset.QuadPart = offset;
|
||||
@ -60,12 +62,13 @@ internal GEN_FILE_SEEK_PROC( _win32_file_seek )
|
||||
return true;
|
||||
}
|
||||
|
||||
internal GEN_FILE_READ_AT_PROC( _win32_file_read )
|
||||
internal
|
||||
GEN_FILE_READ_AT_PROC( _win32_file_read )
|
||||
{
|
||||
// unused( stop_at_newline );
|
||||
b32 result = false;
|
||||
_win32_file_seek( fd, offset, ESeekWhence_BEGIN, NULL );
|
||||
DWORD size_ = zpl_cast( DWORD )( size > GEN_I32_MAX ? GEN_I32_MAX : size );
|
||||
DWORD size_ = scast( DWORD, ( size > GEN_I32_MAX ? GEN_I32_MAX : size ));
|
||||
DWORD bytes_read_;
|
||||
if ( ReadFile( fd.p, buffer, size_, &bytes_read_, NULL ) )
|
||||
{
|
||||
@ -77,9 +80,10 @@ internal GEN_FILE_READ_AT_PROC( _win32_file_read )
|
||||
return result;
|
||||
}
|
||||
|
||||
internal GEN_FILE_WRITE_AT_PROC( _win32_file_write )
|
||||
internal
|
||||
GEN_FILE_WRITE_AT_PROC( _win32_file_write )
|
||||
{
|
||||
DWORD size_ = zpl_cast( DWORD )( size > GEN_I32_MAX ? GEN_I32_MAX : size );
|
||||
DWORD size_ = scast( DWORD, ( size > GEN_I32_MAX ? GEN_I32_MAX : size ));
|
||||
DWORD bytes_written_;
|
||||
_win32_file_seek( fd, offset, ESeekWhence_BEGIN, NULL );
|
||||
if ( WriteFile( fd.p, buffer, size_, &bytes_written_, NULL ) )
|
||||
@ -91,14 +95,16 @@ internal GEN_FILE_WRITE_AT_PROC( _win32_file_write )
|
||||
return false;
|
||||
}
|
||||
|
||||
internal GEN_FILE_CLOSE_PROC( _win32_file_close )
|
||||
internal
|
||||
GEN_FILE_CLOSE_PROC( _win32_file_close )
|
||||
{
|
||||
CloseHandle( fd.p );
|
||||
}
|
||||
|
||||
FileOperations const default_file_operations = { _win32_file_read, _win32_file_write, _win32_file_seek, _win32_file_close };
|
||||
|
||||
neverinline GEN_FILE_OPEN_PROC( _win32_file_open )
|
||||
neverinline
|
||||
GEN_FILE_OPEN_PROC( _win32_file_open )
|
||||
{
|
||||
DWORD desired_access;
|
||||
DWORD creation_disposition;
|
||||
@ -139,7 +145,7 @@ neverinline GEN_FILE_OPEN_PROC( _win32_file_open )
|
||||
w_text = _alloc_utf8_to_ucs2( heap(), filename, NULL );
|
||||
handle = CreateFileW( w_text, desired_access, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, creation_disposition, FILE_ATTRIBUTE_NORMAL, NULL );
|
||||
|
||||
free( heap(), w_text );
|
||||
allocator_free( heap(), w_text );
|
||||
|
||||
if ( handle == INVALID_HANDLE_VALUE )
|
||||
{
|
||||
@ -176,7 +182,8 @@ neverinline GEN_FILE_OPEN_PROC( _win32_file_open )
|
||||
#else // POSIX
|
||||
# include <fcntl.h>
|
||||
|
||||
internal GEN_FILE_SEEK_PROC( _posix_file_seek )
|
||||
internal
|
||||
GEN_FILE_SEEK_PROC( _posix_file_seek )
|
||||
{
|
||||
# if defined( GEN_SYSTEM_OSX )
|
||||
s64 res = lseek( fd.i, offset, whence );
|
||||
@ -190,10 +197,11 @@ internal GEN_FILE_SEEK_PROC( _posix_file_seek )
|
||||
return true;
|
||||
}
|
||||
|
||||
internal GEN_FILE_READ_AT_PROC( _posix_file_read )
|
||||
internal
|
||||
GEN_FILE_READ_AT_PROC( _posix_file_read )
|
||||
{
|
||||
unused( stop_at_newline );
|
||||
sw res = pread( fd.i, buffer, size, offset );
|
||||
ssize res = pread( fd.i, buffer, size, offset );
|
||||
if ( res < 0 )
|
||||
return false;
|
||||
if ( bytes_read )
|
||||
@ -201,19 +209,20 @@ internal GEN_FILE_READ_AT_PROC( _posix_file_read )
|
||||
return true;
|
||||
}
|
||||
|
||||
internal GEN_FILE_WRITE_AT_PROC( _posix_file_write )
|
||||
internal
|
||||
GEN_FILE_WRITE_AT_PROC( _posix_file_write )
|
||||
{
|
||||
sw res;
|
||||
ssize res;
|
||||
s64 curr_offset = 0;
|
||||
_posix_file_seek( fd, 0, ESeekWhence_CURRENT, &curr_offset );
|
||||
if ( curr_offset == offset )
|
||||
{
|
||||
// NOTE: Writing to stdout et al. doesn't like pwrite for numerous reasons
|
||||
res = write( zpl_cast( int ) fd.i, buffer, size );
|
||||
res = write( scast( int, fd.i), buffer, size );
|
||||
}
|
||||
else
|
||||
{
|
||||
res = pwrite( zpl_cast( int ) fd.i, buffer, size, offset );
|
||||
res = pwrite( scast( int, fd.i), buffer, size, offset );
|
||||
}
|
||||
if ( res < 0 )
|
||||
return false;
|
||||
@ -222,14 +231,16 @@ internal GEN_FILE_WRITE_AT_PROC( _posix_file_write )
|
||||
return true;
|
||||
}
|
||||
|
||||
internal GEN_FILE_CLOSE_PROC( _posix_file_close )
|
||||
internal
|
||||
GEN_FILE_CLOSE_PROC( _posix_file_close )
|
||||
{
|
||||
close( fd.i );
|
||||
}
|
||||
|
||||
FileOperations const default_file_operations = { _posix_file_read, _posix_file_write, _posix_file_seek, _posix_file_close };
|
||||
|
||||
neverinline GEN_FILE_OPEN_PROC( _posix_file_open )
|
||||
neverinline
|
||||
GEN_FILE_OPEN_PROC( _posix_file_open )
|
||||
{
|
||||
s32 os_mode;
|
||||
switch ( mode & GEN_FILE_MODES )
|
||||
@ -329,7 +340,7 @@ FileError file_close( FileInfo* f )
|
||||
return EFileError_INVALID;
|
||||
|
||||
if ( f->filename )
|
||||
free( heap(), zpl_cast( char* ) f->filename );
|
||||
allocator_free( heap(), ccast( char*, f->filename ));
|
||||
|
||||
#if defined( GEN_SYSTEM_WINDOWS )
|
||||
if ( f->fd.p == INVALID_HANDLE_VALUE )
|
||||
@ -364,14 +375,14 @@ FileError file_close( FileInfo* f )
|
||||
FileError file_new( FileInfo* f, FileDescriptor fd, FileOperations ops, char const* filename )
|
||||
{
|
||||
FileError err = EFileError_NONE;
|
||||
sw len = str_len( filename );
|
||||
ssize len = str_len( filename );
|
||||
|
||||
f->ops = ops;
|
||||
f->fd = fd;
|
||||
f->dir = nullptr;
|
||||
f->last_write_time = 0;
|
||||
f->filename = alloc_array( heap(), char, len + 1 );
|
||||
mem_copy( zpl_cast( char* ) f->filename, zpl_cast( char* ) filename, len + 1 );
|
||||
mem_copy( ccast( char*, f->filename), ccast( char*, filename), len + 1 );
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -430,7 +441,7 @@ FileContents file_read_contents( AllocatorInfo a, b32 zero_terminate, char const
|
||||
|
||||
if ( file_open( &file, filepath ) == EFileError_NONE )
|
||||
{
|
||||
sw fsize = zpl_cast( sw ) file_size( &file );
|
||||
ssize fsize = scast( ssize , file_size( &file ));
|
||||
if ( fsize > 0 )
|
||||
{
|
||||
result.data = alloc( a, zero_terminate ? fsize + 1 : fsize );
|
||||
@ -438,7 +449,7 @@ FileContents file_read_contents( AllocatorInfo a, b32 zero_terminate, char const
|
||||
file_read_at( &file, result.data, result.size, 0 );
|
||||
if ( zero_terminate )
|
||||
{
|
||||
u8* str = zpl_cast( u8* ) result.data;
|
||||
u8* str = rcast( u8*, result.data);
|
||||
str[ fsize ] = '\0';
|
||||
}
|
||||
}
|
||||
@ -452,26 +463,28 @@ struct _memory_fd
|
||||
{
|
||||
u8 magic;
|
||||
u8* buf; //< zpl_array OR plain buffer if we can't write
|
||||
sw cursor;
|
||||
ssize cursor;
|
||||
AllocatorInfo allocator;
|
||||
|
||||
FileStreamFlags flags;
|
||||
sw cap;
|
||||
ssize cap;
|
||||
};
|
||||
|
||||
#define GEN__FILE_STREAM_FD_MAGIC 37
|
||||
|
||||
GEN_DEF_INLINE FileDescriptor _file_stream_fd_make( _memory_fd* d );
|
||||
GEN_DEF_INLINE _memory_fd* _file_stream_from_fd( FileDescriptor fd );
|
||||
FileDescriptor _file_stream_fd_make( _memory_fd* d );
|
||||
_memory_fd* _file_stream_from_fd( FileDescriptor fd );
|
||||
|
||||
GEN_IMPL_INLINE FileDescriptor _file_stream_fd_make( _memory_fd* d )
|
||||
inline
|
||||
FileDescriptor _file_stream_fd_make( _memory_fd* d )
|
||||
{
|
||||
FileDescriptor fd = { 0 };
|
||||
fd.p = ( void* )d;
|
||||
return fd;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE _memory_fd* _file_stream_from_fd( FileDescriptor fd )
|
||||
inline
|
||||
_memory_fd* _file_stream_from_fd( FileDescriptor fd )
|
||||
{
|
||||
_memory_fd* d = ( _memory_fd* )fd.p;
|
||||
GEN_ASSERT( d->magic == GEN__FILE_STREAM_FD_MAGIC );
|
||||
@ -492,7 +505,7 @@ b8 file_stream_new( FileInfo* file, AllocatorInfo allocator )
|
||||
d->allocator = allocator;
|
||||
d->flags = EFileStream_CLONE_WRITABLE;
|
||||
d->cap = 0;
|
||||
d->buf = Array<u8>::init( allocator );
|
||||
d->buf = array_init<u8>( allocator );
|
||||
|
||||
if ( ! d->buf )
|
||||
return false;
|
||||
@ -506,7 +519,7 @@ b8 file_stream_new( FileInfo* file, AllocatorInfo allocator )
|
||||
return true;
|
||||
}
|
||||
|
||||
b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, sw size, FileStreamFlags flags )
|
||||
b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, ssize size, FileStreamFlags flags )
|
||||
{
|
||||
GEN_ASSERT_NOT_NULL( file );
|
||||
_memory_fd* d = ( _memory_fd* )alloc( allocator, size_of( _memory_fd ) );
|
||||
@ -518,7 +531,7 @@ b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, sw siz
|
||||
d->flags = flags;
|
||||
if ( d->flags & EFileStream_CLONE_WRITABLE )
|
||||
{
|
||||
Array<u8> arr = Array<u8>::init_reserve( allocator, size );
|
||||
Array<u8> arr = array_init_reserve<u8>( allocator, size );
|
||||
d->buf = arr;
|
||||
|
||||
if ( ! d->buf )
|
||||
@ -527,7 +540,7 @@ b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, sw siz
|
||||
mem_copy( d->buf, buffer, size );
|
||||
d->cap = size;
|
||||
|
||||
arr.get_header()->Num = size;
|
||||
array_get_header(arr)->Num = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -543,7 +556,7 @@ b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, sw siz
|
||||
return true;
|
||||
}
|
||||
|
||||
u8* file_stream_buf( FileInfo* file, sw* size )
|
||||
u8* file_stream_buf( FileInfo* file, ssize* size )
|
||||
{
|
||||
GEN_ASSERT_NOT_NULL( file );
|
||||
_memory_fd* d = _file_stream_from_fd( file->fd );
|
||||
@ -552,10 +565,11 @@ u8* file_stream_buf( FileInfo* file, sw* size )
|
||||
return d->buf;
|
||||
}
|
||||
|
||||
internal GEN_FILE_SEEK_PROC( _memory_file_seek )
|
||||
internal
|
||||
GEN_FILE_SEEK_PROC( _memory_file_seek )
|
||||
{
|
||||
_memory_fd* d = _file_stream_from_fd( fd );
|
||||
sw buflen = d->cap;
|
||||
ssize buflen = d->cap;
|
||||
|
||||
if ( whence == ESeekWhence_BEGIN )
|
||||
d->cursor = 0;
|
||||
@ -568,7 +582,8 @@ internal GEN_FILE_SEEK_PROC( _memory_file_seek )
|
||||
return true;
|
||||
}
|
||||
|
||||
internal GEN_FILE_READ_AT_PROC( _memory_file_read )
|
||||
internal
|
||||
GEN_FILE_READ_AT_PROC( _memory_file_read )
|
||||
{
|
||||
// unused( stop_at_newline );
|
||||
_memory_fd* d = _file_stream_from_fd( fd );
|
||||
@ -578,25 +593,26 @@ internal GEN_FILE_READ_AT_PROC( _memory_file_read )
|
||||
return true;
|
||||
}
|
||||
|
||||
internal GEN_FILE_WRITE_AT_PROC( _memory_file_write )
|
||||
internal
|
||||
GEN_FILE_WRITE_AT_PROC( _memory_file_write )
|
||||
{
|
||||
_memory_fd* d = _file_stream_from_fd( fd );
|
||||
|
||||
if ( ! ( d->flags & ( EFileStream_CLONE_WRITABLE | EFileStream_WRITABLE ) ) )
|
||||
return false;
|
||||
|
||||
sw buflen = d->cap;
|
||||
sw extralen = max( 0, size - ( buflen - offset ) );
|
||||
sw rwlen = size - extralen;
|
||||
sw new_cap = buflen + extralen;
|
||||
ssize buflen = d->cap;
|
||||
ssize extralen = max( 0, size - ( buflen - offset ) );
|
||||
ssize rwlen = size - extralen;
|
||||
ssize new_cap = buflen + extralen;
|
||||
|
||||
if ( d->flags & EFileStream_CLONE_WRITABLE )
|
||||
{
|
||||
Array<u8> arr = { d->buf };
|
||||
|
||||
if ( arr.get_header()->Capacity < new_cap )
|
||||
if ( array_get_header(arr)->Capacity < usize(new_cap) )
|
||||
{
|
||||
if ( ! arr.grow( ( s64 )( new_cap ) ) )
|
||||
if ( ! array_grow( & arr, ( s64 )( new_cap ) ) )
|
||||
return false;
|
||||
d->buf = arr;
|
||||
}
|
||||
@ -610,7 +626,7 @@ internal GEN_FILE_WRITE_AT_PROC( _memory_file_write )
|
||||
|
||||
mem_copy( d->buf + offset + rwlen, pointer_add_const( buffer, rwlen ), extralen );
|
||||
d->cap = new_cap;
|
||||
arr.get_header()->Capacity = new_cap;
|
||||
array_get_header(arr)->Capacity = new_cap;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -622,7 +638,8 @@ internal GEN_FILE_WRITE_AT_PROC( _memory_file_write )
|
||||
return true;
|
||||
}
|
||||
|
||||
internal GEN_FILE_CLOSE_PROC( _memory_file_close )
|
||||
internal
|
||||
GEN_FILE_CLOSE_PROC( _memory_file_close )
|
||||
{
|
||||
_memory_fd* d = _file_stream_from_fd( fd );
|
||||
AllocatorInfo allocator = d->allocator;
|
||||
@ -630,10 +647,10 @@ internal GEN_FILE_CLOSE_PROC( _memory_file_close )
|
||||
if ( d->flags & EFileStream_CLONE_WRITABLE )
|
||||
{
|
||||
Array<u8> arr = { d->buf };
|
||||
arr.free();
|
||||
array_free(& arr);
|
||||
}
|
||||
|
||||
free( allocator, d );
|
||||
allocator_free( allocator, d );
|
||||
}
|
||||
|
||||
FileOperations const memory_file_operations = { _memory_file_read, _memory_file_write, _memory_file_seek, _memory_file_close };
|
||||
|
@ -48,8 +48,8 @@ union FileDescriptor
|
||||
typedef struct FileOperations FileOperations;
|
||||
|
||||
#define GEN_FILE_OPEN_PROC( name ) FileError name( FileDescriptor* fd, FileOperations* ops, FileMode mode, char const* filename )
|
||||
#define GEN_FILE_READ_AT_PROC( name ) b32 name( FileDescriptor fd, void* buffer, sw size, s64 offset, sw* bytes_read, b32 stop_at_newline )
|
||||
#define GEN_FILE_WRITE_AT_PROC( name ) b32 name( FileDescriptor fd, void const* buffer, sw size, s64 offset, sw* bytes_written )
|
||||
#define GEN_FILE_READ_AT_PROC( name ) b32 name( FileDescriptor fd, void* buffer, ssize size, s64 offset, ssize* bytes_read, b32 stop_at_newline )
|
||||
#define GEN_FILE_WRITE_AT_PROC( name ) b32 name( FileDescriptor fd, mem_ptr_const buffer, ssize size, s64 offset, ssize* bytes_written )
|
||||
#define GEN_FILE_SEEK_PROC( name ) b32 name( FileDescriptor fd, s64 offset, SeekWhenceType whence, s64* new_offset )
|
||||
#define GEN_FILE_CLOSE_PROC( name ) void name( FileDescriptor fd )
|
||||
|
||||
@ -161,7 +161,7 @@ FileError file_open_mode( FileInfo* file, FileMode mode, char const* filename );
|
||||
* @param buffer Buffer to read to
|
||||
* @param size Size to read
|
||||
*/
|
||||
GEN_DEF_INLINE b32 file_read( FileInfo* file, void* buffer, sw size );
|
||||
b32 file_read( FileInfo* file, void* buffer, ssize size );
|
||||
|
||||
/**
|
||||
* Reads file at a specific offset
|
||||
@ -171,7 +171,7 @@ GEN_DEF_INLINE b32 file_read( FileInfo* file, void* buffer, sw size );
|
||||
* @param offset Offset to read from
|
||||
* @param bytes_read How much data we've actually read
|
||||
*/
|
||||
GEN_DEF_INLINE b32 file_read_at( FileInfo* file, void* buffer, sw size, s64 offset );
|
||||
b32 file_read_at( FileInfo* file, void* buffer, ssize size, s64 offset );
|
||||
|
||||
/**
|
||||
* Reads file safely
|
||||
@ -181,13 +181,13 @@ GEN_DEF_INLINE b32 file_read_at( FileInfo* file, void* buffer, sw size, s64 offs
|
||||
* @param offset Offset to read from
|
||||
* @param bytes_read How much data we've actually read
|
||||
*/
|
||||
GEN_DEF_INLINE b32 file_read_at_check( FileInfo* file, void* buffer, sw size, s64 offset, sw* bytes_read );
|
||||
b32 file_read_at_check( FileInfo* file, void* buffer, ssize size, s64 offset, ssize* bytes_read );
|
||||
|
||||
struct FileContents
|
||||
{
|
||||
AllocatorInfo allocator;
|
||||
void* data;
|
||||
sw size;
|
||||
ssize size;
|
||||
};
|
||||
|
||||
constexpr b32 zero_terminate = true;
|
||||
@ -214,20 +214,20 @@ s64 file_size( FileInfo* file );
|
||||
* @param file
|
||||
* @param offset Offset to seek to
|
||||
*/
|
||||
GEN_DEF_INLINE s64 file_seek( FileInfo* file, s64 offset );
|
||||
s64 file_seek( FileInfo* file, s64 offset );
|
||||
|
||||
/**
|
||||
* Seeks the file cursor to the end of the file
|
||||
* @param file
|
||||
*/
|
||||
GEN_DEF_INLINE s64 file_seek_to_end( FileInfo* file );
|
||||
s64 file_seek_to_end( FileInfo* file );
|
||||
|
||||
/**
|
||||
* Returns the length from the beginning of the file we've read so far
|
||||
* @param file
|
||||
* @return Our current position in file
|
||||
*/
|
||||
GEN_DEF_INLINE s64 file_tell( FileInfo* file );
|
||||
s64 file_tell( FileInfo* file );
|
||||
|
||||
/**
|
||||
* Writes to a file
|
||||
@ -235,7 +235,7 @@ GEN_DEF_INLINE s64 file_tell( FileInfo* file );
|
||||
* @param buffer Buffer to read from
|
||||
* @param size Size to read
|
||||
*/
|
||||
GEN_DEF_INLINE b32 file_write( FileInfo* file, void const* buffer, sw size );
|
||||
b32 file_write( FileInfo* file, void const* buffer, ssize size );
|
||||
|
||||
/**
|
||||
* Writes to file at a specific offset
|
||||
@ -245,7 +245,7 @@ GEN_DEF_INLINE b32 file_write( FileInfo* file, void const* buffer, sw size );
|
||||
* @param offset Offset to write to
|
||||
* @param bytes_written How much data we've actually written
|
||||
*/
|
||||
GEN_DEF_INLINE b32 file_write_at( FileInfo* file, void const* buffer, sw size, s64 offset );
|
||||
b32 file_write_at( FileInfo* file, void const* buffer, ssize size, s64 offset );
|
||||
|
||||
/**
|
||||
* Writes to file safely
|
||||
@ -255,86 +255,7 @@ GEN_DEF_INLINE b32 file_write_at( FileInfo* file, void const* buffer, sw size, s
|
||||
* @param offset Offset to write to
|
||||
* @param bytes_written How much data we've actually written
|
||||
*/
|
||||
GEN_DEF_INLINE b32 file_write_at_check( FileInfo* file, void const* buffer, sw size, s64 offset, sw* bytes_written );
|
||||
|
||||
GEN_IMPL_INLINE s64 file_seek( FileInfo* f, s64 offset )
|
||||
{
|
||||
s64 new_offset = 0;
|
||||
|
||||
if ( ! f->ops.read_at )
|
||||
f->ops = default_file_operations;
|
||||
|
||||
f->ops.seek( f->fd, offset, ESeekWhence_BEGIN, &new_offset );
|
||||
|
||||
return new_offset;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE s64 file_seek_to_end( FileInfo* f )
|
||||
{
|
||||
s64 new_offset = 0;
|
||||
|
||||
if ( ! f->ops.read_at )
|
||||
f->ops = default_file_operations;
|
||||
|
||||
f->ops.seek( f->fd, 0, ESeekWhence_END, &new_offset );
|
||||
|
||||
return new_offset;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE s64 file_tell( FileInfo* f )
|
||||
{
|
||||
s64 new_offset = 0;
|
||||
|
||||
if ( ! f->ops.read_at )
|
||||
f->ops = default_file_operations;
|
||||
|
||||
f->ops.seek( f->fd, 0, ESeekWhence_CURRENT, &new_offset );
|
||||
|
||||
return new_offset;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE b32 file_read( FileInfo* f, void* buffer, sw size )
|
||||
{
|
||||
s64 cur_offset = file_tell( f );
|
||||
b32 result = file_read_at( f, buffer, size, file_tell( f ) );
|
||||
file_seek( f, cur_offset + size );
|
||||
return result;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE b32 file_read_at( FileInfo* f, void* buffer, sw size, s64 offset )
|
||||
{
|
||||
return file_read_at_check( f, buffer, size, offset, NULL );
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE b32 file_read_at_check( FileInfo* f, void* buffer, sw size, s64 offset, sw* bytes_read )
|
||||
{
|
||||
if ( ! f->ops.read_at )
|
||||
f->ops = default_file_operations;
|
||||
return f->ops.read_at( f->fd, buffer, size, offset, bytes_read, false );
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE b32 file_write( FileInfo* f, void const* buffer, sw size )
|
||||
{
|
||||
s64 cur_offset = file_tell( f );
|
||||
b32 result = file_write_at( f, buffer, size, file_tell( f ) );
|
||||
|
||||
file_seek( f, cur_offset + size );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE b32 file_write_at( FileInfo* f, void const* buffer, sw size, s64 offset )
|
||||
{
|
||||
return file_write_at_check( f, buffer, size, offset, NULL );
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE b32 file_write_at_check( FileInfo* f, void const* buffer, sw size, s64 offset, sw* bytes_written )
|
||||
{
|
||||
if ( ! f->ops.read_at )
|
||||
f->ops = default_file_operations;
|
||||
|
||||
return f->ops.write_at( f->fd, buffer, size, offset, bytes_written );
|
||||
}
|
||||
b32 file_write_at_check( FileInfo* file, void const* buffer, ssize size, s64 offset, ssize* bytes_written );
|
||||
|
||||
enum FileStreamFlags : u32
|
||||
{
|
||||
@ -361,15 +282,103 @@ b8 file_stream_new( FileInfo* file, AllocatorInfo allocator );
|
||||
* @param size Buffer's size
|
||||
* @param flags
|
||||
*/
|
||||
b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, sw size, FileStreamFlags flags );
|
||||
b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, ssize size, FileStreamFlags flags );
|
||||
|
||||
/**
|
||||
* Retrieves the stream's underlying buffer and buffer size.
|
||||
* @param file memory stream
|
||||
* @param size (Optional) buffer size
|
||||
*/
|
||||
u8* file_stream_buf( FileInfo* file, sw* size );
|
||||
u8* file_stream_buf( FileInfo* file, ssize* size );
|
||||
|
||||
extern FileOperations const memory_file_operations;
|
||||
|
||||
inline
|
||||
s64 file_seek( FileInfo* f, s64 offset )
|
||||
{
|
||||
s64 new_offset = 0;
|
||||
|
||||
if ( ! f->ops.read_at )
|
||||
f->ops = default_file_operations;
|
||||
|
||||
f->ops.seek( f->fd, offset, ESeekWhence_BEGIN, &new_offset );
|
||||
|
||||
return new_offset;
|
||||
}
|
||||
|
||||
inline
|
||||
s64 file_seek_to_end( FileInfo* f )
|
||||
{
|
||||
s64 new_offset = 0;
|
||||
|
||||
if ( ! f->ops.read_at )
|
||||
f->ops = default_file_operations;
|
||||
|
||||
f->ops.seek( f->fd, 0, ESeekWhence_END, &new_offset );
|
||||
|
||||
return new_offset;
|
||||
}
|
||||
|
||||
inline
|
||||
s64 file_tell( FileInfo* f )
|
||||
{
|
||||
s64 new_offset = 0;
|
||||
|
||||
if ( ! f->ops.read_at )
|
||||
f->ops = default_file_operations;
|
||||
|
||||
f->ops.seek( f->fd, 0, ESeekWhence_CURRENT, &new_offset );
|
||||
|
||||
return new_offset;
|
||||
}
|
||||
|
||||
inline
|
||||
b32 file_read( FileInfo* f, void* buffer, ssize size )
|
||||
{
|
||||
s64 cur_offset = file_tell( f );
|
||||
b32 result = file_read_at( f, buffer, size, file_tell( f ) );
|
||||
file_seek( f, cur_offset + size );
|
||||
return result;
|
||||
}
|
||||
|
||||
inline
|
||||
b32 file_read_at( FileInfo* f, void* buffer, ssize size, s64 offset )
|
||||
{
|
||||
return file_read_at_check( f, buffer, size, offset, NULL );
|
||||
}
|
||||
|
||||
inline
|
||||
b32 file_read_at_check( FileInfo* f, void* buffer, ssize size, s64 offset, ssize* bytes_read )
|
||||
{
|
||||
if ( ! f->ops.read_at )
|
||||
f->ops = default_file_operations;
|
||||
return f->ops.read_at( f->fd, buffer, size, offset, bytes_read, false );
|
||||
}
|
||||
|
||||
inline
|
||||
b32 file_write( FileInfo* f, void const* buffer, ssize size )
|
||||
{
|
||||
s64 cur_offset = file_tell( f );
|
||||
b32 result = file_write_at( f, buffer, size, file_tell( f ) );
|
||||
|
||||
file_seek( f, cur_offset + size );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline
|
||||
b32 file_write_at( FileInfo* f, void const* buffer, ssize size, s64 offset )
|
||||
{
|
||||
return file_write_at_check( f, buffer, size, offset, NULL );
|
||||
}
|
||||
|
||||
inline
|
||||
b32 file_write_at_check( FileInfo* f, void const* buffer, ssize size, s64 offset, ssize* bytes_written )
|
||||
{
|
||||
if ( ! f->ops.read_at )
|
||||
f->ops = default_file_operations;
|
||||
|
||||
return f->ops.write_at( f->fd, buffer, size, offset, bytes_written );
|
||||
}
|
||||
|
||||
#pragma endregion File Handling
|
||||
|
@ -27,11 +27,11 @@ global u32 const _crc32_table[ 256 ] = {
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
|
||||
};
|
||||
|
||||
u32 crc32( void const* data, sw len )
|
||||
u32 crc32( void const* data, ssize len )
|
||||
{
|
||||
sw remaining;
|
||||
u32 result = ~( zpl_cast( u32 ) 0 );
|
||||
u8 const* c = zpl_cast( u8 const* ) data;
|
||||
ssize remaining;
|
||||
u32 result = ~( scast( u32, 0) );
|
||||
u8 const* c = rcast( u8 const*, data);
|
||||
for ( remaining = len; remaining--; c++ )
|
||||
result = ( result >> 8 ) ^ ( _crc32_table[ ( result ^ *c ) & 0xff ] );
|
||||
return ~result;
|
||||
@ -77,11 +77,11 @@ global u64 const _crc64_table[ 256 ] = {
|
||||
0xa6df411fbfb21ca3ull, 0xdc0731d78f8795daull, 0x536fa08fdfd90e51ull, 0x29b7d047efec8728ull,
|
||||
};
|
||||
|
||||
u64 crc64( void const* data, sw len )
|
||||
u64 crc64( void const* data, ssize len )
|
||||
{
|
||||
sw remaining;
|
||||
u64 result = ( zpl_cast( u64 ) 0 );
|
||||
u8 const* c = zpl_cast( u8 const* ) data;
|
||||
ssize remaining;
|
||||
u64 result = ( scast( u64, 0) );
|
||||
u8 const* c = rcast( u8 const*, data);
|
||||
for ( remaining = len; remaining--; c++ )
|
||||
result = ( result >> 8 ) ^ ( _crc64_table[ ( result ^ *c ) & 0xff ] );
|
||||
return result;
|
||||
|
@ -5,7 +5,11 @@
|
||||
|
||||
#pragma region Hashing
|
||||
|
||||
u32 crc32( void const* data, sw len );
|
||||
u64 crc64( void const* data, sw len );
|
||||
GEN_API_C_BEGIN
|
||||
|
||||
u32 crc32( void const* data, ssize len );
|
||||
u64 crc64( void const* data, ssize len );
|
||||
|
||||
GEN_API_C_END
|
||||
|
||||
#pragma endregion Hashing
|
||||
|
@ -1,52 +1,94 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
# include "header_start.hpp"
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#pragma region Macros
|
||||
|
||||
#define zpl_cast( Type ) ( Type )
|
||||
|
||||
// Keywords
|
||||
|
||||
#ifndef global
|
||||
#define global static // Global variables
|
||||
#endif
|
||||
#ifndef internal
|
||||
#define internal static // Internal linkage
|
||||
#endif
|
||||
#ifndef local_persist
|
||||
#define local_persist static // Local Persisting variables
|
||||
|
||||
#ifdef GEN_COMPILER_MSVC
|
||||
# define forceinline __forceinline
|
||||
# define neverinline __declspec( noinline )
|
||||
#elif defined(GEN_COMPILER_GCC)
|
||||
# define forceinline inline __attribute__((__always_inline__))
|
||||
# define neverinline __attribute__( ( __noinline__ ) )
|
||||
#elif defined(GEN_COMPILER_CLANG)
|
||||
#if __has_attribute(__always_inline__)
|
||||
# define forceinline inline __attribute__((__always_inline__))
|
||||
# define neverinline __attribute__( ( __noinline__ ) )
|
||||
#else
|
||||
# define forceinline
|
||||
# define neverinline
|
||||
#endif
|
||||
#else
|
||||
# define forceinline
|
||||
# define neverinline
|
||||
#endif
|
||||
|
||||
// Bits
|
||||
|
||||
#ifndef bit
|
||||
#define bit( Value ) ( 1 << Value )
|
||||
#define bitfield_is_equal( Type, Field, Mask ) ( (Type(Mask) & Type(Field)) == Type(Mask) )
|
||||
#endif
|
||||
|
||||
// Casting
|
||||
#if GEN_COMPILER_CPP
|
||||
# ifndef cast
|
||||
# define cast( type, value ) (tmpl_cast<type>( value ))
|
||||
# endif
|
||||
# ifndef ccast
|
||||
# define ccast( type, value ) ( const_cast< type >( (value) ) )
|
||||
# endif
|
||||
# ifndef pcast
|
||||
# define pcast( type, value ) ( * reinterpret_cast< type* >( & ( value ) ) )
|
||||
# endif
|
||||
# ifndef rcast
|
||||
# define rcast( type, value ) reinterpret_cast< type >( value )
|
||||
# endif
|
||||
# ifndef scast
|
||||
# define scast( type, value ) static_cast< type >( value )
|
||||
# endif
|
||||
#else
|
||||
# ifndef cast
|
||||
# define cast( type, value ) ( (type)(value) )
|
||||
# endif
|
||||
# ifndef ccast
|
||||
# define ccast( type, value ) ( (type)(value) )
|
||||
# endif
|
||||
# ifndef pcast
|
||||
# define pcast( type, value ) ( * (type*)(value) )
|
||||
# endif
|
||||
# ifndef rcast
|
||||
# define rcast( type, value ) ( (type)(value) )
|
||||
# endif
|
||||
# ifndef scast
|
||||
# define scast( type, value ) ( (type)(value) )
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define ccast( Type, Value ) ( * const_cast< Type* >( & (Value) ) )
|
||||
#define pcast( Type, Value ) ( * reinterpret_cast< Type* >( & ( Value ) ) )
|
||||
#define rcast( Type, Value ) reinterpret_cast< Type >( Value )
|
||||
#define scast( Type, Value ) static_cast< Type >( Value )
|
||||
#ifndef stringize
|
||||
#define stringize_va( ... ) #__VA_ARGS__
|
||||
#define stringize( ... ) stringize_va( __VA_ARGS__ )
|
||||
#endif
|
||||
|
||||
// Num Arguments (Varadics)
|
||||
// #if defined(__GNUC__) || defined(__clang__)
|
||||
// Supports 0-50 arguments
|
||||
#ifndef do_once
|
||||
#define do_once( statement ) for ( local_persist b32 once = true; once; once = false, (statement) )
|
||||
|
||||
#define do_once_start \
|
||||
do \
|
||||
{ \
|
||||
local_persist \
|
||||
bool done = false; \
|
||||
if ( done ) \
|
||||
break; \
|
||||
done = true;
|
||||
|
||||
#define do_once_end \
|
||||
} \
|
||||
while(0);
|
||||
#endif
|
||||
|
||||
#ifndef labeled_scope_start
|
||||
#define labeled_scope_start if ( false ) {
|
||||
#define labeled_scope_end }
|
||||
#endif
|
||||
|
||||
#ifndef compiler_decorated_func_name
|
||||
# ifdef COMPILER_CLANG
|
||||
# define compiler_decorated_func_name __PRETTY_NAME__
|
||||
# elif defined(COMPILER_MSVC)
|
||||
# define compiler_decorated_func_name __FUNCDNAME__
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef num_args_impl
|
||||
#define num_args_impl( _0, \
|
||||
_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
|
||||
_11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
|
||||
@ -61,7 +103,7 @@
|
||||
N, ... \
|
||||
) N
|
||||
|
||||
// ## deletes preceding comma if _VA_ARGS__ is empty (GCC, Clang)
|
||||
// ## deletes preceding comma if _VA_ARGS__ is empty (GCC, Clang)
|
||||
#define num_args(...) \
|
||||
num_args_impl(_, ## __VA_ARGS__, \
|
||||
100, 99, 98, 97, 96, 95, 94, 93, 92, 91, \
|
||||
@ -76,93 +118,123 @@
|
||||
10, 9, 8, 7, 6, 5, 4, 3, 2, 1, \
|
||||
0 \
|
||||
)
|
||||
#endif
|
||||
|
||||
// #else
|
||||
// This doesn't work on latest msvc so I had to use /Zc:preprocessor flag.
|
||||
|
||||
// Supports 1-50 arguments
|
||||
// #define num_args_impl( \
|
||||
// _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
|
||||
// _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
|
||||
// _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
|
||||
// _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
|
||||
// _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
|
||||
// _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \
|
||||
// _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, \
|
||||
// _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, \
|
||||
// _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, \
|
||||
// _91, _92, _93, _94, _95, _96, _97, _98, _99, _100, \
|
||||
// N, ... \
|
||||
// ) N
|
||||
|
||||
// #define num_args(...) \
|
||||
// num_args_impl( __VA_ARGS__, \
|
||||
// 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, \
|
||||
// 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, \
|
||||
// 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, \
|
||||
// 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, \
|
||||
// 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \
|
||||
// 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, \
|
||||
// 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, \
|
||||
// 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, \
|
||||
// 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, \
|
||||
// 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, \
|
||||
// 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 \
|
||||
// )
|
||||
// #endif
|
||||
|
||||
// Stringizing
|
||||
#define stringize_va( ... ) #__VA_ARGS__
|
||||
#define stringize( ... ) stringize_va( __VA_ARGS__ )
|
||||
|
||||
// Function do once
|
||||
|
||||
#define do_once() \
|
||||
do \
|
||||
{ \
|
||||
static \
|
||||
bool Done = false; \
|
||||
if ( Done ) \
|
||||
return; \
|
||||
Done = true; \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#define do_once_start \
|
||||
do \
|
||||
{ \
|
||||
static \
|
||||
bool Done = false; \
|
||||
if ( Done ) \
|
||||
break; \
|
||||
Done = true;
|
||||
|
||||
#define do_once_end \
|
||||
} \
|
||||
while(0);
|
||||
|
||||
#define labeled_scope_start if ( false ) {
|
||||
#define labeled_scope_end }
|
||||
|
||||
#ifndef clamp
|
||||
#define clamp( x, lower, upper ) min( max( ( x ), ( lower ) ), ( upper ) )
|
||||
#define count_of( x ) ( ( size_of( x ) / size_of( 0 [ x ] ) ) / ( ( sw )( ! ( size_of( x ) % size_of( 0 [ x ] ) ) ) ) )
|
||||
#endif
|
||||
#ifndef count_of
|
||||
#define count_of( x ) ( ( size_of( x ) / size_of( 0 [ x ] ) ) / ( ( ssize )( ! ( size_of( x ) % size_of( 0 [ x ] ) ) ) ) )
|
||||
#endif
|
||||
#ifndef is_between
|
||||
#define is_between( x, lower, upper ) ( ( ( lower ) <= ( x ) ) && ( ( x ) <= ( upper ) ) )
|
||||
#define max( a, b ) ( ( a ) > ( b ) ? ( a ) : ( b ) )
|
||||
#define min( a, b ) ( ( a ) < ( b ) ? ( a ) : ( b ) )
|
||||
#define size_of( x ) ( sw )( sizeof( x ) )
|
||||
#endif
|
||||
#ifndef size_of
|
||||
#define size_of( x ) ( ssize )( sizeof( x ) )
|
||||
#endif
|
||||
|
||||
#if defined( _MSC_VER ) || defined( GEN_COMPILER_TINYC )
|
||||
# define offset_of( Type, element ) ( ( GEN_NS( gen_sw ) ) & ( ( ( Type* )0 )->element ) )
|
||||
#ifndef max
|
||||
#define max( a, b ) ( (a > b) ? (a) : (b) )
|
||||
#endif
|
||||
#ifndef min
|
||||
#define min( a, b ) ( (a < b) ? (a) : (b) )
|
||||
#endif
|
||||
|
||||
#if GEN_COMPILER_MSVC || GEN_COMPILER_TINYC
|
||||
# define offset_of( Type, element ) ( ( GEN_NS( ssize ) ) & ( ( ( Type* )0 )->element ) )
|
||||
#else
|
||||
# define offset_of( Type, element ) __builtin_offsetof( Type, element )
|
||||
#endif
|
||||
|
||||
template< class Type >
|
||||
void swap( Type& a, Type& b )
|
||||
{
|
||||
Type tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
#ifndef forceinline
|
||||
# if GEN_COMPILER_MSVC
|
||||
# define forceinline __forceinline
|
||||
# define neverinline __declspec( noinline )
|
||||
# elif GEN_COMPILER_GCC
|
||||
# define forceinline inline __attribute__((__always_inline__))
|
||||
# define neverinline __attribute__( ( __noinline__ ) )
|
||||
# elif GEN_COMPILER_CLANG
|
||||
# if __has_attribute(__always_inline__)
|
||||
# define forceinline inline __attribute__((__always_inline__))
|
||||
# define neverinline __attribute__( ( __noinline__ ) )
|
||||
# else
|
||||
# define forceinline
|
||||
# define neverinline
|
||||
# endif
|
||||
# else
|
||||
# define forceinline
|
||||
# define neverinline
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef neverinline
|
||||
# if GEN_COMPILER_MSVC
|
||||
# define neverinline __declspec( noinline )
|
||||
# elif GEN_COMPILER_GCC
|
||||
# define neverinline __attribute__( ( __noinline__ ) )
|
||||
# elif GEN_COMPILER_CLANG
|
||||
# if __has_attribute(__always_inline__)
|
||||
# define neverinline __attribute__( ( __noinline__ ) )
|
||||
# else
|
||||
# define neverinline
|
||||
# endif
|
||||
# else
|
||||
# define neverinline
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(GEN_SUPPORT_CPP_REFERENCES) && (GEN_COMPILER_C || __STDC_VERSION__ < 202311L)
|
||||
# undef GEN_SUPPORT_CPP_REFERENCES
|
||||
# define GEN_SUPPORT_CPP_REFERENCES 0
|
||||
#endif
|
||||
|
||||
#if !defined(GEN_SUPPORT_CPP_MEMBER_FEATURES) && (GEN_COMPILER_C || __STDC_VERSION__ < 202311L)
|
||||
# undef GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||
# define GEN_SUPPORT_CPP_MEMBER_FEATURES 0
|
||||
#endif
|
||||
|
||||
#if ! defined(typeof) && (!GEN_COMPILER_C || __STDC_VERSION__ < 202311L)
|
||||
# if ! GEN_COMPILER_C
|
||||
# define typeof decltype
|
||||
# elif defined(_MSC_VER)
|
||||
# define typeof(x) __typeof(x)
|
||||
# elif defined(__GNUC__) || defined(__clang__)
|
||||
# define typeof(x) __typeof__(x)
|
||||
# else
|
||||
# error "Compiler not supported"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef GEN_API_C_BEGIN
|
||||
# if GEN_COMPILER_C || (GEN_COMPILER_CPP && GEN_SUPPORT_CPP_REFERENCES)
|
||||
# define GEN_API_C_BEGIN
|
||||
# define GEN_API_C_END
|
||||
# else
|
||||
# define GEN_API_C_BEGIN extern "C" {
|
||||
# define GEN_API_C_END }
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if GEN_COMPILER_C
|
||||
# if __STDC_VERSION__ >= 202311L
|
||||
# define enum_underlying(type) : type
|
||||
# else
|
||||
# define enum_underlying(type)
|
||||
# endif
|
||||
#else
|
||||
# define enum_underlying(type) : type
|
||||
#endif
|
||||
|
||||
#if GEN_COMPILER_C
|
||||
# ifndef nullptr
|
||||
# define nullptr NULL
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if ! defined(GEN_PARAM_DEFAULT) && GEN_COMPILER_CPP
|
||||
# define GEN_PARAM_DEFAULT = {}
|
||||
#else
|
||||
# define GEN_PARAM_DEFAULT
|
||||
#endif
|
||||
|
||||
#pragma endregion Macros
|
||||
|
@ -5,7 +5,9 @@
|
||||
|
||||
#pragma region Memory
|
||||
|
||||
void* mem_copy( void* dest, void const* source, sw n )
|
||||
GEN_API_C_BEGIN
|
||||
|
||||
void* mem_copy( void* dest, void const* source, ssize n )
|
||||
{
|
||||
if ( dest == NULL )
|
||||
{
|
||||
@ -15,25 +17,25 @@ void* mem_copy( void* dest, void const* source, sw n )
|
||||
return memcpy( dest, source, n );
|
||||
}
|
||||
|
||||
void const* mem_find( void const* data, u8 c, sw n )
|
||||
void const* mem_find( void const* data, u8 c, ssize n )
|
||||
{
|
||||
u8 const* s = zpl_cast( u8 const* ) data;
|
||||
while ( ( zpl_cast( uptr ) s & ( sizeof( uw ) - 1 ) ) && n && *s != c )
|
||||
u8 const* s = rcast( u8 const*, data);
|
||||
while ( ( rcast( uptr, s) & ( sizeof( usize ) - 1 ) ) && n && *s != c )
|
||||
{
|
||||
s++;
|
||||
n--;
|
||||
}
|
||||
if ( n && *s != c )
|
||||
{
|
||||
sw const* w;
|
||||
sw k = GEN__ONES * c;
|
||||
w = zpl_cast( sw const* ) s;
|
||||
while ( n >= size_of( sw ) && ! GEN__HAS_ZERO( *w ^ k ) )
|
||||
ssize const* w;
|
||||
ssize k = GEN__ONES * c;
|
||||
w = rcast( ssize const*, s);
|
||||
while ( n >= size_of( ssize ) && ! GEN__HAS_ZERO( *w ^ k ) )
|
||||
{
|
||||
w++;
|
||||
n -= size_of( sw );
|
||||
n -= size_of( ssize );
|
||||
}
|
||||
s = zpl_cast( u8 const* ) w;
|
||||
s = rcast( u8 const*, w);
|
||||
while ( n && *s != c )
|
||||
{
|
||||
s++;
|
||||
@ -41,7 +43,7 @@ void const* mem_find( void const* data, u8 c, sw n )
|
||||
}
|
||||
}
|
||||
|
||||
return n ? zpl_cast( void const* ) s : NULL;
|
||||
return n ? rcast( void const*, s ) : NULL;
|
||||
}
|
||||
|
||||
#define GEN_HEAP_STATS_MAGIC 0xDEADC0DE
|
||||
@ -49,8 +51,8 @@ void const* mem_find( void const* data, u8 c, sw n )
|
||||
struct _heap_stats
|
||||
{
|
||||
u32 magic;
|
||||
sw used_memory;
|
||||
sw alloc_count;
|
||||
ssize used_memory;
|
||||
ssize alloc_count;
|
||||
};
|
||||
|
||||
global _heap_stats _heap_stats_info;
|
||||
@ -61,13 +63,13 @@ void heap_stats_init( void )
|
||||
_heap_stats_info.magic = GEN_HEAP_STATS_MAGIC;
|
||||
}
|
||||
|
||||
sw heap_stats_used_memory( void )
|
||||
ssize heap_stats_used_memory( void )
|
||||
{
|
||||
GEN_ASSERT_MSG( _heap_stats_info.magic == GEN_HEAP_STATS_MAGIC, "heap_stats is not initialised yet, call heap_stats_init first!" );
|
||||
return _heap_stats_info.used_memory;
|
||||
}
|
||||
|
||||
sw heap_stats_alloc_count( void )
|
||||
ssize heap_stats_alloc_count( void )
|
||||
{
|
||||
GEN_ASSERT_MSG( _heap_stats_info.magic == GEN_HEAP_STATS_MAGIC, "heap_stats is not initialised yet, call heap_stats_init first!" );
|
||||
return _heap_stats_info.alloc_count;
|
||||
@ -82,11 +84,11 @@ void heap_stats_check( void )
|
||||
|
||||
struct _heap_alloc_info
|
||||
{
|
||||
sw size;
|
||||
ssize size;
|
||||
void* physical_start;
|
||||
};
|
||||
|
||||
void* heap_allocator_proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags )
|
||||
void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
|
||||
{
|
||||
void* ptr = NULL;
|
||||
// unused( allocator_data );
|
||||
@ -95,16 +97,16 @@ void* heap_allocator_proc( void* allocator_data, AllocType type, sw size, sw ali
|
||||
alignment = GEN_DEFAULT_MEMORY_ALIGNMENT;
|
||||
|
||||
#ifdef GEN_HEAP_ANALYSIS
|
||||
sw alloc_info_size = size_of( _heap_alloc_info );
|
||||
sw alloc_info_remainder = ( alloc_info_size % alignment );
|
||||
sw track_size = max( alloc_info_size, alignment ) + alloc_info_remainder;
|
||||
ssize alloc_info_size = size_of( _heap_alloc_info );
|
||||
ssize alloc_info_remainder = ( alloc_info_size % alignment );
|
||||
ssize track_size = max( alloc_info_size, alignment ) + alloc_info_remainder;
|
||||
switch ( type )
|
||||
{
|
||||
case EAllocation_FREE :
|
||||
{
|
||||
if ( ! old_memory )
|
||||
break;
|
||||
_heap_alloc_info* alloc_info = zpl_cast( _heap_alloc_info* ) old_memory - 1;
|
||||
_heap_alloc_info* alloc_info = rcast( _heap_alloc_info*, old_memory) - 1;
|
||||
_heap_stats_info.used_memory -= alloc_info->size;
|
||||
_heap_stats_info.alloc_count--;
|
||||
old_memory = alloc_info->physical_start;
|
||||
@ -195,11 +197,11 @@ void* heap_allocator_proc( void* allocator_data, AllocType type, sw size, sw ali
|
||||
#ifdef GEN_HEAP_ANALYSIS
|
||||
if ( type == EAllocation_ALLOC )
|
||||
{
|
||||
_heap_alloc_info* alloc_info = zpl_cast( _heap_alloc_info* )( zpl_cast( char* ) ptr + alloc_info_remainder );
|
||||
_heap_alloc_info* alloc_info = rcast( _heap_alloc_info*, rcast( char*, ptr) + alloc_info_remainder );
|
||||
zero_item( alloc_info );
|
||||
alloc_info->size = size - track_size;
|
||||
alloc_info->physical_start = ptr;
|
||||
ptr = zpl_cast( void* )( alloc_info + 1 );
|
||||
ptr = rcast( void*, alloc_info + 1 );
|
||||
_heap_stats_info.used_memory += alloc_info->size;
|
||||
_heap_stats_info.alloc_count++;
|
||||
}
|
||||
@ -209,7 +211,7 @@ void* heap_allocator_proc( void* allocator_data, AllocType type, sw size, sw ali
|
||||
}
|
||||
|
||||
#pragma region VirtualMemory
|
||||
VirtualMemory vm_from_memory( void* data, sw size )
|
||||
VirtualMemory vm_from_memory( void* data, ssize size )
|
||||
{
|
||||
VirtualMemory vm;
|
||||
vm.data = data;
|
||||
@ -218,7 +220,7 @@ VirtualMemory vm_from_memory( void* data, sw size )
|
||||
}
|
||||
|
||||
#if defined( GEN_SYSTEM_WINDOWS )
|
||||
VirtualMemory vm_alloc( void* addr, sw size )
|
||||
VirtualMemory vm_alloc( void* addr, ssize size )
|
||||
{
|
||||
VirtualMemory vm;
|
||||
GEN_ASSERT( size > 0 );
|
||||
@ -234,7 +236,7 @@ b32 vm_free( VirtualMemory vm )
|
||||
{
|
||||
if ( VirtualQuery( vm.data, &info, size_of( info ) ) == 0 )
|
||||
return false;
|
||||
if ( info.BaseAddress != vm.data || info.AllocationBase != vm.data || info.State != MEM_COMMIT || info.RegionSize > zpl_cast( uw ) vm.size )
|
||||
if ( info.BaseAddress != vm.data || info.AllocationBase != vm.data || info.State != MEM_COMMIT || info.RegionSize > scast( usize, vm.size) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -246,7 +248,7 @@ b32 vm_free( VirtualMemory vm )
|
||||
return true;
|
||||
}
|
||||
|
||||
VirtualMemory vm_trim( VirtualMemory vm, sw lead_size, sw size )
|
||||
VirtualMemory vm_trim( VirtualMemory vm, ssize lead_size, ssize size )
|
||||
{
|
||||
VirtualMemory new_vm = { 0 };
|
||||
void* ptr;
|
||||
@ -270,7 +272,7 @@ b32 vm_purge( VirtualMemory vm )
|
||||
return true;
|
||||
}
|
||||
|
||||
sw virtual_memory_page_size( sw* alignment_out )
|
||||
ssize virtual_memory_page_size( ssize* alignment_out )
|
||||
{
|
||||
SYSTEM_INFO info;
|
||||
GetSystemInfo( &info );
|
||||
@ -285,7 +287,7 @@ sw virtual_memory_page_size( sw* alignment_out )
|
||||
# ifndef MAP_ANONYMOUS
|
||||
# define MAP_ANONYMOUS MAP_ANON
|
||||
# endif
|
||||
VirtualMemory vm_alloc( void* addr, sw size )
|
||||
VirtualMemory vm_alloc( void* addr, ssize size )
|
||||
{
|
||||
VirtualMemory vm;
|
||||
GEN_ASSERT( size > 0 );
|
||||
@ -300,10 +302,10 @@ b32 vm_free( VirtualMemory vm )
|
||||
return true;
|
||||
}
|
||||
|
||||
VirtualMemory vm_trim( VirtualMemory vm, sw lead_size, sw size )
|
||||
VirtualMemory vm_trim( VirtualMemory vm, ssize lead_size, ssize size )
|
||||
{
|
||||
void* ptr;
|
||||
sw trail_size;
|
||||
ssize trail_size;
|
||||
GEN_ASSERT( vm.size >= lead_size + size );
|
||||
|
||||
ptr = pointer_add( vm.data, lead_size );
|
||||
@ -322,10 +324,10 @@ b32 vm_purge( VirtualMemory vm )
|
||||
return err != 0;
|
||||
}
|
||||
|
||||
sw virtual_memory_page_size( sw* alignment_out )
|
||||
ssize virtual_memory_page_size( ssize* alignment_out )
|
||||
{
|
||||
// TODO: Is this always true?
|
||||
sw result = zpl_cast( sw ) sysconf( _SC_PAGE_SIZE );
|
||||
ssize result = scast( ssize, sysconf( _SC_PAGE_SIZE ));
|
||||
if ( alignment_out )
|
||||
*alignment_out = result;
|
||||
return result;
|
||||
@ -334,7 +336,7 @@ sw virtual_memory_page_size( sw* alignment_out )
|
||||
|
||||
#pragma endregion VirtualMemory
|
||||
|
||||
void* Arena::allocator_proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags )
|
||||
void* arena_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
|
||||
{
|
||||
Arena* arena = rcast(Arena*, allocator_data);
|
||||
void* ptr = NULL;
|
||||
@ -346,10 +348,10 @@ void* Arena::allocator_proc( void* allocator_data, AllocType type, sw size, sw a
|
||||
case EAllocation_ALLOC :
|
||||
{
|
||||
void* end = pointer_add( arena->PhysicalStart, arena->TotalUsed );
|
||||
sw total_size = align_forward_i64( size, alignment );
|
||||
ssize total_size = align_forward_s64( size, alignment );
|
||||
|
||||
// NOTE: Out of memory
|
||||
if ( arena->TotalUsed + total_size > (sw) arena->TotalSize )
|
||||
if ( arena->TotalUsed + total_size > (ssize) arena->TotalSize )
|
||||
{
|
||||
// zpl__printf_err("%s", "Arena out of memory\n");
|
||||
GEN_FATAL("Arena out of memory! (Possibly could not fit for the largest size Arena!!)");
|
||||
@ -384,9 +386,9 @@ void* Arena::allocator_proc( void* allocator_data, AllocType type, sw size, sw a
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* Pool::allocator_proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags )
|
||||
void* pool_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
|
||||
{
|
||||
Pool* pool = zpl_cast( Pool* ) allocator_data;
|
||||
Pool* pool = rcast( Pool*, allocator_data);
|
||||
void* ptr = NULL;
|
||||
|
||||
// unused( old_size );
|
||||
@ -401,9 +403,9 @@ void* Pool::allocator_proc( void* allocator_data, AllocType type, sw size, sw al
|
||||
GEN_ASSERT( alignment == pool->BlockAlign );
|
||||
GEN_ASSERT( pool->FreeList != NULL );
|
||||
|
||||
next_free = *zpl_cast( uptr* ) pool->FreeList;
|
||||
next_free = * rcast( uptr*, pool->FreeList);
|
||||
ptr = pool->FreeList;
|
||||
pool->FreeList = zpl_cast( void* ) next_free;
|
||||
pool->FreeList = rcast( void*, next_free);
|
||||
pool->TotalSize += pool->BlockSize;
|
||||
|
||||
if ( flags & ALLOCATOR_FLAG_CLEAR_TO_ZERO )
|
||||
@ -417,8 +419,8 @@ void* Pool::allocator_proc( void* allocator_data, AllocType type, sw size, sw al
|
||||
if ( old_memory == NULL )
|
||||
return NULL;
|
||||
|
||||
next = zpl_cast( uptr* ) old_memory;
|
||||
*next = zpl_cast( uptr ) pool->FreeList;
|
||||
next = rcast( uptr*, old_memory);
|
||||
*next = rcast( uptr, pool->FreeList);
|
||||
pool->FreeList = old_memory;
|
||||
pool->TotalSize -= pool->BlockSize;
|
||||
}
|
||||
@ -426,7 +428,7 @@ void* Pool::allocator_proc( void* allocator_data, AllocType type, sw size, sw al
|
||||
|
||||
case EAllocation_FREE_ALL :
|
||||
{
|
||||
sw actual_block_size, block_index;
|
||||
ssize actual_block_size, block_index;
|
||||
void* curr;
|
||||
uptr* end;
|
||||
|
||||
@ -437,13 +439,13 @@ void* Pool::allocator_proc( void* allocator_data, AllocType type, sw size, sw al
|
||||
curr = pool->PhysicalStart;
|
||||
for ( block_index = 0; block_index < pool->NumBlocks - 1; block_index++ )
|
||||
{
|
||||
uptr* next = zpl_cast( uptr* ) curr;
|
||||
*next = zpl_cast( uptr ) curr + actual_block_size;
|
||||
uptr* next = rcast( uptr*, curr);
|
||||
* next = rcast( uptr, curr) + actual_block_size;
|
||||
curr = pointer_add( curr, actual_block_size );
|
||||
}
|
||||
|
||||
end = zpl_cast( uptr* ) curr;
|
||||
*end = zpl_cast( uptr ) NULL;
|
||||
end = rcast( uptr*, curr);
|
||||
* end = scast( uptr, NULL);
|
||||
pool->FreeList = pool->PhysicalStart;
|
||||
}
|
||||
break;
|
||||
@ -457,11 +459,11 @@ void* Pool::allocator_proc( void* allocator_data, AllocType type, sw size, sw al
|
||||
return ptr;
|
||||
}
|
||||
|
||||
Pool Pool::init_align( AllocatorInfo backing, sw num_blocks, sw block_size, sw block_align )
|
||||
Pool pool_init_align( AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align )
|
||||
{
|
||||
Pool pool = {};
|
||||
|
||||
sw actual_block_size, pool_size, block_index;
|
||||
ssize actual_block_size, pool_size, block_index;
|
||||
void *data, *curr;
|
||||
uptr* end;
|
||||
|
||||
@ -495,16 +497,16 @@ Pool Pool::init_align( AllocatorInfo backing, sw num_blocks, sw block_size, sw b
|
||||
return pool;
|
||||
}
|
||||
|
||||
void Pool::clear()
|
||||
void pool_clear(Pool* pool)
|
||||
{
|
||||
sw actual_block_size, block_index;
|
||||
ssize actual_block_size, block_index;
|
||||
void* curr;
|
||||
uptr* end;
|
||||
|
||||
actual_block_size = BlockSize + BlockAlign;
|
||||
actual_block_size = pool->BlockSize + pool->BlockAlign;
|
||||
|
||||
curr = PhysicalStart;
|
||||
for ( block_index = 0; block_index < NumBlocks - 1; block_index++ )
|
||||
curr = pool->PhysicalStart;
|
||||
for ( block_index = 0; block_index < pool->NumBlocks - 1; block_index++ )
|
||||
{
|
||||
uptr* next = ( uptr* ) curr;
|
||||
*next = ( uptr ) curr + actual_block_size;
|
||||
@ -514,7 +516,9 @@ void Pool::clear()
|
||||
end = ( uptr* ) curr;
|
||||
*end = ( uptr ) NULL;
|
||||
|
||||
FreeList = PhysicalStart;
|
||||
pool->FreeList = pool->PhysicalStart;
|
||||
}
|
||||
|
||||
GEN_API_C_END
|
||||
|
||||
#pragma endregion Memory
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -23,7 +23,7 @@ u8 adt_make_branch( ADT_Node* node, AllocatorInfo backing, char const* name, b32
|
||||
node->type = type;
|
||||
node->name = name;
|
||||
node->parent = parent;
|
||||
node->nodes = Array<ADT_Node>::init( backing );
|
||||
node->nodes = array_init<ADT_Node>( backing );
|
||||
|
||||
if ( ! node->nodes )
|
||||
return EADT_ERROR_OUT_OF_MEMORY;
|
||||
@ -36,12 +36,12 @@ u8 adt_destroy_branch( ADT_Node* node )
|
||||
GEN_ASSERT_NOT_NULL( node );
|
||||
if ( ( node->type == EADT_TYPE_OBJECT || node->type == EADT_TYPE_ARRAY ) && node->nodes )
|
||||
{
|
||||
for ( sw i = 0; i < node->nodes.num(); ++i )
|
||||
for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); ++i )
|
||||
{
|
||||
adt_destroy_branch( node->nodes + i );
|
||||
}
|
||||
|
||||
node->nodes.free();
|
||||
array_free(& node->nodes);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -66,7 +66,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for ( sw i = 0; i < node->nodes.num(); i++ )
|
||||
for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ )
|
||||
{
|
||||
if ( ! str_compare( node->nodes[ i ].name, name ) )
|
||||
{
|
||||
@ -76,7 +76,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search )
|
||||
|
||||
if ( deep_search )
|
||||
{
|
||||
for ( sw i = 0; i < node->nodes.num(); i++ )
|
||||
for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ )
|
||||
{
|
||||
ADT_Node* res = adt_find( node->nodes + i, name, deep_search );
|
||||
|
||||
@ -111,7 +111,7 @@ internal ADT_Node* _adt_get_value( ADT_Node* node, char const* value )
|
||||
file_stream_open( &tmp, heap(), ( u8* )back, size_of( back ), EFileStream_WRITABLE );
|
||||
adt_print_number( &tmp, node );
|
||||
|
||||
sw fsize = 0;
|
||||
ssize fsize = 0;
|
||||
u8* buf = file_stream_buf( &tmp, &fsize );
|
||||
|
||||
if ( ! str_compare( ( char const* )buf, value ) )
|
||||
@ -132,7 +132,7 @@ internal ADT_Node* _adt_get_value( ADT_Node* node, char const* value )
|
||||
|
||||
internal ADT_Node* _adt_get_field( ADT_Node* node, char* name, char* value )
|
||||
{
|
||||
for ( sw i = 0; i < node->nodes.num(); i++ )
|
||||
for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ )
|
||||
{
|
||||
if ( ! str_compare( node->nodes[ i ].name, name ) )
|
||||
{
|
||||
@ -207,7 +207,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri )
|
||||
/* run a value comparison against any child that is an object node */
|
||||
else if ( node->type == EADT_TYPE_ARRAY )
|
||||
{
|
||||
for ( sw i = 0; i < node->nodes.num(); i++ )
|
||||
for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ )
|
||||
{
|
||||
ADT_Node* child = &node->nodes[ i ];
|
||||
if ( child->type != EADT_TYPE_OBJECT )
|
||||
@ -225,7 +225,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri )
|
||||
/* [value] */
|
||||
else
|
||||
{
|
||||
for ( sw i = 0; i < node->nodes.num(); i++ )
|
||||
for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ )
|
||||
{
|
||||
ADT_Node* child = &node->nodes[ i ];
|
||||
if ( _adt_get_value( child, l_b2 ) )
|
||||
@ -256,8 +256,8 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri )
|
||||
/* handle array index lookup */
|
||||
else
|
||||
{
|
||||
sw idx = ( sw )str_to_i64( buf, NULL, 10 );
|
||||
if ( idx >= 0 && idx < node->nodes.num() )
|
||||
ssize idx = ( ssize )str_to_i64( buf, NULL, 10 );
|
||||
if ( idx >= 0 && idx < scast(ssize, array_num(node->nodes)) )
|
||||
{
|
||||
found_node = &node->nodes[ idx ];
|
||||
|
||||
@ -272,7 +272,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri )
|
||||
return found_node;
|
||||
}
|
||||
|
||||
ADT_Node* adt_alloc_at( ADT_Node* parent, sw index )
|
||||
ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index )
|
||||
{
|
||||
if ( ! parent || ( parent->type != EADT_TYPE_OBJECT && parent->type != EADT_TYPE_ARRAY ) )
|
||||
{
|
||||
@ -282,15 +282,16 @@ ADT_Node* adt_alloc_at( ADT_Node* parent, sw index )
|
||||
if ( ! parent->nodes )
|
||||
return NULL;
|
||||
|
||||
if ( index < 0 || index > parent->nodes.num() )
|
||||
if ( index < 0 || index > scast(ssize, array_num(parent->nodes)) )
|
||||
return NULL;
|
||||
|
||||
ADT_Node o = { 0 };
|
||||
o.parent = parent;
|
||||
if ( ! parent->nodes.append_at( o, index ) )
|
||||
if ( ! array_append_at( & parent->nodes, o, index ) )
|
||||
return NULL;
|
||||
|
||||
return parent->nodes + index;
|
||||
ADT_Node* node = & parent->nodes[index];
|
||||
return node;
|
||||
}
|
||||
|
||||
ADT_Node* adt_alloc( ADT_Node* parent )
|
||||
@ -303,7 +304,7 @@ ADT_Node* adt_alloc( ADT_Node* parent )
|
||||
if ( ! parent->nodes )
|
||||
return NULL;
|
||||
|
||||
return adt_alloc_at( parent, parent->nodes.num() );
|
||||
return adt_alloc_at( parent, array_num(parent->nodes) );
|
||||
}
|
||||
|
||||
b8 adt_set_obj( ADT_Node* obj, char const* name, AllocatorInfo backing )
|
||||
@ -337,7 +338,7 @@ b8 adt_set_int( ADT_Node* obj, char const* name, s64 value )
|
||||
return true;
|
||||
}
|
||||
|
||||
ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, sw index )
|
||||
ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, ssize index )
|
||||
{
|
||||
GEN_ASSERT_NOT_NULL( node );
|
||||
GEN_ASSERT_NOT_NULL( new_parent );
|
||||
@ -357,7 +358,7 @@ ADT_Node* adt_move_node( ADT_Node* node, ADT_Node* new_parent )
|
||||
GEN_ASSERT_NOT_NULL( node );
|
||||
GEN_ASSERT_NOT_NULL( new_parent );
|
||||
GEN_ASSERT( new_parent->type == EADT_TYPE_ARRAY || new_parent->type == EADT_TYPE_OBJECT );
|
||||
return adt_move_node_at( node, new_parent, new_parent->nodes.num() );
|
||||
return adt_move_node_at( node, new_parent, array_num(new_parent->nodes) );
|
||||
}
|
||||
|
||||
void adt_swap_nodes( ADT_Node* node, ADT_Node* other_node )
|
||||
@ -366,8 +367,8 @@ void adt_swap_nodes( ADT_Node* node, ADT_Node* other_node )
|
||||
GEN_ASSERT_NOT_NULL( other_node );
|
||||
ADT_Node* parent = node->parent;
|
||||
ADT_Node* other_parent = other_node->parent;
|
||||
sw index = ( pointer_diff( parent->nodes, node ) / size_of( ADT_Node ) );
|
||||
sw index2 = ( pointer_diff( other_parent->nodes, other_node ) / size_of( ADT_Node ) );
|
||||
ssize index = ( pointer_diff( parent->nodes, node ) / size_of( ADT_Node ) );
|
||||
ssize index2 = ( pointer_diff( other_parent->nodes, other_node ) / size_of( ADT_Node ) );
|
||||
ADT_Node temp = parent->nodes[ index ];
|
||||
temp.parent = other_parent;
|
||||
other_parent->nodes[ index2 ].parent = parent;
|
||||
@ -380,8 +381,8 @@ void adt_remove_node( ADT_Node* node )
|
||||
GEN_ASSERT_NOT_NULL( node );
|
||||
GEN_ASSERT_NOT_NULL( node->parent );
|
||||
ADT_Node* parent = node->parent;
|
||||
sw index = ( pointer_diff( parent->nodes, node ) / size_of( ADT_Node ) );
|
||||
parent->nodes.remove_at( index );
|
||||
ssize index = ( pointer_diff( parent->nodes, node ) / size_of( ADT_Node ) );
|
||||
array_remove_at( parent->nodes, index );
|
||||
}
|
||||
|
||||
ADT_Node* adt_append_obj( ADT_Node* parent, char const* name )
|
||||
@ -389,7 +390,7 @@ ADT_Node* adt_append_obj( ADT_Node* parent, char const* name )
|
||||
ADT_Node* o = adt_alloc( parent );
|
||||
if ( ! o )
|
||||
return NULL;
|
||||
if ( adt_set_obj( o, name, parent->nodes.get_header()->Allocator ) )
|
||||
if ( adt_set_obj( o, name, array_get_header(parent->nodes)->Allocator ) )
|
||||
{
|
||||
adt_remove_node( o );
|
||||
return NULL;
|
||||
@ -402,7 +403,9 @@ ADT_Node* adt_append_arr( ADT_Node* parent, char const* name )
|
||||
ADT_Node* o = adt_alloc( parent );
|
||||
if ( ! o )
|
||||
return NULL;
|
||||
if ( adt_set_arr( o, name, parent->nodes.get_header()->Allocator ) )
|
||||
|
||||
ArrayHeader* node_header = array_get_header(parent->nodes);
|
||||
if ( adt_set_arr( o, name, node_header->Allocator ) )
|
||||
{
|
||||
adt_remove_node( o );
|
||||
return NULL;
|
||||
@ -447,7 +450,7 @@ char* adt_parse_number_strict( ADT_Node* node, char* base_str )
|
||||
while ( *e )
|
||||
++e;
|
||||
|
||||
while ( *p && ( str_find( "eE.+-", *p ) || char_is_hex_digit( *p ) ) )
|
||||
while ( *p && ( char_first_occurence( "eE.+-", *p ) || char_is_hex_digit( *p ) ) )
|
||||
{
|
||||
++p;
|
||||
}
|
||||
@ -476,7 +479,7 @@ char* adt_parse_number( ADT_Node* node, char* base_str )
|
||||
u8 node_props = 0;
|
||||
|
||||
/* skip false positives and special cases */
|
||||
if ( ! ! str_find( "eE", *p ) || ( ! ! str_find( ".+-", *p ) && ! char_is_hex_digit( *( p + 1 ) ) && *( p + 1 ) != '.' ) )
|
||||
if ( ! ! char_first_occurence( "eE", *p ) || ( ! ! char_first_occurence( ".+-", *p ) && ! char_is_hex_digit( *( p + 1 ) ) && *( p + 1 ) != '.' ) )
|
||||
{
|
||||
return ++base_str;
|
||||
}
|
||||
@ -484,7 +487,7 @@ char* adt_parse_number( ADT_Node* node, char* base_str )
|
||||
node_type = EADT_TYPE_INTEGER;
|
||||
neg_zero = false;
|
||||
|
||||
sw ib = 0;
|
||||
ssize ib = 0;
|
||||
char buf[ 48 ] = { 0 };
|
||||
|
||||
if ( *e == '+' )
|
||||
@ -507,7 +510,7 @@ char* adt_parse_number( ADT_Node* node, char* base_str )
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ! str_compare( e, "0x", 2 ) || ! str_compare( e, "0X", 2 ) )
|
||||
if ( ! str_compare_len( e, "0x", 2 ) || ! str_compare_len( e, "0X", 2 ) )
|
||||
{
|
||||
node_props = EADT_PROPS_IS_HEX;
|
||||
}
|
||||
@ -550,9 +553,9 @@ char* adt_parse_number( ADT_Node* node, char* base_str )
|
||||
|
||||
f32 eb = 10;
|
||||
char expbuf[ 6 ] = { 0 };
|
||||
sw expi = 0;
|
||||
ssize expi = 0;
|
||||
|
||||
if ( *e && ! ! str_find( "eE", *e ) )
|
||||
if ( *e && ! ! char_first_occurence( "eE", *e ) )
|
||||
{
|
||||
++e;
|
||||
if ( *e == '+' || *e == '-' || char_is_digit( *e ) )
|
||||
@ -595,7 +598,7 @@ char* adt_parse_number( ADT_Node* node, char* base_str )
|
||||
|
||||
#ifndef GEN_PARSER_DISABLE_ANALYSIS
|
||||
char *q = buf, *base_string = q, *base_string2 = q;
|
||||
base_string = zpl_cast( char* ) str_skip( base_string, '.' );
|
||||
base_string = ccast( char*, str_skip( base_string, '.' ));
|
||||
*base_string = '\0';
|
||||
base_string2 = base_string + 1;
|
||||
char* base_string_off = base_string2;
|
||||
@ -748,7 +751,7 @@ ADT_Error adt_print_string( FileInfo* file, ADT_Node* node, char const* escaped_
|
||||
{
|
||||
p = str_skip_any( p, escaped_chars );
|
||||
_adt_fprintf( file, "%.*s", pointer_diff( b, p ), b );
|
||||
if ( *p && ! ! str_find( escaped_chars, *p ) )
|
||||
if ( *p && ! ! char_first_occurence( escaped_chars, *p ) )
|
||||
{
|
||||
_adt_fprintf( file, "%s%c", escape_symbol, *p );
|
||||
p++;
|
||||
@ -816,13 +819,13 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
|
||||
char* beginChar;
|
||||
char* endChar;
|
||||
|
||||
sw columnIndex = 0;
|
||||
sw totalColumnIndex = 0;
|
||||
ssize columnIndex = 0;
|
||||
ssize totalColumnIndex = 0;
|
||||
|
||||
do
|
||||
{
|
||||
char delimiter = 0;
|
||||
currentChar = zpl_cast( char* ) str_trim( currentChar, false );
|
||||
currentChar = ccast( char*, str_trim( currentChar, false ));
|
||||
|
||||
if ( *currentChar == 0 )
|
||||
break;
|
||||
@ -846,7 +849,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
|
||||
#endif
|
||||
do
|
||||
{
|
||||
endChar = zpl_cast( char* ) str_skip( endChar, '"' );
|
||||
endChar = ccast( char*, str_skip( endChar, '"' ));
|
||||
|
||||
if ( *endChar && *( endChar + 1 ) == '"' )
|
||||
{
|
||||
@ -865,7 +868,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
|
||||
}
|
||||
|
||||
*endChar = 0;
|
||||
currentChar = zpl_cast( char* ) str_trim( endChar + 1, true );
|
||||
currentChar = ccast( char*, str_trim( endChar + 1, true ));
|
||||
delimiter = * currentChar;
|
||||
|
||||
/* unescape escaped quotes (so that unescaped text escapes :) */
|
||||
@ -902,7 +905,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
|
||||
|
||||
if ( * endChar )
|
||||
{
|
||||
currentChar = zpl_cast( char* ) str_trim( endChar, true );
|
||||
currentChar = ccast( char*, str_trim( endChar, true ));
|
||||
|
||||
while ( char_is_space( *( endChar - 1 ) ) )
|
||||
{
|
||||
@ -946,12 +949,12 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
|
||||
}
|
||||
}
|
||||
|
||||
if ( columnIndex >= root->nodes.num() )
|
||||
if ( columnIndex >= scast(ssize, array_num(root->nodes)) )
|
||||
{
|
||||
adt_append_arr( root, NULL );
|
||||
}
|
||||
|
||||
root->nodes[ columnIndex ].nodes.append( rowItem );
|
||||
array_append( & root->nodes[ columnIndex ].nodes, rowItem );
|
||||
|
||||
if ( delimiter == delim )
|
||||
{
|
||||
@ -979,7 +982,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
|
||||
}
|
||||
while ( *currentChar );
|
||||
|
||||
if ( root->nodes.num() == 0 )
|
||||
if (array_num( root->nodes) == 0 )
|
||||
{
|
||||
GEN_CSV_ASSERT( "unexpected end of input. stream is empty." );
|
||||
error = ECSV_Error__UNEXPECTED_END_OF_INPUT;
|
||||
@ -989,12 +992,12 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
|
||||
/* consider first row as a header. */
|
||||
if ( has_header )
|
||||
{
|
||||
for ( sw i = 0; i < root->nodes.num(); i++ )
|
||||
for ( ssize i = 0; i < scast(ssize, array_num(root->nodes)); i++ )
|
||||
{
|
||||
CSV_Object* col = root->nodes + i;
|
||||
CSV_Object* hdr = col->nodes;
|
||||
col->name = hdr->string;
|
||||
col->nodes.remove_at( 0 );
|
||||
array_remove_at(col->nodes, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -1057,11 +1060,11 @@ void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delimiter )
|
||||
GEN_ASSERT_NOT_NULL( file );
|
||||
GEN_ASSERT_NOT_NULL( obj );
|
||||
GEN_ASSERT( obj->nodes );
|
||||
sw cols = obj->nodes.num();
|
||||
ssize cols = array_num(obj->nodes);
|
||||
if ( cols == 0 )
|
||||
return;
|
||||
|
||||
sw rows = obj->nodes[ 0 ].nodes.num();
|
||||
ssize rows = array_num(obj->nodes[ 0 ].nodes);
|
||||
if ( rows == 0 )
|
||||
return;
|
||||
|
||||
@ -1069,7 +1072,7 @@ void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delimiter )
|
||||
|
||||
if ( has_headers )
|
||||
{
|
||||
for ( sw i = 0; i < cols; i++ )
|
||||
for ( ssize i = 0; i < cols; i++ )
|
||||
{
|
||||
_csv_write_header( file, &obj->nodes[ i ] );
|
||||
if ( i + 1 != cols )
|
||||
@ -1080,9 +1083,9 @@ void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delimiter )
|
||||
str_fmt_file( file, "\n" );
|
||||
}
|
||||
|
||||
for ( sw r = 0; r < rows; r++ )
|
||||
for ( ssize r = 0; r < rows; r++ )
|
||||
{
|
||||
for ( sw i = 0; i < cols; i++ )
|
||||
for ( ssize i = 0; i < cols; i++ )
|
||||
{
|
||||
_csv_write_record( file, &obj->nodes[ i ].nodes[ r ] );
|
||||
if ( i + 1 != cols )
|
||||
@ -1099,9 +1102,10 @@ String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delimi
|
||||
FileInfo tmp;
|
||||
file_stream_new( &tmp, a );
|
||||
csv_write_delimiter( &tmp, obj, delimiter );
|
||||
sw fsize;
|
||||
|
||||
ssize fsize;
|
||||
u8* buf = file_stream_buf( &tmp, &fsize );
|
||||
String output = String::make_length( a, ( char* )buf, fsize );
|
||||
String output = string_make_length( a, ( char* )buf, fsize );
|
||||
file_close( &tmp );
|
||||
return output;
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ struct ADT_Node
|
||||
union
|
||||
{
|
||||
char const* string;
|
||||
Array<ADT_Node> nodes; ///< zpl_array
|
||||
Array(ADT_Node) nodes; ///< zpl_array
|
||||
|
||||
struct
|
||||
{
|
||||
@ -178,7 +178,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search );
|
||||
* @param index
|
||||
* @return zpl_adt_node * node
|
||||
*/
|
||||
ADT_Node* adt_alloc_at( ADT_Node* parent, sw index );
|
||||
ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index );
|
||||
|
||||
/**
|
||||
* @brief Allocate an unitialised node within a container.
|
||||
@ -196,7 +196,7 @@ ADT_Node* adt_alloc( ADT_Node* parent );
|
||||
* @param index
|
||||
* @return zpl_adt_node * node
|
||||
*/
|
||||
ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, sw index );
|
||||
ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, ssize index );
|
||||
|
||||
/**
|
||||
* @brief Move an existing node to a new container.
|
||||
@ -400,31 +400,33 @@ enum CSV_Error : u32
|
||||
|
||||
typedef ADT_Node CSV_Object;
|
||||
|
||||
GEN_DEF_INLINE u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header );
|
||||
u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header, char delim );
|
||||
void csv_free( CSV_Object* obj );
|
||||
u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header );
|
||||
u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header, char delim );
|
||||
void csv_free( CSV_Object* obj );
|
||||
|
||||
GEN_DEF_INLINE void csv_write( FileInfo* file, CSV_Object* obj );
|
||||
GEN_DEF_INLINE String csv_write_string( AllocatorInfo a, CSV_Object* obj );
|
||||
void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim );
|
||||
String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delim );
|
||||
void csv_write( FileInfo* file, CSV_Object* obj );
|
||||
String csv_write_string( AllocatorInfo a, CSV_Object* obj );
|
||||
void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim );
|
||||
String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delim );
|
||||
|
||||
/* inline */
|
||||
|
||||
GEN_IMPL_INLINE u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header )
|
||||
inline
|
||||
u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header )
|
||||
{
|
||||
return csv_parse_delimiter( root, text, allocator, has_header, ',' );
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE void csv_write( FileInfo* file, CSV_Object* obj )
|
||||
inline
|
||||
void csv_write( FileInfo* file, CSV_Object* obj )
|
||||
{
|
||||
csv_write_delimiter( file, obj, ',' );
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE String csv_write_string( AllocatorInfo a, CSV_Object* obj )
|
||||
inline
|
||||
String csv_write_string( AllocatorInfo a, CSV_Object* obj )
|
||||
{
|
||||
return csv_write_string_delimiter( a, obj, ',' );
|
||||
}
|
||||
|
||||
#pragma endregion CSV
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
#pragma once
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#pragma region Platform Detection
|
||||
|
||||
@ -74,13 +76,18 @@
|
||||
/* Platform compiler */
|
||||
|
||||
#if defined( _MSC_VER )
|
||||
# define GEN_COMPILER_MSVC 1
|
||||
# define GEN_COMPILER_CLANG 0
|
||||
# define GEN_COMPILER_MSVC 1
|
||||
# define GEN_COMPILER_GCC 0
|
||||
#elif defined( __GNUC__ )
|
||||
# define GEN_COMPILER_GCC 1
|
||||
# define GEN_COMPILER_CLANG 0
|
||||
# define GEN_COMPILER_MSVC 0
|
||||
# define GEN_COMPILER_GCC 1
|
||||
#elif defined( __clang__ )
|
||||
# define GEN_COMPILER_CLANG 1
|
||||
#elif defined( __MINGW32__ )
|
||||
# define GEN_COMPILER_MINGW 1
|
||||
# define GEN_COMPILER_MSVC 0
|
||||
# define GEN_COMPILER_GCC 1
|
||||
#else
|
||||
# error Unknown compiler
|
||||
#endif
|
||||
|
||||
@ -99,8 +106,25 @@
|
||||
# define GEN_GCC_VERSION_CHECK(major,minor,patch) (0)
|
||||
#endif
|
||||
|
||||
#define GEN_DEF_INLINE static
|
||||
#define GEN_IMPL_INLINE static inline
|
||||
#if !defined(GEN_COMPILER_C)
|
||||
# ifdef __cplusplus
|
||||
# define GEN_COMPILER_C 0
|
||||
# define GEN_COMPILER_CPP 1
|
||||
# else
|
||||
# if defined(__STDC__)
|
||||
# define GEN_COMPILER_C 1
|
||||
# define GEN_COMPILER_CPP 0
|
||||
# else
|
||||
// Fallback for very old C compilers
|
||||
# define GEN_COMPILER_C 1
|
||||
# define GEN_COMPILER_CPP 0
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if GEN_COMPILER_C
|
||||
#pragma message("Detected C")
|
||||
#endif
|
||||
|
||||
#pragma endregion Platform Detection
|
||||
|
||||
@ -113,13 +137,32 @@
|
||||
# include <intrin.h>
|
||||
# endif
|
||||
|
||||
#if GEN_COMPILER_C
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#pragma endregion Mandatory Includes
|
||||
|
||||
#ifdef GEN_DONT_USE_NAMESPACE
|
||||
# define GEN_NS
|
||||
# define GEN_NS_BEGIN
|
||||
# define GEN_NS_END
|
||||
#if GEN_DONT_USE_NAMESPACE || GEN_COMPILER_C
|
||||
# if GEN_COMPILER_C
|
||||
# define GEN_NS_PARSER_BEGIN
|
||||
# define GEN_NS_PARSER_END
|
||||
# define GEN_USING_NS_PARSER
|
||||
# define GEN_NS
|
||||
# define GEN_NS_BEGIN
|
||||
# define GEN_NS_END
|
||||
# else
|
||||
# define GEN_NS_PARSER_BEGIN namespace parser {
|
||||
# define GEN_NS_PARSER_END }
|
||||
# define GEN_USING_NS_PARSER using namespace parser
|
||||
# define GEN_NS ::
|
||||
# define GEN_NS_BEGIN
|
||||
# define GEN_NS_END
|
||||
# endif
|
||||
#else
|
||||
# define GEN_NS_PARSER_BEGIN namespace parser {
|
||||
# define GEN_NS_PARSER_END }
|
||||
# define GEN_USING_NS_PARSER using namespace parser
|
||||
# define GEN_NS gen::
|
||||
# define GEN_NS_BEGIN namespace gen {
|
||||
# define GEN_NS_END }
|
@ -41,10 +41,10 @@ struct _format_info
|
||||
s32 precision;
|
||||
};
|
||||
|
||||
internal sw _print_string( char* text, sw max_len, _format_info* info, char const* str )
|
||||
internal ssize _print_string( char* text, ssize max_len, _format_info* info, char const* str )
|
||||
{
|
||||
sw res = 0, len = 0;
|
||||
sw remaining = max_len;
|
||||
ssize res = 0, len = 0;
|
||||
ssize remaining = max_len;
|
||||
char* begin = text;
|
||||
|
||||
if ( str == NULL && max_len >= 6 )
|
||||
@ -75,7 +75,7 @@ internal sw _print_string( char* text, sw max_len, _format_info* info, char cons
|
||||
|
||||
if ( info->width > res )
|
||||
{
|
||||
sw padding = info->width - len;
|
||||
ssize padding = info->width - len;
|
||||
|
||||
char pad = ( info->flags & GEN_FMT_ZERO ) ? '0' : ' ';
|
||||
while ( padding-- > 0 && remaining-- > 0 )
|
||||
@ -86,7 +86,7 @@ internal sw _print_string( char* text, sw max_len, _format_info* info, char cons
|
||||
{
|
||||
if ( info && ( info->width > res ) )
|
||||
{
|
||||
sw padding = info->width - len;
|
||||
ssize padding = info->width - len;
|
||||
char pad = ( info->flags & GEN_FMT_ZERO ) ? '0' : ' ';
|
||||
while ( padding-- > 0 && remaining-- > 0 )
|
||||
*text++ = pad, res++;
|
||||
@ -108,16 +108,16 @@ internal sw _print_string( char* text, sw max_len, _format_info* info, char cons
|
||||
return res;
|
||||
}
|
||||
|
||||
internal sw _print_char( char* text, sw max_len, _format_info* info, char arg )
|
||||
internal ssize _print_char( char* text, ssize max_len, _format_info* info, char arg )
|
||||
{
|
||||
char str[ 2 ] = "";
|
||||
str[ 0 ] = arg;
|
||||
return _print_string( text, max_len, info, str );
|
||||
}
|
||||
|
||||
internal sw _print_repeated_char( char* text, sw max_len, _format_info* info, char arg )
|
||||
internal ssize _print_repeated_char( char* text, ssize max_len, _format_info* info, char arg )
|
||||
{
|
||||
sw res = 0;
|
||||
ssize res = 0;
|
||||
s32 rem = ( info ) ? ( info->width > 0 ) ? info->width : 1 : 1;
|
||||
res = rem;
|
||||
while ( rem-- > 0 )
|
||||
@ -126,24 +126,24 @@ internal sw _print_repeated_char( char* text, sw max_len, _format_info* info, ch
|
||||
return res;
|
||||
}
|
||||
|
||||
internal sw _print_i64( char* text, sw max_len, _format_info* info, s64 value )
|
||||
internal ssize _print_i64( char* text, ssize max_len, _format_info* info, s64 value )
|
||||
{
|
||||
char num[ 130 ];
|
||||
i64_to_str( value, num, info ? info->base : 10 );
|
||||
return _print_string( text, max_len, info, num );
|
||||
}
|
||||
|
||||
internal sw _print_u64( char* text, sw max_len, _format_info* info, u64 value )
|
||||
internal ssize _print_u64( char* text, ssize max_len, _format_info* info, u64 value )
|
||||
{
|
||||
char num[ 130 ];
|
||||
u64_to_str( value, num, info ? info->base : 10 );
|
||||
return _print_string( text, max_len, info, num );
|
||||
}
|
||||
|
||||
internal sw _print_f64( char* text, sw max_len, _format_info* info, b32 is_hexadecimal, f64 arg )
|
||||
internal ssize _print_f64( char* text, ssize max_len, _format_info* info, b32 is_hexadecimal, f64 arg )
|
||||
{
|
||||
// TODO: Handle exponent notation
|
||||
sw width, len, remaining = max_len;
|
||||
ssize width, len, remaining = max_len;
|
||||
char* text_begin = text;
|
||||
|
||||
if ( arg )
|
||||
@ -163,7 +163,7 @@ internal sw _print_f64( char* text, sw max_len, _format_info* info, b32 is_hexad
|
||||
text++;
|
||||
}
|
||||
|
||||
value = zpl_cast( u64 ) arg;
|
||||
value = scast( u64, arg);
|
||||
len = _print_u64( text, remaining, NULL, value );
|
||||
text += len;
|
||||
|
||||
@ -184,14 +184,14 @@ internal sw _print_f64( char* text, sw max_len, _format_info* info, b32 is_hexad
|
||||
text++;
|
||||
while ( info->precision-- > 0 )
|
||||
{
|
||||
value = zpl_cast( u64 )( arg * mult );
|
||||
value = scast( u64, arg * mult );
|
||||
len = _print_u64( text, remaining, NULL, value );
|
||||
text += len;
|
||||
if ( len >= remaining )
|
||||
remaining = min( remaining, 1 );
|
||||
else
|
||||
remaining -= len;
|
||||
arg -= zpl_cast( f64 ) value / mult;
|
||||
arg -= scast( f64, value / mult);
|
||||
mult *= 10;
|
||||
}
|
||||
}
|
||||
@ -239,15 +239,15 @@ internal sw _print_f64( char* text, sw max_len, _format_info* info, b32 is_hexad
|
||||
return ( text - text_begin );
|
||||
}
|
||||
|
||||
neverinline sw str_fmt_va( char* text, sw max_len, char const* fmt, va_list va )
|
||||
neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_list va )
|
||||
{
|
||||
char const* text_begin = text;
|
||||
sw remaining = max_len, res;
|
||||
ssize remaining = max_len, res;
|
||||
|
||||
while ( *fmt )
|
||||
{
|
||||
_format_info info = { 0 };
|
||||
sw len = 0;
|
||||
ssize len = 0;
|
||||
info.precision = -1;
|
||||
|
||||
while ( *fmt && *fmt != '%' && remaining )
|
||||
@ -311,7 +311,7 @@ neverinline sw str_fmt_va( char* text, sw max_len, char const* fmt, va_list va )
|
||||
}
|
||||
else
|
||||
{
|
||||
info.width = zpl_cast( s32 ) str_to_i64( fmt, zpl_cast( char** ) & fmt, 10 );
|
||||
info.width = scast( s32, str_to_i64( fmt, ccast( char**, & fmt), 10 ));
|
||||
if ( info.width != 0 )
|
||||
{
|
||||
info.flags |= GEN_FMT_WIDTH;
|
||||
@ -329,7 +329,7 @@ neverinline sw str_fmt_va( char* text, sw max_len, char const* fmt, va_list va )
|
||||
}
|
||||
else
|
||||
{
|
||||
info.precision = zpl_cast( s32 ) str_to_i64( fmt, zpl_cast( char** ) & fmt, 10 );
|
||||
info.precision = scast( s32, str_to_i64( fmt, ccast( char**, & fmt), 10 ));
|
||||
}
|
||||
info.flags &= ~GEN_FMT_ZERO;
|
||||
}
|
||||
@ -411,7 +411,7 @@ neverinline sw str_fmt_va( char* text, sw max_len, char const* fmt, va_list va )
|
||||
break;
|
||||
|
||||
case 'c' :
|
||||
len = _print_char( text, remaining, &info, zpl_cast( char ) va_arg( va, int ) );
|
||||
len = _print_char( text, remaining, &info, scast( char, va_arg( va, int ) ));
|
||||
break;
|
||||
|
||||
case 's' :
|
||||
@ -420,9 +420,18 @@ neverinline sw str_fmt_va( char* text, sw max_len, char const* fmt, va_list va )
|
||||
|
||||
case 'S':
|
||||
{
|
||||
if ( *(fmt + 1) == 'C' )
|
||||
{
|
||||
++ fmt;
|
||||
StrC gen_str = va_arg( va, StrC);
|
||||
info.precision = gen_str.Len;
|
||||
len = _print_string( text, remaining, &info, gen_str.Ptr );
|
||||
break;
|
||||
}
|
||||
|
||||
String gen_str = String { va_arg( va, char*) };
|
||||
|
||||
info.precision = gen_str.length();
|
||||
info.precision = string_length(gen_str);
|
||||
len = _print_string( text, remaining, &info, gen_str );
|
||||
}
|
||||
break;
|
||||
@ -455,25 +464,25 @@ neverinline sw str_fmt_va( char* text, sw max_len, char const* fmt, va_list va )
|
||||
switch ( info.flags & GEN_FMT_INTS )
|
||||
{
|
||||
case GEN_FMT_CHAR :
|
||||
value = zpl_cast( u64 ) zpl_cast( u8 ) va_arg( va, int );
|
||||
value = scast( u64, scast( u8, va_arg( va, int )));
|
||||
break;
|
||||
case GEN_FMT_SHORT :
|
||||
value = zpl_cast( u64 ) zpl_cast( u16 ) va_arg( va, int );
|
||||
value = scast( u64, scast( u16, va_arg( va, int )));
|
||||
break;
|
||||
case GEN_FMT_LONG :
|
||||
value = zpl_cast( u64 ) va_arg( va, unsigned long );
|
||||
case GEN_FMT_LONG:
|
||||
value = scast( u64, va_arg( va, unsigned long ));
|
||||
break;
|
||||
case GEN_FMT_LLONG :
|
||||
value = zpl_cast( u64 ) va_arg( va, unsigned long long );
|
||||
value = scast( u64, va_arg( va, unsigned long long ));
|
||||
break;
|
||||
case GEN_FMT_SIZE :
|
||||
value = zpl_cast( u64 ) va_arg( va, uw );
|
||||
value = scast( u64, va_arg( va, usize ));
|
||||
break;
|
||||
case GEN_FMT_INTPTR :
|
||||
value = zpl_cast( u64 ) va_arg( va, uptr );
|
||||
value = scast( u64, va_arg( va, uptr ));
|
||||
break;
|
||||
default :
|
||||
value = zpl_cast( u64 ) va_arg( va, unsigned int );
|
||||
value = scast( u64, va_arg( va, unsigned int ));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -485,25 +494,25 @@ neverinline sw str_fmt_va( char* text, sw max_len, char const* fmt, va_list va )
|
||||
switch ( info.flags & GEN_FMT_INTS )
|
||||
{
|
||||
case GEN_FMT_CHAR :
|
||||
value = zpl_cast( s64 ) zpl_cast( s8 ) va_arg( va, int );
|
||||
value = scast( s64, scast( s8, va_arg( va, int )));
|
||||
break;
|
||||
case GEN_FMT_SHORT :
|
||||
value = zpl_cast( s64 ) zpl_cast( s16 ) va_arg( va, int );
|
||||
value = scast( s64, scast( s16, va_arg( va, int )));
|
||||
break;
|
||||
case GEN_FMT_LONG :
|
||||
value = zpl_cast( s64 ) va_arg( va, long );
|
||||
value = scast( s64, va_arg( va, long ));
|
||||
break;
|
||||
case GEN_FMT_LLONG :
|
||||
value = zpl_cast( s64 ) va_arg( va, long long );
|
||||
value = scast( s64, va_arg( va, long long ));
|
||||
break;
|
||||
case GEN_FMT_SIZE :
|
||||
value = zpl_cast( s64 ) va_arg( va, uw );
|
||||
value = scast( s64, va_arg( va, usize ));
|
||||
break;
|
||||
case GEN_FMT_INTPTR :
|
||||
value = zpl_cast( s64 ) va_arg( va, uptr );
|
||||
value = scast( s64, va_arg( va, uptr ));
|
||||
break;
|
||||
default :
|
||||
value = zpl_cast( s64 ) va_arg( va, int );
|
||||
value = scast( s64, va_arg( va, int ));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -540,17 +549,17 @@ char* str_fmt_buf( char const* fmt, ... )
|
||||
return str;
|
||||
}
|
||||
|
||||
sw str_fmt_file_va( struct FileInfo* f, char const* fmt, va_list va )
|
||||
ssize str_fmt_file_va( struct FileInfo* f, char const* fmt, va_list va )
|
||||
{
|
||||
local_persist thread_local char buf[ GEN_PRINTF_MAXLEN ];
|
||||
sw len = str_fmt_va( buf, size_of( buf ), fmt, va );
|
||||
ssize len = str_fmt_va( buf, size_of( buf ), fmt, va );
|
||||
b32 res = file_write( f, buf, len - 1 ); // NOTE: prevent extra whitespace
|
||||
return res ? len : -1;
|
||||
}
|
||||
|
||||
sw str_fmt_file( struct FileInfo* f, char const* fmt, ... )
|
||||
ssize str_fmt_file( struct FileInfo* f, char const* fmt, ... )
|
||||
{
|
||||
sw res;
|
||||
ssize res;
|
||||
va_list va;
|
||||
va_start( va, fmt );
|
||||
res = str_fmt_file_va( f, fmt, va );
|
||||
@ -558,9 +567,9 @@ sw str_fmt_file( struct FileInfo* f, char const* fmt, ... )
|
||||
return res;
|
||||
}
|
||||
|
||||
sw str_fmt( char* str, sw n, char const* fmt, ... )
|
||||
ssize str_fmt( char* str, ssize n, char const* fmt, ... )
|
||||
{
|
||||
sw res;
|
||||
ssize res;
|
||||
va_list va;
|
||||
va_start( va, fmt );
|
||||
res = str_fmt_va( str, n, fmt, va );
|
||||
@ -568,19 +577,19 @@ sw str_fmt( char* str, sw n, char const* fmt, ... )
|
||||
return res;
|
||||
}
|
||||
|
||||
sw str_fmt_out_va( char const* fmt, va_list va )
|
||||
ssize str_fmt_out_va( char const* fmt, va_list va )
|
||||
{
|
||||
return str_fmt_file_va( file_get_standard( EFileStandard_OUTPUT ), fmt, va );
|
||||
}
|
||||
|
||||
sw str_fmt_out_err_va( char const* fmt, va_list va )
|
||||
ssize str_fmt_out_err_va( char const* fmt, va_list va )
|
||||
{
|
||||
return str_fmt_file_va( file_get_standard( EFileStandard_ERROR ), fmt, va );
|
||||
}
|
||||
|
||||
sw str_fmt_out_err( char const* fmt, ... )
|
||||
ssize str_fmt_out_err( char const* fmt, ... )
|
||||
{
|
||||
sw res;
|
||||
ssize res;
|
||||
va_list va;
|
||||
va_start( va, fmt );
|
||||
res = str_fmt_out_err_va( fmt, va );
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
#pragma region Printing
|
||||
|
||||
GEN_API_C_BEGIN
|
||||
|
||||
struct FileInfo;
|
||||
|
||||
#ifndef GEN_PRINTF_MAXLEN
|
||||
@ -12,23 +14,23 @@ struct FileInfo;
|
||||
#endif
|
||||
|
||||
// NOTE: A locally persisting buffer is used internally
|
||||
char* str_fmt_buf ( char const* fmt, ... );
|
||||
char* str_fmt_buf_va ( char const* fmt, va_list va );
|
||||
sw str_fmt ( char* str, sw n, char const* fmt, ... );
|
||||
sw str_fmt_va ( char* str, sw n, char const* fmt, va_list va );
|
||||
sw str_fmt_out_va ( char const* fmt, va_list va );
|
||||
sw str_fmt_out_err ( char const* fmt, ... );
|
||||
sw str_fmt_out_err_va( char const* fmt, va_list va );
|
||||
sw str_fmt_file ( FileInfo* f, char const* fmt, ... );
|
||||
sw str_fmt_file_va ( FileInfo* f, char const* fmt, va_list va );
|
||||
char* str_fmt_buf ( char const* fmt, ... );
|
||||
char* str_fmt_buf_va ( char const* fmt, va_list va );
|
||||
ssize str_fmt ( char* str, ssize n, char const* fmt, ... );
|
||||
ssize str_fmt_va ( char* str, ssize n, char const* fmt, va_list va );
|
||||
ssize str_fmt_out_va ( char const* fmt, va_list va );
|
||||
ssize str_fmt_out_err ( char const* fmt, ... );
|
||||
ssize str_fmt_out_err_va( char const* fmt, va_list va );
|
||||
ssize str_fmt_file ( FileInfo* f, char const* fmt, ... );
|
||||
ssize str_fmt_file_va ( FileInfo* f, char const* fmt, va_list va );
|
||||
|
||||
constexpr
|
||||
char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
|
||||
|
||||
inline
|
||||
sw log_fmt(char const* fmt, ...)
|
||||
ssize log_fmt(char const* fmt, ...)
|
||||
{
|
||||
sw res;
|
||||
ssize res;
|
||||
va_list va;
|
||||
|
||||
va_start(va, fmt);
|
||||
@ -38,4 +40,6 @@ sw log_fmt(char const* fmt, ...)
|
||||
return res;
|
||||
}
|
||||
|
||||
GEN_API_C_END
|
||||
|
||||
#pragma endregion Printing
|
||||
|
@ -7,7 +7,7 @@
|
||||
#pragma region String Ops
|
||||
|
||||
internal
|
||||
sw _scan_zpl_i64( const char* text, s32 base, s64* value )
|
||||
ssize _scan_zpl_i64( const char* text, s32 base, s64* value )
|
||||
{
|
||||
const char* text_begin = text;
|
||||
s64 result = 0;
|
||||
@ -19,7 +19,7 @@ sw _scan_zpl_i64( const char* text, s32 base, s64* value )
|
||||
text++;
|
||||
}
|
||||
|
||||
if ( base == 16 && str_compare( text, "0x", 2 ) == 0 )
|
||||
if ( base == 16 && str_compare_len( text, "0x", 2 ) == 0 )
|
||||
text += 2;
|
||||
|
||||
for ( ;; )
|
||||
@ -56,12 +56,12 @@ global const char _num_to_char_table[] =
|
||||
|
||||
s64 str_to_i64( const char* str, char** end_ptr, s32 base )
|
||||
{
|
||||
sw len;
|
||||
ssize len;
|
||||
s64 value;
|
||||
|
||||
if ( ! base )
|
||||
{
|
||||
if ( ( str_len( str ) > 2 ) && ( str_compare( str, "0x", 2 ) == 0 ) )
|
||||
if ( ( str_len( str ) > 2 ) && ( str_compare_len( str, "0x", 2 ) == 0 ) )
|
||||
base = 16;
|
||||
else
|
||||
base = 10;
|
||||
@ -85,7 +85,7 @@ void i64_to_str( s64 value, char* string, s32 base )
|
||||
value = -value;
|
||||
}
|
||||
|
||||
v = zpl_cast( u64 ) value;
|
||||
v = scast( u64, value);
|
||||
if ( v != 0 )
|
||||
{
|
||||
while ( v > 0 )
|
||||
@ -207,7 +207,7 @@ f64 str_to_f64( const char* str, char** end_ptr )
|
||||
result = sign * ( frac ? ( value / scale ) : ( value * scale ) );
|
||||
|
||||
if ( end_ptr )
|
||||
*end_ptr = zpl_cast( char* ) str;
|
||||
* end_ptr = rcast( char*, ccast(char*, str) );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -5,41 +5,43 @@
|
||||
|
||||
#pragma region String Ops
|
||||
|
||||
GEN_DEF_INLINE const char* char_first_occurence( const char* str, char c );
|
||||
constexpr auto str_find = &char_first_occurence;
|
||||
GEN_API_C_BEGIN
|
||||
|
||||
GEN_DEF_INLINE b32 char_is_alpha( char c );
|
||||
GEN_DEF_INLINE b32 char_is_alphanumeric( char c );
|
||||
GEN_DEF_INLINE b32 char_is_digit( char c );
|
||||
GEN_DEF_INLINE b32 char_is_hex_digit( char c );
|
||||
GEN_DEF_INLINE b32 char_is_space( char c );
|
||||
GEN_DEF_INLINE char char_to_lower( char c );
|
||||
GEN_DEF_INLINE char char_to_upper( char c );
|
||||
const char* char_first_occurence( const char* str, char c );
|
||||
|
||||
GEN_DEF_INLINE s32 digit_to_int( char c );
|
||||
GEN_DEF_INLINE s32 hex_digit_to_int( char c );
|
||||
b32 char_is_alpha( char c );
|
||||
b32 char_is_alphanumeric( char c );
|
||||
b32 char_is_digit( char c );
|
||||
b32 char_is_hex_digit( char c );
|
||||
b32 char_is_space( char c );
|
||||
char char_to_lower( char c );
|
||||
char char_to_upper( char c );
|
||||
|
||||
GEN_DEF_INLINE s32 str_compare( const char* s1, const char* s2 );
|
||||
GEN_DEF_INLINE s32 str_compare( const char* s1, const char* s2, sw len );
|
||||
GEN_DEF_INLINE char* str_copy( char* dest, const char* source, sw len );
|
||||
GEN_DEF_INLINE sw str_copy_nulpad( char* dest, const char* source, sw len );
|
||||
GEN_DEF_INLINE sw str_len( const char* str );
|
||||
GEN_DEF_INLINE sw str_len( const char* str, sw max_len );
|
||||
GEN_DEF_INLINE char* str_reverse( char* str ); // NOTE: ASCII only
|
||||
GEN_DEF_INLINE char const* str_skip( char const* str, char c );
|
||||
GEN_DEF_INLINE char const* str_skip_any( char const* str, char const* char_list );
|
||||
GEN_DEF_INLINE char const* str_trim( char const* str, b32 catch_newline );
|
||||
s32 digit_to_int( char c );
|
||||
s32 hex_digit_to_int( char c );
|
||||
|
||||
s32 str_compare( const char* s1, const char* s2 );
|
||||
s32 str_compare_len( const char* s1, const char* s2, ssize len );
|
||||
char* str_copy( char* dest, const char* source, ssize len );
|
||||
ssize str_copy_nulpad( char* dest, const char* source, ssize len );
|
||||
ssize str_len( const char* str );
|
||||
ssize str_len_capped( const char* str, ssize max_len );
|
||||
char* str_reverse( char* str ); // NOTE: ASCII only
|
||||
char const* str_skip( char const* str, char c );
|
||||
char const* str_skip_any( char const* str, char const* char_list );
|
||||
char const* str_trim( char const* str, b32 catch_newline );
|
||||
|
||||
// NOTE: ASCII only
|
||||
GEN_DEF_INLINE void str_to_lower( char* str );
|
||||
GEN_DEF_INLINE void str_to_upper( char* str );
|
||||
void str_to_lower( char* str );
|
||||
void str_to_upper( char* str );
|
||||
|
||||
s64 str_to_i64( const char* str, char** end_ptr, s32 base );
|
||||
void i64_to_str( s64 value, char* string, s32 base );
|
||||
void u64_to_str( u64 value, char* string, s32 base );
|
||||
f64 str_to_f64( const char* str, char** end_ptr );
|
||||
|
||||
GEN_IMPL_INLINE const char* char_first_occurence( const char* s, char c )
|
||||
inline
|
||||
const char* char_first_occurence( const char* s, char c )
|
||||
{
|
||||
char ch = c;
|
||||
for ( ; *s != ch; s++ )
|
||||
@ -50,59 +52,67 @@ GEN_IMPL_INLINE const char* char_first_occurence( const char* s, char c )
|
||||
return s;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE b32 char_is_alpha( char c )
|
||||
inline
|
||||
b32 char_is_alpha( char c )
|
||||
{
|
||||
if ( ( c >= 'A' && c <= 'Z' ) || ( c >= 'a' && c <= 'z' ) )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE b32 char_is_alphanumeric( char c )
|
||||
inline
|
||||
b32 char_is_alphanumeric( char c )
|
||||
{
|
||||
return char_is_alpha( c ) || char_is_digit( c );
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE b32 char_is_digit( char c )
|
||||
inline
|
||||
b32 char_is_digit( char c )
|
||||
{
|
||||
if ( c >= '0' && c <= '9' )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE b32 char_is_hex_digit( char c )
|
||||
inline
|
||||
b32 char_is_hex_digit( char c )
|
||||
{
|
||||
if ( char_is_digit( c ) || ( c >= 'a' && c <= 'f' ) || ( c >= 'A' && c <= 'F' ) )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE b32 char_is_space( char c )
|
||||
inline
|
||||
b32 char_is_space( char c )
|
||||
{
|
||||
if ( c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v' )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE char char_to_lower( char c )
|
||||
inline
|
||||
char char_to_lower( char c )
|
||||
{
|
||||
if ( c >= 'A' && c <= 'Z' )
|
||||
return 'a' + ( c - 'A' );
|
||||
return c;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE char char_to_upper( char c )
|
||||
inline char char_to_upper( char c )
|
||||
{
|
||||
if ( c >= 'a' && c <= 'z' )
|
||||
return 'A' + ( c - 'a' );
|
||||
return c;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE s32 digit_to_int( char c )
|
||||
inline
|
||||
s32 digit_to_int( char c )
|
||||
{
|
||||
return char_is_digit( c ) ? c - '0' : c - 'W';
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE s32 hex_digit_to_int( char c )
|
||||
inline
|
||||
s32 hex_digit_to_int( char c )
|
||||
{
|
||||
if ( char_is_digit( c ) )
|
||||
return digit_to_int( c );
|
||||
@ -113,7 +123,8 @@ GEN_IMPL_INLINE s32 hex_digit_to_int( char c )
|
||||
return -1;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE s32 str_compare( const char* s1, const char* s2 )
|
||||
inline
|
||||
s32 str_compare( const char* s1, const char* s2 )
|
||||
{
|
||||
while ( *s1 && ( *s1 == *s2 ) )
|
||||
{
|
||||
@ -122,7 +133,8 @@ GEN_IMPL_INLINE s32 str_compare( const char* s1, const char* s2 )
|
||||
return *( u8* )s1 - *( u8* )s2;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE s32 str_compare( const char* s1, const char* s2, sw len )
|
||||
inline
|
||||
s32 str_compare_len( const char* s1, const char* s2, ssize len )
|
||||
{
|
||||
for ( ; len > 0; s1++, s2++, len-- )
|
||||
{
|
||||
@ -134,7 +146,8 @@ GEN_IMPL_INLINE s32 str_compare( const char* s1, const char* s2, sw len )
|
||||
return 0;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE char* str_copy( char* dest, const char* source, sw len )
|
||||
inline
|
||||
char* str_copy( char* dest, const char* source, ssize len )
|
||||
{
|
||||
GEN_ASSERT_NOT_NULL( dest );
|
||||
if ( source )
|
||||
@ -154,9 +167,10 @@ GEN_IMPL_INLINE char* str_copy( char* dest, const char* source, sw len )
|
||||
return dest;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE sw str_copy_nulpad( char* dest, const char* source, sw len )
|
||||
inline
|
||||
ssize str_copy_nulpad( char* dest, const char* source, ssize len )
|
||||
{
|
||||
sw result = 0;
|
||||
ssize result = 0;
|
||||
GEN_ASSERT_NOT_NULL( dest );
|
||||
if ( source )
|
||||
{
|
||||
@ -178,7 +192,8 @@ GEN_IMPL_INLINE sw str_copy_nulpad( char* dest, const char* source, sw len )
|
||||
return result;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE sw str_len( const char* str )
|
||||
inline
|
||||
ssize str_len( const char* str )
|
||||
{
|
||||
if ( str == NULL )
|
||||
{
|
||||
@ -190,17 +205,19 @@ GEN_IMPL_INLINE sw str_len( const char* str )
|
||||
return str - p;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE sw str_len( const char* str, sw max_len )
|
||||
inline
|
||||
ssize str_len_capped( const char* str, ssize max_len )
|
||||
{
|
||||
const char* end = zpl_cast( const char* ) mem_find( str, 0, max_len );
|
||||
const char* end = rcast(const char*, mem_find( str, 0, max_len ));
|
||||
if ( end )
|
||||
return end - str;
|
||||
return max_len;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE char* str_reverse( char* str )
|
||||
inline
|
||||
char* str_reverse( char* str )
|
||||
{
|
||||
sw len = str_len( str );
|
||||
ssize len = str_len( str );
|
||||
char* a = str + 0;
|
||||
char* b = str + len - 1;
|
||||
len /= 2;
|
||||
@ -212,7 +229,8 @@ GEN_IMPL_INLINE char* str_reverse( char* str )
|
||||
return str;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE char const* str_skip( char const* str, char c )
|
||||
inline
|
||||
char const* str_skip( char const* str, char c )
|
||||
{
|
||||
while ( *str && *str != c )
|
||||
{
|
||||
@ -221,11 +239,12 @@ GEN_IMPL_INLINE char const* str_skip( char const* str, char c )
|
||||
return str;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE char const* str_skip_any( char const* str, char const* char_list )
|
||||
inline
|
||||
char const* str_skip_any( char const* str, char const* char_list )
|
||||
{
|
||||
char const* closest_ptr = zpl_cast( char const* ) pointer_add( ( void* )str, str_len( str ) );
|
||||
sw char_list_count = str_len( char_list );
|
||||
for ( sw i = 0; i < char_list_count; i++ )
|
||||
char const* closest_ptr = rcast( char const*, pointer_add_const( rcast(mem_ptr_const, str), str_len( str ) ));
|
||||
ssize char_list_count = str_len( char_list );
|
||||
for ( ssize i = 0; i < char_list_count; i++ )
|
||||
{
|
||||
char const* p = str_skip( str, char_list[ i ] );
|
||||
closest_ptr = min( closest_ptr, p );
|
||||
@ -233,7 +252,8 @@ GEN_IMPL_INLINE char const* str_skip_any( char const* str, char const* char_list
|
||||
return closest_ptr;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE char const* str_trim( char const* str, b32 catch_newline )
|
||||
inline
|
||||
char const* str_trim( char const* str, b32 catch_newline )
|
||||
{
|
||||
while ( *str && char_is_space( *str ) && ( ! catch_newline || ( catch_newline && *str != '\n' ) ) )
|
||||
{
|
||||
@ -242,7 +262,8 @@ GEN_IMPL_INLINE char const* str_trim( char const* str, b32 catch_newline )
|
||||
return str;
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE void str_to_lower( char* str )
|
||||
inline
|
||||
void str_to_lower( char* str )
|
||||
{
|
||||
if ( ! str )
|
||||
return;
|
||||
@ -253,7 +274,8 @@ GEN_IMPL_INLINE void str_to_lower( char* str )
|
||||
}
|
||||
}
|
||||
|
||||
GEN_IMPL_INLINE void str_to_upper( char* str )
|
||||
inline
|
||||
void str_to_upper( char* str )
|
||||
{
|
||||
if ( ! str )
|
||||
return;
|
||||
@ -264,4 +286,6 @@ GEN_IMPL_INLINE void str_to_upper( char* str )
|
||||
}
|
||||
}
|
||||
|
||||
GEN_API_C_END
|
||||
|
||||
#pragma endregion String Ops
|
||||
|
@ -4,20 +4,9 @@
|
||||
#endif
|
||||
|
||||
#pragma region String
|
||||
|
||||
String String::fmt( AllocatorInfo allocator, char* buf, sw buf_size, char const* fmt, ... )
|
||||
String string_make_length( AllocatorInfo allocator, char const* str, ssize length )
|
||||
{
|
||||
va_list va;
|
||||
va_start( va, fmt );
|
||||
str_fmt_va( buf, buf_size, fmt, va );
|
||||
va_end( va );
|
||||
|
||||
return make( allocator, buf );
|
||||
}
|
||||
|
||||
String String::make_length( AllocatorInfo allocator, char const* str, sw length )
|
||||
{
|
||||
constexpr sw header_size = sizeof( Header );
|
||||
constexpr ssize header_size = sizeof( StringHeader );
|
||||
|
||||
s32 alloc_size = header_size + length + 1;
|
||||
void* allocation = alloc( allocator, alloc_size );
|
||||
@ -25,8 +14,8 @@ String String::make_length( AllocatorInfo allocator, char const* str, sw length
|
||||
if ( allocation == nullptr )
|
||||
return { nullptr };
|
||||
|
||||
Header&
|
||||
header = * rcast(Header*, allocation);
|
||||
StringHeader&
|
||||
header = * rcast(StringHeader*, allocation);
|
||||
header = { allocator, length, length };
|
||||
|
||||
String result = { rcast( char*, allocation) + header_size };
|
||||
@ -41,9 +30,9 @@ String String::make_length( AllocatorInfo allocator, char const* str, sw length
|
||||
return result;
|
||||
}
|
||||
|
||||
String String::make_reserve( AllocatorInfo allocator, sw capacity )
|
||||
String string_make_reserve( AllocatorInfo allocator, ssize capacity )
|
||||
{
|
||||
constexpr sw header_size = sizeof( Header );
|
||||
constexpr ssize header_size = sizeof( StringHeader );
|
||||
|
||||
s32 alloc_size = header_size + capacity + 1;
|
||||
void* allocation = alloc( allocator, alloc_size );
|
||||
@ -53,8 +42,8 @@ String String::make_reserve( AllocatorInfo allocator, sw capacity )
|
||||
|
||||
mem_set( allocation, 0, alloc_size );
|
||||
|
||||
Header*
|
||||
header = rcast(Header*, allocation);
|
||||
StringHeader*
|
||||
header = rcast(StringHeader*, allocation);
|
||||
header->Allocator = allocator;
|
||||
header->Capacity = capacity;
|
||||
header->Length = 0;
|
||||
@ -62,69 +51,4 @@ String String::make_reserve( AllocatorInfo allocator, sw capacity )
|
||||
String result = { rcast(char*, allocation) + header_size };
|
||||
return result;
|
||||
}
|
||||
|
||||
String String::fmt_buf( AllocatorInfo allocator, char const* fmt, ... )
|
||||
{
|
||||
local_persist thread_local
|
||||
char buf[ GEN_PRINTF_MAXLEN ] = { 0 };
|
||||
|
||||
va_list va;
|
||||
va_start( va, fmt );
|
||||
str_fmt_va( buf, GEN_PRINTF_MAXLEN, fmt, va );
|
||||
va_end( va );
|
||||
|
||||
return make( allocator, buf );
|
||||
}
|
||||
|
||||
bool String::append_fmt( char const* fmt, ... )
|
||||
{
|
||||
sw res;
|
||||
char buf[ GEN_PRINTF_MAXLEN ] = { 0 };
|
||||
|
||||
va_list va;
|
||||
va_start( va, fmt );
|
||||
res = str_fmt_va( buf, count_of( buf ) - 1, fmt, va ) - 1;
|
||||
va_end( va );
|
||||
|
||||
return append( buf, res );
|
||||
}
|
||||
|
||||
bool String::make_space_for( char const* str, sw add_len )
|
||||
{
|
||||
sw available = avail_space();
|
||||
|
||||
// NOTE: Return if there is enough space left
|
||||
if ( available >= add_len )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
sw new_len, old_size, new_size;
|
||||
|
||||
void* ptr;
|
||||
void* new_ptr;
|
||||
|
||||
AllocatorInfo allocator = get_header().Allocator;
|
||||
Header* header = nullptr;
|
||||
|
||||
new_len = grow_formula( length() + add_len );
|
||||
ptr = & get_header();
|
||||
old_size = size_of( Header ) + length() + 1;
|
||||
new_size = size_of( Header ) + new_len + 1;
|
||||
|
||||
new_ptr = resize( allocator, ptr, old_size, new_size );
|
||||
|
||||
if ( new_ptr == nullptr )
|
||||
return false;
|
||||
|
||||
header = zpl_cast( Header* ) new_ptr;
|
||||
header->Allocator = allocator;
|
||||
header->Capacity = new_len;
|
||||
|
||||
Data = rcast( char*, header + 1 );
|
||||
|
||||
return str;
|
||||
}
|
||||
}
|
||||
#pragma endregion String
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -23,7 +23,7 @@
|
||||
{
|
||||
u32 hi, lo;
|
||||
__asm__ __volatile__( "rdtsc" : "=a"( lo ), "=d"( hi ) );
|
||||
return ( zpl_cast( u64 ) lo ) | ( ( zpl_cast( u64 ) hi ) << 32 );
|
||||
return scast( u64, lo ) | ( scast( u64, hi ) << 32 );
|
||||
}
|
||||
#elif defined( __powerpc__ )
|
||||
u64 read_cpu_time_stamp_counter( void )
|
||||
|
@ -1,7 +1,7 @@
|
||||
// This file is intended to be included within gen.hpp (There is no pragma diagnostic ignores)
|
||||
#pragma once
|
||||
|
||||
#include "dependencies/header_start.hpp"
|
||||
#include "dependencies/platform.hpp"
|
||||
|
||||
GEN_NS_BEGIN
|
||||
|
||||
|
@ -11,31 +11,35 @@ using namespace gen;
|
||||
CodeBody gen_ecode( char const* path )
|
||||
{
|
||||
char scratch_mem[kilobytes(1)];
|
||||
Arena scratch = Arena::init_from_memory( scratch_mem, sizeof(scratch_mem) );
|
||||
Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) );
|
||||
|
||||
file_read_contents( scratch, zero_terminate, path );
|
||||
file_read_contents( arena_allocator_info( & scratch), zero_terminate, path );
|
||||
|
||||
CSV_Object csv_nodes;
|
||||
csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false );
|
||||
|
||||
Array<ADT_Node> enum_strs = csv_nodes.nodes[0].nodes;
|
||||
|
||||
String enum_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
|
||||
String to_str_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
|
||||
String enum_entries = string_make_reserve( GlobalAllocator, kilobytes(1) );
|
||||
String to_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) );
|
||||
|
||||
for ( ADT_Node node : enum_strs )
|
||||
for ( ADT_Node* node = array_begin(enum_strs); node != array_end(enum_strs); node = array_next(enum_strs, node) )
|
||||
{
|
||||
char const* code = node.string;
|
||||
enum_entries.append_fmt( "%s,\n", code );
|
||||
to_str_entries.append_fmt( "{ sizeof(\"%s\"), \"%s\" },\n", code, code );
|
||||
char const* code = node->string;
|
||||
|
||||
string_append_fmt( & enum_entries, "CT_%s,\n", code );
|
||||
string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", code, code );
|
||||
}
|
||||
|
||||
CodeEnum enum_code = parse_enum(gen::token_fmt_impl((3 + 1) / 2, "entries", (StrC)enum_entries, "enum Type : u32 { <entries> NumTypes };"));
|
||||
CodeEnum enum_code = parse_enum(gen::token_fmt_impl((3 + 1) / 2, "entries", string_to_strc(enum_entries),
|
||||
"enum CodeType_Def : u32 { <entries> CT_NumTypes };"
|
||||
));
|
||||
|
||||
#pragma push_macro("local_persist")
|
||||
#undef local_persist
|
||||
CodeFn to_str = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
|
||||
StrC to_str( Type type )
|
||||
CodeFn to_str = parse_function( token_fmt( "entries", string_to_strc(to_str_entries), stringize(
|
||||
inline
|
||||
StrC to_str( CodeType type )
|
||||
{
|
||||
local_persist
|
||||
StrC lookup[] {
|
||||
@ -47,18 +51,19 @@ CodeBody gen_ecode( char const* path )
|
||||
)));
|
||||
#pragma pop_macro("local_persist")
|
||||
|
||||
CodeNS nspace = def_namespace( name(ECode), def_namespace_body( args( enum_code, to_str ) ) );
|
||||
CodeUsing code_t = def_using( name(CodeT), def_type( name(ECode::Type) ) );
|
||||
//CodeNS nspace = def_namespace( name(ECode), def_namespace_body( args( enum_code, to_str ) ) );
|
||||
//CodeUsing code_t = def_using( name(CodeT), def_type( name(ECode::Type) ) );
|
||||
CodeTypedef code_t = parse_typedef(code(typedef enum CodeType_Def CodeType; ));
|
||||
|
||||
return def_global_body( args( nspace, code_t, fmt_newline ) );
|
||||
return def_global_body( args( enum_code, code_t, to_str, fmt_newline ) );
|
||||
}
|
||||
|
||||
CodeBody gen_eoperator( char const* path )
|
||||
{
|
||||
char scratch_mem[kilobytes(4)];
|
||||
Arena scratch = Arena::init_from_memory( scratch_mem, sizeof(scratch_mem) );
|
||||
Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) );
|
||||
|
||||
file_read_contents( scratch, zero_terminate, path );
|
||||
file_read_contents( arena_allocator_info(& scratch), zero_terminate, path );
|
||||
|
||||
CSV_Object csv_nodes;
|
||||
csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false );
|
||||
@ -66,20 +71,20 @@ CodeBody gen_eoperator( char const* path )
|
||||
Array<ADT_Node> enum_strs = csv_nodes.nodes[0].nodes;
|
||||
Array<ADT_Node> str_strs = csv_nodes.nodes[1].nodes;
|
||||
|
||||
String enum_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
|
||||
String to_str_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
|
||||
String enum_entries = string_make_reserve( GlobalAllocator, kilobytes(1) );
|
||||
String to_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) );
|
||||
|
||||
for (uw idx = 0; idx < enum_strs.num(); idx++)
|
||||
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;
|
||||
|
||||
enum_entries.append_fmt( "%s,\n", enum_str );
|
||||
to_str_entries.append_fmt( "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
||||
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);
|
||||
}
|
||||
|
||||
CodeEnum enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, stringize(
|
||||
enum Type : u32
|
||||
CodeEnum enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize(
|
||||
enum Operator_Def : u32
|
||||
{
|
||||
<entries>
|
||||
NumOps
|
||||
@ -88,8 +93,9 @@ CodeBody gen_eoperator( char const* path )
|
||||
|
||||
#pragma push_macro("local_persist")
|
||||
#undef local_persist
|
||||
CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, stringize(
|
||||
StrC to_str( Type op )
|
||||
CodeFn to_str = parse_function(token_fmt("entries", string_to_strc(to_str_entries), stringize(
|
||||
inline
|
||||
StrC to_str( Operator op )
|
||||
{
|
||||
local_persist
|
||||
StrC lookup[] {
|
||||
@ -101,19 +107,19 @@ CodeBody gen_eoperator( char const* path )
|
||||
)));
|
||||
#pragma pop_macro("local_persist")
|
||||
|
||||
CodeNS nspace = def_namespace( name(EOperator), def_namespace_body( args( enum_code, to_str ) ) );
|
||||
//CodeNS nspace = def_namespace( name(EOperator), def_namespace_body( args( enum_code, to_str ) ) );
|
||||
//CodeUsing operator_t = def_using( name(OperatorT), def_type( name(EOperator::Type) ) );
|
||||
CodeTypedef operator_t = parse_typedef(code( typedef enum Operator_Def Operator; ));
|
||||
|
||||
CodeUsing operator_t = def_using( name(OperatorT), def_type( name(EOperator::Type) ) );
|
||||
|
||||
return def_global_body( args( nspace, operator_t, fmt_newline ) );
|
||||
return def_global_body( args( enum_code, operator_t, to_str, fmt_newline ) );
|
||||
}
|
||||
|
||||
CodeBody gen_especifier( char const* path )
|
||||
{
|
||||
char scratch_mem[kilobytes(4)];
|
||||
Arena scratch = Arena::init_from_memory( scratch_mem, sizeof(scratch_mem) );
|
||||
Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) );
|
||||
|
||||
file_read_contents( scratch, zero_terminate, path );
|
||||
file_read_contents( arena_allocator_info(& scratch), zero_terminate, path );
|
||||
|
||||
CSV_Object csv_nodes;
|
||||
csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false );
|
||||
@ -121,30 +127,31 @@ CodeBody gen_especifier( char const* path )
|
||||
Array<ADT_Node> enum_strs = csv_nodes.nodes[0].nodes;
|
||||
Array<ADT_Node> str_strs = csv_nodes.nodes[1].nodes;
|
||||
|
||||
String enum_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
|
||||
String to_str_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
|
||||
String enum_entries = string_make_reserve( GlobalAllocator, kilobytes(1) );
|
||||
String to_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) );
|
||||
|
||||
for (uw idx = 0; idx < enum_strs.num(); idx++)
|
||||
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;
|
||||
|
||||
enum_entries.append_fmt( "%s,\n", enum_str );
|
||||
to_str_entries.append_fmt( "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
||||
string_append_fmt( & enum_entries, "Spec_%s,\n", enum_str );
|
||||
string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
||||
}
|
||||
|
||||
CodeEnum enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, stringize(
|
||||
enum Type : u32
|
||||
CodeEnum enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize(
|
||||
enum Specifier_Def : u32
|
||||
{
|
||||
<entries>
|
||||
NumSpecifiers
|
||||
Spec_NumSpecifiers
|
||||
};
|
||||
)));
|
||||
|
||||
CodeFn is_trailing = parse_function(token_fmt("specifier", (StrC)to_str_entries, stringize(
|
||||
bool is_trailing( Type specifier )
|
||||
CodeFn is_trailing = parse_function(token_fmt("specifier", string_to_strc(to_str_entries), stringize(
|
||||
inline
|
||||
bool is_trailing( Specifier specifier )
|
||||
{
|
||||
return specifier > Virtual;
|
||||
return specifier > Spec_Virtual;
|
||||
}
|
||||
)));
|
||||
|
||||
@ -158,8 +165,9 @@ CodeBody gen_especifier( char const* path )
|
||||
#undef do_once_end
|
||||
#undef forceinline
|
||||
#undef neverinline
|
||||
CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, stringize(
|
||||
StrC to_str( Type type )
|
||||
CodeFn to_str = parse_function(token_fmt("entries", string_to_strc(to_str_entries), stringize(
|
||||
inline
|
||||
StrC to_str( Specifier type )
|
||||
{
|
||||
local_persist
|
||||
StrC lookup[] {
|
||||
@ -170,15 +178,16 @@ CodeBody gen_especifier( char const* path )
|
||||
}
|
||||
)));
|
||||
|
||||
CodeFn to_type = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
|
||||
Type to_type( StrC str )
|
||||
CodeFn to_type = parse_function( token_fmt( "entries", string_to_strc(to_str_entries), stringize(
|
||||
inline
|
||||
Specifier to_specifier( StrC str )
|
||||
{
|
||||
local_persist
|
||||
u32 keymap[ NumSpecifiers ];
|
||||
u32 keymap[ Spec_NumSpecifiers ];
|
||||
do_once_start
|
||||
for ( u32 index = 0; index < NumSpecifiers; index++ )
|
||||
for ( u32 index = 0; index < Spec_NumSpecifiers; index++ )
|
||||
{
|
||||
StrC enum_str = to_str( (Type)index );
|
||||
StrC enum_str = to_str( (Specifier)index );
|
||||
|
||||
// We subtract 1 to remove the null terminator
|
||||
// This is because the tokens lexed are not null terminated.
|
||||
@ -188,13 +197,13 @@ CodeBody gen_especifier( char const* path )
|
||||
|
||||
u32 hash = crc32( str.Ptr, str.Len );
|
||||
|
||||
for ( u32 index = 0; index < NumSpecifiers; index++ )
|
||||
for ( u32 index = 0; index < Spec_NumSpecifiers; index++ )
|
||||
{
|
||||
if ( keymap[index] == hash )
|
||||
return (Type)index;
|
||||
return (Specifier)index;
|
||||
}
|
||||
|
||||
return Invalid;
|
||||
return Spec_Invalid;
|
||||
}
|
||||
)));
|
||||
#pragma pop_macro("local_persist")
|
||||
@ -203,24 +212,26 @@ CodeBody gen_especifier( char const* path )
|
||||
#pragma pop_macro("forceinline")
|
||||
#pragma pop_macro("neverinline")
|
||||
|
||||
CodeNS nspace = def_namespace( name(ESpecifier), def_namespace_body( args( enum_code, is_trailing, to_str, to_type ) ) );
|
||||
//CodeNS nspace = def_namespace( name(ESpecifier), def_namespace_body( args( enum_code, is_trailing, to_str, to_type ) ) );
|
||||
//CodeUsing specifier_t = def_using( name(SpecifierT), def_type( name(ESpecifier::Type) ) );
|
||||
CodeTypedef specifier_t = parse_typedef( code(typedef enum Specifier_Def Specifier; ));
|
||||
|
||||
CodeUsing specifier_t = def_using( name(SpecifierT), def_type( name(ESpecifier::Type) ) );
|
||||
|
||||
return def_global_body( args( nspace, specifier_t, fmt_newline ) );
|
||||
return def_global_body( args( enum_code, specifier_t, is_trailing, to_str, to_type, fmt_newline ) );
|
||||
}
|
||||
|
||||
CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
|
||||
{
|
||||
char scratch_mem[kilobytes(16)];
|
||||
Arena scratch = Arena::init_from_memory( scratch_mem, sizeof(scratch_mem) );
|
||||
Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) );
|
||||
|
||||
FileContents enum_content = file_read_contents( scratch, zero_terminate, etok_path );
|
||||
AllocatorInfo scratch_info = arena_allocator_info(& scratch);
|
||||
|
||||
FileContents enum_content = file_read_contents( scratch_info, zero_terminate, etok_path );
|
||||
|
||||
CSV_Object csv_enum_nodes;
|
||||
csv_parse( &csv_enum_nodes, rcast(char*, enum_content.data), GlobalAllocator, false );
|
||||
|
||||
FileContents attrib_content = file_read_contents( scratch, zero_terminate, attr_path );
|
||||
FileContents attrib_content = file_read_contents( scratch_info, zero_terminate, attr_path );
|
||||
|
||||
CSV_Object csv_attr_nodes;
|
||||
csv_parse( &csv_attr_nodes, rcast(char*, attrib_content.data), GlobalAllocator, false );
|
||||
@ -230,48 +241,48 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
|
||||
Array<ADT_Node> attribute_strs = csv_attr_nodes.nodes[0].nodes;
|
||||
Array<ADT_Node> attribute_str_strs = csv_attr_nodes.nodes[1].nodes;
|
||||
|
||||
String enum_entries = String::make_reserve( GlobalAllocator, kilobytes(2) );
|
||||
String to_str_entries = String::make_reserve( GlobalAllocator, kilobytes(4) );
|
||||
String attribute_entries = String::make_reserve( GlobalAllocator, kilobytes(2) );
|
||||
String to_str_attributes = String::make_reserve( GlobalAllocator, kilobytes(4) );
|
||||
String attribute_define_entries = String::make_reserve( GlobalAllocator, kilobytes(4) );
|
||||
String enum_entries = string_make_reserve( GlobalAllocator, kilobytes(2) );
|
||||
String to_str_entries = string_make_reserve( GlobalAllocator, kilobytes(4) );
|
||||
String attribute_entries = string_make_reserve( GlobalAllocator, kilobytes(2) );
|
||||
String to_str_attributes = string_make_reserve( GlobalAllocator, kilobytes(4) );
|
||||
String attribute_define_entries = string_make_reserve( GlobalAllocator, kilobytes(4) );
|
||||
|
||||
for (uw idx = 0; idx < enum_strs.num(); idx++)
|
||||
for (usize idx = 0; idx < array_num(enum_strs); idx++)
|
||||
{
|
||||
char const* enum_str = enum_strs[idx].string;
|
||||
char const* entry_to_str = enum_str_strs [idx].string;
|
||||
|
||||
enum_entries.append_fmt( "%s,\n", enum_str );
|
||||
to_str_entries.append_fmt( "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
||||
string_append_fmt( & enum_entries, "Tok_%s,\n", enum_str );
|
||||
string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
||||
}
|
||||
|
||||
for ( uw idx = 0; idx < attribute_strs.num(); idx++ )
|
||||
for ( usize idx = 0; idx < array_num(attribute_strs); idx++ )
|
||||
{
|
||||
char const* attribute_str = attribute_strs[idx].string;
|
||||
char const* entry_to_str = attribute_str_strs [idx].string;
|
||||
|
||||
attribute_entries.append_fmt( "Attribute_%s,\n", attribute_str );
|
||||
to_str_attributes.append_fmt( "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
||||
attribute_define_entries.append_fmt( "Entry( Attribute_%s, \"%s\" )", attribute_str, entry_to_str );
|
||||
string_append_fmt( & attribute_entries, "Tok_Attribute_%s,\n", attribute_str );
|
||||
string_append_fmt( & to_str_attributes, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
||||
string_append_fmt( & attribute_define_entries, "Entry( Tok_Attribute_%s, \"%s\" )", attribute_str, entry_to_str );
|
||||
|
||||
if ( idx < attribute_strs.num() - 1 )
|
||||
attribute_define_entries.append( " \\\n");
|
||||
if ( idx < array_num(attribute_strs) - 1 )
|
||||
string_append_strc( & attribute_define_entries, txt(" \\\n"));
|
||||
else
|
||||
attribute_define_entries.append( "\n");
|
||||
string_append_strc( & attribute_define_entries, txt("\n"));
|
||||
}
|
||||
|
||||
#pragma push_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
|
||||
#undef GEN_DEFINE_ATTRIBUTE_TOKENS
|
||||
CodeDefine attribute_entires_def = def_define( name(GEN_DEFINE_ATTRIBUTE_TOKENS), attribute_define_entries );
|
||||
CodeDefine attribute_entires_def = def_define( name(GEN_DEFINE_ATTRIBUTE_TOKENS), string_to_strc(attribute_define_entries) );
|
||||
#pragma pop_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
|
||||
|
||||
// We cannot parse this enum, it has Attribute names as enums
|
||||
CodeEnum enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, "attribute_toks", (StrC)attribute_entries, stringize(
|
||||
enum Type : u32
|
||||
CodeEnum enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), "attribute_toks", string_to_strc(attribute_entries), stringize(
|
||||
enum TokType_Def : u32
|
||||
{
|
||||
<entries>
|
||||
<attribute_toks>
|
||||
NumTokens
|
||||
Tok_NumTokens
|
||||
};
|
||||
)));
|
||||
|
||||
@ -281,8 +292,9 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
|
||||
#undef local_persist
|
||||
#undef do_once_start
|
||||
#undef do_once_end
|
||||
CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, "attribute_toks", (StrC)to_str_attributes, stringize(
|
||||
StrC to_str( Type type )
|
||||
CodeFn to_str = parse_function(token_fmt("entries", string_to_strc(to_str_entries), "attribute_toks", string_to_strc(to_str_attributes), stringize(
|
||||
inline
|
||||
StrC to_str( TokType type )
|
||||
{
|
||||
local_persist
|
||||
StrC lookup[] {
|
||||
@ -294,15 +306,16 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
|
||||
}
|
||||
)));
|
||||
|
||||
CodeFn to_type = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
|
||||
Type to_type( StrC str )
|
||||
CodeFn to_type = parse_function( token_fmt( "entries", string_to_strc(to_str_entries), stringize(
|
||||
inline
|
||||
TokType to_toktype( StrC str )
|
||||
{
|
||||
local_persist
|
||||
u32 keymap[ NumTokens ];
|
||||
u32 keymap[ Tok_NumTokens ];
|
||||
do_once_start
|
||||
for ( u32 index = 0; index < NumTokens; index++ )
|
||||
for ( u32 index = 0; index < Tok_NumTokens; index++ )
|
||||
{
|
||||
StrC enum_str = to_str( (Type)index );
|
||||
StrC enum_str = to_str( (TokType)index );
|
||||
|
||||
// We subtract 1 to remove the null terminator
|
||||
// This is because the tokens lexed are not null terminated.
|
||||
@ -312,92 +325,56 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
|
||||
|
||||
u32 hash = crc32( str.Ptr, str.Len );
|
||||
|
||||
for ( u32 index = 0; index < NumTokens; index++ )
|
||||
for ( u32 index = 0; index < Tok_NumTokens; index++ )
|
||||
{
|
||||
if ( keymap[index] == hash )
|
||||
return (Type)index;
|
||||
return (TokType)index;
|
||||
}
|
||||
|
||||
return Invalid;
|
||||
return Tok_Invalid;
|
||||
}
|
||||
)));
|
||||
#pragma pop_macro("local_persist")
|
||||
#pragma pop_macro("do_once_start")
|
||||
#pragma pop_macro("do_once_end")
|
||||
|
||||
CodeNS nspace = def_namespace( name(ETokType), def_namespace_body( args( attribute_entires_def, enum_code, to_str, to_type ) ) );
|
||||
CodeUsing td_toktype = def_using( name(TokType), def_type( name(ETokType::Type) ) );
|
||||
//CodeNS nspace = def_namespace( name(ETokType), def_namespace_body( args( attribute_entires_def, enum_code, to_str, to_type ) ) );
|
||||
CodeTypedef td_toktype = parse_typedef( code( typedef enum TokType_Def TokType; ));
|
||||
|
||||
return def_global_body( args( nspace, td_toktype ) );
|
||||
return def_global_body( args(
|
||||
attribute_entires_def,
|
||||
enum_code,
|
||||
td_toktype,
|
||||
to_str,
|
||||
to_type
|
||||
));
|
||||
}
|
||||
|
||||
CodeBody gen_ast_inlines()
|
||||
{
|
||||
#pragma push_macro("GEN_NS")
|
||||
#pragma push_macro("rcast")
|
||||
#pragma push_macro("log_failure")
|
||||
#pragma push_macro("CodeInvalid")
|
||||
#undef GEN_NS
|
||||
#undef rcast
|
||||
#undef log_failure
|
||||
#undef CodeInvalid
|
||||
char const* code_impl_tmpl = stringize(
|
||||
\n
|
||||
char const* <typename>::debug_str()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
return "Code::debug_str: AST is null!";
|
||||
|
||||
return rcast(AST*, ast)->debug_str();
|
||||
}
|
||||
Code <typename>::duplicate()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure("Code::duplicate: Cannot duplicate code, AST is null!");
|
||||
return Code::Invalid;
|
||||
}
|
||||
|
||||
return { rcast(AST*, ast)->duplicate() };
|
||||
}
|
||||
bool <typename>::is_equal( Code other )
|
||||
{
|
||||
if ( ast == nullptr || other.ast == nullptr )
|
||||
{
|
||||
// Just check if they're both null.
|
||||
return rcast(AST*, ast) == other.ast;
|
||||
}
|
||||
return rcast(AST*, ast)->is_equal( other.ast );
|
||||
}
|
||||
bool <typename>::is_valid()
|
||||
{
|
||||
return (AST*) ast != nullptr && rcast( AST*, ast)->Type != CodeT::Invalid;
|
||||
}
|
||||
void <typename>::set_global()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure("Code::set_global: Cannot set code as global, AST is null!");
|
||||
return;
|
||||
}
|
||||
|
||||
rcast(AST*, ast)->Parent = Code::Global.ast;
|
||||
}
|
||||
inline
|
||||
<typename>& <typename>::operator =( Code other )
|
||||
{
|
||||
if ( other.ast && other->Parent )
|
||||
{
|
||||
ast = rcast( decltype(ast), other.ast->duplicate() );
|
||||
rcast( AST*, ast)->Parent = nullptr;
|
||||
ast = rcast( decltype(ast), GEN_NS duplicate(other).ast);
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
|
||||
ast = rcast( decltype(ast), other.ast );
|
||||
return *this;
|
||||
}
|
||||
bool <typename>::operator ==( Code other )
|
||||
{
|
||||
return (AST*) ast == other.ast;
|
||||
}
|
||||
bool <typename>::operator !=( Code other )
|
||||
{
|
||||
return (AST*) ast != other.ast;
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return * this;
|
||||
}
|
||||
inline
|
||||
<typename>::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
@ -405,14 +382,12 @@ CodeBody gen_ast_inlines()
|
||||
);
|
||||
|
||||
char const* codetype_impl_tmpl = stringize(
|
||||
AST* Code<typename>::raw()
|
||||
{
|
||||
return rcast( AST*, ast );
|
||||
}
|
||||
inline
|
||||
Code<typename>::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
inline
|
||||
AST_<typename>* Code<typename>::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
@ -424,6 +399,8 @@ CodeBody gen_ast_inlines()
|
||||
}
|
||||
\n
|
||||
);
|
||||
#pragma pop_macro("GEN_NS")
|
||||
#pragma pop_macro("CodeInvalid")
|
||||
|
||||
CodeBody impl_code = parse_global_body( token_fmt( "typename", StrC name(Code), code_impl_tmpl ));
|
||||
CodeBody impl_code_body = parse_global_body( token_fmt( "typename", StrC name(CodeBody), code_impl_tmpl ));
|
||||
@ -449,43 +426,38 @@ CodeBody gen_ast_inlines()
|
||||
CodeBody impl_code_specs = parse_global_body( token_fmt( "typename", StrC name(CodeSpecifiers), code_impl_tmpl ));
|
||||
CodeBody impl_code_struct = parse_global_body( token_fmt( "typename", StrC name(CodeStruct), code_impl_tmpl ));
|
||||
CodeBody impl_code_tmpl = parse_global_body( token_fmt( "typename", StrC name(CodeTemplate), code_impl_tmpl ));
|
||||
CodeBody impl_code_type = parse_global_body( token_fmt( "typename", StrC name(CodeType), code_impl_tmpl ));
|
||||
CodeBody impl_code_type = parse_global_body( token_fmt( "typename", StrC name(CodeTypename), code_impl_tmpl ));
|
||||
CodeBody impl_code_typedef = parse_global_body( token_fmt( "typename", StrC name(CodeTypedef), code_impl_tmpl ));
|
||||
CodeBody impl_code_union = parse_global_body( token_fmt( "typename", StrC name(CodeUnion), code_impl_tmpl ));
|
||||
CodeBody impl_code_using = parse_global_body( token_fmt( "typename", StrC name(CodeUsing), code_impl_tmpl ));
|
||||
CodeBody impl_code_var = parse_global_body( token_fmt( "typename", StrC name(CodeVar), code_impl_tmpl ));
|
||||
|
||||
impl_code_attr. append( parse_global_body( token_fmt( "typename", StrC name(Attributes), codetype_impl_tmpl )));
|
||||
impl_code_cmt. append( parse_global_body( token_fmt( "typename", StrC name(Comment), codetype_impl_tmpl )));
|
||||
impl_code_constr. append( parse_global_body( token_fmt( "typename", StrC name(Constructor), codetype_impl_tmpl )));
|
||||
impl_code_define. append( parse_global_body( token_fmt( "typename", StrC name(Define), codetype_impl_tmpl )));
|
||||
impl_code_destruct.append( parse_global_body( token_fmt( "typename", StrC name(Destructor), codetype_impl_tmpl )));
|
||||
impl_code_enum. append( parse_global_body( token_fmt( "typename", StrC name(Enum), codetype_impl_tmpl )));
|
||||
impl_code_exec. append( parse_global_body( token_fmt( "typename", StrC name(Exec), codetype_impl_tmpl )));
|
||||
impl_code_extern. append( parse_global_body( token_fmt( "typename", StrC name(Extern), codetype_impl_tmpl )));
|
||||
impl_code_include. append( parse_global_body( token_fmt( "typename", StrC name(Include), codetype_impl_tmpl )));
|
||||
impl_code_friend. append( parse_global_body( token_fmt( "typename", StrC name(Friend), codetype_impl_tmpl )));
|
||||
impl_code_fn. append( parse_global_body( token_fmt( "typename", StrC name(Fn), codetype_impl_tmpl )));
|
||||
impl_code_module. append( parse_global_body( token_fmt( "typename", StrC name(Module), codetype_impl_tmpl )));
|
||||
impl_code_ns. append( parse_global_body( token_fmt( "typename", StrC name(NS), codetype_impl_tmpl )));
|
||||
impl_code_op. append( parse_global_body( token_fmt( "typename", StrC name(Operator), codetype_impl_tmpl )));
|
||||
impl_code_opcast. append( parse_global_body( token_fmt( "typename", StrC name(OpCast), codetype_impl_tmpl )));
|
||||
impl_code_pragma . append( parse_global_body( token_fmt( "typename", StrC name(Pragma), codetype_impl_tmpl )));
|
||||
impl_code_precond. append( parse_global_body( token_fmt( "typename", StrC name(PreprocessCond), codetype_impl_tmpl )));
|
||||
impl_code_tmpl. append( parse_global_body( token_fmt( "typename", StrC name(Template), codetype_impl_tmpl )));
|
||||
impl_code_type. append( parse_global_body( token_fmt( "typename", StrC name(Type), codetype_impl_tmpl )));
|
||||
impl_code_typedef. append( parse_global_body( token_fmt( "typename", StrC name(Typedef), codetype_impl_tmpl )));
|
||||
impl_code_union. append( parse_global_body( token_fmt( "typename", StrC name(Union), codetype_impl_tmpl )));
|
||||
impl_code_using. append( parse_global_body( token_fmt( "typename", StrC name(Using), codetype_impl_tmpl )));
|
||||
impl_code_var. append( parse_global_body( token_fmt( "typename", StrC name(Var), codetype_impl_tmpl )));
|
||||
append(impl_code_attr, parse_global_body( token_fmt( "typename", StrC name(Attributes), codetype_impl_tmpl )));
|
||||
append(impl_code_cmt, parse_global_body( token_fmt( "typename", StrC name(Comment), codetype_impl_tmpl )));
|
||||
append(impl_code_constr, parse_global_body( token_fmt( "typename", StrC name(Constructor), codetype_impl_tmpl )));
|
||||
append(impl_code_define, parse_global_body( token_fmt( "typename", StrC name(Define), codetype_impl_tmpl )));
|
||||
append(impl_code_destruct, parse_global_body( token_fmt( "typename", StrC name(Destructor), codetype_impl_tmpl )));
|
||||
append(impl_code_enum, parse_global_body( token_fmt( "typename", StrC name(Enum), codetype_impl_tmpl )));
|
||||
append(impl_code_exec, parse_global_body( token_fmt( "typename", StrC name(Exec), codetype_impl_tmpl )));
|
||||
append(impl_code_extern, parse_global_body( token_fmt( "typename", StrC name(Extern), codetype_impl_tmpl )));
|
||||
append(impl_code_include, parse_global_body( token_fmt( "typename", StrC name(Include), codetype_impl_tmpl )));
|
||||
append(impl_code_friend, parse_global_body( token_fmt( "typename", StrC name(Friend), codetype_impl_tmpl )));
|
||||
append(impl_code_fn, parse_global_body( token_fmt( "typename", StrC name(Fn), codetype_impl_tmpl )));
|
||||
append(impl_code_module, parse_global_body( token_fmt( "typename", StrC name(Module), codetype_impl_tmpl )));
|
||||
append(impl_code_ns, parse_global_body( token_fmt( "typename", StrC name(NS), codetype_impl_tmpl )));
|
||||
append(impl_code_op, parse_global_body( token_fmt( "typename", StrC name(Operator), codetype_impl_tmpl )));
|
||||
append(impl_code_opcast, parse_global_body( token_fmt( "typename", StrC name(OpCast), codetype_impl_tmpl )));
|
||||
append(impl_code_pragma, parse_global_body( token_fmt( "typename", StrC name(Pragma), codetype_impl_tmpl )));
|
||||
append(impl_code_precond, parse_global_body( token_fmt( "typename", StrC name(PreprocessCond), codetype_impl_tmpl )));
|
||||
append(impl_code_tmpl, parse_global_body( token_fmt( "typename", StrC name(Template), codetype_impl_tmpl )));
|
||||
append(impl_code_type, parse_global_body( token_fmt( "typename", StrC name(Typename), codetype_impl_tmpl )));
|
||||
append(impl_code_typedef, parse_global_body( token_fmt( "typename", StrC name(Typedef), codetype_impl_tmpl )));
|
||||
append(impl_code_union, parse_global_body( token_fmt( "typename", StrC name(Union), codetype_impl_tmpl )));
|
||||
append(impl_code_using, parse_global_body( token_fmt( "typename", StrC name(Using), codetype_impl_tmpl )));
|
||||
append(impl_code_var, parse_global_body( token_fmt( "typename", StrC name(Var), codetype_impl_tmpl )));
|
||||
|
||||
char const* cast_tmpl = stringize(
|
||||
AST::operator Code<typename>()
|
||||
{
|
||||
return { rcast( AST_<typename>*, this ) };
|
||||
}
|
||||
|
||||
Code::operator Code<typename>() const
|
||||
inline Code::operator Code<typename>() const
|
||||
{
|
||||
return { (AST_<typename>*) ast };
|
||||
}
|
||||
@ -514,7 +486,7 @@ CodeBody gen_ast_inlines()
|
||||
CodeBody impl_cast_specs = parse_global_body( token_fmt( "typename", StrC name(Specifiers), cast_tmpl ));
|
||||
CodeBody impl_cast_struct = parse_global_body( token_fmt( "typename", StrC name(Struct), cast_tmpl ));
|
||||
CodeBody impl_cast_tmpl = parse_global_body( token_fmt( "typename", StrC name(Template), cast_tmpl ));
|
||||
CodeBody impl_cast_type = parse_global_body( token_fmt( "typename", StrC name(Type), cast_tmpl ));
|
||||
CodeBody impl_cast_type = parse_global_body( token_fmt( "typename", StrC name(Typename), cast_tmpl ));
|
||||
CodeBody impl_cast_typedef = parse_global_body( token_fmt( "typename", StrC name(Typedef), cast_tmpl ));
|
||||
CodeBody impl_cast_union = parse_global_body( token_fmt( "typename", StrC name(Union), cast_tmpl ));
|
||||
CodeBody impl_cast_using = parse_global_body( token_fmt( "typename", StrC name(Using), cast_tmpl ));
|
||||
|
10
project/helpers/member_proc_support.hpp
Normal file
10
project/helpers/member_proc_support.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "gen.hpp"
|
||||
|
||||
GEN_NS_BEGIN
|
||||
#include "dependencies/parsing.hpp"
|
||||
GEN_NS_END
|
||||
|
||||
using namespace gen;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#if __clang__
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if __GNUC__
|
||||
#ifdef __GNUC__
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user