Started to generate the enums from csv (ECode, EOperator, ESpecifier).

- Changed the zpl csv parser to only accept hex values with 0x perfix. it was messing with the add term.
- Small changes to the clang format config.
This commit is contained in:
Edward R. Gonzalez 2023-07-26 14:21:20 -04:00
parent 8232e79aac
commit cf65638979
20 changed files with 871 additions and 744 deletions

View File

@ -0,0 +1,2 @@
API_Export, GEN_API_Export_Code
API_Import, GEN_API_Import_Code
1 API_Export GEN_API_Export_Code
1 API_Export GEN_API_Export_Code
2 API_Import GEN_API_Import_Code

View File

@ -0,0 +1,46 @@
Untyped
Comment
Access_Private
Access_Protected
Access_Public
PlatformAttributes
Class
Class_Fwd
Class_Body
Enum
Enum_Fwd
Enum_Body
Enum_Class
Enum_Class_Fwd
Execution
Export_Body
Extern_Linkage
Extern_Linkage_Body
Friend
Function
Function_Fwd
Function_Body
Global_Body
Module
Namespace
Namespace_Body
Operator
Operator_Fwd
Operator_Member
Operator_Member_Fwd
Operator_Cast
Operator_Cast_Fwd
Parameters
Preprocessor_Include
Specifiers
Struct
Struct_Fwd
Struct_Body
Template
Typedef
Typename
Union
Union_Body
Using
Using_Namespace
Variable
1 Untyped
1 Untyped
2 Comment
3 Access_Private
4 Access_Protected
5 Access_Public
6 PlatformAttributes
7 Class
8 Class_Fwd
9 Class_Body
10 Enum
11 Enum_Fwd
12 Enum_Body
13 Enum_Class
14 Enum_Class_Fwd
15 Execution
16 Export_Body
17 Extern_Linkage
18 Extern_Linkage_Body
19 Friend
20 Function
21 Function_Fwd
22 Function_Body
23 Global_Body
24 Module
25 Namespace
26 Namespace_Body
27 Operator
28 Operator_Fwd
29 Operator_Member
30 Operator_Member_Fwd
31 Operator_Cast
32 Operator_Cast_Fwd
33 Parameters
34 Preprocessor_Include
35 Specifiers
36 Struct
37 Struct_Fwd
38 Struct_Body
39 Template
40 Typedef
41 Typename
42 Union
43 Union_Body
44 Using
45 Using_Namespace
46 Variable

View File

@ -0,0 +1,42 @@
Assign, "="
Assign_Add, "+="
Assign_Subtract, "-="
Assign_Multiply, "*="
Assign_Divide, "/="
Assign_Modulo, "%="
Assign_BAnd, "&="
Assign_BOr, "|="
Assign_BXOr, "^="
Assign_LShift, "<<="
Assign_RShift, ">>="
Increment, "++"
Decrement, "--"
Unary_Plus, "+"
Unary_Minus, "-"
UnaryNot, "!"
Add, "+"
Subtract, "-"
Multiply, "*"
Divide, "/"
Modulo, "%"
BNot, "~"
BAnd, "&"
BOr, "|"
BXOr, "^"
LShift, "<<"
RShift, ">>"
LAnd, "&&"
LOr, "||"
LEqual, "=="
LNot, "!="
Lesser, "<"
Greater, ">"
LesserEqual, "<="
GreaterEqual, ">="
Subscript, "[]"
Indirection, "*"
AddressOf, "&"
MemberOfPointer, "->"
PtrToMemOfPtr, "->*"
FunctionCall, "()"
Comma, ","
1 Assign =
1 Assign =
2 Assign_Add +=
3 Assign_Subtract -=
4 Assign_Multiply *=
5 Assign_Divide /=
6 Assign_Modulo %=
7 Assign_BAnd &=
8 Assign_BOr |=
9 Assign_BXOr ^=
10 Assign_LShift <<=
11 Assign_RShift >>=
12 Increment ++
13 Decrement --
14 Unary_Plus +
15 Unary_Minus -
16 UnaryNot !
17 Add +
18 Subtract -
19 Multiply *
20 Divide /
21 Modulo %
22 BNot ~
23 BAnd &
24 BOr |
25 BXOr ^
26 LShift <<
27 RShift >>
28 LAnd &&
29 LOr ||
30 LEqual ==
31 LNot !=
32 Lesser <
33 Greater >
34 LesserEqual <=
35 GreaterEqual >=
36 Subscript []
37 Indirection *
38 AddressOf &
39 MemberOfPointer ->
40 PtrToMemOfPtr ->*
41 FunctionCall ()
42 Comma ,

View File

@ -0,0 +1,22 @@
Invalid, INVALID
Consteval, consteval
Constexpr, constexpr
Constinit, constinit
Explicit, explicit
External_Linkage, extern
Global, global
Inline, inline
Internal_Linkage, internal
Local_Persist, local_persist
Mutable, mutable
Ptr, *
Ref, &
Register, register
RValue, &&
Static, static
Thread_Local, thread_local
Volatile, volatile
Virtual, virtual
Const, const
Final, final
Override, override
1 Invalid INVALID
1 Invalid INVALID
2 Consteval consteval
3 Constexpr constexpr
4 Constinit constinit
5 Explicit explicit
6 External_Linkage extern
7 Global global
8 Inline inline
9 Internal_Linkage internal
10 Local_Persist local_persist
11 Mutable mutable
12 Ptr *
13 Ref &
14 Register register
15 RValue &&
16 Static static
17 Thread_Local thread_local
18 Volatile volatile
19 Virtual virtual
20 Const const
21 Final final
22 Override override

View File

