Added --lsp output.

This commit is contained in:
Christoffer Lerno
2025-01-10 00:06:42 +01:00
parent 3a1bba19af
commit f1325f6539
8 changed files with 98 additions and 5 deletions

View File

@@ -79,7 +79,7 @@ macro concat(arr1, arr2, Allocator allocator) @nodiscard
@require @typekind(arr1) == SLICE || @typekind(arr1) == ARRAY
@require @typekind(arr2) == SLICE || @typekind(arr2) == ARRAY
@require @typeis(arr1[0], $typeof(arr2[0])) "Arrays must have the same type"
@ensure result.len == arr1.len + arr2.len
@ensure return.len == arr1.len + arr2.len
*>
macro concat_new(arr1, arr2, Allocator allocator = allocator::heap()) @nodiscard
{
@@ -95,7 +95,7 @@ macro concat_new(arr1, arr2, Allocator allocator = allocator::heap()) @nodiscard
@require @typekind(arr1) == SLICE || @typekind(arr1) == ARRAY
@require @typekind(arr2) == SLICE || @typekind(arr2) == ARRAY
@require @typeis(arr1[0], $typeof(arr2[0])) "Arrays must have the same type"
@ensure result.len == arr1.len + arr2.len
@ensure return.len == arr1.len + arr2.len
*>
macro tconcat(arr1, arr2) @nodiscard => concat(arr1, arr2, allocator::temp());

View File

@@ -25,6 +25,7 @@
- Deprecate `fn void! main() type main functions.
- Deprecate old `void!` @benchmark and @test functions.
- Allow test runners to take String[] arguments.
- Added `--lsp` output.
### Fixes
- Fix case trying to initialize a `char[*]*` from a String.

View File

@@ -491,6 +491,7 @@ typedef struct BuildOptions_
bool emit_asm;
bool benchmark_mode;
bool test_mode;
bool lsp_mode;
bool no_entry;
bool no_obj;
bool no_headers;
@@ -600,6 +601,7 @@ typedef struct
bool generate_test_runner;
bool benchmark_output;
bool test_output;
bool lsp_output;
bool output_headers;
bool output_ast;
bool lex_only;

View File

@@ -125,7 +125,9 @@ static void usage(bool full)
PRINTF(" --optsize=<option> - Code size optimization: none, small, tiny.");
PRINTF(" --single-module=<yes|no> - Compile all modules together, enables more inlining.");
PRINTF(" --show-backtrace=<yes|no> - Show detailed backtrace on segfaults.");
PRINTF(" --lsp - Emit data about errors suitable for a LSP.");
PRINTF(" --old-test-bench=<yes|no> - Allow benchmarks and tests to use the deprecated 'void!' returns.");
}
PRINTF("");
PRINTF(" -g - Emit debug info.");
@@ -1082,8 +1084,16 @@ static void parse_option(BuildOptions *options)
options->benchmark_mode = true;
return;
}
if (match_longopt("lsp"))
{
options->lsp_mode = true;
options->strip_unused = STRIP_UNUSED_OFF;
options->test_mode = false;
return;
}
if (match_longopt("test"))
{
options->lsp_mode = false;
options->test_mode = true;
options->strip_unused = STRIP_UNUSED_OFF;
return;

View File

@@ -491,6 +491,13 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
target->emit_asm = false;
target->emit_object_files = false;
}
if (options->lsp_mode)
{
target->lsp_output = true;
target->emit_llvm = false;
target->emit_asm = false;
target->emit_object_files = false;
}
if (options->test_mode)
{
target->test_output = true;

View File

@@ -402,7 +402,16 @@ static void create_output_dir(const char *dir)
void compiler_compile(void)
{
if (compiler.build.lsp_output)
{
eprintf("> BEGINLSP\n");
}
sema_analysis_run();
if (compiler.build.lsp_output)
{
eprintf("< ENDLSP-OK\n");
exit_compiler(0);
}
compiler_sema_time = bench_mark();
Module **modules = compiler.context.module_list;
unsigned module_count = vec_size(modules);
@@ -437,7 +446,7 @@ void compiler_compile(void)
error_exit("Failed to create build directory '%s'.", compiler.build.build_dir);
}
}
if (compiler.build.ir_file_dir && (compiler.build.emit_llvm || compiler.build.test_output))
if (compiler.build.ir_file_dir && (compiler.build.emit_llvm || compiler.build.test_output || compiler.build.lsp_output))
{
if (!file_exists(compiler.build.ir_file_dir) && !dir_make(compiler.build.ir_file_dir))
{

View File

@@ -11,6 +11,38 @@
#define LINES_SHOWN 4
#define MAX_WIDTH 120
static void eprint_escaped_string(const char *message)
{
fputc('"', stderr);
char c;
while ((c = *(message++)) != 0)
{
switch (c)
{
case '\t':
fputs("\\t", stderr);
break;
case '\r':
break;
case '|':
fputs("\\x7c", stderr);
break;
case '\"':
fputs("\\\"", stderr);
break;
case '\\':
fputs("\\\\", stderr);
break;
case '\n':
fputs("\\n", stderr);
break;
default:
fputc(c, stderr);
}
}
fputc('"', stderr);
}
static void print_error_type_at(SourceSpan location, const char *message, PrintType print_type)
{
if (!location.a)
@@ -19,7 +51,31 @@ static void print_error_type_at(SourceSpan location, const char *message, PrintT
return;
}
File *file = source_file_by_id(location.file_id);
if (compiler.build.test_output || compiler.build.benchmark_output)
if (compiler.build.lsp_output)
{
eprintf("> LSPERR|");
switch (print_type)
{
case PRINT_TYPE_ERROR:
eprintf("error");
break;
case PRINT_TYPE_NOTE:
eprintf("note");
break;
case PRINT_TYPE_WARN:
eprintf("warn");
break;
default:
UNREACHABLE
}
eprintf("|");
eprint_escaped_string(file->full_path);
eprintf("|%d|%d|", location.row, location.col);
eprint_escaped_string(message);
eprintf("\n");
return;
}
else if (compiler.build.test_output || compiler.build.benchmark_output)
{
switch (print_type)
{

View File

@@ -133,7 +133,15 @@ void context_pop_defers_and_replace_ast(SemaContext *context, Ast *ast)
static inline void halt_on_error(void)
{
if (compiler.context.errors_found > 0) exit_compiler(EXIT_FAILURE);
if (compiler.context.errors_found > 0)
{
if (compiler.build.lsp_output)
{
eprintf("> ENDLSP-ERROR\n");
exit_compiler(COMPILER_SUCCESS_EXIT);
}
exit_compiler(EXIT_FAILURE);
}
}
void sema_analyze_stage(Module *module, AnalysisStage stage)