diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/all_types.hpp | 1 | ||||
| -rw-r--r-- | src/analyze.cpp | 172 | ||||
| -rw-r--r-- | src/analyze.hpp | 2 | ||||
| -rw-r--r-- | src/ir.cpp | 28 | ||||
| -rw-r--r-- | src/ir_print.cpp | 173 |
5 files changed, 204 insertions, 172 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp index c084fd31a1..4449c5c9a6 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -57,6 +57,7 @@ struct IrExecutable { Buf *c_import_buf; AstNode *source_node; IrExecutable *parent_exec; + Scope *begin_scope; }; enum OutType { diff --git a/src/analyze.cpp b/src/analyze.cpp index bdcca2f780..cb757e1db1 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3381,3 +3381,175 @@ void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue * zig_unreachable(); } } + +void render_const_value(Buf *buf, ConstExprValue *const_val) { + switch (const_val->special) { + case ConstValSpecialRuntime: + zig_unreachable(); + case ConstValSpecialUndef: + buf_appendf(buf, "undefined"); + return; + case ConstValSpecialZeroes: + buf_appendf(buf, "zeroes"); + return; + case ConstValSpecialStatic: + break; + } + assert(const_val->type); + + TypeTableEntry *canon_type = get_underlying_type(const_val->type); + switch (canon_type->id) { + case TypeTableEntryIdTypeDecl: + zig_unreachable(); + case TypeTableEntryIdInvalid: + buf_appendf(buf, "(invalid)"); + return; + case TypeTableEntryIdVar: + buf_appendf(buf, "(var)"); + return; + case TypeTableEntryIdVoid: + buf_appendf(buf, "{}"); + return; + case TypeTableEntryIdNumLitFloat: + buf_appendf(buf, "%f", const_val->data.x_bignum.data.x_float); + return; + case TypeTableEntryIdNumLitInt: + { + BigNum *bignum = &const_val->data.x_bignum; + const char *negative_str = bignum->is_negative ? "-" : ""; + buf_appendf(buf, "%s%llu", negative_str, bignum->data.x_uint); + return; + } + case TypeTableEntryIdMetaType: + buf_appendf(buf, "%s", buf_ptr(&const_val->data.x_type->name)); + return; + case TypeTableEntryIdInt: + { + BigNum *bignum = &const_val->data.x_bignum; + assert(bignum->kind == BigNumKindInt); + const char *negative_str = bignum->is_negative ? "-" : ""; + buf_appendf(buf, "%s%llu", negative_str, bignum->data.x_uint); + } + return; + case TypeTableEntryIdFloat: + { + BigNum *bignum = &const_val->data.x_bignum; + assert(bignum->kind == BigNumKindFloat); + buf_appendf(buf, "%f", bignum->data.x_float); + } + return; + case TypeTableEntryIdUnreachable: + buf_appendf(buf, "@unreachable()"); + return; + case TypeTableEntryIdBool: + { + const char *value = const_val->data.x_bool ? "true" : "false"; + buf_appendf(buf, "%s", value); + return; + } + case TypeTableEntryIdPointer: + buf_appendf(buf, "&"); + if (const_val->data.x_ptr.special == ConstPtrSpecialRuntime) { + buf_appendf(buf, "(runtime pointer value)"); + } else if (const_val->data.x_ptr.special == ConstPtrSpecialCStr) { + buf_appendf(buf, "(c str lit)"); + } else { + render_const_value(buf, const_ptr_pointee(const_val)); + } + return; + case TypeTableEntryIdFn: + { + FnTableEntry *fn_entry = const_val->data.x_fn; + buf_appendf(buf, "%s", buf_ptr(&fn_entry->symbol_name)); + return; + } + case TypeTableEntryIdBlock: + { + AstNode *node = const_val->data.x_block->source_node; + buf_appendf(buf, "(scope:%zu:%zu)", node->line + 1, node->column + 1); + return; + } + case TypeTableEntryIdArray: + { + uint64_t len = canon_type->data.array.len; + buf_appendf(buf, "%s{", buf_ptr(&canon_type->name)); + for (uint64_t i = 0; i < len; i += 1) { + if (i != 0) + buf_appendf(buf, ","); + ConstExprValue *child_value = &const_val->data.x_array.elements[i]; + render_const_value(buf, child_value); + } + buf_appendf(buf, "}"); + return; + } + case TypeTableEntryIdNullLit: + { + buf_appendf(buf, "null"); + return; + } + case TypeTableEntryIdUndefLit: + { + buf_appendf(buf, "undefined"); + return; + } + case TypeTableEntryIdMaybe: + { + if (const_val->data.x_maybe) { + render_const_value(buf, const_val->data.x_maybe); + } else { + buf_appendf(buf, "null"); + } + return; + } + case TypeTableEntryIdNamespace: + { + ImportTableEntry *import = const_val->data.x_import; + if (import->c_import_node) { + buf_appendf(buf, "(namespace from C import)"); + } else { + buf_appendf(buf, "(namespace: %s)", buf_ptr(import->path)); + } + return; + } + case TypeTableEntryIdBoundFn: + { + FnTableEntry *fn_entry = const_val->data.x_bound_fn.fn; + buf_appendf(buf, "(bound fn %s)", buf_ptr(&fn_entry->symbol_name)); + return; + } + case TypeTableEntryIdStruct: + { + buf_appendf(buf, "(struct %s constant)", buf_ptr(&canon_type->name)); + return; + } + case TypeTableEntryIdEnum: + { + buf_appendf(buf, "(enum %s constant)", buf_ptr(&canon_type->name)); + return; + } + case TypeTableEntryIdErrorUnion: + { + buf_appendf(buf, "(error union %s constant)", buf_ptr(&canon_type->name)); + return; + } + case TypeTableEntryIdUnion: + { + buf_appendf(buf, "(union %s constant)", buf_ptr(&canon_type->name)); + return; + } + case TypeTableEntryIdPureError: + { + buf_appendf(buf, "(pure error constant)"); + return; + } + case TypeTableEntryIdEnumTag: + { + TypeTableEntry *enum_type = canon_type->data.enum_tag.enum_type; + TypeEnumField *field = &enum_type->data.enumeration.fields[const_val->data.x_bignum.data.x_uint]; + buf_appendf(buf, "%s.%s", buf_ptr(&enum_type->name), buf_ptr(field->name)); + return; + } + } + zig_unreachable(); +} + diff --git a/src/analyze.hpp b/src/analyze.hpp index 6204f50025..cce39e9fe6 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -82,6 +82,8 @@ bool ir_get_var_is_comptime(VariableTableEntry *var); bool const_values_equal(ConstExprValue *a, ConstExprValue *b); void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val, bool is_max); +void render_const_value(Buf *buf, ConstExprValue *const_val); + ScopeBlock *create_block_scope(AstNode *node, Scope *parent); ScopeDefer *create_defer_scope(AstNode *node, Scope *parent); ScopeDeferExpr *create_defer_expr_scope(AstNode *node, Scope *parent); diff --git a/src/ir.cpp b/src/ir.cpp index eb90a52a3a..75402595a6 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -117,6 +117,7 @@ static void ir_ref_bb(IrBasicBlock *bb) { } static void ir_ref_instruction(IrInstruction *instruction, IrBasicBlock *cur_bb) { + assert(instruction->id != IrInstructionIdInvalid); instruction->ref_count += 1; if (instruction->owner_bb != cur_bb) ir_ref_bb(instruction->owner_bb); @@ -3095,7 +3096,13 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) { IrInstruction *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); + if (op1 == irb->codegen->invalid_instruction) + return op1; + IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); + if (op2 == irb->codegen->invalid_instruction) + return op2; + return ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); } @@ -3956,6 +3963,8 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node for (size_t i = 0; i < arg_count; i += 1) { AstNode *arg_node = node->data.fn_call_expr.params.at(i); args[i] = ir_gen_node(irb, arg_node, scope); + if (args[i] == irb->codegen->invalid_instruction) + return args[i]; } bool is_comptime = node->data.fn_call_expr.is_comptime; @@ -4946,6 +4955,19 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); } +static bool render_instance_name_recursive(Buf *name, Scope *outer_scope, Scope *inner_scope) { + if (inner_scope == nullptr || inner_scope == outer_scope) return false; + bool need_comma = render_instance_name_recursive(name, outer_scope, inner_scope->parent); + if (inner_scope->id != ScopeIdVarDecl) + return need_comma; + + ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope; + if (need_comma) + buf_append_char(name, ','); + render_const_value(name, &var_scope->var->value); + return true; +} + static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope, AstNode *node) { assert(node->type == NodeTypeContainerDecl); @@ -4959,9 +4981,7 @@ static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope, name = buf_alloc(); buf_append_buf(name, &fn_entry->symbol_name); buf_appendf(name, "("); - // TODO render args. note that fn_type_id is likely not complete - // at this time. - // probably have to render them from the fn scope + render_instance_name_recursive(name, &fn_entry->fndef_scope->base, irb->exec->begin_scope); buf_appendf(name, ")"); } else { name = buf_sprintf("(anonymous %s at %s:%zu:%zu)", container_string(kind), @@ -5822,6 +5842,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node ir_executable.is_inline = true; ir_executable.fn_entry = fn_entry; ir_executable.c_import_buf = c_import_buf; + ir_executable.begin_scope = scope; ir_gen(codegen, node, scope, &ir_executable); if (ir_executable.invalid) @@ -5843,6 +5864,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node analyzed_executable.c_import_buf = c_import_buf; analyzed_executable.backward_branch_count = backward_branch_count; analyzed_executable.backward_branch_quota = backward_branch_quota; + analyzed_executable.begin_scope = scope; TypeTableEntry *result_type = ir_analyze(codegen, &ir_executable, &analyzed_executable, expected_type, node); if (result_type->id == TypeTableEntryIdInvalid) return codegen->invalid_instruction; diff --git a/src/ir_print.cpp b/src/ir_print.cpp index eb95a2681e..c3df0df831 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -32,175 +32,10 @@ static void ir_print_prefix(IrPrint *irp, IrInstruction *instruction) { } static void ir_print_const_value(IrPrint *irp, ConstExprValue *const_val) { - switch (const_val->special) { - case ConstValSpecialRuntime: - zig_unreachable(); - case ConstValSpecialUndef: - fprintf(irp->f, "undefined"); - return; - case ConstValSpecialZeroes: - fprintf(irp->f, "zeroes"); - return; - case ConstValSpecialStatic: - break; - } - assert(const_val->type); - - TypeTableEntry *canon_type = get_underlying_type(const_val->type); - switch (canon_type->id) { - case TypeTableEntryIdTypeDecl: - zig_unreachable(); - case TypeTableEntryIdInvalid: - fprintf(irp->f, "(invalid)"); - return; - case TypeTableEntryIdVar: - fprintf(irp->f, "(var)"); - return; - case TypeTableEntryIdVoid: - fprintf(irp->f, "{}"); - return; - case TypeTableEntryIdNumLitFloat: - fprintf(irp->f, "%f", const_val->data.x_bignum.data.x_float); - return; - case TypeTableEntryIdNumLitInt: - { - BigNum *bignum = &const_val->data.x_bignum; - const char *negative_str = bignum->is_negative ? "-" : ""; - fprintf(irp->f, "%s%llu", negative_str, bignum->data.x_uint); - return; - } - case TypeTableEntryIdMetaType: - fprintf(irp->f, "%s", buf_ptr(&const_val->data.x_type->name)); - return; - case TypeTableEntryIdInt: - { - BigNum *bignum = &const_val->data.x_bignum; - assert(bignum->kind == BigNumKindInt); - const char *negative_str = bignum->is_negative ? "-" : ""; - fprintf(irp->f, "%s%llu", negative_str, bignum->data.x_uint); - } - return; - case TypeTableEntryIdFloat: - { - BigNum *bignum = &const_val->data.x_bignum; - assert(bignum->kind == BigNumKindFloat); - fprintf(irp->f, "%f", bignum->data.x_float); - } - return; - case TypeTableEntryIdUnreachable: - fprintf(irp->f, "@unreachable()"); - return; - case TypeTableEntryIdBool: - { - const char *value = const_val->data.x_bool ? "true" : "false"; - fprintf(irp->f, "%s", value); - return; - } - case TypeTableEntryIdPointer: - fprintf(irp->f, "&"); - if (const_val->data.x_ptr.special == ConstPtrSpecialRuntime) { - fprintf(irp->f, "(runtime pointer value)"); - } else if (const_val->data.x_ptr.special == ConstPtrSpecialCStr) { - fprintf(irp->f, "(c str lit)"); - } else { - ir_print_const_value(irp, const_ptr_pointee(const_val)); - } - return; - case TypeTableEntryIdFn: - { - FnTableEntry *fn_entry = const_val->data.x_fn; - fprintf(irp->f, "%s", buf_ptr(&fn_entry->symbol_name)); - return; - } - case TypeTableEntryIdBlock: - { - AstNode *node = const_val->data.x_block->source_node; - fprintf(irp->f, "(scope:%zu:%zu)", node->line + 1, node->column + 1); - return; - } - case TypeTableEntryIdArray: - { - uint64_t len = canon_type->data.array.len; - fprintf(irp->f, "%s{", buf_ptr(&canon_type->name)); - for (uint64_t i = 0; i < len; i += 1) { - if (i != 0) - fprintf(irp->f, ","); - ConstExprValue *child_value = &const_val->data.x_array.elements[i]; - ir_print_const_value(irp, child_value); - } - fprintf(irp->f, "}"); - return; - } - case TypeTableEntryIdNullLit: - { - fprintf(irp->f, "null"); - return; - } - case TypeTableEntryIdUndefLit: - { - fprintf(irp->f, "undefined"); - return; - } - case TypeTableEntryIdMaybe: - { - if (const_val->data.x_maybe) { - ir_print_const_value(irp, const_val->data.x_maybe); - } else { - fprintf(irp->f, "null"); - } - return; - } - case TypeTableEntryIdNamespace: - { - ImportTableEntry *import = const_val->data.x_import; - if (import->c_import_node) { - fprintf(irp->f, "(namespace from C import)"); - } else { - fprintf(irp->f, "(namespace: %s)", buf_ptr(import->path)); - } - return; - } - case TypeTableEntryIdBoundFn: - { - FnTableEntry *fn_entry = const_val->data.x_bound_fn.fn; - fprintf(irp->f, "bound %s to ", buf_ptr(&fn_entry->symbol_name)); - ir_print_other_instruction(irp, const_val->data.x_bound_fn.first_arg); - return; - } - case TypeTableEntryIdStruct: - { - fprintf(irp->f, "(struct %s constant)", buf_ptr(&canon_type->name)); - return; - } - case TypeTableEntryIdEnum: - { - fprintf(irp->f, "(enum %s constant)", buf_ptr(&canon_type->name)); - return; - } - case TypeTableEntryIdErrorUnion: - { - fprintf(irp->f, "(error union %s constant)", buf_ptr(&canon_type->name)); - return; - } - case TypeTableEntryIdUnion: - { - fprintf(irp->f, "(union %s constant)", buf_ptr(&canon_type->name)); - return; - } - case TypeTableEntryIdPureError: - { - fprintf(irp->f, "(pure error constant)"); - return; - } - case TypeTableEntryIdEnumTag: - { - TypeTableEntry *enum_type = canon_type->data.enum_tag.enum_type; - TypeEnumField *field = &enum_type->data.enumeration.fields[const_val->data.x_bignum.data.x_uint]; - fprintf(irp->f, "%s.%s", buf_ptr(&enum_type->name), buf_ptr(field->name)); - return; - } - } - zig_unreachable(); + Buf buf = BUF_INIT; + buf_resize(&buf, 0); + render_const_value(&buf, const_val); + fprintf(irp->f, "%s", buf_ptr(&buf)); } static void ir_print_var_instruction(IrPrint *irp, IrInstruction *instruction) { |