@ -0,0 +1,69 @@
Access_Private, "private"
Access_Protected, "protected"
Access_Public, "public"
Access_MemberSymbol, "."
Access_StaticSymbol, "::"
Ampersand, "&"
Ampersand_DBL, "&&"
Assign_Classifer, ":"
Attribute_Open, "[["
Attribute_Close, "]]"
BraceCurly_Open, "{"
BraceCurly_Close, "}"
BraceSquare_Open, "["
BraceSquare_Close, "]"
Capture_Start, "("
Capture_End, ")"
Comment, "__comment__"
Char, "__char__"
Comma, ","
Decl_Class, "class"
Decl_GNU_Attribute, "__attribute__"
Decl_MSVC_Attribute, "__declspec"
Decl_Enum, "enum"
Decl_Extern_Linkage, "extern"
Decl_Friend, "friend"
Decl_Module, "module"
Decl_Namespace, "namespace"
Decl_Operator, "operator"
Decl_Struct, "struct"
Decl_Template, "template"
Decl_Typedef, "typedef"
Decl_Using, "using"
Decl_Union, "union"
Identifier, "__identifier__"
Module_Import, "import"
Module_Export, "export"
Number, "number"
Operator, "operator"
Preprocessor_Directive, "#"
Preprocessor_Include, "include"
Spec_Alignas, "alignas"
Spec_Const, "const"
Spec_Consteval, "consteval"
Spec_Constexpr, "constexpr"
Spec_Constinit, "constinit"
Spec_Explicit, "explicit"
Spec_Extern, "extern"
Spec_Final, "final"
Spec_Global, "global"
Spec_Inline, "inline"
Spec_Internal_Linkage, "internal"
Spec_LocalPersist, "local_persist"
Spec_Mutable, "mutable"
Spec_Override, "override"
Spec_Static, "static"
Spec_ThreadLocal, "thread_local"
Spec_Volatile, "volatile"
Star, "*"
Statement_End, ";"
String, "__string__"
Type_Unsigned, "unsigned"
Type_Signed, "signed"
Type_Short, "short"
Type_Long, "long"
Type_char, "char"
Type_int, "int"
Type_double, "double"
Varadic_Argument, "..."
Attributes_Start, "__attrib_start__"
1 Access_Private private
1 Access_Private private
2 Access_Protected protected
3 Access_Public public
4 Access_MemberSymbol .
5 Access_StaticSymbol ::
6 Ampersand &
7 Ampersand_DBL &&
8 Assign_Classifer :
9 Attribute_Open [[
10 Attribute_Close ]]
11 BraceCurly_Open {
12 BraceCurly_Close }
13 BraceSquare_Open [
14 BraceSquare_Close ]
15 Capture_Start (
16 Capture_End )
17 Comment __comment__
18 Char __char__
19 Comma ,
20 Decl_Class class
21 Decl_GNU_Attribute __attribute__
22 Decl_MSVC_Attribute __declspec
23 Decl_Enum enum
24 Decl_Extern_Linkage extern
25 Decl_Friend friend
26 Decl_Module module
27 Decl_Namespace namespace
28 Decl_Operator operator
29 Decl_Struct struct
30 Decl_Template template
31 Decl_Typedef typedef
32 Decl_Using using
33 Decl_Union union
34 Identifier __identifier__
35 Module_Import import
36 Module_Export export
37 Number number
38 Operator operator
39 Preprocessor_Directive #
40 Preprocessor_Include include
41 Spec_Alignas alignas
42 Spec_Const const
43 Spec_Consteval consteval
44 Spec_Constexpr constexpr
45 Spec_Constinit constinit
46 Spec_Explicit explicit
47 Spec_Extern extern
48 Spec_Final final
49 Spec_Global global
50 Spec_Inline inline
51 Spec_Internal_Linkage internal
52 Spec_LocalPersist local_persist
53 Spec_Mutable mutable
54 Spec_Override override
55 Spec_Static static
56 Spec_ThreadLocal thread_local
57 Spec_Volatile volatile
58 Star *
59 Statement_End ;
60 String __string__
61 Type_Unsigned unsigned
62 Type_Signed signed
63 Type_Short short
64 Type_Long long
65 Type_char char
66 Type_int int
67 Type_double double
68 Varadic_Argument ...
69 Attributes_Start __attrib_start__

View File

@ -1,3 +1,5 @@
#pragma region AST
Code Code::Global; Code Code::Global;
Code Code::Invalid; Code Code::Invalid;
@ -5,215 +7,11 @@ AST* AST::duplicate()
{ {
using namespace ECode; using namespace ECode;
AST* AST* result = make_code().ast;
result = make_code().ast;
#ifndef GEN_USE_RECURSIVE_AST_DUPLICATION
mem_copy( result, this, sizeof( AST ) ); mem_copy( result, this, sizeof( AST ) );
result->Parent = nullptr; result->Parent = nullptr;
#else
// TODO : Stress test this...
switch ( Type )
{
case Invalid:
log_failure("Attempted to duplicate invalid code! - \n%s", Parent ? Parent->debug_str() : Name );
return nullptr
case Untyped:
case Comment:
case Execution:
case Access_Private:
case Access_Protected:
case Access_Public:
case PlatformAttributes:
case Preprocessor_Include:
case Module:
case Specifiers:
case Using_Namespace:
mem_copy( result, this, sizeof( AST ) );
break;
case Extern_Linkage:
case Friend:
mem_copy( result, this, sizeof( AST ) );
if (Value)
result->Value = Value->duplicate();
break;
case Class:
case Struct:
case Enum:
mem_copy( result, this, sizeof( AST ) );
if ( Attributes)
result->Attributes = Attributes->duplicate();
if ( ParentType )
result->ParentType = ParentType->duplicate();
result->Body = Body->duplicate();
break;
case Enum_Fwd:
case Class_Fwd:
case Struct_Fwd:
mem_copy( result, this, sizeof( AST ) );
if ( Attributes)
result->Attributes = Attributes->duplicate();
if ( ParentType )
result->ParentType = ParentType->duplicate();
break;
case Function:
case Operator:
case Operator_Member:
mem_copy( result, this, sizeof( AST ) );
if ( Attributes)
result->Attributes = Attributes->duplicate();
if ( Specs )
result->ParentType = ParentType->duplicate();
if ( ReturnType )
result->ReturnType = ReturnType->duplicate();
if ( Params )
result->Params = Params->duplicate();
result->Body = Body->duplicate();
break;
case Function_Fwd:
case Operator_Fwd:
case Operator_Member_Fwd:
mem_copy( result, this, sizeof( AST ) );
if ( Attributes)
result->Attributes = Attributes->duplicate();
if ( Specs )
result->ParentType = ParentType->duplicate();
if ( ReturnType )
result->ReturnType = ReturnType->duplicate();
if ( Params )
result->Params = Params->duplicate();
break;
case Namespace:
mem_copy( result, this, sizeof( AST ) );
result->Body = Body->duplicate();
break;
case Operator_Cast:
mem_copy( result, this, sizeof( AST ) );
result->ValueType = ValueType->duplicate();
result->Body = Body->duplicate();
break;
case Operator_Cast_Fwd:
mem_copy( result, this, sizeof( AST ) );
result->ValueType = ValueType->duplicate();
break;
case Parameters:
mem_copy( result, this, sizeof( AST ) );
result->NumEntries = 0;
result->Last = nullptr;
result->Next = nullptr;
if ( NumEntries - 1 > 0 )
{
CodeParam parent = result->cast<CodeParam>();
for ( CodeParam param : Next->cast<CodeParam>() )
{
parent.append( param );
}
}
break;
case Template:
mem_copy( result, this, sizeof( AST ) );
result->Params = Params->duplicate();
result->Declaration = Declaration->duplicate();
break;
case Typename:
mem_copy( result, this, sizeof( AST ) );
if (Attributes)
result->Attributes = Attributes->duplicate();
if ( Specs )
result->Specs = Specs->duplicate();
if ( ArrExpr )
result->ArrExpr = ArrExpr->duplicate();
break;
case Typedef:
case Using:
mem_copy( result, this, sizeof( AST ) );
if (Attributes)
result->Attributes = Attributes->duplicate();
if ( UnderlyingType )
result->UnderlyingType = UnderlyingType->duplicate();
break;
case Union:
mem_copy( result, this, sizeof( AST ) );
if ( Attributes)
result->Attributes = Attributes->duplicate();
result->Body = Body->duplicate();
break;
case Variable:
mem_copy( result, this, sizeof( AST ) );
if (Attributes)
result->Attributes = Attributes->duplicate();
if ( Specs )
result->Specs = Specs->duplicate();
result->ValueType = UnderlyingType->duplicate();
if ( Value )
result->Value = Value->duplicate();
break;
case Class_Body:
case Enum_Body:
case Export_Body:
case Extern_Linkage_Body:
case Function_Body:
case Global_Body:
case Namespace_Body:
case Struct_Body:
case Union_Body:
CodeBody
body = cast<CodeBody>();
body->Name = Name;
body->Type = Type;
for ( Code entry : cast<CodeBody>() )
{
result->append( entry.ast );
}
break;
}
#endif
return result; return result;
} }
@ -1028,3 +826,5 @@ bool AST::validate_body()
return false; return false;
} }
#pragma endregion AST

