36 Commits

Author SHA1 Message Date
Ed_
685bba36d5 .gitignore/ai 2025-04-23 19:52:27 -04:00
Ed_
346e8e3305 fixes for CodeSpecifiers cpp mappings 2025-04-02 21:12:31 -04:00
Ed_
bfc754e66c progress 2025-03-19 13:01:51 -04:00
Ed_
84f4fc5ae9 lexer/parser revamp progress: got c11 ver compiling (synchup before continuation) 2025-03-19 12:09:07 -04:00
Ed_
ad5cb6597b progress on parser and lexer revamp 2025-03-19 11:48:40 -04:00
Ed_
1c7dd4ab32 WIP Broken: Working towards major changes to lexer
Lexer tokens now tracked using TokenSlice. ParserContext as the id for current token during traversal.
Last progress on errors needs updates to interface.parsing.cpp
Not adding message support yet as that will need to revamped with the logging, right now just focused on getting both lexer on parser to use proper info data structures.
Thinking of separating ParseContext from the general lib Context, plan is to just have the parser context have its allocator and other references it needs.
So there will seem to be redundant parameter passing to some procedures for now.
The big endgoal of this other than the parser's compression is the ability to support mult-threading.
Immediate concern other than making sure everything necessary is only within ParseContext, etc is things related to logging, or otherwise that is not thread dependent.
Those can get guarded but I don't have full intuition on what will have that (most likely the library's provided allocator/s as well will need guards introduced).
I'll concern myself more with charting those out once things are at least lifted properly. Worst case a trivial situation can be achived by the user by just abusing multiple contextes/allocators/etc as we already have in place.
2025-03-18 03:26:14 -04:00
Ed_
1e7fdcec16 preparing to revamp lexer 2025-03-17 01:20:56 -04:00
Ed_
2ed36506b1 progress on modularizing parser paths 2025-03-17 01:09:46 -04:00
Ed_
790087aa3c progress on modularizing parser paths 2025-03-16 23:13:46 -04:00
Ed_
441a46daaa changing to just pass lib Context instead of ParseContext.
If I want to make it more granular I can later.
2025-02-19 15:48:56 -05:00
Ed_
26623075ad started to work on modularizing parser code paths 2025-02-19 12:10:11 -05:00
Ed_
7ea90ef349 intellisense still broken... 2025-02-19 11:22:00 -05:00
Ed_
6d531fdf97 Fixing intellisense 2025-02-19 11:08:24 -05:00
Ed_
3b81eea688 Doing some initial prep for parser overhaul 2025-02-19 10:50:55 -05:00
Ed_
844d431e1c Setup Context's logger and fallback. (Not yet used in implementation). 2025-02-19 10:50:36 -05:00
Ed_
727b54c341 Added CodeSpecifiers::index_of for cpp, fix token bug with () operator in parse_operator_after_ret_type 2025-02-15 21:22:33 -05:00
Ed_
ef72d27f3e made optionals for c11 actually work... 2025-02-11 19:24:42 -05:00
Ed_
75b1d42cca changes based off of metadesk genc_c11 2025-02-11 18:59:09 -05:00
Ed_
878bc4c8ae Merge pull request #72 from Ed94/dev
Changes involved with getting gencpp-odin setup
2025-02-04 22:43:18 -05:00
Ed_
ec8dd1e9cd missing delete specifier (gen_unreal_engine) 2025-02-04 22:37:28 -05:00
Ed_
c0ea2ce3ff fix for edge case (running out of tokens while parsing assignment expression 2025-02-04 22:05:24 -05:00
Ed_
b5652a4dad if on c11 segmented (parsing spec defines were mising!) 2025-02-04 21:42:01 -05:00
Ed_
dda70fce36 can't use static globals on static libs 2025-02-04 21:23:51 -05:00
Ed_
3bce2e9b8a rename GEN_INTELLISENSE_DIRECTIVES -> INTELLISENSE_DIRECTIVES 2025-02-04 18:33:07 -05:00
Ed_
f3f8f2fff2 update readme with related repos 2025-02-04 17:24:03 -05:00
Ed_
c600a3e0dc add missing defines 2025-02-04 17:04:33 -05:00
Ed_
372cda734e fixes for generated c11 segemented 2025-02-04 16:17:29 -05:00
Ed_
6481313969 Various fixes and adjustments
* moved constants to components/constants.hpp (adjsuted generators accordingly)
* parser accepts include & defineas parameter identifiers (will add more flags for keywords when necessary
2025-02-04 15:35:28 -05:00
Ed_
5c17983a73 move more strbuilder functions to cpp 2025-02-04 14:53:26 -05:00
Ed_
b6d95e8d70 move strbuilder_make_space_for to strings.cpp (not inlined) 2025-02-04 14:17:15 -05:00
Ed_
6f2d81434e fixes 2025-02-04 12:57:42 -05:00
Ed_
b8695a33db added missing asserts to serialization functions 2025-02-04 11:50:15 -05:00
Ed_
1f958e121c more adjustments based on odin binding drafting 2025-02-04 01:57:23 -05:00
Ed_
e457191f5d moved seiralization inlines to inlines.hpp, more adjustments 2025-02-03 18:53:35 -05:00
Ed_
0d8f30b25c adjustments based on odin bindings drafting 2025-02-03 11:26:03 -05:00
Ed_
d08efcb5ef Corrections while implementing odin bindings 2025-02-03 09:42:31 -05:00
73 changed files with 2345 additions and 1739 deletions

2
.gitignore vendored
View File

@ -44,3 +44,5 @@ test/c_library/gen
test/cpp_library/gen
!scripts/helpers/refactor.exe
ai/**

View File

@ -11,6 +11,14 @@ These build up a code AST to then serialize with a file builder, or can be trave
This code base attempts follow the [handmade philosophy](https://handmade.network/manifesto).
Its not meant to be a black box metaprogramming utility, it should be easy to integrate into a user's project domain.
## Langauge Bindings
* [gencpp-odin](https://github.com/Ed94/gencpp-odin): Bindings for the odin programming language.
## Utility Libraries
* [UnrealGencpp](https://github.com/Ed94/UnrealGencpp): Setup as a plugin to integrate into Unreal Engine or Unreal Projects.
## Documentation
* [docs - General](./docs/Readme.md): Overview and additional docs

View File

@ -191,7 +191,7 @@ These require the following to be handled to the equivalent extent as the other
4. [ast.cpp](./components/ast.cpp): Need to review
* `code_debug_str`
* `code_is_equal`
* `code_to_strbuilder_ptr`
* `code_to_strbuilder_ref`
* `code_validate_body`
5. [code_serialization.cpp](./components/code_serialization.cpp): Define serialization here.
6. [inlines.hpp](./components/inlines.hpp): Any inline definitions for the `struct Code<Name>` are defined here.

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# include "builder.hpp"
#endif

View File

@ -1,9 +1,9 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "helpers/push_ignores.inline.hpp"
# include "components/header_start.hpp"
# include "components/types.hpp"
# include "components/gen/ecode.hpp"
# include "components/gen/ecodetypes.hpp"
# include "components/gen/eoperator.hpp"
# include "components/gen/especifier.hpp"
# include "components/ast.hpp"

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "helpers/push_ignores.inline.hpp"
# include "components/header_start.hpp"

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# include "scanner.hpp"
#endif
@ -24,7 +24,7 @@ Code scan_file( char const* path )
file_read( & file, str, fsize );
strbuilder_get_header(str)->Length = fsize;
// Skip GEN_INTELLISENSE_DIRECTIVES preprocessor blocks
// Skip INTELLISENSE_DIRECTIVES preprocessor blocks
// Its designed so that the directive should be the first thing in the file.
// Anything that comes before it will also be omitted.
{
@ -33,7 +33,7 @@ Code scan_file( char const* path )
#define move_fwd() do { ++ scanner; -- left; } while (0)
const Str directive_start = txt( "ifdef" );
const Str directive_end = txt( "endif" );
const Str def_intellisense = txt("GEN_INTELLISENSE_DIRECTIVES" );
const Str def_intellisense = txt("INTELLISENSE_DIRECTIVES" );
bool found_directive = false;
char const* scanner = (char const*)str;

View File

@ -1,9 +1,9 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "helpers/push_ignores.inline.hpp"
# include "components/header_start.hpp"
# include "components/types.hpp"
# include "components/gen/ecode.hpp"
# include "components/gen/ecodetypes.hpp"
# include "components/gen/eoperator.hpp"
# include "components/gen/especifier.hpp"
# include "components/ast.hpp"

View File

@ -30,7 +30,7 @@ int gen_main()
gen::init( & ctx);
CodeBody gen_component_header = def_global_body( args(
def_preprocess_cond( PreprocessCond_IfDef, txt("GEN_INTELLISENSE_DIRECTIVES") ),
def_preprocess_cond( PreprocessCond_IfDef, txt("INTELLISENSE_DIRECTIVES") ),
pragma_once,
def_include(txt("components/types.hpp")),
preprocess_endif,

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "static_data.cpp"
#endif
@ -379,11 +379,11 @@ Code code_duplicate(Code self)
StrBuilder code_to_strbuilder(Code self)
{
StrBuilder result = strbuilder_make_str( _ctx->Allocator_Temp, txt("") );
code_to_strbuilder_ptr( self, & result );
code_to_strbuilder_ref( self, & result );
return result;
}
void code_to_strbuilder_ptr( Code self, StrBuilder* result )
void code_to_strbuilder_ref( Code self, StrBuilder* result )
{
GEN_ASSERT(self != nullptr);
local_persist thread_local

View File

@ -1,9 +1,6 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "types.hpp"
#include "gen/ecode.hpp"
#include "gen/eoperator.hpp"
#include "gen/especifier.hpp"
#include "parser_types.hpp"
#endif
/*
@ -193,6 +190,7 @@ typedef AST_Stmt_If* CodeStmt_If;
typedef AST_Stmt_For* CodeStmt_For;
typedef AST_Stmt_Goto* CodeStmt_Goto;
typedef AST_Stmt_Label* CodeStmt_Label;
typedef AST_Stmt_Lambda* CodeStmt_Lambda;
typedef AST_Stmt_Switch* CodeStmt_Switch;
typedef AST_Stmt_While* CodeStmt_While;
#else
@ -208,6 +206,7 @@ struct CodeStmt_If;
struct CodeStmt_For;
struct CodeStmt_Goto;
struct CodeStmt_Label;
struct CodeStmt_Lambda;
struct CodeStmt_Switch;
struct CodeStmt_While;
#endif
@ -239,18 +238,18 @@ template< class Type> forceinline Type tmpl_cast( Code self ) { return * rcast(
#pragma region Code C-Interface
GEN_API void code_append (Code code, Code other );
void code_append (Code code, Code other );
GEN_API Str code_debug_str (Code code);
GEN_API Code code_duplicate (Code code);
GEN_API Code* code_entry (Code code, u32 idx );
GEN_API bool code_has_entries (Code code);
GEN_API bool code_is_body (Code code);
Code* code_entry (Code code, u32 idx );
bool code_has_entries (Code code);
bool code_is_body (Code code);
GEN_API bool code_is_equal (Code code, Code other);
GEN_API bool code_is_valid (Code code);
GEN_API void code_set_global (Code code);
bool code_is_valid (Code code);
void code_set_global (Code code);
GEN_API StrBuilder code_to_strbuilder (Code self );
GEN_API void code_to_strbuilder_ptr(Code self, StrBuilder* result );
GEN_API Str code_type_str (Code self );
GEN_API void code_to_strbuilder_ref(Code self, StrBuilder* result );
Str code_type_str (Code self );
GEN_API bool code_validate_body (Code self );
#pragma endregion Code C-Interface
@ -287,7 +286,7 @@ struct Code
forceinline Code* entry(u32 idx) { return code_entry(* this, idx); }
forceinline bool has_entries() { return code_has_entries(* this); }
forceinline StrBuilder to_strbuilder() { return code_to_strbuilder(* this); }
forceinline void to_strbuilder(StrBuilder& result) { return code_to_strbuilder_ptr(* this, & result); }
forceinline void to_strbuilder(StrBuilder& result) { return code_to_strbuilder_ref(* this, & result); }
forceinline Str type_str() { return code_type_str(* this); }
forceinline bool validate_body() { return code_validate_body(*this); }
#endif
@ -399,12 +398,13 @@ struct AST
Code Value; // Parameter, Variable
};
union {
Code NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value )
Code NextVar; // Variable
Code SuffixSpecs; // Typename, Function (Thanks Unreal)
Code PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal)
};
};
StrCached Content; // Attributes, Comment, Execution, Include
TokenSlice ContentToks; // TODO(Ed): Use a token slice for content
struct {
Specifier ArrSpecs[AST_ArrSpecs_Cap]; // Specifiers
Code NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used.
@ -420,7 +420,7 @@ struct AST
Code Next;
Code Back;
};
Token* Token; // Reference to starting token, only available if it was derived from parsing.
Token* Token; // Reference to starting token, only available if it was derived from parsing. // TODO(Ed): Change this to a token slice.
Code Parent;
CodeType Type;
// CodeFlag CodeFlags;

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "code_types.hpp"
#endif
@ -227,7 +227,7 @@ struct AST_Enum
Code Parent;
CodeType Type;
ModuleFlag ModuleFlags;
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
char _PAD_UNUSED_[ sizeof(u32) ];
};
static_assert( sizeof(AST_Enum) == sizeof(AST), "ERROR: AST_Enum is not the same size as AST");
@ -738,8 +738,8 @@ static_assert( sizeof(AST_PreprocessCond) == sizeof(AST), "ERROR: AST_Preprocess
struct AST_Specifiers
{
Specifier ArrSpecs[ AST_ArrSpecs_Cap ];
StrCached Name;
CodeSpecifiers NextSpecs;
StrCached Name;
Code Prev;
Code Next;
Token* Tok;

View File

@ -1,23 +1,8 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "ast.cpp"
#endif
inline
StrBuilder attributes_to_strbuilder(CodeAttributes attributes) {
GEN_ASSERT(attributes);
char* raw = ccast(char*, str_duplicate( attributes->Content, _ctx->Allocator_Temp ).Ptr);
StrBuilder result = { raw };
return result;
}
inline
void attributes_to_strbuilder_ref(CodeAttributes attributes, StrBuilder* result) {
GEN_ASSERT(attributes);
GEN_ASSERT(result);
strbuilder_append_str(result, attributes->Content);
}
StrBuilder body_to_strbuilder(CodeBody body)
{
GEN_ASSERT(body);
@ -47,55 +32,27 @@ StrBuilder body_to_strbuilder(CodeBody body)
return result;
}
void body_to_strbuilder_ref( CodeBody body, StrBuilder* result )
{
GEN_ASSERT(body != nullptr);
GEN_ASSERT(result != nullptr);
Code curr = body->Front;
s32 left = body->NumEntries;
while ( left -- )
{
code_to_strbuilder_ptr(curr, result);
// strbuilder_append_fmt( result, "%SB", code_to_strbuilder(curr) );
++curr;
}
}
void body_to_strbuilder_export( CodeBody body, StrBuilder* result )
{
GEN_ASSERT(body != nullptr);
GEN_ASSERT(result != nullptr);
strbuilder_append_fmt( result, "export\n{\n" );
Code curr = cast(Code, body);
Code curr = body->Front;
s32 left = body->NumEntries;
while ( left-- )
{
code_to_strbuilder_ptr(curr, result);
code_to_strbuilder_ref(curr, result);
// strbuilder_append_fmt( result, "%SB", code_to_strbuilder(curr) );
++curr;
curr = curr->Next;
}
strbuilder_append_fmt( result, "};\n" );
}
inline
StrBuilder comment_to_strbuilder(CodeComment comment) {
GEN_ASSERT(comment);
char* raw = ccast(char*, str_duplicate( comment->Content, _ctx->Allocator_Temp ).Ptr);
StrBuilder result = { raw };
return result;
}
inline
void comment_to_strbuilder_ref(CodeComment comment, StrBuilder* result) {
GEN_ASSERT(comment);
GEN_ASSERT(result);
strbuilder_append_str(result, comment->Content);
}
StrBuilder constructor_to_strbuilder(CodeConstructor self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
switch (self->Type)
{
@ -111,6 +68,8 @@ StrBuilder constructor_to_strbuilder(CodeConstructor self)
void constructor_to_strbuilder_def(CodeConstructor self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
Code ClassStructParent = self->Parent->Parent;
if (ClassStructParent) {
strbuilder_append_str( result, ClassStructParent->Name );
@ -135,6 +94,8 @@ void constructor_to_strbuilder_def(CodeConstructor self, StrBuilder* result )
void constructor_to_strbuilder_fwd(CodeConstructor self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
Code ClassStructParent = self->Parent->Parent;
if (ClassStructParent) {
strbuilder_append_str( result, ClassStructParent->Name );
@ -159,6 +120,7 @@ void constructor_to_strbuilder_fwd(CodeConstructor self, StrBuilder* result )
StrBuilder class_to_strbuilder( CodeClass self )
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
switch ( self->Type )
{
@ -175,6 +137,7 @@ StrBuilder class_to_strbuilder( CodeClass self )
void class_to_strbuilder_def( CodeClass self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -189,7 +152,7 @@ void class_to_strbuilder_def( CodeClass self, StrBuilder* result )
if ( self->Name.Len )
strbuilder_append_str( result, self->Name );
if (self->Specs && specifiers_has(self->Specs, Spec_Final) > -1)
if (self->Specs && specifiers_has(self->Specs, Spec_Final))
strbuilder_append_str(result, txt(" final"));
if ( self->ParentType )
@ -222,6 +185,7 @@ void class_to_strbuilder_def( CodeClass self, StrBuilder* result )
void class_to_strbuilder_fwd( CodeClass self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -241,13 +205,6 @@ void class_to_strbuilder_fwd( CodeClass self, StrBuilder* result )
}
}
StrBuilder define_to_strbuilder(CodeDefine define)
{
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
define_to_strbuilder_ref(define, & result);
return result;
}
void define_to_strbuilder_ref(CodeDefine define, StrBuilder* result )
{
GEN_ASSERT(define);
@ -262,14 +219,6 @@ void define_to_strbuilder_ref(CodeDefine define, StrBuilder* result )
}
}
StrBuilder define_params_to_strbuilder(CodeDefineParams params)
{
GEN_ASSERT(params);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
define_params_to_strbuilder_ref( params, & result );
return result;
}
void define_params_to_strbuilder_ref(CodeDefineParams self, StrBuilder* result)
{
GEN_ASSERT(self);
@ -289,6 +238,7 @@ void define_params_to_strbuilder_ref(CodeDefineParams self, StrBuilder* result)
StrBuilder destructor_to_strbuilder(CodeDestructor self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
switch ( self->Type )
{
@ -304,6 +254,8 @@ StrBuilder destructor_to_strbuilder(CodeDestructor self)
void destructor_to_strbuilder_def(CodeDestructor self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( self->Name.Len )
{
strbuilder_append_fmt( result, "%S()", self->Name );
@ -323,6 +275,8 @@ void destructor_to_strbuilder_def(CodeDestructor self, StrBuilder* result )
void destructor_to_strbuilder_fwd(CodeDestructor self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( self->Specs )
{
if ( specifiers_has(self->Specs, Spec_Virtual ) )
@ -346,6 +300,7 @@ void destructor_to_strbuilder_fwd(CodeDestructor self, StrBuilder* result )
StrBuilder enum_to_strbuilder(CodeEnum self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
switch ( self->Type )
{
@ -367,6 +322,8 @@ StrBuilder enum_to_strbuilder(CodeEnum self)
void enum_to_strbuilder_def(CodeEnum self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -400,6 +357,8 @@ void enum_to_strbuilder_def(CodeEnum self, StrBuilder* result )
void enum_to_strbuilder_fwd(CodeEnum self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -427,6 +386,8 @@ void enum_to_strbuilder_fwd(CodeEnum self, StrBuilder* result )
void enum_to_strbuilder_class_def(CodeEnum self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -459,6 +420,8 @@ void enum_to_strbuilder_class_def(CodeEnum self, StrBuilder* result )
void enum_to_strbuilder_class_fwd(CodeEnum self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -478,56 +441,9 @@ void enum_to_strbuilder_class_fwd(CodeEnum self, StrBuilder* result )
}
}
StrBuilder exec_to_strbuilder(CodeExec exec)
{
GEN_ASSERT(exec);
char* raw = ccast(char*, str_duplicate( exec->Content, _ctx->Allocator_Temp ).Ptr);
StrBuilder result = { raw };
return result;
}
void extern_to_strbuilder(CodeExtern self, StrBuilder* result )
{
if ( self->Body )
strbuilder_append_fmt( result, "extern \"%S\"\n{\n%SB\n}\n", self->Name, body_to_strbuilder(self->Body) );
else
strbuilder_append_fmt( result, "extern \"%S\"\n{}\n", self->Name );
}
StrBuilder include_to_strbuilder(CodeInclude include)
{
return strbuilder_fmt_buf( _ctx->Allocator_Temp, "#include %S\n", include->Content );
}
void include_to_strbuilder_ref( CodeInclude include, StrBuilder* result )
{
strbuilder_append_fmt( result, "#include %S\n", include->Content );
}
StrBuilder friend_to_strbuilder(CodeFriend self)
{
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 256 );
friend_to_strbuilder_ref( self, & result );
return result;
}
void friend_to_strbuilder_ref(CodeFriend self, StrBuilder* result )
{
strbuilder_append_fmt( result, "friend %SB", code_to_strbuilder(self->Declaration) );
if ( self->Declaration->Type != CT_Function && self->Declaration->Type != CT_Operator && (* result)[ strbuilder_length(* result) - 1 ] != ';' )
{
strbuilder_append_str( result, txt(";") );
}
if ( self->InlineCmt )
strbuilder_append_fmt( result, " %S", self->InlineCmt->Content );
else
strbuilder_append_str( result, txt("\n"));
}
StrBuilder fn_to_strbuilder(CodeFn self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
switch ( self->Type )
{
@ -543,6 +459,8 @@ StrBuilder fn_to_strbuilder(CodeFn self)
void fn_to_strbuilder_def(CodeFn self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export") );
@ -600,6 +518,8 @@ void fn_to_strbuilder_def(CodeFn self, StrBuilder* result )
void fn_to_strbuilder_fwd(CodeFn self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -649,9 +569,9 @@ void fn_to_strbuilder_fwd(CodeFn self, StrBuilder* result )
}
}
if ( specifiers_has(self->Specs, Spec_Pure ) >= 0 )
if ( specifiers_has(self->Specs, Spec_Pure ) )
strbuilder_append_str( result, txt(" = 0") );
else if ( specifiers_has(self->Specs, Spec_Delete ) >= 0 )
else if ( specifiers_has(self->Specs, Spec_Delete ) )
strbuilder_append_str( result, txt(" = delete") );
}
@ -668,15 +588,10 @@ void fn_to_strbuilder_fwd(CodeFn self, StrBuilder* result )
strbuilder_append_str( result, txt(";\n") );
}
StrBuilder module_to_strbuilder(CodeModule self)
{
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 64 );
module_to_strbuilder_ref( self, & result );
return result;
}
void module_to_strbuilder_ref(CodeModule self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if (((scast(u32, ModuleFlag_Export) & scast(u32, self->ModuleFlags)) == scast(u32, ModuleFlag_Export)))
strbuilder_append_str( result, txt("export "));
@ -686,23 +601,9 @@ void module_to_strbuilder_ref(CodeModule self, StrBuilder* result )
strbuilder_append_fmt( result, "%S;\n", self->Name );
}
StrBuilder namespace_to_strbuilder(CodeNS self)
{
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
namespace_to_strbuilder_ref( self, & result );
return result;
}
void namespace_to_strbuilder_ref(CodeNS self, StrBuilder* result )
{
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
strbuilder_append_fmt( result, "namespace %S\n{\n%SB\n}\n", self->Name, body_to_strbuilder(self->Body) );
}
StrBuilder code_op_to_strbuilder(CodeOperator self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
switch ( self->Type )
{
@ -720,6 +621,8 @@ StrBuilder code_op_to_strbuilder(CodeOperator self)
void code_op_to_strbuilder_def(CodeOperator self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -774,6 +677,8 @@ void code_op_to_strbuilder_def(CodeOperator self, StrBuilder* result )
void code_op_to_strbuilder_fwd(CodeOperator self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -825,6 +730,7 @@ void code_op_to_strbuilder_fwd(CodeOperator self, StrBuilder* result )
StrBuilder opcast_to_strbuilder(CodeOpCast self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
switch ( self->Type )
{
@ -840,6 +746,8 @@ StrBuilder opcast_to_strbuilder(CodeOpCast self)
void opcast_to_strbuilder_def(CodeOpCast self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( self->Specs )
{
for ( Specifier* spec = begin_CodeSpecifiers(self->Specs); spec != end_CodeSpecifiers(self->Specs); spec = next_CodeSpecifiers(self->Specs, spec) )
@ -877,6 +785,8 @@ void opcast_to_strbuilder_def(CodeOpCast self, StrBuilder* result )
void opcast_to_strbuilder_fwd(CodeOpCast self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( self->Specs )
{
for ( Specifier* spec = begin_CodeSpecifiers(self->Specs); spec != end_CodeSpecifiers(self->Specs); spec = next_CodeSpecifiers(self->Specs, spec) )
@ -912,14 +822,6 @@ void opcast_to_strbuilder_fwd(CodeOpCast self, StrBuilder* result )
strbuilder_append_fmt( result, "operator %SB();\n", typename_to_strbuilder(self->ValueType) );
}
StrBuilder params_to_strbuilder(CodeParams self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
params_to_strbuilder_ref( self, & result );
return result;
}
void params_to_strbuilder_ref( CodeParams self, StrBuilder* result )
{
GEN_ASSERT(self);
@ -987,62 +889,6 @@ StrBuilder preprocess_to_strbuilder(CodePreprocessCond self)
return result;
}
void preprocess_to_strbuilder_if(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
strbuilder_append_fmt( result, "#if %S", cond->Content );
}
void preprocess_to_strbuilder_ifdef(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
strbuilder_append_fmt( result, "#ifdef %S\n", cond->Content );
}
void preprocess_to_strbuilder_ifndef(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
strbuilder_append_fmt( result, "#ifndef %S", cond->Content );
}
void preprocess_to_strbuilder_elif(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
strbuilder_append_fmt( result, "#elif %S\n", cond->Content );
}
void preprocess_to_strbuilder_else(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
strbuilder_append_str( result, txt("#else\n") );
}
void preprocess_to_strbuilder_endif(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
strbuilder_append_str( result, txt("#endif\n") );
}
StrBuilder pragma_to_strbuilder(CodePragma self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 256 );
pragma_to_strbuilder_ref( self, & result );
return result;
}
void pragma_to_strbuilder_ref(CodePragma self, StrBuilder* result )
{
strbuilder_append_fmt( result, "#pragma %S\n", self->Content );
}
StrBuilder specifiers_to_strbuilder(CodeSpecifiers self)
{
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 64 );
specifiers_to_strbuilder_ref( self, & result );
return result;
}
void specifiers_to_strbuilder_ref( CodeSpecifiers self, StrBuilder* result )
{
GEN_ASSERT(self);
@ -1155,14 +1001,6 @@ void struct_to_strbuilder_fwd( CodeStruct self, StrBuilder* result )
}
}
StrBuilder template_to_strbuilder(CodeTemplate self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 1024 );
template_to_strbuilder_ref( self, & result );
return result;
}
void template_to_strbuilder_ref(CodeTemplate self, StrBuilder* result )
{
GEN_ASSERT(self);
@ -1176,15 +1014,10 @@ void template_to_strbuilder_ref(CodeTemplate self, StrBuilder* result )
strbuilder_append_fmt( result, "template<>\n%SB", code_to_strbuilder(self->Declaration) );
}
StrBuilder typedef_to_strbuilder(CodeTypedef self)
{
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
typedef_to_strbuilder_ref( self, & result );
return result;
}
void typedef_to_strbuilder_ref(CodeTypedef self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -1218,15 +1051,10 @@ void typedef_to_strbuilder_ref(CodeTypedef self, StrBuilder* result )
strbuilder_append_str( result, txt("\n"));
}
StrBuilder typename_to_strbuilder(CodeTypename self)
{
StrBuilder result = strbuilder_make_str( _ctx->Allocator_Temp, txt("") );
typename_to_strbuilder_ref( self, & result );
return result;
}
void typename_to_strbuilder_ref(CodeTypename self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
#if defined(GEN_USE_NEW_TYPENAME_PARSING)
if ( self->ReturnType && self->Params )
{
@ -1283,6 +1111,7 @@ void typename_to_strbuilder_ref(CodeTypename self, StrBuilder* result )
StrBuilder union_to_strbuilder(CodeUnion self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
switch ( self->Type )
{
@ -1298,6 +1127,8 @@ StrBuilder union_to_strbuilder(CodeUnion self)
void union_to_strbuilder_def(CodeUnion self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
@ -1346,22 +1177,6 @@ void union_to_strbuilder_fwd(CodeUnion self, StrBuilder* result )
strbuilder_append_str( result, txt(";\n"));
}
StrBuilder using_to_strbuilder(CodeUsing self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
switch ( self->Type )
{
case CT_Using:
using_to_strbuilder_ref( self, & result );
break;
case CT_Using_Namespace:
using_to_strbuilder_ns( self, & result );
break;
}
return result;
}
void using_to_strbuilder_ref(CodeUsing self, StrBuilder* result )
{
GEN_ASSERT(self);
@ -1399,26 +1214,6 @@ void using_to_strbuilder_ref(CodeUsing self, StrBuilder* result )
strbuilder_append_str( result, txt("\n"));
}
inline
void using_to_strbuilder_ns(CodeUsing self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( self->InlineCmt )
strbuilder_append_fmt( result, "using namespace $SC; %S", self->Name, self->InlineCmt->Content );
else
strbuilder_append_fmt( result, "using namespace %S;\n", self->Name );
}
inline
StrBuilder var_to_strbuilder(CodeVar self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 256 );
var_to_strbuilder_ref( self, & result );
return result;
}
neverinline
void var_to_strbuilder_ref(CodeVar self, StrBuilder* result )
{

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "ast.hpp"
#endif
@ -20,58 +20,59 @@
GEN_API void body_append ( CodeBody body, Code other );
GEN_API void body_append_body ( CodeBody body, CodeBody other );
GEN_API StrBuilder body_to_strbuilder ( CodeBody body );
GEN_API void body_to_strbuilder_ref ( CodeBody body, StrBuilder* result );
void body_to_strbuilder_ref ( CodeBody body, StrBuilder* result );
GEN_API void body_to_strbuilder_export( CodeBody body, StrBuilder* result );
GEN_API Code begin_CodeBody( CodeBody body);
GEN_API Code end_CodeBody ( CodeBody body );
GEN_API Code next_CodeBody ( CodeBody body, Code entry_iter );
Code begin_CodeBody( CodeBody body);
Code end_CodeBody ( CodeBody body );
Code next_CodeBody ( CodeBody body, Code entry_iter );
GEN_API void class_add_interface ( CodeClass self, CodeTypename interface );
void class_add_interface ( CodeClass self, CodeTypename interface );
GEN_API StrBuilder class_to_strbuilder ( CodeClass self );
GEN_API void class_to_strbuilder_def( CodeClass self, StrBuilder* result );
GEN_API void class_to_strbuilder_fwd( CodeClass self, StrBuilder* result );
GEN_API void define_params_append (CodeDefineParams appendee, CodeDefineParams other );
GEN_API CodeDefineParams define_params_get (CodeDefineParams params, s32 idx);
GEN_API bool define_params_has_entries (CodeDefineParams params );
GEN_API StrBuilder define_params_to_strbuilder (CodeDefineParams params );
void define_params_append (CodeDefineParams appendee, CodeDefineParams other );
CodeDefineParams define_params_get (CodeDefineParams params, s32 idx);
bool define_params_has_entries (CodeDefineParams params );
StrBuilder define_params_to_strbuilder (CodeDefineParams params );
GEN_API void define_params_to_strbuilder_ref(CodeDefineParams params, StrBuilder* result );
GEN_API CodeDefineParams begin_CodeDefineParams(CodeDefineParams params);
GEN_API CodeDefineParams end_CodeDefineParams (CodeDefineParams params);
GEN_API CodeDefineParams next_CodeDefineParams (CodeDefineParams params, CodeDefineParams entry_iter);
CodeDefineParams begin_CodeDefineParams(CodeDefineParams params);
CodeDefineParams end_CodeDefineParams (CodeDefineParams params);
CodeDefineParams next_CodeDefineParams (CodeDefineParams params, CodeDefineParams entry_iter);
GEN_API void params_append (CodeParams appendee, CodeParams other );
GEN_API CodeParams params_get (CodeParams params, s32 idx);
GEN_API bool params_has_entries (CodeParams params );
GEN_API StrBuilder params_to_strbuilder (CodeParams params );
void params_append (CodeParams appendee, CodeParams other );
CodeParams params_get (CodeParams params, s32 idx);
bool params_has_entries (CodeParams params );
StrBuilder params_to_strbuilder (CodeParams params );
GEN_API void params_to_strbuilder_ref(CodeParams params, StrBuilder* result );
GEN_API CodeParams begin_CodeParams(CodeParams params);
GEN_API CodeParams end_CodeParams (CodeParams params);
GEN_API CodeParams next_CodeParams (CodeParams params, CodeParams entry_iter);
CodeParams begin_CodeParams(CodeParams params);
CodeParams end_CodeParams (CodeParams params);
CodeParams next_CodeParams (CodeParams params, CodeParams entry_iter);
GEN_API bool specifiers_append (CodeSpecifiers specifiers, Specifier spec);
GEN_API s32 specifiers_has (CodeSpecifiers specifiers, Specifier spec);
GEN_API s32 specifiers_remove (CodeSpecifiers specifiers, Specifier to_remove );
GEN_API StrBuilder specifiers_to_strbuilder (CodeSpecifiers specifiers);
bool specifiers_append (CodeSpecifiers specifiers, Specifier spec);
bool specifiers_has (CodeSpecifiers specifiers, Specifier spec);
s32 specifiers_index_of (CodeSpecifiers specifiers, Specifier spec);
s32 specifiers_remove (CodeSpecifiers specifiers, Specifier to_remove );
StrBuilder specifiers_to_strbuilder (CodeSpecifiers specifiers);
GEN_API void specifiers_to_strbuilder_ref(CodeSpecifiers specifiers, StrBuilder* result);
GEN_API Specifier* begin_CodeSpecifiers(CodeSpecifiers specifiers);
GEN_API Specifier* end_CodeSpecifiers (CodeSpecifiers specifiers);
GEN_API Specifier* next_CodeSpecifiers (CodeSpecifiers specifiers, Specifier* spec_iter);
Specifier* begin_CodeSpecifiers(CodeSpecifiers specifiers);
Specifier* end_CodeSpecifiers (CodeSpecifiers specifiers);
Specifier* next_CodeSpecifiers (CodeSpecifiers specifiers, Specifier* spec_iter);
GEN_API void struct_add_interface (CodeStruct self, CodeTypename interface);
void struct_add_interface (CodeStruct self, CodeTypename interface);
GEN_API StrBuilder struct_to_strbuilder (CodeStruct self);
GEN_API void struct_to_strbuilder_fwd(CodeStruct self, StrBuilder* result);
GEN_API void struct_to_strbuilder_def(CodeStruct self, StrBuilder* result);
GEN_API StrBuilder attributes_to_strbuilder (CodeAttributes attributes);
GEN_API void attributes_to_strbuilder_ref(CodeAttributes attributes, StrBuilder* result);
StrBuilder attributes_to_strbuilder (CodeAttributes attributes);
void attributes_to_strbuilder_ref(CodeAttributes attributes, StrBuilder* result);
GEN_API StrBuilder comment_to_strbuilder (CodeComment comment );
GEN_API void comment_to_strbuilder_ref(CodeComment comment, StrBuilder* result );
StrBuilder comment_to_strbuilder (CodeComment comment );
void comment_to_strbuilder_ref(CodeComment comment, StrBuilder* result );
GEN_API StrBuilder constructor_to_strbuilder (CodeConstructor constructor);
GEN_API void constructor_to_strbuilder_def(CodeConstructor constructor, StrBuilder* result );
@ -90,26 +91,26 @@ GEN_API void enum_to_strbuilder_fwd (CodeEnum self, StrBuilder* resul
GEN_API void enum_to_strbuilder_class_def(CodeEnum self, StrBuilder* result );
GEN_API void enum_to_strbuilder_class_fwd(CodeEnum self, StrBuilder* result );
GEN_API StrBuilder exec_to_strbuilder (CodeExec exec);
GEN_API void exec_to_strbuilder_ref(CodeExec exec, StrBuilder* result);
StrBuilder exec_to_strbuilder (CodeExec exec);
void exec_to_strbuilder_ref(CodeExec exec, StrBuilder* result);
GEN_API void extern_to_strbuilder(CodeExtern self, StrBuilder* result);
void extern_to_strbuilder(CodeExtern self, StrBuilder* result);
GEN_API StrBuilder include_to_strbuilder (CodeInclude self);
GEN_API void include_to_strbuilder_ref(CodeInclude self, StrBuilder* result);
StrBuilder include_to_strbuilder (CodeInclude self);
void include_to_strbuilder_ref(CodeInclude self, StrBuilder* result);
GEN_API StrBuilder friend_to_strbuilder (CodeFriend self);
GEN_API void friend_to_strbuilder_ref(CodeFriend self, StrBuilder* result);
StrBuilder friend_to_strbuilder (CodeFriend self);
void friend_to_strbuilder_ref(CodeFriend self, StrBuilder* result);
GEN_API StrBuilder fn_to_strbuilder (CodeFn self);
GEN_API void fn_to_strbuilder_def(CodeFn self, StrBuilder* result);
GEN_API void fn_to_strbuilder_fwd(CodeFn self, StrBuilder* result);
GEN_API StrBuilder module_to_strbuilder (CodeModule self);
StrBuilder module_to_strbuilder (CodeModule self);
GEN_API void module_to_strbuilder_ref(CodeModule self, StrBuilder* result);
GEN_API StrBuilder namespace_to_strbuilder (CodeNS self);
GEN_API void namespace_to_strbuilder_ref(CodeNS self, StrBuilder* result);
StrBuilder namespace_to_strbuilder (CodeNS self);
void namespace_to_strbuilder_ref(CodeNS self, StrBuilder* result);
GEN_API StrBuilder code_op_to_strbuilder (CodeOperator self);
GEN_API void code_op_to_strbuilder_fwd(CodeOperator self, StrBuilder* result );
@ -119,37 +120,39 @@ GEN_API StrBuilder opcast_to_strbuilder (CodeOpCast op_cast );
GEN_API void opcast_to_strbuilder_def(CodeOpCast op_cast, StrBuilder* result );
GEN_API void opcast_to_strbuilder_fwd(CodeOpCast op_cast, StrBuilder* result );
GEN_API StrBuilder pragma_to_strbuilder (CodePragma self);
GEN_API void pragma_to_strbuilder_ref(CodePragma self, StrBuilder* result);
StrBuilder pragma_to_strbuilder (CodePragma self);
void pragma_to_strbuilder_ref(CodePragma self, StrBuilder* result);
GEN_API StrBuilder preprocess_to_strbuilder (CodePreprocessCond cond);
GEN_API void preprocess_to_strbuilder_if (CodePreprocessCond cond, StrBuilder* result );
GEN_API void preprocess_to_strbuilder_ifdef (CodePreprocessCond cond, StrBuilder* result );
GEN_API void preprocess_to_strbuilder_ifndef(CodePreprocessCond cond, StrBuilder* result );
GEN_API void preprocess_to_strbuilder_elif (CodePreprocessCond cond, StrBuilder* result );
GEN_API void preprocess_to_strbuilder_else (CodePreprocessCond cond, StrBuilder* result );
GEN_API void preprocess_to_strbuilder_endif (CodePreprocessCond cond, StrBuilder* result );
void preprocess_to_strbuilder_if (CodePreprocessCond cond, StrBuilder* result );
void preprocess_to_strbuilder_ifdef (CodePreprocessCond cond, StrBuilder* result );
void preprocess_to_strbuilder_ifndef(CodePreprocessCond cond, StrBuilder* result );
void preprocess_to_strbuilder_elif (CodePreprocessCond cond, StrBuilder* result );
void preprocess_to_strbuilder_else (CodePreprocessCond cond, StrBuilder* result );
void preprocess_to_strbuilder_endif (CodePreprocessCond cond, StrBuilder* result );
GEN_API StrBuilder template_to_strbuilder (CodeTemplate self);
StrBuilder template_to_strbuilder (CodeTemplate self);
GEN_API void template_to_strbuilder_ref(CodeTemplate self, StrBuilder* result);
GEN_API StrBuilder typename_to_strbuilder (CodeTypename self);
GEN_API void typename_to_strbuilder_ref(CodeTypename self, StrBuilder* result);
GEN_API StrBuilder typedef_to_strbuilder (CodeTypedef self);
StrBuilder typedef_to_strbuilder (CodeTypedef self);
GEN_API void typedef_to_strbuilder_ref(CodeTypedef self, StrBuilder* result );
StrBuilder typename_to_strbuilder (CodeTypename self);
GEN_API void typename_to_strbuilder_ref(CodeTypename self, StrBuilder* result);
GEN_API StrBuilder union_to_strbuilder (CodeUnion self);
GEN_API void union_to_strbuilder_def(CodeUnion self, StrBuilder* result);
GEN_API void union_to_strbuilder_fwd(CodeUnion self, StrBuilder* result);
GEN_API StrBuilder using_to_strbuilder (CodeUsing op_cast );
StrBuilder using_to_strbuilder (CodeUsing op_cast );
GEN_API void using_to_strbuilder_ref(CodeUsing op_cast, StrBuilder* result );
GEN_API void using_to_strbuilder_ns (CodeUsing op_cast, StrBuilder* result );
void using_to_strbuilder_ns (CodeUsing op_cast, StrBuilder* result );
GEN_API StrBuilder var_to_strbuilder (CodeVar self);
StrBuilder var_to_strbuilder (CodeVar self);
GEN_API void var_to_strbuilder_ref(CodeVar self, StrBuilder* result);
// TODO(Ed): Move C-Interface inlines here...
#pragma endregion Code Type C-Interface
#if GEN_COMPILER_CPP
@ -249,7 +252,8 @@ struct CodeSpecifiers
#if ! GEN_C_LIKE_CPP
Using_Code( CodeSpecifiers );
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 remove( Specifier to_remove ) { return specifiers_remove(* this, to_remove); }
StrBuilder to_strbuilder() { return specifiers_to_strbuilder(* this ); }
void to_strbuilder( StrBuilder& result ) { return specifiers_to_strbuilder_ref(* this, & result); }
@ -1071,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 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 specifiers_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 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); }

View File

@ -0,0 +1,85 @@
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "interface.hpp"
#endif
#pragma region Constants
// Predefined typename codes. Are set to readonly and are setup during gen::init()
GEN_API extern Macro enum_underlying_macro;
GEN_API extern Code access_public;
GEN_API extern Code access_protected;
GEN_API extern Code access_private;
GEN_API extern CodeAttributes attrib_api_export;
GEN_API extern CodeAttributes attrib_api_import;
GEN_API extern Code module_global_fragment;
GEN_API extern Code module_private_fragment;
GEN_API extern Code fmt_newline;
GEN_API extern CodePragma pragma_once;
GEN_API extern CodeParams param_varadic;
GEN_API extern CodePreprocessCond preprocess_else;
GEN_API extern CodePreprocessCond preprocess_endif;
GEN_API extern CodeSpecifiers spec_const;
GEN_API extern CodeSpecifiers spec_consteval;
GEN_API extern CodeSpecifiers spec_constexpr;
GEN_API extern CodeSpecifiers spec_constinit;
GEN_API extern CodeSpecifiers spec_extern_linkage;
GEN_API extern CodeSpecifiers spec_final;
GEN_API extern CodeSpecifiers spec_forceinline;
GEN_API extern CodeSpecifiers spec_global;
GEN_API extern CodeSpecifiers spec_inline;
GEN_API extern CodeSpecifiers spec_internal_linkage;
GEN_API extern CodeSpecifiers spec_local_persist;
GEN_API extern CodeSpecifiers spec_mutable;
GEN_API extern CodeSpecifiers spec_neverinline;
GEN_API extern CodeSpecifiers spec_noexcept;
GEN_API extern CodeSpecifiers spec_override;
GEN_API extern CodeSpecifiers spec_ptr;
GEN_API extern CodeSpecifiers spec_pure;
GEN_API extern CodeSpecifiers spec_ref;
GEN_API extern CodeSpecifiers spec_register;
GEN_API extern CodeSpecifiers spec_rvalue;
GEN_API extern CodeSpecifiers spec_static_member;
GEN_API extern CodeSpecifiers spec_thread_local;
GEN_API extern CodeSpecifiers spec_virtual;
GEN_API extern CodeSpecifiers spec_volatile;
GEN_API extern CodeTypename t_empty; // Used with varaidc parameters. (Exposing just in case its useful for another circumstance)
GEN_API extern CodeTypename t_auto;
GEN_API extern CodeTypename t_void;
GEN_API extern CodeTypename t_int;
GEN_API extern CodeTypename t_bool;
GEN_API extern CodeTypename t_char;
GEN_API extern CodeTypename t_wchar_t;
GEN_API extern CodeTypename t_class;
GEN_API extern CodeTypename t_typename;
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
GEN_API extern CodeTypename t_b32;
GEN_API extern CodeTypename t_s8;
GEN_API extern CodeTypename t_s16;
GEN_API extern CodeTypename t_s32;
GEN_API extern CodeTypename t_s64;
GEN_API extern CodeTypename t_u8;
GEN_API extern CodeTypename t_u16;
GEN_API extern CodeTypename t_u32;
GEN_API extern CodeTypename t_u64;
GEN_API extern CodeTypename t_ssize;
GEN_API extern CodeTypename t_usize;
GEN_API extern CodeTypename t_f32;
GEN_API extern CodeTypename t_f64;
#endif
#pragma endregion Constants

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "components/types.hpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "components/types.hpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "components/types.hpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "components/types.hpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "components/types.hpp"
#endif

View File

@ -1,88 +0,0 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#pragma once
#include "inlines.hpp"
#include "gen/ast_inlines.hpp"
#endif
#pragma region Constants
GEN_API extern Macro enum_underlying_macro;
GEN_API extern Code access_public;
GEN_API extern Code access_protected;
GEN_API extern Code access_private;
GEN_API extern CodeAttributes attrib_api_export;
GEN_API extern CodeAttributes attrib_api_import;
GEN_API extern Code module_global_fragment;
GEN_API extern Code module_private_fragment;
GEN_API extern Code fmt_newline;
GEN_API extern CodePragma pragma_once;
GEN_API extern CodeParams param_varadic;
GEN_API extern CodePreprocessCond preprocess_else;
GEN_API extern CodePreprocessCond preprocess_endif;
GEN_API extern CodeSpecifiers spec_const;
GEN_API extern CodeSpecifiers spec_consteval;
GEN_API extern CodeSpecifiers spec_constexpr;
GEN_API extern CodeSpecifiers spec_constinit;
GEN_API extern CodeSpecifiers spec_extern_linkage;
GEN_API extern CodeSpecifiers spec_final;
GEN_API extern CodeSpecifiers spec_forceinline;
GEN_API extern CodeSpecifiers spec_global;
GEN_API extern CodeSpecifiers spec_inline;
GEN_API extern CodeSpecifiers spec_internal_linkage;
GEN_API extern CodeSpecifiers spec_local_persist;
GEN_API extern CodeSpecifiers spec_mutable;
GEN_API extern CodeSpecifiers spec_neverinline;
GEN_API extern CodeSpecifiers spec_noexcept;
GEN_API extern CodeSpecifiers spec_override;
GEN_API extern CodeSpecifiers spec_ptr;
GEN_API extern CodeSpecifiers spec_pure;
GEN_API extern CodeSpecifiers spec_ref;
GEN_API extern CodeSpecifiers spec_register;
GEN_API extern CodeSpecifiers spec_rvalue;
GEN_API extern CodeSpecifiers spec_static_member;
GEN_API extern CodeSpecifiers spec_thread_local;
GEN_API extern CodeSpecifiers spec_virtual;
GEN_API extern CodeSpecifiers spec_volatile;
GEN_API extern CodeTypename t_empty; // Used with varaidc parameters. (Exposing just in case its useful for another circumstance)
GEN_API extern CodeTypename t_auto;
GEN_API extern CodeTypename t_void;
GEN_API extern CodeTypename t_int;
GEN_API extern CodeTypename t_bool;
GEN_API extern CodeTypename t_char;
GEN_API extern CodeTypename t_wchar_t;
GEN_API extern CodeTypename t_class;
GEN_API extern CodeTypename t_typename;
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
// Predefined typename codes. Are set to readonly and are setup during gen::init()
GEN_API extern Context* _ctx;
GEN_API extern CodeTypename t_b32;
GEN_API extern CodeTypename t_s8;
GEN_API extern CodeTypename t_s16;
GEN_API extern CodeTypename t_s32;
GEN_API extern CodeTypename t_s64;
GEN_API extern CodeTypename t_u8;
GEN_API extern CodeTypename t_u16;
GEN_API extern CodeTypename t_u32;
GEN_API extern CodeTypename t_u64;
GEN_API extern CodeTypename t_ssize;
GEN_API extern CodeTypename t_usize;
GEN_API extern CodeTypename t_f32;
GEN_API extern CodeTypename t_f64;
#endif
#pragma endregion Constants

View File

@ -15,7 +15,7 @@
| \_____|\___}_l |_|\___} ,__/| ,__/ (_____/ \__\__/_|\__, |\___}\__,_l |
| | | | | __} | |
| l_l l_l {___/ |
! ----------------------------------------------------------------------- VERSION: v0.23-Alpha |
! ----------------------------------------------------------------------- VERSION: v0.25-Alpha |
! ============================================================================================ |
! WARNING: THIS IS AN ALPHA VERSION OF THE LIBRARY, USE AT YOUR OWN DISCRETION |
! NEVER DO CODE GENERATION WITHOUT AT LEAST HAVING CONTENT IN A CODEBASE UNDER VERSION CONTROL |

View File

@ -1,8 +1,318 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "interface.hpp"
#include "constants.hpp"
#endif
#pragma region Serialization
inline
StrBuilder attributes_to_strbuilder(CodeAttributes attributes) {
GEN_ASSERT(attributes);
char* raw = ccast(char*, str_duplicate( attributes->Content, get_context()->Allocator_Temp ).Ptr);
StrBuilder result = { raw };
return result;
}
inline
void attributes_to_strbuilder_ref(CodeAttributes attributes, StrBuilder* result) {
GEN_ASSERT(attributes);
GEN_ASSERT(result);
strbuilder_append_str(result, attributes->Content);
}
inline
StrBuilder comment_to_strbuilder(CodeComment comment) {
GEN_ASSERT(comment);
char* raw = ccast(char*, str_duplicate( comment->Content, get_context()->Allocator_Temp ).Ptr);
StrBuilder result = { raw };
return result;
}
inline
void body_to_strbuilder_ref( CodeBody body, StrBuilder* result )
{
GEN_ASSERT(body != nullptr);
GEN_ASSERT(result != nullptr);
Code curr = body->Front;
s32 left = body->NumEntries;
while ( left -- )
{
code_to_strbuilder_ref(curr, result);
// strbuilder_append_fmt( result, "%SB", code_to_strbuilder(curr) );
curr = curr->Next;
}
}
inline
void comment_to_strbuilder_ref(CodeComment comment, StrBuilder* result) {
GEN_ASSERT(comment);
GEN_ASSERT(result);
strbuilder_append_str(result, comment->Content);
}
inline
StrBuilder define_to_strbuilder(CodeDefine define)
{
GEN_ASSERT(define);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
define_to_strbuilder_ref(define, & result);
return result;
}
inline
StrBuilder define_params_to_strbuilder(CodeDefineParams params)
{
GEN_ASSERT(params);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
define_params_to_strbuilder_ref( params, & result );
return result;
}
inline
StrBuilder exec_to_strbuilder(CodeExec exec)
{
GEN_ASSERT(exec);
char* raw = ccast(char*, str_duplicate( exec->Content, _ctx->Allocator_Temp ).Ptr);
StrBuilder result = { raw };
return result;
}
inline
void exec_to_strbuilder_ref(CodeExec exec, StrBuilder* result) {
GEN_ASSERT(exec);
GEN_ASSERT(result);
strbuilder_append_str(result, exec->Content);
}
inline
void extern_to_strbuilder(CodeExtern self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( self->Body )
strbuilder_append_fmt( result, "extern \"%S\"\n{\n%SB\n}\n", self->Name, body_to_strbuilder(self->Body) );
else
strbuilder_append_fmt( result, "extern \"%S\"\n{}\n", self->Name );
}
inline
StrBuilder friend_to_strbuilder(CodeFriend self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 256 );
friend_to_strbuilder_ref( self, & result );
return result;
}
inline
void friend_to_strbuilder_ref(CodeFriend self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
strbuilder_append_fmt( result, "friend %SB", code_to_strbuilder(self->Declaration) );
if ( self->Declaration->Type != CT_Function && self->Declaration->Type != CT_Operator && (* result)[ strbuilder_length(* result) - 1 ] != ';' )
{
strbuilder_append_str( result, txt(";") );
}
if ( self->InlineCmt )
strbuilder_append_fmt( result, " %S", self->InlineCmt->Content );
else
strbuilder_append_str( result, txt("\n"));
}
inline
StrBuilder include_to_strbuilder(CodeInclude include)
{
GEN_ASSERT(include);
return strbuilder_fmt_buf( _ctx->Allocator_Temp, "#include %S\n", include->Content );
}
inline
void include_to_strbuilder_ref( CodeInclude include, StrBuilder* result )
{
GEN_ASSERT(include);
GEN_ASSERT(result);
strbuilder_append_fmt( result, "#include %S\n", include->Content );
}
inline
StrBuilder module_to_strbuilder(CodeModule self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 64 );
module_to_strbuilder_ref( self, & result );
return result;
}
inline
StrBuilder namespace_to_strbuilder(CodeNS self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
namespace_to_strbuilder_ref( self, & result );
return result;
}
inline
void namespace_to_strbuilder_ref(CodeNS self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
strbuilder_append_str( result, txt("export ") );
strbuilder_append_fmt( result, "namespace %S\n{\n%SB\n}\n", self->Name, body_to_strbuilder(self->Body) );
}
inline
StrBuilder params_to_strbuilder(CodeParams self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
params_to_strbuilder_ref( self, & result );
return result;
}
inline
StrBuilder pragma_to_strbuilder(CodePragma self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 256 );
pragma_to_strbuilder_ref( self, & result );
return result;
}
inline
void pragma_to_strbuilder_ref(CodePragma self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
strbuilder_append_fmt( result, "#pragma %S\n", self->Content );
}
inline
void preprocess_to_strbuilder_if(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
GEN_ASSERT(result);
strbuilder_append_fmt( result, "#if %S", cond->Content );
}
inline
void preprocess_to_strbuilder_ifdef(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
GEN_ASSERT(result);
strbuilder_append_fmt( result, "#ifdef %S\n", cond->Content );
}
inline
void preprocess_to_strbuilder_ifndef(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
GEN_ASSERT(result);
strbuilder_append_fmt( result, "#ifndef %S", cond->Content );
}
inline
void preprocess_to_strbuilder_elif(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
GEN_ASSERT(result);
strbuilder_append_fmt( result, "#elif %S\n", cond->Content );
}
inline
void preprocess_to_strbuilder_else(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
GEN_ASSERT(result);
strbuilder_append_str( result, txt("#else\n") );
}
inline
void preprocess_to_strbuilder_endif(CodePreprocessCond cond, StrBuilder* result )
{
GEN_ASSERT(cond);
GEN_ASSERT(result);
strbuilder_append_str( result, txt("#endif\n") );
}
inline
StrBuilder specifiers_to_strbuilder(CodeSpecifiers self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 64 );
specifiers_to_strbuilder_ref( self, & result );
return result;
}
inline
StrBuilder template_to_strbuilder(CodeTemplate self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 1024 );
template_to_strbuilder_ref( self, & result );
return result;
}
inline
StrBuilder typedef_to_strbuilder(CodeTypedef self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
typedef_to_strbuilder_ref( self, & result );
return result;
}
inline
StrBuilder typename_to_strbuilder(CodeTypename self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_str( _ctx->Allocator_Temp, txt("") );
typename_to_strbuilder_ref( self, & result );
return result;
}
inline
StrBuilder using_to_strbuilder(CodeUsing self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
switch ( self->Type )
{
case CT_Using:
using_to_strbuilder_ref( self, & result );
break;
case CT_Using_Namespace:
using_to_strbuilder_ns( self, & result );
break;
}
return result;
}
inline
void using_to_strbuilder_ns(CodeUsing self, StrBuilder* result )
{
GEN_ASSERT(self);
GEN_ASSERT(result);
if ( self->InlineCmt )
strbuilder_append_fmt( result, "using namespace $S; %S", self->Name, self->InlineCmt->Content );
else
strbuilder_append_fmt( result, "using namespace %S;\n", self->Name );
}
inline
StrBuilder var_to_strbuilder(CodeVar self)
{
GEN_ASSERT(self);
StrBuilder result = strbuilder_make_reserve( get_context()->Allocator_Temp, 256 );
var_to_strbuilder_ref( self, & result );
return result;
}
#pragma endregion Serialization
#pragma region Code
inline
void code_append( Code self, Code other )
@ -74,7 +384,7 @@ bool code_is_valid(Code self)
return self != nullptr && self->Type != CT_Invalid;
}
forceinline
bool code_has_entries(AST* self)
bool code_has_entries(Code self)
{
GEN_ASSERT(self);
return self->NumEntries > 0;
@ -169,12 +479,12 @@ void class_add_interface( CodeClass self, CodeTypename type )
// then you'll need to move this over to ParentType->next and update ParentAccess accordingly.
}
while ( possible_slot != nullptr )
while ( possible_slot->Next != nullptr )
{
possible_slot = cast(CodeTypename, possible_slot->Next);
}
possible_slot = type;
possible_slot->Next = cast(Code, type);
}
#pragma endregion CodeClass
@ -296,7 +606,17 @@ bool specifiers_append(CodeSpecifiers self, Specifier spec )
return true;
}
inline
s32 specifiers_has(CodeSpecifiers self, Specifier spec)
bool specifiers_has(CodeSpecifiers self, Specifier spec)
{
GEN_ASSERT(self != nullptr);
for ( s32 idx = 0; idx < self->NumEntries; idx++ ) {
if ( self->ArrSpecs[ idx ] == spec )
return true;
}
return false;
}
inline
s32 specifiers_index_of(CodeSpecifiers self, Specifier spec)
{
GEN_ASSERT(self != nullptr);
for ( s32 idx = 0; idx < self->NumEntries; idx++ ) {
@ -378,12 +698,12 @@ void struct_add_interface(CodeStruct self, CodeTypename type )
// then you'll need to move this over to ParentType->next and update ParentAccess accordingly.
}
while ( possible_slot != nullptr )
while ( possible_slot->Next != nullptr )
{
possible_slot = cast(CodeTypename, possible_slot->Next);
}
possible_slot = type;
possible_slot->Next = cast(Code, type);
}
#pragma endregion Code

View File

@ -1,10 +1,10 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "code_serialization.cpp"
#endif
internal void parser_init();
internal void parser_deinit();
internal void parser_init(Context* ctx);
internal void parser_deinit(Context* ctx);
internal
void* fallback_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
@ -71,6 +71,14 @@ void* fallback_allocator_proc( void* allocator_data, AllocType type, ssize size,
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
void define_constants()
{
@ -283,6 +291,19 @@ void init(Context* ctx)
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).
_ctx = ctx;
@ -298,7 +319,7 @@ void init(Context* ctx)
}
// Setup the code pool and code entries arena.
{
Pool code_pool = pool_init( ctx->Allocator_Pool, ctx->CodePool_NumBlocks, sizeof(AST) );
Pool code_pool = pool_init( ctx->Allocator_Pool, ctx->CodePool_NumBlocks, size_of(AST) );
if ( code_pool.PhysicalStart == nullptr )
GEN_FATAL( "gen::init: Failed to initialize the code pool" );
array_append( ctx->CodePools, code_pool );
@ -311,18 +332,18 @@ void init(Context* ctx)
}
// Setup the hash tables
{
ctx->StrCache = hashtable_init(StrCached, ctx->Allocator_DyanmicContainers);
ctx->StrCache = hashtable_init_reserve(StrCached, ctx->Allocator_DyanmicContainers, ctx->InitSize_StrCacheTable);
if ( ctx->StrCache.Entries == nullptr )
GEN_FATAL( "gen::init: Failed to initialize the StringCache");
ctx->Macros = hashtable_init(Macro, ctx->Allocator_DyanmicContainers);
ctx->Macros = hashtable_init_reserve(Macro, ctx->Allocator_DyanmicContainers, ctx->InitSize_MacrosTable);
if (ctx->Macros.Hashes == nullptr || ctx->Macros.Entries == nullptr) {
GEN_FATAL( "gen::init: Failed to initialize the PreprocessMacros table" );
}
}
define_constants();
parser_init();
parser_init(ctx);
++ context_counter;
}
@ -371,7 +392,7 @@ void deinit(Context* ctx)
while ( left--, left );
array_free( ctx->Fallback_AllocatorBuckets);
}
parser_deinit();
parser_deinit(ctx);
if (_ctx == ctx)
_ctx = nullptr;

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "ast_types.hpp"
#endif
@ -15,24 +15,6 @@
\▓▓▓▓▓▓ \▓▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓ \▓▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓
*/
#if 0
enum LogLevel : u32
{
Info,
Warning,
Panic,
};
struct LogEntry
{
Str msg;
u32 line_num;
void* data;
};
typedef void LoggerCallback(LogEntry entry);
#endif
// Note(Ed): This is subject to heavily change
// with upcoming changes to the library's fallback (default) allocations strategy;
// and major changes to lexer/parser context usage.
@ -64,9 +46,16 @@ struct Context
u32 InitSize_LexerTokens;
u32 SizePer_StringArena;
u32 InitSize_StrCacheTable;
u32 InitSize_MacrosTable;
// TODO(Ed): Symbol Table
// Keep track of all resolved symbols (naemspaced identifiers)
// Logging
LoggerProc* Logger;
// Parser
// Used by the lexer to persistently treat all these identifiers as preprocessor defines.
@ -89,9 +78,6 @@ struct Context
StringTable StrCache;
// TODO(Ed): This needs to be just handled by a parser context
Array(Token) Lexer_Tokens;
// TODO(Ed): Active parse context vs a parse result need to be separated conceptually
ParseContext parser;
@ -99,6 +85,42 @@ struct Context
s32 temp_serialize_indent;
};
// TODO(Ed): Eventually this library should opt out of an implicit context for baseline implementation
// This would automatically make it viable for multi-threaded purposes among other things
// An implicit context interface will be provided instead as wrapper procedures as convience.
GEN_API extern Context* _ctx;
// 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_init();
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
GEN_API void init(Context* ctx);
@ -109,7 +131,7 @@ GEN_API void deinit(Context* ctx);
// Retrieves the active context (not usually needed, but here in case...)
GEN_API Context* get_context();
// Clears the allocations, but doesn't free the memoery, then calls init() again.
// Clears the allocations, but doesn't free the memory, then calls init() again.
// Ease of use.
GEN_API void reset(Context* ctx);
@ -194,7 +216,7 @@ GEN_API CodeEnum def_enum( Str name, Opts_def_enum opts GEN_PARAM_DEFAULT );
GEN_API CodeExec def_execution ( Str content );
GEN_API CodeExtern def_extern_link( Str name, CodeBody body );
GEN_API CodeFriend def_friend ( Code symbol );
GEN_API CodeFriend def_friend ( Code code );
struct Opts_def_function {
CodeParams params;
@ -244,7 +266,7 @@ GEN_API CodeTemplate def_template( CodeParams params, Code definition, Opts_def_
struct Opts_def_type {
ETypenameTag type_tag;
Code arrayexpr;
Code array_expr;
CodeSpecifiers specifiers;
CodeAttributes attributes;
};
@ -280,7 +302,7 @@ struct Opts_def_variable
GEN_API CodeVar def_variable( CodeTypename type, Str name, Opts_def_variable opts GEN_PARAM_DEFAULT );
// Constructs an empty body. Use AST::validate_body() to check if the body is was has valid entries.
GEN_API CodeBody def_body( CodeType type );
CodeBody def_body( CodeType type );
// There are two options for defining a struct body, either varadically provided with the args macro to auto-deduce the arg num,
/// or provide as an array of Code objects.
@ -329,37 +351,33 @@ forceinline CodeBody def_union_body ( s32 num, Code* codes )
#pragma region Parsing
#if 0
struct StackNode
struct ParseStackNode
{
StackNode* Prev;
ParseStackNode* prev;
Token Start;
Token Name; // The name of the AST node (if parsed)
Str FailedProc; // The name of the procedure that failed
};
// Stack nodes are allocated the error's allocator
struct Error
{
StrBuilder message;
StackNode* context_stack;
TokenSlice tokens;
Token* start;
Str name; // The name of the AST node (if parsed)
Str proc_name; // The name of the procedure
Code code_rel; // Relevant AST node
// TODO(Ed): When an error occurs, the parse stack is not released and instead the scope is left dangling.
};
struct ParseInfo
{
Arena FileMem;
Arena TokMem;
Arena CodeMem;
FileContents FileContent;
Array<Token> Tokens;
Array<Error> Errors;
// Errors are allocated to a dedicated general arena.
ParseMessage* messages;
LexedInfo lexed;
Code result;
};
CodeBody parse_file( Str path );
#endif
struct ParseOpts
{
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 CodeConstructor parse_constructor ( Str constructor_def );
@ -388,11 +406,12 @@ GEN_API CodeVar parse_variable ( Str var_def );
GEN_API ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va );
//! Do not use directly. Use the token_fmt macro instead.
GEN_API Str token_fmt_impl( ssize, ... );
Str token_fmt_impl( ssize, ... );
GEN_API Code untyped_str ( Str content);
GEN_API Code untyped_fmt ( 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

View File

@ -1,6 +1,6 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "gen/etoktype.cpp"
#include "gen/etoktype.hpp"
#include "interface.upfront.cpp"
#include "lexer.cpp"
#include "parser.cpp"
@ -8,29 +8,70 @@
// Publically Exposed Interface
ParseInfo wip_parse_str(LexedInfo lexed, ParseOpts* opts)
{
// TODO(Ed): Lift this.
Context* ctx = _ctx;
if (lexed.tokens.num == 0 && lexed.tokens.ptr == nullptr) {
check_parse_args(lexed.text);
lexed = lex(ctx, lexed.text);
}
ParseInfo info = struct_zero(ParseInfo);
info.lexed = lexed;
// TODO(Ed): ParseInfo should be set to the parser context.
ctx->parser = struct_zero(ParseContext);
ctx->parser.tokens = lexed.tokens;
ParseStackNode scope = NullScope;
parser_push(& ctx->parser, & scope);
CodeBody result = parse_global_nspace(ctx,CT_Global_Body);
parser_pop(& ctx->parser);
return info;
}
CodeClass parse_class( Str def )
{
// TODO(Ed): Lift this.
Context* ctx = _ctx;
check_parse_args( def );
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
ctx->parser = struct_zero(ParseContext);
LexedInfo lexed = lex(ctx, def);
ctx->parser.tokens = lexed.tokens;
if ( ctx->parser.tokens.ptr == nullptr )
return InvalidCode;
_ctx->parser.Tokens = toks;
push_scope();
CodeClass result = (CodeClass) parse_class_struct( Tok_Decl_Class, parser_not_inplace_def );
parser_pop(& _ctx->parser);
ParseStackNode scope = NullScope;
parser_push(& ctx->parser, & scope);
CodeClass result = (CodeClass) parse_class_struct( ctx, Tok_Decl_Class, parser_not_inplace_def );
parser_pop(& ctx->parser);
return result;
}
CodeConstructor parse_constructor(Str def )
{
// TODO(Ed): Lift this.
Context* ctx = _ctx;
check_parse_args( def );
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
ctx->parser = struct_zero(ParseContext);
LexedInfo lexed = lex(ctx, def);
ctx->parser.tokens = lexed.tokens;
if ( ctx->parser.tokens.ptr == nullptr )
return InvalidCode;
ParseStackNode scope = NullScope;
parser_push(& ctx->parser, & scope);
// TODO(Ed): Constructors can have prefix attributes
CodeSpecifiers specifiers = NullCode;
@ -57,8 +98,8 @@ CodeConstructor parse_constructor( Str def )
break;
default :
log_failure( "Invalid specifier %s for variable\n%S", spec_to_str( spec ), parser_to_strbuilder(_ctx->parser) );
parser_pop(& _ctx->parser);
log_failure( "Invalid specifier %s for variable\n%S", spec_to_str( spec ), parser_to_strbuilder(& ctx->parser, ctx->Allocator_Temp) );
parser_pop(& ctx->parser);
return InvalidCode;
}
@ -71,247 +112,337 @@ CodeConstructor parse_constructor( Str def )
eat( currtok.Type );
}
if ( NumSpecifiers )
{
if ( NumSpecifiers ) {
specifiers = def_specifiers_arr( NumSpecifiers, specs_found );
// <specifiers> ...
}
_ctx->parser.Tokens = toks;
CodeConstructor result = parser_parse_constructor( specifiers );
CodeConstructor result = parser_parse_constructor(ctx, specifiers);
parser_pop(& ctx->parser);
return result;
}
CodeDefine parse_define( Str def )
{
// TODO(Ed): Lift this.
Context* ctx = _ctx;
check_parse_args( def );
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
ctx->parser = struct_zero(ParseContext);
LexedInfo lexed = lex(ctx, def);
ctx->parser.tokens = lexed.tokens;
if ( ctx->parser.tokens.ptr == nullptr )
return InvalidCode;
_ctx->parser.Tokens = toks;
push_scope();
CodeDefine result = parser_parse_define();
parser_pop(& _ctx->parser);
ParseStackNode scope = NullScope;
parser_push(& ctx->parser, & scope);
CodeDefine result = parser_parse_define(ctx);
parser_pop(& ctx->parser);
return result;
}
CodeDestructor parse_destructor( Str def )
{
// TODO(Ed): Lift this.
Context* ctx = _ctx;
check_parse_args( def );
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
ctx->parser = struct_zero(ParseContext);
LexedInfo lexed = lex(ctx, def);
ctx->parser.tokens = lexed.tokens;
if ( ctx->parser.tokens.ptr == nullptr )
return InvalidCode;
// TODO(Ed): Destructors can have prefix attributes
// TODO(Ed): Destructors can have virtual
_ctx->parser.Tokens = toks;
CodeDestructor result = parser_parse_destructor(NullCode);
CodeDestructor result = parser_parse_destructor(ctx, NullCode);
return result;
}
CodeEnum parse_enum( Str def )
{
// TODO(Ed): Lift this.
Context* ctx = _ctx;
check_parse_args( def );
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
{
parser_pop(& _ctx->parser);
ctx->parser = struct_zero(ParseContext);
LexedInfo lexed = lex(ctx, def);
ctx->parser.tokens = lexed.tokens;
if ( ctx->parser.tokens.ptr == nullptr ) {
return InvalidCode;
}
_ctx->parser.Tokens = toks;
return parser_parse_enum( parser_not_inplace_def);
return parser_parse_enum(ctx, parser_not_inplace_def);
}
CodeBody parse_export_body( Str def )
{
// TODO(Ed): Lift this.
Context* ctx = _ctx;
check_parse_args( def );
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
ctx->parser = struct_zero(ParseContext);
LexedInfo lexed = lex(ctx, def);
ctx->parser.tokens = lexed.tokens;
if ( ctx->parser.tokens.ptr == nullptr )
return InvalidCode;
_ctx->parser.Tokens = toks;
return parser_parse_export_body();
return parser_parse_export_body(ctx);
}
CodeExtern parse_extern_link( Str def )
{
// TODO(Ed): Lift this.
Context* ctx = _ctx;
check_parse_args( def );
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
ctx->parser = struct_zero(ParseContext);
LexedInfo lexed = lex(ctx, def);
ctx->parser.tokens = lexed.tokens;
if ( ctx->parser.tokens.ptr == nullptr )
return InvalidCode;
_ctx->parser.Tokens = toks;
return parser_parse_extern_link();
return parser_parse_extern_link(ctx);
}
CodeFriend parse_friend( Str def )
{
// TODO(Ed): Lift this.
Context* ctx = _ctx;
check_parse_args( def );
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
ctx->parser = struct_zero(ParseContext);
LexedInfo lexed = lex(ctx, def);
ctx->parser.tokens = lexed.tokens;
if ( ctx->parser.tokens.ptr == nullptr )
return InvalidCode;
_ctx->parser.Tokens = toks;
return parser_parse_friend();
return parser_parse_friend(ctx);
}
CodeFn parse_function( Str def )
{
// TODO(Ed): Lift this.
Context* ctx = _ctx;
check_parse_args( def );
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
ctx->parser = struct_zero(ParseContext);
LexedInfo lexed = lex(ctx, def);
ctx->parser.tokens = lexed.tokens;
if ( ctx->parser.tokens.ptr == nullptr )
return InvalidCode;
_ctx->parser.Tokens = toks;
return (CodeFn) parser_parse_function();
return (CodeFn) parser_parse_function(ctx);
}
CodeBody parse_global_body( Str def )
{
// TODO(Ed): Lift this.
Context* ctx = _ctx;
check_parse_args( def );
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
ctx->parser = struct_zero(ParseContext);
LexedInfo lexed = lex(ctx, def);
ctx->parser.tokens = lexed.tokens;
if ( ctx->parser.tokens.ptr == nullptr )
return InvalidCode;
_ctx->parser.Tokens = toks;
push_scope();
CodeBody result = parse_global_nspace( CT_Global_Body );
parser_pop(& _ctx->parser);
ParseStackNode scope = NullScope;
parser_push(& ctx->parser, & scope);
CodeBody result = parse_global_nspace(ctx, CT_Global_Body );
parser_pop(& ctx->parser);
return result;
}
CodeNS parse_namespace( Str def )
{
// TODO(Ed): Lift this.
Context* ctx = _ctx;
check_parse_args( def );
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
ctx->parser = struct_zero(ParseContext);
LexedInfo lexed = lex(ctx, def);
ctx->parser.tokens = lexed.tokens;
if ( ctx->parser.tokens.ptr == nullptr )
return InvalidCode;
_ctx->parser.Tokens = toks;
return parser_parse_namespace();
return parser_parse_namespace(ctx);
}
CodeOperator parse_operator( Str def )
{
// TODO(Ed): Lift this.
Context* ctx = _ctx;
check_parse_args( def );
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
ctx->parser = struct_zero(ParseContext);
LexedInfo lexed = lex(ctx, def);
ctx->parser.tokens = lexed.tokens;
if ( ctx->parser.tokens.ptr == nullptr )
return InvalidCode;
_ctx->parser.Tokens = toks;
return (CodeOperator) parser_parse_operator();
return (CodeOperator) parser_parse_operator(ctx);
}
CodeOpCast parse_operator_cast( Str def )
{
// TODO(Ed): Lift this.
Context* ctx = _ctx;
check_parse_args( def );
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
ctx->parser = struct_zero(ParseContext);
LexedInfo lexed = lex(ctx, def);
ctx->parser.tokens = lexed.tokens;
if ( ctx->parser.tokens.ptr == nullptr )
return InvalidCode;
_ctx->parser.Tokens = toks;
return parser_parse_operator_cast(NullCode);
return parser_parse_operator_cast(ctx, NullCode);
}
CodeStruct parse_struct( Str def )
{
// TODO(Ed): Lift this.
Context* ctx = _ctx;
check_parse_args( def );
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
ctx->parser = struct_zero(ParseContext);
LexedInfo lexed = lex(ctx, def);
ctx->parser.tokens = lexed.tokens;
if ( ctx->parser.tokens.ptr == nullptr )
return InvalidCode;
_ctx->parser.Tokens = toks;
push_scope();
CodeStruct result = (CodeStruct) parse_class_struct( Tok_Decl_Struct, parser_not_inplace_def );
parser_pop(& _ctx->parser);
ParseStackNode scope = NullScope;
parser_push(& ctx->parser, & scope);
CodeStruct result = (CodeStruct) parse_class_struct( ctx, Tok_Decl_Struct, parser_not_inplace_def );
parser_pop(& ctx->parser);
return result;
}
CodeTemplate parse_template( Str def )
{
// TODO(Ed): Lift this.
Context* ctx = _ctx;
check_parse_args( def );
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
ctx->parser = struct_zero(ParseContext);
LexedInfo lexed = lex(ctx, def);
ctx->parser.tokens = lexed.tokens;
if ( ctx->parser.tokens.ptr == nullptr )
return InvalidCode;
_ctx->parser.Tokens = toks;
return parser_parse_template();
return parser_parse_template(ctx);
}
CodeTypename parse_type( Str def )
{
// TODO(Ed): Lift this.
Context* ctx = _ctx;
check_parse_args( def );
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
ctx->parser = struct_zero(ParseContext);
LexedInfo lexed = lex(ctx, def);
ctx->parser.tokens = lexed.tokens;
if ( ctx->parser.tokens.ptr == nullptr )
return InvalidCode;
_ctx->parser.Tokens = toks;
return parser_parse_type( parser_not_from_template, nullptr);
return parser_parse_type( ctx, parser_not_from_template, nullptr);
}
CodeTypedef parse_typedef( Str def )
{
// TODO(Ed): Lift this.
Context* ctx = _ctx;
check_parse_args( def );
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
ctx->parser = struct_zero(ParseContext);
LexedInfo lexed = lex(ctx, def);
ctx->parser.tokens = lexed.tokens;
if ( ctx->parser.tokens.ptr == nullptr )
return InvalidCode;
_ctx->parser.Tokens = toks;
return parser_parse_typedef();
return parser_parse_typedef(ctx);
}
CodeUnion parse_union( Str def )
{
// TODO(Ed): Lift this.
Context* ctx = _ctx;
check_parse_args( def );
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
ctx->parser = struct_zero(ParseContext);
LexedInfo lexed = lex(ctx, def);
ctx->parser.tokens = lexed.tokens;
if ( ctx->parser.tokens.ptr == nullptr )
return InvalidCode;
_ctx->parser.Tokens = toks;
return parser_parse_union( parser_not_inplace_def);
return parser_parse_union(ctx, parser_not_inplace_def);
}
CodeUsing parse_using( Str def )
{
// TODO(Ed): Lift this.
Context* ctx = _ctx;
check_parse_args( def );
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
ctx->parser = struct_zero(ParseContext);
LexedInfo lexed = lex(ctx, def);
ctx->parser.tokens = lexed.tokens;
if ( ctx->parser.tokens.ptr == nullptr )
return InvalidCode;
_ctx->parser.Tokens = toks;
return parser_parse_using();
return parser_parse_using(ctx);
}
CodeVar parse_variable( Str def )
{
// TODO(Ed): Lift this.
Context* ctx = _ctx;
check_parse_args( def );
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
ctx->parser = struct_zero(ParseContext);
LexedInfo lexed = lex(ctx, def);
ctx->parser.tokens = lexed.tokens;
if ( ctx->parser.tokens.ptr == nullptr )
return InvalidCode;
_ctx->parser.Tokens = toks;
return parser_parse_variable();
return parser_parse_variable(ctx);
}
// Undef helper macros
@ -326,6 +457,7 @@ CodeVar parse_variable( Str def )
#undef left
#undef check
#undef push_scope
#undef NullScope
#undef def_assign
// Here for C Variant

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "interface.parsing.cpp"
#endif
@ -176,3 +176,16 @@ Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... )
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;
}

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "interface.cpp"
#endif
@ -473,8 +473,10 @@ CodeComment def_comment( Str content )
return (CodeComment) result;
}
CodeConstructor def_constructor( Opts_def_constructor p )
CodeConstructor def_constructor( Opts_def_constructor opt )
{
Opts_def_constructor p = get_optional(opt);
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));
GEN_DEBUG_TRAP();
@ -510,8 +512,10 @@ CodeConstructor def_constructor( Opts_def_constructor p )
return result;
}
CodeClass def_class( Str name, Opts_def_struct p )
CodeClass def_class( Str name, Opts_def_struct opt )
{
Opts_def_struct p = get_optional(opt);
if ( ! name_check( def_class, name ) ) {
GEN_DEBUG_TRAP();
return InvalidCode;
@ -561,8 +565,10 @@ CodeClass def_class( Str name, Opts_def_struct p )
return result;
}
CodeDefine def_define( Str name, MacroType type, Opts_def_define p )
CodeDefine def_define( Str name, MacroType type, Opts_def_define opt )
{
Opts_def_define p = get_optional(opt);
if ( ! name_check( def_define, name ) ) {
GEN_DEBUG_TRAP();
return InvalidCode;
@ -585,8 +591,10 @@ CodeDefine def_define( Str name, MacroType type, Opts_def_define p )
return result;
}
CodeDestructor def_destructor( Opts_def_destructor p )
CodeDestructor def_destructor( Opts_def_destructor opt )
{
Opts_def_destructor p = get_optional(opt);
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) );
GEN_DEBUG_TRAP();
@ -619,8 +627,10 @@ CodeDestructor def_destructor( Opts_def_destructor p )
return result;
}
CodeEnum def_enum( Str name, Opts_def_enum p )
CodeEnum def_enum( Str name, Opts_def_enum opt )
{
Opts_def_enum p = get_optional(opt);
if ( ! name_check( def_enum, name ) ) {
GEN_DEBUG_TRAP();
return InvalidCode;
@ -742,8 +752,10 @@ CodeFriend def_friend( Code declaration )
return result;
}
CodeFn def_function( Str name, Opts_def_function p )
CodeFn def_function( Str name, Opts_def_function opt )
{
Opts_def_function p = get_optional(opt);
if ( ! name_check( def_function, name )) {
GEN_DEBUG_TRAP();
return InvalidCode;
@ -802,8 +814,10 @@ CodeFn def_function( Str name, Opts_def_function p )
return result;
}
CodeInclude def_include( Str path, Opts_def_include p )
CodeInclude def_include( Str path, Opts_def_include opt )
{
Opts_def_include p = get_optional(opt);
if ( path.Len <= 0 || path.Ptr == nullptr ) {
log_failure( "gen::def_include: Invalid path provided - %d" );
GEN_DEBUG_TRAP();
@ -821,8 +835,10 @@ CodeInclude def_include( Str path, Opts_def_include p )
return result;
}
CodeModule def_module( Str name, Opts_def_module p )
CodeModule def_module( Str name, Opts_def_module opt )
{
Opts_def_module p = get_optional(opt);
if ( ! name_check( def_module, name )) {
GEN_DEBUG_TRAP();
return InvalidCode;
@ -835,8 +851,10 @@ CodeModule def_module( Str name, Opts_def_module p )
return result;
}
CodeNS def_namespace( Str name, CodeBody body, Opts_def_namespace p )
CodeNS def_namespace( Str name, CodeBody body, Opts_def_namespace opt )
{
Opts_def_namespace p = get_optional(opt);
if ( ! name_check( def_namespace, name )) {
GEN_DEBUG_TRAP();
return InvalidCode;
@ -859,8 +877,10 @@ CodeNS def_namespace( Str name, CodeBody body, Opts_def_namespace p )
return result;
}
CodeOperator def_operator( Operator op, Str nspace, Opts_def_operator p )
CodeOperator def_operator( Operator op, Str nspace, Opts_def_operator opt )
{
Opts_def_operator p = get_optional(opt);
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) );
GEN_DEBUG_TRAP();
@ -926,8 +946,10 @@ CodeOperator def_operator( Operator op, Str nspace, Opts_def_operator p )
return result;
}
CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast p )
CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast opt )
{
Opts_def_operator_cast p = get_optional(opt);
if ( ! null_check( def_operator_cast, type )) {
GEN_DEBUG_TRAP();
return InvalidCode;
@ -959,8 +981,10 @@ CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast p )
return result;
}
CodeParams def_param( CodeTypename type, Str name, Opts_def_param p )
CodeParams def_param( CodeTypename type, Str name, Opts_def_param opt )
{
Opts_def_param p = get_optional(opt);
if ( ! name_check( def_param, name ) || ! null_check( def_param, type ) ) {
GEN_DEBUG_TRAP();
return InvalidCode;
@ -1034,8 +1058,10 @@ CodeSpecifiers def_specifier( Specifier spec )
return result;
}
CodeStruct def_struct( Str name, Opts_def_struct p )
CodeStruct def_struct( Str name, Opts_def_struct opt )
{
Opts_def_struct p = get_optional(opt);
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)) );
GEN_DEBUG_TRAP();
@ -1076,8 +1102,10 @@ CodeStruct def_struct( Str name, Opts_def_struct p )
return result;
}
CodeTemplate def_template( CodeParams params, Code declaration, Opts_def_template p )
CodeTemplate def_template( CodeParams params, Code declaration, Opts_def_template opt )
{
Opts_def_template p = get_optional(opt);
if ( ! null_check( def_template, declaration ) ) {
GEN_DEBUG_TRAP();
return InvalidCode;
@ -1108,13 +1136,15 @@ CodeTemplate def_template( CodeParams params, Code declaration, Opts_def_templat
return result;
}
CodeTypename def_type( Str name, Opts_def_type p )
CodeTypename def_type( Str name, Opts_def_type opt )
{
Opts_def_type p = get_optional(opt);
if ( ! name_check( def_type, name )) {
GEN_DEBUG_TRAP();
return InvalidCode;
}
Code arrayexpr = p.arrayexpr;
Code array_expr = p.array_expr;
CodeSpecifiers specifiers = p.specifiers;
CodeAttributes attributes = p.attributes;
if ( p.attributes && p.attributes->Type != CT_PlatformAttributes ) {
@ -1127,8 +1157,8 @@ CodeTypename def_type( Str name, Opts_def_type p )
GEN_DEBUG_TRAP();
return InvalidCode;
}
if ( p.arrayexpr && p.arrayexpr->Type != CT_Untyped ) {
log_failure( "gen::def_type: arrayexpr is not of untyped type - %s", code_debug_str((Code)p.arrayexpr) );
if ( p.array_expr && p.array_expr->Type != CT_Untyped ) {
log_failure( "gen::def_type: arrayexpr is not of untyped type - %s", code_debug_str((Code)p.array_expr) );
GEN_DEBUG_TRAP();
return InvalidCode;
}
@ -1138,13 +1168,15 @@ CodeTypename def_type( Str name, Opts_def_type p )
result->Type = CT_Typename;
result->Attributes = p.attributes;
result->Specs = p.specifiers;
result->ArrExpr = p.arrayexpr;
result->ArrExpr = p.array_expr;
result->TypeTag = p.type_tag;
return result;
}
CodeTypedef def_typedef( Str name, Code type, Opts_def_typedef p )
CodeTypedef def_typedef( Str name, Code type, Opts_def_typedef opt )
{
Opts_def_typedef p = get_optional(opt);
if ( ! null_check( def_typedef, type ) ) {
GEN_DEBUG_TRAP();
return InvalidCode;
@ -1206,8 +1238,10 @@ CodeTypedef def_typedef( Str name, Code type, Opts_def_typedef p )
return result;
}
CodeUnion def_union( Str name, CodeBody body, Opts_def_union p )
CodeUnion def_union( Str name, CodeBody body, Opts_def_union opt )
{
Opts_def_union p = get_optional(opt);
if ( ! null_check( def_union, body ) ) {
GEN_DEBUG_TRAP();
return InvalidCode;
@ -1233,8 +1267,10 @@ CodeUnion def_union( Str name, CodeBody body, Opts_def_union p )
return result;
}
CodeUsing def_using( Str name, CodeTypename type, Opts_def_using p )
CodeUsing def_using( Str name, CodeTypename type, Opts_def_using opt )
{
Opts_def_using p = get_optional(opt);
if ( ! name_check( def_using, name ) || null_check( def_using, type ) ) {
GEN_DEBUG_TRAP();
return InvalidCode;
@ -1274,8 +1310,10 @@ CodeUsing def_using_namespace( Str name )
return result;
}
CodeVar def_variable( CodeTypename type, Str name, Opts_def_variable p )
CodeVar def_variable( CodeTypename type, Str name, Opts_def_variable opt )
{
Opts_def_variable p = get_optional(opt);
if ( ! name_check( def_variable, name ) || ! null_check( def_variable, type ) ) {
GEN_DEBUG_TRAP();
return InvalidCode;

View File

@ -1,7 +1,7 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "interface.upfront.cpp"
#include "gen/etoktype.cpp"
#include "gen/etoktype.hpp"
#endif
StrBuilder tok_to_strbuilder(Token tok)
@ -17,55 +17,55 @@ StrBuilder tok_to_strbuilder(Token tok)
return result;
}
bool lex__eat( TokArray* self, TokType type );
bool lex__eat(Context* ctx, ParseContext* self, TokType type );
Token* lex_current(TokArray* self, bool skip_formatting )
Token* lex_current(ParseContext* self, bool skip_formatting )
{
if ( skip_formatting )
{
while ( self->Arr[self->Idx].Type == Tok_NewLine || self->Arr[self->Idx].Type == Tok_Comment )
self->Idx++;
while ( self->tokens.ptr[self->token_id].Type == Tok_NewLine || self->tokens.ptr[self->token_id].Type == Tok_Comment )
self->token_id++;
}
return & self->Arr[self->Idx];
return & self->tokens.ptr[self->token_id];
}
Token* lex_peek(TokArray self, bool skip_formatting)
Token* lex_peek(ParseContext const* self, bool skip_formatting)
{
s32 idx = self.Idx;
s32 idx = self->token_id;
if ( skip_formatting )
{
while ( self.Arr[idx].Type == Tok_NewLine )
while ( self->tokens.ptr[idx].Type == Tok_NewLine )
idx++;
return & self.Arr[idx];
return & self->tokens.ptr[idx];
}
return & self.Arr[idx];
return & self->tokens.ptr[idx];
}
Token* lex_previous(TokArray self, bool skip_formatting)
Token* lex_previous(ParseContext const* self, bool skip_formatting)
{
s32 idx = self.Idx;
s32 idx = self->token_id;
if ( skip_formatting )
{
while ( self.Arr[idx].Type == Tok_NewLine )
while ( self->tokens.ptr[idx].Type == Tok_NewLine )
idx --;
return & self.Arr[idx];
return & self->tokens.ptr[idx];
}
return & self.Arr[idx - 1];
return & self->tokens.ptr[idx - 1];
}
Token* lex_next(TokArray self, bool skip_formatting)
Token* lex_next(ParseContext const* self, bool skip_formatting)
{
s32 idx = self.Idx;
s32 idx = self->token_id;
if ( skip_formatting )
{
while ( self.Arr[idx].Type == Tok_NewLine )
while ( self->tokens.ptr[idx].Type == Tok_NewLine )
idx++;
return & self.Arr[idx + 1];
return & self->tokens.ptr[idx + 1];
}
return & self.Arr[idx + 1];
return & self->tokens.ptr[idx + 1];
}
enum
@ -137,7 +137,7 @@ s32 lex_preprocessor_define( LexContext* ctx )
);
// GEN_DEBUG_TRAP();
}
array_append( _ctx->Lexer_Tokens, name );
array_append(ctx->tokens, name);
if ( ctx->left && (* ctx->scanner) == '(' )
{
@ -152,7 +152,7 @@ s32 lex_preprocessor_define( LexContext* ctx )
}
Token opening_paren = { { ctx->scanner, 1 }, Tok_Paren_Open, ctx->line, ctx->column, TF_Preprocess };
array_append( _ctx->Lexer_Tokens, opening_paren );
array_append(ctx->tokens, opening_paren);
move_forward();
Token last_parameter = {};
@ -168,7 +168,7 @@ s32 lex_preprocessor_define( LexContext* ctx )
move_forward();
move_forward();
array_append(_ctx->Lexer_Tokens, parameter);
array_append(ctx->tokens, parameter);
skip_whitespace();
last_parameter = parameter;
@ -202,7 +202,7 @@ s32 lex_preprocessor_define( LexContext* ctx )
move_forward();
parameter.Text.Len++;
}
array_append(_ctx->Lexer_Tokens, parameter);
array_append(ctx->tokens, parameter);
skip_whitespace();
last_parameter = parameter;
}
@ -229,7 +229,7 @@ s32 lex_preprocessor_define( LexContext* ctx )
return Lex_ReturnNull;
}
Token comma = { { ctx->scanner, 1 }, Tok_Comma, ctx->line, ctx->column, TF_Preprocess };
array_append(_ctx->Lexer_Tokens, comma);
array_append(ctx->tokens, comma);
move_forward();
}
@ -243,7 +243,7 @@ s32 lex_preprocessor_define( LexContext* ctx )
return Lex_ReturnNull;
}
Token closing_paren = { { ctx->scanner, 1 }, Tok_Paren_Close, ctx->line, ctx->column, TF_Preprocess };
array_append(_ctx->Lexer_Tokens, closing_paren);
array_append(ctx->tokens, closing_paren);
move_forward();
}
else if ( registered_macro && macro_is_functional( * registered_macro) ) {
@ -268,7 +268,7 @@ s32 lex_preprocessor_directive( LexContext* ctx )
{
char const* hash = ctx->scanner;
Token hash_tok = { { hash, 1 }, Tok_Preprocess_Hash, ctx->line, ctx->column, TF_Preprocess };
array_append( _ctx->Lexer_Tokens, hash_tok );
array_append(ctx->tokens, hash_tok);
move_forward();
skip_whitespace();
@ -344,14 +344,14 @@ s32 lex_preprocessor_directive( LexContext* ctx )
ctx->token.Text.Len = ctx->token.Text.Len + ctx->token.Text.Ptr - hash;
ctx->token.Text.Ptr = hash;
array_append( _ctx->Lexer_Tokens, ctx->token );
array_append(ctx->tokens, ctx->token);
return Lex_Continue; // Skip found token, its all handled here.
}
if ( ctx->token.Type == Tok_Preprocess_Else || ctx->token.Type == Tok_Preprocess_EndIf )
{
ctx->token.Flags |= TF_Preprocess_Cond;
array_append( _ctx->Lexer_Tokens, ctx->token );
array_append(ctx->tokens, ctx->token);
end_line();
return Lex_Continue;
}
@ -360,7 +360,7 @@ s32 lex_preprocessor_directive( LexContext* ctx )
ctx->token.Flags |= TF_Preprocess_Cond;
}
array_append( _ctx->Lexer_Tokens, ctx->token );
array_append(ctx->tokens, ctx->token);
skip_whitespace();
@ -411,7 +411,7 @@ s32 lex_preprocessor_directive( LexContext* ctx )
move_forward();
}
array_append( _ctx->Lexer_Tokens, preprocess_content );
array_append(ctx->tokens, preprocess_content);
return Lex_Continue; // Skip found token, its all handled here.
}
@ -475,19 +475,23 @@ s32 lex_preprocessor_directive( LexContext* ctx )
preprocess_content.Text.Len++;
}
array_append( _ctx->Lexer_Tokens, preprocess_content );
array_append(ctx->tokens, preprocess_content);
return Lex_Continue; // Skip found token, its all handled here.
}
void lex_found_token( LexContext* ctx )
{
if ( ctx->token.Type != Tok_Invalid ) {
array_append( _ctx->Lexer_Tokens, ctx->token );
array_append(ctx->tokens, ctx->token);
return;
}
TokType type = str_to_toktype( ctx->token.Text );
if (type == Tok_Preprocess_Define || type == Tok_Preprocess_Include) {
ctx->token.Flags |= TF_Identifier;
}
if (type <= Tok_Access_Public && type >= Tok_Access_Private ) {
ctx->token.Flags |= TF_AccessSpecifier;
}
@ -504,7 +508,7 @@ void lex_found_token( LexContext* ctx )
}
ctx->token.Type = type;
array_append( _ctx->Lexer_Tokens, ctx->token );
array_append(ctx->tokens, ctx->token);
return;
}
if ( ( type <= Tok_Star && type >= Tok_Spec_Alignas)
@ -513,13 +517,13 @@ void lex_found_token( LexContext* ctx )
{
ctx->token.Type = type;
ctx->token.Flags |= TF_Specifier;
array_append( _ctx->Lexer_Tokens, ctx->token );
array_append(ctx->tokens, ctx->token);
return;
}
if ( type != Tok_Invalid )
{
ctx->token.Type = type;
array_append( _ctx->Lexer_Tokens, ctx->token );
array_append(ctx->tokens, ctx->token);
return;
}
@ -557,50 +561,41 @@ void lex_found_token( LexContext* ctx )
ctx->token.Type = Tok_Identifier;
}
array_append( _ctx->Lexer_Tokens, ctx->token );
array_append(ctx->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?
neverinline
// TokArray lex( Array<Token> tokens, Str content )
TokArray lex( Str content )
LexedInfo lex(Context* lib_ctx, Str content)
{
LexContext c; LexContext* ctx = & c;
LexedInfo info = struct_zero(LexedInfo);
LexContext c = struct_zero(LexContext); LexContext* ctx = & c;
c.content = content;
c.left = content.Len;
c.scanner = content.Ptr;
char const* word = c.scanner;
s32 word_length = 0;
c.line = 1;
c.column = 1;
c.tokens = array_init_reserve(Token, lib_ctx->Allocator_DyanmicContainers, lib_ctx->InitSize_LexerTokens );
// TODO(Ed): Re-implement to new constraints:
// 1. Ability to continue on error
// 2. Return a lexed info.
skip_whitespace();
if ( c.left <= 0 )
{
if ( c.left <= 0 ) {
log_failure( "gen::lex: no tokens found (only whitespace provided)" );
TokArray null_array = {};
return null_array;
return info;
}
array_clear(_ctx->Lexer_Tokens);
b32 preprocess_args = true;
while (c.left )
{
#if 0
if (Tokens.num())
{
log_fmt("\nLastTok: %SB", Tokens.back().to_strbuilder());
}
#endif
{
Token thanks_c = { { c.scanner, 0 }, Tok_Invalid, c.line, c.column, TF_Null };
c.token = thanks_c;
}
c.token = struct_init(Token) { { c.scanner, 0 }, Tok_Invalid, c.line, c.column, TF_Null };
bool is_define = false;
@ -619,7 +614,7 @@ TokArray lex( Str content )
c.token.Type = Tok_NewLine;
c.token.Text.Len++;
array_append( _ctx->Lexer_Tokens, c.token );
array_append(c.tokens, c.token);
continue;
}
}
@ -658,7 +653,7 @@ TokArray lex( Str content )
c.token.Text.Len++;
move_forward();
array_append( _ctx->Lexer_Tokens, c.token );
array_append(c.tokens, c.token);
}
}
continue;
@ -666,8 +661,7 @@ TokArray lex( Str content )
case Lex_ReturnNull:
{
TokArray tok_array = {};
return tok_array;
return info;
}
}
}
@ -1115,7 +1109,7 @@ TokArray lex( Str content )
move_forward();
c.token.Text.Len++;
}
array_append( _ctx->Lexer_Tokens, c.token );
array_append(c.tokens, c.token);
continue;
}
else if ( (* ctx->scanner) == '*' )
@ -1151,7 +1145,7 @@ TokArray lex( Str content )
move_forward();
c.token.Text.Len++;
}
array_append( _ctx->Lexer_Tokens, c.token );
array_append(c.tokens, c.token);
// end_line();
continue;
}
@ -1239,14 +1233,14 @@ TokArray lex( Str content )
}
else
{
s32 start = max( 0, array_num(_ctx->Lexer_Tokens) - 100 );
s32 start = max( 0, array_num(c.tokens) - 100 );
log_fmt("\n%d\n", start);
for ( s32 idx = start; idx < array_num(_ctx->Lexer_Tokens); idx++ )
for ( s32 idx = start; idx < array_num(c.tokens); idx++ )
{
log_fmt( "Token %d Type: %s : %.*s\n"
, idx
, toktype_to_str( _ctx->Lexer_Tokens[ idx ].Type ).Ptr
, _ctx->Lexer_Tokens[ idx ].Text.Len, _ctx->Lexer_Tokens[ idx ].Text.Ptr
, toktype_to_str( c.tokens[ idx ].Type ).Ptr
, c.tokens[ idx ].Text.Len, c.tokens[ idx ].Text.Ptr
);
}
@ -1262,7 +1256,7 @@ TokArray lex( Str content )
FoundToken:
{
lex_found_token( ctx );
TokType last_type = array_back(_ctx->Lexer_Tokens)->Type;
TokType last_type = array_back(c.tokens)->Type;
if ( last_type == Tok_Preprocess_Macro_Stmt || last_type == Tok_Preprocess_Macro_Expr )
{
Token thanks_c = { { c.scanner, 0 }, Tok_Invalid, c.line, c.column, TF_Null };
@ -1277,21 +1271,22 @@ TokArray lex( Str content )
c.token.Text.Len++;
move_forward();
array_append( _ctx->Lexer_Tokens, c.token );
array_append(c.tokens, c.token);
continue;
}
}
}
}
if ( array_num(_ctx->Lexer_Tokens) == 0 ) {
if ( array_num(c.tokens) == 0 ) {
log_failure( "Failed to lex any tokens" );
TokArray tok_array = {};
return tok_array;
return info;
}
TokArray result = { _ctx->Lexer_Tokens, 0 };
return result;
info.messages = c.messages;
info.text = content;
info.tokens = struct_init(TokenSlice) { pcast(Token*, c.tokens), scast(s32, array_num(c.tokens)) };
return info;
}
#undef move_forward

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "types.hpp"
#include "gen/ecode.hpp"
#include "gen/ecodetypes.hpp"
#include "gen/eoperator.hpp"
#include "gen/especifier.hpp"
#include "gen/etoktype.hpp"
@ -11,17 +11,18 @@ enum TokFlags : u32
{
TF_Operator = bit(0),
TF_Assign = bit(1),
TF_Preprocess = bit(2),
TF_Preprocess_Cond = bit(3),
TF_Attribute = bit(6),
TF_AccessOperator = bit(7),
TF_AccessSpecifier = bit(8),
TF_Specifier = bit(9),
TF_EndDefinition = bit(10), // Either ; or }
TF_Formatting = bit(11),
TF_Literal = bit(12),
TF_Macro_Functional = bit(13),
TF_Macro_Expects_Body = bit(14),
TF_Identifier = bit(2),
TF_Preprocess = bit(3),
TF_Preprocess_Cond = bit(4),
TF_Attribute = bit(5),
TF_AccessOperator = bit(6),
TF_AccessSpecifier = bit(7),
TF_Specifier = bit(8),
TF_EndDefinition = bit(9), // Either ; or }
TF_Formatting = bit(10),
TF_Literal = bit(11),
TF_Macro_Functional = bit(12),
TF_Macro_Expects_Body = bit(13),
TF_Null = 0,
TF_UnderlyingType = GEN_U32_MAX,
@ -90,36 +91,78 @@ bool tok_is_end_definition(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
{
Array(Token) Arr;
s32 Idx;
};
typedef struct LexerMessage LexerMessage;
struct LexerMessage
{
LexerMessage* next;
Str content;
LogLevel level;
};
struct LexContext
{
LexerMessage* messages;
Str content;
s32 left;
char const* scanner;
s32 line;
s32 column;
// StringTable defines;
Token token;
Array(Token) tokens;
};
struct StackNode
struct LexedInfo
{
StackNode* Prev;
LexerMessage* messages;
Str text;
TokenSlice tokens;
};
Token* Start;
Str Name; // The name of the AST node (if parsed)
Str ProcName; // The name of the procedure
typedef struct ParseStackNode ParseStackNode;
typedef struct ParseMessage ParseMessage;
struct ParseMessage
{
ParseMessage* Next;
ParseStackNode* Scope;
Str Content;
LogLevel Level;
};
struct ParseContext
{
TokArray Tokens;
StackNode* Scope;
ParseMessage* messages;
ParseStackNode* scope;
// TokArray Tokens;
TokenSlice tokens;
s32 token_id;
};
enum MacroType : u16
@ -167,26 +210,36 @@ Str macrotype_to_str( MacroType type )
enum EMacroFlags : u16
{
MF_Functional = bit(0), // Macro has parameters (args expected to be passed)
MF_Expects_Body = bit(1), // Expects to assign a braced scope to its body.
// Macro has parameters (args expected to be passed)
MF_Functional = bit(0),
// 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.
// ^^^ 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),
// 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.
// ^^^ 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.
// 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
MF_Allow_As_Attribute = bit(3),
MF_Allow_As_Attribute = bit(4),
// 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. (Yes this is for Unreal Engine)
// It will consume the macro and treat it as resolving the definition.
// (MUST BE OF MT_Statement TYPE)
MF_Allow_As_Definition = bit(4),
MF_Allow_As_Definition = bit(5),
MF_Allow_As_Specifier = bit(5), // Created for Unreal's PURE_VIRTUAL
// Created for Unreal's PURE_VIRTUAL
MF_Allow_As_Specifier = bit(6),
MF_Null = 0,
MF_UnderlyingType = GEN_U16_MAX,

View File

@ -1,6 +1,6 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "../gen.hpp"
#include "interface.hpp"
#endif
#pragma region StaticData

View File

@ -1,6 +1,18 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "header_start.hpp"
#include "dependencies/platform.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
/*
@ -19,7 +31,38 @@
*/
using LogFailType = ssize(*)(char const*, ...);
enum LogLevel //: u32
{
LL_Null,
LL_Note,
LL_Warning,
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];
}
typedef struct LogEntry LogEntry;
struct LogEntry
{
Str msg;
LogLevel level;
};
typedef void LoggerProc(LogEntry entry);
// 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.

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "macros.hpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "printing.hpp"
#endif
@ -17,6 +17,39 @@ template <class TType> struct RemovePtr<TType*> { typedef TType Type; };
template <class TType> using TRemovePtr = typename RemovePtr<TType>::Type;
#pragma region Slice
#if 0
#define Slice(Type) Slice<Type>
template<class Type> struct Slice;
template<class Type>
Type* slice_get(Slice<Type> self, ssize id) {
GEN_ASSERT(id > -1);
GEN_ASSERT(id < self.len);
return self.ptr[id];
}
template<class Type>
struct Slice
{
Type* ptr;
ssize len;
#if GEN_COMPILER_CPP
forceinline operator Token* () const { return ptr; }
forceinline Token& operator[]( ssize index ) const { return ptr[index]; }
forceinline Type* begin() { return ptr; }
forceinline Type* end() { return ptr + len; }
#endif
#if ! GEN_C_LIKE_CPP && GEN_COMPILER_CPP
forceinline Type& back() { return ptr[len - 1]; }
#endif
};
#endif
#pragma endregion Slice
#pragma region Array
#define Array(Type) Array<Type>
@ -26,10 +59,8 @@ template <class TType> using TRemovePtr = typename RemovePtr<TType>::Type;
struct ArrayHeader;
#if GEN_COMPILER_CPP
template<class Type> struct Array;
#define get_array_underlying_type(array) typename TRemovePtr<typeof(array)>:: DataType
#endif
usize array_grow_formula(ssize value);
@ -59,12 +90,12 @@ struct ArrayHeader {
usize Num;
};
#if GEN_COMPILER_CPP
template<class Type>
struct Array
{
Type* Data;
#if ! GEN_C_LIKE_CPP
#pragma region Member Mapping
forceinline static Array init(AllocatorInfo allocator) { return array_init<Type>(allocator); }
forceinline static Array init_reserve(AllocatorInfo allocator, ssize capacity) { return array_init_reserve<Type>(allocator, capacity); }
@ -88,6 +119,7 @@ struct Array
forceinline bool resize(usize num) { return array_resize<Type>(this, num); }
forceinline bool set_capacity(usize new_capacity) { return array_set_capacity<Type>(this, new_capacity); }
#pragma endregion Member Mapping
#endif
forceinline operator Type*() { return Data; }
forceinline operator Type const*() const { return Data; }
@ -99,9 +131,8 @@ struct Array
using DataType = Type;
};
#endif
#if GEN_COMPILER_CPP && 0
#if 0
template<class Type> bool append(Array<Type>& array, Array<Type> other) { return append( & array, other ); }
template<class Type> bool append(Array<Type>& array, Type value) { return append( & array, value ); }
template<class Type> bool append(Array<Type>& array, Type* items, usize item_num) { return append( & array, items, item_num ); }
@ -416,7 +447,7 @@ bool array_set_capacity(Array<Type>* array, usize new_capacity)
// These are intended for use in the base library of gencpp and the C-variant of the library
// It provides a interoperability between the C++ and C implementation of arrays. (not letting these do any crazy substiution though)
// They are undefined in gen.hpp and gen.cpp at the end of the files.
// We cpp library expects the user to use the regular calls as they can resolve the type fine.
// The cpp library expects the user to use the regular calls as they can resolve the type fine.
#define array_init(type, allocator) array_init <type> (allocator )
#define array_init_reserve(type, allocator, cap) array_init_reserve <type> (allocator, cap)

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "src_start.cpp"
#endif

View File

@ -1,9 +1,6 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "dependencies/platform.hpp"
# include "dependencies/macros.hpp"
# include "basic_types.hpp"
# include "macros.hpp"
#endif
#pragma region Debug

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "strings.cpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "strings.hpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "memory.cpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
#pragma once
#include "containers.hpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "platform.hpp"
#endif
@ -26,7 +26,7 @@
#endif // GEN_API
#ifndef global // Global variables
# ifdef GEN_DYN_EXPORT
# if defined(GEN_STATIC_LINK) || defined(GEN_DYN_LINK)
# define global
# else
# define global static
@ -198,21 +198,16 @@
#ifndef forceinline
# if GEN_COMPILER_MSVC
# define forceinline __forceinline
# define neverinline __declspec( noinline )
# elif GEN_COMPILER_GCC
# define forceinline inline __attribute__((__always_inline__))
# define neverinline __attribute__( ( __noinline__ ) )
# elif GEN_COMPILER_CLANG
# if __has_attribute(__always_inline__)
# define forceinline inline __attribute__((__always_inline__))
# define neverinline __attribute__( ( __noinline__ ) )
# else
# define forceinline
# define neverinline
# endif
# else
# define forceinline
# define neverinline
# endif
#endif
@ -303,10 +298,28 @@
# define GEN_PARAM_DEFAULT
#endif
#ifndef struct_init
# if GEN_COMPILER_CPP
#define struct_init(type, value) {value}
# define struct_init(type)
# else
#define struct_init(type, value) {value}
# define struct_init(type) (type)
# endif
#endif
#ifndef struct_zero
# if GEN_COMPILER_CPP
# define struct_zero(type) {}
# else
# define struct_zero(type) (type) {0}
# endif
#endif
#ifndef struct_zero_init
# if GEN_COMPILER_CPP
# define struct_zero_init() {}
# else
# define struct_zero_init() {0}
# endif
#endif
#if 0
@ -319,4 +332,12 @@
# define GEN_OPITMIZE_MAPPINGS_END
#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

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "printing.cpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "debug.hpp"
#endif
@ -134,12 +134,6 @@ GEN_API void* heap_allocator_proc( void* allocator_data, AllocType type, ssize s
//! The heap allocator backed by operating system's memory manager.
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
{
void* data;
@ -185,6 +179,8 @@ void arena_check (Arena* arena);
void arena_free (Arena* arena);
ssize arena_size_remaining(Arena* arena, ssize alignment);
// TODO(Ed): Add arena_pos, arena_pop, and arena_pop_to
struct Arena
{
AllocatorInfo Backing;

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "parsing.hpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "timing.hpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
#endif

View File

@ -1,6 +1,6 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "strbuilder_ops.cpp"
# include "string_ops.cpp"
#endif
#pragma region Printing

View File

@ -1,6 +1,6 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "strbuilder_ops.hpp"
# include "string_ops.hpp"
#endif
#pragma region Printing
@ -26,17 +26,4 @@ GEN_API ssize c_str_fmt_file_va ( FileInfo* f, char const* fmt, va_list va );
constexpr
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

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "header_start.hpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "debug.cpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "memory.hpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "hashing.cpp"
#endif
@ -58,4 +58,120 @@ StrBuilder strbuilder_make_reserve( AllocatorInfo allocator, ssize capacity )
return result;
}
bool strbuilder_make_space_for(StrBuilder* str, char const* to_append, ssize add_len)
{
ssize available = strbuilder_avail_space(* str);
if (available >= add_len) {
return true;
}
else
{
ssize new_len, old_size, new_size;
void* ptr;
void* new_ptr;
AllocatorInfo allocator = strbuilder_get_header(* str)->Allocator;
StrBuilderHeader* header = nullptr;
new_len = strbuilder_grow_formula(strbuilder_length(* str) + add_len);
ptr = strbuilder_get_header(* str);
old_size = size_of(StrBuilderHeader) + strbuilder_length(* str) + 1;
new_size = size_of(StrBuilderHeader) + new_len + 1;
new_ptr = resize(allocator, ptr, old_size, new_size);
if (new_ptr == nullptr)
return false;
header = rcast(StrBuilderHeader*, new_ptr);
header->Allocator = allocator;
header->Capacity = new_len;
char** Data = rcast(char**, str);
* Data = rcast(char*, header + 1);
return true;
}
}
bool strbuilder_append_c_str_len(StrBuilder* str, char const* c_str_to_append, ssize append_length)
{
GEN_ASSERT(str != nullptr);
if ( rcast(sptr, c_str_to_append) > 0)
{
ssize curr_len = strbuilder_length(* str);
if ( ! strbuilder_make_space_for(str, c_str_to_append, append_length))
return false;
StrBuilderHeader* header = strbuilder_get_header(* str);
char* Data = * str;
mem_copy( Data + curr_len, c_str_to_append, append_length);
Data[curr_len + append_length] = '\0';
header->Length = curr_len + append_length;
}
return c_str_to_append != nullptr;
}
void strbuilder_trim(StrBuilder str, char const* cut_set)
{
ssize len = 0;
char* start_pos = str;
char* end_pos = scast(char*, str) + strbuilder_length(str) - 1;
while (start_pos <= end_pos && char_first_occurence(cut_set, *start_pos))
start_pos++;
while (end_pos > start_pos && char_first_occurence(cut_set, *end_pos))
end_pos--;
len = scast(ssize, (start_pos > end_pos) ? 0 : ((end_pos - start_pos) + 1));
if (str != start_pos)
mem_move(str, start_pos, len);
str[len] = '\0';
strbuilder_get_header(str)->Length = len;
}
StrBuilder strbuilder_visualize_whitespace(StrBuilder const str)
{
StrBuilderHeader* header = (StrBuilderHeader*)(scast(char const*, str) - sizeof(StrBuilderHeader));
StrBuilder result = strbuilder_make_reserve(header->Allocator, strbuilder_length(str) * 2); // Assume worst case for space requirements.
for (char const* c = strbuilder_begin(str); c != strbuilder_end(str); c = strbuilder_next(str, c))
switch ( * c )
{
case ' ':
strbuilder_append_str(& result, txt("·"));
break;
case '\t':
strbuilder_append_str(& result, txt(""));
break;
case '\n':
strbuilder_append_str(& result, txt(""));
break;
case '\r':
strbuilder_append_str(& result, txt(""));
break;
case '\v':
strbuilder_append_str(& result, txt(""));
break;
case '\f':
strbuilder_append_str(& result, txt(""));
break;
default:
strbuilder_append_char(& result, * c);
break;
}
return result;
}
#pragma endregion StrBuilder

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "hashing.hpp"
#endif
@ -124,6 +124,10 @@ forceinline usize strbuilder_grow_formula(usize value);
GEN_API StrBuilder strbuilder_make_reserve (AllocatorInfo allocator, ssize capacity);
GEN_API StrBuilder strbuilder_make_length (AllocatorInfo allocator, char const* str, ssize length);
GEN_API bool strbuilder_make_space_for (StrBuilder* str, char const* to_append, ssize add_len);
GEN_API bool strbuilder_append_c_str_len (StrBuilder* str, char const* c_str_to_append, ssize length);
GEN_API void strbuilder_trim (StrBuilder str, char const* cut_set);
GEN_API StrBuilder strbuilder_visualize_whitespace(StrBuilder const str);
StrBuilder strbuilder_make_c_str (AllocatorInfo allocator, char const* str);
StrBuilder strbuilder_make_str (AllocatorInfo allocator, Str str);
@ -132,10 +136,8 @@ StrBuilder strbuilder_fmt_buf (AllocatorInfo allocator, char
StrBuilder strbuilder_join (AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue);
bool strbuilder_are_equal (StrBuilder const lhs, StrBuilder const rhs);
bool strbuilder_are_equal_str (StrBuilder const lhs, Str rhs);
bool strbuilder_make_space_for (StrBuilder* str, char const* to_append, ssize add_len);
bool strbuilder_append_char (StrBuilder* str, char c);
bool strbuilder_append_c_str (StrBuilder* str, char const* c_str_to_append);
bool strbuilder_append_c_str_len (StrBuilder* str, char const* c_str_to_append, ssize length);
bool strbuilder_append_str (StrBuilder* str, Str c_str_to_append);
bool strbuilder_append_string (StrBuilder* str, StrBuilder const other);
bool strbuilder_append_fmt (StrBuilder* str, char const* fmt, ...);
@ -154,9 +156,7 @@ b32 strbuilder_starts_with_string (StrBuilder const str, StrBuild
void strbuilder_skip_line (StrBuilder str);
void strbuilder_strip_space (StrBuilder str);
Str strbuilder_to_str (StrBuilder str);
void strbuilder_trim (StrBuilder str, char const* cut_set);
void strbuilder_trim_space (StrBuilder str);
StrBuilder strbuilder_visualize_whitespace(StrBuilder const str);
struct StrBuilderHeader {
AllocatorInfo Allocator;
@ -320,7 +320,7 @@ inline
StrBuilder strbuilder_fmt_buf(AllocatorInfo allocator, char const* fmt, ...)
{
local_persist thread_local
PrintF_Buffer buf = struct_init(PrintF_Buffer, {0});
PrintF_Buffer buf = struct_zero_init();
va_list va;
va_start(va, fmt);
@ -358,29 +358,6 @@ bool strbuilder_append_c_str(StrBuilder* str, char const* c_str_to_append) {
return strbuilder_append_c_str_len(str, c_str_to_append, c_str_len(c_str_to_append));
}
inline
bool strbuilder_append_c_str_len(StrBuilder* str, char const* c_str_to_append, ssize append_length)
{
GEN_ASSERT(str != nullptr);
if ( rcast(sptr, c_str_to_append) > 0)
{
ssize curr_len = strbuilder_length(* str);
if ( ! strbuilder_make_space_for(str, c_str_to_append, append_length))
return false;
StrBuilderHeader* header = strbuilder_get_header(* str);
char* Data = * str;
mem_copy( Data + curr_len, c_str_to_append, append_length);
Data[curr_len + append_length] = '\0';
header->Length = curr_len + append_length;
}
return c_str_to_append != nullptr;
}
forceinline
bool strbuilder_append_str(StrBuilder* str, Str c_str_to_append) {
GEN_ASSERT(str != nullptr);
@ -522,44 +499,6 @@ ssize strbuilder_length(StrBuilder const str)
return header->Length;
}
inline
bool strbuilder_make_space_for(StrBuilder* str, char const* to_append, ssize add_len)
{
ssize available = strbuilder_avail_space(* str);
if (available >= add_len) {
return true;
}
else
{
ssize new_len, old_size, new_size;
void* ptr;
void* new_ptr;
AllocatorInfo allocator = strbuilder_get_header(* str)->Allocator;
StrBuilderHeader* header = nullptr;
new_len = strbuilder_grow_formula(strbuilder_length(* str) + add_len);
ptr = strbuilder_get_header(* str);
old_size = size_of(StrBuilderHeader) + strbuilder_length(* str) + 1;
new_size = size_of(StrBuilderHeader) + new_len + 1;
new_ptr = resize(allocator, ptr, old_size, new_size);
if (new_ptr == nullptr)
return false;
header = rcast(StrBuilderHeader*, new_ptr);
header->Allocator = allocator;
header->Capacity = new_len;
char** Data = rcast(char**, str);
* Data = rcast(char*, header + 1);
return true;
}
}
forceinline
b32 strbuilder_starts_with_str(StrBuilder const str, Str substring) {
if (substring.Len > strbuilder_length(str))
@ -627,69 +566,11 @@ Str strbuilder_to_str(StrBuilder str) {
return result;
}
inline
void strbuilder_trim(StrBuilder str, char const* cut_set)
{
ssize len = 0;
char* start_pos = str;
char* end_pos = scast(char*, str) + strbuilder_length(str) - 1;
while (start_pos <= end_pos && char_first_occurence(cut_set, *start_pos))
start_pos++;
while (end_pos > start_pos && char_first_occurence(cut_set, *end_pos))
end_pos--;
len = scast(ssize, (start_pos > end_pos) ? 0 : ((end_pos - start_pos) + 1));
if (str != start_pos)
mem_move(str, start_pos, len);
str[len] = '\0';
strbuilder_get_header(str)->Length = len;
}
forceinline
void strbuilder_trim_space(StrBuilder str) {
strbuilder_trim(str, " \t\r\n\v\f");
}
inline
StrBuilder strbuilder_visualize_whitespace(StrBuilder const str)
{
StrBuilderHeader* header = (StrBuilderHeader*)(scast(char const*, str) - sizeof(StrBuilderHeader));
StrBuilder result = strbuilder_make_reserve(header->Allocator, strbuilder_length(str) * 2); // Assume worst case for space requirements.
for (char const* c = strbuilder_begin(str); c != strbuilder_end(str); c = strbuilder_next(str, c))
switch ( * c )
{
case ' ':
strbuilder_append_str(& result, txt("·"));
break;
case '\t':
strbuilder_append_str(& result, txt(""));
break;
case '\n':
strbuilder_append_str(& result, txt(""));
break;
case '\r':
strbuilder_append_str(& result, txt(""));
break;
case '\v':
strbuilder_append_str(& result, txt(""));
break;
case '\f':
strbuilder_append_str(& result, txt(""));
break;
default:
strbuilder_append_char(& result, * c);
break;
}
return result;
}
#pragma endregion StrBuilder
#if GEN_COMPILER_CPP

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "filesystem.cpp"
#endif

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "filesystem.hpp"
#endif

View File

@ -11,9 +11,6 @@
#include "helpers/push_ignores.inline.hpp"
#include "components/header_start.hpp"
// Has container defines pushed
#include "gen.dep.hpp"
GEN_NS_BEGIN
#include "components/types.hpp"
@ -29,9 +26,9 @@ GEN_NS_BEGIN
#include "components/interface.hpp"
#include "components/constants.hpp"
#include "components/inlines.hpp"
#include "components/gen/ast_inlines.hpp"
#include "components/header_end.hpp"
#include "auxiliary/builder.hpp"
#include "auxiliary/scanner.hpp"

View File

@ -1,6 +1,6 @@
#pragma once
#if GEN_INTELLISENSE_DIRECTIVES
#if INTELLISENSE_DIRECTIVES
# include "../gen.hpp"
# include "misc.hpp"

View File

@ -1,6 +1,6 @@
#pragma once
#ifdef GEN_INTELLISENSE_DIRECTIVES
#ifdef INTELLISENSE_DIRECTIVES
# define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
# define GEN_ENFORCE_STRONG_CODE_TYPES
# define GEN_EXPOSE_BACKEND

View File

@ -53,7 +53,7 @@ StrBuilder <prefix>_to_strbuilder(Code code);
Where the first generates strings allocated using Allocator_StringArena and the other appends an existing strings with their backed allocator.
Serialization of for the AST is defined for `Code` in [`ast.cpp`](../base/components/ast.cpp) with `code_to_strbuilder_ptr` & `code_to_strbuilder`.
Serialization of for the AST is defined for `Code` in [`ast.cpp`](../base/components/ast.cpp) with `code_to_strbuilder_ref` & `code_to_strbuilder`.
Serializtion for the rest of the code types is within [`code_serialization.cpp`](../base/components/code_serialization.cpp).
Gencpp's serialization does not provide coherent formatting of the code. The user should use a formatter after serializing.

View File

@ -306,7 +306,7 @@ do \
break;
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_memory, header_memory );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_header_memory, header_memory );
if (found) break;
header_memory.append(entry);
@ -334,7 +334,7 @@ do \
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_printing, header_printing );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_header_printing, header_printing );
if (found) break;
header_printing.append(entry);
@ -391,7 +391,7 @@ do \
case CT_Preprocess_IfDef:
{
ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings );
ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings );
}
break;
@ -472,7 +472,7 @@ do \
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_filesystem, header_filesystem );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_header_filesystem, header_filesystem );
if (found) break;
header_filesystem.append(entry);
@ -509,7 +509,7 @@ do \
case CT_Variable:
{
CodeVar var = cast(CodeVar, entry);
if (var->Specs.has(Spec_Constexpr) > -1)
if (var->Specs.has(Spec_Constexpr))
{
Opts_def_define opts = { {}, entry->Value->Content };
CodeDefine define = def_define(entry->Name, MT_Expression, opts);
@ -532,7 +532,7 @@ do \
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_parsing, header_parsing );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_header_parsing, header_parsing );
if (found) break;
header_parsing.append(entry);
@ -640,7 +640,7 @@ do \
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_types, types );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_types, types );
if (found) break;
types.append(entry);
@ -702,7 +702,7 @@ do \
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_parser_types, parser_types );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_parser_types, parser_types );
if (found) break;
parser_types.append(entry);
@ -769,7 +769,7 @@ do \
case CT_Variable:
{
CodeVar var = cast(CodeVar, entry);
if (var->Specs && var->Specs.has(Spec_Constexpr) > -1) {
if (var->Specs && var->Specs.has(Spec_Constexpr)) {
Code define_ver = untyped_str(token_fmt(
"name", var->Name
, "value", var->Value->Content
@ -797,7 +797,7 @@ do \
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_ast, ast );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_ast, ast );
if (found) break;
found = ignore_preprocess_cond_block(txt("GEN_EXECUTION_EXPRESSION_SUPPORT"), entry, parsed_ast, ast );
@ -978,7 +978,7 @@ R"(#define AST_ArrSpecs_Cap \
++ entry; // Skip a newline...
break;
}
found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_code_types, code_types );
found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_code_types, code_types );
if (found) break;
found = ignore_preprocess_cond_block(txt("GEN_EXECUTION_EXPRESSION_SUPPORT"), entry, parsed_code_types, code_types);
@ -1078,7 +1078,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
case CT_Preprocess_If:
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_ast_types, ast_types );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_ast_types, ast_types );
if (found) break;
found = ignore_preprocess_cond_block(txt("GEN_EXECUTION_EXPRESSION_SUPPORT"), entry, parsed_ast_types, ast_types);
@ -1132,7 +1132,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
case CT_Preprocess_If:
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_interface, interface );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_interface, interface );
if (found) break;
found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_interface, interface);
@ -1159,6 +1159,8 @@ R"(#define <interface_name>( code ) _Generic( (code), \
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();
opt_param->ValueType->Specs = def_specifier(Spec_Ptr);
// Resolve define's arguments
b32 has_args = fn->Params->NumEntries > 1;
StrBuilder params_str = StrBuilder::make_reserve(_ctx->Allocator_Temp, 32);
@ -1172,10 +1174,10 @@ R"(#define <interface_name>( code ) _Generic( (code), \
}
char const* tmpl_fn_macro = nullptr;
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 {
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(
"def_name", fn->Name
@ -1221,7 +1223,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
case CT_Preprocess_If:
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_inlines, inlines );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_inlines, inlines );
if (found) break;
found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_interface, interface);
@ -1257,16 +1259,16 @@ R"(#define <interface_name>( code ) _Generic( (code), \
}
s32 idx = 0;
CodeBody parsed_header_end = parse_file( path_base "components/header_end.hpp" );
CodeBody header_end = def_body(CT_Global_Body);
for ( Code entry = parsed_header_end.begin(); entry != parsed_header_end.end(); ++ entry, ++ idx ) switch( entry->Type )
CodeBody parsed_constants = parse_file( path_base "components/constants.hpp" );
CodeBody constants = def_body(CT_Global_Body);
for ( Code entry = parsed_constants.begin(); entry != parsed_constants.end(); ++ entry, ++ idx ) switch( entry->Type )
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_end, header_end );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_constants, constants );
if (found) break;
header_end.append(entry);
constants.append(entry);
}
break;
@ -1280,16 +1282,16 @@ R"(#define <interface_name>( code ) _Generic( (code), \
{
Opts_def_define opts = { {}, entry->Value->Content };
CodeDefine define = def_define(entry->Name, MT_Expression, opts );
header_end.append(define);
constants.append(define);
continue;
}
}
header_end.append(entry);
constants.append(entry);
}
break;
default:
header_end.append(entry);
constants.append(entry);
break;
}
#pragma endregion Resolve Components
@ -1302,7 +1304,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_builder, header_builder );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_header_builder, header_builder );
if (found) break;
header_builder.append(entry);
@ -1446,7 +1448,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_src_ast, src_ast );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_src_ast, src_ast );
if (found) break;
src_ast.append(entry);
@ -1481,7 +1483,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_src_upfront, src_upfront );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_src_upfront, src_upfront );
if (found) break;
src_upfront.append(entry);
@ -1504,6 +1506,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
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();
fn->Name = cache_str(new_name);
opt_param->ValueType->Specs = def_specifier(Spec_Ptr);
}
src_upfront.append(fn);
}
@ -1520,7 +1523,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_src_lexer, src_lexer );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_src_lexer, src_lexer );
if (found) break;
src_lexer.append(entry);
@ -1542,7 +1545,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
case CT_Variable:
{
CodeVar var = cast(CodeVar, entry);
if (var->Specs && var->Specs.has(Spec_Constexpr) > -1) {
if (var->Specs && var->Specs.has(Spec_Constexpr)) {
Code define_ver = untyped_str(token_fmt(
"name", var->Name
, "value", var->Value->Content
@ -1569,7 +1572,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_src_parser, src_parser );
b32 found = ignore_preprocess_cond_block(txt("INTELLISENSE_DIRECTIVES"), entry, parsed_src_parser, src_parser );
if (found) break;
src_parser.append(entry);
@ -1587,7 +1590,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
case CT_Variable:
{
CodeVar var = cast(CodeVar, entry);
if (var->Specs && var->Specs.has(Spec_Constexpr) > -1) {
if (var->Specs && var->Specs.has(Spec_Constexpr)) {
Code define_ver = untyped_str(token_fmt(
"name", var->Name
, "value", var->Value->Content
@ -1673,11 +1676,11 @@ R"(#define <interface_name>( code ) _Generic( (code), \
Code rf_ast_types = refactor_and_format(ast_types);
Code rf_interface = refactor_and_format(interface);
Code rf_constants = refactor_and_format(constants);
Code rf_inlines = refactor_and_format(inlines);
Code rf_ht_preprocessor_macro = refactor_and_format(ht_preprocessor_macro);
Code rf_array_string_cached = refactor_and_format(array_string_cached);
Code rf_header_end = refactor_and_format(header_end);
Code rf_header_builder = refactor_and_format(header_builder);
Code rf_header_scanner = refactor_and_format( scan_file( path_base "auxiliary/scanner.hpp" ));
@ -1788,6 +1791,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
header.print( rf_ht_preprocessor_macro );
header.print( rf_interface );
header.print( rf_constants );
header.print(fmt_newline);
header.print_fmt("#pragma region Inlines\n");
@ -1796,7 +1800,6 @@ R"(#define <interface_name>( code ) _Generic( (code), \
header.print(fmt_newline);
header.print( rf_header_end );
header.print( rf_header_builder );
header.print( rf_header_scanner );
@ -1882,6 +1885,9 @@ R"(#define <interface_name>( code ) _Generic( (code), \
header.print( r_header_macros );
header.print( header_generic_macros );
header.print_fmt( "\nGEN_API_C_BEGIN\n" );
header.print( r_header_basic_types );
header.print( r_header_debug );
header.print( rf_header_memory );
@ -1895,6 +1901,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
header.print( r_header_timing );
header.print(rf_header_parsing );
header.print_fmt( "\nGEN_API_C_END\n" );
header.print_fmt( "\nGEN_NS_END\n" );
header.write();
}
@ -1949,7 +1956,17 @@ R"(#define <interface_name>( code ) _Generic( (code), \
header.print( rf_ast_types );
header.print_fmt("\n#pragma endregion AST\n");
header.print( fmt_newline);
header.print( rf_array_arena );
header.print( fmt_newline);
header.print( rf_array_pool);
header.print( fmt_newline);
header.print( rf_array_string_cached );
header.print( fmt_newline);
header.print( rf_ht_preprocessor_macro );
header.print( rf_interface );
header.print( rf_constants );
header.print(fmt_newline);
header.print_fmt("#pragma region Inlines\n");
@ -1957,9 +1974,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
header.print_fmt("#pragma endregion Inlines\n");
header.print(fmt_newline);
header.print( rf_array_string_cached );
header.print( rf_header_end );
header.print( rf_header_builder );
header.print( rf_header_scanner );
@ -1976,11 +1991,6 @@ R"(#define <interface_name>( code ) _Generic( (code), \
builder_print( src, src_start );
src.print_fmt( "\nGEN_NS_BEGIN\n");
src.print( fmt_newline);
src.print( rf_array_arena );
src.print( fmt_newline);
src.print( rf_array_pool);
src.print( r_src_static_data );
src.print( fmt_newline);
@ -1998,6 +2008,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
src.print( fmt_newline);
src.print( rf_array_code_typename );
src.print( fmt_newline);
src.print( r_src_parser_case_macros );
src.print( rf_src_parser );
src.print( r_src_parsing );
src.print_fmt( "\n#pragma endregion Parsing\n" );

View File

@ -53,6 +53,7 @@ word enum_underlying, gen_enum_underlying
word nullptr, gen_nullptr
word struct_init, gen_struct_init
word hash, gen_hash
word txt, gen_txt
// Basic Types
@ -410,6 +411,8 @@ namespace var_, gen_var_
word _ctx, gen__ctx
word get_context, gen_get_context
word init, gen_init
word deinit, gen_deinit
word reset, gen_reset
@ -532,7 +535,7 @@ namespace Lexer_, gen_Lexer_
word LexContext, gen_LexContext
word lex, gen_lex
word StackNode, gen_StackNode
word ParseStackNode, gen_ParseStackNode
word ParseContext, gen_ParseContext
// namespace parse_, gen_parse_

View File

@ -13,7 +13,7 @@
| \_____|\___}_l |_|\___} .__/| .__/ {_____/ \__\__/_l\__. |\___/\__,_l \____}{_____}{_____} |
| | | | | __} | |
| l_l l_l {___/ |
! ----------------------------------------------------------------------- VERSION: v0.23-Alpha |
! ----------------------------------------------------------------------- VERSION: v0.25-Alpha |
! ============================================================================================= |
! WARNING: THIS IS AN ALPHA VERSION OF THE LIBRARY, USE AT YOUR OWN DISCRETION |
! NEVER DO CODE GENERATION WITHOUT AT LEAST HAVING CONTENT IN A CODEBASE UNDER VERSION CONTROL |

View File

@ -1,3 +1,6 @@
#define GEN_IMPLEMENTATION
#define GEN_DONT_ENFORCE_GEN_TIME_GUARD
#define GEN_DEFINE_LIBRARY_CORE_CONSTANTS
#define GEN_ENFORCE_STRONG_CODE_TYPES
#define GEN_EXPOSE_BACKEND
#include "gen/gen_singleheader.h"

View File

@ -114,7 +114,7 @@ int gen_main()
}
CodeBody gen_component_header = def_global_body( args(
def_preprocess_cond( PreprocessCond_IfDef, txt("GEN_INTELLISENSE_DIRECTIVES") ),
def_preprocess_cond( PreprocessCond_IfDef, txt("INTELLISENSE_DIRECTIVES") ),
pragma_once,
def_include(txt("components/types.hpp")),
preprocess_endif,
@ -131,8 +131,8 @@ int gen_main()
Code ast_types = scan_file( path_base "components/ast_types.hpp" );
Code code_types = scan_file( path_base "components/code_types.hpp" );
Code interface = scan_file( path_base "components/interface.hpp" );
Code constants = scan_file( path_base "components/constants.hpp");
Code inlines = scan_file( path_base "components/inlines.hpp" );
Code header_end = scan_file( path_base "components/header_end.hpp" );
CodeBody ecode = gen_ecode ( path_base "enums/ECodeTypes.csv" );
CodeBody eoperator = gen_eoperator ( path_base "enums/EOperator.csv" );
@ -168,6 +168,7 @@ int gen_main()
builder_print_fmt( header, "\n#pragma endregion AST\n" );
builder_print( header, interface );
builder_print( header, constants );
builder_print_fmt( header, "\n#pragma region Inlines\n" );
builder_print( header, inlines );
@ -176,7 +177,6 @@ int gen_main()
builder_print( header, fmt_newline );
builder_print_fmt( header, "#pragma endregion Inlines\n" );
builder_print( header, header_end );
builder_print_fmt( header, "\nGEN_NS_END\n\n" );
builder_print( header, pop_ignores );
builder_write(header);

View File

@ -15,7 +15,7 @@
| \_____|\___}_l |_|\___} ,__/| ,__/ (_____/ \__\__/_|\__, |\___}\__,_l |
| Singleheader | | | | __} | |
| l_l l_l {___/ |
! ----------------------------------------------------------------------- VERSION: v0.23-Alpha |
! ----------------------------------------------------------------------- VERSION: v0.25-Alpha |
! ============================================================================================ |
! WARNING: THIS IS AN ALPHA VERSION OF THE LIBRARY, USE AT YOUR OWN DISCRETION |
! NEVER DO CODE GENERATION WITHOUT AT LEAST HAVING CONTENT IN A CODEBASE UNDER VERSION CONTROL |

View File

@ -117,8 +117,8 @@ int gen_main()
Code ast_types = scan_file( path_base "components/ast_types.hpp" );
Code code_types = scan_file( path_base "components/code_types.hpp" );
Code interface = scan_file( path_base "components/interface.hpp" );
Code constants = scan_file( path_base "components/constants.hpp" );
Code inlines = scan_file( path_base "components/inlines.hpp" );
Code header_end = scan_file( path_base "components/header_end.hpp" );
CodeBody ecode = gen_ecode ( path_base "enums/ECodeTypes.csv" );
CodeBody eoperator = gen_eoperator ( path_base "enums/EOperator.csv" );
@ -149,6 +149,7 @@ int gen_main()
header.print_fmt("\n#pragma endregion AST\n");
header.print( interface );
header.print( constants );
header.print_fmt( "\n#pragma region Inlines\n" );
header.print( inlines );
@ -156,8 +157,6 @@ int gen_main()
header.print( fmt_newline );
header.print_fmt( "#pragma endregion Inlines\n" );
header.print( header_end );
if ( generate_builder ) {
header.print( scan_file( path_base "auxiliary/builder.hpp" ) );
}

View File

@ -16,7 +16,7 @@
| \_____|\___}_l |_|\___} ,__/| ,__/ (_____/ \__\__/_|\__, |\___}\__,_l |
| Unreal Engine | | | | __} | |
| l_l l_l {___/ |
! ----------------------------------------------------------------------- VERSION: v0.23-Alpha |
! ----------------------------------------------------------------------- VERSION: v0.25-Alpha |
! ============================================================================================ |
! WARNING: THIS IS AN ALPHA VERSION OF THE LIBRARY, USE AT YOUR OWN DISCRETION |
! NEVER DO CODE GENERATION WITHOUT AT LEAST HAVING CONTENT IN A CODEBASE UNDER VERSION CONTROL |

View File

@ -24,4 +24,5 @@ Final, final
NoExceptions, noexcept
Override, override
Pure, = 0
Delete, = delete
Volatile, volatile

1 Invalid INVALID
24 NoExceptions noexcept
25 Override override
26 Pure = 0
27 Delete = delete
28 Volatile volatile

View File

@ -224,8 +224,8 @@ int gen_main()
Code ast_types = scan_file( path_base "components/ast_types.hpp" );
Code code_types = scan_file( path_base "components/code_types.hpp" );
Code interface = scan_file( path_base "components/interface.hpp" );
Code constants = scan_file( path_base "components/constants.hpp" );
Code inlines = scan_file( path_base "components/inlines.hpp" );
Code header_end = scan_file( path_base "components/header_end.hpp" );
CodeBody ecode = gen_ecode ( path_base "enums/ECodeTypes.csv" );
CodeBody eoperator = gen_eoperator ( path_base "enums/EOperator.csv" );
@ -266,6 +266,7 @@ int gen_main()
header.print_fmt( "\n#pragma endregion AST\n" );
header.print( interface );
header.print( constants );
header.print_fmt( "\n#pragma region Inlines\n" );
header.print( inlines );
@ -274,7 +275,6 @@ int gen_main()
header.print( fmt_newline );
header.print_fmt( "#pragma endregion Inlines\n" );
header.print( header_end );
header.print_fmt( "\nGEN_NS_END\n\n" );
header.print( pop_ignores );
header.write();

View File

@ -172,7 +172,7 @@ if ( $segmented )
write-host `t $_ -ForegroundColor Green
}
}
write-host "`nBootstrap completed in $($time_taken.TotalMilliseconds) ms"
write-host "`nSegmented completed in $($time_taken.TotalMilliseconds) ms"
}
Pop-Location
}
@ -263,6 +263,7 @@ if ( $c_lib_static )
$compiler_args += $flag_all_c
$compiler_args += $flag_updated_cpp_macro
$compiler_args += $flag_c11
$compiler_args += ($flag_define + 'GEN_STATIC_LINK')
$linker_args = @()
$result = build-simple $path_build $includes $compiler_args $linker_args $unit $path_lib

View File

@ -404,7 +404,7 @@ if ( $vendor -match "msvc" )
$flag_optimize_intrinsics = '/Oi'
$flag_optimized_debug_forceinline = '/d2Obforceinline'
$flag_optimized_debug = '/Zo'
$flag_
# $flag_
# $flag_out_name = '/OUT:'
$flag_path_interm = '/Fo'
$flag_path_debug = '/Fd'
@ -564,6 +564,7 @@ if ( $vendor -match "msvc" )
# Check if output is a static library
if ( $binary -match '\.lib$' )
{
write-host "Running archiver for $binary"
$lib_args = @()
$lib_args += $flag_nologo
$lib_args += $flag_link_win_machine_64

View File

@ -1,4 +1,4 @@
#if GEN_INTELLISENSE_DIRECTIVES
#if INTELLISENSE_DIRECTIVES
#include "../../gen_c_library/gen/gen_singleheader.h"
#endif