From fc8239ad8df35a34ef35039ac66c60155486a00f Mon Sep 17 00:00:00 2001 From: Ed_ Date: Fri, 30 Jun 2023 13:56:31 -0400 Subject: [PATCH] Non parsed buffer implemented. --- Readme.md | 4 +- test/NonParsed/Array.NonParsed.hpp | 39 ++-- test/NonParsed/Buffer.NonParsed.hpp | 281 ++++++++++++++++++++++++++++ test/test.cpp | 4 + thirdparty/zpl.h | 3 +- 5 files changed, 314 insertions(+), 17 deletions(-) create mode 100644 test/NonParsed/Buffer.NonParsed.hpp diff --git a/Readme.md b/Readme.md index 9ba25dd..de47151 100644 --- a/Readme.md +++ b/Readme.md @@ -24,7 +24,7 @@ Intended for small-to midsized projects. ## Notes This project is not minimum feature complete yet. -Version 1 will have C and a subset of C++ features available to it. +Version 1 will have C and a subset of C++ features available to it. I will generate with this library a C99 or 11 variant when Version 1 is complete. A single-header version will also be generated. @@ -35,6 +35,8 @@ With the dependency code being under 10000 sloc. (Containers, Memory, String han Any dependencies from the zpl library will be exposed manually with using declarations into global scope. They will be removed when the library is feature complete for version 1 (zero dependencies milestone). +*Right now the upfront constructors are working to some extent based on testing* + ***The editor and scanner will NOT be implemented by version 1. They require alot code and the focus for version 1 is to have a robust constructor API and builder, witch a wide suite of usage examples in the tests for the project.*** ## Usage diff --git a/test/NonParsed/Array.NonParsed.hpp b/test/NonParsed/Array.NonParsed.hpp index 23d1586..0d88790 100644 --- a/test/NonParsed/Array.NonParsed.hpp +++ b/test/NonParsed/Array.NonParsed.hpp @@ -91,22 +91,31 @@ Code gen__array( StrC type, sw type_size ) init_reserve = def_function( name(init_reserve), params, t_array_type, body, spec_static ); } - Code append = def_function( name(append), def_param(t_type, name(value)), t_bool - , untyped_str( code( - Header& header = get_header(); + Code append; + { + Code param_type; + if ( type_size <= 8 ) + param_type = t_type; + else + param_type = t_type_ref; - if ( header.Num == header.Capacity ) - { - if ( ! grow( header.Capacity )) - return false; - } + append = def_function( name(append), def_param(param_type, name(value)), t_bool + , untyped_str( code( + Header& header = get_header(); - Data[ header.Num ] = value; - header.Num++; + if ( header.Num == header.Capacity ) + { + if ( ! grow( header.Capacity )) + return false; + } - return true; - )) - ); + Data[ header.Num ] = value; + header.Num++; + + return true; + )) + ); + } Code back; { @@ -278,8 +287,8 @@ Code gen__array( StrC type, sw type_size ) struct GenArrayRequest { - StrC Type; StrC Dependency; + StrC Type; sw Size; }; Array(GenArrayRequest) GenArrayRequests; @@ -290,7 +299,7 @@ void gen__array_request( StrC type, sw size, StrC dep = {} ) array_init( GenArrayRequests, g_allocator ); do_once_end - GenArrayRequest request = { type, dep, size }; + GenArrayRequest request = { dep, type, size }; array_append( GenArrayRequests, request ); } #define gen_array( type ) gen__array_request( { txt_n_len(type) }, sizeof(type) ) diff --git a/test/NonParsed/Buffer.NonParsed.hpp b/test/NonParsed/Buffer.NonParsed.hpp new file mode 100644 index 0000000..45c52ce --- /dev/null +++ b/test/NonParsed/Buffer.NonParsed.hpp @@ -0,0 +1,281 @@ +#pragma once + +#if gen_time +#include "gen.hpp" + +using namespace gen; + +Code gen__buffer_base() +{ + Code t_allocator_info = def_type( name(AllocatorInfo) ); + + Code header = def_struct( name(BufferHeader), def_struct_body( 3 + , def_variable( t_allocator_info, name(Backing) ) + , def_variable( t_uw, name(Capacity) ) + , def_variable( t_uw, name(Num) ) + )); + + return def_global_body( code_args( 1, header ) ); +} + +Code gen__buffer( StrC type, sw type_size ) +{ + static Code t_allocator_info = def_type( name(AllocatorInfo)); + + static Code using_header = def_using( name(Header), def_type( name(BufferHeader) ) ); + + StrC name; + { + char const* name_str = str_fmt_buf( "Buffer_%s\0", type.Ptr ); + s32 name_len = str_len( name_str ); + + name = { name_len, name_str }; + }; + + Code t_buffer_type = def_type( name ); + + Code t_type = def_type( type ); + Code t_type_ptr = def_type( type, __, spec_ptr ); + Code t_type_ref = def_type( type, __, spec_ref ); + + Code t_header = def_type( name(Header) ); + Code t_header_ptr = def_type( name(Header), __, spec_ptr ); + Code t_header_ref = def_type( name(Header), __, spec_ref ); + + Code buffer; + { + Code using_type = def_using( name(Type), t_type ); + Code data = def_variable( t_type_ptr, name(Data) ); + + Code init; + { + Code params = def_params( 2 + , def_param( t_allocator_info, name(allocator)) + , def_param( t_sw, name(capacity)) + ); + + Code body = untyped_str( code( + Header* header = rcast( Header*, alloc( allocator, sizeof(Header) + capacity * sizeof(Type) ) ); + + if ( header == nullptr ) + return { nullptr }; + + header->Backing = allocator; + header->Capacity = capacity; + header->Num = 0; + + return { rcast( Type*, header + 1) }; + )); + + init = def_function( name(init), params, t_buffer_type, body, spec_static_member ); + } + + Code init_copy; + { + Code params = def_params( 2 + , def_param( t_allocator_info, name(allocator)) + , def_param( t_buffer_type, name(other)) + ); + + init_copy = def_function( name(init), params, t_buffer_type + , untyped_str( code( + Header& other_header = other.get_header(); + Header* header = rcast( Header*, alloc( allocator, sizeof(Header) + other_header.Capacity * sizeof(Type) ) ); + + if ( header == nullptr ) + return { nullptr }; + + header->Backing = allocator; + header->Capacity = other_header.Capacity; + header->Num = other_header.Num; + + mem_copy( header + 1, other.Data, other_header.Num * sizeof(Type) ); + return { rcast( Type*, header + 1) }; + )) + ); + } + + Code append; + { + Code param_type; + if ( type_size <= 8 ) + param_type = t_type; + else + param_type = t_type_ref; + + append = def_function( name(append), def_param( param_type, name(value)), t_void + , untyped_str( code( + Header& header = get_header(); + Data[ header.Num ] = value; + header.Num++; + )) + , spec_inline + ); + } + + Code appendv; + { + Code params = def_params( 2 + , def_param( t_type_ptr, name( values)) + , def_param( t_sw, name( num)) + ); + + appendv = def_function( name(append), params, t_void + , untyped_str( code( + Header& header = get_header(); + + ZPL_ASSERT( header.Num + num <= header.Capacity); + + mem_copy( Data + header.Num, values, num * sizeof( Type ) ); + + header.Num += num; + )) + , spec_inline + ); + } + + Code clear = def_function( name(clear), __, t_void + , untyped_str( code( + Header& header = get_header(); + header.Num = 0; + )) + , spec_inline + ); + + Code end = def_function( name(end), __, t_type_ref + , untyped_str( code( + Header& header = get_header(); + return Data[ header.Num - 1 ]; + )) + , spec_inline + ); + + Code free = def_function( name(free), __, t_void + , untyped_str( code( + Header& header = get_header(); + zpl::free( header.Backing, & header ); + )) + , spec_inline + ); + + Code get_header = def_function( name(get_header), __, t_header_ref + , untyped_str( code( + return * ( rcast( Header*, Data ) - 1 ); + )) + , spec_inline + ); + + Code num = def_function( name(num), __, t_sw + , untyped_str( code( + return get_header().Num; + )) + , spec_inline + ); + + Code pop = def_function( name(pop), __, t_type + , untyped_str( code( + Header& header = get_header(); + header.Num--; + return Data[ header.Num ]; + )) + , spec_inline + ); + + Code wipe = def_function( name(wipe), __, t_void + , untyped_str( code( + Header& header = get_header(); + header.Num = 0; + mem_set( Data, 0, header.Capacity * sizeof( Type ) ); + )) + , spec_inline + ); + + Code op_type_ptr = untyped_str( code( + operator Type*() + { + return Data; + } + )); + + buffer = def_struct( name, def_struct_body( 14 + , using_header + , using_type + + , init + , init_copy + , append + , appendv + , clear + , end + , free + , get_header + , num + , wipe + + , op_type_ptr + + , data + )); + } + + return buffer; +} + +struct GenBufferRequest +{ + StrC Dependency; + StrC Type; + sw TypeSize; +}; +Array(GenBufferRequest) GenBufferRequests;; + +void gen__buffer_request( StrC type, sw size, StrC dep = {} ) +{ + do_once_start + array_init( GenBufferRequests, g_allocator ); + do_once_end + + GenBufferRequest request = { dep, type, size}; + array_append( GenBufferRequests, request ); +} +#define gen_buffer( type ) gen__buffer_request( { txt_n_len(type) }, sizeof( type )) + +u32 gen_buffer_file() +{ + Builder + gen_buffer_file; + gen_buffer_file.open( "buffer.gen.hpp" ); + + gen_buffer_file.print( def_include( StrC::from("Bloat.hpp")) ); + gen_buffer_file.print( gen__buffer_base() ); + + GenBufferRequest* current = GenBufferRequests; + s32 left = array_count( GenBufferRequests ); + while (left--) + { + GenBufferRequest const& request = * current; + + Code generated_buffer = gen__buffer( current->Type, current->TypeSize ); + + if ( request.Dependency ) + { + char const* cmt_str = str_fmt_buf( "// Dependency for %s type", request.Type ); + s32 cmt_len = str_len( cmt_str ); + + Code cmt = def_comment( { cmt_len, cmt_str } ); + Code include = def_include( request.Dependency ); + + gen_buffer_file.print( cmt ); + gen_buffer_file.print( include ); + } + + gen_buffer_file.print( generated_buffer ); + + ++current; + } + + gen_buffer_file.write(); + return 0; +} + +#endif // gen_time diff --git a/test/test.cpp b/test/test.cpp index 6a29f38..bea69a5 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -1,5 +1,6 @@ #include "Bloat.cpp" #include "NonParsed\Array.NonParsed.hpp" +#include "NonParsed\Buffer.NonParsed.hpp" #include "NonParsed\Sanity.hpp" @@ -20,6 +21,9 @@ int gen_main() // gen_array( sw ); gen_array_file(); + gen_buffer( u8 ); + gen_buffer_file(); + gen::deinit(); Memory::cleanup(); return 0; diff --git a/thirdparty/zpl.h b/thirdparty/zpl.h index 5ac12b8..71e5853 100644 --- a/thirdparty/zpl.h +++ b/thirdparty/zpl.h @@ -3992,6 +3992,7 @@ typedef struct BufferHeader ZPL_NS( buffer_init )( Name, allocator, cap ) #define ZPL_BUFFER_HEADER( x ) ( zpl_cast( ZPL_NS( BufferHeader )* )( x ) - 1 ) +#define buffer_allocator( x ) ( ZPL_BUFFER_HEADER( x )->backing ) #define buffer_count( x ) ( ZPL_BUFFER_HEADER( x )->count ) #define buffer_capacity( x ) ( ZPL_BUFFER_HEADER( x )->capacity ) #define buffer_end( x ) ( x + ( buffer_count( x ) - 1 ) ) @@ -4027,7 +4028,7 @@ typedef struct BufferHeader #define buffer_copy_init( y, x ) \ do \ { \ - ZPL_NS( buffer_init_reserve )( y, ZPL_NS( buffer_allocator )( x ), buffer_capacity( x ) ); \ + buffer_init( y, buffer_allocator( x ), buffer_capacity( x ) ); \ ZPL_NS( mem_copy )( y, x, buffer_capacity( x ) * size_of( *x ) ); \ buffer_count( y ) = buffer_count( x ); \ } while ( 0 )