View File

@ -1,3 +1,5 @@
#pragma region Data Structures
// 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>; using StringTable = HashTable<String const>;
@ -1011,3 +1013,4 @@ struct AST_Var
static_assert( sizeof(AST_Var) == sizeof(AST), "ERROR: AST_Var is not the same size as AST"); static_assert( sizeof(AST_Var) == sizeof(AST), "ERROR: AST_Var is not the same size as AST");
#pragma endregion Filtered ASTs #pragma endregion Filtered ASTs
#pragma endregion Data Structures

View File

@ -0,0 +1,78 @@
// This is the non-bootstraped version of the ECode. This will be obsolete once bootstrap is stress tested.
namespace ECode
{
# define Define_Types \
Entry( Untyped ) \
Entry( Comment ) \
Entry( Access_Private ) \
Entry( Access_Protected ) \
Entry( Access_Public ) \
Entry( PlatformAttributes ) \
Entry( Class ) \
Entry( Class_Fwd ) \
Entry( Class_Body ) \
Entry( Enum ) \
Entry( Enum_Fwd ) \
Entry( Enum_Body ) \
Entry( Enum_Class ) \
Entry( Enum_Class_Fwd ) \
Entry( Execution ) \
Entry( Export_Body ) \
Entry( Extern_Linkage ) \
Entry( Extern_Linkage_Body ) \
Entry( Friend ) \
Entry( Function ) \
Entry( Function_Fwd ) \
Entry( Function_Body ) \
Entry( Global_Body ) \
Entry( Module ) \
Entry( Namespace ) \
Entry( Namespace_Body ) \
Entry( Operator ) \
Entry( Operator_Fwd ) \
Entry( Operator_Member ) \
Entry( Operator_Member_Fwd ) \
Entry( Operator_Cast ) \
Entry( Operator_Cast_Fwd ) \
Entry( Parameters ) \
Entry( Preprocessor_Include ) \
Entry( Specifiers ) \
Entry( Struct ) \
Entry( Struct_Fwd ) \
Entry( Struct_Body ) \
Entry( Template ) \
Entry( Typedef ) \
Entry( Typename ) \
Entry( Union ) \
Entry( Union_Body) \
Entry( Using ) \
Entry( Using_Namespace ) \
Entry( Variable )
enum Type : u32
{
# define Entry( Type ) Type,
Define_Types
# undef Entry
Num_Types,
Invalid
};
inline
StrC to_str( Type type )
{
static
StrC lookup[Num_Types] = {
# define Entry( Type ) { sizeof(stringize(Type)), stringize(Type) },
Define_Types
# undef Entry
};
return lookup[ type ];
}
# undef Define_Types
}
using CodeT = ECode::Type;

View File

@ -0,0 +1,75 @@
// This is the non-bootstraped version of the EOperator. This will be obsolete once bootstrap is stress tested.
namespace EOperator
{
# define Define_Operators \
Entry( Assign, = ) \
Entry( Assign_Add, += ) \
Entry( Assign_Subtract, -= ) \
Entry( Assign_Multiply, *= ) \
Entry( Assign_Divide, /= ) \
Entry( Assign_Modulo, %= ) \
Entry( Assign_BAnd, &= ) \
Entry( Assign_BOr, |= ) \
Entry( Assign_BXOr, ^= ) \
Entry( Assign_LShift, <<= ) \
Entry( Assign_RShift, >>= ) \
Entry( Increment, ++ ) \
Entry( Decrement, -- ) \
Entry( Unary_Plus, + ) \
Entry( Unary_Minus, - ) \
Entry( UnaryNot, ! ) \
Entry( Add, + ) \
Entry( Subtract, - ) \
Entry( Multiply, * ) \
Entry( Divide, / ) \
Entry( Modulo, % ) \
Entry( BNot, ~ ) \
Entry( BAnd, & ) \
Entry( BOr, | ) \
Entry( BXOr, ^ ) \
Entry( LShift, << ) \
Entry( RShift, >> ) \
Entry( LAnd, && ) \
Entry( LOr, || ) \
Entry( LEqual, == ) \
Entry( LNot, != ) \
Entry( Lesser, < ) \
Entry( Greater, > ) \
Entry( LesserEqual, <= ) \
Entry( GreaterEqual, >= ) \
Entry( Subscript, [] ) \
Entry( Indirection, * ) \
Entry( AddressOf, & ) \
Entry( MemberOfPointer, -> ) \
Entry( PtrToMemOfPtr, ->* ) \
Entry( FunctionCall, () )
enum Type : u32
{
# define Entry( Type_, Token_ ) Type_,
Define_Operators
# undef Entry
Comma,
Num_Ops,
Invalid
};
inline
char const* to_str( Type op )
{
local_persist
char const* lookup[ Num_Ops ] = {
# define Entry( Type_, Token_ ) stringize(Token_),
Define_Operators
# undef Entry
","
};
return lookup[ op ];
}
# undef Define_Operators
}
using OperatorT = EOperator::Type;

View File

@ -0,0 +1,104 @@
// This is the non-bootstraped version of the ESpecifier. This will be obsolete once bootstrap is stress tested.
namespace ESpecifier
{
/*
Note: The following are handled separately:
attributes
alignas
*/
# define Define_Specifiers \
Entry( Invalid, INVALID ) \
Entry( Consteval, consteval ) \
Entry( Constexpr, constexpr ) \
Entry( Constinit, constinit ) \
Entry( Explicit, explicit ) \
Entry( External_Linkage, extern ) \
Entry( Global, global ) \
Entry( Inline, inline ) \
Entry( Internal_Linkage, internal ) \
Entry( Local_Persist, local_persist ) \
Entry( Mutable, mutable ) \
Entry( Ptr, * ) \
Entry( Ref, & ) \
Entry( Register, register ) \
Entry( RValue, && ) \
Entry( Static, static ) \
Entry( Thread_Local, thread_local ) \
Entry( Volatile, volatile ) \
Entry( Virtual, virtual ) \
Entry( Const, const ) \
Entry( Final, final ) \
Entry( Override, override )
enum Type : u32
{
# define Entry( Specifier, Code ) Specifier,
Define_Specifiers
# undef Entry
Num_Specifiers,
};
inline
bool is_trailing( Type specifier )
{
return specifier > Virtual;
}
// Specifier to string
inline
StrC to_str( Type specifier )
{
local_persist
StrC lookup[ Num_Specifiers ] = {
# pragma push_macro( "global" )
# pragma push_macro( "internal" )
# pragma push_macro( "local_persist" )
# undef global
# undef internal
# undef local_persist
# define Entry( Spec_, Code_ ) { sizeof(stringize(Code_)), stringize(Code_) },
Define_Specifiers
# undef Entry
# pragma pop_macro( "global" )
# pragma pop_macro( "internal" )
# pragma pop_macro( "local_persist" )
};
return lookup[ specifier ];
}
inline
Type to_type( StrC str )
{
local_persist
u32 keymap[ Num_Specifiers ];
do_once_start
for ( u32 index = 0; index < Num_Specifiers; index++ )
{
StrC enum_str = to_str( (Type)index );
// We subtract 1 to remove the null terminator
// This is because the tokens lexed are not null terminated.
keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1);
}
do_once_end
u32 hash = crc32( str.Ptr, str.Len );
for ( u32 index = 0; index < Num_Specifiers; index++ )
{
if ( keymap[index] == hash )
return (Type)index;
}
return Invalid;
}
# undef Define_Specifiers
}
using SpecifierT = ESpecifier::Type;

