This commit is contained in:
2024-12-16 21:48:01 -05:00
parent 04ae75c698
commit 9c968967e2
28 changed files with 65 additions and 65 deletions

View File

@ -0,0 +1,61 @@
#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;
}
Context* ctx = get_context();
GEN_ASSERT_NOT_NULL(ctx);
result.Buffer = strbuilder_make_reserve( ctx->Allocator_Temp, ctx->InitSize_BuilderBuffer );
// log_fmt("$Builder - Opened file: %s\n", result.File.filename );
return result;
}
void builder_pad_lines( Builder* builder, s32 num )
{
strbuilder_append_str( & builder->Buffer, txt("\n") );
}
void builder_print( Builder* builder, Code code )
{
StrBuilder str = code_to_strbuilder(code);
// const ssize len = str.length();
// log_fmt( "%s - print: %.*s\n", File.filename, len > 80 ? 80 : len, str.Data );
strbuilder_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 = c_str_fmt_va( buf, count_of( buf ) - 1, fmt, va ) - 1;
strbuilder_append_c_str_len( (StrBuilder*) & (builder->Buffer), (char const*)buf, res);
}
void builder_write(Builder* builder)
{
b32 result = file_write( & builder->File, builder->Buffer, strbuilder_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 );
strbuilder_free(& builder->Buffer);
}
#pragma endregion Builder

View File

@ -0,0 +1,71 @@
#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"
using namespace gen;
#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_write ( Builder* builder );
forceinline 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 );
}
struct Builder
{
FileInfo File;
StrBuilder 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
forceinline void builder_pad_lines( Builder& builder, s32 num ) { return builder_pad_lines(& builder, num); }
forceinline void builder_print ( Builder& builder, Code code ) { return builder_print(& builder, code); }
forceinline void builder_write ( Builder& builder ) { return builder_write(& builder ); }
forceinline 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( Str template, Str instantiation );

148
base/auxiliary/scanner.cpp Normal file
View File

@ -0,0 +1,148 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
# include "scanner.hpp"
#endif
#pragma region Scanner
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 );
}
StrBuilder str = strbuilder_make_reserve( get_context()->Allocator_Temp, fsize );
file_read( & file, str, fsize );
strbuilder_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 Str directive_start = txt( "ifdef" );
const Str directive_end = txt( "endif" );
const Str 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 && c_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 && c_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 && c_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 );
strbuilder_get_header(str)->Length = left;
break;
}
mem_move( str, scanner, left );
strbuilder_get_header(str)->Length = left;
break;
}
}
move_fwd();
}
#undef move_fwd
#undef matched
#undef current
}
file_close( & file );
return untyped_str( strbuilder_to_str(str) );
}
CodeBody parse_file( const char* path ) {
FileContents file = file_read_contents( get_context()->Allocator_Temp, true, path );
Str content = { (char const*)file.data, file.size };
CodeBody code = parse_global_body( content );
log_fmt("\nParsed: %s\n", path);
return code;
}
CSV_Column parse_csv_one_column(AllocatorInfo allocator, char const* path) {
FileContents content = file_read_contents( allocator, file_zero_terminate, path );
Arena csv_arena = arena_init_from_memory(content.data, content.size);
CSV_Column result;
csv_parse( & result.ADT, rcast(char*, content.data), allocator, false );
result.Content = result.ADT.nodes[0].nodes;
return result;
}
CSV_Columns2 parse_csv_two_columns(AllocatorInfo allocator, char const* path) {
FileContents content = file_read_contents( allocator, file_zero_terminate, path );
Arena csv_arena = arena_init_from_memory(content.data, content.size);
CSV_Columns2 result;
csv_parse( & result.ADT, rcast(char*, content.data), allocator, false );
result.Col_1 = result.ADT.nodes[0].nodes;
result.Col_2 = result.ADT.nodes[1].nodes;
return result;
}
#pragma endregion Scanner

View File

@ -0,0 +1,46 @@
#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.
Code scan_file( char const* path );
CodeBody parse_file( const char* path );
// 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 ADT;
Array(ADT_Node) Content;
};
typedef struct CSV_Columns2 CSV_Columns2;
struct CSV_Columns2 {
CSV_Object ADT;
Array(ADT_Node) Col_1;
Array(ADT_Node) Col_2;
};
CSV_Column parse_csv_one_column(AllocatorInfo allocator, char const* path);
CSV_Columns2 parse_csv_two_columns(AllocatorInfo allocator, char const* path);
#pragma endregion Scanner