mirror of
https://github.com/Ed94/gencpp.git
synced 2024-12-22 15:54:45 -08:00
Support for module and attribute parsing ( untested )
This commit is contained in:
parent
b1de5b1ac7
commit
e7374ec328
19
Readme.md
19
Readme.md
@ -26,13 +26,17 @@ The project has reached an *alpha* state, all the current functionality works fo
|
||||
|
||||
The project has no external dependencies beyond:
|
||||
|
||||
* `stdarg.h`
|
||||
* `stddef.h`
|
||||
* `stdio.h`
|
||||
* `errno.h`
|
||||
* `unistd.h` (Linux/Mac)
|
||||
* `intrin.h` (Windows)
|
||||
* `windows.h` (Windows)
|
||||
* `errno.h` (gen.cpp)
|
||||
* `stat.h` (gen.cpp)
|
||||
* `stdarg.h` (gen.hpp)
|
||||
* `stddef.h` (gen.hpp
|
||||
* `stdio.h` (gen.cpp)
|
||||
* `copyfile.h` (Mac, gen.cpp)
|
||||
* `types.h` (Linux, gen.cpp)
|
||||
* `unistd.h` (Linux/Mac, gen.cpp)
|
||||
* `intrin.h` (Windows, gen.hpp)
|
||||
* `io.h` (Windows with gcc, gen.cpp)
|
||||
* `windows.h` (Windows, gen.cpp)
|
||||
|
||||
Dependencies for the project are wrapped within `GENCPP_ROLL_OWN_DEPENDENCIES` (Defining it will disable them).
|
||||
The majority of the dependency's implementation was derived from the [c-zpl library](https://github.com/zpl-c/zpl).
|
||||
@ -684,7 +688,6 @@ Names or Content fields are interned strings and thus showed be cached using `ge
|
||||
# TODO
|
||||
|
||||
* Support defining & parsing full definitions inside a typedef. (For C patterns)
|
||||
* Support module and attribute parsing (Marked with TODOs for now..)
|
||||
* Implement a context stack for the parsing, allows for accurate scope validation for the AST types.
|
||||
* Trailing specifiers ( postfix ) for functions (const, override, final)
|
||||
* Make a more robust test suite.
|
||||
|
45
gencpp.10x
Normal file
45
gencpp.10x
Normal file
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0"?>
|
||||
<N10X>
|
||||
<Workspace>
|
||||
<IncludeFilter>*.*</IncludeFilter>
|
||||
<ExcludeFilter>*.obj,*.lib,*.pch,*.dll,*.pdb,.vs,Debug,Release,x64,obj,*.user,Intermediate</ExcludeFilter>
|
||||
<SyncFiles>true</SyncFiles>
|
||||
<Recursive>true</Recursive>
|
||||
<ShowEmptyFolders>true</ShowEmptyFolders>
|
||||
<IsVirtual>false</IsVirtual>
|
||||
<IsFolder>false</IsFolder>
|
||||
<BuildCommand></BuildCommand>
|
||||
<RebuildCommand></RebuildCommand>
|
||||
<BuildFileCommand></BuildFileCommand>
|
||||
<CleanCommand></CleanCommand>
|
||||
<BuildWorkingDirectory></BuildWorkingDirectory>
|
||||
<CancelBuild></CancelBuild>
|
||||
<RunCommand></RunCommand>
|
||||
<RunCommandWorkingDirectory></RunCommandWorkingDirectory>
|
||||
<DebugCommand></DebugCommand>
|
||||
<ExePathCommand></ExePathCommand>
|
||||
<DebugSln></DebugSln>
|
||||
<UseVisualStudioEnvBat>false</UseVisualStudioEnvBat>
|
||||
<Configurations>
|
||||
<Configuration>Debug</Configuration>
|
||||
<Configuration>Release</Configuration>
|
||||
</Configurations>
|
||||
<Platforms>
|
||||
<Platform>x64</Platform>
|
||||
</Platforms>
|
||||
<AdditionalIncludePaths>
|
||||
<AdditionalIncludePath>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.36.32532\include</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.36.32532\ATLMFC\include</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Auxiliary\VS\include</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\um</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\shared</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\winrt</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\cppwinrt</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um</AdditionalIncludePath>
|
||||
</AdditionalIncludePaths>
|
||||
<Defines></Defines>
|
||||
<ConfigProperties></ConfigProperties>
|
||||
<Children></Children>
|
||||
</Workspace>
|
||||
</N10X>
|
@ -102,13 +102,21 @@
|
||||
<None Include="scripts\build.ci.ps1" />
|
||||
<None Include="scripts\build.ps1" />
|
||||
<None Include="scripts\clean.ps1" />
|
||||
<None Include="scripts\gen.ps1" />
|
||||
<None Include="scripts\genccp.natstepfilter" />
|
||||
<None Include="scripts\gencpp.refactor" />
|
||||
<None Include="scripts\get_sources.ps1" />
|
||||
<None Include="test\gen\meson.build" />
|
||||
<None Include="test\meson.build" />
|
||||
<None Include="test\Readme.md" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="project\gen.dep.hpp" />
|
||||
<ClInclude Include="project\gen.editor.hpp" />
|
||||
<ClInclude Include="project\gen.hpp" />
|
||||
<ClInclude Include="project\gen.pop_ignores.inline.hpp" />
|
||||
<ClInclude Include="project\gen.push_ignores.inline.hpp" />
|
||||
<ClInclude Include="project\gen.scanner.hpp" />
|
||||
<ClInclude Include="project\gen.undef.macros.hpp" />
|
||||
<ClInclude Include="test\DummyInclude.hpp" />
|
||||
<ClInclude Include="test\gen\array.Upfront.gen.hpp" />
|
||||
@ -119,7 +127,9 @@
|
||||
<ClInclude Include="test\Parsed\Buffer.Parsed.hpp" />
|
||||
<ClInclude Include="test\Parsed\HashTable.Parsed.hpp" />
|
||||
<ClInclude Include="test\Parsed\Ring.Parsed.hpp" />
|
||||
<ClInclude Include="test\parsing.hpp" />
|
||||
<ClInclude Include="test\SOA.hpp" />
|
||||
<ClInclude Include="test\upfront.hpp" />
|
||||
<ClInclude Include="test\Upfront\Array.Upfront.hpp" />
|
||||
<ClInclude Include="test\Upfront\Buffer.Upfront.hpp" />
|
||||
<ClInclude Include="test\Upfront\HashTable.Upfront.hpp" />
|
||||
@ -130,11 +140,17 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="project\gen.cpp" />
|
||||
<ClCompile Include="project\gen.dep.cpp" />
|
||||
<ClCompile Include="singleheader\gen\gen.singleheader.cpp" />
|
||||
<ClCompile Include="test\gen\build\meson-private\sanitycheckc.c" />
|
||||
<ClCompile Include="test\gen\build\meson-private\sanitycheckcpp.cc" />
|
||||
<ClCompile Include="test\parsing.cpp" />
|
||||
<ClCompile Include="test\sanity.cpp" />
|
||||
<ClCompile Include="test\SOA.cpp" />
|
||||
<ClCompile Include="test\test.cpp" />
|
||||
<ClCompile Include="test\test.parsing.cpp" />
|
||||
<ClCompile Include="test\test.Upfront.cpp" />
|
||||
<ClCompile Include="test\upfront.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include=".vscode\gencpp.natvis" />
|
||||
|
@ -33,6 +33,24 @@
|
||||
<ClCompile Include="test\test.Upfront.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="project\gen.dep.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="test\parsing.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="test\sanity.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="test\SOA.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="test\upfront.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="test\test.parsing.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="project\gen.hpp">
|
||||
@ -92,6 +110,27 @@
|
||||
<ClInclude Include="test\Parsed\Sanity.Parsed.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="project\gen.dep.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="project\gen.editor.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="project\gen.pop_ignores.inline.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="project\gen.push_ignores.inline.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="project\gen.scanner.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="test\parsing.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="test\upfront.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include=".editorconfig" />
|
||||
@ -103,6 +142,9 @@
|
||||
<None Include="test\gen\meson.build" />
|
||||
<None Include="test\meson.build" />
|
||||
<None Include="test\Readme.md" />
|
||||
<None Include="scripts\gen.ps1" />
|
||||
<None Include="scripts\genccp.natstepfilter" />
|
||||
<None Include="scripts\gencpp.refactor" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include=".vscode\gencpp.natvis" />
|
||||
|
280
project/gen.cpp
280
project/gen.cpp
@ -17,7 +17,7 @@
|
||||
namespace gen {
|
||||
|
||||
#pragma region StaticData
|
||||
// TODO : Convert global allocation strategy to use the dual-scratch allocator for a contextual scope.
|
||||
// TODO : Convert global allocation strategy to use a slab allocation strategy.
|
||||
global AllocatorInfo GlobalAllocator;
|
||||
global Array<Arena> Global_AllocatorBuckets;
|
||||
|
||||
@ -849,11 +849,6 @@ String AST::to_string()
|
||||
|
||||
result.append( "typedef ");
|
||||
|
||||
if ( Attributes )
|
||||
{
|
||||
result.append_fmt( "%s ", Attributes->to_string() );
|
||||
}
|
||||
|
||||
result.append_fmt( "%s %s", UnderlyingType->to_string(), Name );
|
||||
|
||||
if ( UnderlyingType->Type == Typename && UnderlyingType->ArrExpr )
|
||||
@ -2567,9 +2562,6 @@ CodeTypedef def_typedef( StrC name, Code type, CodeAttributes attributes, Module
|
||||
|
||||
result->UnderlyingType = type;
|
||||
|
||||
if ( attributes )
|
||||
result->Attributes = attributes;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -3307,6 +3299,8 @@ namespace Parser
|
||||
It will not be capable of lexing C++ code with unsupported features.
|
||||
|
||||
For the sake of scanning files, it can scan preprocessor directives
|
||||
|
||||
Attributes_Start is only used to indicate the start of the user_defined attribute list.
|
||||
*/
|
||||
|
||||
# define Define_TokType \
|
||||
@ -3318,6 +3312,8 @@ namespace Parser
|
||||
Entry( Ampersand, "&" ) \
|
||||
Entry( Ampersand_DBL, "&&" ) \
|
||||
Entry( Assign_Classifer, ":" ) \
|
||||
Entry( Attribute_Open, "[[" ) \
|
||||
Entry( Attribute_Close, "]]" ) \
|
||||
Entry( BraceCurly_Open, "{" ) \
|
||||
Entry( BraceCurly_Close, "}" ) \
|
||||
Entry( BraceSquare_Open, "[" ) \
|
||||
@ -3328,6 +3324,8 @@ namespace Parser
|
||||
Entry( Char, "__char__" ) \
|
||||
Entry( Comma, "," ) \
|
||||
Entry( Decl_Class, "class" ) \
|
||||
Entry( Decl_GNU_Attribute, "__attribute__" ) \
|
||||
Entry( Decl_MSVC_Attribute, "__declspec" ) \
|
||||
Entry( Decl_Enum, "enum" ) \
|
||||
Entry( Decl_Extern_Linkage, "extern" ) \
|
||||
Entry( Decl_Friend, "friend" ) \
|
||||
@ -3369,15 +3367,15 @@ namespace Parser
|
||||
Entry( Type_Long, "long" ) \
|
||||
Entry( Type_char, "char" ) \
|
||||
Entry( Type_int, "int" ) \
|
||||
Entry( Type_double, "double" )
|
||||
Entry( Type_double, "double" ) \
|
||||
Entry( Attributes_Start, "__attrib_start__" )
|
||||
|
||||
enum class TokType : u32
|
||||
{
|
||||
# define Entry( Name_, Str_ ) Name_,
|
||||
Define_TokType
|
||||
GEN_Define_Attribute_Tokens
|
||||
# undef Entry
|
||||
Attr_Keyword,
|
||||
|
||||
Num,
|
||||
Invalid
|
||||
};
|
||||
@ -3408,9 +3406,8 @@ namespace Parser
|
||||
{
|
||||
# define Entry( Name_, Str_ ) { sizeof(Str_), Str_ },
|
||||
Define_TokType
|
||||
GEN_Define_Attribute_Tokens
|
||||
# undef Entry
|
||||
|
||||
{ sizeof(Attribute::Keyword), Attribute::Keyword },
|
||||
};
|
||||
|
||||
for ( u32 index = 0; index < (u32)TokType::Num; index++ )
|
||||
@ -3436,9 +3433,8 @@ namespace Parser
|
||||
{
|
||||
# define Entry( Name_, Str_ ) Str_,
|
||||
Define_TokType
|
||||
GEN_Define_Attribute_Tokens
|
||||
# undef Entry
|
||||
|
||||
Attribute::Keyword,
|
||||
};
|
||||
|
||||
return lookup[(u32)type];
|
||||
@ -3467,6 +3463,11 @@ namespace Parser
|
||||
return scast(AccessSpec, tok.Type);
|
||||
}
|
||||
|
||||
internal inline
|
||||
bool tok_is_attribute( Token const& tok )
|
||||
{
|
||||
return tok.Type > TokType::Attributes_Start;
|
||||
}
|
||||
|
||||
struct TokArray
|
||||
{
|
||||
@ -4108,6 +4109,68 @@ Code parse_array_decl( Parser::TokArray& toks, char const* context )
|
||||
return { nullptr };
|
||||
}
|
||||
|
||||
internal inline
|
||||
CodeAttributes parse_attributes( Parser::TokArray& toks, char const* context )
|
||||
{
|
||||
using namespace Parser;
|
||||
|
||||
Token start;
|
||||
|
||||
if ( check(TokType::Attribute_Open) )
|
||||
{
|
||||
eat( TokType::Attribute_Open);
|
||||
|
||||
while ( left && currtok.Type != TokType::Attribute_Close )
|
||||
{
|
||||
eat( currtok.Type );
|
||||
}
|
||||
|
||||
eat( TokType::Attribute_Close );
|
||||
}
|
||||
|
||||
else if ( check(TokType::Decl_GNU_Attribute) )
|
||||
{
|
||||
eat(TokType::BraceCurly_Open);
|
||||
eat(TokType::BraceCurly_Open);
|
||||
|
||||
while ( left && currtok.Type != TokType::BraceCurly_Close )
|
||||
{
|
||||
eat(currtok.Type);
|
||||
}
|
||||
|
||||
eat(TokType::BraceCurly_Close);
|
||||
eat(TokType::BraceCurly_Close);
|
||||
}
|
||||
|
||||
else if ( check(TokType::Decl_MSVC_Attribute) )
|
||||
{
|
||||
eat( TokType::Decl_MSVC_Attribute );
|
||||
eat( TokType::BraceCurly_Open);
|
||||
|
||||
while ( left && currtok.Type != TokType::BraceCurly_Close )
|
||||
{
|
||||
eat(currtok.Type);
|
||||
}
|
||||
|
||||
eat(TokType::BraceCurly_Close);
|
||||
}
|
||||
|
||||
else if ( tok_is_attribute( currtok ) )
|
||||
{
|
||||
eat(currtok.Type);
|
||||
}
|
||||
|
||||
s32 len = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)start.Text;
|
||||
|
||||
if ( len > 0 )
|
||||
{
|
||||
StrC attribute_txt = { len, start.Text };
|
||||
return def_attributes( attribute_txt );
|
||||
}
|
||||
|
||||
return { nullptr };
|
||||
}
|
||||
|
||||
internal inline
|
||||
Parser::Token parse_identifier( Parser::TokArray& toks, char const* context )
|
||||
{
|
||||
@ -4711,7 +4774,7 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes
|
||||
{
|
||||
if ( expects_function )
|
||||
{
|
||||
log_failure( "gen::parse_template: expected function declaration (consteval was used)" );
|
||||
log_failure( "gen::parse_operator_function_or_variable: expected function declaration (consteval was used)" );
|
||||
return Code::Invalid;
|
||||
}
|
||||
|
||||
@ -4809,36 +4872,14 @@ CodeBody parse_class_struct_body( Parser::TokType which, Parser::TokArray& toks,
|
||||
member = parse_using( toks, context );
|
||||
break;
|
||||
|
||||
case TokType::BraceSquare_Open:
|
||||
case TokType::Attr_Keyword:
|
||||
case TokType::Attribute_Open:
|
||||
case TokType::Decl_GNU_Attribute:
|
||||
case TokType::Decl_MSVC_Attribute:
|
||||
#define Entry( attribute, str ) case TokType::attribute:
|
||||
GEN_Define_Attribute_Tokens
|
||||
#undef Entry
|
||||
{
|
||||
// Standard attribute
|
||||
if ( currtok.Type == TokType::BraceSquare_Open )
|
||||
{
|
||||
eat( TokType::BraceSquare_Open );
|
||||
|
||||
if ( currtok.Type != TokType::BraceSquare_Open )
|
||||
{
|
||||
log_failure( "%s: Error, expected attribute name", context );
|
||||
return result;
|
||||
}
|
||||
|
||||
while ( left && currtok.Type != TokType::BraceSquare_Close )
|
||||
{
|
||||
// TODO : Parse attributes
|
||||
}
|
||||
|
||||
eat( TokType::BraceSquare_Close );
|
||||
eat( TokType::BraceSquare_Close );
|
||||
}
|
||||
|
||||
// Platform Specific attribute
|
||||
eat( TokType::Attr_Keyword );
|
||||
eat( TokType::Capture_Start );
|
||||
|
||||
// TODO : Parse attributes
|
||||
|
||||
eat( TokType::Capture_End );
|
||||
attributes = parse_attributes( toks, context );
|
||||
}
|
||||
//! Fallthrough intended
|
||||
case TokType::Spec_Consteval:
|
||||
@ -4943,11 +4984,15 @@ Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char con
|
||||
|
||||
CodeClass result = CodeInvalid;
|
||||
|
||||
// TODO : Parse module specifiers
|
||||
if ( check(TokType::Module_Export) )
|
||||
{
|
||||
mflags = ModuleFlag::Export;
|
||||
eat( TokType::Module_Export );
|
||||
}
|
||||
|
||||
eat( which );
|
||||
|
||||
// TODO : Parse attributes
|
||||
attributes = parse_attributes( toks, context );
|
||||
|
||||
if ( check( TokType::Identifier ) )
|
||||
name = parse_identifier( toks, context );
|
||||
@ -4979,16 +5024,14 @@ Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char con
|
||||
|
||||
if ( which == TokType::Decl_Class )
|
||||
result = def_class( name, body, parent, access
|
||||
// TODO : Set these up later
|
||||
, NoCode // Attributes
|
||||
, ModuleFlag::None
|
||||
, attributes
|
||||
, mflags
|
||||
);
|
||||
|
||||
else
|
||||
result = def_struct( name, body, (CodeType)parent, access
|
||||
// TODO : Set these up later
|
||||
, NoCode // Attributes
|
||||
, ModuleFlag::None
|
||||
, attributes
|
||||
, mflags
|
||||
);
|
||||
|
||||
return result;
|
||||
@ -5115,38 +5158,13 @@ CodeBody parse_global_nspace( CodeT which, Parser::TokArray& toks, char const* c
|
||||
not_implemented( context );
|
||||
}
|
||||
//! Fallthrough intentional
|
||||
case TokType::BraceSquare_Open:
|
||||
case TokType::Attr_Keyword:
|
||||
case TokType::Decl_GNU_Attribute:
|
||||
case TokType::Decl_MSVC_Attribute:
|
||||
#define Entry( attribute, str ) case TokType::attribute:
|
||||
GEN_Define_Attribute_Tokens
|
||||
#undef Entry
|
||||
{
|
||||
not_implemented( context );
|
||||
|
||||
// Standard attribute
|
||||
if ( currtok.Type == TokType::BraceSquare_Open )
|
||||
{
|
||||
eat( TokType::BraceSquare_Open );
|
||||
|
||||
if ( currtok.Type != TokType::BraceSquare_Open )
|
||||
{
|
||||
log_failure( "%s: Error, expected attribute name", context );
|
||||
return result;
|
||||
}
|
||||
|
||||
while ( left && currtok.Type != TokType::BraceSquare_Close )
|
||||
{
|
||||
// TODO : Parse attributes
|
||||
}
|
||||
|
||||
eat( TokType::BraceSquare_Close );
|
||||
eat( TokType::BraceSquare_Close );
|
||||
}
|
||||
|
||||
// Platform Specific attribute
|
||||
eat( TokType::Attr_Keyword );
|
||||
eat( TokType::Capture_Start );
|
||||
|
||||
// TODO : Parse attributes
|
||||
|
||||
eat( TokType::Capture_End );
|
||||
attributes = parse_attributes( toks, context );
|
||||
}
|
||||
//! Fallthrough intentional
|
||||
case TokType::Spec_Consteval:
|
||||
@ -5494,10 +5512,15 @@ CodeFn parse_functon( Parser::TokArray& toks, char const* context )
|
||||
|
||||
CodeAttributes attributes = { nullptr };
|
||||
CodeSpecifier specifiers = { nullptr };
|
||||
ModuleFlag mflags = ModuleFlag::None;
|
||||
|
||||
// TODO : Parse module specifiers
|
||||
if ( check(TokType::Module_Export) )
|
||||
{
|
||||
mflags = ModuleFlag::Export;
|
||||
eat( TokType::Module_Export );
|
||||
}
|
||||
|
||||
// TODO : Parse attributes
|
||||
attributes = parse_attributes( toks, context );
|
||||
|
||||
while ( left && tok_is_specifier( currtok ) )
|
||||
{
|
||||
@ -5536,7 +5559,7 @@ CodeFn parse_functon( Parser::TokArray& toks, char const* context )
|
||||
if ( ! name )
|
||||
return CodeInvalid;
|
||||
|
||||
CodeFn result = parse_function_after_name( ModuleFlag::None, attributes, specifiers, ret_type, name, toks, context );
|
||||
CodeFn result = parse_function_after_name( mflags, attributes, specifiers, ret_type, name, toks, context );
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -5603,16 +5626,23 @@ CodeNamespace parse_namespace( StrC def )
|
||||
internal
|
||||
CodeOperator parse_operator( Parser::TokArray& toks, char const* context )
|
||||
{
|
||||
// TODO : Parse Module specifier
|
||||
using namespace Parser;
|
||||
|
||||
// TODO : Parse Attributes
|
||||
CodeAttributes attributes = { nullptr };
|
||||
|
||||
CodeSpecifier specifiers = { nullptr };
|
||||
ModuleFlag mflags = ModuleFlag::None;
|
||||
|
||||
SpecifierT specs_found[16] { ESpecifier::Num_Specifiers };
|
||||
s32 num_specifiers = 0;
|
||||
|
||||
if ( check(TokType::Module_Export) )
|
||||
{
|
||||
mflags = ModuleFlag::Export;
|
||||
eat( TokType::Module_Export );
|
||||
}
|
||||
|
||||
attributes = parse_attributes( toks, context );
|
||||
|
||||
while ( left && tok_is_specifier( currtok ) )
|
||||
{
|
||||
SpecifierT spec = ESpecifier::to_type( currtok );
|
||||
@ -5643,7 +5673,7 @@ CodeOperator parse_operator( Parser::TokArray& toks, char const* context )
|
||||
// Parse Return Type
|
||||
CodeType ret_type = parse_type( toks, stringize(parse_operator) );
|
||||
|
||||
CodeOperator result = parse_operator_after_ret_type( ModuleFlag::None, attributes, specifiers, ret_type, toks, context );
|
||||
CodeOperator result = parse_operator_after_ret_type( mflags, attributes, specifiers, ret_type, toks, context );
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -5751,7 +5781,13 @@ CodeTemplate parse_template( Parser::TokArray& toks, char const* context )
|
||||
|
||||
using namespace Parser;
|
||||
|
||||
// TODO : Parse Module specifier
|
||||
ModuleFlag mflags = ModuleFlag::None;
|
||||
|
||||
if ( check(TokType::Module_Export) )
|
||||
{
|
||||
mflags = ModuleFlag::Export;
|
||||
eat( TokType::Module_Export );
|
||||
}
|
||||
|
||||
eat( TokType::Decl_Template );
|
||||
|
||||
@ -5784,17 +5820,16 @@ CodeTemplate parse_template( Parser::TokArray& toks, char const* context )
|
||||
// Its either a function or a variable
|
||||
Token name = { nullptr, 0, TokType::Invalid };
|
||||
|
||||
|
||||
CodeAttributes attributes = { nullptr };
|
||||
CodeSpecifier specifiers = { nullptr };
|
||||
|
||||
// TODO : Parse attributes
|
||||
|
||||
bool expects_function = false;
|
||||
|
||||
SpecifierT specs_found[16] { ESpecifier::Num_Specifiers };
|
||||
s32 num_specifiers = 0;
|
||||
|
||||
attributes = parse_attributes( toks, stringize(parse_template) );
|
||||
|
||||
while ( left && tok_is_specifier( currtok ) )
|
||||
{
|
||||
SpecifierT spec = ESpecifier::to_type( currtok );
|
||||
@ -5846,6 +5881,7 @@ CodeTemplate parse_template( Parser::TokArray& toks, char const* context )
|
||||
result->Type = ECode::Template;
|
||||
result->Params = params;
|
||||
result->Declaration = definition;
|
||||
result->ModuleFlags = mflags;
|
||||
|
||||
return result;
|
||||
# undef UseTemplateCapture
|
||||
@ -5876,6 +5912,8 @@ CodeType parse_type( Parser::TokArray& toks, char const* context )
|
||||
Token name = { nullptr, 0, TokType::Invalid };
|
||||
Token brute_sig = { currtok.Text, 0, TokType::Invalid };
|
||||
|
||||
CodeAttributes attributes = parse_attributes( toks, context );
|
||||
|
||||
while ( left && tok_is_specifier( currtok ) )
|
||||
{
|
||||
SpecifierT spec = ESpecifier::to_type( currtok );
|
||||
@ -6030,6 +6068,9 @@ CodeType parse_type( Parser::TokArray& toks, char const* context )
|
||||
|
||||
result->Name = get_cached_string( name );
|
||||
|
||||
if ( attributes )
|
||||
result->Attributes = attributes;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -6056,6 +6097,14 @@ CodeTypedef parse_typedef( Parser::TokArray& toks, char const* context )
|
||||
Code array_expr = { nullptr };
|
||||
Code type = { nullptr };
|
||||
|
||||
ModuleFlag mflags = ModuleFlag::None;
|
||||
|
||||
if ( check(TokType::Module_Export) )
|
||||
{
|
||||
mflags = ModuleFlag::Export;
|
||||
eat( TokType::Module_Export );
|
||||
}
|
||||
|
||||
eat( TokType::Decl_Typedef );
|
||||
|
||||
if ( check( TokType::Decl_Enum ) )
|
||||
@ -6089,6 +6138,7 @@ CodeTypedef parse_typedef( Parser::TokArray& toks, char const* context )
|
||||
result = (CodeTypedef) make_code();
|
||||
result->Type = Typedef;
|
||||
result->Name = get_cached_string( name );
|
||||
result->ModuleFlags = mflags;
|
||||
|
||||
result->UnderlyingType = type;
|
||||
|
||||
@ -6115,12 +6165,17 @@ CodeUnion parse_union( Parser::TokArray& toks, char const* context )
|
||||
{
|
||||
using namespace Parser;
|
||||
|
||||
// TODO : Parse module spec
|
||||
ModuleFlag mflags = ModuleFlag::None;
|
||||
|
||||
if ( check(TokType::Module_Export) )
|
||||
{
|
||||
mflags = ModuleFlag::Export;
|
||||
eat( TokType::Module_Export );
|
||||
}
|
||||
|
||||
eat( TokType::Decl_Union );
|
||||
|
||||
// TODO : Parse attributes
|
||||
CodeAttributes attributes = { nullptr };
|
||||
CodeAttributes attributes = parse_attributes( toks, context );
|
||||
|
||||
StrC name = { 0, nullptr };
|
||||
|
||||
@ -6151,6 +6206,7 @@ CodeUnion parse_union( Parser::TokArray& toks, char const* context )
|
||||
CodeUnion
|
||||
result = (CodeUnion) make_code();
|
||||
result->Type = ECode::Union;
|
||||
result->ModuleFlags = mflags;
|
||||
|
||||
if ( name )
|
||||
result->Name = get_cached_string( name );
|
||||
@ -6190,7 +6246,14 @@ CodeUsing parse_using( Parser::TokArray& toks, char const* context )
|
||||
|
||||
bool is_namespace = false;
|
||||
|
||||
// TODO : Parse module specs
|
||||
ModuleFlag mflags = ModuleFlag::None;
|
||||
CodeAttributes attributes = { nullptr };
|
||||
|
||||
if ( check(TokType::Module_Export) )
|
||||
{
|
||||
mflags = ModuleFlag::Export;
|
||||
eat( TokType::Module_Export );
|
||||
}
|
||||
|
||||
eat( TokType::Decl_Using );
|
||||
|
||||
@ -6205,7 +6268,7 @@ CodeUsing parse_using( Parser::TokArray& toks, char const* context )
|
||||
|
||||
if ( currtok.IsAssign )
|
||||
{
|
||||
// TODO : Parse Attributes (using type-alias)
|
||||
attributes = parse_attributes( toks, context );
|
||||
|
||||
eat( TokType::Operator );
|
||||
|
||||
@ -6221,6 +6284,7 @@ CodeUsing parse_using( Parser::TokArray& toks, char const* context )
|
||||
CodeUsing
|
||||
result = (CodeUsing) make_code();
|
||||
result->Name = get_cached_string( name );
|
||||
result->ModuleFlags = mflags;
|
||||
|
||||
if ( is_namespace)
|
||||
{
|
||||
@ -6235,6 +6299,9 @@ CodeUsing parse_using( Parser::TokArray& toks, char const* context )
|
||||
|
||||
if ( array_expr )
|
||||
type->ArrExpr = array_expr;
|
||||
|
||||
if ( attributes )
|
||||
result->Attributes = attributes;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -6261,12 +6328,17 @@ CodeVar parse_variable( Parser::TokArray& toks, char const* context )
|
||||
SpecifierT specs_found[16] { ESpecifier::Num_Specifiers };
|
||||
s32 num_specifiers = 0;
|
||||
|
||||
ModuleFlag mflags = ModuleFlag::None;
|
||||
CodeAttributes attributes = { nullptr };
|
||||
CodeSpecifier specifiers = { nullptr };
|
||||
|
||||
// TODO : Parse module specifiers
|
||||
if ( check(TokType::Module_Export) )
|
||||
{
|
||||
mflags = ModuleFlag::Export;
|
||||
eat( TokType::Module_Export );
|
||||
}
|
||||
|
||||
// TODO : Parse attributes
|
||||
attributes = parse_attributes( toks, context );
|
||||
|
||||
while ( left && tok_is_specifier( currtok ) )
|
||||
{
|
||||
@ -6314,7 +6386,7 @@ CodeVar parse_variable( Parser::TokArray& toks, char const* context )
|
||||
name = currtok;
|
||||
eat( TokType::Identifier );
|
||||
|
||||
CodeVar result = parse_variable_after_name( ModuleFlag::None, attributes, specifiers, type, name, toks, context );
|
||||
CodeVar result = parse_variable_after_name( mflags, attributes, specifiers, type, name, toks, context );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ namespace gen {
|
||||
|
||||
// Bits
|
||||
|
||||
#define bit( Value ) ( 1 << (Value) )
|
||||
#define bit( Value ) ( 1 << Value )
|
||||
#define bitfield_is_equal( Type, Field, Mask ) ( (Type(Mask) & Type(Field)) == Type(Mask) )
|
||||
|
||||
// Casting
|
||||
@ -230,7 +230,7 @@ while(0);
|
||||
#define size_of( x ) ( sw )( sizeof( x ) )
|
||||
|
||||
template< class Type >
|
||||
void swap( Type& a, Type& b )
|
||||
void swap( Type a, Type b )
|
||||
{
|
||||
Type tmp = a;
|
||||
a = b;
|
||||
@ -1271,7 +1271,7 @@ struct Array
|
||||
return true;
|
||||
}
|
||||
|
||||
bool append_at( Type item, sw idx )
|
||||
bool append_at( Type item, uw idx )
|
||||
{
|
||||
Header* header = get_header();
|
||||
|
||||
@ -1297,7 +1297,7 @@ struct Array
|
||||
return true;
|
||||
}
|
||||
|
||||
bool append_at( Type* items, uw item_num, sw idx )
|
||||
bool append_at( Type* items, uw item_num, uw idx )
|
||||
{
|
||||
Header* header = get_header();
|
||||
|
||||
@ -1502,7 +1502,7 @@ struct HashTable
|
||||
}
|
||||
|
||||
static
|
||||
HashTable init_reserve( AllocatorInfo allocator, sw num )
|
||||
HashTable init_reserve( AllocatorInfo allocator, uw num )
|
||||
{
|
||||
HashTable<Type> result = { { nullptr }, { nullptr } };
|
||||
|
||||
|
@ -220,7 +220,11 @@ namespace ESpecifier
|
||||
Entry( RValue, && ) \
|
||||
Entry( Static, static ) \
|
||||
Entry( Thread_Local, thread_local ) \
|
||||
Entry( Volatile, volatile )
|
||||
Entry( Volatile, volatile ) \
|
||||
Entry( Virtual, virtual ) \
|
||||
Entry( Const_Fn, const ) \
|
||||
Entry( Final, final ) \
|
||||
Entry( Override, override )
|
||||
|
||||
enum Type : u32
|
||||
{
|
||||
@ -333,40 +337,48 @@ ModuleFlag operator|( ModuleFlag A, ModuleFlag B)
|
||||
|
||||
/*
|
||||
Predefined attributes
|
||||
|
||||
Used for the parser constructors to identify non-standard attributes
|
||||
|
||||
Override these to change the attribute to your own unique identifier convention.
|
||||
|
||||
The tokenizer identifies attribute defines with the GEN_Define_Attribute_Tokens macros.
|
||||
See the example below and the Define_TokType macro used in gen.cpp to know the format.
|
||||
While the library can parse raw attributes, most projects use defines to wrap them for compiler
|
||||
platform indendence. The token define allows support for them without having to modify the library.
|
||||
*/
|
||||
namespace Attribute
|
||||
{
|
||||
#if defined(GEN_SYSTEM_WINDOWS) || defined( __CYGWIN__ )
|
||||
# define GEN_API_
|
||||
#ifndef GEN_Attribute_Keyword
|
||||
# define GEN_API_Export_Code __declspec(dllexport)
|
||||
# define GEN_API_Import_Code __declspec(dllimport)
|
||||
# define GEN_Attribute_Keyword __declspec
|
||||
#endif
|
||||
|
||||
constexpr char const* API_Export = stringize( GEN_API_Export_Code );
|
||||
constexpr char const* API_Import = stringize( GEN_API_Import_Code );
|
||||
constexpr char const* Keyword = stringize( GEN_Attribute_Keyword);
|
||||
constexpr char const* Attribute_Keyword = stringize( GEN_Attribute_Keyword);
|
||||
|
||||
#elif GEN_HAS_ATTRIBUTE( visibility ) || GEN_GCC_VERSION_CHECK( 3, 3, 0 )
|
||||
#ifndef GEN_Attribute_Keyword
|
||||
# define GEN_API_Export_Code __attribute__ ((visibility ("default")))
|
||||
# define GEN_API_Import_Code __attribute__ ((visibility ("default")))
|
||||
# define GEN_Attribute_Keyword __attribute__
|
||||
#endif
|
||||
|
||||
constexpr char const* API_Export = stringize( GEN_API_Export_Code );
|
||||
constexpr char const* API_Import = stringize( GEN_API_Import_Code );
|
||||
constexpr char const* Keyword = stringize( GEN_Attribute_Keyword);
|
||||
constexpr char const* Attribute_Keyword = stringize( GEN_Attribute_Keyword );
|
||||
|
||||
#else
|
||||
#ifndef GEN_Attribute_Keyword
|
||||
# define GEN_API_Export_Code
|
||||
# define GEN_API_Import_Code
|
||||
# define GEN_Attribute_Keyword
|
||||
|
||||
constexpr char const* API_Export = "";
|
||||
constexpr char const* API_Import = "";
|
||||
constexpr char const* Keyword = "";
|
||||
#endif
|
||||
}
|
||||
|
||||
constexpr char const* Attribute_Keyword = "";
|
||||
#endif
|
||||
|
||||
#ifndef GEN_Define_Attribute_Tokens
|
||||
# define GEN_Define_Attribute_Tokens \
|
||||
Entry( API_Export, "GEN_API_Export_Code" ) \
|
||||
Entry( API_Import, "GEN_API_Import_Code" )
|
||||
#endif
|
||||
#pragma endregion Types
|
||||
|
||||
#pragma region Data Structures
|
||||
@ -629,7 +641,7 @@ struct AST_POD
|
||||
union {
|
||||
struct
|
||||
{
|
||||
AST* Attributes; // Class, Enum, Function, Struct, Typedef, Union, Using, Variable
|
||||
AST* Attributes; // Class, Enum, Function, Struct, Typename, Union, Using, Variable
|
||||
AST* Specs; // Function, Operator, Type symbol, Variable
|
||||
union {
|
||||
AST* ParentType; // Class, Struct
|
||||
@ -1254,10 +1266,9 @@ struct AST_Typedef
|
||||
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
|
||||
struct
|
||||
{
|
||||
CodeAttributes Attributes;
|
||||
char _PAD_SPECS_ [ sizeof(AST*) ];
|
||||
Code UnderlyingType;
|
||||
char _PAD_PROPERTIES_[ sizeof(AST*) * 2 ];
|
||||
Code UnderlyingType;
|
||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) * 2 ];
|
||||
};
|
||||
};
|
||||
Code Prev;
|
||||
@ -1907,6 +1918,9 @@ namespace gen
|
||||
extern CodeType t_class;
|
||||
extern CodeType t_typename;
|
||||
|
||||
extern Code attrib_api_export;
|
||||
extern Code attrib_api_import;
|
||||
|
||||
extern Code access_public;
|
||||
extern Code access_protected;
|
||||
extern Code access_private;
|
||||
|
@ -29,3 +29,4 @@ if ( $files )
|
||||
{
|
||||
Remove-Item $files
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user