2023-08-28 20:46:50 -07:00
|
|
|
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
2023-08-21 17:30:13 -07:00
|
|
|
#pragma once
|
2023-08-21 20:02:20 -07:00
|
|
|
#include "types.hpp"
|
2023-08-21 20:28:39 -07:00
|
|
|
#include "gen/ecode.hpp"
|
|
|
|
#include "gen/eoperator.hpp"
|
|
|
|
#include "gen/especifier.hpp"
|
2023-08-28 20:46:50 -07:00
|
|
|
#endif
|
2023-08-21 17:30:13 -07:00
|
|
|
|
2024-12-08 13:37:04 -08:00
|
|
|
/*
|
|
|
|
______ ______ ________ __ __ ______ __
|
|
|
|
/ \ / \| \ | \ | \ / \ | \
|
|
|
|
| ▓▓▓▓▓▓\ ▓▓▓▓▓▓\\▓▓▓▓▓▓▓▓ | ▓▓\ | ▓▓ | ▓▓▓▓▓▓\ ______ ____| ▓▓ ______
|
|
|
|
| ▓▓__| ▓▓ ▓▓___\▓▓ | ▓▓ | ▓▓▓\| ▓▓ | ▓▓ \▓▓/ \ / ▓▓/ \
|
|
|
|
| ▓▓ ▓▓\▓▓ \ | ▓▓ | ▓▓▓▓\ ▓▓ | ▓▓ | ▓▓▓▓▓▓\ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓\
|
|
|
|
| ▓▓▓▓▓▓▓▓_\▓▓▓▓▓▓\ | ▓▓ | ▓▓\▓▓ ▓▓ | ▓▓ __| ▓▓ | ▓▓ ▓▓ | ▓▓ ▓▓ ▓▓
|
|
|
|
| ▓▓ | ▓▓ \__| ▓▓ | ▓▓ | ▓▓ \▓▓▓▓ | ▓▓__/ \ ▓▓__/ ▓▓ ▓▓__| ▓▓ ▓▓▓▓▓▓▓▓
|
|
|
|
| ▓▓ | ▓▓\▓▓ ▓▓ | ▓▓ | ▓▓ \▓▓▓ \▓▓ ▓▓\▓▓ ▓▓\▓▓ ▓▓\▓▓ \
|
|
|
|
\▓▓ \▓▓ \▓▓▓▓▓▓ \▓▓ \▓▓ \▓▓ \▓▓▓▓▓▓ \▓▓▓▓▓▓ \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓
|
|
|
|
*/
|
|
|
|
|
2023-08-03 08:01:43 -07:00
|
|
|
struct AST;
|
|
|
|
struct AST_Body;
|
|
|
|
struct AST_Attributes;
|
|
|
|
struct AST_Comment;
|
2023-08-07 00:10:45 -07:00
|
|
|
struct AST_Constructor;
|
2023-11-21 20:36:56 -08:00
|
|
|
// struct AST_BaseClass;
|
2023-08-03 08:01:43 -07:00
|
|
|
struct AST_Class;
|
|
|
|
struct AST_Define;
|
2023-08-07 00:10:45 -07:00
|
|
|
struct AST_Destructor;
|
2023-08-03 08:01:43 -07:00
|
|
|
struct AST_Enum;
|
|
|
|
struct AST_Exec;
|
|
|
|
struct AST_Extern;
|
|
|
|
struct AST_Include;
|
|
|
|
struct AST_Friend;
|
|
|
|
struct AST_Fn;
|
|
|
|
struct AST_Module;
|
2023-08-06 11:58:43 -07:00
|
|
|
struct AST_NS;
|
2023-08-03 08:01:43 -07:00
|
|
|
struct AST_Operator;
|
|
|
|
struct AST_OpCast;
|
|
|
|
struct AST_Param;
|
|
|
|
struct AST_Pragma;
|
|
|
|
struct AST_PreprocessCond;
|
|
|
|
struct AST_Specifiers;
|
2023-11-21 17:07:49 -08:00
|
|
|
|
|
|
|
#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
|
|
|
|
|
2023-08-03 08:01:43 -07:00
|
|
|
struct AST_Struct;
|
|
|
|
struct AST_Template;
|
2024-12-03 12:19:39 -08:00
|
|
|
struct AST_Typename;
|
2023-08-03 08:01:43 -07:00
|
|
|
struct AST_Typedef;
|
|
|
|
struct AST_Union;
|
|
|
|
struct AST_Using;
|
|
|
|
struct AST_Var;
|
|
|
|
|
2024-12-01 22:56:49 -08:00
|
|
|
#if GEN_COMPILER_C
|
2024-12-10 07:24:48 -08:00
|
|
|
typedef AST* Code;
|
2024-12-01 22:56:49 -08:00
|
|
|
#else
|
2024-12-10 07:24:48 -08:00
|
|
|
struct Code;
|
2024-12-01 22:56:49 -08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if GEN_COMPILER_C
|
2024-12-10 10:56:56 -08:00
|
|
|
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;
|
2024-12-01 22:56:49 -08:00
|
|
|
#else
|
2024-12-10 07:24:48 -08:00
|
|
|
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;
|
2024-12-01 22:56:49 -08:00
|
|
|
#endif
|
2024-12-08 13:37:04 -08:00
|
|
|
|
2023-11-21 17:07:49 -08:00
|
|
|
#if GEN_EXECUTION_EXPRESSION_SUPPORT
|
2024-12-10 07:24:48 -08:00
|
|
|
|
|
|
|
#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;
|
2023-11-21 17:07:49 -08:00
|
|
|
#endif
|
|
|
|
|
2024-12-10 07:24:48 -08:00
|
|
|
#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
|
2024-12-08 13:37:04 -08:00
|
|
|
|
2024-12-01 22:56:49 -08:00
|
|
|
#undef Define_Code
|
2023-08-03 08:01:43 -07:00
|
|
|
|
2024-12-02 19:25:39 -08:00
|
|
|
GEN_NS_PARSER_BEGIN
|
2024-12-07 14:17:02 -08:00
|
|
|
|
2024-12-02 19:25:39 -08:00
|
|
|
struct Token;
|
2024-12-07 14:17:02 -08:00
|
|
|
|
2024-12-02 19:25:39 -08:00
|
|
|
GEN_NS_PARSER_END
|
2023-09-25 09:12:11 -07:00
|
|
|
|
2024-12-06 21:21:09 -08:00
|
|
|
#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
|
2024-12-06 02:29:17 -08:00
|
|
|
|
|
|
|
#if GEN_COMPILER_CPP
|
2024-12-01 23:38:55 -08:00
|
|
|
template< class Type> forceinline Type tmpl_cast( Code self ) { return * rcast( Type*, & self ); }
|
2024-12-01 15:50:37 -08:00
|
|
|
#endif
|
|
|
|
|
2024-12-06 21:21:09 -08:00
|
|
|
#pragma region Code C-Interface
|
2024-12-08 13:37:04 -08:00
|
|
|
|
2024-12-08 20:10:10 -08:00
|
|
|
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 );
|
2024-12-08 13:37:04 -08:00
|
|
|
|
2024-12-06 21:21:09 -08:00
|
|
|
#pragma endregion Code C-Interface
|
2024-12-01 21:03:38 -08:00
|
|
|
|
2024-12-06 02:29:17 -08:00
|
|
|
#if GEN_COMPILER_CPP
|
2023-08-03 08:01:43 -07:00
|
|
|
/*
|
|
|
|
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
|
|
|
|
{
|
2024-12-01 21:16:11 -08:00
|
|
|
AST* ast;
|
2023-08-03 08:01:43 -07:00
|
|
|
|
2024-12-08 20:10:10 -08:00
|
|
|
# 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); }
|
2024-12-06 21:21:09 -08:00
|
|
|
|
|
|
|
# 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; } \
|
2023-08-03 08:01:43 -07:00
|
|
|
operator bool();
|
|
|
|
|
2024-12-06 21:21:09 -08:00
|
|
|
#if ! GEN_C_LIKE_CPP
|
2023-08-03 08:01:43 -07:00
|
|
|
Using_Code( Code );
|
2024-12-08 20:10:10 -08:00
|
|
|
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); }
|
2024-12-01 22:56:49 -08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
Using_CodeOps( Code );
|
2024-12-06 21:21:09 -08:00
|
|
|
forceinline AST* operator ->() { return ast; }
|
2023-08-03 08:01:43 -07:00
|
|
|
|
|
|
|
Code& operator ++();
|
2023-11-20 12:09:01 -08:00
|
|
|
|
2023-11-19 17:34:46 -08:00
|
|
|
// TODO(Ed) : Remove this overload.
|
2023-11-20 12:09:01 -08:00
|
|
|
auto& operator*()
|
|
|
|
{
|
|
|
|
local_persist thread_local
|
|
|
|
Code NullRef = { nullptr };
|
|
|
|
|
|
|
|
if ( ast == nullptr )
|
|
|
|
return NullRef;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
2023-08-03 08:01:43 -07:00
|
|
|
|
|
|
|
#ifdef GEN_ENFORCE_STRONG_CODE_TYPES
|
|
|
|
# define operator explicit operator
|
|
|
|
#endif
|
2023-11-21 20:36:56 -08:00
|
|
|
operator CodeBody() const;
|
2023-08-03 08:01:43 -07:00
|
|
|
operator CodeAttributes() const;
|
2023-11-21 20:36:56 -08:00
|
|
|
// operator CodeBaseClass() const;
|
2023-08-03 08:01:43 -07:00
|
|
|
operator CodeComment() const;
|
|
|
|
operator CodeClass() const;
|
2023-11-21 20:36:56 -08:00
|
|
|
operator CodeConstructor() const;
|
2023-08-03 08:01:43 -07:00
|
|
|
operator CodeDefine() const;
|
2023-11-21 20:36:56 -08:00
|
|
|
operator CodeDestructor() const;
|
2023-08-03 08:01:43 -07:00
|
|
|
operator CodeExec() const;
|
|
|
|
operator CodeEnum() const;
|
|
|
|
operator CodeExtern() const;
|
|
|
|
operator CodeInclude() const;
|
|
|
|
operator CodeFriend() const;
|
|
|
|
operator CodeFn() const;
|
|
|
|
operator CodeModule() const;
|
2023-08-06 11:58:43 -07:00
|
|
|
operator CodeNS() const;
|
2023-08-03 08:01:43 -07:00
|
|
|
operator CodeOperator() const;
|
|
|
|
operator CodeOpCast() const;
|
|
|
|
operator CodeParam() const;
|
|
|
|
operator CodePragma() const;
|
|
|
|
operator CodePreprocessCond() const;
|
|
|
|
operator CodeSpecifiers() const;
|
|
|
|
operator CodeStruct() const;
|
|
|
|
operator CodeTemplate() const;
|
2024-12-03 12:19:39 -08:00
|
|
|
operator CodeTypename() const;
|
2023-08-03 08:01:43 -07:00
|
|
|
operator CodeTypedef() const;
|
|
|
|
operator CodeUnion() const;
|
|
|
|
operator CodeUsing() const;
|
|
|
|
operator CodeVar() const;
|
|
|
|
#undef operator
|
|
|
|
};
|
2024-12-01 22:56:49 -08:00
|
|
|
#endif
|
2023-08-03 08:01:43 -07:00
|
|
|
|
2024-12-01 21:03:38 -08:00
|
|
|
#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
|
|
|
|
|
2023-08-03 08:01:43 -07:00
|
|
|
struct Code_POD
|
|
|
|
{
|
|
|
|
AST* ast;
|
|
|
|
};
|
|
|
|
static_assert( sizeof(Code) == sizeof(Code_POD), "ERROR: Code is not POD" );
|
|
|
|
|
|
|
|
// Desired width of the AST data structure.
|
2023-09-25 13:42:29 -07:00
|
|
|
constexpr int const AST_POD_Size = 128;
|
2023-08-03 08:01:43 -07:00
|
|
|
|
2024-12-02 00:18:52 -08:00
|
|
|
constexpr static
|
|
|
|
int AST_ArrSpecs_Cap =
|
|
|
|
(
|
2024-12-08 20:10:10 -08:00
|
|
|
AST_POD_Size
|
|
|
|
- sizeof(Code)
|
|
|
|
- sizeof(StringCached)
|
|
|
|
- sizeof(Code) * 2
|
|
|
|
- sizeof(Token*)
|
|
|
|
- sizeof(Code)
|
|
|
|
- sizeof(CodeType)
|
|
|
|
- sizeof(ModuleFlag)
|
|
|
|
- sizeof(u32)
|
2024-12-02 00:18:52 -08:00
|
|
|
)
|
2024-12-07 17:49:43 -08:00
|
|
|
/ sizeof(Specifier) - 1;
|
2024-12-02 00:18:52 -08:00
|
|
|
|
2023-08-03 08:01:43 -07:00
|
|
|
/*
|
|
|
|
Simple AST POD with functionality to seralize into C++ syntax.
|
|
|
|
*/
|
|
|
|
struct AST
|
|
|
|
{
|
|
|
|
union {
|
|
|
|
struct
|
|
|
|
{
|
2024-12-02 17:20:30 -08:00
|
|
|
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
|
2023-08-03 08:01:43 -07:00
|
|
|
union {
|
2024-12-02 17:20:30 -08:00
|
|
|
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
|
2023-08-03 08:01:43 -07:00
|
|
|
};
|
|
|
|
union {
|
2024-12-05 21:33:53 -08:00
|
|
|
Code Macro; // Parameter
|
|
|
|
Code BitfieldSize; // Variable (Class/Struct Data Member)
|
|
|
|
Code Params; // Constructor, Function, Operator, Template, Typename
|
|
|
|
Code UnderlyingTypeMacro; // Enum
|
2023-08-03 08:01:43 -07:00
|
|
|
};
|
|
|
|
union {
|
2024-12-02 17:20:30 -08:00
|
|
|
Code ArrExpr; // Typename
|
|
|
|
Code Body; // Class, Constructor, Destructor, Enum, Friend, Function, Namespace, Struct, Union
|
|
|
|
Code Declaration; // Friend, Template
|
|
|
|
Code Value; // Parameter, Variable
|
2023-08-03 08:01:43 -07:00
|
|
|
};
|
2023-09-06 00:06:30 -07:00
|
|
|
union {
|
2024-12-02 17:20:30 -08:00
|
|
|
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)
|
2023-09-06 00:06:30 -07:00
|
|
|
};
|
2023-08-03 08:01:43 -07:00
|
|
|
};
|
2023-09-04 22:44:04 -07:00
|
|
|
StringCached Content; // Attributes, Comment, Execution, Include
|
2023-09-11 20:22:53 -07:00
|
|
|
struct {
|
2024-12-03 10:14:14 -08:00
|
|
|
Specifier ArrSpecs[AST_ArrSpecs_Cap]; // Specifiers
|
2024-12-02 17:20:30 -08:00
|
|
|
Code NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used.
|
2023-09-11 20:22:53 -07:00
|
|
|
};
|
2023-08-03 08:01:43 -07:00
|
|
|
};
|
2024-12-07 17:49:43 -08:00
|
|
|
StringCached Name;
|
2023-08-03 08:01:43 -07:00
|
|
|
union {
|
2024-12-02 17:20:30 -08:00
|
|
|
Code Prev;
|
|
|
|
Code Front;
|
|
|
|
Code Last;
|
2023-08-03 08:01:43 -07:00
|
|
|
};
|
|
|
|
union {
|
2024-12-02 17:20:30 -08:00
|
|
|
Code Next;
|
|
|
|
Code Back;
|
2023-08-03 08:01:43 -07:00
|
|
|
};
|
2024-12-06 21:21:09 -08:00
|
|
|
Token* Token; // Reference to starting token, only avaialble if it was derived from parsing.
|
2024-12-02 17:20:30 -08:00
|
|
|
Code Parent;
|
2024-12-03 12:19:39 -08:00
|
|
|
CodeType Type;
|
2023-11-20 12:09:01 -08:00
|
|
|
// CodeFlag CodeFlags;
|
2023-08-03 08:01:43 -07:00
|
|
|
ModuleFlag ModuleFlags;
|
|
|
|
union {
|
2023-08-23 08:05:49 -07:00
|
|
|
b32 IsFunction; // Used by typedef to not serialize the name field.
|
2024-12-08 17:00:16 -08:00
|
|
|
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)
|
|
|
|
};
|
2024-12-03 10:51:29 -08:00
|
|
|
Operator Op;
|
2023-08-03 08:01:43 -07:00
|
|
|
AccessSpec ParentAccess;
|
|
|
|
s32 NumEntries;
|
2024-12-01 02:30:37 -08:00
|
|
|
s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression.
|
2023-08-03 08:01:43 -07:00
|
|
|
};
|
|
|
|
};
|
2024-12-07 17:49:43 -08:00
|
|
|
static_assert( sizeof(AST) == AST_POD_Size, "ERROR: AST is not size of AST_POD_Size" );
|
2023-08-03 08:01:43 -07:00
|
|
|
|
2024-12-06 02:29:17 -08:00
|
|
|
#if GEN_COMPILER_CPP
|
2024-12-02 17:20:30 -08:00
|
|
|
// 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
|
2024-12-09 11:55:02 -08:00
|
|
|
#define InvalidCode (void*){ (void*)Code_Invalid }
|
2024-12-02 17:20:30 -08:00
|
|
|
#endif
|
|
|
|
|
2024-12-06 21:21:09 -08:00
|
|
|
#if GEN_COMPILER_CPP
|
2024-12-07 14:17:02 -08:00
|
|
|
struct NullCode_ImplicitCaster;
|
2023-08-03 08:01:43 -07:00
|
|
|
// Used when the its desired when omission is allowed in a definition.
|
2024-12-07 14:17:02 -08:00
|
|
|
#define NullCode (NullCode_ImplicitCaster{})
|
2024-12-06 21:21:09 -08:00
|
|
|
#else
|
|
|
|
#define NullCode nullptr
|
|
|
|
#endif
|