View File

@ -1,3 +1,5 @@
#pragma region Gen Interface
// Initialize the library. // Initialize the library.
// This currently just initializes the CodePool. // This currently just initializes the CodePool.
void init(); void init();
@ -32,6 +34,7 @@ void set_allocator_string_table( AllocatorInfo string_allocator );
void set_allocator_type_table ( AllocatorInfo type_reg_allocator ); void set_allocator_type_table ( AllocatorInfo type_reg_allocator );
#pragma region Upfront #pragma region Upfront
CodeAttributes def_attributes( StrC content ); CodeAttributes def_attributes( StrC content );
CodeComment def_comment ( StrC content ); CodeComment def_comment ( StrC content );
@ -122,9 +125,11 @@ CodeBody def_struct_body ( s32 num, ... );
CodeBody def_struct_body ( s32 num, Code* codes ); CodeBody def_struct_body ( s32 num, Code* codes );
CodeBody def_union_body ( s32 num, ... ); CodeBody def_union_body ( s32 num, ... );
CodeBody def_union_body ( s32 num, Code* codes ); CodeBody def_union_body ( s32 num, Code* codes );
#pragma endregion Upfront #pragma endregion Upfront
#pragma region Parsing #pragma region Parsing
CodeClass parse_class ( StrC class_def ); CodeClass parse_class ( StrC class_def );
CodeEnum parse_enum ( StrC enum_def ); CodeEnum parse_enum ( StrC enum_def );
CodeBody parse_export_body ( StrC export_def ); CodeBody parse_export_body ( StrC export_def );
@ -142,13 +147,18 @@ CodeTypedef parse_typedef ( StrC typedef_def );
CodeUnion parse_union ( StrC union_def ); CodeUnion parse_union ( StrC union_def );
CodeUsing parse_using ( StrC using_def ); CodeUsing parse_using ( StrC using_def );
CodeVar parse_variable ( StrC var_def ); CodeVar parse_variable ( StrC var_def );
#pragma endregion Parsing #pragma endregion Parsing
#pragma region Untyped text #pragma region Untyped text
sw token_fmt_va( char* buf, uw buf_size, s32 num_tokens, va_list va ); sw token_fmt_va( char* buf, uw buf_size, s32 num_tokens, va_list va );
StrC token_fmt_impl( sw, ... ); StrC token_fmt_impl( sw, ... );
Code untyped_str ( StrC content); Code untyped_str ( StrC content);
Code untyped_fmt ( char const* fmt, ... ); Code untyped_fmt ( char const* fmt, ... );
Code untyped_token_fmt( char const* fmt, s32 num_tokens, ... ); Code untyped_token_fmt( char const* fmt, s32 num_tokens, ... );
#pragma endregion Untyped text #pragma endregion Untyped text
#pragma endregion Gen Interface

View File

