Compare commits

...

3 Commits

35 changed files with 1428 additions and 1136 deletions

18
.vscode/settings.json vendored
View File

@ -40,7 +40,23 @@
"*.m": "cpp", "*.m": "cpp",
"atomic": "cpp", "atomic": "cpp",
"gen.h": "c", "gen.h": "c",
"string_ops.hpp": "c" "string_ops.hpp": "c",
"assert.h": "c",
"intrin.h": "c",
"bit": "cpp",
"cmath": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"iosfwd": "cpp",
"new": "cpp",
"typeinfo": "cpp",
"unordered_map": "cpp",
"xstddef": "cpp"
}, },
"C_Cpp.intelliSenseEngineFallback": "disabled", "C_Cpp.intelliSenseEngineFallback": "disabled",
"mesonbuild.configureOnOpen": true, "mesonbuild.configureOnOpen": true,

View File

@ -53,7 +53,7 @@ constexpr StrC implementation_guard_end = txt(R"(
void format_file( char const* path ) void format_file( char const* path )
{ {
String resolved_path = String::make(GlobalAllocator, to_str(path)); String resolved_path = String::make(GlobalAllocator, to_strc_from_c_str(path));
String style_arg = String::make(GlobalAllocator, txt("-style=file:")); String style_arg = String::make(GlobalAllocator, txt("-style=file:"));
style_arg.append("../scripts/.clang-format "); style_arg.append("../scripts/.clang-format ");
@ -100,6 +100,9 @@ int gen_main()
#define project_dir "../project/" #define project_dir "../project/"
gen::init(); gen::init();
PreprocessorDefines.append(txt("GEN_API_C_BEGIN"));
PreprocessorDefines.append(txt("GEN_API_C_END"));
Code push_ignores = scan_file( project_dir "helpers/push_ignores.inline.hpp" ); Code push_ignores = scan_file( project_dir "helpers/push_ignores.inline.hpp" );
Code pop_ignores = scan_file( project_dir "helpers/pop_ignores.inline.hpp" ); Code pop_ignores = scan_file( project_dir "helpers/pop_ignores.inline.hpp" );
Code c_library_header_start = scan_file( "components/header_start.hpp" ); Code c_library_header_start = scan_file( "components/header_start.hpp" );
@ -127,15 +130,32 @@ int gen_main()
header.print( basic_types ); header.print( basic_types );
header.print( debug ); header.print( debug );
// Array(StrC) to_rename = array_init_reserve(StrC, GlobalAllocator, 128);
// to_rename.append(txt("align_forward"));
// to_rename.append(txt("pointer_add"));
// to_rename.append(txt("allocator_info"));
// to_rename.append(txt("size_remaining"));
// to_rename.append(txt("free"));
// to_rename.append(txt("clear"));
// to_rename.append(txt("init_sub"));
// to_rename.append(txt("check"));
// NeedsSelectors needs_selectors;
// needs_selectors.table = hashtable_init_reserve(Array(CodeFn), GlobalAllocator, 1024);
// for ( StrC id : to_rename ) {
// needs_selectors.set(id, array_init_reserve(CodeFn, GlobalAllocator, 128));
// }
CodeBody parsed_memory = parse_file( project_dir "dependencies/memory.hpp" ); CodeBody parsed_memory = parse_file( project_dir "dependencies/memory.hpp" );
CodeBody memory = def_body(CT_Global_Body); CodeBody memory = def_body(CT_Global_Body);
for ( Code entry = parsed_memory.begin(); entry != parsed_memory.end(); ++ entry ) for ( Code entry = parsed_memory.begin(); entry != parsed_memory.end(); ++ entry )
{ {
switch (entry->Type) switch (entry->Type)
{ {
case CT_Using: case CT_Using:
{ {
log_fmt("REPLACE THIS MANUALLY: %S\n", entry->Name); log_fmt("REPLACE THIS MANUALLY: %SC\n", entry->Name);
CodeUsing using_ver = cast(CodeUsing, entry); CodeUsing using_ver = cast(CodeUsing, entry);
CodeTypedef typedef_ver = def_typedef(using_ver->Name, using_ver->UnderlyingType); CodeTypedef typedef_ver = def_typedef(using_ver->Name, using_ver->UnderlyingType);
@ -145,11 +165,10 @@ int gen_main()
case CT_Function_Fwd: case CT_Function_Fwd:
{ {
CodeFn fn = cast(CodeFn, entry); CodeFn fn = cast(CodeFn, entry);
if ( fn->Name.is_equal(txt("free")) ) // for ( StrC id : to_rename ) if (fn->Name.is_equal(id)) {
{ // rename_function_to_unique_symbol(fn);
fn->Name = get_cached_string(txt("gen_free_ptr")); // }
} memory.append(fn);
memory.append(entry);
} }
break; break;
case CT_Function: case CT_Function:
@ -160,11 +179,11 @@ int gen_main()
log_fmt("Found constexpr: %S\n", entry.to_string()); log_fmt("Found constexpr: %S\n", entry.to_string());
fn->Specs.append(Spec_Inline); fn->Specs.append(Spec_Inline);
} }
if ( fn->Name.is_equal(txt("free")) ) // for ( StrC id : to_rename ) if (fn->Name.is_equal(id)) {
{ // Array(CodeFn) list = * needs_selectors.get(id);
fn->Name = get_cached_string(txt("gen_free_ptr")); // list.append(rename_function_to_unique_symbol(fn));
} // }
memory.append(entry); memory.append(fn);
} }
break; break;
case CT_Template: case CT_Template:
@ -213,6 +232,9 @@ int gen_main()
b32 found = ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_MEMBER_FEATURES"), entry, parsed_memory ); b32 found = ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_MEMBER_FEATURES"), entry, parsed_memory );
if (found) break; if (found) break;
found = ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_REFERENCES"), entry, parsed_memory );
if (found) break;
memory.append(entry); memory.append(entry);
} }
break; break;
@ -226,6 +248,12 @@ int gen_main()
break; break;
case CT_Preprocess_Pragma: case CT_Preprocess_Pragma:
{ {
CodePragma pragma = cast(CodePragma, entry);
// if (pragma->Content.starts_with(txt("region Memory"))) {
// memory.append(generic_test);
// break;
// }
b32 found = swap_pragma_region_implementation( txt("FixedArena"), gen_fixed_arenas, entry, memory); b32 found = swap_pragma_region_implementation( txt("FixedArena"), gen_fixed_arenas, entry, memory);
if (found) break; if (found) break;
@ -238,10 +266,15 @@ int gen_main()
break; break;
} }
} }
// CodeBody selectors = generate_generic_selectors(needs_selectors);
// memory.append_at(selectors, 0)
// memory.append(fmt_newline);
header.print( dump_to_scratch_and_retireve(memory) ); header.print( dump_to_scratch_and_retireve(memory) );
Code string_ops = scan_file( project_dir "dependencies/string_ops.hpp" ); Code string_ops = scan_file( project_dir "dependencies/string_ops.hpp" );
header.print( string_ops ); // header.print( string_ops );
CodeBody printing_parsed = parse_file( project_dir "dependencies/printing.hpp" ); CodeBody printing_parsed = parse_file( project_dir "dependencies/printing.hpp" );
CodeBody printing = def_body(CT_Global_Body); CodeBody printing = def_body(CT_Global_Body);
@ -259,7 +292,7 @@ int gen_main()
break; break;
case CT_Variable: case CT_Variable:
{ {
if (contains(entry->Name, txt("Msg_Invalid_Value"))) if ( strc_contains(entry->Name, txt("Msg_Invalid_Value")))
{ {
CodeDefine define = def_define(entry->Name, entry->Value->Content); CodeDefine define = def_define(entry->Name, entry->Value->Content);
printing.append(define); printing.append(define);
@ -273,7 +306,7 @@ int gen_main()
break; break;
} }
} }
header.print(dump_to_scratch_and_retireve(printing)); // header.print(dump_to_scratch_and_retireve(printing));
CodeBody containers = def_body(CT_Global_Body); CodeBody containers = def_body(CT_Global_Body);
{ {
@ -285,10 +318,10 @@ int gen_main()
containers.append( def_pragma(code(endregion Containers))); containers.append( def_pragma(code(endregion Containers)));
} }
header.print(fmt_newline); header.print(fmt_newline);
header.print(dump_to_scratch_and_retireve(containers)); // header.print(dump_to_scratch_and_retireve(containers));
Code hashing = scan_file( project_dir "dependencies/hashing.hpp" ); Code hashing = scan_file( project_dir "dependencies/hashing.hpp" );
header.print( hashing ); // header.print( hashing );
CodeBody parsed_strings = parse_file( project_dir "dependencies/strings.hpp" ); CodeBody parsed_strings = parse_file( project_dir "dependencies/strings.hpp" );
CodeBody strings = def_body(CT_Global_Body); CodeBody strings = def_body(CT_Global_Body);
@ -298,7 +331,22 @@ int gen_main()
{ {
case CT_Preprocess_If: case CT_Preprocess_If:
{ {
ignore_preprocess_cond_block(txt("! GEN_COMPILER_C"), entry, parsed_strings); CodePreprocessCond cond = cast(CodePreprocessCond, entry);
if (cond->Content.starts_with(txt("GEN_COMPILER_C || ! GEN_SUPPORT_CPP_MEMBER_FEATURES")))
{
++ entry;
strings.append(entry); // typedef
strings.append(fmt_newline);
for (; entry != end(parsed_strings) && entry->Type != CT_Preprocess_EndIf; ++ entry) {}
++ entry;
break;
}
bool found = ignore_preprocess_cond_block(txt("! GEN_COMPILER_C"), entry, parsed_strings);
if (found) break;
found = ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_REFERENCES"), entry, parsed_strings);
} }
break; break;
@ -350,7 +398,7 @@ int gen_main()
break; break;
} }
} }
header.print(dump_to_scratch_and_retireve(strings)); // header.print(dump_to_scratch_and_retireve(strings));
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" );

View File

@ -283,11 +283,11 @@ CodeBody gen_array( StrC type, StrC array_name )
#pragma pop_macro( "GEN_ASSERT" ) #pragma pop_macro( "GEN_ASSERT" )
return def_global_body( args( return def_global_body( args(
def_pragma( to_str( str_fmt_buf( "region %S", array_type ))), def_pragma( string_to_strc( string_fmt_buf( GlobalAllocator, "region %S", array_type ))),
fmt_newline, fmt_newline,
result, result,
fmt_newline, fmt_newline,
def_pragma( to_str( str_fmt_buf( "endregion %S", array_type ))), def_pragma( string_to_strc(string_fmt_buf( GlobalAllocator, "endregion %S", array_type ))),
fmt_newline fmt_newline
)); ));
}; };

View File

@ -88,7 +88,7 @@ CodeBody gen_hashtable( StrC type, StrC hashtable_name )
void <fn>_remove ( <tbl_type> self, u64 key ); void <fn>_remove ( <tbl_type> self, u64 key );
void <fn>_remove_entry( <tbl_type> self, ssize idx ); void <fn>_remove_entry( <tbl_type> self, ssize idx );
void <fn>_set ( <tbl_type>* self, u64 key, <type> value ); void <fn>_set ( <tbl_type>* self, u64 key, <type> value );
ssize <fn>_slot ( <tbl_type> self, u64 key ); ssize <fn>_slot ( <tbl_type> self, u64 key );
ssize <fn>__add_entry( <tbl_type> self, u64 key ); ssize <fn>__add_entry( <tbl_type> self, u64 key );
HT_FindResult <fn>__find ( <tbl_type> self, u64 key ); HT_FindResult <fn>__find ( <tbl_type> self, u64 key );
@ -341,14 +341,14 @@ CodeBody gen_hashtable( StrC type, StrC hashtable_name )
, type.Len, type.Ptr ); , type.Len, type.Ptr );
return def_global_body(args( return def_global_body(args(
def_pragma( to_str( str_fmt_buf( "region %S", tbl_type ))), def_pragma( string_to_strc( string_fmt_buf( GlobalAllocator, "region %S", tbl_type ))),
fmt_newline, fmt_newline,
hashtable_types, hashtable_types,
fmt_newline, fmt_newline,
entry_array, entry_array,
hashtable_def, hashtable_def,
fmt_newline, fmt_newline,
def_pragma( to_str( str_fmt_buf( "endregion %S", tbl_type ))), def_pragma( string_to_strc( string_fmt_buf( GlobalAllocator, "endregion %S", tbl_type ))),
fmt_newline fmt_newline
)); ));
} }

View File

@ -5,22 +5,67 @@
using SwapContentProc = CodeBody(void); using SwapContentProc = CodeBody(void);
struct NeedsSelectors {
HashTable(Array(CodeFn)) table;
void set(StrC sig, Array(CodeFn) list) {
u32 key = crc32(sig.Ptr, sig.Len);
table.set(key, list);
}
Array(CodeFn)* get(StrC sig) {
u32 key = crc32(sig.Ptr, sig.Len);
return table.get(key);
}
};
CodeBody generate_generic_selectors(Array(Array(CodeFn)) listing)
{
constexpr char const* tmpl_selector =
R"( #define <base_name>(<params>) \
_Generic((
))
);
)";
CodeBody result = def_body(CT_Global_Body);
for (Array(CodeFn) functions : listing)
{
}
return result;
}
b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& body ) b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& body )
{ {
b32 found = false; b32 found = false;
CodePreprocessCond cond = cast(CodePreprocessCond, entry_iter); CodePreprocessCond cond = cast(CodePreprocessCond, entry_iter);
if ( cond->Content.contains(cond_sig) ) if ( cond->Content.contains(cond_sig) )
{ {
log_fmt("Preprocess cond found: %S\n", cond->Content); log_fmt("Preprocess cond found: %SC\n", cond->Content);
found = true; found = true;
s32 depth = 1; s32 depth = 1;
++ entry_iter; for(b32 continue_for = true; continue_for && entry_iter != body.end(); ) switch ++ entry_iter;
for(b32 continue_for = true; continue_for && entry_iter != body.end(); ) switch
(entry_iter->Type) { (entry_iter->Type) {
case CT_Preprocess_If: case CT_Preprocess_If:
case CT_Preprocess_IfDef: case CT_Preprocess_IfDef:
case CT_Preprocess_IfNotDef: case CT_Preprocess_IfNotDef:
depth ++; ++ depth;
++ entry_iter;
break;
case CT_Preprocess_Else:
++ entry_iter;
for(; continue_for && entry_iter != body.end(); ++ entry_iter)
{
if (entry_iter->Type == CT_Preprocess_EndIf)
{
continue_for = false;
break;
}
body.append(entry_iter);
}
break; break;
case CT_Preprocess_EndIf: case CT_Preprocess_EndIf:
@ -30,6 +75,7 @@ b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& bod
continue_for = false; continue_for = false;
break; break;
} }
++ entry_iter;
} }
break; break;
default: default:
@ -41,6 +87,72 @@ b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& bod
return found; return found;
} }
CodeFn rename_function_to_unique_symbol(CodeFn fn, StrC optional_prefix = txt(""))
{
// Get basic components for the name
StrC old_name = fn->Name;
String new_name;
// Add prefix if provided
if (optional_prefix.Len)
new_name = string_fmt_buf(GlobalAllocator, "%SC_%SC_", optional_prefix, old_name);
else
new_name = string_fmt_buf(GlobalAllocator, "%SC_", old_name);
// Add return type to the signature
if (fn->ReturnType)
new_name.append_fmt("_%SC", fn->ReturnType->Name);
// Add parameter types to create a unique signature
bool first_param = true;
for (CodeParam param = fn->Params; param.ast; param = param->Next)
{
if (param->ValueType)
{
// Add separator for readability
if (first_param)
{
new_name.append("_P_");
first_param = false;
}
else
new_name.append("_");
// Add parameter type, handle any specifiers
if (param->ValueType->Specs && param->ValueType->Specs->NumEntries > 0)
{
// Add specifiers (const, volatile, etc)
for (Specifier spec : param->ValueType->Specs)
{
if (spec == Spec_Ptr) {
new_name.append("ptr_");
continue;
}
new_name.append_fmt("%SC_", to_str(spec));
}
}
new_name.append_fmt("%SC", param->ValueType->Name);
}
}
// Handle function specifiers if present
if (fn->Specs && fn->Specs->NumEntries > 0)
{
new_name.append("_S_");
for (Specifier* spec = begin(fn->Specs);
spec != end(fn->Specs);
++spec)
{
new_name.append_fmt("%SC_", to_str(*spec));
}
}
fn->Name = new_name;
return fn;
}
bool swap_pragma_region_implementation( StrC region_name, SwapContentProc* swap_content, Code& entry_iter, CodeBody& body ) bool swap_pragma_region_implementation( StrC region_name, SwapContentProc* swap_content, Code& entry_iter, CodeBody& body )
{ {
bool found = false; bool found = false;
@ -54,7 +166,8 @@ bool swap_pragma_region_implementation( StrC region_name, SwapContentProc* swap_
// body.append(possible_region); // body.append(possible_region);
body.append(swap_content()); body.append(swap_content());
++ entry_iter; for(b32 continue_for = true; continue_for; ++entry_iter) switch ++ entry_iter;
for(b32 continue_for = true; continue_for; ++entry_iter) switch
(entry_iter->Type) { (entry_iter->Type) {
case CT_Preprocess_Pragma: case CT_Preprocess_Pragma:
{ {

View File

@ -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" ); string_append_strc( & Buffer, txt("\n") );
} }
void Builder::print( Code code ) void Builder::print( Code code )
@ -29,7 +29,7 @@ void Builder::print( Code code )
String str = to_string(code); String str = to_string(code);
// const ssize len = str.length(); // const ssize len = str.length();
// log_fmt( "%s - print: %.*s\n", File.filename, len > 80 ? 80 : len, str.Data ); // log_fmt( "%s - print: %.*s\n", File.filename, len > 80 ? 80 : len, str.Data );
append( & Buffer, str ); string_append_string( & Buffer, str );
} }
void Builder::print_fmt( char const* fmt, ... ) void Builder::print_fmt( char const* fmt, ... )
@ -43,17 +43,17 @@ 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( (String*) & Buffer, (char const*)buf, res ); string_append_c_str_len( (String*) & Buffer, (char const*)buf, res );
} }
void Builder::write() void Builder::write()
{ {
b32 result = file_write( & File, Buffer, length(Buffer) ); b32 result = file_write( & File, Buffer, string_length(Buffer) );
if ( result == false ) if ( result == false )
log_failure("gen::File::write - Failed to write to file: %s\n", file_name( & File ) ); log_failure("gen::File::write - Failed to write to file: %s\n", file_name( & File ) );
log_fmt( "Generated: %s\n", File.filename ); log_fmt( "Generated: %s\n", File.filename );
file_close( & File ); file_close( & File );
free(& Buffer); string_free(& Buffer);
} }

View File

@ -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; string_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.
@ -52,7 +52,7 @@ Code scan_file( char const* path )
if ( ! found_directive ) if ( ! found_directive )
{ {
if ( left && str_compare( scanner, directive_start.Ptr, directive_start.Len ) == matched ) if ( left && str_compare_len( scanner, directive_start.Ptr, directive_start.Len ) == matched )
{ {
scanner += directive_start.Len; scanner += directive_start.Len;
left -= directive_start.Len; left -= directive_start.Len;
@ -60,7 +60,7 @@ Code scan_file( char const* path )
while ( left && char_is_space( current ) ) while ( left && char_is_space( current ) )
move_fwd(); move_fwd();
if ( left && str_compare( scanner, def_intellisense.Ptr, def_intellisense.Len ) == matched ) if ( left && str_compare_len( scanner, def_intellisense.Ptr, def_intellisense.Len ) == matched )
{ {
scanner += def_intellisense.Len; scanner += def_intellisense.Len;
left -= def_intellisense.Len; left -= def_intellisense.Len;
@ -80,7 +80,7 @@ Code scan_file( char const* path )
continue; continue;
} }
if ( left && str_compare( scanner, directive_end.Ptr, directive_end.Len ) == matched ) if ( left && str_compare_len( scanner, directive_end.Ptr, directive_end.Len ) == matched )
{ {
scanner += directive_end.Len; scanner += directive_end.Len;
left -= directive_end.Len; left -= directive_end.Len;
@ -97,12 +97,12 @@ Code scan_file( char const* path )
if ( (scanner + 2) >= ( (char const*) str + fsize ) ) if ( (scanner + 2) >= ( (char const*) str + fsize ) )
{ {
mem_move( str, scanner, left ); mem_move( str, scanner, left );
get_header(str)->Length = left; string_get_header(str)->Length = left;
break; break;
} }
mem_move( str, scanner, left ); mem_move( str, scanner, left );
get_header(str)->Length = left; string_get_header(str)->Length = left;
break; break;
} }
@ -116,7 +116,7 @@ Code scan_file( char const* path )
} }
file_close( & file ); file_close( & file );
return untyped_str( to_strc(str) ); return untyped_str( string_to_strc(str) );
} }
#if 0 #if 0

View File

@ -26,20 +26,20 @@ constexpr char const* generation_notice =
void format_file( char const* path ) void format_file( char const* path )
{ {
String resolved_path = string_make(GlobalAllocator, to_str(path)); String resolved_path = string_make_strc(GlobalAllocator, to_strc_from_c_str(path));
String style_arg = string_make(GlobalAllocator, txt("-style=file:")); String style_arg = string_make_strc(GlobalAllocator, txt("-style=file:"));
append( & style_arg, "../scripts/.clang-format "); string_append_strc( & style_arg, txt("../scripts/.clang-format "));
// Need to execute clang format on the generated file to get it to match the original. // Need to execute clang format on the generated file to get it to match the original.
#define clang_format "clang-format " #define clang_format txt("clang-format ")
#define cf_format_inplace "-i " #define cf_format_inplace txt("-i ")
#define cf_verbose "-verbose " #define cf_verbose txt("-verbose ")
String command = string_make( GlobalAllocator, clang_format ); String command = string_make_strc( GlobalAllocator, clang_format );
append( & command, cf_format_inplace ); string_append_strc( & command, cf_format_inplace );
append( & command, cf_verbose ); string_append_strc( & command, cf_verbose );
append( & command, style_arg ); string_append_string( & command, style_arg );
append( & command, resolved_path ); string_append_string( & 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");
@ -145,7 +145,7 @@ int gen_main()
def_include(txt("components/types.hpp")), def_include(txt("components/types.hpp")),
preprocess_endif, preprocess_endif,
fmt_newline, fmt_newline,
untyped_str( to_str(generation_notice) ) untyped_str( to_strc_from_c_str(generation_notice) )
)); ));
// gen.hpp // gen.hpp

