mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Fix JSON and compile issue.
This commit is contained in:
@@ -48,138 +48,138 @@ const char *trust_level[3] = {
|
||||
};
|
||||
|
||||
#define EOUTPUT(string, ...) fprintf(stderr, string "\n", ##__VA_ARGS__)
|
||||
#define OUTPUT(string, ...) fprintf(stdout, string "\n", ##__VA_ARGS__)
|
||||
#define PRINTF(string, ...) fprintf(stdout, string "\n", ##__VA_ARGS__) // NOLINT
|
||||
#define FAIL_WITH_ERR(string, ...) do { fprintf(stderr, "Error: " string "\n\n", ##__VA_ARGS__); usage(); exit_compiler(EXIT_FAILURE); } while (0)
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
OUTPUT("Usage: %s [<options>] <command> [<args>]", args[0]);
|
||||
OUTPUT("");
|
||||
OUTPUT("Commands:");
|
||||
OUTPUT("");
|
||||
OUTPUT(" compile <file1> [<file2> ...] Compile files without a project into an executable.");
|
||||
OUTPUT(" init <project name> Initialize a new project structure.");
|
||||
OUTPUT(" init-lib <library name> Initialize a new library structure.");
|
||||
OUTPUT(" build [<target>] Build the target in the current project.");
|
||||
OUTPUT(" benchmark Run the benchmarks in the current project.");
|
||||
OUTPUT(" test Run the unit tests in the current project.");
|
||||
OUTPUT(" clean Clean all build files.");
|
||||
OUTPUT(" run [<target>] Run (and build if needed) the target in the current project.");
|
||||
OUTPUT(" dist [<target>] Clean and build a target for distribution.");
|
||||
OUTPUT(" directives [<target>] Generate documentation for the target.");
|
||||
OUTPUT(" bench [<target>] Benchmark a target.");
|
||||
OUTPUT(" clean-run [<target>] Clean, then run the target.");
|
||||
OUTPUT(" compile-run <file1> [<file2> ...] Compile files then immediately run the result.");
|
||||
OUTPUT(" compile-only <file1> [<file2> ...] Compile files but do not perform linking.");
|
||||
OUTPUT(" compile-benchmark <file1> [<file2> ...] Compile files into an executable and run benchmarks.");
|
||||
OUTPUT(" compile-test <file1> [<file2> ...] Compile files into an executable and run unit tests.");
|
||||
OUTPUT(" static-lib <file1> [<file2> ...] Compile files without a project into a static library.");
|
||||
OUTPUT(" dynamic-lib <file1> [<file2> ...] Compile files without a project into a dynamic library.");
|
||||
OUTPUT(" headers <file1> [<file2> ...] Analyse files and generate C headers for public methods.");
|
||||
OUTPUT(" vendor-fetch <library> ... Fetches one or more libraries from the vendor collection.");
|
||||
OUTPUT("");
|
||||
OUTPUT("Options:");
|
||||
OUTPUT(" --tb - Use Tilde Backend for compilation.");
|
||||
OUTPUT(" --stdlib <dir> - Use this directory as the C3 standard library path.");
|
||||
OUTPUT(" --no-entry - Do not generate (or require) a main function.");
|
||||
OUTPUT(" --libdir <dir> - Add this directory to the C3 library search paths.");
|
||||
OUTPUT(" --lib <name> - Add this library to the compilation.");
|
||||
OUTPUT(" --path <dir> - Use this as the base directory for the current command.");
|
||||
OUTPUT(" --template <template> - Select template for 'init': \"exe\", \"static-lib\", \"dynamic-lib\" or a path.");
|
||||
OUTPUT(" --about - Prints a short description of C3.");
|
||||
OUTPUT(" --symtab <value> - Sets the preferred symtab size.");
|
||||
OUTPUT(" -V --version - Print version information.");
|
||||
OUTPUT(" -E - Lex only.");
|
||||
OUTPUT(" -P - Only parse and output the AST as JSON.");
|
||||
OUTPUT(" -C - Only lex, parse and check.");
|
||||
OUTPUT(" - - Read code from standard in.");
|
||||
OUTPUT(" -o <file> - Write output to <file>.");
|
||||
OUTPUT(" -O0 - Safe, no optimizations, emit debug info.");
|
||||
OUTPUT(" -O1 - Safe, high optimization, emit debug info.");
|
||||
OUTPUT(" -O2 - Unsafe, high optimization, emit debug info.");
|
||||
OUTPUT(" -O3 - Unsafe, high optimization, single module, emit debug info.");
|
||||
OUTPUT(" -O4 - Unsafe, highest optimization, relaxed maths, single module, emit debug info, no panic messages.");
|
||||
OUTPUT(" -O5 - Unsafe, highest optimization, fast maths, single module, emit debug info, no panic messages.");
|
||||
OUTPUT(" -Os - Unsafe, high optimization, small code, single module, no debug info, no panic messages.");
|
||||
OUTPUT(" -Oz - Unsafe, high optimization, tiny code, single module, no debug info, no panic messages.");
|
||||
OUTPUT(" -D <name> - Add feature flag <name>.");
|
||||
OUTPUT(" -U <name> - Remove feature flag <name>.");
|
||||
OUTPUT(" --trust=<option> - Trust level: none (default), include ($include allowed), full ($exec / exec allowed).");
|
||||
OUTPUT(" --output-dir <dir> - Override general output directory.");
|
||||
OUTPUT(" --build-dir <dir> - Override build output directory.");
|
||||
OUTPUT(" --obj-out <dir> - Override object file output directory.");
|
||||
OUTPUT(" --script-dir <dir> - Override the base directory for $exec.");
|
||||
OUTPUT(" --llvm-out <dir> - Override llvm output directory for '--emit-llvm'.");
|
||||
OUTPUT(" --emit-llvm - Emit LLVM IR as a .ll file per module.");
|
||||
OUTPUT(" --asm-out <dir> - Override asm output directory for '--emit-asm'.");
|
||||
OUTPUT(" --emit-asm - Emit asm as a .s file per module.");
|
||||
OUTPUT(" --obj - Emit object files. (Enabled by default)");
|
||||
OUTPUT(" --no-obj - Do not output object files, this is only valid for `compile-only`.");
|
||||
OUTPUT(" --target <target> - Compile for a particular architecture + OS target.");
|
||||
OUTPUT(" --threads <number> - Set the number of threads to use for compilation.");
|
||||
OUTPUT(" --safe=<yes|no> - Turn safety (contracts, runtime bounds checking, null pointer checks etc) on or off.");
|
||||
OUTPUT(" --panic-msg=<yes|no> - Turn panic message output on or off.");
|
||||
OUTPUT(" --optlevel=<option> - Code optimization level: none, less, more, max.");
|
||||
OUTPUT(" --optsize=<option> - Code size optimization: none, small, tiny.");
|
||||
OUTPUT(" --single-module=<yes|no> - Compile all modules together, enables more inlining.");
|
||||
OUTPUT("");
|
||||
OUTPUT(" -g - Emit debug info.");
|
||||
OUTPUT(" -g0 - Emit no debug info.");
|
||||
OUTPUT("");
|
||||
OUTPUT("");
|
||||
OUTPUT(" -l <library> - Link with the library provided.");
|
||||
OUTPUT(" -L <library dir> - Append the directory to the linker search paths.");
|
||||
OUTPUT(" -z <argument> - Send the <argument> as a parameter to the linker.");
|
||||
OUTPUT(" --cc <path> - Set C compiler (for C files in projects and use as system linker).");
|
||||
OUTPUT(" --linker=<option> [<path>] - Linker: builtin, cc, custom (default is 'cc'), 'custom' requires a path.");
|
||||
OUTPUT("");
|
||||
OUTPUT(" --use-stdlib=<yes|no> - Include the standard library (default: yes).");
|
||||
OUTPUT(" --link-libc=<yes|no> - Link libc other default libraries (default: yes).");
|
||||
OUTPUT(" --emit-stdlib=<yes|no> - Output files for the standard library. (default: yes)");
|
||||
OUTPUT(" --panicfn <name> - Override the panic function name.");
|
||||
OUTPUT(" --testfn <name> - Override the test runner function name.");
|
||||
OUTPUT(" --benchfn <name> - Override the benchmark runner function name.");
|
||||
OUTPUT("");
|
||||
OUTPUT(" --reloc=<option> - Relocation model: none, pic, PIC, pie, PIE.");
|
||||
OUTPUT(" --x86cpu=<option> - Set general level of x64 cpu: baseline, ssse3, sse4, avx1, avx2-v1, avx2-v2 (Skylake/Zen1+), avx512 (Icelake/Zen4+), native.");
|
||||
OUTPUT(" --x86vec=<option> - Set max type of vector use: none, mmx, sse, avx, avx512, default.");
|
||||
OUTPUT(" --riscvfloat=<option> - Set type of RISC-V float support: none, float, double");
|
||||
OUTPUT(" --memory-env=<option> - Set the memory environment: normal, small, tiny, none.");
|
||||
OUTPUT(" --strip-unused=<yes|no> - Strip unused code and globals from the output. (default: yes)");
|
||||
OUTPUT(" --fp-math=<option> - FP math behaviour: strict, relaxed, fast.");
|
||||
OUTPUT(" --win64-simd=<option> - Win64 SIMD ABI: array, full.");
|
||||
OUTPUT("");
|
||||
OUTPUT(" --debug-stats - Print debug statistics.");
|
||||
OUTPUT(" --print-linking - Print linker arguments.");
|
||||
PRINTF("Usage: %s [<options>] <command> [<args>]", args[0]);
|
||||
PRINTF("");
|
||||
PRINTF("Commands:");
|
||||
PRINTF("");
|
||||
PRINTF(" compile <file1> [<file2> ...] Compile files without a project into an executable.");
|
||||
PRINTF(" init <project name> Initialize a new project structure.");
|
||||
PRINTF(" init-lib <library name> Initialize a new library structure.");
|
||||
PRINTF(" build [<target>] Build the target in the current project.");
|
||||
PRINTF(" benchmark Run the benchmarks in the current project.");
|
||||
PRINTF(" test Run the unit tests in the current project.");
|
||||
PRINTF(" clean Clean all build files.");
|
||||
PRINTF(" run [<target>] Run (and build if needed) the target in the current project.");
|
||||
PRINTF(" dist [<target>] Clean and build a target for distribution.");
|
||||
PRINTF(" directives [<target>] Generate documentation for the target.");
|
||||
PRINTF(" bench [<target>] Benchmark a target.");
|
||||
PRINTF(" clean-run [<target>] Clean, then run the target.");
|
||||
PRINTF(" compile-run <file1> [<file2> ...] Compile files then immediately run the result.");
|
||||
PRINTF(" compile-only <file1> [<file2> ...] Compile files but do not perform linking.");
|
||||
PRINTF(" compile-benchmark <file1> [<file2> ...] Compile files into an executable and run benchmarks.");
|
||||
PRINTF(" compile-test <file1> [<file2> ...] Compile files into an executable and run unit tests.");
|
||||
PRINTF(" static-lib <file1> [<file2> ...] Compile files without a project into a static library.");
|
||||
PRINTF(" dynamic-lib <file1> [<file2> ...] Compile files without a project into a dynamic library.");
|
||||
PRINTF(" headers <file1> [<file2> ...] Analyse files and generate C headers for public methods.");
|
||||
PRINTF(" vendor-fetch <library> ... Fetches one or more libraries from the vendor collection.");
|
||||
PRINTF("");
|
||||
PRINTF("Options:");
|
||||
PRINTF(" --tb - Use Tilde Backend for compilation.");
|
||||
PRINTF(" --stdlib <dir> - Use this directory as the C3 standard library path.");
|
||||
PRINTF(" --no-entry - Do not generate (or require) a main function.");
|
||||
PRINTF(" --libdir <dir> - Add this directory to the C3 library search paths.");
|
||||
PRINTF(" --lib <name> - Add this library to the compilation.");
|
||||
PRINTF(" --path <dir> - Use this as the base directory for the current command.");
|
||||
PRINTF(" --template <template> - Select template for 'init': \"exe\", \"static-lib\", \"dynamic-lib\" or a path.");
|
||||
PRINTF(" --about - Prints a short description of C3.");
|
||||
PRINTF(" --symtab <value> - Sets the preferred symtab size.");
|
||||
PRINTF(" -V --version - Print version information.");
|
||||
PRINTF(" -E - Lex only.");
|
||||
PRINTF(" -P - Only parse and output the AST as JSON.");
|
||||
PRINTF(" -C - Only lex, parse and check.");
|
||||
PRINTF(" - - Read code from standard in.");
|
||||
PRINTF(" -o <file> - Write output to <file>.");
|
||||
PRINTF(" -O0 - Safe, no optimizations, emit debug info.");
|
||||
PRINTF(" -O1 - Safe, high optimization, emit debug info.");
|
||||
PRINTF(" -O2 - Unsafe, high optimization, emit debug info.");
|
||||
PRINTF(" -O3 - Unsafe, high optimization, single module, emit debug info.");
|
||||
PRINTF(" -O4 - Unsafe, highest optimization, relaxed maths, single module, emit debug info, no panic messages.");
|
||||
PRINTF(" -O5 - Unsafe, highest optimization, fast maths, single module, emit debug info, no panic messages.");
|
||||
PRINTF(" -Os - Unsafe, high optimization, small code, single module, no debug info, no panic messages.");
|
||||
PRINTF(" -Oz - Unsafe, high optimization, tiny code, single module, no debug info, no panic messages.");
|
||||
PRINTF(" -D <name> - Add feature flag <name>.");
|
||||
PRINTF(" -U <name> - Remove feature flag <name>.");
|
||||
PRINTF(" --trust=<option> - Trust level: none (default), include ($include allowed), full ($exec / exec allowed).");
|
||||
PRINTF(" --output-dir <dir> - Override general output directory.");
|
||||
PRINTF(" --build-dir <dir> - Override build output directory.");
|
||||
PRINTF(" --obj-out <dir> - Override object file output directory.");
|
||||
PRINTF(" --script-dir <dir> - Override the base directory for $exec.");
|
||||
PRINTF(" --llvm-out <dir> - Override llvm output directory for '--emit-llvm'.");
|
||||
PRINTF(" --emit-llvm - Emit LLVM IR as a .ll file per module.");
|
||||
PRINTF(" --asm-out <dir> - Override asm output directory for '--emit-asm'.");
|
||||
PRINTF(" --emit-asm - Emit asm as a .s file per module.");
|
||||
PRINTF(" --obj - Emit object files. (Enabled by default)");
|
||||
PRINTF(" --no-obj - Do not output object files, this is only valid for `compile-only`.");
|
||||
PRINTF(" --target <target> - Compile for a particular architecture + OS target.");
|
||||
PRINTF(" --threads <number> - Set the number of threads to use for compilation.");
|
||||
PRINTF(" --safe=<yes|no> - Turn safety (contracts, runtime bounds checking, null pointer checks etc) on or off.");
|
||||
PRINTF(" --panic-msg=<yes|no> - Turn panic message output on or off.");
|
||||
PRINTF(" --optlevel=<option> - Code optimization level: none, less, more, max.");
|
||||
PRINTF(" --optsize=<option> - Code size optimization: none, small, tiny.");
|
||||
PRINTF(" --single-module=<yes|no> - Compile all modules together, enables more inlining.");
|
||||
PRINTF("");
|
||||
PRINTF(" -g - Emit debug info.");
|
||||
PRINTF(" -g0 - Emit no debug info.");
|
||||
PRINTF("");
|
||||
PRINTF("");
|
||||
PRINTF(" -l <library> - Link with the library provided.");
|
||||
PRINTF(" -L <library dir> - Append the directory to the linker search paths.");
|
||||
PRINTF(" -z <argument> - Send the <argument> as a parameter to the linker.");
|
||||
PRINTF(" --cc <path> - Set C compiler (for C files in projects and use as system linker).");
|
||||
PRINTF(" --linker=<option> [<path>] - Linker: builtin, cc, custom (default is 'cc'), 'custom' requires a path.");
|
||||
PRINTF("");
|
||||
PRINTF(" --use-stdlib=<yes|no> - Include the standard library (default: yes).");
|
||||
PRINTF(" --link-libc=<yes|no> - Link libc other default libraries (default: yes).");
|
||||
PRINTF(" --emit-stdlib=<yes|no> - Output files for the standard library. (default: yes)");
|
||||
PRINTF(" --panicfn <name> - Override the panic function name.");
|
||||
PRINTF(" --testfn <name> - Override the test runner function name.");
|
||||
PRINTF(" --benchfn <name> - Override the benchmark runner function name.");
|
||||
PRINTF("");
|
||||
PRINTF(" --reloc=<option> - Relocation model: none, pic, PIC, pie, PIE.");
|
||||
PRINTF(" --x86cpu=<option> - Set general level of x64 cpu: baseline, ssse3, sse4, avx1, avx2-v1, avx2-v2 (Skylake/Zen1+), avx512 (Icelake/Zen4+), native.");
|
||||
PRINTF(" --x86vec=<option> - Set max type of vector use: none, mmx, sse, avx, avx512, default.");
|
||||
PRINTF(" --riscvfloat=<option> - Set type of RISC-V float support: none, float, double");
|
||||
PRINTF(" --memory-env=<option> - Set the memory environment: normal, small, tiny, none.");
|
||||
PRINTF(" --strip-unused=<yes|no> - Strip unused code and globals from the output. (default: yes)");
|
||||
PRINTF(" --fp-math=<option> - FP math behaviour: strict, relaxed, fast.");
|
||||
PRINTF(" --win64-simd=<option> - Win64 SIMD ABI: array, full.");
|
||||
PRINTF("");
|
||||
PRINTF(" --debug-stats - Print debug statistics.");
|
||||
PRINTF(" --print-linking - Print linker arguments.");
|
||||
#ifndef NDEBUG
|
||||
OUTPUT(" --debug-log - Print debug logging to stdout.");
|
||||
PRINTF(" --debug-log - Print debug logging to stdout.");
|
||||
#endif
|
||||
OUTPUT("");
|
||||
OUTPUT(" --benchmarking - Run built-in benchmarks.");
|
||||
OUTPUT(" --testing - Run built-in tests.");
|
||||
OUTPUT("");
|
||||
OUTPUT(" --list-attributes - List all attributes.");
|
||||
OUTPUT(" --list-builtins - List all builtins.");
|
||||
OUTPUT(" --list-keywords - List all keywords.");
|
||||
OUTPUT(" --list-operators - List all operators.");
|
||||
OUTPUT(" --list-precedence - List operator precedence order.");
|
||||
OUTPUT(" --list-project-properties - List all available keys used in project.json files.");
|
||||
OUTPUT(" --list-targets - List all architectures the compiler supports.");
|
||||
OUTPUT(" --list-type-properties - List all type properties.");
|
||||
OUTPUT("");
|
||||
OUTPUT(" --print-output - Print the object files created to stdout.");
|
||||
OUTPUT(" --print-input - Print inputted C3 files to stdout.");
|
||||
OUTPUT("");
|
||||
OUTPUT(" --winsdk <dir> - Set the directory for Windows system library files for cross compilation.");
|
||||
OUTPUT(" --wincrt=<option> - Windows CRT linking: none, static, dynamic (default).");
|
||||
OUTPUT(" --windef <file> - Use Windows 'def' file for function exports instead of 'dllexport'.");
|
||||
OUTPUT("");
|
||||
OUTPUT(" --macossdk <dir> - Set the directory for the MacOS SDK for cross compilation.");
|
||||
OUTPUT(" --macos-min-version <ver> - Set the minimum MacOS version to compile for.");
|
||||
OUTPUT(" --macos-sdk-version <ver> - Set the MacOS SDK compiled for.");
|
||||
OUTPUT("");
|
||||
OUTPUT(" --linux-crt <dir> - Set the directory to use for finding crt1.o and related files.");
|
||||
OUTPUT(" --linux-crtbegin <dir> - Set the directory to use for finding crtbegin.o and related files.");
|
||||
PRINTF("");
|
||||
PRINTF(" --benchmarking - Run built-in benchmarks.");
|
||||
PRINTF(" --testing - Run built-in tests.");
|
||||
PRINTF("");
|
||||
PRINTF(" --list-attributes - List all attributes.");
|
||||
PRINTF(" --list-builtins - List all builtins.");
|
||||
PRINTF(" --list-keywords - List all keywords.");
|
||||
PRINTF(" --list-operators - List all operators.");
|
||||
PRINTF(" --list-precedence - List operator precedence order.");
|
||||
PRINTF(" --list-project-properties - List all available keys used in project.json files.");
|
||||
PRINTF(" --list-targets - List all architectures the compiler supports.");
|
||||
PRINTF(" --list-type-properties - List all type properties.");
|
||||
PRINTF("");
|
||||
PRINTF(" --print-output - Print the object files created to stdout.");
|
||||
PRINTF(" --print-input - Print inputted C3 files to stdout.");
|
||||
PRINTF("");
|
||||
PRINTF(" --winsdk <dir> - Set the directory for Windows system library files for cross compilation.");
|
||||
PRINTF(" --wincrt=<option> - Windows CRT linking: none, static, dynamic (default).");
|
||||
PRINTF(" --windef <file> - Use Windows 'def' file for function exports instead of 'dllexport'.");
|
||||
PRINTF("");
|
||||
PRINTF(" --macossdk <dir> - Set the directory for the MacOS SDK for cross compilation.");
|
||||
PRINTF(" --macos-min-version <ver> - Set the minimum MacOS version to compile for.");
|
||||
PRINTF(" --macos-sdk-version <ver> - Set the MacOS SDK compiled for.");
|
||||
PRINTF("");
|
||||
PRINTF(" --linux-crt <dir> - Set the directory to use for finding crt1.o and related files.");
|
||||
PRINTF(" --linux-crtbegin <dir> - Set the directory to use for finding crtbegin.o and related files.");
|
||||
}
|
||||
|
||||
|
||||
@@ -391,19 +391,19 @@ static void parse_command(BuildOptions *options)
|
||||
}
|
||||
static void print_all_targets(void)
|
||||
{
|
||||
OUTPUT("Available targets:");
|
||||
PRINTF("Available targets:");
|
||||
for (unsigned i = 1; i <= ARCH_OS_TARGET_LAST; i++)
|
||||
{
|
||||
OUTPUT(" %s", arch_os_target[i]);
|
||||
PRINTF(" %s", arch_os_target[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_version(void)
|
||||
{
|
||||
OUTPUT("C3 Compiler Version: %s%s", COMPILER_VERSION, PRERELEASE ? " (prerelease)" : "");
|
||||
OUTPUT("Installed directory: %s", find_executable_path());
|
||||
OUTPUT("LLVM version: %s", llvm_version);
|
||||
OUTPUT("LLVM default target: %s", llvm_target);
|
||||
PRINTF("C3 Compiler Version: %s%s", COMPILER_VERSION, PRERELEASE ? " (prerelease)" : "");
|
||||
PRINTF("Installed directory: %s", find_executable_path());
|
||||
PRINTF("LLVM version: %s", llvm_version);
|
||||
PRINTF("LLVM default target: %s", llvm_target);
|
||||
}
|
||||
|
||||
static void add_linker_arg(BuildOptions *options, const char *arg)
|
||||
@@ -649,7 +649,7 @@ static void parse_option(BuildOptions *options)
|
||||
if (at_end() || next_is_opt()) error_exit("error: --symtab needs a valid integer.");
|
||||
const char *symtab_string = next_arg();
|
||||
int symtab = atoi(symtab_string);
|
||||
if (symtab < 1024) OUTPUT("Expected a valid positive integer >= 1024.");
|
||||
if (symtab < 1024) PRINTF("Expected a valid positive integer >= 1024.");
|
||||
options->symtab_size = next_highest_power_of_2(symtab);
|
||||
return;
|
||||
}
|
||||
@@ -751,8 +751,8 @@ static void parse_option(BuildOptions *options)
|
||||
}
|
||||
if (match_longopt("about"))
|
||||
{
|
||||
OUTPUT("The C3 Compiler");
|
||||
OUTPUT("C3 is low level programming language based on C.");
|
||||
PRINTF("The C3 Compiler");
|
||||
PRINTF("C3 is low level programming language based on C.");
|
||||
exit_compiler(COMPILER_SUCCESS_EXIT);
|
||||
}
|
||||
if (match_longopt("no-obj"))
|
||||
@@ -828,8 +828,8 @@ static void parse_option(BuildOptions *options)
|
||||
if (at_end() || next_is_opt()) error_exit("error: --threads needs a valid integer 1 or higher.");
|
||||
const char *thread_string = next_arg();
|
||||
int threads = atoi(thread_string);
|
||||
if (threads < 1) OUTPUT("Expected a valid integer 1 or higher.");
|
||||
if (threads > MAX_THREADS) OUTPUT("Cannot exceed %d threads.", MAX_THREADS);
|
||||
if (threads < 1) PRINTF("Expected a valid integer 1 or higher.");
|
||||
if (threads > MAX_THREADS) PRINTF("Cannot exceed %d threads.", MAX_THREADS);
|
||||
options->build_threads = threads;
|
||||
return;
|
||||
}
|
||||
@@ -843,7 +843,7 @@ static void parse_option(BuildOptions *options)
|
||||
options->arch_os_target_override = target_arch_os;
|
||||
return;
|
||||
}
|
||||
OUTPUT("Available targets:");
|
||||
PRINTF("Available targets:");
|
||||
EOUTPUT("Invalid target %s.", target);
|
||||
EOUTPUT("These targets are supported:");
|
||||
for (unsigned i = 1; i <= ARCH_OS_TARGET_LAST; i++)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "compiler_internal.h"
|
||||
|
||||
#define OUTPUT(x, ...) fprintf(file, x, ## __VA_ARGS__)
|
||||
#define PRINTF(x, ...) fprintf(file, x, ## __VA_ARGS__)
|
||||
#define INDENT() indent_line(file, indent)
|
||||
#define OUT(file, x, ...) fprintf(file, x, ## __VA_ARGS__)
|
||||
|
||||
@@ -37,7 +37,7 @@ static void header_print_type(FILE *file, Type *type)
|
||||
{
|
||||
if (type_is_func_pointer(type))
|
||||
{
|
||||
OUTPUT("%s", decl_get_extname(type->decl));
|
||||
PRINTF("%s", decl_get_extname(type->decl));
|
||||
return;
|
||||
}
|
||||
assert(!type_is_optional(type));
|
||||
@@ -48,116 +48,116 @@ static void header_print_type(FILE *file, Type *type)
|
||||
case TYPE_OPTIONAL:
|
||||
UNREACHABLE
|
||||
case TYPE_VOID:
|
||||
OUTPUT("void");
|
||||
PRINTF("void");
|
||||
return;
|
||||
case TYPE_BOOL:
|
||||
OUTPUT("bool");
|
||||
PRINTF("bool");
|
||||
return;
|
||||
case TYPE_I8:
|
||||
OUTPUT("int8_t");
|
||||
PRINTF("int8_t");
|
||||
return;
|
||||
case TYPE_I16:
|
||||
OUTPUT("int16_t");
|
||||
PRINTF("int16_t");
|
||||
return;
|
||||
case TYPE_I32:
|
||||
OUTPUT("int32_t");
|
||||
PRINTF("int32_t");
|
||||
return;
|
||||
case TYPE_I64:
|
||||
OUTPUT("int64_t");
|
||||
PRINTF("int64_t");
|
||||
return;
|
||||
case TYPE_I128:
|
||||
OUTPUT("__int128");
|
||||
PRINTF("__int128");
|
||||
return;
|
||||
case TYPE_U8:
|
||||
OUTPUT("uint8_t");
|
||||
PRINTF("uint8_t");
|
||||
return;
|
||||
case TYPE_U16:
|
||||
OUTPUT("uint16_t");
|
||||
PRINTF("uint16_t");
|
||||
return;
|
||||
case TYPE_U32:
|
||||
OUTPUT("uint32_t");
|
||||
PRINTF("uint32_t");
|
||||
return;
|
||||
case TYPE_U64:
|
||||
OUTPUT("uint64_t");
|
||||
PRINTF("uint64_t");
|
||||
return;
|
||||
case TYPE_U128:
|
||||
OUTPUT("unsigned __int128");
|
||||
PRINTF("unsigned __int128");
|
||||
return;
|
||||
case TYPE_BF16:
|
||||
OUTPUT("__bf16");
|
||||
PRINTF("__bf16");
|
||||
return;
|
||||
case TYPE_F16:
|
||||
OUTPUT("__fp16");
|
||||
PRINTF("__fp16");
|
||||
return;
|
||||
case TYPE_F32:
|
||||
OUTPUT("float");
|
||||
PRINTF("float");
|
||||
return;
|
||||
case TYPE_F64:
|
||||
OUTPUT("double");
|
||||
PRINTF("double");
|
||||
return;
|
||||
case TYPE_F128:
|
||||
OUTPUT("__float128");
|
||||
PRINTF("__float128");
|
||||
return;
|
||||
case TYPE_TYPEID:
|
||||
OUTPUT("c3typeid_t");
|
||||
PRINTF("c3typeid_t");
|
||||
return;
|
||||
case TYPE_POINTER:
|
||||
header_print_type(file, type->pointer);
|
||||
OUTPUT("*");
|
||||
PRINTF("*");
|
||||
return;
|
||||
case TYPE_FUNC_PTR:
|
||||
type = type->pointer;
|
||||
FALLTHROUGH;
|
||||
case TYPE_FUNC_RAW:
|
||||
OUTPUT("%s", decl_get_extname(type->function.decl));
|
||||
PRINTF("%s", decl_get_extname(type->function.decl));
|
||||
return;
|
||||
case TYPE_STRUCT:
|
||||
case TYPE_UNION:
|
||||
case TYPE_ENUM:
|
||||
OUTPUT("%s", decl_get_extname(type->decl));
|
||||
PRINTF("%s", decl_get_extname(type->decl));
|
||||
return;
|
||||
case TYPE_BITSTRUCT:
|
||||
header_print_type(file, type->decl->bitstruct.base_type->type);
|
||||
return;
|
||||
case TYPE_ANYFAULT:
|
||||
case TYPE_FAULTTYPE:
|
||||
OUTPUT("c3fault_t");
|
||||
PRINTF("c3fault_t");
|
||||
return;
|
||||
case TYPE_DISTINCT:
|
||||
case TYPE_TYPEDEF:
|
||||
UNREACHABLE
|
||||
case TYPE_FLEXIBLE_ARRAY:
|
||||
header_print_type(file, type->array.base);
|
||||
OUTPUT("[]");
|
||||
PRINTF("[]");
|
||||
return;
|
||||
case TYPE_ARRAY:
|
||||
OUTPUT("struct { ");
|
||||
PRINTF("struct { ");
|
||||
header_print_type(file, type->array.base);
|
||||
OUTPUT(" arr[%d]; }", type->array.len);
|
||||
PRINTF(" arr[%d]; }", type->array.len);
|
||||
return;
|
||||
case TYPE_ANY:
|
||||
case TYPE_INTERFACE:
|
||||
OUTPUT("c3any_t");
|
||||
PRINTF("c3any_t");
|
||||
return;
|
||||
case TYPE_SLICE:
|
||||
OUTPUT("c3slice_t");
|
||||
PRINTF("c3slice_t");
|
||||
return;
|
||||
case TYPE_VECTOR:
|
||||
switch (type->array.base->type_kind)
|
||||
{
|
||||
case ALL_SIGNED_INTS:
|
||||
OUTPUT("int");
|
||||
PRINTF("int");
|
||||
break;
|
||||
case ALL_UNSIGNED_INTS:
|
||||
OUTPUT("uint");
|
||||
PRINTF("uint");
|
||||
break;
|
||||
case ALL_FLOATS:
|
||||
OUTPUT("float");
|
||||
PRINTF("float");
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE;
|
||||
}
|
||||
OUTPUT("%dx%d", (int)type_bit_size(type->array.base), type->array.len);
|
||||
PRINTF("%dx%d", (int)type_bit_size(type->array.base), type->array.len);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -179,32 +179,32 @@ static void header_gen_function_ptr(FILE *file, HTable *table, Type *type)
|
||||
header_gen_maybe_generate_type(file, table, param->type);
|
||||
FOREACH_END();
|
||||
|
||||
OUTPUT("typedef ");
|
||||
PRINTF("typedef ");
|
||||
header_print_type(file, rtype);
|
||||
OUTPUT("(*%s)(", decl_get_extname(type->decl));
|
||||
PRINTF("(*%s)(", decl_get_extname(type->decl));
|
||||
if (!vec_size(sig->params) && !extra_ret)
|
||||
{
|
||||
OUTPUT("void);\n");
|
||||
PRINTF("void);\n");
|
||||
return;
|
||||
}
|
||||
if (extra_ret)
|
||||
{
|
||||
header_print_type(file, type_get_ptr(extra_ret));
|
||||
OUTPUT(" return_ref");
|
||||
PRINTF(" return_ref");
|
||||
}
|
||||
FOREACH_BEGIN_IDX(i, Decl *param, sig->params)
|
||||
if (i || extra_ret) OUTPUT(", ");
|
||||
if (i || extra_ret) PRINTF(", ");
|
||||
header_print_type(file, param->type);
|
||||
if (param->name) OUTPUT(" %s", param->name);
|
||||
if (param->name) PRINTF(" %s", param->name);
|
||||
FOREACH_END();
|
||||
OUTPUT(");\n");
|
||||
PRINTF(");\n");
|
||||
}
|
||||
|
||||
static void header_gen_function(FILE *file, FILE *file_types, HTable *table, Decl *decl)
|
||||
{
|
||||
if (!decl->is_export) return;
|
||||
Signature *sig = &decl->func_decl.signature;
|
||||
OUTPUT("extern ");
|
||||
PRINTF("extern ");
|
||||
Type *rtype = typeget(sig->rtype);
|
||||
Type *extra_ret = NULL;
|
||||
if (type_is_optional(rtype))
|
||||
@@ -215,24 +215,24 @@ static void header_gen_function(FILE *file, FILE *file_types, HTable *table, Dec
|
||||
}
|
||||
header_gen_maybe_generate_type(file_types, table, rtype);
|
||||
header_print_type(file, rtype);
|
||||
OUTPUT(" %s(", decl_get_extname(decl));
|
||||
PRINTF(" %s(", decl_get_extname(decl));
|
||||
if (!vec_size(sig->params) && !extra_ret)
|
||||
{
|
||||
OUTPUT("void);\n");
|
||||
PRINTF("void);\n");
|
||||
return;
|
||||
}
|
||||
if (extra_ret)
|
||||
{
|
||||
header_print_type(file, type_get_ptr(extra_ret));
|
||||
OUTPUT(" return_ref");
|
||||
PRINTF(" return_ref");
|
||||
}
|
||||
FOREACH_BEGIN_IDX(i, Decl *param, sig->params)
|
||||
if (i || extra_ret) OUTPUT(", ");
|
||||
if (i || extra_ret) PRINTF(", ");
|
||||
header_print_type(file, param->type);
|
||||
header_gen_maybe_generate_type(file_types, table, param->type);
|
||||
if (param->name) OUTPUT(" %s", param->name);
|
||||
if (param->name) PRINTF(" %s", param->name);
|
||||
FOREACH_END();
|
||||
OUTPUT(");\n");
|
||||
PRINTF(");\n");
|
||||
}
|
||||
|
||||
static void header_gen_members(FILE *file, int indent, Decl **members)
|
||||
@@ -247,11 +247,11 @@ static void header_gen_members(FILE *file, int indent, Decl **members)
|
||||
if (member->type->canonical->type_kind == TYPE_ARRAY)
|
||||
{
|
||||
header_print_type(file, member->type->canonical->array.base);
|
||||
OUTPUT(" %s[%d];\n", member->name, member->type->canonical->array.len);
|
||||
PRINTF(" %s[%d];\n", member->name, member->type->canonical->array.len);
|
||||
break;
|
||||
}
|
||||
header_print_type(file, member->type);
|
||||
OUTPUT(" %s;\n", member->name);
|
||||
PRINTF(" %s;\n", member->name);
|
||||
break;
|
||||
case DECL_STRUCT:
|
||||
case DECL_UNION:
|
||||
@@ -266,22 +266,22 @@ static void header_gen_struct_union(FILE *file, int indent, Decl *decl)
|
||||
{
|
||||
if (!indent)
|
||||
{
|
||||
OUTPUT("typedef struct %s__ %s;\n", decl->extname, decl->extname);
|
||||
PRINTF("typedef struct %s__ %s;\n", decl->extname, decl->extname);
|
||||
}
|
||||
INDENT();
|
||||
if (decl->name)
|
||||
{
|
||||
OUTPUT("%s %s__\n", struct_union_str(decl), decl->extname);
|
||||
PRINTF("%s %s__\n", struct_union_str(decl), decl->extname);
|
||||
}
|
||||
else
|
||||
{
|
||||
OUTPUT("%s\n", struct_union_str(decl));
|
||||
PRINTF("%s\n", struct_union_str(decl));
|
||||
}
|
||||
INDENT();
|
||||
OUTPUT("{\n");
|
||||
PRINTF("{\n");
|
||||
header_gen_members(file, indent + 1, decl->strukt.members);
|
||||
INDENT();
|
||||
OUTPUT("};\n");
|
||||
PRINTF("};\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -292,10 +292,10 @@ static void header_gen_enum(FILE *file, int indent, Decl *decl)
|
||||
|
||||
static void header_gen_err(FILE *file, int indent, Decl *decl)
|
||||
{
|
||||
OUTPUT("typedef struct %s_error__ %s_error;\n", decl_get_extname(decl), decl_get_extname(decl));
|
||||
OUTPUT("struct %s_error__\n{\n", decl_get_extname(decl));
|
||||
PRINTF("typedef struct %s_error__ %s_error;\n", decl_get_extname(decl), decl_get_extname(decl));
|
||||
PRINTF("struct %s_error__\n{\n", decl_get_extname(decl));
|
||||
header_gen_members(file, indent, decl->strukt.members);
|
||||
OUTPUT("};\n");
|
||||
PRINTF("};\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -395,19 +395,19 @@ RETRY:
|
||||
Type *underlying_type = decl->enums.type_info->type->canonical;
|
||||
if (underlying_type == type_cint->canonical)
|
||||
{
|
||||
OUTPUT("typedef enum %s__ %s;\n", decl_get_extname(decl), decl_get_extname(decl));
|
||||
OUTPUT("enum %s__\n{\n", decl_get_extname(decl));
|
||||
PRINTF("typedef enum %s__ %s;\n", decl_get_extname(decl), decl_get_extname(decl));
|
||||
PRINTF("enum %s__\n{\n", decl_get_extname(decl));
|
||||
FOREACH_BEGIN(Decl *enum_member, decl->enums.values)
|
||||
OUTPUT("\t %s_%s,\n", decl_get_extname(decl), enum_member->name);
|
||||
PRINTF("\t %s_%s,\n", decl_get_extname(decl), enum_member->name);
|
||||
FOREACH_END();
|
||||
OUTPUT("};\n");
|
||||
PRINTF("};\n");
|
||||
return;
|
||||
}
|
||||
OUTPUT("typedef ");
|
||||
PRINTF("typedef ");
|
||||
header_print_type(file, underlying_type);
|
||||
OUTPUT(" %s;\n", decl_get_extname(decl));
|
||||
PRINTF(" %s;\n", decl_get_extname(decl));
|
||||
FOREACH_BEGIN_IDX(i, Decl *enum_member, decl->enums.values)
|
||||
OUTPUT("%s %s_%s = %d;\n", decl_get_extname(decl), decl_get_extname(decl), enum_member->name, i);
|
||||
PRINTF("%s %s_%s = %d;\n", decl_get_extname(decl), decl_get_extname(decl), enum_member->name, i);
|
||||
FOREACH_END();
|
||||
return;
|
||||
}
|
||||
@@ -419,13 +419,13 @@ RETRY:
|
||||
if (htable_get(table, type)) return;
|
||||
{
|
||||
Decl *decl = type->decl;
|
||||
OUTPUT("typedef struct %s__ %s;\n", decl_get_extname(decl), decl_get_extname(decl));
|
||||
PRINTF("typedef struct %s__ %s;\n", decl_get_extname(decl), decl_get_extname(decl));
|
||||
htable_set(table, type, type);
|
||||
header_ensure_member_types_exist(file, table, decl->strukt.members);
|
||||
OUTPUT("%s %s__\n", struct_union_str(decl), decl->extname);
|
||||
OUTPUT("{\n");
|
||||
PRINTF("%s %s__\n", struct_union_str(decl), decl->extname);
|
||||
PRINTF("{\n");
|
||||
header_gen_members(file, 1, decl->strukt.members);
|
||||
OUTPUT("};\n");
|
||||
PRINTF("};\n");
|
||||
return;
|
||||
}
|
||||
case TYPE_ARRAY:
|
||||
@@ -434,13 +434,13 @@ RETRY:
|
||||
if (htable_get(table, type)) return;
|
||||
{
|
||||
Decl *decl = type->decl;
|
||||
OUTPUT("typedef struct %s__slice__ %s;\n", decl_get_extname(decl), decl_get_extname(decl));
|
||||
PRINTF("typedef struct %s__slice__ %s;\n", decl_get_extname(decl), decl_get_extname(decl));
|
||||
htable_set(table, type, type);
|
||||
header_ensure_member_types_exist(file, table, decl->strukt.members);
|
||||
OUTPUT("%s %s__\n", struct_union_str(decl), decl->extname);
|
||||
OUTPUT("{\n");
|
||||
PRINTF("%s %s__\n", struct_union_str(decl), decl->extname);
|
||||
PRINTF("{\n");
|
||||
header_gen_members(file, 1, decl->strukt.members);
|
||||
OUTPUT("};\n");
|
||||
PRINTF("};\n");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@@ -449,11 +449,11 @@ RETRY:
|
||||
goto RETRY;
|
||||
case TYPE_VECTOR:
|
||||
if (htable_get(table, type)) return;
|
||||
OUTPUT("typedef ");
|
||||
PRINTF("typedef ");
|
||||
header_print_type(file, type->array.base);
|
||||
OUTPUT(" ");
|
||||
PRINTF(" ");
|
||||
header_print_type(file, type);
|
||||
OUTPUT(" __attribute__((vector_size(%d)));\n", (int)type_size(type->array.base) * type->array.len);
|
||||
PRINTF(" __attribute__((vector_size(%d)));\n", (int)type_size(type->array.base) * type->array.len);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -477,26 +477,26 @@ static void header_gen_global_var(FILE *file, FILE *file_type, HTable *table, De
|
||||
{
|
||||
Expr *init = decl->var.init_expr;
|
||||
if (type_is_arraylike(type) || type_is_user_defined(type) || !init) return;
|
||||
OUTPUT("#define %s ", decl_get_extname(decl));
|
||||
PRINTF("#define %s ", decl_get_extname(decl));
|
||||
assert(expr_is_const(init));
|
||||
switch (init->const_expr.const_kind)
|
||||
{
|
||||
case CONST_INTEGER:
|
||||
OUTPUT("%s\n", int_to_str(init->const_expr.ixx, 10));
|
||||
PRINTF("%s\n", int_to_str(init->const_expr.ixx, 10));
|
||||
return;
|
||||
case CONST_FLOAT:
|
||||
OUTPUT("%.15g\n", init->const_expr.fxx.f);
|
||||
PRINTF("%.15g\n", init->const_expr.fxx.f);
|
||||
return;
|
||||
case CONST_BOOL:
|
||||
OUTPUT("%s\n", init->const_expr.b ? "true" : "false");
|
||||
PRINTF("%s\n", init->const_expr.b ? "true" : "false");
|
||||
return;
|
||||
case CONST_POINTER:
|
||||
if (!init->const_expr.ptr)
|
||||
{
|
||||
OUTPUT("(void*)0\n");
|
||||
PRINTF("(void*)0\n");
|
||||
return;
|
||||
}
|
||||
OUTPUT("(void*)0x%llx\n", (unsigned long long)init->const_expr.ptr);
|
||||
PRINTF("(void*)0x%llx\n", (unsigned long long)init->const_expr.ptr);
|
||||
return;
|
||||
case CONST_STRING:
|
||||
putc('\"', file);
|
||||
@@ -508,13 +508,13 @@ static void header_gen_global_var(FILE *file, FILE *file_type, HTable *table, De
|
||||
fputc(ch, file);
|
||||
continue;
|
||||
}
|
||||
OUTPUT("\\x%02x", ch);
|
||||
PRINTF("\\x%02x", ch);
|
||||
}
|
||||
OUTPUT("\"\n");
|
||||
PRINTF("\"\n");
|
||||
return;
|
||||
case CONST_ENUM:
|
||||
case CONST_ERR:
|
||||
OUTPUT("%s\n", decl_get_extname(init->const_expr.enum_err_val));
|
||||
PRINTF("%s\n", decl_get_extname(init->const_expr.enum_err_val));
|
||||
return;
|
||||
case CONST_TYPEID:
|
||||
case CONST_MEMBER:
|
||||
@@ -525,11 +525,11 @@ static void header_gen_global_var(FILE *file, FILE *file_type, HTable *table, De
|
||||
}
|
||||
}
|
||||
assert(decl->var.kind == VARDECL_GLOBAL || decl->var.kind == VARDECL_CONST);
|
||||
OUTPUT("extern ");
|
||||
if (decl->var.kind == VARDECL_CONST) OUTPUT("const ");
|
||||
PRINTF("extern ");
|
||||
if (decl->var.kind == VARDECL_CONST) PRINTF("const ");
|
||||
header_gen_maybe_generate_type(file_type, table, decl->type);
|
||||
header_print_type(file, decl->type);
|
||||
OUTPUT(" %s;\n", decl_get_extname(decl));
|
||||
PRINTF(" %s;\n", decl_get_extname(decl));
|
||||
}
|
||||
|
||||
|
||||
@@ -551,7 +551,7 @@ void header_gen(Module **modules, unsigned module_count)
|
||||
OUT(file_types, "typedef struct { void* ptr; size_t len; } c3slice_t;\n");
|
||||
OUT(file_types, "typedef struct { void* ptr; c3typeid_t type; } c3any_t;\n");
|
||||
OUT(file_types, "\n#endif\n\n");
|
||||
OUTPUT("#include \"%s_types.h\"\n", name);
|
||||
PRINTF("#include \"%s_types.h\"\n", name);
|
||||
|
||||
for (unsigned i = 0; i < module_count; i++)
|
||||
{
|
||||
@@ -565,7 +565,7 @@ void header_gen(Module **modules, unsigned module_count)
|
||||
FOREACH_END();
|
||||
}
|
||||
|
||||
OUTPUT("/* Constants */\n");
|
||||
PRINTF("/* Constants */\n");
|
||||
for (unsigned i = 0; i < module_count; i++)
|
||||
{
|
||||
Module *module = modules[i];
|
||||
@@ -578,7 +578,7 @@ void header_gen(Module **modules, unsigned module_count)
|
||||
FOREACH_END();
|
||||
}
|
||||
|
||||
OUTPUT("\n/* Globals */\n");
|
||||
PRINTF("\n/* Globals */\n");
|
||||
for (unsigned i = 0; i < module_count; i++)
|
||||
{
|
||||
Module *module = modules[i];
|
||||
@@ -592,7 +592,7 @@ void header_gen(Module **modules, unsigned module_count)
|
||||
FOREACH_END();
|
||||
}
|
||||
|
||||
OUTPUT("\n/* Functions */\n");
|
||||
PRINTF("\n/* Functions */\n");
|
||||
for (unsigned i = 0; i < module_count; i++)
|
||||
{
|
||||
Module *module = modules[i];
|
||||
@@ -605,7 +605,7 @@ void header_gen(Module **modules, unsigned module_count)
|
||||
FOREACH_END();
|
||||
}
|
||||
|
||||
OUTPUT("\n/* Methods */\n");
|
||||
PRINTF("\n/* Methods */\n");
|
||||
for (unsigned i = 0; i < module_count; i++)
|
||||
{
|
||||
// Ignore stdlib modules
|
||||
|
||||
@@ -10,25 +10,25 @@
|
||||
unsigned decl_count_ = vec_size(unit->global_decls); \
|
||||
for (unsigned k_ = 0; k_ < decl_count_; k_++) { \
|
||||
a__ = unit->global_decls[k_];
|
||||
|
||||
#define PRINTF(string, ...) fprintf(file, string, ##__VA_ARGS__) /* NOLINT */
|
||||
#define FOREACH_DECL_END } } }
|
||||
#define INERT_COMMA do { if (first) { first = false; } else { fputs(",\n", file); } } while(0)
|
||||
|
||||
static inline void emit_modules(FILE *file)
|
||||
{
|
||||
|
||||
fputs("\t\"modules\": {\n", file);
|
||||
fputs("\t\"modules\": [\n", file);
|
||||
FOREACH_BEGIN_IDX(i, Module *module, global_context.module_list)
|
||||
if (i != 0) fputs(",\n", file);
|
||||
fprintf(file, "\t\t\"%s\"", module->name->module);
|
||||
PRINTF("\t\t\"%s\"", module->name->module);
|
||||
FOREACH_END();
|
||||
fputs("\n\t},\n", file);
|
||||
fputs("\t\"generic_modules\": {\n", file);
|
||||
fputs("\n\t],\n", file);
|
||||
fputs("\t\"generic_modules\": [\n", file);
|
||||
FOREACH_BEGIN_IDX(i, Module *module, global_context.generic_module_list)
|
||||
if (i != 0) fputs(",\n", file);
|
||||
fprintf(file, "\t\t\"%s\"", module->name->module);
|
||||
PRINTF("\t\t\"%s\"", module->name->module);
|
||||
FOREACH_END();
|
||||
fputs("\n\t}\n", file);
|
||||
fputs("\n\t]\n", file);
|
||||
}
|
||||
|
||||
static inline const char *decl_type_to_string(Decl *type)
|
||||
@@ -68,14 +68,14 @@ static inline const char *decl_type_to_string(Decl *type)
|
||||
}
|
||||
static inline void emit_type_data(FILE *file, Module *module, Decl *type)
|
||||
{
|
||||
fprintf(file, "\t\t\"%s::%s\": {\n", module->name->module, type->name);
|
||||
fprintf(file, "\t\t\t\"kind\": \"%s\"", decl_type_to_string(type));
|
||||
PRINTF("\t\t\"%s::%s\": {\n", module->name->module, type->name);
|
||||
PRINTF("\t\t\t\"kind\": \"%s\"", decl_type_to_string(type));
|
||||
if (type->decl_kind == DECL_STRUCT || type->decl_kind == DECL_UNION)
|
||||
{
|
||||
fputs(",\n\t\t\t\"members\": {\n", file);
|
||||
FOREACH_BEGIN_IDX(i, Decl *member, type->strukt.members)
|
||||
if (i != 0) fputs(",\n", file);
|
||||
fprintf(file, "\t\t\t\t\"%s\"", member->name);
|
||||
PRINTF("\t\t\t\t\"%s\"", member->name);
|
||||
FOREACH_END();
|
||||
fputs("\n\t\t\t}", file);
|
||||
}
|
||||
@@ -97,35 +97,35 @@ void print_type(FILE *file, TypeInfo *type)
|
||||
case TYPE_INFO_CT_IDENTIFIER:
|
||||
if (type->unresolved.path)
|
||||
{
|
||||
fprintf(file, "%s::", type->unresolved.path->module);
|
||||
PRINTF("%s::", type->unresolved.path->module);
|
||||
}
|
||||
fputs(type->unresolved.name, file);
|
||||
break;
|
||||
case TYPE_INFO_TYPEOF:
|
||||
scratch_buffer_clear();
|
||||
span_to_scratch(type->unresolved_type_expr->span);
|
||||
fprintf(file, "$typeof(%s)", scratch_buffer_to_string());
|
||||
PRINTF("$typeof(%s)", scratch_buffer_to_string());
|
||||
break;
|
||||
case TYPE_INFO_VATYPE:
|
||||
fprintf(file, "$vatype(...)");
|
||||
PRINTF("$vatype(...)");
|
||||
break;
|
||||
case TYPE_INFO_EVALTYPE:
|
||||
fprintf(file, "$evaltype(...)");
|
||||
PRINTF("$evaltype(...)");
|
||||
break;
|
||||
case TYPE_INFO_TYPEFROM:
|
||||
fprintf(file, "$typefrom(...)");
|
||||
PRINTF("$typefrom(...)");
|
||||
break;
|
||||
case TYPE_INFO_ARRAY:
|
||||
print_type(file, type->array.base);
|
||||
scratch_buffer_clear();
|
||||
span_to_scratch(type->array.len->span);
|
||||
fprintf(file, "[%s]", scratch_buffer_to_string());
|
||||
PRINTF("[%s]", scratch_buffer_to_string());
|
||||
break;
|
||||
case TYPE_INFO_VECTOR:
|
||||
print_type(file, type->array.base);
|
||||
scratch_buffer_clear();
|
||||
span_to_scratch(type->array.len->span);
|
||||
fprintf(file, "[<%s>]", scratch_buffer_to_string());
|
||||
PRINTF("[<%s>]", scratch_buffer_to_string());
|
||||
break;
|
||||
case TYPE_INFO_INFERRED_ARRAY:
|
||||
print_type(file, type->array.base);
|
||||
@@ -174,17 +174,17 @@ void print_type(FILE *file, TypeInfo *type)
|
||||
}
|
||||
static inline void emit_func_data(FILE *file, Module *module, Decl *func)
|
||||
{
|
||||
fprintf(file, "\t\t\"%s::%s\": {\n", module->name->module, func->name);
|
||||
fprintf(file, "\t\t\t\"rtype\": \"");
|
||||
PRINTF("\t\t\"%s::%s\": {\n", module->name->module, func->name);
|
||||
PRINTF("\t\t\t\"rtype\": \"");
|
||||
print_type(file, type_infoptr(func->func_decl.signature.rtype));
|
||||
fprintf(file, "\",\n");
|
||||
PRINTF("\",\n");
|
||||
fputs("\t\t\t\"params\": [\n", file);
|
||||
FOREACH_BEGIN_IDX(i, Decl *decl, func->func_decl.signature.params)
|
||||
if (i != 0) fputs(",\n", file);
|
||||
if (!decl) continue;
|
||||
fputs("\t\t\t\t{\n", file);
|
||||
fprintf(file, "\t\t\t\t\t\"name\": \"%s\",\n", decl->name ? decl->name : "");
|
||||
fprintf(file, "\t\t\t\t\t\"type\": \"");
|
||||
PRINTF("\t\t\t\t\t\"name\": \"%s\",\n", decl->name ? decl->name : "");
|
||||
PRINTF("\t\t\t\t\t\"type\": \"");
|
||||
if (decl->var.type_info)
|
||||
{
|
||||
print_type(file, type_infoptr(decl->var.type_info));
|
||||
|
||||
@@ -635,8 +635,7 @@ Decl *sema_resolve_method(CompilationUnit *unit, Decl *type, const char *method_
|
||||
return sema_resolve_type_method(unit, type->type, method_name, ambiguous_ref, private_ref);
|
||||
}
|
||||
|
||||
__attribute__((unused))
|
||||
bool sema_check_type_variable_array(SemaContext *context, TypeInfo *type_info)
|
||||
UNUSED bool sema_check_type_variable_array(SemaContext *context, TypeInfo *type_info)
|
||||
{
|
||||
if (!type_info_ok(type_info)) return false;
|
||||
Type *type = type_info->type;
|
||||
|
||||
Reference in New Issue
Block a user