diff --git a/.editorconfig b/.editorconfig
index bda6668..079738c 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,5 +1,9 @@
root = true
+[*.refactor]
+indent_style = space
+indent_size = 4
+
[*.md]
indent_style = space
indent_size = 4
@@ -23,3 +27,7 @@ indent_size = 4
[*.ps1]
indent_style = tab
indent_size = 4
+
+[*.natvis]
+indent_style = tab
+indent_size = 4
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 0465b58..81b9a60 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -17,7 +17,8 @@
"xmemory": "cpp",
"algorithm": "cpp",
"limits": "cpp",
- "concepts": "cpp"
+ "concepts": "cpp",
+ "*.rh": "cpp"
},
"C_Cpp.intelliSenseEngineFallback": "disabled",
"mesonbuild.configureOnOpen": true,
diff --git a/gencpp.vcxproj b/gencpp.vcxproj
index b8a05e0..fd76f32 100644
--- a/gencpp.vcxproj
+++ b/gencpp.vcxproj
@@ -121,7 +121,6 @@
-
diff --git a/project/Readme.md b/project/Readme.md
index f620342..66d8b33 100644
--- a/project/Readme.md
+++ b/project/Readme.md
@@ -30,17 +30,16 @@ Major enum definitions and their associated functions used with the AST data
* `ESpecifier` : Used with specifier ASTs for all specifiers the user may tag an associated
AST with.
* `AccessSpec` : Used with class and struct ASTs to denote the public, protected, or private fields.
+* `EnumT` : Used with def_enum to determine if constructing a regular enum or an enum class.
* `ModuleFlag` : Used with any valid definition that can have export or import related keywords assoicated with it.
#### Data Structures
-`StringTable` : Hash table for cached strings. (`StringCached` typedef used to denote strings managed by it)
+`StringCache` : Hash table for cached strings. (`StringCached` typedef used to denote strings managed by it)
`AST` : The node data strucuture for the code.
`Code` : Wrapper for `AST` with functionality for handling it appropriately.
-`TypeTable` : Hash table for cached typename ASTs.
-
#### Gen Interface
First set of fowards are either backend functions used for various aspects of AST generation or configurating allocators used for different containers.
diff --git a/project/gen.cpp b/project/gen.cpp
index 14a3b5e..5f03c67 100644
--- a/project/gen.cpp
+++ b/project/gen.cpp
@@ -1722,33 +1722,33 @@ namespace gen
}
#pragma region Constants
- global Code t_auto;
- global Code t_void;
- global Code t_int;
- global Code t_bool;
- global Code t_char;
- global Code t_wchar_t;
- global Code t_class;
- global Code t_typename;
+ global CodeType t_auto;
+ global CodeType t_void;
+ global CodeType t_int;
+ global CodeType t_bool;
+ global CodeType t_char;
+ global CodeType t_wchar_t;
+ global CodeType t_class;
+ global CodeType t_typename;
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
- global Code t_b32;
+ global CodeType t_b32;
- global Code t_s8;
- global Code t_s16;
- global Code t_s32;
- global Code t_s64;
+ global CodeType t_s8;
+ global CodeType t_s16;
+ global CodeType t_s32;
+ global CodeType t_s64;
- global Code t_u8;
- global Code t_u16;
- global Code t_u32;
- global Code t_u64;
+ global CodeType t_u8;
+ global CodeType t_u16;
+ global CodeType t_u32;
+ global CodeType t_u64;
- global Code t_sw;
- global Code t_uw;
+ global CodeType t_sw;
+ global CodeType t_uw;
- global Code t_f32;
- global Code t_f64;
+ global CodeType t_f32;
+ global CodeType t_f64;
#endif
global Code access_public;
@@ -1760,23 +1760,23 @@ namespace gen
global Code pragma_once;
- global Code spec_const;
- global Code spec_consteval;
- global Code spec_constexpr;
- global Code spec_constinit;
- global Code spec_extern_linkage;
- global Code spec_global;
- global Code spec_inline;
- global Code spec_internal_linkage;
- global Code spec_local_persist;
- global Code spec_mutable;
- global Code spec_ptr;
- global Code spec_ref;
- global Code spec_register;
- global Code spec_rvalue;
- global Code spec_static_member;
- global Code spec_thread_local;
- global Code spec_volatile;
+ global CodeSpecifiers spec_const;
+ global CodeSpecifiers spec_consteval;
+ global CodeSpecifiers spec_constexpr;
+ global CodeSpecifiers spec_constinit;
+ global CodeSpecifiers spec_extern_linkage;
+ global CodeSpecifiers spec_global;
+ global CodeSpecifiers spec_inline;
+ global CodeSpecifiers spec_internal_linkage;
+ global CodeSpecifiers spec_local_persist;
+ global CodeSpecifiers spec_mutable;
+ global CodeSpecifiers spec_ptr;
+ global CodeSpecifiers spec_ref;
+ global CodeSpecifiers spec_register;
+ global CodeSpecifiers spec_rvalue;
+ global CodeSpecifiers spec_static_member;
+ global CodeSpecifiers spec_thread_local;
+ global CodeSpecifiers spec_volatile;
#pragma endregion Constants
#pragma region AST Body Case Macros
@@ -3184,7 +3184,7 @@ namespace gen
};
inline
- OpValidateResult operator__validate( OperatorT op, Code params_code, Code ret_type, Code specifier )
+ OpValidateResult operator__validate( OperatorT op, CodeParams params_code, Code ret_type, Code specifier )
{
using namespace EOperator;
@@ -3208,7 +3208,7 @@ namespace gen
}
# define check_param_eq_ret() \
- if ( ! is_member_symbol && params_code->param_type() != ret_type ) \
+ if ( ! is_member_symbol && params_code.type() != ret_type ) \
{ \
log_failure("gen_def_operator: operator%s requires first parameter to equal return type\n" \
"param types: %s\n" \
@@ -3240,7 +3240,7 @@ namespace gen
case Assign:
check_params();
- if ( params_code->param_count() > 1 )
+ if ( params_code.num() > 1 )
{
log_failure("gen::def_operator: "
"operator%s does not support non-member definition (more than one parameter provided) - %s",
@@ -3265,17 +3265,17 @@ namespace gen
case Assign_RShift:
check_params();
- if ( params_code->param_count() == 1 )
+ if ( params_code.num() == 1 )
is_member_symbol = true;
else
check_param_eq_ret();
- if (params_code->param_count() > 2 )
+ if (params_code.num() > 2 )
{
log_failure("gen::def_operator: operator%s may not be defined with more than two parametes - param count; %d\n%s"
, to_str(op)
- , params_code->param_count()
+ , params_code.num()
, params_code->debug_str()
);
return OpValidateResult::Fail;
@@ -3296,10 +3296,10 @@ namespace gen
return OpValidateResult::Fail;
}
- switch ( params_code->param_count() )
+ switch ( params_code.num() )
{
case 1:
- if ( params_code->param_type()->is_equal( t_int ) )
+ if ( params_code.type()->is_equal( t_int ) )
is_member_symbol = true;
else
@@ -3309,7 +3309,7 @@ namespace gen
case 2:
check_param_eq_ret();
- if ( ! params_code->get_param(1)->is_equal( t_int ) )
+ if ( ! params_code.get(1)->is_equal( t_int ) )
{
log_failure("gen::def_operator: "
"operator%s requires second parameter of non-member definition to be int for post-decrement",
@@ -3320,9 +3320,9 @@ namespace gen
break;
default:
- log_failure("gen::def_operator: operator%s recieved unexpected number of paramters recived %d instead of 0-2"
+ log_failure("gen::def_operator: operator%s recieved unexpected number of parameters recived %d instead of 0-2"
, to_str(op)
- , params_code->param_count()
+ , params_code.num()
);
return OpValidateResult::Fail;
}
@@ -3343,7 +3343,7 @@ namespace gen
return OpValidateResult::Fail;
}
- if ( params_code->param_type()->is_equal( ret_type ) )
+ if ( params_code.type()->is_equal( ret_type ) )
{
log_failure("gen::def_operator: "
"operator%s is non-member symbol yet first paramter does not equal return type\n"
@@ -3355,11 +3355,11 @@ namespace gen
return OpValidateResult::Fail;
}
- if ( params_code->param_count() > 1 )
+ if ( params_code.num() > 1 )
{
log_failure("gen::def_operator: operator%s may not have more than one parameter - param count: %d"
, to_str(op)
- , params_code->param_count()
+ , params_code.num()
);
return OpValidateResult::Fail;
}
@@ -3378,14 +3378,14 @@ namespace gen
case RShift:
check_params();
- switch ( params_code->param_count() )
+ switch ( params_code.num() )
{
case 1:
is_member_symbol = true;
break;
case 2:
- if ( ! params_code->param_type()->is_equal( ret_type ) )
+ if ( ! params_code.type()->is_equal( ret_type ) )
{
log_failure("gen::def_operator: "
"operator%s is non-member symbol yet first paramter does not equal return type\n"
@@ -3401,7 +3401,7 @@ namespace gen
default:
log_failure("gen::def_operator: operator%s recieved unexpected number of paramters recived %d instead of 0-2"
, to_str(op)
- , params_code->param_count()
+ , params_code.num()
);
return OpValidateResult::Fail;
}
@@ -3588,7 +3588,7 @@ namespace gen
The largest of the functions is related to operator overload definitions.
The library validates a good protion of their form and thus the argument processing for is quite a bit.
*/
- Code def_attributes( StrC content )
+ CodeAttributes def_attributes( StrC content )
{
if ( content.Len <= 0 || content.Ptr == nullptr )
{
@@ -3605,7 +3605,7 @@ namespace gen
return result;
}
- Code def_comment( StrC content )
+ CodeComment def_comment( StrC content )
{
if ( content.Len <= 0 || content.Ptr == nullptr )
{
@@ -3622,7 +3622,7 @@ namespace gen
return result;
}
- Code def_class( StrC name
+ CodeClass def_class( StrC name
, Code body
, Code parent, AccessSpec parent_access
, Code attributes
@@ -3682,7 +3682,7 @@ namespace gen
return result;
}
- Code def_enum( StrC name
+ CodeEnum def_enum( StrC name
, Code body, Code type
, EnumT specifier, Code attributes
, ModuleFlag mflags )
@@ -3748,7 +3748,7 @@ namespace gen
return result;
}
- Code def_execution( StrC content )
+ CodeExec def_execution( StrC content )
{
if ( content.Len <= 0 || content.Ptr == nullptr )
{
@@ -3765,7 +3765,7 @@ namespace gen
return result;
}
- Code def_extern_link( StrC name, Code body, ModuleFlag mflags )
+ CodeExtern def_extern_link( StrC name, Code body, ModuleFlag mflags )
{
using namespace ECode;
@@ -3784,12 +3784,12 @@ namespace gen
result->Name = get_cached_string( name );
result->ModuleFlags = mflags;
- result->add_entry( body );
+ result->entry( AST::Entry_Body ) = body;
return result;
}
- Code def_friend( Code declaration )
+ CodeFriend def_friend( Code declaration )
{
using namespace ECode;
@@ -5773,7 +5773,7 @@ namespace gen
untyped_tok.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)untyped_tok.Text;
- Code array_expr = untyped_str( untyped_tok );
+ Code array_expr = code_str( untyped_tok );
if ( left == 0 )
{
@@ -6297,7 +6297,7 @@ namespace gen
}
expr_tok.Length = ( (sptr)currtok.Text + currtok.Length ) - (sptr)expr_tok.Text;
- expr = untyped_str( expr_tok );
+ expr = code_str( expr_tok );
}
eat( TokType::Statement_End );
@@ -6352,7 +6352,7 @@ namespace gen
eat( currtok.Type );
}
- expr = untyped_str( expr_tok );
+ expr = code_str( expr_tok );
}
return expr;
@@ -6585,7 +6585,7 @@ namespace gen
eat( currtok.Type );
}
- member = untyped_str( untyped_tok );
+ member = code_str( untyped_tok );
break;
}
@@ -7006,7 +7006,7 @@ namespace gen
{
// mem_copy( entries_code, body.Text, body.Length );
- Code untyped_body = untyped_str( body );
+ Code untyped_body = code_str( body );
result->Type = is_enum_class ? Enum_Class : Enum;
result->add_entry( untyped_body );
@@ -7370,7 +7370,7 @@ namespace gen
body_str.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)body_str.Text;
- body = untyped_str( body_str );
+ body = code_str( body_str );
eat( TokType::BraceCurly_Close );
}
@@ -8093,7 +8093,7 @@ namespace gen
return result;
}
- Code untyped_str( StrC content )
+ Code code_str( StrC content )
{
Code
result = make_code();
@@ -8104,7 +8104,7 @@ namespace gen
return result;
}
- Code untyped_fmt( char const* fmt, ...)
+ Code code_fmt( char const* fmt, ...)
{
local_persist thread_local
char buf[GEN_PRINTF_MAXLEN] = { 0 };
diff --git a/project/gen.hpp b/project/gen.hpp
index 6109703..8cd7e4c 100644
--- a/project/gen.hpp
+++ b/project/gen.hpp
@@ -2338,15 +2338,6 @@ namespace gen
constexpr EnumT EnumClass = EnumT::Class;
constexpr EnumT EnumRegular = EnumT::Regular;
- enum class UsingT : u8
- {
- Regular,
- Namespace
- };
-
- constexpr UsingT UsingRegular = UsingT::Regular;
- constexpr UsingT UsingNamespace = UsingT::Namespace;
-
namespace EOperator
{
# define Define_Operators \
@@ -2603,171 +2594,72 @@ namespace gen
// Should never be modified, if changed string is desired, cache_string( str ) another.
using StringCached = String const;
+ struct AST;
+ struct Code;
+
+ // These are to offer strong type safety for the AST.
+ struct CodeAttributes;
+ struct CodeComment;
+ struct CodeClass;
+ struct CodeExec;
+ struct CodeEnum;
+ struct CodeExtern;
+ struct CodeInclude;
+ struct CodeFriend;
+ struct CodeFn;
+ struct CodeModule;
+ struct CodeNamespace;
+ struct CodeOperator;
+ struct CodeOpCast;
+ struct CodeParams;
+ struct CodeSpecifiers;
+ struct CodeStruct;
+ struct CodeTemplate;
+ struct CodeType;
+ struct CodeTypedef;
+ struct CodeUnion;
+ struct CodeUsing;
+ struct CodeUsingNamespace;
+ struct CodeVar;
+ struct CodeClassBody;
+ struct CodeEnumBody;
+ struct CodeExportBody;
+ struct CodeExternBody;
+ struct CodeFnBody;
+ struct CodeGlobalBody;
+ struct CodeNamespaceBody;
+ struct CodeStructBody;
+ struct CodeUnionBody;
+
// Desired width of the AST data structure.
constexpr u32 AST_POD_Size = 256;
- struct AST;
-
- /*
- AST* typedef as to not constantly have to add the '*' as this is written often..
- */
- struct Code
- {
- # pragma region Statics
- // Used to identify ASTs that should always be duplicated. (Global constant ASTs)
- static Code Global;
-
- // Used to identify invalid generated code.
- static Code Invalid;
- # pragma endregion Statics
-
- # pragma region Member Functions
- void set_global();
-
- bool is_valid();
-
- bool operator ==( Code other )
- {
- return ast == other.ast;
- }
-
- bool operator !=( Code other )
- {
- return ast != other.ast;
- }
-
- operator AST*()
- {
- return ast;
- }
-
- AST* operator->()
- {
- if ( ast == nullptr )
- {
- log_failure("Attempt to dereference a nullptr!");
- return nullptr;
- }
-
- return ast;
- }
- # pragma endregion Member Functions
-
- AST* ast;
- };
-
- struct Code_POD
- {
- AST* ast;
- };
-
- // TODO: If perf needs it, convert layout an SOA format.
/*
Simple AST POD with functionality to seralize into C++ syntax.
-
- ASTs are currently stored as an AOS. They are always reconstructed on demand.
- Thus redundant AST can easily occur.
- Not sure if its better to store them in a hashmap.
-
- Any type specific functions assume the construction of the AST was done correctly.
*/
struct AST
{
+ enum Entry : u32
+ {
+ Entry_Array_Expression,
+ Entry_Attributes,
+ Entry_Body,
+ Entry_Parameters,
+ Entry_Parameter_Type,
+ Entry_Parent_Type,
+ Entry_Return_Type,
+ Entry_Specifiers,
+ Entry_Value,
+ };
+
# pragma region Member Functions
- // add_entry with validation
- void add( AST* other );
-
- void add_entry( AST* other );
-
- AST* body()
- {
- return entry( 0 );
- }
-
- AST* duplicate();
-
- AST* entry( u32 idx )
- {
- return DynamicEntries ? ArrDyn[ idx ] : ArrStatic[ idx ];
- }
-
- bool has_entries()
- {
- return num_entries();
- }
-
- bool is_equal( AST* other );
-
- s32 num_entries()
- {
- return DynamicEntries ? ArrDyn.num() : StaticIndex;
- }
-
- // Parameter
-
- AST* get_param( s32 index )
- {
- if ( index <= 0 )
- return this;
-
- return entry( index + 1 );
- }
-
- s32 param_count()
- {
- // The first entry (which holds the type) represents the first parameter.
- return num_entries();
- }
-
- AST* param_type()
- {
- return entry( 0 );
- }
-
- // Specifiers
-
- bool add_specifier( SpecifierT spec )
- {
- if ( StaticIndex == AST::ArrSpecs_Cap )
- {
- log_failure("AST::add_specifier: Attempted to add over %d specifiers to a specifiers AST!", AST::ArrSpecs_Cap );
- return false;
- }
-
- ArrSpecs[ StaticIndex ] = spec;
- StaticIndex++;
- return true;
- }
-
- s32 has_specifier( SpecifierT spec )
- {
- for ( s32 idx = 0; idx < StaticIndex; idx++ )
- {
- if ( ArrSpecs[StaticIndex] == spec )
- return idx;
- }
-
- return -1;
- }
-
- // Typename
-
- bool typename_is_ptr()
- {
- assert_crash("not implemented");
- return false;
- }
-
- bool typename_is_ref()
- {
- assert_crash("not implemented");
- return false;
- }
-
- AST* typename_specifiers()
- {
- return entry( 0 );
- }
+ void add_entry( AST* other );
+ // AST* body();
+ AST* duplicate();
+ AST*& entry( u32 idx );
+ bool has_entries();
+ bool is_equal( AST* other );
+ s32 num_entries();
// Serialization
@@ -2849,12 +2741,358 @@ namespace gen
// Its intended for the AST to have equivalent size to its POD.
// All extra functionality within the AST namespace should just be syntatic sugar.
- static_assert( sizeof(Code) == sizeof(Code_POD), "ERROR: Code is not POD" );
static_assert( sizeof(AST) == sizeof(AST_POD), "ERROR: AST IS NOT POD" );
static_assert( sizeof(AST_POD) == AST_POD_Size, "ERROR: AST POD is not size of AST_POD_Size" );
+ /*
+ AST* typedef as to not constantly have to add the '*' as this is written often..
+ */
+ struct Code
+ {
+ # pragma region Statics
+ // Used to identify ASTs that should always be duplicated. (Global constant ASTs)
+ static Code Global;
+
+ // Used to identify invalid generated code.
+ static Code Invalid;
+ # pragma endregion Statics
+
+ #define Using_Code \
+ void set_global() \
+ { \
+ if ( ast == nullptr ) \
+ { \
+ log_failure("Code::set_global: Cannot set code as global, AST is null!"); \
+ return; \
+ } \
+ \
+ ast->Parent = Code::Global.ast; \
+ } \
+ bool is_valid() \
+ { \
+ return ast != nullptr && ast->Type != CodeT::Invalid; \
+ } \
+ bool operator ==( Code other ) \
+ { \
+ return ast == other.ast; \
+ } \
+ bool operator !=( Code other ) \
+ { \
+ return ast != other.ast; \
+ } \
+ AST* operator->() \
+ { \
+ if ( ast == nullptr ) \
+ { \
+ log_failure("Attempt to dereference a nullptr!"); \
+ return nullptr; \
+ } \
+ \
+ return ast; \
+ } \
+ operator AST*() \
+ { \
+ return ast; \
+ } \
+ AST* ast
+
+ Using_Code;
+
+ operator CodeAttributes() const;
+ operator CodeComment() const;
+ operator CodeClass() const;
+ operator CodeExec() const;
+ operator CodeEnum() const;
+ operator CodeExtern() const;
+ operator CodeInclude() const;
+ operator CodeFriend() const;
+ operator CodeFn() const;
+ operator CodeModule() const;
+ operator CodeNamespace() const;
+ operator CodeOperator() const;
+ operator CodeOpCast() const;
+ operator CodeParams() const;
+ operator CodeSpecifiers() const;
+ operator CodeStruct() const;
+ operator CodeTemplate() const;
+ operator CodeType() const;
+ operator CodeTypedef() const;
+ operator CodeUnion() const;
+ operator CodeUsing() const;
+ operator CodeUsingNamespace() const;
+ operator CodeVar() const;
+ operator CodeBody() const;
+ operator CodeClassBody() const;
+ operator CodeEnumBody() const;
+ operator CodeExportBody() const;
+ operator CodeExternBody() const;
+ operator CodeFnBody() const;
+ operator CodeGlobalBody() const;
+ operator CodeNamespaceBody() const;
+ operator CodeStructBody() const;
+ operator CodeUnionBody() const;
+ };
+
+ struct Code_POD
+ {
+ AST* ast;
+ };
+
+ static_assert( sizeof(Code) == sizeof(Code_POD), "ERROR: Code is not POD" );
+
// Used when the its desired when omission is allowed in a definition.
constexpr Code NoCode = { nullptr };
+
+#pragma region Code Types
+#ifndef GEN_ENFORCE_STRONG_CODE_TYPES
+ #define Define_ParentCast \
+ operator Code() \
+ { \
+ return * rcast( Code*, this ); \
+ }
+#else
+ #define Define_ParentCast \
+ explicit operator Code() \
+ { \
+ return * rcast( Code*, this ); \
+ }
+#endif
+
+ #define Define_CodeBodyType( Name ) \
+ struct Code##Name \
+ { \
+ Using_Code; \
+ Define_ParentCast; \
+ \
+ Code* begin() \
+ { \
+ return rcast( Code*, ast->entry(0)); \
+ } \
+ Code* end() \
+ { \
+ return rcast( Code*, ast->entry( ast->num_entries() ) ); \
+ } \
+ }
+
+ Define_CodeBodyType( Body );
+ Define_CodeBodyType( ClassBody );
+ Define_CodeBodyType( EnumBody );
+ Define_CodeBodyType( ExportBody );
+ Define_CodeBodyType( ExternBody );
+ Define_CodeBodyType( FnBody );
+ Define_CodeBodyType( GlobalBody );
+ Define_CodeBodyType( NamespaceBody );
+ Define_CodeBodyType( StructBody );
+ Define_CodeBodyType( UnionBody );
+
+ struct CodeAttributes
+ {
+ Using_Code;
+ Define_ParentCast;
+ };
+
+ struct CodeComment
+ {
+ Using_Code;
+ Define_ParentCast;
+ };
+
+ struct CodeClass
+ {
+ Using_Code;
+ Define_ParentCast;
+
+ CodeAttributes attributes();
+ CodeClassBody body();
+ CodeType parent();
+ };
+
+ struct CodeExec
+ {
+ Using_Code;
+ Define_ParentCast;
+ };
+
+ struct CodeEnum
+ {
+ Using_Code;
+ Define_ParentCast;
+
+ CodeAttributes attributes();
+ CodeEnumBody body();
+ CodeType type();
+ };
+
+ struct CodeExtern
+ {
+ Using_Code;
+ Define_ParentCast;
+
+ CodeExternBody body();
+ };
+
+ struct CodeInclude
+ {
+ Using_Code;
+ Define_ParentCast;
+ };
+
+ struct CodeFriend
+ {
+ Using_Code;
+ Define_ParentCast;
+
+ Code definition();
+ };
+
+ struct CodeFn
+ {
+ Using_Code;
+ Define_ParentCast;
+
+ CodeAttributes attributes();
+ CodeFnBody body();
+ CodeParams params();
+ CodeType return_type();
+ CodeSpecifiers specifiers();
+ };
+
+ struct CodeModule
+ {
+ Using_Code;
+ Define_ParentCast;
+ };
+
+ struct CodeNamespace
+ {
+ Using_Code;
+ Define_ParentCast;
+
+ CodeNamespaceBody body();
+ };
+
+ struct CodeUsingNamespace
+ {
+ Using_Code;
+ Define_ParentCast;
+ };
+
+ struct CodeOperator
+ {
+ Using_Code;
+ Define_ParentCast;
+
+ CodeAttributes attributes();
+ CodeFnBody body();
+ CodeParams params();
+ CodeType return_type();
+ CodeSpecifiers specifiers();
+ };
+
+ struct CodeOpCast
+ {
+ Using_Code;
+ Define_ParentCast;
+
+ CodeFnBody body();
+ CodeType type();
+ };
+
+ struct CodeParams
+ {
+ Using_Code;
+ Define_ParentCast;
+
+ void add_param( CodeParams param );
+ bool has_params();
+ CodeParams get( s32 idx );
+ s32 num();
+ CodeType type();
+ };
+
+ struct CodeSpecifiers
+ {
+ Using_Code;
+ Define_ParentCast;
+
+ SpecifierT begin();
+ SpecifierT end();
+
+ bool add( SpecifierT spec );
+ s32 has( SpecifierT spec );
+ };
+
+ struct CodeStruct
+ {
+ Using_Code;
+ Define_ParentCast;
+
+ CodeAttributes attributes();
+ CodeStructBody body();
+ CodeType parent();
+ };
+
+ struct CodeTemplate
+ {
+ Using_Code;
+ Define_ParentCast;
+
+ Code definition();
+ Code params();
+ };
+
+ struct CodeType
+ {
+ Using_Code;
+ Define_ParentCast;
+
+ Code array_expr();
+ CodeAttributes attributes();
+ CodeSpecifiers specifiers();
+ };
+
+ struct CodeTypedef
+ {
+ Using_Code;
+ Define_ParentCast;
+
+ CodeAttributes attributes();
+ CodeType type();
+ };
+
+ struct CodeUnion
+ {
+ Using_Code;
+ Define_ParentCast;
+
+ CodeAttributes attributes();
+ CodeUnionBody body();
+ };
+
+ struct CodeUsing
+ {
+ Using_Code;
+ Define_ParentCast;
+
+ Code attributes();
+ Code type();
+ };
+
+ struct CodeVar
+ {
+ Using_Code;
+ Define_ParentCast;
+
+ CodeAttributes attributes();
+ CodeSpecifiers specifiers();
+ CodeType type();
+ };
+
+ #undef Define_CodeBodyType
+ #undef Define_ParentCast
+ #undef Using_Code
+#pragma endregion Code Types
+
#pragma endregion Data Structures
#pragma region Gen Interface
@@ -2892,115 +3130,115 @@ namespace gen
void set_allocator_type_table ( AllocatorInfo type_reg_allocator );
# pragma region Upfront
- Code def_attributes( StrC content );
- Code def_comment ( StrC content );
+ CodeAttributes def_attributes( StrC content );
+ CodeComment def_comment ( StrC content );
- Code def_class( StrC name
- , Code body = NoCode
- , Code parent = NoCode, AccessSpec access = AccessSpec::Default
- , Code attributes = NoCode
+ CodeClass def_class( StrC name
+ , CodeClassBody body = NoCode
+ , CodeType parent = NoCode, AccessSpec access = AccessSpec::Default
+ , CodeAttributes attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None );
- Code def_enum( StrC
+ CodeEnum def_enum( StrC
, Code body = NoCode, Code type = NoCode
, EnumT specifier = EnumRegular, Code attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None );
- Code def_execution ( StrC content );
- Code def_extern_link( StrC name, Code body, ModuleFlag mflags = ModuleFlag::None );
- Code def_friend ( Code symbol );
+ CodeExec def_execution ( StrC content );
+ CodeExtern def_extern_link( StrC name, Code body, ModuleFlag mflags = ModuleFlag::None );
+ CodeFriend def_friend ( Code symbol );
- Code def_function( StrC name
+ CodeFn def_function( StrC name
, Code params = NoCode, Code ret_type = NoCode, Code body = NoCode
, Code specifiers = NoCode, Code attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None );
- Code def_include ( StrC content );
- Code def_module ( StrC name, ModuleFlag mflags = ModuleFlag::None );
- Code def_namespace( StrC name, Code body, ModuleFlag mflags = ModuleFlag::None );
+ CodeInclude def_include ( StrC content );
+ CodeModule def_module ( StrC name, ModuleFlag mflags = ModuleFlag::None );
+ CodeNamespace def_namespace( StrC name, Code body, ModuleFlag mflags = ModuleFlag::None );
- Code def_operator( OperatorT op
+ CodeOperator def_operator( OperatorT op
, Code params = NoCode, Code ret_type = NoCode, Code body = NoCode
, Code specifiers = NoCode, Code attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None );
- Code def_operator_cast( Code type, Code body = NoCode );
+ CodeOpCast def_operator_cast( Code type, Code body = NoCode );
- Code def_param ( Code type, StrC name, Code value = NoCode );
- Code def_specifier( SpecifierT specifier );
+ CodeParams def_param ( Code type, StrC name, Code value = NoCode );
+ CodeSpecifiers def_specifier( SpecifierT specifier );
- Code def_struct( StrC name
+ CodeStruct def_struct( StrC name
, Code body
, Code parent = NoCode, AccessSpec access = AccessSpec::Default
, Code attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None );
- Code def_template( Code params, Code body, ModuleFlag mflags = ModuleFlag::None );
+ CodeTemplate def_template( Code params, Code body, ModuleFlag mflags = ModuleFlag::None );
- Code def_type ( StrC name, Code arrayexpr = NoCode, Code specifiers = NoCode, Code attributes = NoCode );
- Code def_typedef( StrC name, Code type, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None );
+ CodeType def_type ( StrC name, Code arrayexpr = NoCode, Code specifiers = NoCode, Code attributes = NoCode );
+ CodeTypedef def_typedef( StrC name, Code type, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None );
- Code def_union( StrC name, Code body, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None );
+ CodeUnion def_union( StrC name, Code body, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None );
- Code def_using( StrC name, Code type = NoCode
+ CodeUsing def_using( StrC name, Code type = NoCode
, Code attributess = NoCode
, ModuleFlag mflags = ModuleFlag::None );
- Code def_using_namespace( StrC name );
+ CodeUsingNamespace def_using_namespace( StrC name );
- Code def_variable( Code type, StrC name, Code value = NoCode
+ CodeVar def_variable( Code type, StrC name, Code value = NoCode
, Code specifiers = NoCode, Code attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None );
// Constructs an empty body. Use AST::validate_body() to check if the body is was has valid entries.
- Code def_body( CodeT type );
+ CodeBody def_body( CodeT type );
// There are two options for defining a struct body, either varadically provided with the args macro to auto-deduce the arg num,
/// or provide as an array of Code objects.
- Code def_class_body ( s32 num, ... );
- Code def_class_body ( s32 num, Code* codes );
- Code def_enum_body ( s32 num, ... );
- Code def_enum_body ( s32 num, Code* codes );
- Code def_export_body ( s32 num, ... );
- Code def_export_body ( s32 num, Code* codes);
- Code def_extern_link_body( s32 num, ... );
- Code def_extern_link_body( s32 num, Code* codes );
- Code def_function_body ( s32 num, ... );
- Code def_function_body ( s32 num, Code* codes );
- Code def_global_body ( s32 num, ... );
- Code def_global_body ( s32 num, Code* codes );
- Code def_namespace_body ( s32 num, ... );
- Code def_namespace_body ( s32 num, Code* codes );
- Code def_params ( s32 num, ... );
- Code def_params ( s32 num, Code* params );
- Code def_specifiers ( s32 num, ... );
- Code def_specifiers ( s32 num, SpecifierT* specs );
- Code def_struct_body ( s32 num, ... );
- Code def_struct_body ( s32 num, Code* codes );
- Code def_union_body ( s32 num, ... );
- Code def_union_body ( s32 num, Code* codes );
+ CodeClassBody def_class_body ( s32 num, ... );
+ CodeClassBody def_class_body ( s32 num, Code* codes );
+ CodeEnumBody def_enum_body ( s32 num, ... );
+ CodeEnumBody def_enum_body ( s32 num, Code* codes );
+ CodeExportBody def_export_body ( s32 num, ... );
+ CodeExportBody def_export_body ( s32 num, Code* codes);
+ CodeExternBody def_extern_link_body( s32 num, ... );
+ CodeExternBody def_extern_link_body( s32 num, Code* codes );
+ CodeFnBody def_function_body ( s32 num, ... );
+ CodeFnBody def_function_body ( s32 num, Code* codes );
+ CodeGlobalBody def_global_body ( s32 num, ... );
+ CodeGlobalBody def_global_body ( s32 num, Code* codes );
+ CodeNamespace def_namespace_body ( s32 num, ... );
+ CodeNamespace def_namespace_body ( s32 num, Code* codes );
+ CodeParams def_params ( s32 num, ... );
+ CodeParams def_params ( s32 num, Code* params );
+ CodeSpecifiers def_specifiers ( s32 num, ... );
+ CodeSpecifiers def_specifiers ( s32 num, SpecifierT* specs );
+ CodeStructBody def_struct_body ( s32 num, ... );
+ CodeStructBody def_struct_body ( s32 num, Code* codes );
+ CodeUnionBody def_union_body ( s32 num, ... );
+ CodeUnionBody def_union_body ( s32 num, Code* codes );
# pragma endregion Upfront
# pragma region Parsing
# ifdef GEN_FEATURE_PARSING
- Code parse_class ( StrC class_def );
- Code parse_enum ( StrC enum_def );
- Code parse_export_body ( StrC export_def );
- Code parse_extern_link ( StrC exten_link_def);
- Code parse_friend ( StrC friend_def );
- Code parse_function ( StrC fn_def );
- Code parse_global_body ( StrC body_def );
- Code parse_namespace ( StrC namespace_def );
- Code parse_operator ( StrC operator_def );
- Code parse_operator_cast( StrC operator_def );
- Code parse_struct ( StrC struct_def );
- Code parse_template ( StrC template_def );
- Code parse_type ( StrC type_def );
- Code parse_typedef ( StrC typedef_def );
- Code parse_union ( StrC union_def );
- Code parse_using ( StrC using_def );
- Code parse_variable ( StrC var_def );
+ CodeClass parse_class ( StrC class_def );
+ CodeEnum parse_enum ( StrC enum_def );
+ CodeExportBody parse_export_body ( StrC export_def );
+ CodeExtern parse_extern_link ( StrC exten_link_def);
+ CodeFriend parse_friend ( StrC friend_def );
+ CodeFn parse_function ( StrC fn_def );
+ CodeGlobalBody parse_global_body ( StrC body_def );
+ CodeNamespace parse_namespace ( StrC namespace_def );
+ CodeOperator parse_operator ( StrC operator_def );
+ CodeOpCast parse_operator_cast( StrC operator_def );
+ CodeStruct parse_struct ( StrC struct_def );
+ CodeTemplate parse_template ( StrC template_def );
+ CodeType parse_type ( StrC type_def );
+ CodeTypedef parse_typedef ( StrC typedef_def );
+ CodeUnion parse_union ( StrC union_def );
+ CodeUsing parse_using ( StrC using_def );
+ CodeVar parse_variable ( StrC var_def );
# endif
# pragma endregion Parsing
@@ -3148,8 +3386,11 @@ namespace gen
# define args( ... ) num_args( __VA_ARGS__ ), __VA_ARGS__
+# define code_str( ... ) gen::untyped_str( code( __VA_ARGS__ ) )
+# define code_fmt( ... ) gen::untyped_str( token_fmt( __VA_ARGS__ ) )
+
// Takes a format string (char const*) and a list of tokens (StrC) and returns a StrC of the formatted string.
-# define token_fmt( ... ) token_fmt_impl( (num_args( __VA_ARGS__ ) + 1) / 2, __VA_ARGS__ )
+# define token_fmt( ... ) gen::token_fmt_impl( (num_args( __VA_ARGS__ ) + 1) / 2, __VA_ARGS__ )
#pragma endregion Macros
#pragma region Constants
@@ -3158,23 +3399,23 @@ namespace gen
{
// Predefined typename codes. Are set to readonly and are setup during gen::init()
- extern Code t_b32;
+ extern CodeType t_b32;
- extern Code t_s8;
- extern Code t_s16;
- extern Code t_s32;
- extern Code t_s64;
+ extern CodeType t_s8;
+ extern CodeType t_s16;
+ extern CodeType t_s32;
+ extern CodeType t_s64;
- extern Code t_u8;
- extern Code t_u16;
- extern Code t_u32;
- extern Code t_u64;
+ extern CodeType t_u8;
+ extern CodeType t_u16;
+ extern CodeType t_u32;
+ extern CodeType t_u64;
- extern Code t_sw;
- extern Code t_uw;
+ extern CodeType t_sw;
+ extern CodeType t_uw;
- extern Code t_f32;
- extern Code t_f64;
+ extern CodeType t_f32;
+ extern CodeType t_f64;
}
#endif
@@ -3200,14 +3441,14 @@ namespace gen
// Predefined Codes. Are set to readonly and are setup during gen::init()
- extern Code t_auto;
- extern Code t_void;
- extern Code t_int;
- extern Code t_bool;
- extern Code t_char;
- extern Code t_wchar_t;
- extern Code t_class;
- extern Code t_typename;
+ extern CodeType t_auto;
+ extern CodeType t_void;
+ extern CodeType t_int;
+ extern CodeType t_bool;
+ extern CodeType t_char;
+ extern CodeType t_wchar_t;
+ extern CodeType t_class;
+ extern CodeType t_typename;
extern Code access_public;
extern Code access_protected;
@@ -3218,23 +3459,23 @@ namespace gen
extern Code pragma_once;
- extern Code spec_const;
- extern Code spec_consteval;
- extern Code spec_constexpr;
- extern Code spec_constinit;
- extern Code spec_extern_linkage;
- extern Code spec_global;
- extern Code spec_inline;
- extern Code spec_internal_linkage;
- extern Code spec_local_persist;
- extern Code spec_mutable;
- extern Code spec_ptr;
- extern Code spec_ref;
- extern Code spec_register;
- extern Code spec_rvalue;
- extern Code spec_static_member;
- extern Code spec_thread_local;
- extern Code spec_volatile;
+ extern CodeSpecifiers spec_const;
+ extern CodeSpecifiers spec_consteval;
+ extern CodeSpecifiers spec_constexpr;
+ extern CodeSpecifiers spec_constinit;
+ extern CodeSpecifiers spec_extern_linkage;
+ extern CodeSpecifiers spec_global;
+ extern CodeSpecifiers spec_inline;
+ extern CodeSpecifiers spec_internal_linkage;
+ extern CodeSpecifiers spec_local_persist;
+ extern CodeSpecifiers spec_mutable;
+ extern CodeSpecifiers spec_ptr;
+ extern CodeSpecifiers spec_ref;
+ extern CodeSpecifiers spec_register;
+ extern CodeSpecifiers spec_rvalue;
+ extern CodeSpecifiers spec_static_member;
+ extern CodeSpecifiers spec_thread_local;
+ extern CodeSpecifiers spec_volatile;
}
#pragma endregion Constants
@@ -3276,29 +3517,116 @@ namespace gen
}
inline
- void Code::set_global()
+ bool AST::has_entries()
{
- if ( ast == nullptr )
- {
- log_failure("Code::set_global: Cannot set code as global, AST is null!");
- return;
- }
-
- ast->Parent = Global.ast;
+ return num_entries();
}
inline
- bool Code::is_valid()
+ AST*& AST::entry( u32 idx )
{
- return ast != nullptr && ast->Type != CodeT::Invalid;
+ return DynamicEntries ? ArrDyn[ idx ] : ArrStatic[ idx ];
}
- AST::operator gen::Code()
+ inline
+ s32 AST::num_entries()
+ {
+ return DynamicEntries ? ArrDyn.num() : StaticIndex;
+ }
+
+ inline
+ AST::operator Code()
{
return { this };
}
- Code def_body( CodeT type )
+ inline
+ CodeParams CodeParams::get( s32 index )
+ {
+ if ( index <= 0 )
+ return * this;
+
+ return (Code){ ast->entry( index + 1 ) };
+ }
+
+ inline
+ s32 CodeParams::num()
+ {
+ // The first entry (which holds the type) represents the first parameter.
+ return ast->num_entries();
+ }
+
+ inline
+ bool CodeSpecifiers::add( SpecifierT spec )
+ {
+ if ( ast->StaticIndex == AST::ArrSpecs_Cap )
+ {
+ log_failure("AST::add_specifier: Attempted to add over %d specifiers to a specifiers AST!", AST::ArrSpecs_Cap );
+ return false;
+ }
+
+ ast->ArrSpecs[ ast->StaticIndex ] = spec;
+ ast->StaticIndex++;
+ return true;
+ }
+
+ inline
+ s32 CodeSpecifiers::has( SpecifierT spec )
+ {
+ for ( s32 idx = 0; idx < ast->StaticIndex; idx++ )
+ {
+ if ( ast->ArrSpecs[ ast->StaticIndex ] == spec )
+ return idx;
+ }
+
+ return -1;
+ }
+
+#pragma region Operater Cast Impl
+ #define Define_CodeCast( type ) \
+ inline Code::operator type() const \
+ { \
+ return * rcast( type*, ast ); \
+ }
+
+ Define_CodeCast( CodeAttributes );
+ Define_CodeCast( CodeComment );
+ Define_CodeCast( CodeClass );
+ Define_CodeCast( CodeExec );
+ Define_CodeCast( CodeEnum );
+ Define_CodeCast( CodeExtern );
+ Define_CodeCast( CodeInclude );
+ Define_CodeCast( CodeFriend );
+ Define_CodeCast( CodeFn );
+ Define_CodeCast( CodeModule );
+ Define_CodeCast( CodeNamespace );
+ Define_CodeCast( CodeOperator );
+ Define_CodeCast( CodeOpCast );
+ Define_CodeCast( CodeParams );
+ Define_CodeCast( CodeSpecifiers );
+ Define_CodeCast( CodeStruct );
+ Define_CodeCast( CodeTemplate );
+ Define_CodeCast( CodeType );
+ Define_CodeCast( CodeTypedef );
+ Define_CodeCast( CodeUnion );
+ Define_CodeCast( CodeUsing );
+ Define_CodeCast( CodeUsingNamespace );
+ Define_CodeCast( CodeVar );
+ Define_CodeCast( CodeBody );
+ Define_CodeCast( CodeClassBody );
+ Define_CodeCast( CodeEnumBody );
+ Define_CodeCast( CodeExportBody );
+ Define_CodeCast( CodeExternBody );
+ Define_CodeCast( CodeFnBody );
+ Define_CodeCast( CodeGlobalBody );
+ Define_CodeCast( CodeNamespaceBody );
+ Define_CodeCast( CodeStructBody );
+ Define_CodeCast( CodeUnionBody );
+
+ #undef Define_CodeCast
+#pragma endregion Operater Cast Impl
+
+ CodeBody def_body( CodeT type )
{
switch ( type )
{
diff --git a/scripts/gencpp.refactor b/scripts/gencpp.refactor
index 3a6deb2..ca01406 100644
--- a/scripts/gencpp.refactor
+++ b/scripts/gencpp.refactor
@@ -240,7 +240,6 @@
// word StringTable new_name
// word UsingRegular new_name
// word UsingNamespace new_name
-// word UsingT new_name
// gencpp Data
diff --git a/test/Parsed/Sanity.Parsed.hpp b/test/Parsed/Sanity.Parsed.hpp
index 2c8ce76..42e3aee 100644
--- a/test/Parsed/Sanity.Parsed.hpp
+++ b/test/Parsed/Sanity.Parsed.hpp
@@ -27,16 +27,16 @@ u32 gen_sanity()
// Class
{
- Code fwd = parse_class( code(
+ CodeClass fwd = parse_class( code(
class TestEmptyClass;
));
- Code empty_body = parse_class( code(
+ CodeClass empty_body = parse_class( code(
class TestEmptyClass
{};
));
- empty_body->body()->add_entry( def_comment( txt_StrC("Empty class body") ) );
+ empty_body.body()->add_entry( def_comment( txt_StrC("Empty class body") ) );
gen_sanity_file.print(fwd);
gen_sanity_file.print(empty_body);
@@ -72,15 +72,15 @@ u32 gen_sanity()
// External Linkage
{
- Code empty_comment = def_comment( txt_StrC("Empty external linkage") );
+ CodeComment empty_comment = def_comment( txt_StrC("Empty external linkage") );
- Code c_extern = parse_extern_link( code(
+ CodeExtern c_extern = parse_extern_link( code(
extern "C"
{
};
));
- c_extern->body()->add_entry( empty_comment );
+ c_extern.body()->add_entry( empty_comment );
gen_sanity_file.print(c_extern);
}
@@ -108,17 +108,17 @@ u32 gen_sanity()
// Function
{
- Code fwd = parse_function( code(
+ CodeFn fwd = parse_function( code(
void test_function();
));
- Code def = parse_function( code(
+ CodeFn def = parse_function( code(
void test_function()
{
}
));
- def->body()->add_entry( def_comment( txt_StrC("Empty function body") ) );
+ def.body()->add_entry( def_comment( txt_StrC("Empty function body") ) );
gen_sanity_file.print(fwd);
gen_sanity_file.print(def);
@@ -128,13 +128,13 @@ u32 gen_sanity()
// Namespace
{
- Code def = parse_namespace( code(
+ CodeNamespace def = parse_namespace( code(
namespace TestNamespace
{
}
));
- def->body()->add_entry( def_comment( txt_StrC("Empty namespace body") ) );
+ def.body()->add_entry( def_comment( txt_StrC("Empty namespace body") ) );
gen_sanity_file.print(def);
}
@@ -172,17 +172,17 @@ u32 gen_sanity()
// Operator cast
{
- Code op_ptr = parse_operator_cast( code(
+ CodeClass op_ptr = parse_operator_cast( code(
operator u8* ();
));
- Code class_def = parse_class( code(
+ CodeClass class_def = parse_class( code(
class TestClass
{
};
));
- class_def->body()->add_entry( op_ptr );
+ class_def.body()->add_entry( op_ptr );
gen_sanity_file.print(class_def);
}
@@ -191,17 +191,17 @@ u32 gen_sanity()
// Parameters
{
- Code fwd = parse_function( code(
+ CodeFn fwd = parse_function( code(
void test_function_param( int a );
));
- Code def = parse_function( code(
+ CodeFn def = parse_function( code(
void test_function_param2( int a, int b )
{
}
));
- def->body()->add_entry( def_comment( txt_StrC("Empty function body") ) );
+ def.body()->add_entry( def_comment( txt_StrC("Empty function body") ) );
gen_sanity_file.print(fwd);
gen_sanity_file.print(def);
@@ -228,16 +228,16 @@ u32 gen_sanity()
// Struct
{
- Code fwd = parse_struct( code(
+ CodeStruct fwd = parse_struct( code(
struct TestEmptyStruct;
));
- Code empty_body = parse_struct( code(
+ CodeStruct empty_body = parse_struct( code(
struct TestEmptyStruct
{};
));
- empty_body->body()->add_entry( def_comment( txt_StrC("Empty struct body") ) );
+ empty_body.body()->add_entry( def_comment( txt_StrC("Empty struct body") ) );
gen_sanity_file.print(fwd);
gen_sanity_file.print(empty_body);
@@ -247,13 +247,13 @@ u32 gen_sanity()
// Union
{
- Code empty = parse_union( code(
+ CodeUnion empty = parse_union( code(
union TestEmptyUnion
{
};
));
- empty->body()->add_entry( def_comment( txt_StrC("Empty union body") ) );
+ empty.body()->add_entry( def_comment( txt_StrC("Empty union body") ) );
gen_sanity_file.print( parse_typedef( code( typedef unsigned short u16; )) );
gen_sanity_file.print( parse_typedef( code( typedef unsigned long u32; )) );
diff --git a/test/SOA.hpp b/test/SOA.hpp
index 98423ed..4d07a66 100644
--- a/test/SOA.hpp
+++ b/test/SOA.hpp
@@ -4,7 +4,7 @@
#include "gen.hpp"
using namespace gen;
-Code gen_SOA( Code struct_def, s32 num_entries = 0 )
+Code gen_SOA( CodeStruct struct_def, s32 num_entries = 0 )
{
StringCached name = get_cached_string( token_fmt( "name", (StrC)struct_def->Name,
stringize( SOA_ )
@@ -22,22 +22,18 @@ Code gen_SOA( Code struct_def, s32 num_entries = 0 )
var_arena = Arena::init_from_memory( var_memory, kilobytes(Num_Vars_Cap) );
do_once_end
- Array vars = Array::init( var_arena );;
+ Array vars = Array::init( var_arena );;
- Code soa = def_struct( name, def_body( ECode::Struct_Body ));
+ CodeStruct soa = def_struct( name, def_body( ECode::Struct_Body ));
{
- Code body = *struct_def->body();
- for ( s32 idx = 0; idx < body->num_entries(); idx++ )
+ for ( Code struct_mem : struct_def.body() )
{
- Code struct_mem = { body->entry( idx ) };
-
if ( struct_mem->Type == ECode::Variable )
{
- Code var_type = { struct_mem->entry(0) };
+ CodeType var_type = CodeVar(struct_mem).type();
+ StrC num_entries_str = to_StrC( str_fmt_buf( "%d", num_entries ) );
- StrC num_entries_str = to_StrC( str_fmt_buf( "%d", num_entries ) );
-
- Code entry_arr = { nullptr };
+ CodeVar entry_arr = { nullptr };
if ( ! num_entries)
{
entry_arr = parse_variable( token_fmt( "type", (StrC)var_type->Name, "name", (StrC)struct_mem->Name,
@@ -52,12 +48,12 @@ Code gen_SOA( Code struct_def, s32 num_entries = 0 )
}
vars.append( entry_arr );
- soa->body()->add_entry( entry_arr );
+ soa.body()->add_entry( entry_arr );
}
}
}
- Code make;
+ CodeFn make;
{
make = parse_function( token_fmt("SOA_Type", (StrC)name,
stringize(
@@ -71,22 +67,20 @@ Code gen_SOA( Code struct_def, s32 num_entries = 0 )
if ( ! num_entries )
{
- for ( s32 idx = 0; idx < vars.num(); idx++ )
+ for ( CodeVar member : vars )
{
- Code member = vars[idx];
-
Code arr_init = def_execution( token_fmt( "var_name", (StrC)member->Name, "var_type", (StrC)member->entry(0)->Name,
stringize( soa. = ::init( allocator ); )
));
- make->body()->add_entry( arr_init );
+ make.body()->add_entry( arr_init );
}
}
- make->body()->add_entry( def_execution( code( return soa; ) ));
+ make.body()->add_entry( def_execution( code( return soa; ) ));
}
- Code get;
+ CodeFn get;
{
get = parse_function( code(
Entry get( s32 idx )
@@ -96,10 +90,8 @@ Code gen_SOA( Code struct_def, s32 num_entries = 0 )
String content = String::make( Memory::GlobalAllocator, "return\n{\n" );
- for ( s32 idx = 0; idx < vars.num(); idx ++ )
+ for ( CodeVar member : vars )
{
- Code member = vars[idx];
-
content.append_fmt( token_fmt( "var_name", (StrC)member->Name,
"[idx],"
));
@@ -107,14 +99,14 @@ Code gen_SOA( Code struct_def, s32 num_entries = 0 )
content.append( "};" );
- Code ret = def_execution( content );
+ CodeExec ret = def_execution( content );
- get->body()->add_entry( ret );
+ get.body()->add_entry( ret );
}
- soa->body()->add_entry( make );
- soa->body()->add_entry( get );
- soa->body()->validate_body();
+ soa.body()->add_entry( make );
+ soa.body()->add_entry( get );
+ soa.body()->validate_body();
vars.free();
return soa;
diff --git a/test/Upfront/Array.Upfront.hpp b/test/Upfront/Array.Upfront.hpp
index 426496a..c3fb4fb 100644
--- a/test/Upfront/Array.Upfront.hpp
+++ b/test/Upfront/Array.Upfront.hpp
@@ -27,14 +27,14 @@ Code gen__array_base()
Code gen__array( StrC type )
{
static Code t_allocator_info = def_type( name(AllocatorInfo) );
- static Code v_nullptr = untyped_str( code(nullptr));
+ static Code v_nullptr = code_str( code(nullptr));
static Code spec_ct_member = def_specifiers( 2, ESpecifier::Constexpr, ESpecifier::Static_Member );
static Code spec_static_inline = def_specifiers( 2, ESpecifier::Static_Member, ESpecifier::Inline );
static Code spec_static = def_specifier( ESpecifier::Static_Member );
static Code using_header = def_using( name(Header), def_type( name(ArrayHeader) ) );
- static Code ct_grow_formula = def_variable( t_auto, name(grow_formula), untyped_str( code( & array_grow_formula )), spec_ct_member );
+ static Code ct_grow_formula = def_variable( t_auto, name(grow_formula), code_str( code( & array_grow_formula )), spec_ct_member );
StrC name;
{
@@ -134,7 +134,7 @@ Code gen__array( StrC type )
, def_param( t_alias, name(value) )
);
- Code body = untyped_str( code(
+ Code body = code_str( code(
Header& header = * get_header();
if ( begin < 0 || end >= header.Num )
diff --git a/test/Upfront/HashTable.Upfront.hpp b/test/Upfront/HashTable.Upfront.hpp
index 203dbc5..b8d4461 100644
--- a/test/Upfront/HashTable.Upfront.hpp
+++ b/test/Upfront/HashTable.Upfront.hpp
@@ -140,7 +140,7 @@ Code gen__hashtable( StrC type )
char const* tmpl = stringize(
void (*) ( u64 key, value )
);
- Code value = untyped_str( token_fmt( "type", (StrC)t_type->to_string(), tmpl ) );
+ Code value = code_str( token_fmt( "type", (StrC)t_type->to_string(), tmpl ) );
using_map_proc = def_using ( name(MapProc), value);
}
@@ -166,7 +166,7 @@ Code gen__hashtable( StrC type )
char const* tmpl = stringize(
void (*) ( u64 key, value )
);
- Code value = untyped_str( token_fmt( "type", (StrC)t_type_ptr->to_string(), tmpl ) );
+ Code value = code_str( token_fmt( "type", (StrC)t_type_ptr->to_string(), tmpl ) );
using_map_mut_proc = def_using ( name(MapMutProc), value);
}
diff --git a/test/Upfront/Sanity.Upfront.hpp b/test/Upfront/Sanity.Upfront.hpp
index 979dda3..3484e23 100644
--- a/test/Upfront/Sanity.Upfront.hpp
+++ b/test/Upfront/Sanity.Upfront.hpp
@@ -54,7 +54,7 @@ u32 gen_sanity_upfront()
Code fwd = def_enum( name(ETestEnum), NoCode, t_u8 );
Code def;
{
- Code body = untyped_str( code(
+ Code body = code_str( code(
A,
B,
C
@@ -160,7 +160,7 @@ u32 gen_sanity_upfront()
Code bitflagtest;
{
- Code body = def_enum_body( 1, untyped_str( code(
+ Code body = def_enum_body( 1, code_str( code(
A = 1 << 0,
B = 1 << 1,
C = 1 << 2
@@ -177,7 +177,7 @@ u32 gen_sanity_upfront()
);
op_fwd = def_operator( EOperator::BOr, params, t_bitflag );
- op_or = def_operator( EOperator::BOr, params, t_bitflag, untyped_str( code(
+ op_or = def_operator( EOperator::BOr, params, t_bitflag, code_str( code(
return EBitFlagtest( (u8)a | (u8)b );
)));
}
@@ -299,7 +299,7 @@ u32 gen_sanity_upfront()
// Variable
{
Code bss = def_variable( t_u8, name(test_variable) );
- Code data = def_variable( t_u8, name(test_variable2), untyped_str( code( 0x12 )) );
+ Code data = def_variable( t_u8, name(test_variable2), code_str( code( 0x12 )) );
gen_sanity_file.print(bss);
gen_sanity_file.print(data);