From 713199d7beda3dadc5dca5864b7f3c17788c1959 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Thu, 9 Jan 2025 20:45:42 +0100 Subject: [PATCH] Fix -P output. --- src/compiler/json_output.c | 747 ++----------------------------------- 1 file changed, 22 insertions(+), 725 deletions(-) diff --git a/src/compiler/json_output.c b/src/compiler/json_output.c index a86db0dae..75b09894e 100644 --- a/src/compiler/json_output.c +++ b/src/compiler/json_output.c @@ -162,734 +162,31 @@ void print_type(FILE *file, TypeInfo *type) void print_var_expr(FILE *file, Expr *expr); -void print_var_expr_unary(FILE *file, ExprUnary *expr, bool is_post) -{ - if (is_post) print_var_expr(file, expr->expr); - switch (expr->operator) - { - case UNARYOP_ERROR: - UNREACHABLE - case UNARYOP_DEREF: - fputs("*", file); - break; - case UNARYOP_ADDR: - fputs("&", file); - break; - case UNARYOP_NEG: - fputs("-", file); - break; - case UNARYOP_PLUS: - fputs("+", file); - break; - case UNARYOP_BITNEG: - fputs("~", file); - break; - case UNARYOP_NOT: - fputs("!", file); - break; - case UNARYOP_INC: - fputs("++", file); - break; - case UNARYOP_DEC: - fputs("--", file); - break; - case UNARYOP_TADDR: - fputs("&&", file); - break; - } - if (!is_post) print_var_expr(file, expr->expr); -} - -void print_var_expr_range(FILE *file, Range *r) -{ - if (r->is_len) - { - if (r->start_from_end) fputs("^", file); - PRINTF("%d", r->start_index); - fputs(" : ", file); - if (r->end_from_end) fputs("^", file); - PRINTF("%d", r->len_index); - } - else - { - switch (r->range_type) - { - case RANGE_DYNAMIC: - if (r->start_from_end) fputs("^", file); - print_var_expr(file, exprptr(r->start)); - fputs("..", file); - if (r->end) print_var_expr(file, exprptr(r->end)); - break; - case RANGE_CONST_END: - fputs("TODO: RANGE_CONST_END", file); - break; - case RANGE_CONST_LEN: - fputs("TODO: RANGE_CONST_LEN", file); - break; - case RANGE_CONST_RANGE: - fputs("TODO: RANGE_CONST_RANGE", file); - break; - } - } -} void print_var_expr(FILE *file, Expr *expr) { - if (!expr) - { - fputs("NULL EXPR", file); - return; - } - - switch ( expr->expr_kind) - { - case EXPR_ADDR_CONVERSION: - print_var_expr(file, expr->inner_expr); - break; - case EXPR_MAKE_SLICE: - fputs("TODO: MAKE_SLICE", file); - break; - case EXPR_MAKE_ANY: - fputs("TODO: MAKE_ANY", file); - break; - case EXPR_DISCARD: - fputs("(void)", file); - print_var_expr(file, expr->access_expr.parent); - break; - case EXPR_BITASSIGN: - case EXPR_BITACCESS: - case EXPR_ACCESS: - print_var_expr(file, expr->access_expr.parent); - fputs(".", file); - print_var_expr(file, expr->access_expr.child); - break; - case EXPR_RVALUE: - case EXPR_RECAST: - fputs("(", file); - print_var_expr(file, expr->access_expr.parent); - fputs(")", file); - break; - case EXPR_ANYFAULT_TO_FAULT: - fputs("TODO: ANYFAULT TO FAULT", file); - break; - case EXPR_VECTOR_FROM_ARRAY: - fputs("TODO: VEC FROM ARRAY", file); - break; - case EXPR_SLICE_LEN: - print_var_expr(file, expr->access_expr.parent); - fputs(".len", file); - break; - case EXPR_FLOAT_TO_INT: - case EXPR_INT_TO_FLOAT: - case EXPR_INT_TO_PTR: - case EXPR_PTR_TO_INT: - case EXPR_ENUM_FROM_ORD: - case EXPR_VECTOR_TO_ARRAY: - case EXPR_SLICE_TO_VEC_ARRAY: - case EXPR_SCALAR_TO_VECTOR: - case EXPR_EXT_TRUNC: - fputs("TODO: MISSING IMPL", file); - break; - case EXPR_PTR_ACCESS: - print_var_expr(file, expr->access_expr.parent); - fputs(".ptr", file); - break; - case EXPR_INT_TO_BOOL: - fputs(expr->int_to_bool_expr.negate ? "!" : "!!", file); - print_var_expr(file, expr->inner_expr); - break; - case EXPR_BINARY: - print_var_expr(file, exprptr(expr->binary_expr.left)); - switch (expr->binary_expr.operator) - { - case BINARYOP_ERROR: - UNREACHABLE - case BINARYOP_MULT: - fputs(" * ", file); - break; - case BINARYOP_SUB: - fputs(" - ", file); - break; - case BINARYOP_ADD: - fputs(" + ", file); - break; - case BINARYOP_DIV: - fputs(" / ", file); - break; - case BINARYOP_MOD: - fputs(" % ", file); - break; - case BINARYOP_SHR: - fputs(" >> ", file); - break; - case BINARYOP_SHL: - fputs(" << ", file); - break; - case BINARYOP_BIT_OR: - fputs(" | ", file); - break; - case BINARYOP_BIT_XOR: - fputs(" ^ ", file); - break; - case BINARYOP_BIT_AND: - fputs(" & ", file); - break; - case BINARYOP_AND: - case BINARYOP_CT_AND: - fputs(" && ", file); - break; - case BINARYOP_OR: - case BINARYOP_CT_OR: - fputs(" || ", file); - break; - case BINARYOP_ELSE: - fputs(" ?? ", file); - break; - case BINARYOP_CT_CONCAT: - fputs(" +++ ", file); - break; - case BINARYOP_GT: - fputs(" > ", file); - break; - case BINARYOP_GE: - fputs(" >= ", file); - break; - case BINARYOP_LT: - fputs(" < ", file); - break; - case BINARYOP_LE: - fputs(" <= ", file); - break; - case BINARYOP_NE: - fputs(" != ", file); - break; - case BINARYOP_EQ: - fputs(" == ", file); - break; - case BINARYOP_ASSIGN: - fputs(" = ", file); - break; - case BINARYOP_ADD_ASSIGN: - fputs(" += ", file); - break; - case BINARYOP_BIT_AND_ASSIGN: - fputs(" &= ", file); - break; - case BINARYOP_BIT_OR_ASSIGN: - fputs(" |= ", file); - break; - case BINARYOP_BIT_XOR_ASSIGN: - fputs(" ^= ", file); - break; - case BINARYOP_DIV_ASSIGN: - fputs(" /= ", file); - break; - case BINARYOP_MOD_ASSIGN: - fputs(" %= ", file); - break; - case BINARYOP_MULT_ASSIGN: - fputs(" *= ", file); - break; - case BINARYOP_SHR_ASSIGN: - fputs(" >>= ", file); - break; - case BINARYOP_SHL_ASSIGN: - fputs(" <<= ", file); - break; - case BINARYOP_SUB_ASSIGN: - fputs(" -= ", file); - break; - case BINARYOP_VEC_GT: - case BINARYOP_VEC_GE: - case BINARYOP_VEC_LT: - case BINARYOP_VEC_LE: - case BINARYOP_VEC_NE: - case BINARYOP_VEC_EQ: - fputs("/*VEC COMPARE TODO*/", file); - break; - } - print_var_expr(file, exprptr(expr->binary_expr.right)); - break; - case EXPR_TYPECALL: - case EXPR_CALL: - { - if (!expr->call_expr.is_pointer_call) print_var_expr(file, exprptr(expr->call_expr.function)); - fputs("(", file); - FOREACH_IDX(i, Expr *, e, expr->call_expr.arguments) - { - print_var_expr(file, e); - if (i != vec_size(expr->call_expr.arguments) - 1) fputs(", ", file); - } - fputs(")", file); - } - break; - case EXPR_CAST: - UNREACHABLE - case EXPR_BUILTIN: - case EXPR_COMPILER_CONST: - PRINTF("$$%s", expr->builtin_expr.ident); - break; - case EXPR_COMPOUND_LITERAL: - print_type(file, expr->expr_compound_literal.type_info); - print_var_expr(file, expr->expr_compound_literal.initializer); - break; - case EXPR_CONST: - switch (expr->const_expr.const_kind) - { - case CONST_FLOAT: - PRINTF("%f", expr->const_expr.fxx.f); - break; - case CONST_INTEGER: - fputs(i128_to_string(expr->const_expr.ixx.i, 10, true, false), file); - break; - case CONST_BOOL: - fputs(expr->const_expr.b ? "true" : "false", file); - break; - case CONST_ENUM: - PRINTF("%u", expr->const_expr.enum_err_val->enum_constant.ordinal); - break; - case CONST_ERR: - fputs("TODO: CONST_ERR", file); - break; - case CONST_BYTES: - { - fputs("x\\\"", file); - ArraySize len = expr->const_expr.bytes.len; - if (len == 0) - { - fputs("\\\"", file); - break; - } - const unsigned char *ptr = (unsigned char *)expr->const_expr.bytes.ptr; - char *res = malloc_string((size_t)(len * 3 + 1)); - char *c = res; - for (ArraySize i = 0; i < len; ++i) - { - unsigned char curr = ptr[i]; - char h = (curr & 0xF0) >> 4; - *(c++) = h > 0x09 ? h - 10 + 'A' : h + '0'; - char l = curr & 0x0F; - *(c++) = l > 0x09 ? l - 10 + 'A' : l + '0'; - } - *(c - 1) = '\\'; - *c = 0; - fputs(res, file); - fputs("\"", file); - } - break; - case CONST_STRING: - { - fputs("\\\"", file); - ArraySize len = expr->const_expr.bytes.len; - const char *ptr = expr->const_expr.bytes.ptr; - char *res = malloc_string((size_t)(len * 6 + 1)); - char *c = res; - for (ArraySize i = 0; i < len; ++i) - { - char curr = ptr[i]; - if (curr <= 0x1F && curr >= 0x00) - { - *(c++) = '\\'; - *(c++) = 'u'; - *(c++) = '0'; - *(c++) = '0'; - *(c++) = ((curr & 0x10) >> 4) + '0'; - char b = curr & 0x0F; - *(c++) = b > 0x09 ? b - 10 + 'A' : b + '0'; - } - else - { - if (curr == '\\' || curr == '\"') *(c++) = '\\'; - *(c++) = curr; - } - } - *c = 0; - fputs(res, file); - fputs("\\\"", file); - } - break; - case CONST_POINTER: - PRINTF("%llu", (unsigned long long) expr->const_expr.ptr); - break; - case CONST_TYPEID: - fputs(expr->const_expr.typeid->name, file); - break; - case CONST_SLICE: - fputs("TODO: CONST_SLICE", file); - break; - case CONST_INITIALIZER: - fputs("TODO: CONST_INITIALIZER", file); - break; - case CONST_UNTYPED_LIST: - fputs("{", file); - { - FOREACH_IDX(i, Expr *, e, expr->const_expr.untyped_list) - { - print_var_expr(file, e); - if (i != vec_size(expr->const_expr.untyped_list) - 1) fputs(", ", file); - } - } - fputs("}", file); - break; - case CONST_REF: - fputs("TODO: CONST_REF", file); - break; - case CONST_MEMBER: - fputs("TODO: CONST_MEMBER", file); - break; - } - break; - case EXPR_CT_AND_OR: - { - if (expr->ct_and_or_expr.is_and) - { - fputs("$and(", file); - } - else - { - fputs("$or(", file); - } - FOREACH_IDX(i, Expr *, e, expr->ct_and_or_expr.args) - { - print_var_expr(file, e); - if (i != vec_size(expr->ct_and_or_expr.args) - 1) fputs(", ", file); - } - fputs(")", file); - } - break; - case EXPR_CT_ARG: - fputs("$", file); - print_var_expr(file, exprptr(expr->ct_arg_expr.arg)); - break; - case EXPR_CT_CALL: - switch (expr->ct_call_expr.token_type) - { - case TOKEN_CT_ALIGNOF: // $alignof - fputs("$alignof(", file); - break; - case TOKEN_CT_APPEND: // $append - fputs("$append(", file); - break; - case TOKEN_CT_ASSERT: // $assert - fputs("$assert(", file); - break; - case TOKEN_CT_ECHO: // $echo - fputs("$echo(", file); - break; - case TOKEN_CT_EMBED: // $embed - fputs("$embed(", file); - break; - case TOKEN_CT_EVALTYPE: // $evaltype - fputs("$evaltype(", file); - break; - case TOKEN_CT_ERROR: // $error - fputs("$error(", file); - break; - case TOKEN_CT_EXEC: // $exec - fputs("$exec(", file); - break; - case TOKEN_CT_EXTNAMEOF: // $extnameof - fputs("$extnameof(", file); - break; - case TOKEN_CT_FEATURE: // $feature - fputs("$feature(", file); - break; - case TOKEN_CT_NAMEOF: // $nameof - fputs("$nameof(", file); - break; - case TOKEN_CT_OFFSETOF: // $offsetof - fputs("$offsetof(", file); - break; - case TOKEN_CT_QNAMEOF: // $qnameof - fputs("$qnameof(", file); - break; - case TOKEN_CT_SIZEOF: // $sizeof - fputs("$sizeof(", file); - break; - case TOKEN_CT_STRINGIFY: // $stringify - fputs("$stringify(", file); - break; - case TOKEN_CT_TYPEFROM: // $typefrom - fputs("$typefrom(", file); - break; - case TOKEN_CT_TYPEOF: // $typeof - fputs("$typeof(", file); - break; - case TOKEN_CT_VACOUNT: // $vacount - fputs("$vacount(", file); - break; - case TOKEN_CT_VATYPE: // $vatype - fputs("$vatype(", file); - break; - case TOKEN_CT_VACONST: // $vaconst, - fputs("$vaconst(", file); - break; - case TOKEN_CT_VAREF: // $varef, - fputs("$varef(", file); - break; - case TOKEN_CT_VAARG: // $vaarg, - fputs("$vaarg(", file); - break; - case TOKEN_CT_VAEXPR: // $vaexpr, - fputs("$vaexpr(", file); - break; - default: - UNREACHABLE - } - print_var_expr(file, expr->ct_call_expr.main_var); - fputs(")", file); - break; - case EXPR_CT_CASTABLE: - fputs("$assignable(", file); - print_var_expr(file, exprptr(expr->castable_expr.expr)); - fputs(", ", file); - print_type(file, type_infoptr(expr->castable_expr.type)); - fputs(")", file); - break; - case EXPR_CT_APPEND: - case EXPR_CT_CONCAT: - { - FOREACH_IDX(i, Expr *, e, expr->ct_concat) - { - print_var_expr(file, e); - if (i != vec_size(expr->ct_concat) - 1) fputs(" +++ ", file); - } - } - break; - case EXPR_CT_DEFINED: - fputs("$defined(", file); - { - FOREACH_IDX(i, Expr *, e, expr->expression_list) - { - print_var_expr(file, e); - if (i != vec_size(expr->ct_concat) - 1) fputs(", ", file); - } - } - fputs(")", file); - break; - case EXPR_CT_EVAL: - fputs("$eval(", file); - print_var_expr(file, expr->inner_expr); - fputs(")", file); - break; - case EXPR_CT_IDENT: - fputs(expr->ct_ident_expr.identifier, file); - break; - case EXPR_CT_IS_CONST: - fputs("$is_const(", file); - print_var_expr(file, expr->inner_expr); - fputs(")", file); - break; - case EXPR_DECL: - fputs("TODO: EXPR_DECL", file); - break; - case EXPR_DESIGNATOR: - { - FOREACH(DesignatorElement *, d, expr->designator_expr.path) - { - switch (d->kind) - { - case DESIGNATOR_FIELD: - fputs(".", file); - print_var_expr(file, d->field_expr); - break; - case DESIGNATOR_ARRAY: - case DESIGNATOR_RANGE: - fputs("[", file); - if (d->index_expr) print_var_expr(file, d->index_expr); - if (d->index_end_expr) - { - fputs("..", file); - print_var_expr(file, d->index_end_expr); - } - fputs("]", file); - break; - } - } - fputs(" = ", file); - print_var_expr(file, expr->designator_expr.value); - } - break; - case EXPR_EMBED: - fputs("$embed(", file); - print_var_expr(file, expr->embed_expr.filename); - if (expr->embed_expr.len) - { - fputs(", ", file); - print_var_expr(file, expr->embed_expr.len); - } - break; - case EXPR_EXPRESSION_LIST: - { - FOREACH_IDX(i, Expr *, e, expr->expression_list) - { - print_var_expr(file, e); - if (i != vec_size(expr->ct_concat) - 1) fputs(", ", file); - } - } - break; - case EXPR_EXPR_BLOCK: - fputs("TODO: EXPR_EXPR_BLOCK", file); - break; - case EXPR_FORCE_UNWRAP: - print_var_expr(file, expr->inner_expr); - fputs("!!", file); - break; - case EXPR_GENERIC_IDENT: - print_var_expr(file, exprptr(expr->generic_ident_expr.parent)); - fputs("(<", file); - { - FOREACH_IDX(i, Expr *, e, expr->generic_ident_expr.parmeters) - { - print_var_expr(file, e); - if (i != vec_size(expr->call_expr.arguments) - 1) fputs(", ", file); - } - } - fputs(">)", file); - break; - case EXPR_HASH_IDENT: - PRINTF("#%s", expr->hash_ident_expr.identifier); - break; - case EXPR_IDENTIFIER: - if (expr->identifier_expr.path) - { - if (expr->identifier_expr.path->module) - { - PRINTF("%s::", expr->identifier_expr.path->module); - } - } - if (expr->identifier_expr.ident) - { - fputs(expr->identifier_expr.ident, file); - } - break; - case EXPR_DESIGNATED_INITIALIZER_LIST: - case EXPR_INITIALIZER_LIST: - { - fputs("{ ", file); - FOREACH_IDX(i, Expr *, e, expr->initializer_list) - { - print_var_expr(file, e); - if (i != vec_size(expr->initializer_list) - 1) fputs(", ", file); - } - fputs(" }", file); - } - break; - case EXPR_LAMBDA: - fputs("TODO: EXPR_LAMBDA", file); - break; - case EXPR_MACRO_BLOCK: - fputs("TODO: EXPR_MACRO_BLOCK", file); - break; - case EXPR_MACRO_BODY_EXPANSION: - fputs("TODO: EXPR_MACRO_BODY_EXPANSION", file); - break; - case EXPR_MEMBER_GET: - fputs("TODO: EXPR_MEMBER_GET", file); - break; - case EXPR_NAMED_ARGUMENT: - PRINTF("%s: ", expr->named_argument_expr.name); - print_var_expr(file, expr->named_argument_expr.value); - break; - case EXPR_OPERATOR_CHARS: - fputs("TODO: EXPR_OPERATOR_CHARS", file); - break; - case EXPR_OPTIONAL: - print_var_expr(file, expr->inner_expr); - fputs("?", file); - break; - case EXPR_OTHER_CONTEXT: - fputs("TODO: EXPR_OTHER_CONTEXT", file); - break; - case EXPR_POINTER_OFFSET: - fputs("TODO: EXPR_POINTER_OFFSET", file); - break; - case EXPR_POST_UNARY: - print_var_expr_unary(file, &expr->unary_expr, true); - break; - case EXPR_RETHROW: - print_var_expr(file, expr->rethrow_expr.inner); - fputs("!", file); - break; - case EXPR_SLICE: - { - print_var_expr(file, exprptr(expr->slice_expr.expr)); - fputs("[", file); - print_var_expr_range(file, &expr->slice_expr.range); - fputs("]", file); - } - break; - case EXPR_SLICE_ASSIGN: - fputs("TODO: EXPR_SLICE_ASSIGN", file); - break; - case EXPR_SLICE_COPY: - fputs("TODO: EXPR_SLICE_COPY", file); - break; - case EXPR_SPLAT: - fputs("TODO: EXPR_SPLAT", file); - break; - case EXPR_STRINGIFY: - fputs("$stringify(", file); - print_var_expr(file, expr->inner_expr); - fputs(")", file); - break; - case EXPR_SUBSCRIPT: - fputs("TODO: EXPR_SUBSCRIPT", file); - break; - case EXPR_SUBSCRIPT_ADDR: - fputs("TODO: EXPR_SUBSCRIPT_ADDR", file); - break; - case EXPR_SUBSCRIPT_ASSIGN: - UNREACHABLE - case EXPR_SWIZZLE: - fputs("TODO: EXPR_SWIZZLE", file); - break; - case EXPR_TERNARY: - { - print_var_expr(file, exprptr(expr->ternary_expr.cond)); - fputs(" ? ", file); - Expr *then = exprptr(expr->ternary_expr.then_expr); - if (then) print_var_expr(file, then); - fputs(" : ", file); - print_var_expr(file, exprptr(expr->ternary_expr.else_expr)); - } - break; - case EXPR_TYPEID: - print_type(file, expr->typeid_expr); - break; - case EXPR_TYPEID_INFO: - print_var_expr(file, exprptr(expr->typeid_info_expr.parent)); - break; - case EXPR_TYPEINFO: - print_type(file, expr->type_expr); - break; - case EXPR_UNARY: - print_var_expr_unary(file, &expr->unary_expr, false); - break; - case EXPR_VASPLAT: - fputs("$vasplat[", file); - print_var_expr_range(file, &expr->vasplat_expr); - fputs("]", file); - break; - case EXPR_NOP: - case EXPR_ASM: - case EXPR_COND: - case EXPR_RETVAL: - // if not in doc lexing "mode", this is unreachable - case EXPR_POISONED: - case EXPR_TEST_HOOK: - case EXPR_ANYSWITCH: - case EXPR_TRY_UNWRAP: - case EXPR_LAST_FAULT: - case EXPR_MACRO_BODY: - // nested inside EXPR_CALL, avoid macro substitution - case EXPR_DEFAULT_ARG: - case EXPR_CATCH_UNWRAP: - case EXPR_BENCHMARK_HOOK: - case EXPR_BUILTIN_ACCESS: - case EXPR_TRY_UNWRAP_CHAIN: - UNREACHABLE - } + scratch_buffer_clear(); + span_to_scratch(expr->span); + const char *str = scratch_buffer_to_string(); + while (*str != 0) + { + char c = *str; + switch (c) + { + case '\r': + break; + case '\n': + fputs("\\n", file); + break; + case '\"': + fputs("\\\"", file); + break; + default: + fputc(c, file); + break; + } + ++str; + } } static inline void emit_type_data(FILE *file, Module *module, Decl *type)