mirror of
https://github.com/Ed94/gencpp.git
synced 2024-12-22 07:44:45 -08:00
Compare commits
5 Commits
31a3609b28
...
ed0c0422ad
Author | SHA1 | Date | |
---|---|---|---|
ed0c0422ad | |||
e5acac1d18 | |||
c7b072266f | |||
a96d03eaed | |||
0b4ccac8f9 |
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -39,7 +39,8 @@
|
|||||||
"raylib.h": "c",
|
"raylib.h": "c",
|
||||||
"*.m": "cpp",
|
"*.m": "cpp",
|
||||||
"atomic": "cpp",
|
"atomic": "cpp",
|
||||||
"gen.h": "c"
|
"gen.h": "c",
|
||||||
|
"string_ops.hpp": "c"
|
||||||
},
|
},
|
||||||
"C_Cpp.intelliSenseEngineFallback": "disabled",
|
"C_Cpp.intelliSenseEngineFallback": "disabled",
|
||||||
"mesonbuild.configureOnOpen": true,
|
"mesonbuild.configureOnOpen": true,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||||
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
||||||
#define GEN_EXPOSE_BACKEND
|
#define GEN_EXPOSE_BACKEND
|
||||||
|
#define GEN_SUPPORT_CPP_MEMBER_FEATURES 1
|
||||||
#include "../project/gen.cpp"
|
#include "../project/gen.cpp"
|
||||||
|
|
||||||
#include "helpers/push_ignores.inline.hpp"
|
#include "helpers/push_ignores.inline.hpp"
|
||||||
@ -18,6 +19,8 @@ GEN_NS_END
|
|||||||
|
|
||||||
#include "components/memory.fixed_arena.hpp"
|
#include "components/memory.fixed_arena.hpp"
|
||||||
#include "components/misc.hpp"
|
#include "components/misc.hpp"
|
||||||
|
#include "components/containers.array.hpp"
|
||||||
|
#include "components/containers.hashtable.hpp"
|
||||||
|
|
||||||
using namespace gen;
|
using namespace gen;
|
||||||
|
|
||||||
@ -114,6 +117,14 @@ int gen_main()
|
|||||||
Code basic_types = scan_file( project_dir "dependencies/basic_types.hpp" );
|
Code basic_types = scan_file( project_dir "dependencies/basic_types.hpp" );
|
||||||
Code debug = scan_file( project_dir "dependencies/debug.hpp" );
|
Code debug = scan_file( project_dir "dependencies/debug.hpp" );
|
||||||
|
|
||||||
|
header.print_fmt( roll_own_dependencies_guard_start );
|
||||||
|
header.print( platform );
|
||||||
|
header.print_fmt( "\nGEN_NS_BEGIN\n" );
|
||||||
|
|
||||||
|
header.print( macros );
|
||||||
|
header.print( basic_types );
|
||||||
|
header.print( debug );
|
||||||
|
|
||||||
CodeBody parsed_memory = parse_file( project_dir "dependencies/memory.hpp" );
|
CodeBody parsed_memory = parse_file( project_dir "dependencies/memory.hpp" );
|
||||||
CodeBody memory = def_body(ECode::Struct_Body);
|
CodeBody memory = def_body(ECode::Struct_Body);
|
||||||
for ( Code entry = parsed_memory.begin(); entry != parsed_memory.end(); ++ entry )
|
for ( Code entry = parsed_memory.begin(); entry != parsed_memory.end(); ++ entry )
|
||||||
@ -164,7 +175,12 @@ int gen_main()
|
|||||||
break;
|
break;
|
||||||
case ECode::Preprocess_If:
|
case ECode::Preprocess_If:
|
||||||
{
|
{
|
||||||
ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_MEMBER_FEATURES"), entry, memory );
|
ignore_preprocess_cond_block(txt("GEN_SUPPORT_CPP_MEMBER_FEATURES"), entry, parsed_memory );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ECode::Preprocess_IfDef:
|
||||||
|
{
|
||||||
|
ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_memory );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ECode::Preprocess_Pragma:
|
case ECode::Preprocess_Pragma:
|
||||||
@ -179,14 +195,58 @@ int gen_main()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
header.print_fmt( roll_own_dependencies_guard_start );
|
|
||||||
header.print( platform );
|
|
||||||
header.print_fmt( "\nGEN_NS_BEGIN\n" );
|
|
||||||
|
|
||||||
header.print( macros );
|
|
||||||
header.print( basic_types );
|
|
||||||
header.print( debug );
|
|
||||||
header.print( memory );
|
header.print( memory );
|
||||||
|
|
||||||
|
Code string_ops = scan_file( project_dir "dependencies/string_ops.hpp" );
|
||||||
|
header.print( string_ops );
|
||||||
|
|
||||||
|
CodeBody printing_parsed = parse_file( project_dir "dependencies/printing.hpp" );
|
||||||
|
CodeBody printing = def_body(ECode::Struct_Body);
|
||||||
|
for ( Code entry = printing_parsed.begin(); entry != printing_parsed.end(); ++ entry )
|
||||||
|
{
|
||||||
|
switch (entry->Type)
|
||||||
|
{
|
||||||
|
case ECode::Preprocess_IfDef:
|
||||||
|
{
|
||||||
|
ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, printing_parsed );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry->Type == ECode::Variable &&
|
||||||
|
contains(entry->Name, txt("Msg_Invalid_Value")))
|
||||||
|
{
|
||||||
|
CodeDefine define = def_define(entry->Name, entry->Value->Content);
|
||||||
|
printing.append(define);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printing.append(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
header.print(printing);
|
||||||
|
|
||||||
|
CodeBody parsed_containers = parse_file( project_dir "dependencies/containers.hpp" );
|
||||||
|
CodeBody containers = def_body(ECode::Struct_Body);
|
||||||
|
for ( Code entry = parsed_containers.begin(); entry != parsed_containers.end(); ++ entry )
|
||||||
|
{
|
||||||
|
switch ( entry->Type )
|
||||||
|
{
|
||||||
|
case ECode::Preprocess_Pragma:
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
found = swap_pragma_region_implementation( txt("Array"), gen_array_base, entry, containers);
|
||||||
|
if (found) break;
|
||||||
|
|
||||||
|
found = swap_pragma_region_implementation( txt("Hashtable"), gen_hashtable_base, entry, containers);
|
||||||
|
if (found) break;
|
||||||
|
|
||||||
|
containers.append(entry);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
header.print(containers);
|
||||||
}
|
}
|
||||||
|
|
||||||
header.print( pop_ignores );
|
header.print( pop_ignores );
|
||||||
|
295
gen_c_library/components/containers.array.hpp
Normal file
295
gen_c_library/components/containers.array.hpp
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../project/gen.hpp"
|
||||||
|
|
||||||
|
using namespace gen;
|
||||||
|
|
||||||
|
CodeBody gen_array_base()
|
||||||
|
{
|
||||||
|
CodeTypedef td_header = parse_typedef( code( typedef struct ArrayHeader ArrayHeader; ));
|
||||||
|
CodeStruct header = parse_struct( code(
|
||||||
|
struct ArrayHeader
|
||||||
|
{
|
||||||
|
AllocatorInfo Allocator;
|
||||||
|
usize Capacity;
|
||||||
|
usize Num;
|
||||||
|
};
|
||||||
|
));
|
||||||
|
|
||||||
|
// Code grow_formula = untyped_str( txt( "#define gen_array_grow_formula( value ) ( 2 * value + 8 )\n" ));
|
||||||
|
Code get_header = untyped_str( txt( "#define array_get_header( Type, self ) ( (ArrayHeader*)( self ) - 1)\n" ));
|
||||||
|
|
||||||
|
return def_global_body( args( td_header, header, get_header ) );
|
||||||
|
};
|
||||||
|
|
||||||
|
CodeBody gen_array( StrC type, StrC array_name )
|
||||||
|
{
|
||||||
|
String array_type = String::fmt_buf( GlobalAllocator, "%.*s", array_name.Len, array_name.Ptr );
|
||||||
|
String fn = String::fmt_buf( GlobalAllocator, "%.*s", array_name.Len, array_name.Ptr );
|
||||||
|
str_to_lower(fn.Data);
|
||||||
|
|
||||||
|
#pragma push_macro( "GEN_ASSERT" )
|
||||||
|
#undef GEN_ASSERT
|
||||||
|
CodeBody result = parse_global_body( token_fmt( "array_type", (StrC)array_type, "fn", (StrC)fn, "type", (StrC)type
|
||||||
|
, stringize(
|
||||||
|
typedef <type>* <array_type>;
|
||||||
|
|
||||||
|
<array_type> <fn>_init ( AllocatorInfo allocator );
|
||||||
|
<array_type> <fn>_init_reserve ( AllocatorInfo allocator, usize capacity );
|
||||||
|
bool <fn>_append ( <array_type>* self, <type> value );
|
||||||
|
bool <fn>_append_items ( <array_type>* self, <type>* items, usize item_num );
|
||||||
|
bool <fn>_append_at ( <array_type>* self, <type> item, usize idx );
|
||||||
|
bool <fn>_append_items_at( <array_type>* self, <type>* items, usize item_num, usize idx );
|
||||||
|
<type>* <fn>_back ( <array_type> self );
|
||||||
|
void <fn>_clear ( <array_type> self );
|
||||||
|
bool <fn>_fill ( <array_type> self, usize begin, usize end, <type> value );
|
||||||
|
void <fn>_free ( <array_type> self );
|
||||||
|
bool <fn>_grow ( <array_type>* self, usize min_capacity );
|
||||||
|
usize <fn>_num ( <array_type> self );
|
||||||
|
<type> <fn>_pop ( <array_type> self );
|
||||||
|
bool <fn>_reserve ( <array_type>* self, usize new_capacity );
|
||||||
|
bool <fn>_resize ( <array_type>* self, usize num );
|
||||||
|
bool <fn>_set_capacity ( <array_type>* self, usize new_capacity );
|
||||||
|
|
||||||
|
<array_type> <fn>_init( AllocatorInfo allocator )
|
||||||
|
{
|
||||||
|
return <fn>_init_reserve( allocator, array_grow_formula( 0 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
<array_type> <fn>_init_reserve( AllocatorInfo allocator, usize capacity )
|
||||||
|
{
|
||||||
|
ArrayHeader* header = cast(ArrayHeader*, alloc( allocator, sizeof(ArrayHeader) + sizeof(<type>) * capacity ) );
|
||||||
|
|
||||||
|
if ( header == NULL )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
header->Allocator = allocator;
|
||||||
|
header->Capacity = capacity;
|
||||||
|
header->Num = 0;
|
||||||
|
|
||||||
|
return cast( <type>*, header + 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool <fn>_append( <array_type>* self, <type> value )
|
||||||
|
{
|
||||||
|
ArrayHeader* header = get_header( * self );
|
||||||
|
|
||||||
|
if ( header->Num == header->Capacity )
|
||||||
|
{
|
||||||
|
if ( ! <fn>_grow( self, header->Capacity))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
header = get_header( * self );
|
||||||
|
}
|
||||||
|
|
||||||
|
(* self)[ header->Num ] = value;
|
||||||
|
header->Num++;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool <fn>_append_items( <array_type>* self, <type>* items, usize item_num )
|
||||||
|
{
|
||||||
|
ArrayHeader* header = get_header( * self );
|
||||||
|
|
||||||
|
if ( header->Num + item_num > header->Capacity )
|
||||||
|
{
|
||||||
|
if ( ! <fn>_grow( self, header->Capacity + item_num ))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
header = get_header( * self );
|
||||||
|
}
|
||||||
|
|
||||||
|
mem_copy( (* self) + header->Num, items, sizeof(<type>) * item_num );
|
||||||
|
header->Num += item_num;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool <fn>_append_at( <array_type>* self, <type> item, usize idx )
|
||||||
|
{
|
||||||
|
ArrayHeader* header = get_header( * self );
|
||||||
|
|
||||||
|
if ( idx >= header->Num )
|
||||||
|
idx = header->Num - 1;
|
||||||
|
|
||||||
|
if ( idx < 0 )
|
||||||
|
idx = 0;
|
||||||
|
|
||||||
|
if ( header->Capacity < header->Num + 1 )
|
||||||
|
{
|
||||||
|
if ( ! <fn>_grow( self, header->Capacity + 1 ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
header = get_header( * self );
|
||||||
|
}
|
||||||
|
|
||||||
|
<array_type> target = (* self) + idx;
|
||||||
|
|
||||||
|
mem_move( target + 1, target, (header->Num - idx) * sizeof(<type>) );
|
||||||
|
header->Num++;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool <fn>_append_items_at( <array_type>* self, <type>* items, usize item_num, usize idx )
|
||||||
|
{
|
||||||
|
ArrayHeader* header = get_header( * self );
|
||||||
|
|
||||||
|
if ( idx >= header->Num )
|
||||||
|
{
|
||||||
|
return <fn>_append_items( self, items, item_num );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( item_num > header->Capacity )
|
||||||
|
{
|
||||||
|
if ( ! <fn>_grow( self, item_num + header->Capacity ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
header = get_header( * self );
|
||||||
|
}
|
||||||
|
|
||||||
|
<type>* target = (* self) + idx + item_num;
|
||||||
|
<type>* src = (* self) + idx;
|
||||||
|
|
||||||
|
mem_move( target, src, (header->Num - idx) * sizeof(<type>) );
|
||||||
|
mem_copy( src, items, item_num * sizeof(<type>) );
|
||||||
|
header->Num += item_num;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
<type>* <fn>_back( <array_type> self )
|
||||||
|
{
|
||||||
|
ArrayHeader* header = get_header( self );
|
||||||
|
|
||||||
|
if ( header->Num == 0 )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return self + header->Num - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void <fn>_clear( <array_type> self )
|
||||||
|
{
|
||||||
|
ArrayHeader* header = get_header( self );
|
||||||
|
header->Num = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool <fn>_fill( <array_type> self, usize begin, usize end, <type> value )
|
||||||
|
{
|
||||||
|
ArrayHeader* header = get_header( self );
|
||||||
|
|
||||||
|
if ( begin < 0 || end >= header->Num )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for ( ssize idx = begin; idx < end; idx ++ )
|
||||||
|
self[ idx ] = value;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void <fn>_free( <array_type> self )
|
||||||
|
{
|
||||||
|
ArrayHeader* header = get_header( self );
|
||||||
|
free( header->Allocator, header );
|
||||||
|
self = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool <fn>_grow( <array_type>* self, usize min_capacity )
|
||||||
|
{
|
||||||
|
ArrayHeader* header = get_header( *self );
|
||||||
|
usize new_capacity = array_grow_formula( header->Capacity );
|
||||||
|
|
||||||
|
if ( new_capacity < min_capacity )
|
||||||
|
new_capacity = min_capacity;
|
||||||
|
|
||||||
|
return <fn>_set_capacity( self, new_capacity );
|
||||||
|
}
|
||||||
|
|
||||||
|
usize <fn>_num( <array_type> self )
|
||||||
|
{
|
||||||
|
return get_header(self)->Num;
|
||||||
|
}
|
||||||
|
|
||||||
|
<type> <fn>_pop( <array_type> self )
|
||||||
|
{
|
||||||
|
ArrayHeader* header = get_header( self );
|
||||||
|
GEN_ASSERT( header->Num > 0 );
|
||||||
|
|
||||||
|
<type> result = self[ header->Num - 1 ];
|
||||||
|
header->Num--;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void <fn>_remove_at( <array_type> self, usize idx )
|
||||||
|
{
|
||||||
|
ArrayHeader* header = get_header( self );
|
||||||
|
GEN_ASSERT( idx < header->Num );
|
||||||
|
|
||||||
|
mem_move( self + idx, self + idx + 1, sizeof( <type> ) * ( header->Num - idx - 1 ) );
|
||||||
|
header->Num--;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool <fn>_reserve( <array_type>* self, usize new_capacity )
|
||||||
|
{
|
||||||
|
ArrayHeader* header = get_header( * self );
|
||||||
|
|
||||||
|
if ( header->Capacity < new_capacity )
|
||||||
|
return <fn>_set_capacity( self, new_capacity );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool <fn>_resize( <array_type>* self, usize num )
|
||||||
|
{
|
||||||
|
ArrayHeader* header = get_header( * self );
|
||||||
|
|
||||||
|
if ( header->Capacity < num )
|
||||||
|
{
|
||||||
|
if ( ! <fn>_grow( self, num ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
header = get_header( * self );
|
||||||
|
}
|
||||||
|
|
||||||
|
header->Num = num;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool <fn>_set_capacity( <array_type>* self, usize new_capacity )
|
||||||
|
{
|
||||||
|
ArrayHeader* header = get_header( * self );
|
||||||
|
|
||||||
|
if ( new_capacity == header->Capacity )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if ( new_capacity < header->Num )
|
||||||
|
header->Num = new_capacity;
|
||||||
|
|
||||||
|
usize size = sizeof( ArrayHeader ) + sizeof( <type> ) * new_capacity;
|
||||||
|
ArrayHeader* new_header = cast( ArrayHeader*, alloc( header->Allocator, size ));
|
||||||
|
|
||||||
|
if ( new_header == NULL )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
mem_move( new_header, header, sizeof( ArrayHeader ) + sizeof( <type> ) * header->Num );
|
||||||
|
free( header->Allocator, & header );
|
||||||
|
|
||||||
|
new_header->Capacity = new_capacity;
|
||||||
|
* self = cast( <type>*, new_header + 1 );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
)));
|
||||||
|
#pragma pop_macro( "GEN_ASSERT" )
|
||||||
|
|
||||||
|
return def_global_body( args(
|
||||||
|
def_pragma( to_str( str_fmt_buf( "region %S", array_type ))),
|
||||||
|
fmt_newline,
|
||||||
|
result,
|
||||||
|
fmt_newline,
|
||||||
|
def_pragma( to_str( str_fmt_buf( "endregion %S", array_type ))),
|
||||||
|
fmt_newline
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
|
// CodeBody gen_
|
354
gen_c_library/components/containers.hashtable.hpp
Normal file
354
gen_c_library/components/containers.hashtable.hpp
Normal file
@ -0,0 +1,354 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../project/gen.hpp"
|
||||||
|
#include "containers.array.hpp"
|
||||||
|
|
||||||
|
using namespace gen;
|
||||||
|
|
||||||
|
CodeBody gen_hashtable_base()
|
||||||
|
{
|
||||||
|
return parse_global_body( code(
|
||||||
|
typedef struct HT_FindResult HT_FindResult;
|
||||||
|
struct HT_FindResult
|
||||||
|
{
|
||||||
|
ssize HashIndex;
|
||||||
|
ssize PrevIndex;
|
||||||
|
ssize EntryIndex;
|
||||||
|
};
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
CodeBody gen_hashtable( StrC type, StrC hashtable_name )
|
||||||
|
{
|
||||||
|
String
|
||||||
|
fn = String::make_reserve( GlobalAllocator, hashtable_name.Len + sizeof("gen") );
|
||||||
|
fn.append_fmt( "%.*s", hashtable_name.Len, hashtable_name.Ptr );
|
||||||
|
str_to_lower(fn.Data);
|
||||||
|
|
||||||
|
String
|
||||||
|
tbl_type = String::make_reserve( GlobalAllocator, hashtable_name.Len + sizeof("gen") );
|
||||||
|
tbl_type.append_fmt( "%.*s", hashtable_name.Len, hashtable_name.Ptr );
|
||||||
|
|
||||||
|
String name_lower = String::make( GlobalAllocator, hashtable_name );
|
||||||
|
str_to_lower( name_lower.Data );
|
||||||
|
|
||||||
|
String hashtable_entry = String::fmt_buf( GlobalAllocator, "HTE_%.*s", hashtable_name.Len, hashtable_name.Ptr );
|
||||||
|
String entry_array_name = String::fmt_buf( GlobalAllocator, "Arr_HTE_%.*s", hashtable_name.Len, hashtable_name.Ptr );
|
||||||
|
String entry_array_fn_ns = String::fmt_buf( GlobalAllocator, "arr_hte_%.*s", name_lower.length(), name_lower.Data );
|
||||||
|
|
||||||
|
CodeBody hashtable_types = parse_global_body( token_fmt(
|
||||||
|
"type", (StrC) type,
|
||||||
|
"tbl_name", (StrC) hashtable_name,
|
||||||
|
"tbl_type", (StrC) tbl_type,
|
||||||
|
stringize(
|
||||||
|
typedef struct HTE_<tbl_name> HTE_<tbl_name>;
|
||||||
|
struct HTE_<tbl_name>
|
||||||
|
{
|
||||||
|
u64 Key;
|
||||||
|
ssize Next;
|
||||||
|
<type> Value;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (* <tbl_type>_MapProc) ( <tbl_type> self, u64 key, <type> value );
|
||||||
|
typedef void (* <tbl_type>_MapMutProc) ( <tbl_type> self, u64 key, <type>* value );
|
||||||
|
)));
|
||||||
|
|
||||||
|
CodeBody entry_array = gen_array( hashtable_entry, entry_array_name );
|
||||||
|
|
||||||
|
#pragma push_macro( "GEN_ASSERT" )
|
||||||
|
#pragma push_macro( "GEN_ASSERT_NOT_NULL" )
|
||||||
|
#undef GEN_ASSERT
|
||||||
|
#undef GEN_ASSERT_NOT_NULL
|
||||||
|
CodeBody hashtable_def = parse_global_body( token_fmt(
|
||||||
|
"type", (StrC) type,
|
||||||
|
"tbl_name", (StrC) hashtable_name,
|
||||||
|
"tbl_type", (StrC) tbl_type,
|
||||||
|
"fn", (StrC) fn,
|
||||||
|
"entry_type", (StrC) hashtable_entry,
|
||||||
|
"array_entry", (StrC) entry_array_name,
|
||||||
|
"fn_array", (StrC) entry_array_fn_ns,
|
||||||
|
stringize(
|
||||||
|
typedef struct <tbl_type> <tbl_type>;
|
||||||
|
struct <tbl_type>
|
||||||
|
{
|
||||||
|
Array_ssize Hashes;
|
||||||
|
<array_entry> Entries;
|
||||||
|
};
|
||||||
|
|
||||||
|
<tbl_type> <fn>_make ( AllocatorInfo allocator );
|
||||||
|
<tbl_type> <fn>_make_reserve( AllocatorInfo allocator, ssize num );
|
||||||
|
void <fn>_clear ( <tbl_type> self );
|
||||||
|
void <fn>_destroy ( <tbl_type> self );
|
||||||
|
<type>* <fn>_get ( <tbl_type> self, u64 key );
|
||||||
|
void <fn>_map ( <tbl_type> self, <tbl_type>_MapProc map_proc );
|
||||||
|
void <fn>_map_mut ( <tbl_type> self, <tbl_type>_MapMutProc map_proc );
|
||||||
|
void <fn>_grow ( <tbl_type>* self );
|
||||||
|
void <fn>_rehash ( <tbl_type>* self, ssize new_num );
|
||||||
|
void <fn>_rehash_fast ( <tbl_type> self );
|
||||||
|
void <fn>_remove ( <tbl_type> self, u64 key );
|
||||||
|
void <fn>_remove_entry( <tbl_type> self, ssize idx );
|
||||||
|
void <fn>_set ( <tbl_type>* self, u64 key, <type> value );
|
||||||
|
ssize <fn>_slot ( <tbl_type> self, u64 key );
|
||||||
|
|
||||||
|
ssize <fn>__add_entry( <tbl_type> self, u64 key );
|
||||||
|
HT_FindResult <fn>__find ( <tbl_type> self, u64 key );
|
||||||
|
b32 <fn>__full ( <tbl_type> self );
|
||||||
|
|
||||||
|
<tbl_type> <fn>_make( AllocatorInfo allocator )
|
||||||
|
{
|
||||||
|
<tbl_type>
|
||||||
|
result = { NULL, NULL };
|
||||||
|
result.Hashes = array_ssize_make( allocator );
|
||||||
|
result.Entries = <fn_array>_make( allocator );
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
<tbl_type> <fn>_make_reserve( AllocatorInfo allocator, ssize num )
|
||||||
|
{
|
||||||
|
<tbl_type>
|
||||||
|
result = { NULL, NULL };
|
||||||
|
result.Hashes = array_ssize_make_reserve( allocator, num );
|
||||||
|
result.Entries = <fn_array>_make_reserve( allocator, num );
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void <fn>_clear( <tbl_type> self )
|
||||||
|
{
|
||||||
|
for ( ssize idx = 0; idx < array_header( self.Hashes )->Num; idx++ )
|
||||||
|
self.Hashes[idx] = -1;
|
||||||
|
|
||||||
|
array_ssize_clear( self.Hashes );
|
||||||
|
<fn_array>_clear( self.Entries );
|
||||||
|
}
|
||||||
|
|
||||||
|
void <fn>_destroy( <tbl_type> self )
|
||||||
|
{
|
||||||
|
if ( self.Hashes && self.Entries )
|
||||||
|
{
|
||||||
|
array_ssize_free( self.Hashes );
|
||||||
|
<fn_array>_free( self.Entries );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<type>* <fn>_get( <tbl_type> self, u64 key )
|
||||||
|
{
|
||||||
|
ssize idx = <fn>__find( self, key ).EntryIndex;
|
||||||
|
if ( idx > 0 )
|
||||||
|
return & self.Entries[idx].Value;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void <fn>_map( <tbl_type> self, <tbl_type>_MapProc map_proc )
|
||||||
|
{
|
||||||
|
GEN_ASSERT_NOT_NULL( map_proc );
|
||||||
|
|
||||||
|
for ( ssize idx = 0; idx < array_header( self.Entries )->Num; idx++ )
|
||||||
|
{
|
||||||
|
map_proc( self, self.Entries[idx].Key, self.Entries[idx].Value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void <fn>_map_mut( <tbl_type> self, <tbl_type>_MapMutProc map_proc )
|
||||||
|
{
|
||||||
|
GEN_ASSERT_NOT_NULL( map_proc );
|
||||||
|
|
||||||
|
for ( ssize idx = 0; idx < array_header( self.Entries )->Num; idx++ )
|
||||||
|
{
|
||||||
|
map_proc( self, self.Entries[idx].Key, & self.Entries[idx].Value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void <fn>_grow( <tbl_type>* self )
|
||||||
|
{
|
||||||
|
ssize new_num = array_grow_formula( array_header( self->Entries )->Num );
|
||||||
|
<fn>_rehash( self, new_num );
|
||||||
|
}
|
||||||
|
|
||||||
|
void <fn>_rehash( <tbl_type>* self, ssize new_num )
|
||||||
|
{
|
||||||
|
ssize idx;
|
||||||
|
ssize last_added_index;
|
||||||
|
|
||||||
|
ArrayHeader* old_hash_header = array_header( self->Hashes );
|
||||||
|
ArrayHeader* old_entries_header = array_header( self->Entries );
|
||||||
|
|
||||||
|
<tbl_type> new_tbl = <fn>_make_reserve( old_hash_header->Allocator, old_hash_header->Num );
|
||||||
|
|
||||||
|
ArrayHeader* new_hash_header = array_header( new_tbl.Hashes );
|
||||||
|
|
||||||
|
for ( idx = 0; idx < new_hash_header->Num; idx++ )
|
||||||
|
new_tbl.Hashes[idx] = -1;
|
||||||
|
|
||||||
|
for ( idx = 0; idx < old_entries_header->Num; idx++ )
|
||||||
|
{
|
||||||
|
<entry_type>* entry;
|
||||||
|
HT_FindResult find_result;
|
||||||
|
|
||||||
|
if ( new_hash_header->Num == 0 )
|
||||||
|
<fn>_grow( & new_tbl );
|
||||||
|
|
||||||
|
entry = & self->Entries[ idx ];
|
||||||
|
find_result = <fn>__find( new_tbl, entry->Key );
|
||||||
|
last_added_index = <fn>__add_entry( new_tbl, entry->Key );
|
||||||
|
|
||||||
|
if ( find_result.PrevIndex < 0 )
|
||||||
|
new_tbl.Hashes[ find_result.HashIndex ] = last_added_index;
|
||||||
|
else
|
||||||
|
new_tbl.Entries[ find_result.PrevIndex ].Next = last_added_index;
|
||||||
|
|
||||||
|
new_tbl.Entries[ last_added_index ].Next = find_result.EntryIndex;
|
||||||
|
new_tbl.Entries[ last_added_index ].Value = entry->Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
<fn>_destroy( *self );
|
||||||
|
* self = new_tbl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void <fn>_rehash_fast( <tbl_type> self )
|
||||||
|
{
|
||||||
|
ssize idx;
|
||||||
|
|
||||||
|
for ( idx = 0; idx < array_header( self.Entries )->Num; idx++ )
|
||||||
|
self.Entries[ idx ].Next = -1;
|
||||||
|
|
||||||
|
for ( idx = 0; idx < array_header( self.Hashes )->Num; idx++ )
|
||||||
|
self.Hashes[ idx ] = -1;
|
||||||
|
|
||||||
|
for ( idx = 0; idx < array_header( self.Entries )->Num; idx++ )
|
||||||
|
{
|
||||||
|
<entry_type>* entry;
|
||||||
|
HT_FindResult find_result;
|
||||||
|
|
||||||
|
entry = & self.Entries[ idx ];
|
||||||
|
find_result = <fn>__find( self, entry->Key );
|
||||||
|
|
||||||
|
if ( find_result.PrevIndex < 0 )
|
||||||
|
self.Hashes[ find_result.HashIndex ] = idx;
|
||||||
|
else
|
||||||
|
self.Entries[ find_result.PrevIndex ].Next = idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void <fn>_remove( <tbl_type> self, u64 key )
|
||||||
|
{
|
||||||
|
HT_FindResult find_result = <fn>__find( self, key );
|
||||||
|
|
||||||
|
if ( find_result.EntryIndex >= 0 )
|
||||||
|
{
|
||||||
|
<fn_array>_remove_at( self.Entries, find_result.EntryIndex );
|
||||||
|
<fn>_rehash_fast( self );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void <fn>_remove_entry( <tbl_type> self, ssize idx )
|
||||||
|
{
|
||||||
|
<fn_array>_remove_at( self.Entries, idx );
|
||||||
|
}
|
||||||
|
|
||||||
|
void <fn>_set( <tbl_type>* self, u64 key, <type> value )
|
||||||
|
{
|
||||||
|
ssize idx;
|
||||||
|
HT_FindResult find_result;
|
||||||
|
|
||||||
|
if ( array_header( self->Hashes )->Num == 0 )
|
||||||
|
<fn>_grow( self );
|
||||||
|
|
||||||
|
find_result = <fn>__find( * self, key );
|
||||||
|
|
||||||
|
if ( find_result.EntryIndex >= 0 )
|
||||||
|
{
|
||||||
|
idx = find_result.EntryIndex;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
idx = <fn>__add_entry( * self, key );
|
||||||
|
|
||||||
|
if ( find_result.PrevIndex >= 0 )
|
||||||
|
{
|
||||||
|
self->Entries[ find_result.PrevIndex ].Next = idx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self->Hashes[ find_result.HashIndex ] = idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self->Entries[ idx ].Value = value;
|
||||||
|
|
||||||
|
if ( <fn>__full( * self ) )
|
||||||
|
<fn>_grow( self );
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize <fn>_slot( <tbl_type> self, u64 key )
|
||||||
|
{
|
||||||
|
for ( ssize idx = 0; idx < array_header( self.Hashes )->Num; ++idx )
|
||||||
|
if ( self.Hashes[ idx ] == key )
|
||||||
|
return idx;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize <fn>__add_entry( <tbl_type> self, u64 key )
|
||||||
|
{
|
||||||
|
ssize idx;
|
||||||
|
<entry_type> entry = { key, -1 };
|
||||||
|
|
||||||
|
idx = array_header( self.Entries )->Num;
|
||||||
|
<fn_array>_append( & self.Entries, entry );
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
HT_FindResult <fn>__find( <tbl_type> self, u64 key )
|
||||||
|
{
|
||||||
|
HT_FindResult result = { -1, -1, -1 };
|
||||||
|
|
||||||
|
ArrayHeader* hash_header = array_header( self.Hashes );
|
||||||
|
|
||||||
|
if ( hash_header->Num > 0 )
|
||||||
|
{
|
||||||
|
result.HashIndex = key % hash_header->Num;
|
||||||
|
result.EntryIndex = self.Hashes[ result.HashIndex ];
|
||||||
|
|
||||||
|
while ( result.EntryIndex >= 0 )
|
||||||
|
{
|
||||||
|
if ( self.Entries[ result.EntryIndex ].Key == key )
|
||||||
|
break;
|
||||||
|
|
||||||
|
result.PrevIndex = result.EntryIndex;
|
||||||
|
result.EntryIndex = self.Entries[ result.EntryIndex ].Next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
b32 <fn>__full( <tbl_type> self )
|
||||||
|
{
|
||||||
|
ArrayHeader* hash_header = array_header( self.Hashes );
|
||||||
|
ArrayHeader* entries_header = array_header( self.Entries );
|
||||||
|
|
||||||
|
return 0.75f * hash_header->Num < entries_header->Num;
|
||||||
|
}
|
||||||
|
)));
|
||||||
|
#pragma pop_macro( "GEN_ASSERT" )
|
||||||
|
#pragma pop_macro( "GEN_ASSERT_NOT_NULL" )
|
||||||
|
|
||||||
|
char const* cmt_str = str_fmt_buf( "Name: %.*s Type: %.*s"
|
||||||
|
, tbl_type.length(), tbl_type.Data
|
||||||
|
, type.Len, type.Ptr );
|
||||||
|
|
||||||
|
return def_global_body(args(
|
||||||
|
def_pragma( to_str( str_fmt_buf( "region %S", tbl_type ))),
|
||||||
|
fmt_newline,
|
||||||
|
hashtable_types,
|
||||||
|
fmt_newline,
|
||||||
|
entry_array,
|
||||||
|
hashtable_def,
|
||||||
|
fmt_newline,
|
||||||
|
def_pragma( to_str( str_fmt_buf( "endregion %S", tbl_type ))),
|
||||||
|
fmt_newline
|
||||||
|
));
|
||||||
|
}
|
@ -6,6 +6,7 @@ using namespace gen;
|
|||||||
CodeBody gen_fixed_arenas()
|
CodeBody gen_fixed_arenas()
|
||||||
{
|
{
|
||||||
CodeBody result = def_body(ECode::Global_Body);
|
CodeBody result = def_body(ECode::Global_Body);
|
||||||
|
result.append(def_pragma(txt("region FixedArena")));
|
||||||
|
|
||||||
char const* template_struct = stringize(
|
char const* template_struct = stringize(
|
||||||
struct FixedArena_<Name>
|
struct FixedArena_<Name>
|
||||||
@ -115,5 +116,7 @@ CodeBody gen_fixed_arenas()
|
|||||||
)"
|
)"
|
||||||
)));
|
)));
|
||||||
|
|
||||||
|
result.append(def_pragma(txt("endregion FixedArena")));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& bod
|
|||||||
if ( cond->Content.contains(cond_sig) )
|
if ( cond->Content.contains(cond_sig) )
|
||||||
{
|
{
|
||||||
s32 depth = 1;
|
s32 depth = 1;
|
||||||
++ entry_iter; for(b32 continue_for = true; continue_for && entry_iter != body.end(); ++ entry_iter) switch
|
++ entry_iter; for(b32 continue_for = true; continue_for && entry_iter != body.end(); ) switch
|
||||||
(entry_iter->Type) {
|
(entry_iter->Type) {
|
||||||
case ECode::Preprocess_If:
|
case ECode::Preprocess_If:
|
||||||
case ECode::Preprocess_IfDef:
|
case ECode::Preprocess_IfDef:
|
||||||
@ -24,24 +24,30 @@ b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& bod
|
|||||||
depth --;
|
depth --;
|
||||||
if (depth == 0) {
|
if (depth == 0) {
|
||||||
continue_for = false;
|
continue_for = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
++ entry_iter;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry_iter != body.end();
|
return entry_iter != body.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void 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;
|
||||||
CodePragma possible_region = entry_iter.cast<CodePragma>();
|
CodePragma possible_region = entry_iter.cast<CodePragma>();
|
||||||
|
|
||||||
String region_sig = string_fmt_buf(GlobalAllocator, "region %s", region_name.Ptr);
|
String region_sig = string_fmt_buf(GlobalAllocator, "region %s", region_name.Ptr);
|
||||||
String endregion_sig = string_fmt_buf(GlobalAllocator, "endregion %s", region_name.Ptr);
|
String endregion_sig = string_fmt_buf(GlobalAllocator, "endregion %s", region_name.Ptr);
|
||||||
if ( possible_region->Content.contains(region_sig))
|
if ( possible_region->Content.contains(region_sig))
|
||||||
{
|
{
|
||||||
body.append(possible_region);
|
found = true;
|
||||||
|
// 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
|
||||||
@ -50,12 +56,13 @@ void swap_pragma_region_implementation( StrC region_name, SwapContentProc* swap_
|
|||||||
{
|
{
|
||||||
CodePragma possible_end_region = entry_iter.cast<CodePragma>();
|
CodePragma possible_end_region = entry_iter.cast<CodePragma>();
|
||||||
if ( possible_end_region->Content.contains(endregion_sig) ) {
|
if ( possible_end_region->Content.contains(endregion_sig) ) {
|
||||||
body.append(possible_end_region);
|
// body.append(possible_end_region);
|
||||||
continue_for = false;
|
continue_for = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
body.append(entry_iter);
|
||||||
}
|
}
|
||||||
body.append(entry_iter);
|
return found;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ Builder Builder::open( char const* path )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.Buffer = String::make_reserve( GlobalAllocator, Builder_StrBufferReserve );
|
result.Buffer = string_make_reserve( GlobalAllocator, Builder_StrBufferReserve );
|
||||||
|
|
||||||
// log_fmt("$Builder - Opened file: %s\n", result.File.filename );
|
// log_fmt("$Builder - Opened file: %s\n", result.File.filename );
|
||||||
return result;
|
return result;
|
||||||
@ -21,7 +21,7 @@ Builder Builder::open( char const* path )
|
|||||||
|
|
||||||
void Builder::pad_lines( s32 num )
|
void Builder::pad_lines( s32 num )
|
||||||
{
|
{
|
||||||
Buffer.append( "\n" );
|
append( Buffer, "\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builder::print( Code code )
|
void Builder::print( Code code )
|
||||||
@ -29,7 +29,7 @@ void Builder::print( Code code )
|
|||||||
String str = code->to_string();
|
String str = code->to_string();
|
||||||
// const ssize len = str.length();
|
// const ssize len = str.length();
|
||||||
// log_fmt( "%s - print: %.*s\n", File.filename, len > 80 ? 80 : len, str.Data );
|
// log_fmt( "%s - print: %.*s\n", File.filename, len > 80 ? 80 : len, str.Data );
|
||||||
Buffer.append( str );
|
append( 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 );
|
||||||
Buffer.append( buf, res );
|
append( Buffer, buf, res );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builder::write()
|
void Builder::write()
|
||||||
{
|
{
|
||||||
b32 result = file_write( & File, Buffer, Buffer.length() );
|
b32 result = file_write( & File, Buffer, 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 );
|
||||||
Buffer.free();
|
free(Buffer);
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,9 @@ Code scan_file( char const* path )
|
|||||||
GEN_FATAL("scan_file: %s is empty", path );
|
GEN_FATAL("scan_file: %s is empty", path );
|
||||||
}
|
}
|
||||||
|
|
||||||
String str = String::make_reserve( GlobalAllocator, fsize );
|
String str = string_make_reserve( GlobalAllocator, fsize );
|
||||||
file_read( & file, str, fsize );
|
file_read( & file, str, fsize );
|
||||||
str.get_header().Length = fsize;
|
get_header(str).Length = fsize;
|
||||||
|
|
||||||
// Skip GEN_INTELLISENSE_DIRECTIVES preprocessor blocks
|
// Skip GEN_INTELLISENSE_DIRECTIVES preprocessor blocks
|
||||||
// Its designed so that the directive should be the first thing in the file.
|
// Its designed so that the directive should be the first thing in the file.
|
||||||
@ -97,12 +97,12 @@ Code scan_file( char const* path )
|
|||||||
if ( (scanner + 2) >= ( str.Data + fsize ) )
|
if ( (scanner + 2) >= ( str.Data + fsize ) )
|
||||||
{
|
{
|
||||||
mem_move( str, scanner, left );
|
mem_move( str, scanner, left );
|
||||||
str.get_header().Length = left;
|
get_header(str).Length = left;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mem_move( str, scanner, left );
|
mem_move( str, scanner, left );
|
||||||
str.get_header().Length = left;
|
get_header(str).Length = left;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||||
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
||||||
#define GEN_EXPOSE_BACKEND
|
#define GEN_EXPOSE_BACKEND
|
||||||
|
#define GEN_SUPPORT_CPP_MEMBER_FEATURES 0
|
||||||
#include "gen.cpp"
|
#include "gen.cpp"
|
||||||
|
|
||||||
#include "helpers/push_ignores.inline.hpp"
|
#include "helpers/push_ignores.inline.hpp"
|
||||||
@ -24,20 +25,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(GlobalAllocator, to_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 ");
|
append( style_arg, "../scripts/.clang-format ");
|
||||||
|
|
||||||
// Need to execute clang format on the generated file to get it to match the original.
|
// Need to execute clang format on the generated file to get it to match the original.
|
||||||
#define clang_format "clang-format "
|
#define clang_format "clang-format "
|
||||||
#define cf_format_inplace "-i "
|
#define cf_format_inplace "-i "
|
||||||
#define cf_verbose "-verbose "
|
#define cf_verbose "-verbose "
|
||||||
String command = String::make( GlobalAllocator, clang_format );
|
String command = string_make( GlobalAllocator, clang_format );
|
||||||
command.append( cf_format_inplace );
|
append( command, cf_format_inplace );
|
||||||
command.append( cf_verbose );
|
append( command, cf_verbose );
|
||||||
command.append( style_arg );
|
append( command, style_arg );
|
||||||
command.append( resolved_path );
|
append( command, resolved_path );
|
||||||
log_fmt("\tRunning clang-format on file:\n");
|
log_fmt("\tRunning clang-format on file:\n");
|
||||||
system( command );
|
system( command );
|
||||||
log_fmt("\tclang-format finished reformatting.\n");
|
log_fmt("\tclang-format finished reformatting.\n");
|
||||||
|
@ -9,16 +9,16 @@ Code Code::Invalid;
|
|||||||
// This serializes all the data-members in a "debug" format, where each member is printed with its associated value.
|
// This serializes all the data-members in a "debug" format, where each member is printed with its associated value.
|
||||||
char const* AST::debug_str()
|
char const* AST::debug_str()
|
||||||
{
|
{
|
||||||
String result = String::make_reserve( GlobalAllocator, kilobytes(1) );
|
String result = string_make_reserve( GlobalAllocator, kilobytes(1) );
|
||||||
|
|
||||||
if ( Parent )
|
if ( Parent )
|
||||||
result.append_fmt( "\n\tParent : %S %S", Parent->type_str(), Name ? Name : "" );
|
append_fmt( result, "\n\tParent : %S %S", Parent->type_str(), Name ? Name : "" );
|
||||||
else
|
else
|
||||||
result.append_fmt( "\n\tParent : %S", "Null" );
|
append_fmt( result, "\n\tParent : %S", "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tName : %S", Name ? Name : "Null" );
|
append_fmt( result, "\n\tName : %S", Name ? Name : "Null" );
|
||||||
result.append_fmt( "\n\tType : %S", type_str() );
|
append_fmt( result, "\n\tType : %S", type_str() );
|
||||||
result.append_fmt( "\n\tModule Flags : %S", to_str( ModuleFlags ) );
|
append_fmt( result, "\n\tModule Flags : %S", to_str( ModuleFlags ) );
|
||||||
|
|
||||||
switch ( Type )
|
switch ( Type )
|
||||||
{
|
{
|
||||||
@ -30,9 +30,9 @@ char const* AST::debug_str()
|
|||||||
case Access_Protected:
|
case Access_Protected:
|
||||||
case Access_Public:
|
case Access_Public:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Untyped:
|
case Untyped:
|
||||||
@ -48,74 +48,74 @@ char const* AST::debug_str()
|
|||||||
case Preprocess_IfDef:
|
case Preprocess_IfDef:
|
||||||
case Preprocess_IfNotDef:
|
case Preprocess_IfNotDef:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tContent: %S", Content );
|
append_fmt( result, "\n\tContent: %S", Content );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Class:
|
case Class:
|
||||||
case Struct:
|
case Struct:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tInlineCmd : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
append_fmt( result, "\n\tInlineCmd : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
||||||
result.append_fmt( "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" );
|
append_fmt( result, "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tParentAccess: %s", ParentType ? to_str( ParentAccess ) : "No Parent" );
|
append_fmt( result, "\n\tParentAccess: %s", ParentType ? to_str( ParentAccess ) : "No Parent" );
|
||||||
result.append_fmt( "\n\tParentType : %s", ParentType ? ParentType->type_str() : "Null" );
|
append_fmt( result, "\n\tParentType : %s", ParentType ? ParentType->type_str() : "Null" );
|
||||||
result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" );
|
append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Class_Fwd:
|
case Class_Fwd:
|
||||||
case Struct_Fwd:
|
case Struct_Fwd:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tInlineCmd : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
append_fmt( result, "\n\tInlineCmd : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
||||||
result.append_fmt( "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" );
|
append_fmt( result, "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tParentAccess: %s", ParentType ? to_str( ParentAccess ) : "No Parent" );
|
append_fmt( result, "\n\tParentAccess: %s", ParentType ? to_str( ParentAccess ) : "No Parent" );
|
||||||
result.append_fmt( "\n\tParentType : %s", ParentType ? ParentType->type_str() : "Null" );
|
append_fmt( result, "\n\tParentType : %s", ParentType ? ParentType->type_str() : "Null" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Constructor:
|
case Constructor:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
||||||
result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tInitializerList: %S", InitializerList ? InitializerList->to_string() : "Null" );
|
append_fmt( result, "\n\tInitializerList: %S", InitializerList ? InitializerList->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tParams : %S", Params ? Params->to_string() : "Null" );
|
append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" );
|
append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Constructor_Fwd:
|
case Constructor_Fwd:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
||||||
result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tInitializerList: %S", InitializerList ? InitializerList->to_string() : "Null" );
|
append_fmt( result, "\n\tInitializerList: %S", InitializerList ? InitializerList->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tParams : %S", Params ? Params->to_string() : "Null" );
|
append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Destructor:
|
case Destructor:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
||||||
result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" );
|
append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Destructor_Fwd:
|
case Destructor_Fwd:
|
||||||
@ -124,208 +124,208 @@ char const* AST::debug_str()
|
|||||||
case Enum:
|
case Enum:
|
||||||
case Enum_Class:
|
case Enum_Class:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
||||||
result.append_fmt( "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" );
|
append_fmt( result, "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tUnderlying Type : %S", UnderlyingType ? UnderlyingType->to_string() : "Null" );
|
append_fmt( result, "\n\tUnderlying Type : %S", UnderlyingType ? UnderlyingType->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" );
|
append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Enum_Fwd:
|
case Enum_Fwd:
|
||||||
case Enum_Class_Fwd:
|
case Enum_Class_Fwd:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
||||||
result.append_fmt( "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" );
|
append_fmt( result, "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tUnderlying Type : %S", UnderlyingType ? UnderlyingType->to_string() : "Null" );
|
append_fmt( result, "\n\tUnderlying Type : %S", UnderlyingType ? UnderlyingType->to_string() : "Null" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Extern_Linkage:
|
case Extern_Linkage:
|
||||||
case Namespace:
|
case Namespace:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tBody: %S", Body ? Body->debug_str() : "Null" );
|
append_fmt( result, "\n\tBody: %S", Body ? Body->debug_str() : "Null" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Friend:
|
case Friend:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
||||||
result.append_fmt( "\n\tDeclaration: %S", Declaration ? Declaration->to_string() : "Null" );
|
append_fmt( result, "\n\tDeclaration: %S", Declaration ? Declaration->to_string() : "Null" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Function:
|
case Function:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
||||||
result.append_fmt( "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" );
|
append_fmt( result, "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tReturnType: %S", ReturnType ? ReturnType->to_string() : "Null" );
|
append_fmt( result, "\n\tReturnType: %S", ReturnType ? ReturnType->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tParams : %S", Params ? Params->to_string() : "Null" );
|
append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" );
|
append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Function_Fwd:
|
case Function_Fwd:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
||||||
result.append_fmt( "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" );
|
append_fmt( result, "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tReturnType: %S", ReturnType ? ReturnType->to_string() : "Null" );
|
append_fmt( result, "\n\tReturnType: %S", ReturnType ? ReturnType->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tParams : %S", Params ? Params->to_string() : "Null" );
|
append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Module:
|
case Module:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Operator:
|
case Operator:
|
||||||
case Operator_Member:
|
case Operator_Member:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
||||||
result.append_fmt( "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" );
|
append_fmt( result, "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tReturnType: %S", ReturnType ? ReturnType->to_string() : "Null" );
|
append_fmt( result, "\n\tReturnType: %S", ReturnType ? ReturnType->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tParams : %S", Params ? Params->to_string() : "Null" );
|
append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" );
|
append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" );
|
||||||
result.append_fmt( "\n\tOp : %S", to_str( Op ) );
|
append_fmt( result, "\n\tOp : %S", to_str( Op ) );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Operator_Fwd:
|
case Operator_Fwd:
|
||||||
case Operator_Member_Fwd:
|
case Operator_Member_Fwd:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
||||||
result.append_fmt( "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" );
|
append_fmt( result, "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tReturnType: %S", ReturnType ? ReturnType->to_string() : "Null" );
|
append_fmt( result, "\n\tReturnType: %S", ReturnType ? ReturnType->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tParams : %S", Params ? Params->to_string() : "Null" );
|
append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tOp : %S", to_str( Op ) );
|
append_fmt( result, "\n\tOp : %S", to_str( Op ) );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Operator_Cast:
|
case Operator_Cast:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
||||||
result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tValueType : %S", ValueType ? ValueType->to_string() : "Null" );
|
append_fmt( result, "\n\tValueType : %S", ValueType ? ValueType->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" );
|
append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Operator_Cast_Fwd:
|
case Operator_Cast_Fwd:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
||||||
result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tValueType : %S", ValueType ? ValueType->to_string() : "Null" );
|
append_fmt( result, "\n\tValueType : %S", ValueType ? ValueType->to_string() : "Null" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Parameters:
|
case Parameters:
|
||||||
result.append_fmt( "\n\tNumEntries: %d", NumEntries );
|
append_fmt( result, "\n\tNumEntries: %d", NumEntries );
|
||||||
result.append_fmt( "\n\tLast : %S", Last->Name );
|
append_fmt( result, "\n\tLast : %S", Last->Name );
|
||||||
result.append_fmt( "\n\tNext : %S", Next->Name );
|
append_fmt( result, "\n\tNext : %S", Next->Name );
|
||||||
result.append_fmt( "\n\tValueType : %S", ValueType ? ValueType->to_string() : "Null" );
|
append_fmt( result, "\n\tValueType : %S", ValueType ? ValueType->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tValue : %S", Value ? Value->to_string() : "Null" );
|
append_fmt( result, "\n\tValue : %S", Value ? Value->to_string() : "Null" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Specifiers:
|
case Specifiers:
|
||||||
{
|
{
|
||||||
result.append_fmt( "\n\tNumEntries: %d", NumEntries );
|
append_fmt( result, "\n\tNumEntries: %d", NumEntries );
|
||||||
result.append( "\n\tArrSpecs: " );
|
GEN_NS append( result, "\n\tArrSpecs: " );
|
||||||
|
|
||||||
s32 idx = 0;
|
s32 idx = 0;
|
||||||
s32 left = NumEntries;
|
s32 left = NumEntries;
|
||||||
while ( left-- )
|
while ( left-- )
|
||||||
{
|
{
|
||||||
StrC spec = ESpecifier::to_str( ArrSpecs[idx] );
|
StrC spec = ESpecifier::to_str( ArrSpecs[idx] );
|
||||||
result.append_fmt( "%.*s, ", spec.Len, spec.Ptr );
|
append_fmt( result, "%.*s, ", spec.Len, spec.Ptr );
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
result.append_fmt( "\n\tNextSpecs: %S", NextSpecs ? NextSpecs->debug_str() : "Null" );
|
append_fmt( result, "\n\tNextSpecs: %S", NextSpecs ? NextSpecs->debug_str() : "Null" );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Template:
|
case Template:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tParams : %S", Params ? Params->to_string() : "Null" );
|
append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tDeclaration: %S", Declaration ? Declaration->to_string() : "Null" );
|
append_fmt( result, "\n\tDeclaration: %S", Declaration ? Declaration->to_string() : "Null" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Typedef:
|
case Typedef:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
||||||
result.append_fmt( "\n\tUnderlyingType: %S", UnderlyingType ? UnderlyingType->to_string() : "Null" );
|
append_fmt( result, "\n\tUnderlyingType: %S", UnderlyingType ? UnderlyingType->to_string() : "Null" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Typename:
|
case Typename:
|
||||||
result.append_fmt( "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" );
|
append_fmt( result, "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tReturnType : %S", ReturnType ? ReturnType->to_string() : "Null" );
|
append_fmt( result, "\n\tReturnType : %S", ReturnType ? ReturnType->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tParams : %S", Params ? Params->to_string() : "Null" );
|
append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tArrExpr : %S", ArrExpr ? ArrExpr->to_string() : "Null" );
|
append_fmt( result, "\n\tArrExpr : %S", ArrExpr ? ArrExpr->to_string() : "Null" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Union:
|
case Union:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" );
|
append_fmt( result, "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" );
|
append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Using:
|
case Using:
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
||||||
result.append_fmt( "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" );
|
append_fmt( result, "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tUnderlyingType: %S", UnderlyingType ? UnderlyingType->to_string() : "Null" );
|
append_fmt( result, "\n\tUnderlyingType: %S", UnderlyingType ? UnderlyingType->to_string() : "Null" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Variable:
|
case Variable:
|
||||||
@ -333,25 +333,25 @@ char const* AST::debug_str()
|
|||||||
if ( Parent && Parent->Type == Variable )
|
if ( Parent && Parent->Type == Variable )
|
||||||
{
|
{
|
||||||
// Its a NextVar
|
// Its a NextVar
|
||||||
result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tValue : %S", Value ? Value->to_string() : "Null" );
|
append_fmt( result, "\n\tValue : %S", Value ? Value->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tBitfieldSize: %S", BitfieldSize ? BitfieldSize->to_string() : "Null" );
|
append_fmt( result, "\n\tBitfieldSize: %S", BitfieldSize ? BitfieldSize->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tNextVar : %S", NextVar ? NextVar->debug_str() : "Null" );
|
append_fmt( result, "\n\tNextVar : %S", NextVar ? NextVar->debug_str() : "Null" );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( Prev )
|
if ( Prev )
|
||||||
result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
if ( Next )
|
if ( Next )
|
||||||
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
|
||||||
|
|
||||||
result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" );
|
||||||
result.append_fmt( "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" );
|
append_fmt( result, "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tValueType : %S", ValueType ? ValueType->to_string() : "Null" );
|
append_fmt( result, "\n\tValueType : %S", ValueType ? ValueType->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tBitfieldSize: %S", BitfieldSize ? BitfieldSize->to_string() : "Null" );
|
append_fmt( result, "\n\tBitfieldSize: %S", BitfieldSize ? BitfieldSize->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tValue : %S", Value ? Value->to_string() : "Null" );
|
append_fmt( result, "\n\tValue : %S", Value ? Value->to_string() : "Null" );
|
||||||
result.append_fmt( "\n\tNextVar : %S", NextVar ? NextVar->debug_str() : "Null" );
|
append_fmt( result, "\n\tNextVar : %S", NextVar ? NextVar->debug_str() : "Null" );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,7 +372,7 @@ AST* AST::duplicate()
|
|||||||
|
|
||||||
String AST::to_string()
|
String AST::to_string()
|
||||||
{
|
{
|
||||||
String result = String::make( GlobalAllocator, "" );
|
String result = string_make( GlobalAllocator, "" );
|
||||||
to_string( result );
|
to_string( result );
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -390,25 +390,25 @@ void AST::to_string( 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
|
||||||
result.append_fmt( "Invalid Code!" );
|
append_fmt( result, "Invalid Code!" );
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NewLine:
|
case NewLine:
|
||||||
result.append("\n");
|
GEN_NS append( result,"\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Untyped:
|
case Untyped:
|
||||||
case Execution:
|
case Execution:
|
||||||
case Comment:
|
case Comment:
|
||||||
case PlatformAttributes:
|
case PlatformAttributes:
|
||||||
result.append( Content );
|
GEN_NS append( result, Content );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Access_Private:
|
case Access_Private:
|
||||||
case Access_Protected:
|
case Access_Protected:
|
||||||
case Access_Public:
|
case Access_Public:
|
||||||
result.append( Name );
|
GEN_NS append( result, Name );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Class:
|
case Class:
|
||||||
@ -659,8 +659,8 @@ bool AST::is_equal( AST* other )
|
|||||||
"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" \
|
||||||
, content.visualize_whitespace() \
|
, visualize_whitespace(content) \
|
||||||
, other->content.visualize_whitespace() \
|
, visualize_whitespace(other->content) \
|
||||||
); \
|
); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,7 +376,8 @@ struct AST
|
|||||||
OperatorT Op;
|
OperatorT Op;
|
||||||
AccessSpec ParentAccess;
|
AccessSpec ParentAccess;
|
||||||
s32 NumEntries;
|
s32 NumEntries;
|
||||||
s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression.
|
s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression.
|
||||||
|
b32 EnumUnderlyingMacro; // Used by enums incase the user wants to wrap underlying type specification in a macro
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ struct AST_Enum
|
|||||||
CodeAttributes Attributes;
|
CodeAttributes Attributes;
|
||||||
char _PAD_SPEC_ [ sizeof(AST*) ];
|
char _PAD_SPEC_ [ sizeof(AST*) ];
|
||||||
CodeType UnderlyingType;
|
CodeType UnderlyingType;
|
||||||
char _PAD_PARAMS_[ sizeof(AST*) ];
|
Code UnderlyingTypeMacro;
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
@ -186,7 +186,7 @@ struct AST_Enum
|
|||||||
StringCached Name;
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
char _PAD_UNUSED_[ sizeof(u32) ];
|
b32 EnumUnderlyingMacro;
|
||||||
};
|
};
|
||||||
static_assert( sizeof(AST_Enum) == sizeof(AST), "ERROR: AST_Enum is not the same size as AST");
|
static_assert( sizeof(AST_Enum) == sizeof(AST), "ERROR: AST_Enum is not the same size as AST");
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -78,7 +78,7 @@ void CodeClass::add_interface( CodeType type )
|
|||||||
if ( possible_slot.ast )
|
if ( possible_slot.ast )
|
||||||
{
|
{
|
||||||
// Were adding an interface to parent type, so we need to make sure the parent type is public.
|
// Were adding an interface to parent type, so we need to make sure the parent type is public.
|
||||||
ast->ParentAccess = AccessSpec::Public;
|
ast->ParentAccess = AccessSpec_Public;
|
||||||
// If your planning on adding a proper parent,
|
// If your planning on adding a proper parent,
|
||||||
// then you'll need to move this over to ParentType->next and update ParentAccess accordingly.
|
// then you'll need to move this over to ParentType->next and update ParentAccess accordingly.
|
||||||
}
|
}
|
||||||
@ -151,7 +151,7 @@ void CodeStruct::add_interface( CodeType type )
|
|||||||
if ( possible_slot.ast )
|
if ( possible_slot.ast )
|
||||||
{
|
{
|
||||||
// Were adding an interface to parent type, so we need to make sure the parent type is public.
|
// Were adding an interface to parent type, so we need to make sure the parent type is public.
|
||||||
ast->ParentAccess = AccessSpec::Public;
|
ast->ParentAccess = AccessSpec_Public;
|
||||||
// If your planning on adding a proper parent,
|
// If your planning on adding a proper parent,
|
||||||
// then you'll need to move this over to ParentType->next and update ParentAccess accordingly.
|
// then you'll need to move this over to ParentType->next and update ParentAccess accordingly.
|
||||||
}
|
}
|
||||||
|
@ -74,16 +74,16 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, s
|
|||||||
internal
|
internal
|
||||||
void define_constants()
|
void define_constants()
|
||||||
{
|
{
|
||||||
Code::Global = make_code();
|
Code::Global = make_code();
|
||||||
Code::Global->Name = get_cached_string( txt("Global Code") );
|
scast(String, Code::Global->Name) = get_cached_string( txt("Global Code") );
|
||||||
Code::Global->Content = Code::Global->Name;
|
scast(String, Code::Global->Content) = Code::Global->Name;
|
||||||
|
|
||||||
Code::Invalid = make_code();
|
Code::Invalid = make_code();
|
||||||
Code::Invalid.set_global();
|
Code::Invalid.set_global();
|
||||||
|
|
||||||
t_empty = (CodeType) make_code();
|
t_empty = (CodeType) make_code();
|
||||||
t_empty->Type = ECode::Typename;
|
t_empty->Type = ECode::Typename;
|
||||||
t_empty->Name = get_cached_string( txt("") );
|
t_empty->Name = get_cached_string( txt("") );
|
||||||
t_empty.set_global();
|
t_empty.set_global();
|
||||||
|
|
||||||
access_private = make_code();
|
access_private = make_code();
|
||||||
@ -226,6 +226,10 @@ void define_constants()
|
|||||||
# pragma pop_macro("local_persist")
|
# pragma pop_macro("local_persist")
|
||||||
# pragma pop_macro("neverinline")
|
# pragma pop_macro("neverinline")
|
||||||
|
|
||||||
|
# pragma push_macro("enum_underlying")
|
||||||
|
|
||||||
|
# pragma pop_macro("enum_underlying")
|
||||||
|
|
||||||
# undef def_constant_spec
|
# undef def_constant_spec
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,7 +286,7 @@ void init()
|
|||||||
|
|
||||||
// Setup the hash tables
|
// Setup the hash tables
|
||||||
{
|
{
|
||||||
StringCache = StringTable::init( Allocator_StringTable );
|
StringCache = hashtable_init<StringCached>(Allocator_StringTable);
|
||||||
|
|
||||||
if ( StringCache.Entries == nullptr )
|
if ( StringCache.Entries == nullptr )
|
||||||
GEN_FATAL( "gen::init: Failed to initialize the StringCache");
|
GEN_FATAL( "gen::init: Failed to initialize the StringCache");
|
||||||
@ -317,7 +321,7 @@ void deinit()
|
|||||||
}
|
}
|
||||||
while ( left--, left );
|
while ( left--, left );
|
||||||
|
|
||||||
StringCache.destroy();
|
destroy(StringCache);
|
||||||
|
|
||||||
free(CodePools);
|
free(CodePools);
|
||||||
free(StringArenas);
|
free(StringArenas);
|
||||||
@ -392,14 +396,14 @@ StringCached get_cached_string( StrC str )
|
|||||||
s32 hash_length = str.Len > kilobytes(1) ? kilobytes(1) : str.Len;
|
s32 hash_length = str.Len > kilobytes(1) ? kilobytes(1) : str.Len;
|
||||||
u64 key = crc32( str.Ptr, hash_length );
|
u64 key = crc32( str.Ptr, hash_length );
|
||||||
{
|
{
|
||||||
StringCached* result = StringCache.get( key );
|
StringCached* result = get(StringCache, key );
|
||||||
|
|
||||||
if ( result )
|
if ( result )
|
||||||
return * result;
|
return * result;
|
||||||
}
|
}
|
||||||
|
|
||||||
String result = String::make( get_string_allocator( str.Len ), str );
|
String result = string_make( get_string_allocator( str.Len ), str );
|
||||||
StringCache.set( key, result );
|
set<StringCached>(StringCache, key, result );
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -44,9 +44,9 @@ CodeComment def_comment ( StrC content );
|
|||||||
|
|
||||||
CodeClass def_class( StrC name
|
CodeClass def_class( StrC name
|
||||||
, Code body = NoCode
|
, Code body = NoCode
|
||||||
, CodeType parent = NoCode, AccessSpec access = AccessSpec::Default
|
, CodeType parent = NoCode, AccessSpec access = AccessSpec_Default
|
||||||
, CodeAttributes attributes = NoCode
|
, CodeAttributes attributes = NoCode
|
||||||
, ModuleFlag mflags = ModuleFlag::None
|
, ModuleFlag mflags = ModuleFlag_None
|
||||||
, CodeType* interfaces = nullptr, s32 num_interfaces = 0 );
|
, CodeType* interfaces = nullptr, s32 num_interfaces = 0 );
|
||||||
|
|
||||||
CodeConstructor def_constructor( CodeParam params = NoCode, Code initializer_list = NoCode, Code body = NoCode );
|
CodeConstructor def_constructor( CodeParam params = NoCode, Code initializer_list = NoCode, Code body = NoCode );
|
||||||
@ -56,9 +56,9 @@ CodeDefine def_define( StrC name, StrC content );
|
|||||||
CodeDestructor def_destructor( Code body = NoCode, CodeSpecifiers specifiers = NoCode );
|
CodeDestructor def_destructor( Code body = NoCode, CodeSpecifiers specifiers = NoCode );
|
||||||
|
|
||||||
CodeEnum def_enum( StrC name
|
CodeEnum def_enum( StrC name
|
||||||
, Code body = NoCode, CodeType type = NoCode
|
, Code body = NoCode, CodeType type = NoCode
|
||||||
, EnumT specifier = EnumRegular, CodeAttributes attributes = NoCode
|
, EnumT specifier = EnumDecl_Regular, CodeAttributes attributes = NoCode
|
||||||
, ModuleFlag mflags = ModuleFlag::None );
|
, ModuleFlag mflags = ModuleFlag_None );
|
||||||
|
|
||||||
CodeExec def_execution ( StrC content );
|
CodeExec def_execution ( StrC content );
|
||||||
CodeExtern def_extern_link( StrC name, Code body );
|
CodeExtern def_extern_link( StrC name, Code body );
|
||||||
@ -67,16 +67,16 @@ CodeFriend def_friend ( Code symbol );
|
|||||||
CodeFn def_function( StrC name
|
CodeFn def_function( StrC name
|
||||||
, CodeParam params = NoCode, CodeType ret_type = NoCode, Code body = NoCode
|
, CodeParam params = NoCode, CodeType ret_type = NoCode, Code body = NoCode
|
||||||
, CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode
|
, CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode
|
||||||
, ModuleFlag mflags = ModuleFlag::None );
|
, ModuleFlag mflags = ModuleFlag_None );
|
||||||
|
|
||||||
CodeInclude def_include ( StrC content, bool foreign = false );
|
CodeInclude def_include ( StrC content, bool foreign = false );
|
||||||
CodeModule def_module ( StrC name, ModuleFlag mflags = ModuleFlag::None );
|
CodeModule def_module ( StrC name, ModuleFlag mflags = ModuleFlag_None );
|
||||||
CodeNS def_namespace( StrC name, Code body, ModuleFlag mflags = ModuleFlag::None );
|
CodeNS def_namespace( StrC name, Code body, ModuleFlag mflags = ModuleFlag_None );
|
||||||
|
|
||||||
CodeOperator def_operator( OperatorT op, StrC nspace
|
CodeOperator def_operator( OperatorT op, StrC nspace
|
||||||
, CodeParam params = NoCode, CodeType ret_type = NoCode, Code body = NoCode
|
, CodeParam params = NoCode, CodeType ret_type = NoCode, Code body = NoCode
|
||||||
, CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode
|
, CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode
|
||||||
, ModuleFlag mflags = ModuleFlag::None );
|
, ModuleFlag mflags = ModuleFlag_None );
|
||||||
|
|
||||||
CodeOpCast def_operator_cast( CodeType type, Code body = NoCode, CodeSpecifiers specs = NoCode );
|
CodeOpCast def_operator_cast( CodeType type, Code body = NoCode, CodeSpecifiers specs = NoCode );
|
||||||
|
|
||||||
@ -89,27 +89,27 @@ CodeSpecifiers def_specifier( SpecifierT specifier );
|
|||||||
|
|
||||||
CodeStruct def_struct( StrC name
|
CodeStruct def_struct( StrC name
|
||||||
, Code body = NoCode
|
, Code body = NoCode
|
||||||
, CodeType parent = NoCode, AccessSpec access = AccessSpec::Default
|
, CodeType parent = NoCode, AccessSpec access = AccessSpec_Default
|
||||||
, CodeAttributes attributes = NoCode
|
, CodeAttributes attributes = NoCode
|
||||||
, ModuleFlag mflags = ModuleFlag::None
|
, ModuleFlag mflags = ModuleFlag_None
|
||||||
, CodeType* interfaces = nullptr, s32 num_interfaces = 0 );
|
, CodeType* interfaces = nullptr, s32 num_interfaces = 0 );
|
||||||
|
|
||||||
CodeTemplate def_template( CodeParam params, Code definition, ModuleFlag mflags = ModuleFlag::None );
|
CodeTemplate def_template( CodeParam params, Code definition, ModuleFlag mflags = ModuleFlag_None );
|
||||||
|
|
||||||
CodeType def_type ( StrC name, Code arrayexpr = NoCode, CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode );
|
CodeType def_type ( StrC name, Code arrayexpr = NoCode, CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode );
|
||||||
CodeTypedef def_typedef( StrC name, Code type, CodeAttributes attributes = NoCode, ModuleFlag mflags = ModuleFlag::None );
|
CodeTypedef def_typedef( StrC name, Code type, CodeAttributes attributes = NoCode, ModuleFlag mflags = ModuleFlag_None );
|
||||||
|
|
||||||
CodeUnion def_union( StrC name, Code body, CodeAttributes attributes = NoCode, ModuleFlag mflags = ModuleFlag::None );
|
CodeUnion def_union( StrC name, Code body, CodeAttributes attributes = NoCode, ModuleFlag mflags = ModuleFlag_None );
|
||||||
|
|
||||||
CodeUsing def_using( StrC name, CodeType type = NoCode
|
CodeUsing def_using( StrC name, CodeType type = NoCode
|
||||||
, CodeAttributes attributess = NoCode
|
, CodeAttributes attributess = NoCode
|
||||||
, ModuleFlag mflags = ModuleFlag::None );
|
, ModuleFlag mflags = ModuleFlag_None );
|
||||||
|
|
||||||
CodeUsing def_using_namespace( StrC name );
|
CodeUsing def_using_namespace( StrC name );
|
||||||
|
|
||||||
CodeVar def_variable( CodeType type, StrC name, Code value = NoCode
|
CodeVar def_variable( CodeType type, StrC name, Code value = NoCode
|
||||||
, CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode
|
, CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode
|
||||||
, ModuleFlag mflags = ModuleFlag::None );
|
, ModuleFlag mflags = ModuleFlag_None );
|
||||||
|
|
||||||
// Constructs an empty body. Use AST::validate_body() to check if the body is was has valid entries.
|
// Constructs an empty body. Use AST::validate_body() to check if the body is was has valid entries.
|
||||||
CodeBody def_body( CodeT type );
|
CodeBody def_body( CodeT type );
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
|
ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
|
||||||
{
|
{
|
||||||
char const* buf_begin = buf;
|
char const* buf_begin = buf;
|
||||||
ssize remaining = buf_size;
|
ssize remaining = buf_size;
|
||||||
|
|
||||||
local_persist
|
local_persist
|
||||||
Arena tok_map_arena;
|
Arena tok_map_arena;
|
||||||
@ -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<StrC>::init( allocator_info(tok_map_arena) );
|
tok_map = hashtable_init<StrC>( allocator_info(tok_map_arena) );
|
||||||
|
|
||||||
s32 left = num_tokens - 1;
|
s32 left = num_tokens - 1;
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
|
|||||||
|
|
||||||
u32 key = crc32( token, str_len(token) );
|
u32 key = crc32( token, str_len(token) );
|
||||||
|
|
||||||
tok_map.set( key, value );
|
set(tok_map, key, value );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
|
|||||||
char const* token = fmt + 1;
|
char const* token = fmt + 1;
|
||||||
|
|
||||||
u32 key = crc32( token, tok_len );
|
u32 key = crc32( token, tok_len );
|
||||||
StrC* value = tok_map.get( key );
|
StrC* value = get(tok_map, key );
|
||||||
|
|
||||||
if ( value )
|
if ( value )
|
||||||
{
|
{
|
||||||
@ -94,7 +94,7 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tok_map.clear();
|
clear(tok_map);
|
||||||
free(tok_map_arena);
|
free(tok_map_arena);
|
||||||
|
|
||||||
ssize result = buf_size - remaining;
|
ssize result = buf_size - remaining;
|
||||||
|
@ -458,7 +458,7 @@ CodeComment def_comment( StrC content )
|
|||||||
|
|
||||||
static char line[ MaxCommentLineLength ];
|
static char line[ MaxCommentLineLength ];
|
||||||
|
|
||||||
String cmt_formatted = String::make_reserve( GlobalAllocator, kilobytes(1) );
|
String cmt_formatted = string_make_reserve( GlobalAllocator, kilobytes(1) );
|
||||||
char const* end = content.Ptr + content.Len;
|
char const* end = content.Ptr + content.Len;
|
||||||
char const* scanner = content.Ptr;
|
char const* scanner = content.Ptr;
|
||||||
s32 curr = 0;
|
s32 curr = 0;
|
||||||
@ -474,15 +474,15 @@ CodeComment def_comment( StrC content )
|
|||||||
length++;
|
length++;
|
||||||
|
|
||||||
str_copy( line, scanner, length );
|
str_copy( line, scanner, length );
|
||||||
cmt_formatted.append_fmt( "//%.*s", length, line );
|
append_fmt(cmt_formatted, "//%.*s", length, line );
|
||||||
mem_set( line, 0, MaxCommentLineLength );
|
mem_set( line, 0, MaxCommentLineLength );
|
||||||
|
|
||||||
scanner += length;
|
scanner += length;
|
||||||
}
|
}
|
||||||
while ( scanner <= end );
|
while ( scanner <= end );
|
||||||
|
|
||||||
if ( cmt_formatted.back() != '\n' )
|
if ( back(cmt_formatted) != '\n' )
|
||||||
cmt_formatted.append( "\n" );
|
append( cmt_formatted, "\n" );
|
||||||
|
|
||||||
Code
|
Code
|
||||||
result = make_code();
|
result = make_code();
|
||||||
@ -490,7 +490,7 @@ CodeComment def_comment( StrC content )
|
|||||||
result->Name = get_cached_string( cmt_formatted );
|
result->Name = get_cached_string( cmt_formatted );
|
||||||
result->Content = result->Name;
|
result->Content = result->Name;
|
||||||
|
|
||||||
cmt_formatted.free();
|
free(cmt_formatted);
|
||||||
|
|
||||||
return (CodeComment) result;
|
return (CodeComment) result;
|
||||||
}
|
}
|
||||||
@ -719,14 +719,14 @@ CodeEnum def_enum( StrC name
|
|||||||
return CodeInvalid;
|
return CodeInvalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
result->Type = specifier == EnumClass ?
|
result->Type = specifier == EnumDecl_Class ?
|
||||||
Enum_Class : Enum;
|
Enum_Class : Enum;
|
||||||
|
|
||||||
result->Body = body;
|
result->Body = body;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result->Type = specifier == EnumClass ?
|
result->Type = specifier == EnumDecl_Class ?
|
||||||
Enum_Class_Fwd : Enum_Fwd;
|
Enum_Class_Fwd : Enum_Fwd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1145,16 +1145,16 @@ CodePreprocessCond def_preprocess_cond( EPreprocessCond type, StrC expr )
|
|||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case EPreprocessCond::If:
|
case PreprocessCond_If:
|
||||||
result->Type = Preprocess_If;
|
result->Type = Preprocess_If;
|
||||||
break;
|
break;
|
||||||
case EPreprocessCond::IfDef:
|
case PreprocessCond_IfDef:
|
||||||
result->Type = Preprocess_IfDef;
|
result->Type = Preprocess_IfDef;
|
||||||
break;
|
break;
|
||||||
case EPreprocessCond::IfNotDef:
|
case PreprocessCond_IfNotDef:
|
||||||
result->Type = Preprocess_IfNotDef;
|
result->Type = Preprocess_IfNotDef;
|
||||||
break;
|
break;
|
||||||
case EPreprocessCond::ElIf:
|
case PreprocessCond_ElIf:
|
||||||
result->Type = Preprocess_ElIf;
|
result->Type = Preprocess_ElIf;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -89,11 +89,11 @@ struct Token
|
|||||||
|
|
||||||
String to_string()
|
String to_string()
|
||||||
{
|
{
|
||||||
String result = String::make_reserve( GlobalAllocator, kilobytes(4) );
|
String result = string_make_reserve( GlobalAllocator, kilobytes(4) );
|
||||||
|
|
||||||
StrC type_str = ETokType::to_str( Type );
|
StrC type_str = ETokType::to_str( Type );
|
||||||
|
|
||||||
result.append_fmt( "Line: %d Column: %d, Type: %.*s Content: %.*s"
|
append_fmt( result, "Line: %d Column: %d, Type: %.*s Content: %.*s"
|
||||||
, Line, Column
|
, Line, Column
|
||||||
, type_str.Len, type_str.Ptr
|
, type_str.Len, type_str.Ptr
|
||||||
, Length, Text
|
, Length, Text
|
||||||
@ -341,7 +341,7 @@ s32 lex_preprocessor_directive(
|
|||||||
append(Tokens, name );
|
append(Tokens, name );
|
||||||
|
|
||||||
u64 key = crc32( name.Text, name.Length );
|
u64 key = crc32( name.Text, name.Length );
|
||||||
defines.set( key, name );
|
set<StrC>(defines, key, name );
|
||||||
}
|
}
|
||||||
|
|
||||||
Token preprocess_content = { scanner, 0, TokType::Preprocess_Content, line, column, TF_Preprocess };
|
Token preprocess_content = { scanner, 0, TokType::Preprocess_Content, line, column, TF_Preprocess };
|
||||||
@ -352,7 +352,7 @@ s32 lex_preprocessor_directive(
|
|||||||
|
|
||||||
if ( current != '"' && current != '<' )
|
if ( current != '"' && current != '<' )
|
||||||
{
|
{
|
||||||
String directive_str = String::fmt_buf( GlobalAllocator, "%.*s", min( 80, left + preprocess_content.Length ), token.Text );
|
String directive_str = string_fmt_buf( GlobalAllocator, "%.*s", min( 80, left + preprocess_content.Length ), token.Text );
|
||||||
|
|
||||||
log_failure( "gen::Parser::lex: Expected '\"' or '<' after #include, not '%c' (%d, %d)\n%s"
|
log_failure( "gen::Parser::lex: Expected '\"' or '<' after #include, not '%c' (%d, %d)\n%s"
|
||||||
, current
|
, current
|
||||||
@ -419,8 +419,8 @@ s32 lex_preprocessor_directive(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
String directive_str = String::make_length( GlobalAllocator, token.Text, token.Length );
|
String directive_str = string_make_length( GlobalAllocator, token.Text, token.Length );
|
||||||
String content_str = String::fmt_buf( GlobalAllocator, "%.*s", min( 400, left + preprocess_content.Length ), preprocess_content.Text );
|
String content_str = string_fmt_buf( GlobalAllocator, "%.*s", min( 400, left + preprocess_content.Length ), preprocess_content.Text );
|
||||||
|
|
||||||
log_failure( "gen::Parser::lex: Invalid escape sequence '\\%c' (%d, %d)"
|
log_failure( "gen::Parser::lex: Invalid escape sequence '\\%c' (%d, %d)"
|
||||||
" in preprocessor directive '%s' (%d, %d)\n%s"
|
" in preprocessor directive '%s' (%d, %d)\n%s"
|
||||||
@ -516,7 +516,7 @@ void lex_found_token( StrC& content
|
|||||||
else
|
else
|
||||||
key = crc32( token.Text, token.Length );
|
key = crc32( token.Text, token.Length );
|
||||||
|
|
||||||
StrC* define = defines.get( key );
|
StrC* define = get(defines, key );
|
||||||
if ( define )
|
if ( define )
|
||||||
{
|
{
|
||||||
token.Type = TokType::Preprocess_Macro;
|
token.Type = TokType::Preprocess_Macro;
|
||||||
@ -586,7 +586,7 @@ TokArray lex( StrC content )
|
|||||||
{
|
{
|
||||||
s32 length = 0;
|
s32 length = 0;
|
||||||
char const* scanner = entry.Data;
|
char const* scanner = entry.Data;
|
||||||
while ( entry.length() > length && (char_is_alphanumeric( *scanner ) || *scanner == '_') )
|
while ( GEN_NS length(entry) > length && (char_is_alphanumeric( *scanner ) || *scanner == '_') )
|
||||||
{
|
{
|
||||||
scanner++;
|
scanner++;
|
||||||
length ++;
|
length ++;
|
||||||
@ -597,7 +597,7 @@ TokArray lex( StrC content )
|
|||||||
}
|
}
|
||||||
|
|
||||||
u64 key = crc32( entry.Data, length );
|
u64 key = crc32( entry.Data, length );
|
||||||
defines.set( key, entry );
|
set<StrC>(defines, key, entry );
|
||||||
}
|
}
|
||||||
|
|
||||||
clear(Tokens);
|
clear(Tokens);
|
||||||
@ -678,7 +678,7 @@ TokArray lex( StrC content )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
String context_str = String::fmt_buf( GlobalAllocator, "%s", scanner, min( 100, left ) );
|
String context_str = string_fmt_buf( GlobalAllocator, "%s", scanner, min( 100, left ) );
|
||||||
|
|
||||||
log_failure( "gen::lex: invalid varadic argument, expected '...' got '..%c' (%d, %d)\n%s", current, line, column, context_str );
|
log_failure( "gen::lex: invalid varadic argument, expected '...' got '..%c' (%d, %d)\n%s", current, line, column, context_str );
|
||||||
}
|
}
|
||||||
@ -1239,7 +1239,7 @@ TokArray lex( StrC content )
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String context_str = String::fmt_buf( GlobalAllocator, "%.*s", min( 100, left ), scanner );
|
String context_str = string_fmt_buf( GlobalAllocator, "%.*s", min( 100, left ), scanner );
|
||||||
log_failure( "Failed to lex token '%c' (%d, %d)\n%s", current, line, column, context_str );
|
log_failure( "Failed to lex token '%c' (%d, %d)\n%s", current, line, column, context_str );
|
||||||
|
|
||||||
// Skip to next whitespace since we can't know if anything else is valid until then.
|
// Skip to next whitespace since we can't know if anything else is valid until then.
|
||||||
@ -1259,7 +1259,7 @@ TokArray lex( StrC content )
|
|||||||
return { { nullptr }, 0 };
|
return { { nullptr }, 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
defines.clear();
|
clear(defines);
|
||||||
// defines_map_arena.free();
|
// defines_map_arena.free();
|
||||||
return { Tokens, 0 };
|
return { Tokens, 0 };
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ struct ParseContext
|
|||||||
|
|
||||||
String to_string()
|
String to_string()
|
||||||
{
|
{
|
||||||
String result = String::make_reserve( GlobalAllocator, kilobytes(4) );
|
String result = string_make_reserve( GlobalAllocator, kilobytes(4) );
|
||||||
|
|
||||||
Token scope_start = Scope->Start;
|
Token scope_start = Scope->Start;
|
||||||
Token last_valid = Tokens.Idx >= num(Tokens.Arr) ? Tokens.Arr[num(Tokens.Arr) -1] : Tokens.current();
|
Token last_valid = Tokens.Idx >= num(Tokens.Arr) ? Tokens.Arr[num(Tokens.Arr) -1] : Tokens.current();
|
||||||
@ -58,18 +58,18 @@ struct ParseContext
|
|||||||
length++;
|
length++;
|
||||||
}
|
}
|
||||||
|
|
||||||
String line = String::make( GlobalAllocator, { length, scope_start.Text } );
|
String line = string_make( GlobalAllocator, { length, scope_start.Text } );
|
||||||
result.append_fmt("\tScope : %s\n", line );
|
append_fmt( result, "\tScope : %s\n", line );
|
||||||
line.free();
|
free(line);
|
||||||
|
|
||||||
sptr dist = (sptr)last_valid.Text - (sptr)scope_start.Text + 2;
|
sptr dist = (sptr)last_valid.Text - (sptr)scope_start.Text + 2;
|
||||||
sptr length_from_err = dist;
|
sptr length_from_err = dist;
|
||||||
String line_from_err = String::make( GlobalAllocator, { length_from_err, last_valid.Text } );
|
String line_from_err = string_make( GlobalAllocator, { length_from_err, last_valid.Text } );
|
||||||
|
|
||||||
if ( length_from_err < 100 )
|
if ( length_from_err < 100 )
|
||||||
result.append_fmt("\t(%d, %d):%*c\n", last_valid.Line, last_valid.Column, length_from_err, '^' );
|
append_fmt(result, "\t(%d, %d):%*c\n", last_valid.Line, last_valid.Column, length_from_err, '^' );
|
||||||
else
|
else
|
||||||
result.append_fmt("\t(%d, %d)\n", last_valid.Line, last_valid.Column );
|
append_fmt(result, "\t(%d, %d)\n", last_valid.Line, last_valid.Column );
|
||||||
|
|
||||||
StackNode* curr_scope = Scope;
|
StackNode* curr_scope = Scope;
|
||||||
s32 level = 0;
|
s32 level = 0;
|
||||||
@ -77,11 +77,11 @@ struct ParseContext
|
|||||||
{
|
{
|
||||||
if ( curr_scope->Name )
|
if ( curr_scope->Name )
|
||||||
{
|
{
|
||||||
result.append_fmt("\t%d: %s, AST Name: %.*s\n", level, curr_scope->ProcName.Ptr, curr_scope->Name.Length, curr_scope->Name.Text );
|
append_fmt(result, "\t%d: %s, AST Name: %.*s\n", level, curr_scope->ProcName.Ptr, curr_scope->Name.Length, curr_scope->Name.Text );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result.append_fmt("\t%d: %s\n", level, curr_scope->ProcName.Ptr );
|
append_fmt(result, "\t%d: %s\n", level, curr_scope->ProcName.Ptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
curr_scope = curr_scope->Prev;
|
curr_scope = curr_scope->Prev;
|
||||||
@ -137,7 +137,7 @@ void init()
|
|||||||
);
|
);
|
||||||
|
|
||||||
fixed_arena_init(defines_map_arena);
|
fixed_arena_init(defines_map_arena);
|
||||||
defines = HashTable<StrC>::init_reserve( allocator_info(defines_map_arena), 256 );
|
defines = hashtable_init_reserve<StrC>( allocator_info(defines_map_arena), 256 );
|
||||||
}
|
}
|
||||||
|
|
||||||
internal
|
internal
|
||||||
@ -243,7 +243,7 @@ constexpr bool strip_formatting_dont_preserve_newlines = false;
|
|||||||
internal
|
internal
|
||||||
String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
||||||
{
|
{
|
||||||
String content = String::make_reserve( GlobalAllocator, raw_text.Len );
|
String content = string_make_reserve( GlobalAllocator, raw_text.Len );
|
||||||
|
|
||||||
if ( raw_text.Len == 0 )
|
if ( raw_text.Len == 0 )
|
||||||
return content;
|
return content;
|
||||||
@ -290,7 +290,7 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
if ( tokleft )
|
if ( tokleft )
|
||||||
move_fwd();
|
move_fwd();
|
||||||
|
|
||||||
content.append( cut_ptr, cut_length );
|
append( content, cut_ptr, cut_length );
|
||||||
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -312,7 +312,7 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
if ( tokleft )
|
if ( tokleft )
|
||||||
move_fwd();
|
move_fwd();
|
||||||
|
|
||||||
content.append( cut_ptr, cut_length );
|
append( content, cut_ptr, cut_length );
|
||||||
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -326,7 +326,7 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
scanner += 2;
|
scanner += 2;
|
||||||
tokleft -= 2;
|
tokleft -= 2;
|
||||||
|
|
||||||
content.append( cut_ptr, cut_length );
|
append( content, cut_ptr, cut_length );
|
||||||
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -345,7 +345,7 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
if (tokleft)
|
if (tokleft)
|
||||||
move_fwd();
|
move_fwd();
|
||||||
|
|
||||||
content.append( cut_ptr, cut_length );
|
append( content, cut_ptr, cut_length );
|
||||||
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -354,10 +354,10 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
if (scanner[0] == '\t')
|
if (scanner[0] == '\t')
|
||||||
{
|
{
|
||||||
if (pos > last_cut)
|
if (pos > last_cut)
|
||||||
content.append(cut_ptr, cut_length);
|
append( content, cut_ptr, cut_length);
|
||||||
|
|
||||||
if ( content.back() != ' ' )
|
if ( back( content ) != ' ' )
|
||||||
content.append(' ');
|
append( content, ' ');
|
||||||
|
|
||||||
move_fwd();
|
move_fwd();
|
||||||
last_cut = sptr(scanner) - sptr(raw_text.Ptr);
|
last_cut = sptr(scanner) - sptr(raw_text.Ptr);
|
||||||
@ -373,17 +373,17 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
scanner += 2;
|
scanner += 2;
|
||||||
tokleft -= 2;
|
tokleft -= 2;
|
||||||
|
|
||||||
content.append( cut_ptr, cut_length );
|
append( content, cut_ptr, cut_length );
|
||||||
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pos > last_cut )
|
if ( pos > last_cut )
|
||||||
content.append( cut_ptr, cut_length );
|
append( content, cut_ptr, cut_length );
|
||||||
|
|
||||||
// Replace with a space
|
// Replace with a space
|
||||||
if ( content.back() != ' ' )
|
if ( back( content ) != ' ' )
|
||||||
content.append( ' ' );
|
append( content, ' ' );
|
||||||
|
|
||||||
scanner += 2;
|
scanner += 2;
|
||||||
tokleft -= 2;
|
tokleft -= 2;
|
||||||
@ -400,17 +400,17 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
|
|
||||||
move_fwd();
|
move_fwd();
|
||||||
|
|
||||||
content.append( cut_ptr, cut_length );
|
append( content, cut_ptr, cut_length );
|
||||||
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pos > last_cut )
|
if ( pos > last_cut )
|
||||||
content.append( cut_ptr, cut_length );
|
append( content, cut_ptr, cut_length );
|
||||||
|
|
||||||
// Replace with a space
|
// Replace with a space
|
||||||
if ( content.back() != ' ' )
|
if ( back( content ) != ' ' )
|
||||||
content.append( ' ' );
|
append( content, ' ' );
|
||||||
|
|
||||||
move_fwd();
|
move_fwd();
|
||||||
|
|
||||||
@ -421,7 +421,7 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
// Escaped newlines
|
// Escaped newlines
|
||||||
if ( scanner[0] == '\\' )
|
if ( scanner[0] == '\\' )
|
||||||
{
|
{
|
||||||
content.append( cut_ptr, cut_length );
|
append( content, cut_ptr, cut_length );
|
||||||
|
|
||||||
s32 amount_to_skip = 1;
|
s32 amount_to_skip = 1;
|
||||||
if ( tokleft > 1 && scanner[1] == '\n' )
|
if ( tokleft > 1 && scanner[1] == '\n' )
|
||||||
@ -448,7 +448,7 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
// Consectuive spaces
|
// Consectuive spaces
|
||||||
if ( tokleft > 1 && char_is_space( scanner[0] ) && char_is_space( scanner[ 1 ] ) )
|
if ( tokleft > 1 && char_is_space( scanner[0] ) && char_is_space( scanner[ 1 ] ) )
|
||||||
{
|
{
|
||||||
content.append( cut_ptr, cut_length );
|
append( content, cut_ptr, cut_length );
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
move_fwd();
|
move_fwd();
|
||||||
@ -458,8 +458,8 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
last_cut = sptr( scanner ) - sptr( raw_text.Ptr );
|
||||||
|
|
||||||
// Preserve only 1 space of formattting
|
// Preserve only 1 space of formattting
|
||||||
if ( content.back() != ' ' )
|
if ( back( content ) != ' ' )
|
||||||
content.append( ' ' );
|
append( content, ' ' );
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -469,7 +469,7 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true )
|
|||||||
|
|
||||||
if ( last_cut < raw_text.Len )
|
if ( last_cut < raw_text.Len )
|
||||||
{
|
{
|
||||||
content.append( cut_ptr, raw_text.Len - last_cut );
|
append( content, cut_ptr, raw_text.Len - last_cut );
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef cut_ptr
|
#undef cut_ptr
|
||||||
@ -682,17 +682,17 @@ Code parse_class_struct( TokType which, bool inplace_def = false )
|
|||||||
|
|
||||||
Token name { nullptr, 0, TokType::Invalid };
|
Token name { nullptr, 0, TokType::Invalid };
|
||||||
|
|
||||||
AccessSpec access = AccessSpec::Default;
|
AccessSpec access = AccessSpec_Default;
|
||||||
CodeType parent = { nullptr };
|
CodeType parent = { nullptr };
|
||||||
CodeBody body = { nullptr };
|
CodeBody body = { nullptr };
|
||||||
CodeAttributes attributes = { nullptr };
|
CodeAttributes attributes = { nullptr };
|
||||||
ModuleFlag mflags = ModuleFlag::None;
|
ModuleFlag mflags = ModuleFlag_None;
|
||||||
|
|
||||||
CodeClass result = CodeInvalid;
|
CodeClass result = CodeInvalid;
|
||||||
|
|
||||||
if ( check(TokType::Module_Export) )
|
if ( check(TokType::Module_Export) )
|
||||||
{
|
{
|
||||||
mflags = ModuleFlag::Export;
|
mflags = ModuleFlag_Export;
|
||||||
eat( TokType::Module_Export );
|
eat( TokType::Module_Export );
|
||||||
}
|
}
|
||||||
// <ModuleFlags>
|
// <ModuleFlags>
|
||||||
@ -1039,8 +1039,8 @@ CodeBody parse_class_struct_body( TokType which, Token name )
|
|||||||
|
|
||||||
if ( attributes )
|
if ( attributes )
|
||||||
{
|
{
|
||||||
String fused = String::make_reserve( GlobalAllocator, attributes->Content.length() + more_attributes->Content.length() );
|
String fused = string_make_reserve( GlobalAllocator, length(attributes->Content) + length(more_attributes->Content) );
|
||||||
fused.append_fmt( "%S %S", attributes->Content, more_attributes->Content );
|
append_fmt( fused, "%S %S", attributes->Content, more_attributes->Content );
|
||||||
|
|
||||||
attributes->Name = get_cached_string(fused);
|
attributes->Name = get_cached_string(fused);
|
||||||
attributes->Content = attributes->Name;
|
attributes->Content = attributes->Name;
|
||||||
@ -1484,8 +1484,8 @@ CodeFn parse_function_after_name(
|
|||||||
using namespace ECode;
|
using namespace ECode;
|
||||||
|
|
||||||
String
|
String
|
||||||
name_stripped = String::make( GlobalAllocator, name );
|
name_stripped = string_make( GlobalAllocator, name );
|
||||||
name_stripped.strip_space();
|
strip_space(name_stripped);
|
||||||
|
|
||||||
CodeFn
|
CodeFn
|
||||||
result = (CodeFn) make_code();
|
result = (CodeFn) make_code();
|
||||||
@ -2534,7 +2534,7 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes
|
|||||||
if ( found_operator )
|
if ( found_operator )
|
||||||
{
|
{
|
||||||
// Dealing with an operator overload
|
// Dealing with an operator overload
|
||||||
result = parse_operator_after_ret_type( ModuleFlag::None, attributes, specifiers, type );
|
result = parse_operator_after_ret_type( ModuleFlag_None, attributes, specifiers, type );
|
||||||
// <Attributes> <Specifiers> <ReturnType> operator ...
|
// <Attributes> <Specifiers> <ReturnType> operator ...
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2552,7 +2552,7 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes
|
|||||||
if ( detected_capture && ! detected_comma )
|
if ( detected_capture && ! detected_comma )
|
||||||
{
|
{
|
||||||
// Dealing with a function
|
// Dealing with a function
|
||||||
result = parse_function_after_name( ModuleFlag::None, attributes, specifiers, type, name );
|
result = parse_function_after_name( ModuleFlag_None, attributes, specifiers, type, name );
|
||||||
// <Attributes> <Specifiers> <ReturnType> <Name> ( ...
|
// <Attributes> <Specifiers> <ReturnType> <Name> ( ...
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2565,7 +2565,7 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dealing with a variable
|
// Dealing with a variable
|
||||||
result = parse_variable_after_name( ModuleFlag::None, attributes, specifiers, type, name );
|
result = parse_variable_after_name( ModuleFlag_None, attributes, specifiers, type, name );
|
||||||
// <Attributes> <Specifiers> <ValueType> <Name> ...
|
// <Attributes> <Specifiers> <ValueType> <Name> ...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3319,7 +3319,7 @@ CodeVar parse_variable_declaration_list()
|
|||||||
eat( TokType::Identifier );
|
eat( TokType::Identifier );
|
||||||
// , <Specifiers> <Name>
|
// , <Specifiers> <Name>
|
||||||
|
|
||||||
CodeVar var = parse_variable_after_name( ModuleFlag::None, NoCode, specifiers, NoCode, name );
|
CodeVar var = parse_variable_after_name( ModuleFlag_None, NoCode, specifiers, NoCode, name );
|
||||||
// , <Specifiers> <Name> ...
|
// , <Specifiers> <Name> ...
|
||||||
|
|
||||||
if ( ! result )
|
if ( ! result )
|
||||||
@ -3589,6 +3589,8 @@ CodeEnum parse_enum( bool inplace_def )
|
|||||||
}
|
}
|
||||||
// enum <class> <Attributes> <Name>
|
// enum <class> <Attributes> <Name>
|
||||||
|
|
||||||
|
b32 use_macro_underlying = false;
|
||||||
|
Code underlying_macro = { nullptr };
|
||||||
if ( currtok.Type == TokType::Assign_Classifer )
|
if ( currtok.Type == TokType::Assign_Classifer )
|
||||||
{
|
{
|
||||||
eat( TokType::Assign_Classifer );
|
eat( TokType::Assign_Classifer );
|
||||||
@ -3603,6 +3605,17 @@ CodeEnum parse_enum( bool inplace_def )
|
|||||||
}
|
}
|
||||||
// enum <class> <Attributes> <Name> : <UnderlyingType>
|
// enum <class> <Attributes> <Name> : <UnderlyingType>
|
||||||
}
|
}
|
||||||
|
else if ( currtok.Type == TokType::Preprocess_Define )
|
||||||
|
{
|
||||||
|
// We'll support the enum_underlying macro
|
||||||
|
StrC sig = txt("enum_underlying");
|
||||||
|
|
||||||
|
if (currtok.Length >= sig.Len && str_compare(currtok.Text, sig.Ptr, sig.Len) == 0 )
|
||||||
|
{
|
||||||
|
use_macro_underlying = true;
|
||||||
|
underlying_macro = parse_simple_preprocess( ETokType::Preprocess_Macro);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CodeBody body = { nullptr };
|
CodeBody body = { nullptr };
|
||||||
|
|
||||||
@ -3770,11 +3783,18 @@ CodeEnum parse_enum( bool inplace_def )
|
|||||||
result->Attributes = attributes;
|
result->Attributes = attributes;
|
||||||
|
|
||||||
if ( type )
|
if ( type )
|
||||||
result->UnderlyingType = type;
|
{
|
||||||
|
result->EnumUnderlyingMacro = use_macro_underlying;
|
||||||
|
if ( use_macro_underlying )
|
||||||
|
result->UnderlyingTypeMacro = underlying_macro;
|
||||||
|
else
|
||||||
|
result->UnderlyingType = type;
|
||||||
|
}
|
||||||
|
|
||||||
if ( inline_cmt )
|
if ( inline_cmt )
|
||||||
result->InlineCmt = inline_cmt;
|
result->InlineCmt = inline_cmt;
|
||||||
|
|
||||||
|
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -3860,7 +3880,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, NoCode, NoCode, type, name );
|
function = parse_function_after_name( ModuleFlag_None, NoCode, NoCode, type, name );
|
||||||
|
|
||||||
// Parameter list
|
// Parameter list
|
||||||
// CodeParam params = parse_params();
|
// CodeParam params = parse_params();
|
||||||
@ -3914,11 +3934,11 @@ CodeFn parse_function()
|
|||||||
|
|
||||||
CodeAttributes attributes = { nullptr };
|
CodeAttributes attributes = { nullptr };
|
||||||
CodeSpecifiers specifiers = { nullptr };
|
CodeSpecifiers specifiers = { nullptr };
|
||||||
ModuleFlag mflags = ModuleFlag::None;
|
ModuleFlag mflags = ModuleFlag_None;
|
||||||
|
|
||||||
if ( check(TokType::Module_Export) )
|
if ( check(TokType::Module_Export) )
|
||||||
{
|
{
|
||||||
mflags = ModuleFlag::Export;
|
mflags = ModuleFlag_Export;
|
||||||
eat( TokType::Module_Export );
|
eat( TokType::Module_Export );
|
||||||
}
|
}
|
||||||
// <export>
|
// <export>
|
||||||
@ -4024,14 +4044,14 @@ CodeOperator parse_operator()
|
|||||||
|
|
||||||
CodeAttributes attributes = { nullptr };
|
CodeAttributes attributes = { nullptr };
|
||||||
CodeSpecifiers specifiers = { nullptr };
|
CodeSpecifiers specifiers = { nullptr };
|
||||||
ModuleFlag mflags = ModuleFlag::None;
|
ModuleFlag mflags = ModuleFlag_None;
|
||||||
|
|
||||||
SpecifierT specs_found[16] { ESpecifier::NumSpecifiers };
|
SpecifierT specs_found[16] { ESpecifier::NumSpecifiers };
|
||||||
s32 NumSpecifiers = 0;
|
s32 NumSpecifiers = 0;
|
||||||
|
|
||||||
if ( check(TokType::Module_Export) )
|
if ( check(TokType::Module_Export) )
|
||||||
{
|
{
|
||||||
mflags = ModuleFlag::Export;
|
mflags = ModuleFlag_Export;
|
||||||
eat( TokType::Module_Export );
|
eat( TokType::Module_Export );
|
||||||
}
|
}
|
||||||
// <export>
|
// <export>
|
||||||
@ -4114,7 +4134,7 @@ CodeOpCast parse_operator_cast( CodeSpecifiers specifiers )
|
|||||||
Code type = parse_type();
|
Code type = parse_type();
|
||||||
// <Specifiers> <Qualifier> :: ... operator <UnderlyingType>
|
// <Specifiers> <Qualifier> :: ... operator <UnderlyingType>
|
||||||
|
|
||||||
Context.Scope->Name = { type->Name.Data, type->Name.length() };
|
Context.Scope->Name = { type->Name.Data, length(type->Name) };
|
||||||
|
|
||||||
eat( TokType::Capture_Start );
|
eat( TokType::Capture_Start );
|
||||||
eat( TokType::Capture_End );
|
eat( TokType::Capture_End );
|
||||||
@ -4212,11 +4232,11 @@ CodeTemplate parse_template()
|
|||||||
|
|
||||||
push_scope();
|
push_scope();
|
||||||
|
|
||||||
ModuleFlag mflags = ModuleFlag::None;
|
ModuleFlag mflags = ModuleFlag_None;
|
||||||
|
|
||||||
if ( check( TokType::Module_Export ) )
|
if ( check( TokType::Module_Export ) )
|
||||||
{
|
{
|
||||||
mflags = ModuleFlag::Export;
|
mflags = ModuleFlag_Export;
|
||||||
eat( TokType::Module_Export );
|
eat( TokType::Module_Export );
|
||||||
}
|
}
|
||||||
// <export> template
|
// <export> template
|
||||||
@ -4855,11 +4875,11 @@ CodeTypedef parse_typedef()
|
|||||||
Code array_expr = { nullptr };
|
Code array_expr = { nullptr };
|
||||||
Code type = { nullptr };
|
Code type = { nullptr };
|
||||||
|
|
||||||
ModuleFlag mflags = ModuleFlag::None;
|
ModuleFlag mflags = ModuleFlag_None;
|
||||||
|
|
||||||
if ( check(TokType::Module_Export) )
|
if ( check(TokType::Module_Export) )
|
||||||
{
|
{
|
||||||
mflags = ModuleFlag::Export;
|
mflags = ModuleFlag_Export;
|
||||||
eat( TokType::Module_Export );
|
eat( TokType::Module_Export );
|
||||||
}
|
}
|
||||||
// <ModuleFlags>
|
// <ModuleFlags>
|
||||||
@ -5050,11 +5070,11 @@ CodeUnion parse_union( bool inplace_def )
|
|||||||
{
|
{
|
||||||
push_scope();
|
push_scope();
|
||||||
|
|
||||||
ModuleFlag mflags = ModuleFlag::None;
|
ModuleFlag mflags = ModuleFlag_None;
|
||||||
|
|
||||||
if ( check(TokType::Module_Export) )
|
if ( check(TokType::Module_Export) )
|
||||||
{
|
{
|
||||||
mflags = ModuleFlag::Export;
|
mflags = ModuleFlag_Export;
|
||||||
eat( TokType::Module_Export );
|
eat( TokType::Module_Export );
|
||||||
}
|
}
|
||||||
// <ModuleFlags>
|
// <ModuleFlags>
|
||||||
@ -5199,12 +5219,12 @@ CodeUsing parse_using()
|
|||||||
|
|
||||||
bool is_namespace = false;
|
bool is_namespace = false;
|
||||||
|
|
||||||
ModuleFlag mflags = ModuleFlag::None;
|
ModuleFlag mflags = ModuleFlag_None;
|
||||||
CodeAttributes attributes = { nullptr };
|
CodeAttributes attributes = { nullptr };
|
||||||
|
|
||||||
if ( check(TokType::Module_Export) )
|
if ( check(TokType::Module_Export) )
|
||||||
{
|
{
|
||||||
mflags = ModuleFlag::Export;
|
mflags = ModuleFlag_Export;
|
||||||
eat( TokType::Module_Export );
|
eat( TokType::Module_Export );
|
||||||
}
|
}
|
||||||
// <ModuleFlags>
|
// <ModuleFlags>
|
||||||
@ -5293,13 +5313,13 @@ CodeVar parse_variable()
|
|||||||
SpecifierT specs_found[16] { ESpecifier::NumSpecifiers };
|
SpecifierT specs_found[16] { ESpecifier::NumSpecifiers };
|
||||||
s32 NumSpecifiers = 0;
|
s32 NumSpecifiers = 0;
|
||||||
|
|
||||||
ModuleFlag mflags = ModuleFlag::None;
|
ModuleFlag mflags = ModuleFlag_None;
|
||||||
CodeAttributes attributes = { nullptr };
|
CodeAttributes attributes = { nullptr };
|
||||||
CodeSpecifiers specifiers = { nullptr };
|
CodeSpecifiers specifiers = { nullptr };
|
||||||
|
|
||||||
if ( check(TokType::Module_Export) )
|
if ( check(TokType::Module_Export) )
|
||||||
{
|
{
|
||||||
mflags = ModuleFlag::Export;
|
mflags = ModuleFlag_Export;
|
||||||
eat( TokType::Module_Export );
|
eat( TokType::Module_Export );
|
||||||
}
|
}
|
||||||
// <ModuleFlags>
|
// <ModuleFlags>
|
||||||
|
@ -13,63 +13,71 @@ using LogFailType = ssize(*)(char const*, ...);
|
|||||||
#define log_failure GEN_FATAL
|
#define log_failure GEN_FATAL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum class AccessSpec : u32
|
enum AccessSpec enum_underlying(u32)
|
||||||
{
|
{
|
||||||
Default,
|
AccessSpec_Default,
|
||||||
Private,
|
AccessSpec_Private,
|
||||||
Protected,
|
AccessSpec_Protected,
|
||||||
Public,
|
AccessSpec_Public,
|
||||||
|
|
||||||
Num_AccessSpec,
|
AccessSpec_Num_AccessSpec,
|
||||||
Invalid,
|
AccessSpec_Invalid,
|
||||||
|
|
||||||
|
AccessSpec_SizeDef = GEN_U32_MAX,
|
||||||
};
|
};
|
||||||
|
static_assert( size_of(AccessSpec) == size_of(u32));
|
||||||
|
|
||||||
inline
|
inline
|
||||||
char const* to_str( AccessSpec type )
|
char const* to_str( AccessSpec type )
|
||||||
{
|
{
|
||||||
local_persist
|
local_persist
|
||||||
char const* lookup[ (u32)AccessSpec::Num_AccessSpec ] = {
|
char const* lookup[ (u32)AccessSpec_Num_AccessSpec ] = {
|
||||||
"",
|
"",
|
||||||
"private",
|
"private",
|
||||||
"protected",
|
"protected",
|
||||||
"public",
|
"public",
|
||||||
};
|
};
|
||||||
|
|
||||||
if ( type > AccessSpec::Public )
|
if ( type > AccessSpec_Public )
|
||||||
return "Invalid";
|
return "Invalid";
|
||||||
|
|
||||||
return lookup[ (u32)type ];
|
return lookup[ (u32)type ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum CodeFlag enum_underlying(u32)
|
||||||
enum CodeFlag : u32
|
|
||||||
{
|
{
|
||||||
None = 0,
|
CodeFlag_None = 0,
|
||||||
FunctionType = bit(0),
|
CodeFlag_FunctionType = bit(0),
|
||||||
ParamPack = bit(1),
|
CodeFlag_ParamPack = bit(1),
|
||||||
Module_Export = bit(2),
|
CodeFlag_Module_Export = bit(2),
|
||||||
Module_Import = bit(3),
|
CodeFlag_Module_Import = bit(3),
|
||||||
|
|
||||||
|
CodeFlag_SizeDef = GEN_U32_MAX,
|
||||||
};
|
};
|
||||||
|
static_assert( size_of(CodeFlag) == size_of(u32));
|
||||||
|
|
||||||
// Used to indicate if enum definitoin is an enum class or regular enum.
|
// Used to indicate if enum definitoin is an enum class or regular enum.
|
||||||
enum class EnumT : u8
|
enum EnumDecl enum_underlying(u8)
|
||||||
{
|
{
|
||||||
Regular,
|
EnumDecl_Regular,
|
||||||
Class
|
EnumDecl_Class,
|
||||||
|
|
||||||
|
EnumT_SizeDef = GEN_U8_MAX,
|
||||||
};
|
};
|
||||||
|
typedef u8 EnumT;
|
||||||
|
|
||||||
constexpr EnumT EnumClass = EnumT::Class;
|
enum ModuleFlag enum_underlying(u32)
|
||||||
constexpr EnumT EnumRegular = EnumT::Regular;
|
|
||||||
|
|
||||||
enum class ModuleFlag : u32
|
|
||||||
{
|
{
|
||||||
None = 0,
|
ModuleFlag_None = 0,
|
||||||
Export = bit(0),
|
ModuleFlag_Export = bit(0),
|
||||||
Import = bit(1),
|
ModuleFlag_Import = bit(1),
|
||||||
|
|
||||||
Num_ModuleFlags,
|
Num_ModuleFlags,
|
||||||
Invalid,
|
ModuleFlag_Invalid,
|
||||||
|
|
||||||
|
ModuleFlag_SizeDef = GEN_U32_MAX,
|
||||||
};
|
};
|
||||||
|
static_assert( size_of(ModuleFlag) == size_of(u32));
|
||||||
|
|
||||||
inline
|
inline
|
||||||
StrC to_str( ModuleFlag flag )
|
StrC to_str( ModuleFlag flag )
|
||||||
@ -81,7 +89,7 @@ StrC to_str( ModuleFlag flag )
|
|||||||
{ sizeof("import"), "import" },
|
{ sizeof("import"), "import" },
|
||||||
};
|
};
|
||||||
|
|
||||||
if ( flag > ModuleFlag::Import )
|
if ( flag > ModuleFlag_Import )
|
||||||
return { sizeof("invalid"), "invalid" };
|
return { sizeof("invalid"), "invalid" };
|
||||||
|
|
||||||
return lookup[ (u32)flag ];
|
return lookup[ (u32)flag ];
|
||||||
@ -93,15 +101,13 @@ ModuleFlag operator|( ModuleFlag A, ModuleFlag B)
|
|||||||
return (ModuleFlag)( (u32)A | (u32)B );
|
return (ModuleFlag)( (u32)A | (u32)B );
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class EPreprocessCond : u32
|
enum EPreprocessCond enum_underlying(u32)
|
||||||
{
|
{
|
||||||
If,
|
PreprocessCond_If,
|
||||||
IfDef,
|
PreprocessCond_IfDef,
|
||||||
IfNotDef,
|
PreprocessCond_IfNotDef,
|
||||||
ElIf
|
PreprocessCond_ElIf,
|
||||||
};
|
|
||||||
|
|
||||||
constexpr EPreprocessCond PreprocessCond_If = EPreprocessCond::If;
|
EPreprocessCond_SizeDef = GEN_U32_MAX,
|
||||||
constexpr EPreprocessCond PreprocessCond_IfDef = EPreprocessCond::IfDef;
|
};
|
||||||
constexpr EPreprocessCond PreprocessCond_IfNotDef = EPreprocessCond::IfNotDef;
|
static_assert( size_of(EPreprocessCond) == size_of(u32));
|
||||||
constexpr EPreprocessCond PreprocessCond_ElIf = EPreprocessCond::ElIf;
|
|
||||||
|
@ -352,6 +352,28 @@ bool set_capacity(Array<Type>& array, usize new_capacity)
|
|||||||
Data = rcast(Type*, new_header + 1);
|
Data = rcast(Type*, new_header + 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define array_init(Type, allocator) array_init<Type>(allocator)
|
||||||
|
#define array_init(Type, allocator) array_init<Type>(allocator)
|
||||||
|
#define array_init_reserve(Type, allocator, capacity) array_init_reserve<Type>(allocator, capacity)
|
||||||
|
#define array_append(Type, array, other) append<Type>(array, other)
|
||||||
|
#define array_append_value(Type, array, value) append<Type>(array, value)
|
||||||
|
#define array_append_items(Type, array, items, item_num) append<Type>(array, items, item_num)
|
||||||
|
#define array_append_at(Type, array, item, idx) append_at<Type>(array, item, idx)
|
||||||
|
#define array_append_items_at(Type, array, items, num, idx) append_at<Type>(array, items, num, idx)
|
||||||
|
#define array_back(Type, array) back<Type>(array)
|
||||||
|
#define array_clear(Type, array) clear<Type>(array)
|
||||||
|
#define array_fill(Type, array, begin, end, value) fill<Type>(array, begin, end, value)
|
||||||
|
#define array_free(Type, array) free<Type>(array)
|
||||||
|
#define array_grow(Type, array, min_capacity) grow<Type>(array, min_capacity)
|
||||||
|
#define array_num(Type, array) num<Type>(array)
|
||||||
|
#define array_pop(Type, array) pop<Type>(array)
|
||||||
|
#define array_remove_at(Type, array, idx) remove_at<Type>(array, idx)
|
||||||
|
#define array_reserve(Type, array, new_capacity) reserve<Type>(array, new_capacity)
|
||||||
|
#define array_resize(Type, array, num) resize<Type>(array, num)
|
||||||
|
#define array_set_capacity(Type, array, new_capacity) set_capacity<Type>(array, new_capacity)
|
||||||
|
#define array_get_header(array) get_header(array)
|
||||||
|
|
||||||
#pragma endregion Array
|
#pragma endregion Array
|
||||||
|
|
||||||
// TODO(Ed) : This thing needs ALOT of work.
|
// TODO(Ed) : This thing needs ALOT of work.
|
||||||
@ -372,7 +394,8 @@ struct HashTableEntry {
|
|||||||
Type Value;
|
Type Value;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Forward declarations for all lifted functions
|
#define HashTableEntry(Type) HashTableEntry<Type>
|
||||||
|
|
||||||
template<class Type> HashTable<Type> hashtable_init(AllocatorInfo allocator);
|
template<class Type> HashTable<Type> hashtable_init(AllocatorInfo allocator);
|
||||||
template<class Type> HashTable<Type> hashtable_init_reserve(AllocatorInfo allocator, usize num);
|
template<class Type> HashTable<Type> hashtable_init_reserve(AllocatorInfo allocator, usize num);
|
||||||
template<class Type> void clear(HashTable<Type>& table);
|
template<class Type> void clear(HashTable<Type>& table);
|
||||||
@ -399,7 +422,7 @@ struct HashTable
|
|||||||
Array<ssize> Hashes;
|
Array<ssize> Hashes;
|
||||||
Array<HashTableEntry<Type>> Entries;
|
Array<HashTableEntry<Type>> Entries;
|
||||||
|
|
||||||
#if 1
|
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||||
#pragma region Member Mapping
|
#pragma region Member Mapping
|
||||||
forceinline static HashTable init(AllocatorInfo allocator) { return GEN_NS hashtable_init<Type>(allocator); }
|
forceinline static HashTable init(AllocatorInfo allocator) { return GEN_NS hashtable_init<Type>(allocator); }
|
||||||
forceinline static HashTable init_reserve(AllocatorInfo allocator, usize num) { return GEN_NS hashtable_init_reserve<Type>(allocator, num); }
|
forceinline static HashTable init_reserve(AllocatorInfo allocator, usize num) { return GEN_NS hashtable_init_reserve<Type>(allocator, num); }
|
||||||
@ -634,6 +657,25 @@ bool full(HashTable<Type>& table) {
|
|||||||
b32 result = num(table.Entries) > critical_load;
|
b32 result = num(table.Entries) > critical_load;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define hashtable_init(Type, allocator) hashtable_init<Type>(allocator)
|
||||||
|
#define hashtable_init_reserve(Type, allocator, num) hashtable_init_reserve<Type>(allocator, num)
|
||||||
|
#define hashtable_clear(Type, table) clear<Type>(table)
|
||||||
|
#define hashtable_destroy(Type, table) destroy<Type>(table)
|
||||||
|
#define hashtable_get(Type, table, key) get<Type>(table, key)
|
||||||
|
#define hashtable_grow(Type, table) grow<Type>(table)
|
||||||
|
#define hashtable_rehash(Type, table, new_num) rehash<Type>(table, new_num)
|
||||||
|
#define hashtable_rehash_fast(Type, table) rehash_fast<Type>(table)
|
||||||
|
#define hashtable_remove(Type, table, key) remove<Type>(table, key)
|
||||||
|
#define hashtable_remove_entry(Type, table, idx) remove_entry<Type>(table, idx)
|
||||||
|
#define hashtable_set(Type, table, key, value) set<Type>(table, key, value)
|
||||||
|
#define hashtable_slot(Type, table, key) slot<Type>(table, key)
|
||||||
|
#define hashtable_add_entry(Type, table, key) add_entry<Type>(table, key)
|
||||||
|
#define hashtable_find(Type, table, key) find<Type>(table, key)
|
||||||
|
#define hashtable_full(Type, table) full<Type>(table)
|
||||||
|
#define hashtable_map(Type, table, map_proc) map<Type>(table, map_proc)
|
||||||
|
#define hashtable_map_mut(Type, table, map_proc) map_mut<Type>(table, map_proc)
|
||||||
|
|
||||||
#pragma endregion HashTable
|
#pragma endregion HashTable
|
||||||
|
|
||||||
#pragma endregion Containers
|
#pragma endregion Containers
|
||||||
|
@ -205,4 +205,14 @@
|
|||||||
# define foreach(Type, entry_id, iterable) for ( Type entry_id : iterable )
|
# define foreach(Type, entry_id, iterable) for ( Type entry_id : iterable )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if GENC_COMPILERC
|
||||||
|
# if __STDC_VERSION__ >= 202311L
|
||||||
|
# define enum_underlying(type) : type
|
||||||
|
# else
|
||||||
|
# define enum_underlying(type)
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define enum_underlying(type) : type
|
||||||
|
#endif
|
||||||
|
|
||||||
#pragma endregion Macros
|
#pragma endregion Macros
|
||||||
|
@ -447,7 +447,7 @@ char* adt_parse_number_strict( ADT_Node* node, char* base_str )
|
|||||||
while ( *e )
|
while ( *e )
|
||||||
++e;
|
++e;
|
||||||
|
|
||||||
while ( *p && ( str_find( "eE.+-", *p ) || char_is_hex_digit( *p ) ) )
|
while ( *p && ( char_first_occurence( "eE.+-", *p ) || char_is_hex_digit( *p ) ) )
|
||||||
{
|
{
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
@ -476,7 +476,7 @@ char* adt_parse_number( ADT_Node* node, char* base_str )
|
|||||||
u8 node_props = 0;
|
u8 node_props = 0;
|
||||||
|
|
||||||
/* skip false positives and special cases */
|
/* skip false positives and special cases */
|
||||||
if ( ! ! str_find( "eE", *p ) || ( ! ! str_find( ".+-", *p ) && ! char_is_hex_digit( *( p + 1 ) ) && *( p + 1 ) != '.' ) )
|
if ( ! ! char_first_occurence( "eE", *p ) || ( ! ! char_first_occurence( ".+-", *p ) && ! char_is_hex_digit( *( p + 1 ) ) && *( p + 1 ) != '.' ) )
|
||||||
{
|
{
|
||||||
return ++base_str;
|
return ++base_str;
|
||||||
}
|
}
|
||||||
@ -552,7 +552,7 @@ char* adt_parse_number( ADT_Node* node, char* base_str )
|
|||||||
char expbuf[ 6 ] = { 0 };
|
char expbuf[ 6 ] = { 0 };
|
||||||
ssize expi = 0;
|
ssize expi = 0;
|
||||||
|
|
||||||
if ( *e && ! ! str_find( "eE", *e ) )
|
if ( *e && ! ! char_first_occurence( "eE", *e ) )
|
||||||
{
|
{
|
||||||
++e;
|
++e;
|
||||||
if ( *e == '+' || *e == '-' || char_is_digit( *e ) )
|
if ( *e == '+' || *e == '-' || char_is_digit( *e ) )
|
||||||
@ -748,7 +748,7 @@ ADT_Error adt_print_string( FileInfo* file, ADT_Node* node, char const* escaped_
|
|||||||
{
|
{
|
||||||
p = str_skip_any( p, escaped_chars );
|
p = str_skip_any( p, escaped_chars );
|
||||||
_adt_fprintf( file, "%.*s", pointer_diff( b, p ), b );
|
_adt_fprintf( file, "%.*s", pointer_diff( b, p ), b );
|
||||||
if ( *p && ! ! str_find( escaped_chars, *p ) )
|
if ( *p && ! ! char_first_occurence( escaped_chars, *p ) )
|
||||||
{
|
{
|
||||||
_adt_fprintf( file, "%s%c", escape_symbol, *p );
|
_adt_fprintf( file, "%s%c", escape_symbol, *p );
|
||||||
p++;
|
p++;
|
||||||
@ -1099,10 +1099,10 @@ String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delimi
|
|||||||
FileInfo tmp;
|
FileInfo tmp;
|
||||||
file_stream_new( &tmp, a );
|
file_stream_new( &tmp, a );
|
||||||
csv_write_delimiter( &tmp, obj, delimiter );
|
csv_write_delimiter( &tmp, obj, delimiter );
|
||||||
|
|
||||||
ssize fsize;
|
ssize fsize;
|
||||||
u8* buf = file_stream_buf( &tmp, &fsize );
|
u8* buf = file_stream_buf( &tmp, &fsize );
|
||||||
String output = String::make_length( a, ( char* )buf, fsize );
|
String output = string_make_length( a, ( char* )buf, fsize );
|
||||||
file_close( &tmp );
|
file_close( &tmp );
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#define GEN_SUPPORT_CPP_MEMBER_FEATURES 1
|
|
||||||
|
|
||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
#endif
|
#endif
|
||||||
@ -78,13 +76,18 @@
|
|||||||
/* Platform compiler */
|
/* Platform compiler */
|
||||||
|
|
||||||
#if defined( _MSC_VER )
|
#if defined( _MSC_VER )
|
||||||
# define GEN_COMPILER_MSVC 1
|
# define GEN_COMPILER_CLANG 0
|
||||||
|
# define GEN_COMPILER_MSVC 1
|
||||||
|
# define GEN_COMPILER_GCC 0
|
||||||
#elif defined( __GNUC__ )
|
#elif defined( __GNUC__ )
|
||||||
# define GEN_COMPILER_GCC 1
|
# define GEN_COMPILER_CLANG 0
|
||||||
|
# define GEN_COMPILER_MSVC 0
|
||||||
|
# define GEN_COMPILER_GCC 1
|
||||||
#elif defined( __clang__ )
|
#elif defined( __clang__ )
|
||||||
# define GEN_COMPILER_CLANG 1
|
# define GEN_COMPILER_CLANG 1
|
||||||
#elif defined( __MINGW32__ )
|
# define GEN_COMPILER_MSVC 0
|
||||||
# define GEN_COMPILER_MINGW 1
|
# define GEN_COMPILER_GCC 1
|
||||||
|
#else
|
||||||
# error Unknown compiler
|
# error Unknown compiler
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -124,11 +127,23 @@
|
|||||||
|
|
||||||
#pragma endregion Mandatory Includes
|
#pragma endregion Mandatory Includes
|
||||||
|
|
||||||
#if GEN_DONT_USE_NAMESPACE || GEN_COMPILER_C
|
#if GEN_DONT_USE_NAMESPACE
|
||||||
# define GEN_NS
|
# if GEN_COMPILER_C
|
||||||
# define GEN_NS_BEGIN
|
# define GEN_NS_ENUM_BEGIN
|
||||||
# define GEN_NS_END
|
# define GEN_NS_ENUM_END
|
||||||
|
# define GEN_NS
|
||||||
|
# define GEN_NS_BEGIN
|
||||||
|
# define GEN_NS_END
|
||||||
|
# else
|
||||||
|
# define GEN_NS_ENUM_BEGIN namespace gen_internal_enums {
|
||||||
|
# define GEN_NS_ENUM_END }
|
||||||
|
# define GEN_NS ::
|
||||||
|
# define GEN_NS_BEGIN
|
||||||
|
# define GEN_NS_END
|
||||||
|
# endif
|
||||||
#else
|
#else
|
||||||
|
# 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 }
|
||||||
|
@ -422,7 +422,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 = gen_str.length();
|
info.precision = length(gen_str);
|
||||||
len = _print_string( text, remaining, &info, gen_str );
|
len = _print_string( text, remaining, &info, gen_str );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#pragma region String Ops
|
#pragma region String Ops
|
||||||
|
|
||||||
const char* char_first_occurence( const char* str, char c );
|
const char* char_first_occurence( const char* str, char c );
|
||||||
constexpr auto str_find = &char_first_occurence;
|
|
||||||
|
|
||||||
b32 char_is_alpha( char c );
|
b32 char_is_alpha( char c );
|
||||||
b32 char_is_alphanumeric( char c );
|
b32 char_is_alphanumeric( char c );
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
// Constant string with length.
|
// Constant string with length.
|
||||||
struct StrC
|
struct StrC
|
||||||
{
|
{
|
||||||
ssize Len;
|
ssize Len;
|
||||||
char const* Ptr;
|
char const* Ptr;
|
||||||
|
|
||||||
operator char const* () const { return Ptr; }
|
operator char const* () const { return Ptr; }
|
||||||
@ -28,10 +28,14 @@ StrC to_str( char const* str ) {
|
|||||||
// They used a header pattern
|
// They used a header pattern
|
||||||
// I kept it for simplicty of porting but its not necessary to keep it that way.
|
// I kept it for simplicty of porting but its not necessary to keep it that way.
|
||||||
#pragma region String
|
#pragma region String
|
||||||
struct String;
|
|
||||||
struct StringHeader;
|
struct StringHeader;
|
||||||
|
|
||||||
// Forward declarations for all file-scope functions
|
#if GEN_COMPILER_C
|
||||||
|
typedef char* String;
|
||||||
|
#else
|
||||||
|
struct String;
|
||||||
|
#endif
|
||||||
|
|
||||||
String string_make(AllocatorInfo allocator, char const* str);
|
String string_make(AllocatorInfo allocator, char const* str);
|
||||||
String string_make(AllocatorInfo allocator, StrC str);
|
String string_make(AllocatorInfo allocator, StrC str);
|
||||||
String string_make_reserve(AllocatorInfo allocator, ssize capacity);
|
String string_make_reserve(AllocatorInfo allocator, ssize capacity);
|
||||||
@ -73,11 +77,33 @@ struct StringHeader {
|
|||||||
ssize Length;
|
ssize Length;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if ! GEN_COMPILER_C
|
||||||
struct String
|
struct String
|
||||||
{
|
{
|
||||||
char* Data;
|
char* Data;
|
||||||
|
|
||||||
#if 1
|
forceinline operator bool() { return Data != nullptr; }
|
||||||
|
forceinline operator char*() { return Data; }
|
||||||
|
forceinline operator char const*() const { return Data; }
|
||||||
|
forceinline operator StrC() const { return { GEN_NS length(* this), Data }; }
|
||||||
|
|
||||||
|
String const& operator=(String const& other) const {
|
||||||
|
if (this == &other)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
String* this_ = ccast(String*, this);
|
||||||
|
this_->Data = other.Data;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
forceinline char& operator[](ssize index) { return Data[index]; }
|
||||||
|
forceinline char const& operator[](ssize index) const { return Data[index]; }
|
||||||
|
|
||||||
|
forceinline char* begin() const { return Data; }
|
||||||
|
forceinline char* end() const { return Data + GEN_NS length(* this); }
|
||||||
|
|
||||||
|
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
|
||||||
#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 GEN_NS string_make(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 GEN_NS string_make(allocator, str); }
|
||||||
@ -143,30 +169,14 @@ struct String
|
|||||||
|
|
||||||
return GEN_NS append(*this, buf, res);
|
return GEN_NS append(*this, buf, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline operator bool() { return Data != nullptr; }
|
|
||||||
forceinline operator char*() { return Data; }
|
|
||||||
forceinline operator char const*() const { return Data; }
|
|
||||||
forceinline operator StrC() const { return { length(), Data }; }
|
|
||||||
|
|
||||||
String const& operator=(String const& other) const {
|
|
||||||
if (this == &other)
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
String* this_ = ccast(String*, this);
|
|
||||||
this_->Data = other.Data;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
forceinline char& operator[](ssize index) { return Data[index]; }
|
|
||||||
forceinline char const& operator[](ssize index) const { return Data[index]; }
|
|
||||||
|
|
||||||
forceinline char* begin() const { return Data; }
|
|
||||||
forceinline char* end() const { return Data + length(); }
|
|
||||||
#pragma endregion Member Mapping
|
#pragma endregion Member Mapping
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline char* begin(String& str) { return str; }
|
||||||
|
inline char* end(String& str) { return scast(char*, str) + length(str); }
|
||||||
|
inline char* next(String& str) { return scast(char*, str) + 1; }
|
||||||
|
|
||||||
inline
|
inline
|
||||||
usize string_grow_formula(usize value) {
|
usize string_grow_formula(usize value) {
|
||||||
@ -247,9 +257,9 @@ bool append(String& str, char const* str_to_append, ssize append_length)
|
|||||||
|
|
||||||
StringHeader& header = get_header(str);
|
StringHeader& header = get_header(str);
|
||||||
|
|
||||||
mem_copy(str.Data + curr_len, str_to_append, append_length);
|
mem_copy( scast(char*, str) + curr_len, str_to_append, append_length);
|
||||||
|
|
||||||
str.Data[curr_len + append_length] = '\0';
|
str[curr_len + append_length] = '\0';
|
||||||
|
|
||||||
header.Length = curr_len + append_length;
|
header.Length = curr_len + append_length;
|
||||||
}
|
}
|
||||||
@ -263,7 +273,19 @@ bool append(String& str, StrC str_to_append) {
|
|||||||
|
|
||||||
inline
|
inline
|
||||||
bool append(String& str, const String other) {
|
bool append(String& str, const String other) {
|
||||||
return append(str, other.Data, length(other));
|
return append(str, other, length(other));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool append_fmt(String& str, char const* fmt, ...) {
|
||||||
|
ssize res;
|
||||||
|
char buf[GEN_PRINTF_MAXLEN] = { 0 };
|
||||||
|
|
||||||
|
va_list va;
|
||||||
|
va_start(va, fmt);
|
||||||
|
res = str_fmt_va(buf, count_of(buf) - 1, fmt, va) - 1;
|
||||||
|
va_end(va);
|
||||||
|
|
||||||
|
return append(str, buf, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
@ -294,7 +316,7 @@ bool are_equal(String lhs, StrC rhs)
|
|||||||
|
|
||||||
inline
|
inline
|
||||||
ssize avail_space(String const& str) {
|
ssize avail_space(String const& str) {
|
||||||
StringHeader const& header = *rcast(StringHeader const*, str.Data - sizeof(StringHeader));
|
StringHeader const& header = *rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
||||||
return header.Capacity - header.Length;
|
return header.Capacity - header.Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,7 +328,7 @@ char& back(String& str) {
|
|||||||
inline
|
inline
|
||||||
bool contains(String const& str, StrC substring)
|
bool contains(String const& str, StrC substring)
|
||||||
{
|
{
|
||||||
StringHeader const& header = *rcast(StringHeader const*, str.Data - sizeof(StringHeader));
|
StringHeader const& header = *rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
||||||
|
|
||||||
if (substring.Len > header.Length)
|
if (substring.Len > header.Length)
|
||||||
return false;
|
return false;
|
||||||
@ -326,7 +348,7 @@ bool contains(String const& str, StrC substring)
|
|||||||
inline
|
inline
|
||||||
bool contains(String const& str, String const& substring)
|
bool contains(String const& str, String const& substring)
|
||||||
{
|
{
|
||||||
StringHeader const& header = *rcast(StringHeader const*, str.Data - sizeof(StringHeader));
|
StringHeader const& header = *rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
||||||
|
|
||||||
if (length(substring) > header.Length)
|
if (length(substring) > header.Length)
|
||||||
return false;
|
return false;
|
||||||
@ -345,7 +367,7 @@ bool contains(String const& str, String const& substring)
|
|||||||
|
|
||||||
inline
|
inline
|
||||||
ssize capacity(String const& str) {
|
ssize capacity(String const& str) {
|
||||||
StringHeader const& header = *rcast(StringHeader const*, str.Data - sizeof(StringHeader));
|
StringHeader const& header = *rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
||||||
return header.Capacity;
|
return header.Capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,7 +378,7 @@ void clear(String& str) {
|
|||||||
|
|
||||||
inline
|
inline
|
||||||
String duplicate(String const& str, AllocatorInfo allocator) {
|
String duplicate(String const& str, AllocatorInfo allocator) {
|
||||||
return string_make_length(allocator, str.Data, length(str));
|
return string_make_length(allocator, str, length(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
@ -376,7 +398,7 @@ StringHeader& get_header(String& str) {
|
|||||||
inline
|
inline
|
||||||
ssize length(String const& str)
|
ssize length(String const& str)
|
||||||
{
|
{
|
||||||
StringHeader const& header = *rcast(StringHeader const*, str.Data - sizeof(StringHeader));
|
StringHeader const& header = *rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader));
|
||||||
return header.Length;
|
return header.Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -511,10 +533,10 @@ void trim_space(String& str) {
|
|||||||
inline
|
inline
|
||||||
String visualize_whitespace(String const& str)
|
String visualize_whitespace(String const& str)
|
||||||
{
|
{
|
||||||
StringHeader* header = (StringHeader*)(str.Data - sizeof(StringHeader));
|
StringHeader* header = (StringHeader*)(scast(char const*, str) - sizeof(StringHeader));
|
||||||
String result = string_make_reserve(header->Allocator, length(str) * 2); // Assume worst case for space requirements.
|
String result = string_make_reserve(header->Allocator, length(str) * 2); // Assume worst case for space requirements.
|
||||||
|
|
||||||
for (char c : str) switch (c)
|
for (auto c : str) switch (c)
|
||||||
{
|
{
|
||||||
case ' ':
|
case ' ':
|
||||||
append(result, txt("·"));
|
append(result, txt("·"));
|
||||||
@ -549,10 +571,10 @@ 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" );
|
||||||
|
|
||||||
// Implements basic string interning. Data structure is based off the ZPL Hashtable.
|
// Implements basic string interning. Data structure is based off the ZPL Hashtable.
|
||||||
using StringTable = HashTable<String const>;
|
typedef HashTable<String const> StringTable;
|
||||||
|
|
||||||
// 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.
|
||||||
using StringCached = String const;
|
typedef String const StringCached;
|
||||||
|
|
||||||
#pragma endregion Strings
|
#pragma endregion Strings
|
||||||
|
@ -20,14 +20,14 @@ CodeBody gen_ecode( char const* path )
|
|||||||
|
|
||||||
Array<ADT_Node> enum_strs = csv_nodes.nodes[0].nodes;
|
Array<ADT_Node> enum_strs = csv_nodes.nodes[0].nodes;
|
||||||
|
|
||||||
String enum_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
|
String enum_entries = string_make_reserve( GlobalAllocator, kilobytes(1) );
|
||||||
String to_str_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
|
String to_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) );
|
||||||
|
|
||||||
for ( ADT_Node node : enum_strs )
|
for ( ADT_Node node : enum_strs )
|
||||||
{
|
{
|
||||||
char const* code = node.string;
|
char const* code = node.string;
|
||||||
enum_entries.append_fmt( "%s,\n", code );
|
append_fmt( enum_entries, "%s,\n", code );
|
||||||
to_str_entries.append_fmt( "{ sizeof(\"%s\"), \"%s\" },\n", code, code );
|
append_fmt( to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", code, code );
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeEnum enum_code = parse_enum(gen::token_fmt_impl((3 + 1) / 2, "entries", (StrC)enum_entries, "enum Type : u32 { <entries> NumTypes };"));
|
CodeEnum enum_code = parse_enum(gen::token_fmt_impl((3 + 1) / 2, "entries", (StrC)enum_entries, "enum Type : u32 { <entries> NumTypes };"));
|
||||||
@ -67,16 +67,16 @@ CodeBody gen_eoperator( char const* path )
|
|||||||
Array<ADT_Node> enum_strs = csv_nodes.nodes[0].nodes;
|
Array<ADT_Node> enum_strs = csv_nodes.nodes[0].nodes;
|
||||||
Array<ADT_Node> str_strs = csv_nodes.nodes[1].nodes;
|
Array<ADT_Node> str_strs = csv_nodes.nodes[1].nodes;
|
||||||
|
|
||||||
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 < 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;
|
||||||
|
|
||||||
enum_entries.append_fmt( "%s,\n", enum_str );
|
append_fmt( enum_entries, "%s,\n", enum_str );
|
||||||
to_str_entries.append_fmt( "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
append_fmt( to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeEnum enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, stringize(
|
CodeEnum enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, stringize(
|
||||||
@ -123,16 +123,16 @@ CodeBody gen_especifier( char const* path )
|
|||||||
Array<ADT_Node> enum_strs = csv_nodes.nodes[0].nodes;
|
Array<ADT_Node> enum_strs = csv_nodes.nodes[0].nodes;
|
||||||
Array<ADT_Node> str_strs = csv_nodes.nodes[1].nodes;
|
Array<ADT_Node> str_strs = csv_nodes.nodes[1].nodes;
|
||||||
|
|
||||||
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 < 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;
|
||||||
|
|
||||||
enum_entries.append_fmt( "%s,\n", enum_str );
|
append_fmt( enum_entries, "%s,\n", enum_str );
|
||||||
to_str_entries.append_fmt( "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
append_fmt( to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeEnum enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, stringize(
|
CodeEnum enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, stringize(
|
||||||
@ -237,19 +237,19 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
|
|||||||
Array<ADT_Node> attribute_strs = csv_attr_nodes.nodes[0].nodes;
|
Array<ADT_Node> attribute_strs = csv_attr_nodes.nodes[0].nodes;
|
||||||
Array<ADT_Node> attribute_str_strs = csv_attr_nodes.nodes[1].nodes;
|
Array<ADT_Node> attribute_str_strs = csv_attr_nodes.nodes[1].nodes;
|
||||||
|
|
||||||
String enum_entries = String::make_reserve( GlobalAllocator, kilobytes(2) );
|
String enum_entries = string_make_reserve( GlobalAllocator, kilobytes(2) );
|
||||||
String to_str_entries = String::make_reserve( GlobalAllocator, kilobytes(4) );
|
String to_str_entries = string_make_reserve( GlobalAllocator, kilobytes(4) );
|
||||||
String attribute_entries = String::make_reserve( GlobalAllocator, kilobytes(2) );
|
String attribute_entries = string_make_reserve( GlobalAllocator, kilobytes(2) );
|
||||||
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 < 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;
|
||||||
|
|
||||||
enum_entries.append_fmt( "%s,\n", enum_str );
|
append_fmt( enum_entries, "%s,\n", enum_str );
|
||||||
to_str_entries.append_fmt( "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
append_fmt( to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( usize idx = 0; idx < num(attribute_strs); idx++ )
|
for ( usize idx = 0; idx < num(attribute_strs); idx++ )
|
||||||
@ -257,14 +257,14 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
|
|||||||
char const* attribute_str = attribute_strs[idx].string;
|
char const* attribute_str = attribute_strs[idx].string;
|
||||||
char const* entry_to_str = attribute_str_strs [idx].string;
|
char const* entry_to_str = attribute_str_strs [idx].string;
|
||||||
|
|
||||||
attribute_entries.append_fmt( "Attribute_%s,\n", attribute_str );
|
append_fmt( attribute_entries, "Attribute_%s,\n", attribute_str );
|
||||||
to_str_attributes.append_fmt( "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
append_fmt( to_str_attributes, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
|
||||||
attribute_define_entries.append_fmt( "Entry( Attribute_%s, \"%s\" )", attribute_str, entry_to_str );
|
append_fmt( attribute_define_entries, "Entry( Attribute_%s, \"%s\" )", attribute_str, entry_to_str );
|
||||||
|
|
||||||
if ( idx < num(attribute_strs) - 1 )
|
if ( idx < num(attribute_strs) - 1 )
|
||||||
attribute_define_entries.append( " \\\n");
|
append( attribute_define_entries, " \\\n");
|
||||||
else
|
else
|
||||||
attribute_define_entries.append( "\n");
|
append( attribute_define_entries, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma push_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
|
#pragma push_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
|
||||||
|
Loading…
Reference in New Issue
Block a user