View File

@ -14,13 +14,13 @@ char const* debug_str(Code self)
String* result = & result_stack; String* result = & result_stack;
if ( self->Parent ) if ( self->Parent )
append_fmt( result, "\n\tParent : %S %S", type_str(self->Parent), self->Name ? self->Name : "" ); string_append_fmt( result, "\n\tParent : %S %S", type_str(self->Parent), self->Name ? self->Name : "" );
else else
append_fmt( result, "\n\tParent : %S", "Null" ); string_append_fmt( result, "\n\tParent : %S", "Null" );
append_fmt( result, "\n\tName : %S", self->Name ? self->Name : "Null" ); string_append_fmt( result, "\n\tName : %S", self->Name ? self->Name : "Null" );
append_fmt( result, "\n\tType : %S", type_str(self) ); string_append_fmt( result, "\n\tType : %S", type_str(self) );
append_fmt( result, "\n\tModule Flags : %S", to_str( self->ModuleFlags ) ); string_append_fmt( result, "\n\tModule Flags : %S", to_str( self->ModuleFlags ) );
switch ( self->Type ) switch ( self->Type )
{ {
@ -30,9 +30,9 @@ char const* debug_str(Code self)
case CT_Access_Protected: case CT_Access_Protected:
case CT_Access_Public: case CT_Access_Public:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
break; break;
case CT_Untyped: case CT_Untyped:
@ -48,74 +48,74 @@ char const* debug_str(Code self)
case CT_Preprocess_IfDef: case CT_Preprocess_IfDef:
case CT_Preprocess_IfNotDef: case CT_Preprocess_IfNotDef:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tContent: %S", self->Content ); string_append_fmt( result, "\n\tContent: %S", self->Content );
break; break;
case CT_Class: case CT_Class:
case CT_Struct: case CT_Struct:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" ); string_append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tParentAccess: %s", self->ParentType ? to_str( self->ParentAccess ) : "No Parent" ); string_append_fmt( result, "\n\tParentAccess: %s", self->ParentType ? to_str( self->ParentAccess ) : "No Parent" );
append_fmt( result, "\n\tParentType : %s", self->ParentType ? type_str(self->ParentType) : "Null" ); string_append_fmt( result, "\n\tParentType : %s", self->ParentType ? type_str(self->ParentType) : "Null" );
append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" ); string_append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" );
break; break;
case CT_Class_Fwd: case CT_Class_Fwd:
case CT_Struct_Fwd: case CT_Struct_Fwd:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" ); string_append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tParentAccess: %s", self->ParentType ? to_str( self->ParentAccess ) : "No Parent" ); string_append_fmt( result, "\n\tParentAccess: %s", self->ParentType ? to_str( self->ParentAccess ) : "No Parent" );
append_fmt( result, "\n\tParentType : %s", self->ParentType ? type_str(self->ParentType) : "Null" ); string_append_fmt( result, "\n\tParentType : %s", self->ParentType ? type_str(self->ParentType) : "Null" );
break; break;
case CT_Constructor: case CT_Constructor:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tInitializerList: %S", self->InitializerList ? to_string(self->InitializerList) : "Null" ); string_append_fmt( result, "\n\tInitializerList: %S", self->InitializerList ? to_string(self->InitializerList) : "Null" );
append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" ); string_append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" );
append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" ); string_append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" );
break; break;
case CT_Constructor_Fwd: case CT_Constructor_Fwd:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tInitializerList: %S", self->InitializerList ? to_string(self->InitializerList) : "Null" ); string_append_fmt( result, "\n\tInitializerList: %S", self->InitializerList ? to_string(self->InitializerList) : "Null" );
append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" ); string_append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" );
break; break;
case CT_Destructor: case CT_Destructor:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" ); string_append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" );
break; break;
case CT_Destructor_Fwd: case CT_Destructor_Fwd:
@ -124,208 +124,208 @@ char const* debug_str(Code self)
case CT_Enum: case CT_Enum:
case CT_Enum_Class: case CT_Enum_Class:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" ); string_append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tUnderlying Type : %S", self->UnderlyingType ? to_string(self->UnderlyingType) : "Null" ); string_append_fmt( result, "\n\tUnderlying Type : %S", self->UnderlyingType ? to_string(self->UnderlyingType) : "Null" );
append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" ); string_append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" );
break; break;
case CT_Enum_Fwd: case CT_Enum_Fwd:
case CT_Enum_Class_Fwd: case CT_Enum_Class_Fwd:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" ); string_append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tUnderlying Type : %S", self->UnderlyingType ? to_string(self->UnderlyingType) : "Null" ); string_append_fmt( result, "\n\tUnderlying Type : %S", self->UnderlyingType ? to_string(self->UnderlyingType) : "Null" );
break; break;
case CT_Extern_Linkage: case CT_Extern_Linkage:
case CT_Namespace: case CT_Namespace:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tBody: %S", self->Body ? debug_str(self->Body) : "Null" ); string_append_fmt( result, "\n\tBody: %S", self->Body ? debug_str(self->Body) : "Null" );
break; break;
case CT_Friend: case CT_Friend:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tDeclaration: %S", self->Declaration ? to_string(self->Declaration) : "Null" ); string_append_fmt( result, "\n\tDeclaration: %S", self->Declaration ? to_string(self->Declaration) : "Null" );
break; break;
case CT_Function: case CT_Function:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tAttributes: %S", self->Attributes ? to_string(self->Attributes) : "Null" ); string_append_fmt( result, "\n\tAttributes: %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? to_string(self->ReturnType) : "Null" ); string_append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? to_string(self->ReturnType) : "Null" );
append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" ); string_append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" );
append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" ); string_append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" );
break; break;
case CT_Function_Fwd: case CT_Function_Fwd:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tAttributes: %S", self->Attributes ? to_string(self->Attributes) : "Null" ); string_append_fmt( result, "\n\tAttributes: %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? to_string(self->ReturnType) : "Null" ); string_append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? to_string(self->ReturnType) : "Null" );
append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" ); string_append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" );
break; break;
case CT_Module: case CT_Module:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
break; break;
case CT_Operator: case CT_Operator:
case CT_Operator_Member: case CT_Operator_Member:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tAttributes: %S", self->Attributes ? to_string(self->Attributes) : "Null" ); string_append_fmt( result, "\n\tAttributes: %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? to_string(self->ReturnType) : "Null" ); string_append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? to_string(self->ReturnType) : "Null" );
append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" ); string_append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" );
append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" ); string_append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" );
append_fmt( result, "\n\tOp : %S", to_str( self->Op ) ); string_append_fmt( result, "\n\tOp : %S", to_str( self->Op ) );
break; break;
case CT_Operator_Fwd: case CT_Operator_Fwd:
case CT_Operator_Member_Fwd: case CT_Operator_Member_Fwd:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tAttributes: %S", self->Attributes ? to_string(self->Attributes) : "Null" ); string_append_fmt( result, "\n\tAttributes: %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? to_string(self->ReturnType) : "Null" ); string_append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? to_string(self->ReturnType) : "Null" );
append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" ); string_append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" );
append_fmt( result, "\n\tOp : %S", to_str( self->Op ) ); string_append_fmt( result, "\n\tOp : %S", to_str( self->Op ) );
break; break;
case CT_Operator_Cast: case CT_Operator_Cast:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tValueType : %S", self->ValueType ? to_string(self->ValueType) : "Null" ); string_append_fmt( result, "\n\tValueType : %S", self->ValueType ? to_string(self->ValueType) : "Null" );
append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" ); string_append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" );
break; break;
case CT_Operator_Cast_Fwd: case CT_Operator_Cast_Fwd:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tValueType : %S", self->ValueType ? to_string(self->ValueType) : "Null" ); string_append_fmt( result, "\n\tValueType : %S", self->ValueType ? to_string(self->ValueType) : "Null" );
break; break;
case CT_Parameters: case CT_Parameters:
append_fmt( result, "\n\tNumEntries: %d", self->NumEntries ); string_append_fmt( result, "\n\tNumEntries: %d", self->NumEntries );
append_fmt( result, "\n\tLast : %S", self->Last->Name ); string_append_fmt( result, "\n\tLast : %S", self->Last->Name );
append_fmt( result, "\n\tNext : %S", self->Next->Name ); string_append_fmt( result, "\n\tNext : %S", self->Next->Name );
append_fmt( result, "\n\tValueType : %S", self->ValueType ? to_string(self->ValueType) : "Null" ); string_append_fmt( result, "\n\tValueType : %S", self->ValueType ? to_string(self->ValueType) : "Null" );
append_fmt( result, "\n\tValue : %S", self->Value ? to_string(self->Value) : "Null" ); string_append_fmt( result, "\n\tValue : %S", self->Value ? to_string(self->Value) : "Null" );
break; break;
case CT_Specifiers: case CT_Specifiers:
{ {
append_fmt( result, "\n\tNumEntries: %d", self->NumEntries ); string_append_fmt( result, "\n\tNumEntries: %d", self->NumEntries );
GEN_NS append( result, "\n\tArrSpecs: " ); string_append_strc( result, txt("\n\tArrSpecs: ") );
s32 idx = 0; s32 idx = 0;
s32 left = self->NumEntries; s32 left = self->NumEntries;
while ( left-- ) while ( left-- )
{ {
StrC spec = to_str( self->ArrSpecs[idx] ); StrC spec = to_str( self->ArrSpecs[idx] );
append_fmt( result, "%.*s, ", spec.Len, spec.Ptr ); string_append_fmt( result, "%.*s, ", spec.Len, spec.Ptr );
idx++; idx++;
} }
append_fmt( result, "\n\tNextSpecs: %S", self->NextSpecs ? debug_str(self->NextSpecs) : "Null" ); string_append_fmt( result, "\n\tNextSpecs: %S", self->NextSpecs ? debug_str(self->NextSpecs) : "Null" );
} }
break; break;
case CT_Template: case CT_Template:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" ); string_append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" );
append_fmt( result, "\n\tDeclaration: %S", self->Declaration ? to_string(self->Declaration) : "Null" ); string_append_fmt( result, "\n\tDeclaration: %S", self->Declaration ? to_string(self->Declaration) : "Null" );
break; break;
case CT_Typedef: case CT_Typedef:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tUnderlyingType: %S", self->UnderlyingType ? to_string(self->UnderlyingType) : "Null" ); string_append_fmt( result, "\n\tUnderlyingType: %S", self->UnderlyingType ? to_string(self->UnderlyingType) : "Null" );
break; break;
case CT_Typename: case CT_Typename:
append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" ); string_append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tReturnType : %S", self->ReturnType ? to_string(self->ReturnType) : "Null" ); string_append_fmt( result, "\n\tReturnType : %S", self->ReturnType ? to_string(self->ReturnType) : "Null" );
append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" ); string_append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" );
append_fmt( result, "\n\tArrExpr : %S", self->ArrExpr ? to_string(self->ArrExpr) : "Null" ); string_append_fmt( result, "\n\tArrExpr : %S", self->ArrExpr ? to_string(self->ArrExpr) : "Null" );
break; break;
case CT_Union: case CT_Union:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tAttributes: %S", self->Attributes ? to_string(self->Attributes) : "Null" ); string_append_fmt( result, "\n\tAttributes: %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" ); string_append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" );
break; break;
case CT_Using: case CT_Using:
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" ); string_append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tUnderlyingType: %S", self->UnderlyingType ? to_string(self->UnderlyingType) : "Null" ); string_append_fmt( result, "\n\tUnderlyingType: %S", self->UnderlyingType ? to_string(self->UnderlyingType) : "Null" );
break; break;
case CT_Variable: case CT_Variable:
@ -333,25 +333,25 @@ char const* debug_str(Code self)
if ( self->Parent && self->Parent->Type == CT_Variable ) if ( self->Parent && self->Parent->Type == CT_Variable )
{ {
// Its a NextVar // Its a NextVar
append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tValue : %S", self->Value ? to_string(self->Value) : "Null" ); string_append_fmt( result, "\n\tValue : %S", self->Value ? to_string(self->Value) : "Null" );
append_fmt( result, "\n\tBitfieldSize: %S", self->BitfieldSize ? to_string(self->BitfieldSize) : "Null" ); string_append_fmt( result, "\n\tBitfieldSize: %S", self->BitfieldSize ? to_string(self->BitfieldSize) : "Null" );
append_fmt( result, "\n\tNextVar : %S", self->NextVar ? debug_str(self->NextVar) : "Null" ); string_append_fmt( result, "\n\tNextVar : %S", self->NextVar ? debug_str(self->NextVar) : "Null" );
break; break;
} }
if ( self->Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( self->Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); string_append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" ); string_append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tValueType : %S", self->ValueType ? to_string(self->ValueType) : "Null" ); string_append_fmt( result, "\n\tValueType : %S", self->ValueType ? to_string(self->ValueType) : "Null" );
append_fmt( result, "\n\tBitfieldSize: %S", self->BitfieldSize ? to_string(self->BitfieldSize) : "Null" ); string_append_fmt( result, "\n\tBitfieldSize: %S", self->BitfieldSize ? to_string(self->BitfieldSize) : "Null" );
append_fmt( result, "\n\tValue : %S", self->Value ? to_string(self->Value) : "Null" ); string_append_fmt( result, "\n\tValue : %S", self->Value ? to_string(self->Value) : "Null" );
append_fmt( result, "\n\tNextVar : %S", self->NextVar ? debug_str(self->NextVar) : "Null" ); string_append_fmt( result, "\n\tNextVar : %S", self->NextVar ? debug_str(self->NextVar) : "Null" );
break; break;
} }
@ -370,7 +370,7 @@ Code duplicate(Code self)
String to_string(Code self) String to_string(Code self)
{ {
String result = string_make( GlobalAllocator, "" ); String result = string_make_strc( GlobalAllocator, txt("") );
GEN_NS to_string( self, & result ); GEN_NS to_string( self, & result );
return result; return result;
} }
@ -387,25 +387,25 @@ void to_string( Code self, String* result )
#ifdef GEN_DONT_ALLOW_INVALID_CODE #ifdef GEN_DONT_ALLOW_INVALID_CODE
log_failure("Attempted to serialize invalid code! - %S", Parent ? Parent->debug_str() : Name ); log_failure("Attempted to serialize invalid code! - %S", Parent ? Parent->debug_str() : Name );
#else #else
append_fmt( result, "Invalid Code!" ); string_append_fmt( result, "Invalid Code!" );
#endif #endif
break; break;
case CT_NewLine: case CT_NewLine:
append( result,"\n"); string_append_strc( result, txt("\n"));
break; break;
case CT_Untyped: case CT_Untyped:
case CT_Execution: case CT_Execution:
case CT_Comment: case CT_Comment:
case CT_PlatformAttributes: case CT_PlatformAttributes:
append( result, self->Content ); string_append_strc( result, self->Content );
break; break;
case CT_Access_Private: case CT_Access_Private:
case CT_Access_Protected: case CT_Access_Protected:
case CT_Access_Public: case CT_Access_Public:
append( result, self->Name ); string_append_strc( result, self->Name );
break; break;
case CT_Class: case CT_Class:
@ -640,23 +640,23 @@ bool is_equal( Code self, Code other )
return false; \ return false; \
} }
#define check_member_content( content ) \ #define check_member_content( content ) \
if ( self->content != other->content ) \ if ( self->content != other->content ) \
{ \ { \
log_fmt("\nAST::is_equal: Member content - "#content " failed\n" \ log_fmt("\nAST::is_equal: Member content - "#content " failed\n" \
"AST : %S\n" \ "AST : %S\n" \
"Other: %S\n" \ "Other: %S\n" \
, debug_str(self) \ , debug_str(self) \
,debug_str(other) \ , debug_str(other) \
); \ ); \
\ \
log_fmt("Content cannot be trusted to be unique with this check " \ log_fmt("Content cannot be trusted to be unique with this check " \
"so it must be verified by eye for now\n" \ "so it must be verified by eye for now\n" \
"AST Content:\n%S\n" \ "AST Content:\n%S\n" \
"Other Content:\n%S\n" \ "Other Content:\n%S\n" \
, visualize_whitespace(self->content, GlobalAllocator) \ , strc_visualize_whitespace(self->content, GlobalAllocator) \
, visualize_whitespace(other->content, GlobalAllocator) \ , strc_visualize_whitespace(other->content, GlobalAllocator) \
); \ ); \
} }
#define check_member_ast( ast ) \ #define check_member_ast( ast ) \

File diff suppressed because it is too large Load Diff

View File

@ -159,16 +159,16 @@ extern CodeTypename t_typename;
// Used by the lexer to persistently treat all these identifiers as preprocessor defines. // Used by the lexer to persistently treat all these identifiers as preprocessor defines.
// Populate with strings via gen::get_cached_string. // Populate with strings via gen::get_cached_string.
// Functional defines must have format: id( ;at minimum to indicate that the define is only valid with arguments. // Functional defines must have format: id( ;at minimum to indicate that the define is only valid with arguments.
extern Array< StringCached > PreprocessorDefines; extern Array(StringCached) PreprocessorDefines;
#ifdef GEN_EXPOSE_BACKEND #ifdef GEN_EXPOSE_BACKEND
// Global allocator used for data with process lifetime. // Global allocator used for data with process lifetime.
extern AllocatorInfo GlobalAllocator; extern AllocatorInfo GlobalAllocator;
extern Array< Arena > Global_AllocatorBuckets; extern Array(Arena) Global_AllocatorBuckets;
extern Array< Pool > CodePools; extern Array(Pool) CodePools;
extern Array< Arena > StringArenas; extern Array(Arena) StringArenas;
extern StringTable StringCache; extern StringTable StringCache;

View File

@ -134,7 +134,7 @@ Code begin( CodeBody body) {
} }
inline inline
Code end(CodeBody body ){ Code end(CodeBody body ){
return { nullptr }; return { rcast(AST*, body.ast)->Back->Next };
} }
#pragma endregion CodeBody #pragma endregion CodeBody

View File

@ -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 = array_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 ( ! array_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 = array_back(& Global_AllocatorBuckets);
} }
return alloc_align( allocator_info(last), size, alignment ); return alloc_align( arena_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 ( ! array_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 = array_back(& Global_AllocatorBuckets);
} }
void* result = alloc_align( last->Backing, size, alignment ); void* result = alloc_align( last->Backing, size, alignment );
@ -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 ); array_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 ); array_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 ); array_append( & StringArenas, string_arena );
} }
// Setup the hash tables // Setup the hash tables
@ -302,62 +302,62 @@ void init()
void deinit() void deinit()
{ {
usize index = 0; usize index = 0;
usize left = num(CodePools); usize left = array_num(CodePools);
do do
{ {
Pool* code_pool = & CodePools[index]; Pool* code_pool = & CodePools[index];
free(code_pool); pool_free(code_pool);
index++; index++;
} }
while ( left--, left ); while ( left--, left );
index = 0; index = 0;
left = num(StringArenas); left = array_num(StringArenas);
do do
{ {
Arena* string_arena = & StringArenas[index]; Arena* string_arena = & StringArenas[index];
free(string_arena); arena_free(string_arena);
index++; index++;
} }
while ( left--, left ); while ( left--, left );
destroy(& StringCache); destroy(& StringCache);
free( & CodePools); array_free( & CodePools);
free( & StringArenas); array_free( & StringArenas);
free(& LexArena); arena_free(& LexArena);
free(& PreprocessorDefines); array_free(& PreprocessorDefines);
index = 0; index = 0;
left = num(Global_AllocatorBuckets); left = array_num(Global_AllocatorBuckets);
do do
{ {
Arena* bucket = & Global_AllocatorBuckets[ index ]; Arena* bucket = & Global_AllocatorBuckets[ index ];
free(bucket); arena_free(bucket);
index++; index++;
} }
while ( left--, left ); while ( left--, left );
free(Global_AllocatorBuckets); array_free(& Global_AllocatorBuckets);
parser::deinit(); parser::deinit();
} }
void reset() void reset()
{ {
s32 index = 0; s32 index = 0;
s32 left = num(CodePools); s32 left = array_num(CodePools);
do do
{ {
Pool* code_pool = & CodePools[index]; Pool* code_pool = & CodePools[index];
clear(* code_pool); pool_clear(code_pool);
index++; index++;
} }
while ( left--, left ); while ( left--, left );
index = 0; index = 0;
left = num(StringArenas); left = array_num(StringArenas);
do do
{ {
Arena* string_arena = & StringArenas[index]; Arena* string_arena = & StringArenas[index];
@ -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 = array_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 ( ! array_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 = array_back(& StringArenas);
} }
return allocator_info(last); return arena_allocator_info(last);
} }
// Will either make or retrive a code string. // Will either make or retrive a code string.
@ -402,16 +402,16 @@ StringCached get_cached_string( StrC str )
return * result; return * result;
} }
String result = string_make( get_string_allocator( str.Len ), str ); String result = string_make_strc( get_string_allocator( str.Len ), str );
set(& StringCache, key, { length(result), result } ); set(& StringCache, key, { str.Len, result } );
return { length(result), result }; return { str.Len, result };
} }
// 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 = array_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 ( ! array_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 = array_back( & CodePools);
} }
Code result { rcast( AST*, alloc( allocator_info(allocator), sizeof(AST) )) }; Code result { rcast( AST*, alloc( pool_allocator_info(allocator), sizeof(AST) )) };
mem_set( result.ast, 0, sizeof(AST) ); mem_set( result.ast, 0, sizeof(AST) );
// result->Type = ECode::Invalid; // result->Type = ECode::Invalid;

View File