@ -8,83 +8,6 @@ using LogFailType = sw(*)(char const*, ...);
constexpr LogFailType log_failure = fatal; constexpr LogFailType log_failure = fatal;
#endif #endif
namespace ECode
{
# define Define_Types \
Entry( Untyped ) \
Entry( Comment ) \
Entry( Access_Private ) \
Entry( Access_Protected ) \
Entry( Access_Public ) \
Entry( PlatformAttributes ) \
Entry( Class ) \
Entry( Class_Fwd ) \
Entry( Class_Body ) \
Entry( Enum ) \
Entry( Enum_Fwd ) \
Entry( Enum_Body ) \
Entry( Enum_Class ) \
Entry( Enum_Class_Fwd ) \
Entry( Execution ) \
Entry( Export_Body ) \
Entry( Extern_Linkage ) \
Entry( Extern_Linkage_Body ) \
Entry( Friend ) \
Entry( Function ) \
Entry( Function_Fwd ) \
Entry( Function_Body ) \
Entry( Global_Body ) \
Entry( Module ) \
Entry( Namespace ) \
Entry( Namespace_Body ) \
Entry( Operator ) \
Entry( Operator_Fwd ) \
Entry( Operator_Member ) \
Entry( Operator_Member_Fwd ) \
Entry( Operator_Cast ) \
Entry( Operator_Cast_Fwd ) \
Entry( Parameters ) \
Entry( Preprocessor_Include ) \
Entry( Specifiers ) \
Entry( Struct ) \
Entry( Struct_Fwd ) \
Entry( Struct_Body ) \
Entry( Template ) \
Entry( Typedef ) \
Entry( Typename ) \
Entry( Union ) \
Entry( Union_Body) \
Entry( Using ) \
Entry( Using_Namespace ) \
Entry( Variable )
enum Type : u32
{
# define Entry( Type ) Type,
Define_Types
# undef Entry
Num_Types,
Invalid
};
inline
StrC to_str( Type type )
{
static
StrC lookup[Num_Types] = {
# define Entry( Type ) { sizeof(stringize(Type)), stringize(Type) },
Define_Types
# undef Entry
};
return lookup[ type ];
}
# undef Define_Types
}
using CodeT = ECode::Type;
// 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 class EnumT : u8
{ {
@ -95,183 +18,6 @@ enum class EnumT : u8
constexpr EnumT EnumClass = EnumT::Class; constexpr EnumT EnumClass = EnumT::Class;
constexpr EnumT EnumRegular = EnumT::Regular; constexpr EnumT EnumRegular = EnumT::Regular;
namespace EOperator
{
# define Define_Operators \
Entry( Assign, = ) \
Entry( Assign_Add, += ) \
Entry( Assign_Subtract, -= ) \
Entry( Assign_Multiply, *= ) \
Entry( Assign_Divide, /= ) \
Entry( Assign_Modulo, %= ) \
Entry( Assign_BAnd, &= ) \
Entry( Assign_BOr, |= ) \
Entry( Assign_BXOr, ^= ) \
Entry( Assign_LShift, <<= ) \
Entry( Assign_RShift, >>= ) \
Entry( Increment, ++ ) \
Entry( Decrement, -- ) \
Entry( Unary_Plus, + ) \
Entry( Unary_Minus, - ) \
Entry( UnaryNot, ! ) \
Entry( Add, + ) \
Entry( Subtract, - ) \
Entry( Multiply, * ) \
Entry( Divide, / ) \
Entry( Modulo, % ) \
Entry( BNot, ~ ) \
Entry( BAnd, & ) \
Entry( BOr, | ) \
Entry( BXOr, ^ ) \
Entry( LShift, << ) \
Entry( RShift, >> ) \
Entry( LAnd, && ) \
Entry( LOr, || ) \
Entry( LEqual, == ) \
Entry( LNot, != ) \
Entry( Lesser, < ) \
Entry( Greater, > ) \
Entry( LesserEqual, <= ) \
Entry( GreaterEqual, >= ) \
Entry( Subscript, [] ) \
Entry( Indirection, * ) \
Entry( AddressOf, & ) \
Entry( MemberOfPointer, -> ) \
Entry( PtrToMemOfPtr, ->* ) \
Entry( FunctionCall, () )
enum Type : u32
{
# define Entry( Type_, Token_ ) Type_,
Define_Operators
# undef Entry
Comma,
Num_Ops,
Invalid
};
inline
char const* to_str( Type op )
{
local_persist
char const* lookup[ Num_Ops ] = {
# define Entry( Type_, Token_ ) stringize(Token_),
Define_Operators
# undef Entry
","
};
return lookup[ op ];
}
# undef Define_Operators
}
using OperatorT = EOperator::Type;
namespace ESpecifier
{
/*
Note: The following are handled separately:
attributes
alignas
*/
# define Define_Specifiers \
Entry( Invalid, INVALID ) \
Entry( Consteval, consteval ) \
Entry( Constexpr, constexpr ) \
Entry( Constinit, constinit ) \
Entry( Explicit, explicit ) \
Entry( External_Linkage, extern ) \
Entry( Global, global ) \
Entry( Inline, inline ) \
Entry( Internal_Linkage, internal ) \
Entry( Local_Persist, local_persist ) \
Entry( Mutable, mutable ) \
Entry( Ptr, * ) \
Entry( Ref, & ) \
Entry( Register, register ) \
Entry( RValue, && ) \
Entry( Static, static ) \
Entry( Thread_Local, thread_local ) \
Entry( Volatile, volatile ) \
Entry( Virtual, virtual ) \
Entry( Const, const ) \
Entry( Final, final ) \
Entry( Override, override )
enum Type : u32
{
# define Entry( Specifier, Code ) Specifier,
Define_Specifiers
# undef Entry
Num_Specifiers,
};
inline
bool is_trailing( Type specifier )
{
return specifier > Virtual;
}
// Specifier to string
inline
StrC to_str( Type specifier )
{
local_persist
StrC lookup[ Num_Specifiers ] = {
# pragma push_macro( "global" )
# pragma push_macro( "internal" )
# pragma push_macro( "local_persist" )
# undef global
# undef internal
# undef local_persist
# define Entry( Spec_, Code_ ) { sizeof(stringize(Code_)), stringize(Code_) },
Define_Specifiers
# undef Entry
# pragma pop_macro( "global" )
# pragma pop_macro( "internal" )
# pragma pop_macro( "local_persist" )
};
return lookup[ specifier ];
}
inline
Type to_type( StrC str )
{
local_persist
u32 keymap[ Num_Specifiers ];
do_once_start
for ( u32 index = 0; index < Num_Specifiers; index++ )
{
StrC enum_str = to_str( (Type)index );
// We subtract 1 to remove the null terminator
// This is because the tokens lexed are not null terminated.
keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1);
}
do_once_end
u32 hash = crc32( str.Ptr, str.Len );
for ( u32 index = 0; index < Num_Specifiers; index++ )
{
if ( keymap[index] == hash )
return (Type)index;
}
return Invalid;
}
# undef Define_Specifiers
}
using SpecifierT = ESpecifier::Type;
enum class AccessSpec : u32 enum class AccessSpec : u32
{ {
Default, Default,

View File

@ -507,6 +507,13 @@ char* adt_parse_number( ADT_Node* node, char* base_str )
{ {
node_props = EADT_PROPS_IS_HEX; node_props = EADT_PROPS_IS_HEX;
} }
/* bail if ZPL_ADT_PROPS_IS_HEX is unset but we get 'x' on input */
if ( char_to_lower( *e ) == 'x' && ( node_props != EADT_PROPS_IS_HEX ) )
{
return ++base_str;
}
while ( char_is_hex_digit( *e ) || char_to_lower( *e ) == 'x' ) while ( char_is_hex_digit( *e ) || char_to_lower( *e ) == 'x' )
{ {
buf[ ib++ ] = *e++; buf[ ib++ ] = *e++;
@ -795,155 +802,185 @@ ADT_Error adt_str_to_number_strict( ADT_Node* node )
u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header, char delim ) u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header, char delim )
{ {
CSV_Error err = ECSV_Error__NONE; CSV_Error error = ECSV_Error__NONE;
GEN_ASSERT_NOT_NULL( root ); GEN_ASSERT_NOT_NULL( root );
GEN_ASSERT_NOT_NULL( text ); GEN_ASSERT_NOT_NULL( text );
zero_item( root ); zero_item( root );
adt_make_branch( root, allocator, NULL, has_header ? false : true ); adt_make_branch( root, allocator, NULL, has_header ? false : true );
char* p = text; char* currentChar = text;
char* b = p; char* beginChar;
char* e = p; char* endChar;
sw colc = 0; sw columnIndex = 0;
sw total_colc = 0; sw totalColumnIndex = 0;
do do
{ {
char d = 0; char delimiter = 0;
p = zpl_cast( char* ) str_trim( p, false ); currentChar = zpl_cast( char* ) str_trim( currentChar, false );
if ( *p == 0 )
if ( *currentChar == 0 )
break; break;
ADT_Node row_item = { 0 };
row_item.type = EADT_TYPE_STRING; ADT_Node rowItem = { 0 };
#ifndef GEN_PARSER_DISABLE_ANALYSIS rowItem.type = EADT_TYPE_STRING;
row_item.name_style = EADT_NAME_STYLE_NO_QUOTES;
#endif #ifndef GEN_PARSER_DISABLE_ANALYSIS
rowItem.name_style = EADT_NAME_STYLE_NO_QUOTES;
#endif
/* handle string literals */ /* handle string literals */
if ( *p == '"' ) if ( *currentChar == '"' )
{ {
p = b = e = p + 1; currentChar += 1;
row_item.string = b; beginChar = currentChar;
#ifndef GEN_PARSER_DISABLE_ANALYSIS endChar = currentChar;
row_item.name_style = EADT_NAME_STYLE_DOUBLE_QUOTE; rowItem.string = beginChar;
#endif #ifndef GEN_PARSER_DISABLE_ANALYSIS
rowItem.name_style = EADT_NAME_STYLE_DOUBLE_QUOTE;
#endif
do do
{ {
e = zpl_cast( char* ) str_skip( e, '"' ); endChar = zpl_cast( char* ) str_skip( endChar, '"' );
if ( *e && *( e + 1 ) == '"' )
if ( *endChar && *( endChar + 1 ) == '"' )
{ {
e += 2; endChar += 2;
} }
else else
break; break;
} while ( *e ); }
if ( *e == 0 ) while ( *endChar );
if ( *endChar == 0 )
{ {
GEN_CSV_ASSERT( "unmatched quoted string" ); GEN_CSV_ASSERT( "unmatched quoted string" );
err = ECSV_Error__UNEXPECTED_END_OF_INPUT; error = ECSV_Error__UNEXPECTED_END_OF_INPUT;
return err; return error;
} }
*e = 0;
p = zpl_cast( char* ) str_trim( e + 1, true ); *endChar = 0;
d = *p; currentChar = zpl_cast( char* ) str_trim( endChar + 1, true );
delimiter = * currentChar;
/* unescape escaped quotes (so that unescaped text escapes :) */ /* unescape escaped quotes (so that unescaped text escapes :) */
{ {
char* ep = b; char* escapedChar = beginChar;
do do
{ {
if ( *ep == '"' && *( ep + 1 ) == '"' ) if ( *escapedChar == '"' && *( escapedChar + 1 ) == '"' )
{ {
mem_move( ep, ep + 1, str_len( ep ) ); mem_move( escapedChar, escapedChar + 1, str_len( escapedChar ) );
} }
ep++; escapedChar++;
} while ( *ep ); }
while ( *escapedChar );
} }
} }
else if ( *p == delim ) else if ( *currentChar == delim )
{ {
d = *p; delimiter = * currentChar;
row_item.string = ""; rowItem.string = "";
} }
else if ( *p ) else if ( *currentChar )
{ {
/* regular data */ /* regular data */
b = e = p; beginChar = currentChar;
row_item.string = b; endChar = currentChar;
rowItem.string = beginChar;
do do
{ {
e++; endChar++;
} while ( *e && *e != delim && *e != '\n' );
if ( *e )
{
p = zpl_cast( char* ) str_trim( e, true );
while ( char_is_space( *( e - 1 ) ) )
{
e--;
} }
d = *p; while ( * endChar && * endChar != delim && * endChar != '\n' );
*e = 0;
if ( * endChar )
{
currentChar = zpl_cast( char* ) str_trim( endChar, true );
while ( char_is_space( *( endChar - 1 ) ) )
{
endChar--;
}
delimiter = * currentChar;
* endChar = 0;
} }
else else
{ {
d = 0; delimiter = 0;
p = e; currentChar = endChar;
} }
/* check if number and process if so */ /* check if number and process if so */
b32 skip_number = false; b32 skip_number = false;
char* num_p = b; char* num_p = beginChar;
// We only consider hexadecimal values if they start with 0x
if ( str_len(num_p) > 2 && num_p[0] == '0' && (num_p[1] == 'x' || num_p[1] == 'X') )
{
num_p += 2; // skip '0x' prefix
do do
{ {
if ( ! char_is_hex_digit( *num_p ) && ( ! str_find( "+-.eExX", *num_p ) ) ) if (!char_is_hex_digit(*num_p))
{ {
skip_number = true; skip_number = true;
break; break;
} }
} while ( *num_p++ ); } while (*num_p++);
}
if ( ! skip_number ) else
{ {
adt_str_to_number( &row_item ); skip_number = true;
}
if (!skip_number)
{
adt_str_to_number(&rowItem);
} }
} }
if ( colc >= root->nodes.num() ) if ( columnIndex >= root->nodes.num() )
{ {
adt_append_arr( root, NULL ); adt_append_arr( root, NULL );
} }
root->nodes[ colc ].nodes.append( row_item ); root->nodes[ columnIndex ].nodes.append( rowItem );
if ( d == delim ) if ( delimiter == delim )
{ {
colc++; columnIndex++;
p++; currentChar++;
} }
else if ( d == '\n' || d == 0 ) else if ( delimiter == '\n' || delimiter == 0 )
{ {
/* check if number of rows is not mismatched */ /* check if number of rows is not mismatched */
if ( total_colc < colc ) if ( totalColumnIndex < columnIndex )
total_colc = colc; totalColumnIndex = columnIndex;
else if ( total_colc != colc )
else if ( totalColumnIndex != columnIndex )
{ {
GEN_CSV_ASSERT( "mismatched rows" ); GEN_CSV_ASSERT( "mismatched rows" );
err = ECSV_Error__MISMATCHED_ROWS; error = ECSV_Error__MISMATCHED_ROWS;
return err; return error;
} }
colc = 0;
if ( d != 0 ) columnIndex = 0;
p++;
if ( delimiter != 0 )
currentChar++;
} }
} while ( *p ); }
while ( *currentChar );
if ( root->nodes.num() == 0 ) if ( root->nodes.num() == 0 )
{ {
GEN_CSV_ASSERT( "unexpected end of input. stream is empty." ); GEN_CSV_ASSERT( "unexpected end of input. stream is empty." );
err = ECSV_Error__UNEXPECTED_END_OF_INPUT; error = ECSV_Error__UNEXPECTED_END_OF_INPUT;
return err; return error;
} }
/* consider first row as a header. */ /* consider first row as a header. */
@ -958,7 +995,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
} }
} }
return err; return error;
} }
void csv_free( CSV_Object* obj ) void csv_free( CSV_Object* obj )

