mirror of
https://github.com/Ed94/gencpp.git
synced 2025-07-01 11:21:04 -07:00
Compare commits
1 Commits
441a46daaa
...
main
Author | SHA1 | Date | |
---|---|---|---|
2ad164dc39 |
@ -3,7 +3,7 @@
|
|||||||
# include "helpers/push_ignores.inline.hpp"
|
# include "helpers/push_ignores.inline.hpp"
|
||||||
# include "components/header_start.hpp"
|
# include "components/header_start.hpp"
|
||||||
# include "components/types.hpp"
|
# include "components/types.hpp"
|
||||||
# include "components/gen/ecodetypes.hpp"
|
# include "components/gen/ecode.hpp"
|
||||||
# include "components/gen/eoperator.hpp"
|
# include "components/gen/eoperator.hpp"
|
||||||
# include "components/gen/especifier.hpp"
|
# include "components/gen/especifier.hpp"
|
||||||
# include "components/ast.hpp"
|
# include "components/ast.hpp"
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
# include "helpers/push_ignores.inline.hpp"
|
# include "helpers/push_ignores.inline.hpp"
|
||||||
# include "components/header_start.hpp"
|
# include "components/header_start.hpp"
|
||||||
# include "components/types.hpp"
|
# include "components/types.hpp"
|
||||||
# include "components/gen/ecodetypes.hpp"
|
# include "components/gen/ecode.hpp"
|
||||||
# include "components/gen/eoperator.hpp"
|
# include "components/gen/eoperator.hpp"
|
||||||
# include "components/gen/especifier.hpp"
|
# include "components/gen/especifier.hpp"
|
||||||
# include "components/ast.hpp"
|
# include "components/ast.hpp"
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
#ifdef INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "parser_types.hpp"
|
#include "types.hpp"
|
||||||
|
#include "gen/ecode.hpp"
|
||||||
|
#include "gen/eoperator.hpp"
|
||||||
|
#include "gen/especifier.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -403,8 +406,7 @@ struct AST
|
|||||||
Code PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal)
|
Code PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StrCached Content; // Attributes, Comment, Execution, Include
|
StrCached Content; // Attributes, Comment, Execution, Include
|
||||||
TokenSlice ContentToks; // TODO(Ed): Use a token slice for content
|
|
||||||
struct {
|
struct {
|
||||||
Specifier ArrSpecs[AST_ArrSpecs_Cap]; // Specifiers
|
Specifier ArrSpecs[AST_ArrSpecs_Cap]; // Specifiers
|
||||||
Code NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used.
|
Code NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used.
|
||||||
@ -420,7 +422,7 @@ struct AST
|
|||||||
Code Next;
|
Code Next;
|
||||||
Code Back;
|
Code Back;
|
||||||
};
|
};
|
||||||
Token* Token; // Reference to starting token, only available if it was derived from parsing. // TODO(Ed): Change this to a token slice.
|
Token* Token; // Reference to starting token, only available if it was derived from parsing.
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
// CodeFlag CodeFlags;
|
// CodeFlag CodeFlags;
|
||||||
|
@ -38,13 +38,13 @@ void body_to_strbuilder_export( CodeBody body, StrBuilder* result )
|
|||||||
GEN_ASSERT(result != nullptr);
|
GEN_ASSERT(result != nullptr);
|
||||||
strbuilder_append_fmt( result, "export\n{\n" );
|
strbuilder_append_fmt( result, "export\n{\n" );
|
||||||
|
|
||||||
Code curr = body->Front;
|
Code curr = cast(Code, body);
|
||||||
s32 left = body->NumEntries;
|
s32 left = body->NumEntries;
|
||||||
while ( left-- )
|
while ( left-- )
|
||||||
{
|
{
|
||||||
code_to_strbuilder_ref(curr, result);
|
code_to_strbuilder_ref(curr, result);
|
||||||
// strbuilder_append_fmt( result, "%SB", code_to_strbuilder(curr) );
|
// strbuilder_append_fmt( result, "%SB", code_to_strbuilder(curr) );
|
||||||
curr = curr->Next;
|
++curr;
|
||||||
}
|
}
|
||||||
|
|
||||||
strbuilder_append_fmt( result, "};\n" );
|
strbuilder_append_fmt( result, "};\n" );
|
||||||
|
@ -252,8 +252,8 @@ struct CodeSpecifiers
|
|||||||
#if ! GEN_C_LIKE_CPP
|
#if ! GEN_C_LIKE_CPP
|
||||||
Using_Code( CodeSpecifiers );
|
Using_Code( CodeSpecifiers );
|
||||||
bool append( Specifier spec ) { return specifiers_append(* this, spec); }
|
bool append( Specifier spec ) { return specifiers_append(* this, spec); }
|
||||||
s32 has( Specifier spec ) { return specifiers_has(* this, spec); }
|
bool has( Specifier spec ) { return specifiers_has(* this, spec); }
|
||||||
s32 index_of( Specifier spec ) { return specifiers_index_of(* this, spec); }
|
s32 index_of(Specifier spec) { return specifiers_index_of(* this, spec); }
|
||||||
s32 remove( Specifier to_remove ) { return specifiers_remove(* this, to_remove); }
|
s32 remove( Specifier to_remove ) { return specifiers_remove(* this, to_remove); }
|
||||||
StrBuilder to_strbuilder() { return specifiers_to_strbuilder(* this ); }
|
StrBuilder to_strbuilder() { return specifiers_to_strbuilder(* this ); }
|
||||||
void to_strbuilder( StrBuilder& result ) { return specifiers_to_strbuilder_ref(* this, & result); }
|
void to_strbuilder( StrBuilder& result ) { return specifiers_to_strbuilder_ref(* this, & result); }
|
||||||
@ -1075,7 +1075,8 @@ forceinline StrBuilder to_strbuilder(CodeParams params ) {
|
|||||||
forceinline void to_strbuilder(CodeParams params, StrBuilder& result ) { return params_to_strbuilder_ref(params, & result); }
|
forceinline void to_strbuilder(CodeParams params, StrBuilder& result ) { return params_to_strbuilder_ref(params, & result); }
|
||||||
|
|
||||||
forceinline bool append (CodeSpecifiers specifiers, Specifier spec) { return specifiers_append(specifiers, spec); }
|
forceinline bool append (CodeSpecifiers specifiers, Specifier spec) { return specifiers_append(specifiers, spec); }
|
||||||
forceinline s32 has (CodeSpecifiers specifiers, Specifier spec) { return specifiers_has(specifiers, spec); }
|
forceinline bool has (CodeSpecifiers specifiers, Specifier spec) { return specifiers_has(specifiers, spec); }
|
||||||
|
forceinline s32 index_of (CodeSpecifiers specifiers, Specifier spec) { return specifiers_index_of(specifiers, spec); }
|
||||||
forceinline s32 remove (CodeSpecifiers specifiers, Specifier to_remove ) { return specifiers_remove(specifiers, to_remove); }
|
forceinline s32 remove (CodeSpecifiers specifiers, Specifier to_remove ) { return specifiers_remove(specifiers, to_remove); }
|
||||||
forceinline StrBuilder to_strbuilder(CodeSpecifiers specifiers) { return specifiers_to_strbuilder(specifiers); }
|
forceinline StrBuilder to_strbuilder(CodeSpecifiers specifiers) { return specifiers_to_strbuilder(specifiers); }
|
||||||
forceinline void to_strbuilder(CodeSpecifiers specifiers, StrBuilder& result) { return specifiers_to_strbuilder_ref(specifiers, & result); }
|
forceinline void to_strbuilder(CodeSpecifiers specifiers, StrBuilder& result) { return specifiers_to_strbuilder_ref(specifiers, & result); }
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#ifdef INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "constants.hpp"
|
#include "interface.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma region Serialization
|
#pragma region Serialization
|
||||||
@ -38,7 +38,7 @@ void body_to_strbuilder_ref( CodeBody body, StrBuilder* result )
|
|||||||
{
|
{
|
||||||
code_to_strbuilder_ref(curr, result);
|
code_to_strbuilder_ref(curr, result);
|
||||||
// strbuilder_append_fmt( result, "%SB", code_to_strbuilder(curr) );
|
// strbuilder_append_fmt( result, "%SB", code_to_strbuilder(curr) );
|
||||||
curr = curr->Next;
|
++curr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,14 +71,6 @@ void* fallback_allocator_proc( void* allocator_data, AllocType type, ssize size,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal
|
|
||||||
void fallback_logger(LogEntry entry)
|
|
||||||
{
|
|
||||||
GEN_ASSERT(entry.msg.Len > 0);
|
|
||||||
GEN_ASSERT(entry.msg.Ptr);
|
|
||||||
log_fmt("%S: %S", loglevel_to_str(entry.level), entry.msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal
|
internal
|
||||||
void define_constants()
|
void define_constants()
|
||||||
{
|
{
|
||||||
@ -291,19 +283,6 @@ void init(Context* ctx)
|
|||||||
ctx->InitSize_Fallback_Allocator_Bucket_Size = megabytes(8);
|
ctx->InitSize_Fallback_Allocator_Bucket_Size = megabytes(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->InitSize_StrCacheTable == 0)
|
|
||||||
{
|
|
||||||
ctx->InitSize_StrCacheTable = kilobytes(8);
|
|
||||||
}
|
|
||||||
if (ctx->InitSize_MacrosTable == 0)
|
|
||||||
{
|
|
||||||
ctx->InitSize_MacrosTable = kilobytes(8);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctx->Logger == nullptr) {
|
|
||||||
ctx->Logger = & fallback_logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Override the current context (user has to put it back if unwanted).
|
// Override the current context (user has to put it back if unwanted).
|
||||||
_ctx = ctx;
|
_ctx = ctx;
|
||||||
|
|
||||||
@ -319,7 +298,7 @@ void init(Context* ctx)
|
|||||||
}
|
}
|
||||||
// Setup the code pool and code entries arena.
|
// Setup the code pool and code entries arena.
|
||||||
{
|
{
|
||||||
Pool code_pool = pool_init( ctx->Allocator_Pool, ctx->CodePool_NumBlocks, size_of(AST) );
|
Pool code_pool = pool_init( ctx->Allocator_Pool, ctx->CodePool_NumBlocks, sizeof(AST) );
|
||||||
if ( code_pool.PhysicalStart == nullptr )
|
if ( code_pool.PhysicalStart == nullptr )
|
||||||
GEN_FATAL( "gen::init: Failed to initialize the code pool" );
|
GEN_FATAL( "gen::init: Failed to initialize the code pool" );
|
||||||
array_append( ctx->CodePools, code_pool );
|
array_append( ctx->CodePools, code_pool );
|
||||||
@ -332,11 +311,11 @@ void init(Context* ctx)
|
|||||||
}
|
}
|
||||||
// Setup the hash tables
|
// Setup the hash tables
|
||||||
{
|
{
|
||||||
ctx->StrCache = hashtable_init_reserve(StrCached, ctx->Allocator_DyanmicContainers, ctx->InitSize_StrCacheTable);
|
ctx->StrCache = hashtable_init(StrCached, ctx->Allocator_DyanmicContainers);
|
||||||
if ( ctx->StrCache.Entries == nullptr )
|
if ( ctx->StrCache.Entries == nullptr )
|
||||||
GEN_FATAL( "gen::init: Failed to initialize the StringCache");
|
GEN_FATAL( "gen::init: Failed to initialize the StringCache");
|
||||||
|
|
||||||
ctx->Macros = hashtable_init_reserve(Macro, ctx->Allocator_DyanmicContainers, ctx->InitSize_MacrosTable);
|
ctx->Macros = hashtable_init(Macro, ctx->Allocator_DyanmicContainers);
|
||||||
if (ctx->Macros.Hashes == nullptr || ctx->Macros.Entries == nullptr) {
|
if (ctx->Macros.Hashes == nullptr || ctx->Macros.Entries == nullptr) {
|
||||||
GEN_FATAL( "gen::init: Failed to initialize the PreprocessMacros table" );
|
GEN_FATAL( "gen::init: Failed to initialize the PreprocessMacros table" );
|
||||||
}
|
}
|
||||||
|
@ -15,37 +15,23 @@
|
|||||||
\▓▓▓▓▓▓ \▓▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓ \▓▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓
|
\▓▓▓▓▓▓ \▓▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓ \▓▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum LogLevel //: u32
|
#if 0
|
||||||
|
enum LogLevel : u32
|
||||||
{
|
{
|
||||||
LL_Null,
|
Info,
|
||||||
LL_Note,
|
Warning,
|
||||||
LL_Warning,
|
Panic,
|
||||||
LL_Error,
|
|
||||||
LL_Fatal,
|
|
||||||
LL_UnderlyingType = GEN_U32_MAX,
|
|
||||||
};
|
};
|
||||||
typedef enum LogLevel LogLevel;
|
|
||||||
|
|
||||||
Str loglevel_to_str(LogLevel level)
|
|
||||||
{
|
|
||||||
local_persist
|
|
||||||
Str lookup[] = {
|
|
||||||
{ "Null", sizeof("Null") - 1 },
|
|
||||||
{ "Note", sizeof("Note") - 1 },
|
|
||||||
{ "Warning", sizeof("Info") - 1 },
|
|
||||||
{ "Error", sizeof("Error") - 1 },
|
|
||||||
{ "Fatal", sizeof("Fatal") - 1 },
|
|
||||||
};
|
|
||||||
return lookup[level];
|
|
||||||
}
|
|
||||||
|
|
||||||
struct LogEntry
|
struct LogEntry
|
||||||
{
|
{
|
||||||
Str msg;
|
Str msg;
|
||||||
LogLevel level;
|
u32 line_num;
|
||||||
|
void* data;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void LoggerProc(LogEntry entry);
|
typedef void LoggerCallback(LogEntry entry);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Note(Ed): This is subject to heavily change
|
// Note(Ed): This is subject to heavily change
|
||||||
// with upcoming changes to the library's fallback (default) allocations strategy;
|
// with upcoming changes to the library's fallback (default) allocations strategy;
|
||||||
@ -78,16 +64,9 @@ struct Context
|
|||||||
u32 InitSize_LexerTokens;
|
u32 InitSize_LexerTokens;
|
||||||
u32 SizePer_StringArena;
|
u32 SizePer_StringArena;
|
||||||
|
|
||||||
u32 InitSize_StrCacheTable;
|
|
||||||
u32 InitSize_MacrosTable;
|
|
||||||
|
|
||||||
// TODO(Ed): Symbol Table
|
// TODO(Ed): Symbol Table
|
||||||
// Keep track of all resolved symbols (naemspaced identifiers)
|
// Keep track of all resolved symbols (naemspaced identifiers)
|
||||||
|
|
||||||
// Logging
|
|
||||||
|
|
||||||
LoggerProc* Logger;
|
|
||||||
|
|
||||||
// Parser
|
// Parser
|
||||||
|
|
||||||
// Used by the lexer to persistently treat all these identifiers as preprocessor defines.
|
// Used by the lexer to persistently treat all these identifiers as preprocessor defines.
|
||||||
@ -125,45 +104,6 @@ struct Context
|
|||||||
// An implicit context interface will be provided instead as wrapper procedures as convience.
|
// An implicit context interface will be provided instead as wrapper procedures as convience.
|
||||||
GEN_API extern Context* _ctx;
|
GEN_API extern Context* _ctx;
|
||||||
|
|
||||||
// By default this library will either crash or exit if an error is detected while generating codes.
|
|
||||||
// Even if set to not use GEN_FATAL, GEN_FATAL will still be used for memory failures as the library is unusable when they occur.
|
|
||||||
#ifdef GEN_DONT_USE_FATAL
|
|
||||||
#define log_failure log_fmt
|
|
||||||
#else
|
|
||||||
#define log_failure GEN_FATAL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// TODO(Ed): Swap all usage of this with logger_fmt (then rename logger_fmt to log_fmt)
|
|
||||||
inline
|
|
||||||
ssize log_fmt(char const* fmt, ...)
|
|
||||||
{
|
|
||||||
ssize res;
|
|
||||||
va_list va;
|
|
||||||
|
|
||||||
va_start(va, fmt);
|
|
||||||
res = c_str_fmt_out_va(fmt, va);
|
|
||||||
va_end(va);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
void logger_fmt(Context* ctx, LogLevel level, char const* fmt, ...)
|
|
||||||
{
|
|
||||||
local_persist thread_local
|
|
||||||
PrintF_Buffer buf = struct_zero(PrintF_Buffer);
|
|
||||||
|
|
||||||
va_list va;
|
|
||||||
va_start(va, fmt);
|
|
||||||
ssize res = c_str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va) -1;
|
|
||||||
va_end(va);
|
|
||||||
|
|
||||||
StrBuilder msg = strbuilder_make_length(ctx->Allocator_Temp, buf, res);
|
|
||||||
|
|
||||||
LogEntry entry = { strbuilder_to_str(msg), level };
|
|
||||||
ctx->Logger(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the library. There first ctx initialized must exist for lifetime of other contextes that come after as its the one that
|
// Initialize the library. There first ctx initialized must exist for lifetime of other contextes that come after as its the one that
|
||||||
GEN_API void init(Context* ctx);
|
GEN_API void init(Context* ctx);
|
||||||
|
|
||||||
@ -174,7 +114,7 @@ GEN_API void deinit(Context* ctx);
|
|||||||
// Retrieves the active context (not usually needed, but here in case...)
|
// Retrieves the active context (not usually needed, but here in case...)
|
||||||
GEN_API Context* get_context();
|
GEN_API Context* get_context();
|
||||||
|
|
||||||
// Clears the allocations, but doesn't free the memory, then calls init() again.
|
// Clears the allocations, but doesn't free the memoery, then calls init() again.
|
||||||
// Ease of use.
|
// Ease of use.
|
||||||
GEN_API void reset(Context* ctx);
|
GEN_API void reset(Context* ctx);
|
||||||
|
|
||||||
@ -394,42 +334,37 @@ forceinline CodeBody def_union_body ( s32 num, Code* codes )
|
|||||||
|
|
||||||
#pragma region Parsing
|
#pragma region Parsing
|
||||||
|
|
||||||
struct ParseStackNode
|
#if 0
|
||||||
|
struct StackNode
|
||||||
{
|
{
|
||||||
ParseStackNode* Prev;
|
StackNode* Prev;
|
||||||
|
|
||||||
TokenSlice Tokens;
|
Token Start;
|
||||||
Token* Start;
|
Token Name; // The name of the AST node (if parsed)
|
||||||
Str Name; // The name of the AST node (if parsed)
|
Str FailedProc; // The name of the procedure that failed
|
||||||
Str ProcName; // The name of the procedure
|
|
||||||
Code CodeRel; // Relevant AST node
|
|
||||||
// TODO(Ed): When an error occurs, the parse stack is not released and instead the scope is left dangling.
|
|
||||||
};
|
};
|
||||||
|
// Stack nodes are allocated the error's allocator
|
||||||
|
|
||||||
typedef struct ParseMessage ParseMessage;
|
struct Error
|
||||||
struct ParseMessage
|
|
||||||
{
|
{
|
||||||
ParseMessage* Next;
|
StrBuilder message;
|
||||||
ParseStackNode* Scope;
|
StackNode* context_stack;
|
||||||
Str Log;
|
|
||||||
LogLevel Level;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ParseInfo
|
struct ParseInfo
|
||||||
{
|
{
|
||||||
ParseMessage* messages;
|
Arena FileMem;
|
||||||
LexedInfo lexed;
|
Arena TokMem;
|
||||||
Code result;
|
Arena CodeMem;
|
||||||
|
|
||||||
|
FileContents FileContent;
|
||||||
|
Array<Token> Tokens;
|
||||||
|
Array<Error> Errors;
|
||||||
|
// Errors are allocated to a dedicated general arena.
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ParseOpts
|
CodeBody parse_file( Str path );
|
||||||
{
|
#endif
|
||||||
AllocatorInfo backing_msgs;
|
|
||||||
AllocatorInfo backing_tokens;
|
|
||||||
AllocatorInfo backing_ast;
|
|
||||||
};
|
|
||||||
|
|
||||||
ParseInfo wip_parse_str( LexedInfo lexed, ParseOpts* opts GEN_PARAM_DEFAULT );
|
|
||||||
|
|
||||||
GEN_API CodeClass parse_class ( Str class_def );
|
GEN_API CodeClass parse_class ( Str class_def );
|
||||||
GEN_API CodeConstructor parse_constructor ( Str constructor_def );
|
GEN_API CodeConstructor parse_constructor ( Str constructor_def );
|
||||||
@ -460,10 +395,9 @@ GEN_API ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list v
|
|||||||
//! Do not use directly. Use the token_fmt macro instead.
|
//! Do not use directly. Use the token_fmt macro instead.
|
||||||
Str token_fmt_impl( ssize, ... );
|
Str token_fmt_impl( ssize, ... );
|
||||||
|
|
||||||
GEN_API Code untyped_str ( Str content);
|
GEN_API Code untyped_str( Str content);
|
||||||
GEN_API Code untyped_fmt ( char const* fmt, ... );
|
GEN_API Code untyped_fmt ( char const* fmt, ... );
|
||||||
GEN_API Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... );
|
GEN_API Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... );
|
||||||
GEN_API Code untyped_toks ( TokenSlice tokens );
|
|
||||||
|
|
||||||
#pragma endregion Untyped text
|
#pragma endregion Untyped text
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#ifdef INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "gen/etoktype.hpp"
|
#include "gen/etoktype.cpp"
|
||||||
#include "interface.upfront.cpp"
|
#include "interface.upfront.cpp"
|
||||||
#include "lexer.cpp"
|
#include "lexer.cpp"
|
||||||
#include "parser.cpp"
|
#include "parser.cpp"
|
||||||
@ -8,29 +8,6 @@
|
|||||||
|
|
||||||
// Publically Exposed Interface
|
// Publically Exposed Interface
|
||||||
|
|
||||||
ParseInfo wip_parse_str(LexedInfo lexed, ParseOpts* opts)
|
|
||||||
{
|
|
||||||
TokArray toks;
|
|
||||||
if (lexed.tokens.Num == 0 && lexed.tokens.Ptr == nullptr) {
|
|
||||||
check_parse_args(lexed.text);
|
|
||||||
toks = lex(lexed.text);
|
|
||||||
|
|
||||||
TokenSlice slice = { toks.Arr, scast(s32, array_num(toks.Arr)) };
|
|
||||||
lexed.tokens = slice;
|
|
||||||
}
|
|
||||||
ParseInfo info = struct_zero(ParseInfo);
|
|
||||||
info.lexed = lexed;
|
|
||||||
|
|
||||||
// TODO(Ed): ParseInfo should be set to the parser context.
|
|
||||||
|
|
||||||
_ctx->parser.Tokens = toks;
|
|
||||||
push_scope();
|
|
||||||
CodeBody result = parse_global_nspace(CT_Global_Body);
|
|
||||||
parser_pop(& _ctx->parser);
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
CodeClass parse_class( Str def )
|
CodeClass parse_class( Str def )
|
||||||
{
|
{
|
||||||
check_parse_args( def );
|
check_parse_args( def );
|
||||||
@ -349,7 +326,6 @@ CodeVar parse_variable( Str def )
|
|||||||
#undef left
|
#undef left
|
||||||
#undef check
|
#undef check
|
||||||
#undef push_scope
|
#undef push_scope
|
||||||
#undef NullScope
|
|
||||||
#undef def_assign
|
#undef def_assign
|
||||||
|
|
||||||
// Here for C Variant
|
// Here for C Variant
|
||||||
|
@ -176,16 +176,3 @@ Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... )
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Code untyped_toks( TokenSlice tokens )
|
|
||||||
{
|
|
||||||
if ( tokens.Num == 0 ) {
|
|
||||||
log_failure( "untyped_toks: empty token slice" );
|
|
||||||
return InvalidCode;
|
|
||||||
}
|
|
||||||
Code
|
|
||||||
result = make_code();
|
|
||||||
result->Type = CT_Untyped;
|
|
||||||
result->ContentToks = tokens;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
@ -473,10 +473,8 @@ CodeComment def_comment( Str content )
|
|||||||
return (CodeComment) result;
|
return (CodeComment) result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeConstructor def_constructor( Opts_def_constructor opt )
|
CodeConstructor def_constructor( Opts_def_constructor p )
|
||||||
{
|
{
|
||||||
Opts_def_constructor p = get_optional(opt);
|
|
||||||
|
|
||||||
if ( p.params && p.params->Type != CT_Parameters ) {
|
if ( p.params && p.params->Type != CT_Parameters ) {
|
||||||
log_failure("gen::def_constructor: params must be of Parameters type - %s", code_debug_str((Code)p.params));
|
log_failure("gen::def_constructor: params must be of Parameters type - %s", code_debug_str((Code)p.params));
|
||||||
GEN_DEBUG_TRAP();
|
GEN_DEBUG_TRAP();
|
||||||
@ -512,10 +510,8 @@ CodeConstructor def_constructor( Opts_def_constructor opt )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeClass def_class( Str name, Opts_def_struct opt )
|
CodeClass def_class( Str name, Opts_def_struct p )
|
||||||
{
|
{
|
||||||
Opts_def_struct p = get_optional(opt);
|
|
||||||
|
|
||||||
if ( ! name_check( def_class, name ) ) {
|
if ( ! name_check( def_class, name ) ) {
|
||||||
GEN_DEBUG_TRAP();
|
GEN_DEBUG_TRAP();
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
@ -565,10 +561,8 @@ CodeClass def_class( Str name, Opts_def_struct opt )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeDefine def_define( Str name, MacroType type, Opts_def_define opt )
|
CodeDefine def_define( Str name, MacroType type, Opts_def_define p )
|
||||||
{
|
{
|
||||||
Opts_def_define p = get_optional(opt);
|
|
||||||
|
|
||||||
if ( ! name_check( def_define, name ) ) {
|
if ( ! name_check( def_define, name ) ) {
|
||||||
GEN_DEBUG_TRAP();
|
GEN_DEBUG_TRAP();
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
@ -591,10 +585,8 @@ CodeDefine def_define( Str name, MacroType type, Opts_def_define opt )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeDestructor def_destructor( Opts_def_destructor opt )
|
CodeDestructor def_destructor( Opts_def_destructor p )
|
||||||
{
|
{
|
||||||
Opts_def_destructor p = get_optional(opt);
|
|
||||||
|
|
||||||
if ( p.specifiers && p.specifiers->Type != CT_Specifiers ) {
|
if ( p.specifiers && p.specifiers->Type != CT_Specifiers ) {
|
||||||
log_failure( "gen::def_destructor: specifiers was not a 'Specifiers' type: %s", code_debug_str(p.specifiers) );
|
log_failure( "gen::def_destructor: specifiers was not a 'Specifiers' type: %s", code_debug_str(p.specifiers) );
|
||||||
GEN_DEBUG_TRAP();
|
GEN_DEBUG_TRAP();
|
||||||
@ -627,10 +619,8 @@ CodeDestructor def_destructor( Opts_def_destructor opt )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeEnum def_enum( Str name, Opts_def_enum opt )
|
CodeEnum def_enum( Str name, Opts_def_enum p )
|
||||||
{
|
{
|
||||||
Opts_def_enum p = get_optional(opt);
|
|
||||||
|
|
||||||
if ( ! name_check( def_enum, name ) ) {
|
if ( ! name_check( def_enum, name ) ) {
|
||||||
GEN_DEBUG_TRAP();
|
GEN_DEBUG_TRAP();
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
@ -752,10 +742,8 @@ CodeFriend def_friend( Code declaration )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeFn def_function( Str name, Opts_def_function opt )
|
CodeFn def_function( Str name, Opts_def_function p )
|
||||||
{
|
{
|
||||||
Opts_def_function p = get_optional(opt);
|
|
||||||
|
|
||||||
if ( ! name_check( def_function, name )) {
|
if ( ! name_check( def_function, name )) {
|
||||||
GEN_DEBUG_TRAP();
|
GEN_DEBUG_TRAP();
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
@ -814,10 +802,8 @@ CodeFn def_function( Str name, Opts_def_function opt )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeInclude def_include( Str path, Opts_def_include opt )
|
CodeInclude def_include( Str path, Opts_def_include p )
|
||||||
{
|
{
|
||||||
Opts_def_include p = get_optional(opt);
|
|
||||||
|
|
||||||
if ( path.Len <= 0 || path.Ptr == nullptr ) {
|
if ( path.Len <= 0 || path.Ptr == nullptr ) {
|
||||||
log_failure( "gen::def_include: Invalid path provided - %d" );
|
log_failure( "gen::def_include: Invalid path provided - %d" );
|
||||||
GEN_DEBUG_TRAP();
|
GEN_DEBUG_TRAP();
|
||||||
@ -835,10 +821,8 @@ CodeInclude def_include( Str path, Opts_def_include opt )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeModule def_module( Str name, Opts_def_module opt )
|
CodeModule def_module( Str name, Opts_def_module p )
|
||||||
{
|
{
|
||||||
Opts_def_module p = get_optional(opt);
|
|
||||||
|
|
||||||
if ( ! name_check( def_module, name )) {
|
if ( ! name_check( def_module, name )) {
|
||||||
GEN_DEBUG_TRAP();
|
GEN_DEBUG_TRAP();
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
@ -851,10 +835,8 @@ CodeModule def_module( Str name, Opts_def_module opt )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeNS def_namespace( Str name, CodeBody body, Opts_def_namespace opt )
|
CodeNS def_namespace( Str name, CodeBody body, Opts_def_namespace p )
|
||||||
{
|
{
|
||||||
Opts_def_namespace p = get_optional(opt);
|
|
||||||
|
|
||||||
if ( ! name_check( def_namespace, name )) {
|
if ( ! name_check( def_namespace, name )) {
|
||||||
GEN_DEBUG_TRAP();
|
GEN_DEBUG_TRAP();
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
@ -877,10 +859,8 @@ CodeNS def_namespace( Str name, CodeBody body, Opts_def_namespace opt )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeOperator def_operator( Operator op, Str nspace, Opts_def_operator opt )
|
CodeOperator def_operator( Operator op, Str nspace, Opts_def_operator p )
|
||||||
{
|
{
|
||||||
Opts_def_operator p = get_optional(opt);
|
|
||||||
|
|
||||||
if ( p.attributes && p.attributes->Type != CT_PlatformAttributes ) {
|
if ( p.attributes && p.attributes->Type != CT_PlatformAttributes ) {
|
||||||
log_failure( "gen::def_operator: PlatformAttributes was provided but its not of attributes type: %s", code_debug_str(p.attributes) );
|
log_failure( "gen::def_operator: PlatformAttributes was provided but its not of attributes type: %s", code_debug_str(p.attributes) );
|
||||||
GEN_DEBUG_TRAP();
|
GEN_DEBUG_TRAP();
|
||||||
@ -946,10 +926,8 @@ CodeOperator def_operator( Operator op, Str nspace, Opts_def_operator opt )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast opt )
|
CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast p )
|
||||||
{
|
{
|
||||||
Opts_def_operator_cast p = get_optional(opt);
|
|
||||||
|
|
||||||
if ( ! null_check( def_operator_cast, type )) {
|
if ( ! null_check( def_operator_cast, type )) {
|
||||||
GEN_DEBUG_TRAP();
|
GEN_DEBUG_TRAP();
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
@ -981,10 +959,8 @@ CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast opt )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeParams def_param( CodeTypename type, Str name, Opts_def_param opt )
|
CodeParams def_param( CodeTypename type, Str name, Opts_def_param p )
|
||||||
{
|
{
|
||||||
Opts_def_param p = get_optional(opt);
|
|
||||||
|
|
||||||
if ( ! name_check( def_param, name ) || ! null_check( def_param, type ) ) {
|
if ( ! name_check( def_param, name ) || ! null_check( def_param, type ) ) {
|
||||||
GEN_DEBUG_TRAP();
|
GEN_DEBUG_TRAP();
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
@ -1058,10 +1034,8 @@ CodeSpecifiers def_specifier( Specifier spec )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeStruct def_struct( Str name, Opts_def_struct opt )
|
CodeStruct def_struct( Str name, Opts_def_struct p )
|
||||||
{
|
{
|
||||||
Opts_def_struct p = get_optional(opt);
|
|
||||||
|
|
||||||
if ( p.attributes && p.attributes->Type != CT_PlatformAttributes ) {
|
if ( p.attributes && p.attributes->Type != CT_PlatformAttributes ) {
|
||||||
log_failure( "gen::def_struct: attributes was not a `PlatformAttributes` type - %s", code_debug_str(cast(Code, p.attributes)) );
|
log_failure( "gen::def_struct: attributes was not a `PlatformAttributes` type - %s", code_debug_str(cast(Code, p.attributes)) );
|
||||||
GEN_DEBUG_TRAP();
|
GEN_DEBUG_TRAP();
|
||||||
@ -1102,10 +1076,8 @@ CodeStruct def_struct( Str name, Opts_def_struct opt )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeTemplate def_template( CodeParams params, Code declaration, Opts_def_template opt )
|
CodeTemplate def_template( CodeParams params, Code declaration, Opts_def_template p )
|
||||||
{
|
{
|
||||||
Opts_def_template p = get_optional(opt);
|
|
||||||
|
|
||||||
if ( ! null_check( def_template, declaration ) ) {
|
if ( ! null_check( def_template, declaration ) ) {
|
||||||
GEN_DEBUG_TRAP();
|
GEN_DEBUG_TRAP();
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
@ -1136,10 +1108,8 @@ CodeTemplate def_template( CodeParams params, Code declaration, Opts_def_templat
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeTypename def_type( Str name, Opts_def_type opt )
|
CodeTypename def_type( Str name, Opts_def_type p )
|
||||||
{
|
{
|
||||||
Opts_def_type p = get_optional(opt);
|
|
||||||
|
|
||||||
if ( ! name_check( def_type, name )) {
|
if ( ! name_check( def_type, name )) {
|
||||||
GEN_DEBUG_TRAP();
|
GEN_DEBUG_TRAP();
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
@ -1173,10 +1143,8 @@ CodeTypename def_type( Str name, Opts_def_type opt )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeTypedef def_typedef( Str name, Code type, Opts_def_typedef opt )
|
CodeTypedef def_typedef( Str name, Code type, Opts_def_typedef p )
|
||||||
{
|
{
|
||||||
Opts_def_typedef p = get_optional(opt);
|
|
||||||
|
|
||||||
if ( ! null_check( def_typedef, type ) ) {
|
if ( ! null_check( def_typedef, type ) ) {
|
||||||
GEN_DEBUG_TRAP();
|
GEN_DEBUG_TRAP();
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
@ -1238,10 +1206,8 @@ CodeTypedef def_typedef( Str name, Code type, Opts_def_typedef opt )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeUnion def_union( Str name, CodeBody body, Opts_def_union opt )
|
CodeUnion def_union( Str name, CodeBody body, Opts_def_union p )
|
||||||
{
|
{
|
||||||
Opts_def_union p = get_optional(opt);
|
|
||||||
|
|
||||||
if ( ! null_check( def_union, body ) ) {
|
if ( ! null_check( def_union, body ) ) {
|
||||||
GEN_DEBUG_TRAP();
|
GEN_DEBUG_TRAP();
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
@ -1267,10 +1233,8 @@ CodeUnion def_union( Str name, CodeBody body, Opts_def_union opt )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeUsing def_using( Str name, CodeTypename type, Opts_def_using opt )
|
CodeUsing def_using( Str name, CodeTypename type, Opts_def_using p )
|
||||||
{
|
{
|
||||||
Opts_def_using p = get_optional(opt);
|
|
||||||
|
|
||||||
if ( ! name_check( def_using, name ) || null_check( def_using, type ) ) {
|
if ( ! name_check( def_using, name ) || null_check( def_using, type ) ) {
|
||||||
GEN_DEBUG_TRAP();
|
GEN_DEBUG_TRAP();
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
@ -1310,10 +1274,8 @@ CodeUsing def_using_namespace( Str name )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeVar def_variable( CodeTypename type, Str name, Opts_def_variable opt )
|
CodeVar def_variable( CodeTypename type, Str name, Opts_def_variable p )
|
||||||
{
|
{
|
||||||
Opts_def_variable p = get_optional(opt);
|
|
||||||
|
|
||||||
if ( ! name_check( def_variable, name ) || ! null_check( def_variable, type ) ) {
|
if ( ! name_check( def_variable, name ) || ! null_check( def_variable, type ) ) {
|
||||||
GEN_DEBUG_TRAP();
|
GEN_DEBUG_TRAP();
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifdef INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "interface.upfront.cpp"
|
#include "interface.upfront.cpp"
|
||||||
#include "gen/etoktype.hpp"
|
#include "gen/etoktype.cpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
StrBuilder tok_to_strbuilder(Token tok)
|
StrBuilder tok_to_strbuilder(Token tok)
|
||||||
@ -564,12 +564,9 @@ void lex_found_token( LexContext* ctx )
|
|||||||
array_append( _ctx->Lexer_Tokens, ctx->token );
|
array_append( _ctx->Lexer_Tokens, ctx->token );
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(Ed): We should dynamically allocate the lexer's array in Allocator_DyanmicContainers.
|
|
||||||
|
|
||||||
// TODO(Ed): We need to to attempt to recover from a lex failure?
|
// TODO(Ed): We need to to attempt to recover from a lex failure?
|
||||||
|
|
||||||
neverinline
|
neverinline
|
||||||
// void lex( Array<Token> tokens, Str content )
|
// TokArray lex( Array<Token> tokens, Str content )
|
||||||
TokArray lex( Str content )
|
TokArray lex( Str content )
|
||||||
{
|
{
|
||||||
LexContext c; LexContext* ctx = & c;
|
LexContext c; LexContext* ctx = & c;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#ifdef INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "gen/etoktype.hpp"
|
#include "gen/etoktype.cpp"
|
||||||
#include "parser_case_macros.cpp"
|
#include "parser_case_macros.cpp"
|
||||||
#include "interface.upfront.cpp"
|
#include "interface.upfront.cpp"
|
||||||
#include "lexer.cpp"
|
#include "lexer.cpp"
|
||||||
@ -11,7 +11,7 @@
|
|||||||
constexpr bool lex_dont_skip_formatting = false;
|
constexpr bool lex_dont_skip_formatting = false;
|
||||||
constexpr bool lex_skip_formatting = true;
|
constexpr bool lex_skip_formatting = true;
|
||||||
|
|
||||||
void parser_push( ParseContext* ctx, ParseStackNode* node )
|
void parser_push( ParseContext* ctx, StackNode* node )
|
||||||
{
|
{
|
||||||
node->Prev = ctx->Scope;
|
node->Prev = ctx->Scope;
|
||||||
ctx->Scope = node;
|
ctx->Scope = node;
|
||||||
@ -60,7 +60,7 @@ StrBuilder parser_to_strbuilder(ParseContext ctx)
|
|||||||
else
|
else
|
||||||
strbuilder_append_fmt(& result, "\t(%d, %d)\n", last_valid.Line, last_valid.Column );
|
strbuilder_append_fmt(& result, "\t(%d, %d)\n", last_valid.Line, last_valid.Column );
|
||||||
|
|
||||||
ParseStackNode* curr_scope = ctx.Scope;
|
StackNode* curr_scope = ctx.Scope;
|
||||||
s32 level = 0;
|
s32 level = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -181,25 +181,18 @@ bool _check_parse_args( Str def, char const* func_name )
|
|||||||
# define check_noskip( Type_ ) ( left && currtok_noskip.Type == Type_ )
|
# define check_noskip( Type_ ) ( left && currtok_noskip.Type == Type_ )
|
||||||
# define check( Type_ ) ( left && currtok.Type == Type_ )
|
# define check( Type_ ) ( left && currtok.Type == Type_ )
|
||||||
|
|
||||||
// TODO(Ed): Don't do this anymore, we need a better initializer.
|
# define push_scope() \
|
||||||
# define push_scope() \
|
Str null_name = {}; \
|
||||||
Str null_name = {}; \
|
StackNode scope = { nullptr, lex_current( & _ctx->parser.Tokens, lex_dont_skip_formatting ), null_name, txt( __func__ ) }; \
|
||||||
ParseStackNode scope = { nullptr, {nullptr, 0}, lex_current( & _ctx->parser.Tokens, lex_dont_skip_formatting ), null_name, txt( __func__ ), { nullptr} }; \
|
parser_push( & _ctx->parser, & scope )
|
||||||
parser_push( & _ctx->parser, & scope )
|
|
||||||
|
|
||||||
#if GEN_COMPILER_CPP
|
|
||||||
# define NullScope { nullptr, {nullptr, 0}, lex_current( & ctx->parser.Tokens, lex_dont_skip_formatting ), Str{nullptr, 0}, txt( __func__ ), { nullptr} }
|
|
||||||
#else
|
|
||||||
# define NullScope (ParseStackNode){ nullptr, {nullptr, 0}, lex_current( & ctx->parser.Tokens, lex_dont_skip_formatting ), (Str){nullptr, 0}, txt( __func__ ), { nullptr} }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#pragma endregion Helper Macros
|
#pragma endregion Helper Macros
|
||||||
|
|
||||||
// Procedure Forwards ( Entire parser internal parser interface )
|
// Procedure Forwards ( Entire parser internal parser interface )
|
||||||
|
|
||||||
internal Code parse_array_decl (Context* ctx);
|
internal Code parse_array_decl ();
|
||||||
internal CodeAttributes parse_attributes (Context* ctx);
|
internal CodeAttributes parse_attributes ();
|
||||||
internal CodeComment parse_comment (Context* ctx);
|
internal CodeComment parse_comment ();
|
||||||
internal Code parse_complicated_definition ( TokType which );
|
internal Code parse_complicated_definition ( TokType which );
|
||||||
internal CodeBody parse_class_struct_body ( TokType which, Token name );
|
internal CodeBody parse_class_struct_body ( TokType which, Token name );
|
||||||
internal Code parse_class_struct ( TokType which, bool inplace_def );
|
internal Code parse_class_struct ( TokType which, bool inplace_def );
|
||||||
@ -497,18 +490,10 @@ StrBuilder parser_strip_formatting( Str raw_text, bool preserve_newlines )
|
|||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
StrBuilder parser_strip_formatting_2(TokenSlice tokens)
|
|
||||||
{
|
|
||||||
// TODO(Ed): Use this to produce strings for validation purposes. We shouldn't serialize down from tokens once we start storing token slices for content.
|
|
||||||
StrBuilder result = struct_zero(StrBuilder);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal
|
internal
|
||||||
Code parse_array_decl(Context* ctx)
|
Code parse_array_decl()
|
||||||
{
|
{
|
||||||
ParseStackNode scope = NullScope;
|
push_scope();
|
||||||
parser_push(& ctx->parser, & scope );
|
|
||||||
|
|
||||||
if ( check( Tok_Operator ) && currtok.Text.Ptr[0] == '[' && currtok.Text.Ptr[1] == ']' )
|
if ( check( Tok_Operator ) && currtok.Text.Ptr[0] == '[' && currtok.Text.Ptr[1] == ']' )
|
||||||
{
|
{
|
||||||
@ -516,7 +501,7 @@ Code parse_array_decl(Context* ctx)
|
|||||||
eat( Tok_Operator );
|
eat( Tok_Operator );
|
||||||
// []
|
// []
|
||||||
|
|
||||||
parser_pop(& ctx->parser);
|
parser_pop(& _ctx->parser);
|
||||||
return array_expr;
|
return array_expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -527,45 +512,41 @@ Code parse_array_decl(Context* ctx)
|
|||||||
|
|
||||||
if ( left == 0 )
|
if ( left == 0 )
|
||||||
{
|
{
|
||||||
log_failure( "Error, unexpected end of array declaration ( '[]' scope started )\n%s", parser_to_strbuilder(ctx->parser) );
|
log_failure( "Error, unexpected end of array declaration ( '[]' scope started )\n%s", parser_to_strbuilder(_ctx->parser) );
|
||||||
parser_pop(& ctx->parser);
|
parser_pop(& _ctx->parser);
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( currtok.Type == Tok_BraceSquare_Close )
|
if ( currtok.Type == Tok_BraceSquare_Close )
|
||||||
{
|
{
|
||||||
log_failure( "Error, empty array expression in definition\n%s", parser_to_strbuilder(ctx->parser) );
|
log_failure( "Error, empty array expression in definition\n%s", parser_to_strbuilder(_ctx->parser) );
|
||||||
parser_pop(& ctx->parser);
|
parser_pop(& _ctx->parser);
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
TokenSlice tokens = { & currtok, 1 };
|
|
||||||
Token untyped_tok = currtok;
|
Token untyped_tok = currtok;
|
||||||
|
|
||||||
while ( left && currtok.Type != Tok_BraceSquare_Close )
|
while ( left && currtok.Type != Tok_BraceSquare_Close )
|
||||||
{
|
{
|
||||||
eat( currtok.Type );
|
eat( currtok.Type );
|
||||||
++ tokens.Num;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// untyped_tok.Text.Len = ( (sptr)prevtok.Text.Ptr + prevtok.Text.Len ) - (sptr)untyped_tok.Text.Ptr;
|
untyped_tok.Text.Len = ( (sptr)prevtok.Text.Ptr + prevtok.Text.Len ) - (sptr)untyped_tok.Text.Ptr;
|
||||||
untyped_tok.Text = token_range_to_str(untyped_tok, prevtok);
|
|
||||||
|
|
||||||
Code array_expr = untyped_str( untyped_tok.Text );
|
Code array_expr = untyped_str( untyped_tok.Text );
|
||||||
// Code array_expr = untyped_toks( tokens ); // TODO(Ed): Use token slice instead of untyped strings.
|
|
||||||
// [ <Content>
|
// [ <Content>
|
||||||
|
|
||||||
if ( left == 0 )
|
if ( left == 0 )
|
||||||
{
|
{
|
||||||
log_failure( "Error, unexpected end of array declaration, expected ]\n%s", parser_to_strbuilder(ctx->parser) );
|
log_failure( "Error, unexpected end of array declaration, expected ]\n%s", parser_to_strbuilder(_ctx->parser) );
|
||||||
parser_pop(& ctx->parser);
|
parser_pop(& _ctx->parser);
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( currtok.Type != Tok_BraceSquare_Close )
|
if ( currtok.Type != Tok_BraceSquare_Close )
|
||||||
{
|
{
|
||||||
log_failure( "%s: Error, expected ] in array declaration, not %s\n%s", toktype_to_str( currtok.Type ), parser_to_strbuilder(ctx->parser) );
|
log_failure( "%s: Error, expected ] in array declaration, not %s\n%s", toktype_to_str( currtok.Type ), parser_to_strbuilder(_ctx->parser) );
|
||||||
parser_pop(& ctx->parser);
|
parser_pop(& _ctx->parser);
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -575,25 +556,24 @@ Code parse_array_decl(Context* ctx)
|
|||||||
// Its a multi-dimensional array
|
// Its a multi-dimensional array
|
||||||
if ( check( Tok_BraceSquare_Open ))
|
if ( check( Tok_BraceSquare_Open ))
|
||||||
{
|
{
|
||||||
Code adjacent_arr_expr = parse_array_decl(ctx);
|
Code adjacent_arr_expr = parse_array_decl();
|
||||||
// [ <Content> ][ <Content> ]...
|
// [ <Content> ][ <Content> ]...
|
||||||
|
|
||||||
array_expr->Next = adjacent_arr_expr;
|
array_expr->Next = adjacent_arr_expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
parser_pop(& ctx->parser);
|
parser_pop(& _ctx->parser);
|
||||||
return array_expr;
|
return array_expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
parser_pop(& ctx->parser);
|
parser_pop(& _ctx->parser);
|
||||||
return NullCode;
|
return NullCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal inline
|
internal inline
|
||||||
CodeAttributes parse_attributes(Context* ctx)
|
CodeAttributes parse_attributes()
|
||||||
{
|
{
|
||||||
ParseStackNode scope = NullScope;
|
push_scope();
|
||||||
parser_push(& ctx->parser, & scope);
|
|
||||||
|
|
||||||
Token start = currtok;
|
Token start = currtok;
|
||||||
s32 len = 0;
|
s32 len = 0;
|
||||||
@ -684,7 +664,7 @@ CodeAttributes parse_attributes(Context* ctx)
|
|||||||
if ( len > 0 )
|
if ( len > 0 )
|
||||||
{
|
{
|
||||||
Str attribute_txt = { start.Text.Ptr, len };
|
Str attribute_txt = { start.Text.Ptr, len };
|
||||||
parser_pop(& ctx->parser);
|
parser_pop(& _ctx->parser);
|
||||||
|
|
||||||
StrBuilder name_stripped = parser_strip_formatting( attribute_txt, parser_strip_formatting_dont_preserve_newlines );
|
StrBuilder name_stripped = parser_strip_formatting( attribute_txt, parser_strip_formatting_dont_preserve_newlines );
|
||||||
|
|
||||||
@ -693,10 +673,11 @@ CodeAttributes parse_attributes(Context* ctx)
|
|||||||
result->Name = cache_str( strbuilder_to_str(name_stripped) );
|
result->Name = cache_str( strbuilder_to_str(name_stripped) );
|
||||||
result->Content = result->Name;
|
result->Content = result->Name;
|
||||||
// result->Token =
|
// result->Token =
|
||||||
|
|
||||||
return ( CodeAttributes )result;
|
return ( CodeAttributes )result;
|
||||||
}
|
}
|
||||||
|
|
||||||
parser_pop(& ctx->parser);
|
parser_pop(& _ctx->parser);
|
||||||
return NullCode;
|
return NullCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -727,7 +708,7 @@ Code parse_class_struct( TokType which, bool inplace_def )
|
|||||||
eat( which );
|
eat( which );
|
||||||
// <ModuleFlags> <class/struct>
|
// <ModuleFlags> <class/struct>
|
||||||
|
|
||||||
attributes = parse_attributes(_ctx);
|
attributes = parse_attributes();
|
||||||
// <ModuleFlags> <class/struct> <Attributes>
|
// <ModuleFlags> <class/struct> <Attributes>
|
||||||
|
|
||||||
if ( check( Tok_Identifier ) ) {
|
if ( check( Tok_Identifier ) ) {
|
||||||
@ -794,7 +775,7 @@ Code parse_class_struct( TokType which, bool inplace_def )
|
|||||||
// <ModuleFlags> <class/struct> <Attributes> <Name> <final> : <Access Specifier> <Name>, ... { <Body> };
|
// <ModuleFlags> <class/struct> <Attributes> <Name> <final> : <Access Specifier> <Name>, ... { <Body> };
|
||||||
|
|
||||||
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
||||||
inline_cmt = parse_comment(_ctx);
|
inline_cmt = parse_comment();
|
||||||
// <ModuleFlags> <class/struct> <Attributes> <Name> <final> : <Access Specifier> <Name>, ... { <Body> }; <InlineCmt>
|
// <ModuleFlags> <class/struct> <Attributes> <Name> <final> : <Access Specifier> <Name>, ... { <Body> }; <InlineCmt>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -855,7 +836,7 @@ CodeBody parse_class_struct_body( TokType which, Token name )
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Tok_Comment: {
|
case Tok_Comment: {
|
||||||
member = cast(Code, parse_comment(_ctx));
|
member = cast(Code, parse_comment());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Tok_Access_Public: {
|
case Tok_Access_Public: {
|
||||||
@ -1014,7 +995,7 @@ CodeBody parse_class_struct_body( TokType which, Token name )
|
|||||||
GEN_DEFINE_ATTRIBUTE_TOKENS
|
GEN_DEFINE_ATTRIBUTE_TOKENS
|
||||||
#undef Entry
|
#undef Entry
|
||||||
{
|
{
|
||||||
attributes = parse_attributes(_ctx);
|
attributes = parse_attributes();
|
||||||
// <Attributes>
|
// <Attributes>
|
||||||
}
|
}
|
||||||
//! Fallthrough intended
|
//! Fallthrough intended
|
||||||
@ -1066,7 +1047,7 @@ CodeBody parse_class_struct_body( TokType which, Token name )
|
|||||||
if ( tok_is_attribute(currtok) )
|
if ( tok_is_attribute(currtok) )
|
||||||
{
|
{
|
||||||
// Unfortuantely Unreal has code where there is attirbutes before specifiers
|
// Unfortuantely Unreal has code where there is attirbutes before specifiers
|
||||||
CodeAttributes more_attributes = parse_attributes(_ctx);
|
CodeAttributes more_attributes = parse_attributes();
|
||||||
|
|
||||||
if ( attributes )
|
if ( attributes )
|
||||||
{
|
{
|
||||||
@ -1154,10 +1135,9 @@ CodeBody parse_class_struct_body( TokType which, Token name )
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal
|
internal
|
||||||
CodeComment parse_comment(Context* ctx)
|
CodeComment parse_comment()
|
||||||
{
|
{
|
||||||
ParseStackNode scope = NullScope;
|
push_scope();
|
||||||
parser_push(& ctx->parser, & scope );
|
|
||||||
|
|
||||||
CodeComment
|
CodeComment
|
||||||
result = (CodeComment) make_code();
|
result = (CodeComment) make_code();
|
||||||
@ -1166,7 +1146,7 @@ CodeComment parse_comment(Context* ctx)
|
|||||||
// result->Token = currtok_noskip;
|
// result->Token = currtok_noskip;
|
||||||
eat( Tok_Comment );
|
eat( Tok_Comment );
|
||||||
|
|
||||||
parser_pop(& ctx->parser);
|
parser_pop(& _ctx->parser);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1463,22 +1443,6 @@ CodeFn parse_function_after_name(
|
|||||||
}
|
}
|
||||||
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers>
|
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers>
|
||||||
|
|
||||||
// Check for trailing specifiers...
|
|
||||||
CodeAttributes post_rt_attributes = parse_attributes(_ctx);
|
|
||||||
if (post_rt_attributes)
|
|
||||||
{
|
|
||||||
if (attributes)
|
|
||||||
{
|
|
||||||
StrBuilder merged = strbuilder_fmt_buf(_ctx->Allocator_Temp, "%S %S", attributes->Content, post_rt_attributes->Content);
|
|
||||||
attributes->Content = cache_str(strbuilder_to_str(merged));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
attributes = post_rt_attributes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> <Attributes>
|
|
||||||
|
|
||||||
CodeBody body = NullCode;
|
CodeBody body = NullCode;
|
||||||
CodeComment inline_cmt = NullCode;
|
CodeComment inline_cmt = NullCode;
|
||||||
if ( check( Tok_BraceCurly_Open ) )
|
if ( check( Tok_BraceCurly_Open ) )
|
||||||
@ -1516,20 +1480,18 @@ CodeFn parse_function_after_name(
|
|||||||
eat( Tok_Statement_End );
|
eat( Tok_Statement_End );
|
||||||
|
|
||||||
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
||||||
inline_cmt = parse_comment(_ctx);
|
inline_cmt = parse_comment();
|
||||||
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> < = 0 or delete > ; <InlineCmt>
|
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers>; <InlineCmt>
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
|
||||||
if (body == nullptr)
|
|
||||||
{
|
{
|
||||||
Token stmt_end = currtok;
|
Token stmt_end = currtok;
|
||||||
eat( Tok_Statement_End );
|
eat( Tok_Statement_End );
|
||||||
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> <Attributes> < = 0 or delete > ;
|
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers>;
|
||||||
|
|
||||||
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
||||||
inline_cmt = parse_comment(_ctx);
|
inline_cmt = parse_comment();
|
||||||
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> < = 0 or delete > ; <InlineCmt>
|
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers>; <InlineCmt>
|
||||||
}
|
}
|
||||||
|
|
||||||
StrBuilder
|
StrBuilder
|
||||||
@ -1682,7 +1644,7 @@ CodeBody parse_global_nspace( CodeType which )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Tok_Comment:
|
case Tok_Comment:
|
||||||
member = cast(Code, parse_comment(_ctx));
|
member = cast(Code, parse_comment());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Tok_Decl_Class:
|
case Tok_Decl_Class:
|
||||||
@ -1804,7 +1766,7 @@ CodeBody parse_global_nspace( CodeType which )
|
|||||||
|
|
||||||
case Tok_Preprocess_Macro_Expr:
|
case Tok_Preprocess_Macro_Expr:
|
||||||
{
|
{
|
||||||
if ( ! tok_is_attribute(currtok))
|
if (tok_is_attribute(currtok))
|
||||||
{
|
{
|
||||||
log_failure("Unbounded macro expression residing in class/struct body\n%S", parser_to_strbuilder(_ctx->parser));
|
log_failure("Unbounded macro expression residing in class/struct body\n%S", parser_to_strbuilder(_ctx->parser));
|
||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
@ -1818,7 +1780,7 @@ CodeBody parse_global_nspace( CodeType which )
|
|||||||
GEN_DEFINE_ATTRIBUTE_TOKENS
|
GEN_DEFINE_ATTRIBUTE_TOKENS
|
||||||
#undef Entry
|
#undef Entry
|
||||||
{
|
{
|
||||||
attributes = parse_attributes(_ctx);
|
attributes = parse_attributes();
|
||||||
// <Attributes>
|
// <Attributes>
|
||||||
}
|
}
|
||||||
//! Fallthrough intentional
|
//! Fallthrough intentional
|
||||||
@ -2087,20 +2049,11 @@ Token parse_identifier( bool* possible_member_function )
|
|||||||
|
|
||||||
Macro* macro = lookup_macro(currtok.Text);
|
Macro* macro = lookup_macro(currtok.Text);
|
||||||
b32 accept_as_identifier = macro && bitfield_is_set(MacroFlags, macro->Flags, MF_Allow_As_Identifier );
|
b32 accept_as_identifier = macro && bitfield_is_set(MacroFlags, macro->Flags, MF_Allow_As_Identifier );
|
||||||
b32 is_decarator = macro && bitfield_is_set(MacroFlags, macro->Flags, MF_Identifier_Decorator );
|
|
||||||
|
|
||||||
// Typename can be: '::' <name>
|
// Typename can be: '::' <name>
|
||||||
// If that is the case first option will be Tok_Access_StaticSymbol below
|
// If that is the case first option will be Tok_Access_StaticSymbol below
|
||||||
if (check(Tok_Identifier) || accept_as_identifier)
|
if (check(Tok_Identifier) || accept_as_identifier)
|
||||||
{
|
eat( Tok_Identifier );
|
||||||
if (is_decarator) {
|
|
||||||
Code name_macro = parse_simple_preprocess(currtok.Type);
|
|
||||||
name.Text.Len = ( ( sptr )prevtok.Text.Ptr + prevtok.Text.Len ) - ( sptr )name.Text.Ptr;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
eat(Tok_Identifier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// <Name>
|
// <Name>
|
||||||
|
|
||||||
parse_template_args( & name );
|
parse_template_args( & name );
|
||||||
@ -2410,10 +2363,7 @@ CodeOperator parse_operator_after_ret_type(
|
|||||||
case '(':
|
case '(':
|
||||||
{
|
{
|
||||||
if ( currtok.Text.Ptr[1] == ')' )
|
if ( currtok.Text.Ptr[1] == ')' )
|
||||||
{
|
|
||||||
op = Op_FunctionCall;
|
op = Op_FunctionCall;
|
||||||
eat(Tok_Paren_Open);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
else
|
||||||
op = Op_Invalid;
|
op = Op_Invalid;
|
||||||
@ -2563,7 +2513,7 @@ CodeOperator parse_operator_after_ret_type(
|
|||||||
// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> ( <Parameters> ) <Specifiers>;
|
// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> ( <Parameters> ) <Specifiers>;
|
||||||
|
|
||||||
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
||||||
inline_cmt = parse_comment(_ctx);
|
inline_cmt = parse_comment();
|
||||||
// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> ( <Parameters> ) <Specifiers>; <InlineCmt>
|
// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> ( <Parameters> ) <Specifiers>; <InlineCmt>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2594,7 +2544,7 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes
|
|||||||
// <Attributes> <Specifiers> <ReturnType/ValueType>
|
// <Attributes> <Specifiers> <ReturnType/ValueType>
|
||||||
|
|
||||||
// Thanks Unreal
|
// Thanks Unreal
|
||||||
CodeAttributes post_rt_attributes = parse_attributes(_ctx);
|
CodeAttributes post_rt_attributes = parse_attributes();
|
||||||
if (post_rt_attributes)
|
if (post_rt_attributes)
|
||||||
{
|
{
|
||||||
if (attributes)
|
if (attributes)
|
||||||
@ -3310,7 +3260,7 @@ CodeVar parse_variable_after_name(
|
|||||||
{
|
{
|
||||||
push_scope();
|
push_scope();
|
||||||
|
|
||||||
Code array_expr = parse_array_decl(_ctx);
|
Code array_expr = parse_array_decl();
|
||||||
Code expr = NullCode;
|
Code expr = NullCode;
|
||||||
Code bitfield_expr = NullCode;
|
Code bitfield_expr = NullCode;
|
||||||
|
|
||||||
@ -3420,7 +3370,7 @@ CodeVar parse_variable_after_name(
|
|||||||
|
|
||||||
// Check for inline comment : <type> <identifier> = <expression>; // <inline comment>
|
// Check for inline comment : <type> <identifier> = <expression>; // <inline comment>
|
||||||
if ( left && ( currtok_noskip.Type == Tok_Comment ) && currtok_noskip.Line == stmt_end.Line ) {
|
if ( left && ( currtok_noskip.Type == Tok_Comment ) && currtok_noskip.Line == stmt_end.Line ) {
|
||||||
inline_cmt = parse_comment(_ctx);
|
inline_cmt = parse_comment();
|
||||||
// <Attributes> <Specifiers> <ValueType> <Name> : <Expression>, ...; <InlineCmt>
|
// <Attributes> <Specifiers> <ValueType> <Name> : <Expression>, ...; <InlineCmt>
|
||||||
// <Attributes> <Specifiers> <ValueType> <Name> = <Expression>, ...; <InlineCmt>
|
// <Attributes> <Specifiers> <ValueType> <Name> = <Expression>, ...; <InlineCmt>
|
||||||
// <Attributes> <Specifiers> <ValueType> <Name> { <Expression> }, ...; <InlineCmt>
|
// <Attributes> <Specifiers> <ValueType> <Name> { <Expression> }, ...; <InlineCmt>
|
||||||
@ -3604,7 +3554,7 @@ CodeConstructor parser_parse_constructor( CodeSpecifiers specifiers )
|
|||||||
// <Name> ( <Parameters> );
|
// <Name> ( <Parameters> );
|
||||||
|
|
||||||
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
||||||
inline_cmt = parse_comment(_ctx);
|
inline_cmt = parse_comment();
|
||||||
// <Name> ( <Parameters> ); <InlineCmt>
|
// <Name> ( <Parameters> ); <InlineCmt>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3806,7 +3756,7 @@ CodeDestructor parser_parse_destructor( CodeSpecifiers specifiers )
|
|||||||
// <Virtual Specifier> ~<Name>() <Pure Specifier>;
|
// <Virtual Specifier> ~<Name>() <Pure Specifier>;
|
||||||
|
|
||||||
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
||||||
inline_cmt = parse_comment(_ctx);
|
inline_cmt = parse_comment();
|
||||||
// <Virtual Specifier> ~<Name>() <Pure Specifier>; <InlineCmt>
|
// <Virtual Specifier> ~<Name>() <Pure Specifier>; <InlineCmt>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3860,7 +3810,7 @@ CodeEnum parser_parse_enum( bool inplace_def )
|
|||||||
// enum class
|
// enum class
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes = parse_attributes(_ctx);
|
attributes = parse_attributes();
|
||||||
// enum <class> <Attributes>
|
// enum <class> <Attributes>
|
||||||
|
|
||||||
if ( check( Tok_Identifier ) )
|
if ( check( Tok_Identifier ) )
|
||||||
@ -3930,7 +3880,7 @@ CodeEnum parser_parse_enum( bool inplace_def )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Tok_Comment:
|
case Tok_Comment:
|
||||||
member = cast(Code, parse_comment(_ctx));
|
member = cast(Code, parse_comment());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Tok_Preprocess_Define:
|
case Tok_Preprocess_Define:
|
||||||
@ -4045,7 +3995,7 @@ CodeEnum parser_parse_enum( bool inplace_def )
|
|||||||
// enum <class> <Attributes> <Name> : <UnderlyingType> { <Body> };
|
// enum <class> <Attributes> <Name> : <UnderlyingType> { <Body> };
|
||||||
|
|
||||||
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
||||||
inline_cmt = parse_comment(_ctx);
|
inline_cmt = parse_comment();
|
||||||
// enum <class> <Attributes> <Name> : <UnderlyingType> { <Body> }; <InlineCmt>
|
// enum <class> <Attributes> <Name> : <UnderlyingType> { <Body> }; <InlineCmt>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4223,7 +4173,7 @@ CodeFriend parser_parse_friend()
|
|||||||
// friend <ReturnType> <Name> ( <Parameters> );
|
// friend <ReturnType> <Name> ( <Parameters> );
|
||||||
|
|
||||||
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
||||||
inline_cmt = parse_comment(_ctx);
|
inline_cmt = parse_comment();
|
||||||
// friend <Type>; <InlineCmt>
|
// friend <Type>; <InlineCmt>
|
||||||
// friend <ReturnType> <Name> ( <Parameters> ); <InlineCmt>
|
// friend <ReturnType> <Name> ( <Parameters> ); <InlineCmt>
|
||||||
}
|
}
|
||||||
@ -4263,7 +4213,7 @@ CodeFn parser_parse_function()
|
|||||||
}
|
}
|
||||||
// <export>
|
// <export>
|
||||||
|
|
||||||
attributes = parse_attributes(_ctx);
|
attributes = parse_attributes();
|
||||||
// <export> <Attributes>
|
// <export> <Attributes>
|
||||||
|
|
||||||
while ( left && tok_is_specifier(currtok) )
|
while ( left && tok_is_specifier(currtok) )
|
||||||
@ -4364,7 +4314,7 @@ CodeOperator parser_parse_operator()
|
|||||||
}
|
}
|
||||||
// <export>
|
// <export>
|
||||||
|
|
||||||
attributes = parse_attributes(_ctx);
|
attributes = parse_attributes();
|
||||||
// <export> <Attributes>
|
// <export> <Attributes>
|
||||||
|
|
||||||
while ( left && tok_is_specifier(currtok) )
|
while ( left && tok_is_specifier(currtok) )
|
||||||
@ -4492,7 +4442,7 @@ CodeOpCast parser_parse_operator_cast( CodeSpecifiers specifiers )
|
|||||||
// <Specifiers> <Qualifier> :: ... operator <UnderlyingType>() <const>;
|
// <Specifiers> <Qualifier> :: ... operator <UnderlyingType>() <const>;
|
||||||
|
|
||||||
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
||||||
inline_cmt = parse_comment(_ctx);
|
inline_cmt = parse_comment();
|
||||||
// <Specifiers> <Qualifier> :: ... operator <UnderlyingType>() <const>; <InlineCmt>
|
// <Specifiers> <Qualifier> :: ... operator <UnderlyingType>() <const>; <InlineCmt>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4595,7 +4545,7 @@ CodeTemplate parser_parse_template()
|
|||||||
Specifier specs_found[ 16 ] = { Spec_NumSpecifiers };
|
Specifier specs_found[ 16 ] = { Spec_NumSpecifiers };
|
||||||
s32 NumSpecifiers = 0;
|
s32 NumSpecifiers = 0;
|
||||||
|
|
||||||
attributes = parse_attributes(_ctx);
|
attributes = parse_attributes();
|
||||||
// <export> template< <Parameters> > <Attributes>
|
// <export> template< <Parameters> > <Attributes>
|
||||||
|
|
||||||
// Specifiers Parsing
|
// Specifiers Parsing
|
||||||
@ -4726,7 +4676,7 @@ CodeTypename parser_parse_type( bool from_template, bool* typedef_is_function )
|
|||||||
ETypenameTag tag = Tag_None;
|
ETypenameTag tag = Tag_None;
|
||||||
|
|
||||||
// Attributes are assumed to be before the type signature
|
// Attributes are assumed to be before the type signature
|
||||||
CodeAttributes attributes = parse_attributes(_ctx);
|
CodeAttributes attributes = parse_attributes();
|
||||||
// <Attributes>
|
// <Attributes>
|
||||||
|
|
||||||
// Prefix specifiers
|
// Prefix specifiers
|
||||||
@ -4764,37 +4714,21 @@ CodeTypename parser_parse_type( bool from_template, bool* typedef_is_function )
|
|||||||
else if ( currtok.Type == Tok_Decl_Class || currtok.Type == Tok_Decl_Enum || currtok.Type == Tok_Decl_Struct
|
else if ( currtok.Type == Tok_Decl_Class || currtok.Type == Tok_Decl_Enum || currtok.Type == Tok_Decl_Struct
|
||||||
|| currtok.Type == Tok_Decl_Union )
|
|| currtok.Type == Tok_Decl_Union )
|
||||||
{
|
{
|
||||||
Token next = nexttok;
|
switch (currtok.Type) {
|
||||||
|
case Tok_Decl_Class : tag = Tag_Class; break;
|
||||||
if (next.Type == Tok_Identifier)
|
case Tok_Decl_Enum : tag = Tag_Enum; break;
|
||||||
{
|
case Tok_Decl_Struct : tag = Tag_Struct; break;
|
||||||
switch (currtok.Type) {
|
case Tok_Decl_Union : tag = Tag_Union; break;
|
||||||
case Tok_Decl_Class : tag = Tag_Class; break;
|
default:
|
||||||
case Tok_Decl_Enum : tag = Tag_Enum; break;
|
break;
|
||||||
case Tok_Decl_Struct : tag = Tag_Struct; break;
|
|
||||||
case Tok_Decl_Union : tag = Tag_Union; break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
eat( currtok.Type );
|
|
||||||
// <Attributes> <Specifiers> <class, enum, struct, union>
|
|
||||||
|
|
||||||
name = parse_identifier(nullptr);
|
|
||||||
// <Attributes> <Specifiers> <class, enum, struct, union> <Name>
|
|
||||||
}
|
}
|
||||||
else if (next.Type == Tok_BraceCurly_Open)
|
eat( currtok.Type );
|
||||||
{
|
// <Attributes> <Specifiers> <class, enum, struct, union>
|
||||||
name = currtok;
|
|
||||||
// We have an inplace definition, we need to consume that...
|
|
||||||
|
|
||||||
// TODO(Ed): we need to add a way for AST_CodeTypename to track an implace definition..
|
name = parse_identifier(nullptr);
|
||||||
b32 const inplace = true;
|
|
||||||
Code indplace_def = cast(Code, parser_parse_struct(inplace));
|
|
||||||
|
|
||||||
// For now we lose the structural information,
|
// name.Length = ( ( sptr )currtok.Text + currtok.Length ) - ( sptr )name.Text;
|
||||||
name.Text.Len = ( ( sptr )prevtok.Text.Ptr + prevtok.Text.Len ) - ( sptr )name.Text.Ptr;
|
// eat( Tok_Identifier );
|
||||||
// <Attributes> <Specifiers> <class, enum, struct, union> <inplace def>
|
|
||||||
}
|
|
||||||
_ctx->parser.Scope->Name = name.Text;
|
_ctx->parser.Scope->Name = name.Text;
|
||||||
// <Attributes> <Specifiers> <class, enum, struct, union> <Name>
|
// <Attributes> <Specifiers> <class, enum, struct, union> <Name>
|
||||||
}
|
}
|
||||||
@ -5364,7 +5298,7 @@ CodeTypedef parser_parse_typedef()
|
|||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
array_expr = parse_array_decl(_ctx);
|
array_expr = parse_array_decl();
|
||||||
// <UnderlyingType> + <ArrayExpr>
|
// <UnderlyingType> + <ArrayExpr>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5374,7 +5308,7 @@ CodeTypedef parser_parse_typedef()
|
|||||||
|
|
||||||
CodeComment inline_cmt = NullCode;
|
CodeComment inline_cmt = NullCode;
|
||||||
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
|
||||||
inline_cmt = parse_comment(_ctx);
|
inline_cmt = parse_comment();
|
||||||
// <ModuleFalgs> typedef <UnderlyingType> <Name> <ArrayExpr>; <InlineCmt>
|
// <ModuleFalgs> typedef <UnderlyingType> <Name> <ArrayExpr>; <InlineCmt>
|
||||||
|
|
||||||
CodeTypedef
|
CodeTypedef
|
||||||
@ -5427,7 +5361,7 @@ CodeUnion parser_parse_union( bool inplace_def )
|
|||||||
eat( Tok_Decl_Union );
|
eat( Tok_Decl_Union );
|
||||||
// <ModuleFlags> union
|
// <ModuleFlags> union
|
||||||
|
|
||||||
CodeAttributes attributes = parse_attributes(_ctx);
|
CodeAttributes attributes = parse_attributes();
|
||||||
// <ModuleFlags> union <Attributes>
|
// <ModuleFlags> union <Attributes>
|
||||||
|
|
||||||
Str name = { nullptr, 0 };
|
Str name = { nullptr, 0 };
|
||||||
@ -5463,7 +5397,7 @@ CodeUnion parser_parse_union( bool inplace_def )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Tok_Comment:
|
case Tok_Comment:
|
||||||
member = cast(Code, parse_comment(_ctx));
|
member = cast(Code, parse_comment());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// TODO(Ed) : Unions can have constructors and destructors
|
// TODO(Ed) : Unions can have constructors and destructors
|
||||||
@ -5596,12 +5530,12 @@ CodeUsing parser_parse_using()
|
|||||||
|
|
||||||
if ( ! is_namespace )
|
if ( ! is_namespace )
|
||||||
{
|
{
|
||||||
attributes = parse_attributes(_ctx);
|
attributes = parse_attributes();
|
||||||
// <ModuleFlags> using <Name> <Attributes>
|
// <ModuleFlags> using <Name> <Attributes>
|
||||||
|
|
||||||
if ( bitfield_is_set( u32, currtok.Flags, TF_Assign ))
|
if ( bitfield_is_set( u32, currtok.Flags, TF_Assign ))
|
||||||
{
|
{
|
||||||
attributes = parse_attributes(_ctx);
|
attributes = parse_attributes();
|
||||||
// <ModuleFlags> using <Name> <Attributes>
|
// <ModuleFlags> using <Name> <Attributes>
|
||||||
|
|
||||||
eat( Tok_Operator );
|
eat( Tok_Operator );
|
||||||
@ -5610,7 +5544,7 @@ CodeUsing parser_parse_using()
|
|||||||
type = parser_parse_type(parser_not_from_template, nullptr);
|
type = parser_parse_type(parser_not_from_template, nullptr);
|
||||||
// <ModuleFlags> using <Name> <Attributes> = <UnderlyingType>
|
// <ModuleFlags> using <Name> <Attributes> = <UnderlyingType>
|
||||||
|
|
||||||
array_expr = parse_array_decl(_ctx);
|
array_expr = parse_array_decl();
|
||||||
// <UnderlyingType> + <ArrExpr>
|
// <UnderlyingType> + <ArrExpr>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5621,7 +5555,7 @@ CodeUsing parser_parse_using()
|
|||||||
|
|
||||||
CodeComment inline_cmt = NullCode;
|
CodeComment inline_cmt = NullCode;
|
||||||
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line ) {
|
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line ) {
|
||||||
inline_cmt = parse_comment(_ctx);
|
inline_cmt = parse_comment();
|
||||||
}
|
}
|
||||||
// <ModuleFlags> using <namespace> <Attributes> <Name> = <UnderlyingType>; <InlineCmt>
|
// <ModuleFlags> using <namespace> <Attributes> <Name> = <UnderlyingType>; <InlineCmt>
|
||||||
|
|
||||||
@ -5673,7 +5607,7 @@ CodeVar parser_parse_variable()
|
|||||||
}
|
}
|
||||||
// <ModuleFlags>
|
// <ModuleFlags>
|
||||||
|
|
||||||
attributes = parse_attributes(_ctx);
|
attributes = parse_attributes();
|
||||||
// <ModuleFlags> <Attributes>
|
// <ModuleFlags> <Attributes>
|
||||||
|
|
||||||
while ( left && tok_is_specifier(currtok) )
|
while ( left && tok_is_specifier(currtok) )
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifdef INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
#include "gen/ecodetypes.hpp"
|
#include "gen/ecode.hpp"
|
||||||
#include "gen/eoperator.hpp"
|
#include "gen/eoperator.hpp"
|
||||||
#include "gen/especifier.hpp"
|
#include "gen/especifier.hpp"
|
||||||
#include "gen/etoktype.hpp"
|
#include "gen/etoktype.hpp"
|
||||||
@ -91,27 +91,6 @@ bool tok_is_end_definition(Token tok) {
|
|||||||
|
|
||||||
StrBuilder tok_to_strbuilder(Token tok);
|
StrBuilder tok_to_strbuilder(Token tok);
|
||||||
|
|
||||||
struct TokenSlice
|
|
||||||
{
|
|
||||||
Token* Ptr;
|
|
||||||
s32 Num;
|
|
||||||
|
|
||||||
#if GEN_COMPILER_CPP
|
|
||||||
forceinline operator Token* () const { return Ptr; }
|
|
||||||
forceinline Token& operator[]( ssize index ) const { return Ptr[index]; }
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
forceinline
|
|
||||||
Str token_range_to_str(Token start, Token end)
|
|
||||||
{
|
|
||||||
Str result = {
|
|
||||||
start.Text.Ptr,
|
|
||||||
(scast(sptr, rcast(uptr, end.Text.Ptr)) + end.Text.Len) - scast(sptr, rcast(uptr, start.Text.Ptr))
|
|
||||||
};
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct TokArray
|
struct TokArray
|
||||||
{
|
{
|
||||||
Array(Token) Arr;
|
Array(Token) Arr;
|
||||||
@ -125,21 +104,23 @@ struct LexContext
|
|||||||
char const* scanner;
|
char const* scanner;
|
||||||
s32 line;
|
s32 line;
|
||||||
s32 column;
|
s32 column;
|
||||||
|
// StringTable defines;
|
||||||
Token token;
|
Token token;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LexedInfo
|
struct StackNode
|
||||||
{
|
{
|
||||||
Str text;
|
StackNode* Prev;
|
||||||
TokenSlice tokens;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct ParseStackNode ParseStackNode;
|
Token* Start;
|
||||||
|
Str Name; // The name of the AST node (if parsed)
|
||||||
|
Str ProcName; // The name of the procedure
|
||||||
|
};
|
||||||
|
|
||||||
struct ParseContext
|
struct ParseContext
|
||||||
{
|
{
|
||||||
TokArray Tokens;
|
TokArray Tokens;
|
||||||
ParseStackNode* Scope;
|
StackNode* Scope;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MacroType : u16
|
enum MacroType : u16
|
||||||
@ -187,36 +168,26 @@ Str macrotype_to_str( MacroType type )
|
|||||||
|
|
||||||
enum EMacroFlags : u16
|
enum EMacroFlags : u16
|
||||||
{
|
{
|
||||||
// Macro has parameters (args expected to be passed)
|
MF_Functional = bit(0), // Macro has parameters (args expected to be passed)
|
||||||
MF_Functional = bit(0),
|
MF_Expects_Body = bit(1), // Expects to assign a braced scope to its body.
|
||||||
|
|
||||||
// Expects to assign a braced scope to its body.
|
|
||||||
MF_Expects_Body = bit(1),
|
|
||||||
|
|
||||||
// lex__eat wil treat this macro as an identifier if the parser attempts to consume it as one.
|
// lex__eat wil treat this macro as an identifier if the parser attempts to consume it as one.
|
||||||
// This is a kludge because we don't support push/pop macro pragmas rn.
|
// ^^^ This is a kludge because we don't support push/pop macro pragmas rn.
|
||||||
MF_Allow_As_Identifier = bit(2),
|
MF_Allow_As_Identifier = bit(2),
|
||||||
|
|
||||||
// When parsing identifiers, it will allow the consumption of the macro parameters (as its expected to be a part of constructing the identifier)
|
|
||||||
// Example of a decarator macro from stb_sprintf.h:
|
|
||||||
// STBSP__PUBLICDEC int STB_SPRINTF_DECORATE(sprintf)(char* buf, char const *fmt, ...) STBSP__ATTRIBUTE_FORMAT(2,3);
|
|
||||||
// ^^ STB_SPRINTF_DECORATE is decorating sprintf
|
|
||||||
MF_Identifier_Decorator = bit(3),
|
|
||||||
|
|
||||||
// lex__eat wil treat this macro as an attribute if the parser attempts to consume it as one.
|
// lex__eat wil treat this macro as an attribute if the parser attempts to consume it as one.
|
||||||
// This a kludge because unreal has a macro that behaves as both a 'statement' and an attribute (UE_DEPRECATED, PRAGMA_ENABLE_DEPRECATION_WARNINGS, etc)
|
// ^^^ This a kludge because unreal has a macro that behaves as both a 'statement' and an attribute (UE_DEPRECATED, PRAGMA_ENABLE_DEPRECATION_WARNINGS, etc)
|
||||||
// TODO(Ed): We can keep the MF_Allow_As_Attribute flag for macros, however, we need to add the ability of AST_Attributes to chain themselves.
|
// TODO(Ed): We can keep the MF_Allow_As_Attribute flag for macros, however, we need to add the ability of AST_Attributes to chain themselves.
|
||||||
// Its thats already a thing in the standard language anyway
|
// Its thats already a thing in the standard language anyway
|
||||||
// & it would allow UE_DEPRECATED, (UE_PROPERTY / UE_FUNCTION) to chain themselves as attributes of a resolved member function/variable definition
|
// & it would allow UE_DEPRECATED, (UE_PROPERTY / UE_FUNCTION) to chain themselves as attributes of a resolved member function/variable definition
|
||||||
MF_Allow_As_Attribute = bit(4),
|
MF_Allow_As_Attribute = bit(3),
|
||||||
|
|
||||||
// When a macro is encountered after attributes and specifiers while parsing a function, or variable:
|
// When a macro is encountered after attributes and specifiers while parsing a function, or variable:
|
||||||
// It will consume the macro and treat it as resolving the definition.
|
// It will consume the macro and treat it as resolving the definition. (Yes this is for Unreal Engine)
|
||||||
// (MUST BE OF MT_Statement TYPE)
|
// (MUST BE OF MT_Statement TYPE)
|
||||||
MF_Allow_As_Definition = bit(5),
|
MF_Allow_As_Definition = bit(4),
|
||||||
|
|
||||||
// Created for Unreal's PURE_VIRTUAL
|
MF_Allow_As_Specifier = bit(5), // Created for Unreal's PURE_VIRTUAL
|
||||||
MF_Allow_As_Specifier = bit(6),
|
|
||||||
|
|
||||||
MF_Null = 0,
|
MF_Null = 0,
|
||||||
MF_UnderlyingType = GEN_U16_MAX,
|
MF_UnderlyingType = GEN_U16_MAX,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#ifdef INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "interface.hpp"
|
#include "../gen.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma region StaticData
|
#pragma region StaticData
|
||||||
|
@ -1,18 +1,6 @@
|
|||||||
#ifdef INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "dependencies/platform.hpp"
|
#include "header_start.hpp"
|
||||||
#include "dependencies/macros.hpp"
|
|
||||||
#include "dependencies/basic_types.hpp"
|
|
||||||
#include "dependencies/debug.hpp"
|
|
||||||
#include "dependencies/memory.hpp"
|
|
||||||
#include "dependencies/string_ops.hpp"
|
|
||||||
#include "dependencies/printing.hpp"
|
|
||||||
#include "dependencies/containers.hpp"
|
|
||||||
#include "dependencies/hashing.hpp"
|
|
||||||
#include "dependencies/strings.hpp"
|
|
||||||
#include "dependencies/filesystem.hpp"
|
|
||||||
#include "dependencies/timing.hpp"
|
|
||||||
#include "dependencies/parsing.hpp"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -31,6 +19,16 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using LogFailType = ssize(*)(char const*, ...);
|
||||||
|
|
||||||
|
// By default this library will either crash or exit if an error is detected while generating codes.
|
||||||
|
// Even if set to not use GEN_FATAL, GEN_FATAL will still be used for memory failures as the library is unusable when they occur.
|
||||||
|
#ifdef GEN_DONT_USE_FATAL
|
||||||
|
#define log_failure log_fmt
|
||||||
|
#else
|
||||||
|
#define log_failure GEN_FATAL
|
||||||
|
#endif
|
||||||
|
|
||||||
enum AccessSpec : u32
|
enum AccessSpec : u32
|
||||||
{
|
{
|
||||||
AccessSpec_Default,
|
AccessSpec_Default,
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
#ifdef INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
|
# include "dependencies/platform.hpp"
|
||||||
|
# include "dependencies/macros.hpp"
|
||||||
# include "basic_types.hpp"
|
# include "basic_types.hpp"
|
||||||
|
# include "macros.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma region Debug
|
#pragma region Debug
|
||||||
|
@ -187,7 +187,7 @@ struct FileContents
|
|||||||
{
|
{
|
||||||
AllocatorInfo allocator;
|
AllocatorInfo allocator;
|
||||||
void* data;
|
void* data;
|
||||||
ssize size;
|
ssize size;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr b32 file_zero_terminate = true;
|
constexpr b32 file_zero_terminate = true;
|
||||||
|
@ -198,16 +198,21 @@
|
|||||||
#ifndef forceinline
|
#ifndef forceinline
|
||||||
# if GEN_COMPILER_MSVC
|
# if GEN_COMPILER_MSVC
|
||||||
# define forceinline __forceinline
|
# define forceinline __forceinline
|
||||||
|
# define neverinline __declspec( noinline )
|
||||||
# elif GEN_COMPILER_GCC
|
# elif GEN_COMPILER_GCC
|
||||||
# define forceinline inline __attribute__((__always_inline__))
|
# define forceinline inline __attribute__((__always_inline__))
|
||||||
|
# define neverinline __attribute__( ( __noinline__ ) )
|
||||||
# elif GEN_COMPILER_CLANG
|
# elif GEN_COMPILER_CLANG
|
||||||
# if __has_attribute(__always_inline__)
|
# if __has_attribute(__always_inline__)
|
||||||
# define forceinline inline __attribute__((__always_inline__))
|
# define forceinline inline __attribute__((__always_inline__))
|
||||||
|
# define neverinline __attribute__( ( __noinline__ ) )
|
||||||
# else
|
# else
|
||||||
# define forceinline
|
# define forceinline
|
||||||
|
# define neverinline
|
||||||
# endif
|
# endif
|
||||||
# else
|
# else
|
||||||
# define forceinline
|
# define forceinline
|
||||||
|
# define neverinline
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -298,20 +303,10 @@
|
|||||||
# define GEN_PARAM_DEFAULT
|
# define GEN_PARAM_DEFAULT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef struct_init
|
#if GEN_COMPILER_CPP
|
||||||
# if GEN_COMPILER_CPP
|
#define struct_init(type, value) {value}
|
||||||
# define struct_init(type, value) value
|
#else
|
||||||
# else
|
#define struct_init(type, value) {value}
|
||||||
# define struct_init(type, value) (type) value
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef struct_zero
|
|
||||||
# if GEN_COMPILER_CPP
|
|
||||||
# define struct_zero(type) {}
|
|
||||||
# else
|
|
||||||
# define struct_zero(type) {0}
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -324,12 +319,4 @@
|
|||||||
# define GEN_OPITMIZE_MAPPINGS_END
|
# define GEN_OPITMIZE_MAPPINGS_END
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef get_optional
|
|
||||||
# if GEN_COMPILER_C
|
|
||||||
# define get_optional(opt) opt ? *opt : (typeof(*opt)){0}
|
|
||||||
# else
|
|
||||||
# define get_optional(opt) opt
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#pragma endregion Macros
|
#pragma endregion Macros
|
||||||
|
@ -134,6 +134,12 @@ GEN_API void* heap_allocator_proc( void* allocator_data, AllocType type, ssize s
|
|||||||
//! The heap allocator backed by operating system's memory manager.
|
//! The heap allocator backed by operating system's memory manager.
|
||||||
constexpr AllocatorInfo heap( void ) { AllocatorInfo allocator = { heap_allocator_proc, nullptr }; return allocator; }
|
constexpr AllocatorInfo heap( void ) { AllocatorInfo allocator = { heap_allocator_proc, nullptr }; return allocator; }
|
||||||
|
|
||||||
|
//! Helper to allocate memory using heap allocator.
|
||||||
|
#define malloc( sz ) alloc( heap(), sz )
|
||||||
|
|
||||||
|
//! Helper to free memory allocated by heap allocator.
|
||||||
|
#define mfree( ptr ) free( heap(), ptr )
|
||||||
|
|
||||||
struct VirtualMemory
|
struct VirtualMemory
|
||||||
{
|
{
|
||||||
void* data;
|
void* data;
|
||||||
@ -179,8 +185,6 @@ void arena_check (Arena* arena);
|
|||||||
void arena_free (Arena* arena);
|
void arena_free (Arena* arena);
|
||||||
ssize arena_size_remaining(Arena* arena, ssize alignment);
|
ssize arena_size_remaining(Arena* arena, ssize alignment);
|
||||||
|
|
||||||
// TODO(Ed): Add arena_pos, arena_pop, and arena_pop_to
|
|
||||||
|
|
||||||
struct Arena
|
struct Arena
|
||||||
{
|
{
|
||||||
AllocatorInfo Backing;
|
AllocatorInfo Backing;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#ifdef INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "string_ops.cpp"
|
# include "strbuilder_ops.cpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma region Printing
|
#pragma region Printing
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#ifdef INTELLISENSE_DIRECTIVES
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
# pragma once
|
# pragma once
|
||||||
# include "string_ops.hpp"
|
# include "strbuilder_ops.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma region Printing
|
#pragma region Printing
|
||||||
@ -26,4 +26,17 @@ GEN_API ssize c_str_fmt_file_va ( FileInfo* f, char const* fmt, va_list va );
|
|||||||
constexpr
|
constexpr
|
||||||
char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
|
char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
|
||||||
|
|
||||||
|
inline
|
||||||
|
ssize log_fmt(char const* fmt, ...)
|
||||||
|
{
|
||||||
|
ssize res;
|
||||||
|
va_list va;
|
||||||
|
|
||||||
|
va_start(va, fmt);
|
||||||
|
res = c_str_fmt_out_va(fmt, va);
|
||||||
|
va_end(va);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma endregion Printing
|
#pragma endregion Printing
|
||||||
|
@ -320,7 +320,7 @@ inline
|
|||||||
StrBuilder strbuilder_fmt_buf(AllocatorInfo allocator, char const* fmt, ...)
|
StrBuilder strbuilder_fmt_buf(AllocatorInfo allocator, char const* fmt, ...)
|
||||||
{
|
{
|
||||||
local_persist thread_local
|
local_persist thread_local
|
||||||
PrintF_Buffer buf = struct_zero(PrintF_Buffer);
|
PrintF_Buffer buf = struct_init(PrintF_Buffer, {0});
|
||||||
|
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start(va, fmt);
|
va_start(va, fmt);
|
||||||
|
@ -11,6 +11,9 @@
|
|||||||
#include "helpers/push_ignores.inline.hpp"
|
#include "helpers/push_ignores.inline.hpp"
|
||||||
#include "components/header_start.hpp"
|
#include "components/header_start.hpp"
|
||||||
|
|
||||||
|
// Has container defines pushed
|
||||||
|
#include "gen.dep.hpp"
|
||||||
|
|
||||||
GEN_NS_BEGIN
|
GEN_NS_BEGIN
|
||||||
|
|
||||||
#include "components/types.hpp"
|
#include "components/types.hpp"
|
||||||
|
@ -1159,8 +1159,6 @@ R"(#define <interface_name>( code ) _Generic( (code), \
|
|||||||
Str actual_name = { fn->Name.Ptr + prefix.Len, fn->Name.Len - prefix.Len };
|
Str actual_name = { fn->Name.Ptr + prefix.Len, fn->Name.Len - prefix.Len };
|
||||||
Str new_name = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "def__%S", actual_name ).to_str();
|
Str new_name = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "def__%S", actual_name ).to_str();
|
||||||
|
|
||||||
opt_param->ValueType->Specs = def_specifier(Spec_Ptr);
|
|
||||||
|
|
||||||
// Resolve define's arguments
|
// Resolve define's arguments
|
||||||
b32 has_args = fn->Params->NumEntries > 1;
|
b32 has_args = fn->Params->NumEntries > 1;
|
||||||
StrBuilder params_str = StrBuilder::make_reserve(_ctx->Allocator_Temp, 32);
|
StrBuilder params_str = StrBuilder::make_reserve(_ctx->Allocator_Temp, 32);
|
||||||
@ -1174,10 +1172,10 @@ R"(#define <interface_name>( code ) _Generic( (code), \
|
|||||||
}
|
}
|
||||||
char const* tmpl_fn_macro = nullptr;
|
char const* tmpl_fn_macro = nullptr;
|
||||||
if (params_str.length() > 0 ) {
|
if (params_str.length() > 0 ) {
|
||||||
tmpl_fn_macro= "#define <def_name>( <params> ... ) <def__name>( <params> & (<opts_type>) { __VA_ARGS__ } )\n";
|
tmpl_fn_macro= "#define <def_name>( <params> ... ) <def__name>( <params> (<opts_type>) { __VA_ARGS__ } )\n";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tmpl_fn_macro= "#define <def_name>( ... ) <def__name>( & (<opts_type>) { __VA_ARGS__ } )\n";
|
tmpl_fn_macro= "#define <def_name>( ... ) <def__name>( (<opts_type>) { __VA_ARGS__ } )\n";
|
||||||
}
|
}
|
||||||
Code fn_macro = untyped_str(token_fmt(
|
Code fn_macro = untyped_str(token_fmt(
|
||||||
"def_name", fn->Name
|
"def_name", fn->Name
|
||||||
@ -1506,7 +1504,6 @@ R"(#define <interface_name>( code ) _Generic( (code), \
|
|||||||
Str actual_name = { fn->Name.Ptr + prefix.Len, fn->Name.Len - prefix.Len };
|
Str actual_name = { fn->Name.Ptr + prefix.Len, fn->Name.Len - prefix.Len };
|
||||||
Str new_name = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "def__%S", actual_name ).to_str();
|
Str new_name = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "def__%S", actual_name ).to_str();
|
||||||
fn->Name = cache_str(new_name);
|
fn->Name = cache_str(new_name);
|
||||||
opt_param->ValueType->Specs = def_specifier(Spec_Ptr);
|
|
||||||
}
|
}
|
||||||
src_upfront.append(fn);
|
src_upfront.append(fn);
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,6 @@ word enum_underlying, gen_enum_underlying
|
|||||||
word nullptr, gen_nullptr
|
word nullptr, gen_nullptr
|
||||||
word struct_init, gen_struct_init
|
word struct_init, gen_struct_init
|
||||||
word hash, gen_hash
|
word hash, gen_hash
|
||||||
word txt, gen_txt
|
|
||||||
|
|
||||||
// Basic Types
|
// Basic Types
|
||||||
|
|
||||||
@ -411,8 +410,6 @@ namespace var_, gen_var_
|
|||||||
|
|
||||||
word _ctx, gen__ctx
|
word _ctx, gen__ctx
|
||||||
|
|
||||||
word get_context, gen_get_context
|
|
||||||
|
|
||||||
word init, gen_init
|
word init, gen_init
|
||||||
word deinit, gen_deinit
|
word deinit, gen_deinit
|
||||||
word reset, gen_reset
|
word reset, gen_reset
|
||||||
@ -535,7 +532,7 @@ namespace Lexer_, gen_Lexer_
|
|||||||
word LexContext, gen_LexContext
|
word LexContext, gen_LexContext
|
||||||
word lex, gen_lex
|
word lex, gen_lex
|
||||||
|
|
||||||
word ParseStackNode, gen_ParseStackNode
|
word StackNode, gen_StackNode
|
||||||
word ParseContext, gen_ParseContext
|
word ParseContext, gen_ParseContext
|
||||||
|
|
||||||
// namespace parse_, gen_parse_
|
// namespace parse_, gen_parse_
|
||||||
|
@ -404,7 +404,7 @@ if ( $vendor -match "msvc" )
|
|||||||
$flag_optimize_intrinsics = '/Oi'
|
$flag_optimize_intrinsics = '/Oi'
|
||||||
$flag_optimized_debug_forceinline = '/d2Obforceinline'
|
$flag_optimized_debug_forceinline = '/d2Obforceinline'
|
||||||
$flag_optimized_debug = '/Zo'
|
$flag_optimized_debug = '/Zo'
|
||||||
# $flag_
|
$flag_
|
||||||
# $flag_out_name = '/OUT:'
|
# $flag_out_name = '/OUT:'
|
||||||
$flag_path_interm = '/Fo'
|
$flag_path_interm = '/Fo'
|
||||||
$flag_path_debug = '/Fd'
|
$flag_path_debug = '/Fd'
|
||||||
|
Reference in New Issue
Block a user