mirror of
https://github.com/Ed94/gencpp.git
synced 2024-12-22 15:54:45 -08:00
Parsing base case for class works!
This commit is contained in:
parent
498a51c899
commit
a8e03aa7ba
182
project/gen.cpp
182
project/gen.cpp
@ -1702,7 +1702,7 @@ namespace gen
|
|||||||
identify the issue without having to debug too much (at least they can debug though...)
|
identify the issue without having to debug too much (at least they can debug though...)
|
||||||
|
|
||||||
The largest of the functions is related to operator overload definitions.
|
The largest of the functions is related to operator overload definitions.
|
||||||
I decided to validate a good protion of their form and thus the argument processing for is quite a bit.
|
The library validates a good protion of their form and thus the argument processing for is quite a bit.
|
||||||
*/
|
*/
|
||||||
Code def_attributes( StrC content )
|
Code def_attributes( StrC content )
|
||||||
{
|
{
|
||||||
@ -2423,7 +2423,7 @@ namespace gen
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Body related functions typically follow the same implementation pattern.
|
Body related functions typically follow the same implementation pattern.
|
||||||
So I opted to use inline helper macros to get the implementaiton done.
|
Opted to use inline helper macros to get the implementaiton done.
|
||||||
|
|
||||||
The implementation pattern is as follows:
|
The implementation pattern is as follows:
|
||||||
* Validate a valid parameter num was provided, or code array
|
* Validate a valid parameter num was provided, or code array
|
||||||
@ -3269,6 +3269,10 @@ namespace gen
|
|||||||
{
|
{
|
||||||
Token token = { nullptr, 0, TokType::Invalid, false };
|
Token token = { nullptr, 0, TokType::Invalid, false };
|
||||||
|
|
||||||
|
SkipWhitespace();
|
||||||
|
if ( left <= 0 )
|
||||||
|
break;
|
||||||
|
|
||||||
switch ( current )
|
switch ( current )
|
||||||
{
|
{
|
||||||
case '.':
|
case '.':
|
||||||
@ -3568,10 +3572,6 @@ namespace gen
|
|||||||
goto FoundToken;
|
goto FoundToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkipWhitespace();
|
|
||||||
if ( left <= 0 )
|
|
||||||
break;
|
|
||||||
|
|
||||||
if ( char_is_alpha( current ) || current == '_' )
|
if ( char_is_alpha( current ) || current == '_' )
|
||||||
{
|
{
|
||||||
token.Text = scanner;
|
token.Text = scanner;
|
||||||
@ -3657,6 +3657,7 @@ namespace gen
|
|||||||
# define check( Type_ ) ( left && currtok.Type == Type_ )
|
# define check( Type_ ) ( left && currtok.Type == Type_ )
|
||||||
#pragma endregion Helper Macros
|
#pragma endregion Helper Macros
|
||||||
|
|
||||||
|
Code parse_class_struct_body( Parser::TokArray& toks, char const* context );
|
||||||
Code parse_function_body ( Parser::TokArray& toks, char const* context );
|
Code parse_function_body ( Parser::TokArray& toks, char const* context );
|
||||||
Code parse_global_nspace ( Parser::TokArray& toks, char const* context );
|
Code parse_global_nspace ( Parser::TokArray& toks, char const* context );
|
||||||
|
|
||||||
@ -3856,9 +3857,71 @@ namespace gen
|
|||||||
{
|
{
|
||||||
using namespace Parser;
|
using namespace Parser;
|
||||||
|
|
||||||
|
if ( which != TokType::Decl_Class && which != TokType::Decl_Struct )
|
||||||
|
{
|
||||||
|
log_failure( "%s: Error, expected class or struct, not %s", context, str_tok_type( which ) );
|
||||||
return Code::Invalid;
|
return Code::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Token name { nullptr, 0, TokType::Invalid };
|
||||||
|
|
||||||
|
Code parent = { nullptr };
|
||||||
|
Code body = { nullptr };
|
||||||
|
Code attributes = { nullptr };
|
||||||
|
ModuleFlag mflags = ModuleFlag::None;
|
||||||
|
|
||||||
|
Code result = Code::Invalid;
|
||||||
|
|
||||||
|
// TODO: Parse module specifiers
|
||||||
|
|
||||||
|
eat( which );
|
||||||
|
|
||||||
|
// TODO: Parse attributes
|
||||||
|
|
||||||
|
name = parse_identifier( toks, context );
|
||||||
|
|
||||||
|
AccessSpec access = AccessSpec::Invalid;
|
||||||
|
Token parent_tok = { nullptr, 0, TokType::Invalid };
|
||||||
|
|
||||||
|
if ( check( TokType::Assign_Classifer ) )
|
||||||
|
{
|
||||||
|
eat( TokType::Assign_Classifer );
|
||||||
|
|
||||||
|
if ( tok_is_access_specifier( currtok ) )
|
||||||
|
{
|
||||||
|
access = tok_to_access_specifier( currtok );
|
||||||
|
}
|
||||||
|
|
||||||
|
parent_tok = parse_identifier( toks, context );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( check( TokType::BraceCurly_Open ) )
|
||||||
|
{
|
||||||
|
body = parse_class_struct_body( toks, context );
|
||||||
|
}
|
||||||
|
|
||||||
|
eat( TokType::Statement_End );
|
||||||
|
|
||||||
|
if ( parent_tok )
|
||||||
|
parent = def_type( parent_tok );
|
||||||
|
|
||||||
|
if ( which == TokType::Decl_Class )
|
||||||
|
result = def_class( name, body, parent, access
|
||||||
|
// TODO: Set these up later
|
||||||
|
, NoCode // Attributes
|
||||||
|
, ModuleFlag::None
|
||||||
|
);
|
||||||
|
|
||||||
|
else
|
||||||
|
result = def_struct( name, body, parent, access
|
||||||
|
// TODO: Set these up later
|
||||||
|
, NoCode // Attributes
|
||||||
|
, ModuleFlag::None
|
||||||
|
);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
Code parse_class_struct_body( Parser::TokArray& toks, char const* context )
|
Code parse_class_struct_body( Parser::TokArray& toks, char const* context )
|
||||||
{
|
{
|
||||||
using namespace Parser;
|
using namespace Parser;
|
||||||
@ -4162,87 +4225,7 @@ namespace gen
|
|||||||
|
|
||||||
Code parse_class( Parser::TokArray& toks, char const* context )
|
Code parse_class( Parser::TokArray& toks, char const* context )
|
||||||
{
|
{
|
||||||
using namespace Parser;
|
return parse_class_struct( Parser::TokType::Decl_Class, toks, context );
|
||||||
|
|
||||||
Token name { nullptr, 0, TokType::Invalid };
|
|
||||||
|
|
||||||
Code parent = { nullptr };
|
|
||||||
Code specifiers = { nullptr };
|
|
||||||
Code body = { nullptr };
|
|
||||||
Code lang_linkage = { nullptr };
|
|
||||||
|
|
||||||
Code result = Code::Invalid;
|
|
||||||
|
|
||||||
SpecifierT specs_found[16] { ESpecifier::Num_Specifiers };
|
|
||||||
s32 num_specifiers = 0;
|
|
||||||
|
|
||||||
// Parse module specifiers
|
|
||||||
eat( TokType::Decl_Class );
|
|
||||||
|
|
||||||
// Parse specifiers
|
|
||||||
while ( left && tok_is_specifier( currtok ) )
|
|
||||||
{
|
|
||||||
SpecifierT spec = ESpecifier::to_type( currtok );
|
|
||||||
|
|
||||||
switch ( spec )
|
|
||||||
{
|
|
||||||
case ESpecifier::External_Linkage:
|
|
||||||
case ESpecifier::Local_Persist:
|
|
||||||
case ESpecifier::Mutable:
|
|
||||||
case ESpecifier::Static_Member:
|
|
||||||
case ESpecifier::Thread_Local:
|
|
||||||
case ESpecifier::Volatile:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
log_failure( "gen::parse_variable: invalid specifier " txt(spec) " for variable" );
|
|
||||||
return Code::Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( spec == ESpecifier::External_Linkage )
|
|
||||||
{
|
|
||||||
specs_found[num_specifiers] = spec;
|
|
||||||
num_specifiers++;
|
|
||||||
eat( TokType::Spec_Extern );
|
|
||||||
|
|
||||||
if ( currtok.Type == TokType::String )
|
|
||||||
{
|
|
||||||
lang_linkage = untyped_str( currtok );
|
|
||||||
eat( TokType::String );
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
specs_found[num_specifiers] = spec;
|
|
||||||
num_specifiers++;
|
|
||||||
eat( currtok.Type );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( num_specifiers )
|
|
||||||
{
|
|
||||||
specifiers = def_specifiers( num_specifiers, specs_found );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse alignment
|
|
||||||
|
|
||||||
name = parse_identifier( toks, context );
|
|
||||||
|
|
||||||
if ( check( TokType::Assign_Classifer ) )
|
|
||||||
{
|
|
||||||
eat( TokType::Assign_Classifer );
|
|
||||||
|
|
||||||
AccessSpec access = AccessSpec::Invalid;
|
|
||||||
|
|
||||||
if ( tok_is_access_specifier( currtok ) )
|
|
||||||
{
|
|
||||||
access = tok_to_access_specifier( currtok );
|
|
||||||
}
|
|
||||||
|
|
||||||
Token parent_tok = parse_identifier( toks, context );
|
|
||||||
}
|
|
||||||
|
|
||||||
not_implemented();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Code parse_class( StrC def )
|
Code parse_class( StrC def )
|
||||||
@ -4254,7 +4237,7 @@ namespace gen
|
|||||||
if ( toks.Arr == nullptr )
|
if ( toks.Arr == nullptr )
|
||||||
return Code::Invalid;
|
return Code::Invalid;
|
||||||
|
|
||||||
return parse_class( toks, txt(parse_class) );
|
return parse_class_struct( TokType::Decl_Class, toks, txt(parse_class) );
|
||||||
}
|
}
|
||||||
|
|
||||||
Code parse_enum( Parser::TokArray& toks, char const* context )
|
Code parse_enum( Parser::TokArray& toks, char const* context )
|
||||||
@ -4631,28 +4614,19 @@ namespace gen
|
|||||||
|
|
||||||
Code parse_struct( Parser::TokArray& toks, char const* context )
|
Code parse_struct( Parser::TokArray& toks, char const* context )
|
||||||
{
|
{
|
||||||
not_implemented();
|
return parse_class_struct( Parser::TokType::Decl_Struct, toks, txt(parse_struct) );
|
||||||
}
|
}
|
||||||
|
|
||||||
Code parse_struct( StrC def )
|
Code parse_struct( StrC def )
|
||||||
{
|
{
|
||||||
Arena mem;
|
check_parse_args( parse_struct, def );
|
||||||
do_once_start
|
using namespace Parser;
|
||||||
arena_init_from_allocator( & mem, heap(), kilobytes( 10 ) );
|
|
||||||
do_once_end
|
|
||||||
|
|
||||||
// Pretty sure its impossible to have more than this.
|
|
||||||
SpecifierT specs_found[16] { ESpecifier::Num_Specifiers };
|
|
||||||
|
|
||||||
u8 num_specifiers;
|
|
||||||
|
|
||||||
// Making all significant tokens have a max length of 128 for this parser.
|
|
||||||
constexpr sw LengthID = 128;
|
|
||||||
|
|
||||||
char const name [LengthID] { 0 };
|
|
||||||
char const parent[LengthID] { 0 };
|
|
||||||
|
|
||||||
|
TokArray toks = lex( def );
|
||||||
|
if ( toks.Arr == nullptr )
|
||||||
return Code::Invalid;
|
return Code::Invalid;
|
||||||
|
|
||||||
|
return parse_class_struct( TokType::Decl_Struct, toks, txt(parse_struct) );
|
||||||
}
|
}
|
||||||
|
|
||||||
Code parse_type( Parser::TokArray& toks, char const* context )
|
Code parse_type( Parser::TokArray& toks, char const* context )
|
||||||
|
@ -606,7 +606,7 @@ namespace gen
|
|||||||
return Invalid;
|
return Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
return * (Code*)( ast->body() );
|
return { ast->body() };
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
|
@ -26,7 +26,6 @@ void gen_sanity()
|
|||||||
gen_sanity_file.print_fmt("\n");
|
gen_sanity_file.print_fmt("\n");
|
||||||
|
|
||||||
// Class
|
// Class
|
||||||
if (0)
|
|
||||||
{
|
{
|
||||||
Code fwd = parse_class( code(
|
Code fwd = parse_class( code(
|
||||||
class TestEmptyClass;
|
class TestEmptyClass;
|
||||||
@ -46,10 +45,39 @@ void gen_sanity()
|
|||||||
gen_sanity_file.print_fmt("\n");
|
gen_sanity_file.print_fmt("\n");
|
||||||
|
|
||||||
// Enum
|
// Enum
|
||||||
|
if (0)
|
||||||
|
{
|
||||||
|
Code fwd = parse_enum( code(
|
||||||
|
enum ETestEnum : u8;
|
||||||
|
));
|
||||||
|
|
||||||
|
Code def = parse_enum( code(
|
||||||
|
enum ETestEnum : u8
|
||||||
|
{
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
C
|
||||||
|
};
|
||||||
|
));
|
||||||
|
|
||||||
|
Code fwd_enum_class = parse_enum( code(
|
||||||
|
enum class ETestEnum : u8;
|
||||||
|
));
|
||||||
|
|
||||||
|
gen_sanity_file.print(fwd);
|
||||||
|
gen_sanity_file.print(def);
|
||||||
|
gen_sanity_file.print(fwd_enum_class);
|
||||||
|
}
|
||||||
|
|
||||||
|
gen_sanity_file.print_fmt("\n");
|
||||||
|
|
||||||
|
// External Linkage
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gen_sanity_file.print_fmt("\n");
|
||||||
|
|
||||||
gen_sanity_file.write();
|
gen_sanity_file.write();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user