WIP: Restructuring project

This commit is contained in:
2024-12-10 16:13:14 -05:00
parent e3b3882443
commit 2c51a2f9c8
107 changed files with 417 additions and 4168 deletions

View File

@@ -0,0 +1,59 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
# include "builder.hpp"
#endif
#pragma region Builder
Builder builder_open( char const* path )
{
Builder result;
FileError error = file_open_mode( & result.File, EFileMode_WRITE, path );
if ( error != EFileError_NONE )
{
log_failure( "gen::File::open - Could not open file: %s", path);
return result;
}
result.Buffer = string_make_reserve( GlobalAllocator, Builder_StrBufferReserve );
// log_fmt("$Builder - Opened file: %s\n", result.File.filename );
return result;
}
void builder_pad_lines( Builder* builder, s32 num )
{
string_append_strc( & builder->Buffer, txt("\n") );
}
void builder_print( Builder* builder, Code code )
{
String str = code_to_string(code);
// const ssize len = str.length();
// log_fmt( "%s - print: %.*s\n", File.filename, len > 80 ? 80 : len, str.Data );
string_append_string( & builder->Buffer, str );
}
void builder_print_fmt_va( Builder* builder, char const* fmt, va_list va )
{
ssize res;
char buf[ GEN_PRINTF_MAXLEN ] = { 0 };
res = str_fmt_va( buf, count_of( buf ) - 1, fmt, va ) - 1;
string_append_c_str_len( (String*) & (builder->Buffer), (char const*)buf, res);
}
void builder_write(Builder* builder)
{
b32 result = file_write( & builder->File, builder->Buffer, string_length(builder->Buffer) );
if ( result == false )
log_failure("gen::File::write - Failed to write to file: %s\n", file_name( & builder->File ) );
log_fmt( "Generated: %s\n", builder->File.filename );
file_close( & builder->File );
string_free(& builder->Buffer);
}
#pragma endregion Builder

View File

@@ -0,0 +1,69 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
# pragma once
# include "helpers/push_ignores.inline.hpp"
# include "components/header_start.hpp"
# include "components/types.hpp"
# include "components/gen/ecode.hpp"
# include "components/gen/eoperator.hpp"
# include "components/gen/especifier.hpp"
# include "components/ast.hpp"
# include "components/code_types.hpp"
# include "components/ast_types.hpp"
# include "components/interface.hpp"
# include "components/inlines.hpp"
# include "components/gen/ast_inlines.hpp"
# include "components/header_end.hpp"
#endif
#pragma region Builder
struct Builder;
typedef struct Builder Builder;
Builder builder_open ( char const* path );
void builder_pad_lines ( Builder* builder, s32 num );
void builder_print ( Builder* builder, Code code );
void builder_print_fmt_va( Builder* builder, char const* fmt, va_list va );
void builder_print_fmt ( Builder* builder, char const* fmt, ... ) {
va_list va;
va_start( va, fmt );
builder_print_fmt_va( builder, fmt, va );
va_end( va );
}
void builder_write( Builder* builder );
struct Builder
{
FileInfo File;
String Buffer;
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
forceinline static Builder open( char const* path ) { return builder_open(path); }
forceinline void pad_lines( s32 num ) { return builder_pad_lines(this, num); }
forceinline void print( Code code ) { return builder_print(this, code); }
forceinline void print_fmt( char const* fmt, ... ) {
va_list va;
va_start( va, fmt );
builder_print_fmt_va( this, fmt, va );
va_end( va );
}
forceinline void write() { return builder_write(this); }
#endif
};
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
void builder_pad_lines( Builder& builder, s32 num ) { return builder_pad_lines(& builder, num); }
void builder_print ( Builder& builder, Code code ) { return builder_print(& builder, code); }
void builder_write ( Builder& builder ) { return builder_write(& builder ); }
void builder_print_fmt( Builder& builder, char const* fmt, ...) {
va_list va;
va_start( va, fmt );
builder_print_fmt_va( & builder, fmt, va );
va_end( va );
}
#endif
#pragma endregion Builder

View File

@@ -0,0 +1,35 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
# pragma once
# include "helpers/push_ignores.inline.hpp"
# include "components/header_start.hpp"
# include "components/types.hpp"
# include "components/gen/ecode.hpp"
# include "components/gen/eoperator.hpp"
# include "components/gen/especifier.hpp"
# include "components/ast.hpp"
# include "components/code_types.hpp"
# include "components/ast_types.hpp"
# include "components/interface.hpp"
# include "components/inlines.hpp"
# include "components/gen/ast_inlines.hpp"
# include "components/header_end.hpp"
#endif
/*
Explicitly generates a resolved definition of a cpp template definition.
TODO(Ed): Needs implementing for the C-library variant.
TODO(Ed): We need a non <token> syntax subst implemtnation for Strings for this to work. It must subst keywords directly based on template parameter names.
This is only meant to be used on relatively trivial templates, where the type or numeric is mostly a 'duck' type.
It cannot parse complex template parameters.
The varadic args should correspond 1:1 with the type of objects the generator expects from the template's parameters.alignas.
*/
CodeOperator gen_operator_template( CodeTemplate template, ... );
CodeFn gen_func_template( CodeTemplate template, ... );
Code gen_class_struct_template( CodeTemplate template, ... );
Code gen_template( CodeTemplate template, ... );
Code gen_template( StrC template, StrC instantiation );

