mirror of
https://github.com/Ed94/gencpp.git
synced 2024-11-10 02:54:53 -08:00
Added initial support for comma-separated variable declaration lists.
This commit is contained in:
parent
b22f589203
commit
d0f3b6187e
@ -1,8 +1,9 @@
|
|||||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||||
#define GEN_BENCHMARK
|
#define GEN_BENCHMARK
|
||||||
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
||||||
#define GEN_IMPLEMENTATION
|
// #define GEN_IMPLEMENTATION
|
||||||
#include "gen.hpp"
|
#include "gen.cpp"
|
||||||
|
#include "gen.builder.cpp"
|
||||||
|
|
||||||
|
|
||||||
constexpr char const* path_config = "config.h";
|
constexpr char const* path_config = "config.h";
|
||||||
|
@ -87,7 +87,7 @@ function setup-raylib {
|
|||||||
|
|
||||||
# Refactor raylib
|
# Refactor raylib
|
||||||
if ( $true ) {
|
if ( $true ) {
|
||||||
$path_gencpp = join-path $path_root 'singleheader/gen'
|
$path_gencpp = join-path $path_root 'project/gen'
|
||||||
|
|
||||||
$includes = @(
|
$includes = @(
|
||||||
$path_gencpp
|
$path_gencpp
|
||||||
|
@ -1317,6 +1317,8 @@ String AST::to_string()
|
|||||||
// Keep the chain going...
|
// Keep the chain going...
|
||||||
if ( NextVar )
|
if ( NextVar )
|
||||||
result.append_fmt( ", %S", NextVar->to_string() );
|
result.append_fmt( ", %S", NextVar->to_string() );
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export ))
|
if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export ))
|
||||||
|
@ -1309,6 +1309,7 @@ internal Code parse_simple_preprocess ( Parser::TokType
|
|||||||
internal Code parse_static_assert ();
|
internal Code parse_static_assert ();
|
||||||
internal void parse_template_args ( Parser::Token& token );
|
internal void parse_template_args ( Parser::Token& token );
|
||||||
internal CodeVar parse_variable_after_name ( ModuleFlag mflags, CodeAttributes attributes, CodeSpecifiers specifiers, CodeType type, StrC name );
|
internal CodeVar parse_variable_after_name ( ModuleFlag mflags, CodeAttributes attributes, CodeSpecifiers specifiers, CodeType type, StrC name );
|
||||||
|
internal CodeVar parse_variable_declaration_list ();
|
||||||
|
|
||||||
internal CodeClass parse_class ( bool inplace_def = false );
|
internal CodeClass parse_class ( bool inplace_def = false );
|
||||||
internal CodeConstructor parse_constructor ();
|
internal CodeConstructor parse_constructor ();
|
||||||
@ -1783,7 +1784,9 @@ Code parse_complicated_definition( Parser::TokType which )
|
|||||||
if ( (idx - 2 ) == tokens.Idx )
|
if ( (idx - 2 ) == tokens.Idx )
|
||||||
{
|
{
|
||||||
// Its a forward declaration only
|
// Its a forward declaration only
|
||||||
return parse_foward_or_definition( which, is_inplace );
|
Code result = parse_foward_or_definition( which, is_inplace );
|
||||||
|
Context.pop();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token tok = tokens[ idx - 1 ];
|
Token tok = tokens[ idx - 1 ];
|
||||||
@ -1831,7 +1834,9 @@ Code parse_complicated_definition( Parser::TokType which )
|
|||||||
{
|
{
|
||||||
// Its a definition
|
// Its a definition
|
||||||
// <which> { ... };
|
// <which> { ... };
|
||||||
return parse_foward_or_definition( which, is_inplace );
|
Code result = parse_foward_or_definition( which, is_inplace );
|
||||||
|
Context.pop();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
else if ( tok.Type == TokType::BraceSquare_Close)
|
else if ( tok.Type == TokType::BraceSquare_Close)
|
||||||
{
|
{
|
||||||
@ -2272,22 +2277,18 @@ Code parse_foward_or_definition( Parser::TokType which, bool is_inplace )
|
|||||||
{
|
{
|
||||||
case TokType::Decl_Class:
|
case TokType::Decl_Class:
|
||||||
result = parse_class( is_inplace );
|
result = parse_class( is_inplace );
|
||||||
Context.pop();
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
case TokType::Decl_Enum:
|
case TokType::Decl_Enum:
|
||||||
result = parse_enum( is_inplace );
|
result = parse_enum( is_inplace );
|
||||||
Context.pop();
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
case TokType::Decl_Struct:
|
case TokType::Decl_Struct:
|
||||||
result = parse_struct( is_inplace );
|
result = parse_struct( is_inplace );
|
||||||
Context.pop();
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
case TokType::Decl_Union:
|
case TokType::Decl_Union:
|
||||||
result = parse_union( is_inplace );
|
result = parse_union( is_inplace );
|
||||||
Context.pop();
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -2295,7 +2296,6 @@ Code parse_foward_or_definition( Parser::TokType which, bool is_inplace )
|
|||||||
"(only supports class, enum, struct, union) \n%s"
|
"(only supports class, enum, struct, union) \n%s"
|
||||||
, Context.to_string() );
|
, Context.to_string() );
|
||||||
|
|
||||||
Context.pop();
|
|
||||||
return CodeInvalid;
|
return CodeInvalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3636,16 +3636,30 @@ CodeVar parse_variable_after_name(
|
|||||||
bitfield_expr = untyped_str( expr_tok );
|
bitfield_expr = untyped_str( expr_tok );
|
||||||
}
|
}
|
||||||
|
|
||||||
Token stmt_end = currtok;
|
CodeVar next_var = NoCode;
|
||||||
eat( TokType::Statement_End );
|
Token stmt_end = NullToken;
|
||||||
|
|
||||||
// Check for inline comment : <type> <identifier> = <expression>; // <inline comment>
|
|
||||||
CodeComment inline_cmt = NoCode;
|
CodeComment inline_cmt = NoCode;
|
||||||
if ( left
|
if ( currtok.Type == TokType::Comma )
|
||||||
&& ( currtok_noskip.Type == TokType::Comment )
|
|
||||||
&& currtok_noskip.Line == stmt_end.Line )
|
|
||||||
{
|
{
|
||||||
inline_cmt = parse_comment();
|
// Were dealing with a statement with more than one declaration
|
||||||
|
// This is only handled this way if its the first declaration
|
||||||
|
// Otherwise its looped through in parse_variable_declaration_list
|
||||||
|
next_var = parse_variable_declaration_list();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're dealing with a "comma-procedding then we cannot expect a statement end or inline comment
|
||||||
|
// Any comma procedding variable will not have a type provided so it can act as a indicator to skip this
|
||||||
|
else if ( type )
|
||||||
|
{
|
||||||
|
Token stmt_end = currtok;
|
||||||
|
eat( TokType::Statement_End );
|
||||||
|
|
||||||
|
// Check for inline comment : <type> <identifier> = <expression>; // <inline comment>
|
||||||
|
CodeComment inline_cmt = NoCode;
|
||||||
|
if ( left && ( currtok_noskip.Type == TokType::Comment ) && currtok_noskip.Line == stmt_end.Line )
|
||||||
|
{
|
||||||
|
inline_cmt = parse_comment();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace ECode;
|
using namespace ECode;
|
||||||
@ -3656,7 +3670,9 @@ CodeVar parse_variable_after_name(
|
|||||||
result->Name = get_cached_string( name );
|
result->Name = get_cached_string( name );
|
||||||
result->ModuleFlags = mflags;
|
result->ModuleFlags = mflags;
|
||||||
|
|
||||||
result->ValueType = type;
|
// Type can be null if we're dealing with a declaration from a variable declaration-list
|
||||||
|
if ( type )
|
||||||
|
result->ValueType = type;
|
||||||
|
|
||||||
if (array_expr )
|
if (array_expr )
|
||||||
type->ArrExpr = array_expr;
|
type->ArrExpr = array_expr;
|
||||||
@ -3676,6 +3692,84 @@ CodeVar parse_variable_after_name(
|
|||||||
if ( inline_cmt )
|
if ( inline_cmt )
|
||||||
result->InlineCmt = inline_cmt;
|
result->InlineCmt = inline_cmt;
|
||||||
|
|
||||||
|
if ( next_var )
|
||||||
|
result->NextVar = next_var;
|
||||||
|
|
||||||
|
Context.pop();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Note(Ed): This does not support the following:
|
||||||
|
* Function Pointers
|
||||||
|
*/
|
||||||
|
internal CodeVar parse_variable_declaration_list()
|
||||||
|
{
|
||||||
|
using namespace Parser;
|
||||||
|
push_scope();
|
||||||
|
|
||||||
|
CodeVar result = NoCode;
|
||||||
|
CodeVar last_var = NoCode;
|
||||||
|
while ( check( TokType::Comma ) )
|
||||||
|
{
|
||||||
|
eat( TokType::Comma );
|
||||||
|
|
||||||
|
CodeSpecifiers specifiers = NoCode;
|
||||||
|
|
||||||
|
while ( left && currtok.is_specifier() )
|
||||||
|
{
|
||||||
|
SpecifierT spec = ESpecifier::to_type( currtok );
|
||||||
|
|
||||||
|
switch ( spec )
|
||||||
|
{
|
||||||
|
case ESpecifier::Const:
|
||||||
|
if ( specifiers->NumEntries && specifiers->ArrSpecs[ specifiers->NumEntries - 1 ] != ESpecifier::Ptr )
|
||||||
|
{
|
||||||
|
log_failure( "Error, const specifier must come after pointer specifier for variable declaration proceeding comma\n"
|
||||||
|
"(Parser will add and continue to specifiers, but will most likely fail to compile)\n%s"
|
||||||
|
, Context.to_string() );
|
||||||
|
|
||||||
|
specifiers.append( spec );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ESpecifier::Ptr:
|
||||||
|
case ESpecifier::Ref:
|
||||||
|
case ESpecifier::RValue:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
log_failure( "Error, invalid specifier '%s' proceeding comma\n"
|
||||||
|
"(Parser will add and continue to specifiers, but will most likely fail to compile)\n%s"
|
||||||
|
, currtok.Text, Context.to_string() );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( specifiers )
|
||||||
|
specifiers.append( spec );
|
||||||
|
else
|
||||||
|
specifiers = def_specifier( spec );
|
||||||
|
}
|
||||||
|
|
||||||
|
StrC name = currtok;
|
||||||
|
eat( TokType::Identifier );
|
||||||
|
|
||||||
|
CodeVar var = parse_variable_after_name( ModuleFlag::None, NoCode, specifiers, NoCode, name );
|
||||||
|
if ( ! result )
|
||||||
|
{
|
||||||
|
result = var;
|
||||||
|
last_var = var;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
last_var->NextVar = var;
|
||||||
|
last_var = var;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -4837,6 +4931,7 @@ CodeType parse_type( bool* typedef_is_function )
|
|||||||
// Check if native type keywords are used, eat them for the signature.
|
// Check if native type keywords are used, eat them for the signature.
|
||||||
else if ( currtok.Type >= TokType::Type_Unsigned && currtok.Type <= TokType::Type_MS_W64 )
|
else if ( currtok.Type >= TokType::Type_Unsigned && currtok.Type <= TokType::Type_MS_W64 )
|
||||||
{
|
{
|
||||||
|
// TODO(Ed) : Review this... Its necessary for parsing however the algo's path to this is lost...
|
||||||
name = currtok;
|
name = currtok;
|
||||||
eat( currtok.Type );
|
eat( currtok.Type );
|
||||||
|
|
||||||
@ -4846,7 +4941,6 @@ CodeType parse_type( bool* typedef_is_function )
|
|||||||
}
|
}
|
||||||
|
|
||||||
name.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)name.Text;
|
name.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)name.Text;
|
||||||
Context.Scope->Name = name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The usual Identifier type signature that may have namespace qualifiers
|
// The usual Identifier type signature that may have namespace qualifiers
|
||||||
@ -5203,6 +5297,7 @@ CodeTypedef parse_typedef()
|
|||||||
|| currtok.Type == TokType::Decl_Struct
|
|| currtok.Type == TokType::Decl_Struct
|
||||||
|| currtok.Type == TokType::Decl_Union;
|
|| currtok.Type == TokType::Decl_Union;
|
||||||
|
|
||||||
|
// This code is highly correlated with parse_compilcated_definition
|
||||||
if ( is_complicated )
|
if ( is_complicated )
|
||||||
{
|
{
|
||||||
TokArray tokens = Context.Tokens;
|
TokArray tokens = Context.Tokens;
|
||||||
@ -5263,7 +5358,9 @@ CodeTypedef parse_typedef()
|
|||||||
return CodeInvalid;
|
return CodeInvalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
type = parse_type();
|
// TODO(Ed) : I'm not sure if I have to use parse_type here, I'd rather not as that would complicate parse_type.
|
||||||
|
// type = parse_type();
|
||||||
|
type = parse_foward_or_definition( currtok.Type, from_typedef );
|
||||||
}
|
}
|
||||||
else if ( tok.Type == TokType::BraceCurly_Close )
|
else if ( tok.Type == TokType::BraceCurly_Close )
|
||||||
{
|
{
|
||||||
@ -5327,7 +5424,12 @@ CodeTypedef parse_typedef()
|
|||||||
result->IsFunction = false;
|
result->IsFunction = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
result->UnderlyingType = type;
|
if ( type )
|
||||||
|
{
|
||||||
|
result->UnderlyingType = type;
|
||||||
|
result->UnderlyingType->Parent = rcast(AST*, result.ast);
|
||||||
|
}
|
||||||
|
// Type needs to be aware of its parent so that it can be serialized properly.
|
||||||
|
|
||||||
if ( type->Type == Typename && array_expr && array_expr->Type != Invalid )
|
if ( type->Type == Typename && array_expr && array_expr->Type != Invalid )
|
||||||
type.cast<CodeType>()->ArrExpr = array_expr;
|
type.cast<CodeType>()->ArrExpr = array_expr;
|
||||||
|
@ -57,11 +57,18 @@ if ( $release -eq $null ) {
|
|||||||
write-host "No build type specified, assuming debug"
|
write-host "No build type specified, assuming debug"
|
||||||
$release = $false
|
$release = $false
|
||||||
}
|
}
|
||||||
|
elseif ( $release -eq $false ) {
|
||||||
|
$debug = $true
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$optimize = treu
|
||||||
|
}
|
||||||
|
|
||||||
if ( $bootstrap -eq $false -and $singleheader -eq $false -and $test -eq $false ) {
|
if ( $bootstrap -eq $false -and $singleheader -eq $false -and $test -eq $false ) {
|
||||||
throw "No build target specified. One must be specified, this script will not assume one"
|
throw "No build target specified. One must be specified, this script will not assume one"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
. $vendor_toolchain
|
. $vendor_toolchain
|
||||||
. $incremental_checks
|
. $incremental_checks
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user