Take code from stdin. Version bump.

This commit is contained in:
Christoffer Lerno
2022-10-18 19:26:45 +02:00
committed by Christoffer Lerno
parent f8f249ee2c
commit 7d58ce0dcb
9 changed files with 75 additions and 2 deletions

View File

@@ -90,6 +90,7 @@ static void usage(void)
OUTPUT(" -E - Lex only.");
OUTPUT(" -P - Only parse and output the AST as S-expressions.");
OUTPUT(" -C - Only lex, parse and check.");
OUTPUT(" - - Read code from standard in.");
OUTPUT(" -o <file> - Write output to <file>.");
OUTPUT(" -O0 - Optimizations off.");
OUTPUT(" -O1 - Simple optimizations only.");
@@ -360,6 +361,9 @@ static void parse_option(BuildOptions *options)
const char *argopt;
switch (current_arg[1])
{
case '\0':
options->read_stdin = true;
return;
case '?':
if (match_shortopt("?"))
{

View File

@@ -265,6 +265,7 @@ typedef struct BuildOptions_
bool no_stdlib;
bool no_libc;
bool force_linker;
bool read_stdin;
const char *panicfn;
const char *cc;
const char *build_dir;
@@ -347,6 +348,7 @@ typedef struct
bool force_linker;
bool benchmarking;
bool testing;
bool read_stdin;
OptimizationLevel optimization_level;
SizeOptimizationLevel size_optimization_level;
bool single_module;

View File

@@ -283,6 +283,7 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
void init_default_build_target(BuildTarget *target, BuildOptions *options)
{
*target = (BuildTarget) {
.read_stdin = options->read_stdin,
.type = TARGET_TYPE_EXECUTABLE,
.source_dirs = options->files,
.name = options->output_name,

View File

@@ -102,6 +102,11 @@ void compiler_parse(void)
global_context_clear_errors();
parse_file(file);
}
if (active_target.read_stdin)
{
global_context_clear_errors();
parse_stdin();
}
exit_compiler(COMPILER_SUCCESS_EXIT);
}
@@ -663,7 +668,7 @@ void compile()
compiler_init_time = bench_mark();
if (!vec_size(active_target.sources)) error_exit("No files to compile.");
if (!vec_size(active_target.sources) && !active_target.read_stdin) error_exit("No files to compile.");
if (active_target.lex_only)
{
compiler_lex();

View File

@@ -236,6 +236,9 @@ typedef union
uint64_t a;
} SourceSpan;
extern File stdin_file;
#define stdin_file_id 0xFFFF
static_assert(sizeof(SourceSpan) == 8, "Expected 8 bytes");
typedef struct
@@ -2145,6 +2148,7 @@ Decl *module_find_symbol(Module *module, const char *symbol);
const char *module_create_object_file_name(Module *module);
bool parse_file(File *file);
bool parse_stdin(void);
Path *path_create_from_string(const char *string, uint32_t len, SourceSpan span);
#define SEMA_ERROR_HERE(...) sema_error_at(c->span, __VA_ARGS__)

View File

@@ -108,6 +108,57 @@ bool parse_file(File *file)
return !global_context.errors_found;
}
File stdin_file;
/**
* Parse stdin
*
* @return true if parsing succeeds.
*/
bool parse_stdin(void)
{
stdin_file = (File){
.name = "stdin",
.file_id = stdin_file_id,
.full_path = "<stdin>",
};
#define BUF_SIZE 65536
char buffer[BUF_SIZE];
size_t capacity = BUF_SIZE;
size_t len = 0;
char *data = buffer;
while (true)
{
int c = getchar();
if (c == -1) break;
if (len >= capacity - 1)
{
capacity *= 2;
if (buffer == data)
{
data = malloc(capacity);
memcpy(data, buffer, len);
}
else
{
data = realloc(data, capacity);
}
}
data[len++] = c;
}
buffer[len] = 0;
char *stdin_data = MALLOC(len + 1);
memcpy(stdin_data, data, len + 1);
if (data != buffer) free(data);
stdin_file.contents = stdin_data;
CompilationUnit *unit = unit_create(&stdin_file);
ParseContext parse_context = { .unit = unit };
parse_context.lexer = (Lexer) { .file = &stdin_file, .context = &parse_context };
lexer_init(&parse_context.lexer);
if (global_context.errors_found) return false;
parse_translation_unit(&parse_context);
return !global_context.errors_found;
}

View File

@@ -242,6 +242,11 @@ void sema_analysis_run(void)
if (loaded) continue;
if (!parse_file(file)) has_error = true;
}
if (active_target.read_stdin)
{
if (!parse_stdin()) has_error = true;
}
if (has_error) exit_compiler(EXIT_FAILURE);
compiler_parsing_time = bench_mark();

View File

@@ -17,6 +17,7 @@ static const size_t LEXER_FILES_START_CAPACITY = 128;
File *source_file_by_id(FileId file)
{
if (file == stdin_file_id) return &stdin_file;
assert(file < vec_size(global_context.loaded_sources));
return global_context.loaded_sources[file];
}

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.3.87"
#define COMPILER_VERSION "0.3.88"