View File

@ -3,6 +3,7 @@
#define GEN_EXPOSE_BACKEND #define GEN_EXPOSE_BACKEND
#include "gen.cpp" #include "gen.cpp"
#include "filesystem/gen.scanner.hpp" #include "filesystem/gen.scanner.hpp"
#include "helpers/gen.helper.hpp"
using namespace gen; using namespace gen;
@ -46,7 +47,7 @@ int gen_main()
Code string_ops = scan_file( "dependencies/gen.string_ops.hpp" ); Code string_ops = scan_file( "dependencies/gen.string_ops.hpp" );
Code printing = scan_file( "dependencies/gen.printing.hpp" ); Code printing = scan_file( "dependencies/gen.printing.hpp" );
Code containers = scan_file( "dependencies/gen.containers.hpp" ); Code containers = scan_file( "dependencies/gen.containers.hpp" );
Core hashing = scan_file( "dependencies/gen.hashing.hpp" ); Code hashing = scan_file( "dependencies/gen.hashing.hpp" );
Code string = scan_file( "dependencies/gen.string.hpp" ); Code string = scan_file( "dependencies/gen.string.hpp" );
Code file_handling = scan_file( "dependencies/gen.file_handling.hpp" ); Code file_handling = scan_file( "dependencies/gen.file_handling.hpp" );
Code parsing = scan_file( "dependencies/gen.parsing.hpp" ); Code parsing = scan_file( "dependencies/gen.parsing.hpp" );
@ -60,6 +61,7 @@ int gen_main()
deps_header.print( header_start ); deps_header.print( header_start );
deps_header.print( nspace_macro ); deps_header.print( nspace_macro );
deps_header.print_fmt( "GEN_NS_BEGIN\n\n"); deps_header.print_fmt( "GEN_NS_BEGIN\n\n");
deps_header.print( macros ); deps_header.print( macros );
deps_header.print( basic_types ); deps_header.print( basic_types );
deps_header.print( debug ); deps_header.print( debug );
@ -72,6 +74,7 @@ int gen_main()
deps_header.print( file_handling ); deps_header.print( file_handling );
deps_header.print( parsing ); deps_header.print( parsing );
deps_header.print( timing ); deps_header.print( timing );
deps_header.print_fmt( "GEN_NS_END\n\n"); deps_header.print_fmt( "GEN_NS_END\n\n");
deps_header.write(); deps_header.write();
} }
@ -96,13 +99,16 @@ int gen_main()
deps_impl.print( impl_start ); deps_impl.print( impl_start );
deps_impl.print( header ); deps_impl.print( header );
deps_impl.print_fmt( "\nGEN_NS_BEGIN\n"); deps_impl.print_fmt( "\nGEN_NS_BEGIN\n");
deps_impl.print( debug ); deps_impl.print( debug );
deps_impl.print( string_ops ); deps_impl.print( string_ops );
deps_impl.print( printing ); deps_impl.print( printing );
deps_impl.print( hashing );
deps_impl.print( memory ); deps_impl.print( memory );
deps_impl.print( parsing ); deps_impl.print( parsing );
deps_impl.print( string ); deps_impl.print( string );
deps_impl.print( timing ); deps_impl.print( timing );
deps_impl.print_fmt( "GEN_NS_END\n\n"); deps_impl.print_fmt( "GEN_NS_END\n\n");
deps_impl.write(); deps_impl.write();
} }
@ -116,6 +122,10 @@ int gen_main()
Code interface = scan_file( "components/gen.interface.hpp" ); Code interface = scan_file( "components/gen.interface.hpp" );
Code header_end = scan_file( "components/gen.header_end.hpp" ); Code header_end = scan_file( "components/gen.header_end.hpp" );
CodeBody ecode = gen_ecode( "./components/ECode.csv" );
CodeBody eoperator = gen_eoperator( "./components/EOperator.csv" );
CodeBody especifier = gen_especifier( "./components/ESpecifier.csv" );
Code builder = scan_file( "filesystem/gen.builder.hpp" ); Code builder = scan_file( "filesystem/gen.builder.hpp" );
Builder Builder
@ -126,11 +136,20 @@ int gen_main()
header.print( header_start ); header.print( header_start );
header.print( nspace_macro ); header.print( nspace_macro );
header.print_fmt( "GEN_NS_BEGIN\n\n"); header.print_fmt( "GEN_NS_BEGIN\n\n");
header.print_fmt("#pragma region Types");
header.print( types ); header.print( types );
header.print( ecode );
header.print( eoperator );
header.print( especifier );
header.print_fmt("#pragma endregion Types");
header.print( data_structs ); header.print( data_structs );
header.print( interface ); header.print( interface );
header.print( header_end ); header.print( header_end );
header.print( builder ); header.print( builder );
header.print_fmt( "GEN_NS_END\n\n"); header.print_fmt( "GEN_NS_END\n\n");
header.print( pop_ignores ); header.print( pop_ignores );
header.write(); header.write();
@ -157,6 +176,7 @@ int gen_main()
impl.print( impl_start ); impl.print( impl_start );
impl.print( header ); impl.print( header );
impl.print_fmt( "\nGEN_NS_BEGIN\n\n"); impl.print_fmt( "\nGEN_NS_BEGIN\n\n");
impl.print( data ); impl.print( data );
impl.print( ast_case_macros ); impl.print( ast_case_macros );
impl.print( ast ); impl.print( ast );
@ -164,6 +184,7 @@ int gen_main()
impl.print( upfront ); impl.print( upfront );
impl.print( parsing ); impl.print( parsing );
impl.print( untyped ); impl.print( untyped );
impl.print( builder ); impl.print( builder );
impl.print_fmt( "GEN_NS_END\n\n"); impl.print_fmt( "GEN_NS_END\n\n");
impl.print( pop_ignores ); impl.print( pop_ignores );

