Iniital commit

This commit is contained in:
Edward R. Gonzalez 2023-04-01 22:21:46 -04:00
commit f09fe6aa15
19 changed files with 19851 additions and 0 deletions

11
.editorconfig Normal file
View 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
View File

@ -0,0 +1,3 @@
.idea
build/*

11
.vscode/settings.json vendored Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View File

@ -0,0 +1,2 @@
cls
Invoke-Expression "& $(Join-Path $PSScriptRoot 'build.ci.ps1') $args"

24
scripts/clean.ps1 Normal file
View 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
View 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
View 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 )

View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff