2023-08-28 20:46:50 -07:00
|
|
|
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
2023-08-21 17:30:13 -07:00
|
|
|
#pragma once
|
2023-08-21 20:28:39 -07:00
|
|
|
#include "gen/etoktype.cpp"
|
2023-08-21 20:02:20 -07:00
|
|
|
#include "interface.upfront.cpp"
|
2023-11-20 12:09:01 -08:00
|
|
|
#include "lexer.cpp"
|
|
|
|
#include "parser.cpp"
|
2023-08-28 20:46:50 -07:00
|
|
|
#endif
|
2023-08-21 17:30:13 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
// Publically Exposed Interface
|
2023-09-03 20:36:51 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
CodeClass parse_class( StrC def )
|
|
|
|
{
|
|
|
|
check_parse_args( def );
|
|
|
|
using namespace parser;
|
2023-09-04 22:44:04 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
TokArray toks = lex( def );
|
|
|
|
if ( toks.Arr == nullptr )
|
|
|
|
return CodeInvalid;
|
2023-09-03 20:36:51 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
Context.Tokens = toks;
|
|
|
|
push_scope();
|
|
|
|
CodeClass result = (CodeClass) parse_class_struct( TokType::Decl_Class );
|
2023-07-29 02:52:06 -07:00
|
|
|
Context.pop();
|
2023-07-24 14:45:27 -07:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
CodeConstructor parse_constructor( StrC def )
|
2023-07-24 14:45:27 -07:00
|
|
|
{
|
2023-07-29 03:32:16 -07:00
|
|
|
check_parse_args( def );
|
2023-11-20 12:09:01 -08:00
|
|
|
using namespace parser;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
TokArray toks = lex( def );
|
|
|
|
if ( toks.Arr == nullptr )
|
|
|
|
return CodeInvalid;
|
|
|
|
|
2024-04-17 14:40:32 -07:00
|
|
|
// TODO(Ed): Constructors can have prefix attributes
|
|
|
|
|
|
|
|
CodeSpecifiers specifiers;
|
|
|
|
SpecifierT specs_found[ 16 ] { ESpecifier::NumSpecifiers };
|
|
|
|
s32 NumSpecifiers = 0;
|
|
|
|
|
|
|
|
while ( left && currtok.is_specifier() )
|
|
|
|
{
|
|
|
|
SpecifierT spec = ESpecifier::to_type( currtok );
|
|
|
|
|
|
|
|
b32 ignore_spec = false;
|
|
|
|
|
|
|
|
switch ( spec )
|
|
|
|
{
|
|
|
|
case ESpecifier::Constexpr :
|
|
|
|
case ESpecifier::Explicit:
|
|
|
|
case ESpecifier::Inline :
|
|
|
|
case ESpecifier::ForceInline :
|
|
|
|
case ESpecifier::NeverInline :
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ESpecifier::Const :
|
|
|
|
ignore_spec = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default :
|
|
|
|
log_failure( "Invalid specifier %s for variable\n%s", ESpecifier::to_str( spec ), Context.to_string() );
|
|
|
|
Context.pop();
|
|
|
|
return CodeInvalid;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Every specifier after would be considered part of the type type signature
|
|
|
|
if (ignore_spec)
|
|
|
|
break;
|
|
|
|
|
|
|
|
specs_found[ NumSpecifiers ] = spec;
|
|
|
|
NumSpecifiers++;
|
|
|
|
eat( currtok.Type );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( NumSpecifiers )
|
|
|
|
{
|
|
|
|
specifiers = def_specifiers( NumSpecifiers, specs_found );
|
|
|
|
// <specifiers> ...
|
|
|
|
}
|
|
|
|
|
|
|
|
Context.Tokens = toks;
|
|
|
|
CodeConstructor result = parse_constructor( specifiers );
|
2023-11-20 12:09:01 -08:00
|
|
|
return result;
|
2023-07-24 14:45:27 -07:00
|
|
|
}
|
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
CodeDestructor parse_destructor( StrC def )
|
2023-07-24 14:45:27 -07:00
|
|
|
{
|
2023-11-20 12:09:01 -08:00
|
|
|
check_parse_args( def );
|
|
|
|
using namespace parser;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
TokArray toks = lex( def );
|
|
|
|
if ( toks.Arr == nullptr )
|
|
|
|
return CodeInvalid;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-04-17 14:40:32 -07:00
|
|
|
// TODO(Ed): Destructors can have prefix attributes
|
|
|
|
// TODO(Ed): Destructors can have virtual
|
|
|
|
|
|
|
|
Context.Tokens = toks;
|
2023-11-20 12:09:01 -08:00
|
|
|
CodeDestructor result = parse_destructor();
|
|
|
|
return result;
|
|
|
|
}
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
CodeEnum parse_enum( StrC def )
|
|
|
|
{
|
|
|
|
check_parse_args( def );
|
|
|
|
using namespace parser;
|
2023-08-07 17:16:04 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
TokArray toks = lex( def );
|
|
|
|
if ( toks.Arr == nullptr )
|
2023-10-24 21:25:35 -07:00
|
|
|
{
|
2023-11-20 12:09:01 -08:00
|
|
|
Context.pop();
|
|
|
|
return CodeInvalid;
|
2023-10-24 21:25:35 -07:00
|
|
|
}
|
2023-08-22 23:17:47 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
Context.Tokens = toks;
|
|
|
|
return parse_enum();
|
2023-07-24 14:45:27 -07:00
|
|
|
}
|
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
CodeBody parse_export_body( StrC def )
|
2023-07-24 14:45:27 -07:00
|
|
|
{
|
2023-07-29 03:32:16 -07:00
|
|
|
check_parse_args( def );
|
2023-11-20 12:09:01 -08:00
|
|
|
using namespace parser;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
TokArray toks = lex( def );
|
|
|
|
if ( toks.Arr == nullptr )
|
|
|
|
return CodeInvalid;
|
|
|
|
|
2023-07-29 09:25:38 -07:00
|
|
|
Context.Tokens = toks;
|
2023-11-20 12:09:01 -08:00
|
|
|
return parse_export_body();
|
2023-07-24 14:45:27 -07:00
|
|
|
}
|
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
CodeExtern parse_extern_link( StrC def )
|
2023-07-24 14:45:27 -07:00
|
|
|
{
|
2023-11-20 12:09:01 -08:00
|
|
|
check_parse_args( def );
|
|
|
|
using namespace parser;
|
2023-08-01 11:02:54 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
TokArray toks = lex( def );
|
|
|
|
if ( toks.Arr == nullptr )
|
|
|
|
return CodeInvalid;
|
2023-08-01 11:02:54 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
Context.Tokens = toks;
|
|
|
|
return parse_extern_link();
|
|
|
|
}
|
2023-08-01 13:07:47 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
CodeFriend parse_friend( StrC def )
|
|
|
|
{
|
|
|
|
check_parse_args( def );
|
|
|
|
using namespace parser;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
TokArray toks = lex( def );
|
|
|
|
if ( toks.Arr == nullptr )
|
|
|
|
return CodeInvalid;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
Context.Tokens = toks;
|
|
|
|
return parse_friend();
|
|
|
|
}
|
2023-07-31 21:42:08 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
CodeFn parse_function( StrC def )
|
|
|
|
{
|
|
|
|
check_parse_args( def );
|
|
|
|
using namespace parser;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
TokArray toks = lex( def );
|
|
|
|
if ( toks.Arr == nullptr )
|
|
|
|
return CodeInvalid;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
Context.Tokens = toks;
|
|
|
|
return (CodeFn) parse_function();
|
|
|
|
}
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
CodeBody parse_global_body( StrC def )
|
|
|
|
{
|
|
|
|
check_parse_args( def );
|
|
|
|
using namespace parser;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
TokArray toks = lex( def );
|
|
|
|
if ( toks.Arr == nullptr )
|
|
|
|
return CodeInvalid;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
Context.Tokens = toks;
|
|
|
|
push_scope();
|
|
|
|
CodeBody result = parse_global_nspace( ECode::Global_Body );
|
2023-07-29 02:52:06 -07:00
|
|
|
Context.pop();
|
2023-07-24 14:45:27 -07:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
CodeNS parse_namespace( StrC def )
|
2023-07-24 14:45:27 -07:00
|
|
|
{
|
2023-07-29 03:32:16 -07:00
|
|
|
check_parse_args( def );
|
2023-11-20 12:09:01 -08:00
|
|
|
using namespace parser;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
TokArray toks = lex( def );
|
|
|
|
if ( toks.Arr == nullptr )
|
|
|
|
return CodeInvalid;
|
|
|
|
|
2023-07-29 09:25:38 -07:00
|
|
|
Context.Tokens = toks;
|
2023-11-20 12:09:01 -08:00
|
|
|
return parse_namespace();
|
2023-07-24 14:45:27 -07:00
|
|
|
}
|
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
CodeOperator parse_operator( StrC def )
|
2023-07-24 14:45:27 -07:00
|
|
|
{
|
2023-11-20 12:09:01 -08:00
|
|
|
check_parse_args( def );
|
|
|
|
using namespace parser;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
TokArray toks = lex( def );
|
|
|
|
if ( toks.Arr == nullptr )
|
|
|
|
return CodeInvalid;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
Context.Tokens = toks;
|
|
|
|
return (CodeOperator) parse_operator();
|
|
|
|
}
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
CodeOpCast parse_operator_cast( StrC def )
|
|
|
|
{
|
|
|
|
check_parse_args( def );
|
|
|
|
using namespace parser;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
TokArray toks = lex( def );
|
|
|
|
if ( toks.Arr == nullptr )
|
|
|
|
return CodeInvalid;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
Context.Tokens = toks;
|
|
|
|
return parse_operator_cast();
|
|
|
|
}
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
CodeStruct parse_struct( StrC def )
|
|
|
|
{
|
|
|
|
check_parse_args( def );
|
|
|
|
using namespace parser;
|
2023-08-26 08:55:05 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
TokArray toks = lex( def );
|
|
|
|
if ( toks.Arr == nullptr )
|
|
|
|
return CodeInvalid;
|
2023-07-29 02:52:06 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
Context.Tokens = toks;
|
|
|
|
push_scope();
|
|
|
|
CodeStruct result = (CodeStruct) parse_class_struct( TokType::Decl_Struct );
|
2023-07-29 02:52:06 -07:00
|
|
|
Context.pop();
|
2023-07-24 14:45:27 -07:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
CodeTemplate parse_template( StrC def )
|
2023-07-24 14:45:27 -07:00
|
|
|
{
|
2023-07-29 03:32:16 -07:00
|
|
|
check_parse_args( def );
|
2023-11-20 12:09:01 -08:00
|
|
|
using namespace parser;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
TokArray toks = lex( def );
|
|
|
|
if ( toks.Arr == nullptr )
|
|
|
|
return CodeInvalid;
|
|
|
|
|
2023-07-29 09:25:38 -07:00
|
|
|
Context.Tokens = toks;
|
2023-11-20 12:09:01 -08:00
|
|
|
return parse_template();
|
2023-07-24 14:45:27 -07:00
|
|
|
}
|
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
CodeType parse_type( StrC def )
|
2023-07-24 14:45:27 -07:00
|
|
|
{
|
2023-11-20 12:09:01 -08:00
|
|
|
check_parse_args( def );
|
|
|
|
using namespace parser;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
TokArray toks = lex( def );
|
|
|
|
if ( toks.Arr == nullptr )
|
|
|
|
return CodeInvalid;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
Context.Tokens = toks;
|
|
|
|
return parse_type();
|
|
|
|
}
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
CodeTypedef parse_typedef( StrC def )
|
|
|
|
{
|
|
|
|
check_parse_args( def );
|
|
|
|
using namespace parser;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
TokArray toks = lex( def );
|
|
|
|
if ( toks.Arr == nullptr )
|
|
|
|
return CodeInvalid;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
Context.Tokens = toks;
|
|
|
|
return parse_typedef();
|
|
|
|
}
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
CodeUnion parse_union( StrC def )
|
|
|
|
{
|
|
|
|
check_parse_args( def );
|
|
|
|
using namespace parser;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
TokArray toks = lex( def );
|
|
|
|
if ( toks.Arr == nullptr )
|
|
|
|
return CodeInvalid;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
Context.Tokens = toks;
|
|
|
|
return parse_union();
|
|
|
|
}
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
CodeUsing parse_using( StrC def )
|
|
|
|
{
|
|
|
|
check_parse_args( def );
|
|
|
|
using namespace parser;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
TokArray toks = lex( def );
|
|
|
|
if ( toks.Arr == nullptr )
|
2023-07-24 14:45:27 -07:00
|
|
|
return CodeInvalid;
|
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
Context.Tokens = toks;
|
|
|
|
return parse_using();
|
2023-07-24 14:45:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
CodeVar parse_variable( StrC def )
|
|
|
|
{
|
2023-07-29 03:32:16 -07:00
|
|
|
check_parse_args( def );
|
2023-11-20 12:09:01 -08:00
|
|
|
using namespace parser;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
TokArray toks = lex( def );
|
|
|
|
if ( toks.Arr == nullptr )
|
|
|
|
return CodeInvalid;
|
|
|
|
|
2023-07-29 09:25:38 -07:00
|
|
|
Context.Tokens = toks;
|
2023-07-28 18:44:31 -07:00
|
|
|
return parse_variable();
|
2023-07-24 14:45:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Undef helper macros
|
|
|
|
# undef check_parse_args
|
2023-07-29 02:52:06 -07:00
|
|
|
# undef currtok
|
|
|
|
# undef prevtok
|
2023-08-07 00:10:45 -07:00
|
|
|
# undef nexttok
|
2023-07-24 14:45:27 -07:00
|
|
|
# undef eat
|
|
|
|
# undef left
|
2023-07-29 02:52:06 -07:00
|
|
|
# undef check
|
|
|
|
# undef push_scope
|