mirror of
https://github.com/Ed94/gencpp.git
synced 2025-06-15 03:01:47 -07:00
WIP: Still reworking based on design changes.
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
#define BLOAT_IMPL
|
||||
#include "Bloat.hpp"
|
||||
|
||||
|
||||
namespace Global
|
||||
{
|
||||
bool ShouldShowDebug = false;
|
||||
@ -40,131 +41,88 @@ namespace Memory
|
||||
}
|
||||
|
||||
|
||||
bool opts_custom_add(opts* options, opts_entry *t, char* b)
|
||||
struct TokEntry
|
||||
{
|
||||
if (t->type != ZPL_OPTS_STRING)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
char const* Str;
|
||||
s32 Length;
|
||||
};
|
||||
|
||||
t->text = string_append_length(t->text, " ", 1);
|
||||
t->text = string_appendc( t->text, b );
|
||||
ZPL_TABLE( static, TokMap, tokmap_, TokEntry )
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
b32 opts_custom_compile(opts *options, int argc, char **argv)
|
||||
sw token_fmt_va( char* buf, uw buf_size, char const* fmt, s32 num_tokens, va_list va )
|
||||
{
|
||||
b32 had_errors = false;
|
||||
char const* buf_begin = buf;
|
||||
sw remaining = buf_size;
|
||||
|
||||
for (int i = 1; i < argc; ++i)
|
||||
TokMap tok_map;
|
||||
{
|
||||
char* arg = argv[i];
|
||||
|
||||
if (*arg)
|
||||
tokmap_init( & tok_map, g_allocator );
|
||||
|
||||
s32 left = num_tokens;
|
||||
|
||||
while ( left-- )
|
||||
{
|
||||
arg = (char*)str_trim(arg, false);
|
||||
char const* token = va_arg( va, char const* );
|
||||
char const* value = va_arg( va, char const* );
|
||||
|
||||
if (*arg == '-')
|
||||
{
|
||||
opts_entry* entry = 0;
|
||||
b32 checkln = false;
|
||||
if ( *(arg + 1) == '-')
|
||||
{
|
||||
checkln = true;
|
||||
++arg;
|
||||
}
|
||||
TokEntry entry
|
||||
{
|
||||
value,
|
||||
zpl_strnlen(value, 128)
|
||||
};
|
||||
|
||||
char *b = arg + 1, *e = b;
|
||||
u32 key = crc32( token, zpl_strnlen(token, 32) );
|
||||
|
||||
while (char_is_alphanumeric(*e) || *e == '-' || *e == '_') {
|
||||
++e;
|
||||
}
|
||||
|
||||
entry = zpl__opts_find(options, b, (e - b), checkln);
|
||||
|
||||
if (entry)
|
||||
{
|
||||
char *ob = b;
|
||||
b = e;
|
||||
|
||||
/**/
|
||||
if (*e == '=')
|
||||
{
|
||||
if (entry->type == ZPL_OPTS_FLAG)
|
||||
{
|
||||
*e = '\0';
|
||||
zpl__opts_push_error(options, ob, ZPL_OPTS_ERR_EXTRA_VALUE);
|
||||
had_errors = true;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
b = e = e + 1;
|
||||
}
|
||||
else if (*e == '\0')
|
||||
{
|
||||
char *sp = argv[i+1];
|
||||
|
||||
if (sp && *sp != '-' && (array_count(options->positioned) < 1 || entry->type != ZPL_OPTS_FLAG))
|
||||
{
|
||||
if (entry->type == ZPL_OPTS_FLAG)
|
||||
{
|
||||
zpl__opts_push_error(options, b, ZPL_OPTS_ERR_EXTRA_VALUE);
|
||||
had_errors = true;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
arg = sp;
|
||||
b = e = sp;
|
||||
++i;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (entry->type != ZPL_OPTS_FLAG)
|
||||
{
|
||||
zpl__opts_push_error(options, ob, ZPL_OPTS_ERR_MISSING_VALUE);
|
||||
had_errors = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
entry->met = true;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
e = (char *)str_control_skip(e, '\0');
|
||||
zpl__opts_set_value(options, entry, b);
|
||||
|
||||
if ( (i + 1) < argc )
|
||||
{
|
||||
for ( b = argv[i + 1]; i < argc && b[0] != '-'; i++, b = argv[i + 1] )
|
||||
{
|
||||
opts_custom_add(options, entry, b );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
zpl__opts_push_error(options, b, ZPL_OPTS_ERR_OPTION);
|
||||
had_errors = true;
|
||||
}
|
||||
}
|
||||
else if (array_count(options->positioned))
|
||||
{
|
||||
opts_entry *l = array_back(options->positioned);
|
||||
array_pop(options->positioned);
|
||||
zpl__opts_set_value(options, l, arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
zpl__opts_push_error(options, arg, ZPL_OPTS_ERR_VALUE);
|
||||
had_errors = true;
|
||||
}
|
||||
tokmap_set( & tok_map, key, entry );
|
||||
}
|
||||
}
|
||||
|
||||
return !had_errors;
|
||||
sw result = 0;
|
||||
char current = *fmt;
|
||||
|
||||
while ( current )
|
||||
{
|
||||
sw len = 0;
|
||||
|
||||
while ( current && current != '{' && remaining )
|
||||
{
|
||||
*buf = *fmt;
|
||||
buf++;
|
||||
fmt++;
|
||||
|
||||
current = *fmt;
|
||||
}
|
||||
|
||||
if ( current == '{' )
|
||||
{
|
||||
char const* scanner = fmt;
|
||||
|
||||
s32 tok_len = 0;
|
||||
|
||||
while ( *scanner != '}' )
|
||||
{
|
||||
tok_len++;
|
||||
scanner++;
|
||||
}
|
||||
|
||||
char const* token = fmt;
|
||||
|
||||
s32 key = crc32( token, tok_len );
|
||||
TokEntry value = * tokmap_get( & tok_map, key );
|
||||
s32 left = value.Length;
|
||||
|
||||
while ( left-- )
|
||||
{
|
||||
*buf = *value.Str;
|
||||
buf++;
|
||||
value.Str++;
|
||||
}
|
||||
|
||||
scanner++;
|
||||
fmt = scanner;
|
||||
current = *fmt;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -1,35 +1,15 @@
|
||||
/*
|
||||
BLOAT.
|
||||
|
||||
This contians all definitions not directly related to the project.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__) || 1
|
||||
// Supports 0-10 arguments
|
||||
#define VA_NARGS_IMPL( _0, \
|
||||
_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
|
||||
_11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
|
||||
_21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
|
||||
N, ...) N
|
||||
// ## deletes preceding comma if _VA_ARGS__ is empty (GCC, Clang)
|
||||
#define VA_NARGS(...) VA_NARGS_IMPL(_, ## __VA_ARGS__, \
|
||||
30, 29, 28, 27, 26, 25, 24, 23, 22, 21, \
|
||||
20, 19, 18, 17, 16, 15, 14, 13, 12, 11, \
|
||||
10, 9, 8, 7, 6, 5, 4, 3, 2, 1, \
|
||||
0)
|
||||
|
||||
#else
|
||||
// Supports 1-10 arguments
|
||||
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
|
||||
#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
|
||||
#endif
|
||||
|
||||
#define VA_NARGS2(...) ((int)(sizeof((int[]){ __VA_ARGS__ })/sizeof(int)))
|
||||
|
||||
#ifdef BLOAT_IMPL
|
||||
# define ZPL_IMPLEMENTATION
|
||||
#endif
|
||||
|
||||
|
||||
#pragma region ZPL INCLUDE
|
||||
#if __clang__
|
||||
# pragma clang diagnostic push
|
||||
@ -44,15 +24,15 @@
|
||||
# define ZPL_MODULE_CORE
|
||||
# define ZPL_MODULE_TIMER
|
||||
# define ZPL_MODULE_HASHING
|
||||
// # define ZPL_MODULE_REGEX
|
||||
// # define ZPL_MODULE_EVENT
|
||||
// # define ZPL_MODULE_DLL
|
||||
# define ZPL_MODULE_OPTS
|
||||
// # define ZPL_MODULE_PROCESS
|
||||
// # define ZPL_MODULE_MAT
|
||||
// # define ZPL_MODULE_THREADING
|
||||
// # define ZPL_MODULE_JOBS
|
||||
// # define ZPL_MODULE_PARSER
|
||||
// # define ZPL_MODULE_REGEX
|
||||
// # define ZPL_MODULE_EVENT
|
||||
// # define ZPL_MODULE_DLL
|
||||
// # define ZPL_MODULE_OPTS
|
||||
// # define ZPL_MODULE_PROCESS
|
||||
// # define ZPL_MODULE_MAT
|
||||
// # define ZPL_MODULE_THREADING
|
||||
// # define ZPL_MODULE_JOBS
|
||||
// # define ZPL_MODULE_PARSER
|
||||
#include "zpl.h"
|
||||
|
||||
#if __clang__
|
||||
@ -61,7 +41,6 @@
|
||||
#pragma endregion ZPL INCLUDE
|
||||
|
||||
|
||||
|
||||
#if __clang__
|
||||
# pragma clang diagnostic ignored "-Wunused-const-variable"
|
||||
# pragma clang diagnostic ignored "-Wswitch"
|
||||
@ -70,16 +49,41 @@
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__) || 1
|
||||
// Supports 0-10 arguments
|
||||
#define VA_NARGS_IMPL( _0, \
|
||||
_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
|
||||
_11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
|
||||
_21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
|
||||
_31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
|
||||
_41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
|
||||
N, ...) N
|
||||
// ## deletes preceding comma if _VA_ARGS__ is empty (GCC, Clang)
|
||||
#define VA_NARGS(...) VA_NARGS_IMPL(_, ## __VA_ARGS__, \
|
||||
50, 49, 48, 47, 46, 45, 44, 43, 42, 41, \
|
||||
40, 39, 38, 37, 36, 35, 34, 33, 32, 31, \
|
||||
30, 29, 28, 27, 26, 25, 24, 23, 22, 21, \
|
||||
20, 19, 18, 17, 16, 15, 14, 13, 12, 11, \
|
||||
10, 9, 8, 7, 6, 5, 4, 3, 2, 1, \
|
||||
0)
|
||||
#else
|
||||
// Supports 1-10 arguments
|
||||
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
|
||||
#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
|
||||
#endif
|
||||
|
||||
#define bit( Value_ ) ( 1 << Value_ )
|
||||
#define bitfield_is_equal( Field_, Mask_ ) ( ( Mask_ & Field_ ) == Mask_ )
|
||||
#define ct constexpr
|
||||
#define forceinline ZPL_ALWAYS_INLINE
|
||||
#define print_nl( _) zpl_printf("\n")
|
||||
#define ccast( Type_, Value_ ) * const_cast< Type_* >( & Value_ )
|
||||
#define scast( Type_, Value_ ) static_cast< Type_ >( Value_ )
|
||||
#define rcast( Type_, Value_ ) reinterpret_cast< Type_ >( Value_ )
|
||||
#define pcast( Type_, Value_ ) ( * (Type_*)( & Value_ ) )
|
||||
#define txt( Value_ ) ZPL_STRINGIFY_EX( Value_ )
|
||||
#define txt_impl( Value_ ) #Value_
|
||||
#define txt( Value_ ) txt_impl( Value_ )
|
||||
#define txt_with_length( Value_ ) txt_impl( Value_ ), sizeof( txt_impl( Value_) )
|
||||
|
||||
#define do_once() \
|
||||
do \
|
||||
@ -90,7 +94,7 @@ do \
|
||||
return; \
|
||||
Done = true; \
|
||||
} \
|
||||
while(0) \
|
||||
while(0)
|
||||
|
||||
#define do_once_start \
|
||||
do \
|
||||
@ -105,14 +109,8 @@ do \
|
||||
} \
|
||||
while(0);
|
||||
|
||||
|
||||
using Line = char*;
|
||||
using Array_Line = array( Line );
|
||||
|
||||
|
||||
ct char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
|
||||
|
||||
|
||||
namespace Global
|
||||
{
|
||||
extern bool ShouldShowDebug;
|
||||
@ -124,6 +122,8 @@ namespace Memory
|
||||
|
||||
extern arena Global_Arena;
|
||||
// #define g_allocator arena_allocator( & Memory::Global_Arena)
|
||||
|
||||
// Heap allocator is being used for now to isolate errors from being memory related (tech debt till ready to address)
|
||||
#define g_allocator heap()
|
||||
|
||||
void setup();
|
||||
@ -131,9 +131,19 @@ namespace Memory
|
||||
void cleanup();
|
||||
}
|
||||
|
||||
// Had to be made to support multiple sub-arguments per "opt" argument.
|
||||
b32 opts_custom_compile(opts *options, int argc, char **argv);
|
||||
inline
|
||||
char const* token_fmt( char const* fmt, sw num_tokens, ... )
|
||||
{
|
||||
local_persist thread_local
|
||||
char buf[ZPL_PRINTF_MAXLEN] = { 0 };
|
||||
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
token_fmt_va(buf, ZPL_PRINTF_MAXLEN, fmt, num_tokens, va);
|
||||
va_end(va);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
inline
|
||||
sw log_fmt(char const *fmt, ...)
|
||||
@ -152,7 +162,7 @@ sw log_fmt(char const *fmt, ...)
|
||||
}
|
||||
|
||||
inline
|
||||
void fatal(char const *fmt, ...)
|
||||
sw fatal(char const *fmt, ...)
|
||||
{
|
||||
local_persist thread_local
|
||||
char buf[ZPL_PRINTF_MAXLEN] = { 0 };
|
||||
@ -165,11 +175,13 @@ void fatal(char const *fmt, ...)
|
||||
va_end(va);
|
||||
|
||||
assert_crash(buf);
|
||||
return -1;
|
||||
#else
|
||||
va_start(va, fmt);
|
||||
zpl_printf_err_va( fmt, va);
|
||||
va_end(va);
|
||||
|
||||
zpl_exit(1);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
18
project/Bloat.undef.hpp
Normal file
18
project/Bloat.undef.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
Remvoe any macro definitions related to the Bloat header.
|
||||
*/
|
||||
|
||||
#undef bit
|
||||
#undef bitfield_is_equal
|
||||
#undef ct
|
||||
#undef forceinline
|
||||
#undef print_nl
|
||||
#undef scast
|
||||
#undef rcast
|
||||
#undef pcast
|
||||
#undef txt
|
||||
|
||||
#undef do_once
|
||||
#undef do_once_start
|
||||
#undef do_once_end
|
||||
|
730
project/gen.cpp
730
project/gen.cpp
File diff suppressed because it is too large
Load Diff
628
project/gen.hpp
628
project/gen.hpp
@ -1,105 +1,163 @@
|
||||
/*
|
||||
gencpp: A simple staged metaprogramming library for C++.
|
||||
|
||||
This library is intended for small-to midsize projects that want rapid complation times
|
||||
for fast debugging.
|
||||
|
||||
This library is intended for small-to midsize projects.
|
||||
|
||||
AST type checking supports only a small subset of c++.
|
||||
See the 'ECode' namespace and 'gen API' region to see what is supported.
|
||||
|
||||
There is no support for accessability fields in structs.
|
||||
WHAT IS NOT PROVIDED:
|
||||
* Macro or template generation : This library is to avoid those, adding support for them
|
||||
adds unnecessary complexity.
|
||||
If you desire define them outside the gen_time scopes.
|
||||
|
||||
* Modern c++ (STL library) features :
|
||||
* Expression validation : Execution expressions are defined using the untyped string API.
|
||||
: There is no parse API for validating expression (possibly will add in the future)
|
||||
|
||||
* Complete file parser DSL : This isn't like the unreal header tool.
|
||||
Code injection to file or based off a file contents is not supported by the api.
|
||||
However nothing is stopping you using the library for that purpose.
|
||||
|
||||
|
||||
There are four different of construction of Code ast's the library provides:
|
||||
* Upfront construction
|
||||
* Incremental construction
|
||||
* Parse construction
|
||||
* Untyped
|
||||
|
||||
Upfront Construction:
|
||||
All component ASTs must be previously constructed, and provided on creation of the code AST.
|
||||
The construction will fail and return InvalidCode otherwise.
|
||||
|
||||
API:
|
||||
* def_forward_decl
|
||||
* def_class
|
||||
* def_global_body
|
||||
* def_proc
|
||||
* def_proc_body
|
||||
* def_namespace
|
||||
* def_namespace_body
|
||||
* def_param
|
||||
* def_params
|
||||
* def_operator
|
||||
* def_specifier
|
||||
* def_specifiers
|
||||
* def_struct
|
||||
* def_struct_body
|
||||
* def_variable
|
||||
* def_type
|
||||
* def_using
|
||||
* def_using_namespace
|
||||
|
||||
Incremental construction:
|
||||
A Code ast is provided but only completed upfront if all components are provided.
|
||||
Components are then added using the AST API for adding ASTs:
|
||||
* code.add( AST* ) // Adds AST with validation.
|
||||
* code.add_entry( AST* ) // Adds AST entry without validation.
|
||||
* code.add_content( AST* ) // Adds AST string content without validation.
|
||||
|
||||
API:
|
||||
* make_forward_decl
|
||||
* make_class
|
||||
* make_global_body
|
||||
* make_proc
|
||||
* make_namespace
|
||||
* make_params
|
||||
* make_operator
|
||||
* make_specifiers
|
||||
* make_struct
|
||||
* make_variable
|
||||
* make_type
|
||||
* make_using
|
||||
* make_using_namespace
|
||||
|
||||
Parse construction:
|
||||
A string provided to the API is parsed for the intended language construct.
|
||||
|
||||
API:
|
||||
* parse_forward_decl
|
||||
* parse_class
|
||||
* parse_glboal_body
|
||||
* parse_proc
|
||||
* parse_namespace
|
||||
* parse_params
|
||||
* parse_operator
|
||||
* parse_specifiers
|
||||
* parse_struct
|
||||
* parse_variable
|
||||
* parse_type
|
||||
* parse_using
|
||||
* parse_using
|
||||
|
||||
The parse API treats any execution scope definitions with no validation and are turned into untyped Code ASTs.
|
||||
This includes the assignmetn of variables; due to the library not yet supporting c/c++ expression parsing.
|
||||
|
||||
Untyped constructions:
|
||||
Code ASTs are constructed using unvalidated strings.
|
||||
|
||||
API:
|
||||
* untyped_str
|
||||
* untyped_fmt
|
||||
* untyped_token_fmt
|
||||
|
||||
During serialization any untyped Code AST is has its string value directly injected inline of
|
||||
whatever context the content existed as an entry within.
|
||||
Even though thse are not validated from somewhat correct c/c++ syntax or components, it doesn't mean that
|
||||
Untyped code can be added as any component of a Code AST:
|
||||
* Untyped code cannot have children, thus there cannot be recursive injection this way.
|
||||
* Untyped code can only be a child of a parent of body AST, or for values of an assignment.
|
||||
These restrictions help prevent abuse of untyped code to some extent.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Bloat.hpp"
|
||||
|
||||
// Defined by default.
|
||||
|
||||
#define GEN_ENABLE_READONLY_AST
|
||||
// #define GEN_DEFINE_DSL
|
||||
|
||||
// Temporarily here for debugging purposes.
|
||||
#define gen_time
|
||||
#define GEN_ENFORCE_READONLY_AST
|
||||
// #define GEN_DEFINE_DSL
|
||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||
// #define GEN_BAN_CPP_TEMPLATES
|
||||
// #define GEN_USE_FATAL
|
||||
|
||||
#ifdef gen_time
|
||||
namespace gen
|
||||
{
|
||||
#if 0
|
||||
ct sw ColumnLimit = 256;
|
||||
ct sw MaxLines = kilobytes(256);
|
||||
using LogFailType = sw(*)(char const*, ...);
|
||||
|
||||
using LineStr = char[ColumnLimit];
|
||||
#endif
|
||||
#ifdef GEN_BAN_CPP_TEMPLATES
|
||||
#define template static_assert("Templates are banned within gen_time scope blocks")
|
||||
#endif
|
||||
|
||||
// Specifier Type
|
||||
enum Specifier : u8
|
||||
{
|
||||
Alignas, // alignas(#)
|
||||
Constexpr, // constexpr
|
||||
Inline, // inline
|
||||
#ifdef GEN_USE_FATAL
|
||||
ct LogFailType log_failure = fatal;
|
||||
#else
|
||||
ct LogFailType log_failure = log_fmt;
|
||||
#endif
|
||||
|
||||
C_Linkage, // extern "C"
|
||||
API_Import, // Vendor specific way dynamic import symbol
|
||||
API_Export, // Vendor specific way to dynamic export
|
||||
External_Linkage, // extern
|
||||
Internal_Linkage, // static (within unit file)
|
||||
Static_Member, // static (within sturct/class)
|
||||
Local_Persist, // static (within function)
|
||||
Thread_Local, // thread_local
|
||||
|
||||
Num_Specifiers
|
||||
};
|
||||
|
||||
// Specifier to string
|
||||
inline
|
||||
char const* specifier_str( Specifier specifier )
|
||||
{
|
||||
static
|
||||
char const* lookup[ Num_Specifiers ] = {
|
||||
"alignas",
|
||||
"constexpr",
|
||||
"inline",
|
||||
|
||||
"extern \"C\"",
|
||||
#if defined(ZPL_SYSTEM_WINDOWS)
|
||||
"__declspec(dllexport)",
|
||||
"__declspec(dllimport)",
|
||||
#elif defined(ZPL_SYSTEM_MACOS)
|
||||
"__attribute__ ((visibility ("default")))",
|
||||
"__attribute__ ((visibility ("default")))",
|
||||
#endif
|
||||
"extern",
|
||||
"static",
|
||||
"static",
|
||||
"static",
|
||||
"thread_local"
|
||||
};
|
||||
|
||||
return lookup[ specifier ];
|
||||
}
|
||||
|
||||
// Code Type
|
||||
namespace ECode
|
||||
{
|
||||
enum Type : u8
|
||||
{
|
||||
Invalid,
|
||||
|
||||
Untyped, // User provided raw string.
|
||||
|
||||
Decl_Function, // Forward a function
|
||||
Decl_Type, // Forward a type.
|
||||
Invalid, // Used only with improperly created Code nodes
|
||||
Untyped, // User provided raw string
|
||||
Decl_Function, // <specifier> <type> <name> ( <params> )
|
||||
Decl_Type, // <type> <name>;
|
||||
Function, // <type> <name>( <parameters> )
|
||||
Function_Body, // { <body> }
|
||||
Namespace,
|
||||
Namespace_Body,
|
||||
Parameters, // Used with functions.
|
||||
Specifiers,
|
||||
Struct,
|
||||
Struct_Body,
|
||||
Variable,
|
||||
Typedef,
|
||||
Typename,
|
||||
Using,
|
||||
Namespace, // Define a namespace
|
||||
Namespace_Body, // { <body> }
|
||||
Parameters, // <type> <param> ...
|
||||
Specifiers, // Used with functions, structs, variables
|
||||
Struct, // struct <specifier> <name> <parent>
|
||||
Struct_Body, // {<body> }
|
||||
Variable, // <type> <name>
|
||||
Typedef, // typedef <type> <alias>
|
||||
Typename, // Typename, used with other types
|
||||
Using, // using <name> = <type>
|
||||
Unit, // Represents a file.
|
||||
|
||||
Num_Types
|
||||
};
|
||||
@ -110,11 +168,9 @@ namespace gen
|
||||
static
|
||||
char const* lookup[Num_Types] = {
|
||||
"Invalid",
|
||||
|
||||
"Untyped",
|
||||
|
||||
"Decl_Function",
|
||||
"Decl_type",
|
||||
"Decl_Type",
|
||||
"Function",
|
||||
"Function_Body",
|
||||
"Namespace",
|
||||
@ -126,7 +182,8 @@ namespace gen
|
||||
"Variable",
|
||||
"Typedef",
|
||||
"Typename",
|
||||
"using"
|
||||
"Using",
|
||||
"Unit",
|
||||
};
|
||||
|
||||
return lookup[ type ];
|
||||
@ -134,6 +191,116 @@ namespace gen
|
||||
}
|
||||
using CodeT = ECode::Type;
|
||||
|
||||
namespace EOperator
|
||||
{
|
||||
enum Type : u8
|
||||
{
|
||||
Add,
|
||||
Subtract,
|
||||
Multiply,
|
||||
Divide,
|
||||
Modulo,
|
||||
|
||||
Num_Ops
|
||||
};
|
||||
|
||||
inline
|
||||
char const* str( Type op )
|
||||
{
|
||||
static
|
||||
char const* lookup[ Num_Ops ] = {
|
||||
"+",
|
||||
"-",
|
||||
"*",
|
||||
"/",
|
||||
};
|
||||
|
||||
return lookup[ op ];
|
||||
}
|
||||
}
|
||||
using OperatorT = EOperator::Type;
|
||||
|
||||
namespace ESpecifier
|
||||
{
|
||||
enum Type : u8
|
||||
{
|
||||
Attribute, // [ <attributes ]
|
||||
Alignas, // alignas(#)
|
||||
Constexpr, // constexpr
|
||||
Const, // const
|
||||
Inline, // inline
|
||||
RValue, //
|
||||
|
||||
C_Linkage, // extern "C"
|
||||
API_Import, // Vendor specific way dynamic import symbol
|
||||
API_Export, // Vendor specific way to dynamic export
|
||||
External_Linkage, // extern
|
||||
Internal_Linkage, // static (within unit file)
|
||||
Static_Member, // static (within sturct/class)
|
||||
Local_Persist, // static (within function)
|
||||
Thread_Local, // thread_local
|
||||
|
||||
Num_Specifiers,
|
||||
Invalid
|
||||
};
|
||||
|
||||
// Specifier to string
|
||||
inline
|
||||
char const* to_str( Type specifier )
|
||||
{
|
||||
static
|
||||
char const* lookup[ Num_Specifiers ] = {
|
||||
"alignas",
|
||||
"constexpr",
|
||||
"const",
|
||||
"inline",
|
||||
|
||||
"extern \"C\"",
|
||||
|
||||
#if defined(ZPL_SYSTEM_WINDOWS) && 0// API_Import and API_Export strings
|
||||
"__declspec(dllexport)",
|
||||
"__declspec(dllimport)",
|
||||
#elif defined(ZPL_SYSTEM_MACOS) || 1
|
||||
"__attribute__ ((visibility (\"default\")))",
|
||||
"__attribute__ ((visibility (\"default\")))",
|
||||
#endif
|
||||
|
||||
"extern",
|
||||
"static",
|
||||
"static",
|
||||
"static",
|
||||
"thread_local"
|
||||
};
|
||||
|
||||
return lookup[ specifier ];
|
||||
}
|
||||
|
||||
Type to_type( char const* str, s32 length )
|
||||
{
|
||||
static
|
||||
u32 keymap[ Num_Specifiers ];
|
||||
do_once_start
|
||||
for ( u32 index = 0; index < Num_Specifiers; index++ )
|
||||
{
|
||||
char const* enum_str = to_str( (Type)index );
|
||||
|
||||
keymap[index] = crc32( enum_str, strnlen(enum_str, 42) );
|
||||
}
|
||||
do_once_end
|
||||
|
||||
u32 hash = crc32(str, length );
|
||||
|
||||
for ( u32 index = 0; index < Num_Specifiers; index++ )
|
||||
{
|
||||
if ( keymap[index] == hash )
|
||||
return (Type)index;
|
||||
}
|
||||
|
||||
return Invalid;
|
||||
}
|
||||
}
|
||||
using SpecifierT = ESpecifier::Type;
|
||||
|
||||
// TODO: If perf needs it, convert layout an SOA format.
|
||||
/*
|
||||
Simple AST POD with functionality to seralize into C++ syntax.
|
||||
@ -154,38 +321,40 @@ namespace gen
|
||||
}
|
||||
|
||||
forceinline
|
||||
bool has_entries()
|
||||
bool has_entries() const
|
||||
{
|
||||
static bool lookup[ ECode::Num_Types] = {
|
||||
false, // Invalid
|
||||
false, // Unused
|
||||
false, // Untyped
|
||||
true, // Decl_Type
|
||||
true, // Decl_Function
|
||||
true, // Parameter
|
||||
true, // Struct
|
||||
true, // Decl_Type
|
||||
true, // Function
|
||||
false, // Specifier
|
||||
true, // Parameters
|
||||
false, // Specifies
|
||||
true, // Struct
|
||||
true, // Struct_Body
|
||||
true, // Variable
|
||||
true, // Typedef
|
||||
true, // Typename
|
||||
true, // Using
|
||||
};
|
||||
|
||||
return lookup[Type];
|
||||
}
|
||||
|
||||
forceinline
|
||||
bool is_invalid()
|
||||
bool is_invalid() const
|
||||
{
|
||||
return Type != ECode::Invalid;
|
||||
}
|
||||
|
||||
forceinline
|
||||
char const* type_str()
|
||||
char const* type_str() const
|
||||
{
|
||||
return ECode::str( Type );
|
||||
}
|
||||
|
||||
string to_string();
|
||||
string to_string() const;
|
||||
|
||||
#pragma endregion Member API
|
||||
|
||||
@ -215,7 +384,7 @@ namespace gen
|
||||
/*
|
||||
AST* typedef as to not constantly have to add the '*' as this is written often..
|
||||
|
||||
If GEN_ENABLE_READONLY_AST is defined, readonly assertions will be done on any member dreference,
|
||||
If GEN_ENFORCE_READONLY_AST is defined, readonly assertions will be done on any member dreference,
|
||||
and the 'gen API' related functions. will set their created ASTs to readonly before returning.
|
||||
|
||||
Casting to AST* will bypass.
|
||||
@ -224,13 +393,32 @@ namespace gen
|
||||
{
|
||||
AST* ast;
|
||||
|
||||
forceinline
|
||||
operator bool()
|
||||
Code body()
|
||||
{
|
||||
return ast->is_invalid();
|
||||
if ( ast->Type == ECode::Invalid )
|
||||
fatal("Code::body: Type is invalid, cannot get");
|
||||
|
||||
if ( ast->Entries == nullptr || array_count(ast->Entries) == 0 )
|
||||
fatal("Code::body: Entries of ast not properly setup.");
|
||||
|
||||
return pcast( Code, ast->Entries[0]);
|
||||
}
|
||||
|
||||
bool operator ==( Code other )
|
||||
forceinline
|
||||
void lock()
|
||||
{
|
||||
#ifdef GEN_ENFORCE_READONLY_AST
|
||||
ast->Readonly = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
forceinline
|
||||
operator bool() const
|
||||
{
|
||||
return ast && ast->is_invalid();
|
||||
}
|
||||
|
||||
bool operator ==( Code other ) const
|
||||
{
|
||||
return ast == other.ast;
|
||||
}
|
||||
@ -247,28 +435,27 @@ namespace gen
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef GEN_ENABLE_READONLY_AST
|
||||
forceinline
|
||||
AST* operator ->()
|
||||
{
|
||||
#ifdef GEN_ENFORCE_READONLY_AST
|
||||
if ( ast == nullptr )
|
||||
fatal("Attempt to dereference a nullptr!");
|
||||
|
||||
if ( ast->Readonly )
|
||||
fatal("Attempted to access a member from a readonly ast!");
|
||||
#endif
|
||||
|
||||
return ast;
|
||||
}
|
||||
|
||||
Code& operator *() = delete;
|
||||
#endif
|
||||
};
|
||||
static_assert( sizeof(Code) == sizeof(AST*), "ERROR: Code is not POD" );
|
||||
|
||||
// Used when the its desired when omission is allowed in a definition.
|
||||
ct Code UnusedCode = { nullptr };
|
||||
|
||||
// Used internally for the most part to identify invaidly generated code.
|
||||
ct CodePOD InvalidCode = { ECode::Invalid, false, nullptr, nullptr, nullptr, { nullptr } };
|
||||
extern const Code InvalidCode;
|
||||
|
||||
/*
|
||||
Type registy: Used to store Typename ASTs. Types are registered by their string literal value.
|
||||
@ -277,7 +464,7 @@ namespace gen
|
||||
Strings made with the Typename ASTs are stored in thier own arena allocator.
|
||||
TODO: Implement and replace usage of def_type.
|
||||
*/
|
||||
// ZPL_TABLE_DECLARE( ZPL_EXTERN, TypeRegistry, type_reg_, Code );
|
||||
ZPL_TABLE_DECLARE( ZPL_EXTERN, TypeRegistry, type_reg_, Code );
|
||||
|
||||
#pragma region gen API
|
||||
/*
|
||||
@ -286,17 +473,18 @@ namespace gen
|
||||
*/
|
||||
void init();
|
||||
|
||||
#pragma region Upfront
|
||||
/*
|
||||
Foward Declare a type:
|
||||
<specifiers> <type> <name>;
|
||||
*/
|
||||
Code decl_type( char const* name, Code type, Code specifiers = UnusedCode );
|
||||
Code def_fwd_type( Code type, char const* name, Code specifiers = UnusedCode );
|
||||
|
||||
/*
|
||||
Foward Declare a function:
|
||||
<specifiers> <name> ( <params> );
|
||||
*/
|
||||
Code decl_fn( char const* name
|
||||
Code def_fwd_proc( char const* name
|
||||
, Code specifiers
|
||||
, Code params
|
||||
, Code ret_type
|
||||
@ -305,8 +493,10 @@ namespace gen
|
||||
/*
|
||||
Define an expression:
|
||||
< c/c++ expression >
|
||||
|
||||
TODO: Evalute if you want to validiate at the execution layer during gen_time (dosen't seem necessary)
|
||||
*/
|
||||
Code def_expression( Code value );
|
||||
// Code def_expression( Code value );
|
||||
|
||||
/*
|
||||
Define a function:
|
||||
@ -315,7 +505,7 @@ namespace gen
|
||||
<body>
|
||||
}
|
||||
*/
|
||||
Code def_function( char const* name
|
||||
Code def_proc( char const* name
|
||||
, Code specifiers
|
||||
, Code params
|
||||
, Code ret_type
|
||||
@ -330,9 +520,10 @@ namespace gen
|
||||
...
|
||||
}
|
||||
|
||||
Each entry is provided an empty line separation.
|
||||
There will be an empty line separation between entires
|
||||
*/
|
||||
Code def_function_body( s32 num, ... );
|
||||
Code def_proc_body( s32 num, ... );
|
||||
Code def_proc_body( s32 num, Code* codes );
|
||||
|
||||
/*
|
||||
Define a namespace;
|
||||
@ -351,7 +542,7 @@ namespace gen
|
||||
...
|
||||
}
|
||||
|
||||
Each entry is provided an empty line separation.
|
||||
There will be an empty line separation between entires
|
||||
*/
|
||||
Code def_namespace_body( s32 num, ... );
|
||||
|
||||
@ -359,12 +550,23 @@ namespace gen
|
||||
Define a set of parameters for a function:
|
||||
<name> <type>, ...
|
||||
*/
|
||||
Code def_parameters( s32 num, ... );
|
||||
Code def_params( s32 num, ... );
|
||||
Code def_params( s32 num, char const** params );
|
||||
|
||||
/*
|
||||
Define an operator definition.
|
||||
*/
|
||||
Code def_operator( OperatorT op, Code specifiers, Code params, Code ret_type, Code body );
|
||||
|
||||
/*
|
||||
Define a set of specifiers for a function, struct, type, or varaible
|
||||
|
||||
Note:
|
||||
If alignas is specified the procedure expects the next argument to be the alignment value.
|
||||
If attribute is specified the procedure expects the next argument to be its content as a string.
|
||||
*/
|
||||
Code def_specifiers( s32 num , ... );
|
||||
Code def_specifiers( s32 num, SpecifierT* specs );
|
||||
|
||||
/*
|
||||
Define a struct:
|
||||
@ -383,19 +585,26 @@ namespace gen
|
||||
...
|
||||
}
|
||||
|
||||
Each entry is provided an empty line separation.
|
||||
There will be an empty line separation between entires
|
||||
*/
|
||||
Code def_struct_body( s32 num, ... );
|
||||
Code def_struct_body( s32 num, Code* codes );
|
||||
|
||||
/*
|
||||
Define a variable:
|
||||
<specifiers> <type> <name> = <value>;
|
||||
*/
|
||||
Code def_variable( char const* name, Code type, Code value = UnusedCode, Code specifiers = UnusedCode );
|
||||
Code def_variable( Code type, char const* name, Code value = UnusedCode, Code specifiers = UnusedCode );
|
||||
|
||||
/*
|
||||
Define a type AST value.
|
||||
Useless by itself, its intended to be used in conjunction with
|
||||
Define a typename AST value.
|
||||
Useless by itself, its intended to be used in conjunction with other Code.
|
||||
|
||||
Planned - Not yet Implemented:
|
||||
Typename Codes are not held in the CodePool, instead they are stored in a
|
||||
type registry (hastable where the key is a crc hash of the name string).
|
||||
|
||||
If a key exists the existing code value will be provided.
|
||||
*/
|
||||
Code def_type( char const* name );
|
||||
|
||||
@ -412,7 +621,88 @@ namespace gen
|
||||
Can only be used in either a
|
||||
*/
|
||||
Code def_using_namespace( char const* name );
|
||||
#pragma endregion Upfront
|
||||
|
||||
#pragma region Incremental
|
||||
/*
|
||||
Provides an incomplete procedure AST but sets the intended type.
|
||||
Any adds will be type checked.
|
||||
|
||||
Body is automatically made. Use body() to retrieve.
|
||||
*/
|
||||
Code make_proc( char const* name
|
||||
, Code specifiers = UnusedCode
|
||||
, Code params = UnusedCode
|
||||
, Code ret_type = UnusedCode
|
||||
);
|
||||
|
||||
/*
|
||||
Provides an incomplete struct AST but sets the intended type.
|
||||
Any adds will be type checked.
|
||||
|
||||
Body is automatically made. Use body() to retrieve.
|
||||
*/
|
||||
Code make_struct( char const* name, Code parent = UnusedCode, Code specifiers = UnusedCode );
|
||||
|
||||
/*
|
||||
Creates a unit file.
|
||||
|
||||
These represent an encapsulation of a generated file
|
||||
Used this if you need to pass around a group of Code entires at file scope level.
|
||||
|
||||
The name provided is the name of the file.
|
||||
*/
|
||||
Code make_file_body( char const* name );
|
||||
#pragma endregion Incremental
|
||||
|
||||
/*
|
||||
*/
|
||||
Code parse_variable( char const* var_def, s32 length );
|
||||
|
||||
/*
|
||||
*/
|
||||
Code parse_using( char const* using_def, s32 length );
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
Code parse_operator( char const* operator_def, s32 length );
|
||||
|
||||
/*
|
||||
Define a procedure by parsing a string.
|
||||
|
||||
Note: This parser only supports the language features the library supports
|
||||
Any other features used and the lex or parse operation will fail.
|
||||
|
||||
This is not a full-on c/c++ parser, it literally only grabs
|
||||
what it needs to reconstruct the Code AST for seralization in the
|
||||
builder, nothing else.
|
||||
*/
|
||||
Code parse_proc( char const* proc_def, s32 length );
|
||||
|
||||
/*
|
||||
Define a struct by parsing a string.
|
||||
|
||||
Note: This parser only supports the language features the library supports
|
||||
Any other features used and the lex or parse operation will fail.
|
||||
|
||||
This is not a full-on c/c++ parser, it literally only grabs
|
||||
what it needs to reconstruct the Code AST for seralization in the
|
||||
builder, nothing else.
|
||||
*/
|
||||
Code parse_struct( char const* struct_def, s32 length );
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
s32 parse_vars( char const* vars_def, s32 length, Code* out_vars_codes );
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
s32 parse_usings( char const* usings_def, s32 length, Code* out_usings_codes );
|
||||
|
||||
#pragma region Untyped text
|
||||
/*
|
||||
Define an untyped code string.
|
||||
|
||||
@ -423,6 +713,7 @@ namespace gen
|
||||
Consider this an a preprocessor define.
|
||||
*/
|
||||
Code untyped_str( char const* str );
|
||||
Code untyped_str( char const* str, s32 length);
|
||||
|
||||
/*
|
||||
Define an untyped code string using traditional 'printf'.
|
||||
@ -449,18 +740,8 @@ namespace gen
|
||||
Because the code within it is untyped, errors will naturally not be provided.
|
||||
Consider this an a preprocessor define.
|
||||
*/
|
||||
Code token_fmt( char const* fmt, s32 num_tokens, ... );
|
||||
|
||||
|
||||
/*
|
||||
Creates a unit file.
|
||||
|
||||
These represent an encapsulation of a generated file
|
||||
Used this if you need to pass around a group of Code entires at file scope level.
|
||||
|
||||
The name provided is the name of the file.
|
||||
*/
|
||||
Code create_Unit( char const* name );
|
||||
Code untyped_token_fmt( char const* fmt, s32 num_tokens, ... );
|
||||
#pragma endregion Untyped text
|
||||
|
||||
/*
|
||||
Used to generate the files.
|
||||
@ -492,62 +773,93 @@ namespace gen
|
||||
|
||||
#pragma region MACROS
|
||||
# define gen_main main
|
||||
|
||||
# define __ UnusedCode
|
||||
# define __ UnusedCode
|
||||
|
||||
/*
|
||||
gen's Domain Specific Langauge.
|
||||
|
||||
Completely optional, makes the code gen syntax less verbose..
|
||||
Completely optional, makes the code gen syntax less verbose and cumbersome...
|
||||
Since its C macros ends up looking like a lisp dialect...
|
||||
|
||||
Longforms auto-define the variable.
|
||||
Shorthands are just the function call.
|
||||
|
||||
Anything below the make() macro is intended to be syntacticall used int he follwing format:
|
||||
make( <type>, <name> )
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
Where ... are whatever is deemed necessary to produce the definition for the def( <name> ).
|
||||
|
||||
The code macros are used to embed c/c++ to insert into the desired lcoation.
|
||||
*/
|
||||
#ifdef GEN_DEFINE_DSL
|
||||
# define type( Name_, Value_ ) Code Name_ = gen::def_type( txt(Value_) )
|
||||
# define type_fmt( Name_, Fmt_, ... ) Code Name_ = gen::def_type( bprintf( Fmt_, __VA_ARGS__ ) )
|
||||
# define value( Name_, Value_ ) Code Name_ = gen::untyped_str( Value_ )
|
||||
# define specifiers( Name_, ... ) Code Name_ = gen::def_specifiers( VA_NARGS( __VA_ARGS__ ), __VA_ARGS__ )
|
||||
# define using( Name_, Type_ ) Code Name_ = gen::def_using( #Name_, Type_ )
|
||||
# define untyped_code( Name_, Value_ ) Code Name_ = gen::untyped_str( txt(Value_) )
|
||||
# define typename( Name_, Value_ ) Code t_##Name_ = gen::def_type( txt(Value_) )
|
||||
# define typename_fmt( Name_, Fmt_, ... ) Code t_##Name_ = gen::def_type( bprintf( Fmt_, __VA_ARGS__ ) )
|
||||
# define using_type( Name_, Type_ ) Code Name_ = gen::def_using( #Name_, t_##Type_ )
|
||||
# define variable( Type_, Name_, ... ) Code Name_ = gen::def_variable( t_##Type_, #Name_, __VA_ARGS__ )
|
||||
|
||||
# define var( Name_, Type_, Value_, Specifiers_ ) \
|
||||
Code Name_ = gen::def_variable( #Name_, Type_, untyped_str( #Value_ ), Specifiers_ )
|
||||
# define untyped( Value_ ) gen::untyped_str( txt(Value_) )
|
||||
# define code_token( Fmt_, ... ) gen::untyped_token_fmt( Fmt_, VA_NARGS( __VA_ARGS__), __VA_ARGS__ )
|
||||
# define code_fmt( Fmt_, ... ) gen::untyped_fmt( Fmt_, __VA_ARGS__ )
|
||||
# define specifiers( ... ) gen::def_specifiers( VA_NARGS( __VA_ARGS__ ), __VA_ARGS__ )
|
||||
# define type( Value_ ) gen::def_type( txt(Value_) )
|
||||
# define type_fmt( Fmt_, ... ) gen::def_type( bprintf( Fmt_, __VA_ARGS__ ) )
|
||||
# define using( Name_, Type_ ) gen::def_using( #Name_, Type_ )
|
||||
# define var( Type_, Name_, ... ) gen::def_variable( Type_, #Name_, __VA_ARGS__ )
|
||||
|
||||
// # define def ( Name _ ) Code Name_;
|
||||
# define make( Type_, Name_, ... ) Code Name_ = make_##Type_( #Name_, __VA_ARGS__ );
|
||||
# define proc( Name_, Specifiers_, RetType_, Parameters_, Body_ ) Name_ = gen::def_proc( #Name_, Specifiers_, Parameters_, RetType_, Body_ )
|
||||
# define proc_body( ... ) gen::def_proc_body( VA_NARGS( __VA_ARS__ ), __VA_ARGS__ )
|
||||
# define params( ... ) gen::def_params( VA_NARGS( __VA_ARGS__ ) / 2, __VA_ARGS__ )
|
||||
# define struct( Name_, Parent_, Specifiers_, Body_ ) Name_ = gen::def_struct( #Name_, Body_, Parent_, Specifiers_ )
|
||||
# define struct_body( ... ) gen::def_struct_body( VA_NARGS( __VA_ARGS__ ), __VA_ARGS__ )
|
||||
|
||||
# define params( ... ) gen::def_parameters( VA_NARGS( __VA_ARGS__ ) / 2, __VA_ARGS__ )
|
||||
# define add_var( Type_, Name_, ... ) add( gen::def_variable( t_##Type_, #Name_, __VA_ARGS__ ) )
|
||||
# define add_untyped( Value_ ) add( gen::untyped_str( txt( Value ) ) )
|
||||
# define add_ret_type( ... )
|
||||
# define add_params( ... )
|
||||
|
||||
/*
|
||||
Defines scoped symbol.
|
||||
|
||||
Used with:
|
||||
- function
|
||||
- namespace
|
||||
- struct
|
||||
*/
|
||||
# define def( Name_ ) Code Name_;
|
||||
|
||||
# define function( Name_, Specifiers_, ReturnType_, Parameters_, Body_ ) \
|
||||
Name_ = gen::def_function( #Name_, Specifiers_, Parameters_, ReturnType_, Body_ )
|
||||
|
||||
# define function_body( ... ) \
|
||||
gen::def_function_body( VA_NARGS( __VA_ARS__ ), __VA_ARGS__ )
|
||||
|
||||
# define struct( Name_, Parent_, Specifiers_, Body_ ) \
|
||||
Name_ = gen::def_struct( #Name_, Body_, Parent_, Specifiers_ )
|
||||
|
||||
# define struct_body( ... ) \
|
||||
gen::def_struct_body( VA_NARGS( __VA_ARGS__ ), __VA_ARGS__ )
|
||||
# define proc_code( Def_ ) gen::parse_proc( txt( Def_ ), sizeof( txt( Def_ )) )
|
||||
# define struct_code( Def_ ) gen::parse_struct( txt( Def_ ), sizeof( txt( Def_ )) )
|
||||
#endif
|
||||
#pragma endregion MACROS
|
||||
|
||||
#pragma region CONSTANTS
|
||||
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||
namespace gen
|
||||
{
|
||||
// Predefined typename codes.
|
||||
// These are not set until gen::init is called.
|
||||
// This just preloads a bunch of Code types into the code pool.
|
||||
|
||||
extern const Code t_void;
|
||||
|
||||
extern const Code t_bool;
|
||||
extern const Code t_char;
|
||||
extern const Code t_wchar_t;
|
||||
|
||||
extern const Code t_s8;
|
||||
extern const Code t_s16;
|
||||
extern const Code t_s32;
|
||||
extern const Code t_s64;
|
||||
|
||||
extern const Code t_u8;
|
||||
extern const Code t_u16;
|
||||
extern const Code t_u32;
|
||||
extern const Code t_u64;
|
||||
|
||||
extern const Code t_sw;
|
||||
extern const Code t_uw;
|
||||
|
||||
extern const Code t_f32;
|
||||
extern const Code t_f64;
|
||||
|
||||
extern const Code spec_constexpr;
|
||||
extern const Code spec_inline;
|
||||
}
|
||||
#endif
|
||||
#pragma endregion CONSTANTS
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user