mirror of
https://github.com/Ed94/gencpp.git
synced 2025-06-15 03:01:47 -07:00
WIP: Restructuring project
This commit is contained in:
1277
base/components/ast.cpp
Normal file
1277
base/components/ast.cpp
Normal file
File diff suppressed because it is too large
Load Diff
479
base/components/ast.hpp
Normal file
479
base/components/ast.hpp
Normal file
@ -0,0 +1,479 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "types.hpp"
|
||||
#include "gen/ecode.hpp"
|
||||
#include "gen/eoperator.hpp"
|
||||
#include "gen/especifier.hpp"
|
||||
#endif
|
||||
|
||||
/*
|
||||
______ ______ ________ __ __ ______ __
|
||||
/ \ / \| \ | \ | \ / \ | \
|
||||
| ▓▓▓▓▓▓\ ▓▓▓▓▓▓\\▓▓▓▓▓▓▓▓ | ▓▓\ | ▓▓ | ▓▓▓▓▓▓\ ______ ____| ▓▓ ______
|
||||
| ▓▓__| ▓▓ ▓▓___\▓▓ | ▓▓ | ▓▓▓\| ▓▓ | ▓▓ \▓▓/ \ / ▓▓/ \
|
||||
| ▓▓ ▓▓\▓▓ \ | ▓▓ | ▓▓▓▓\ ▓▓ | ▓▓ | ▓▓▓▓▓▓\ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓\
|
||||
| ▓▓▓▓▓▓▓▓_\▓▓▓▓▓▓\ | ▓▓ | ▓▓\▓▓ ▓▓ | ▓▓ __| ▓▓ | ▓▓ ▓▓ | ▓▓ ▓▓ ▓▓
|
||||
| ▓▓ | ▓▓ \__| ▓▓ | ▓▓ | ▓▓ \▓▓▓▓ | ▓▓__/ \ ▓▓__/ ▓▓ ▓▓__| ▓▓ ▓▓▓▓▓▓▓▓
|
||||
| ▓▓ | ▓▓\▓▓ ▓▓ | ▓▓ | ▓▓ \▓▓▓ \▓▓ ▓▓\▓▓ ▓▓\▓▓ ▓▓\▓▓ \
|
||||
\▓▓ \▓▓ \▓▓▓▓▓▓ \▓▓ \▓▓ \▓▓ \▓▓▓▓▓▓ \▓▓▓▓▓▓ \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓
|
||||
*/
|
||||
|
||||
struct AST;
|
||||
struct AST_Body;
|
||||
struct AST_Attributes;
|
||||
struct AST_Comment;
|
||||
struct AST_Constructor;
|
||||
// struct AST_BaseClass;
|
||||
struct AST_Class;
|
||||
struct AST_Define;
|
||||
struct AST_Destructor;
|
||||
struct AST_Enum;
|
||||
struct AST_Exec;
|
||||
struct AST_Extern;
|
||||
struct AST_Include;
|
||||
struct AST_Friend;
|
||||
struct AST_Fn;
|
||||
struct AST_Module;
|
||||
struct AST_NS;
|
||||
struct AST_Operator;
|
||||
struct AST_OpCast;
|
||||
struct AST_Param;
|
||||
struct AST_Pragma;
|
||||
struct AST_PreprocessCond;
|
||||
struct AST_Specifiers;
|
||||
|
||||
#if GEN_EXECUTION_EXPRESSION_SUPPORT
|
||||
struct AST_Expr;
|
||||
struct AST_Expr_Assign;
|
||||
struct AST_Expr_Alignof;
|
||||
struct AST_Expr_Binary;
|
||||
struct AST_Expr_CStyleCast;
|
||||
struct AST_Expr_FunctionalCast;
|
||||
struct AST_Expr_CppCast;
|
||||
struct AST_Expr_ProcCall;
|
||||
struct AST_Expr_Decltype;
|
||||
struct AST_Expr_Comma; // TODO(Ed) : This is a binary op not sure if it needs its own AST...
|
||||
struct AST_Expr_AMS; // Access Member Symbol
|
||||
struct AST_Expr_Sizeof;
|
||||
struct AST_Expr_Subscript;
|
||||
struct AST_Expr_Ternary;
|
||||
struct AST_Expr_UnaryPrefix;
|
||||
struct AST_Expr_UnaryPostfix;
|
||||
struct AST_Expr_Element;
|
||||
|
||||
struct AST_Stmt;
|
||||
struct AST_Stmt_Break;
|
||||
struct AST_Stmt_Case;
|
||||
struct AST_Stmt_Continue;
|
||||
struct AST_Stmt_Decl;
|
||||
struct AST_Stmt_Do;
|
||||
struct AST_Stmt_Expr; // TODO(Ed) : Is this distinction needed? (Should it be a flag instead?)
|
||||
struct AST_Stmt_Else;
|
||||
struct AST_Stmt_If;
|
||||
struct AST_Stmt_For;
|
||||
struct AST_Stmt_Goto;
|
||||
struct AST_Stmt_Label;
|
||||
struct AST_Stmt_Switch;
|
||||
struct AST_Stmt_While;
|
||||
#endif
|
||||
|
||||
struct AST_Struct;
|
||||
struct AST_Template;
|
||||
struct AST_Typename;
|
||||
struct AST_Typedef;
|
||||
struct AST_Union;
|
||||
struct AST_Using;
|
||||
struct AST_Var;
|
||||
|
||||
#if GEN_COMPILER_C
|
||||
typedef AST* Code;
|
||||
#else
|
||||
struct Code;
|
||||
#endif
|
||||
|
||||
#if GEN_COMPILER_C
|
||||
typedef AST_Body* CodeBody;
|
||||
typedef AST_Attributes* CodeAttributes;
|
||||
typedef AST_Comment* CodeComment;
|
||||
typedef AST_Class* CodeClass;
|
||||
typedef AST_Constructor* CodeConstructor;
|
||||
typedef AST_Define* CodeDefine;
|
||||
typedef AST_Destructor* CodeDestructor;
|
||||
typedef AST_Enum* CodeEnum;
|
||||
typedef AST_Exec* CodeExec;
|
||||
typedef AST_Extern* CodeExtern;
|
||||
typedef AST_Include* CodeInclude;
|
||||
typedef AST_Friend* CodeFriend;
|
||||
typedef AST_Fn* CodeFn;
|
||||
typedef AST_Module* CodeModule;
|
||||
typedef AST_NS* CodeNS;
|
||||
typedef AST_Operator* CodeOperator;
|
||||
typedef AST_OpCast* CodeOpCast;
|
||||
typedef AST_Param* CodeParam;
|
||||
typedef AST_PreprocessCond* CodePreprocessCond;
|
||||
typedef AST_Pragma* CodePragma;
|
||||
typedef AST_Specifiers* CodeSpecifiers;
|
||||
#else
|
||||
struct CodeBody;
|
||||
struct CodeAttributes;
|
||||
struct CodeComment;
|
||||
struct CodeClass;
|
||||
struct CodeConstructor;
|
||||
struct CodeDefine;
|
||||
struct CodeDestructor;
|
||||
struct CodeEnum;
|
||||
struct CodeExec;
|
||||
struct CodeExtern;
|
||||
struct CodeInclude;
|
||||
struct CodeFriend;
|
||||
struct CodeFn;
|
||||
struct CodeModule;
|
||||
struct CodeNS;
|
||||
struct CodeOperator;
|
||||
struct CodeOpCast;
|
||||
struct CodeParam;
|
||||
struct CodePreprocessCond;
|
||||
struct CodePragma;
|
||||
struct CodeSpecifiers;
|
||||
#endif
|
||||
|
||||
#if GEN_EXECUTION_EXPRESSION_SUPPORT
|
||||
|
||||
#if GEN_COMPILER_C
|
||||
typedef AST_Expr* CodeExpr;
|
||||
typedef AST_Expr_Assign* CodeExpr_Assign;
|
||||
typedef AST_Expr_Alignof* CodeExpr_Alignof;
|
||||
typedef AST_Expr_Binary* CodeExpr_Binary;
|
||||
typedef AST_Expr_CStyleCast* CodeExpr_CStyleCast;
|
||||
typedef AST_Expr_FunctionalCast* CodeExpr_FunctionalCast;
|
||||
typedef AST_Expr_CppCast* CodeExpr_CppCast;
|
||||
typedef AST_Expr_Element* CodeExpr_Element;
|
||||
typedef AST_Expr_ProcCall* CodeExpr_ProcCall;
|
||||
typedef AST_Expr_Decltype* CodeExpr_Decltype;
|
||||
typedef AST_Expr_Comma* CodeExpr_Comma;
|
||||
typedef AST_Expr_AMS* CodeExpr_AMS; // Access Member Symbol
|
||||
typedef AST_Expr_Sizeof* CodeExpr_Sizeof;
|
||||
typedef AST_Expr_Subscript* CodeExpr_Subscript;
|
||||
typedef AST_Expr_Ternary* CodeExpr_Ternary;
|
||||
typedef AST_Expr_UnaryPrefix* CodeExpr_UnaryPrefix;
|
||||
typedef AST_Expr_UnaryPostfix* CodeExpr_UnaryPostfix;
|
||||
#else
|
||||
struct CodeExpr;
|
||||
struct CodeExpr_Assign;
|
||||
struct CodeExpr_Alignof;
|
||||
struct CodeExpr_Binary;
|
||||
struct CodeExpr_CStyleCast;
|
||||
struct CodeExpr_FunctionalCast;
|
||||
struct CodeExpr_CppCast;
|
||||
struct CodeExpr_Element;
|
||||
struct CodeExpr_ProcCall;
|
||||
struct CodeExpr_Decltype;
|
||||
struct CodeExpr_Comma;
|
||||
struct CodeExpr_AMS; // Access Member Symbol
|
||||
struct CodeExpr_Sizeof;
|
||||
struct CodeExpr_Subscript;
|
||||
struct CodeExpr_Ternary;
|
||||
struct CodeExpr_UnaryPrefix;
|
||||
struct CodeExpr_UnaryPostfix;
|
||||
#endif
|
||||
|
||||
#if GEN_COMPILER_C
|
||||
typedef AST_Stmt* CodeStmt;
|
||||
typedef AST_Stmt_Break* CodeStmt_Break;
|
||||
typedef AST_Stmt_Case* CodeStmt_Case;
|
||||
typedef AST_Stmt_Continue* CodeStmt_Continue;
|
||||
typedef AST_Stmt_Decl* CodeStmt_Decl;
|
||||
typedef AST_Stmt_Do* CodeStmt_Do;
|
||||
typedef AST_Stmt_Expr* CodeStmt_Expr;
|
||||
typedef AST_Stmt_Else* CodeStmt_Else;
|
||||
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_Switch* CodeStmt_Switch;
|
||||
typedef AST_Stmt_While* CodeStmt_While;
|
||||
#else
|
||||
struct CodeStmt;
|
||||
struct CodeStmt_Break;
|
||||
struct CodeStmt_Case;
|
||||
struct CodeStmt_Continue;
|
||||
struct CodeStmt_Decl;
|
||||
struct CodeStmt_Do;
|
||||
struct CodeStmt_Expr;
|
||||
struct CodeStmt_Else;
|
||||
struct CodeStmt_If;
|
||||
struct CodeStmt_For;
|
||||
struct CodeStmt_Goto;
|
||||
struct CodeStmt_Label;
|
||||
struct CodeStmt_Switch;
|
||||
struct CodeStmt_While;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if GEN_COMPILER_C
|
||||
typedef AST_Struct* CodeStruct;
|
||||
typedef AST_Template* CodeTemplate;
|
||||
typedef AST_Typename* CodeTypename;
|
||||
typedef AST_Typedef* CodeTypedef;
|
||||
typedef AST_Union* CodeUnion;
|
||||
typedef AST_Using* CodeUsing;
|
||||
typedef AST_Var* CodeVar;
|
||||
#else
|
||||
struct CodeStruct;
|
||||
struct CodeTemplate;
|
||||
struct CodeTypename;
|
||||
struct CodeTypedef;
|
||||
struct CodeUnion;
|
||||
struct CodeUsing;
|
||||
struct CodeVar;
|
||||
#endif
|
||||
|
||||
#undef Define_Code
|
||||
|
||||
GEN_NS_PARSER_BEGIN
|
||||
|
||||
struct Token;
|
||||
|
||||
GEN_NS_PARSER_END
|
||||
|
||||
#if GEN_COMPILER_CPP
|
||||
// Note(Ed): This is to alleviate an edge case with parsing usings or typedefs where I don't really have it setup
|
||||
// to parse a 'namespace' macro or a type with a macro.
|
||||
// I have ideas for ways to pack that into the typedef/using ast, but for now just keeping it like this
|
||||
#define ParserTokenType GEN_NS_PARSER Token
|
||||
typedef ParserTokenType Token;
|
||||
#undef ParserTokenType
|
||||
#endif
|
||||
|
||||
#if GEN_COMPILER_CPP
|
||||
template< class Type> forceinline Type tmpl_cast( Code self ) { return * rcast( Type*, & self ); }
|
||||
#endif
|
||||
|
||||
#pragma region Code C-Interface
|
||||
|
||||
void code_append (Code code, Code other );
|
||||
StrC code_debug_str (Code code);
|
||||
Code code_duplicate (Code code);
|
||||
Code* code_entry (Code code, u32 idx );
|
||||
bool code_has_entries (Code code);
|
||||
bool code_is_body (Code code);
|
||||
bool code_is_equal (Code code, Code other);
|
||||
bool code_is_valid (Code code);
|
||||
void code_set_global (Code code);
|
||||
String code_to_string (Code self );
|
||||
void code_to_string_ptr(Code self, String* result );
|
||||
StrC code_type_str (Code self );
|
||||
bool code_validate_body(Code self );
|
||||
|
||||
#pragma endregion Code C-Interface
|
||||
|
||||
#if GEN_COMPILER_CPP
|
||||
/*
|
||||
AST* wrapper
|
||||
- Not constantly have to append the '*' as this is written often..
|
||||
- Allows for implicit conversion to any of the ASTs (raw or filtered).
|
||||
*/
|
||||
struct Code
|
||||
{
|
||||
AST* ast;
|
||||
|
||||
# define Using_Code( Typename ) \
|
||||
forceinline StrC debug_str() { return code_debug_str(* this); } \
|
||||
forceinline Code duplicate() { return code_duplicate(* this); } \
|
||||
forceinline bool is_equal( Code other ) { return code_is_equal(* this, other); } \
|
||||
forceinline bool is_body() { return code_is_body(* this); } \
|
||||
forceinline bool is_valid() { return code_is_valid(* this); } \
|
||||
forceinline void set_global() { return code_set_global(* this); }
|
||||
|
||||
# define Using_CodeOps( Typename ) \
|
||||
forceinline Typename& operator = ( Code other ); \
|
||||
forceinline bool operator ==( Code other ) { return (AST*)ast == other.ast; } \
|
||||
forceinline bool operator !=( Code other ) { return (AST*)ast != other.ast; } \
|
||||
forceinline bool operator ==(std::nullptr_t) const { return ast == nullptr; } \
|
||||
forceinline bool operator !=(std::nullptr_t) const { return ast != nullptr; } \
|
||||
operator bool();
|
||||
|
||||
#if ! GEN_C_LIKE_CPP
|
||||
Using_Code( Code );
|
||||
forceinline void append(Code other) { return code_append(* this, other); }
|
||||
forceinline Code* entry(u32 idx) { return code_entry(* this, idx); }
|
||||
forceinline bool has_entries() { return code_has_entries(* this); }
|
||||
forceinline String to_string() { return code_to_string(* this); }
|
||||
forceinline void to_string(String& result) { return code_to_string_ptr(* this, & result); }
|
||||
forceinline StrC type_str() { return code_type_str(* this); }
|
||||
forceinline bool validate_body() { return code_validate_body(*this); }
|
||||
#endif
|
||||
|
||||
Using_CodeOps( Code );
|
||||
forceinline AST* operator ->() { return ast; }
|
||||
|
||||
Code& operator ++();
|
||||
|
||||
// TODO(Ed) : Remove this overload.
|
||||
auto& operator*()
|
||||
{
|
||||
local_persist thread_local
|
||||
Code NullRef = { nullptr };
|
||||
|
||||
if ( ast == nullptr )
|
||||
return NullRef;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef GEN_ENFORCE_STRONG_CODE_TYPES
|
||||
# define operator explicit operator
|
||||
#endif
|
||||
operator CodeBody() const;
|
||||
operator CodeAttributes() const;
|
||||
// operator CodeBaseClass() const;
|
||||
operator CodeComment() const;
|
||||
operator CodeClass() const;
|
||||
operator CodeConstructor() const;
|
||||
operator CodeDefine() const;
|
||||
operator CodeDestructor() const;
|
||||
operator CodeExec() const;
|
||||
operator CodeEnum() const;
|
||||
operator CodeExtern() const;
|
||||
operator CodeInclude() const;
|
||||
operator CodeFriend() const;
|
||||
operator CodeFn() const;
|
||||
operator CodeModule() const;
|
||||
operator CodeNS() const;
|
||||
operator CodeOperator() const;
|
||||
operator CodeOpCast() const;
|
||||
operator CodeParam() const;
|
||||
operator CodePragma() const;
|
||||
operator CodePreprocessCond() const;
|
||||
operator CodeSpecifiers() const;
|
||||
operator CodeStruct() const;
|
||||
operator CodeTemplate() const;
|
||||
operator CodeTypename() const;
|
||||
operator CodeTypedef() const;
|
||||
operator CodeUnion() const;
|
||||
operator CodeUsing() const;
|
||||
operator CodeVar() const;
|
||||
#undef operator
|
||||
};
|
||||
#endif
|
||||
|
||||
#pragma region Statics
|
||||
// Used to identify ASTs that should always be duplicated. (Global constant ASTs)
|
||||
extern Code Code_Global;
|
||||
|
||||
// Used to identify invalid generated code.
|
||||
extern Code Code_Invalid;
|
||||
#pragma endregion Statics
|
||||
|
||||
struct Code_POD
|
||||
{
|
||||
AST* ast;
|
||||
};
|
||||
static_assert( sizeof(Code) == sizeof(Code_POD), "ERROR: Code is not POD" );
|
||||
|
||||
// Desired width of the AST data structure.
|
||||
constexpr int const AST_POD_Size = 128;
|
||||
|
||||
constexpr static
|
||||
int AST_ArrSpecs_Cap =
|
||||
(
|
||||
AST_POD_Size
|
||||
- sizeof(Code)
|
||||
- sizeof(StringCached)
|
||||
- sizeof(Code) * 2
|
||||
- sizeof(Token*)
|
||||
- sizeof(Code)
|
||||
- sizeof(CodeType)
|
||||
- sizeof(ModuleFlag)
|
||||
- sizeof(u32)
|
||||
)
|
||||
/ sizeof(Specifier) - 1;
|
||||
|
||||
/*
|
||||
Simple AST POD with functionality to seralize into C++ syntax.
|
||||
*/
|
||||
struct AST
|
||||
{
|
||||
union {
|
||||
struct
|
||||
{
|
||||
Code InlineCmt; // Class, Constructor, Destructor, Enum, Friend, Functon, Operator, OpCast, Struct, Typedef, Using, Variable
|
||||
Code Attributes; // Class, Enum, Function, Struct, Typedef, Union, Using, Variable
|
||||
Code Specs; // Destructor, Function, Operator, Typename, Variable
|
||||
union {
|
||||
Code InitializerList; // Constructor
|
||||
Code ParentType; // Class, Struct, ParentType->Next has a possible list of interfaces.
|
||||
Code ReturnType; // Function, Operator, Typename
|
||||
Code UnderlyingType; // Enum, Typedef
|
||||
Code ValueType; // Parameter, Variable
|
||||
};
|
||||
union {
|
||||
Code Macro; // Parameter
|
||||
Code BitfieldSize; // Variable (Class/Struct Data Member)
|
||||
Code Params; // Constructor, Function, Operator, Template, Typename
|
||||
Code UnderlyingTypeMacro; // Enum
|
||||
};
|
||||
union {
|
||||
Code ArrExpr; // Typename
|
||||
Code Body; // Class, Constructor, Destructor, Enum, Friend, Function, Namespace, Struct, Union
|
||||
Code Declaration; // Friend, Template
|
||||
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 SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed )
|
||||
Code PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal)
|
||||
};
|
||||
};
|
||||
StringCached Content; // Attributes, Comment, Execution, Include
|
||||
struct {
|
||||
Specifier ArrSpecs[AST_ArrSpecs_Cap]; // Specifiers
|
||||
Code NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used.
|
||||
};
|
||||
};
|
||||
StringCached Name;
|
||||
union {
|
||||
Code Prev;
|
||||
Code Front;
|
||||
Code Last;
|
||||
};
|
||||
union {
|
||||
Code Next;
|
||||
Code Back;
|
||||
};
|
||||
Token* Token; // Reference to starting token, only avaialble if it was derived from parsing.
|
||||
Code Parent;
|
||||
CodeType Type;
|
||||
// CodeFlag CodeFlags;
|
||||
ModuleFlag ModuleFlags;
|
||||
union {
|
||||
b32 IsFunction; // Used by typedef to not serialize the name field.
|
||||
struct {
|
||||
b16 IsParamPack; // Used by typename to know if type should be considered a parameter pack.
|
||||
ETypenameTag TypeTag; // Used by typename to keep track of explicitly declared tags for the identifier (enum, struct, union)
|
||||
};
|
||||
Operator Op;
|
||||
AccessSpec ParentAccess;
|
||||
s32 NumEntries;
|
||||
s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression.
|
||||
};
|
||||
};
|
||||
static_assert( sizeof(AST) == AST_POD_Size, "ERROR: AST is not size of AST_POD_Size" );
|
||||
|
||||
#if GEN_COMPILER_CPP
|
||||
// Uses an implicitly overloaded cast from the AST to the desired code type.
|
||||
// Necessary if the user wants GEN_ENFORCE_STRONG_CODE_TYPES
|
||||
struct InvalidCode_ImplictCaster;
|
||||
#define InvalidCode (InvalidCode_ImplictCaster{})
|
||||
#else
|
||||
#define InvalidCode (void*){ (void*)Code_Invalid }
|
||||
#endif
|
||||
|
||||
#if GEN_COMPILER_CPP
|
||||
struct NullCode_ImplicitCaster;
|
||||
// Used when the its desired when omission is allowed in a definition.
|
||||
#define NullCode (NullCode_ImplicitCaster{})
|
||||
#else
|
||||
#define NullCode nullptr
|
||||
#endif
|
78
base/components/ast_case_macros.cpp
Normal file
78
base/components/ast_case_macros.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
# define GEN_AST_BODY_CLASS_UNALLOWED_TYPES \
|
||||
case CT_PlatformAttributes: \
|
||||
case CT_Class_Body: \
|
||||
case CT_Enum_Body: \
|
||||
case CT_Extern_Linkage: \
|
||||
case CT_Function_Body: \
|
||||
case CT_Function_Fwd: \
|
||||
case CT_Global_Body: \
|
||||
case CT_Namespace: \
|
||||
case CT_Namespace_Body: \
|
||||
case CT_Operator: \
|
||||
case CT_Operator_Fwd: \
|
||||
case CT_Parameters: \
|
||||
case CT_Specifiers: \
|
||||
case CT_Struct_Body: \
|
||||
case CT_Typename:
|
||||
# define GEN_AST_BODY_STRUCT_UNALLOWED_TYPES GEN_AST_BODY_CLASS_UNALLOWED_TYPES
|
||||
|
||||
# define GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES \
|
||||
case CT_Access_Public: \
|
||||
case CT_Access_Protected: \
|
||||
case CT_Access_Private: \
|
||||
case CT_PlatformAttributes: \
|
||||
case CT_Class_Body: \
|
||||
case CT_Enum_Body: \
|
||||
case CT_Extern_Linkage: \
|
||||
case CT_Friend: \
|
||||
case CT_Function_Body: \
|
||||
case CT_Function_Fwd: \
|
||||
case CT_Global_Body: \
|
||||
case CT_Namespace: \
|
||||
case CT_Namespace_Body: \
|
||||
case CT_Operator: \
|
||||
case CT_Operator_Fwd: \
|
||||
case CT_Operator_Member: \
|
||||
case CT_Operator_Member_Fwd: \
|
||||
case CT_Parameters: \
|
||||
case CT_Specifiers: \
|
||||
case CT_Struct_Body: \
|
||||
case CT_Typename:
|
||||
|
||||
# define GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES \
|
||||
case CT_Access_Public: \
|
||||
case CT_Access_Protected: \
|
||||
case CT_Access_Private: \
|
||||
case CT_PlatformAttributes: \
|
||||
case CT_Class_Body: \
|
||||
case CT_Enum_Body: \
|
||||
case CT_Execution: \
|
||||
case CT_Friend: \
|
||||
case CT_Function_Body: \
|
||||
case CT_Namespace_Body: \
|
||||
case CT_Operator_Member: \
|
||||
case CT_Operator_Member_Fwd: \
|
||||
case CT_Parameters: \
|
||||
case CT_Specifiers: \
|
||||
case CT_Struct_Body: \
|
||||
case CT_Typename:
|
||||
# define GEN_AST_BODY_EXPORT_UNALLOWED_TYPES GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES
|
||||
# define GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES
|
||||
|
||||
# define GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES \
|
||||
case CT_Access_Public: \
|
||||
case CT_Access_Protected: \
|
||||
case CT_Access_Private: \
|
||||
case CT_PlatformAttributes: \
|
||||
case CT_Class_Body: \
|
||||
case CT_Enum_Body: \
|
||||
case CT_Execution: \
|
||||
case CT_Friend: \
|
||||
case CT_Function_Body: \
|
||||
case CT_Namespace_Body: \
|
||||
case CT_Operator_Member: \
|
||||
case CT_Operator_Member_Fwd: \
|
||||
case CT_Parameters: \
|
||||
case CT_Specifiers: \
|
||||
case CT_Struct_Body: \
|
||||
case CT_Typename:
|
1147
base/components/ast_types.hpp
Normal file
1147
base/components/ast_types.hpp
Normal file
File diff suppressed because it is too large
Load Diff
1492
base/components/code_serialization.cpp
Normal file
1492
base/components/code_serialization.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1130
base/components/code_types.hpp
Normal file
1130
base/components/code_types.hpp
Normal file
File diff suppressed because it is too large
Load Diff
965
base/components/gen/ast_inlines.hpp
Normal file
965
base/components/gen/ast_inlines.hpp
Normal file
@ -0,0 +1,965 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "components/types.hpp"
|
||||
#endif
|
||||
|
||||
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
|
||||
|
||||
#pragma region generated code inline implementation
|
||||
|
||||
inline Code& Code::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Code::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeBody& CodeBody::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeBody::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeAttributes& CodeAttributes::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeAttributes::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeAttributes::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_Attributes* CodeAttributes::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodeComment& CodeComment::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeComment::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeComment::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_Comment* CodeComment::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodeConstructor& CodeConstructor::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeConstructor::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeConstructor::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_Constructor* CodeConstructor::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodeClass& CodeClass::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeClass::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeDefine& CodeDefine::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeDefine::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeDefine::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_Define* CodeDefine::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodeDestructor& CodeDestructor::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeDestructor::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeDestructor::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_Destructor* CodeDestructor::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodeEnum& CodeEnum::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeEnum::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeEnum::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_Enum* CodeEnum::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodeExec& CodeExec::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeExec::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeExec::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_Exec* CodeExec::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodeExtern& CodeExtern::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeExtern::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeExtern::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_Extern* CodeExtern::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodeFriend& CodeFriend::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeFriend::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeFriend::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_Friend* CodeFriend::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodeFn& CodeFn::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeFn::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeFn::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_Fn* CodeFn::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodeInclude& CodeInclude::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeInclude::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeInclude::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_Include* CodeInclude::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodeModule& CodeModule::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeModule::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeModule::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_Module* CodeModule::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodeNS& CodeNS::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeNS::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeNS::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_NS* CodeNS::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodeOperator& CodeOperator::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeOperator::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeOperator::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_Operator* CodeOperator::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodeOpCast& CodeOpCast::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeOpCast::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeOpCast::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_OpCast* CodeOpCast::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodeParam& CodeParam::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeParam::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodePragma& CodePragma::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodePragma::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodePragma::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_Pragma* CodePragma::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodePreprocessCond& CodePreprocessCond::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodePreprocessCond::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodePreprocessCond::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_PreprocessCond* CodePreprocessCond::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodeSpecifiers& CodeSpecifiers::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeSpecifiers::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeStruct& CodeStruct::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeStruct::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeTemplate& CodeTemplate::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeTemplate::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeTemplate::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_Template* CodeTemplate::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodeTypename& CodeTypename::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeTypename::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeTypename::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_Typename* CodeTypename::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodeTypedef& CodeTypedef::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeTypedef::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeTypedef::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_Typedef* CodeTypedef::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodeUnion& CodeUnion::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeUnion::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeUnion::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_Union* CodeUnion::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodeUsing& CodeUsing::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeUsing::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeUsing::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_Using* CodeUsing::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
inline CodeVar& CodeVar::operator=( Code other )
|
||||
{
|
||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||
{
|
||||
ast = rcast( decltype( ast ), code_duplicate( other ).ast );
|
||||
ast->Parent = { nullptr };
|
||||
}
|
||||
ast = rcast( decltype( ast ), other.ast );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CodeVar::operator bool()
|
||||
{
|
||||
return ast != nullptr;
|
||||
}
|
||||
|
||||
inline CodeVar::operator Code()
|
||||
{
|
||||
return *rcast( Code*, this );
|
||||
}
|
||||
|
||||
inline AST_Var* CodeVar::operator->()
|
||||
{
|
||||
if ( ast == nullptr )
|
||||
{
|
||||
log_failure( "Attempt to dereference a nullptr!" );
|
||||
return nullptr;
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
#pragma endregion generated code inline implementation
|
||||
|
||||
#pragma region generated AST/Code cast implementation
|
||||
GEN_OPTIMIZE_MAPPINGS_BEGIN
|
||||
|
||||
forceinline Code::operator CodeBody() const
|
||||
{
|
||||
return { (AST_Body*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeAttributes() const
|
||||
{
|
||||
return { (AST_Attributes*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeComment() const
|
||||
{
|
||||
return { (AST_Comment*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeConstructor() const
|
||||
{
|
||||
return { (AST_Constructor*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeClass() const
|
||||
{
|
||||
return { (AST_Class*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeDefine() const
|
||||
{
|
||||
return { (AST_Define*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeDestructor() const
|
||||
{
|
||||
return { (AST_Destructor*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeEnum() const
|
||||
{
|
||||
return { (AST_Enum*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeExec() const
|
||||
{
|
||||
return { (AST_Exec*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeExtern() const
|
||||
{
|
||||
return { (AST_Extern*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeFriend() const
|
||||
{
|
||||
return { (AST_Friend*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeFn() const
|
||||
{
|
||||
return { (AST_Fn*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeInclude() const
|
||||
{
|
||||
return { (AST_Include*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeModule() const
|
||||
{
|
||||
return { (AST_Module*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeNS() const
|
||||
{
|
||||
return { (AST_NS*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeOperator() const
|
||||
{
|
||||
return { (AST_Operator*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeOpCast() const
|
||||
{
|
||||
return { (AST_OpCast*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeParam() const
|
||||
{
|
||||
return { (AST_Param*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodePragma() const
|
||||
{
|
||||
return { (AST_Pragma*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodePreprocessCond() const
|
||||
{
|
||||
return { (AST_PreprocessCond*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeSpecifiers() const
|
||||
{
|
||||
return { (AST_Specifiers*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeStruct() const
|
||||
{
|
||||
return { (AST_Struct*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeTemplate() const
|
||||
{
|
||||
return { (AST_Template*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeTypename() const
|
||||
{
|
||||
return { (AST_Typename*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeTypedef() const
|
||||
{
|
||||
return { (AST_Typedef*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeUnion() const
|
||||
{
|
||||
return { (AST_Union*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeUsing() const
|
||||
{
|
||||
return { (AST_Using*)ast };
|
||||
}
|
||||
|
||||
forceinline Code::operator CodeVar() const
|
||||
{
|
||||
return { (AST_Var*)ast };
|
||||
}
|
||||
|
||||
GEN_OPITMIZE_MAPPINGS_END
|
||||
#pragma endregion generated AST / Code cast implementation
|
219
base/components/gen/ecode.hpp
Normal file
219
base/components/gen/ecode.hpp
Normal file
@ -0,0 +1,219 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "components/types.hpp"
|
||||
#endif
|
||||
|
||||
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
|
||||
|
||||
enum CodeType : u32
|
||||
{
|
||||
CT_Invalid,
|
||||
CT_Untyped,
|
||||
CT_NewLine,
|
||||
CT_Comment,
|
||||
CT_Access_Private,
|
||||
CT_Access_Protected,
|
||||
CT_Access_Public,
|
||||
CT_PlatformAttributes,
|
||||
CT_Class,
|
||||
CT_Class_Fwd,
|
||||
CT_Class_Body,
|
||||
CT_Constructor,
|
||||
CT_Constructor_Fwd,
|
||||
CT_Destructor,
|
||||
CT_Destructor_Fwd,
|
||||
CT_Enum,
|
||||
CT_Enum_Fwd,
|
||||
CT_Enum_Body,
|
||||
CT_Enum_Class,
|
||||
CT_Enum_Class_Fwd,
|
||||
CT_Execution,
|
||||
CT_Export_Body,
|
||||
CT_Extern_Linkage,
|
||||
CT_Extern_Linkage_Body,
|
||||
CT_Friend,
|
||||
CT_Function,
|
||||
CT_Function_Fwd,
|
||||
CT_Function_Body,
|
||||
CT_Global_Body,
|
||||
CT_Module,
|
||||
CT_Namespace,
|
||||
CT_Namespace_Body,
|
||||
CT_Operator,
|
||||
CT_Operator_Fwd,
|
||||
CT_Operator_Member,
|
||||
CT_Operator_Member_Fwd,
|
||||
CT_Operator_Cast,
|
||||
CT_Operator_Cast_Fwd,
|
||||
CT_Parameters,
|
||||
CT_Preprocess_Define,
|
||||
CT_Preprocess_Include,
|
||||
CT_Preprocess_If,
|
||||
CT_Preprocess_IfDef,
|
||||
CT_Preprocess_IfNotDef,
|
||||
CT_Preprocess_ElIf,
|
||||
CT_Preprocess_Else,
|
||||
CT_Preprocess_EndIf,
|
||||
CT_Preprocess_Pragma,
|
||||
CT_Specifiers,
|
||||
CT_Struct,
|
||||
CT_Struct_Fwd,
|
||||
CT_Struct_Body,
|
||||
CT_Template,
|
||||
CT_Typedef,
|
||||
CT_Typename,
|
||||
CT_Union,
|
||||
CT_Union_Fwd,
|
||||
CT_Union_Body,
|
||||
CT_Using,
|
||||
CT_Using_Namespace,
|
||||
CT_Variable,
|
||||
CT_NumTypes,
|
||||
CT_UnderlyingType = GEN_U32_MAX
|
||||
};
|
||||
|
||||
inline StrC codetype_to_str( CodeType type )
|
||||
{
|
||||
local_persist StrC lookup[61] = {
|
||||
{ sizeof( "Invalid" ), "Invalid" },
|
||||
{ sizeof( "Untyped" ), "Untyped" },
|
||||
{ sizeof( "NewLine" ), "NewLine" },
|
||||
{ sizeof( "Comment" ), "Comment" },
|
||||
{ sizeof( "Access_Private" ), "Access_Private" },
|
||||
{ sizeof( "Access_Protected" ), "Access_Protected" },
|
||||
{ sizeof( "Access_Public" ), "Access_Public" },
|
||||
{ sizeof( "PlatformAttributes" ), "PlatformAttributes" },
|
||||
{ sizeof( "Class" ), "Class" },
|
||||
{ sizeof( "Class_Fwd" ), "Class_Fwd" },
|
||||
{ sizeof( "Class_Body" ), "Class_Body" },
|
||||
{ sizeof( "Constructor" ), "Constructor" },
|
||||
{ sizeof( "Constructor_Fwd" ), "Constructor_Fwd" },
|
||||
{ sizeof( "Destructor" ), "Destructor" },
|
||||
{ sizeof( "Destructor_Fwd" ), "Destructor_Fwd" },
|
||||
{ sizeof( "Enum" ), "Enum" },
|
||||
{ sizeof( "Enum_Fwd" ), "Enum_Fwd" },
|
||||
{ sizeof( "Enum_Body" ), "Enum_Body" },
|
||||
{ sizeof( "Enum_Class" ), "Enum_Class" },
|
||||
{ sizeof( "Enum_Class_Fwd" ), "Enum_Class_Fwd" },
|
||||
{ sizeof( "Execution" ), "Execution" },
|
||||
{ sizeof( "Export_Body" ), "Export_Body" },
|
||||
{ sizeof( "Extern_Linkage" ), "Extern_Linkage" },
|
||||
{ sizeof( "Extern_Linkage_Body" ), "Extern_Linkage_Body" },
|
||||
{ sizeof( "Friend" ), "Friend" },
|
||||
{ sizeof( "Function" ), "Function" },
|
||||
{ sizeof( "Function_Fwd" ), "Function_Fwd" },
|
||||
{ sizeof( "Function_Body" ), "Function_Body" },
|
||||
{ sizeof( "Global_Body" ), "Global_Body" },
|
||||
{ sizeof( "Module" ), "Module" },
|
||||
{ sizeof( "Namespace" ), "Namespace" },
|
||||
{ sizeof( "Namespace_Body" ), "Namespace_Body" },
|
||||
{ sizeof( "Operator" ), "Operator" },
|
||||
{ sizeof( "Operator_Fwd" ), "Operator_Fwd" },
|
||||
{ sizeof( "Operator_Member" ), "Operator_Member" },
|
||||
{ sizeof( "Operator_Member_Fwd" ), "Operator_Member_Fwd" },
|
||||
{ sizeof( "Operator_Cast" ), "Operator_Cast" },
|
||||
{ sizeof( "Operator_Cast_Fwd" ), "Operator_Cast_Fwd" },
|
||||
{ sizeof( "Parameters" ), "Parameters" },
|
||||
{ sizeof( "Preprocess_Define" ), "Preprocess_Define" },
|
||||
{ sizeof( "Preprocess_Include" ), "Preprocess_Include" },
|
||||
{ sizeof( "Preprocess_If" ), "Preprocess_If" },
|
||||
{ sizeof( "Preprocess_IfDef" ), "Preprocess_IfDef" },
|
||||
{ sizeof( "Preprocess_IfNotDef" ), "Preprocess_IfNotDef" },
|
||||
{ sizeof( "Preprocess_ElIf" ), "Preprocess_ElIf" },
|
||||
{ sizeof( "Preprocess_Else" ), "Preprocess_Else" },
|
||||
{ sizeof( "Preprocess_EndIf" ), "Preprocess_EndIf" },
|
||||
{ sizeof( "Preprocess_Pragma" ), "Preprocess_Pragma" },
|
||||
{ sizeof( "Specifiers" ), "Specifiers" },
|
||||
{ sizeof( "Struct" ), "Struct" },
|
||||
{ sizeof( "Struct_Fwd" ), "Struct_Fwd" },
|
||||
{ sizeof( "Struct_Body" ), "Struct_Body" },
|
||||
{ sizeof( "Template" ), "Template" },
|
||||
{ sizeof( "Typedef" ), "Typedef" },
|
||||
{ sizeof( "Typename" ), "Typename" },
|
||||
{ sizeof( "Union" ), "Union" },
|
||||
{ sizeof( "Union_Fwd" ), "Union_Fwd" },
|
||||
{ sizeof( "Union_Body" ), "Union_Body" },
|
||||
{ sizeof( "Using" ), "Using" },
|
||||
{ sizeof( "Using_Namespace" ), "Using_Namespace" },
|
||||
{ sizeof( "Variable" ), "Variable" },
|
||||
};
|
||||
return lookup[type];
|
||||
}
|
||||
|
||||
inline StrC codetype_to_keyword_str( CodeType type )
|
||||
{
|
||||
local_persist StrC lookup[61] = {
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "//" ) - 1, "//" },
|
||||
{ sizeof( "private" ) - 1, "private" },
|
||||
{ sizeof( "protected" ) - 1, "protected" },
|
||||
{ sizeof( "public" ) - 1, "public" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "class" ) - 1, "class" },
|
||||
{ sizeof( "clsss" ) - 1, "clsss" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "enum" ) - 1, "enum" },
|
||||
{ sizeof( "enum" ) - 1, "enum" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "enum class" ) - 1, "enum class" },
|
||||
{ sizeof( "enum class" ) - 1, "enum class" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "extern" ) - 1, "extern" },
|
||||
{ sizeof( "extern" ) - 1, "extern" },
|
||||
{ sizeof( "friend" ) - 1, "friend" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "module" ) - 1, "module" },
|
||||
{ sizeof( "namespace" ) - 1, "namespace" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "operator" ) - 1, "operator" },
|
||||
{ sizeof( "operator" ) - 1, "operator" },
|
||||
{ sizeof( "operator" ) - 1, "operator" },
|
||||
{ sizeof( "operator" ) - 1, "operator" },
|
||||
{ sizeof( "operator" ) - 1, "operator" },
|
||||
{ sizeof( "operator" ) - 1, "operator" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "define" ) - 1, "define" },
|
||||
{ sizeof( "include" ) - 1, "include" },
|
||||
{ sizeof( "if" ) - 1, "if" },
|
||||
{ sizeof( "ifdef" ) - 1, "ifdef" },
|
||||
{ sizeof( "ifndef" ) - 1, "ifndef" },
|
||||
{ sizeof( "elif" ) - 1, "elif" },
|
||||
{ sizeof( "else" ) - 1, "else" },
|
||||
{ sizeof( "endif" ) - 1, "endif" },
|
||||
{ sizeof( "pragma" ) - 1, "pragma" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "struct" ) - 1, "struct" },
|
||||
{ sizeof( "struct" ) - 1, "struct" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "template" ) - 1, "template" },
|
||||
{ sizeof( "typedef" ) - 1, "typedef" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "union" ) - 1, "union" },
|
||||
{ sizeof( "union" ) - 1, "union" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
{ sizeof( "using" ) - 1, "using" },
|
||||
{ sizeof( "using namespace" ) - 1, "using namespace" },
|
||||
{ sizeof( "__NA__" ) - 1, "__NA__" },
|
||||
};
|
||||
return lookup[type];
|
||||
}
|
||||
|
||||
forceinline StrC to_str( CodeType type )
|
||||
{
|
||||
return codetype_to_str( type );
|
||||
}
|
||||
|
||||
forceinline StrC to_keyword_str( CodeType type )
|
||||
{
|
||||
return codetype_to_keyword_str( type );
|
||||
}
|
118
base/components/gen/eoperator.hpp
Normal file
118
base/components/gen/eoperator.hpp
Normal file
@ -0,0 +1,118 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "components/types.hpp"
|
||||
#endif
|
||||
|
||||
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
|
||||
|
||||
enum Operator : u32
|
||||
{
|
||||
Op_Invalid,
|
||||
Op_Assign,
|
||||
Op_Assign_Add,
|
||||
Op_Assign_Subtract,
|
||||
Op_Assign_Multiply,
|
||||
Op_Assign_Divide,
|
||||
Op_Assign_Modulo,
|
||||
Op_Assign_BAnd,
|
||||
Op_Assign_BOr,
|
||||
Op_Assign_BXOr,
|
||||
Op_Assign_LShift,
|
||||
Op_Assign_RShift,
|
||||
Op_Increment,
|
||||
Op_Decrement,
|
||||
Op_Unary_Plus,
|
||||
Op_Unary_Minus,
|
||||
Op_UnaryNot,
|
||||
Op_Add,
|
||||
Op_Subtract,
|
||||
Op_Multiply,
|
||||
Op_Divide,
|
||||
Op_Modulo,
|
||||
Op_BNot,
|
||||
Op_BAnd,
|
||||
Op_BOr,
|
||||
Op_BXOr,
|
||||
Op_LShift,
|
||||
Op_RShift,
|
||||
Op_LAnd,
|
||||
Op_LOr,
|
||||
Op_LEqual,
|
||||
Op_LNot,
|
||||
Op_Lesser,
|
||||
Op_Greater,
|
||||
Op_LesserEqual,
|
||||
Op_GreaterEqual,
|
||||
Op_Subscript,
|
||||
Op_Indirection,
|
||||
Op_AddressOf,
|
||||
Op_MemberOfPointer,
|
||||
Op_PtrToMemOfPtr,
|
||||
Op_FunctionCall,
|
||||
Op_Comma,
|
||||
Op_New,
|
||||
Op_NewArray,
|
||||
Op_Delete,
|
||||
Op_DeleteArray,
|
||||
Op_NumOps,
|
||||
Op_UnderlyingType = 0xffffffffu
|
||||
};
|
||||
|
||||
inline StrC operator_to_str( Operator op )
|
||||
{
|
||||
local_persist StrC lookup[47] = {
|
||||
{ sizeof( "INVALID" ), "INVALID" },
|
||||
{ sizeof( "=" ), "=" },
|
||||
{ sizeof( "+=" ), "+=" },
|
||||
{ sizeof( "-=" ), "-=" },
|
||||
{ sizeof( "*=" ), "*=" },
|
||||
{ sizeof( "/=" ), "/=" },
|
||||
{ sizeof( "%=" ), "%=" },
|
||||
{ sizeof( "&=" ), "&=" },
|
||||
{ sizeof( "|=" ), "|=" },
|
||||
{ sizeof( "^=" ), "^=" },
|
||||
{ sizeof( "<<=" ), "<<=" },
|
||||
{ sizeof( ">>=" ), ">>=" },
|
||||
{ sizeof( "++" ), "++" },
|
||||
{ sizeof( "--" ), "--" },
|
||||
{ sizeof( "+" ), "+" },
|
||||
{ sizeof( "-" ), "-" },
|
||||
{ sizeof( "!" ), "!" },
|
||||
{ sizeof( "+" ), "+" },
|
||||
{ sizeof( "-" ), "-" },
|
||||
{ sizeof( "*" ), "*" },
|
||||
{ sizeof( "/" ), "/" },
|
||||
{ sizeof( "%" ), "%" },
|
||||
{ sizeof( "~" ), "~" },
|
||||
{ sizeof( "&" ), "&" },
|
||||
{ sizeof( "|" ), "|" },
|
||||
{ sizeof( "^" ), "^" },
|
||||
{ sizeof( "<<" ), "<<" },
|
||||
{ sizeof( ">>" ), ">>" },
|
||||
{ sizeof( "&&" ), "&&" },
|
||||
{ sizeof( "||" ), "||" },
|
||||
{ sizeof( "==" ), "==" },
|
||||
{ sizeof( "!=" ), "!=" },
|
||||
{ sizeof( "<" ), "<" },
|
||||
{ sizeof( ">" ), ">" },
|
||||
{ sizeof( "<=" ), "<=" },
|
||||
{ sizeof( ">=" ), ">=" },
|
||||
{ sizeof( "[]" ), "[]" },
|
||||
{ sizeof( "*" ), "*" },
|
||||
{ sizeof( "&" ), "&" },
|
||||
{ sizeof( "->" ), "->" },
|
||||
{ sizeof( "->*" ), "->*" },
|
||||
{ sizeof( "()" ), "()" },
|
||||
{ sizeof( "," ), "," },
|
||||
{ sizeof( "new" ), "new" },
|
||||
{ sizeof( "new[]" ), "new[]" },
|
||||
{ sizeof( "delete" ), "delete" },
|
||||
{ sizeof( "delete[]" ), "delete[]" },
|
||||
};
|
||||
return lookup[op];
|
||||
}
|
||||
|
||||
forceinline StrC to_str( Operator op )
|
||||
{
|
||||
return operator_to_str( op );
|
||||
}
|
108
base/components/gen/especifier.hpp
Normal file
108
base/components/gen/especifier.hpp
Normal file
@ -0,0 +1,108 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "components/types.hpp"
|
||||
#endif
|
||||
|
||||
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
|
||||
|
||||
enum Specifier : u32
|
||||
{
|
||||
Spec_Invalid,
|
||||
Spec_Consteval,
|
||||
Spec_Constexpr,
|
||||
Spec_Constinit,
|
||||
Spec_Explicit,
|
||||
Spec_External_Linkage,
|
||||
Spec_ForceInline,
|
||||
Spec_Global,
|
||||
Spec_Inline,
|
||||
Spec_Internal_Linkage,
|
||||
Spec_Local_Persist,
|
||||
Spec_Mutable,
|
||||
Spec_NeverInline,
|
||||
Spec_Ptr,
|
||||
Spec_Ref,
|
||||
Spec_Register,
|
||||
Spec_RValue,
|
||||
Spec_Static,
|
||||
Spec_Thread_Local,
|
||||
Spec_Virtual,
|
||||
Spec_Const,
|
||||
Spec_Final,
|
||||
Spec_NoExceptions,
|
||||
Spec_Override,
|
||||
Spec_Pure,
|
||||
Spec_Volatile,
|
||||
Spec_NumSpecifiers,
|
||||
Spec_UnderlyingType = 0xffffffffu
|
||||
};
|
||||
|
||||
inline StrC spec_to_str( Specifier type )
|
||||
{
|
||||
local_persist StrC lookup[26] = {
|
||||
{ sizeof( "INVALID" ), "INVALID" },
|
||||
{ sizeof( "consteval" ), "consteval" },
|
||||
{ sizeof( "constexpr" ), "constexpr" },
|
||||
{ sizeof( "constinit" ), "constinit" },
|
||||
{ sizeof( "explicit" ), "explicit" },
|
||||
{ sizeof( "extern" ), "extern" },
|
||||
{ sizeof( "forceinline" ), "forceinline" },
|
||||
{ sizeof( "global" ), "global" },
|
||||
{ sizeof( "inline" ), "inline" },
|
||||
{ sizeof( "internal" ), "internal" },
|
||||
{ sizeof( "local_persist" ), "local_persist" },
|
||||
{ sizeof( "mutable" ), "mutable" },
|
||||
{ sizeof( "neverinline" ), "neverinline" },
|
||||
{ sizeof( "*" ), "*" },
|
||||
{ sizeof( "&" ), "&" },
|
||||
{ sizeof( "register" ), "register" },
|
||||
{ sizeof( "&&" ), "&&" },
|
||||
{ sizeof( "static" ), "static" },
|
||||
{ sizeof( "thread_local" ), "thread_local" },
|
||||
{ sizeof( "virtual" ), "virtual" },
|
||||
{ sizeof( "const" ), "const" },
|
||||
{ sizeof( "final" ), "final" },
|
||||
{ sizeof( "noexcept" ), "noexcept" },
|
||||
{ sizeof( "override" ), "override" },
|
||||
{ sizeof( "= 0" ), "= 0" },
|
||||
{ sizeof( "volatile" ), "volatile" },
|
||||
};
|
||||
return lookup[type];
|
||||
}
|
||||
|
||||
inline bool spec_is_trailing( Specifier specifier )
|
||||
{
|
||||
return specifier > Spec_Virtual;
|
||||
}
|
||||
|
||||
inline Specifier strc_to_specifier( StrC str )
|
||||
{
|
||||
local_persist u32 keymap[Spec_NumSpecifiers];
|
||||
do_once_start for ( u32 index = 0; index < Spec_NumSpecifiers; index++ )
|
||||
{
|
||||
StrC enum_str = spec_to_str( (Specifier)index );
|
||||
keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1 );
|
||||
}
|
||||
do_once_end u32 hash = crc32( str.Ptr, str.Len );
|
||||
for ( u32 index = 0; index < Spec_NumSpecifiers; index++ )
|
||||
{
|
||||
if ( keymap[index] == hash )
|
||||
return (Specifier)index;
|
||||
}
|
||||
return Spec_Invalid;
|
||||
}
|
||||
|
||||
forceinline StrC to_str( Specifier spec )
|
||||
{
|
||||
return spec_to_str( spec );
|
||||
}
|
||||
|
||||
forceinline Specifier to_type( StrC str )
|
||||
{
|
||||
return strc_to_specifier( str );
|
||||
}
|
||||
|
||||
forceinline bool is_trailing( Specifier specifier )
|
||||
{
|
||||
return spec_is_trailing( specifier );
|
||||
}
|
235
base/components/gen/etoktype.cpp
Normal file
235
base/components/gen/etoktype.cpp
Normal file
@ -0,0 +1,235 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "components/types.hpp"
|
||||
#endif
|
||||
|
||||
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
|
||||
|
||||
GEN_NS_PARSER_BEGIN
|
||||
|
||||
#define GEN_DEFINE_ATTRIBUTE_TOKENS Entry( Tok_Attribute_API_Export, "GEN_API_Export_Code" ) Entry( Tok_Attribute_API_Import, "GEN_API_Import_Code" )
|
||||
|
||||
enum TokType : u32
|
||||
{
|
||||
Tok_Invalid,
|
||||
Tok_Access_Private,
|
||||
Tok_Access_Protected,
|
||||
Tok_Access_Public,
|
||||
Tok_Access_MemberSymbol,
|
||||
Tok_Access_StaticSymbol,
|
||||
Tok_Ampersand,
|
||||
Tok_Ampersand_DBL,
|
||||
Tok_Assign_Classifer,
|
||||
Tok_Attribute_Open,
|
||||
Tok_Attribute_Close,
|
||||
Tok_BraceCurly_Open,
|
||||
Tok_BraceCurly_Close,
|
||||
Tok_BraceSquare_Open,
|
||||
Tok_BraceSquare_Close,
|
||||
Tok_Capture_Start,
|
||||
Tok_Capture_End,
|
||||
Tok_Comment,
|
||||
Tok_Comment_End,
|
||||
Tok_Comment_Start,
|
||||
Tok_Char,
|
||||
Tok_Comma,
|
||||
Tok_Decl_Class,
|
||||
Tok_Decl_GNU_Attribute,
|
||||
Tok_Decl_MSVC_Attribute,
|
||||
Tok_Decl_Enum,
|
||||
Tok_Decl_Extern_Linkage,
|
||||
Tok_Decl_Friend,
|
||||
Tok_Decl_Module,
|
||||
Tok_Decl_Namespace,
|
||||
Tok_Decl_Operator,
|
||||
Tok_Decl_Struct,
|
||||
Tok_Decl_Template,
|
||||
Tok_Decl_Typedef,
|
||||
Tok_Decl_Using,
|
||||
Tok_Decl_Union,
|
||||
Tok_Identifier,
|
||||
Tok_Module_Import,
|
||||
Tok_Module_Export,
|
||||
Tok_NewLine,
|
||||
Tok_Number,
|
||||
Tok_Operator,
|
||||
Tok_Preprocess_Hash,
|
||||
Tok_Preprocess_Define,
|
||||
Tok_Preprocess_If,
|
||||
Tok_Preprocess_IfDef,
|
||||
Tok_Preprocess_IfNotDef,
|
||||
Tok_Preprocess_ElIf,
|
||||
Tok_Preprocess_Else,
|
||||
Tok_Preprocess_EndIf,
|
||||
Tok_Preprocess_Include,
|
||||
Tok_Preprocess_Pragma,
|
||||
Tok_Preprocess_Content,
|
||||
Tok_Preprocess_Macro,
|
||||
Tok_Preprocess_Unsupported,
|
||||
Tok_Spec_Alignas,
|
||||
Tok_Spec_Const,
|
||||
Tok_Spec_Consteval,
|
||||
Tok_Spec_Constexpr,
|
||||
Tok_Spec_Constinit,
|
||||
Tok_Spec_Explicit,
|
||||
Tok_Spec_Extern,
|
||||
Tok_Spec_Final,
|
||||
Tok_Spec_ForceInline,
|
||||
Tok_Spec_Global,
|
||||
Tok_Spec_Inline,
|
||||
Tok_Spec_Internal_Linkage,
|
||||
Tok_Spec_LocalPersist,
|
||||
Tok_Spec_Mutable,
|
||||
Tok_Spec_NeverInline,
|
||||
Tok_Spec_Override,
|
||||
Tok_Spec_Static,
|
||||
Tok_Spec_ThreadLocal,
|
||||
Tok_Spec_Volatile,
|
||||
Tok_Spec_Virtual,
|
||||
Tok_Star,
|
||||
Tok_Statement_End,
|
||||
Tok_StaticAssert,
|
||||
Tok_String,
|
||||
Tok_Type_Typename,
|
||||
Tok_Type_Unsigned,
|
||||
Tok_Type_Signed,
|
||||
Tok_Type_Short,
|
||||
Tok_Type_Long,
|
||||
Tok_Type_bool,
|
||||
Tok_Type_char,
|
||||
Tok_Type_int,
|
||||
Tok_Type_double,
|
||||
Tok_Type_MS_int8,
|
||||
Tok_Type_MS_int16,
|
||||
Tok_Type_MS_int32,
|
||||
Tok_Type_MS_int64,
|
||||
Tok_Type_MS_W64,
|
||||
Tok_Varadic_Argument,
|
||||
Tok___Attributes_Start,
|
||||
Tok_Attribute_API_Export,
|
||||
Tok_Attribute_API_Import,
|
||||
Tok_NumTokens
|
||||
};
|
||||
|
||||
inline StrC toktype_to_str( TokType type )
|
||||
{
|
||||
local_persist StrC lookup[] = {
|
||||
{ sizeof( "__invalid__" ), "__invalid__" },
|
||||
{ sizeof( "private" ), "private" },
|
||||
{ sizeof( "protected" ), "protected" },
|
||||
{ sizeof( "public" ), "public" },
|
||||
{ sizeof( "." ), "." },
|
||||
{ sizeof( "::" ), "::" },
|
||||
{ sizeof( "&" ), "&" },
|
||||
{ sizeof( "&&" ), "&&" },
|
||||
{ sizeof( ":" ), ":" },
|
||||
{ sizeof( "[[" ), "[[" },
|
||||
{ sizeof( "]]" ), "]]" },
|
||||
{ sizeof( "{" ), "{" },
|
||||
{ sizeof( "}" ), "}" },
|
||||
{ sizeof( "[" ), "[" },
|
||||
{ sizeof( "]" ), "]" },
|
||||
{ sizeof( "(" ), "(" },
|
||||
{ sizeof( ")" ), ")" },
|
||||
{ sizeof( "__comment__" ), "__comment__" },
|
||||
{ sizeof( "__comment_end__" ), "__comment_end__" },
|
||||
{ sizeof( "__comment_start__" ), "__comment_start__" },
|
||||
{ sizeof( "__character__" ), "__character__" },
|
||||
{ sizeof( "," ), "," },
|
||||
{ sizeof( "class" ), "class" },
|
||||
{ sizeof( "__attribute__" ), "__attribute__" },
|
||||
{ sizeof( "__declspec" ), "__declspec" },
|
||||
{ sizeof( "enum" ), "enum" },
|
||||
{ sizeof( "extern" ), "extern" },
|
||||
{ sizeof( "friend" ), "friend" },
|
||||
{ sizeof( "module" ), "module" },
|
||||
{ sizeof( "namespace" ), "namespace" },
|
||||
{ sizeof( "operator" ), "operator" },
|
||||
{ sizeof( "struct" ), "struct" },
|
||||
{ sizeof( "template" ), "template" },
|
||||
{ sizeof( "typedef" ), "typedef" },
|
||||
{ sizeof( "using" ), "using" },
|
||||
{ sizeof( "union" ), "union" },
|
||||
{ sizeof( "__identifier__" ), "__identifier__" },
|
||||
{ sizeof( "import" ), "import" },
|
||||
{ sizeof( "export" ), "export" },
|
||||
{ sizeof( "__new_line__" ), "__new_line__" },
|
||||
{ sizeof( "__number__" ), "__number__" },
|
||||
{ sizeof( "__operator__" ), "__operator__" },
|
||||
{ sizeof( "#" ), "#" },
|
||||
{ sizeof( "define" ), "define" },
|
||||
{ sizeof( "if" ), "if" },
|
||||
{ sizeof( "ifdef" ), "ifdef" },
|
||||
{ sizeof( "ifndef" ), "ifndef" },
|
||||
{ sizeof( "elif" ), "elif" },
|
||||
{ sizeof( "else" ), "else" },
|
||||
{ sizeof( "endif" ), "endif" },
|
||||
{ sizeof( "include" ), "include" },
|
||||
{ sizeof( "pragma" ), "pragma" },
|
||||
{ sizeof( "__macro_content__" ), "__macro_content__" },
|
||||
{ sizeof( "__macro__" ), "__macro__" },
|
||||
{ sizeof( "__unsupported__" ), "__unsupported__" },
|
||||
{ sizeof( "alignas" ), "alignas" },
|
||||
{ sizeof( "const" ), "const" },
|
||||
{ sizeof( "consteval" ), "consteval" },
|
||||
{ sizeof( "constexpr" ), "constexpr" },
|
||||
{ sizeof( "constinit" ), "constinit" },
|
||||
{ sizeof( "explicit" ), "explicit" },
|
||||
{ sizeof( "extern" ), "extern" },
|
||||
{ sizeof( "final" ), "final" },
|
||||
{ sizeof( "forceinline" ), "forceinline" },
|
||||
{ sizeof( "global" ), "global" },
|
||||
{ sizeof( "inline" ), "inline" },
|
||||
{ sizeof( "internal" ), "internal" },
|
||||
{ sizeof( "local_persist" ), "local_persist" },
|
||||
{ sizeof( "mutable" ), "mutable" },
|
||||
{ sizeof( "neverinline" ), "neverinline" },
|
||||
{ sizeof( "override" ), "override" },
|
||||
{ sizeof( "static" ), "static" },
|
||||
{ sizeof( "thread_local" ), "thread_local" },
|
||||
{ sizeof( "volatile" ), "volatile" },
|
||||
{ sizeof( "virtual" ), "virtual" },
|
||||
{ sizeof( "*" ), "*" },
|
||||
{ sizeof( ";" ), ";" },
|
||||
{ sizeof( "static_assert" ), "static_assert" },
|
||||
{ sizeof( "__string__" ), "__string__" },
|
||||
{ sizeof( "typename" ), "typename" },
|
||||
{ sizeof( "unsigned" ), "unsigned" },
|
||||
{ sizeof( "signed" ), "signed" },
|
||||
{ sizeof( "short" ), "short" },
|
||||
{ sizeof( "long" ), "long" },
|
||||
{ sizeof( "bool" ), "bool" },
|
||||
{ sizeof( "char" ), "char" },
|
||||
{ sizeof( "int" ), "int" },
|
||||
{ sizeof( "double" ), "double" },
|
||||
{ sizeof( "__int8" ), "__int8" },
|
||||
{ sizeof( "__int16" ), "__int16" },
|
||||
{ sizeof( "__int32" ), "__int32" },
|
||||
{ sizeof( "__int64" ), "__int64" },
|
||||
{ sizeof( "_W64" ), "_W64" },
|
||||
{ sizeof( "..." ), "..." },
|
||||
{ sizeof( "__attrib_start__" ), "__attrib_start__" },
|
||||
{ sizeof( "GEN_API_Export_Code" ), "GEN_API_Export_Code" },
|
||||
{ sizeof( "GEN_API_Import_Code" ), "GEN_API_Import_Code" },
|
||||
};
|
||||
return lookup[type];
|
||||
}
|
||||
|
||||
inline TokType strc_to_toktype( StrC str )
|
||||
{
|
||||
local_persist u32 keymap[Tok_NumTokens];
|
||||
do_once_start for ( u32 index = 0; index < Tok_NumTokens; index++ )
|
||||
{
|
||||
StrC enum_str = toktype_to_str( (TokType)index );
|
||||
keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1 );
|
||||
}
|
||||
do_once_end u32 hash = crc32( str.Ptr, str.Len );
|
||||
for ( u32 index = 0; index < Tok_NumTokens; index++ )
|
||||
{
|
||||
if ( keymap[index] == hash )
|
||||
return (TokType)index;
|
||||
}
|
||||
return Tok_Invalid;
|
||||
}
|
||||
|
||||
GEN_NS_PARSER_END
|
157
base/components/header_end.hpp
Normal file
157
base/components/header_end.hpp
Normal file
@ -0,0 +1,157 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "inlines.hpp"
|
||||
#include "gen/ast_inlines.hpp"
|
||||
#endif
|
||||
|
||||
#pragma region Constants
|
||||
|
||||
#ifndef GEN_GLOBAL_BUCKET_SIZE
|
||||
# define GEN_GLOBAL_BUCKET_SIZE megabytes(8)
|
||||
#endif
|
||||
#ifndef GEN_CODEPOOL_NUM_BLOCKS
|
||||
# define GEN_CODEPOOL_NUM_BLOCKS kilobytes(16)
|
||||
#endif
|
||||
#ifndef GEN_SIZE_PER_STRING_ARENA
|
||||
# define GEN_SIZE_PER_STRING_ARENA megabytes(1)
|
||||
#endif
|
||||
#ifndef GEN_MAX_COMMENT_LINE_LENGTH
|
||||
# define GEN_MAX_COMMENT_LINE_LENGTH 1024
|
||||
#endif
|
||||
#ifndef GEN_MAX_NAME_LENGTH
|
||||
# define GEN_MAX_NAME_LENGTH 128
|
||||
#endif
|
||||
#ifndef GEN_MAX_UNTYPED_STR_LENGTH
|
||||
# define GEN_MAX_UNTYPED_STR_LENGTH megabytes(1)
|
||||
#endif
|
||||
#ifndef TokenMap_FixedArena
|
||||
# define TokenMap_FixedArena FixedArena_8KB
|
||||
#endif
|
||||
#ifndef GEN_LEX_ALLOCATOR_SIZE
|
||||
# define GEN_LEX_ALLOCATOR_SIZE megabytes(4)
|
||||
#endif
|
||||
#ifndef GEN_BUILDER_STR_BUFFER_RESERVE
|
||||
# define GEN_BUILDER_STR_BUFFER_RESERVE megabytes(2)
|
||||
#endif
|
||||
|
||||
// These constexprs are used for allocation behavior of data structures
|
||||
// or string handling while constructing or serializing.
|
||||
// Change them to suit your needs.
|
||||
|
||||
constexpr s32 InitSize_DataArrays = 16;
|
||||
|
||||
// NOTE: This limits the maximum size of an allocation
|
||||
// If you are generating a string larger than this, increase the size of the bucket here.
|
||||
constexpr usize Global_BucketSize = GEN_GLOBAL_BUCKET_SIZE;
|
||||
constexpr s32 CodePool_NumBlocks = GEN_CODEPOOL_NUM_BLOCKS;
|
||||
constexpr s32 SizePer_StringArena = GEN_SIZE_PER_STRING_ARENA;
|
||||
|
||||
constexpr s32 MaxCommentLineLength = GEN_MAX_COMMENT_LINE_LENGTH;
|
||||
constexpr s32 MaxNameLength = GEN_MAX_NAME_LENGTH;
|
||||
constexpr s32 MaxUntypedStrLength = GEN_MAX_UNTYPED_STR_LENGTH;
|
||||
// constexpr s32 TokenFmt_TokenMap_MemSize = GEN_TOKEN_FMT_TOKEN_MAP_MEM_SIZE;
|
||||
constexpr s32 LexAllocator_Size = GEN_LEX_ALLOCATOR_SIZE;
|
||||
constexpr s32 Builder_StrBufferReserve = GEN_BUILDER_STR_BUFFER_RESERVE;
|
||||
|
||||
extern Code access_public;
|
||||
extern Code access_protected;
|
||||
extern Code access_private;
|
||||
|
||||
extern CodeAttributes attrib_api_export;
|
||||
extern CodeAttributes attrib_api_import;
|
||||
|
||||
extern Code module_global_fragment;
|
||||
extern Code module_private_fragment;
|
||||
|
||||
extern Code fmt_newline;
|
||||
|
||||
extern CodePragma pragma_once;
|
||||
|
||||
extern CodeParam param_varadic;
|
||||
|
||||
extern CodePreprocessCond preprocess_else;
|
||||
extern CodePreprocessCond preprocess_endif;
|
||||
|
||||
extern CodeSpecifiers spec_const;
|
||||
extern CodeSpecifiers spec_consteval;
|
||||
extern CodeSpecifiers spec_constexpr;
|
||||
extern CodeSpecifiers spec_constinit;
|
||||
extern CodeSpecifiers spec_extern_linkage;
|
||||
extern CodeSpecifiers spec_final;
|
||||
extern CodeSpecifiers spec_forceinline;
|
||||
extern CodeSpecifiers spec_global;
|
||||
extern CodeSpecifiers spec_inline;
|
||||
extern CodeSpecifiers spec_internal_linkage;
|
||||
extern CodeSpecifiers spec_local_persist;
|
||||
extern CodeSpecifiers spec_mutable;
|
||||
extern CodeSpecifiers spec_neverinline;
|
||||
extern CodeSpecifiers spec_noexcept;
|
||||
extern CodeSpecifiers spec_override;
|
||||
extern CodeSpecifiers spec_ptr;
|
||||
extern CodeSpecifiers spec_pure;
|
||||
extern CodeSpecifiers spec_ref;
|
||||
extern CodeSpecifiers spec_register;
|
||||
extern CodeSpecifiers spec_rvalue;
|
||||
extern CodeSpecifiers spec_static_member;
|
||||
extern CodeSpecifiers spec_thread_local;
|
||||
extern CodeSpecifiers spec_virtual;
|
||||
extern CodeSpecifiers spec_volatile;
|
||||
|
||||
extern CodeTypename t_empty; // Used with varaidc parameters. (Exposing just in case its useful for another circumstance)
|
||||
extern CodeTypename t_auto;
|
||||
extern CodeTypename t_void;
|
||||
extern CodeTypename t_int;
|
||||
extern CodeTypename t_bool;
|
||||
extern CodeTypename t_char;
|
||||
extern CodeTypename t_wchar_t;
|
||||
extern CodeTypename t_class;
|
||||
extern CodeTypename t_typename;
|
||||
|
||||
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||
// Predefined typename codes. Are set to readonly and are setup during gen::init()
|
||||
|
||||
extern CodeTypename t_b32;
|
||||
|
||||
extern CodeTypename t_s8;
|
||||
extern CodeTypename t_s16;
|
||||
extern CodeTypename t_s32;
|
||||
extern CodeTypename t_s64;
|
||||
|
||||
extern CodeTypename t_u8;
|
||||
extern CodeTypename t_u16;
|
||||
extern CodeTypename t_u32;
|
||||
extern CodeTypename t_u64;
|
||||
|
||||
extern CodeTypename t_ssize;
|
||||
extern CodeTypename t_usize;
|
||||
|
||||
extern CodeTypename t_f32;
|
||||
extern CodeTypename t_f64;
|
||||
#endif
|
||||
|
||||
#pragma endregion Constants
|
||||
|
||||
// Used by the lexer to persistently treat all these identifiers as preprocessor defines.
|
||||
// Populate with strings via gen::get_cached_string.
|
||||
// Functional defines must have format: id( ;at minimum to indicate that the define is only valid with arguments.
|
||||
extern Array(StringCached) PreprocessorDefines;
|
||||
|
||||
#ifdef GEN_EXPOSE_BACKEND
|
||||
// Global allocator used for data with process lifetime.
|
||||
extern AllocatorInfo GlobalAllocator;
|
||||
extern Array(Arena) Global_AllocatorBuckets;
|
||||
|
||||
extern Array(Pool) CodePools;
|
||||
extern Array(Arena) StringArenas;
|
||||
|
||||
extern StringTable StringCache;
|
||||
|
||||
extern Arena LexArena;
|
||||
|
||||
extern AllocatorInfo Allocator_DataArrays;
|
||||
extern AllocatorInfo Allocator_CodePool;
|
||||
extern AllocatorInfo Allocator_Lexer;
|
||||
extern AllocatorInfo Allocator_StringArena;
|
||||
extern AllocatorInfo Allocator_StringTable;
|
||||
extern AllocatorInfo Allocator_TypeTable;
|
||||
#endif
|
32
base/components/header_start.hpp
Normal file
32
base/components/header_start.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
gencpp: An attempt at "simple" staged metaprogramming for c/c++.
|
||||
|
||||
See Readme.md for more information from the project repository.
|
||||
|
||||
Public Address:
|
||||
https://github.com/Ed94/gencpp --------------------------------------------------------------.
|
||||
| _____ _____ _ _ |
|
||||
| / ____) / ____} | | | |
|
||||
| | / ___ ___ _ __ ___ _ __ _ __ | {___ | |__ _ _, __ _, ___ __| | |
|
||||
| | |{_ |/ _ \ '_ \ / __} '_ l| '_ l `\___ \| __/ _` |/ _` |/ _ \/ _` | |
|
||||
| | l__j | ___/ | | | {__; |+l } |+l | ____) | l| (_| | {_| | ___/ (_| | |
|
||||
| \_____|\___}_l |_|\___} ,__/| ,__/ (_____/ \__\__/_|\__, |\___}\__,_l |
|
||||
| | | | | __} | |
|
||||
| l_l l_l {___/ |
|
||||
! ----------------------------------------------------------------------- VERSION: v0.20-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 |
|
||||
! ============================================================================================ /
|
||||
*/
|
||||
#if ! defined(GEN_DONT_ENFORCE_GEN_TIME_GUARD) && ! defined(GEN_TIME)
|
||||
# error Gen.hpp : GEN_TIME not defined
|
||||
#endif
|
||||
|
||||
//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file.
|
||||
// Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
|
||||
#ifndef GEN_ROLL_OWN_DEPENDENCIES
|
||||
# include "gen.dep.hpp"
|
||||
#endif
|
414
base/components/inlines.hpp
Normal file
414
base/components/inlines.hpp
Normal file
@ -0,0 +1,414 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "interface.hpp"
|
||||
#endif
|
||||
|
||||
#pragma region Code
|
||||
inline
|
||||
void code_append( Code self, Code other )
|
||||
{
|
||||
GEN_ASSERT(self);
|
||||
GEN_ASSERT(other);
|
||||
GEN_ASSERT_MSG(self != other, "Attempted to recursively append Code AST to itself.");
|
||||
|
||||
if ( other->Parent != nullptr )
|
||||
other = code_duplicate(other);
|
||||
|
||||
other->Parent = self;
|
||||
|
||||
if ( self->Front == nullptr )
|
||||
{
|
||||
self->Front = other;
|
||||
self->Back = other;
|
||||
|
||||
self->NumEntries++;
|
||||
return;
|
||||
}
|
||||
|
||||
Code
|
||||
Current = self->Back;
|
||||
Current->Next = other;
|
||||
other->Prev = Current;
|
||||
self->Back = other;
|
||||
self->NumEntries++;
|
||||
}
|
||||
inline
|
||||
bool code_is_body(Code self)
|
||||
{
|
||||
GEN_ASSERT(self);
|
||||
switch (self->Type)
|
||||
{
|
||||
case CT_Enum_Body:
|
||||
case CT_Class_Body:
|
||||
case CT_Union_Body:
|
||||
case CT_Export_Body:
|
||||
case CT_Global_Body:
|
||||
case CT_Struct_Body:
|
||||
case CT_Function_Body:
|
||||
case CT_Namespace_Body:
|
||||
case CT_Extern_Linkage_Body:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
inline
|
||||
Code* code_entry( Code self, u32 idx )
|
||||
{
|
||||
GEN_ASSERT(self != nullptr);
|
||||
Code* current = & self->Front;
|
||||
while ( idx >= 0 && current != nullptr )
|
||||
{
|
||||
if ( idx == 0 )
|
||||
return rcast( Code*, current);
|
||||
|
||||
current = & ( * current )->Next;
|
||||
idx--;
|
||||
}
|
||||
|
||||
return rcast( Code*, current);
|
||||
}
|
||||
forceinline
|
||||
bool code_is_valid(Code self)
|
||||
{
|
||||
GEN_ASSERT(self);
|
||||
return self != nullptr && self->Type != CT_Invalid;
|
||||
}
|
||||
forceinline
|
||||
bool code_has_entries(AST* self)
|
||||
{
|
||||
GEN_ASSERT(self);
|
||||
return self->NumEntries > 0;
|
||||
}
|
||||
forceinline
|
||||
void code_set_global(Code self)
|
||||
{
|
||||
if ( self == nullptr )
|
||||
{
|
||||
log_failure("Code::set_global: Cannot set code as global, AST is null!");
|
||||
return;
|
||||
}
|
||||
|
||||
self->Parent = Code_Global;
|
||||
}
|
||||
#if GEN_COMPILER_CPP
|
||||
forceinline
|
||||
Code& Code::operator ++()
|
||||
{
|
||||
if ( ast )
|
||||
ast = ast->Next.ast;
|
||||
|
||||
return * this;
|
||||
}
|
||||
#endif
|
||||
forceinline
|
||||
StrC code_type_str(Code self)
|
||||
{
|
||||
GEN_ASSERT(self != nullptr);
|
||||
return codetype_to_str( self->Type );
|
||||
}
|
||||
#pragma endregion Code
|
||||
|
||||
#pragma region CodeBody
|
||||
inline
|
||||
void body_append( CodeBody self, Code other )
|
||||
{
|
||||
GEN_ASSERT(self);
|
||||
GEN_ASSERT(other);
|
||||
|
||||
if (code_is_body(other)) {
|
||||
body_append_body( self, cast(CodeBody, other) );
|
||||
return;
|
||||
}
|
||||
|
||||
code_append( cast(Code, self), other );
|
||||
}
|
||||
inline
|
||||
void body_append_body( CodeBody self, CodeBody body )
|
||||
{
|
||||
GEN_ASSERT(self);
|
||||
GEN_ASSERT(body);
|
||||
GEN_ASSERT_MSG(self != body, "Attempted to append body to itself.");
|
||||
|
||||
for ( Code entry = begin_CodeBody(body); entry != end_CodeBody(body); entry = next_CodeBody(body, entry) ) {
|
||||
body_append( self, entry );
|
||||
}
|
||||
}
|
||||
inline
|
||||
Code begin_CodeBody( CodeBody body) {
|
||||
GEN_ASSERT(body);
|
||||
if ( body != nullptr )
|
||||
return body->Front;
|
||||
|
||||
return NullCode;
|
||||
}
|
||||
forceinline
|
||||
Code end_CodeBody(CodeBody body ){
|
||||
GEN_ASSERT(body);
|
||||
return body->Back->Next;
|
||||
}
|
||||
inline
|
||||
Code next_CodeBody(CodeBody body, Code entry) {
|
||||
GEN_ASSERT(body);
|
||||
GEN_ASSERT(entry);
|
||||
return entry->Next;
|
||||
}
|
||||
#pragma endregion CodeBody
|
||||
|
||||
#pragma region CodeClass
|
||||
inline
|
||||
void class_add_interface( CodeClass self, CodeTypename type )
|
||||
{
|
||||
GEN_ASSERT(self);
|
||||
GEN_ASSERT(type);
|
||||
CodeTypename possible_slot = self->ParentType;
|
||||
if ( possible_slot != nullptr )
|
||||
{
|
||||
// Were adding an interface to parent type, so we need to make sure the parent type is public.
|
||||
self->ParentAccess = AccessSpec_Public;
|
||||
// If your planning on adding a proper parent,
|
||||
// then you'll need to move this over to ParentType->next and update ParentAccess accordingly.
|
||||
}
|
||||
|
||||
while ( possible_slot != nullptr )
|
||||
{
|
||||
possible_slot = cast(CodeTypename, possible_slot->Next);
|
||||
}
|
||||
|
||||
possible_slot = type;
|
||||
}
|
||||
#pragma endregion CodeClass
|
||||
|
||||
#pragma region CodeParam
|
||||
inline
|
||||
void params_append( CodeParam appendee, CodeParam other )
|
||||
{
|
||||
GEN_ASSERT(appendee);
|
||||
GEN_ASSERT(other);
|
||||
GEN_ASSERT_MSG(appendee != other, "Attempted to append parameter to itself.");
|
||||
Code self = cast(Code, appendee);
|
||||
Code entry = cast(Code, other);
|
||||
|
||||
if ( entry->Parent != nullptr )
|
||||
entry = code_duplicate( entry );
|
||||
|
||||
entry->Parent = self;
|
||||
|
||||
if ( self->Last == nullptr )
|
||||
{
|
||||
self->Last = entry;
|
||||
self->Next = entry;
|
||||
self->NumEntries++;
|
||||
return;
|
||||
}
|
||||
|
||||
self->Last->Next = entry;
|
||||
self->Last = entry;
|
||||
self->NumEntries++;
|
||||
}
|
||||
inline
|
||||
CodeParam params_get(CodeParam self, s32 idx )
|
||||
{
|
||||
GEN_ASSERT(self);
|
||||
CodeParam param = self;
|
||||
do
|
||||
{
|
||||
if ( ++ param != nullptr )
|
||||
return NullCode;
|
||||
|
||||
param = cast(CodeParam, cast(Code, param)->Next);
|
||||
}
|
||||
while ( --idx );
|
||||
|
||||
return param;
|
||||
}
|
||||
forceinline
|
||||
bool params_has_entries(CodeParam self)
|
||||
{
|
||||
GEN_ASSERT(self);
|
||||
return self->NumEntries > 0;
|
||||
}
|
||||
#if GEN_COMPILER_CPP
|
||||
forceinline
|
||||
CodeParam& CodeParam::operator ++()
|
||||
{
|
||||
* this = ast->Next;
|
||||
return * this;
|
||||
}
|
||||
#endif
|
||||
forceinline
|
||||
CodeParam begin_CodeParam(CodeParam params)
|
||||
{
|
||||
if ( params != nullptr )
|
||||
return params;
|
||||
|
||||
return NullCode;
|
||||
}
|
||||
forceinline
|
||||
CodeParam end_CodeParam(CodeParam params)
|
||||
{
|
||||
// return { (AST_Param*) rcast( AST*, ast)->Last };
|
||||
return NullCode;
|
||||
}
|
||||
forceinline
|
||||
CodeParam next_CodeParam(CodeParam params, CodeParam param_iter)
|
||||
{
|
||||
GEN_ASSERT(param_iter);
|
||||
return param_iter->Next;
|
||||
}
|
||||
#pragma endregion CodeParam
|
||||
|
||||
#pragma region CodeSpecifiers
|
||||
inline
|
||||
bool specifiers_append(CodeSpecifiers self, Specifier spec )
|
||||
{
|
||||
if ( self == nullptr )
|
||||
{
|
||||
log_failure("CodeSpecifiers: Attempted to append to a null specifiers AST!");
|
||||
return false;
|
||||
}
|
||||
if ( self->NumEntries == AST_ArrSpecs_Cap )
|
||||
{
|
||||
log_failure("CodeSpecifiers: Attempted to append over %d specifiers to a specifiers AST!", AST_ArrSpecs_Cap );
|
||||
return false;
|
||||
}
|
||||
|
||||
self->ArrSpecs[ self->NumEntries ] = spec;
|
||||
self->NumEntries++;
|
||||
return true;
|
||||
}
|
||||
inline
|
||||
s32 specifiers_has(CodeSpecifiers self, Specifier spec)
|
||||
{
|
||||
GEN_ASSERT(self != nullptr);
|
||||
for ( s32 idx = 0; idx < self->NumEntries; idx++ ) {
|
||||
if ( self->ArrSpecs[ idx ] == spec )
|
||||
return idx;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
inline
|
||||
s32 specifiers_remove( CodeSpecifiers self, Specifier to_remove )
|
||||
{
|
||||
if ( self == nullptr )
|
||||
{
|
||||
log_failure("CodeSpecifiers: Attempted to append to a null specifiers AST!");
|
||||
return -1;
|
||||
}
|
||||
if ( self->NumEntries == AST_ArrSpecs_Cap )
|
||||
{
|
||||
log_failure("CodeSpecifiers: Attempted to append over %d specifiers to a specifiers AST!", AST_ArrSpecs_Cap );
|
||||
return -1;
|
||||
}
|
||||
|
||||
s32 result = -1;
|
||||
|
||||
s32 curr = 0;
|
||||
s32 next = 0;
|
||||
for(; next < self->NumEntries; ++ curr, ++ next)
|
||||
{
|
||||
Specifier spec = self->ArrSpecs[next];
|
||||
if (spec == to_remove)
|
||||
{
|
||||
result = next;
|
||||
|
||||
next ++;
|
||||
if (next >= self->NumEntries)
|
||||
break;
|
||||
|
||||
spec = self->ArrSpecs[next];
|
||||
}
|
||||
|
||||
self->ArrSpecs[ curr ] = spec;
|
||||
}
|
||||
|
||||
if (result > -1) {
|
||||
self->NumEntries --;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
forceinline
|
||||
Specifier* begin_CodeSpecifiers(CodeSpecifiers self)
|
||||
{
|
||||
if ( self != nullptr )
|
||||
return & self->ArrSpecs[0];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
forceinline
|
||||
Specifier* end_CodeSpecifiers(CodeSpecifiers self)
|
||||
{
|
||||
return self->ArrSpecs + self->NumEntries;
|
||||
}
|
||||
forceinline
|
||||
Specifier* next_CodeSpecifiers(CodeSpecifiers self, Specifier* spec_iter)
|
||||
{
|
||||
return spec_iter + 1;
|
||||
}
|
||||
#pragma endregion CodeSpecifiers
|
||||
|
||||
#pragma region CodeStruct
|
||||
inline
|
||||
void struct_add_interface(CodeStruct self, CodeTypename type )
|
||||
{
|
||||
CodeTypename possible_slot = self->ParentType;
|
||||
if ( possible_slot != nullptr )
|
||||
{
|
||||
// Were adding an interface to parent type, so we need to make sure the parent type is public.
|
||||
self->ParentAccess = AccessSpec_Public;
|
||||
// If your planning on adding a proper parent,
|
||||
// then you'll need to move this over to ParentType->next and update ParentAccess accordingly.
|
||||
}
|
||||
|
||||
while ( possible_slot != nullptr )
|
||||
{
|
||||
possible_slot = cast(CodeTypename, possible_slot->Next);
|
||||
}
|
||||
|
||||
possible_slot = type;
|
||||
}
|
||||
#pragma endregion Code
|
||||
|
||||
#pragma region Interface
|
||||
inline
|
||||
CodeBody def_body( CodeType type )
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case CT_Class_Body:
|
||||
case CT_Enum_Body:
|
||||
case CT_Export_Body:
|
||||
case CT_Extern_Linkage:
|
||||
case CT_Function_Body:
|
||||
case CT_Global_Body:
|
||||
case CT_Namespace_Body:
|
||||
case CT_Struct_Body:
|
||||
case CT_Union_Body:
|
||||
break;
|
||||
|
||||
default:
|
||||
log_failure( "def_body: Invalid type %s", codetype_to_str(type).Ptr );
|
||||
return (CodeBody)Code_Invalid;
|
||||
}
|
||||
|
||||
Code
|
||||
result = make_code();
|
||||
result->Type = type;
|
||||
return (CodeBody)result;
|
||||
}
|
||||
|
||||
inline
|
||||
StrC token_fmt_impl( ssize num, ... )
|
||||
{
|
||||
local_persist thread_local
|
||||
char buf[GEN_PRINTF_MAXLEN] = { 0 };
|
||||
mem_set( buf, 0, GEN_PRINTF_MAXLEN );
|
||||
|
||||
va_list va;
|
||||
va_start(va, num );
|
||||
ssize result = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num, va);
|
||||
va_end(va);
|
||||
|
||||
StrC str = { result, buf };
|
||||
return str;
|
||||
}
|
||||
#pragma endregion Interface
|
462
base/components/interface.cpp
Normal file
462
base/components/interface.cpp
Normal file
@ -0,0 +1,462 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "code_serialization.cpp"
|
||||
#endif
|
||||
|
||||
GEN_NS_PARSER_BEGIN
|
||||
internal void parser_init();
|
||||
internal void parser_deinit();
|
||||
GEN_NS_PARSER_END
|
||||
|
||||
internal
|
||||
void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
|
||||
{
|
||||
Arena* last = array_back(Global_AllocatorBuckets);
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case EAllocation_ALLOC:
|
||||
{
|
||||
if ( ( last->TotalUsed + size ) > last->TotalSize )
|
||||
{
|
||||
Arena bucket = arena_init_from_allocator( heap(), Global_BucketSize );
|
||||
|
||||
if ( bucket.PhysicalStart == nullptr )
|
||||
GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets");
|
||||
|
||||
if ( ! array_append( Global_AllocatorBuckets, bucket ) )
|
||||
GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets");
|
||||
|
||||
last = array_back(Global_AllocatorBuckets);
|
||||
}
|
||||
|
||||
return alloc_align( arena_allocator_info(last), size, alignment );
|
||||
}
|
||||
case EAllocation_FREE:
|
||||
{
|
||||
// Doesn't recycle.
|
||||
}
|
||||
break;
|
||||
case EAllocation_FREE_ALL:
|
||||
{
|
||||
// Memory::cleanup instead.
|
||||
}
|
||||
break;
|
||||
case EAllocation_RESIZE:
|
||||
{
|
||||
if ( last->TotalUsed + size > last->TotalSize )
|
||||
{
|
||||
Arena bucket = arena_init_from_allocator( heap(), Global_BucketSize );
|
||||
|
||||
if ( bucket.PhysicalStart == nullptr )
|
||||
GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets");
|
||||
|
||||
if ( ! array_append( Global_AllocatorBuckets, bucket ) )
|
||||
GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets");
|
||||
|
||||
last = array_back(Global_AllocatorBuckets);
|
||||
}
|
||||
|
||||
void* result = alloc_align( last->Backing, size, alignment );
|
||||
|
||||
if ( result != nullptr && old_memory != nullptr )
|
||||
{
|
||||
mem_copy( result, old_memory, old_size );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
internal
|
||||
void define_constants()
|
||||
{
|
||||
Code_Global = make_code();
|
||||
Code_Global->Name = get_cached_string( txt("Global Code") );
|
||||
Code_Global->Content = Code_Global->Name;
|
||||
|
||||
Code_Invalid = make_code();
|
||||
code_set_global(Code_Invalid);
|
||||
|
||||
t_empty = (CodeTypename) make_code();
|
||||
t_empty->Type = CT_Typename;
|
||||
t_empty->Name = get_cached_string( txt("") );
|
||||
code_set_global(cast(Code, t_empty));
|
||||
|
||||
access_private = make_code();
|
||||
access_private->Type = CT_Access_Private;
|
||||
access_private->Name = get_cached_string( txt("private:\n") );
|
||||
code_set_global(cast(Code, access_private));
|
||||
|
||||
access_protected = make_code();
|
||||
access_protected->Type = CT_Access_Protected;
|
||||
access_protected->Name = get_cached_string( txt("protected:\n") );
|
||||
code_set_global(access_protected);
|
||||
|
||||
access_public = make_code();
|
||||
access_public->Type = CT_Access_Public;
|
||||
access_public->Name = get_cached_string( txt("public:\n") );
|
||||
code_set_global(access_public);
|
||||
|
||||
StrC api_export_str = code(GEN_API_Export_Code);
|
||||
attrib_api_export = def_attributes( api_export_str );
|
||||
code_set_global(cast(Code, attrib_api_export));
|
||||
|
||||
StrC api_import_str = code(GEN_API_Import_Code);
|
||||
attrib_api_import = def_attributes( api_import_str );
|
||||
code_set_global(cast(Code, attrib_api_import));
|
||||
|
||||
module_global_fragment = make_code();
|
||||
module_global_fragment->Type = CT_Untyped;
|
||||
module_global_fragment->Name = get_cached_string( txt("module;") );
|
||||
module_global_fragment->Content = module_global_fragment->Name;
|
||||
code_set_global(cast(Code, module_global_fragment));
|
||||
|
||||
module_private_fragment = make_code();
|
||||
module_private_fragment->Type = CT_Untyped;
|
||||
module_private_fragment->Name = get_cached_string( txt("module : private;") );
|
||||
module_private_fragment->Content = module_private_fragment->Name;
|
||||
code_set_global(cast(Code, module_private_fragment));
|
||||
|
||||
fmt_newline = make_code();
|
||||
fmt_newline->Type = CT_NewLine;
|
||||
code_set_global((Code)fmt_newline);
|
||||
|
||||
pragma_once = (CodePragma) make_code();
|
||||
pragma_once->Type = CT_Preprocess_Pragma;
|
||||
pragma_once->Name = get_cached_string( txt("once") );
|
||||
pragma_once->Content = pragma_once->Name;
|
||||
code_set_global((Code)pragma_once);
|
||||
|
||||
param_varadic = (CodeParam) make_code();
|
||||
param_varadic->Type = CT_Parameters;
|
||||
param_varadic->Name = get_cached_string( txt("...") );
|
||||
param_varadic->ValueType = t_empty;
|
||||
code_set_global((Code)param_varadic);
|
||||
|
||||
preprocess_else = (CodePreprocessCond) make_code();
|
||||
preprocess_else->Type = CT_Preprocess_Else;
|
||||
code_set_global((Code)preprocess_else);
|
||||
|
||||
preprocess_endif = (CodePreprocessCond) make_code();
|
||||
preprocess_endif->Type = CT_Preprocess_EndIf;
|
||||
code_set_global((Code)preprocess_endif);
|
||||
|
||||
# define def_constant_code_type( Type_ ) \
|
||||
do \
|
||||
{ \
|
||||
StrC name_str = name(Type_); \
|
||||
t_##Type_ = def_type( name_str ); \
|
||||
code_set_global( cast(Code, t_##Type_)); \
|
||||
} while(0)
|
||||
|
||||
def_constant_code_type( auto );
|
||||
def_constant_code_type( void );
|
||||
def_constant_code_type( int );
|
||||
def_constant_code_type( bool );
|
||||
def_constant_code_type( char );
|
||||
def_constant_code_type( wchar_t );
|
||||
def_constant_code_type( class );
|
||||
def_constant_code_type( typename );
|
||||
|
||||
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||
t_b32 = def_type( name(b32) );
|
||||
|
||||
def_constant_code_type( s8 );
|
||||
def_constant_code_type( s16 );
|
||||
def_constant_code_type( s32 );
|
||||
def_constant_code_type( s64 );
|
||||
|
||||
def_constant_code_type( u8 );
|
||||
def_constant_code_type( u16 );
|
||||
def_constant_code_type( u32 );
|
||||
def_constant_code_type( u64 );
|
||||
|
||||
def_constant_code_type( ssize );
|
||||
def_constant_code_type( usize );
|
||||
|
||||
def_constant_code_type( f32 );
|
||||
def_constant_code_type( f64 );
|
||||
#endif
|
||||
# undef def_constant_code_type
|
||||
|
||||
|
||||
spec_const = def_specifier( Spec_Const); code_set_global( cast(Code, spec_const ));
|
||||
spec_consteval = def_specifier( Spec_Consteval); code_set_global( cast(Code, spec_consteval ));;
|
||||
spec_constexpr = def_specifier( Spec_Constexpr); code_set_global( cast(Code, spec_constexpr ));;
|
||||
spec_constinit = def_specifier( Spec_Constinit); code_set_global( cast(Code, spec_constinit ));;
|
||||
spec_extern_linkage = def_specifier( Spec_External_Linkage); code_set_global( cast(Code, spec_extern_linkage ));;
|
||||
spec_final = def_specifier( Spec_Final); code_set_global( cast(Code, spec_final ));;
|
||||
spec_forceinline = def_specifier( Spec_ForceInline); code_set_global( cast(Code, spec_forceinline ));;
|
||||
spec_global = def_specifier( Spec_Global); code_set_global( cast(Code, spec_global ));;
|
||||
spec_inline = def_specifier( Spec_Inline); code_set_global( cast(Code, spec_inline ));;
|
||||
spec_internal_linkage = def_specifier( Spec_Internal_Linkage); code_set_global( cast(Code, spec_internal_linkage ));;
|
||||
spec_local_persist = def_specifier( Spec_Local_Persist); code_set_global( cast(Code, spec_local_persist ));;
|
||||
spec_mutable = def_specifier( Spec_Mutable); code_set_global( cast(Code, spec_mutable ));;
|
||||
spec_neverinline = def_specifier( Spec_NeverInline); code_set_global( cast(Code, spec_neverinline ));;
|
||||
spec_noexcept = def_specifier( Spec_NoExceptions); code_set_global( cast(Code, spec_noexcept ));;
|
||||
spec_override = def_specifier( Spec_Override); code_set_global( cast(Code, spec_override ));;
|
||||
spec_ptr = def_specifier( Spec_Ptr); code_set_global( cast(Code, spec_ptr ));;
|
||||
spec_pure = def_specifier( Spec_Pure); code_set_global( cast(Code, spec_pure ));
|
||||
spec_ref = def_specifier( Spec_Ref); code_set_global( cast(Code, spec_ref ));;
|
||||
spec_register = def_specifier( Spec_Register); code_set_global( cast(Code, spec_register ));;
|
||||
spec_rvalue = def_specifier( Spec_RValue); code_set_global( cast(Code, spec_rvalue ));;
|
||||
spec_static_member = def_specifier( Spec_Static); code_set_global( cast(Code, spec_static_member ));;
|
||||
spec_thread_local = def_specifier( Spec_Thread_Local); code_set_global( cast(Code, spec_thread_local ));;
|
||||
spec_virtual = def_specifier( Spec_Virtual); code_set_global( cast(Code, spec_virtual ));;
|
||||
spec_volatile = def_specifier( Spec_Volatile); code_set_global( cast(Code, spec_volatile ));
|
||||
|
||||
spec_local_persist = def_specifiers( 1, Spec_Local_Persist );
|
||||
code_set_global(cast(Code, spec_local_persist));
|
||||
|
||||
# pragma push_macro("enum_underlying")
|
||||
array_append(PreprocessorDefines, txt("enum_underlying("));
|
||||
# pragma pop_macro("enum_underlying")
|
||||
|
||||
# undef def_constant_spec
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
// Setup global allocator
|
||||
{
|
||||
AllocatorInfo becasue_C = { & Global_Allocator_Proc, nullptr };
|
||||
GlobalAllocator = becasue_C;
|
||||
|
||||
Global_AllocatorBuckets = array_init_reserve(Arena, heap(), 128 );
|
||||
|
||||
if ( Global_AllocatorBuckets == nullptr )
|
||||
GEN_FATAL( "Failed to reserve memory for Global_AllocatorBuckets");
|
||||
|
||||
Arena bucket = arena_init_from_allocator( heap(), Global_BucketSize );
|
||||
|
||||
if ( bucket.PhysicalStart == nullptr )
|
||||
GEN_FATAL( "Failed to create first bucket for Global_AllocatorBuckets");
|
||||
|
||||
array_append( Global_AllocatorBuckets, bucket );
|
||||
}
|
||||
|
||||
if (Allocator_DataArrays.Proc == nullptr) {
|
||||
Allocator_DataArrays = heap();
|
||||
}
|
||||
if (Allocator_CodePool.Proc == nullptr ) {
|
||||
Allocator_CodePool = heap();
|
||||
}
|
||||
if (Allocator_Lexer.Proc == nullptr) {
|
||||
Allocator_Lexer = heap();
|
||||
}
|
||||
if (Allocator_StringArena.Proc == nullptr) {
|
||||
Allocator_StringArena = heap();
|
||||
}
|
||||
if (Allocator_StringTable.Proc == nullptr) {
|
||||
Allocator_StringTable = heap();
|
||||
}
|
||||
if (Allocator_TypeTable.Proc == nullptr) {
|
||||
Allocator_TypeTable = heap();
|
||||
}
|
||||
|
||||
// Setup the arrays
|
||||
{
|
||||
CodePools = array_init_reserve(Pool, Allocator_DataArrays, InitSize_DataArrays );
|
||||
|
||||
if ( CodePools == nullptr )
|
||||
GEN_FATAL( "gen::init: Failed to initialize the CodePools array" );
|
||||
|
||||
StringArenas = array_init_reserve(Arena, Allocator_DataArrays, InitSize_DataArrays );
|
||||
|
||||
if ( StringArenas == nullptr )
|
||||
GEN_FATAL( "gen::init: Failed to initialize the StringArenas array" );
|
||||
}
|
||||
|
||||
// Setup the code pool and code entries arena.
|
||||
{
|
||||
Pool code_pool = pool_init( Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) );
|
||||
|
||||
if ( code_pool.PhysicalStart == nullptr )
|
||||
GEN_FATAL( "gen::init: Failed to initialize the code pool" );
|
||||
|
||||
array_append( CodePools, code_pool );
|
||||
|
||||
LexArena = arena_init_from_allocator( Allocator_Lexer, LexAllocator_Size );
|
||||
|
||||
Arena string_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena );
|
||||
|
||||
if ( string_arena.PhysicalStart == nullptr )
|
||||
GEN_FATAL( "gen::init: Failed to initialize the string arena" );
|
||||
|
||||
array_append( StringArenas, string_arena );
|
||||
}
|
||||
|
||||
// Setup the hash tables
|
||||
{
|
||||
StringCache = hashtable_init(StringCached, Allocator_StringTable);
|
||||
|
||||
if ( StringCache.Entries == nullptr )
|
||||
GEN_FATAL( "gen::init: Failed to initialize the StringCache");
|
||||
}
|
||||
|
||||
// Preprocessor Defines
|
||||
PreprocessorDefines = array_init_reserve(StringCached, GlobalAllocator, kilobytes(1) );
|
||||
|
||||
define_constants();
|
||||
GEN_NS_PARSER parser_init();
|
||||
}
|
||||
|
||||
void deinit()
|
||||
{
|
||||
usize index = 0;
|
||||
usize left = array_num(CodePools);
|
||||
do
|
||||
{
|
||||
Pool* code_pool = & CodePools[index];
|
||||
pool_free(code_pool);
|
||||
index++;
|
||||
}
|
||||
while ( left--, left );
|
||||
|
||||
index = 0;
|
||||
left = array_num(StringArenas);
|
||||
do
|
||||
{
|
||||
Arena* string_arena = & StringArenas[index];
|
||||
arena_free(string_arena);
|
||||
index++;
|
||||
}
|
||||
while ( left--, left );
|
||||
|
||||
hashtable_destroy(StringCache);
|
||||
|
||||
array_free( CodePools);
|
||||
array_free( StringArenas);
|
||||
|
||||
arena_free(& LexArena);
|
||||
|
||||
array_free(PreprocessorDefines);
|
||||
|
||||
index = 0;
|
||||
left = array_num(Global_AllocatorBuckets);
|
||||
do
|
||||
{
|
||||
Arena* bucket = & Global_AllocatorBuckets[ index ];
|
||||
arena_free(bucket);
|
||||
index++;
|
||||
}
|
||||
while ( left--, left );
|
||||
|
||||
array_free(Global_AllocatorBuckets);
|
||||
GEN_NS_PARSER parser_deinit();
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
s32 index = 0;
|
||||
s32 left = array_num(CodePools);
|
||||
do
|
||||
{
|
||||
Pool* code_pool = & CodePools[index];
|
||||
pool_clear(code_pool);
|
||||
index++;
|
||||
}
|
||||
while ( left--, left );
|
||||
|
||||
index = 0;
|
||||
left = array_num(StringArenas);
|
||||
do
|
||||
{
|
||||
Arena* string_arena = & StringArenas[index];
|
||||
string_arena->TotalUsed = 0;;
|
||||
index++;
|
||||
}
|
||||
while ( left--, left );
|
||||
|
||||
hashtable_clear(StringCache);
|
||||
|
||||
define_constants();
|
||||
}
|
||||
|
||||
AllocatorInfo get_string_allocator( s32 str_length )
|
||||
{
|
||||
Arena* last = array_back(StringArenas);
|
||||
|
||||
usize size_req = str_length + sizeof(StringHeader) + sizeof(char*);
|
||||
|
||||
if ( last->TotalUsed + scast(ssize, size_req) > last->TotalSize )
|
||||
{
|
||||
Arena new_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena );
|
||||
|
||||
if ( ! array_append( StringArenas, new_arena ) )
|
||||
GEN_FATAL( "gen::get_string_allocator: Failed to allocate a new string arena" );
|
||||
|
||||
last = array_back(StringArenas);
|
||||
}
|
||||
|
||||
return arena_allocator_info(last);
|
||||
}
|
||||
|
||||
// Will either make or retrive a code string.
|
||||
StringCached get_cached_string( StrC str )
|
||||
{
|
||||
s32 hash_length = str.Len > kilobytes(1) ? kilobytes(1) : str.Len;
|
||||
u64 key = crc32( str.Ptr, hash_length );
|
||||
{
|
||||
StringCached* result = hashtable_get(StringCache, key );
|
||||
|
||||
if ( result )
|
||||
return * result;
|
||||
}
|
||||
|
||||
StrC result = string_to_strc( string_make_strc( get_string_allocator( str.Len ), str ));
|
||||
hashtable_set(StringCache, key, result );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Used internally to retireve a Code object form the CodePool.
|
||||
Code make_code()
|
||||
{
|
||||
Pool* allocator = array_back( CodePools);
|
||||
if ( allocator->FreeList == nullptr )
|
||||
{
|
||||
Pool code_pool = pool_init( Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) );
|
||||
|
||||
if ( code_pool.PhysicalStart == nullptr )
|
||||
GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePool allcoator returned nullptr." );
|
||||
|
||||
if ( ! array_append( CodePools, code_pool ) )
|
||||
GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePools failed to append new pool." );
|
||||
|
||||
allocator = array_back( CodePools);
|
||||
}
|
||||
|
||||
Code result = { rcast( AST*, alloc( pool_allocator_info(allocator), sizeof(AST) )) };
|
||||
mem_set( rcast(void*, cast(AST*, result)), 0, sizeof(AST) );
|
||||
return result;
|
||||
}
|
||||
|
||||
void set_allocator_data_arrays( AllocatorInfo allocator )
|
||||
{
|
||||
Allocator_DataArrays = allocator;
|
||||
}
|
||||
|
||||
void set_allocator_code_pool( AllocatorInfo allocator )
|
||||
{
|
||||
Allocator_CodePool = allocator;
|
||||
}
|
||||
|
||||
void set_allocator_lexer( AllocatorInfo allocator )
|
||||
{
|
||||
Allocator_Lexer = allocator;
|
||||
}
|
||||
|
||||
void set_allocator_string_arena( AllocatorInfo allocator )
|
||||
{
|
||||
Allocator_StringArena = allocator;
|
||||
}
|
||||
|
||||
void set_allocator_string_table( AllocatorInfo allocator )
|
||||
{
|
||||
Allocator_StringArena = allocator;
|
||||
}
|
343
base/components/interface.hpp
Normal file
343
base/components/interface.hpp
Normal file
@ -0,0 +1,343 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "ast_types.hpp"
|
||||
#endif
|
||||
|
||||
#pragma region Gen Interface
|
||||
/*
|
||||
/ \ | \ | \ / \
|
||||
| ▓▓▓▓▓▓\ ______ _______ \▓▓▓▓▓▓_______ _| ▓▓_ ______ ______ | ▓▓▓▓▓▓\ ______ _______ ______
|
||||
| ▓▓ __\▓▓/ \| \ | ▓▓ | \| ▓▓ \ / \ / \| ▓▓_ \▓▓| \ / \/ \
|
||||
| ▓▓| \ ▓▓▓▓▓▓\ ▓▓▓▓▓▓▓\ | ▓▓ | ▓▓▓▓▓▓▓\\▓▓▓▓▓▓ | ▓▓▓▓▓▓\ ▓▓▓▓▓▓\ ▓▓ \ \▓▓▓▓▓▓\ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓\
|
||||
| ▓▓ \▓▓▓▓ ▓▓ ▓▓ ▓▓ | ▓▓ | ▓▓ | ▓▓ | ▓▓ | ▓▓ __| ▓▓ ▓▓ ▓▓ \▓▓ ▓▓▓▓ / ▓▓ ▓▓ | ▓▓ ▓▓
|
||||
| ▓▓__| ▓▓ ▓▓▓▓▓▓▓▓ ▓▓ | ▓▓ _| ▓▓_| ▓▓ | ▓▓ | ▓▓| \ ▓▓▓▓▓▓▓▓ ▓▓ | ▓▓ | ▓▓▓▓▓▓▓ ▓▓_____| ▓▓▓▓▓▓▓▓
|
||||
\▓▓ ▓▓\▓▓ \ ▓▓ | ▓▓ | ▓▓ \ ▓▓ | ▓▓ \▓▓ ▓▓\▓▓ \ ▓▓ | ▓▓ \▓▓ ▓▓\▓▓ \\▓▓ \
|
||||
\▓▓▓▓▓▓ \▓▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓ \▓▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓
|
||||
*/
|
||||
|
||||
// Initialize the library.
|
||||
void init();
|
||||
|
||||
// Currently manually free's the arenas, code for checking for leaks.
|
||||
// However on Windows at least, it doesn't need to occur as the OS will clean up after the process.
|
||||
void deinit();
|
||||
|
||||
// Clears the allocations, but doesn't return to the heap, the calls init() again.
|
||||
// Ease of use.
|
||||
void reset();
|
||||
|
||||
// Used internally to retrive or make string allocations.
|
||||
// Strings are stored in a series of string arenas of fixed size (SizePer_StringArena)
|
||||
StringCached get_cached_string( StrC str );
|
||||
|
||||
/*
|
||||
This provides a fresh Code AST.
|
||||
The gen interface use this as their method from getting a new AST object from the CodePool.
|
||||
Use this if you want to make your own API for formatting the supported Code Types.
|
||||
*/
|
||||
Code make_code();
|
||||
|
||||
// Set these before calling gen's init() procedure.
|
||||
|
||||
void set_allocator_data_arrays ( AllocatorInfo data_array_allocator );
|
||||
void set_allocator_code_pool ( AllocatorInfo pool_allocator );
|
||||
void set_allocator_lexer ( AllocatorInfo lex_allocator );
|
||||
void set_allocator_string_arena( AllocatorInfo string_allocator );
|
||||
void set_allocator_string_table( AllocatorInfo string_allocator );
|
||||
void set_allocator_type_table ( AllocatorInfo type_reg_allocator );
|
||||
|
||||
#pragma region Upfront
|
||||
|
||||
CodeAttributes def_attributes( StrC content );
|
||||
CodeComment def_comment ( StrC content );
|
||||
|
||||
struct Opts_def_struct {
|
||||
CodeBody body;
|
||||
CodeTypename parent;
|
||||
AccessSpec parent_access;
|
||||
CodeAttributes attributes;
|
||||
CodeTypename* interfaces;
|
||||
s32 num_interfaces;
|
||||
ModuleFlag mflags;
|
||||
};
|
||||
CodeClass def_class( StrC name, Opts_def_struct otps GEN_PARAM_DEFAULT );
|
||||
|
||||
struct Opts_def_constructor {
|
||||
CodeParam params;
|
||||
Code initializer_list;
|
||||
Code body;
|
||||
};
|
||||
CodeConstructor def_constructor( Opts_def_constructor opts GEN_PARAM_DEFAULT );
|
||||
|
||||
CodeDefine def_define( StrC name, StrC content );
|
||||
|
||||
struct Opts_def_destructor {
|
||||
Code body;
|
||||
CodeSpecifiers specifiers;
|
||||
};
|
||||
CodeDestructor def_destructor( Opts_def_destructor opts GEN_PARAM_DEFAULT );
|
||||
|
||||
struct Opts_def_enum {
|
||||
CodeBody body;
|
||||
CodeTypename type;
|
||||
EnumT specifier;
|
||||
CodeAttributes attributes;
|
||||
ModuleFlag mflags;
|
||||
};
|
||||
CodeEnum def_enum( StrC name, Opts_def_enum opts GEN_PARAM_DEFAULT );
|
||||
|
||||
CodeExec def_execution ( StrC content );
|
||||
CodeExtern def_extern_link( StrC name, CodeBody body );
|
||||
CodeFriend def_friend ( Code symbol );
|
||||
|
||||
struct Opts_def_function {
|
||||
CodeParam params;
|
||||
CodeTypename ret_type;
|
||||
CodeBody body;
|
||||
CodeSpecifiers specs;
|
||||
CodeAttributes attrs;
|
||||
ModuleFlag mflags;
|
||||
};
|
||||
CodeFn def_function( StrC name, Opts_def_function opts GEN_PARAM_DEFAULT );
|
||||
|
||||
struct Opts_def_include { b32 foreign; };
|
||||
struct Opts_def_module { ModuleFlag mflags; };
|
||||
struct Opts_def_namespace { ModuleFlag mflags; };
|
||||
CodeInclude def_include ( StrC content, Opts_def_include opts GEN_PARAM_DEFAULT );
|
||||
CodeModule def_module ( StrC name, Opts_def_module opts GEN_PARAM_DEFAULT );
|
||||
CodeNS def_namespace( StrC name, CodeBody body, Opts_def_namespace opts GEN_PARAM_DEFAULT );
|
||||
|
||||
struct Opts_def_operator {
|
||||
CodeParam params;
|
||||
CodeTypename ret_type;
|
||||
CodeBody body;
|
||||
CodeSpecifiers specifiers;
|
||||
CodeAttributes attributes;
|
||||
ModuleFlag mflags;
|
||||
};
|
||||
CodeOperator def_operator( Operator op, StrC nspace, Opts_def_operator opts GEN_PARAM_DEFAULT );
|
||||
|
||||
struct Opts_def_operator_cast {
|
||||
CodeBody body;
|
||||
CodeSpecifiers specs;
|
||||
};
|
||||
CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast opts GEN_PARAM_DEFAULT );
|
||||
|
||||
struct Opts_def_param { Code value; };
|
||||
CodeParam def_param ( CodeTypename type, StrC name, Opts_def_param opts GEN_PARAM_DEFAULT );
|
||||
CodePragma def_pragma( StrC directive );
|
||||
|
||||
CodePreprocessCond def_preprocess_cond( EPreprocessCond type, StrC content );
|
||||
|
||||
CodeSpecifiers def_specifier( Specifier specifier );
|
||||
|
||||
CodeStruct def_struct( StrC name, Opts_def_struct opts GEN_PARAM_DEFAULT );
|
||||
|
||||
struct Opts_def_template { ModuleFlag mflags; };
|
||||
CodeTemplate def_template( CodeParam params, Code definition, Opts_def_template opts GEN_PARAM_DEFAULT );
|
||||
|
||||
struct Opts_def_type {
|
||||
ETypenameTag type_tag;
|
||||
Code arrayexpr;
|
||||
CodeSpecifiers specifiers;
|
||||
CodeAttributes attributes;
|
||||
};
|
||||
CodeTypename def_type( StrC name, Opts_def_type opts GEN_PARAM_DEFAULT );
|
||||
|
||||
struct Opts_def_typedef {
|
||||
CodeAttributes attributes;
|
||||
ModuleFlag mflags;
|
||||
};
|
||||
CodeTypedef def_typedef( StrC name, Code type, Opts_def_typedef opts GEN_PARAM_DEFAULT );
|
||||
|
||||
struct Opts_def_union {
|
||||
CodeAttributes attributes;
|
||||
ModuleFlag mflags;
|
||||
};
|
||||
CodeUnion def_union( StrC name, CodeBody body, Opts_def_union opts GEN_PARAM_DEFAULT );
|
||||
|
||||
struct Opts_def_using {
|
||||
CodeAttributes attributes;
|
||||
ModuleFlag mflags;
|
||||
};
|
||||
CodeUsing def_using( StrC name, CodeTypename type, Opts_def_using opts GEN_PARAM_DEFAULT );
|
||||
|
||||
CodeUsing def_using_namespace( StrC name );
|
||||
|
||||
struct Opts_def_variable
|
||||
{
|
||||
Code value;
|
||||
CodeSpecifiers specifiers;
|
||||
CodeAttributes attributes;
|
||||
ModuleFlag mflags;
|
||||
};
|
||||
CodeVar def_variable( CodeTypename type, StrC 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.
|
||||
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.
|
||||
|
||||
CodeBody def_class_body ( s32 num, ... );
|
||||
CodeBody def_class_body ( s32 num, Code* codes );
|
||||
CodeBody def_enum_body ( s32 num, ... );
|
||||
CodeBody def_enum_body ( s32 num, Code* codes );
|
||||
CodeBody def_export_body ( s32 num, ... );
|
||||
CodeBody def_export_body ( s32 num, Code* codes);
|
||||
CodeBody def_extern_link_body( s32 num, ... );
|
||||
CodeBody def_extern_link_body( s32 num, Code* codes );
|
||||
CodeBody def_function_body ( s32 num, ... );
|
||||
CodeBody def_function_body ( s32 num, Code* codes );
|
||||
CodeBody def_global_body ( s32 num, ... );
|
||||
CodeBody def_global_body ( s32 num, Code* codes );
|
||||
CodeBody def_namespace_body ( s32 num, ... );
|
||||
CodeBody def_namespace_body ( s32 num, Code* codes );
|
||||
CodeParam def_params ( s32 num, ... );
|
||||
CodeParam def_params ( s32 num, CodeParam* params );
|
||||
CodeSpecifiers def_specifiers ( s32 num, ... );
|
||||
CodeSpecifiers def_specifiers ( s32 num, Specifier* specs );
|
||||
CodeBody def_struct_body ( s32 num, ... );
|
||||
CodeBody def_struct_body ( s32 num, Code* codes );
|
||||
CodeBody def_union_body ( s32 num, ... );
|
||||
CodeBody def_union_body ( s32 num, Code* codes );
|
||||
|
||||
#pragma endregion Upfront
|
||||
|
||||
#pragma region Parsing
|
||||
|
||||
// TODO(Ed) : Implmeent the new parser API design.
|
||||
|
||||
#if 0
|
||||
GEN_NS_PARSER_BEGIN
|
||||
struct StackNode
|
||||
{
|
||||
StackNode* Prev;
|
||||
|
||||
Token Start;
|
||||
Token Name; // The name of the AST node (if parsed)
|
||||
StrC FailedProc; // The name of the procedure that failed
|
||||
};
|
||||
// Stack nodes are allocated the error's allocator
|
||||
|
||||
struct Error
|
||||
{
|
||||
String message;
|
||||
StackNode* context_stack;
|
||||
};
|
||||
GEN_NS_PARSER_END
|
||||
|
||||
struct ParseInfo
|
||||
{
|
||||
Arena FileMem;
|
||||
Arena TokMem;
|
||||
Arena CodeMem;
|
||||
|
||||
FileContents FileContent;
|
||||
Array<Token> Tokens;
|
||||
Array<Error> Errors;
|
||||
// Errors are allocated to a dedicated general arena.
|
||||
};
|
||||
|
||||
CodeBody parse_file( StrC path );
|
||||
#endif
|
||||
|
||||
CodeClass parse_class ( StrC class_def );
|
||||
CodeConstructor parse_constructor ( StrC constructor_def );
|
||||
CodeDestructor parse_destructor ( StrC destructor_def );
|
||||
CodeEnum parse_enum ( StrC enum_def );
|
||||
CodeBody parse_export_body ( StrC export_def );
|
||||
CodeExtern parse_extern_link ( StrC exten_link_def );
|
||||
CodeFriend parse_friend ( StrC friend_def );
|
||||
CodeFn parse_function ( StrC fn_def );
|
||||
CodeBody parse_global_body ( StrC body_def );
|
||||
CodeNS parse_namespace ( StrC namespace_def );
|
||||
CodeOperator parse_operator ( StrC operator_def );
|
||||
CodeOpCast parse_operator_cast( StrC operator_def );
|
||||
CodeStruct parse_struct ( StrC struct_def );
|
||||
CodeTemplate parse_template ( StrC template_def );
|
||||
CodeTypename parse_type ( StrC type_def );
|
||||
CodeTypedef parse_typedef ( StrC typedef_def );
|
||||
CodeUnion parse_union ( StrC union_def );
|
||||
CodeUsing parse_using ( StrC using_def );
|
||||
CodeVar parse_variable ( StrC var_def );
|
||||
|
||||
#pragma endregion Parsing
|
||||
|
||||
#pragma region Untyped text
|
||||
|
||||
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.
|
||||
StrC token_fmt_impl( ssize, ... );
|
||||
|
||||
Code untyped_str ( StrC content);
|
||||
Code untyped_fmt ( char const* fmt, ... );
|
||||
Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... );
|
||||
|
||||
#pragma endregion Untyped text
|
||||
|
||||
#pragma region Macros
|
||||
|
||||
#ifndef gen_main
|
||||
#define gen_main main
|
||||
#endif
|
||||
|
||||
#ifndef name
|
||||
// Convienence for defining any name used with the gen api.
|
||||
// Lets you provide the length and string literal to the functions without the need for the DSL.
|
||||
#define name( Id_ ) { sizeof(stringize( Id_ )) - 1, stringize(Id_) }
|
||||
#endif
|
||||
|
||||
#ifndef code
|
||||
// Same as name just used to indicate intention of literal for code instead of names.
|
||||
#define code( ... ) { sizeof(stringize(__VA_ARGS__)) - 1, stringize( __VA_ARGS__ ) }
|
||||
#endif
|
||||
|
||||
#ifndef args
|
||||
// Provides the number of arguments while passing args inplace.
|
||||
#define args( ... ) num_args( __VA_ARGS__ ), __VA_ARGS__
|
||||
#endif
|
||||
|
||||
#ifndef code_str
|
||||
// Just wrappers over common untyped code definition constructions.
|
||||
#define code_str( ... ) GEN_NS untyped_str( code( __VA_ARGS__ ) )
|
||||
#endif
|
||||
|
||||
#ifndef code_fmt
|
||||
#define code_fmt( ... ) GEN_NS untyped_str( token_fmt( __VA_ARGS__ ) )
|
||||
#endif
|
||||
|
||||
#ifndef parse_fmt
|
||||
#define parse_fmt( type, ... ) GEN_NS parse_##type( token_fmt( __VA_ARGS__ ) )
|
||||
#endif
|
||||
|
||||
#ifndef token_fmt
|
||||
/*
|
||||
Takes a format string (char const*) and a list of tokens (StrC) and returns a StrC of the formatted string.
|
||||
Tokens are provided in '<'identifier'>' format where '<' '>' are just angle brackets (you can change it in token_fmt_va)
|
||||
---------------------------------------------------------
|
||||
Example - A string with:
|
||||
typedef <type> <name> <name>;
|
||||
Will have a token_fmt arguments populated with:
|
||||
"type", strc_for_type,
|
||||
"name", strc_for_name,
|
||||
and:
|
||||
stringize( typedef <type> <name> <name>; )
|
||||
-----------------------------------------------------------
|
||||
So the full call for this example would be:
|
||||
token_fmt(
|
||||
"type", strc_for_type
|
||||
, "name", strc_for_name
|
||||
, stringize(
|
||||
typedef <type> <name> <name>
|
||||
));
|
||||
!----------------------------------------------------------
|
||||
! Note: token_fmt_va is whitespace sensitive for the tokens.
|
||||
! This can be alleviated by skipping whitespace between brackets but it was choosen to not have that implementation by default.
|
||||
*/
|
||||
#define token_fmt( ... ) GEN_NS token_fmt_impl( (num_args( __VA_ARGS__ ) + 1) / 2, __VA_ARGS__ )
|
||||
#endif
|
||||
|
||||
#pragma endregion Macros
|
||||
|
||||
#pragma endregion Gen Interface
|
345
base/components/interface.parsing.cpp
Normal file
345
base/components/interface.parsing.cpp
Normal file
@ -0,0 +1,345 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "gen/etoktype.cpp"
|
||||
#include "interface.upfront.cpp"
|
||||
#include "lexer.cpp"
|
||||
#include "parser.cpp"
|
||||
#endif
|
||||
|
||||
// Publically Exposed Interface
|
||||
|
||||
CodeClass parse_class( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
push_scope();
|
||||
CodeClass result = (CodeClass) parse_class_struct( Tok_Decl_Class, parser_not_inplace_def );
|
||||
parser_pop(& Context);
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeConstructor parse_constructor( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return InvalidCode;
|
||||
|
||||
// TODO(Ed): Constructors can have prefix attributes
|
||||
|
||||
CodeSpecifiers specifiers = NullCode;
|
||||
Specifier specs_found[ 16 ] = { Spec_NumSpecifiers };
|
||||
s32 NumSpecifiers = 0;
|
||||
|
||||
while ( left && tok_is_specifier(currtok) )
|
||||
{
|
||||
Specifier spec = strc_to_specifier( tok_to_str(currtok) );
|
||||
|
||||
b32 ignore_spec = false;
|
||||
|
||||
switch ( spec )
|
||||
{
|
||||
case Spec_Constexpr :
|
||||
case Spec_Explicit:
|
||||
case Spec_Inline :
|
||||
case Spec_ForceInline :
|
||||
case Spec_NeverInline :
|
||||
break;
|
||||
|
||||
case Spec_Const :
|
||||
ignore_spec = true;
|
||||
break;
|
||||
|
||||
default :
|
||||
log_failure( "Invalid specifier %s for variable\n%s", spec_to_str( spec ), parser_to_string(Context) );
|
||||
parser_pop(& Context);
|
||||
return InvalidCode;
|
||||
}
|
||||
|
||||
// Every specifier after would be considered part of the type type signature
|
||||
if (ignore_spec)
|
||||
break;
|
||||
|
||||
specs_found[ NumSpecifiers ] = spec;
|
||||
NumSpecifiers++;
|
||||
eat( currtok.Type );
|
||||
}
|
||||
|
||||
if ( NumSpecifiers )
|
||||
{
|
||||
specifiers = def_specifiers( NumSpecifiers, specs_found );
|
||||
// <specifiers> ...
|
||||
}
|
||||
|
||||
Context.Tokens = toks;
|
||||
CodeConstructor result = parser_parse_constructor( specifiers );
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeDestructor parse_destructor( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return InvalidCode;
|
||||
|
||||
// TODO(Ed): Destructors can have prefix attributes
|
||||
// TODO(Ed): Destructors can have virtual
|
||||
|
||||
Context.Tokens = toks;
|
||||
CodeDestructor result = parser_parse_destructor(NullCode);
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeEnum parse_enum( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
{
|
||||
parser_pop(& Context);
|
||||
return InvalidCode;
|
||||
}
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parser_parse_enum( parser_not_inplace_def);
|
||||
}
|
||||
|
||||
CodeBody parse_export_body( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parser_parse_export_body();
|
||||
}
|
||||
|
||||
CodeExtern parse_extern_link( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parser_parse_extern_link();
|
||||
}
|
||||
|
||||
CodeFriend parse_friend( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parser_parse_friend();
|
||||
}
|
||||
|
||||
CodeFn parse_function( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return (CodeFn) parser_parse_function();
|
||||
}
|
||||
|
||||
CodeBody parse_global_body( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
push_scope();
|
||||
CodeBody result = parse_global_nspace( CT_Global_Body );
|
||||
parser_pop(& Context);
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeNS parse_namespace( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parser_parse_namespace();
|
||||
}
|
||||
|
||||
CodeOperator parse_operator( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return (CodeOperator) parser_parse_operator();
|
||||
}
|
||||
|
||||
CodeOpCast parse_operator_cast( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parser_parse_operator_cast(NullCode);
|
||||
}
|
||||
|
||||
CodeStruct parse_struct( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
push_scope();
|
||||
CodeStruct result = (CodeStruct) parse_class_struct( Tok_Decl_Struct, parser_not_inplace_def );
|
||||
parser_pop(& Context);
|
||||
return result;
|
||||
}
|
||||
|
||||
CodeTemplate parse_template( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parser_parse_template();
|
||||
}
|
||||
|
||||
CodeTypename parse_type( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parser_parse_type( parser_not_from_template, nullptr);
|
||||
}
|
||||
|
||||
CodeTypedef parse_typedef( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parser_parse_typedef();
|
||||
}
|
||||
|
||||
CodeUnion parse_union( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parser_parse_union( parser_not_inplace_def);
|
||||
}
|
||||
|
||||
CodeUsing parse_using( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parser_parse_using();
|
||||
}
|
||||
|
||||
CodeVar parse_variable( StrC def )
|
||||
{
|
||||
GEN_USING_NS_PARSER;
|
||||
check_parse_args( def );
|
||||
|
||||
TokArray toks = lex( def );
|
||||
if ( toks.Arr == nullptr )
|
||||
return InvalidCode;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return parser_parse_variable();
|
||||
}
|
||||
|
||||
// Undef helper macros
|
||||
#undef check_parse_args
|
||||
#undef currtok_noskip
|
||||
#undef currtok
|
||||
#undef peektok
|
||||
#undef prevtok
|
||||
#undef nexttok
|
||||
#undef nexttok_noskip
|
||||
#undef eat
|
||||
#undef left
|
||||
#undef check
|
||||
#undef push_scope
|
||||
#undef def_assign
|
||||
|
||||
// Here for C Variant
|
||||
#undef lex_dont_skip_formatting
|
||||
#undef lex_skip_formatting
|
||||
|
||||
#undef parser_inplace_def
|
||||
#undef parser_not_inplace_def
|
||||
#undef parser_dont_consume_braces
|
||||
#undef parser_consume_braces
|
||||
#undef parser_not_from_template
|
||||
#undef parser_use_parenthesis
|
||||
#undef parser_strip_formatting_dont_preserve_newlines
|
190
base/components/interface.untyped.cpp
Normal file
190
base/components/interface.untyped.cpp
Normal file
@ -0,0 +1,190 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "interface.parsing.cpp"
|
||||
#endif
|
||||
|
||||
ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
|
||||
{
|
||||
char const* buf_begin = buf;
|
||||
ssize remaining = buf_size;
|
||||
|
||||
local_persist
|
||||
TokenMap_FixedArena tok_map_arena;
|
||||
fixed_arena_init( & tok_map_arena);
|
||||
|
||||
local_persist
|
||||
StringTable tok_map;
|
||||
{
|
||||
tok_map = hashtable_init(StrC, fixed_arena_allocator_info(& tok_map_arena) );
|
||||
|
||||
s32 left = num_tokens - 1;
|
||||
|
||||
while ( left-- )
|
||||
{
|
||||
char const* token = va_arg( va, char const* );
|
||||
StrC value = va_arg( va, StrC );
|
||||
|
||||
u32 key = crc32( token, str_len(token) );
|
||||
hashtable_set( tok_map, key, value );
|
||||
}
|
||||
}
|
||||
|
||||
char const* fmt = va_arg( va, char const* );
|
||||
char current = *fmt;
|
||||
|
||||
while ( current )
|
||||
{
|
||||
ssize len = 0;
|
||||
|
||||
while ( current && current != '<' && remaining )
|
||||
{
|
||||
* buf = * fmt;
|
||||
buf++;
|
||||
fmt++;
|
||||
remaining--;
|
||||
|
||||
current = * fmt;
|
||||
}
|
||||
|
||||
if ( current == '<' )
|
||||
{
|
||||
char const* scanner = fmt + 1;
|
||||
|
||||
s32 tok_len = 0;
|
||||
|
||||
while ( *scanner != '>' )
|
||||
{
|
||||
tok_len++;
|
||||
scanner++;
|
||||
}
|
||||
|
||||
char const* token = fmt + 1;
|
||||
|
||||
u32 key = crc32( token, tok_len );
|
||||
StrC* value = hashtable_get(tok_map, key );
|
||||
|
||||
if ( value )
|
||||
{
|
||||
ssize left = value->Len;
|
||||
char const* str = value->Ptr;
|
||||
|
||||
while ( left-- )
|
||||
{
|
||||
* buf = * str;
|
||||
buf++;
|
||||
str++;
|
||||
remaining--;
|
||||
}
|
||||
|
||||
scanner++;
|
||||
fmt = scanner;
|
||||
current = * fmt;
|
||||
continue;
|
||||
}
|
||||
|
||||
* buf = * fmt;
|
||||
buf++;
|
||||
fmt++;
|
||||
remaining--;
|
||||
|
||||
current = * fmt;
|
||||
}
|
||||
}
|
||||
|
||||
hashtable_clear(tok_map);
|
||||
fixed_arena_free(& tok_map_arena);
|
||||
|
||||
ssize result = buf_size - remaining;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Code untyped_str( StrC content )
|
||||
{
|
||||
if ( content.Len == 0 )
|
||||
{
|
||||
log_failure( "untyped_str: empty string" );
|
||||
return InvalidCode;
|
||||
}
|
||||
|
||||
Code
|
||||
result = make_code();
|
||||
result->Name = get_cached_string( content );
|
||||
result->Type = CT_Untyped;
|
||||
result->Content = result->Name;
|
||||
|
||||
if ( result->Name.Len == 0 )
|
||||
{
|
||||
log_failure( "untyped_str: could not cache string" );
|
||||
return InvalidCode;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Code untyped_fmt( char const* fmt, ...)
|
||||
{
|
||||
if ( fmt == nullptr )
|
||||
{
|
||||
log_failure( "untyped_fmt: null format string" );
|
||||
return InvalidCode;
|
||||
}
|
||||
|
||||
local_persist thread_local
|
||||
char buf[GEN_PRINTF_MAXLEN] = { 0 };
|
||||
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
ssize length = str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va);
|
||||
va_end(va);
|
||||
|
||||
StrC buf_str = { str_len_capped(fmt, MaxNameLength), fmt };
|
||||
StrC uncapped_str = { length, buf };
|
||||
|
||||
Code
|
||||
result = make_code();
|
||||
result->Name = get_cached_string( buf_str );
|
||||
result->Type = CT_Untyped;
|
||||
result->Content = get_cached_string( uncapped_str );
|
||||
|
||||
if ( result->Name.Len == 0 )
|
||||
{
|
||||
log_failure( "untyped_fmt: could not cache string" );
|
||||
return InvalidCode;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... )
|
||||
{
|
||||
if ( num_tokens == 0 )
|
||||
{
|
||||
log_failure( "untyped_token_fmt: zero tokens" );
|
||||
return InvalidCode;
|
||||
}
|
||||
|
||||
local_persist thread_local
|
||||
char buf[GEN_PRINTF_MAXLEN] = { 0 };
|
||||
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
ssize length = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num_tokens, va);
|
||||
va_end(va);
|
||||
|
||||
StrC buf_str = { length, buf };
|
||||
|
||||
Code
|
||||
result = make_code();
|
||||
result->Name = get_cached_string( buf_str );
|
||||
result->Type = CT_Untyped;
|
||||
result->Content = result->Name;
|
||||
|
||||
if ( result->Name.Len == 0 )
|
||||
{
|
||||
log_failure( "untyped_fmt: could not cache string" );
|
||||
return InvalidCode;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
2339
base/components/interface.upfront.cpp
Normal file
2339
base/components/interface.upfront.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1345
base/components/lexer.cpp
Normal file
1345
base/components/lexer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
5590
base/components/parser.cpp
Normal file
5590
base/components/parser.cpp
Normal file
File diff suppressed because it is too large
Load Diff
11
base/components/src_start.cpp
Normal file
11
base/components/src_start.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#if ! defined(GEN_DONT_ENFORCE_GEN_TIME_GUARD) && ! defined(GEN_TIME)
|
||||
# error Gen.hpp : GEN_TIME not defined
|
||||
#endif
|
||||
|
||||
#include "gen.hpp"
|
||||
|
||||
//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file.
|
||||
//! Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
|
||||
#ifndef GEN_ROLL_OWN_DEPENDENCIES
|
||||
# include "gen.dep.cpp"
|
||||
#endif
|
107
base/components/static_data.cpp
Normal file
107
base/components/static_data.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "gen.hpp"
|
||||
#endif
|
||||
|
||||
#pragma region StaticData
|
||||
|
||||
// TODO : Convert global allocation strategy to use a slab allocation strategy.
|
||||
global AllocatorInfo GlobalAllocator;
|
||||
global Array( Arena ) Global_AllocatorBuckets;
|
||||
|
||||
// TODO(Ed) : Make the code pool a dynamic arena
|
||||
global Array( Pool ) CodePools = { nullptr };
|
||||
global Array( Arena ) StringArenas = { nullptr };
|
||||
|
||||
global StringTable StringCache;
|
||||
|
||||
global Arena LexArena;
|
||||
|
||||
global AllocatorInfo Allocator_DataArrays = {0};
|
||||
global AllocatorInfo Allocator_CodePool = {0};
|
||||
global AllocatorInfo Allocator_Lexer = {0};
|
||||
global AllocatorInfo Allocator_StringArena = {0};
|
||||
global AllocatorInfo Allocator_StringTable = {0};
|
||||
global AllocatorInfo Allocator_TypeTable = {0};
|
||||
|
||||
#pragma endregion StaticData
|
||||
|
||||
#pragma region Constants
|
||||
|
||||
global Code access_public;
|
||||
global Code access_protected;
|
||||
global Code access_private;
|
||||
|
||||
global CodeAttributes attrib_api_export;
|
||||
global CodeAttributes attrib_api_import;
|
||||
|
||||
global Code module_global_fragment;
|
||||
global Code module_private_fragment;
|
||||
|
||||
global Code fmt_newline;
|
||||
|
||||
global CodeParam param_varadic;
|
||||
|
||||
global CodePragma pragma_once;
|
||||
|
||||
global CodePreprocessCond preprocess_else;
|
||||
global CodePreprocessCond preprocess_endif;
|
||||
|
||||
global CodeSpecifiers spec_const;
|
||||
global CodeSpecifiers spec_consteval;
|
||||
global CodeSpecifiers spec_constexpr;
|
||||
global CodeSpecifiers spec_constinit;
|
||||
global CodeSpecifiers spec_extern_linkage;
|
||||
global CodeSpecifiers spec_final;
|
||||
global CodeSpecifiers spec_forceinline;
|
||||
global CodeSpecifiers spec_global;
|
||||
global CodeSpecifiers spec_inline;
|
||||
global CodeSpecifiers spec_internal_linkage;
|
||||
global CodeSpecifiers spec_local_persist;
|
||||
global CodeSpecifiers spec_mutable;
|
||||
global CodeSpecifiers spec_noexcept;
|
||||
global CodeSpecifiers spec_neverinline;
|
||||
global CodeSpecifiers spec_override;
|
||||
global CodeSpecifiers spec_ptr;
|
||||
global CodeSpecifiers spec_pure;
|
||||
global CodeSpecifiers spec_ref;
|
||||
global CodeSpecifiers spec_register;
|
||||
global CodeSpecifiers spec_rvalue;
|
||||
global CodeSpecifiers spec_static_member;
|
||||
global CodeSpecifiers spec_thread_local;
|
||||
global CodeSpecifiers spec_virtual;
|
||||
global CodeSpecifiers spec_volatile;
|
||||
|
||||
global CodeTypename t_empty;
|
||||
global CodeTypename t_auto;
|
||||
global CodeTypename t_void;
|
||||
global CodeTypename t_int;
|
||||
global CodeTypename t_bool;
|
||||
global CodeTypename t_char;
|
||||
global CodeTypename t_wchar_t;
|
||||
global CodeTypename t_class;
|
||||
global CodeTypename t_typename;
|
||||
|
||||
global Array(StringCached) PreprocessorDefines;
|
||||
|
||||
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||
global CodeTypename t_b32;
|
||||
|
||||
global CodeTypename t_s8;
|
||||
global CodeTypename t_s16;
|
||||
global CodeTypename t_s32;
|
||||
global CodeTypename t_s64;
|
||||
|
||||
global CodeTypename t_u8;
|
||||
global CodeTypename t_u16;
|
||||
global CodeTypename t_u32;
|
||||
global CodeTypename t_u64;
|
||||
|
||||
global CodeTypename t_ssize;
|
||||
global CodeTypename t_usize;
|
||||
|
||||
global CodeTypename t_f32;
|
||||
global CodeTypename t_f64;
|
||||
#endif
|
||||
|
||||
#pragma endregion Constants
|
138
base/components/types.hpp
Normal file
138
base/components/types.hpp
Normal file
@ -0,0 +1,138 @@
|
||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#include "header_start.hpp"
|
||||
#endif
|
||||
|
||||
/*
|
||||
________ __ __ ________
|
||||
| \ | \ | \ | \
|
||||
| ▓▓▓▓▓▓▓▓_______ __ __ ______ ____ _______ | ▓▓\ | ▓▓ \▓▓▓▓▓▓▓▓__ __ ______ ______ _______
|
||||
| ▓▓__ | \| \ | \ \ \ / \ | ▓▓▓\| ▓▓ | ▓▓ | \ | \/ \ / \ / \
|
||||
| ▓▓ \ | ▓▓▓▓▓▓▓\ ▓▓ | ▓▓ ▓▓▓▓▓▓\▓▓▓▓\ ▓▓▓▓▓▓▓ | ▓▓▓▓\ ▓▓ | ▓▓ | ▓▓ | ▓▓ ▓▓▓▓▓▓\ ▓▓▓▓▓▓\ ▓▓▓▓▓▓▓
|
||||
| ▓▓▓▓▓ | ▓▓ | ▓▓ ▓▓ | ▓▓ ▓▓ | ▓▓ | ▓▓\▓▓ \ | ▓▓\▓▓ ▓▓ | ▓▓ | ▓▓ | ▓▓ ▓▓ | ▓▓ ▓▓ ▓▓\▓▓ \
|
||||
| ▓▓_____| ▓▓ | ▓▓ ▓▓__/ ▓▓ ▓▓ | ▓▓ | ▓▓_\▓▓▓▓▓▓\ | ▓▓ \▓▓▓▓ | ▓▓ | ▓▓__/ ▓▓ ▓▓__/ ▓▓ ▓▓▓▓▓▓▓▓_\▓▓▓▓▓▓\
|
||||
| ▓▓ \ ▓▓ | ▓▓\▓▓ ▓▓ ▓▓ | ▓▓ | ▓▓ ▓▓ | ▓▓ \▓▓▓ | ▓▓ \▓▓ ▓▓ ▓▓ ▓▓\▓▓ \ ▓▓
|
||||
\▓▓▓▓▓▓▓▓\▓▓ \▓▓ \▓▓▓▓▓▓ \▓▓ \▓▓ \▓▓\▓▓▓▓▓▓▓ \▓▓ \▓▓ \▓▓ _\▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓\▓▓▓▓▓▓▓
|
||||
| \__| ▓▓ ▓▓
|
||||
\▓▓ ▓▓ ▓▓
|
||||
\▓▓▓▓▓▓ \▓▓
|
||||
|
||||
*/
|
||||
|
||||
using LogFailType = ssize(*)(char const*, ...);
|
||||
|
||||
// By default this library will either crash or exit if an error is detected while generating codes.
|
||||
// Even if set to not use GEN_FATAL, GEN_FATAL will still be used for memory failures as the library is unusable when they occur.
|
||||
#ifdef GEN_DONT_USE_FATAL
|
||||
#define log_failure log_fmt
|
||||
#else
|
||||
#define log_failure GEN_FATAL
|
||||
#endif
|
||||
|
||||
enum AccessSpec : u32
|
||||
{
|
||||
AccessSpec_Default,
|
||||
AccessSpec_Private,
|
||||
AccessSpec_Protected,
|
||||
AccessSpec_Public,
|
||||
|
||||
AccessSpec_Num_AccessSpec,
|
||||
AccessSpec_Invalid,
|
||||
|
||||
AccessSpec_SizeDef = GEN_U32_MAX,
|
||||
};
|
||||
static_assert( size_of(AccessSpec) == size_of(u32), "AccessSpec not u32 size" );
|
||||
|
||||
inline
|
||||
StrC access_spec_to_str( AccessSpec type )
|
||||
{
|
||||
local_persist
|
||||
StrC lookup[ (u32)AccessSpec_Num_AccessSpec ] = {
|
||||
{ sizeof("") - 1, "" },
|
||||
{ sizeof("prviate") - 1, "private" },
|
||||
{ sizeof("protected") - 1, "private" },
|
||||
{ sizeof("public") - 1, "public" },
|
||||
};
|
||||
|
||||
StrC invalid = { sizeof("Invalid") - 1, "Invalid" };
|
||||
if ( type > AccessSpec_Public )
|
||||
return invalid;
|
||||
|
||||
return lookup[ (u32)type ];
|
||||
}
|
||||
|
||||
enum CodeFlag : u32
|
||||
{
|
||||
CodeFlag_None = 0,
|
||||
CodeFlag_FunctionType = bit(0),
|
||||
CodeFlag_ParamPack = bit(1),
|
||||
CodeFlag_Module_Export = bit(2),
|
||||
CodeFlag_Module_Import = bit(3),
|
||||
|
||||
CodeFlag_SizeDef = GEN_U32_MAX,
|
||||
};
|
||||
static_assert( size_of(CodeFlag) == size_of(u32), "CodeFlag not u32 size" );
|
||||
|
||||
// Used to indicate if enum definitoin is an enum class or regular enum.
|
||||
enum EnumDecl : u8
|
||||
{
|
||||
EnumDecl_Regular,
|
||||
EnumDecl_Class,
|
||||
|
||||
EnumT_SizeDef = GEN_U8_MAX,
|
||||
};
|
||||
typedef u8 EnumT;
|
||||
|
||||
enum ModuleFlag : u32
|
||||
{
|
||||
ModuleFlag_None = 0,
|
||||
ModuleFlag_Export = bit(0),
|
||||
ModuleFlag_Import = bit(1),
|
||||
|
||||
Num_ModuleFlags,
|
||||
ModuleFlag_Invalid,
|
||||
|
||||
ModuleFlag_SizeDef = GEN_U32_MAX,
|
||||
};
|
||||
static_assert( size_of(ModuleFlag) == size_of(u32), "ModuleFlag not u32 size" );
|
||||
|
||||
inline
|
||||
StrC module_flag_to_str( ModuleFlag flag )
|
||||
{
|
||||
local_persist
|
||||
StrC lookup[ (u32)Num_ModuleFlags ] = {
|
||||
{ sizeof("__none__"), "__none__" },
|
||||
{ sizeof("export"), "export" },
|
||||
{ sizeof("import"), "import" },
|
||||
};
|
||||
|
||||
local_persist
|
||||
StrC invalid_flag = { sizeof("invalid"), "invalid" };
|
||||
if ( flag > ModuleFlag_Import )
|
||||
return invalid_flag;
|
||||
|
||||
return lookup[ (u32)flag ];
|
||||
}
|
||||
|
||||
enum EPreprocessCond : u32
|
||||
{
|
||||
PreprocessCond_If,
|
||||
PreprocessCond_IfDef,
|
||||
PreprocessCond_IfNotDef,
|
||||
PreprocessCond_ElIf,
|
||||
|
||||
EPreprocessCond_SizeDef = GEN_U32_MAX,
|
||||
};
|
||||
static_assert( size_of(EPreprocessCond) == size_of(u32), "EPreprocessCond not u32 size" );
|
||||
|
||||
enum ETypenameTag : u16
|
||||
{
|
||||
Tag_None,
|
||||
Tag_Class,
|
||||
Tag_Enum,
|
||||
Tag_Struct,
|
||||
Tag_Union,
|
||||
|
||||
Tag_UnderlyingType = GEN_U16_MAX,
|
||||
};
|
||||
static_assert( size_of(ETypenameTag) == size_of(u16), "ETypenameTag is not u16 size");
|
Reference in New Issue
Block a user