@ -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, arena_allocator_info(& tok_map_arena) );
s32 left = num_tokens - 1; s32 left = num_tokens - 1;
@ -94,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); arena_free(& tok_map_arena);
ssize result = buf_size - remaining; ssize result = buf_size - remaining;
@ -142,7 +142,7 @@ Code untyped_fmt( char const* fmt, ...)
Code Code
result = make_code(); result = make_code();
result->Name = get_cached_string( { str_len(fmt, MaxNameLength), fmt } ); result->Name = get_cached_string( { str_len_capped(fmt, MaxNameLength), fmt } );
result->Type = CT_Untyped; result->Type = CT_Untyped;
result->Content = get_cached_string( { length, buf } ); result->Content = get_cached_string( { length, buf } );

View File

@ -472,23 +472,23 @@ CodeComment def_comment( StrC content )
length++; length++;
str_copy( line, scanner, length ); str_copy( line, scanner, length );
append_fmt(& cmt_formatted, "//%.*s", length, line ); string_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 ( * string_back(cmt_formatted) != '\n' )
append( & cmt_formatted, "\n" ); string_append_strc( & cmt_formatted, txt("\n") );
Code Code
result = make_code(); result = make_code();
result->Type = CT_Comment; result->Type = CT_Comment;
result->Name = get_cached_string( { length(cmt_formatted), cmt_formatted } ); result->Name = get_cached_string( { string_length(cmt_formatted), cmt_formatted } );
result->Content = result->Name; result->Content = result->Name;
free(& cmt_formatted); string_free(& cmt_formatted);
return (CodeComment) result; return (CodeComment) result;
} }
@ -907,14 +907,14 @@ CodeInclude def_include( StrC path, Opts_def_include p )
return InvalidCode; return InvalidCode;
} }
StrC content = p.foreign ? String content = p.foreign ?
to_str( str_fmt_buf( "<%.*s>", path.Len, path.Ptr )) string_fmt_buf( GlobalAllocator, "<%.*s>", path.Len, path.Ptr )
: to_str( str_fmt_buf( "\"%.*s\"", path.Len, path.Ptr )); : string_fmt_buf( GlobalAllocator, "\"%.*s\"", path.Len, path.Ptr );
Code Code
result = make_code(); result = make_code();
result->Type = CT_Preprocess_Include; result->Type = CT_Preprocess_Include;
result->Name = get_cached_string( content ); result->Name = get_cached_string( string_to_strc(content) );
result->Content = result->Name; result->Content = result->Name;
return (CodeInclude) result; return (CodeInclude) result;
@ -938,7 +938,7 @@ CodeNS def_namespace( StrC name, Code body, Opts_def_namespace p )
{ {
name_check( def_namespace, name ); name_check( def_namespace, name );
null_check( def_namespace, body); null_check( def_namespace, body);
if ( body && body->Type != CT_Namespace_Body && body->Type != CT_Untyped ) if ( body && body->Type != CT_Namespace_Body && body->Type != CT_Untyped )
{ {
log_failure("gen::def_namespace: body is not of namespace or untyped type %s", debug_str(body)); log_failure("gen::def_namespace: body is not of namespace or untyped type %s", debug_str(body));

View File

@ -96,7 +96,7 @@ String to_string(Token tok)
StrC type_str = to_str( tok.Type ); StrC type_str = to_str( tok.Type );
append_fmt( & result, "Line: %d Column: %d, Type: %.*s Content: %.*s" string_append_fmt( & result, "Line: %d Column: %d, Type: %.*s Content: %.*s"
, tok.Line, tok.Column , tok.Line, tok.Column
, type_str.Len, type_str.Ptr , type_str.Len, type_str.Ptr
, tok.Length, tok.Text , tok.Length, tok.Text
@ -221,7 +221,7 @@ forceinline
s32 lex_preprocessor_directive( LexContext* ctx ) s32 lex_preprocessor_directive( LexContext* ctx )
{ {
char const* hash = ctx->scanner; char const* hash = ctx->scanner;
append( & Tokens, { hash, 1, Tok_Preprocess_Hash, ctx->line, ctx->column, TF_Preprocess } ); array_append( & Tokens, { hash, 1, Tok_Preprocess_Hash, ctx->line, ctx->column, TF_Preprocess } );
move_forward(); move_forward();
SkipWhitespace(); SkipWhitespace();
@ -297,14 +297,14 @@ s32 lex_preprocessor_directive( LexContext* ctx )
ctx->token.Length = ctx->token.Length + ctx->token.Text - hash; ctx->token.Length = ctx->token.Length + ctx->token.Text - hash;
ctx->token.Text = hash; ctx->token.Text = hash;
append( & Tokens, ctx->token ); array_append( & Tokens, ctx->token );
return Lex_Continue; // Skip found token, its all handled here. return Lex_Continue; // Skip found token, its all handled here.
} }
if ( ctx->token.Type == Tok_Preprocess_Else || ctx->token.Type == Tok_Preprocess_EndIf ) if ( ctx->token.Type == Tok_Preprocess_Else || ctx->token.Type == Tok_Preprocess_EndIf )
{ {
ctx->token.Flags |= TF_Preprocess_Cond; ctx->token.Flags |= TF_Preprocess_Cond;
append( & Tokens, ctx->token ); array_append( & Tokens, ctx->token );
end_line(); end_line();
return Lex_Continue; return Lex_Continue;
} }
@ -313,7 +313,7 @@ s32 lex_preprocessor_directive( LexContext* ctx )
ctx->token.Flags |= TF_Preprocess_Cond; ctx->token.Flags |= TF_Preprocess_Cond;
} }
append( & Tokens, ctx->token ); array_append( & Tokens, ctx->token );
SkipWhitespace(); SkipWhitespace();
@ -337,7 +337,7 @@ s32 lex_preprocessor_directive( LexContext* ctx )
name.Length++; name.Length++;
} }
append( & Tokens, name ); array_append( & Tokens, name );
u64 key = crc32( name.Text, name.Length ); u64 key = crc32( name.Text, name.Length );
set(& ctx->defines, key, to_str(name) ); set(& ctx->defines, key, to_str(name) );
@ -383,7 +383,7 @@ s32 lex_preprocessor_directive( LexContext* ctx )
move_forward(); move_forward();
} }
append( & Tokens, preprocess_content ); array_append( & Tokens, preprocess_content );
return Lex_Continue; // Skip found token, its all handled here. return Lex_Continue; // Skip found token, its all handled here.
} }
@ -445,7 +445,7 @@ s32 lex_preprocessor_directive( LexContext* ctx )
preprocess_content.Length++; preprocess_content.Length++;
} }
append( & Tokens, preprocess_content ); array_append( & Tokens, preprocess_content );
return Lex_Continue; // Skip found token, its all handled here. return Lex_Continue; // Skip found token, its all handled here.
} }
@ -454,7 +454,7 @@ void lex_found_token( LexContext* ctx )
{ {
if ( ctx->token.Type != Tok_Invalid ) if ( ctx->token.Type != Tok_Invalid )
{ {
append( & Tokens, ctx->token ); array_append( & Tokens, ctx->token );
return; return;
} }
@ -481,7 +481,7 @@ void lex_found_token( LexContext* ctx )
} }
ctx->token.Type = type; ctx->token.Type = type;
append( & Tokens, ctx->token ); array_append( & Tokens, ctx->token );
return; return;
} }
@ -491,7 +491,7 @@ void lex_found_token( LexContext* ctx )
{ {
ctx->token.Type = type; ctx->token.Type = type;
ctx->token.Flags |= TF_Specifier; ctx->token.Flags |= TF_Specifier;
append( & Tokens, ctx->token ); array_append( & Tokens, ctx->token );
return; return;
} }
@ -499,7 +499,7 @@ void lex_found_token( LexContext* ctx )
if ( type != Tok_Invalid ) if ( type != Tok_Invalid )
{ {
ctx->token.Type = type; ctx->token.Type = type;
append( & Tokens, ctx->token ); array_append( & Tokens, ctx->token );
return; return;
} }
@ -551,7 +551,7 @@ void lex_found_token( LexContext* ctx )
ctx->token.Type = Tok_Identifier; ctx->token.Type = Tok_Identifier;
} }
append( & Tokens, ctx->token ); array_append( & Tokens, ctx->token );
} }
@ -578,16 +578,16 @@ TokArray lex( StrC content )
return { {}, 0 }; return { {}, 0 };
} }
foreach( StringCached*, entry, PreprocessorDefines ) for ( StringCached* entry = array_begin(PreprocessorDefines); entry != array_end(PreprocessorDefines); entry = array_next(PreprocessorDefines, entry))
{ {
s32 length = 0; s32 length = 0;
char const* scanner = * entry; char const* entry_scanner = * entry;
while ( entry->Len > length && (char_is_alphanumeric( *scanner ) || *scanner == '_') ) while ( entry->Len > length && (char_is_alphanumeric( *entry_scanner ) || *entry_scanner == '_') )
{ {
c.scanner++; entry_scanner++;
length ++; length ++;
} }
if ( c.scanner[0] == '(' ) if ( entry_scanner[0] == '(' )
{ {
length++; length++;
} }
@ -596,7 +596,7 @@ TokArray lex( StrC content )
set(& c.defines, key, (StrC) * entry ); set(& c.defines, key, (StrC) * entry );
} }
clear(Tokens); array_clear(Tokens);
while (c.left ) while (c.left )
{ {
@ -626,7 +626,7 @@ TokArray lex( StrC content )
c.token.Type = Tok_NewLine; c.token.Type = Tok_NewLine;
c.token.Length++; c.token.Length++;
append( & Tokens, c.token ); array_append( & Tokens, c.token );
continue; continue;
} }
} }
@ -1095,7 +1095,7 @@ TokArray lex( StrC content )
move_forward(); move_forward();
c.token.Length++; c.token.Length++;
} }
append( & Tokens, c.token ); array_append( & Tokens, c.token );
continue; continue;
} }
else if ( current == '*' ) else if ( current == '*' )
@ -1131,7 +1131,7 @@ TokArray lex( StrC content )
move_forward(); move_forward();
c.token.Length++; c.token.Length++;
} }
append( & Tokens, c.token ); array_append( & Tokens, c.token );
// end_line(); // end_line();
continue; continue;
} }
@ -1224,9 +1224,9 @@ TokArray lex( StrC content )
} }
else else
{ {
s32 start = max( 0, num(Tokens) - 100 ); s32 start = max( 0, array_num(Tokens) - 100 );
log_fmt("\n%d\n", start); log_fmt("\n%d\n", start);
for ( s32 idx = start; idx < num(Tokens); idx++ ) for ( s32 idx = start; idx < array_num(Tokens); idx++ )
{ {
log_fmt( "Token %d Type: %s : %.*s\n" log_fmt( "Token %d Type: %s : %.*s\n"
, idx , idx
@ -1249,7 +1249,7 @@ TokArray lex( StrC content )
lex_found_token( ctx ); lex_found_token( ctx );
} }
if ( num(Tokens) == 0 ) if ( array_num(Tokens) == 0 )
{ {
log_failure( "Failed to lex any tokens" ); log_failure( "Failed to lex any tokens" );
return { {}, 0 }; return { {}, 0 };

View File

@ -50,28 +50,28 @@ String to_string(ParseContext ctx)
String result = string_make_reserve( GlobalAllocator, kilobytes(4) ); String result = string_make_reserve( GlobalAllocator, kilobytes(4) );
Token scope_start = ctx.Scope->Start; Token scope_start = ctx.Scope->Start;
Token last_valid = ctx.Tokens.Idx >= num(ctx.Tokens.Arr) ? ctx.Tokens.Arr[num(ctx.Tokens.Arr) -1] : (* current(& ctx.Tokens, true)); Token last_valid = ctx.Tokens.Idx >= array_num(ctx.Tokens.Arr) ? ctx.Tokens.Arr[array_num(ctx.Tokens.Arr) -1] : (* current(& ctx.Tokens, true));
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( & ctx.Tokens.Arr)->Text && *current != '\n' && length < 74 ) while ( current <= array_back( & ctx.Tokens.Arr)->Text && *current != '\n' && length < 74 )
{ {
current++; current++;
length++; length++;
} }
String line = string_make( GlobalAllocator, { length, scope_start.Text } ); String line = string_make_strc( GlobalAllocator, { length, scope_start.Text } );
append_fmt( & result, "\tScope : %s\n", line ); string_append_fmt( & result, "\tScope : %s\n", line );
free(& line); string_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_strc( 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, '^' ); string_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 ); string_append_fmt(& result, "\t(%d, %d)\n", last_valid.Line, last_valid.Column );
StackNode* curr_scope = ctx.Scope; StackNode* curr_scope = ctx.Scope;
s32 level = 0; s32 level = 0;
@ -79,11 +79,11 @@ String to_string(ParseContext ctx)
{ {
if ( is_valid(curr_scope->Name) ) if ( is_valid(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 ); string_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 ); string_append_fmt(& result, "\t%d: %s\n", level, curr_scope->ProcName.Ptr );
} }
curr_scope = curr_scope->Prev; curr_scope = curr_scope->Prev;
@ -97,7 +97,7 @@ global ParseContext Context;
bool __eat(TokArray* self, TokType type ) bool __eat(TokArray* self, TokType type )
{ {
if ( num(self->Arr) - self->Idx <= 0 ) if ( array_num(self->Arr) - self->Idx <= 0 )
{ {
log_failure( "No tokens left.\n%s", to_string(Context) ); log_failure( "No tokens left.\n%s", to_string(Context) );
return false; return false;
@ -136,12 +136,12 @@ bool __eat(TokArray* self, TokType type )
internal internal
void init() void init()
{ {
Tokens = array_init_reserve<Token>( allocator_info( & LexArena) Tokens = array_init_reserve(Token, arena_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
@ -175,7 +175,7 @@ bool _check_parse_args( StrC def, char const* func_name )
# define prevtok (* previous( Context.Tokens, dont_skip_formatting)) # define prevtok (* previous( Context.Tokens, dont_skip_formatting))
# define nexttok (* next( Context.Tokens, skip_formatting )) # define nexttok (* next( Context.Tokens, skip_formatting ))
# define eat( Type_ ) __eat( & Context.Tokens, Type_ ) # define eat( Type_ ) __eat( & Context.Tokens, Type_ )
# define left ( num(Context.Tokens.Arr) - Context.Tokens.Idx ) # define left ( array_num(Context.Tokens.Arr) - Context.Tokens.Idx )
#ifdef check #ifdef check
#define CHECK_WAS_DEFINED #define CHECK_WAS_DEFINED
@ -298,7 +298,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 ); string_append_c_str_len( & content, cut_ptr, cut_length );
last_cut = sptr( scanner ) - sptr( raw_text.Ptr ); last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
continue; continue;
} }
@ -320,7 +320,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 ); string_append_c_str_len( & content, cut_ptr, cut_length );
last_cut = sptr( scanner ) - sptr( raw_text.Ptr ); last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
continue; continue;
} }
@ -334,7 +334,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 ); string_append_c_str_len( & content, cut_ptr, cut_length );
last_cut = sptr( scanner ) - sptr( raw_text.Ptr ); last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
continue; continue;
} }
@ -353,7 +353,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 ); string_append_c_str_len( & content, cut_ptr, cut_length );
last_cut = sptr( scanner ) - sptr( raw_text.Ptr ); last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
continue; continue;
} }
@ -362,10 +362,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); string_append_c_str_len( & content, cut_ptr, cut_length);
if ( * back( & content ) != ' ' ) if ( * string_back( content ) != ' ' )
append( & content, ' '); string_append_char( & content, ' ' );
move_fwd(); move_fwd();
last_cut = sptr(scanner) - sptr(raw_text.Ptr); last_cut = sptr(scanner) - sptr(raw_text.Ptr);
@ -381,17 +381,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 ); string_append_c_str_len( & 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 ); string_append_c_str_len( & content, cut_ptr, cut_length );
// Replace with a space // Replace with a space
if ( * back( & content ) != ' ' ) if ( * string_back( content ) != ' ' )
append( & content, ' ' ); string_append_char( & content, ' ' );
scanner += 2; scanner += 2;
tokleft -= 2; tokleft -= 2;
@ -408,17 +408,17 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
move_fwd(); move_fwd();
append( & content, cut_ptr, cut_length ); string_append_c_str_len( & 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 ); string_append_c_str_len( & content, cut_ptr, cut_length );
// Replace with a space // Replace with a space
if ( * back( & content ) != ' ' ) if ( * string_back( content ) != ' ' )
append( & content, ' ' ); string_append_char( & content, ' ' );
move_fwd(); move_fwd();
@ -429,7 +429,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 ); string_append_c_str_len( & 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' )
@ -456,7 +456,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 ); string_append_c_str_len( & content, cut_ptr, cut_length );
do do
{ {
move_fwd(); move_fwd();
@ -466,9 +466,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
char* last = back(& content); char* last = string_back(content);
if ( last == nullptr || * last != ' ' ) if ( last == nullptr || * last != ' ' )
append( & content, ' ' ); string_append_char( & content, ' ' );
continue; continue;
} }
@ -478,7 +478,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 ); string_append_c_str_len( & content, cut_ptr, raw_text.Len - last_cut );
} }
#undef cut_ptr #undef cut_ptr
@ -669,7 +669,7 @@ CodeAttributes parse_attributes()
Code result = make_code(); Code result = make_code();
result->Type = CT_PlatformAttributes; result->Type = CT_PlatformAttributes;
result->Name = get_cached_string( { length(name_stripped), name_stripped } ); result->Name = get_cached_string( { string_length(name_stripped), name_stripped } );
result->Content = result->Name; result->Content = result->Name;
// result->Token = // result->Token =
@ -723,7 +723,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<CodeTypename> interfaces; { Array<CodeTypename> 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<CodeTypename>( allocator_info(& arena), 4 ); interfaces = array_init_reserve(CodeTypename, arena_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.
@ -754,7 +754,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( to_str(interface_tok) ) ); array_append( & interfaces, def_type( to_str(interface_tok) ) );
// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Name>, ... // <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Name>, ...
} }
} }
@ -786,7 +786,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); array_free(& interfaces);
return result; return result;
} }
@ -1048,9 +1048,9 @@ CodeBody parse_class_struct_body( TokType which, Token name )
if ( attributes ) if ( attributes )
{ {
String fused = string_make_reserve( GlobalAllocator, attributes->Content.Len + more_attributes->Content.Len ); String fused = string_make_reserve( GlobalAllocator, attributes->Content.Len + more_attributes->Content.Len );
append_fmt( & fused, "%S %S", attributes->Content, more_attributes->Content ); string_append_fmt( & fused, "%S %S", attributes->Content, more_attributes->Content );
attributes->Name = get_cached_string({ length(fused), fused }); attributes->Name = get_cached_string( { string_length(fused), fused });
attributes->Content = attributes->Name; attributes->Content = attributes->Name;
// <Attributes> <Specifiers> <Attributes> // <Attributes> <Specifiers> <Attributes>
} }
@ -1086,7 +1086,7 @@ CodeBody parse_class_struct_body( TokType which, Token name )
{ {
if ( nexttok.Type == Tok_Capture_Start && name.Length && currtok.Type == Tok_Identifier ) if ( nexttok.Type == Tok_Capture_Start && name.Length && currtok.Type == Tok_Identifier )
{ {
if ( str_compare( name.Text, currtok.Text, name.Length ) == 0 ) if ( str_compare_len( name.Text, currtok.Text, name.Length ) == 0 )
{ {
member = parse_constructor( specifiers ); member = parse_constructor( specifiers );
// <Attributes> <Specifiers> <Name>() // <Attributes> <Specifiers> <Name>()
@ -1159,7 +1159,7 @@ Code parse_complicated_definition( TokType which )
s32 idx = tokens.Idx; s32 idx = tokens.Idx;
s32 level = 0; s32 level = 0;
for ( ; idx < num(tokens.Arr); idx++ ) for ( ; idx < array_num(tokens.Arr); idx++ )
{ {
if ( tokens.Arr[ idx ].Type == Tok_BraceCurly_Open ) if ( tokens.Arr[ idx ].Type == Tok_BraceCurly_Open )
level++; level++;
@ -1344,7 +1344,7 @@ CodeDefine parse_define()
return define; return define;
} }
define->Content = get_cached_string( to_strc( strip_formatting( to_str(currtok), strip_formatting_dont_preserve_newlines )) ); define->Content = get_cached_string( string_to_strc( strip_formatting( to_str(currtok), strip_formatting_dont_preserve_newlines )) );
eat( Tok_Preprocess_Content ); eat( Tok_Preprocess_Content );
// #define <Name> <Content> // #define <Name> <Content>
@ -1489,12 +1489,12 @@ CodeFn parse_function_after_name(
} }
String String
name_stripped = string_make( GlobalAllocator, to_str(name) ); name_stripped = string_make_strc( GlobalAllocator, to_str(name) );
strip_space(name_stripped); strip_space(name_stripped);
CodeFn CodeFn
result = (CodeFn) make_code(); result = (CodeFn) make_code();
result->Name = get_cached_string( to_strc(name_stripped) ); result->Name = get_cached_string( string_to_strc(name_stripped) );
result->ModuleFlags = mflags; result->ModuleFlags = mflags;
if ( body ) if ( body )
@ -1840,7 +1840,7 @@ CodeBody parse_global_nspace( CodeType which )
bool found_operator_cast_outside_class_implmentation = false; bool found_operator_cast_outside_class_implmentation = false;
s32 idx = Context.Tokens.Idx; s32 idx = Context.Tokens.Idx;
for ( ; idx < num(Context.Tokens.Arr); idx++ ) for ( ; idx < array_num(Context.Tokens.Arr); idx++ )
{ {
Token tok = Context.Tokens.Arr[ idx ]; Token tok = Context.Tokens.Arr[ idx ];
@ -1912,14 +1912,14 @@ Code parse_global_nspace_constructor_destructor( CodeSpecifiers specifiers )
s32 idx = tokens.Idx; s32 idx = tokens.Idx;
Token nav = tokens.Arr[ idx ]; Token nav = tokens.Arr[ idx ];
for ( ; idx < num(tokens.Arr); idx++, nav = tokens.Arr[ idx ] ) for ( ; idx < array_num(tokens.Arr); idx++, nav = tokens.Arr[ idx ] )
{ {
if ( nav.Text[0] == '<' ) if ( nav.Text[0] == '<' )
{ {
// Skip templated expressions as they mey have expressions with the () operators // Skip templated expressions as they mey have expressions with the () operators
s32 capture_level = 0; s32 capture_level = 0;
s32 template_level = 0; s32 template_level = 0;
for ( ; idx < num(tokens.Arr); idx++, nav = tokens.Arr[idx] ) for ( ; idx < array_num(tokens.Arr); idx++, nav = tokens.Arr[idx] )
{ {
if (nav.Text[ 0 ] == '<') if (nav.Text[ 0 ] == '<')
++ template_level; ++ template_level;
@ -2001,7 +2001,7 @@ Code parse_global_nspace_constructor_destructor( CodeSpecifiers specifiers )
tok_left = tokens.Arr[idx]; tok_left = tokens.Arr[idx];
} }
bool is_same = str_compare( tok_right.Text, tok_left.Text, tok_right.Length ) == 0; bool is_same = str_compare_len( tok_right.Text, tok_left.Text, tok_right.Length ) == 0;
if (tok_left.Type == Tok_Identifier && is_same) if (tok_left.Type == Tok_Identifier && is_same)
{ {
// We have found the pattern we desired // We have found the pattern we desired
@ -2357,7 +2357,7 @@ CodeOperator parse_operator_after_ret_type(
{ {
StrC str_new = to_str(Op_New); StrC str_new = to_str(Op_New);
StrC str_delete = to_str(Op_Delete); StrC str_delete = to_str(Op_Delete);
if ( str_compare( currtok.Text, str_new.Ptr, max(str_new.Len - 1, currtok.Length)) == 0) if ( str_compare_len( currtok.Text, str_new.Ptr, max(str_new.Len - 1, currtok.Length)) == 0)
{ {
op = Op_New; op = Op_New;
eat( Tok_Identifier ); eat( Tok_Identifier );
@ -2369,7 +2369,7 @@ CodeOperator parse_operator_after_ret_type(
idx++; idx++;
} }
Token next = Context.Tokens.Arr[idx]; Token next = Context.Tokens.Arr[idx];
if ( currtok.Type == Tok_Operator && str_compare(currtok.Text, "[]", 2) == 0) if ( currtok.Type == Tok_Operator && str_compare_len(currtok.Text, "[]", 2) == 0)
{ {
eat(Tok_Operator); eat(Tok_Operator);
op = Op_NewArray; op = Op_NewArray;
@ -2381,7 +2381,7 @@ CodeOperator parse_operator_after_ret_type(
op = Op_NewArray; op = Op_NewArray;
} }
} }
else if ( str_compare( currtok.Text, str_delete.Ptr, max(str_delete.Len - 1, currtok.Length )) == 0) else if ( str_compare_len( currtok.Text, str_delete.Ptr, max(str_delete.Len - 1, currtok.Length )) == 0)
{ {
op = Op_Delete; op = Op_Delete;
eat(Tok_Identifier); eat(Tok_Identifier);
@ -2393,7 +2393,7 @@ CodeOperator parse_operator_after_ret_type(
idx++; idx++;
} }
Token next = Context.Tokens.Arr[idx]; Token next = Context.Tokens.Arr[idx];
if ( currtok.Type == Tok_Operator && str_compare(currtok.Text, "[]", 2) == 0) if ( currtok.Type == Tok_Operator && str_compare_len(currtok.Text, "[]", 2) == 0)
{ {
eat(Tok_Operator); eat(Tok_Operator);
op = Op_DeleteArray; op = Op_DeleteArray;
@ -2513,7 +2513,7 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes
bool found_operator = false; bool found_operator = false;
s32 idx = Context.Tokens.Idx; s32 idx = Context.Tokens.Idx;
for ( ; idx < num(Context.Tokens.Arr); idx++ ) for ( ; idx < array_num(Context.Tokens.Arr); idx++ )
{ {
Token tok = Context.Tokens.Arr[ idx ]; Token tok = Context.Tokens.Arr[ idx ];
@ -2730,7 +2730,7 @@ CodeParam parse_params( bool use_template_capture )
eat( currtok.Type ); eat( currtok.Type );
} }
value = untyped_str( to_strc(strip_formatting( to_str(value_tok), strip_formatting_dont_preserve_newlines )) ); value = untyped_str( string_to_strc(strip_formatting( to_str(value_tok), strip_formatting_dont_preserve_newlines )) );
// ( <Macro> <ValueType> <Name> = <Expression> // ( <Macro> <ValueType> <Name> = <Expression>
} }
} }
@ -2845,7 +2845,7 @@ CodeParam parse_params( bool use_template_capture )
eat( currtok.Type ); eat( currtok.Type );
} }
value = untyped_str( to_strc(strip_formatting( to_str(value_tok), strip_formatting_dont_preserve_newlines )) ); value = untyped_str( string_to_strc(strip_formatting( to_str(value_tok), strip_formatting_dont_preserve_newlines )) );
// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> = <Expression> // ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> = <Expression>
} }
// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> = <Expression>, .. // ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> = <Expression>, ..
@ -2957,7 +2957,7 @@ Code parse_simple_preprocess( TokType which )
// <Macro> { <Body> } // <Macro> { <Body> }
StrC prev_proc = Context.Scope->Prev->ProcName; StrC prev_proc = Context.Scope->Prev->ProcName;
if ( str_compare( prev_proc.Ptr, "parse_typedef", prev_proc.Len ) != 0 ) if ( str_compare_len( prev_proc.Ptr, "parse_typedef", prev_proc.Len ) != 0 )
{ {
if ( check( Tok_Statement_End )) if ( check( Tok_Statement_End ))
{ {
@ -2975,7 +2975,7 @@ Code parse_simple_preprocess( TokType which )
} }
else else
{ {
if ( str_compare( Context.Scope->Prev->ProcName.Ptr, "parse_typedef", Context.Scope->Prev->ProcName.Len ) != 0 ) if ( str_compare_len( Context.Scope->Prev->ProcName.Ptr, "parse_typedef", Context.Scope->Prev->ProcName.Len ) != 0 )
{ {
if ( check( Tok_Statement_End )) if ( check( Tok_Statement_End ))
{ {
@ -2994,7 +2994,7 @@ Code parse_simple_preprocess( TokType which )
char const* content = str_fmt_buf( "%.*s ", tok.Length, tok.Text ); char const* content = str_fmt_buf( "%.*s ", tok.Length, tok.Text );
Code result = untyped_str( GEN_NS to_str(content) ); Code result = untyped_str( to_strc_from_c_str(content) );
Context.Scope->Name = tok; Context.Scope->Name = tok;
pop(& Context); pop(& Context);
@ -3494,7 +3494,7 @@ CodeDestructor parse_destructor( CodeSpecifiers specifiers )
append(specifiers, Spec_Pure ); append(specifiers, Spec_Pure );
} }
else if ( left && str_compare( upcoming.Text, "default", sizeof("default") - 1 ) == 0) else if ( left && str_compare_len( upcoming.Text, "default", sizeof("default") - 1 ) == 0)
{ {
body = parse_assignment_expression(); body = parse_assignment_expression();
// <Virtual Specifier> ~< // <Virtual Specifier> ~<
@ -3609,7 +3609,7 @@ CodeEnum parse_enum( bool inplace_def )
// We'll support the enum_underlying macro // We'll support the enum_underlying macro
StrC sig = txt("enum_underlying"); StrC sig = txt("enum_underlying");
if (currtok.Length >= sig.Len && str_compare(currtok.Text, sig.Ptr, sig.Len) == 0 ) if (currtok.Length >= sig.Len && str_compare_len(currtok.Text, sig.Ptr, sig.Len) == 0 )
{ {
use_macro_underlying = true; use_macro_underlying = true;
underlying_macro = parse_simple_preprocess( Tok_Preprocess_Macro); underlying_macro = parse_simple_preprocess( Tok_Preprocess_Macro);
@ -3859,8 +3859,47 @@ CodeFriend parse_friend()
eat( Tok_Decl_Friend ); eat( Tok_Decl_Friend );
// friend // friend
CodeFn function = { nullptr }; CodeFn function = { nullptr };
CodeOperator op = { nullptr }; CodeOperator op = { nullptr };
CodeSpecifiers specifiers = { nullptr };
// Specifiers Parsing
{
Specifier specs_found[ 16 ] { Spec_NumSpecifiers };
s32 NumSpecifiers = 0;
while ( left && is_specifier(currtok) )
{
Specifier spec = to_specifier( to_str(currtok) );
switch ( spec )
{
case Spec_Const :
case Spec_Inline :
case Spec_ForceInline :
break;
default :
log_failure( "Invalid specifier %s for friend definition\n%s", to_str( spec ), to_string(Context) );
pop(& Context);
return InvalidCode;
}
// Ignore const it will be handled by the type
if ( spec == Spec_Const )
break;
specs_found[ NumSpecifiers ] = spec;
NumSpecifiers++;
eat( currtok.Type );
}
if ( NumSpecifiers )
{
specifiers = def_specifiers( NumSpecifiers, specs_found );
}
// <friend> <specifiers>
}
// Type declaration or return type // Type declaration or return type
CodeTypename type = parse_type(); CodeTypename type = parse_type();
@ -3879,7 +3918,7 @@ CodeFriend parse_friend()
Context.Scope->Name = name; Context.Scope->Name = name;
// friend <ReturnType> <Name> // friend <ReturnType> <Name>
function = parse_function_after_name( ModuleFlag_None, NullCode, NullCode, type, name ); function = parse_function_after_name( ModuleFlag_None, NullCode, specifiers, type, name );
// Parameter list // Parameter list
// CodeParam params = parse_params(); // CodeParam params = parse_params();
@ -3897,7 +3936,7 @@ CodeFriend parse_friend()
// Operator declaration or definition // Operator declaration or definition
if ( currtok.Type == Tok_Decl_Operator ) if ( currtok.Type == Tok_Decl_Operator )
{ {
op = parse_operator_after_ret_type( ModuleFlag_None, NullCode, NullCode, type ); op = parse_operator_after_ret_type( ModuleFlag_None, NullCode, specifiers, type );
} }
CodeComment inline_cmt = NullCode; CodeComment inline_cmt = NullCode;
@ -4375,7 +4414,7 @@ CodeTemplate parse_template()
bool found_operator_cast_outside_class_implmentation = false; bool found_operator_cast_outside_class_implmentation = false;
s32 idx = Context.Tokens.Idx; s32 idx = Context.Tokens.Idx;
for ( ; idx < num(Context.Tokens.Arr); idx++ ) for ( ; idx < array_num(Context.Tokens.Arr); idx++ )
{ {
Token tok = Context.Tokens.Arr[ idx ]; Token tok = Context.Tokens.Arr[ idx ];
@ -4829,7 +4868,7 @@ else if ( currtok.Type == Tok_DeclType )
} }
#endif #endif
result->Name = get_cached_string( to_strc(name_stripped) ); result->Name = get_cached_string( string_to_strc(name_stripped) );
if ( attributes ) if ( attributes )
result->Attributes = attributes; result->Attributes = attributes;
@ -4924,7 +4963,7 @@ CodeTypedef parse_typedef()
s32 idx = tokens.Idx; s32 idx = tokens.Idx;
s32 level = 0; s32 level = 0;
for ( ; idx < num(tokens.Arr); idx ++ ) for ( ; idx < array_num(tokens.Arr); idx ++ )
{ {
if ( tokens.Arr[idx].Type == Tok_BraceCurly_Open ) if ( tokens.Arr[idx].Type == Tok_BraceCurly_Open )
level++; level++;

View File

@ -82,7 +82,7 @@ global CodeTypename t_wchar_t;
global CodeTypename t_class; global CodeTypename t_class;
global CodeTypename t_typename; global CodeTypename t_typename;
global Array< StringCached > PreprocessorDefines; global Array(StringCached) PreprocessorDefines;
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS #ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
global CodeTypename t_b32; global CodeTypename t_b32;

View File

@ -31,23 +31,23 @@ 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 array_append (Array(Type)* array, Array(Type) other);
template<class Type> bool append (Array(Type)* array, Type value); template<class Type> bool array_append (Array(Type)* array, Type value);
template<class Type> bool append (Array(Type)* array, Type* items, usize item_num); template<class Type> bool array_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 array_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 array_append_at (Array(Type)* array, Type* items, usize item_num, usize idx);
template<class Type> Type* back (Array(Type) array); template<class Type> Type* array_back (Array(Type) array);
template<class Type> void clear (Array(Type) array); template<class Type> void array_clear (Array(Type) array);
template<class Type> bool fill (Array(Type) array, usize begin, usize end, Type value); template<class Type> bool array_fill (Array(Type) array, usize begin, usize end, Type value);
template<class Type> void free (Array(Type)* array); template<class Type> void array_free (Array(Type)* array);
template<class Type> bool grow (Array(Type)* array, usize min_capacity); template<class Type> bool arary_grow (Array(Type)* array, usize min_capacity);
template<class Type> usize num (Array(Type) array); template<class Type> usize array_num (Array(Type) array);
template<class Type> void pop (Array(Type) array); template<class Type> void arary_pop (Array(Type) array);
template<class Type> void remove_at (Array(Type) array, usize idx); template<class Type> void arary_remove_at (Array(Type) array, usize idx);
template<class Type> bool reserve (Array(Type)* array, usize new_capacity); template<class Type> bool arary_reserve (Array(Type)* array, usize new_capacity);
template<class Type> bool resize (Array(Type)* array, usize num); template<class Type> bool arary_resize (Array(Type)* array, usize num);
template<class Type> bool set_capacity (Array(Type)* array, usize new_capacity); template<class Type> bool arary_set_capacity(Array(Type)* array, usize new_capacity);
template<class Type> ArrayHeader* get_header (Array(Type) array); template<class Type> ArrayHeader* arary_get_header (Array(Type) array);
struct ArrayHeader { struct ArrayHeader {
AllocatorInfo Allocator; AllocatorInfo Allocator;
@ -66,23 +66,23 @@ 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 array_append<Type>(this, other); }
forceinline bool append(Type value) { return GEN_NS append<Type>(this, value); } forceinline bool append(Type value) { return GEN_NS array_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 array_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 array_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 array_append_at<Type>(this, items, item_num, idx); }
forceinline Type* back() { return GEN_NS back<Type>(* this); } forceinline Type* back() { return GEN_NS array_back<Type>(* this); }
forceinline void clear() { GEN_NS clear<Type>(* this); } forceinline void clear() { GEN_NS array_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 array_fill<Type>(* this, begin, end, value); }
forceinline void free() { GEN_NS free<Type>(this); } forceinline void free() { GEN_NS array_free<Type>(this); }
forceinline ArrayHeader* get_header() { return GEN_NS get_header<Type>(* this); } forceinline ArrayHeader* get_header() { return GEN_NS array_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 array_grow<Type>(this, min_capacity); }
forceinline usize num() { return GEN_NS num<Type>(*this); } forceinline usize num() { return GEN_NS array_num<Type>(*this); }
forceinline void pop() { GEN_NS pop<Type>(* this); } forceinline void pop() { GEN_NS array_pop<Type>(* this); }
forceinline void remove_at(usize idx) { GEN_NS remove_at<Type>(* this, idx); } forceinline void remove_at(usize idx) { GEN_NS array_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 array_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 array_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 array_set_capacity<Type>(this, new_capacity); }
#pragma endregion Member Mapping #pragma endregion Member Mapping
forceinline operator Type*() { return Data; } forceinline operator Type*() { return Data; }
@ -108,14 +108,14 @@ template<class Type> bool resize(Array<Type>& array, usize num)
template<class Type> bool set_capacity(Array<Type>& array, usize new_capacity) { return GEN_NS set_capacity( & array, new_capacity); } template<class Type> bool set_capacity(Array<Type>& array, usize new_capacity) { return GEN_NS set_capacity( & array, new_capacity); }
template<class Type> forceinline Type* begin(Array<Type>& array) { return array; } template<class Type> forceinline Type* begin(Array<Type>& array) { return array; }
template<class Type> forceinline Type* end(Array<Type>& array) { return array + get_header(array)->Num; } template<class Type> forceinline Type* end(Array<Type>& array) { return array + array_get_header(array)->Num; }
template<class Type> forceinline Type* next(Array<Type>& array, Type* entry) { return entry + 1; } 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 #endif
template<class Type> forceinline Type* array_begin(Array<Type> array) { return array; }
template<class Type> forceinline Type* array_end(Array<Type> array) { return array + array_get_header(array)->Num; }
template<class Type> forceinline Type* array_next(Array<Type> array, Type* entry) { return ++ entry; }
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));
@ -141,20 +141,20 @@ usize array_grow_formula(ssize value) {
} }
template<class Type> inline template<class Type> inline
bool append(Array<Type>* array, Array<Type> other) { bool array_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 array_append(Array<Type>* array, Type value)
{ {
ArrayHeader* header = get_header(* array); ArrayHeader* header = array_get_header(* array);
if (header->Num == header->Capacity) if (header->Num == header->Capacity)
{ {
if ( ! grow(array, header->Capacity)) if ( ! array_grow(array, header->Capacity))
return false; return false;
header = get_header(* array); header = array_get_header(* array);
} }
(*array)[ header->Num] = value; (*array)[ header->Num] = value;
@ -164,15 +164,15 @@ bool append(Array<Type>* array, Type value)
} }
template<class Type> inline template<class Type> inline
bool append(Array<Type>* array, Type* items, usize item_num) bool array_append(Array<Type>* array, Type* items, usize item_num)
{ {
ArrayHeader* header = get_header(array); ArrayHeader* header = array_get_header(array);
if (header->Num + item_num > header->Capacity) if (header->Num + 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 = array_get_header(array);
} }
mem_copy((Type*)array + header->Num, items, item_num * sizeof(Type)); mem_copy((Type*)array + header->Num, items, item_num * sizeof(Type));
@ -182,9 +182,9 @@ 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 array_append_at(Array<Type>* array, Type item, usize idx)
{ {
ArrayHeader* header = get_header(* array); ArrayHeader* header = array_get_header(* array);
ssize slot = idx; ssize slot = idx;
if (slot >= header->Num) if (slot >= header->Num)
@ -195,10 +195,10 @@ bool append_at(Array<Type>* array, Type item, usize idx)
if (header->Capacity < header->Num + 1) if (header->Capacity < header->Num + 1)
{ {
if ( ! grow(array, header->Capacity + 1)) if ( ! array_grow(array, header->Capacity + 1))
return false; return false;
header = get_header(* array); header = array_get_header(* array);
} }
Type* target = &(*array)[slot]; Type* target = &(*array)[slot];
@ -206,13 +206,13 @@ bool append_at(Array<Type>* array, Type item, usize idx)
mem_move(target + 1, target, (header->Num - slot) * sizeof(Type)); mem_move(target + 1, target, (header->Num - slot) * sizeof(Type));
header->Num++; header->Num++;
header = get_header(* array); header = array_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 array_append_at(Array<Type>* array, Type* items, usize item_num, usize idx)
{ {
ArrayHeader* header = get_header(array); ArrayHeader* header = get_header(array);
@ -240,11 +240,11 @@ 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* array_back(Array<Type>* array)
{ {
GEN_ASSERT(array != nullptr); GEN_ASSERT(array != nullptr);
ArrayHeader* header = get_header(* array); ArrayHeader* header = array_get_header(* array);
if (header->Num <= 0) if (header->Num <= 0)
return nullptr; return nullptr;
@ -252,15 +252,15 @@ Type* back(Array<Type>* array)
} }
template<class Type> inline template<class Type> inline
void clear(Array<Type> array) { void array_clear(Array<Type> array) {
ArrayHeader* header = get_header(array); ArrayHeader* header = array_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 array_fill(Array<Type> array, usize begin, usize end, Type value)
{ {
ArrayHeader* header = get_header(array); ArrayHeader* header = array_get_header(array);
if (begin < 0 || end > header->Num) if (begin < 0 || end > header->Num)
return false; return false;
@ -274,49 +274,49 @@ 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 array_free(Array<Type>* array) {
GEN_ASSERT(array != nullptr); GEN_ASSERT(array != nullptr);
ArrayHeader* header = get_header(* array); ArrayHeader* header = array_get_header(* array);
GEN_NS free(header->Allocator, header); allocator_free(header->Allocator, header);
Type** Data = (Type**)array; Type** Data = (Type**)array;
*Data = nullptr; *Data = nullptr;
} }
template<class Type> forceinline template<class Type> forceinline
ArrayHeader* get_header(Array<Type> array) { ArrayHeader* array_get_header(Array<Type> array) {
Type* Data = array; Type* Data = array;
using NonConstType = TRemoveConst<Type>; using NonConstType = TRemoveConst<Type>;
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 array_grow(Array<Type>* array, usize min_capacity)
{ {
ArrayHeader* header = get_header(* array); ArrayHeader* header = array_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;
return set_capacity(array, new_capacity); return array_set_capacity(array, new_capacity);
} }
template<class Type> inline template<class Type> inline
usize num(Array<Type> array) { usize array_num(Array<Type> array) {
return get_header(array)->Num; return array_get_header(array)->Num;
} }
template<class Type> inline template<class Type> inline
void pop(Array<Type> array) { void array_pop(Array<Type> array) {
ArrayHeader* header = get_header(array); ArrayHeader* header = array_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 array_remove_at(Array<Type> array, usize idx)
{ {
ArrayHeader* header = get_header(array); ArrayHeader* header = array_get_header(array);
GEN_ASSERT(idx < header->Num); GEN_ASSERT(idx < header->Num);
mem_move(array + idx, array + idx + 1, sizeof(Type) * (header->Num - idx - 1)); mem_move(array + idx, array + idx + 1, sizeof(Type) * (header->Num - idx - 1));
@ -324,9 +324,9 @@ 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 array_reserve(Array<Type>* array, usize new_capacity)
{ {
ArrayHeader* header = get_header(array); ArrayHeader* header = array_get_header(array);
if (header->Capacity < new_capacity) if (header->Capacity < new_capacity)
return set_capacity(array, new_capacity); return set_capacity(array, new_capacity);
@ -335,14 +335,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 array_resize(Array<Type>* array, usize num)
{ {
ArrayHeader* header = get_header(* array); ArrayHeader* header = array_get_header(* array);
if (header->Capacity < num) { if (header->Capacity < num) {
if (! grow( array, num)) if (! array_grow( array, num))
return false; return false;
header = get_header(* array); header = array_get_header(* array);
} }
header->Num = num; header->Num = num;
@ -350,9 +350,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 array_set_capacity(Array<Type>* array, usize new_capacity)
{ {
ArrayHeader* header = get_header(* array); ArrayHeader* header = array_get_header(* array);
if (new_capacity == header->Capacity) if (new_capacity == header->Capacity)
return true; return true;
@ -373,13 +373,15 @@ bool set_capacity(Array<Type>* array, usize new_capacity)
new_header->Capacity = new_capacity; new_header->Capacity = new_capacity;
GEN_NS free(header->Allocator, header); allocator_free(header->Allocator, header);
Type** Data = (Type**)array; Type** Data = (Type**)array;
* Data = rcast(Type*, new_header + 1); * Data = rcast(Type*, new_header + 1);
return true; return true;
} }
#define array_init_reserve(type, allocator, cap) array_init_reserve<type>(allocator, cap)
#pragma endregion Array #pragma endregion Array
// TODO(Ed) : This thing needs ALOT of work. // TODO(Ed) : This thing needs ALOT of work.
@ -471,9 +473,9 @@ HashTable<Type> hashtable_init_reserve(AllocatorInfo allocator, usize num)
HashTable<Type> result = { { nullptr }, { nullptr } }; HashTable<Type> result = { { nullptr }, { nullptr } };
result.Hashes = array_init_reserve<ssize>(allocator, num); result.Hashes = array_init_reserve<ssize>(allocator, num);
get_header(result.Hashes)->Num = num; array_get_header(result.Hashes)->Num = num;
resize(& result.Hashes, num); array_resize(& result.Hashes, num);
fill<ssize>(result.Hashes, 0, num, -1); array_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);
return result; return result;
@ -481,15 +483,15 @@ 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); array_clear(table.Entries);
fill<ssize>(table.Hashes, 0, num(table.Hashes), -1); array_fill(table.Hashes, 0, array_num(table.Hashes), (ssize)-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 && array_get_header(table->Hashes)->Capacity) {
free(& table->Hashes); array_free(& table->Hashes);
free(& table->Entries); array_free(& table->Entries);
} }
} }
@ -522,7 +524,7 @@ void map_mut(HashTable<Type> table, void (*map_proc)(u64 key, Type* 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( array_num(table->Entries));
rehash(table, new_num); rehash(table, new_num);
} }
@ -530,9 +532,9 @@ 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>( array_get_header(table->Hashes)->Allocator, new_num);
for (ssize idx = 0; idx < ssize(num(table->Entries)); ++idx) for (ssize idx = 0; idx < ssize( array_num(table->Entries)); ++idx)
{ {
HashTableFindResult find_result; HashTableFindResult find_result;
HashTableEntry<Type>& entry = table->Entries[idx]; HashTableEntry<Type>& entry = table->Entries[idx];
@ -639,8 +641,8 @@ 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 = array_num(table->Entries);
append( & table->Entries, entry); array_append( & table->Entries, entry);
return idx; return idx;
} }
@ -649,9 +651,9 @@ HashTableFindResult find(HashTable<Type> table, u64 key)
{ {
HashTableFindResult result = { -1, -1, -1 }; HashTableFindResult result = { -1, -1, -1 };
if (num(table.Hashes) > 0) if (array_num(table.Hashes) > 0)
{ {
result.HashIndex = key % num(table.Hashes); result.HashIndex = key % array_num(table.Hashes);
result.EntryIndex = table.Hashes[result.HashIndex]; result.EntryIndex = table.Hashes[result.HashIndex];
while (result.EntryIndex >= 0) while (result.EntryIndex >= 0)
@ -669,8 +671,8 @@ 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(array_num(table.Hashes)));
b32 result = num(table.Entries) > critical_load; b32 result = array_num(table.Entries) > critical_load;
return result; return result;
} }

View File

@ -56,8 +56,10 @@
while (0) while (0)
#endif #endif
GEN_API_C_BEGIN
void assert_handler( char const* condition, char const* file, s32 line, char const* msg, ... ); void assert_handler( char const* condition, char const* file, s32 line, char const* msg, ... );
s32 assert_crash( char const* condition ); s32 assert_crash( char const* condition );
void process_exit( u32 code ); void process_exit( u32 code );
GEN_API_C_END
#pragma endregion Debug #pragma endregion Debug

View File

@ -36,7 +36,7 @@ wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, ssize* w_len_ )
w_len1 = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, text, scast( int, len), w_text, scast( int, w_len) ); w_len1 = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, text, scast( int, len), w_text, scast( int, w_len) );
if ( w_len1 == 0 ) if ( w_len1 == 0 )
{ {
free( a, w_text ); allocator_free( a, w_text );
if ( w_len_ ) if ( w_len_ )
*w_len_ = 0; *w_len_ = 0;
return NULL; return NULL;
@ -145,7 +145,7 @@ GEN_FILE_OPEN_PROC( _win32_file_open )
w_text = _alloc_utf8_to_ucs2( heap(), filename, NULL ); w_text = _alloc_utf8_to_ucs2( heap(), filename, NULL );
handle = CreateFileW( w_text, desired_access, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, creation_disposition, FILE_ATTRIBUTE_NORMAL, NULL ); handle = CreateFileW( w_text, desired_access, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, creation_disposition, FILE_ATTRIBUTE_NORMAL, NULL );
free( heap(), w_text ); allocator_free( heap(), w_text );
if ( handle == INVALID_HANDLE_VALUE ) if ( handle == INVALID_HANDLE_VALUE )
{ {
@ -340,7 +340,7 @@ FileError file_close( FileInfo* f )
return EFileError_INVALID; return EFileError_INVALID;
if ( f->filename ) if ( f->filename )
free( heap(), ccast( char*, f->filename )); allocator_free( heap(), ccast( char*, f->filename ));
#if defined( GEN_SYSTEM_WINDOWS ) #if defined( GEN_SYSTEM_WINDOWS )
if ( f->fd.p == INVALID_HANDLE_VALUE ) if ( f->fd.p == INVALID_HANDLE_VALUE )
@ -540,7 +540,7 @@ b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, ssize
mem_copy( d->buf, buffer, size ); mem_copy( d->buf, buffer, size );
d->cap = size; d->cap = size;
get_header(arr)->Num = size; array_get_header(arr)->Num = size;
} }
else else
{ {
@ -610,9 +610,9 @@ GEN_FILE_WRITE_AT_PROC( _memory_file_write )
{ {
Array<u8> arr = { d->buf }; Array<u8> arr = { d->buf };
if ( get_header(arr)->Capacity < usize(new_cap) ) if ( array_get_header(arr)->Capacity < usize(new_cap) )
{ {
if ( ! grow( & arr, ( s64 )( new_cap ) ) ) if ( ! array_grow( & arr, ( s64 )( new_cap ) ) )
return false; return false;
d->buf = arr; d->buf = arr;
} }
@ -626,7 +626,7 @@ GEN_FILE_WRITE_AT_PROC( _memory_file_write )
mem_copy( d->buf + offset + rwlen, pointer_add_const( buffer, rwlen ), extralen ); mem_copy( d->buf + offset + rwlen, pointer_add_const( buffer, rwlen ), extralen );
d->cap = new_cap; d->cap = new_cap;
get_header(arr)->Capacity = new_cap; array_get_header(arr)->Capacity = new_cap;
} }
else else
{ {
@ -647,10 +647,10 @@ 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); array_free(& arr);
} }
free( allocator, d ); allocator_free( allocator, d );
} }
FileOperations const memory_file_operations = { _memory_file_read, _memory_file_write, _memory_file_seek, _memory_file_close }; FileOperations const memory_file_operations = { _memory_file_read, _memory_file_write, _memory_file_seek, _memory_file_close };

View File

@ -49,7 +49,7 @@ typedef struct FileOperations FileOperations;
#define GEN_FILE_OPEN_PROC( name ) FileError name( FileDescriptor* fd, FileOperations* ops, FileMode mode, char const* filename ) #define GEN_FILE_OPEN_PROC( name ) FileError name( FileDescriptor* fd, FileOperations* ops, FileMode mode, char const* filename )
#define GEN_FILE_READ_AT_PROC( name ) b32 name( FileDescriptor fd, void* buffer, ssize size, s64 offset, ssize* bytes_read, b32 stop_at_newline ) #define GEN_FILE_READ_AT_PROC( name ) b32 name( FileDescriptor fd, void* buffer, ssize size, s64 offset, ssize* bytes_read, b32 stop_at_newline )
#define GEN_FILE_WRITE_AT_PROC( name ) b32 name( FileDescriptor fd, void const* buffer, ssize size, s64 offset, ssize* bytes_written ) #define GEN_FILE_WRITE_AT_PROC( name ) b32 name( FileDescriptor fd, mem_ptr_const buffer, ssize size, s64 offset, ssize* bytes_written )
#define GEN_FILE_SEEK_PROC( name ) b32 name( FileDescriptor fd, s64 offset, SeekWhenceType whence, s64* new_offset ) #define GEN_FILE_SEEK_PROC( name ) b32 name( FileDescriptor fd, s64 offset, SeekWhenceType whence, s64* new_offset )
#define GEN_FILE_CLOSE_PROC( name ) void name( FileDescriptor fd ) #define GEN_FILE_CLOSE_PROC( name ) void name( FileDescriptor fd )

View File

@ -5,7 +5,11 @@
#pragma region Hashing #pragma region Hashing
GEN_API_C_BEGIN
u32 crc32( void const* data, ssize len ); u32 crc32( void const* data, ssize len );
u64 crc64( void const* data, ssize len ); u64 crc64( void const* data, ssize len );
GEN_API_C_END
#pragma endregion Hashing #pragma endregion Hashing

View File

@ -14,17 +14,12 @@
#define local_persist static // Local Persisting variables #define local_persist static // Local Persisting variables
#endif #endif
#ifndef api_c
#define api_c extern "C"
#endif
#ifndef bit #ifndef bit
#define bit( Value ) ( 1 << Value ) #define bit( Value ) ( 1 << Value )
#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_COMPILER_CPP
#if ! GEN_C_COMPILER
# ifndef cast # ifndef cast
# define cast( type, value ) (tmpl_cast<type>( value )) # define cast( type, value ) (tmpl_cast<type>( value ))
# endif # endif
@ -198,7 +193,7 @@
# define GEN_SUPPORT_CPP_MEMBER_FEATURES 0 # 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)
# if ! GEN_COMPILER_C # if ! GEN_COMPILER_C
# define typeof decltype # define typeof decltype
# elif defined(_MSC_VER) # elif defined(_MSC_VER)
@ -210,9 +205,15 @@
# endif # endif
#endif #endif
// This is intended to only really be used internally or with the C-library variant #ifndef GEN_API_C_BEGIN
// C++ users can just use the for-range directly. # if GEN_COMPILER_C || (GEN_COMPILER_CPP && GEN_SUPPORT_CPP_REFERENCES)
#define foreach(Type, entry_id, iterable) for ( Type entry_id = begin(iterable); entry_id != end(iterable); entry_id = next(iterable, entry_id) ) # define GEN_API_C_BEGIN
# define GEN_API_C_END
# else
# define GEN_API_C_BEGIN extern "C" {
# define GEN_API_C_END }
# endif
#endif
#if GEN_COMPILER_C #if GEN_COMPILER_C
# if __STDC_VERSION__ >= 202311L # if __STDC_VERSION__ >= 202311L
@ -230,7 +231,7 @@
# endif # endif
#endif #endif
#if ! defined(GEN_PARAM_DEFAULT) && ! GEN_COMPILER_C #if ! defined(GEN_PARAM_DEFAULT) && GEN_COMPILER_CPP
# define GEN_PARAM_DEFAULT = {} # define GEN_PARAM_DEFAULT = {}
#else #else
# define GEN_PARAM_DEFAULT # define GEN_PARAM_DEFAULT

View File

@ -5,6 +5,8 @@
#pragma region Memory #pragma region Memory
GEN_API_C_BEGIN
void* mem_copy( void* dest, void const* source, ssize n ) void* mem_copy( void* dest, void const* source, ssize n )
{ {
if ( dest == NULL ) if ( dest == NULL )
@ -346,7 +348,7 @@ void* arena_allocator_proc( void* allocator_data, AllocType type, ssize size, ss
case EAllocation_ALLOC : case EAllocation_ALLOC :
{ {
void* end = pointer_add( arena->PhysicalStart, arena->TotalUsed ); void* end = pointer_add( arena->PhysicalStart, arena->TotalUsed );
ssize total_size = align_forward_i64( size, alignment ); ssize total_size = align_forward_s64( size, alignment );
// NOTE: Out of memory // NOTE: Out of memory
if ( arena->TotalUsed + total_size > (ssize) arena->TotalSize ) if ( arena->TotalUsed + total_size > (ssize) arena->TotalSize )
@ -495,16 +497,16 @@ Pool pool_init_align( AllocatorInfo backing, ssize num_blocks, ssize block_size,
return pool; return pool;
} }
void clear(Pool& pool) void pool_clear(Pool* pool)
{ {
ssize actual_block_size, block_index; ssize actual_block_size, block_index;
void* curr; void* curr;
uptr* end; uptr* end;
actual_block_size = pool.BlockSize + pool.BlockAlign; actual_block_size = pool->BlockSize + pool->BlockAlign;
curr = pool.PhysicalStart; curr = pool->PhysicalStart;
for ( block_index = 0; block_index < pool.NumBlocks - 1; block_index++ ) for ( block_index = 0; block_index < pool->NumBlocks - 1; block_index++ )
{ {
uptr* next = ( uptr* ) curr; uptr* next = ( uptr* ) curr;
*next = ( uptr ) curr + actual_block_size; *next = ( uptr ) curr + actual_block_size;
@ -514,7 +516,9 @@ void clear(Pool& pool)
end = ( uptr* ) curr; end = ( uptr* ) curr;
*end = ( uptr ) NULL; *end = ( uptr ) NULL;
pool.FreeList = pool.PhysicalStart; pool->FreeList = pool->PhysicalStart;
} }
GEN_API_C_END
#pragma endregion Memory #pragma endregion Memory

View File

@ -22,6 +22,8 @@ void swap( Type& a, Type& b )
b = tmp; b = tmp;
} }
GEN_API_C_BEGIN
//! Checks if value is power of 2. //! Checks if value is power of 2.
b32 is_power_of_two( ssize x ); b32 is_power_of_two( ssize x );
@ -29,7 +31,7 @@ b32 is_power_of_two( ssize x );
void* align_forward( void* ptr, ssize alignment ); void* align_forward( void* ptr, ssize alignment );
//! Aligns value to a specified alignment. //! Aligns value to a specified alignment.
s64 align_forward_i64( s64 value, ssize alignment ); s64 align_forward_by_value( s64 value, ssize alignment );
//! Moves pointer forward by bytes. //! Moves pointer forward by bytes.
void* pointer_add( void* ptr, ssize bytes ); void* pointer_add( void* ptr, ssize bytes );
@ -100,7 +102,7 @@ void* alloc( AllocatorInfo a, ssize size );
void* alloc_align( AllocatorInfo a, ssize size, ssize alignment ); void* alloc_align( AllocatorInfo a, ssize size, ssize alignment );
//! Free allocated memory. //! Free allocated memory.
void free( AllocatorInfo a, void* ptr ); void allocator_free( AllocatorInfo a, void* ptr );
//! Free all memory allocated by an allocator. //! Free all memory allocated by an allocator.
void free_all( AllocatorInfo a ); void free_all( AllocatorInfo a );
@ -142,11 +144,12 @@ constexpr AllocatorInfo heap( void ) { AllocatorInfo allocator = { heap_allocato
//! Helper to free memory allocated by heap allocator. //! Helper to free memory allocated by heap allocator.
#define mfree( ptr ) free( heap(), ptr ) #define mfree( ptr ) free( heap(), ptr )
struct VirtualMemory struct VirtualMemory_Def
{ {
void* data; void* data;
ssize size; ssize size;
}; };
typedef struct VirtualMemory_Def VirtualMemory;
//! Initialize virtual memory from existing data. //! Initialize virtual memory from existing data.
VirtualMemory vm_from_memory( void* data, ssize size ); VirtualMemory vm_from_memory( void* data, ssize size );
@ -164,15 +167,16 @@ b32 vm_free( VirtualMemory vm );
VirtualMemory vm_trim( VirtualMemory vm, ssize lead_size, ssize size ); VirtualMemory vm_trim( VirtualMemory vm, ssize lead_size, ssize size );
//! Purge virtual memory. //! Purge virtual memory.
b32 gen_vm_purge( VirtualMemory vm ); b32 vm_purge( VirtualMemory vm );
//! Retrieve VM's page size and alignment. //! Retrieve VM's page size and alignment.
ssize gen_virtual_memory_page_size( ssize* alignment_out ); ssize virtual_memory_page_size( ssize* alignment_out );
#pragma region Arena #pragma region Arena
struct Arena; struct Arena_Def;
typedef struct Arena_Def Arena;
AllocatorInfo allocator_info( Arena* arena ); AllocatorInfo arena_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);
@ -181,18 +185,13 @@ void* arena_allocator_proc(void* allocator_data, AllocType type, ssize size, ssi
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); Arena arena_init_sub (Arena* parent, ssize size);
ssize alignment_of (Arena* arena, ssize alignment); ssize arena_alignment_of (Arena* arena, ssize alignment);
void free (Arena* arena); void arena_check (Arena* arena);
ssize size_remaining(Arena* arena, ssize alignment); void arena_free (Arena* arena);
ssize arena_size_remaining(Arena* arena, ssize alignment);
// This id is defined by Unreal for asserts struct Arena_Def
#pragma push_macro("check")
#undef check
void check(Arena* arena);
#pragma pop_macro("check")
struct Arena
{ {
AllocatorInfo Backing; AllocatorInfo Backing;
void* PhysicalStart; void* PhysicalStart;
@ -202,20 +201,20 @@ 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 arena_allocator_info(this); }
forceinline static void* allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ) { return GEN_NS arena_allocator_proc( allocator_data, type, size, alignment, old_memory, old_size, flags ); } forceinline static void* allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ) { return 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 arena_alignment_of(this, alignment); }
forceinline void free() { return GEN_NS free(this); } forceinline void free() { return GEN_NS arena_free(this); }
forceinline ssize size_remaining( ssize alignment ) { return GEN_NS size_remaining(this, alignment); } forceinline ssize size_remaining( ssize alignment ) { return GEN_NS arena_size_remaining(this, alignment); }
// This id is defined by Unreal for asserts // This id is defined by Unreal for asserts
#pragma push_macro("check") #pragma push_macro("check")
#undef check #undef check
forceinline void check() { GEN_NS check(this); } forceinline void check() { GEN_NS arena_check(this); }
#pragma pop_macro("check") #pragma pop_macro("check")
#pragma endregion Member Mapping #pragma endregion Member Mapping
@ -223,24 +222,27 @@ struct Arena
}; };
#if GEN_SUPPORT_CPP_REFERENCES #if GEN_SUPPORT_CPP_REFERENCES
forceinline AllocatorInfo allocator_info(Arena& arena ) { return allocator_info(& arena); } GEN_API_C_END
forceinline Arena init_sub (Arena& parent, ssize size) { return init_sub( & parent, size); } forceinline AllocatorInfo allocator_info(Arena& arena ) { return arena_allocator_info(& arena); }
forceinline ssize alignment_of (Arena& arena, ssize alignment) { return alignment_of( & arena, alignment); } forceinline Arena init_sub (Arena& parent, ssize size) { return arena_init_sub( & parent, size); }
forceinline void free (Arena& arena) { return free(& arena); } forceinline ssize alignment_of (Arena& arena, ssize alignment) { return arena_alignment_of( & arena, alignment); }
forceinline ssize size_remaining(Arena& arena, ssize alignment) { return size_remaining(& arena, alignment); } forceinline void free (Arena& arena) { return arena_free(& arena); }
forceinline ssize size_remaining(Arena& arena, ssize alignment) { return arena_size_remaining(& arena, 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(Arena& arena) { return check(& arena); }; forceinline void check(Arena& arena) { return arena_check(& arena); };
#pragma pop_macro("check") #pragma pop_macro("check")
GEN_API_C_BEGIN
#endif #endif
inline inline
AllocatorInfo allocator_info( Arena* arena ) { AllocatorInfo arena_allocator_info( Arena* arena ) {
GEN_ASSERT(arena != nullptr); GEN_ASSERT(arena != nullptr);
return { arena_allocator_proc, arena }; AllocatorInfo info = { arena_allocator_proc, arena };
return info;
} }
inline inline
@ -269,13 +271,13 @@ Arena arena_init_from_allocator(AllocatorInfo backing, ssize size) {
} }
inline inline
Arena init_sub(Arena* parent, ssize size) { Arena arena_init_sub(Arena* parent, ssize size) {
GEN_ASSERT(parent != nullptr); GEN_ASSERT(parent != nullptr);
return arena_init_from_allocator(parent->Backing, size); return arena_init_from_allocator(parent->Backing, size);
} }
inline inline
ssize alignment_of(Arena* arena, ssize alignment) ssize arena_alignment_of(Arena* arena, ssize alignment)
{ {
GEN_ASSERT(arena != nullptr); GEN_ASSERT(arena != nullptr);
ssize alignment_offset, result_pointer, mask; ssize alignment_offset, result_pointer, mask;
@ -291,36 +293,37 @@ ssize alignment_of(Arena* arena, ssize alignment)
return alignment_offset; return alignment_offset;
} }
#pragma push_macro("check")
#undef check
inline inline
void check(Arena* arena) void arena_check(Arena* arena)
{ {
GEN_ASSERT(arena != nullptr ); GEN_ASSERT(arena != nullptr );
GEN_ASSERT(arena->TempCount == 0); GEN_ASSERT(arena->TempCount == 0);
} }
#pragma pop_macro("check")
inline inline
void free(Arena* arena) void arena_free(Arena* arena)
{ {
GEN_ASSERT(arena != nullptr); GEN_ASSERT(arena != nullptr);
if (arena->Backing.Proc) if (arena->Backing.Proc)
{ {
GEN_NS free(arena->Backing, arena->PhysicalStart); allocator_free(arena->Backing, arena->PhysicalStart);
arena->PhysicalStart = nullptr; arena->PhysicalStart = nullptr;
} }
} }
inline inline
ssize size_remaining(Arena* arena, ssize alignment) ssize arena_size_remaining(Arena* arena, ssize alignment)
{ {
GEN_ASSERT(arena != nullptr); GEN_ASSERT(arena != nullptr);
ssize result = arena->TotalSize - (arena->TotalUsed + alignment_of(arena, alignment)); ssize result = arena->TotalSize - (arena->TotalUsed + arena_alignment_of(arena, alignment));
return result; return result;
} }
#pragma endregion Arena #pragma endregion Arena
GEN_API_C_END
#pragma region FixedArena #pragma region FixedArena
template<s32 Size> template<s32 Size>
struct FixedArena; struct FixedArena;
@ -383,24 +386,31 @@ using Arena_2MB = FixedArena< megabytes( 2 ) >;
using Arena_4MB = FixedArena< megabytes( 4 ) >; using Arena_4MB = FixedArena< megabytes( 4 ) >;
#pragma endregion FixedArena #pragma endregion FixedArena
GEN_API_C_BEGIN
#pragma region Pool #pragma region Pool
struct Pool; struct Pool_Def;
typedef struct Pool_Def Pool;
void* pool_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags); void* pool_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags);
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); AllocatorInfo pool_allocator_info(Pool* pool);
void clear(Pool* pool); void pool_clear(Pool* pool);
void free(Pool* pool); void pool_free(Pool* pool);
#if GEN_SUPPORT_CPP_REFERENCES #if GEN_SUPPORT_CPP_REFERENCES
AllocatorInfo allocator_info(Pool& pool); GEN_API_C_END
void clear(Pool& pool); AllocatorInfo allocator_info(Pool& pool) { return pool_allocator_info(& pool); }
void free(Pool& pool); void clear(Pool& pool) { return pool_clear(& pool); }
void free(Pool& pool) { return pool_free(& pool); }
GEN_API_C_BEGIN
#endif #endif
struct Pool struct Pool_Def
{ {
AllocatorInfo Backing; AllocatorInfo Backing;
void* PhysicalStart; void* PhysicalStart;
@ -412,19 +422,19 @@ 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 pool_allocator_info(this); }
forceinline static void* allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags) { return GEN_NS pool_allocator_proc(allocator_data, type, size, alignment, old_memory, old_size, flags); } forceinline static void* allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags) { return 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 pool_clear( this); }
forceinline void free() { GEN_NS free( this); } forceinline void free() { GEN_NS pool_free( this); }
#pragma endregion #pragma endregion
#endif #endif
}; };
inline inline
AllocatorInfo allocator_info(Pool* pool) { AllocatorInfo pool_allocator_info(Pool* pool) {
return { pool_allocator_proc, pool }; return { pool_allocator_proc, pool };
} }
@ -434,9 +444,9 @@ Pool pool_init(AllocatorInfo backing, ssize num_blocks, ssize block_size) {
} }
inline inline
void free(Pool* pool) { void pool_free(Pool* pool) {
if(pool->Backing.Proc) { if(pool->Backing.Proc) {
GEN_NS free(pool->Backing, pool->PhysicalStart); allocator_free(pool->Backing, pool->PhysicalStart);
} }
} }
#pragma endregion Pool #pragma endregion Pool
@ -458,9 +468,9 @@ mem_ptr align_forward( void* ptr, ssize alignment )
return to_mem_ptr(forward); return to_mem_ptr(forward);
} }
inline s64 align_forward_i64( s64 value, ssize alignment ) { return value + ( alignment - value % alignment ) % alignment; } inline s64 align_forward_s64( s64 value, ssize alignment ) { return value + ( alignment - value % alignment ) % alignment; }
inline void* pointer_add ( void* ptr, ssize bytes ) { return rcast(void*, rcast( u8*, ptr) + bytes ); } inline void* pointer_add ( void* ptr, ssize bytes ) { return rcast(void*, rcast( u8*, ptr) + bytes ); }
inline void const* pointer_add_const( void const* ptr, ssize bytes ) { return rcast(void const*, rcast( u8 const*, ptr) + bytes ); } inline void const* pointer_add_const( void const* ptr, ssize bytes ) { return rcast(void const*, rcast( u8 const*, ptr) + bytes ); }
inline sptr pointer_diff( mem_ptr_const begin, mem_ptr_const end ) { inline sptr pointer_diff( mem_ptr_const begin, mem_ptr_const end ) {
@ -616,7 +626,7 @@ void* alloc( AllocatorInfo a, ssize size ) {
} }
inline inline
void free( AllocatorInfo a, void* ptr ) { void allocator_free( AllocatorInfo a, void* ptr ) {
if ( ptr != nullptr ) if ( ptr != nullptr )
a.Proc( a.Data, EAllocation_FREE, 0, 0, ptr, 0, GEN_DEFAULT_ALLOCATOR_FLAGS ); a.Proc( a.Data, EAllocation_FREE, 0, 0, ptr, 0, GEN_DEFAULT_ALLOCATOR_FLAGS );
} }
@ -644,7 +654,7 @@ void* default_resize_align( AllocatorInfo a, void* old_memory, ssize old_size, s
if ( new_size == 0 ) if ( new_size == 0 )
{ {
free( a, old_memory ); allocator_free( a, old_memory );
return nullptr; return nullptr;
} }
@ -662,7 +672,7 @@ void* default_resize_align( AllocatorInfo a, void* old_memory, ssize old_size, s
return nullptr; return nullptr;
mem_move( new_memory, old_memory, min( new_size, old_size ) ); mem_move( new_memory, old_memory, min( new_size, old_size ) );
free( a, old_memory ); allocator_free( a, old_memory );
return new_memory; return new_memory;
} }
} }
@ -672,4 +682,6 @@ void zero_size( void* ptr, ssize size ) {
mem_set( ptr, 0, size ); mem_set( ptr, 0, size );
} }
GEN_API_C_END
#pragma endregion Memory #pragma endregion Memory

View File

@ -36,12 +36,12 @@ u8 adt_destroy_branch( ADT_Node* node )
GEN_ASSERT_NOT_NULL( node ); GEN_ASSERT_NOT_NULL( node );
if ( ( node->type == EADT_TYPE_OBJECT || node->type == EADT_TYPE_ARRAY ) && node->nodes ) if ( ( node->type == EADT_TYPE_OBJECT || node->type == EADT_TYPE_ARRAY ) && node->nodes )
{ {
for ( ssize i = 0; i < scast(ssize, num(node->nodes)); ++i ) for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); ++i )
{ {
adt_destroy_branch( node->nodes + i ); adt_destroy_branch( node->nodes + i );
} }
free(& node->nodes); array_free(& node->nodes);
} }
return 0; return 0;
} }
@ -66,7 +66,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search )
return NULL; return NULL;
} }
for ( ssize i = 0; i < scast(ssize, num(node->nodes)); i++ ) for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ )
{ {
if ( ! str_compare( node->nodes[ i ].name, name ) ) if ( ! str_compare( node->nodes[ i ].name, name ) )
{ {
@ -76,7 +76,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search )
if ( deep_search ) if ( deep_search )
{ {
for ( ssize i = 0; i < scast(ssize, num(node->nodes)); i++ ) for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ )
{ {
ADT_Node* res = adt_find( node->nodes + i, name, deep_search ); ADT_Node* res = adt_find( node->nodes + i, name, deep_search );
@ -132,7 +132,7 @@ internal ADT_Node* _adt_get_value( ADT_Node* node, char const* value )
internal ADT_Node* _adt_get_field( ADT_Node* node, char* name, char* value ) internal ADT_Node* _adt_get_field( ADT_Node* node, char* name, char* value )
{ {
for ( ssize i = 0; i < scast(ssize, num(node->nodes)); i++ ) for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ )
{ {
if ( ! str_compare( node->nodes[ i ].name, name ) ) if ( ! str_compare( node->nodes[ i ].name, name ) )
{ {
@ -207,7 +207,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri )
/* run a value comparison against any child that is an object node */ /* run a value comparison against any child that is an object node */
else if ( node->type == EADT_TYPE_ARRAY ) else if ( node->type == EADT_TYPE_ARRAY )
{ {
for ( ssize i = 0; i < scast(ssize, num(node->nodes)); i++ ) for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ )
{ {
ADT_Node* child = &node->nodes[ i ]; ADT_Node* child = &node->nodes[ i ];
if ( child->type != EADT_TYPE_OBJECT ) if ( child->type != EADT_TYPE_OBJECT )
@ -225,7 +225,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri )
/* [value] */ /* [value] */
else else
{ {
for ( ssize i = 0; i < scast(ssize, num(node->nodes)); i++ ) for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ )
{ {
ADT_Node* child = &node->nodes[ i ]; ADT_Node* child = &node->nodes[ i ];
if ( _adt_get_value( child, l_b2 ) ) if ( _adt_get_value( child, l_b2 ) )
@ -257,7 +257,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri )
else else
{ {
ssize idx = ( ssize )str_to_i64( buf, NULL, 10 ); ssize idx = ( ssize )str_to_i64( buf, NULL, 10 );
if ( idx >= 0 && idx < scast(ssize, num(node->nodes)) ) if ( idx >= 0 && idx < scast(ssize, array_num(node->nodes)) )
{ {
found_node = &node->nodes[ idx ]; found_node = &node->nodes[ idx ];
@ -282,12 +282,12 @@ ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index )
if ( ! parent->nodes ) if ( ! parent->nodes )
return NULL; return NULL;
if ( index < 0 || index > scast(ssize, num(parent->nodes)) ) if ( index < 0 || index > scast(ssize, array_num(parent->nodes)) )
return NULL; return NULL;
ADT_Node o = { 0 }; ADT_Node o = { 0 };
o.parent = parent; o.parent = parent;
if ( ! append_at( & parent->nodes, o, index ) ) if ( ! array_append_at( & parent->nodes, o, index ) )
return NULL; return NULL;
ADT_Node* node = & parent->nodes[index]; ADT_Node* node = & parent->nodes[index];
@ -304,7 +304,7 @@ ADT_Node* adt_alloc( ADT_Node* parent )
if ( ! parent->nodes ) if ( ! parent->nodes )
return NULL; return NULL;
return adt_alloc_at( parent, num(parent->nodes) ); return adt_alloc_at( parent, array_num(parent->nodes) );
} }
b8 adt_set_obj( ADT_Node* obj, char const* name, AllocatorInfo backing ) b8 adt_set_obj( ADT_Node* obj, char const* name, AllocatorInfo backing )
@ -358,7 +358,7 @@ ADT_Node* adt_move_node( ADT_Node* node, ADT_Node* new_parent )
GEN_ASSERT_NOT_NULL( node ); GEN_ASSERT_NOT_NULL( node );
GEN_ASSERT_NOT_NULL( new_parent ); GEN_ASSERT_NOT_NULL( new_parent );
GEN_ASSERT( new_parent->type == EADT_TYPE_ARRAY || new_parent->type == EADT_TYPE_OBJECT ); GEN_ASSERT( new_parent->type == EADT_TYPE_ARRAY || new_parent->type == EADT_TYPE_OBJECT );
return adt_move_node_at( node, new_parent, num(new_parent->nodes) ); return adt_move_node_at( node, new_parent, array_num(new_parent->nodes) );
} }
void adt_swap_nodes( ADT_Node* node, ADT_Node* other_node ) void adt_swap_nodes( ADT_Node* node, ADT_Node* other_node )
@ -382,7 +382,7 @@ void adt_remove_node( ADT_Node* node )
GEN_ASSERT_NOT_NULL( node->parent ); GEN_ASSERT_NOT_NULL( node->parent );
ADT_Node* parent = node->parent; ADT_Node* parent = node->parent;
ssize index = ( pointer_diff( parent->nodes, node ) / size_of( ADT_Node ) ); ssize index = ( pointer_diff( parent->nodes, node ) / size_of( ADT_Node ) );
remove_at( parent->nodes, index ); array_remove_at( parent->nodes, index );
} }
ADT_Node* adt_append_obj( ADT_Node* parent, char const* name ) ADT_Node* adt_append_obj( ADT_Node* parent, char const* name )
@ -390,7 +390,7 @@ ADT_Node* adt_append_obj( 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_obj( o, name, get_header(parent->nodes)->Allocator ) ) if ( adt_set_obj( o, name, array_get_header(parent->nodes)->Allocator ) )
{ {
adt_remove_node( o ); adt_remove_node( o );
return NULL; return NULL;
@ -404,7 +404,7 @@ ADT_Node* adt_append_arr( ADT_Node* parent, char const* name )
if ( ! o ) if ( ! o )
return NULL; return NULL;
ArrayHeader* node_header = get_header(parent->nodes); ArrayHeader* node_header = array_get_header(parent->nodes);
if ( adt_set_arr( o, name, node_header->Allocator ) ) if ( adt_set_arr( o, name, node_header->Allocator ) )
{ {
adt_remove_node( o ); adt_remove_node( o );
@ -510,7 +510,7 @@ char* adt_parse_number( ADT_Node* node, char* base_str )
} }
else else
{ {
if ( ! str_compare( e, "0x", 2 ) || ! str_compare( e, "0X", 2 ) ) if ( ! str_compare_len( e, "0x", 2 ) || ! str_compare_len( e, "0X", 2 ) )
{ {
node_props = EADT_PROPS_IS_HEX; node_props = EADT_PROPS_IS_HEX;
} }
@ -949,12 +949,12 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
} }
} }
if ( columnIndex >= scast(ssize, num(root->nodes)) ) if ( columnIndex >= scast(ssize, array_num(root->nodes)) )
{ {
adt_append_arr( root, NULL ); adt_append_arr( root, NULL );
} }
append( & root->nodes[ columnIndex ].nodes, rowItem ); array_append( & root->nodes[ columnIndex ].nodes, rowItem );
if ( delimiter == delim ) if ( delimiter == delim )
{ {
@ -982,7 +982,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
} }
while ( *currentChar ); while ( *currentChar );
if (num( root->nodes) == 0 ) if (array_num( root->nodes) == 0 )
{ {
GEN_CSV_ASSERT( "unexpected end of input. stream is empty." ); GEN_CSV_ASSERT( "unexpected end of input. stream is empty." );
error = ECSV_Error__UNEXPECTED_END_OF_INPUT; error = ECSV_Error__UNEXPECTED_END_OF_INPUT;
@ -992,12 +992,12 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
/* consider first row as a header. */ /* consider first row as a header. */
if ( has_header ) if ( has_header )
{ {
for ( ssize i = 0; i < scast(ssize, num(root->nodes)); i++ ) for ( ssize i = 0; i < scast(ssize, array_num(root->nodes)); i++ )
{ {
CSV_Object* col = root->nodes + i; CSV_Object* col = root->nodes + i;
CSV_Object* hdr = col->nodes; CSV_Object* hdr = col->nodes;
col->name = hdr->string; col->name = hdr->string;
remove_at(col->nodes, 0 ); array_remove_at(col->nodes, 0 );
} }
} }
@ -1060,11 +1060,11 @@ void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delimiter )
GEN_ASSERT_NOT_NULL( file ); GEN_ASSERT_NOT_NULL( file );
GEN_ASSERT_NOT_NULL( obj ); GEN_ASSERT_NOT_NULL( obj );
GEN_ASSERT( obj->nodes ); GEN_ASSERT( obj->nodes );
ssize cols = num(obj->nodes); ssize cols = array_num(obj->nodes);
if ( cols == 0 ) if ( cols == 0 )
return; return;
ssize rows = num(obj->nodes[ 0 ].nodes); ssize rows = array_num(obj->nodes[ 0 ].nodes);
if ( rows == 0 ) if ( rows == 0 )
return; return;

View File

@ -106,12 +106,24 @@
# define GEN_GCC_VERSION_CHECK(major,minor,patch) (0) # define GEN_GCC_VERSION_CHECK(major,minor,patch) (0)
#endif #endif
#ifndef GEN_COMPILER_C #if !defined(GEN_COMPILER_C)
# if defined(__STDC_VERSION__) # ifdef __cplusplus
# define GEN_COMPILER_C 1 # define GEN_COMPILER_C 0
# define GEN_COMPILER_CPP 1
# else # else
# define GEN_COMPILER_C 0 # if defined(__STDC__)
# endif # define GEN_COMPILER_C 1
# define GEN_COMPILER_CPP 0
# else
// Fallback for very old C compilers
# define GEN_COMPILER_C 1
# define GEN_COMPILER_CPP 0
# endif
# endif
#endif
#if GEN_COMPILER_C
#pragma message("Detected C")
#endif #endif
#pragma endregion Platform Detection #pragma endregion Platform Detection
@ -136,8 +148,6 @@
# define GEN_NS_PARSER_BEGIN # define GEN_NS_PARSER_BEGIN
# define GEN_NS_PARSER_END # define GEN_NS_PARSER_END
# define GEN_USING_NS_PARSER # define GEN_USING_NS_PARSER
# define GEN_NS_ENUM_BEGIN
# define GEN_NS_ENUM_END
# define GEN_NS # define GEN_NS
# define GEN_NS_BEGIN # define GEN_NS_BEGIN
# define GEN_NS_END # define GEN_NS_END
@ -145,8 +155,6 @@
# define GEN_NS_PARSER_BEGIN namespace parser { # define GEN_NS_PARSER_BEGIN namespace parser {
# define GEN_NS_PARSER_END } # define GEN_NS_PARSER_END }
# define GEN_USING_NS_PARSER using namespace parser # define GEN_USING_NS_PARSER using namespace parser
# define GEN_NS_ENUM_BEGIN namespace gen_internal_enums {
# define GEN_NS_ENUM_END }
# define GEN_NS :: # define GEN_NS ::
# define GEN_NS_BEGIN # define GEN_NS_BEGIN
# define GEN_NS_END # define GEN_NS_END
@ -155,8 +163,6 @@
# define GEN_NS_PARSER_BEGIN namespace parser { # define GEN_NS_PARSER_BEGIN namespace parser {
# define GEN_NS_PARSER_END } # define GEN_NS_PARSER_END }
# define GEN_USING_NS_PARSER using namespace parser # define GEN_USING_NS_PARSER using namespace parser
# define GEN_NS_ENUM_BEGIN namespace gen_internal_enums {
# define GEN_NS_ENUM_END }
# define GEN_NS gen:: # define GEN_NS gen::
# define GEN_NS_BEGIN namespace gen { # define GEN_NS_BEGIN namespace gen {
# define GEN_NS_END } # define GEN_NS_END }

View File

@ -431,7 +431,7 @@ neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_lis
String gen_str = String { va_arg( va, char*) }; String gen_str = String { va_arg( va, char*) };
info.precision = length(gen_str); info.precision = string_length(gen_str);
len = _print_string( text, remaining, &info, gen_str ); len = _print_string( text, remaining, &info, gen_str );
} }
break; break;

View File

@ -5,6 +5,8 @@
#pragma region Printing #pragma region Printing
GEN_API_C_BEGIN
struct FileInfo; struct FileInfo;
#ifndef GEN_PRINTF_MAXLEN #ifndef GEN_PRINTF_MAXLEN
@ -38,4 +40,6 @@ ssize log_fmt(char const* fmt, ...)
return res; return res;
} }
GEN_API_C_END
#pragma endregion Printing #pragma endregion Printing

View File

@ -19,7 +19,7 @@ ssize _scan_zpl_i64( const char* text, s32 base, s64* value )
text++; text++;
} }
if ( base == 16 && str_compare( text, "0x", 2 ) == 0 ) if ( base == 16 && str_compare_len( text, "0x", 2 ) == 0 )
text += 2; text += 2;
for ( ;; ) for ( ;; )
@ -61,7 +61,7 @@ s64 str_to_i64( const char* str, char** end_ptr, s32 base )
if ( ! base ) if ( ! base )
{ {
if ( ( str_len( str ) > 2 ) && ( str_compare( str, "0x", 2 ) == 0 ) ) if ( ( str_len( str ) > 2 ) && ( str_compare_len( str, "0x", 2 ) == 0 ) )
base = 16; base = 16;
else else
base = 10; base = 10;

View File

@ -5,6 +5,8 @@
#pragma region String Ops #pragma region String Ops
GEN_API_C_BEGIN
const char* char_first_occurence( const char* str, char c ); const char* char_first_occurence( const char* str, char c );
b32 char_is_alpha( char c ); b32 char_is_alpha( char c );
@ -19,11 +21,11 @@ s32 digit_to_int( char c );
s32 hex_digit_to_int( char c ); s32 hex_digit_to_int( char c );
s32 str_compare( const char* s1, const char* s2 ); s32 str_compare( const char* s1, const char* s2 );
s32 str_compare( const char* s1, const char* s2, ssize len ); s32 str_compare_len( const char* s1, const char* s2, ssize len );
char* str_copy( char* dest, const char* source, ssize len ); char* str_copy( char* dest, const char* source, ssize len );
ssize str_copy_nulpad( char* dest, const char* source, ssize len ); ssize str_copy_nulpad( char* dest, const char* source, ssize len );
ssize str_len( const char* str ); ssize str_len( const char* str );
ssize str_len( const char* str, ssize max_len ); ssize str_len_capped( const char* str, ssize max_len );
char* str_reverse( char* str ); // NOTE: ASCII only char* str_reverse( char* str ); // NOTE: ASCII only
char const* str_skip( char const* str, char c ); char const* str_skip( char const* str, char c );
char const* str_skip_any( char const* str, char const* char_list ); char const* str_skip_any( char const* str, char const* char_list );
@ -132,7 +134,7 @@ s32 str_compare( const char* s1, const char* s2 )
} }
inline inline
s32 str_compare( const char* s1, const char* s2, ssize len ) s32 str_compare_len( const char* s1, const char* s2, ssize len )
{ {
for ( ; len > 0; s1++, s2++, len-- ) for ( ; len > 0; s1++, s2++, len-- )
{ {
@ -204,7 +206,7 @@ ssize str_len( const char* str )
} }
inline inline
ssize str_len( const char* str, ssize max_len ) ssize str_len_capped( const char* str, ssize max_len )
{ {
const char* end = rcast(const char*, mem_find( str, 0, max_len )); const char* end = rcast(const char*, mem_find( str, 0, max_len ));
if ( end ) if ( end )
@ -240,7 +242,7 @@ char const* str_skip( char const* str, char c )
inline inline
char const* str_skip_any( char const* str, char const* char_list ) char const* str_skip_any( char const* str, char const* char_list )
{ {
char const* closest_ptr = rcast( char const*, pointer_add_const( rcast(void const*, str), str_len( str ) )); char const* closest_ptr = rcast( char const*, pointer_add_const( rcast(mem_ptr_const, str), str_len( str ) ));
ssize char_list_count = str_len( char_list ); ssize char_list_count = str_len( char_list );
for ( ssize i = 0; i < char_list_count; i++ ) for ( ssize i = 0; i < char_list_count; i++ )
{ {
@ -284,4 +286,6 @@ void str_to_upper( char* str )
} }
} }
GEN_API_C_END
#pragma endregion String Ops #pragma endregion String Ops

View File

@ -5,15 +5,19 @@
#pragma region Strings #pragma region Strings
GEN_API_C_BEGIN
struct StrC; struct StrC;
bool are_equal (StrC lhs, StrC rhs); bool strc_are_equal (StrC lhs, StrC rhs);
char const* back (StrC str); char const* strc_back (StrC str);
bool contains (StrC str, StrC substring); bool strc_contains (StrC str, StrC substring);
StrC duplicate (StrC str, AllocatorInfo allocator); StrC strc_duplicate (StrC str, AllocatorInfo allocator);
b32 starts_with (StrC str, StrC substring); b32 strc_starts_with (StrC str, StrC substring);
StrC to_str (char const* bad_string); StrC strc_to_str (char const* bad_string);
StrC visualize_whitespace(StrC str, AllocatorInfo allocator); StrC strc_visualize_whitespace(StrC str, AllocatorInfo allocator);
GEN_API_C_END
// Constant string with length. // Constant string with length.
struct StrC struct StrC
@ -21,17 +25,17 @@ struct StrC
ssize Len; ssize Len;
char const* Ptr; char const* Ptr;
#if ! GEN_COMPILER_C #if GEN_COMPILER_CPP
operator char const* () const { return Ptr; } forceinline operator char const* () const { return Ptr; }
char const& operator[]( ssize index ) const { return Ptr[index]; } forceinline char const& operator[]( ssize index ) const { return Ptr[index]; }
#if GEN_SUPPORT_CPP_MEMBER_FEATURES #if GEN_SUPPORT_CPP_MEMBER_FEATURES
bool is_equal (StrC rhs) const { return GEN_NS are_equal(* this, rhs); } forceinline bool is_equal (StrC rhs) const { return GEN_NS strc_are_equal(* this, rhs); }
char const* back () const { return GEN_NS back(* this); } forceinline char const* back () const { return GEN_NS strc_back(* this); }
bool contains (StrC substring) const { return GEN_NS contains(* this, substring); } forceinline bool contains (StrC substring) const { return GEN_NS strc_contains(* this, substring); }
StrC duplicate (AllocatorInfo allocator) const { return GEN_NS duplicate(* this, allocator); } forceinline StrC duplicate (AllocatorInfo allocator) const { return GEN_NS strc_duplicate(* this, allocator); }
b32 starts_with (StrC substring) const { return GEN_NS starts_with(* this, substring); } forceinline b32 starts_with (StrC substring) const { return GEN_NS strc_starts_with(* this, substring); }
StrC visualize_whitespace(AllocatorInfo allocator) const { return GEN_NS visualize_whitespace(* this, allocator); } forceinline StrC visualize_whitespace(AllocatorInfo allocator) const { return GEN_NS strc_visualize_whitespace(* this, allocator); }
#endif #endif
#endif #endif
}; };
@ -39,12 +43,22 @@ struct StrC
#define cast_to_strc( str ) * rcast( StrC*, (str) - sizeof(ssize) ) #define cast_to_strc( str ) * rcast( StrC*, (str) - sizeof(ssize) )
#define txt( text ) StrC { sizeof( text ) - 1, ( text ) } #define txt( text ) StrC { sizeof( text ) - 1, ( text ) }
inline char const* begin(StrC str) { return str.Ptr; } GEN_API_C_BEGIN
inline char const* end (StrC str) { return str.Ptr + str.Len; } forceinline char const* strc_begin(StrC str) { return str.Ptr; }
inline char const* next (StrC str, char const* iter) { return iter + 1; } forceinline char const* strc_end (StrC str) { return str.Ptr + str.Len; }
forceinline char const* strc_next (StrC str, char const* iter) { return iter + 1; }
GEN_API_C_END
#if GEN_COMPILER_CPP
forceinline char const* begin(StrC str) { return str.Ptr; }
forceinline char const* end (StrC str) { return str.Ptr + str.Len; }
forceinline char const* next (StrC str, char const* iter) { return iter + 1; }
#endif
GEN_API_C_BEGIN
inline inline
bool are_equal(StrC lhs, StrC rhs) bool strc_are_equal(StrC lhs, StrC rhs)
{ {
if (lhs.Len != rhs.Len) if (lhs.Len != rhs.Len)
return false; return false;
@ -57,12 +71,12 @@ bool are_equal(StrC lhs, StrC rhs)
} }
inline inline
char const* back(StrC str) { char const* strc_back(StrC str) {
return & str.Ptr[str.Len - 1]; return & str.Ptr[str.Len - 1];
} }
inline inline
bool contains(StrC str, StrC substring) bool strc_contains(StrC str, StrC substring)
{ {
if (substring.Len > str.Len) if (substring.Len > str.Len)
return false; return false;
@ -71,25 +85,26 @@ bool contains(StrC str, StrC substring)
ssize sub_len = substring.Len; ssize sub_len = substring.Len;
for (ssize idx = 0; idx <= main_len - sub_len; ++idx) for (ssize idx = 0; idx <= main_len - sub_len; ++idx)
{ {
if (str_compare(str.Ptr + idx, substring.Ptr, sub_len) == 0) if (str_compare_len(str.Ptr + idx, substring.Ptr, sub_len) == 0)
return true; return true;
} }
return false; return false;
} }
inline inline
b32 starts_with(StrC str, StrC substring) { b32 strc_starts_with(StrC str, StrC substring) {
if (substring.Len > str.Len) if (substring.Len > str.Len)
return false; return false;
b32 result = str_compare(str.Ptr, substring.Ptr, substring.Len) == 0; b32 result = str_compare_len(str.Ptr, substring.Ptr, substring.Len) == 0;
return result; return result;
} }
inline inline
StrC to_str( char const* bad_str ) { StrC to_strc_from_c_str( char const* bad_str ) {
return { str_len( bad_str ), bad_str }; return { str_len( bad_str ), bad_str };
} }
GEN_API_C_END
// Dynamic String // Dynamic String
// This is directly based off the ZPL string api. // This is directly based off the ZPL string api.
@ -104,42 +119,46 @@ typedef char* String;
struct String; struct String;
#endif #endif
usize string_grow_formula(usize value); GEN_API_C_BEGIN
String string_make (AllocatorInfo allocator, char const* str); forceinline usize string_grow_formula(usize value);
String string_make (AllocatorInfo allocator, StrC str);
String string_make_reserve (AllocatorInfo allocator, ssize capacity); String string_make_c_str (AllocatorInfo allocator, char const* str);
String string_make_length (AllocatorInfo allocator, char const* str, ssize length); String string_make_strc (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, ...);
bool are_equal (String const lhs, String const rhs); String string_fmt_buf (AllocatorInfo allocator, char const* fmt, ...);
bool are_equal (String const lhs, StrC rhs); String string_join (AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue);
bool make_space_for (String* str, char const* to_append, ssize add_len); bool string_are_equal (String const lhs, String const rhs);
bool append (String* str, char c); bool string_are_equal_strc (String const lhs, StrC rhs);
bool append (String* str, char const* str_to_append); bool string_make_space_for (String* str, char const* to_append, ssize add_len);
bool append (String* str, char const* str_to_append, ssize length); bool string_append_char (String* str, char c);
bool append (String* str, StrC str_to_append); bool string_append_c_str (String* str, char const* str_to_append);
bool append (String* str, String const other); bool string_append_c_str_len (String* str, char const* str_to_append, ssize length);
bool append_fmt (String* str, char const* fmt, ...); bool string_append_strc (String* str, StrC str_to_append);
ssize avail_space (String const str); bool string_append_string (String* str, String const other);
char* back (String str); bool string_append_fmt (String* str, char const* fmt, ...);
bool contains (String const str, StrC substring); ssize string_avail_space (String const str);
bool contains (String const str, String const substring); char* string_back (String str);
ssize capacity (String const str); bool string_contains_strc (String const str, StrC substring);
void clear (String str); bool string_contains_string (String const str, String const substring);
String duplicate (String const str, AllocatorInfo allocator); ssize string_capacity (String const str);
void free (String* str); void string_clear (String str);
StringHeader* get_header (String str); String string_duplicate (String const str, AllocatorInfo allocator);
ssize length (String const str); void string_free (String* str);
b32 starts_with (String const str, StrC substring); StringHeader* string_get_header (String str);
b32 starts_with (String const str, String substring); ssize string_length (String const str);
void skip_line (String str); b32 string_starts_with_strc (String const str, StrC substring);
void strip_space (String str); b32 string_starts_with_string (String const str, String substring);
StrC to_strc (String str); void string_skip_line (String str);
void trim (String str, char const* cut_set); void string_strip_space (String str);
void trim_space (String str); StrC string_to_strc (String str);
String visualize_whitespace(String const str); void string_trim (String str, char const* cut_set);
void string_trim_space (String str);
String string_visualize_whitespace(String const str);
GEN_API_C_END
struct StringHeader { struct StringHeader {
AllocatorInfo Allocator; AllocatorInfo Allocator;
@ -147,14 +166,14 @@ struct StringHeader {
ssize Length; ssize Length;
}; };
#if ! GEN_COMPILER_C && GEN_SUPPORT_CPP_MEMBER_FEATURES #if GEN_COMPILER_CPP && GEN_SUPPORT_CPP_MEMBER_FEATURES
struct String struct String
{ {
char* Data; char* Data;
forceinline operator char*() { return Data; } forceinline operator char*() { return Data; }
forceinline operator char const*() const { return Data; } forceinline operator char const*() const { return Data; }
forceinline operator StrC() const { return { GEN_NS length(* this), Data }; } forceinline operator StrC() const { return { string_length(* this), Data }; }
String const& operator=(String const& other) const { String const& operator=(String const& other) const {
if (this == &other) if (this == &other)
@ -169,29 +188,29 @@ struct String
forceinline char& operator[](ssize index) { return Data[index]; } forceinline char& operator[](ssize index) { return Data[index]; }
forceinline char const& operator[](ssize index) const { return Data[index]; } forceinline char const& operator[](ssize index) const { return Data[index]; }
bool operator==(std::nullptr_t) const { return Data == nullptr; } forceinline bool operator==(std::nullptr_t) const { return Data == nullptr; }
bool operator!=(std::nullptr_t) const { return Data != nullptr; } forceinline bool operator!=(std::nullptr_t) const { return Data != nullptr; }
friend bool operator==(std::nullptr_t, const String str) { return str.Data == nullptr; } friend forceinline bool operator==(std::nullptr_t, const String str) { return str.Data == nullptr; }
friend bool operator!=(std::nullptr_t, const String str) { return str.Data != nullptr; } friend forceinline bool operator!=(std::nullptr_t, const String str) { return str.Data != nullptr; }
forceinline char* begin() const { return Data; } forceinline char* begin() const { return Data; }
forceinline char* end() const { return Data + GEN_NS length(* this); } forceinline char* end() const { return Data + string_length(* this); }
#pragma region Member Mapping #pragma region Member Mapping
forceinline static String make(AllocatorInfo allocator, char const* str) { return GEN_NS string_make(allocator, str); } forceinline static String make(AllocatorInfo allocator, char const* str) { return string_make_c_str(allocator, str); }
forceinline static String make(AllocatorInfo allocator, StrC str) { return GEN_NS string_make(allocator, str); } forceinline static String make(AllocatorInfo allocator, StrC str) { return string_make_strc(allocator, str); }
forceinline static String make_reserve(AllocatorInfo allocator, ssize cap) { return GEN_NS string_make_reserve(allocator, cap); } forceinline static String make_reserve(AllocatorInfo allocator, ssize cap) { return string_make_reserve(allocator, cap); }
forceinline static String make_length(AllocatorInfo a, char const* s, ssize l) { return GEN_NS string_make_length(a, s, l); } forceinline static String make_length(AllocatorInfo a, char const* s, ssize l) { return string_make_length(a, s, l); }
forceinline static String join(AllocatorInfo a, char const** p, ssize n, char const* g) { return GEN_NS string_join(a, p, n, g); } forceinline static String join(AllocatorInfo a, char const** p, ssize n, char const* g) { return string_join(a, p, n, g); }
forceinline static usize grow_formula(usize value) { return GEN_NS string_grow_formula(value); } forceinline static usize grow_formula(usize value) { return string_grow_formula(value); }
static static
String fmt(AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...) { String fmt(AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...) {
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
str_fmt_va(buf, buf_size, fmt, va); ssize res = str_fmt_va(buf, buf_size, fmt, va);
va_end(va); va_end(va);
return GEN_NS string_make(allocator, buf); return string_make_length(allocator, buf, res);
} }
static static
@ -200,37 +219,37 @@ struct String
char buf[GEN_PRINTF_MAXLEN] = { 0 }; char buf[GEN_PRINTF_MAXLEN] = { 0 };
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va); ssize res = str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va);
va_end(va); va_end(va);
return GEN_NS string_make(allocator, buf); return string_make_length(allocator, buf, res);
} }
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 string_make_space_for(this, str, add_len); }
forceinline bool append(char c) { return GEN_NS append(this, c); } forceinline bool append(char c) { return string_append_char(this, c); }
forceinline bool append(char const* str) { return GEN_NS append(this, str); } forceinline bool append(char const* str) { return string_append_c_str(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 string_append_c_str_len(this, str, length); }
forceinline bool append(StrC str) { return GEN_NS append(this, str); } forceinline bool append(StrC str) { return string_append_strc(this, str); }
forceinline bool append(const String other) { return GEN_NS append(this, other); } forceinline bool append(const String other) { return string_append_string(this, other); }
forceinline ssize avail_space() const { return GEN_NS avail_space(* this); } forceinline ssize avail_space() const { return string_avail_space(* this); }
forceinline char* back() { return GEN_NS back(* this); } forceinline char* back() { return string_back(* this); }
forceinline bool contains(StrC substring) const { return GEN_NS contains(* this, substring); } forceinline bool contains(StrC substring) const { return string_contains_strc(* this, substring); }
forceinline bool contains(String const& substring) const { return GEN_NS contains(* this, substring); } forceinline bool contains(String const& substring) const { return string_contains_string(* this, substring); }
forceinline ssize capacity() const { return GEN_NS capacity(* this); } forceinline ssize capacity() const { return string_capacity(* this); }
forceinline void clear() { GEN_NS clear(* this); } forceinline void clear() { string_clear(* this); }
forceinline String duplicate(AllocatorInfo allocator) const { return GEN_NS duplicate(* this, allocator); } forceinline String duplicate(AllocatorInfo allocator) const { return string_duplicate(* this, allocator); }
forceinline void free() { GEN_NS free(this); } forceinline void free() { string_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 string_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 string_are_equal_strc(* this, other); }
forceinline ssize length() const { return GEN_NS length(* this); } forceinline ssize length() const { return string_length(* this); }
forceinline b32 starts_with(StrC substring) const { return GEN_NS starts_with(* this, substring); } forceinline b32 starts_with(StrC substring) const { return string_starts_with_strc(* this, substring); }
forceinline b32 starts_with(String substring) const { return GEN_NS starts_with(* this, substring); } forceinline b32 starts_with(String substring) const { return string_starts_with_string(* this, substring); }
forceinline void skip_line() { GEN_NS skip_line(* this); } forceinline void skip_line() { string_skip_line(* this); }
forceinline void strip_space() { GEN_NS strip_space(* this); } forceinline void strip_space() { string_strip_space(* this); }
forceinline StrC to_strc() { return { length(), Data}; } forceinline StrC to_strc() { return { string_length(*this), Data}; }
forceinline void trim(char const* cut_set) { GEN_NS trim(* this, cut_set); } forceinline void trim(char const* cut_set) { string_trim(* this, cut_set); }
forceinline void trim_space() { GEN_NS trim_space(* this); } forceinline void trim_space() { string_trim_space(* this); }
forceinline String visualize_whitespace() const { return GEN_NS visualize_whitespace(* this); } forceinline String visualize_whitespace() const { return string_visualize_whitespace(* this); }
forceinline StringHeader& get_header() { return * GEN_NS get_header(* this); } forceinline StringHeader& get_header() { return * string_get_header(* this); }
bool append_fmt(char const* fmt, ...) { bool append_fmt(char const* fmt, ...) {
ssize res; ssize res;
@ -241,43 +260,53 @@ 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 string_append_c_str_len(this, buf, res);
} }
#pragma endregion Member Mapping #pragma endregion Member Mapping
}; };
#endif #endif
inline char* begin(String str) { return ((char*) str); } GEN_API_C_BEGIN
inline char* end (String str) { return ((char*) str + length(str)); } forceinline char* string_begin(String str) { return ((char*) str); }
inline char* next (String str, char* iter) { return ((char*) iter + 1); } forceinline char* string_end (String str) { return ((char*) str + string_length(str)); }
forceinline char* string_next (String str, char const* iter) { return ((char*) iter + 1); }
GEN_API_C_END
#if GEN_SUPPORT_CPP_REFERENCES #if GEN_COMPILER_CPP && 0
inline bool make_space_for(String& str, char const* to_append, ssize add_len); forceinline char* begin(String str) { return ((char*) str); }
inline bool append(String& str, char c); forceinline char* end (String str) { return ((char*) str + string_length(str)); }
inline bool append(String& str, char const* str_to_append); forceinline char* next (String str, char* iter) { return ((char*) iter + 1); }
inline bool append(String& str, char const* str_to_append, ssize length);
inline bool append(String& str, StrC str_to_append);
inline bool append(String& str, const String other);
inline bool append_fmt(String& str, char const* fmt, ...);
inline char& back(String& str);
inline void clear(String& str);
inline void free(String& str);
#endif #endif
inline #if GEN_SUPPORT_CPP_REFERENCES
forceinline bool make_space_for(String& str, char const* to_append, ssize add_len);
forceinline bool append(String& str, char c);
forceinline bool append(String& str, char const* str_to_append);
forceinline bool append(String& str, char const* str_to_append, ssize length);
forceinline bool append(String& str, StrC str_to_append);
forceinline bool append(String& str, const String other);
forceinline bool append_fmt(String& str, char const* fmt, ...);
forceinline char& back(String& str);
forceinline void clear(String& str);
forceinline void free(String& str);
#endif
GEN_API_C_BEGIN
forceinline
usize string_grow_formula(usize value) { usize string_grow_formula(usize value) {
// Using a very aggressive growth formula to reduce time mem_copying with recursive calls to append in this library. // Using a very aggressive growth formula to reduce time mem_copying with recursive calls to append in this library.
return 4 * value + 8; return 4 * value + 8;
} }
inline forceinline
String string_make(AllocatorInfo allocator, char const* str) { String string_make_c_str(AllocatorInfo allocator, char const* str) {
ssize length = str ? str_len(str) : 0; ssize length = str ? str_len(str) : 0;
return string_make_length(allocator, str, length); return string_make_length(allocator, str, length);
} }
inline forceinline
String string_make(AllocatorInfo allocator, StrC str) { String string_make_strc(AllocatorInfo allocator, StrC str) {
return string_make_length(allocator, str.Ptr, str.Len); return string_make_length(allocator, str.Ptr, str.Len);
} }
@ -285,10 +314,10 @@ inline
String string_fmt(AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...) { String string_fmt(AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...) {
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
str_fmt_va(buf, buf_size, fmt, va); ssize res = str_fmt_va(buf, buf_size, fmt, va);
va_end(va); va_end(va);
return string_make(allocator, buf); return string_make_length(allocator, buf, res);
} }
inline inline
@ -299,52 +328,52 @@ String string_fmt_buf(AllocatorInfo allocator, char const* fmt, ...)
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va); ssize res = str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va);
va_end(va); va_end(va);
return string_make(allocator, buf); return string_make_length(allocator, buf, res);
} }
inline inline
String string_join(AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue) String string_join(AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue)
{ {
String result = string_make(allocator, ""); String result = string_make_c_str(allocator, "");
for (ssize idx = 0; idx < num_parts; ++idx) for (ssize idx = 0; idx < num_parts; ++idx)
{ {
append(& result, parts[idx]); string_append_c_str(& result, parts[idx]);
if (idx < num_parts - 1) if (idx < num_parts - 1)
append(& result, glue); string_append_c_str(& result, glue);
} }
return result; return result;
} }
inline forceinline
bool append(String* str, char c) { bool string_append_char(String* str, char c) {
GEN_ASSERT(str != nullptr); GEN_ASSERT(str != nullptr);
return append( str, (char const*)& c, (ssize)1); return string_append_c_str_len( str, (char const*)& c, (ssize)1);
}
forceinline
bool string_append_c_str(String* str, char const* str_to_append) {
GEN_ASSERT(str != nullptr);
return string_append_c_str_len(str, str_to_append, str_len(str_to_append));
} }
inline inline
bool append(String* str, char const* str_to_append) { bool string_append_c_str_len(String* str, char const* str_to_append, ssize append_length)
GEN_ASSERT(str != nullptr);
return append(str, str_to_append, str_len(str_to_append));
}
inline
bool append(String* str, char const* str_to_append, ssize append_length)
{ {
GEN_ASSERT(str != nullptr); GEN_ASSERT(str != nullptr);
if (sptr(str_to_append) > 0) if (sptr(str_to_append) > 0)
{ {
ssize curr_len = length(* str); ssize curr_len = string_length(* str);
if ( ! make_space_for(str, str_to_append, append_length)) if ( ! string_make_space_for(str, str_to_append, append_length))
return false; return false;
StringHeader* header = get_header(* str); StringHeader* header = string_get_header(* str);
char* Data = * str; char* Data = * str;
mem_copy( Data + curr_len, str_to_append, append_length); mem_copy( Data + curr_len, str_to_append, append_length);
@ -356,19 +385,19 @@ bool append(String* str, char const* str_to_append, ssize append_length)
return str_to_append != nullptr; return str_to_append != nullptr;
} }
inline forceinline
bool append(String* str, StrC str_to_append) { bool string_append_strc(String* str, StrC str_to_append) {
GEN_ASSERT(str != nullptr); GEN_ASSERT(str != nullptr);
return append(str, str_to_append.Ptr, str_to_append.Len); return string_append_c_str_len(str, str_to_append.Ptr, str_to_append.Len);
} }
inline forceinline
bool append(String* str, String const other) { bool string_append_string(String* str, String const other) {
GEN_ASSERT(str != nullptr); GEN_ASSERT(str != nullptr);
return append(str, (char const*)other, length(other)); return string_append_c_str_len(str, (char const*)other, string_length(other));
} }
bool append_fmt(String* str, char const* fmt, ...) { bool string_append_fmt(String* str, char const* fmt, ...) {
GEN_ASSERT(str != nullptr); GEN_ASSERT(str != nullptr);
ssize res; ssize res;
char buf[GEN_PRINTF_MAXLEN] = { 0 }; char buf[GEN_PRINTF_MAXLEN] = { 0 };
@ -378,16 +407,16 @@ bool append_fmt(String* str, char const* fmt, ...) {
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 append(str, (char const*)buf, res); return string_append_c_str_len(str, (char const*)buf, res);
} }
inline inline
bool are_equal(String const lhs, String const rhs) bool string_are_equal_string(String const lhs, String const rhs)
{ {
if (length(lhs) != length(rhs)) if (string_length(lhs) != string_length(rhs))
return false; return false;
for (ssize idx = 0; idx < length(lhs); ++idx) for (ssize idx = 0; idx < string_length(lhs); ++idx)
if (lhs[idx] != rhs[idx]) if (lhs[idx] != rhs[idx])
return false; return false;
@ -395,31 +424,31 @@ bool are_equal(String const lhs, String const rhs)
} }
inline inline
bool are_equal(String const lhs, StrC rhs) bool string_are_equal_strc(String const lhs, StrC rhs)
{ {
if (length(lhs) != (rhs.Len)) if (string_length(lhs) != (rhs.Len))
return false; return false;
for (ssize idx = 0; idx < length(lhs); ++idx) for (ssize idx = 0; idx < string_length(lhs); ++idx)
if (lhs[idx] != rhs.Ptr[idx]) if (lhs[idx] != rhs.Ptr[idx])
return false; return false;
return true; return true;
} }
inline forceinline
ssize avail_space(String const str) { ssize string_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 forceinline
char* back(String* str) { char* string_back(String str) {
return & (*str)[length(* str) - 1]; return & (str)[string_length(str) - 1];
} }
inline inline
bool contains(String const str, StrC substring) bool string_contains_StrC(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));
@ -431,7 +460,7 @@ bool contains(String const str, StrC substring)
for (ssize idx = 0; idx <= main_len - sub_len; ++idx) for (ssize idx = 0; idx <= main_len - sub_len; ++idx)
{ {
if (str_compare(str + idx, substring.Ptr, sub_len) == 0) if (str_compare_len(str + idx, substring.Ptr, sub_len) == 0)
return true; return true;
} }
@ -439,67 +468,67 @@ bool contains(String const str, StrC substring)
} }
inline inline
bool contains(String const str, String const substring) bool string_contains_string(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 (string_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 = string_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 + idx, substring, sub_len) == 0) if (str_compare_len(str + idx, substring, sub_len) == 0)
return true; return true;
} }
return false; return false;
} }
inline forceinline
ssize capacity(String const str) { ssize string_capacity(String const str) {
StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
return header->Capacity; return header->Capacity;
} }
inline forceinline
void clear(String str) { void string_clear(String str) {
get_header(str)->Length = 0; string_get_header(str)->Length = 0;
} }
inline forceinline
String duplicate(String const str, AllocatorInfo allocator) { String string_duplicate(String const str, AllocatorInfo allocator) {
return string_make_length(allocator, str, length(str)); return string_make_length(allocator, str, string_length(str));
} }
inline forceinline
void free(String* str) { void string_free(String* str) {
GEN_ASSERT(str != nullptr); GEN_ASSERT(str != nullptr);
if (! (* str)) if (! (* str))
return; return;
StringHeader* header = get_header(* str); StringHeader* header = string_get_header(* str);
GEN_NS free(header->Allocator, header); allocator_free(header->Allocator, header);
} }
inline forceinline
StringHeader* get_header(String str) { StringHeader* string_get_header(String str) {
return (StringHeader*)(scast(char*, str) - sizeof(StringHeader)); return (StringHeader*)(scast(char*, str) - sizeof(StringHeader));
} }
inline forceinline
ssize length(String const str) ssize string_length(String const str)
{ {
StringHeader const& header = *rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); StringHeader const& header = *rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
return header.Length; return header.Length;
} }
inline inline
bool make_space_for(String* str, char const* to_append, ssize add_len) bool string_make_space_for(String* str, char const* to_append, ssize add_len)
{ {
ssize available = avail_space(* str); ssize available = string_avail_space(* str);
if (available >= add_len) { if (available >= add_len) {
return true; return true;
@ -510,12 +539,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 = string_get_header(* str)->Allocator;
StringHeader* header = nullptr; StringHeader* header = nullptr;
new_len = string_grow_formula(length(* str) + add_len); new_len = string_grow_formula(string_length(* str) + add_len);
ptr = get_header(* str); ptr = string_get_header(* str);
old_size = size_of(StringHeader) + length(* str) + 1; old_size = size_of(StringHeader) + string_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);
@ -534,26 +563,26 @@ bool make_space_for(String* str, char const* to_append, ssize add_len)
} }
} }
inline forceinline
b32 starts_with(String const str, StrC substring) { b32 string_starts_with_strc(String const str, StrC substring) {
if (substring.Len > length(str)) if (substring.Len > string_length(str))
return false; return false;
b32 result = str_compare(str, substring.Ptr, substring.Len) == 0; b32 result = str_compare_len(str, substring.Ptr, substring.Len) == 0;
return result; return result;
} }
inline forceinline
b32 starts_with(String const str, String substring) { b32 string_starts_with_string(String const str, String substring) {
if (length(substring) > length(str)) if (string_length(substring) > string_length(str))
return false; return false;
b32 result = str_compare(str, substring, length(substring) - 1) == 0; b32 result = str_compare_len(str, substring, string_length(substring) - 1) == 0;
return result; return result;
} }
inline inline
void skip_line(String str) void string_skip_line(String str)
{ {
#define current (*scanner) #define current (*scanner)
char* scanner = str; char* scanner = str;
@ -569,7 +598,7 @@ void skip_line(String str)
mem_move((char*)str, scanner, new_length); mem_move((char*)str, scanner, new_length);
StringHeader* header = get_header(str); StringHeader* header = string_get_header(str);
header->Length = new_length; header->Length = new_length;
#undef current #undef current
} }
@ -593,12 +622,12 @@ 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; string_get_header(str)->Length = write_pos - str;
} }
inline forceinline
StrC to_strc(String str) { StrC string_to_strc(String str) {
return { length(str), (char const*)str }; return { string_length(str), (char const*)str };
} }
inline inline
@ -607,7 +636,7 @@ void trim(String str, char const* cut_set)
ssize len = 0; ssize len = 0;
char* start_pos = str; char* start_pos = str;
char* end_pos = scast(char*, str) + length(str) - 1; char* end_pos = scast(char*, str) + string_length(str) - 1;
while (start_pos <= end_pos && char_first_occurence(cut_set, *start_pos)) while (start_pos <= end_pos && char_first_occurence(cut_set, *start_pos))
start_pos++; start_pos++;
@ -622,10 +651,10 @@ void trim(String str, char const* cut_set)
str[len] = '\0'; str[len] = '\0';
get_header(str)->Length = len; string_get_header(str)->Length = len;
} }
inline forceinline
void trim_space(String str) { void trim_space(String str) {
trim(str, " \t\r\n\v\f"); trim(str, " \t\r\n\v\f");
} }
@ -634,30 +663,31 @@ 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, string_length(str) * 2); // Assume worst case for space requirements.
foreach (char*, c, str) switch ( * c ) for (char const* c = string_begin(str); c != string_end(str); c = string_next(str, c))
switch ( * c )
{ {
case ' ': case ' ':
append(& result, txt("·")); string_append_strc(& result, txt("·"));
break; break;
case '\t': case '\t':
append(& result, txt("")); string_append_strc(& result, txt(""));
break; break;
case '\n': case '\n':
append(& result, txt("")); string_append_strc(& result, txt(""));
break; break;
case '\r': case '\r':
append(& result, txt("")); string_append_strc(& result, txt(""));
break; break;
case '\v': case '\v':
append(& result, txt("")); string_append_strc(& result, txt(""));
break; break;
case '\f': case '\f':
append(& result, txt("")); string_append_strc(& result, txt(""));
break; break;
default: default:
append(& result, c); string_append_char(& result, * c);
break; break;
} }
@ -670,47 +700,50 @@ struct String_POD {
}; };
static_assert( sizeof( String_POD ) == sizeof( String ), "String is not a POD" ); static_assert( sizeof( String_POD ) == sizeof( String ), "String is not a POD" );
inline forceinline
StrC duplicate(StrC str, AllocatorInfo allocator) { StrC strc_duplicate(StrC str, AllocatorInfo allocator) {
String result = string_make_length(allocator, str.Ptr, str.Len); String result = string_make_length(allocator, str.Ptr, str.Len);
return { get_header(result)->Length, result }; return { string_get_header(result)->Length, result };
} }
inline inline
StrC visualize_whitespace(StrC str, AllocatorInfo allocator) StrC strc_visualize_whitespace(StrC str, AllocatorInfo allocator)
{ {
String result = string_make_reserve(allocator, str.Len * 2); // Assume worst case for space requirements. String result = string_make_reserve(allocator, str.Len * 2); // Assume worst case for space requirements.
foreach (char const*, c, str) switch ( * c ) for (char const* c = strc_begin(str); c != strc_end(str); c = strc_next(str, c))
switch ( * c )
{ {
case ' ': case ' ':
append(& result, txt("·")); string_append_strc(& result, txt("·"));
break; break;
case '\t': case '\t':
append(& result, txt("")); string_append_strc(& result, txt(""));
break; break;
case '\n': case '\n':
append(& result, txt("")); string_append_strc(& result, txt(""));
break; break;
case '\r': case '\r':
append(& result, txt("")); string_append_strc(& result, txt(""));
break; break;
case '\v': case '\v':
append(& result, txt("")); string_append_strc(& result, txt(""));
break; break;
case '\f': case '\f':
append(& result, txt("")); string_append_strc(& result, txt(""));
break; break;
default: default:
append(& result, c); string_append_char(& result, * c);
break; break;
} }
return to_strc(result); return string_to_strc(result);
} }
// Represents strings cached with the string table. // Represents strings cached with the string table.
// Should never be modified, if changed string is desired, cache_string( str ) another. // Should never be modified, if changed string is desired, cache_string( str ) another.
typedef StrC StringCached; typedef StrC StringCached;
GEN_API_C_END
// Implements basic string interning. Data structure is based off the ZPL Hashtable. // Implements basic string interning. Data structure is based off the ZPL Hashtable.
typedef HashTable<StringCached> StringTable; typedef HashTable<StringCached> StringTable;
#pragma endregion Strings #pragma endregion Strings

View File

@ -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( arena_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,19 +23,21 @@ 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 = array_begin(enum_strs); node != array_end(enum_strs); node = array_next(enum_strs, node) )
{ {
char const* code = node.string; char const* code = node->string;
append_fmt( & enum_entries, "CT_%s,\n", code ); string_append_fmt( & enum_entries, "CT_%s,\n", code );
append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", code, code ); string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", code, code );
} }
CodeEnum enum_code = parse_enum(gen::token_fmt_impl((3 + 1) / 2, "entries", to_strc(enum_entries), "enum CodeType_Def : u32 { <entries> CT_NumTypes };")); CodeEnum enum_code = parse_enum(gen::token_fmt_impl((3 + 1) / 2, "entries", string_to_strc(enum_entries),
"enum CodeType_Def : u32 { <entries> CT_NumTypes };"
));
#pragma push_macro("local_persist") #pragma push_macro("local_persist")
#undef local_persist #undef local_persist
CodeFn to_str = parse_function( token_fmt( "entries", to_strc(to_str_entries), stringize( CodeFn to_str = parse_function( token_fmt( "entries", string_to_strc(to_str_entries), stringize(
inline inline
StrC to_str( CodeType type ) StrC to_str( CodeType type )
{ {
@ -61,7 +63,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( arena_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 );
@ -72,16 +74,16 @@ CodeBody gen_eoperator( 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 (usize idx = 0; idx < num(enum_strs); idx++) for (usize idx = 0; idx < array_num(enum_strs); idx++)
{ {
char const* enum_str = enum_strs[idx].string; char const* enum_str = enum_strs[idx].string;
char const* entry_to_str = str_strs [idx].string; char const* entry_to_str = str_strs [idx].string;
append_fmt( & enum_entries, "Op_%s,\n", enum_str ); string_append_fmt( & enum_entries, "Op_%s,\n", enum_str );
append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
} }
CodeEnum enum_code = parse_enum(token_fmt("entries", to_strc(enum_entries), stringize( CodeEnum enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize(
enum Operator_Def : u32 enum Operator_Def : u32
{ {
<entries> <entries>
@ -91,7 +93,7 @@ CodeBody gen_eoperator( char const* path )
#pragma push_macro("local_persist") #pragma push_macro("local_persist")
#undef local_persist #undef local_persist
CodeFn to_str = parse_function(token_fmt("entries", to_strc(to_str_entries), stringize( CodeFn to_str = parse_function(token_fmt("entries", string_to_strc(to_str_entries), stringize(
inline inline
StrC to_str( Operator op ) StrC to_str( Operator op )
{ {
@ -117,7 +119,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( arena_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 );
@ -128,16 +130,16 @@ CodeBody gen_especifier( 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 (usize idx = 0; idx < num(enum_strs); idx++) for (usize idx = 0; idx < array_num(enum_strs); idx++)
{ {
char const* enum_str = enum_strs[idx].string; char const* enum_str = enum_strs[idx].string;
char const* entry_to_str = str_strs [idx].string; char const* entry_to_str = str_strs [idx].string;
append_fmt( & enum_entries, "Spec_%s,\n", enum_str ); string_append_fmt( & enum_entries, "Spec_%s,\n", enum_str );
append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
} }
CodeEnum enum_code = parse_enum(token_fmt("entries", to_strc(enum_entries), stringize( CodeEnum enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize(
enum Specifier_Def : u32 enum Specifier_Def : u32
{ {
<entries> <entries>
@ -145,7 +147,7 @@ CodeBody gen_especifier( char const* path )
}; };
))); )));
CodeFn is_trailing = parse_function(token_fmt("specifier", to_strc(to_str_entries), stringize( CodeFn is_trailing = parse_function(token_fmt("specifier", string_to_strc(to_str_entries), stringize(
inline inline
bool is_trailing( Specifier specifier ) bool is_trailing( Specifier specifier )
{ {
@ -163,7 +165,7 @@ CodeBody gen_especifier( char const* path )
#undef do_once_end #undef do_once_end
#undef forceinline #undef forceinline
#undef neverinline #undef neverinline
CodeFn to_str = parse_function(token_fmt("entries", to_strc(to_str_entries), stringize( CodeFn to_str = parse_function(token_fmt("entries", string_to_strc(to_str_entries), stringize(
inline inline
StrC to_str( Specifier type ) StrC to_str( Specifier type )
{ {
@ -176,7 +178,7 @@ CodeBody gen_especifier( char const* path )
} }
))); )));
CodeFn to_type = parse_function( token_fmt( "entries", to_strc(to_str_entries), stringize( CodeFn to_type = parse_function( token_fmt( "entries", string_to_strc(to_str_entries), stringize(
inline inline
Specifier to_specifier( StrC str ) Specifier to_specifier( StrC str )
{ {
@ -222,7 +224,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 = arena_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 );
@ -245,37 +247,37 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
String to_str_attributes = string_make_reserve( GlobalAllocator, kilobytes(4) ); String to_str_attributes = string_make_reserve( GlobalAllocator, kilobytes(4) );
String attribute_define_entries = string_make_reserve( GlobalAllocator, kilobytes(4) ); String attribute_define_entries = string_make_reserve( GlobalAllocator, kilobytes(4) );
for (usize idx = 0; idx < num(enum_strs); idx++) for (usize idx = 0; idx < array_num(enum_strs); idx++)
{ {
char const* enum_str = enum_strs[idx].string; char const* enum_str = enum_strs[idx].string;
char const* entry_to_str = enum_str_strs [idx].string; char const* entry_to_str = enum_str_strs [idx].string;
append_fmt( & enum_entries, "Tok_%s,\n", enum_str ); string_append_fmt( & enum_entries, "Tok_%s,\n", enum_str );
append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
} }
for ( usize idx = 0; idx < num(attribute_strs); idx++ ) for ( usize idx = 0; idx < array_num(attribute_strs); idx++ )
{ {
char const* attribute_str = attribute_strs[idx].string; char const* attribute_str = attribute_strs[idx].string;
char const* entry_to_str = attribute_str_strs [idx].string; char const* entry_to_str = attribute_str_strs [idx].string;
append_fmt( & attribute_entries, "Tok_Attribute_%s,\n", attribute_str ); string_append_fmt( & attribute_entries, "Tok_Attribute_%s,\n", attribute_str );
append_fmt( & to_str_attributes, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); string_append_fmt( & to_str_attributes, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
append_fmt( & attribute_define_entries, "Entry( Tok_Attribute_%s, \"%s\" )", attribute_str, entry_to_str ); string_append_fmt( & attribute_define_entries, "Entry( Tok_Attribute_%s, \"%s\" )", attribute_str, entry_to_str );
if ( idx < num(attribute_strs) - 1 ) if ( idx < array_num(attribute_strs) - 1 )
append( & attribute_define_entries, " \\\n"); string_append_strc( & attribute_define_entries, txt(" \\\n"));
else else
append( & attribute_define_entries, "\n"); string_append_strc( & attribute_define_entries, txt("\n"));
} }
#pragma push_macro("GEN_DEFINE_ATTRIBUTE_TOKENS") #pragma push_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
#undef GEN_DEFINE_ATTRIBUTE_TOKENS #undef GEN_DEFINE_ATTRIBUTE_TOKENS
CodeDefine attribute_entires_def = def_define( name(GEN_DEFINE_ATTRIBUTE_TOKENS), to_strc(attribute_define_entries) ); CodeDefine attribute_entires_def = def_define( name(GEN_DEFINE_ATTRIBUTE_TOKENS), string_to_strc(attribute_define_entries) );
#pragma pop_macro("GEN_DEFINE_ATTRIBUTE_TOKENS") #pragma pop_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
// We cannot parse this enum, it has Attribute names as enums // We cannot parse this enum, it has Attribute names as enums
CodeEnum enum_code = parse_enum(token_fmt("entries", to_str(enum_entries), "attribute_toks", to_str(attribute_entries), stringize( CodeEnum enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), "attribute_toks", string_to_strc(attribute_entries), stringize(
enum TokType_Def : u32 enum TokType_Def : u32
{ {
<entries> <entries>
@ -290,7 +292,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
#undef local_persist #undef local_persist
#undef do_once_start #undef do_once_start
#undef do_once_end #undef do_once_end
CodeFn to_str = parse_function(token_fmt("entries", to_strc(to_str_entries), "attribute_toks", to_strc(to_str_attributes), stringize( CodeFn to_str = parse_function(token_fmt("entries", string_to_strc(to_str_entries), "attribute_toks", string_to_strc(to_str_attributes), stringize(
inline inline
StrC to_str( TokType type ) StrC to_str( TokType type )
{ {
@ -304,7 +306,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
} }
))); )));
CodeFn to_type = parse_function( token_fmt( "entries", to_strc(to_str_entries), stringize( CodeFn to_type = parse_function( token_fmt( "entries", string_to_strc(to_str_entries), stringize(
inline inline
TokType to_toktype( StrC str ) TokType to_toktype( StrC str )
{ {

View File

@ -231,10 +231,12 @@ if ( $c_library )
$executable = join-path $path_build "gen_c_library_test.exe" $executable = join-path $path_build "gen_c_library_test.exe"
if ($vendor -eq "clang") { if ($vendor -eq "clang") {
$compiler_args += "-x" $compiler_args += '-x'
$compiler_args += "c" $compiler_args += 'c'
$compiler_args += '-std=c11'
} elseif ($vendor -eq "msvc") { } elseif ($vendor -eq "msvc") {
$compiler_args += "/TC" $compiler_args += "/TC" # Compile as C
$compiler_args += "/Zc:__cplusplus" # Fix __cplusplus macro
} }
build-simple $path_build $includes $compiler_args $linker_args $unit $executable build-simple $path_build $includes $compiler_args $linker_args $unit $executable