View File

@ -22,6 +22,9 @@
GEN_NS_BEGIN GEN_NS_BEGIN
#include "components/gen.types.hpp" #include "components/gen.types.hpp"
#include "components/gen.ecode.hpp"
#include "components/gen.eoperator.hpp"
#include "components/gen.especifier.hpp"
#include "components/gen.data_structures.hpp" #include "components/gen.data_structures.hpp"
#include "components/gen.interface.hpp" #include "components/gen.interface.hpp"
#include "components/gen.header_end.hpp" #include "components/gen.header_end.hpp"

View File

@ -0,0 +1,215 @@
#pragma once
#include "gen.hpp"
using namespace gen;
CodeBody gen_ecode( char const* path )
{
char scratch_mem[kilobytes(1)];
Arena scratch = Arena::init_from_memory( scratch_mem, sizeof(scratch_mem) );
file_read_contents( scratch, zero_terminate, path );
CSV_Object csv_nodes;
csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false );
Array<ADT_Node> enum_strs = csv_nodes.nodes[0].nodes;
String enum_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
String to_str_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
for ( ADT_Node node : enum_strs )
{
char const* code = node.string;
enum_entries.append_fmt( "%s,\n", code );
to_str_entries.append_fmt( "{ sizeof(\"%s\"), \"%s\" },\n", code, code );
}
CodeEnum enum_code = parse_enum( token_fmt( "entries", (StrC)enum_entries, stringize(
enum Type : u32
{
<entries>
NumTypes
};
)));
#pragma push_macro( "local_persist" )
#undef local_persist
CodeFn to_str = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
StrC to_str( Type type )
{
local_persist
StrC lookup[] {
<entries>
};
return lookup[ type ];
}
)));
#pragma pop_macro( "local_persist" )
CodeNamespace nspace = def_namespace( name(ECode), def_namespace_body( args( enum_code, to_str ) ) );
CodeUsing code_t = def_using( name(CodeT), def_type( name(ECode::Type) ) );
return def_global_body( args( nspace, code_t ) );
}
CodeBody gen_eoperator( char const* path )
{
char scratch_mem[kilobytes(1)];
Arena scratch = Arena::init_from_memory( scratch_mem, sizeof(scratch_mem) );
file_read_contents( scratch, zero_terminate, path );
CSV_Object csv_nodes;
csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false );
Array<ADT_Node> enum_strs = csv_nodes.nodes[0].nodes;
Array<ADT_Node> str_strs = csv_nodes.nodes[1].nodes;
String enum_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
String to_str_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
for (uw idx = 0; idx < enum_strs.num(); idx++)
{
char const* enum_str = enum_strs[idx].string;
char const* entry_to_str = str_strs [idx].string;
enum_entries.append_fmt( "%s,\n", enum_str );
to_str_entries.append_fmt( "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
}
CodeEnum enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, stringize(
enum Type : u32
{
<entries>
NumOps
};
)));
#pragma push_macro( "local_persist" )
#undef local_persist
CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, stringize(
StrC to_str( Type op )
{
local_persist
StrC lookup[] {
<entries>
};
return lookup[ op ];
}
)));
#pragma pop_macro( "local_persist" )
CodeNamespace nspace = def_namespace( name(EOperator), def_namespace_body( args( enum_code, to_str ) ) );
CodeUsing operator_t = def_using( name(OperatorT), def_type( name(EOperator::Type) ) );
return def_global_body( args( nspace, operator_t ) );
}
CodeBody gen_especifier( char const* path )
{
char scratch_mem[kilobytes(1)];
Arena scratch = Arena::init_from_memory( scratch_mem, sizeof(scratch_mem) );
file_read_contents( scratch, zero_terminate, path );
CSV_Object csv_nodes;
csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false );
Array<ADT_Node> enum_strs = csv_nodes.nodes[0].nodes;
Array<ADT_Node> str_strs = csv_nodes.nodes[1].nodes;
String enum_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
String to_str_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
for (uw idx = 0; idx < enum_strs.num(); idx++)
{
char const* enum_str = enum_strs[idx].string;
char const* entry_to_str = str_strs [idx].string;
enum_entries.append_fmt( "%s,\n", enum_str );
to_str_entries.append_fmt( "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
}
CodeEnum enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, stringize(
enum Type : u32
{
<entries>
NumSpecifiers
};
)));
CodeFn is_trailing = parse_function(token_fmt("specifier", (StrC)to_str_entries, stringize(
bool is_trailing( Type specifier )
{
return specifier > Virtual;
}
)));
#pragma push_macro( "local_persist" )
#pragma push_macro( "do_once_start" )
#pragma push_macro( "do_once_end" )
#undef local_persist
#undef do_once_start
#undef do_once_end
CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, stringize(
StrC to_str( Type type )
{
local_persist
StrC lookup[] {
<entries>
};
return lookup[ type ];
}
)));
CodeFn to_type = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
Type to_type( StrC str )
{
local_persist
u32 keymap[ NumSpecifiers ];
do_once_start
for ( u32 index = 0; index < NumSpecifiers; index++ )
{
StrC enum_str = to_str( (Type)index );
// We subtract 1 to remove the null terminator
// This is because the tokens lexed are not null terminated.
keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1);
}
do_once_end
u32 hash = crc32( str.Ptr, str.Len );
for ( u32 index = 0; index < NumSpecifiers; index++ )
{
if ( keymap[index] == hash )
return (Type)index;
}
return Invalid;
}
)));
#pragma pop_macro( "local_persist" )
#pragma pop_macro( "do_once_start" )
#pragma pop_macro( "do_once_end" )
CodeNamespace nspace = def_namespace( name(ESpecifier), def_namespace_body( args( enum_code, is_trailing, to_str, to_type ) ) );
CodeUsing specifier_t = def_using( name(SpecifierT), def_type( name(ESpecifier::Type) ) );
return def_global_body( args( nspace, specifier_t ) );
}
CodeBody gen_etoktype()
{
return CodeInvalid;
}

