2023-08-28 21:03:08 -07:00
|
|
|
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
|
|
|
# pragma once
|
|
|
|
# include "gen.hpp"
|
|
|
|
#endif
|
2023-08-21 18:40:23 -07:00
|
|
|
|
2023-08-21 17:27:00 -07:00
|
|
|
// 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.
|
2024-10-24 23:59:56 -07:00
|
|
|
inline
|
2023-08-28 20:46:50 -07:00
|
|
|
Code scan_file( char const* path )
|
2023-07-24 19:19:21 -07:00
|
|
|
{
|
|
|
|
FileInfo file;
|
|
|
|
|
|
|
|
FileError error = file_open_mode( & file, EFileMode_READ, path );
|
|
|
|
if ( error != EFileError_NONE )
|
|
|
|
{
|
2023-08-09 15:47:59 -07:00
|
|
|
GEN_FATAL( "scan_file: Could not open: %s", path );
|
2023-07-24 19:19:21 -07:00
|
|
|
}
|
|
|
|
|
2024-10-27 15:58:37 -07:00
|
|
|
ssize fsize = file_size( & file );
|
2023-07-24 19:19:21 -07:00
|
|
|
if ( fsize <= 0 )
|
|
|
|
{
|
2023-08-09 15:47:59 -07:00
|
|
|
GEN_FATAL("scan_file: %s is empty", path );
|
2023-07-24 19:19:21 -07:00
|
|
|
}
|
|
|
|
|
2024-12-01 00:06:30 -08:00
|
|
|
String str = string_make_reserve( GlobalAllocator, fsize );
|
2023-07-24 19:19:21 -07:00
|
|
|
file_read( & file, str, fsize );
|
2024-12-04 08:01:53 -08:00
|
|
|
string_get_header(str)->Length = fsize;
|
2023-07-24 19:19:21 -07:00
|
|
|
|
2023-08-28 20:46:50 -07:00
|
|
|
// 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.
|
2023-08-21 17:27:00 -07:00
|
|
|
{
|
|
|
|
#define current (*scanner)
|
2023-08-28 20:46:50 -07:00
|
|
|
#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;
|
2024-12-03 15:47:12 -08:00
|
|
|
char const* scanner = (char const*)str;
|
2023-08-28 20:46:50 -07:00
|
|
|
s32 left = fsize;
|
|
|
|
while ( left )
|
2023-08-21 17:27:00 -07:00
|
|
|
{
|
2023-08-28 20:46:50 -07:00
|
|
|
// Processing directive.
|
|
|
|
if ( current == '#' )
|
2023-08-21 17:27:00 -07:00
|
|
|
{
|
2023-08-28 20:46:50 -07:00
|
|
|
move_fwd();
|
|
|
|
while ( left && char_is_space( current ) )
|
|
|
|
move_fwd();
|
2023-08-21 17:27:00 -07:00
|
|
|
|
2023-08-28 20:46:50 -07:00
|
|
|
if ( ! found_directive )
|
2023-08-21 17:27:00 -07:00
|
|
|
{
|
2024-12-04 08:01:53 -08:00
|
|
|
if ( left && str_compare_len( scanner, directive_start.Ptr, directive_start.Len ) == matched )
|
2023-08-21 17:27:00 -07:00
|
|
|
{
|
2023-08-28 20:46:50 -07:00
|
|
|
scanner += directive_start.Len;
|
|
|
|
left -= directive_start.Len;
|
2023-08-21 17:27:00 -07:00
|
|
|
|
2023-08-28 20:46:50 -07:00
|
|
|
while ( left && char_is_space( current ) )
|
|
|
|
move_fwd();
|
2023-08-21 19:48:05 -07:00
|
|
|
|
2024-12-04 08:01:53 -08:00
|
|
|
if ( left && str_compare_len( scanner, def_intellisense.Ptr, def_intellisense.Len ) == matched )
|
2023-08-28 20:46:50 -07:00
|
|
|
{
|
|
|
|
scanner += def_intellisense.Len;
|
|
|
|
left -= def_intellisense.Len;
|
|
|
|
|
|
|
|
found_directive = true;
|
|
|
|
}
|
2023-08-21 17:27:00 -07:00
|
|
|
}
|
2023-08-28 20:46:50 -07:00
|
|
|
|
|
|
|
// Skip to end of line
|
|
|
|
while ( left && current != '\r' && current != '\n' )
|
|
|
|
move_fwd();
|
|
|
|
move_fwd();
|
|
|
|
|
|
|
|
if ( left && current == '\n' )
|
|
|
|
move_fwd();
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2024-12-04 08:01:53 -08:00
|
|
|
if ( left && str_compare_len( scanner, directive_end.Ptr, directive_end.Len ) == matched )
|
2023-08-28 20:46:50 -07:00
|
|
|
{
|
|
|
|
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();
|
|
|
|
|
2023-09-07 19:51:15 -07:00
|
|
|
// sptr skip_size = fsize - left;
|
2024-12-03 15:47:12 -08:00
|
|
|
if ( (scanner + 2) >= ( (char const*) str + fsize ) )
|
2023-08-21 17:27:00 -07:00
|
|
|
{
|
2023-08-28 20:46:50 -07:00
|
|
|
mem_move( str, scanner, left );
|
2024-12-04 08:01:53 -08:00
|
|
|
string_get_header(str)->Length = left;
|
2023-08-28 20:46:50 -07:00
|
|
|
break;
|
2023-08-21 17:27:00 -07:00
|
|
|
}
|
|
|
|
|
2023-08-28 20:46:50 -07:00
|
|
|
mem_move( str, scanner, left );
|
2024-12-04 08:01:53 -08:00
|
|
|
string_get_header(str)->Length = left;
|
2023-08-21 17:27:00 -07:00
|
|
|
|
2023-08-28 20:46:50 -07:00
|
|
|
break;
|
2023-08-21 17:27:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-28 20:46:50 -07:00
|
|
|
move_fwd();
|
2023-08-21 17:27:00 -07:00
|
|
|
}
|
2023-08-28 20:46:50 -07:00
|
|
|
#undef move_fwd
|
|
|
|
#undef matched
|
2023-08-21 17:27:00 -07:00
|
|
|
#undef current
|
|
|
|
}
|
2023-07-24 19:19:21 -07:00
|
|
|
|
2023-08-21 17:27:00 -07:00
|
|
|
file_close( & file );
|
2024-12-04 08:01:53 -08:00
|
|
|
return untyped_str( string_to_strc(str) );
|
2023-07-24 19:19:21 -07:00
|
|
|
}
|
|
|
|
|
2023-08-03 20:18:33 -07:00
|
|
|
#if 0
|
2023-09-11 20:22:53 -07:00
|
|
|
struct CodeFile
|
2023-07-24 19:19:21 -07:00
|
|
|
{
|
2023-09-11 20:22:53 -07:00
|
|
|
using namespace Parser;
|
2023-07-18 20:33:00 -07:00
|
|
|
|
2023-09-11 20:22:53 -07:00
|
|
|
String FilePath;
|
|
|
|
TokArray Tokens;
|
|
|
|
Array<ParseFailure> ParseFailures;
|
|
|
|
Code CodeRoot;
|
2023-07-18 20:33:00 -07:00
|
|
|
};
|
|
|
|
|
2023-09-11 20:22:53 -07:00
|
|
|
namespace Parser
|
2023-07-18 20:33:00 -07:00
|
|
|
{
|
2023-09-11 20:22:53 -07:00
|
|
|
struct ParseFailure
|
2023-07-18 20:33:00 -07:00
|
|
|
{
|
2023-09-11 20:22:53 -07:00
|
|
|
String Reason;
|
|
|
|
Code Node;
|
2023-07-18 20:33:00 -07:00
|
|
|
};
|
2023-09-11 20:22:53 -07:00
|
|
|
}
|
2023-07-18 20:33:00 -07:00
|
|
|
|
2023-09-11 20:22:53 -07:00
|
|
|
CodeFile scan_file( char const* path )
|
|
|
|
{
|
|
|
|
using namespace Parser;
|
2023-07-18 20:33:00 -07:00
|
|
|
|
2023-09-11 20:22:53 -07:00
|
|
|
CodeFile
|
|
|
|
result = {};
|
|
|
|
result.FilePath = String::make( GlobalAllocator, path );
|
2023-07-18 20:33:00 -07:00
|
|
|
|
2023-09-11 20:22:53 -07:00
|
|
|
Code code = scan_file( path );
|
|
|
|
result.CodeRoot = code;
|
2023-07-18 20:33:00 -07:00
|
|
|
|
2023-09-11 20:22:53 -07:00
|
|
|
ParseContext context = parser_get_last_context();
|
|
|
|
result.Tokens = context.Tokens;
|
|
|
|
result.ParseFailures = context.Failures;
|
2023-07-18 20:33:00 -07:00
|
|
|
|
2023-09-11 20:22:53 -07:00
|
|
|
return result;
|
|
|
|
}
|
2023-08-03 20:18:33 -07:00
|
|
|
#endif
|