mirror of
https://github.com/Ed94/gencpp.git
synced 2024-12-22 07:44:45 -08:00
Compare commits
10 Commits
9e88cb8724
...
c38b077c37
Author | SHA1 | Date | |
---|---|---|---|
c38b077c37 | |||
f9b5029e64 | |||
2b24511f7d | |||
5cd69e1742 | |||
007bfa0cb0 | |||
37c33ffb3e | |||
937235b776 | |||
f9c21ebc04 | |||
fec709cc76 | |||
80cb3f4eca |
@ -25,6 +25,8 @@ This library was written in a subset of C++ where the following are not used at
|
|||||||
* Exceptions
|
* Exceptions
|
||||||
|
|
||||||
Polymorphic & Member-functions are used as an ergonomic choice, along with a conserative use of operator overloads.
|
Polymorphic & Member-functions are used as an ergonomic choice, along with a conserative use of operator overloads.
|
||||||
|
The base library itself does not use anything but C-like features to allow for generating a derviative compatiable with C (WIP).
|
||||||
|
|
||||||
There are only 4 template definitions in the entire library. (`Array<Type>`, `Hashtable<Type>`, `swap<Type>`, and `AST/Code::cast<Type>`)
|
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:
|
Two generic templated containers are used throughout the library:
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
||||||
#define GEN_EXPOSE_BACKEND
|
#define GEN_EXPOSE_BACKEND
|
||||||
#define GEN_SUPPORT_CPP_MEMBER_FEATURES 1
|
#define GEN_SUPPORT_CPP_MEMBER_FEATURES 1
|
||||||
|
#define GEN_SUPPORT_CPP_REFERENCES 1
|
||||||
#include "../project/gen.cpp"
|
#include "../project/gen.cpp"
|
||||||
|
|
||||||
#include "helpers/push_ignores.inline.hpp"
|
#include "helpers/push_ignores.inline.hpp"
|
||||||
@ -135,26 +136,40 @@ int gen_main()
|
|||||||
case ECode::Using:
|
case ECode::Using:
|
||||||
{
|
{
|
||||||
log_fmt("REPLACE THIS MANUALLY: %S\n", entry->Name);
|
log_fmt("REPLACE THIS MANUALLY: %S\n", entry->Name);
|
||||||
CodeUsing using_ver = entry.cast<CodeUsing>();
|
CodeUsing using_ver = entry.code_cast<CodeUsing>();
|
||||||
CodeTypedef typedef_ver = def_typedef(using_ver->Name, using_ver->UnderlyingType);
|
CodeTypedef typedef_ver = def_typedef(using_ver->Name, using_ver->UnderlyingType);
|
||||||
|
|
||||||
memory.append(typedef_ver);
|
memory.append(typedef_ver);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ECode::Function_Fwd:
|
||||||
|
{
|
||||||
|
CodeFn fn = entry.code_cast<CodeFn>();
|
||||||
|
if ( fn->Name.is_equal(txt("free")) )
|
||||||
|
{
|
||||||
|
fn->Name = get_cached_string(txt("gen_free_ptr"));
|
||||||
|
}
|
||||||
|
memory.append(entry);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case ECode::Function:
|
case ECode::Function:
|
||||||
{
|
{
|
||||||
CodeFn fn = entry.cast<CodeFn>();
|
CodeFn fn = entry.code_cast<CodeFn>();
|
||||||
s32 constexpr_found = fn->Specs.remove( ESpecifier::Constexpr );
|
s32 constexpr_found = fn->Specs.remove( ESpecifier::Constexpr );
|
||||||
if (constexpr_found > -1) {
|
if (constexpr_found > -1) {
|
||||||
log_fmt("Found constexpr: %S\n", entry->to_string());
|
log_fmt("Found constexpr: %S\n", entry->to_string());
|
||||||
fn->Specs.append(ESpecifier::Inline);
|
fn->Specs.append(ESpecifier::Inline);
|
||||||
}
|
}
|
||||||
|
if ( fn->Name.is_equal(txt("free")) )
|
||||||
|
{
|
||||||
|
fn->Name = get_cached_string(txt("gen_free_ptr"));
|
||||||
|
}
|
||||||
memory.append(entry);
|
memory.append(entry);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ECode::Template:
|
case ECode::Template:
|
||||||
{
|
{
|
||||||
CodeTemplate tmpl = entry.cast<CodeTemplate>();
|
CodeTemplate tmpl = entry.code_cast<CodeTemplate>();
|
||||||
if ( tmpl->Declaration->Name.contains(txt("swap")))
|
if ( tmpl->Declaration->Name.contains(txt("swap")))
|
||||||
{
|
{
|
||||||
CodeBody macro_swap = parse_global_body( txt(R"(
|
CodeBody macro_swap = parse_global_body( txt(R"(
|
||||||
@ -297,7 +312,7 @@ int gen_main()
|
|||||||
{
|
{
|
||||||
if ( entry->Name.is_equal(txt("String")) )
|
if ( entry->Name.is_equal(txt("String")) )
|
||||||
{
|
{
|
||||||
CodeTypedef c_def = parse_typedef(code( typedef Type* String; ));
|
CodeTypedef c_def = parse_typedef(code( typedef char* String; ));
|
||||||
strings.append(c_def);
|
strings.append(c_def);
|
||||||
strings.append(fmt_newline);
|
strings.append(fmt_newline);
|
||||||
++ entry;
|
++ entry;
|
||||||
@ -307,6 +322,29 @@ int gen_main()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ECode::Struct:
|
||||||
|
{
|
||||||
|
CodeBody body = entry->Body->operator CodeBody();
|
||||||
|
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 ECode::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 = rcast(AST*, new_body.ast);
|
||||||
|
strings.append(entry);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
strings.append(entry);
|
strings.append(entry);
|
||||||
break;
|
break;
|
||||||
@ -316,8 +354,8 @@ int gen_main()
|
|||||||
|
|
||||||
Code filesystem = scan_file( project_dir "dependencies/filesystem.hpp" );
|
Code filesystem = scan_file( project_dir "dependencies/filesystem.hpp" );
|
||||||
Code timing = scan_file( project_dir "dependencies/timing.hpp" );
|
Code timing = scan_file( project_dir "dependencies/timing.hpp" );
|
||||||
header.print( filesystem );
|
// header.print( filesystem );
|
||||||
header.print( timing );
|
// header.print( timing );
|
||||||
|
|
||||||
header.print_fmt( "\nGEN_NS_END\n" );
|
header.print_fmt( "\nGEN_NS_END\n" );
|
||||||
header.print_fmt( roll_own_dependencies_guard_end );
|
header.print_fmt( roll_own_dependencies_guard_end );
|
||||||
@ -335,6 +373,7 @@ int gen_main()
|
|||||||
CodeBody especifier = gen_especifier( project_dir "enums/ESpecifier.csv" );
|
CodeBody especifier = gen_especifier( project_dir "enums/ESpecifier.csv" );
|
||||||
CodeBody ast_inlines = gen_ast_inlines();
|
CodeBody ast_inlines = gen_ast_inlines();
|
||||||
|
|
||||||
|
#if 0
|
||||||
header.print_fmt("#pragma region Types\n");
|
header.print_fmt("#pragma region Types\n");
|
||||||
header.print( types );
|
header.print( types );
|
||||||
header.print( fmt_newline );
|
header.print( fmt_newline );
|
||||||
@ -345,6 +384,7 @@ int gen_main()
|
|||||||
header.print( dump_to_scratch_and_retireve( especifier ));
|
header.print( dump_to_scratch_and_retireve( especifier ));
|
||||||
header.print( fmt_newline );
|
header.print( fmt_newline );
|
||||||
header.print_fmt("#pragma endregion Types\n\n");
|
header.print_fmt("#pragma endregion Types\n\n");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
header.print( pop_ignores );
|
header.print( pop_ignores );
|
||||||
|
@ -20,7 +20,7 @@ CodeBody gen_fixed_arenas()
|
|||||||
inline
|
inline
|
||||||
void fixed_arena_init_<Name>(FixedArena_<Name>* result) {
|
void fixed_arena_init_<Name>(FixedArena_<Name>* result) {
|
||||||
zero_size(& result->memory[0], <Size>);
|
zero_size(& result->memory[0], <Size>);
|
||||||
result.arena = arena_init_from_memory(& result->memory[0], <Size>);
|
result->arena = arena_init_from_memory(& result->memory[0], <Size>);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
|
@ -8,7 +8,7 @@ using SwapContentProc = CodeBody(void);
|
|||||||
b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& body )
|
b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& body )
|
||||||
{
|
{
|
||||||
b32 found = false;
|
b32 found = false;
|
||||||
CodePreprocessCond cond = entry_iter.cast<CodePreprocessCond>();
|
CodePreprocessCond cond = entry_iter.code_cast<CodePreprocessCond>();
|
||||||
if ( cond->Content.contains(cond_sig) )
|
if ( cond->Content.contains(cond_sig) )
|
||||||
{
|
{
|
||||||
log_fmt("Preprocess cond found: %S\n", cond->Content);
|
log_fmt("Preprocess cond found: %S\n", cond->Content);
|
||||||
@ -44,7 +44,7 @@ b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& bod
|
|||||||
bool swap_pragma_region_implementation( StrC region_name, SwapContentProc* swap_content, Code& entry_iter, CodeBody& body )
|
bool swap_pragma_region_implementation( StrC region_name, SwapContentProc* swap_content, Code& entry_iter, CodeBody& body )
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
CodePragma possible_region = entry_iter.cast<CodePragma>();
|
CodePragma possible_region = entry_iter.code_cast<CodePragma>();
|
||||||
|
|
||||||
String region_sig = string_fmt_buf(GlobalAllocator, "region %s", region_name.Ptr);
|
String region_sig = string_fmt_buf(GlobalAllocator, "region %s", region_name.Ptr);
|
||||||
String endregion_sig = string_fmt_buf(GlobalAllocator, "endregion %s", region_name.Ptr);
|
String endregion_sig = string_fmt_buf(GlobalAllocator, "endregion %s", region_name.Ptr);
|
||||||
@ -58,7 +58,7 @@ bool swap_pragma_region_implementation( StrC region_name, SwapContentProc* swap_
|
|||||||
(entry_iter->Type) {
|
(entry_iter->Type) {
|
||||||
case ECode::Preprocess_Pragma:
|
case ECode::Preprocess_Pragma:
|
||||||
{
|
{
|
||||||
CodePragma possible_end_region = entry_iter.cast<CodePragma>();
|
CodePragma possible_end_region = entry_iter.code_cast<CodePragma>();
|
||||||
if ( possible_end_region->Content.contains(endregion_sig) ) {
|
if ( possible_end_region->Content.contains(endregion_sig) ) {
|
||||||
// body.append(possible_end_region);
|
// body.append(possible_end_region);
|
||||||
continue_for = false;
|
continue_for = false;
|
||||||
|
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();
|
||||||
|
}
|
@ -30,6 +30,13 @@ Feature Macros:
|
|||||||
* `GEN_ROLL_OWN_DEPENDENCIES` : Optional override so that user may define the dependencies themselves.
|
* `GEN_ROLL_OWN_DEPENDENCIES` : Optional override so that user may define the dependencies themselves.
|
||||||
* `GEN_DONT_ALLOW_INVALID_CODE` (Not implemented yet) : Will fail when an invalid code is constructed, parsed, or serialized.
|
* `GEN_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
|
## On multi-threading
|
||||||
|
|
||||||
Currently unsupported. I want the library to be *stable* and *correct*, with the addition of exhausting all basic single-threaded optimizations before I consider multi-threading.
|
Currently unsupported. I want the library to be *stable* and *correct*, with the addition of exhausting all basic single-threaded optimizations before I consider multi-threading.
|
||||||
|
@ -21,7 +21,7 @@ Builder Builder::open( char const* path )
|
|||||||
|
|
||||||
void Builder::pad_lines( s32 num )
|
void Builder::pad_lines( s32 num )
|
||||||
{
|
{
|
||||||
append( Buffer, "\n" );
|
append( & Buffer, "\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builder::print( Code code )
|
void Builder::print( Code code )
|
||||||
@ -29,7 +29,7 @@ void Builder::print( Code code )
|
|||||||
String str = code->to_string();
|
String str = code->to_string();
|
||||||
// const ssize len = str.length();
|
// const ssize len = str.length();
|
||||||
// log_fmt( "%s - print: %.*s\n", File.filename, len > 80 ? 80 : len, str.Data );
|
// log_fmt( "%s - print: %.*s\n", File.filename, len > 80 ? 80 : len, str.Data );
|
||||||
append( Buffer, str );
|
append( & Buffer, str );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builder::print_fmt( char const* fmt, ... )
|
void Builder::print_fmt( char const* fmt, ... )
|
||||||
@ -43,7 +43,7 @@ void Builder::print_fmt( char const* fmt, ... )
|
|||||||
va_end( va );
|
va_end( va );
|
||||||
|
|
||||||
// log_fmt( "$%s - print_fmt: %.*s\n", File.filename, res > 80 ? 80 : res, buf );
|
// log_fmt( "$%s - print_fmt: %.*s\n", File.filename, res > 80 ? 80 : res, buf );
|
||||||
append( Buffer, buf, res );
|
append( & Buffer, buf, res );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builder::write()
|
void Builder::write()
|
||||||
@ -55,5 +55,5 @@ void Builder::write()
|
|||||||
|
|
||||||
log_fmt( "Generated: %s\n", File.filename );
|
log_fmt( "Generated: %s\n", File.filename );
|
||||||
file_close( & File );
|
file_close( & File );
|
||||||
free(Buffer);
|
free(& Buffer);
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ Code scan_file( char const* path )
|
|||||||
|
|
||||||
String str = string_make_reserve( GlobalAllocator, fsize );
|
String str = string_make_reserve( GlobalAllocator, fsize );
|
||||||
file_read( & file, str, fsize );
|
file_read( & file, str, fsize );
|
||||||
get_header(str).Length = fsize;
|
get_header(str)->Length = fsize;
|
||||||
|
|
||||||
// Skip GEN_INTELLISENSE_DIRECTIVES preprocessor blocks
|
// Skip GEN_INTELLISENSE_DIRECTIVES preprocessor blocks
|
||||||
// Its designed so that the directive should be the first thing in the file.
|
// Its designed so that the directive should be the first thing in the file.
|
||||||
@ -97,12 +97,12 @@ Code scan_file( char const* path )
|
|||||||
if ( (scanner + 2) >= ( str.Data + fsize ) )
|
if ( (scanner + 2) >= ( str.Data + fsize ) )
|
||||||
{
|
{
|
||||||
mem_move( str, scanner, left );
|
mem_move( str, scanner, left );
|
||||||
get_header(str).Length = left;
|
get_header(str)->Length = left;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mem_move( str, scanner, left );
|
mem_move( str, scanner, left );
|
||||||
get_header(str).Length = left;
|
get_header(str)->Length = left;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||||
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
||||||
#define GEN_EXPOSE_BACKEND
|
#define GEN_EXPOSE_BACKEND
|
||||||
#define GEN_SUPPORT_CPP_MEMBER_FEATURES 0
|
#define GEN_SUPPORT_CPP_MEMBER_FEATURES 1
|
||||||
|
#define GEN_SUPPORT_CPP_REFERENCES 0
|
||||||
#include "gen.cpp"
|
#include "gen.cpp"
|
||||||
|
|
||||||
#include "helpers/push_ignores.inline.hpp"
|
#include "helpers/push_ignores.inline.hpp"
|
||||||
@ -28,17 +29,17 @@ void format_file( char const* path )
|
|||||||
String resolved_path = string_make(GlobalAllocator, to_str(path));
|
String resolved_path = string_make(GlobalAllocator, to_str(path));
|
||||||
|
|
||||||
String style_arg = string_make(GlobalAllocator, txt("-style=file:"));
|
String style_arg = string_make(GlobalAllocator, txt("-style=file:"));
|
||||||
append( style_arg, "../scripts/.clang-format ");
|
append( & style_arg, "../scripts/.clang-format ");
|
||||||
|
|
||||||
// Need to execute clang format on the generated file to get it to match the original.
|
// Need to execute clang format on the generated file to get it to match the original.
|
||||||
#define clang_format "clang-format "
|
#define clang_format "clang-format "
|
||||||
#define cf_format_inplace "-i "
|
#define cf_format_inplace "-i "
|
||||||
#define cf_verbose "-verbose "
|
#define cf_verbose "-verbose "
|
||||||
String command = string_make( GlobalAllocator, clang_format );
|
String command = string_make( GlobalAllocator, clang_format );
|
||||||
append( command, cf_format_inplace );
|
append( & command, cf_format_inplace );
|
||||||
append( command, cf_verbose );
|
append( & command, cf_verbose );
|
||||||
append( command, style_arg );
|
append( & command, style_arg );
|
||||||
append( command, resolved_path );
|
append( & command, resolved_path );
|
||||||
log_fmt("\tRunning clang-format on file:\n");
|
log_fmt("\tRunning clang-format on file:\n");
|
||||||
system( command );
|
system( command );
|
||||||
log_fmt("\tclang-format finished reformatting.\n");
|
log_fmt("\tclang-format finished reformatting.\n");
|
||||||
@ -63,6 +64,8 @@ int gen_main()
|
|||||||
{
|
{
|
||||||
gen::init();
|
gen::init();
|
||||||
|
|
||||||
|
// PreprocessorDefines.append("GEN_NS");
|
||||||
|
|
||||||
Code push_ignores = scan_file( "helpers/push_ignores.inline.hpp" );
|
Code push_ignores = scan_file( "helpers/push_ignores.inline.hpp" );
|
||||||
Code pop_ignores = scan_file( "helpers/pop_ignores.inline.hpp" );
|
Code pop_ignores = scan_file( "helpers/pop_ignores.inline.hpp" );
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -146,6 +146,19 @@ namespace parser
|
|||||||
struct Token;
|
struct Token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template< class Type> forceinline Type tmpl_cast( Code* self ) { return * rcast( Type*, self ); }
|
||||||
|
#if ! GEN_COMPILER_C && 0
|
||||||
|
template< class Type> forceinline Type tmpl_cast( Code& self ) { return * rcast( Type*, & self ); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char const* debug_str (Code code);
|
||||||
|
Code duplicate (Code code);
|
||||||
|
bool is_equal (Code code, Code other);
|
||||||
|
bool is_body (Code code);
|
||||||
|
bool is_valid (Code code);
|
||||||
|
void set_global(Code code);
|
||||||
|
String to_string (Code code);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
AST* wrapper
|
AST* wrapper
|
||||||
- Not constantly have to append the '*' as this is written often..
|
- Not constantly have to append the '*' as this is written often..
|
||||||
@ -153,32 +166,26 @@ namespace parser
|
|||||||
*/
|
*/
|
||||||
struct Code
|
struct Code
|
||||||
{
|
{
|
||||||
# pragma region Statics
|
AST* ast;
|
||||||
// Used to identify ASTs that should always be duplicated. (Global constant ASTs)
|
|
||||||
static Code Global;
|
|
||||||
|
|
||||||
// Used to identify invalid generated code.
|
|
||||||
static Code Invalid;
|
|
||||||
# pragma endregion Statics
|
|
||||||
|
|
||||||
# define Using_Code( Typename ) \
|
# define Using_Code( Typename ) \
|
||||||
char const* debug_str(); \
|
char const* debug_str() { return GEN_NS debug_str(* this); } \
|
||||||
Code duplicate(); \
|
Code duplicate() { return GEN_NS duplicate(* this); } \
|
||||||
bool is_equal( Code other ); \
|
bool is_equal( Code other ) { return GEN_NS is_equal(* this, other); } \
|
||||||
bool is_body(); \
|
bool is_body() { return GEN_NS is_body(* this); } \
|
||||||
bool is_valid(); \
|
bool is_valid() { return GEN_NS is_valid(* this); } \
|
||||||
void set_global(); \
|
void set_global() { return GEN_NS set_global(* this); } \
|
||||||
String to_string(); \
|
String to_string(); \
|
||||||
Typename& operator = ( AST* other ); \
|
Typename& operator = ( AST* other ); \
|
||||||
Typename& operator = ( Code other ); \
|
Typename& operator = ( Code other ); \
|
||||||
bool operator ==( Code other ); \
|
bool operator ==( Code other ) { return (AST*)ast == other.ast; } \
|
||||||
bool operator !=( Code other ); \
|
bool operator !=( Code other ) { return (AST*)ast != other.ast; } \
|
||||||
operator bool();
|
operator bool();
|
||||||
|
|
||||||
Using_Code( Code );
|
Using_Code( Code );
|
||||||
|
|
||||||
template< class Type >
|
template< class Type >
|
||||||
forceinline Type cast()
|
forceinline Type code_cast()
|
||||||
{
|
{
|
||||||
return * rcast( Type*, this );
|
return * rcast( Type*, this );
|
||||||
}
|
}
|
||||||
@ -201,8 +208,6 @@ struct Code
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
AST* ast;
|
|
||||||
|
|
||||||
#ifdef GEN_ENFORCE_STRONG_CODE_TYPES
|
#ifdef GEN_ENFORCE_STRONG_CODE_TYPES
|
||||||
# define operator explicit operator
|
# define operator explicit operator
|
||||||
#endif
|
#endif
|
||||||
@ -238,6 +243,14 @@ struct Code
|
|||||||
#undef operator
|
#undef operator
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#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
|
struct Code_POD
|
||||||
{
|
{
|
||||||
AST* ast;
|
AST* ast;
|
||||||
@ -248,33 +261,55 @@ static_assert( sizeof(Code) == sizeof(Code_POD), "ERROR: Code is not POD" );
|
|||||||
// Desired width of the AST data structure.
|
// Desired width of the AST data structure.
|
||||||
constexpr int const AST_POD_Size = 128;
|
constexpr int const AST_POD_Size = 128;
|
||||||
|
|
||||||
|
void append ( AST* self, AST* other );
|
||||||
|
char const* debug_str ( AST* self );
|
||||||
|
AST* duplicate ( AST* self );
|
||||||
|
Code* entry ( AST* self, u32 idx );
|
||||||
|
bool has_entries( AST* self );
|
||||||
|
bool is_body ( AST* self );
|
||||||
|
bool is_equal ( AST* self, AST* other );
|
||||||
|
String to_string ( AST* self );
|
||||||
|
char const* type_str ( AST* self );
|
||||||
|
|
||||||
|
#if GEN_CPP_SUPPORT_REFERENCES
|
||||||
|
void append ( AST& self, AST& other ) { return append(& self, & other); }
|
||||||
|
bool is_body ( AST& self ) { return is_body(& self); }
|
||||||
|
bool is_equal ( AST& self, AST& other ) { return is_equal(& self, & other); }
|
||||||
|
char const* debug_str( AST& self ) { return debug_str( & self ); }
|
||||||
|
String to_string( AST& self ) { return to_string( & self ); }
|
||||||
|
char const* type_str ( AST& self ) { return type_str( & self ); }
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Simple AST POD with functionality to seralize into C++ syntax.
|
Simple AST POD with functionality to seralize into C++ syntax.
|
||||||
*/
|
*/
|
||||||
struct AST
|
struct AST
|
||||||
{
|
{
|
||||||
|
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||||
# pragma region Member Functions
|
# pragma region Member Functions
|
||||||
void append ( AST* other );
|
void append ( AST* other ) { GEN_NS append(this, other); }
|
||||||
char const* debug_str ();
|
char const* debug_str () { return GEN_NS debug_str(this); }
|
||||||
AST* duplicate ();
|
AST* duplicate () { return GEN_NS duplicate(this); }
|
||||||
Code& entry ( u32 idx );
|
Code* entry ( u32 idx ) { return GEN_NS entry(this, idx); }
|
||||||
bool has_entries();
|
bool has_entries();
|
||||||
bool is_equal ( AST* other );
|
bool is_equal ( AST* other ) { return GEN_NS is_equal(this, other); }
|
||||||
bool is_body();
|
bool is_body() { return GEN_NS is_body(this); }
|
||||||
char const* type_str();
|
char const* type_str() { return GEN_NS type_str(this); }
|
||||||
bool validate_body();
|
bool validate_body();
|
||||||
|
|
||||||
String to_string();
|
String to_string(); //{ return GEN_NS to_string(this); }
|
||||||
|
|
||||||
neverinline
|
|
||||||
void to_string( String& result );
|
|
||||||
|
|
||||||
template< class Type >
|
template< class Type >
|
||||||
forceinline Type cast()
|
forceinline Type code_cast()
|
||||||
{
|
{
|
||||||
return * this;
|
return * this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
neverinline
|
||||||
|
void to_string( String& result );
|
||||||
|
# pragma endregion Member Functions
|
||||||
|
#endif
|
||||||
|
|
||||||
operator Code();
|
operator Code();
|
||||||
operator CodeBody();
|
operator CodeBody();
|
||||||
operator CodeAttributes();
|
operator CodeAttributes();
|
||||||
@ -305,7 +340,6 @@ struct AST
|
|||||||
operator CodeUnion();
|
operator CodeUnion();
|
||||||
operator CodeUsing();
|
operator CodeUsing();
|
||||||
operator CodeVar();
|
operator CodeVar();
|
||||||
# pragma endregion Member Functions
|
|
||||||
|
|
||||||
constexpr static
|
constexpr static
|
||||||
int ArrSpecs_Cap =
|
int ArrSpecs_Cap =
|
||||||
@ -446,12 +480,9 @@ struct AST_POD
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct test {
|
|
||||||
SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers
|
|
||||||
AST* NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used.
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr int pls = sizeof(test);
|
// TODO(Ed): Convert
|
||||||
|
String to_string ( AST* self ) { return self->to_string(); }
|
||||||
|
|
||||||
// Its intended for the AST to have equivalent size to its POD.
|
// Its intended for the AST to have equivalent size to its POD.
|
||||||
// All extra functionality within the AST namespace should just be syntatic sugar.
|
// All extra functionality within the AST namespace should just be syntatic sugar.
|
||||||
@ -460,4 +491,4 @@ static_assert( sizeof(AST_POD) == AST_POD_Size, "ERROR: AST POD is not size o
|
|||||||
|
|
||||||
// Used when the its desired when omission is allowed in a definition.
|
// Used when the its desired when omission is allowed in a definition.
|
||||||
#define NoCode { nullptr }
|
#define NoCode { nullptr }
|
||||||
#define CodeInvalid (* Code::Invalid.ast) // Uses an implicitly overloaded cast from the AST to the desired code type.
|
#define InvalidCode (* Code_Invalid.ast) // Uses an implicitly overloaded cast from the AST to the desired code type.
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -11,37 +11,30 @@ struct CodeBody
|
|||||||
|
|
||||||
void append( Code other )
|
void append( Code other )
|
||||||
{
|
{
|
||||||
if (other.is_body())
|
GEN_ASSERT(other.ast != nullptr);
|
||||||
{
|
|
||||||
append( other.cast<CodeBody>() );
|
if (other.is_body()) {
|
||||||
|
append( cast(CodeBody, & other) );
|
||||||
}
|
}
|
||||||
raw()->append( other.ast );
|
|
||||||
|
GEN_NS append( raw(), other.ast );
|
||||||
}
|
}
|
||||||
void append( CodeBody body )
|
void append( CodeBody body )
|
||||||
{
|
{
|
||||||
for ( Code entry : body )
|
for ( Code entry : body ) {
|
||||||
{
|
|
||||||
append( entry );
|
append( entry );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool has_entries()
|
bool has_entries() { return GEN_NS has_entries(rcast( AST*, ast )); }
|
||||||
{
|
AST* raw() { return rcast( AST*, ast ); }
|
||||||
return rcast( AST*, ast )->has_entries();
|
|
||||||
}
|
|
||||||
void to_string( String& result );
|
void to_string( String& result );
|
||||||
void to_string_export( String& result );
|
void to_string_export( String& result );
|
||||||
AST* raw()
|
|
||||||
{
|
AST_Body* operator->() { return ast; }
|
||||||
return rcast( AST*, ast );
|
|
||||||
}
|
operator Code() { return * rcast( Code*, this ); }
|
||||||
AST_Body* operator->()
|
|
||||||
{
|
|
||||||
return ast;
|
|
||||||
}
|
|
||||||
operator Code()
|
|
||||||
{
|
|
||||||
return * rcast( Code*, this );
|
|
||||||
}
|
|
||||||
#pragma region Iterator
|
#pragma region Iterator
|
||||||
Code begin()
|
Code begin()
|
||||||
{
|
{
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -4,56 +4,62 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void AST::append( AST* other )
|
void append( AST* self, AST* other )
|
||||||
{
|
{
|
||||||
|
GEN_ASSERT(self != nullptr);
|
||||||
|
GEN_ASSERT(other != nullptr);
|
||||||
|
|
||||||
if ( other->Parent )
|
if ( other->Parent )
|
||||||
other = other->duplicate();
|
other = duplicate(other);
|
||||||
|
|
||||||
other->Parent = this;
|
other->Parent = self;
|
||||||
|
|
||||||
if ( Front == nullptr )
|
if ( self->Front == nullptr )
|
||||||
{
|
{
|
||||||
Front = other;
|
self->Front = other;
|
||||||
Back = other;
|
self->Back = other;
|
||||||
|
|
||||||
NumEntries++;
|
self->NumEntries++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AST*
|
AST*
|
||||||
Current = Back;
|
Current = self->Back;
|
||||||
Current->Next = other;
|
Current->Next = other;
|
||||||
other->Prev = Current;
|
other->Prev = Current;
|
||||||
Back = other;
|
self->Back = other;
|
||||||
NumEntries++;
|
self->NumEntries++;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
Code& AST::entry( u32 idx )
|
Code* entry( AST* self, u32 idx )
|
||||||
{
|
{
|
||||||
AST** current = & Front;
|
GEN_ASSERT(self != nullptr);
|
||||||
|
AST** current = & self->Front;
|
||||||
while ( idx >= 0 && current != nullptr )
|
while ( idx >= 0 && current != nullptr )
|
||||||
{
|
{
|
||||||
if ( idx == 0 )
|
if ( idx == 0 )
|
||||||
return * rcast( Code*, current);
|
return rcast( Code*, current);
|
||||||
|
|
||||||
current = & ( * current )->Next;
|
current = & ( * current )->Next;
|
||||||
idx--;
|
idx--;
|
||||||
}
|
}
|
||||||
|
|
||||||
return * rcast( Code*, current);
|
return rcast( Code*, current);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool AST::has_entries()
|
bool has_entries(AST* self)
|
||||||
{
|
{
|
||||||
return NumEntries > 0;
|
GEN_ASSERT(self != nullptr);
|
||||||
|
return self->NumEntries > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool AST::is_body()
|
bool is_body(AST* self)
|
||||||
{
|
{
|
||||||
switch (Type)
|
GEN_ASSERT(self != nullptr);
|
||||||
|
switch (self->Type)
|
||||||
{
|
{
|
||||||
case ECode::Enum_Body:
|
case ECode::Enum_Body:
|
||||||
case ECode::Class_Body:
|
case ECode::Class_Body:
|
||||||
@ -70,9 +76,10 @@ bool AST::is_body()
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
char const* AST::type_str()
|
char const* type_str(AST* self)
|
||||||
{
|
{
|
||||||
return ECode::to_str( Type );
|
GEN_ASSERT(self != nullptr);
|
||||||
|
return ECode::to_str( self->Type );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
@ -81,6 +88,69 @@ AST::operator Code()
|
|||||||
return { this };
|
return { this };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma region Code
|
||||||
|
|
||||||
|
inline
|
||||||
|
char const* debug_str( Code code )
|
||||||
|
{
|
||||||
|
if ( code.ast == nullptr )
|
||||||
|
return "Code::debug_str: AST is null!";
|
||||||
|
|
||||||
|
return debug_str( code.ast );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
Code duplicate( Code code )
|
||||||
|
{
|
||||||
|
if ( code.ast == nullptr )
|
||||||
|
{
|
||||||
|
log_failure("Code::duplicate: Cannot duplicate code, AST is null!");
|
||||||
|
return Code_Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { duplicate(code.ast) };
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool is_body(Code code)
|
||||||
|
{
|
||||||
|
if ( code.ast == nullptr )
|
||||||
|
{
|
||||||
|
return is_body(code.ast);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool is_equal( Code self, Code other )
|
||||||
|
{
|
||||||
|
if ( self.ast == nullptr || other.ast == nullptr )
|
||||||
|
{
|
||||||
|
// Just check if they're both null.
|
||||||
|
// log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
|
||||||
|
return self.ast == nullptr && other.ast == nullptr;
|
||||||
|
}
|
||||||
|
return is_equal( self.ast, other.ast );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool is_valid(Code self)
|
||||||
|
{
|
||||||
|
return self.ast != nullptr && self.ast->Type != CodeT::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void set_global(Code self)
|
||||||
|
{
|
||||||
|
if ( self.ast == nullptr )
|
||||||
|
{
|
||||||
|
log_failure("Code::set_global: Cannot set code as global, AST is null!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->Parent = Code_Global.ast;
|
||||||
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
Code& Code::operator ++()
|
Code& Code::operator ++()
|
||||||
{
|
{
|
||||||
@ -90,6 +160,8 @@ Code& Code::operator ++()
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma endregion Code
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void CodeClass::add_interface( CodeType type )
|
void CodeClass::add_interface( CodeType type )
|
||||||
{
|
{
|
||||||
@ -117,7 +189,7 @@ void CodeParam::append( CodeParam other )
|
|||||||
AST* entry = (AST*) other.ast;
|
AST* entry = (AST*) other.ast;
|
||||||
|
|
||||||
if ( entry->Parent )
|
if ( entry->Parent )
|
||||||
entry = entry->duplicate();
|
entry = GEN_NS duplicate( entry );
|
||||||
|
|
||||||
entry->Parent = self;
|
entry->Parent = self;
|
||||||
|
|
||||||
@ -202,7 +274,7 @@ CodeBody def_body( CodeT type )
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
log_failure( "def_body: Invalid type %s", (char const*)ECode::to_str(type) );
|
log_failure( "def_body: Invalid type %s", (char const*)ECode::to_str(type) );
|
||||||
return (CodeBody)Code::Invalid;
|
return (CodeBody)Code_Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
Code
|
Code
|
||||||
|
@ -11,7 +11,7 @@ internal void deinit();
|
|||||||
internal
|
internal
|
||||||
void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
|
void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
|
||||||
{
|
{
|
||||||
Arena* last = & back(Global_AllocatorBuckets);
|
Arena* last = back(& Global_AllocatorBuckets);
|
||||||
|
|
||||||
switch ( type )
|
switch ( type )
|
||||||
{
|
{
|
||||||
@ -24,13 +24,13 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, s
|
|||||||
if ( bucket.PhysicalStart == nullptr )
|
if ( bucket.PhysicalStart == nullptr )
|
||||||
GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets");
|
GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets");
|
||||||
|
|
||||||
if ( ! append( Global_AllocatorBuckets, bucket ) )
|
if ( ! append( & Global_AllocatorBuckets, bucket ) )
|
||||||
GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets");
|
GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets");
|
||||||
|
|
||||||
last = & back(Global_AllocatorBuckets);
|
last = back(& Global_AllocatorBuckets);
|
||||||
}
|
}
|
||||||
|
|
||||||
return alloc_align( allocator_info(* last), size, alignment );
|
return alloc_align( allocator_info(last), size, alignment );
|
||||||
}
|
}
|
||||||
case EAllocation_FREE:
|
case EAllocation_FREE:
|
||||||
{
|
{
|
||||||
@ -51,10 +51,10 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, s
|
|||||||
if ( bucket.PhysicalStart == nullptr )
|
if ( bucket.PhysicalStart == nullptr )
|
||||||
GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets");
|
GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets");
|
||||||
|
|
||||||
if ( ! append( Global_AllocatorBuckets, bucket ) )
|
if ( ! append( & Global_AllocatorBuckets, bucket ) )
|
||||||
GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets");
|
GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets");
|
||||||
|
|
||||||
last = & back(Global_AllocatorBuckets);
|
last = back(& Global_AllocatorBuckets);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* result = alloc_align( last->Backing, size, alignment );
|
void* result = alloc_align( last->Backing, size, alignment );
|
||||||
@ -74,12 +74,12 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, s
|
|||||||
internal
|
internal
|
||||||
void define_constants()
|
void define_constants()
|
||||||
{
|
{
|
||||||
Code::Global = make_code();
|
Code_Global = make_code();
|
||||||
scast(String, Code::Global->Name) = get_cached_string( txt("Global Code") );
|
scast(String, Code_Global->Name) = get_cached_string( txt("Global Code") );
|
||||||
scast(String, Code::Global->Content) = Code::Global->Name;
|
scast(String, Code_Global->Content) = Code_Global->Name;
|
||||||
|
|
||||||
Code::Invalid = make_code();
|
Code_Invalid = make_code();
|
||||||
Code::Invalid.set_global();
|
Code_Invalid.set_global();
|
||||||
|
|
||||||
t_empty = (CodeType) make_code();
|
t_empty = (CodeType) make_code();
|
||||||
t_empty->Type = ECode::Typename;
|
t_empty->Type = ECode::Typename;
|
||||||
@ -249,7 +249,7 @@ void init()
|
|||||||
if ( bucket.PhysicalStart == nullptr )
|
if ( bucket.PhysicalStart == nullptr )
|
||||||
GEN_FATAL( "Failed to create first bucket for Global_AllocatorBuckets");
|
GEN_FATAL( "Failed to create first bucket for Global_AllocatorBuckets");
|
||||||
|
|
||||||
append( Global_AllocatorBuckets, bucket );
|
append( & Global_AllocatorBuckets, bucket );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup the arrays
|
// Setup the arrays
|
||||||
@ -272,7 +272,7 @@ void init()
|
|||||||
if ( code_pool.PhysicalStart == nullptr )
|
if ( code_pool.PhysicalStart == nullptr )
|
||||||
GEN_FATAL( "gen::init: Failed to initialize the code pool" );
|
GEN_FATAL( "gen::init: Failed to initialize the code pool" );
|
||||||
|
|
||||||
append(CodePools, code_pool );
|
append( & CodePools, code_pool );
|
||||||
|
|
||||||
LexArena = arena_init_from_allocator( Allocator_Lexer, LexAllocator_Size );
|
LexArena = arena_init_from_allocator( Allocator_Lexer, LexAllocator_Size );
|
||||||
|
|
||||||
@ -281,7 +281,7 @@ void init()
|
|||||||
if ( string_arena.PhysicalStart == nullptr )
|
if ( string_arena.PhysicalStart == nullptr )
|
||||||
GEN_FATAL( "gen::init: Failed to initialize the string arena" );
|
GEN_FATAL( "gen::init: Failed to initialize the string arena" );
|
||||||
|
|
||||||
append(StringArenas, string_arena );
|
append( & StringArenas, string_arena );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup the hash tables
|
// Setup the hash tables
|
||||||
@ -306,7 +306,7 @@ void deinit()
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
Pool* code_pool = & CodePools[index];
|
Pool* code_pool = & CodePools[index];
|
||||||
free(* code_pool);
|
free(code_pool);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
while ( left--, left );
|
while ( left--, left );
|
||||||
@ -316,26 +316,26 @@ void deinit()
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
Arena* string_arena = & StringArenas[index];
|
Arena* string_arena = & StringArenas[index];
|
||||||
free(* string_arena);
|
free(string_arena);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
while ( left--, left );
|
while ( left--, left );
|
||||||
|
|
||||||
destroy(StringCache);
|
destroy(& StringCache);
|
||||||
|
|
||||||
free(CodePools);
|
free( & CodePools);
|
||||||
free(StringArenas);
|
free( & StringArenas);
|
||||||
|
|
||||||
free(LexArena);
|
free(& LexArena);
|
||||||
|
|
||||||
free(PreprocessorDefines);
|
free(& PreprocessorDefines);
|
||||||
|
|
||||||
index = 0;
|
index = 0;
|
||||||
left = num(Global_AllocatorBuckets);
|
left = num(Global_AllocatorBuckets);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
Arena* bucket = & Global_AllocatorBuckets[ index ];
|
Arena* bucket = & Global_AllocatorBuckets[ index ];
|
||||||
free(* bucket);
|
free(bucket);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
while ( left--, left );
|
while ( left--, left );
|
||||||
@ -373,7 +373,7 @@ void reset()
|
|||||||
|
|
||||||
AllocatorInfo get_string_allocator( s32 str_length )
|
AllocatorInfo get_string_allocator( s32 str_length )
|
||||||
{
|
{
|
||||||
Arena* last = & back(StringArenas);
|
Arena* last = back(& StringArenas);
|
||||||
|
|
||||||
usize size_req = str_length + sizeof(StringHeader) + sizeof(char*);
|
usize size_req = str_length + sizeof(StringHeader) + sizeof(char*);
|
||||||
|
|
||||||
@ -381,13 +381,13 @@ AllocatorInfo get_string_allocator( s32 str_length )
|
|||||||
{
|
{
|
||||||
Arena new_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena );
|
Arena new_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena );
|
||||||
|
|
||||||
if ( ! append(StringArenas, new_arena ) )
|
if ( ! append( & StringArenas, new_arena ) )
|
||||||
GEN_FATAL( "gen::get_string_allocator: Failed to allocate a new string arena" );
|
GEN_FATAL( "gen::get_string_allocator: Failed to allocate a new string arena" );
|
||||||
|
|
||||||
last = & back(StringArenas);
|
last = back(& StringArenas);
|
||||||
}
|
}
|
||||||
|
|
||||||
return allocator_info(* last);
|
return allocator_info(last);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Will either make or retrive a code string.
|
// Will either make or retrive a code string.
|
||||||
@ -403,7 +403,7 @@ StringCached get_cached_string( StrC str )
|
|||||||
}
|
}
|
||||||
|
|
||||||
String result = string_make( get_string_allocator( str.Len ), str );
|
String result = string_make( get_string_allocator( str.Len ), str );
|
||||||
set<StringCached>(StringCache, key, result );
|
set<StringCached>(& StringCache, key, result );
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -411,7 +411,7 @@ StringCached get_cached_string( StrC str )
|
|||||||
// Used internally to retireve a Code object form the CodePool.
|
// Used internally to retireve a Code object form the CodePool.
|
||||||
Code make_code()
|
Code make_code()
|
||||||
{
|
{
|
||||||
Pool* allocator = & back(CodePools);
|
Pool* allocator = back( & CodePools);
|
||||||
if ( allocator->FreeList == nullptr )
|
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) );
|
||||||
@ -419,13 +419,13 @@ Code make_code()
|
|||||||
if ( code_pool.PhysicalStart == nullptr )
|
if ( code_pool.PhysicalStart == nullptr )
|
||||||
GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePool allcoator returned nullptr." );
|
GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePool allcoator returned nullptr." );
|
||||||
|
|
||||||
if ( ! append( CodePools, code_pool ) )
|
if ( ! append( & CodePools, code_pool ) )
|
||||||
GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePools failed to append new pool." );
|
GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePools failed to append new pool." );
|
||||||
|
|
||||||
allocator = & back(CodePools);
|
allocator = back( & CodePools);
|
||||||
}
|
}
|
||||||
|
|
||||||
Code result { rcast( AST*, alloc( allocator_info(* allocator), sizeof(AST) )) };
|
Code result { rcast( AST*, alloc( allocator_info(allocator), sizeof(AST) )) };
|
||||||
mem_set( result.ast, 0, sizeof(AST) );
|
mem_set( result.ast, 0, sizeof(AST) );
|
||||||
// result->Type = ECode::Invalid;
|
// result->Type = ECode::Invalid;
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ CodeClass parse_class( StrC def )
|
|||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
Context.Tokens = toks;
|
||||||
push_scope();
|
push_scope();
|
||||||
@ -31,7 +31,7 @@ CodeConstructor parse_constructor( StrC def )
|
|||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
// TODO(Ed): Constructors can have prefix attributes
|
// TODO(Ed): Constructors can have prefix attributes
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ CodeConstructor parse_constructor( StrC def )
|
|||||||
default :
|
default :
|
||||||
log_failure( "Invalid specifier %s for variable\n%s", ESpecifier::to_str( spec ), Context.to_string() );
|
log_failure( "Invalid specifier %s for variable\n%s", ESpecifier::to_str( spec ), Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Every specifier after would be considered part of the type type signature
|
// Every specifier after would be considered part of the type type signature
|
||||||
@ -91,7 +91,7 @@ CodeDestructor parse_destructor( StrC def )
|
|||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
// TODO(Ed): Destructors can have prefix attributes
|
// TODO(Ed): Destructors can have prefix attributes
|
||||||
// TODO(Ed): Destructors can have virtual
|
// TODO(Ed): Destructors can have virtual
|
||||||
@ -110,7 +110,7 @@ CodeEnum parse_enum( StrC def )
|
|||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
{
|
{
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Context.Tokens = toks;
|
Context.Tokens = toks;
|
||||||
@ -124,7 +124,7 @@ CodeBody parse_export_body( StrC def )
|
|||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
Context.Tokens = toks;
|
||||||
return parse_export_body();
|
return parse_export_body();
|
||||||
@ -137,7 +137,7 @@ CodeExtern parse_extern_link( StrC def )
|
|||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
Context.Tokens = toks;
|
||||||
return parse_extern_link();
|
return parse_extern_link();
|
||||||
@ -150,7 +150,7 @@ CodeFriend parse_friend( StrC def )
|
|||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
Context.Tokens = toks;
|
||||||
return parse_friend();
|
return parse_friend();
|
||||||
@ -163,7 +163,7 @@ CodeFn parse_function( StrC def )
|
|||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
Context.Tokens = toks;
|
||||||
return (CodeFn) parse_function();
|
return (CodeFn) parse_function();
|
||||||
@ -176,7 +176,7 @@ CodeBody parse_global_body( StrC def )
|
|||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
Context.Tokens = toks;
|
||||||
push_scope();
|
push_scope();
|
||||||
@ -192,7 +192,7 @@ CodeNS parse_namespace( StrC def )
|
|||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
Context.Tokens = toks;
|
||||||
return parse_namespace();
|
return parse_namespace();
|
||||||
@ -205,7 +205,7 @@ CodeOperator parse_operator( StrC def )
|
|||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
Context.Tokens = toks;
|
||||||
return (CodeOperator) parse_operator();
|
return (CodeOperator) parse_operator();
|
||||||
@ -218,7 +218,7 @@ CodeOpCast parse_operator_cast( StrC def )
|
|||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
Context.Tokens = toks;
|
||||||
return parse_operator_cast();
|
return parse_operator_cast();
|
||||||
@ -231,7 +231,7 @@ CodeStruct parse_struct( StrC def )
|
|||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
Context.Tokens = toks;
|
||||||
push_scope();
|
push_scope();
|
||||||
@ -247,7 +247,7 @@ CodeTemplate parse_template( StrC def )
|
|||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
Context.Tokens = toks;
|
||||||
return parse_template();
|
return parse_template();
|
||||||
@ -260,7 +260,7 @@ CodeType parse_type( StrC def )
|
|||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
Context.Tokens = toks;
|
||||||
return parse_type();
|
return parse_type();
|
||||||
@ -273,7 +273,7 @@ CodeTypedef parse_typedef( StrC def )
|
|||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
Context.Tokens = toks;
|
||||||
return parse_typedef();
|
return parse_typedef();
|
||||||
@ -286,7 +286,7 @@ CodeUnion parse_union( StrC def )
|
|||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
Context.Tokens = toks;
|
||||||
return parse_union();
|
return parse_union();
|
||||||
@ -299,7 +299,7 @@ CodeUsing parse_using( StrC def )
|
|||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
Context.Tokens = toks;
|
||||||
return parse_using();
|
return parse_using();
|
||||||
@ -312,7 +312,7 @@ CodeVar parse_variable( StrC def )
|
|||||||
|
|
||||||
TokArray toks = lex( def );
|
TokArray toks = lex( def );
|
||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Tokens = toks;
|
Context.Tokens = toks;
|
||||||
return parse_variable();
|
return parse_variable();
|
||||||
|
@ -17,7 +17,7 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
|
|||||||
char tok_map_mem[ TokenFmt_TokenMap_MemSize ];
|
char tok_map_mem[ TokenFmt_TokenMap_MemSize ];
|
||||||
|
|
||||||
tok_map_arena = arena_init_from_memory( tok_map_mem, sizeof(tok_map_mem) );
|
tok_map_arena = arena_init_from_memory( tok_map_mem, sizeof(tok_map_mem) );
|
||||||
tok_map = hashtable_init<StrC>( allocator_info(tok_map_arena) );
|
tok_map = hashtable_init<StrC>( allocator_info(& tok_map_arena) );
|
||||||
|
|
||||||
s32 left = num_tokens - 1;
|
s32 left = num_tokens - 1;
|
||||||
|
|
||||||
@ -27,8 +27,7 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
|
|||||||
StrC value = va_arg( va, StrC );
|
StrC value = va_arg( va, StrC );
|
||||||
|
|
||||||
u32 key = crc32( token, str_len(token) );
|
u32 key = crc32( token, str_len(token) );
|
||||||
|
set(& tok_map, key, value );
|
||||||
set(tok_map, key, value );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +94,7 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
|
|||||||
}
|
}
|
||||||
|
|
||||||
clear(tok_map);
|
clear(tok_map);
|
||||||
free(tok_map_arena);
|
free(& tok_map_arena);
|
||||||
|
|
||||||
ssize result = buf_size - remaining;
|
ssize result = buf_size - remaining;
|
||||||
|
|
||||||
@ -107,7 +106,7 @@ Code untyped_str( StrC content )
|
|||||||
if ( content.Len == 0 )
|
if ( content.Len == 0 )
|
||||||
{
|
{
|
||||||
log_failure( "untyped_str: empty string" );
|
log_failure( "untyped_str: empty string" );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Code
|
Code
|
||||||
@ -119,7 +118,7 @@ Code untyped_str( StrC content )
|
|||||||
if ( result->Name == nullptr )
|
if ( result->Name == nullptr )
|
||||||
{
|
{
|
||||||
log_failure( "untyped_str: could not cache string" );
|
log_failure( "untyped_str: could not cache string" );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -130,7 +129,7 @@ Code untyped_fmt( char const* fmt, ...)
|
|||||||
if ( fmt == nullptr )
|
if ( fmt == nullptr )
|
||||||
{
|
{
|
||||||
log_failure( "untyped_fmt: null format string" );
|
log_failure( "untyped_fmt: null format string" );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
local_persist thread_local
|
local_persist thread_local
|
||||||
@ -150,7 +149,7 @@ Code untyped_fmt( char const* fmt, ...)
|
|||||||
if ( result->Name == nullptr )
|
if ( result->Name == nullptr )
|
||||||
{
|
{
|
||||||
log_failure( "untyped_fmt: could not cache string" );
|
log_failure( "untyped_fmt: could not cache string" );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -161,7 +160,7 @@ Code untyped_token_fmt( s32 num_tokens, ... )
|
|||||||
if ( num_tokens == 0 )
|
if ( num_tokens == 0 )
|
||||||
{
|
{
|
||||||
log_failure( "untyped_token_fmt: zero tokens" );
|
log_failure( "untyped_token_fmt: zero tokens" );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
local_persist thread_local
|
local_persist thread_local
|
||||||
@ -181,7 +180,7 @@ Code untyped_token_fmt( s32 num_tokens, ... )
|
|||||||
if ( result->Name == nullptr )
|
if ( result->Name == nullptr )
|
||||||
{
|
{
|
||||||
log_failure( "untyped_fmt: could not cache string" );
|
log_failure( "untyped_fmt: could not cache string" );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -381,13 +381,13 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy
|
|||||||
if ( Name_.Len <= 0 ) \
|
if ( Name_.Len <= 0 ) \
|
||||||
{ \
|
{ \
|
||||||
log_failure( "gen::" stringize(Context_) ": Invalid name length provided - %d", Name_.Len ); \
|
log_failure( "gen::" stringize(Context_) ": Invalid name length provided - %d", Name_.Len ); \
|
||||||
return CodeInvalid; \
|
return InvalidCode; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
if ( Name_.Ptr == nullptr ) \
|
if ( Name_.Ptr == nullptr ) \
|
||||||
{ \
|
{ \
|
||||||
log_failure( "gen::" stringize(Context_) ": name is null" ); \
|
log_failure( "gen::" stringize(Context_) ": name is null" ); \
|
||||||
return CodeInvalid; \
|
return InvalidCode; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,7 +395,7 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy
|
|||||||
if ( ! Code_ ) \
|
if ( ! Code_ ) \
|
||||||
{ \
|
{ \
|
||||||
log_failure( "gen::" stringize(Context_) ": " stringize(Code_) " provided is null" ); \
|
log_failure( "gen::" stringize(Context_) ": " stringize(Code_) " provided is null" ); \
|
||||||
return CodeInvalid; \
|
return InvalidCode; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define null_or_invalid_check( Context_, Code_ ) \
|
#define null_or_invalid_check( Context_, Code_ ) \
|
||||||
@ -403,19 +403,19 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy
|
|||||||
if ( ! Code_ ) \
|
if ( ! Code_ ) \
|
||||||
{ \
|
{ \
|
||||||
log_failure( "gen::" stringize(Context_) ": " stringize(Code_) " provided is null" ); \
|
log_failure( "gen::" stringize(Context_) ": " stringize(Code_) " provided is null" ); \
|
||||||
return CodeInvalid; \
|
return InvalidCode; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
if ( Code_->is_invalid() ) \
|
if ( Code_->is_invalid() ) \
|
||||||
{ \
|
{ \
|
||||||
log_failure("gen::" stringize(Context_) ": " stringize(Code_) " provided is invalid" ); \
|
log_failure("gen::" stringize(Context_) ": " stringize(Code_) " provided is invalid" ); \
|
||||||
return CodeInvalid; \
|
return InvalidCode; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define not_implemented( Context_ ) \
|
#define not_implemented( Context_ ) \
|
||||||
log_failure( "gen::%s: This function is not implemented" ); \
|
log_failure( "gen::%s: This function is not implemented" ); \
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
#pragma endregion Helper Marcos
|
#pragma endregion Helper Marcos
|
||||||
|
|
||||||
|
|
||||||
@ -436,7 +436,7 @@ CodeAttributes def_attributes( StrC content )
|
|||||||
if ( content.Len <= 0 || content.Ptr == nullptr )
|
if ( content.Len <= 0 || content.Ptr == nullptr )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_attributes: Invalid attributes provided" );
|
log_failure( "gen::def_attributes: Invalid attributes provided" );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Code
|
Code
|
||||||
@ -453,7 +453,7 @@ CodeComment def_comment( StrC content )
|
|||||||
if ( content.Len <= 0 || content.Ptr == nullptr )
|
if ( content.Len <= 0 || content.Ptr == nullptr )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_comment: Invalid comment provided:" );
|
log_failure( "gen::def_comment: Invalid comment provided:" );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char line[ MaxCommentLineLength ];
|
static char line[ MaxCommentLineLength ];
|
||||||
@ -474,15 +474,15 @@ CodeComment def_comment( StrC content )
|
|||||||
length++;
|
length++;
|
||||||
|
|
||||||
str_copy( line, scanner, length );
|
str_copy( line, scanner, length );
|
||||||
append_fmt(cmt_formatted, "//%.*s", length, line );
|
append_fmt(& cmt_formatted, "//%.*s", length, line );
|
||||||
mem_set( line, 0, MaxCommentLineLength );
|
mem_set( line, 0, MaxCommentLineLength );
|
||||||
|
|
||||||
scanner += length;
|
scanner += length;
|
||||||
}
|
}
|
||||||
while ( scanner <= end );
|
while ( scanner <= end );
|
||||||
|
|
||||||
if ( back(cmt_formatted) != '\n' )
|
if ( * back(& cmt_formatted) != '\n' )
|
||||||
append( cmt_formatted, "\n" );
|
append( & cmt_formatted, "\n" );
|
||||||
|
|
||||||
Code
|
Code
|
||||||
result = make_code();
|
result = make_code();
|
||||||
@ -490,7 +490,7 @@ CodeComment def_comment( StrC content )
|
|||||||
result->Name = get_cached_string( cmt_formatted );
|
result->Name = get_cached_string( cmt_formatted );
|
||||||
result->Content = result->Name;
|
result->Content = result->Name;
|
||||||
|
|
||||||
free(cmt_formatted);
|
free(& cmt_formatted);
|
||||||
|
|
||||||
return (CodeComment) result;
|
return (CodeComment) result;
|
||||||
}
|
}
|
||||||
@ -502,7 +502,7 @@ CodeConstructor def_constructor( CodeParam params, Code initializer_list, Code b
|
|||||||
if ( params && params->Type != Parameters )
|
if ( params && params->Type != Parameters )
|
||||||
{
|
{
|
||||||
log_failure("gen::def_constructor: params must be of Parameters type - %s", params.debug_str());
|
log_failure("gen::def_constructor: params must be of Parameters type - %s", params.debug_str());
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeConstructor
|
CodeConstructor
|
||||||
@ -528,7 +528,7 @@ CodeConstructor def_constructor( CodeParam params, Code initializer_list, Code b
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
log_failure("gen::def_constructor: body must be either of Function_Body or Untyped type - %s", body.debug_str());
|
log_failure("gen::def_constructor: body must be either of Function_Body or Untyped type - %s", body.debug_str());
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
result->Type = Constructor;
|
result->Type = Constructor;
|
||||||
@ -556,13 +556,13 @@ CodeClass def_class( StrC name
|
|||||||
if ( attributes && attributes->Type != PlatformAttributes )
|
if ( attributes && attributes->Type != PlatformAttributes )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_class: attributes was not a 'PlatformAttributes' type: %s", attributes.debug_str() );
|
log_failure( "gen::def_class: attributes was not a 'PlatformAttributes' type: %s", attributes.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( parent && ( parent->Type != Class && parent->Type != Struct && parent->Type != Typename && parent->Type != Untyped ) )
|
if ( parent && ( parent->Type != Class && parent->Type != Struct && parent->Type != Typename && parent->Type != Untyped ) )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_class: parent provided is not type 'Class', 'Struct', 'Typeanme', or 'Untyped': %s", parent.debug_str() );
|
log_failure( "gen::def_class: parent provided is not type 'Class', 'Struct', 'Typeanme', or 'Untyped': %s", parent.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeClass
|
CodeClass
|
||||||
@ -580,7 +580,7 @@ CodeClass def_class( StrC name
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
log_failure("gen::def_class: body must be either of Class_Body or Untyped type - %s", body.debug_str());
|
log_failure("gen::def_class: body must be either of Class_Body or Untyped type - %s", body.debug_str());
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
result->Type = Class;
|
result->Type = Class;
|
||||||
@ -623,7 +623,7 @@ CodeDefine def_define( StrC name, StrC content )
|
|||||||
if ( content.Len <= 0 || content.Ptr == nullptr )
|
if ( content.Len <= 0 || content.Ptr == nullptr )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_define: Invalid value provided" );
|
log_failure( "gen::def_define: Invalid value provided" );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -648,7 +648,7 @@ CodeDestructor def_destructor( Code body, CodeSpecifiers specifiers )
|
|||||||
if ( specifiers && specifiers->Type != Specifiers )
|
if ( specifiers && specifiers->Type != Specifiers )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_destructor: specifiers was not a 'Specifiers' type: %s", specifiers.debug_str() );
|
log_failure( "gen::def_destructor: specifiers was not a 'Specifiers' type: %s", specifiers.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeDestructor result = (CodeDestructor) make_code();
|
CodeDestructor result = (CodeDestructor) make_code();
|
||||||
@ -666,7 +666,7 @@ CodeDestructor def_destructor( Code body, CodeSpecifiers specifiers )
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
log_failure("gen::def_destructor: body must be either of Function_Body or Untyped type - %s", body.debug_str());
|
log_failure("gen::def_destructor: body must be either of Function_Body or Untyped type - %s", body.debug_str());
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
result->Type = Destructor;
|
result->Type = Destructor;
|
||||||
@ -692,13 +692,13 @@ CodeEnum def_enum( StrC name
|
|||||||
if ( type && type->Type != Typename )
|
if ( type && type->Type != Typename )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_enum: enum underlying type provided was not of type Typename: %s", type.debug_str() );
|
log_failure( "gen::def_enum: enum underlying type provided was not of type Typename: %s", type.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( attributes && attributes->Type != PlatformAttributes )
|
if ( attributes && attributes->Type != PlatformAttributes )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_enum: attributes was not a 'PlatformAttributes' type: %s", attributes.debug_str() );
|
log_failure( "gen::def_enum: attributes was not a 'PlatformAttributes' type: %s", attributes.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeEnum
|
CodeEnum
|
||||||
@ -716,7 +716,7 @@ CodeEnum def_enum( StrC name
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
log_failure( "gen::def_enum: body must be of Enum_Body or Untyped type %s", body.debug_str());
|
log_failure( "gen::def_enum: body must be of Enum_Body or Untyped type %s", body.debug_str());
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
result->Type = specifier == EnumDecl_Class ?
|
result->Type = specifier == EnumDecl_Class ?
|
||||||
@ -740,7 +740,7 @@ CodeEnum def_enum( StrC name
|
|||||||
else if ( result->Type != Enum_Class_Fwd && result->Type != Enum_Fwd )
|
else if ( result->Type != Enum_Class_Fwd && result->Type != Enum_Fwd )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_enum: enum forward declaration must have an underlying type" );
|
log_failure( "gen::def_enum: enum forward declaration must have an underlying type" );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -751,7 +751,7 @@ CodeExec def_execution( StrC content )
|
|||||||
if ( content.Len <= 0 || content.Ptr == nullptr )
|
if ( content.Len <= 0 || content.Ptr == nullptr )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_execution: Invalid execution provided" );
|
log_failure( "gen::def_execution: Invalid execution provided" );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Code
|
Code
|
||||||
@ -773,7 +773,7 @@ CodeExtern def_extern_link( StrC name, Code body )
|
|||||||
if ( body->Type != Extern_Linkage_Body && body->Type != Untyped )
|
if ( body->Type != Extern_Linkage_Body && body->Type != Untyped )
|
||||||
{
|
{
|
||||||
log_failure("gen::def_extern_linkage: body is not of extern_linkage or untyped type %s", body->debug_str());
|
log_failure("gen::def_extern_linkage: body is not of extern_linkage or untyped type %s", body->debug_str());
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeExtern
|
CodeExtern
|
||||||
@ -805,7 +805,7 @@ CodeFriend def_friend( Code declaration )
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
log_failure("gen::def_friend: requires declartion to have class, function, operator, or struct - %s", declaration->debug_str());
|
log_failure("gen::def_friend: requires declartion to have class, function, operator, or struct - %s", declaration->debug_str());
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeFriend
|
CodeFriend
|
||||||
@ -829,25 +829,25 @@ CodeFn def_function( StrC name
|
|||||||
if ( params && params->Type != Parameters )
|
if ( params && params->Type != Parameters )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_function: params was not a `Parameters` type: %s", params.debug_str() );
|
log_failure( "gen::def_function: params was not a `Parameters` type: %s", params.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ret_type && ret_type->Type != Typename )
|
if ( ret_type && ret_type->Type != Typename )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_function: ret_type was not a Typename: %s", ret_type.debug_str() );
|
log_failure( "gen::def_function: ret_type was not a Typename: %s", ret_type.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( specifiers && specifiers->Type != Specifiers )
|
if ( specifiers && specifiers->Type != Specifiers )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_function: specifiers was not a `Specifiers` type: %s", specifiers.debug_str() );
|
log_failure( "gen::def_function: specifiers was not a `Specifiers` type: %s", specifiers.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( attributes && attributes->Type != PlatformAttributes )
|
if ( attributes && attributes->Type != PlatformAttributes )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_function: attributes was not a `PlatformAttributes` type: %s", attributes.debug_str() );
|
log_failure( "gen::def_function: attributes was not a `PlatformAttributes` type: %s", attributes.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeFn
|
CodeFn
|
||||||
@ -867,7 +867,7 @@ CodeFn def_function( StrC name
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
log_failure("gen::def_function: body must be either of Function_Body, Execution, or Untyped type. %s", body->debug_str());
|
log_failure("gen::def_function: body must be either of Function_Body, Execution, or Untyped type. %s", body->debug_str());
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -905,7 +905,7 @@ CodeInclude def_include( StrC path, bool foreign )
|
|||||||
if ( path.Len <= 0 || path.Ptr == nullptr )
|
if ( path.Len <= 0 || path.Ptr == nullptr )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_include: Invalid path provided - %d" );
|
log_failure( "gen::def_include: Invalid path provided - %d" );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
StrC content = foreign ?
|
StrC content = foreign ?
|
||||||
@ -945,7 +945,7 @@ CodeNS def_namespace( StrC name, Code body, ModuleFlag mflags )
|
|||||||
if ( body->Type != Namespace_Body && body->Type != Untyped )
|
if ( body->Type != Namespace_Body && body->Type != Untyped )
|
||||||
{
|
{
|
||||||
log_failure("gen::def_namespace: body is not of namespace or untyped type %s", body.debug_str());
|
log_failure("gen::def_namespace: body is not of namespace or untyped type %s", body.debug_str());
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeNS
|
CodeNS
|
||||||
@ -968,20 +968,20 @@ CodeOperator def_operator( OperatorT op, StrC nspace
|
|||||||
if ( attributes && attributes->Type != PlatformAttributes )
|
if ( attributes && attributes->Type != PlatformAttributes )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_operator: PlatformAttributes was provided but its not of attributes type: %s", attributes.debug_str() );
|
log_failure( "gen::def_operator: PlatformAttributes was provided but its not of attributes type: %s", attributes.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( specifiers && specifiers->Type != Specifiers )
|
if ( specifiers && specifiers->Type != Specifiers )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_operator: Specifiers was provided but its not of specifiers type: %s", specifiers.debug_str() );
|
log_failure( "gen::def_operator: Specifiers was provided but its not of specifiers type: %s", specifiers.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
OpValidateResult check_result = operator__validate( op, params_code, ret_type, specifiers );
|
OpValidateResult check_result = operator__validate( op, params_code, ret_type, specifiers );
|
||||||
|
|
||||||
if ( check_result == OpValidateResult::Fail )
|
if ( check_result == OpValidateResult::Fail )
|
||||||
{
|
{
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
char const* name = nullptr;
|
char const* name = nullptr;
|
||||||
@ -1009,7 +1009,7 @@ CodeOperator def_operator( OperatorT op, StrC nspace
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
log_failure("gen::def_operator: body must be either of Function_Body, Execution, or Untyped type. %s", body->debug_str());
|
log_failure("gen::def_operator: body must be either of Function_Body, Execution, or Untyped type. %s", body->debug_str());
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1046,7 +1046,7 @@ CodeOpCast def_operator_cast( CodeType type, Code body, CodeSpecifiers const_spe
|
|||||||
if ( type->Type != Typename )
|
if ( type->Type != Typename )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_operator_cast: type is not a typename - %s", type.debug_str() );
|
log_failure( "gen::def_operator_cast: type is not a typename - %s", type.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeOpCast result = (CodeOpCast) make_code();
|
CodeOpCast result = (CodeOpCast) make_code();
|
||||||
@ -1058,7 +1058,7 @@ CodeOpCast def_operator_cast( CodeType type, Code body, CodeSpecifiers const_spe
|
|||||||
if ( body->Type != Function_Body && body->Type != Execution )
|
if ( body->Type != Function_Body && body->Type != Execution )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_operator_cast: body is not of function body or execution type - %s", body.debug_str() );
|
log_failure( "gen::def_operator_cast: body is not of function body or execution type - %s", body.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
result->Body = body;
|
result->Body = body;
|
||||||
@ -1087,13 +1087,13 @@ CodeParam def_param( CodeType type, StrC name, Code value )
|
|||||||
if ( type->Type != Typename )
|
if ( type->Type != Typename )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_param: type is not a typename - %s", type.debug_str() );
|
log_failure( "gen::def_param: type is not a typename - %s", type.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( value && value->Type != Untyped )
|
if ( value && value->Type != Untyped )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_param: value is not untyped - %s", value.debug_str() );
|
log_failure( "gen::def_param: value is not untyped - %s", value.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeParam
|
CodeParam
|
||||||
@ -1118,7 +1118,7 @@ CodePragma def_pragma( StrC directive )
|
|||||||
if ( directive.Len <= 0 || directive.Ptr == nullptr )
|
if ( directive.Len <= 0 || directive.Ptr == nullptr )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_comment: Invalid comment provided:" );
|
log_failure( "gen::def_comment: Invalid comment provided:" );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodePragma
|
CodePragma
|
||||||
@ -1136,7 +1136,7 @@ CodePreprocessCond def_preprocess_cond( EPreprocessCond type, StrC expr )
|
|||||||
if ( expr.Len <= 0 || expr.Ptr == nullptr )
|
if ( expr.Len <= 0 || expr.Ptr == nullptr )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_comment: Invalid comment provided:" );
|
log_failure( "gen::def_comment: Invalid comment provided:" );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodePreprocessCond
|
CodePreprocessCond
|
||||||
@ -1184,19 +1184,19 @@ CodeStruct def_struct( StrC name
|
|||||||
if ( attributes && attributes->Type != PlatformAttributes )
|
if ( attributes && attributes->Type != PlatformAttributes )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_struct: attributes was not a `PlatformAttributes` type - %s", attributes.debug_str() );
|
log_failure( "gen::def_struct: attributes was not a `PlatformAttributes` type - %s", attributes.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( parent && parent->Type != Typename )
|
if ( parent && parent->Type != Typename )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_struct: parent was not a `Struct` type - %s", parent.debug_str() );
|
log_failure( "gen::def_struct: parent was not a `Struct` type - %s", parent.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( body && body->Type != Struct_Body )
|
if ( body && body->Type != Struct_Body )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_struct: body was not a Struct_Body type - %s", body.debug_str() );
|
log_failure( "gen::def_struct: body was not a Struct_Body type - %s", body.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeStruct
|
CodeStruct
|
||||||
@ -1243,7 +1243,7 @@ CodeTemplate def_template( CodeParam params, Code declaration, ModuleFlag mflags
|
|||||||
if ( params && params->Type != ECode::Parameters )
|
if ( params && params->Type != ECode::Parameters )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_template: params is not of parameters type - %s", params.debug_str() );
|
log_failure( "gen::def_template: params is not of parameters type - %s", params.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (declaration->Type )
|
switch (declaration->Type )
|
||||||
@ -1276,19 +1276,19 @@ CodeType def_type( StrC name, Code arrayexpr, CodeSpecifiers specifiers, CodeAtt
|
|||||||
if ( attributes && attributes->Type != ECode::PlatformAttributes )
|
if ( attributes && attributes->Type != ECode::PlatformAttributes )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_type: attributes is not of attributes type - %s", attributes.debug_str() );
|
log_failure( "gen::def_type: attributes is not of attributes type - %s", attributes.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( specifiers && specifiers->Type != ECode::Specifiers )
|
if ( specifiers && specifiers->Type != ECode::Specifiers )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_type: specifiers is not of specifiers type - %s", specifiers.debug_str() );
|
log_failure( "gen::def_type: specifiers is not of specifiers type - %s", specifiers.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( arrayexpr && arrayexpr->Type != ECode::Untyped )
|
if ( arrayexpr && arrayexpr->Type != ECode::Untyped )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_type: arrayexpr is not of untyped type - %s", arrayexpr->debug_str() );
|
log_failure( "gen::def_type: arrayexpr is not of untyped type - %s", arrayexpr->debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeType
|
CodeType
|
||||||
@ -1330,13 +1330,13 @@ CodeTypedef def_typedef( StrC name, Code type, CodeAttributes attributes, Module
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log_failure( "gen::def_typedef: type was not a Class, Enum, Function Forward, Struct, Typename, or Union - %s", type.debug_str() );
|
log_failure( "gen::def_typedef: type was not a Class, Enum, Function Forward, Struct, Typename, or Union - %s", type.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( attributes && attributes->Type != ECode::PlatformAttributes )
|
if ( attributes && attributes->Type != ECode::PlatformAttributes )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_typedef: attributes was not a PlatformAttributes - %s", attributes.debug_str() );
|
log_failure( "gen::def_typedef: attributes was not a PlatformAttributes - %s", attributes.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Registering the type.
|
// Registering the type.
|
||||||
@ -1345,7 +1345,7 @@ CodeTypedef def_typedef( StrC name, Code type, CodeAttributes attributes, Module
|
|||||||
if ( ! registered_type )
|
if ( ! registered_type )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_typedef: failed to register type" );
|
log_failure( "gen::def_typedef: failed to register type" );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeTypedef
|
CodeTypedef
|
||||||
@ -1360,7 +1360,7 @@ CodeTypedef def_typedef( StrC name, Code type, CodeAttributes attributes, Module
|
|||||||
if (type->Type != Untyped)
|
if (type->Type != Untyped)
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_typedef: name was empty and type was not untyped (indicating its a function typedef) - %s", type.debug_str() );
|
log_failure( "gen::def_typedef: name was empty and type was not untyped (indicating its a function typedef) - %s", type.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
result->Name = get_cached_string( type->Name );
|
result->Name = get_cached_string( type->Name );
|
||||||
@ -1382,13 +1382,13 @@ CodeUnion def_union( StrC name, Code body, CodeAttributes attributes, ModuleFlag
|
|||||||
if ( body->Type != ECode::Union_Body )
|
if ( body->Type != ECode::Union_Body )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_union: body was not a Union_Body type - %s", body.debug_str() );
|
log_failure( "gen::def_union: body was not a Union_Body type - %s", body.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( attributes && attributes->Type != ECode::PlatformAttributes )
|
if ( attributes && attributes->Type != ECode::PlatformAttributes )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_union: attributes was not a PlatformAttributes type - %s", attributes.debug_str() );
|
log_failure( "gen::def_union: attributes was not a PlatformAttributes type - %s", attributes.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeUnion
|
CodeUnion
|
||||||
@ -1419,13 +1419,13 @@ CodeUsing def_using( StrC name, CodeType type
|
|||||||
if ( ! register_type )
|
if ( ! register_type )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_using: failed to register type" );
|
log_failure( "gen::def_using: failed to register type" );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( attributes && attributes->Type != ECode::PlatformAttributes )
|
if ( attributes && attributes->Type != ECode::PlatformAttributes )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_using: attributes was not a PlatformAttributes type - %s", attributes.debug_str() );
|
log_failure( "gen::def_using: attributes was not a PlatformAttributes type - %s", attributes.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeUsing
|
CodeUsing
|
||||||
@ -1465,25 +1465,25 @@ CodeVar def_variable( CodeType type, StrC name, Code value
|
|||||||
if ( attributes && attributes->Type != ECode::PlatformAttributes )
|
if ( attributes && attributes->Type != ECode::PlatformAttributes )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_variable: attributes was not a `PlatformAttributes` type - %s", attributes.debug_str() );
|
log_failure( "gen::def_variable: attributes was not a `PlatformAttributes` type - %s", attributes.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( specifiers && specifiers->Type != ECode::Specifiers )
|
if ( specifiers && specifiers->Type != ECode::Specifiers )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_variable: specifiers was not a `Specifiers` type - %s", specifiers.debug_str() );
|
log_failure( "gen::def_variable: specifiers was not a `Specifiers` type - %s", specifiers.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( type->Type != ECode::Typename )
|
if ( type->Type != ECode::Typename )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_variable: type was not a Typename - %s", type.debug_str() );
|
log_failure( "gen::def_variable: type was not a Typename - %s", type.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( value && value->Type != ECode::Untyped )
|
if ( value && value->Type != ECode::Untyped )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_variable: value was not a `Untyped` type - %s", value.debug_str() );
|
log_failure( "gen::def_variable: value was not a `Untyped` type - %s", value.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeVar
|
CodeVar
|
||||||
@ -1513,7 +1513,7 @@ using namespace ECode; \
|
|||||||
if ( num <= 0 ) \
|
if ( num <= 0 ) \
|
||||||
{ \
|
{ \
|
||||||
log_failure("gen::" stringize(Name_) ": num cannot be zero or negative"); \
|
log_failure("gen::" stringize(Name_) ": num cannot be zero or negative"); \
|
||||||
return CodeInvalid; \
|
return InvalidCode; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define def_body_code_array_start( Name_ ) \
|
#define def_body_code_array_start( Name_ ) \
|
||||||
@ -1522,13 +1522,13 @@ using namespace ECode; \
|
|||||||
if ( num <= 0 ) \
|
if ( num <= 0 ) \
|
||||||
{ \
|
{ \
|
||||||
log_failure("gen::" stringize(Name_) ": num cannot be zero or negative"); \
|
log_failure("gen::" stringize(Name_) ": num cannot be zero or negative"); \
|
||||||
return CodeInvalid; \
|
return InvalidCode; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
if ( codes == nullptr ) \
|
if ( codes == nullptr ) \
|
||||||
{ \
|
{ \
|
||||||
log_failure("gen::" stringize(Name_)" : Provided a null array of codes"); \
|
log_failure("gen::" stringize(Name_)" : Provided a null array of codes"); \
|
||||||
return CodeInvalid; \
|
return InvalidCode; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma endregion Helper Macros for def_**_body functions
|
#pragma endregion Helper Macros for def_**_body functions
|
||||||
@ -1552,14 +1552,14 @@ CodeBody def_class_body( s32 num, ... )
|
|||||||
log_failure("gen::"
|
log_failure("gen::"
|
||||||
"def_class_body"
|
"def_class_body"
|
||||||
": Provided an null entry");
|
": Provided an null entry");
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (entry->Type)
|
switch (entry->Type)
|
||||||
{
|
{
|
||||||
GEN_AST_BODY_CLASS_UNALLOWED_TYPES
|
GEN_AST_BODY_CLASS_UNALLOWED_TYPES
|
||||||
log_failure("gen::" "def_class_body" ": Entry type is not allowed: %s", entry.debug_str());
|
log_failure("gen::" "def_class_body" ": Entry type is not allowed: %s", entry.debug_str());
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1589,14 +1589,14 @@ CodeBody def_class_body( s32 num, Code* codes )
|
|||||||
if (!entry)
|
if (!entry)
|
||||||
{
|
{
|
||||||
log_failure("gen::" "def_class_body" ": Provided an null entry");
|
log_failure("gen::" "def_class_body" ": Provided an null entry");
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (entry->Type)
|
switch (entry->Type)
|
||||||
{
|
{
|
||||||
GEN_AST_BODY_CLASS_UNALLOWED_TYPES
|
GEN_AST_BODY_CLASS_UNALLOWED_TYPES
|
||||||
log_failure("gen::" "def_class_body" ": Entry type is not allowed: %s", entry.debug_str());
|
log_failure("gen::" "def_class_body" ": Entry type is not allowed: %s", entry.debug_str());
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1627,13 +1627,13 @@ CodeBody def_enum_body( s32 num, ... )
|
|||||||
if ( ! entry )
|
if ( ! entry )
|
||||||
{
|
{
|
||||||
log_failure("gen::def_enum_body: Provided a null entry");
|
log_failure("gen::def_enum_body: Provided a null entry");
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( entry->Type != Untyped && entry->Type != Comment )
|
if ( entry->Type != Untyped && entry->Type != Comment )
|
||||||
{
|
{
|
||||||
log_failure("gen::def_enum_body: Entry type is not allowed - %s. Must be of untyped or comment type.", entry.debug_str() );
|
log_failure("gen::def_enum_body: Entry type is not allowed - %s. Must be of untyped or comment type.", entry.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.append( entry );
|
result.append( entry );
|
||||||
@ -1659,13 +1659,13 @@ CodeBody def_enum_body( s32 num, Code* codes )
|
|||||||
if ( ! entry )
|
if ( ! entry )
|
||||||
{
|
{
|
||||||
log_failure("gen::def_enum_body: Provided a null entry");
|
log_failure("gen::def_enum_body: Provided a null entry");
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( entry->Type != Untyped && entry->Type != Comment )
|
if ( entry->Type != Untyped && entry->Type != Comment )
|
||||||
{
|
{
|
||||||
log_failure("gen::def_enum_body: Entry type is not allowed: %s", entry.debug_str() );
|
log_failure("gen::def_enum_body: Entry type is not allowed: %s", entry.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.append( entry );
|
result.append( entry );
|
||||||
@ -1693,14 +1693,14 @@ CodeBody def_export_body( s32 num, ... )
|
|||||||
if (!entry)
|
if (!entry)
|
||||||
{
|
{
|
||||||
log_failure("gen::" "def_export_body" ": Provided an null entry");
|
log_failure("gen::" "def_export_body" ": Provided an null entry");
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (entry->Type)
|
switch (entry->Type)
|
||||||
{
|
{
|
||||||
GEN_AST_BODY_EXPORT_UNALLOWED_TYPES
|
GEN_AST_BODY_EXPORT_UNALLOWED_TYPES
|
||||||
log_failure("gen::" "def_export_body" ": Entry type is not allowed: %s", entry.debug_str());
|
log_failure("gen::" "def_export_body" ": Entry type is not allowed: %s", entry.debug_str());
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1730,14 +1730,14 @@ CodeBody def_export_body( s32 num, Code* codes )
|
|||||||
if (!entry)
|
if (!entry)
|
||||||
{
|
{
|
||||||
log_failure("gen::" "def_export_body" ": Provided an null entry");
|
log_failure("gen::" "def_export_body" ": Provided an null entry");
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (entry->Type)
|
switch (entry->Type)
|
||||||
{
|
{
|
||||||
GEN_AST_BODY_EXPORT_UNALLOWED_TYPES
|
GEN_AST_BODY_EXPORT_UNALLOWED_TYPES
|
||||||
log_failure("gen::" "def_export_body" ": Entry type is not allowed: %s", entry.debug_str());
|
log_failure("gen::" "def_export_body" ": Entry type is not allowed: %s", entry.debug_str());
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1768,14 +1768,14 @@ CodeBody def_extern_link_body( s32 num, ... )
|
|||||||
if (!entry)
|
if (!entry)
|
||||||
{
|
{
|
||||||
log_failure("gen::" "def_extern_linkage_body" ": Provided an null entry");
|
log_failure("gen::" "def_extern_linkage_body" ": Provided an null entry");
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (entry->Type)
|
switch (entry->Type)
|
||||||
{
|
{
|
||||||
GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES
|
GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES
|
||||||
log_failure("gen::" "def_extern_linkage_body" ": Entry type is not allowed: %s", entry.debug_str());
|
log_failure("gen::" "def_extern_linkage_body" ": Entry type is not allowed: %s", entry.debug_str());
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1805,14 +1805,14 @@ CodeBody def_extern_link_body( s32 num, Code* codes )
|
|||||||
if (!entry)
|
if (!entry)
|
||||||
{
|
{
|
||||||
log_failure("gen::" "def_extern_linkage_body" ": Provided an null entry");
|
log_failure("gen::" "def_extern_linkage_body" ": Provided an null entry");
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (entry->Type)
|
switch (entry->Type)
|
||||||
{
|
{
|
||||||
GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES
|
GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES
|
||||||
log_failure("gen::" "def_extern_linkage_body" ": Entry type is not allowed: %s", entry.debug_str());
|
log_failure("gen::" "def_extern_linkage_body" ": Entry type is not allowed: %s", entry.debug_str());
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1844,7 +1844,7 @@ CodeBody def_function_body( s32 num, ... )
|
|||||||
if (!entry)
|
if (!entry)
|
||||||
{
|
{
|
||||||
log_failure("gen::" stringize(def_function_body) ": Provided an null entry");
|
log_failure("gen::" stringize(def_function_body) ": Provided an null entry");
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (entry->Type)
|
switch (entry->Type)
|
||||||
@ -1852,7 +1852,7 @@ CodeBody def_function_body( s32 num, ... )
|
|||||||
|
|
||||||
GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES
|
GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES
|
||||||
log_failure("gen::" stringize(def_function_body) ": Entry type is not allowed: %s", entry.debug_str());
|
log_failure("gen::" stringize(def_function_body) ": Entry type is not allowed: %s", entry.debug_str());
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1882,14 +1882,14 @@ CodeBody def_function_body( s32 num, Code* codes )
|
|||||||
if (!entry)
|
if (!entry)
|
||||||
{
|
{
|
||||||
log_failure("gen::" "def_function_body" ": Provided an null entry");
|
log_failure("gen::" "def_function_body" ": Provided an null entry");
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (entry->Type)
|
switch (entry->Type)
|
||||||
{
|
{
|
||||||
GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES
|
GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES
|
||||||
log_failure("gen::" "def_function_body" ": Entry type is not allowed: %s", entry.debug_str());
|
log_failure("gen::" "def_function_body" ": Entry type is not allowed: %s", entry.debug_str());
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1919,18 +1919,18 @@ CodeBody def_global_body( s32 num, ... )
|
|||||||
if (!entry)
|
if (!entry)
|
||||||
{
|
{
|
||||||
log_failure("gen::" "def_global_body" ": Provided an null entry");
|
log_failure("gen::" "def_global_body" ": Provided an null entry");
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (entry->Type)
|
switch (entry->Type)
|
||||||
{
|
{
|
||||||
case Global_Body:
|
case Global_Body:
|
||||||
result.append( entry.cast<CodeBody>() ) ;
|
result.append( entry.code_cast<CodeBody>() ) ;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES
|
GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES
|
||||||
log_failure("gen::" "def_global_body" ": Entry type is not allowed: %s", entry.debug_str());
|
log_failure("gen::" "def_global_body" ": Entry type is not allowed: %s", entry.debug_str());
|
||||||
return (*Code::Invalid.ast);
|
return InvalidCode;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1960,18 +1960,18 @@ CodeBody def_global_body( s32 num, Code* codes )
|
|||||||
if (!entry)
|
if (!entry)
|
||||||
{
|
{
|
||||||
log_failure("gen::" "def_global_body" ": Provided an null entry");
|
log_failure("gen::" "def_global_body" ": Provided an null entry");
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (entry->Type)
|
switch (entry->Type)
|
||||||
{
|
{
|
||||||
case Global_Body:
|
case Global_Body:
|
||||||
result.append( entry.cast<CodeBody>() ) ;
|
result.append( entry.code_cast<CodeBody>() ) ;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES
|
GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES
|
||||||
log_failure("gen::" "def_global_body" ": Entry type is not allowed: %s", entry.debug_str());
|
log_failure("gen::" "def_global_body" ": Entry type is not allowed: %s", entry.debug_str());
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -2002,14 +2002,14 @@ CodeBody def_namespace_body( s32 num, ... )
|
|||||||
if (!entry)
|
if (!entry)
|
||||||
{
|
{
|
||||||
log_failure("gen::" "def_namespace_body" ": Provided an null entry");
|
log_failure("gen::" "def_namespace_body" ": Provided an null entry");
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (entry->Type)
|
switch (entry->Type)
|
||||||
{
|
{
|
||||||
GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES
|
GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES
|
||||||
log_failure("gen::" "def_namespace_body" ": Entry type is not allowed: %s", entry.debug_str());
|
log_failure("gen::" "def_namespace_body" ": Entry type is not allowed: %s", entry.debug_str());
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -2039,14 +2039,14 @@ CodeBody def_namespace_body( s32 num, Code* codes )
|
|||||||
if (!entry)
|
if (!entry)
|
||||||
{
|
{
|
||||||
log_failure("gen::" "def_namespace_body" ": Provided an null entry");
|
log_failure("gen::" "def_namespace_body" ": Provided an null entry");
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (entry->Type)
|
switch (entry->Type)
|
||||||
{
|
{
|
||||||
GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES
|
GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES
|
||||||
log_failure("gen::" "def_namespace_body" ": Entry type is not allowed: %s", entry.debug_str() );
|
log_failure("gen::" "def_namespace_body" ": Entry type is not allowed: %s", entry.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
@ -2073,7 +2073,7 @@ CodeParam def_params( s32 num, ... )
|
|||||||
if ( param->Type != Parameters )
|
if ( param->Type != Parameters )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_params: param %d is not a Parameters", num - num + 1 );
|
log_failure( "gen::def_params: param %d is not a Parameters", num - num + 1 );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeParam result = (CodeParam) param.duplicate();
|
CodeParam result = (CodeParam) param.duplicate();
|
||||||
@ -2086,7 +2086,7 @@ CodeParam def_params( s32 num, ... )
|
|||||||
if ( param->Type != Parameters )
|
if ( param->Type != Parameters )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_params: param %d is not a Parameters", num - num + 1 );
|
log_failure( "gen::def_params: param %d is not a Parameters", num - num + 1 );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.append( param );
|
result.append( param );
|
||||||
@ -2104,13 +2104,13 @@ CodeParam def_params( s32 num, CodeParam* codes )
|
|||||||
if ( current.ast == nullptr ) \
|
if ( current.ast == nullptr ) \
|
||||||
{ \
|
{ \
|
||||||
log_failure("gen::def_params: Provide a null code in codes array"); \
|
log_failure("gen::def_params: Provide a null code in codes array"); \
|
||||||
return CodeInvalid; \
|
return InvalidCode; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
if (current->Type != Parameters ) \
|
if (current->Type != Parameters ) \
|
||||||
{ \
|
{ \
|
||||||
log_failure("gen::def_params: Code in coes array is not of paramter type - %s", current.debug_str() ); \
|
log_failure("gen::def_params: Code in coes array is not of paramter type - %s", current.debug_str() ); \
|
||||||
return CodeInvalid; \
|
return InvalidCode; \
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeParam current = (CodeParam) codes->duplicate();
|
CodeParam current = (CodeParam) codes->duplicate();
|
||||||
@ -2137,13 +2137,13 @@ CodeSpecifiers def_specifiers( s32 num, ... )
|
|||||||
if ( num <= 0 )
|
if ( num <= 0 )
|
||||||
{
|
{
|
||||||
log_failure("gen::def_specifiers: num cannot be zero or less");
|
log_failure("gen::def_specifiers: num cannot be zero or less");
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( num > AST::ArrSpecs_Cap )
|
if ( num > AST::ArrSpecs_Cap )
|
||||||
{
|
{
|
||||||
log_failure("gen::def_specifiers: num of speciifers to define AST larger than AST specicifier capacity - %d", num);
|
log_failure("gen::def_specifiers: num of speciifers to define AST larger than AST specicifier capacity - %d", num);
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeSpecifiers
|
CodeSpecifiers
|
||||||
@ -2169,13 +2169,13 @@ CodeSpecifiers def_specifiers( s32 num, SpecifierT* specs )
|
|||||||
if ( num <= 0 )
|
if ( num <= 0 )
|
||||||
{
|
{
|
||||||
log_failure("gen::def_specifiers: num cannot be zero or less");
|
log_failure("gen::def_specifiers: num cannot be zero or less");
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( num > AST::ArrSpecs_Cap )
|
if ( num > AST::ArrSpecs_Cap )
|
||||||
{
|
{
|
||||||
log_failure("gen::def_specifiers: num of speciifers to define AST larger than AST specicifier capacity - %d", num);
|
log_failure("gen::def_specifiers: num of speciifers to define AST larger than AST specicifier capacity - %d", num);
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeSpecifiers
|
CodeSpecifiers
|
||||||
@ -2211,14 +2211,14 @@ CodeBody def_struct_body( s32 num, ... )
|
|||||||
if (!entry)
|
if (!entry)
|
||||||
{
|
{
|
||||||
log_failure("gen::" "def_struct_body" ": Provided an null entry");
|
log_failure("gen::" "def_struct_body" ": Provided an null entry");
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (entry->Type)
|
switch (entry->Type)
|
||||||
{
|
{
|
||||||
GEN_AST_BODY_STRUCT_UNALLOWED_TYPES
|
GEN_AST_BODY_STRUCT_UNALLOWED_TYPES
|
||||||
log_failure("gen::" "def_struct_body" ": Entry type is not allowed: %s", entry.debug_str());
|
log_failure("gen::" "def_struct_body" ": Entry type is not allowed: %s", entry.debug_str());
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -2248,14 +2248,14 @@ CodeBody def_struct_body( s32 num, Code* codes )
|
|||||||
if (!entry)
|
if (!entry)
|
||||||
{
|
{
|
||||||
log_failure("gen::" "def_struct_body" ": Provided an null entry");
|
log_failure("gen::" "def_struct_body" ": Provided an null entry");
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (entry->Type)
|
switch (entry->Type)
|
||||||
{
|
{
|
||||||
GEN_AST_BODY_STRUCT_UNALLOWED_TYPES
|
GEN_AST_BODY_STRUCT_UNALLOWED_TYPES
|
||||||
log_failure("gen::" "def_struct_body" ": Entry type is not allowed: %s", entry.debug_str() );
|
log_failure("gen::" "def_struct_body" ": Entry type is not allowed: %s", entry.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -2286,13 +2286,13 @@ CodeBody def_union_body( s32 num, ... )
|
|||||||
if ( ! entry )
|
if ( ! entry )
|
||||||
{
|
{
|
||||||
log_failure("gen::def_union_body: Provided a null entry");
|
log_failure("gen::def_union_body: Provided a null entry");
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( entry->Type != Untyped && entry->Type != Comment )
|
if ( entry->Type != Untyped && entry->Type != Comment )
|
||||||
{
|
{
|
||||||
log_failure("gen::def_union_body: Entry type is not allowed - %s. Must be of untyped or comment type.", entry.debug_str() );
|
log_failure("gen::def_union_body: Entry type is not allowed - %s. Must be of untyped or comment type.", entry.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.append( entry );
|
result.append( entry );
|
||||||
@ -2318,13 +2318,13 @@ CodeBody def_union_body( s32 num, CodeUnion* codes )
|
|||||||
if ( ! entry )
|
if ( ! entry )
|
||||||
{
|
{
|
||||||
log_failure("gen::def_union_body: Provided a null entry");
|
log_failure("gen::def_union_body: Provided a null entry");
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( entry->Type != Untyped && entry->Type != Comment )
|
if ( entry->Type != Untyped && entry->Type != Comment )
|
||||||
{
|
{
|
||||||
log_failure("gen::def_union_body: Entry type is not allowed: %s", entry.debug_str() );
|
log_failure("gen::def_union_body: Entry type is not allowed: %s", entry.debug_str() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.append( entry );
|
result.append( entry );
|
||||||
|
@ -93,7 +93,7 @@ struct Token
|
|||||||
|
|
||||||
StrC type_str = ETokType::to_str( Type );
|
StrC type_str = ETokType::to_str( Type );
|
||||||
|
|
||||||
append_fmt( result, "Line: %d Column: %d, Type: %.*s Content: %.*s"
|
append_fmt( & result, "Line: %d Column: %d, Type: %.*s Content: %.*s"
|
||||||
, Line, Column
|
, Line, Column
|
||||||
, type_str.Len, type_str.Ptr
|
, type_str.Len, type_str.Ptr
|
||||||
, Length, Text
|
, Length, Text
|
||||||
@ -222,7 +222,7 @@ s32 lex_preprocessor_directive(
|
|||||||
, Token& token )
|
, Token& token )
|
||||||
{
|
{
|
||||||
char const* hash = scanner;
|
char const* hash = scanner;
|
||||||
append(Tokens, { hash, 1, TokType::Preprocess_Hash, line, column, TF_Preprocess } );
|
append( & Tokens, { hash, 1, TokType::Preprocess_Hash, line, column, TF_Preprocess } );
|
||||||
|
|
||||||
move_forward();
|
move_forward();
|
||||||
SkipWhitespace();
|
SkipWhitespace();
|
||||||
@ -298,14 +298,14 @@ s32 lex_preprocessor_directive(
|
|||||||
|
|
||||||
token.Length = token.Length + token.Text - hash;
|
token.Length = token.Length + token.Text - hash;
|
||||||
token.Text = hash;
|
token.Text = hash;
|
||||||
append(Tokens, token );
|
append( & Tokens, token );
|
||||||
return Lex_Continue; // Skip found token, its all handled here.
|
return Lex_Continue; // Skip found token, its all handled here.
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( token.Type == TokType::Preprocess_Else || token.Type == TokType::Preprocess_EndIf )
|
if ( token.Type == TokType::Preprocess_Else || token.Type == TokType::Preprocess_EndIf )
|
||||||
{
|
{
|
||||||
token.Flags |= TF_Preprocess_Cond;
|
token.Flags |= TF_Preprocess_Cond;
|
||||||
append(Tokens, token );
|
append( & Tokens, token );
|
||||||
end_line();
|
end_line();
|
||||||
return Lex_Continue;
|
return Lex_Continue;
|
||||||
}
|
}
|
||||||
@ -314,7 +314,7 @@ s32 lex_preprocessor_directive(
|
|||||||
token.Flags |= TF_Preprocess_Cond;
|
token.Flags |= TF_Preprocess_Cond;
|
||||||
}
|
}
|
||||||
|
|
||||||
append(Tokens, token );
|
append( & Tokens, token );
|
||||||
|
|
||||||
SkipWhitespace();
|
SkipWhitespace();
|
||||||
|
|
||||||
@ -338,10 +338,10 @@ s32 lex_preprocessor_directive(
|
|||||||
name.Length++;
|
name.Length++;
|
||||||
}
|
}
|
||||||
|
|
||||||
append(Tokens, name );
|
append( & Tokens, name );
|
||||||
|
|
||||||
u64 key = crc32( name.Text, name.Length );
|
u64 key = crc32( name.Text, name.Length );
|
||||||
set<StrC>(defines, key, name );
|
set<StrC>(& defines, key, name );
|
||||||
}
|
}
|
||||||
|
|
||||||
Token preprocess_content = { scanner, 0, TokType::Preprocess_Content, line, column, TF_Preprocess };
|
Token preprocess_content = { scanner, 0, TokType::Preprocess_Content, line, column, TF_Preprocess };
|
||||||
@ -384,7 +384,7 @@ s32 lex_preprocessor_directive(
|
|||||||
move_forward();
|
move_forward();
|
||||||
}
|
}
|
||||||
|
|
||||||
append(Tokens, preprocess_content );
|
append( & Tokens, preprocess_content );
|
||||||
return Lex_Continue; // Skip found token, its all handled here.
|
return Lex_Continue; // Skip found token, its all handled here.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,7 +446,7 @@ s32 lex_preprocessor_directive(
|
|||||||
preprocess_content.Length++;
|
preprocess_content.Length++;
|
||||||
}
|
}
|
||||||
|
|
||||||
append(Tokens, preprocess_content );
|
append( & Tokens, preprocess_content );
|
||||||
return Lex_Continue; // Skip found token, its all handled here.
|
return Lex_Continue; // Skip found token, its all handled here.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,7 +461,7 @@ void lex_found_token( StrC& content
|
|||||||
{
|
{
|
||||||
if ( token.Type != TokType::Invalid )
|
if ( token.Type != TokType::Invalid )
|
||||||
{
|
{
|
||||||
append(Tokens, token );
|
append( & Tokens, token );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,7 +488,7 @@ void lex_found_token( StrC& content
|
|||||||
}
|
}
|
||||||
|
|
||||||
token.Type = type;
|
token.Type = type;
|
||||||
append(Tokens, token );
|
append( & Tokens, token );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,7 +498,7 @@ void lex_found_token( StrC& content
|
|||||||
{
|
{
|
||||||
token.Type = type;
|
token.Type = type;
|
||||||
token.Flags |= TF_Specifier;
|
token.Flags |= TF_Specifier;
|
||||||
append(Tokens, token );
|
append( & Tokens, token );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,7 +506,7 @@ void lex_found_token( StrC& content
|
|||||||
if ( type != TokType::Invalid )
|
if ( type != TokType::Invalid )
|
||||||
{
|
{
|
||||||
token.Type = type;
|
token.Type = type;
|
||||||
append(Tokens, token );
|
append( & Tokens, token );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -558,7 +558,7 @@ void lex_found_token( StrC& content
|
|||||||
token.Type = TokType::Identifier;
|
token.Type = TokType::Identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
append(Tokens, token );
|
append( & Tokens, token );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -579,7 +579,7 @@ TokArray lex( StrC content )
|
|||||||
if ( left <= 0 )
|
if ( left <= 0 )
|
||||||
{
|
{
|
||||||
log_failure( "gen::lex: no tokens found (only whitespace provided)" );
|
log_failure( "gen::lex: no tokens found (only whitespace provided)" );
|
||||||
return { { nullptr }, 0 };
|
return { {}, 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach( StringCached, entry, PreprocessorDefines )
|
foreach( StringCached, entry, PreprocessorDefines )
|
||||||
@ -597,7 +597,7 @@ TokArray lex( StrC content )
|
|||||||
}
|
}
|
||||||
|
|
||||||
u64 key = crc32( entry.Data, length );
|
u64 key = crc32( entry.Data, length );
|
||||||
set<StrC>(defines, key, entry );
|
set<StrC>(& defines, key, entry );
|
||||||
}
|
}
|
||||||
|
|
||||||
clear(Tokens);
|
clear(Tokens);
|
||||||
@ -630,7 +630,7 @@ TokArray lex( StrC content )
|
|||||||
token.Type = TokType::NewLine;
|
token.Type = TokType::NewLine;
|
||||||
token.Length++;
|
token.Length++;
|
||||||
|
|
||||||
append(Tokens, token );
|
append( & Tokens, token );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -652,7 +652,7 @@ TokArray lex( StrC content )
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lex_ReturnNull:
|
case Lex_ReturnNull:
|
||||||
return { { nullptr }, 0 };
|
return { {}, 0 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case '.':
|
case '.':
|
||||||
@ -1099,7 +1099,7 @@ TokArray lex( StrC content )
|
|||||||
move_forward();
|
move_forward();
|
||||||
token.Length++;
|
token.Length++;
|
||||||
}
|
}
|
||||||
append(Tokens, token );
|
append( & Tokens, token );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if ( current == '*' )
|
else if ( current == '*' )
|
||||||
@ -1135,7 +1135,7 @@ TokArray lex( StrC content )
|
|||||||
move_forward();
|
move_forward();
|
||||||
token.Length++;
|
token.Length++;
|
||||||
}
|
}
|
||||||
append(Tokens, token );
|
append( & Tokens, token );
|
||||||
// end_line();
|
// end_line();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1256,7 +1256,7 @@ TokArray lex( StrC content )
|
|||||||
if ( num(Tokens) == 0 )
|
if ( num(Tokens) == 0 )
|
||||||
{
|
{
|
||||||
log_failure( "Failed to lex any tokens" );
|
log_failure( "Failed to lex any tokens" );
|
||||||
return { { nullptr }, 0 };
|
return { {}, 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
clear(defines);
|
clear(defines);
|
||||||
|
@ -52,24 +52,24 @@ struct ParseContext
|
|||||||
|
|
||||||
sptr length = scope_start.Length;
|
sptr length = scope_start.Length;
|
||||||
char const* current = scope_start.Text + length;
|
char const* current = scope_start.Text + length;
|
||||||
while ( current <= back(Tokens.Arr).Text && *current != '\n' && length < 74 )
|
while ( current <= back( & Tokens.Arr)->Text && *current != '\n' && length < 74 )
|
||||||
{
|
{
|
||||||
current++;
|
current++;
|
||||||
length++;
|
length++;
|
||||||
}
|
}
|
||||||
|
|
||||||
String line = string_make( GlobalAllocator, { length, scope_start.Text } );
|
String line = string_make( GlobalAllocator, { length, scope_start.Text } );
|
||||||
append_fmt( result, "\tScope : %s\n", line );
|
append_fmt( & result, "\tScope : %s\n", line );
|
||||||
free(line);
|
free(& line);
|
||||||
|
|
||||||
sptr dist = (sptr)last_valid.Text - (sptr)scope_start.Text + 2;
|
sptr dist = (sptr)last_valid.Text - (sptr)scope_start.Text + 2;
|
||||||
sptr length_from_err = dist;
|
sptr length_from_err = dist;
|
||||||
String line_from_err = string_make( GlobalAllocator, { length_from_err, last_valid.Text } );
|
String line_from_err = string_make( GlobalAllocator, { length_from_err, last_valid.Text } );
|
||||||
|
|
||||||
if ( length_from_err < 100 )
|
if ( length_from_err < 100 )
|
||||||
append_fmt(result, "\t(%d, %d):%*c\n", last_valid.Line, last_valid.Column, length_from_err, '^' );
|
append_fmt(& result, "\t(%d, %d):%*c\n", last_valid.Line, last_valid.Column, length_from_err, '^' );
|
||||||
else
|
else
|
||||||
append_fmt(result, "\t(%d, %d)\n", last_valid.Line, last_valid.Column );
|
append_fmt(& result, "\t(%d, %d)\n", last_valid.Line, last_valid.Column );
|
||||||
|
|
||||||
StackNode* curr_scope = Scope;
|
StackNode* curr_scope = Scope;
|
||||||
s32 level = 0;
|
s32 level = 0;
|
||||||
@ -77,11 +77,11 @@ struct ParseContext
|
|||||||
{
|
{
|
||||||
if ( curr_scope->Name )
|
if ( curr_scope->Name )
|
||||||
{
|
{
|
||||||
append_fmt(result, "\t%d: %s, AST Name: %.*s\n", level, curr_scope->ProcName.Ptr, curr_scope->Name.Length, curr_scope->Name.Text );
|
append_fmt(& result, "\t%d: %s, AST Name: %.*s\n", level, curr_scope->ProcName.Ptr, curr_scope->Name.Length, curr_scope->Name.Text );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
append_fmt(result, "\t%d: %s\n", level, curr_scope->ProcName.Ptr );
|
append_fmt(& result, "\t%d: %s\n", level, curr_scope->ProcName.Ptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
curr_scope = curr_scope->Prev;
|
curr_scope = curr_scope->Prev;
|
||||||
@ -132,12 +132,12 @@ bool TokArray::__eat( TokType type )
|
|||||||
internal
|
internal
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
Tokens = array_init_reserve<Token>( allocator_info(LexArena)
|
Tokens = array_init_reserve<Token>( allocator_info( & LexArena)
|
||||||
, ( LexAllocator_Size - sizeof( ArrayHeader ) ) / sizeof(Token)
|
, ( LexAllocator_Size - sizeof( ArrayHeader ) ) / sizeof(Token)
|
||||||
);
|
);
|
||||||
|
|
||||||
fixed_arena_init(defines_map_arena);
|
fixed_arena_init(& defines_map_arena);
|
||||||
defines = hashtable_init_reserve<StrC>( allocator_info(defines_map_arena), 256 );
|
defines = hashtable_init_reserve<StrC>( allocator_info( & defines_map_arena), 256 );
|
||||||
}
|
}
|
||||||
|
|
||||||
internal
|
internal
|
||||||
@ -153,13 +153,13 @@ if ( def.Len <= 0 ) \
|
|||||||
{ \
|
{ \
|
||||||
log_failure( "gen::" stringize(__func__) ": length must greater than 0" ); \
|
log_failure( "gen::" stringize(__func__) ": length must greater than 0" ); \
|
||||||
parser::Context.pop(); \
|
parser::Context.pop(); \
|
||||||
return CodeInvalid; \
|
return InvalidCode; \
|
||||||
} \
|
} \
|
||||||
if ( def.Ptr == nullptr ) \
|
if ( def.Ptr == nullptr ) \
|
||||||
{ \
|
{ \
|
||||||
log_failure( "gen::" stringize(__func__) ": def was null" ); \
|
log_failure( "gen::" stringize(__func__) ": def was null" ); \
|
||||||
parser::Context.pop(); \
|
parser::Context.pop(); \
|
||||||
return CodeInvalid; \
|
return InvalidCode; \
|
||||||
}
|
}
|
||||||
|
|
||||||
# define currtok_noskip Context.Tokens.current( dont_skip_formatting )
|
# define currtok_noskip Context.Tokens.current( dont_skip_formatting )
|
||||||
@ -290,7 +290,7 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
if ( tokleft )
|
if ( tokleft )
|
||||||
move_fwd();
|
move_fwd();
|
||||||
|
|
||||||
append( content, cut_ptr, cut_length );
|
append( & content, cut_ptr, cut_length );
|
||||||
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -312,7 +312,7 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
if ( tokleft )
|
if ( tokleft )
|
||||||
move_fwd();
|
move_fwd();
|
||||||
|
|
||||||
append( content, cut_ptr, cut_length );
|
append( & content, cut_ptr, cut_length );
|
||||||
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -326,7 +326,7 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
scanner += 2;
|
scanner += 2;
|
||||||
tokleft -= 2;
|
tokleft -= 2;
|
||||||
|
|
||||||
append( content, cut_ptr, cut_length );
|
append( & content, cut_ptr, cut_length );
|
||||||
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -345,7 +345,7 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
if (tokleft)
|
if (tokleft)
|
||||||
move_fwd();
|
move_fwd();
|
||||||
|
|
||||||
append( content, cut_ptr, cut_length );
|
append( & content, cut_ptr, cut_length );
|
||||||
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -354,10 +354,10 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
if (scanner[0] == '\t')
|
if (scanner[0] == '\t')
|
||||||
{
|
{
|
||||||
if (pos > last_cut)
|
if (pos > last_cut)
|
||||||
append( content, cut_ptr, cut_length);
|
append( & content, cut_ptr, cut_length);
|
||||||
|
|
||||||
if ( back( content ) != ' ' )
|
if ( * back( & content ) != ' ' )
|
||||||
append( content, ' ');
|
append( & content, ' ');
|
||||||
|
|
||||||
move_fwd();
|
move_fwd();
|
||||||
last_cut = sptr(scanner) - sptr(raw_text.Ptr);
|
last_cut = sptr(scanner) - sptr(raw_text.Ptr);
|
||||||
@ -373,17 +373,17 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
scanner += 2;
|
scanner += 2;
|
||||||
tokleft -= 2;
|
tokleft -= 2;
|
||||||
|
|
||||||
append( content, cut_ptr, cut_length );
|
append( & content, cut_ptr, cut_length );
|
||||||
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pos > last_cut )
|
if ( pos > last_cut )
|
||||||
append( content, cut_ptr, cut_length );
|
append( & content, cut_ptr, cut_length );
|
||||||
|
|
||||||
// Replace with a space
|
// Replace with a space
|
||||||
if ( back( content ) != ' ' )
|
if ( * back( & content ) != ' ' )
|
||||||
append( content, ' ' );
|
append( & content, ' ' );
|
||||||
|
|
||||||
scanner += 2;
|
scanner += 2;
|
||||||
tokleft -= 2;
|
tokleft -= 2;
|
||||||
@ -400,17 +400,17 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
|
|
||||||
move_fwd();
|
move_fwd();
|
||||||
|
|
||||||
append( content, cut_ptr, cut_length );
|
append( & content, cut_ptr, cut_length );
|
||||||
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pos > last_cut )
|
if ( pos > last_cut )
|
||||||
append( content, cut_ptr, cut_length );
|
append( & content, cut_ptr, cut_length );
|
||||||
|
|
||||||
// Replace with a space
|
// Replace with a space
|
||||||
if ( back( content ) != ' ' )
|
if ( * back( & content ) != ' ' )
|
||||||
append( content, ' ' );
|
append( & content, ' ' );
|
||||||
|
|
||||||
move_fwd();
|
move_fwd();
|
||||||
|
|
||||||
@ -421,7 +421,7 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
// Escaped newlines
|
// Escaped newlines
|
||||||
if ( scanner[0] == '\\' )
|
if ( scanner[0] == '\\' )
|
||||||
{
|
{
|
||||||
append( content, cut_ptr, cut_length );
|
append( & content, cut_ptr, cut_length );
|
||||||
|
|
||||||
s32 amount_to_skip = 1;
|
s32 amount_to_skip = 1;
|
||||||
if ( tokleft > 1 && scanner[1] == '\n' )
|
if ( tokleft > 1 && scanner[1] == '\n' )
|
||||||
@ -448,7 +448,7 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
// Consectuive spaces
|
// Consectuive spaces
|
||||||
if ( tokleft > 1 && char_is_space( scanner[0] ) && char_is_space( scanner[ 1 ] ) )
|
if ( tokleft > 1 && char_is_space( scanner[0] ) && char_is_space( scanner[ 1 ] ) )
|
||||||
{
|
{
|
||||||
append( content, cut_ptr, cut_length );
|
append( & content, cut_ptr, cut_length );
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
move_fwd();
|
move_fwd();
|
||||||
@ -458,8 +458,9 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
||||||
|
|
||||||
// Preserve only 1 space of formattting
|
// Preserve only 1 space of formattting
|
||||||
if ( back( content ) != ' ' )
|
char* last = back(& content);
|
||||||
append( content, ' ' );
|
if ( last == nullptr || * last != ' ' )
|
||||||
|
append( & content, ' ' );
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -469,7 +470,7 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
|
|
||||||
if ( last_cut < raw_text.Len )
|
if ( last_cut < raw_text.Len )
|
||||||
{
|
{
|
||||||
append( content, cut_ptr, raw_text.Len - last_cut );
|
append( & content, cut_ptr, raw_text.Len - last_cut );
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef cut_ptr
|
#undef cut_ptr
|
||||||
@ -504,14 +505,14 @@ Code parse_array_decl()
|
|||||||
{
|
{
|
||||||
log_failure( "Error, unexpected end of array declaration ( '[]' scope started )\n%s", Context.to_string() );
|
log_failure( "Error, unexpected end of array declaration ( '[]' scope started )\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( currtok.Type == TokType::BraceSquare_Close )
|
if ( currtok.Type == TokType::BraceSquare_Close )
|
||||||
{
|
{
|
||||||
log_failure( "Error, empty array expression in definition\n%s", Context.to_string() );
|
log_failure( "Error, empty array expression in definition\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token untyped_tok = currtok;
|
Token untyped_tok = currtok;
|
||||||
@ -530,14 +531,14 @@ Code parse_array_decl()
|
|||||||
{
|
{
|
||||||
log_failure( "Error, unexpected end of array declaration, expected ]\n%s", Context.to_string() );
|
log_failure( "Error, unexpected end of array declaration, expected ]\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( currtok.Type != TokType::BraceSquare_Close )
|
if ( currtok.Type != TokType::BraceSquare_Close )
|
||||||
{
|
{
|
||||||
log_failure( "%s: Error, expected ] in array declaration, not %s\n%s", ETokType::to_str( currtok.Type ), Context.to_string() );
|
log_failure( "%s: Error, expected ] in array declaration, not %s\n%s", ETokType::to_str( currtok.Type ), Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
eat( TokType::BraceSquare_Close );
|
eat( TokType::BraceSquare_Close );
|
||||||
@ -677,7 +678,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false )
|
|||||||
if ( which != TokType::Decl_Class && which != TokType::Decl_Struct )
|
if ( which != TokType::Decl_Class && which != TokType::Decl_Struct )
|
||||||
{
|
{
|
||||||
log_failure( "Error, expected class or struct, not %s\n%s", ETokType::to_str( which ), Context.to_string() );
|
log_failure( "Error, expected class or struct, not %s\n%s", ETokType::to_str( which ), Context.to_string() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token name { nullptr, 0, TokType::Invalid };
|
Token name { nullptr, 0, TokType::Invalid };
|
||||||
@ -688,7 +689,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false )
|
|||||||
CodeAttributes attributes = { nullptr };
|
CodeAttributes attributes = { nullptr };
|
||||||
ModuleFlag mflags = ModuleFlag_None;
|
ModuleFlag mflags = ModuleFlag_None;
|
||||||
|
|
||||||
CodeClass result = CodeInvalid;
|
CodeClass result = InvalidCode;
|
||||||
|
|
||||||
if ( check(TokType::Module_Export) )
|
if ( check(TokType::Module_Export) )
|
||||||
{
|
{
|
||||||
@ -714,7 +715,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false )
|
|||||||
char interface_arr_mem[ kilobytes(4) ] {0};
|
char interface_arr_mem[ kilobytes(4) ] {0};
|
||||||
Array<CodeType> interfaces; {
|
Array<CodeType> interfaces; {
|
||||||
Arena arena = arena_init_from_memory( interface_arr_mem, kilobytes(4) );
|
Arena arena = arena_init_from_memory( interface_arr_mem, kilobytes(4) );
|
||||||
interfaces = array_init_reserve<CodeType>( allocator_info(arena), 4 );
|
interfaces = array_init_reserve<CodeType>( allocator_info(& arena), 4 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(Ed) : Make an AST_DerivedType, we'll store any arbitary derived type into there as a linear linked list of them.
|
// TODO(Ed) : Make an AST_DerivedType, we'll store any arbitary derived type into there as a linear linked list of them.
|
||||||
@ -745,7 +746,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false )
|
|||||||
}
|
}
|
||||||
Token interface_tok = parse_identifier();
|
Token interface_tok = parse_identifier();
|
||||||
|
|
||||||
append(interfaces, def_type( interface_tok ) );
|
append( & interfaces, def_type( interface_tok ) );
|
||||||
// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Name>, ...
|
// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Name>, ...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -777,7 +778,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false )
|
|||||||
if ( inline_cmt )
|
if ( inline_cmt )
|
||||||
result->InlineCmt = inline_cmt;
|
result->InlineCmt = inline_cmt;
|
||||||
|
|
||||||
free(interfaces);
|
free(& interfaces);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -801,7 +802,7 @@ CodeBody parse_class_struct_body( TokType which, Token name )
|
|||||||
|
|
||||||
while ( left && currtok_noskip.Type != TokType::BraceCurly_Close )
|
while ( left && currtok_noskip.Type != TokType::BraceCurly_Close )
|
||||||
{
|
{
|
||||||
Code member = Code::Invalid;
|
Code member = Code_Invalid;
|
||||||
CodeAttributes attributes = { nullptr };
|
CodeAttributes attributes = { nullptr };
|
||||||
CodeSpecifiers specifiers = { nullptr };
|
CodeSpecifiers specifiers = { nullptr };
|
||||||
|
|
||||||
@ -900,7 +901,7 @@ CodeBody parse_class_struct_body( TokType which, Token name )
|
|||||||
if ( currtok.Text[0] != '~' )
|
if ( currtok.Text[0] != '~' )
|
||||||
{
|
{
|
||||||
log_failure( "Operator token found in global body but not destructor unary negation\n%s", Context.to_string() );
|
log_failure( "Operator token found in global body but not destructor unary negation\n%s", Context.to_string() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
member = parse_destructor();
|
member = parse_destructor();
|
||||||
@ -1014,7 +1015,7 @@ CodeBody parse_class_struct_body( TokType which, Token name )
|
|||||||
default:
|
default:
|
||||||
log_failure( "Invalid specifier %s for variable\n%s", ESpecifier::to_str(spec), Context.to_string() );
|
log_failure( "Invalid specifier %s for variable\n%s", ESpecifier::to_str(spec), Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Every specifier after would be considered part of the type type signature
|
// Every specifier after would be considered part of the type type signature
|
||||||
@ -1040,7 +1041,7 @@ CodeBody parse_class_struct_body( TokType which, Token name )
|
|||||||
if ( attributes )
|
if ( attributes )
|
||||||
{
|
{
|
||||||
String fused = string_make_reserve( GlobalAllocator, length(attributes->Content) + length(more_attributes->Content) );
|
String fused = string_make_reserve( GlobalAllocator, length(attributes->Content) + length(more_attributes->Content) );
|
||||||
append_fmt( fused, "%S %S", attributes->Content, more_attributes->Content );
|
append_fmt( & fused, "%S %S", attributes->Content, more_attributes->Content );
|
||||||
|
|
||||||
attributes->Name = get_cached_string(fused);
|
attributes->Name = get_cached_string(fused);
|
||||||
attributes->Content = attributes->Name;
|
attributes->Content = attributes->Name;
|
||||||
@ -1107,11 +1108,11 @@ CodeBody parse_class_struct_body( TokType which, Token name )
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( member == Code::Invalid )
|
if ( member == Code_Invalid )
|
||||||
{
|
{
|
||||||
log_failure( "Failed to parse member\n%s", Context.to_string() );
|
log_failure( "Failed to parse member\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.append( member );
|
result.append( member );
|
||||||
@ -1199,7 +1200,7 @@ Code parse_complicated_definition( TokType which )
|
|||||||
|
|
||||||
log_failure( "Unsupported or bad member definition after %s declaration\n%s", to_str(which), Context.to_string() );
|
log_failure( "Unsupported or bad member definition after %s declaration\n%s", to_str(which), Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
if ( tok.Type == TokType::Identifier )
|
if ( tok.Type == TokType::Identifier )
|
||||||
{
|
{
|
||||||
@ -1244,7 +1245,7 @@ Code parse_complicated_definition( TokType which )
|
|||||||
{
|
{
|
||||||
log_failure( "Unsupported or bad member definition after %s declaration\n%s", to_str(which), Context.to_string() );
|
log_failure( "Unsupported or bad member definition after %s declaration\n%s", to_str(which), Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Code result = parse_operator_function_or_variable( false, { nullptr }, { nullptr } );
|
Code result = parse_operator_function_or_variable( false, { nullptr }, { nullptr } );
|
||||||
@ -1263,7 +1264,7 @@ Code parse_complicated_definition( TokType which )
|
|||||||
{
|
{
|
||||||
log_failure( "Unsupported or bad member definition after %s declaration\n%s", to_str(which), Context.to_string() );
|
log_failure( "Unsupported or bad member definition after %s declaration\n%s", to_str(which), Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Its a forward declaration of an enum class
|
// Its a forward declaration of an enum class
|
||||||
@ -1293,7 +1294,7 @@ Code parse_complicated_definition( TokType which )
|
|||||||
{
|
{
|
||||||
log_failure( "Unsupported or bad member definition after %s declaration\n%S", to_str(which).Ptr, Context.to_string() );
|
log_failure( "Unsupported or bad member definition after %s declaration\n%S", to_str(which).Ptr, Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1312,7 +1313,7 @@ CodeDefine parse_define()
|
|||||||
{
|
{
|
||||||
log_failure( "Error, expected identifier after #define\n%s", Context.to_string() );
|
log_failure( "Error, expected identifier after #define\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Context.Scope->Name = currtok;
|
Context.Scope->Name = currtok;
|
||||||
@ -1324,7 +1325,7 @@ CodeDefine parse_define()
|
|||||||
{
|
{
|
||||||
log_failure( "Error, expected content after #define %s\n%s", define->Name, Context.to_string() );
|
log_failure( "Error, expected content after #define %s\n%s", define->Name, Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( currtok.Length == 0 )
|
if ( currtok.Length == 0 )
|
||||||
@ -1359,7 +1360,7 @@ Code parse_assignment_expression()
|
|||||||
{
|
{
|
||||||
log_failure( "Expected expression after assignment operator\n%s", Context.to_string() );
|
log_failure( "Expected expression after assignment operator\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 level = 0;
|
s32 level = 0;
|
||||||
@ -1386,7 +1387,7 @@ Code parse_assignment_expression()
|
|||||||
internal inline
|
internal inline
|
||||||
Code parse_forward_or_definition( TokType which, bool is_inplace )
|
Code parse_forward_or_definition( TokType which, bool is_inplace )
|
||||||
{
|
{
|
||||||
Code result = CodeInvalid;
|
Code result = InvalidCode;
|
||||||
|
|
||||||
switch ( which )
|
switch ( which )
|
||||||
{
|
{
|
||||||
@ -1411,7 +1412,7 @@ Code parse_forward_or_definition( TokType which, bool is_inplace )
|
|||||||
"(only supports class, enum, struct, union) \n%s"
|
"(only supports class, enum, struct, union) \n%s"
|
||||||
, Context.to_string() );
|
, Context.to_string() );
|
||||||
|
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1449,10 +1450,10 @@ CodeFn parse_function_after_name(
|
|||||||
if ( check( TokType::BraceCurly_Open ) )
|
if ( check( TokType::BraceCurly_Open ) )
|
||||||
{
|
{
|
||||||
body = parse_function_body();
|
body = parse_function_body();
|
||||||
if ( body == Code::Invalid )
|
if ( body == Code_Invalid )
|
||||||
{
|
{
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> { <Body> }
|
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> { <Body> }
|
||||||
}
|
}
|
||||||
@ -1504,7 +1505,7 @@ CodeFn parse_function_after_name(
|
|||||||
{
|
{
|
||||||
log_failure("Body must be either of Function_Body or Untyped type, %s\n%s", body.debug_str(), Context.to_string());
|
log_failure("Body must be either of Function_Body or Untyped type, %s\n%s", body.debug_str(), Context.to_string());
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1584,7 +1585,7 @@ CodeBody parse_global_nspace( CodeT which )
|
|||||||
push_scope();
|
push_scope();
|
||||||
|
|
||||||
if ( which != Namespace_Body && which != Global_Body && which != Export_Body && which != Extern_Linkage_Body )
|
if ( which != Namespace_Body && which != Global_Body && which != Export_Body && which != Extern_Linkage_Body )
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
if ( which != Global_Body )
|
if ( which != Global_Body )
|
||||||
eat( TokType::BraceCurly_Open );
|
eat( TokType::BraceCurly_Open );
|
||||||
@ -1596,7 +1597,7 @@ CodeBody parse_global_nspace( CodeT which )
|
|||||||
|
|
||||||
while ( left && currtok_noskip.Type != TokType::BraceCurly_Close )
|
while ( left && currtok_noskip.Type != TokType::BraceCurly_Close )
|
||||||
{
|
{
|
||||||
Code member = Code::Invalid;
|
Code member = Code_Invalid;
|
||||||
CodeAttributes attributes = { nullptr };
|
CodeAttributes attributes = { nullptr };
|
||||||
CodeSpecifiers specifiers = { nullptr };
|
CodeSpecifiers specifiers = { nullptr };
|
||||||
|
|
||||||
@ -1797,7 +1798,7 @@ CodeBody parse_global_nspace( CodeT which )
|
|||||||
|
|
||||||
log_failure( "Invalid specifier %.*s for variable\n%s", spec_str.Len, spec_str, Context.to_string() );
|
log_failure( "Invalid specifier %.*s for variable\n%s", spec_str.Len, spec_str, Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ignore_spec)
|
if (ignore_spec)
|
||||||
@ -1869,11 +1870,11 @@ CodeBody parse_global_nspace( CodeT which )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( member == Code::Invalid )
|
if ( member == Code_Invalid )
|
||||||
{
|
{
|
||||||
log_failure( "Failed to parse member\n%s", Context.to_string() );
|
log_failure( "Failed to parse member\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// log_fmt("Global Body Member: %s", member->debug_str());
|
// log_fmt("Global Body Member: %s", member->debug_str());
|
||||||
@ -2107,7 +2108,7 @@ CodeInclude parse_include()
|
|||||||
{
|
{
|
||||||
log_failure( "Error, expected include string after #include\n%s", Context.to_string() );
|
log_failure( "Error, expected include string after #include\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Context.Scope->Name = currtok;
|
Context.Scope->Name = currtok;
|
||||||
@ -2156,7 +2157,7 @@ CodeOperator parse_operator_after_ret_type(
|
|||||||
{
|
{
|
||||||
log_failure( "Expected operator after 'operator' keyword\n%s", Context.to_string() );
|
log_failure( "Expected operator after 'operator' keyword\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Context.Scope->Name = currtok;
|
Context.Scope->Name = currtok;
|
||||||
@ -2409,7 +2410,7 @@ CodeOperator parse_operator_after_ret_type(
|
|||||||
{
|
{
|
||||||
log_failure( "Invalid operator '%s'\n%s", prevtok.Text, Context.to_string() );
|
log_failure( "Invalid operator '%s'\n%s", prevtok.Text, Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2419,7 +2420,7 @@ CodeOperator parse_operator_after_ret_type(
|
|||||||
{
|
{
|
||||||
log_failure( "Invalid operator '%s'\n%s", currtok.Text, Context.to_string() );
|
log_failure( "Invalid operator '%s'\n%s", currtok.Text, Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! was_new_or_delete)
|
if ( ! was_new_or_delete)
|
||||||
@ -2453,10 +2454,10 @@ CodeOperator parse_operator_after_ret_type(
|
|||||||
if ( check( TokType::BraceCurly_Open ) )
|
if ( check( TokType::BraceCurly_Open ) )
|
||||||
{
|
{
|
||||||
body = parse_function_body();
|
body = parse_function_body();
|
||||||
if ( body == Code::Invalid )
|
if ( body == Code_Invalid )
|
||||||
{
|
{
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> ( <Parameters> ) <Specifiers> { ... }
|
// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> ( <Parameters> ) <Specifiers> { ... }
|
||||||
}
|
}
|
||||||
@ -2486,7 +2487,7 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes
|
|||||||
{
|
{
|
||||||
push_scope();
|
push_scope();
|
||||||
|
|
||||||
Code result = CodeInvalid;
|
Code result = InvalidCode;
|
||||||
|
|
||||||
#ifndef GEN_PARSER_DISABLE_MACRO_FUNCTION_SIGNATURES
|
#ifndef GEN_PARSER_DISABLE_MACRO_FUNCTION_SIGNATURES
|
||||||
if ( currtok.Type == TokType::Preprocess_Macro )
|
if ( currtok.Type == TokType::Preprocess_Macro )
|
||||||
@ -2502,10 +2503,10 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes
|
|||||||
CodeType type = parse_type();
|
CodeType type = parse_type();
|
||||||
// <Attributes> <Specifiers> <ReturnType/ValueType>
|
// <Attributes> <Specifiers> <ReturnType/ValueType>
|
||||||
|
|
||||||
if ( type == CodeInvalid )
|
if ( type == InvalidCode )
|
||||||
{
|
{
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool found_operator = false;
|
bool found_operator = false;
|
||||||
@ -2561,7 +2562,7 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes
|
|||||||
{
|
{
|
||||||
log_failure( "Expected function declaration (consteval was used)\n%s", Context.to_string() );
|
log_failure( "Expected function declaration (consteval was used)\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dealing with a variable
|
// Dealing with a variable
|
||||||
@ -2589,7 +2590,7 @@ CodePragma parse_pragma()
|
|||||||
{
|
{
|
||||||
log_failure( "Error, expected content after #pragma\n%s", Context.to_string() );
|
log_failure( "Error, expected content after #pragma\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Context.Scope->Name = currtok;
|
Context.Scope->Name = currtok;
|
||||||
@ -2666,10 +2667,10 @@ CodeParam parse_params( bool use_template_capture )
|
|||||||
if ( currtok.Type != TokType::Comma )
|
if ( currtok.Type != TokType::Comma )
|
||||||
{
|
{
|
||||||
type = parse_type( use_template_capture );
|
type = parse_type( use_template_capture );
|
||||||
if ( type == Code::Invalid )
|
if ( type == Code_Invalid )
|
||||||
{
|
{
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
// ( <Macro> <ValueType>
|
// ( <Macro> <ValueType>
|
||||||
|
|
||||||
@ -2703,7 +2704,7 @@ CodeParam parse_params( bool use_template_capture )
|
|||||||
{
|
{
|
||||||
log_failure( "Expected value after assignment operator\n%s.", Context.to_string() );
|
log_failure( "Expected value after assignment operator\n%s.", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 capture_level = 0;
|
s32 capture_level = 0;
|
||||||
@ -2776,10 +2777,10 @@ CodeParam parse_params( bool use_template_capture )
|
|||||||
if ( currtok.Type != TokType::Comma )
|
if ( currtok.Type != TokType::Comma )
|
||||||
{
|
{
|
||||||
type = parse_type( use_template_capture );
|
type = parse_type( use_template_capture );
|
||||||
if ( type == Code::Invalid )
|
if ( type == Code_Invalid )
|
||||||
{
|
{
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType>
|
// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType>
|
||||||
|
|
||||||
@ -2815,7 +2816,7 @@ CodeParam parse_params( bool use_template_capture )
|
|||||||
{
|
{
|
||||||
log_failure( "Expected value after assignment operator\n%s", Context.to_string() );
|
log_failure( "Expected value after assignment operator\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 capture_level = 0;
|
s32 capture_level = 0;
|
||||||
@ -2876,7 +2877,7 @@ CodeParam parse_params( bool use_template_capture )
|
|||||||
{
|
{
|
||||||
log_failure( "Expected '<' after 'template' keyword\n%s", Context.to_string() );
|
log_failure( "Expected '<' after 'template' keyword\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
eat( TokType::Operator );
|
eat( TokType::Operator );
|
||||||
// < <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> = <Expression>, .. >
|
// < <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> = <Expression>, .. >
|
||||||
@ -2896,7 +2897,7 @@ CodePreprocessCond parse_preprocess_cond()
|
|||||||
{
|
{
|
||||||
log_failure( "Error, expected preprocess conditional\n%s", Context.to_string() );
|
log_failure( "Error, expected preprocess conditional\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodePreprocessCond
|
CodePreprocessCond
|
||||||
@ -2909,7 +2910,7 @@ CodePreprocessCond parse_preprocess_cond()
|
|||||||
{
|
{
|
||||||
log_failure( "Error, expected content after #define\n%s", Context.to_string() );
|
log_failure( "Error, expected content after #define\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Context.Scope->Name = currtok;
|
Context.Scope->Name = currtok;
|
||||||
@ -3167,7 +3168,7 @@ CodeVar parse_variable_after_name(
|
|||||||
{
|
{
|
||||||
log_failure( "Expected expression after bitfield \n%s", Context.to_string() );
|
log_failure( "Expected expression after bitfield \n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ( left && currtok.Type != TokType::Statement_End )
|
while ( left && currtok.Type != TokType::Statement_End )
|
||||||
@ -3465,7 +3466,7 @@ CodeDestructor parse_destructor( CodeSpecifiers specifiers )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
log_failure( "Expected destructor '~' token\n%s", Context.to_string() );
|
log_failure( "Expected destructor '~' token\n%s", Context.to_string() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
// <Virtual Specifier> ~
|
// <Virtual Specifier> ~
|
||||||
|
|
||||||
@ -3502,7 +3503,7 @@ CodeDestructor parse_destructor( CodeSpecifiers specifiers )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
log_failure( "Pure or default specifier expected due to '=' token\n%s", Context.to_string() );
|
log_failure( "Pure or default specifier expected due to '=' token\n%s", Context.to_string() );
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
pure_virtual = true;
|
pure_virtual = true;
|
||||||
@ -3597,11 +3598,11 @@ CodeEnum parse_enum( bool inplace_def )
|
|||||||
// enum <class> <Attributes> <Name> :
|
// enum <class> <Attributes> <Name> :
|
||||||
|
|
||||||
type = parse_type();
|
type = parse_type();
|
||||||
if ( type == Code::Invalid )
|
if ( type == Code_Invalid )
|
||||||
{
|
{
|
||||||
log_failure( "Failed to parse enum classifier\n%s", Context.to_string() );
|
log_failure( "Failed to parse enum classifier\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
// enum <class> <Attributes> <Name> : <UnderlyingType>
|
// enum <class> <Attributes> <Name> : <UnderlyingType>
|
||||||
}
|
}
|
||||||
@ -3627,7 +3628,7 @@ CodeEnum parse_enum( bool inplace_def )
|
|||||||
eat( TokType::BraceCurly_Open );
|
eat( TokType::BraceCurly_Open );
|
||||||
// enum <class> <Attributes> <Name> : <UnderlyingType> {
|
// enum <class> <Attributes> <Name> : <UnderlyingType> {
|
||||||
|
|
||||||
Code member = CodeInvalid;
|
Code member = InvalidCode;
|
||||||
|
|
||||||
bool expects_entry = true;
|
bool expects_entry = true;
|
||||||
while ( left && currtok_noskip.Type != TokType::BraceCurly_Close )
|
while ( left && currtok_noskip.Type != TokType::BraceCurly_Close )
|
||||||
@ -3735,11 +3736,11 @@ CodeEnum parse_enum( bool inplace_def )
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( member == Code::Invalid )
|
if ( member == Code_Invalid )
|
||||||
{
|
{
|
||||||
log_failure( "Failed to parse member\n%s", Context.to_string() );
|
log_failure( "Failed to parse member\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.append( member );
|
body.append( member );
|
||||||
@ -3838,7 +3839,7 @@ CodeExtern parse_extern_link()
|
|||||||
result->Name = get_cached_string( name );
|
result->Name = get_cached_string( name );
|
||||||
|
|
||||||
Code entry = parse_extern_link_body();
|
Code entry = parse_extern_link_body();
|
||||||
if ( entry == Code::Invalid )
|
if ( entry == Code_Invalid )
|
||||||
{
|
{
|
||||||
log_failure( "Failed to parse body\n%s", Context.to_string() );
|
log_failure( "Failed to parse body\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
@ -3865,10 +3866,10 @@ CodeFriend parse_friend()
|
|||||||
|
|
||||||
// Type declaration or return type
|
// Type declaration or return type
|
||||||
CodeType type = parse_type();
|
CodeType type = parse_type();
|
||||||
if ( type == Code::Invalid )
|
if ( type == Code_Invalid )
|
||||||
{
|
{
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
// friend <Type>
|
// friend <Type>
|
||||||
|
|
||||||
@ -3965,7 +3966,7 @@ CodeFn parse_function()
|
|||||||
default:
|
default:
|
||||||
log_failure( "Invalid specifier %s for functon\n%s", ESpecifier::to_str(spec), Context.to_string() );
|
log_failure( "Invalid specifier %s for functon\n%s", ESpecifier::to_str(spec), Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( spec == ESpecifier::Const )
|
if ( spec == ESpecifier::Const )
|
||||||
@ -3983,10 +3984,10 @@ CodeFn parse_function()
|
|||||||
// <export> <Attributes> <Specifiers>
|
// <export> <Attributes> <Specifiers>
|
||||||
|
|
||||||
CodeType ret_type = parse_type();
|
CodeType ret_type = parse_type();
|
||||||
if ( ret_type == Code::Invalid )
|
if ( ret_type == Code_Invalid )
|
||||||
{
|
{
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
// <export> <Attributes> <Specifiers> <ReturnType>
|
// <export> <Attributes> <Specifiers> <ReturnType>
|
||||||
|
|
||||||
@ -3995,7 +3996,7 @@ CodeFn parse_function()
|
|||||||
if ( ! name )
|
if ( ! name )
|
||||||
{
|
{
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
// <export> <Attributes> <Specifiers> <ReturnType> <Name>
|
// <export> <Attributes> <Specifiers> <ReturnType> <Name>
|
||||||
|
|
||||||
@ -4019,10 +4020,10 @@ CodeNS parse_namespace()
|
|||||||
// namespace <Name>
|
// namespace <Name>
|
||||||
|
|
||||||
CodeBody body = parse_global_nspace( ECode::Namespace_Body );
|
CodeBody body = parse_global_nspace( ECode::Namespace_Body );
|
||||||
if ( body == Code::Invalid )
|
if ( body == Code_Invalid )
|
||||||
{
|
{
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
// namespace <Name> { <Body> }
|
// namespace <Name> { <Body> }
|
||||||
|
|
||||||
@ -4076,7 +4077,7 @@ CodeOperator parse_operator()
|
|||||||
default:
|
default:
|
||||||
log_failure( "Invalid specifier " "%s" " for operator\n%s", ESpecifier::to_str(spec), Context.to_string() );
|
log_failure( "Invalid specifier " "%s" " for operator\n%s", ESpecifier::to_str(spec), Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( spec == ESpecifier::Const )
|
if ( spec == ESpecifier::Const )
|
||||||
@ -4245,10 +4246,10 @@ CodeTemplate parse_template()
|
|||||||
// <export> template
|
// <export> template
|
||||||
|
|
||||||
Code params = parse_params( UseTemplateCapture );
|
Code params = parse_params( UseTemplateCapture );
|
||||||
if ( params == Code::Invalid )
|
if ( params == Code_Invalid )
|
||||||
{
|
{
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
// <export> template< <Parameters> >
|
// <export> template< <Parameters> >
|
||||||
|
|
||||||
@ -4327,7 +4328,7 @@ CodeTemplate parse_template()
|
|||||||
default :
|
default :
|
||||||
log_failure( "Invalid specifier %s for variable or function\n%s", ESpecifier::to_str( spec ), Context.to_string() );
|
log_failure( "Invalid specifier %s for variable or function\n%s", ESpecifier::to_str( spec ), Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore const it will be handled by the type
|
// Ignore const it will be handled by the type
|
||||||
@ -4450,7 +4451,7 @@ CodeType parse_type( bool from_template, bool* typedef_is_function )
|
|||||||
{
|
{
|
||||||
log_failure( "Error, invalid specifier used in type definition: %s\n%s", currtok.Text, Context.to_string() );
|
log_failure( "Error, invalid specifier used in type definition: %s\n%s", currtok.Text, Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
specs_found[ NumSpecifiers ] = spec;
|
specs_found[ NumSpecifiers ] = spec;
|
||||||
@ -4463,7 +4464,7 @@ CodeType parse_type( bool from_template, bool* typedef_is_function )
|
|||||||
{
|
{
|
||||||
log_failure( "Error, unexpected end of type definition\n%s", Context.to_string() );
|
log_failure( "Error, unexpected end of type definition\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( from_template && currtok.Type == TokType::Decl_Class )
|
if ( from_template && currtok.Type == TokType::Decl_Class )
|
||||||
@ -4547,7 +4548,7 @@ else if ( currtok.Type == TokType::DeclType )
|
|||||||
{
|
{
|
||||||
log_failure( "Error, failed to type signature\n%s", Context.to_string() );
|
log_failure( "Error, failed to type signature\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4561,7 +4562,7 @@ else if ( currtok.Type == TokType::DeclType )
|
|||||||
{
|
{
|
||||||
log_failure( "Error, failed to type signature\n%s", Context.to_string() );
|
log_failure( "Error, failed to type signature\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
// <Attributes> <Specifiers> <Qualifier ::> <Identifier>
|
// <Attributes> <Specifiers> <Qualifier ::> <Identifier>
|
||||||
// <Attributes> <Specifiers> <Identifier>
|
// <Attributes> <Specifiers> <Identifier>
|
||||||
@ -4576,7 +4577,7 @@ else if ( currtok.Type == TokType::DeclType )
|
|||||||
{
|
{
|
||||||
log_failure( "Error, invalid specifier used in type definition: %s\n%s", currtok.Text, Context.to_string() );
|
log_failure( "Error, invalid specifier used in type definition: %s\n%s", currtok.Text, Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
specs_found[ NumSpecifiers ] = spec;
|
specs_found[ NumSpecifiers ] = spec;
|
||||||
@ -4709,7 +4710,7 @@ else if ( currtok.Type == TokType::DeclType )
|
|||||||
{
|
{
|
||||||
log_failure( "Error, invalid specifier used in type definition: %s\n%s", currtok.Text, Context.to_string() );
|
log_failure( "Error, invalid specifier used in type definition: %s\n%s", currtok.Text, Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
specs_found[ NumSpecifiers ] = spec;
|
specs_found[ NumSpecifiers ] = spec;
|
||||||
@ -4779,7 +4780,7 @@ else if ( currtok.Type == TokType::DeclType )
|
|||||||
{
|
{
|
||||||
log_failure( "Error, invalid specifier used in type definition: %s\n%s", currtok.Text, Context.to_string() );
|
log_failure( "Error, invalid specifier used in type definition: %s\n%s", currtok.Text, Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
specs_found[ NumSpecifiers ] = spec;
|
specs_found[ NumSpecifiers ] = spec;
|
||||||
@ -4910,10 +4911,12 @@ CodeTypedef parse_typedef()
|
|||||||
|| currtok.Type == TokType::Decl_Struct
|
|| currtok.Type == TokType::Decl_Struct
|
||||||
|| currtok.Type == TokType::Decl_Union;
|
|| currtok.Type == TokType::Decl_Union;
|
||||||
|
|
||||||
|
|
||||||
// This code is highly correlated with parse_complicated_definition
|
// This code is highly correlated with parse_complicated_definition
|
||||||
if ( is_complicated )
|
if ( is_complicated )
|
||||||
{
|
{
|
||||||
TokArray tokens = Context.Tokens;
|
TokArray tokens = Context.Tokens;
|
||||||
|
TokType which = currtok.Type;
|
||||||
|
|
||||||
s32 idx = tokens.Idx;
|
s32 idx = tokens.Idx;
|
||||||
s32 level = 0;
|
s32 level = 0;
|
||||||
@ -4929,73 +4932,80 @@ CodeTypedef parse_typedef()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (idx - 2 ) == tokens.Idx )
|
Token pre_foward_tok = currtok;
|
||||||
|
if ( (idx - 3 ) == tokens.Idx )
|
||||||
{
|
{
|
||||||
|
log_fmt("Identified forward typedef\n");
|
||||||
// Its a forward declaration only
|
// Its a forward declaration only
|
||||||
type = parse_forward_or_definition( currtok.Type, from_typedef );
|
type = parse_forward_or_definition( which, from_typedef );
|
||||||
// <ModuleFalgs> typedef <UnderlyingType: Forward Decl>
|
// <ModuleFalgs> typedef <UnderlyingType: Forward Decl>
|
||||||
}
|
}
|
||||||
|
|
||||||
Token tok = tokens[ idx - 1 ];
|
|
||||||
if ( tok.Type == TokType::Identifier )
|
|
||||||
{
|
|
||||||
tok = tokens[ idx - 2 ];
|
|
||||||
|
|
||||||
bool is_indirection = tok.Type == TokType::Ampersand
|
|
||||||
|| tok.Type == TokType::Star;
|
|
||||||
|
|
||||||
bool ok_to_parse = false;
|
|
||||||
|
|
||||||
if ( tok.Type == TokType::BraceCurly_Close )
|
|
||||||
{
|
|
||||||
// Its an inplace definition
|
|
||||||
// typdef <which> <type_identifier> { ... } <identifier>;
|
|
||||||
ok_to_parse = true;
|
|
||||||
}
|
|
||||||
else if ( tok.Type == TokType::Identifier && tokens[ idx - 3 ].Type == TokType::Decl_Struct )
|
|
||||||
{
|
|
||||||
// Its a variable with type ID using struct namespace.
|
|
||||||
// <which> <type_identifier> <identifier>;
|
|
||||||
ok_to_parse = true;
|
|
||||||
}
|
|
||||||
else if ( is_indirection )
|
|
||||||
{
|
|
||||||
// Its a indirection type with type ID using struct namespace.
|
|
||||||
// <which> <type_identifier>* <identifier>;
|
|
||||||
ok_to_parse = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! ok_to_parse )
|
|
||||||
{
|
|
||||||
log_failure( "Unsupported or bad member definition after struct declaration\n%s", Context.to_string() );
|
|
||||||
Context.pop();
|
|
||||||
return CodeInvalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(Ed) : I'm not sure if I have to use parse_type here, I'd rather not as that would complicate parse_type.
|
|
||||||
// type = parse_type();
|
|
||||||
type = parse_forward_or_definition( currtok.Type, from_typedef );
|
|
||||||
// <ModuleFalgs> typedef <UnderlyingType>
|
|
||||||
}
|
|
||||||
else if ( tok.Type == TokType::BraceCurly_Close )
|
|
||||||
{
|
|
||||||
// Its a definition
|
|
||||||
// <which> { ... };
|
|
||||||
type = parse_forward_or_definition( currtok.Type, from_typedef );
|
|
||||||
// <ModuleFalgs> typedef <UnderlyingType>
|
|
||||||
}
|
|
||||||
else if ( tok.Type == TokType::BraceSquare_Close)
|
|
||||||
{
|
|
||||||
// Its an array definition
|
|
||||||
// <which> <type_identifier> <identifier> [ ... ];
|
|
||||||
type = parse_type();
|
|
||||||
// <ModuleFalgs> typedef <UnderlyingType>
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
log_failure( "Unsupported or bad member definition after struct declaration\n%s", Context.to_string() );
|
Token tok = tokens.Arr[ idx - 1 ];
|
||||||
Context.pop();
|
if ( tok.Type == TokType::Identifier )
|
||||||
return CodeInvalid;
|
{
|
||||||
|
log_fmt("Found id\n");
|
||||||
|
tok = tokens.Arr[ idx - 2 ];
|
||||||
|
|
||||||
|
bool is_indirection = tok.Type == TokType::Ampersand
|
||||||
|
|| tok.Type == TokType::Star;
|
||||||
|
|
||||||
|
bool ok_to_parse = false;
|
||||||
|
|
||||||
|
Token temp_3 = tokens.Arr[ idx - 3 ];
|
||||||
|
|
||||||
|
if ( tok.Type == TokType::BraceCurly_Close )
|
||||||
|
{
|
||||||
|
// Its an inplace definition
|
||||||
|
// typedef <which> <type_identifier> { ... } <identifier>;
|
||||||
|
ok_to_parse = true;
|
||||||
|
}
|
||||||
|
else if ( tok.Type == TokType::Identifier && tokens.Arr[ idx - 3 ].Type == which )
|
||||||
|
{
|
||||||
|
// Its a variable with type ID using which namespace.
|
||||||
|
// typedef <which> <type_identifier> <identifier>;
|
||||||
|
ok_to_parse = true;
|
||||||
|
}
|
||||||
|
else if ( is_indirection )
|
||||||
|
{
|
||||||
|
// Its a indirection type with type ID using struct namespace.
|
||||||
|
// typedef <which> <type_identifier>* <identifier>;
|
||||||
|
ok_to_parse = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! ok_to_parse )
|
||||||
|
{
|
||||||
|
log_failure( "Unsupported or bad member definition after struct declaration\n%s", Context.to_string() );
|
||||||
|
Context.pop();
|
||||||
|
return InvalidCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(Ed) : I'm not sure if I have to use parse_type here, I'd rather not as that would complicate parse_type.
|
||||||
|
// type = parse_type();
|
||||||
|
type = parse_forward_or_definition( which, from_typedef );
|
||||||
|
// <ModuleFalgs> typedef <UnderlyingType>
|
||||||
|
}
|
||||||
|
else if ( tok.Type == TokType::BraceCurly_Close )
|
||||||
|
{
|
||||||
|
// Its a definition
|
||||||
|
// <which> { ... };
|
||||||
|
type = parse_forward_or_definition( currtok.Type, from_typedef );
|
||||||
|
// <ModuleFalgs> typedef <UnderlyingType>
|
||||||
|
}
|
||||||
|
else if ( tok.Type == TokType::BraceSquare_Close)
|
||||||
|
{
|
||||||
|
// Its an array definition
|
||||||
|
// <which> <type_identifier> <identifier> [ ... ];
|
||||||
|
type = parse_type();
|
||||||
|
// <ModuleFalgs> typedef <UnderlyingType>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log_failure( "Unsupported or bad member definition after struct declaration\n%s", Context.to_string() );
|
||||||
|
Context.pop();
|
||||||
|
return InvalidCode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -5015,7 +5025,7 @@ CodeTypedef parse_typedef()
|
|||||||
{
|
{
|
||||||
log_failure( "Error, expected identifier for typedef\n%s", Context.to_string() );
|
log_failure( "Error, expected identifier for typedef\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
array_expr = parse_array_decl();
|
array_expr = parse_array_decl();
|
||||||
@ -5057,7 +5067,7 @@ CodeTypedef parse_typedef()
|
|||||||
// Type needs to be aware of its parent so that it can be serialized properly.
|
// Type needs to be aware of its parent so that it can be serialized properly.
|
||||||
|
|
||||||
if ( type->Type == Typename && array_expr && array_expr->Type != Invalid )
|
if ( type->Type == Typename && array_expr && array_expr->Type != Invalid )
|
||||||
type.cast<CodeType>()->ArrExpr = array_expr;
|
type.code_cast<CodeType>()->ArrExpr = array_expr;
|
||||||
|
|
||||||
if ( inline_cmt )
|
if ( inline_cmt )
|
||||||
result->InlineCmt = inline_cmt;
|
result->InlineCmt = inline_cmt;
|
||||||
@ -5350,7 +5360,7 @@ CodeVar parse_variable()
|
|||||||
default:
|
default:
|
||||||
log_failure( "Invalid specifier %s for variable\n%s", ESpecifier::to_str( spec ), Context.to_string() );
|
log_failure( "Invalid specifier %s for variable\n%s", ESpecifier::to_str( spec ), Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore const specifiers, they're handled by the type
|
// Ignore const specifiers, they're handled by the type
|
||||||
@ -5371,8 +5381,8 @@ CodeVar parse_variable()
|
|||||||
CodeType type = parse_type();
|
CodeType type = parse_type();
|
||||||
// <ModuleFlags> <Attributes> <Specifiers> <ValueType>
|
// <ModuleFlags> <Attributes> <Specifiers> <ValueType>
|
||||||
|
|
||||||
if ( type == Code::Invalid )
|
if ( type == Code_Invalid )
|
||||||
return CodeInvalid;
|
return InvalidCode;
|
||||||
|
|
||||||
Context.Scope->Name = parse_identifier();
|
Context.Scope->Name = parse_identifier();
|
||||||
// <ModuleFlags> <Attributes> <Specifiers> <ValueType> <Name>
|
// <ModuleFlags> <Attributes> <Specifiers> <ValueType> <Name>
|
||||||
|
@ -25,7 +25,7 @@ enum AccessSpec enum_underlying(u32)
|
|||||||
|
|
||||||
AccessSpec_SizeDef = GEN_U32_MAX,
|
AccessSpec_SizeDef = GEN_U32_MAX,
|
||||||
};
|
};
|
||||||
static_assert( size_of(AccessSpec) == size_of(u32));
|
static_assert( size_of(AccessSpec) == size_of(u32), "AccessSpec not u32 size" );
|
||||||
|
|
||||||
inline
|
inline
|
||||||
char const* to_str( AccessSpec type )
|
char const* to_str( AccessSpec type )
|
||||||
@ -54,7 +54,7 @@ enum CodeFlag enum_underlying(u32)
|
|||||||
|
|
||||||
CodeFlag_SizeDef = GEN_U32_MAX,
|
CodeFlag_SizeDef = GEN_U32_MAX,
|
||||||
};
|
};
|
||||||
static_assert( size_of(CodeFlag) == size_of(u32));
|
static_assert( size_of(CodeFlag) == size_of(u32), "CodeFlag not u32 size" );
|
||||||
|
|
||||||
// Used to indicate if enum definitoin is an enum class or regular enum.
|
// Used to indicate if enum definitoin is an enum class or regular enum.
|
||||||
enum EnumDecl enum_underlying(u8)
|
enum EnumDecl enum_underlying(u8)
|
||||||
@ -77,7 +77,7 @@ enum ModuleFlag enum_underlying(u32)
|
|||||||
|
|
||||||
ModuleFlag_SizeDef = GEN_U32_MAX,
|
ModuleFlag_SizeDef = GEN_U32_MAX,
|
||||||
};
|
};
|
||||||
static_assert( size_of(ModuleFlag) == size_of(u32));
|
static_assert( size_of(ModuleFlag) == size_of(u32), "ModuleFlag not u32 size" );
|
||||||
|
|
||||||
inline
|
inline
|
||||||
StrC to_str( ModuleFlag flag )
|
StrC to_str( ModuleFlag flag )
|
||||||
@ -110,4 +110,4 @@ enum EPreprocessCond enum_underlying(u32)
|
|||||||
|
|
||||||
EPreprocessCond_SizeDef = GEN_U32_MAX,
|
EPreprocessCond_SizeDef = GEN_U32_MAX,
|
||||||
};
|
};
|
||||||
static_assert( size_of(EPreprocessCond) == size_of(u32));
|
static_assert( size_of(EPreprocessCond) == size_of(u32), "EPreprocessCond not u32 size" );
|
||||||
|
@ -29,29 +29,25 @@ struct ArrayHeader;
|
|||||||
|
|
||||||
usize array_grow_formula(ssize value);
|
usize array_grow_formula(ssize value);
|
||||||
|
|
||||||
template<class Type> Array<Type> array_init(AllocatorInfo allocator);
|
template<class Type> Array(Type) array_init (AllocatorInfo allocator);
|
||||||
template<class Type> Array<Type> array_init_reserve(AllocatorInfo allocator, ssize capacity);
|
template<class Type> Array(Type) array_init_reserve(AllocatorInfo allocator, ssize capacity);
|
||||||
template<class Type> bool append(Array<Type>& array, Array<Type> other);
|
template<class Type> bool append (Array(Type)* array, Array(Type) other);
|
||||||
template<class Type> bool append(Array<Type>& array, Type value);
|
template<class Type> bool append (Array(Type)* array, Type value);
|
||||||
template<class Type> bool append(Array<Type>& array, Type* items, usize item_num);
|
template<class Type> bool append (Array(Type)* array, Type* items, usize item_num);
|
||||||
template<class Type> bool append_at(Array<Type>& array, Type item, usize idx);
|
template<class Type> bool append_at (Array(Type)* array, Type item, usize idx);
|
||||||
template<class Type> bool append_at(Array<Type>& array, Type* items, usize item_num, usize idx);
|
template<class Type> bool append_at (Array(Type)* array, Type* items, usize item_num, usize idx);
|
||||||
template<class Type> Type& back(Array<Type>& array);
|
template<class Type> Type* back (Array(Type) array);
|
||||||
template<class Type> void clear(Array<Type>& array);
|
template<class Type> void clear (Array(Type) array);
|
||||||
template<class Type> bool fill(Array<Type>& array, usize begin, usize end, Type value);
|
template<class Type> bool fill (Array(Type) array, usize begin, usize end, Type value);
|
||||||
template<class Type> void free(Array<Type>& array);
|
template<class Type> void free (Array(Type)* array);
|
||||||
template<class Type> bool grow(Array<Type>& array, usize min_capacity);
|
template<class Type> bool grow (Array(Type)* array, usize min_capacity);
|
||||||
template<class Type> usize num(Array<Type>& array);
|
template<class Type> usize num (Array(Type) array);
|
||||||
template<class Type> void pop(Array<Type>& array);
|
template<class Type> void pop (Array(Type) array);
|
||||||
template<class Type> void remove_at(Array<Type>& array, usize idx);
|
template<class Type> void remove_at (Array(Type) array, usize idx);
|
||||||
template<class Type> bool reserve(Array<Type>& array, usize new_capacity);
|
template<class Type> bool reserve (Array(Type)* array, usize new_capacity);
|
||||||
template<class Type> bool resize(Array<Type>& array, usize num);
|
template<class Type> bool resize (Array(Type)* array, usize num);
|
||||||
template<class Type> bool set_capacity(Array<Type>& array, usize new_capacity);
|
template<class Type> bool set_capacity (Array(Type)* array, usize new_capacity);
|
||||||
template<class Type> ArrayHeader* get_header(Array<Type>& array);
|
template<class Type> ArrayHeader* get_header (Array(Type) array);
|
||||||
|
|
||||||
template<class Type> forceinline Type* begin(Array<Type>& array) { return array; }
|
|
||||||
template<class Type> forceinline Type* end(Array<Type>& array) { return array + get_header(array)->Num; }
|
|
||||||
template<class Type> forceinline Type* next(Array<Type>& array, Type* entry) { return entry + 1; }
|
|
||||||
|
|
||||||
struct ArrayHeader {
|
struct ArrayHeader {
|
||||||
AllocatorInfo Allocator;
|
AllocatorInfo Allocator;
|
||||||
@ -70,32 +66,56 @@ struct Array
|
|||||||
forceinline static Array init_reserve(AllocatorInfo allocator, ssize capacity) { return GEN_NS array_init_reserve<Type>(allocator, capacity); }
|
forceinline static Array init_reserve(AllocatorInfo allocator, ssize capacity) { return GEN_NS array_init_reserve<Type>(allocator, capacity); }
|
||||||
forceinline static usize grow_formula(ssize value) { return GEN_NS array_grow_formula<Type>(value); }
|
forceinline static usize grow_formula(ssize value) { return GEN_NS array_grow_formula<Type>(value); }
|
||||||
|
|
||||||
forceinline bool append(Array other) { return GEN_NS append<Type>(*this, other); }
|
forceinline bool append(Array other) { return GEN_NS append<Type>(this, other); }
|
||||||
forceinline bool append(Type value) { return GEN_NS append<Type>(*this, value); }
|
forceinline bool append(Type value) { return GEN_NS append<Type>(this, value); }
|
||||||
forceinline bool append(Type* items, usize item_num) { return GEN_NS append<Type>(*this, items, item_num); }
|
forceinline bool append(Type* items, usize item_num) { return GEN_NS append<Type>(this, items, item_num); }
|
||||||
forceinline bool append_at(Type item, usize idx) { return GEN_NS append_at<Type>(*this, item, idx); }
|
forceinline bool append_at(Type item, usize idx) { return GEN_NS append_at<Type>(this, item, idx); }
|
||||||
forceinline bool append_at(Type* items, usize item_num, usize idx) { return GEN_NS append_at<Type>(*this, items, item_num, idx); }
|
forceinline bool append_at(Type* items, usize item_num, usize idx) { return GEN_NS append_at<Type>(this, items, item_num, idx); }
|
||||||
forceinline Type& back() { return GEN_NS back<Type>(*this); }
|
forceinline Type* back() { return GEN_NS back<Type>(* this); }
|
||||||
forceinline void clear() { GEN_NS clear<Type>(*this); }
|
forceinline void clear() { GEN_NS clear<Type>(* this); }
|
||||||
forceinline bool fill(usize begin, usize end, Type value) { return GEN_NS fill<Type>(*this, begin, end, value); }
|
forceinline bool fill(usize begin, usize end, Type value) { return GEN_NS fill<Type>(* this, begin, end, value); }
|
||||||
forceinline void free() { GEN_NS free<Type>(*this); }
|
forceinline void free() { GEN_NS free<Type>(this); }
|
||||||
forceinline ArrayHeader* get_header() { return GEN_NS get_header<Type>(*this); }
|
forceinline ArrayHeader* get_header() { return GEN_NS get_header<Type>(* this); }
|
||||||
forceinline bool grow(usize min_capacity) { return GEN_NS grow<Type>(*this, min_capacity); }
|
forceinline bool grow(usize min_capacity) { return GEN_NS grow<Type>(this, min_capacity); }
|
||||||
forceinline usize num() { return GEN_NS num<Type>(*this); }
|
forceinline usize num() { return GEN_NS num<Type>(*this); }
|
||||||
forceinline void pop() { GEN_NS pop<Type>(*this); }
|
forceinline void pop() { GEN_NS pop<Type>(* this); }
|
||||||
forceinline void remove_at(usize idx) { GEN_NS remove_at<Type>(*this, idx); }
|
forceinline void remove_at(usize idx) { GEN_NS remove_at<Type>(* this, idx); }
|
||||||
forceinline bool reserve(usize new_capacity) { return GEN_NS reserve<Type>(*this, new_capacity); }
|
forceinline bool reserve(usize new_capacity) { return GEN_NS reserve<Type>(this, new_capacity); }
|
||||||
forceinline bool resize(usize num) { return GEN_NS resize<Type>(*this, num); }
|
forceinline bool resize(usize num) { return GEN_NS resize<Type>(this, num); }
|
||||||
forceinline bool set_capacity(usize new_capacity) { return GEN_NS set_capacity<Type>(*this, new_capacity); }
|
forceinline bool set_capacity(usize new_capacity) { return GEN_NS set_capacity<Type>(this, new_capacity); }
|
||||||
|
#pragma endregion Member Mapping
|
||||||
|
|
||||||
forceinline operator Type*() { return Data; }
|
forceinline operator Type*() { return Data; }
|
||||||
forceinline operator Type const*() const { return Data; }
|
forceinline operator Type const*() const { return Data; }
|
||||||
forceinline Type* begin() { return Data; }
|
forceinline Type* begin() { return Data; }
|
||||||
forceinline Type* end() { return Data + get_header()->Num; }
|
forceinline Type* end() { return Data + get_header()->Num; }
|
||||||
#pragma endregion Member Mapping
|
|
||||||
|
forceinline Type& operator[](ssize index) { return Data[index]; }
|
||||||
|
forceinline Type const& operator[](ssize index) const { return Data[index]; }
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if GEN_SUPPORT_CPP_REFERENCES
|
||||||
|
template<class Type> bool append(Array<Type>& array, Array<Type> other) { return GEN_NS append( & array, other ); }
|
||||||
|
template<class Type> bool append(Array<Type>& array, Type value) { return GEN_NS append( & array, value ); }
|
||||||
|
template<class Type> bool append(Array<Type>& array, Type* items, usize item_num) { return GEN_NS append( & array, items, item_num ); }
|
||||||
|
template<class Type> bool append_at(Array<Type>& array, Type item, usize idx) { return GEN_NS append_at( & array, item, idx ); }
|
||||||
|
template<class Type> bool append_at(Array<Type>& array, Type* items, usize item_num, usize idx) { return GEN_NS append_at( & array, items, item_num, idx ); }
|
||||||
|
template<class Type> void free(Array<Type>& array) { return GEN_NS free( & array ); }
|
||||||
|
template<class Type> bool grow(Array<Type>& array, usize min_capacity) { return GEN_NS grow( & array, min_capacity); }
|
||||||
|
template<class Type> bool reserve(Array<Type>& array, usize new_capacity) { return GEN_NS reserve( & array, new_capacity); }
|
||||||
|
template<class Type> bool resize(Array<Type>& array, usize num) { return GEN_NS resize( & array, num); }
|
||||||
|
template<class Type> bool set_capacity(Array<Type>& array, usize new_capacity) { return GEN_NS set_capacity( & array, new_capacity); }
|
||||||
|
|
||||||
|
template<class Type> forceinline Type* begin(Array<Type>& array) { return array; }
|
||||||
|
template<class Type> forceinline Type* end(Array<Type>& array) { return array + get_header(array)->Num; }
|
||||||
|
template<class Type> forceinline Type* next(Array<Type>& array, Type* entry) { return entry + 1; }
|
||||||
|
#else
|
||||||
|
template<class Type> forceinline Type* begin(Array<Type> array) { return array; }
|
||||||
|
template<class Type> forceinline Type* end(Array<Type> array) { return array + get_header(array)->Num; }
|
||||||
|
template<class Type> forceinline Type* next(Array<Type> array, Type* entry) { return entry + 1; }
|
||||||
|
#endif
|
||||||
|
|
||||||
template<class Type> inline
|
template<class Type> inline
|
||||||
Array<Type> array_init(AllocatorInfo allocator) {
|
Array<Type> array_init(AllocatorInfo allocator) {
|
||||||
return array_init_reserve<Type>(allocator, array_grow_formula(0));
|
return array_init_reserve<Type>(allocator, array_grow_formula(0));
|
||||||
@ -121,30 +141,30 @@ usize array_grow_formula(ssize value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class Type> inline
|
template<class Type> inline
|
||||||
bool append(Array<Type>& array, Array<Type> other) {
|
bool append(Array<Type>* array, Array<Type> other) {
|
||||||
return append(array, other, num(other));
|
return append(array, other, num(other));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Type> inline
|
template<class Type> inline
|
||||||
bool append(Array<Type>& array, Type value)
|
bool append(Array<Type>* array, Type value)
|
||||||
{
|
{
|
||||||
ArrayHeader* header = get_header(array);
|
ArrayHeader* header = get_header(* array);
|
||||||
|
|
||||||
if (header->Num == header->Capacity)
|
if (header->Num == header->Capacity)
|
||||||
{
|
{
|
||||||
if (!grow(array, header->Capacity))
|
if (!grow(array, header->Capacity))
|
||||||
return false;
|
return false;
|
||||||
header = get_header(array);
|
header = get_header(* array);
|
||||||
}
|
}
|
||||||
|
|
||||||
array[header->Num] = value;
|
(*array)[ header->Num] = value;
|
||||||
header->Num++;
|
header->Num++;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Type> inline
|
template<class Type> inline
|
||||||
bool append(Array<Type>& array, Type* items, usize item_num)
|
bool append(Array<Type>* array, Type* items, usize item_num)
|
||||||
{
|
{
|
||||||
ArrayHeader* header = get_header(array);
|
ArrayHeader* header = get_header(array);
|
||||||
|
|
||||||
@ -162,34 +182,37 @@ bool append(Array<Type>& array, Type* items, usize item_num)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class Type> inline
|
template<class Type> inline
|
||||||
bool append_at(Array<Type>& array, Type item, usize idx)
|
bool append_at(Array<Type>* array, Type item, usize idx)
|
||||||
{
|
{
|
||||||
ArrayHeader* header = get_header(array);
|
ArrayHeader* header = get_header(* array);
|
||||||
|
|
||||||
if (idx >= header->Num)
|
ssize slot = idx;
|
||||||
idx = header->Num - 1;
|
if (slot >= header->Num)
|
||||||
|
slot = header->Num - 1;
|
||||||
|
|
||||||
if (idx < 0)
|
if (slot < 0)
|
||||||
idx = 0;
|
slot = 0;
|
||||||
|
|
||||||
if (header->Capacity < header->Num + 1)
|
if (header->Capacity < header->Num + 1)
|
||||||
{
|
{
|
||||||
if (!grow(array, header->Capacity + 1))
|
if ( ! grow(array, header->Capacity + 1))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
header = get_header(array);
|
header = get_header(* array);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type* target = array + idx;
|
Type* target = array->Data + slot;
|
||||||
|
|
||||||
mem_move(target + 1, target, (header->Num - idx) * sizeof(Type));
|
mem_move(target + 1, target, (header->Num - slot) * sizeof(Type));
|
||||||
header->Num++;
|
header->Num++;
|
||||||
|
|
||||||
|
header = get_header(* array);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Type> inline
|
template<class Type> inline
|
||||||
bool append_at(Array<Type>& array, Type* items, usize item_num, usize idx)
|
bool append_at(Array<Type>* array, Type* items, usize item_num, usize idx)
|
||||||
{
|
{
|
||||||
ArrayHeader* header = get_header(array);
|
ArrayHeader* header = get_header(array);
|
||||||
|
|
||||||
@ -200,7 +223,7 @@ bool append_at(Array<Type>& array, Type* items, usize item_num, usize idx)
|
|||||||
|
|
||||||
if (item_num > header->Capacity)
|
if (item_num > header->Capacity)
|
||||||
{
|
{
|
||||||
if (!grow(array, header->Capacity + item_num))
|
if (! grow(array, header->Capacity + item_num))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
header = get_header(array);
|
header = get_header(array);
|
||||||
@ -217,19 +240,25 @@ bool append_at(Array<Type>& array, Type* items, usize item_num, usize idx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class Type> inline
|
template<class Type> inline
|
||||||
Type& back(Array<Type>& array) {
|
Type* back(Array<Type>* array)
|
||||||
ArrayHeader* header = get_header(array);
|
{
|
||||||
return array[header->Num - 1];
|
GEN_ASSERT(array != nullptr);
|
||||||
|
|
||||||
|
ArrayHeader* header = get_header(* array);
|
||||||
|
if (header->Num <= 0)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return & (*array)[header->Num - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Type> inline
|
template<class Type> inline
|
||||||
void clear(Array<Type>& array) {
|
void clear(Array<Type> array) {
|
||||||
ArrayHeader* header = get_header(array);
|
ArrayHeader* header = get_header(array);
|
||||||
header->Num = 0;
|
header->Num = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Type> inline
|
template<class Type> inline
|
||||||
bool fill(Array<Type>& array, usize begin, usize end, Type value)
|
bool fill(Array<Type> array, usize begin, usize end, Type value)
|
||||||
{
|
{
|
||||||
ArrayHeader* header = get_header(array);
|
ArrayHeader* header = get_header(array);
|
||||||
|
|
||||||
@ -245,25 +274,25 @@ bool fill(Array<Type>& array, usize begin, usize end, Type value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class Type> inline
|
template<class Type> inline
|
||||||
void free(Array<Type>& array) {
|
void free(Array<Type>* array) {
|
||||||
ArrayHeader* header = get_header(array);
|
GEN_ASSERT(array != nullptr);
|
||||||
|
ArrayHeader* header = get_header(* array);
|
||||||
GEN_NS free(header->Allocator, header);
|
GEN_NS free(header->Allocator, header);
|
||||||
Type*& Data = rcast(Type*&, array);
|
array->Data = nullptr;
|
||||||
Data = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Type> inline
|
template<class Type> forceinline
|
||||||
ArrayHeader* get_header(Array<Type>& array) {
|
ArrayHeader* get_header(Array<Type> array) {
|
||||||
|
Type* Data = array;
|
||||||
|
|
||||||
using NonConstType = TRemoveConst<Type>;
|
using NonConstType = TRemoveConst<Type>;
|
||||||
Type* Data = array; // This should do nothing in C but in C++ gets member Data struct.
|
return rcast(ArrayHeader*, const_cast<NonConstType*>(Data)) - 1;
|
||||||
return rcast(ArrayHeader*, const_cast<NonConstType*>(Data)) - 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Type> inline
|
template<class Type> inline
|
||||||
bool grow(Array<Type>& array, usize min_capacity)
|
bool grow(Array<Type>* array, usize min_capacity)
|
||||||
{
|
{
|
||||||
ArrayHeader* header = get_header(array);
|
ArrayHeader* header = get_header(* array);
|
||||||
usize new_capacity = array_grow_formula(header->Capacity);
|
usize new_capacity = array_grow_formula(header->Capacity);
|
||||||
|
|
||||||
if (new_capacity < min_capacity)
|
if (new_capacity < min_capacity)
|
||||||
new_capacity = min_capacity;
|
new_capacity = min_capacity;
|
||||||
@ -272,19 +301,19 @@ bool grow(Array<Type>& array, usize min_capacity)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class Type> inline
|
template<class Type> inline
|
||||||
usize num(Array<Type>& array) {
|
usize num(Array<Type> array) {
|
||||||
return get_header(array)->Num;
|
return get_header(array)->Num;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Type> inline
|
template<class Type> inline
|
||||||
void pop(Array<Type>& array) {
|
void pop(Array<Type> array) {
|
||||||
ArrayHeader* header = get_header(array);
|
ArrayHeader* header = get_header(array);
|
||||||
GEN_ASSERT(header->Num > 0);
|
GEN_ASSERT(header->Num > 0);
|
||||||
header->Num--;
|
header->Num--;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Type> inline
|
template<class Type> inline
|
||||||
void remove_at(Array<Type>& array, usize idx)
|
void remove_at(Array<Type> array, usize idx)
|
||||||
{
|
{
|
||||||
ArrayHeader* header = get_header(array);
|
ArrayHeader* header = get_header(array);
|
||||||
GEN_ASSERT(idx < header->Num);
|
GEN_ASSERT(idx < header->Num);
|
||||||
@ -294,7 +323,7 @@ void remove_at(Array<Type>& array, usize idx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class Type> inline
|
template<class Type> inline
|
||||||
bool reserve(Array<Type>& array, usize new_capacity)
|
bool reserve(Array<Type>* array, usize new_capacity)
|
||||||
{
|
{
|
||||||
ArrayHeader* header = get_header(array);
|
ArrayHeader* header = get_header(array);
|
||||||
|
|
||||||
@ -305,14 +334,14 @@ bool reserve(Array<Type>& array, usize new_capacity)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class Type> inline
|
template<class Type> inline
|
||||||
bool resize(Array<Type>& array, usize num)
|
bool resize(Array<Type>* array, usize num)
|
||||||
{
|
{
|
||||||
ArrayHeader* header = get_header(array);
|
ArrayHeader* header = get_header(* array);
|
||||||
|
|
||||||
if (header->Capacity < num) {
|
if (header->Capacity < num) {
|
||||||
if (!grow(array, num))
|
if (! grow( array, num))
|
||||||
return false;
|
return false;
|
||||||
header = get_header(array);
|
header = get_header(* array);
|
||||||
}
|
}
|
||||||
|
|
||||||
header->Num = num;
|
header->Num = num;
|
||||||
@ -320,9 +349,9 @@ bool resize(Array<Type>& array, usize num)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class Type> inline
|
template<class Type> inline
|
||||||
bool set_capacity(Array<Type>& array, usize new_capacity)
|
bool set_capacity(Array<Type>* array, usize new_capacity)
|
||||||
{
|
{
|
||||||
ArrayHeader* header = get_header(array);
|
ArrayHeader* header = get_header(* array);
|
||||||
|
|
||||||
if (new_capacity == header->Capacity)
|
if (new_capacity == header->Capacity)
|
||||||
return true;
|
return true;
|
||||||
@ -333,7 +362,7 @@ bool set_capacity(Array<Type>& array, usize new_capacity)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize size = sizeof(ArrayHeader) + sizeof(Type) * new_capacity;
|
ssize size = sizeof(ArrayHeader) + sizeof(Type) * new_capacity;
|
||||||
ArrayHeader* new_header = rcast(ArrayHeader*, alloc(header->Allocator, size));
|
ArrayHeader* new_header = rcast(ArrayHeader*, alloc(header->Allocator, size));
|
||||||
|
|
||||||
if (new_header == nullptr)
|
if (new_header == nullptr)
|
||||||
@ -345,32 +374,10 @@ bool set_capacity(Array<Type>& array, usize new_capacity)
|
|||||||
|
|
||||||
GEN_NS free(header->Allocator, header);
|
GEN_NS free(header->Allocator, header);
|
||||||
|
|
||||||
Type*& Data = rcast(Type*&, array);
|
array->Data = rcast(Type*, new_header + 1);
|
||||||
Data = rcast(Type*, new_header + 1);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define array_init(Type, allocator) array_init<Type>(allocator)
|
|
||||||
#define array_init(Type, allocator) array_init<Type>(allocator)
|
|
||||||
#define array_init_reserve(Type, allocator, capacity) array_init_reserve<Type>(allocator, capacity)
|
|
||||||
#define array_append(Type, array, other) append<Type>(array, other)
|
|
||||||
#define array_append_value(Type, array, value) append<Type>(array, value)
|
|
||||||
#define array_append_items(Type, array, items, item_num) append<Type>(array, items, item_num)
|
|
||||||
#define array_append_at(Type, array, item, idx) append_at<Type>(array, item, idx)
|
|
||||||
#define array_append_items_at(Type, array, items, num, idx) append_at<Type>(array, items, num, idx)
|
|
||||||
#define array_back(Type, array) back<Type>(array)
|
|
||||||
#define array_clear(Type, array) clear<Type>(array)
|
|
||||||
#define array_fill(Type, array, begin, end, value) fill<Type>(array, begin, end, value)
|
|
||||||
#define array_free(Type, array) free<Type>(array)
|
|
||||||
#define array_grow(Type, array, min_capacity) grow<Type>(array, min_capacity)
|
|
||||||
#define array_num(Type, array) num<Type>(array)
|
|
||||||
#define array_pop(Type, array) pop<Type>(array)
|
|
||||||
#define array_remove_at(Type, array, idx) remove_at<Type>(array, idx)
|
|
||||||
#define array_reserve(Type, array, new_capacity) reserve<Type>(array, new_capacity)
|
|
||||||
#define array_resize(Type, array, num) resize<Type>(array, num)
|
|
||||||
#define array_set_capacity(Type, array, new_capacity) set_capacity<Type>(array, new_capacity)
|
|
||||||
#define array_get_header(array) get_header(array)
|
|
||||||
|
|
||||||
#pragma endregion Array
|
#pragma endregion Array
|
||||||
|
|
||||||
// TODO(Ed) : This thing needs ALOT of work.
|
// TODO(Ed) : This thing needs ALOT of work.
|
||||||
@ -395,21 +402,21 @@ struct HashTableEntry {
|
|||||||
|
|
||||||
template<class Type> HashTable<Type> hashtable_init(AllocatorInfo allocator);
|
template<class Type> HashTable<Type> hashtable_init(AllocatorInfo allocator);
|
||||||
template<class Type> HashTable<Type> hashtable_init_reserve(AllocatorInfo allocator, usize num);
|
template<class Type> HashTable<Type> hashtable_init_reserve(AllocatorInfo allocator, usize num);
|
||||||
template<class Type> void clear(HashTable<Type>& table);
|
template<class Type> void clear (HashTable<Type> table);
|
||||||
template<class Type> void destroy(HashTable<Type>& table);
|
template<class Type> void destroy (HashTable<Type>* table);
|
||||||
template<class Type> Type* get(HashTable<Type>& table, u64 key);
|
template<class Type> Type* get (HashTable<Type> table, u64 key);
|
||||||
template<class Type> void grow(HashTable<Type>& table);
|
template<class Type> void grow (HashTable<Type>* table);
|
||||||
template<class Type> void rehash(HashTable<Type>& table, ssize new_num);
|
template<class Type> void rehash (HashTable<Type>* table, ssize new_num);
|
||||||
template<class Type> void rehash_fast(HashTable<Type>& table);
|
template<class Type> void rehash_fast (HashTable<Type> table);
|
||||||
template<class Type> void remove(HashTable<Type>& table, u64 key);
|
template<class Type> void remove (HashTable<Type> table, u64 key);
|
||||||
template<class Type> void remove_entry(HashTable<Type>& table, ssize idx);
|
template<class Type> void remove_entry (HashTable<Type> table, ssize idx);
|
||||||
template<class Type> void set(HashTable<Type>& table, u64 key, Type value);
|
template<class Type> void set (HashTable<Type>* table, u64 key, Type value);
|
||||||
template<class Type> ssize slot(HashTable<Type>& table, u64 key);
|
template<class Type> ssize slot (HashTable<Type> table, u64 key);
|
||||||
template<class Type> ssize add_entry(HashTable<Type>& table, u64 key);
|
template<class Type> ssize add_entry (HashTable<Type>* table, u64 key);
|
||||||
template<class Type> HashTableFindResult find(HashTable<Type>& table, u64 key);
|
template<class Type> HashTableFindResult find (HashTable<Type> table, u64 key);
|
||||||
template<class Type> bool full(HashTable<Type>& table);
|
template<class Type> bool full (HashTable<Type> table);
|
||||||
template<class Type> void map(HashTable<Type>& table, void (*map_proc)(u64 key, Type value));
|
template<class Type> void map (HashTable<Type> table, void (*map_proc)(u64 key, Type value));
|
||||||
template<class Type> void map_mut(HashTable<Type>& table, void (*map_proc)(u64 key, Type* value));
|
template<class Type> void map_mut (HashTable<Type> table, void (*map_proc)(u64 key, Type* value));
|
||||||
|
|
||||||
static constexpr f32 HashTable_CriticalLoadScale = 0.7f;
|
static constexpr f32 HashTable_CriticalLoadScale = 0.7f;
|
||||||
|
|
||||||
@ -440,6 +447,14 @@ struct HashTable
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if GEN_SUPPORT_CPP_REFERENCES
|
||||||
|
template<class Type> void destroy (HashTable<Type>& table) { destroy(& table); }
|
||||||
|
template<class Type> void grow (HashTable<Type>& table) { grow(& table); }
|
||||||
|
template<class Type> void rehash (HashTable<Type>& table, ssize new_num) { rehash(& table, new_num); }
|
||||||
|
template<class Type> void set (HashTable<Type>& table, u64 key, Type value) { set(& table, key, value); }
|
||||||
|
template<class Type> ssize add_entry(HashTable<Type>& table, u64 key) { add_entry(& table, key); }
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename Type> inline
|
template<typename Type> inline
|
||||||
HashTable<Type> hashtable_init(AllocatorInfo allocator) {
|
HashTable<Type> hashtable_init(AllocatorInfo allocator) {
|
||||||
HashTable<Type> result = hashtable_init_reserve<Type>(allocator, 8);
|
HashTable<Type> result = hashtable_init_reserve<Type>(allocator, 8);
|
||||||
@ -453,7 +468,7 @@ HashTable<Type> hashtable_init_reserve(AllocatorInfo allocator, usize num)
|
|||||||
|
|
||||||
result.Hashes = array_init_reserve<ssize>(allocator, num);
|
result.Hashes = array_init_reserve<ssize>(allocator, num);
|
||||||
get_header(result.Hashes)->Num = num;
|
get_header(result.Hashes)->Num = num;
|
||||||
resize(result.Hashes, num);
|
resize(& result.Hashes, num);
|
||||||
fill<ssize>(result.Hashes, 0, num, -1);
|
fill<ssize>(result.Hashes, 0, num, -1);
|
||||||
|
|
||||||
result.Entries = array_init_reserve<HashTableEntry<Type>>(allocator, num);
|
result.Entries = array_init_reserve<HashTableEntry<Type>>(allocator, num);
|
||||||
@ -461,65 +476,65 @@ HashTable<Type> hashtable_init_reserve(AllocatorInfo allocator, usize num)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type> inline
|
template<typename Type> inline
|
||||||
void clear(HashTable<Type>& table) {
|
void clear(HashTable<Type> table) {
|
||||||
clear(table.Entries);
|
clear(table.Entries);
|
||||||
fill<ssize>(table.Hashes, 0, num(table.Hashes), -1);
|
fill<ssize>(table.Hashes, 0, num(table.Hashes), -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type> inline
|
template<typename Type> inline
|
||||||
void destroy(HashTable<Type>& table) {
|
void destroy(HashTable<Type>* table) {
|
||||||
if (table.Hashes && get_header(table.Hashes)->Capacity) {
|
if (table->Hashes && get_header(table->Hashes)->Capacity) {
|
||||||
free(table.Hashes);
|
free(& table->Hashes);
|
||||||
free(table.Entries);
|
free(& table->Entries);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type> inline
|
template<typename Type> inline
|
||||||
Type* get(HashTable<Type>& table, u64 key) {
|
Type* get(HashTable<Type> table, u64 key) {
|
||||||
ssize idx = find(table, key).EntryIndex;
|
ssize idx = find(table, key).EntryIndex;
|
||||||
if (idx >= 0)
|
if (idx >= 0)
|
||||||
return &table.Entries[idx].Value;
|
return & table.Entries[idx].Value;
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type> inline
|
template<typename Type> inline
|
||||||
void map(HashTable<Type>& table, void (*map_proc)(u64 key, Type value)) {
|
void map(HashTable<Type> table, void (*map_proc)(u64 key, Type value)) {
|
||||||
GEN_ASSERT_NOT_NULL(map_proc);
|
GEN_ASSERT_NOT_NULL(map_proc);
|
||||||
|
|
||||||
for (ssize idx = 0; idx < ssize(table.Entries.num()); ++idx) {
|
for (ssize idx = 0; idx < ssize(num(table.Entries)); ++idx) {
|
||||||
map_proc(table.Entries[idx].Key, table.Entries[idx].Value);
|
map_proc(table.Entries[idx].Key, table.Entries[idx].Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type> inline
|
template<typename Type> inline
|
||||||
void map_mut(HashTable<Type>& table, void (*map_proc)(u64 key, Type* value)) {
|
void map_mut(HashTable<Type> table, void (*map_proc)(u64 key, Type* value)) {
|
||||||
GEN_ASSERT_NOT_NULL(map_proc);
|
GEN_ASSERT_NOT_NULL(map_proc);
|
||||||
|
|
||||||
for (ssize idx = 0; idx < ssize(table.Entries.num()); ++idx) {
|
for (ssize idx = 0; idx < ssize(num(table.Entries)); ++idx) {
|
||||||
map_proc(table.Entries[idx].Key, &table.Entries[idx].Value);
|
map_proc(table.Entries[idx].Key, & table.Entries[idx].Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type> inline
|
template<typename Type> inline
|
||||||
void grow(HashTable<Type>& table) {
|
void grow(HashTable<Type>* table) {
|
||||||
ssize new_num = array_grow_formula(num(table.Entries));
|
ssize new_num = array_grow_formula(num(table->Entries));
|
||||||
rehash(table, new_num);
|
rehash(table, new_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type> inline
|
template<typename Type> inline
|
||||||
void rehash(HashTable<Type>& table, ssize new_num)
|
void rehash(HashTable<Type>* table, ssize new_num)
|
||||||
{
|
{
|
||||||
ssize last_added_index;
|
ssize last_added_index;
|
||||||
HashTable<Type> new_ht = hashtable_init_reserve<Type>(get_header(table.Hashes)->Allocator, new_num);
|
HashTable<Type> new_ht = hashtable_init_reserve<Type>(get_header(table->Hashes)->Allocator, new_num);
|
||||||
|
|
||||||
for (ssize idx = 0; idx < ssize(num(table.Entries)); ++idx)
|
for (ssize idx = 0; idx < ssize(num(table->Entries)); ++idx)
|
||||||
{
|
{
|
||||||
HashTableFindResult find_result;
|
HashTableFindResult find_result;
|
||||||
HashTableEntry<Type>& entry = table.Entries[idx];
|
HashTableEntry<Type>& entry = table->Entries[idx];
|
||||||
|
|
||||||
find_result = find(new_ht, entry.Key);
|
find_result = find(new_ht, entry.Key);
|
||||||
last_added_index = add_entry(new_ht, entry.Key);
|
last_added_index = add_entry(& new_ht, entry.Key);
|
||||||
|
|
||||||
if (find_result.PrevIndex < 0)
|
if (find_result.PrevIndex < 0)
|
||||||
new_ht.Hashes[find_result.HashIndex] = last_added_index;
|
new_ht.Hashes[find_result.HashIndex] = last_added_index;
|
||||||
@ -531,21 +546,21 @@ void rehash(HashTable<Type>& table, ssize new_num)
|
|||||||
}
|
}
|
||||||
|
|
||||||
destroy(table);
|
destroy(table);
|
||||||
table = new_ht;
|
* table = new_ht;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type> inline
|
template<typename Type> inline
|
||||||
void rehash_fast(HashTable<Type>& table)
|
void rehash_fast(HashTable<Type> table)
|
||||||
{
|
{
|
||||||
ssize idx;
|
ssize idx;
|
||||||
|
|
||||||
for (idx = 0; idx < ssize(table.Entries.num()); idx++)
|
for (idx = 0; idx < ssize(num(table.Entries)); idx++)
|
||||||
table.Entries[idx].Next = -1;
|
table.Entries[idx].Next = -1;
|
||||||
|
|
||||||
for (idx = 0; idx < ssize(table.Hashes.num()); idx++)
|
for (idx = 0; idx < ssize(num(table.Hashes)); idx++)
|
||||||
table.Hashes[idx] = -1;
|
table.Hashes[idx] = -1;
|
||||||
|
|
||||||
for (idx = 0; idx < ssize(table.Entries.num()); idx++)
|
for (idx = 0; idx < ssize(num(table.Entries)); idx++)
|
||||||
{
|
{
|
||||||
HashTableEntry<Type>* entry;
|
HashTableEntry<Type>* entry;
|
||||||
HashTableFindResult find_result;
|
HashTableFindResult find_result;
|
||||||
@ -561,30 +576,30 @@ void rehash_fast(HashTable<Type>& table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type> inline
|
template<typename Type> inline
|
||||||
void remove(HashTable<Type>& table, u64 key) {
|
void remove(HashTable<Type> table, u64 key) {
|
||||||
HashTableFindResult find_result = find(table, key);
|
HashTableFindResult find_result = find(table, key);
|
||||||
|
|
||||||
if (find_result.EntryIndex >= 0) {
|
if (find_result.EntryIndex >= 0) {
|
||||||
table.Entries.remove_at(find_result.EntryIndex);
|
remove_at(table.Entries, find_result.EntryIndex);
|
||||||
rehash_fast(table);
|
rehash_fast(table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type> inline
|
template<typename Type> inline
|
||||||
void remove_entry(HashTable<Type>& table, ssize idx) {
|
void remove_entry(HashTable<Type> table, ssize idx) {
|
||||||
table.Entries.remove_at(idx);
|
remove_at(table.Entries, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type> inline
|
template<typename Type> inline
|
||||||
void set(HashTable<Type>& table, u64 key, Type value)
|
void set(HashTable<Type>* table, u64 key, Type value)
|
||||||
{
|
{
|
||||||
ssize idx;
|
ssize idx;
|
||||||
HashTableFindResult find_result;
|
HashTableFindResult find_result;
|
||||||
|
|
||||||
if (full(table))
|
if (full(* table))
|
||||||
grow(table);
|
grow(table);
|
||||||
|
|
||||||
find_result = find(table, key);
|
find_result = find(* table, key);
|
||||||
if (find_result.EntryIndex >= 0) {
|
if (find_result.EntryIndex >= 0) {
|
||||||
idx = find_result.EntryIndex;
|
idx = find_result.EntryIndex;
|
||||||
}
|
}
|
||||||
@ -593,22 +608,22 @@ void set(HashTable<Type>& table, u64 key, Type value)
|
|||||||
idx = add_entry(table, key);
|
idx = add_entry(table, key);
|
||||||
|
|
||||||
if (find_result.PrevIndex >= 0) {
|
if (find_result.PrevIndex >= 0) {
|
||||||
table.Entries[find_result.PrevIndex].Next = idx;
|
table->Entries[find_result.PrevIndex].Next = idx;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
table.Hashes[find_result.HashIndex] = idx;
|
table->Hashes[find_result.HashIndex] = idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
table.Entries[idx].Value = value;
|
table->Entries[idx].Value = value;
|
||||||
|
|
||||||
if (full(table))
|
if (full(* table))
|
||||||
grow(table);
|
grow(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type> inline
|
template<typename Type> inline
|
||||||
ssize slot(HashTable<Type>& table, u64 key) {
|
ssize slot(HashTable<Type> table, u64 key) {
|
||||||
for (ssize idx = 0; idx < ssize(table.Hashes.num()); ++idx)
|
for (ssize idx = 0; idx < ssize(num(table.Hashes)); ++idx)
|
||||||
if (table.Hashes[idx] == key)
|
if (table.Hashes[idx] == key)
|
||||||
return idx;
|
return idx;
|
||||||
|
|
||||||
@ -616,17 +631,17 @@ ssize slot(HashTable<Type>& table, u64 key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type> inline
|
template<typename Type> inline
|
||||||
ssize add_entry(HashTable<Type>& table, u64 key) {
|
ssize add_entry(HashTable<Type>* table, u64 key) {
|
||||||
ssize idx;
|
ssize idx;
|
||||||
HashTableEntry<Type> entry = { key, -1 };
|
HashTableEntry<Type> entry = { key, -1 };
|
||||||
|
|
||||||
idx = num(table.Entries);
|
idx = num(table->Entries);
|
||||||
append(table.Entries, entry);
|
append( & table->Entries, entry);
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type> inline
|
template<typename Type> inline
|
||||||
HashTableFindResult find(HashTable<Type>& table, u64 key)
|
HashTableFindResult find(HashTable<Type> table, u64 key)
|
||||||
{
|
{
|
||||||
HashTableFindResult result = { -1, -1, -1 };
|
HashTableFindResult result = { -1, -1, -1 };
|
||||||
|
|
||||||
@ -649,7 +664,7 @@ HashTableFindResult find(HashTable<Type>& table, u64 key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type> inline
|
template<typename Type> inline
|
||||||
bool full(HashTable<Type>& table) {
|
bool full(HashTable<Type> table) {
|
||||||
usize critical_load = usize(HashTable_CriticalLoadScale * f32(num(table.Hashes)));
|
usize critical_load = usize(HashTable_CriticalLoadScale * f32(num(table.Hashes)));
|
||||||
b32 result = num(table.Entries) > critical_load;
|
b32 result = num(table.Entries) > critical_load;
|
||||||
return result;
|
return result;
|
||||||
|
@ -612,7 +612,7 @@ GEN_FILE_WRITE_AT_PROC( _memory_file_write )
|
|||||||
|
|
||||||
if ( get_header(arr)->Capacity < usize(new_cap) )
|
if ( get_header(arr)->Capacity < usize(new_cap) )
|
||||||
{
|
{
|
||||||
if ( ! grow( arr, ( s64 )( new_cap ) ) )
|
if ( ! grow( & arr, ( s64 )( new_cap ) ) )
|
||||||
return false;
|
return false;
|
||||||
d->buf = arr;
|
d->buf = arr;
|
||||||
}
|
}
|
||||||
@ -647,7 +647,7 @@ GEN_FILE_CLOSE_PROC( _memory_file_close )
|
|||||||
if ( d->flags & EFileStream_CLONE_WRITABLE )
|
if ( d->flags & EFileStream_CLONE_WRITABLE )
|
||||||
{
|
{
|
||||||
Array<u8> arr = { d->buf };
|
Array<u8> arr = { d->buf };
|
||||||
free(arr);
|
free(& arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
free( allocator, d );
|
free( allocator, d );
|
||||||
|
@ -23,7 +23,11 @@
|
|||||||
#define bitfield_is_equal( Type, Field, Mask ) ( (Type(Mask) & Type(Field)) == Type(Mask) )
|
#define bitfield_is_equal( Type, Field, Mask ) ( (Type(Mask) & Type(Field)) == Type(Mask) )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if ! GEN_C_COMPILER
|
#if ! GEN_C_COMPILER
|
||||||
|
# ifndef cast
|
||||||
|
# define cast( type, value ) (tmpl_cast<type>( value ))
|
||||||
|
# endif
|
||||||
# ifndef ccast
|
# ifndef ccast
|
||||||
# define ccast( type, value ) ( const_cast< type >( (value) ) )
|
# define ccast( type, value ) ( const_cast< type >( (value) ) )
|
||||||
# endif
|
# endif
|
||||||
@ -37,11 +41,14 @@
|
|||||||
# define scast( type, value ) static_cast< type >( value )
|
# define scast( type, value ) static_cast< type >( value )
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
|
# ifndef cast
|
||||||
|
# define cast( type, value ) ( (type)(value) )
|
||||||
|
# endif
|
||||||
# ifndef ccast
|
# ifndef ccast
|
||||||
# define ccast( type, value ) ( (type)(value) )
|
# define ccast( type, value ) ( (type)(value) )
|
||||||
# endif
|
# endif
|
||||||
# ifndef pcast
|
# ifndef pcast
|
||||||
# define pcast( type, value ) ( (type)(value) )
|
# define pcast( type, value ) ( * (type*)(value) )
|
||||||
# endif
|
# endif
|
||||||
# ifndef rcast
|
# ifndef rcast
|
||||||
# define rcast( type, value ) ( (type)(value) )
|
# define rcast( type, value ) ( (type)(value) )
|
||||||
@ -181,8 +188,14 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(GEN_SUPPORT_CPP_MEMBER_FEATURES) && (!GEN_COMPILER_C || __STDC_VERSION__ < 202311L)
|
#if !defined(GEN_SUPPORT_CPP_REFERENCES) && (GEN_COMPILER_C || __STDC_VERSION__ < 202311L)
|
||||||
# define GEN_SUPPORT_CPP_MEMBER_FEATURES 0
|
# 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
|
#endif
|
||||||
|
|
||||||
#if !defined(typeof) && (!GEN_COMPILER_C || __STDC_VERSION__ < 202311L)
|
#if !defined(typeof) && (!GEN_COMPILER_C || __STDC_VERSION__ < 202311L)
|
||||||
@ -215,4 +228,10 @@
|
|||||||
# define enum_underlying(type) : type
|
# define enum_underlying(type) : type
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if GEN_COMPILER_C
|
||||||
|
# ifndef nullptr
|
||||||
|
# define nullptr NULL
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#pragma endregion Macros
|
#pragma endregion Macros
|
||||||
|
@ -62,21 +62,23 @@ void zero_size( void* ptr, ssize size );
|
|||||||
//! Clears up an array.
|
//! Clears up an array.
|
||||||
#define zero_array( a, count ) zero_size( ( a ), size_of( *( a ) ) * count )
|
#define zero_array( a, count ) zero_size( ( a ), size_of( *( a ) ) * count )
|
||||||
|
|
||||||
enum AllocType : u8
|
enum AllocType_Def //enum_underlying(u8)
|
||||||
{
|
{
|
||||||
EAllocation_ALLOC,
|
EAllocation_ALLOC,
|
||||||
EAllocation_FREE,
|
EAllocation_FREE,
|
||||||
EAllocation_FREE_ALL,
|
EAllocation_FREE_ALL,
|
||||||
EAllocation_RESIZE,
|
EAllocation_RESIZE,
|
||||||
};
|
};
|
||||||
|
typedef enum AllocType_Def AllocType;
|
||||||
|
|
||||||
typedef void*(AllocatorProc)( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
|
typedef void*(AllocatorProc)( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
|
||||||
|
|
||||||
struct AllocatorInfo
|
struct AllocatorInfo_Def
|
||||||
{
|
{
|
||||||
AllocatorProc* Proc;
|
AllocatorProc* Proc;
|
||||||
void* Data;
|
void* Data;
|
||||||
};
|
};
|
||||||
|
typedef struct AllocatorInfo_Def AllocatorInfo;
|
||||||
|
|
||||||
enum AllocFlag
|
enum AllocFlag
|
||||||
{
|
{
|
||||||
@ -132,7 +134,7 @@ void* default_resize_align( AllocatorInfo a, void* ptr, ssize old_size, ssize ne
|
|||||||
void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize 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 );
|
||||||
|
|
||||||
//! The heap allocator backed by operating system's memory manager.
|
//! The heap allocator backed by operating system's memory manager.
|
||||||
constexpr AllocatorInfo heap( void ) { return { heap_allocator_proc, nullptr }; }
|
constexpr AllocatorInfo heap( void ) { AllocatorInfo allocator = { heap_allocator_proc, nullptr }; return allocator; }
|
||||||
|
|
||||||
//! Helper to allocate memory using heap allocator.
|
//! Helper to allocate memory using heap allocator.
|
||||||
#define malloc( sz ) alloc( heap(), sz )
|
#define malloc( sz ) alloc( heap(), sz )
|
||||||
@ -170,26 +172,26 @@ ssize gen_virtual_memory_page_size( ssize* alignment_out );
|
|||||||
#pragma region Arena
|
#pragma region Arena
|
||||||
struct Arena;
|
struct Arena;
|
||||||
|
|
||||||
AllocatorInfo allocator_info( Arena& arena );
|
AllocatorInfo allocator_info( Arena* arena );
|
||||||
|
|
||||||
// Remove static keyword and rename allocator_proc
|
// Remove static keyword and rename allocator_proc
|
||||||
void* arena_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize 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);
|
||||||
|
|
||||||
// Add these declarations after the Arena struct
|
// Add these declarations after the Arena struct
|
||||||
Arena arena_init_from_allocator(AllocatorInfo backing, ssize size);
|
Arena arena_init_from_allocator(AllocatorInfo backing, ssize size);
|
||||||
Arena arena_init_from_memory( void* start, ssize size );
|
Arena arena_init_from_memory ( void* start, ssize size );
|
||||||
Arena init_sub(Arena& parent, ssize size);
|
|
||||||
ssize alignment_of(Arena& arena, ssize alignment);
|
Arena init_sub (Arena* parent, ssize size);
|
||||||
|
ssize alignment_of (Arena* arena, ssize alignment);
|
||||||
|
void free (Arena* arena);
|
||||||
|
ssize size_remaining(Arena* arena, ssize alignment);
|
||||||
|
|
||||||
// This id is defined by Unreal for asserts
|
// This id is defined by Unreal for asserts
|
||||||
#pragma push_macro("check")
|
#pragma push_macro("check")
|
||||||
#undef check
|
#undef check
|
||||||
void check(Arena& arena);
|
void check(Arena* arena);
|
||||||
#pragma pop_macro("check")
|
#pragma pop_macro("check")
|
||||||
|
|
||||||
void free(Arena& arena);
|
|
||||||
ssize size_remaining(Arena& arena, ssize alignment);
|
|
||||||
|
|
||||||
struct Arena
|
struct Arena
|
||||||
{
|
{
|
||||||
AllocatorInfo Backing;
|
AllocatorInfo Backing;
|
||||||
@ -200,29 +202,45 @@ struct Arena
|
|||||||
|
|
||||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||||
#pragma region Member Mapping
|
#pragma region Member Mapping
|
||||||
forceinline operator AllocatorInfo() { return GEN_NS allocator_info(* this); }
|
forceinline operator AllocatorInfo() { return GEN_NS allocator_info(this); }
|
||||||
|
|
||||||
forceinline static void* allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ) { return GEN_NS arena_allocator_proc( allocator_data, type, size, alignment, old_memory, old_size, flags ); }
|
forceinline static void* allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ) { return GEN_NS arena_allocator_proc( allocator_data, type, size, alignment, old_memory, old_size, flags ); }
|
||||||
forceinline static Arena init_from_memory( void* start, ssize size ) { return GEN_NS arena_init_from_memory( start, size ); }
|
forceinline static Arena init_from_memory( void* start, ssize size ) { return GEN_NS arena_init_from_memory( start, size ); }
|
||||||
forceinline static Arena init_from_allocator( AllocatorInfo backing, ssize size ) { return GEN_NS arena_init_from_allocator( backing, size ); }
|
forceinline static Arena init_from_allocator( AllocatorInfo backing, ssize size ) { return GEN_NS arena_init_from_allocator( backing, size ); }
|
||||||
forceinline static Arena init_sub( Arena& parent, ssize size ) { return GEN_NS arena_init_from_allocator( parent.Backing, size ); }
|
forceinline static Arena init_sub( Arena& parent, ssize size ) { return GEN_NS arena_init_from_allocator( parent.Backing, size ); }
|
||||||
forceinline ssize alignment_of( ssize alignment ) { return GEN_NS alignment_of(* this, alignment); }
|
forceinline ssize alignment_of( ssize alignment ) { return GEN_NS alignment_of(this, alignment); }
|
||||||
forceinline void free() { return GEN_NS free(* this); }
|
forceinline void free() { return GEN_NS free(this); }
|
||||||
forceinline ssize size_remaining( ssize alignment ) { return GEN_NS size_remaining(* this, alignment); }
|
forceinline ssize size_remaining( ssize alignment ) { return GEN_NS size_remaining(this, alignment); }
|
||||||
|
|
||||||
// This id is defined by Unreal for asserts
|
// This id is defined by Unreal for asserts
|
||||||
#pragma push_macro("check")
|
#pragma push_macro("check")
|
||||||
#undef check
|
#undef check
|
||||||
forceinline void check() { GEN_NS check(* this); }
|
forceinline void check() { GEN_NS check(this); }
|
||||||
#pragma pop_macro("check")
|
#pragma pop_macro("check")
|
||||||
|
|
||||||
#pragma endregion Member Mapping
|
#pragma endregion Member Mapping
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if GEN_SUPPORT_CPP_REFERENCES
|
||||||
|
forceinline AllocatorInfo allocator_info(Arena& arena ) { return allocator_info(& arena); }
|
||||||
|
forceinline Arena init_sub (Arena& parent, ssize size) { return init_sub( & parent, size); }
|
||||||
|
forceinline ssize alignment_of (Arena& arena, ssize alignment) { return alignment_of( & arena, alignment); }
|
||||||
|
forceinline void free (Arena& arena) { return free(& arena); }
|
||||||
|
forceinline ssize size_remaining(Arena& arena, ssize alignment) { return size_remaining(& arena, alignment); }
|
||||||
|
|
||||||
|
// This id is defined by Unreal for asserts
|
||||||
|
#pragma push_macro("check")
|
||||||
|
#undef check
|
||||||
|
forceinline void check(Arena& arena) { return check(& arena); };
|
||||||
|
#pragma pop_macro("check")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
inline
|
inline
|
||||||
AllocatorInfo allocator_info( Arena& arena ) {
|
AllocatorInfo allocator_info( Arena* arena ) {
|
||||||
return { arena_allocator_proc, &arena };
|
GEN_ASSERT(arena != nullptr);
|
||||||
|
return { arena_allocator_proc, arena };
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
@ -251,18 +269,20 @@ Arena arena_init_from_allocator(AllocatorInfo backing, ssize size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
Arena init_sub(Arena& parent, ssize size) {
|
Arena init_sub(Arena* parent, ssize size) {
|
||||||
return arena_init_from_allocator(parent.Backing, size);
|
GEN_ASSERT(parent != nullptr);
|
||||||
|
return arena_init_from_allocator(parent->Backing, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
ssize alignment_of(Arena& arena, ssize alignment)
|
ssize alignment_of(Arena* arena, ssize alignment)
|
||||||
{
|
{
|
||||||
|
GEN_ASSERT(arena != nullptr);
|
||||||
ssize alignment_offset, result_pointer, mask;
|
ssize alignment_offset, result_pointer, mask;
|
||||||
GEN_ASSERT(is_power_of_two(alignment));
|
GEN_ASSERT(is_power_of_two(alignment));
|
||||||
|
|
||||||
alignment_offset = 0;
|
alignment_offset = 0;
|
||||||
result_pointer = (ssize)arena.PhysicalStart + arena.TotalUsed;
|
result_pointer = (ssize)arena->PhysicalStart + arena->TotalUsed;
|
||||||
mask = alignment - 1;
|
mask = alignment - 1;
|
||||||
|
|
||||||
if (result_pointer & mask)
|
if (result_pointer & mask)
|
||||||
@ -274,26 +294,29 @@ ssize alignment_of(Arena& arena, ssize alignment)
|
|||||||
#pragma push_macro("check")
|
#pragma push_macro("check")
|
||||||
#undef check
|
#undef check
|
||||||
inline
|
inline
|
||||||
void check(Arena& arena)
|
void check(Arena* arena)
|
||||||
{
|
{
|
||||||
GEN_ASSERT(arena.TempCount == 0);
|
GEN_ASSERT(arena != nullptr );
|
||||||
|
GEN_ASSERT(arena->TempCount == 0);
|
||||||
}
|
}
|
||||||
#pragma pop_macro("check")
|
#pragma pop_macro("check")
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void free(Arena& arena)
|
void free(Arena* arena)
|
||||||
{
|
{
|
||||||
if (arena.Backing.Proc)
|
GEN_ASSERT(arena != nullptr);
|
||||||
|
if (arena->Backing.Proc)
|
||||||
{
|
{
|
||||||
GEN_NS free(arena.Backing, arena.PhysicalStart);
|
GEN_NS free(arena->Backing, arena->PhysicalStart);
|
||||||
arena.PhysicalStart = nullptr;
|
arena->PhysicalStart = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
ssize size_remaining(Arena& arena, ssize alignment)
|
ssize size_remaining(Arena* arena, ssize alignment)
|
||||||
{
|
{
|
||||||
ssize result = arena.TotalSize - (arena.TotalUsed + alignment_of(arena, alignment));
|
GEN_ASSERT(arena != nullptr);
|
||||||
|
ssize result = arena->TotalSize - (arena->TotalUsed + alignment_of(arena, alignment));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#pragma endregion Arena
|
#pragma endregion Arena
|
||||||
@ -302,9 +325,14 @@ ssize size_remaining(Arena& arena, ssize alignment)
|
|||||||
template<s32 Size>
|
template<s32 Size>
|
||||||
struct FixedArena;
|
struct FixedArena;
|
||||||
|
|
||||||
template<s32 Size> AllocatorInfo allocator_info( FixedArena<Size>& fixed_arena );
|
|
||||||
template<s32 Size> FixedArena<Size> fixed_arena_init();
|
template<s32 Size> FixedArena<Size> fixed_arena_init();
|
||||||
template<s32 Size> ssize size_remaining(FixedArena<Size>& fixed_arena, ssize alignment);
|
template<s32 Size> AllocatorInfo allocator_info(FixedArena<Size>* fixed_arena );
|
||||||
|
template<s32 Size> ssize size_remaining(FixedArena<Size>* fixed_arena, ssize alignment);
|
||||||
|
|
||||||
|
#if GEN_SUPPORT_CPP_REFERENCES
|
||||||
|
template<s32 Size> AllocatorInfo allocator_info( FixedArena<Size>& fixed_arena ) { return allocator_info(& fixed_arena); }
|
||||||
|
template<s32 Size> ssize size_remaining(FixedArena<Size>& fixed_arena, ssize alignment) { return size_remaining( & fixed_arena, alignment); }
|
||||||
|
#endif
|
||||||
|
|
||||||
// Just a wrapper around using an arena with memory associated with its scope instead of from an allocator.
|
// Just a wrapper around using an arena with memory associated with its scope instead of from an allocator.
|
||||||
// Used for static segment or stack allocations.
|
// Used for static segment or stack allocations.
|
||||||
@ -316,26 +344,29 @@ struct FixedArena
|
|||||||
|
|
||||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||||
#pragma region Member Mapping
|
#pragma region Member Mapping
|
||||||
forceinline operator AllocatorInfo() { return GEN_NS allocator_info(* this); }
|
forceinline operator AllocatorInfo() { return GEN_NS allocator_info(this); }
|
||||||
|
|
||||||
forceinline static FixedArena init() { FixedArena result; GEN_NS fixed_arena_init<Size>(result); return result; }
|
forceinline static FixedArena init() { FixedArena result; GEN_NS fixed_arena_init<Size>(result); return result; }
|
||||||
forceinline ssize size_remaining(ssize alignment) { GEN_NS size_remaining(*this, alignment); }
|
forceinline ssize size_remaining(ssize alignment) { GEN_NS size_remaining(this, alignment); }
|
||||||
#pragma endregion Member Mapping
|
#pragma endregion Member Mapping
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
template<s32 Size> inline
|
template<s32 Size> inline
|
||||||
AllocatorInfo allocator_info( FixedArena<Size>& fixed_arena ) { return { arena_allocator_proc, & fixed_arena.arena }; }
|
AllocatorInfo allocator_info( FixedArena<Size>* fixed_arena ) {
|
||||||
|
GEN_ASSERT(fixed_arena);
|
||||||
template<s32 Size> inline
|
return { arena_allocator_proc, & fixed_arena->arena };
|
||||||
void fixed_arena_init(FixedArena<Size>& result) {
|
|
||||||
zero_size(& result.memory[0], Size);
|
|
||||||
result.arena = arena_init_from_memory(& result.memory[0], Size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<s32 Size> inline
|
template<s32 Size> inline
|
||||||
ssize size_remaining(FixedArena<Size>& fixed_arena, ssize alignment) {
|
void fixed_arena_init(FixedArena<Size>* result) {
|
||||||
return size_remaining(fixed_arena.arena, alignment);
|
zero_size(& result->memory[0], Size);
|
||||||
|
result->arena = arena_init_from_memory(& result->memory[0], Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<s32 Size> inline
|
||||||
|
ssize size_remaining(FixedArena<Size>* fixed_arena, ssize alignment) {
|
||||||
|
return size_remaining(fixed_arena->arena, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
using Arena_1KB = FixedArena< kilobytes( 1 ) >;
|
using Arena_1KB = FixedArena< kilobytes( 1 ) >;
|
||||||
@ -355,12 +386,19 @@ using Arena_4MB = FixedArena< megabytes( 4 ) >;
|
|||||||
#pragma region Pool
|
#pragma region Pool
|
||||||
struct Pool;
|
struct Pool;
|
||||||
|
|
||||||
AllocatorInfo allocator_info(Pool& pool);
|
void* pool_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags);
|
||||||
void* pool_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags);
|
|
||||||
Pool pool_init(AllocatorInfo backing, ssize num_blocks, ssize block_size);
|
Pool pool_init(AllocatorInfo backing, ssize num_blocks, ssize block_size);
|
||||||
Pool pool_init_align(AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align);
|
Pool pool_init_align(AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align);
|
||||||
|
AllocatorInfo allocator_info(Pool* pool);
|
||||||
|
void clear(Pool* pool);
|
||||||
|
void free(Pool* pool);
|
||||||
|
|
||||||
|
#if GEN_SUPPORT_CPP_REFERENCES
|
||||||
|
AllocatorInfo allocator_info(Pool& pool);
|
||||||
void clear(Pool& pool);
|
void clear(Pool& pool);
|
||||||
void free(Pool& pool);
|
void free(Pool& pool);
|
||||||
|
#endif
|
||||||
|
|
||||||
struct Pool
|
struct Pool
|
||||||
{
|
{
|
||||||
@ -374,20 +412,20 @@ struct Pool
|
|||||||
|
|
||||||
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||||
#pragma region Member Mapping
|
#pragma region Member Mapping
|
||||||
forceinline operator AllocatorInfo() { return GEN_NS allocator_info(* this); }
|
forceinline operator AllocatorInfo() { return GEN_NS allocator_info(this); }
|
||||||
|
|
||||||
forceinline static void* allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags) { return GEN_NS pool_allocator_proc(allocator_data, type, size, alignment, old_memory, old_size, flags); }
|
forceinline static void* allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags) { return GEN_NS pool_allocator_proc(allocator_data, type, size, alignment, old_memory, old_size, flags); }
|
||||||
forceinline static Pool init(AllocatorInfo backing, ssize num_blocks, ssize block_size) { return GEN_NS pool_init(backing, num_blocks, block_size); }
|
forceinline static Pool init(AllocatorInfo backing, ssize num_blocks, ssize block_size) { return GEN_NS pool_init(backing, num_blocks, block_size); }
|
||||||
forceinline static Pool init_align(AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align) { return GEN_NS pool_init_align(backing, num_blocks, block_size, block_align); }
|
forceinline static Pool init_align(AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align) { return GEN_NS pool_init_align(backing, num_blocks, block_size, block_align); }
|
||||||
forceinline void clear() { GEN_NS clear(* this); }
|
forceinline void clear() { GEN_NS clear( this); }
|
||||||
forceinline void free() { GEN_NS free(* this); }
|
forceinline void free() { GEN_NS free( this); }
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
inline
|
inline
|
||||||
AllocatorInfo allocator_info(Pool& pool) {
|
AllocatorInfo allocator_info(Pool* pool) {
|
||||||
return { pool_allocator_proc, &pool };
|
return { pool_allocator_proc, pool };
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
@ -396,9 +434,9 @@ Pool pool_init(AllocatorInfo backing, ssize num_blocks, ssize block_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void free(Pool& pool) {
|
void free(Pool* pool) {
|
||||||
if(pool.Backing.Proc) {
|
if(pool->Backing.Proc) {
|
||||||
GEN_NS free(pool.Backing, pool.PhysicalStart);
|
GEN_NS free(pool->Backing, pool->PhysicalStart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#pragma endregion Pool
|
#pragma endregion Pool
|
||||||
|
@ -41,7 +41,7 @@ u8 adt_destroy_branch( ADT_Node* node )
|
|||||||
adt_destroy_branch( node->nodes + i );
|
adt_destroy_branch( node->nodes + i );
|
||||||
}
|
}
|
||||||
|
|
||||||
free(node->nodes);
|
free(& node->nodes);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -287,10 +287,11 @@ ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index )
|
|||||||
|
|
||||||
ADT_Node o = { 0 };
|
ADT_Node o = { 0 };
|
||||||
o.parent = parent;
|
o.parent = parent;
|
||||||
if ( ! append_at( parent->nodes, o, index ) )
|
if ( ! append_at( & parent->nodes, o, index ) )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return parent->nodes + index;
|
ADT_Node* node = & parent->nodes[index];
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
ADT_Node* adt_alloc( ADT_Node* parent )
|
ADT_Node* adt_alloc( ADT_Node* parent )
|
||||||
@ -402,7 +403,9 @@ ADT_Node* adt_append_arr( ADT_Node* parent, char const* name )
|
|||||||
ADT_Node* o = adt_alloc( parent );
|
ADT_Node* o = adt_alloc( parent );
|
||||||
if ( ! o )
|
if ( ! o )
|
||||||
return NULL;
|
return NULL;
|
||||||
if ( adt_set_arr( o, name, get_header(parent->nodes)->Allocator ) )
|
|
||||||
|
ArrayHeader* node_header = get_header(parent->nodes);
|
||||||
|
if ( adt_set_arr( o, name, node_header->Allocator ) )
|
||||||
{
|
{
|
||||||
adt_remove_node( o );
|
adt_remove_node( o );
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -951,7 +954,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
|
|||||||
adt_append_arr( root, NULL );
|
adt_append_arr( root, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
append(root->nodes[ columnIndex ].nodes, rowItem );
|
append( & root->nodes[ columnIndex ].nodes, rowItem );
|
||||||
|
|
||||||
if ( delimiter == delim )
|
if ( delimiter == delim )
|
||||||
{
|
{
|
||||||
|
@ -83,7 +83,7 @@ struct ADT_Node
|
|||||||
union
|
union
|
||||||
{
|
{
|
||||||
char const* string;
|
char const* string;
|
||||||
Array<ADT_Node> nodes; ///< zpl_array
|
Array(ADT_Node) nodes; ///< zpl_array
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -125,9 +125,13 @@
|
|||||||
# include <intrin.h>
|
# include <intrin.h>
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
#if GEN_COMPILER_C
|
||||||
|
#include <assert.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#pragma endregion Mandatory Includes
|
#pragma endregion Mandatory Includes
|
||||||
|
|
||||||
#if GEN_DONT_USE_NAMESPACE
|
#if GEN_DONT_USE_NAMESPACE || GEN_COMPILER_C
|
||||||
# if GEN_COMPILER_C
|
# if GEN_COMPILER_C
|
||||||
# define GEN_NS_ENUM_BEGIN
|
# define GEN_NS_ENUM_BEGIN
|
||||||
# define GEN_NS_ENUM_END
|
# define GEN_NS_ENUM_END
|
||||||
|
@ -33,40 +33,41 @@ StrC to_str( char const* str ) {
|
|||||||
struct StringHeader;
|
struct StringHeader;
|
||||||
struct String;
|
struct String;
|
||||||
|
|
||||||
String string_make(AllocatorInfo allocator, char const* str);
|
usize string_grow_formula(usize value);
|
||||||
String string_make(AllocatorInfo allocator, StrC str);
|
|
||||||
String string_make_reserve(AllocatorInfo allocator, ssize capacity);
|
String string_make (AllocatorInfo allocator, char const* str);
|
||||||
String string_make_length(AllocatorInfo allocator, char const* str, ssize length);
|
String string_make (AllocatorInfo allocator, StrC str);
|
||||||
String string_fmt(AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...);
|
String string_make_reserve (AllocatorInfo allocator, ssize capacity);
|
||||||
String string_fmt_buf(AllocatorInfo allocator, char const* fmt, ...);
|
String string_make_length (AllocatorInfo allocator, char const* str, ssize length);
|
||||||
String string_join(AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue);
|
String string_fmt (AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...);
|
||||||
usize string_grow_formula(usize value);
|
String string_fmt_buf (AllocatorInfo allocator, char const* fmt, ...);
|
||||||
bool are_equal(String const& lhs, String const& rhs);
|
String string_join (AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue);
|
||||||
bool are_equal(String const& lhs, StrC rhs);
|
bool are_equal (String const lhs, String const rhs);
|
||||||
bool make_space_for(String& str, char const* to_append, ssize add_len);
|
bool are_equal (String const lhs, StrC rhs);
|
||||||
bool append(String& str, char c);
|
bool make_space_for (String* str, char const* to_append, ssize add_len);
|
||||||
bool append(String& str, char const* str_to_append);
|
bool append (String* str, char c);
|
||||||
bool append(String& str, char const* str_to_append, ssize length);
|
bool append (String* str, char const* str_to_append);
|
||||||
bool append(String& str, StrC str_to_append);
|
bool append (String* str, char const* str_to_append, ssize length);
|
||||||
bool append(String& str, const String other);
|
bool append (String* str, StrC str_to_append);
|
||||||
bool append_fmt(String& str, char const* fmt, ...);
|
bool append (String* str, String const other);
|
||||||
ssize avail_space(String const& str);
|
bool append_fmt (String* str, char const* fmt, ...);
|
||||||
char& back(String& str);
|
ssize avail_space (String const str);
|
||||||
bool contains(String const& str, StrC substring);
|
char* back (String str);
|
||||||
bool contains(String const& str, String const& substring);
|
bool contains (String const str, StrC substring);
|
||||||
ssize capacity(String const& str);
|
bool contains (String const str, String const substring);
|
||||||
void clear(String& str);
|
ssize capacity (String const str);
|
||||||
String duplicate(String const& str, AllocatorInfo allocator);
|
void clear (String str);
|
||||||
void free(String& str);
|
String duplicate (String const str, AllocatorInfo allocator);
|
||||||
StringHeader& get_header(String& str);
|
void free (String* str);
|
||||||
ssize length(String const& str);
|
StringHeader* get_header (String str);
|
||||||
b32 starts_with(String const& str, StrC substring);
|
ssize length (String const str);
|
||||||
b32 starts_with(String const& str, String substring);
|
b32 starts_with (String const str, StrC substring);
|
||||||
void skip_line(String& str);
|
b32 starts_with (String const str, String substring);
|
||||||
void strip_space(String& str);
|
void skip_line (String str);
|
||||||
void trim(String& str, char const* cut_set);
|
void strip_space (String str);
|
||||||
void trim_space(String& str);
|
void trim (String str, char const* cut_set);
|
||||||
String visualize_whitespace(String const& str);
|
void trim_space (String str);
|
||||||
|
String visualize_whitespace(String const str);
|
||||||
|
|
||||||
struct StringHeader {
|
struct StringHeader {
|
||||||
AllocatorInfo Allocator;
|
AllocatorInfo Allocator;
|
||||||
@ -129,31 +130,31 @@ struct String
|
|||||||
return GEN_NS string_make(allocator, buf);
|
return GEN_NS string_make(allocator, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline bool make_space_for(char const* str, ssize add_len) { return GEN_NS make_space_for(*this, str, add_len); }
|
forceinline bool make_space_for(char const* str, ssize add_len) { return GEN_NS make_space_for(this, str, add_len); }
|
||||||
forceinline bool append(char c) { return GEN_NS append(*this, c); }
|
forceinline bool append(char c) { return GEN_NS append(this, c); }
|
||||||
forceinline bool append(char const* str) { return GEN_NS append(*this, str); }
|
forceinline bool append(char const* str) { return GEN_NS append(this, str); }
|
||||||
forceinline bool append(char const* str, ssize length) { return GEN_NS append(*this, str, length); }
|
forceinline bool append(char const* str, ssize length) { return GEN_NS append(this, str, length); }
|
||||||
forceinline bool append(StrC str) { return GEN_NS append(*this, str); }
|
forceinline bool append(StrC str) { return GEN_NS append(this, str); }
|
||||||
forceinline bool append(const String other) { return GEN_NS append(*this, other); }
|
forceinline bool append(const String other) { return GEN_NS append(this, other); }
|
||||||
forceinline ssize avail_space() const { return GEN_NS avail_space(*this); }
|
forceinline ssize avail_space() const { return GEN_NS avail_space(* this); }
|
||||||
forceinline char& back() { return GEN_NS back(*this); }
|
forceinline char* back() { return GEN_NS back(* this); }
|
||||||
forceinline bool contains(StrC substring) const { return GEN_NS contains(*this, substring); }
|
forceinline bool contains(StrC substring) const { return GEN_NS contains(* this, substring); }
|
||||||
forceinline bool contains(String const& substring) const { return GEN_NS contains(*this, substring); }
|
forceinline bool contains(String const& substring) const { return GEN_NS contains(* this, substring); }
|
||||||
forceinline ssize capacity() const { return GEN_NS capacity(*this); }
|
forceinline ssize capacity() const { return GEN_NS capacity(* this); }
|
||||||
forceinline void clear() { GEN_NS clear(*this); }
|
forceinline void clear() { GEN_NS clear(* this); }
|
||||||
forceinline String duplicate(AllocatorInfo allocator) const { return GEN_NS duplicate(*this, allocator); }
|
forceinline String duplicate(AllocatorInfo allocator) const { return GEN_NS duplicate(* this, allocator); }
|
||||||
forceinline void free() { GEN_NS free(*this); }
|
forceinline void free() { GEN_NS free(this); }
|
||||||
forceinline bool is_equal(String const& other) const { return GEN_NS are_equal(* this, other); }
|
forceinline bool is_equal(String const& other) const { return GEN_NS are_equal(* this, other); }
|
||||||
forceinline bool is_equal(StrC other) const { return GEN_NS are_equal(* this, other); }
|
forceinline bool is_equal(StrC other) const { return GEN_NS are_equal(* this, other); }
|
||||||
forceinline ssize length() const { return GEN_NS length(*this); }
|
forceinline ssize length() const { return GEN_NS length(* this); }
|
||||||
forceinline b32 starts_with(StrC substring) const { return GEN_NS starts_with(*this, substring); }
|
forceinline b32 starts_with(StrC substring) const { return GEN_NS starts_with(* this, substring); }
|
||||||
forceinline b32 starts_with(String substring) const { return GEN_NS starts_with(*this, substring); }
|
forceinline b32 starts_with(String substring) const { return GEN_NS starts_with(* this, substring); }
|
||||||
forceinline void skip_line() { GEN_NS skip_line(*this); }
|
forceinline void skip_line() { GEN_NS skip_line(* this); }
|
||||||
forceinline void strip_space() { GEN_NS strip_space(*this); }
|
forceinline void strip_space() { GEN_NS strip_space(* this); }
|
||||||
forceinline void trim(char const* cut_set) { GEN_NS trim(*this, cut_set); }
|
forceinline void trim(char const* cut_set) { GEN_NS trim(* this, cut_set); }
|
||||||
forceinline void trim_space() { GEN_NS trim_space(*this); }
|
forceinline void trim_space() { GEN_NS trim_space(* this); }
|
||||||
forceinline String visualize_whitespace() const { return GEN_NS visualize_whitespace(*this); }
|
forceinline String visualize_whitespace() const { return GEN_NS visualize_whitespace(* this); }
|
||||||
forceinline StringHeader& get_header() { return GEN_NS get_header(*this); }
|
forceinline StringHeader& get_header() { return * GEN_NS get_header(* this); }
|
||||||
|
|
||||||
bool append_fmt(char const* fmt, ...) {
|
bool append_fmt(char const* fmt, ...) {
|
||||||
ssize res;
|
ssize res;
|
||||||
@ -164,13 +165,26 @@ struct String
|
|||||||
res = str_fmt_va(buf, count_of(buf) - 1, fmt, va) - 1;
|
res = str_fmt_va(buf, count_of(buf) - 1, fmt, va) - 1;
|
||||||
va_end(va);
|
va_end(va);
|
||||||
|
|
||||||
return GEN_NS append(*this, buf, res);
|
return GEN_NS append(this, buf, res);
|
||||||
}
|
}
|
||||||
#pragma endregion Member Mapping
|
#pragma endregion Member Mapping
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if GEN_SUPPORT_CPP_REFERENCES
|
||||||
|
bool make_space_for(String& str, char const* to_append, ssize add_len);
|
||||||
|
bool append(String& str, char c);
|
||||||
|
bool append(String& str, char const* str_to_append);
|
||||||
|
bool append(String& str, char const* str_to_append, ssize length);
|
||||||
|
bool append(String& str, StrC str_to_append);
|
||||||
|
bool append(String& str, const String other);
|
||||||
|
bool append_fmt(String& str, char const* fmt, ...);
|
||||||
|
char& back(String& str);
|
||||||
|
void clear(String& str);
|
||||||
|
void free(String& str);
|
||||||
|
#endif
|
||||||
|
|
||||||
inline char* begin(String& str) { return str; }
|
inline char* begin(String& str) { return str; }
|
||||||
inline char* end(String& str) { return scast(char*, str) + length(str); }
|
inline char* end(String& str) { return scast(char*, str) + length(str); }
|
||||||
inline char* next(String& str) { return scast(char*, str) + 1; }
|
inline char* next(String& str) { return scast(char*, str) + 1; }
|
||||||
@ -223,57 +237,64 @@ String string_join(AllocatorInfo allocator, char const** parts, ssize num_parts,
|
|||||||
|
|
||||||
for (ssize idx = 0; idx < num_parts; ++idx)
|
for (ssize idx = 0; idx < num_parts; ++idx)
|
||||||
{
|
{
|
||||||
append(result, parts[idx]);
|
append(& result, parts[idx]);
|
||||||
|
|
||||||
if (idx < num_parts - 1)
|
if (idx < num_parts - 1)
|
||||||
append(result, glue);
|
append(& result, glue);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool append(String& str, char c) {
|
bool append(String* str, char c) {
|
||||||
|
GEN_ASSERT(str != nullptr);
|
||||||
return append(str, &c, 1);
|
return append(str, &c, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool append(String& str, char const* str_to_append) {
|
bool append(String* str, char const* str_to_append) {
|
||||||
|
GEN_ASSERT(str != nullptr);
|
||||||
return append(str, str_to_append, str_len(str_to_append));
|
return append(str, str_to_append, str_len(str_to_append));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool append(String& str, char const* str_to_append, ssize append_length)
|
bool append(String* str, char const* str_to_append, ssize append_length)
|
||||||
{
|
{
|
||||||
|
GEN_ASSERT(str != nullptr);
|
||||||
if (sptr(str_to_append) > 0)
|
if (sptr(str_to_append) > 0)
|
||||||
{
|
{
|
||||||
ssize curr_len = length(str);
|
ssize curr_len = length(* str);
|
||||||
|
|
||||||
if (!make_space_for(str, str_to_append, append_length))
|
if ( ! make_space_for(str, str_to_append, append_length))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
StringHeader& header = get_header(str);
|
StringHeader* header = get_header(* str);
|
||||||
|
|
||||||
mem_copy( scast(char*, str) + curr_len, str_to_append, append_length);
|
char* Data = * str;
|
||||||
|
mem_copy( Data + curr_len, str_to_append, append_length);
|
||||||
|
|
||||||
str[curr_len + append_length] = '\0';
|
Data[curr_len + append_length] = '\0';
|
||||||
|
|
||||||
header.Length = curr_len + append_length;
|
header->Length = curr_len + append_length;
|
||||||
}
|
}
|
||||||
return str_to_append != nullptr;
|
return str_to_append != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool append(String& str, StrC str_to_append) {
|
bool append(String* str, StrC str_to_append) {
|
||||||
|
GEN_ASSERT(str != nullptr);
|
||||||
return append(str, str_to_append.Ptr, str_to_append.Len);
|
return append(str, str_to_append.Ptr, str_to_append.Len);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool append(String& str, const String other) {
|
bool append(String* str, const String other) {
|
||||||
|
GEN_ASSERT(str != nullptr);
|
||||||
return append(str, other, length(other));
|
return append(str, other, length(other));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool append_fmt(String& str, char const* fmt, ...) {
|
bool append_fmt(String* str, char const* fmt, ...) {
|
||||||
|
GEN_ASSERT(str != nullptr);
|
||||||
ssize res;
|
ssize res;
|
||||||
char buf[GEN_PRINTF_MAXLEN] = { 0 };
|
char buf[GEN_PRINTF_MAXLEN] = { 0 };
|
||||||
|
|
||||||
@ -286,7 +307,7 @@ bool append_fmt(String& str, char const* fmt, ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool are_equal(String const& lhs, String const& rhs)
|
bool are_equal(String const lhs, String const rhs)
|
||||||
{
|
{
|
||||||
if (length(lhs) != length(rhs))
|
if (length(lhs) != length(rhs))
|
||||||
return false;
|
return false;
|
||||||
@ -299,43 +320,43 @@ bool are_equal(String const& lhs, String const& rhs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool are_equal(String const& lhs, StrC rhs)
|
bool are_equal(String const lhs, StrC rhs)
|
||||||
{
|
{
|
||||||
if (length(lhs) != (rhs.Len))
|
if (length(lhs) != (rhs.Len))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (ssize idx = 0; idx < length(lhs); ++idx)
|
for (ssize idx = 0; idx < length(lhs); ++idx)
|
||||||
if (lhs[idx] != rhs[idx])
|
if (lhs[idx] != rhs.Ptr[idx])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
ssize avail_space(String const& str) {
|
ssize avail_space(String const str) {
|
||||||
StringHeader const& header = *rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
||||||
return header.Capacity - header.Length;
|
return header->Capacity - header->Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
char& back(String& str) {
|
char* back(String* str) {
|
||||||
return str.Data[length(str) - 1];
|
return & (*str)[length(* str) - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool contains(String const& str, StrC substring)
|
bool contains(String const str, StrC substring)
|
||||||
{
|
{
|
||||||
StringHeader const& header = *rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
||||||
|
|
||||||
if (substring.Len > header.Length)
|
if (substring.Len > header->Length)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ssize main_len = header.Length;
|
ssize main_len = header->Length;
|
||||||
ssize sub_len = substring.Len;
|
ssize sub_len = substring.Len;
|
||||||
|
|
||||||
for (ssize idx = 0; idx <= main_len - sub_len; ++idx)
|
for (ssize idx = 0; idx <= main_len - sub_len; ++idx)
|
||||||
{
|
{
|
||||||
if (str_compare(str.Data + idx, substring.Ptr, sub_len) == 0)
|
if (str_compare(str + idx, substring.Ptr, sub_len) == 0)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,19 +364,19 @@ bool contains(String const& str, StrC substring)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool contains(String const& str, String const& substring)
|
bool contains(String const str, String const substring)
|
||||||
{
|
{
|
||||||
StringHeader const& header = *rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
||||||
|
|
||||||
if (length(substring) > header.Length)
|
if (length(substring) > header->Length)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ssize main_len = header.Length;
|
ssize main_len = header->Length;
|
||||||
ssize sub_len = length(substring);
|
ssize sub_len = length(substring);
|
||||||
|
|
||||||
for (ssize idx = 0; idx <= main_len - sub_len; ++idx)
|
for (ssize idx = 0; idx <= main_len - sub_len; ++idx)
|
||||||
{
|
{
|
||||||
if (str_compare(str.Data + idx, substring.Data, sub_len) == 0)
|
if (str_compare(str + idx, substring, sub_len) == 0)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,46 +384,47 @@ bool contains(String const& str, String const& substring)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
ssize capacity(String const& str) {
|
ssize capacity(String const str) {
|
||||||
StringHeader const& header = *rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
||||||
return header.Capacity;
|
return header->Capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void clear(String& str) {
|
void clear(String str) {
|
||||||
get_header(str).Length = 0;
|
get_header(str)->Length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
String duplicate(String const& str, AllocatorInfo allocator) {
|
String duplicate(String const str, AllocatorInfo allocator) {
|
||||||
return string_make_length(allocator, str, length(str));
|
return string_make_length(allocator, str, length(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void free(String& str) {
|
void free(String* str) {
|
||||||
if (!str.Data)
|
GEN_ASSERT(str != nullptr);
|
||||||
return;
|
if (! (* str))
|
||||||
|
return;
|
||||||
|
|
||||||
StringHeader& header = get_header(str);
|
StringHeader* header = get_header(* str);
|
||||||
GEN_NS free(header.Allocator, &header);
|
GEN_NS free(header->Allocator, header);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
StringHeader& get_header(String& str) {
|
StringHeader* get_header(String str) {
|
||||||
return *(StringHeader*)(str.Data - sizeof(StringHeader));
|
return (StringHeader*)(scast(char*, str) - sizeof(StringHeader));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
ssize length(String const& str)
|
ssize length(String const str)
|
||||||
{
|
{
|
||||||
StringHeader const& header = *rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
StringHeader const& header = *rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
||||||
return header.Length;
|
return header.Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool make_space_for(String& str, char const* to_append, ssize add_len)
|
bool make_space_for(String* str, char const* to_append, ssize add_len)
|
||||||
{
|
{
|
||||||
ssize available = avail_space(str);
|
ssize available = avail_space(* str);
|
||||||
|
|
||||||
if (available >= add_len) {
|
if (available >= add_len) {
|
||||||
return true;
|
return true;
|
||||||
@ -413,12 +435,12 @@ bool make_space_for(String& str, char const* to_append, ssize add_len)
|
|||||||
void* ptr;
|
void* ptr;
|
||||||
void* new_ptr;
|
void* new_ptr;
|
||||||
|
|
||||||
AllocatorInfo allocator = get_header(str).Allocator;
|
AllocatorInfo allocator = get_header(* str)->Allocator;
|
||||||
StringHeader* header = nullptr;
|
StringHeader* header = nullptr;
|
||||||
|
|
||||||
new_len = string_grow_formula(length(str) + add_len);
|
new_len = string_grow_formula(length(* str) + add_len);
|
||||||
ptr = &get_header(str);
|
ptr = get_header(* str);
|
||||||
old_size = size_of(StringHeader) + length(str) + 1;
|
old_size = size_of(StringHeader) + length(* str) + 1;
|
||||||
new_size = size_of(StringHeader) + new_len + 1;
|
new_size = size_of(StringHeader) + new_len + 1;
|
||||||
|
|
||||||
new_ptr = resize(allocator, ptr, old_size, new_size);
|
new_ptr = resize(allocator, ptr, old_size, new_size);
|
||||||
@ -428,16 +450,17 @@ bool make_space_for(String& str, char const* to_append, ssize add_len)
|
|||||||
|
|
||||||
header = rcast(StringHeader*, new_ptr);
|
header = rcast(StringHeader*, new_ptr);
|
||||||
header->Allocator = allocator;
|
header->Allocator = allocator;
|
||||||
header->Capacity = new_len;
|
header->Capacity = new_len;
|
||||||
|
|
||||||
str.Data = rcast(char*, header + 1);
|
char** Data = rcast(char**, str);
|
||||||
|
* Data = rcast(char*, header + 1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
b32 starts_with(String const& str, StrC substring) {
|
b32 starts_with(String const str, StrC substring) {
|
||||||
if (substring.Len > length(str))
|
if (substring.Len > length(str))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -446,7 +469,7 @@ b32 starts_with(String const& str, StrC substring) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
b32 starts_with(String const& str, String substring) {
|
b32 starts_with(String const str, String substring) {
|
||||||
if (length(substring) > length(str))
|
if (length(substring) > length(str))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -455,7 +478,7 @@ b32 starts_with(String const& str, String substring) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void skip_line(String& str)
|
void skip_line(String str)
|
||||||
{
|
{
|
||||||
#define current (*scanner)
|
#define current (*scanner)
|
||||||
char* scanner = str.Data;
|
char* scanner = str.Data;
|
||||||
@ -471,23 +494,23 @@ void skip_line(String& str)
|
|||||||
|
|
||||||
mem_move(str.Data, scanner, new_length);
|
mem_move(str.Data, scanner, new_length);
|
||||||
|
|
||||||
StringHeader* header = &get_header(str);
|
StringHeader* header = get_header(str);
|
||||||
header->Length = new_length;
|
header->Length = new_length;
|
||||||
#undef current
|
#undef current
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void strip_space(String& str)
|
void strip_space(String str)
|
||||||
{
|
{
|
||||||
char* write_pos = str.Data;
|
char* write_pos = str;
|
||||||
char* read_pos = str.Data;
|
char* read_pos = str;
|
||||||
|
|
||||||
while (*read_pos)
|
while (* read_pos)
|
||||||
{
|
{
|
||||||
if (!char_is_space(*read_pos))
|
if (! char_is_space(* read_pos))
|
||||||
{
|
{
|
||||||
*write_pos = *read_pos;
|
* write_pos = * read_pos;
|
||||||
write_pos++;
|
write_pos++;
|
||||||
}
|
}
|
||||||
read_pos++;
|
read_pos++;
|
||||||
}
|
}
|
||||||
@ -495,11 +518,11 @@ void strip_space(String& str)
|
|||||||
write_pos[0] = '\0'; // Null-terminate the modified string
|
write_pos[0] = '\0'; // Null-terminate the modified string
|
||||||
|
|
||||||
// Update the length if needed
|
// Update the length if needed
|
||||||
get_header(str).Length = write_pos - str.Data;
|
get_header(str)->Length = write_pos - str.Data;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void trim(String& str, char const* cut_set)
|
void trim(String str, char const* cut_set)
|
||||||
{
|
{
|
||||||
ssize len = 0;
|
ssize len = 0;
|
||||||
|
|
||||||
@ -519,16 +542,16 @@ void trim(String& str, char const* cut_set)
|
|||||||
|
|
||||||
str.Data[len] = '\0';
|
str.Data[len] = '\0';
|
||||||
|
|
||||||
get_header(str).Length = len;
|
get_header(str)->Length = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void trim_space(String& str) {
|
void trim_space(String str) {
|
||||||
trim(str, " \t\r\n\v\f");
|
trim(str, " \t\r\n\v\f");
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
String visualize_whitespace(String const& str)
|
String visualize_whitespace(String const str)
|
||||||
{
|
{
|
||||||
StringHeader* header = (StringHeader*)(scast(char const*, str) - sizeof(StringHeader));
|
StringHeader* header = (StringHeader*)(scast(char const*, str) - sizeof(StringHeader));
|
||||||
String result = string_make_reserve(header->Allocator, length(str) * 2); // Assume worst case for space requirements.
|
String result = string_make_reserve(header->Allocator, length(str) * 2); // Assume worst case for space requirements.
|
||||||
@ -536,25 +559,25 @@ String visualize_whitespace(String const& str)
|
|||||||
for (auto c : str) switch (c)
|
for (auto c : str) switch (c)
|
||||||
{
|
{
|
||||||
case ' ':
|
case ' ':
|
||||||
append(result, txt("·"));
|
append(& result, txt("·"));
|
||||||
break;
|
break;
|
||||||
case '\t':
|
case '\t':
|
||||||
append(result, txt("→"));
|
append(& result, txt("→"));
|
||||||
break;
|
break;
|
||||||
case '\n':
|
case '\n':
|
||||||
append(result, txt("↵"));
|
append(& result, txt("↵"));
|
||||||
break;
|
break;
|
||||||
case '\r':
|
case '\r':
|
||||||
append(result, txt("⏎"));
|
append(& result, txt("⏎"));
|
||||||
break;
|
break;
|
||||||
case '\v':
|
case '\v':
|
||||||
append(result, txt("⇕"));
|
append(& result, txt("⇕"));
|
||||||
break;
|
break;
|
||||||
case '\f':
|
case '\f':
|
||||||
append(result, txt("⌂"));
|
append(& result, txt("⌂"));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
append(result, c);
|
append(& result, c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ CodeBody gen_ecode( char const* path )
|
|||||||
char scratch_mem[kilobytes(1)];
|
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( allocator_info(scratch), zero_terminate, path );
|
file_read_contents( allocator_info( & scratch), zero_terminate, path );
|
||||||
|
|
||||||
CSV_Object csv_nodes;
|
CSV_Object csv_nodes;
|
||||||
csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false );
|
csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false );
|
||||||
@ -23,11 +23,12 @@ CodeBody gen_ecode( char const* path )
|
|||||||
String enum_entries = string_make_reserve( GlobalAllocator, kilobytes(1) );
|
String enum_entries = string_make_reserve( GlobalAllocator, kilobytes(1) );
|
||||||
String to_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) );
|
String to_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) );
|
||||||
|
|
||||||
for ( ADT_Node node : enum_strs )
|
for ( ADT_Node& node : enum_strs )
|
||||||
{
|
{
|
||||||
char const* code = node.string;
|
char const* code = node.string;
|
||||||
append_fmt( enum_entries, "%s,\n", code );
|
|
||||||
append_fmt( to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", code, code );
|
append_fmt( & enum_entries, "%s,\n", code );
|
||||||
|
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", (StrC)enum_entries, "enum Type : u32 { <entries> NumTypes };"));
|
||||||
@ -59,7 +60,7 @@ CodeBody gen_eoperator( char const* path )
|
|||||||
char scratch_mem[kilobytes(4)];
|
char scratch_mem[kilobytes(4)];
|
||||||
Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) );
|
Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) );
|
||||||
|
|
||||||
file_read_contents( allocator_info(scratch), zero_terminate, path );
|
file_read_contents( allocator_info(& scratch), zero_terminate, path );
|
||||||
|
|
||||||
CSV_Object csv_nodes;
|
CSV_Object csv_nodes;
|
||||||
csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false );
|
csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false );
|
||||||
@ -75,8 +76,8 @@ CodeBody gen_eoperator( char const* path )
|
|||||||
char const* enum_str = enum_strs[idx].string;
|
char const* enum_str = enum_strs[idx].string;
|
||||||
char const* entry_to_str = str_strs [idx].string;
|
char const* entry_to_str = str_strs [idx].string;
|
||||||
|
|
||||||
append_fmt( enum_entries, "%s,\n", enum_str );
|
append_fmt( & enum_entries, "%s,\n", enum_str );
|
||||||
append_fmt( to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
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(
|
CodeEnum enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, stringize(
|
||||||
@ -115,7 +116,7 @@ CodeBody gen_especifier( char const* path )
|
|||||||
char scratch_mem[kilobytes(4)];
|
char scratch_mem[kilobytes(4)];
|
||||||
Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) );
|
Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) );
|
||||||
|
|
||||||
file_read_contents( allocator_info(scratch), zero_terminate, path );
|
file_read_contents( allocator_info(& scratch), zero_terminate, path );
|
||||||
|
|
||||||
CSV_Object csv_nodes;
|
CSV_Object csv_nodes;
|
||||||
csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false );
|
csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false );
|
||||||
@ -131,8 +132,8 @@ CodeBody gen_especifier( char const* path )
|
|||||||
char const* enum_str = enum_strs[idx].string;
|
char const* enum_str = enum_strs[idx].string;
|
||||||
char const* entry_to_str = str_strs [idx].string;
|
char const* entry_to_str = str_strs [idx].string;
|
||||||
|
|
||||||
append_fmt( enum_entries, "%s,\n", enum_str );
|
append_fmt( & enum_entries, "%s,\n", enum_str );
|
||||||
append_fmt( to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
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(
|
CodeEnum enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, stringize(
|
||||||
@ -220,7 +221,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
|
|||||||
char scratch_mem[kilobytes(16)];
|
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) );
|
||||||
|
|
||||||
AllocatorInfo scratch_info = allocator_info(scratch);
|
AllocatorInfo scratch_info = allocator_info(& scratch);
|
||||||
|
|
||||||
FileContents enum_content = file_read_contents( scratch_info, zero_terminate, etok_path );
|
FileContents enum_content = file_read_contents( scratch_info, zero_terminate, etok_path );
|
||||||
|
|
||||||
@ -248,8 +249,8 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
|
|||||||
char const* enum_str = enum_strs[idx].string;
|
char const* enum_str = enum_strs[idx].string;
|
||||||
char const* entry_to_str = enum_str_strs [idx].string;
|
char const* entry_to_str = enum_str_strs [idx].string;
|
||||||
|
|
||||||
append_fmt( enum_entries, "%s,\n", enum_str );
|
append_fmt( & enum_entries, "%s,\n", enum_str );
|
||||||
append_fmt( to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( usize idx = 0; idx < num(attribute_strs); idx++ )
|
for ( usize idx = 0; idx < num(attribute_strs); idx++ )
|
||||||
@ -257,14 +258,14 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
|
|||||||
char const* attribute_str = attribute_strs[idx].string;
|
char const* attribute_str = attribute_strs[idx].string;
|
||||||
char const* entry_to_str = attribute_str_strs [idx].string;
|
char const* entry_to_str = attribute_str_strs [idx].string;
|
||||||
|
|
||||||
append_fmt( attribute_entries, "Attribute_%s,\n", attribute_str );
|
append_fmt( & attribute_entries, "Attribute_%s,\n", attribute_str );
|
||||||
append_fmt( to_str_attributes, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
append_fmt( & to_str_attributes, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
||||||
append_fmt( attribute_define_entries, "Entry( Attribute_%s, \"%s\" )", attribute_str, entry_to_str );
|
append_fmt( & attribute_define_entries, "Entry( Attribute_%s, \"%s\" )", attribute_str, entry_to_str );
|
||||||
|
|
||||||
if ( idx < num(attribute_strs) - 1 )
|
if ( idx < num(attribute_strs) - 1 )
|
||||||
append( attribute_define_entries, " \\\n");
|
append( & attribute_define_entries, " \\\n");
|
||||||
else
|
else
|
||||||
append( attribute_define_entries, "\n");
|
append( & attribute_define_entries, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma push_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
|
#pragma push_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
|
||||||
@ -342,68 +343,17 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
|
|||||||
|
|
||||||
CodeBody gen_ast_inlines()
|
CodeBody gen_ast_inlines()
|
||||||
{
|
{
|
||||||
|
#pragma push_macro("GEN_NS")
|
||||||
#pragma push_macro("rcast")
|
#pragma push_macro("rcast")
|
||||||
#pragma push_macro("log_failure")
|
#pragma push_macro("log_failure")
|
||||||
|
#pragma push_macro("CodeInvalid")
|
||||||
|
#undef GEN_NS
|
||||||
#undef rcast
|
#undef rcast
|
||||||
#undef log_failure
|
#undef log_failure
|
||||||
|
#undef CodeInvalid
|
||||||
char const* code_impl_tmpl = stringize(
|
char const* code_impl_tmpl = stringize(
|
||||||
\n
|
\n
|
||||||
inline
|
inline
|
||||||
char const* <typename>::debug_str()
|
|
||||||
{
|
|
||||||
if ( ast == nullptr )
|
|
||||||
return "Code::debug_str: AST is null!";
|
|
||||||
|
|
||||||
return rcast(AST*, ast)->debug_str();
|
|
||||||
}
|
|
||||||
inline
|
|
||||||
Code <typename>::duplicate()
|
|
||||||
{
|
|
||||||
if ( ast == nullptr )
|
|
||||||
{
|
|
||||||
log_failure("Code::duplicate: Cannot duplicate code, AST is null!");
|
|
||||||
return Code::Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
return { rcast(AST*, ast)->duplicate() };
|
|
||||||
}
|
|
||||||
inline
|
|
||||||
bool <typename>::is_body()
|
|
||||||
{
|
|
||||||
if ( ast == nullptr )
|
|
||||||
{
|
|
||||||
return rcast(AST*, ast)->is_body();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
inline
|
|
||||||
bool <typename>::is_equal( Code other )
|
|
||||||
{
|
|
||||||
if ( ast == nullptr || other.ast == nullptr )
|
|
||||||
{
|
|
||||||
// Just check if they're both null.
|
|
||||||
// log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
|
|
||||||
return ast == nullptr && other.ast == nullptr;
|
|
||||||
}
|
|
||||||
return rcast(AST*, ast)->is_equal( other.ast );
|
|
||||||
}
|
|
||||||
inline
|
|
||||||
bool <typename>::is_valid()
|
|
||||||
{
|
|
||||||
return (AST*) ast != nullptr && rcast( AST*, ast)->Type != CodeT::Invalid;
|
|
||||||
}
|
|
||||||
inline
|
|
||||||
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 )
|
<typename>& <typename>::operator =( Code other )
|
||||||
{
|
{
|
||||||
if ( other.ast && other->Parent )
|
if ( other.ast && other->Parent )
|
||||||
@ -416,16 +366,6 @@ CodeBody gen_ast_inlines()
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline
|
inline
|
||||||
bool <typename>::operator ==( Code other )
|
|
||||||
{
|
|
||||||
return (AST*) ast == other.ast;
|
|
||||||
}
|
|
||||||
inline
|
|
||||||
bool <typename>::operator !=( Code other )
|
|
||||||
{
|
|
||||||
return (AST*) ast != other.ast;
|
|
||||||
}
|
|
||||||
inline
|
|
||||||
<typename>::operator bool()
|
<typename>::operator bool()
|
||||||
{
|
{
|
||||||
return ast != nullptr;
|
return ast != nullptr;
|
||||||
@ -455,6 +395,8 @@ CodeBody gen_ast_inlines()
|
|||||||
}
|
}
|
||||||
\n
|
\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 = 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 ));
|
CodeBody impl_code_body = parse_global_body( token_fmt( "typename", StrC name(CodeBody), code_impl_tmpl ));
|
||||||
|
@ -226,6 +226,30 @@ if ( $c_library )
|
|||||||
write-host "`nc_library generator completed in $($time_taken.TotalMilliseconds) ms"
|
write-host "`nc_library generator completed in $($time_taken.TotalMilliseconds) ms"
|
||||||
}
|
}
|
||||||
Pop-Location
|
Pop-Location
|
||||||
|
|
||||||
|
$unit = join-path $path_c_library "gen.c"
|
||||||
|
$executable = join-path $path_build "gen_c_library_test.exe"
|
||||||
|
|
||||||
|
if ($vendor -eq "clang") {
|
||||||
|
$compiler_args += "-x"
|
||||||
|
$compiler_args += "c"
|
||||||
|
} elseif ($vendor -eq "msvc") {
|
||||||
|
$compiler_args += "/TC"
|
||||||
|
}
|
||||||
|
|
||||||
|
build-simple $path_build $includes $compiler_args $linker_args $unit $executable
|
||||||
|
|
||||||
|
Push-Location $path_c_library
|
||||||
|
if ( Test-Path( $executable ) ) {
|
||||||
|
write-host "`nRunning c_library test"
|
||||||
|
$time_taken = Measure-Command { & $executable
|
||||||
|
| ForEach-Object {
|
||||||
|
write-host `t $_ -ForegroundColor Green
|
||||||
|
}
|
||||||
|
}
|
||||||
|
write-host "`nc_library generator completed in $($time_taken.TotalMilliseconds) ms"
|
||||||
|
}
|
||||||
|
Pop-Location
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $unreal )
|
if ( $unreal )
|
||||||
|
Loading…
Reference in New Issue
Block a user