View File

@@ -0,0 +1,5 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
# include "scanner.hpp"
#endif

185
base/auxillary/scanner.hpp Normal file
View File

@@ -0,0 +1,185 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
# pragma once
# include "helpers/push_ignores.inline.hpp"
# include "components/header_start.hpp"
# include "components/types.hpp"
# include "components/gen/ecode.hpp"
# include "components/gen/eoperator.hpp"
# include "components/gen/especifier.hpp"
# include "components/ast.hpp"
# include "components/code_types.hpp"
# include "components/ast_types.hpp"
# include "components/interface.hpp"
# include "components/inlines.hpp"
# include "components/gen/ast_inlines.hpp"
# include "components/header_end.hpp"
#endif
#pragma region Scanner
// This is a simple file reader that reads the entire file into memory.
// It has an extra option to skip the first few lines for undesired includes.
// This is done so that includes can be kept in dependency and component files so that intellisense works.
inline
Code scan_file( char const* path )
{
FileInfo file;
FileError error = file_open_mode( & file, EFileMode_READ, path );
if ( error != EFileError_NONE )
{
GEN_FATAL( "scan_file: Could not open: %s", path );
}
ssize fsize = file_size( & file );
if ( fsize <= 0 )
{
GEN_FATAL("scan_file: %s is empty", path );
}
String str = string_make_reserve( GlobalAllocator, fsize );
file_read( & file, str, fsize );
string_get_header(str)->Length = fsize;
// Skip GEN_INTELLISENSE_DIRECTIVES preprocessor blocks
// Its designed so that the directive should be the first thing in the file.
// Anything that comes before it will also be omitted.
{
#define current (*scanner)
#define matched 0
#define move_fwd() do { ++ scanner; -- left; } while (0)
const StrC directive_start = txt( "ifdef" );
const StrC directive_end = txt( "endif" );
const StrC def_intellisense = txt("GEN_INTELLISENSE_DIRECTIVES" );
bool found_directive = false;
char const* scanner = (char const*)str;
s32 left = fsize;
while ( left )
{
// Processing directive.
if ( current == '#' )
{
move_fwd();
while ( left && char_is_space( current ) )
move_fwd();
if ( ! found_directive )
{
if ( left && str_compare_len( scanner, directive_start.Ptr, directive_start.Len ) == matched )
{
scanner += directive_start.Len;
left -= directive_start.Len;
while ( left && char_is_space( current ) )
move_fwd();
if ( left && str_compare_len( scanner, def_intellisense.Ptr, def_intellisense.Len ) == matched )
{
scanner += def_intellisense.Len;
left -= def_intellisense.Len;
found_directive = true;
}
}
// Skip to end of line
while ( left && current != '\r' && current != '\n' )
move_fwd();
move_fwd();
if ( left && current == '\n' )
move_fwd();
continue;
}
if ( left && str_compare_len( scanner, directive_end.Ptr, directive_end.Len ) == matched )
{
scanner += directive_end.Len;
left -= directive_end.Len;
// Skip to end of line
while ( left && current != '\r' && current != '\n' )
move_fwd();
move_fwd();
if ( left && current == '\n' )
move_fwd();
// sptr skip_size = fsize - left;
if ( (scanner + 2) >= ( (char const*) str + fsize ) )
{
mem_move( str, scanner, left );
string_get_header(str)->Length = left;
break;
}
mem_move( str, scanner, left );
string_get_header(str)->Length = left;
break;
}
}
move_fwd();
}
#undef move_fwd
#undef matched
#undef current
}
file_close( & file );
return untyped_str( string_to_strc(str) );
}
CodeBody parse_file( const char* path )
{
FileContents file = file_read_contents( GlobalAllocator, true, path );
CodeBody code = parse_global_body( { file.size, (char const*)file.data } );
log_fmt("\nParsed: %s\n", path);
return code;
}
// The follow is basic support for light csv parsing (use it as an example)
// Make something robust if its more serious.
typedef struct CSV_Column CSV_Column;
struct CSV_Column {
CSV_Object Owner;
Array<ADT_Node> Content;
};
typedef struct CSV_Columns2 CSV_Columns2;
struct CSV_Columns2 {
CSV_Object Owner;
Array<ADT_Node> Col_1;
Array<ADT_Node> Col_2;
};
CSV_Column parse_csv_one_column(AllocatorInfo allocator, char const* path) {
char scratch_mem[kilobytes(32)];
Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) );
file_read_contents( arena_allocator_info( & scratch), file_zero_terminate, path );
CSV_Column result;
csv_parse( & result.owner, scratch_mem, allocator, false );
result.Content = csv_nodes.nodes[0].nodes;
return result;
}
CSV_Columns2 parse_csv_two_columns(AllocatorInfo allocator, char const* path) {
char scratch_mem[kilobytes(32)];
Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) );
file_read_contents( arena_allocator_info( & scratch), file_zero_terminate, path );
CSV_Columns2 result;
csv_parse( & result.owner, scratch_mem, allocator, false );
result.Col_1 = csv_nodes.nodes[0].nodes;
result.Col_2 = csv_nodes.nodes[1].nodes;
return result;
}
#pragma endregion Scanner