mirror of
https://github.com/Ed94/gencpp.git
synced 2024-11-10 02:54:53 -08:00
Iniital commit
This commit is contained in:
commit
f09fe6aa15
11
.editorconfig
Normal file
11
.editorconfig
Normal file
@ -0,0 +1,11 @@
|
||||
[*.md]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[*.c]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[*.cpp]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
.idea
|
||||
|
||||
build/*
|
11
.vscode/settings.json
vendored
Normal file
11
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"*.rmd": "markdown",
|
||||
"array": "cpp",
|
||||
"compare": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"xtr1common": "cpp",
|
||||
"xutility": "cpp"
|
||||
}
|
||||
}
|
170
project/Bloat.cpp
Normal file
170
project/Bloat.cpp
Normal file
@ -0,0 +1,170 @@
|
||||
#define BLOAT_IMPL
|
||||
#include "Bloat.refactored.hpp"
|
||||
|
||||
namespace Global
|
||||
{
|
||||
bool ShouldShowDebug = false;
|
||||
}
|
||||
|
||||
namespace Memory
|
||||
{
|
||||
arena Global_Arena {};
|
||||
|
||||
void setup()
|
||||
{
|
||||
arena_init_from_allocator( & Global_Arena, heap(), Initial_Reserve );
|
||||
|
||||
if ( Global_Arena.total_size == 0 )
|
||||
{
|
||||
assert_crash( "Failed to reserve memory for Tests:: Global_Arena" );
|
||||
}
|
||||
}
|
||||
|
||||
void resize( uw new_size )
|
||||
{
|
||||
void* new_memory = resize( heap(), Global_Arena.physical_start, Global_Arena.total_size, new_size );
|
||||
|
||||
if ( new_memory == nullptr )
|
||||
{
|
||||
fatal("Failed to resize global arena!");
|
||||
}
|
||||
|
||||
Global_Arena.physical_start = new_memory;
|
||||
Global_Arena.total_size = new_size;
|
||||
}
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
arena_free( & Global_Arena);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool opts_custom_add(opts* options, opts_entry *t, char* b)
|
||||
{
|
||||
if (t->type != ZPL_OPTS_STRING)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
t->text = string_append_length(t->text, " ", 1);
|
||||
t->text = string_appendc( t->text, b );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
b32 opts_custom_compile(opts *options, int argc, char **argv)
|
||||
{
|
||||
b32 had_errors = false;
|
||||
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
char* arg = argv[i];
|
||||
|
||||
if (*arg)
|
||||
{
|
||||
arg = (char*)str_trim(arg, false);
|
||||
|
||||
if (*arg == '-')
|
||||
{
|
||||
opts_entry* entry = 0;
|
||||
b32 checkln = false;
|
||||
if ( *(arg + 1) == '-')
|
||||
{
|
||||
checkln = true;
|
||||
++arg;
|
||||
}
|
||||
|
||||
char *b = arg + 1, *e = b;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !had_errors;
|
||||
}
|
138
project/Bloat.hpp
Normal file
138
project/Bloat.hpp
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
BLOAT.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef BLOAT_IMPL
|
||||
# define ZPL_IMPLEMENTATION
|
||||
#endif
|
||||
|
||||
#pragma region ZPL INCLUDE
|
||||
#if __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wmissing-braces"
|
||||
# pragma clang diagnostic ignored "-Wbraced-scalar-init"
|
||||
#endif
|
||||
|
||||
// # define ZPL_HEAP_ANALYSIS
|
||||
# define ZPL_NO_MATH_H
|
||||
# define ZPL_CUSTOM_MODULES
|
||||
# define ZPL_MODULE_ESSENTIALS
|
||||
# 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
|
||||
#include "zpl.h"
|
||||
|
||||
#if __clang__
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
||||
#pragma endregion ZPL INCLUDE
|
||||
|
||||
|
||||
|
||||
#if __clang__
|
||||
# pragma clang diagnostic ignored "-Wunused-const-variable"
|
||||
# pragma clang diagnostic ignored "-Wswitch"
|
||||
# pragma clang diagnostic ignored "-Wunused-variable"
|
||||
# pragma clang diagnostic ignored "-Wunknown-pragmas"
|
||||
#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 scast( Type_, Value_ ) static_cast< Type_ >( Value_ )
|
||||
#define rcast( Type_, Value_ ) reinterpret_cast< Type_ >( Value_ )
|
||||
#define pcast( Type_, Value_ ) ( * (Type_*)( & Value_ ) )
|
||||
|
||||
#define do_once() \
|
||||
do \
|
||||
{ \
|
||||
static \
|
||||
bool Done = false; \
|
||||
if ( Done ) \
|
||||
return; \
|
||||
Done = true; \
|
||||
} \
|
||||
while(0) \
|
||||
|
||||
|
||||
using Line = char*;
|
||||
using Array_Line = array( Line );
|
||||
|
||||
|
||||
ct char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
|
||||
|
||||
|
||||
namespace Global
|
||||
{
|
||||
extern bool ShouldShowDebug;
|
||||
}
|
||||
|
||||
namespace Memory
|
||||
{
|
||||
ct uw Initial_Reserve = megabytes(2);
|
||||
|
||||
extern arena Global_Arena;
|
||||
#define g_allocator arena_allocator( & Memory::Global_Arena)
|
||||
|
||||
void setup();
|
||||
void resize( uw new_size );
|
||||
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
|
||||
sw log_fmt(char const *fmt, ...)
|
||||
{
|
||||
if ( Global::ShouldShowDebug == false )
|
||||
return 0;
|
||||
|
||||
sw res;
|
||||
va_list va;
|
||||
|
||||
va_start(va, fmt);
|
||||
res = zpl_printf_va(fmt, va);
|
||||
va_end(va);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
inline
|
||||
void fatal(char const *fmt, ...)
|
||||
{
|
||||
local_persist thread_local
|
||||
char buf[ZPL_PRINTF_MAXLEN] = { 0 };
|
||||
|
||||
va_list va;
|
||||
|
||||
#if Build_Debug
|
||||
va_start(va, fmt);
|
||||
zpl_snprintf_va(buf, ZPL_PRINTF_MAXLEN, fmt, va);
|
||||
va_end(va);
|
||||
|
||||
assert_crash(buf);
|
||||
#else
|
||||
va_start(va, fmt);
|
||||
zpl_printf_err_va( fmt, va);
|
||||
va_end(va);
|
||||
|
||||
zpl_exit(1);
|
||||
#endif
|
||||
}
|
277
project/gen.cpp
Normal file
277
project/gen.cpp
Normal file
@ -0,0 +1,277 @@
|
||||
#include "Bloat.hpp"
|
||||
#include "gen.hpp"
|
||||
|
||||
#ifdef gen_time
|
||||
namespace gen
|
||||
{
|
||||
static Code Unused()
|
||||
{
|
||||
static Code value = {
|
||||
Code::Unused,
|
||||
string_make( g_allocator, "Unused" )
|
||||
};
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
Code decl_type( char const* name, Code specifiers, Code type )
|
||||
{
|
||||
Code
|
||||
result;
|
||||
result.Type = Code::Decl_Type;
|
||||
result.Name = string_make( g_allocator, name );
|
||||
result.add( specifiers );
|
||||
result.add( type );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Code decl_fn( char const* name
|
||||
, Code specifiers
|
||||
, Code params
|
||||
, Code ret_type
|
||||
)
|
||||
{
|
||||
Code
|
||||
result;
|
||||
result.Type = Code::Decl_Function;
|
||||
result.Name = string_make( g_allocator, name );
|
||||
|
||||
array_init( result.Content, g_allocator );
|
||||
|
||||
if ( specifiers )
|
||||
result.add( specifiers );
|
||||
|
||||
result.add( ret_type );
|
||||
|
||||
if ( params )
|
||||
result.add( params );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Code make_parameters( s32 num, ... )
|
||||
{
|
||||
if (num <= 0)
|
||||
fatal("TT::make_paramters: num is %d", num);
|
||||
|
||||
Code result;
|
||||
|
||||
va_list va;
|
||||
va_start(va, num);
|
||||
|
||||
result.Name = string_make( g_allocator, va_arg(va, char const*) );
|
||||
result.add( va_arg(va, Code) );
|
||||
|
||||
while( num -= 2, num % 2 )
|
||||
{
|
||||
Code
|
||||
param;
|
||||
param.Name = string_make( g_allocator, va_arg(va, char const*) );
|
||||
param.add( va_arg(va, Code) );
|
||||
|
||||
result.add(param);
|
||||
}
|
||||
|
||||
va_end(va);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Code make_fmt(char const* fmt, ...)
|
||||
{
|
||||
local_persist thread_local
|
||||
char buf[ZPL_PRINTF_MAXLEN] = { 0 };
|
||||
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
zpl_snprintf_va(buf, ZPL_PRINTF_MAXLEN, fmt, va);
|
||||
va_end(va);
|
||||
|
||||
Code
|
||||
code;
|
||||
code.Name = string_make( g_allocator, fmt );
|
||||
code.Type = Code::Untyped;
|
||||
code.Content = string_make( g_allocator, buf );
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
Code make_function( char const* name
|
||||
, Code specifiers
|
||||
, Code params
|
||||
, Code ret_type
|
||||
, Code body )
|
||||
{
|
||||
Code
|
||||
result;
|
||||
result.Name = string_make( g_allocator, name );
|
||||
result.Type = Code::Function;
|
||||
|
||||
array_init( result.Content, g_allocator );
|
||||
|
||||
if ( specifiers )
|
||||
result.add( specifiers );
|
||||
|
||||
result.add( ret_type );
|
||||
|
||||
if ( params )
|
||||
result.add( params );
|
||||
|
||||
result.add( body );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Code make_specifier( u32 num, ... )
|
||||
{
|
||||
if ( num <= 0 )
|
||||
fatal("gen::make_specifier: num cannot be zero.");
|
||||
|
||||
Code
|
||||
result;
|
||||
|
||||
va_list va;
|
||||
va_start(va, num);
|
||||
do
|
||||
{
|
||||
Specifier type = va_arg(va, Specifier);
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case Alignas:
|
||||
result.Content = string_sprintf_buf( g_allocator, "%s(%d)", specifier_str(type), va_arg(va, u32) );
|
||||
break;
|
||||
|
||||
default:
|
||||
result.Content = string_make( g_allocator, specifier_str(type) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
while ( num-- );
|
||||
va_end(va);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
string Code::to_string()
|
||||
{
|
||||
string result = string_make( g_allocator, "" );
|
||||
|
||||
if ( Comment )
|
||||
result = string_append_fmt( result, "// %s\n", Comment );
|
||||
|
||||
switch ( Type )
|
||||
{
|
||||
case Invalid:
|
||||
fatal("Attempted to serialize invalid code! - %s", Name);
|
||||
break;
|
||||
|
||||
case Untyped:
|
||||
result = string_append_length( result, Content, string_length(Content) );
|
||||
break;
|
||||
|
||||
case Decl_Type:
|
||||
if ( Entries[0].Type == Specifiers )
|
||||
result = string_append_fmt("%s\n", Entries[0].to_string());
|
||||
|
||||
result = string_append_fmt( result, "%s %s;\n", Entries[1].to_string(), Name );
|
||||
break;
|
||||
|
||||
case Decl_Function:
|
||||
u32 index = 0;
|
||||
u32 left = array_count( Entries );
|
||||
|
||||
if ( left <= 0 )
|
||||
fatal( "Code::to_string - Name: %s Type: %s, expected definition", Name, Type );
|
||||
|
||||
if ( Entries[index].Type == Specifiers )
|
||||
{
|
||||
result = string_append_fmt( result, "%s\n", Entries[index].to_string() );
|
||||
index++;
|
||||
left--;
|
||||
}
|
||||
|
||||
if ( left <= 0 )
|
||||
fatal( "Code::to_string - Name: %s Type: %s, expected return type", Name, Type );
|
||||
|
||||
result = string_append_fmt( result, "\n%s %s(", Entries[index].to_string(), Name );
|
||||
index++;
|
||||
left--;
|
||||
|
||||
if ( left && Entries[index].Type == Parameters )
|
||||
{
|
||||
result = string_append_fmt( result, "%s, ", Entries[index].to_string() );
|
||||
index++;
|
||||
left--;
|
||||
}
|
||||
|
||||
result = string_appendc( result, ");\n" );
|
||||
break;
|
||||
|
||||
case Parameters:
|
||||
result = string_append_fmt( result, "%s %s", Entries[0], Name );
|
||||
|
||||
u32 index = 1;
|
||||
u32 left = array_count( Entries ) - 1;
|
||||
|
||||
while ( left-- )
|
||||
result = string_append_fmt( result, ", %s %s", Entries[index].Entries[0], Entries[index].Name );
|
||||
break;
|
||||
|
||||
case Struct:
|
||||
fatal("NOT SUPPORTED YET");
|
||||
break;
|
||||
|
||||
case Function:
|
||||
u32 index = 0;
|
||||
u32 left = array_count( Entries );
|
||||
|
||||
if ( left <= 0 )
|
||||
fatal( "Code::to_string - Name: %s Type: %s, expected definition", Name, Type );
|
||||
|
||||
while ( Entries[index].Type == EType::Specifiers )
|
||||
{
|
||||
result = string_append_fmt( result, "%s ", Entries[index] );
|
||||
index++;
|
||||
}
|
||||
|
||||
if ( left <= 0 )
|
||||
fatal( "Code::to_string - Name: %s Type: %s, expected return type", Name, Type );
|
||||
|
||||
result = string_append_fmt( result, "\n%s %s(", Entries[index], Name );
|
||||
index++;
|
||||
|
||||
while ( left && Entries[index].Type == Parameters )
|
||||
{
|
||||
result = string_append_fmt( result, "%s, ", Entries[index] );
|
||||
index++;
|
||||
}
|
||||
|
||||
result = string_append_fmt( result, ")\n{\n%s\n}", Entries[index] );
|
||||
break;
|
||||
|
||||
case Specifiers:
|
||||
result = string_append_fmt( result, "%s", Content );
|
||||
break;
|
||||
|
||||
case Variable:
|
||||
// result = string_append_fmt( result, "%s", )
|
||||
break;
|
||||
|
||||
case Typename:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
gen_main();
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif gen_time
|
216
project/gen.hpp
Normal file
216
project/gen.hpp
Normal file
@ -0,0 +1,216 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef gen_time
|
||||
#include "Bloat.hpp"
|
||||
|
||||
namespace gen
|
||||
{
|
||||
ct sw ColumnLimit = 256;
|
||||
ct sw MaxLines = kilobytes(256);
|
||||
|
||||
using LineStr = char[ColumnLimit];
|
||||
|
||||
enum Specifier : u8
|
||||
{
|
||||
Alignas, // alignas(#)
|
||||
Constexpr, // constexpr
|
||||
Inline, // inline
|
||||
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)
|
||||
Local_Persist, // static (within function)
|
||||
Thread_Local, // thread_local
|
||||
|
||||
Num_Specifiers
|
||||
};
|
||||
|
||||
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",
|
||||
"thread_local"
|
||||
};
|
||||
|
||||
return lookup[ specifier ];
|
||||
}
|
||||
|
||||
struct Code
|
||||
{
|
||||
enum EType : u8
|
||||
{
|
||||
Invalid,
|
||||
Unused,
|
||||
|
||||
Untyped, // User provided raw string.
|
||||
|
||||
Decl_Type,
|
||||
Decl_Function,
|
||||
Parameters, // Used with functions.
|
||||
Struct,
|
||||
Function,
|
||||
Specifiers,
|
||||
Variable,
|
||||
Typename,
|
||||
|
||||
Num_Types
|
||||
};
|
||||
|
||||
#pragma region Member API
|
||||
void comment( string value )
|
||||
{
|
||||
Comment = value;
|
||||
}
|
||||
|
||||
forceinline
|
||||
void add( Code other )
|
||||
{
|
||||
array_append( Entries, other );
|
||||
}
|
||||
|
||||
forceinline
|
||||
void add( array(Code) other )
|
||||
{
|
||||
array_appendv( Entries, other, sizeof(other) );
|
||||
}
|
||||
|
||||
forceinline
|
||||
void add( Code* entries, u32 num_entries )
|
||||
{
|
||||
array_appendv( Entries, entries, num_entries );
|
||||
}
|
||||
|
||||
forceinline
|
||||
bool has_entries()
|
||||
{
|
||||
static bool lookup[Num_Types] = {
|
||||
false, // Invalid
|
||||
false, // Unused
|
||||
false, // Untyped
|
||||
true, // Decl_Type
|
||||
true, // Decl_Function
|
||||
true, // Parameter
|
||||
true, // Struct
|
||||
true, // Function
|
||||
false, // Specifier
|
||||
true, // Variable
|
||||
true, // Typename
|
||||
};
|
||||
|
||||
return lookup[Type];
|
||||
}
|
||||
|
||||
string to_string();
|
||||
|
||||
forceinline
|
||||
operator bool()
|
||||
{
|
||||
return Type == Invalid;
|
||||
}
|
||||
|
||||
operator char const*()
|
||||
{
|
||||
return to_string();
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool operator ==( Code& other )
|
||||
{
|
||||
bool children_equal = true;
|
||||
|
||||
#define is( Value_ ) Type == Value_
|
||||
|
||||
if ( has_children() )
|
||||
{
|
||||
u32 left = array_count( Children );
|
||||
do
|
||||
{
|
||||
|
||||
}
|
||||
while ( left--, left > 0 )
|
||||
}
|
||||
|
||||
return
|
||||
Type == other.Type
|
||||
&& Name == other.Name
|
||||
&& children_equal
|
||||
;
|
||||
}
|
||||
#endif
|
||||
#pragma endregion Member API
|
||||
|
||||
#define Using_Code_POD \
|
||||
Code::EType Type; \
|
||||
string Name; \
|
||||
string Comment; \
|
||||
union { \
|
||||
array(Code) Entries; \
|
||||
string Content; \
|
||||
};
|
||||
|
||||
Using_Code_POD;
|
||||
};
|
||||
|
||||
using CodeType = Code::EType;
|
||||
|
||||
struct Code_POD
|
||||
{
|
||||
Using_Code_POD;
|
||||
};
|
||||
|
||||
Code decl_type( char const* name, Code specifiers, Code type);
|
||||
|
||||
Code decl_fn( char const* name
|
||||
, Code specifiers
|
||||
, Code params
|
||||
, Code ret_type
|
||||
);
|
||||
|
||||
Code make_parameters( u32 num, ... );
|
||||
|
||||
Code make_fmt( char const* fmt, ... );
|
||||
|
||||
Code make_function( char const* name
|
||||
, Code specifiers
|
||||
, Code params
|
||||
, Code ret_type
|
||||
, Code body
|
||||
);
|
||||
|
||||
Code make_specifiers( u32 num , ... );
|
||||
|
||||
// Code make_variable( char const* name, char const* type );
|
||||
|
||||
// Code make_template( Code subject, u32 num_dependents, ... );
|
||||
|
||||
// Code make_type( char const* name );
|
||||
|
||||
// Code make_using( char const* name, char const* type );
|
||||
|
||||
|
||||
struct File
|
||||
{
|
||||
zpl_file file;
|
||||
string Content;
|
||||
|
||||
s32 print( Code );
|
||||
|
||||
bool open( char const* Path );
|
||||
void write();
|
||||
};
|
||||
}
|
||||
#endif
|
114
scripts/build.ci.ps1
Normal file
114
scripts/build.ci.ps1
Normal file
@ -0,0 +1,114 @@
|
||||
[string] $type = $null
|
||||
[string] $test = $false
|
||||
|
||||
foreach ( $arg in $args )
|
||||
{
|
||||
if ( $arg -eq "test" )
|
||||
{
|
||||
$test = $true
|
||||
}
|
||||
else
|
||||
{
|
||||
$type = $arg
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($false)
|
||||
{
|
||||
#region Regular Build
|
||||
write-host "Building project`n"
|
||||
|
||||
$path_root = git rev-parse --show-toplevel
|
||||
$path_build = Join-Path $path_root build
|
||||
$path_scripts = Join-Path $path_root scripts
|
||||
|
||||
|
||||
if ( -not( Test-Path $path_build ) )
|
||||
{
|
||||
$args_meson = @()
|
||||
$args_meson += "setup"
|
||||
$args_meson += $path_build
|
||||
|
||||
# Start-Process meson $args_meson -NoNewWindow -Wait -WorkingDirectory $path_scripts
|
||||
Push-Location $path_scripts
|
||||
Invoke-Expression "& meson $args_meson"
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
if ( $type )
|
||||
{
|
||||
$args_meson = @()
|
||||
$args_meson += "configure"
|
||||
$args_meson += $path_build
|
||||
$args_meson += "--buildtype $($type)"
|
||||
|
||||
# Start-Process meson $args_meson -NoNewWindow -Wait -WorkingDirectory $path_scripts
|
||||
Push-Location $path_scripts
|
||||
Invoke-Expression "& meson $args_meson"
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
$args_ninja = @()
|
||||
$args_ninja += "-C"
|
||||
$args_ninja += $path_build
|
||||
|
||||
Push-Location $path_root
|
||||
ninja $args_ninja
|
||||
Pop-Location
|
||||
#endregion Regular Build
|
||||
}
|
||||
|
||||
|
||||
# if ( $test -eq $true )
|
||||
# {
|
||||
#region Test Build
|
||||
write-host "`n`nBuilding Test`n"
|
||||
|
||||
$path_test = Join-Path $path_root test
|
||||
$path_gen = Join-Path $path_test gen
|
||||
$path_test_build = Join-Path $path_test build
|
||||
$path_gen_build = Join-Path $path_gen build
|
||||
|
||||
# Generate files using metaprogram.
|
||||
if ( -not( Test-Path $path_gen_build ) )
|
||||
{
|
||||
$args_meson = @()
|
||||
$args_meson += "setup"
|
||||
$args_meson += $path_gen_build
|
||||
|
||||
Push-Location $path_gen
|
||||
& meson $args_meson
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
$args_ninja = @()
|
||||
$args_ninja += "-C"
|
||||
$args_ninja += $path_gen_build
|
||||
|
||||
Push-Location $path_root
|
||||
ninja $args_ninja
|
||||
Pop-Location
|
||||
|
||||
|
||||
# Build the program depending on generated files.
|
||||
# if ( -not( Test-Path $path_test_build ) )
|
||||
# {
|
||||
# $args_meson = @()
|
||||
# $args_meson += "setup"
|
||||
# $args_meson += $path_test_build
|
||||
|
||||
# Push-Location $path_test
|
||||
# & meson $args_meson
|
||||
# Pop-Location
|
||||
# }
|
||||
|
||||
# $args_ninja = @()
|
||||
# $args_ninja += "-C"
|
||||
# $args_ninja += $path_test_build
|
||||
|
||||
# Push-Location $path_root
|
||||
# ninja $args_ninja
|
||||
# Pop-Location
|
||||
#endregion Test Build
|
||||
# }
|
2
scripts/build.ps1
Normal file
2
scripts/build.ps1
Normal file
@ -0,0 +1,2 @@
|
||||
cls
|
||||
Invoke-Expression "& $(Join-Path $PSScriptRoot 'build.ci.ps1') $args"
|
24
scripts/clean.ps1
Normal file
24
scripts/clean.ps1
Normal file
@ -0,0 +1,24 @@
|
||||
$path_root = git rev-parse --show-toplevel
|
||||
$path_build = Join-Path $path_root build
|
||||
$path_test = Join-Path $path_root test
|
||||
$path_test_build = Join-Path $path_test build
|
||||
|
||||
if ( Test-Path $path_build )
|
||||
{
|
||||
Remove-Item $path_build -Recurse
|
||||
}
|
||||
|
||||
if ( Test-Path $path_test_build )
|
||||
{
|
||||
Remove-Item $path_test_build -Recurse
|
||||
}
|
||||
|
||||
# [string[]] $include = '*.h', '*.hpp', '*.cpp'
|
||||
# [string[]] $exclude =
|
||||
|
||||
# $files = Get-ChildItem -Recurse -Path $path_test -Include $include -Exclude $exclude
|
||||
|
||||
# if ( $files )
|
||||
# {
|
||||
# Remove-Item $files
|
||||
# }
|
12
scripts/get_sources.ps1
Normal file
12
scripts/get_sources.ps1
Normal file
@ -0,0 +1,12 @@
|
||||
[string[]] $include = 'gen.cpp' #'*.c', '*.cc', '*.cpp'
|
||||
# [string[]] $exclude =
|
||||
|
||||
$path_root = git rev-parse --show-toplevel
|
||||
$path_proj = Join-Path $path_root project
|
||||
|
||||
$files = Get-ChildItem -Recurse -Path $path_proj -Include $include -Exclude $exclude
|
||||
|
||||
$sources = $files | Select-Object -ExpandProperty FullName | Resolve-Path -Relative
|
||||
$sources = $sources.Replace( '\', '/' )
|
||||
|
||||
return $sources
|
19
scripts/meson.build
Normal file
19
scripts/meson.build
Normal file
@ -0,0 +1,19 @@
|
||||
project( 'refactor', 'c', 'cpp', default_options : ['buildtype=release'] )
|
||||
|
||||
# add_global_arguments('-E', language : 'cpp')
|
||||
|
||||
includes = include_directories(
|
||||
[ '../project'
|
||||
, '../thirdparty'
|
||||
])
|
||||
|
||||
get_sources = files('./get_sources.ps1')
|
||||
sources = files(run_command('powershell', get_sources, check: true).stdout().strip().split('\n'))
|
||||
|
||||
if get_option('buildtype').startswith('debug')
|
||||
|
||||
add_project_arguments('-DBuild_Debug', language : ['c', 'cpp'])
|
||||
|
||||
endif
|
||||
|
||||
executable( 'refactor', sources, include_directories : includes )
|
13
test/array.gen.manual.hpp.txt
Normal file
13
test/array.gen.manual.hpp.txt
Normal file
@ -0,0 +1,13 @@
|
||||
// Handwritten generated code:
|
||||
|
||||
|
||||
#pragma region gen_array
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma endregion gen_array
|
||||
|
||||
|
||||
|
||||
#define Array( Type_ ) Array_##Type_
|
164
test/array.hpp.txt
Normal file
164
test/array.hpp.txt
Normal file
@ -0,0 +1,164 @@
|
||||
#include "gen.hpp"
|
||||
#include "bloat.hpp"
|
||||
|
||||
#if tt
|
||||
#define gen_array( Type_ ) gen__array( #Type_ )
|
||||
Code* gen__array( char const* type )
|
||||
{
|
||||
Code codegen;
|
||||
|
||||
Code
|
||||
data;
|
||||
data.add( "%type* data" );
|
||||
|
||||
Code header;
|
||||
header.define_struct( "Header",
|
||||
"uw Num;"
|
||||
"uw Capacity;"
|
||||
"allocator Allocator;"
|
||||
);
|
||||
|
||||
Code grow_formula;
|
||||
grow_formula.define_function( "grow_formula", "static", "forceinline",
|
||||
"return 2 * value * 8"
|
||||
);
|
||||
|
||||
codegen.define_struct( "Array",
|
||||
data
|
||||
, header
|
||||
, grow_formula
|
||||
);
|
||||
|
||||
codegen.define
|
||||
|
||||
R"(
|
||||
%type* data;
|
||||
|
||||
struct Header
|
||||
{
|
||||
uw Num;
|
||||
uw Capacity;
|
||||
allocator Allocator;
|
||||
};
|
||||
|
||||
static forceinline
|
||||
sw grow_formula ( sw value )
|
||||
{
|
||||
return 2 * value * 8;
|
||||
}
|
||||
|
||||
static
|
||||
bool init ( %Array& array, allocator mem_handler )
|
||||
{
|
||||
return init_reserve( array, mem_handler, grow_formula(0) );
|
||||
}
|
||||
|
||||
static
|
||||
bool init_reserve( %Array& array, allocator mem_handler, uw capacity )
|
||||
{
|
||||
Header*
|
||||
header = nullptr;
|
||||
header = rcast( Header*, alloc( mem_handler, size_of( Header ) + sizeof(type) * capacity ));
|
||||
|
||||
if (header == nullptr)
|
||||
return false;
|
||||
|
||||
header->Num = 0;
|
||||
header->Capacity = capacity;
|
||||
header->Allocator = mem_handler;
|
||||
|
||||
array.data = rcast( %type*, header + 1 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void append( %type value )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
type back()
|
||||
{
|
||||
Header& header = get_header();
|
||||
return data[ header.Num - 1 ];
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
get_header().Num = 0;
|
||||
}
|
||||
|
||||
void fill( uw begin, uw end, type value )
|
||||
{
|
||||
Header& header = get_header();
|
||||
|
||||
if ( begin < 0 || end >= header.Num )
|
||||
{
|
||||
fatal( "Range out of bounds" );
|
||||
}
|
||||
}
|
||||
|
||||
void free()
|
||||
{
|
||||
Header& header = get_header();
|
||||
::free( header.Allocator, & get_header() );
|
||||
}
|
||||
|
||||
bool grow( uw min_capacity )
|
||||
{
|
||||
Header& header = get_header();
|
||||
|
||||
uw new_capacity = grow_formula( header.Capacity );
|
||||
|
||||
if ( new_capacity < min_capacity )
|
||||
new_capacity = min_capacity;
|
||||
|
||||
return set_capacity( new_capacity );
|
||||
}
|
||||
|
||||
forceinline
|
||||
Header& get_header()
|
||||
{
|
||||
return vcast( Header, data - 1 );
|
||||
}
|
||||
|
||||
void pop()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void reserve()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void resize()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool set_capacity( uw capacity )
|
||||
{
|
||||
Header& header = get_header();
|
||||
|
||||
if ( capacity == header.Capacity )
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
)"
|
||||
, type
|
||||
);
|
||||
};
|
||||
#endif
|
||||
|
||||
void tt_run()
|
||||
{
|
||||
gen_array( u32 );
|
||||
}
|
||||
#endif tt
|
||||
|
||||
|
||||
#if !tt
|
||||
#include "array.gen.manual.hpp"
|
||||
#endif
|
25
test/gen/meson.build
Normal file
25
test/gen/meson.build
Normal file
@ -0,0 +1,25 @@
|
||||
project( 'test', 'c', 'cpp', default_options : ['buildtype=debug'] )
|
||||
|
||||
# add_global_arguments('-E', language : 'cpp')
|
||||
|
||||
includes = include_directories(
|
||||
[
|
||||
'../test'
|
||||
'../project'
|
||||
, '../thirdparty'
|
||||
])
|
||||
|
||||
# get_sources = files('./get_sources.ps1')
|
||||
# sources = files(run_command('powershell', get_sources, check: true).stdout().strip().split('\n'))
|
||||
|
||||
sources = [ 'test.cpp' ]
|
||||
|
||||
if get_option('buildtype').startswith('debug')
|
||||
|
||||
add_project_arguments('-DBuild_Debug', language : ['c', 'cpp'])
|
||||
|
||||
endif
|
||||
|
||||
add_project_arguments('-Dgen_time', langauge : ['c', 'cpp'])
|
||||
|
||||
executable( '', sources, include_directories : includes )
|
71
test/math.hpp
Normal file
71
test/math.hpp
Normal file
@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef gen_time
|
||||
#include "Bloat.hpp"
|
||||
#include "gen.hpp"
|
||||
|
||||
using namespace gen;
|
||||
|
||||
/*
|
||||
What it should generate:
|
||||
|
||||
inline
|
||||
type square_#type( type value )
|
||||
{
|
||||
return value * value;
|
||||
}
|
||||
*/
|
||||
#define gen_square( Type_ ) gen__squre( #Type_ )
|
||||
Code gen__squre( char const* type )
|
||||
{
|
||||
Code integral_type = make_type( type );
|
||||
|
||||
string name = string_sprintf_buf( g_allocator, "square_%s", type );
|
||||
Code specifiers = make_specifiers( 1, Specifier::Inline );
|
||||
Code params = make_parameters( 1, "value", integral_type );
|
||||
Code ret_stmt = make_fmt( "return value * value" );
|
||||
|
||||
Code result = make_function( name,
|
||||
specifiers,
|
||||
params,
|
||||
integral_type,
|
||||
ret_stmt
|
||||
);
|
||||
|
||||
if ( ! result )
|
||||
fatal( "Failed to generate square function for: %s", type );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
u32 gen_math()
|
||||
{
|
||||
Code fadd_u8 = gen_square( u8 );
|
||||
Code fadd_u16 = gen_square( u16 );
|
||||
Code fadd_u32 = gen_square( u32 );
|
||||
Code fadd_u64 = gen_square( u64 );
|
||||
|
||||
File
|
||||
mathgen;
|
||||
mathgen.open( "math.gen.hpp" );
|
||||
mathgen.print( fadd_u8 );
|
||||
mathgen.print( fadd_u16 );
|
||||
mathgen.print( fadd_u32 );
|
||||
mathgen.print( fadd_u64 );
|
||||
mathgen.write();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef gen_time
|
||||
#include "math.gen.hpp"
|
||||
#undef square
|
||||
|
||||
#define sym_square( Type_, Value_ ) square_#Type_( Value_ )
|
||||
|
||||
template<class type>
|
||||
type square( type value )
|
||||
[
|
||||
sym_square( type, value );
|
||||
]
|
||||
#endif
|
22
test/meson.build
Normal file
22
test/meson.build
Normal file
@ -0,0 +1,22 @@
|
||||
project( 'test', 'c', 'cpp', default_options : ['buildtype=debug'] )
|
||||
|
||||
# add_global_arguments('-E', language : 'cpp')
|
||||
|
||||
includes = include_directories(
|
||||
[
|
||||
'../project'
|
||||
, '../thirdparty'
|
||||
])
|
||||
|
||||
# get_sources = files('./get_sources.ps1')
|
||||
# sources = files(run_command('powershell', get_sources, check: true).stdout().strip().split('\n'))
|
||||
|
||||
sources = [ 'math.hpp' ]
|
||||
|
||||
if get_option('buildtype').startswith('debug')
|
||||
|
||||
add_project_arguments('-DBuild_Debug', language : ['c', 'cpp'])
|
||||
|
||||
endif
|
||||
|
||||
executable( '', sources, include_directories : includes )
|
21
test/test.cpp
Normal file
21
test/test.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
#include "math.hpp"
|
||||
|
||||
|
||||
#ifdef gen_time
|
||||
u32 gen_main()
|
||||
{
|
||||
return gen_math();
|
||||
}
|
||||
|
||||
#include "gen.cpp"
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef gen_time
|
||||
int main()
|
||||
{
|
||||
u32 result = square(5);
|
||||
|
||||
zpl_printf("TEST RESULT: %d", result);
|
||||
}
|
||||
#endif
|
18538
thirdparty/zpl.h
vendored
Normal file
18538
thirdparty/zpl.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user