mirror of
https://github.com/Ed94/gencpp.git
synced 2024-12-22 07:44:45 -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