mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Take code from stdin. Version bump.
This commit is contained in:
committed by
Christoffer Lerno
parent
f8f249ee2c
commit
7d58ce0dcb
@@ -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("?"))
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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__)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.3.87"
|
||||
#define COMPILER_VERSION "0.3.88"
|
||||
Reference in New Issue
Block a user