View File

@ -12,8 +12,11 @@ AlignConsecutiveAssignments:
PadOperators: true PadOperators: true
AlignConsecutiveBitFields: AcrossComments AlignConsecutiveBitFields: AcrossComments
AlignConsecutiveDeclarations: AcrossComments AlignConsecutiveDeclarations: AcrossComments
AlignConsecutiveMacros: AcrossComments AlignConsecutiveMacros:
AlignEscapedNewlines: Right Enabled: true
AcrossEmptyLines: true
AcrossComments: false
AlignEscapedNewlines: Left
AlignOperands: DontAlign AlignOperands: DontAlign
AlignTrailingComments: true AlignTrailingComments: true
@ -90,10 +93,10 @@ FixNamespaceComments: true
IncludeBlocks: Preserve IncludeBlocks: Preserve
IndentCaseBlocks: true IndentCaseBlocks: false
IndentCaseLabels: true IndentCaseLabels: false
IndentExternBlock: AfterExternBlock IndentExternBlock: AfterExternBlock
IndentGotoLabels: true IndentGotoLabels: false
IndentPPDirectives: AfterHash IndentPPDirectives: AfterHash
IndentRequires: true IndentRequires: true
IndentWidth: 4 IndentWidth: 4

View File

@ -3,6 +3,7 @@
#define GEN_EXPOSE_BACKEND #define GEN_EXPOSE_BACKEND
#include "gen.cpp" #include "gen.cpp"
#include "filesystem/gen.scanner.hpp" #include "filesystem/gen.scanner.hpp"
#include "helpers/gen.helper.hpp"
using namespace gen; using namespace gen;
@ -87,6 +88,7 @@ int gen_main()
Code string_ops = scan_file( project_dir "dependencies/gen.string_ops.hpp" ); Code string_ops = scan_file( project_dir "dependencies/gen.string_ops.hpp" );
Code printing = scan_file( project_dir "dependencies/gen.printing.hpp" ); Code printing = scan_file( project_dir "dependencies/gen.printing.hpp" );
Code containers = scan_file( project_dir "dependencies/gen.containers.hpp" ); Code containers = scan_file( project_dir "dependencies/gen.containers.hpp" );
Code hashing = scan_file( project_dir "dependencies/gen.hashing.hpp" );
Code string = scan_file( project_dir "dependencies/gen.string.hpp" ); Code string = scan_file( project_dir "dependencies/gen.string.hpp" );
Code file_handling = scan_file( project_dir "dependencies/gen.file_handling.hpp" ); Code file_handling = scan_file( project_dir "dependencies/gen.file_handling.hpp" );
Code parsing = scan_file( project_dir "dependencies/gen.parsing.hpp" ); Code parsing = scan_file( project_dir "dependencies/gen.parsing.hpp" );
@ -101,6 +103,7 @@ int gen_main()
header.print( string_ops ); header.print( string_ops );
header.print( printing ); header.print( printing );
header.print( containers ); header.print( containers );
header.print( hashing );
header.print( string ); header.print( string );
header.print( file_handling ); header.print( file_handling );
header.print( parsing ); header.print( parsing );
@ -115,10 +118,21 @@ int gen_main()
Code interface = scan_file( project_dir "components/gen.interface.hpp" ); Code interface = scan_file( project_dir "components/gen.interface.hpp" );
Code header_end = scan_file( project_dir "components/gen.header_end.hpp" ); Code header_end = scan_file( project_dir "components/gen.header_end.hpp" );
CodeBody ecode = gen_ecode( project_dir "components/ECode.csv" );
CodeBody eoperator = gen_eoperator( project_dir "components/EOperator.csv" );
CodeBody especifier = gen_especifier( project_dir "components/ESpecifier.csv" );
Code builder = scan_file( project_dir "filesystem/gen.builder.hpp" ); Code builder = scan_file( project_dir "filesystem/gen.builder.hpp" );
header.print_fmt( "GEN_NS_BEGIN\n\n" ); header.print_fmt( "GEN_NS_BEGIN\n\n" );
header.print_fmt("#pragma region Types");
header.print( types ); header.print( types );
header.print( ecode );
header.print( eoperator );
header.print( especifier );
header.print_fmt("#pragma endregion Types");
header.print( data_structs ); header.print( data_structs );
header.print( interface ); header.print( interface );
header.print( header_end ); header.print( header_end );

View File

@ -1,163 +0,0 @@
# Format Style Options - Created with Clang Power Tools
---
AccessModifierOffset: -4
AlignAfterOpenBracket: BlockIndent
AlignArrayOfStructures: Right
AlignConsecutiveAssignments:
Enabled: true
AcrossEmptyLines: false
AcrossComments: true
AlignCompound: true
PadOperators: true
AlignConsecutiveBitFields: AcrossComments
AlignConsecutiveDeclarations: AcrossComments
AlignConsecutiveMacros: AcrossComments
AlignEscapedNewlines: Right
AlignOperands: DontAlign
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortLambdasOnASingleLine: None
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: false
BitFieldColonSpacing: Both
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BeforeLambdaBody: false
BeforeWhile: false
# BreakAfterAttributes: Always
# BreakArrays: false
# BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Allman
BreakBeforeInheritanceComma: true
BreakInheritanceList: BeforeComma
BreakBeforeConceptDeclarations: true
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeComma
BreakStringLiterals: true
ColumnLimit: 180
CompactNamespaces: true
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth : 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
DeriveLineEnding: true
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
IncludeBlocks: Preserve
IndentCaseBlocks: true
IndentCaseLabels: true
IndentExternBlock: AfterExternBlock
IndentGotoLabels: true
IndentPPDirectives: AfterHash
IndentRequires: true
IndentWidth: 4
IndentWrappedFunctionNames: false
# InsertNewlineAtEOF: true
InsertTrailingCommas: Wrapped
LambdaBodyIndentation: OuterScope
Language: Cpp
MaxEmptyLinesToKeep: 4
NamespaceIndentation: All
PointerAlignment: Left
QualifierAlignment: Leave
ReferenceAlignment: Left
ReflowComments: true
# RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Always
ShortNamespaceLines: 40
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: true
SpaceAfterTemplateKeyword: false
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: true
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatementsExceptControlMacros
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpacesBeforeTrailingComments: 4
SpaceInEmptyBlock: true
SpaceInEmptyParentheses: false
SpacesInAngles: true
SpacesInCStyleCastParentheses: true
SpacesInConditionalStatement: true
SpacesInContainerLiterals: true
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: 20
SpacesInParentheses: true
SpacesInSquareBrackets: true
Standard: c++17
TabWidth: 4
UseTab: ForIndentation
...