mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-18 20:40:28 +00:00
switch on typeid with type cases
This commit is contained in:
@@ -239,8 +239,7 @@ write_type :: proc(buf: ^String_Buffer, ti: ^runtime.Type_Info) {
|
||||
case runtime.Type_Info_Named:
|
||||
write_string(buf, info.name);
|
||||
case runtime.Type_Info_Integer:
|
||||
a := any{id = ti.id};
|
||||
switch in a {
|
||||
switch ti.id {
|
||||
case int: write_string(buf, "int");
|
||||
case uint: write_string(buf, "uint");
|
||||
case uintptr: write_string(buf, "uintptr");
|
||||
@@ -263,8 +262,7 @@ write_type :: proc(buf: ^String_Buffer, ti: ^runtime.Type_Info) {
|
||||
write_string(buf, "string");
|
||||
}
|
||||
case runtime.Type_Info_Boolean:
|
||||
a := any{id = ti.id};
|
||||
switch in a {
|
||||
switch ti.id {
|
||||
case bool: write_string(buf, "bool");
|
||||
case:
|
||||
write_byte(buf, 'b');
|
||||
|
||||
@@ -63,8 +63,7 @@ print_type :: proc(fd: os.Handle, ti: ^Type_Info) {
|
||||
case Type_Info_Named:
|
||||
os.write_string(fd, info.name);
|
||||
case Type_Info_Integer:
|
||||
a := any{id = ti.id};
|
||||
switch _ in a {
|
||||
switch ti.id {
|
||||
case int: os.write_string(fd, "int");
|
||||
case uint: os.write_string(fd, "uint");
|
||||
case uintptr: os.write_string(fd, "uintptr");
|
||||
@@ -83,8 +82,7 @@ print_type :: proc(fd: os.Handle, ti: ^Type_Info) {
|
||||
case Type_Info_String:
|
||||
os.write_string(fd, "string");
|
||||
case Type_Info_Boolean:
|
||||
a := any{id = ti.id};
|
||||
switch _ in a {
|
||||
switch ti.id {
|
||||
case bool: os.write_string(fd, "bool");
|
||||
case:
|
||||
os.write_byte(fd, 'b');
|
||||
|
||||
@@ -729,32 +729,46 @@ void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
|
||||
add_constant_switch_case(ctx, &seen, rhs);
|
||||
} else {
|
||||
Operand y = {};
|
||||
check_expr(ctx, &y, expr);
|
||||
if (is_type_typeid(x.type)) {
|
||||
check_expr_or_type(ctx, &y, expr, x.type);
|
||||
} else {
|
||||
check_expr(ctx, &y, expr);
|
||||
}
|
||||
|
||||
if (x.mode == Addressing_Invalid ||
|
||||
y.mode == Addressing_Invalid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
convert_to_typed(ctx, &y, x.type);
|
||||
if (y.mode == Addressing_Invalid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// NOTE(bill): the ordering here matters
|
||||
Operand z = y;
|
||||
check_comparison(ctx, &z, &x, Token_CmpEq);
|
||||
if (z.mode == Addressing_Invalid) {
|
||||
continue;
|
||||
}
|
||||
if (y.mode != Addressing_Constant) {
|
||||
if (complete) {
|
||||
error(y.expr, "#complete switch statement only allows constant case clauses");
|
||||
if (y.mode == Addressing_Type) {
|
||||
Type *t = y.type;
|
||||
if (t == nullptr || t == t_invalid || is_type_polymorphic(t)) {
|
||||
error(y.expr, "Invalid type for case clause");
|
||||
continue;
|
||||
}
|
||||
t = default_type(t);
|
||||
add_type_info_type(ctx, t);
|
||||
} else {
|
||||
convert_to_typed(ctx, &y, x.type);
|
||||
if (y.mode == Addressing_Invalid) {
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
add_constant_switch_case(ctx, &seen, y);
|
||||
// NOTE(bill): the ordering here matters
|
||||
Operand z = y;
|
||||
check_comparison(ctx, &z, &x, Token_CmpEq);
|
||||
if (z.mode == Addressing_Invalid) {
|
||||
continue;
|
||||
}
|
||||
if (y.mode != Addressing_Constant) {
|
||||
if (complete) {
|
||||
error(y.expr, "#complete switch statement only allows constant case clauses");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
add_constant_switch_case(ctx, &seen, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7145,7 +7145,14 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) {
|
||||
irValue *cond_rhs = ir_emit_comp(proc, op, tag, rhs);
|
||||
cond = ir_emit_arith(proc, Token_And, cond_lhs, cond_rhs, t_bool);
|
||||
} else {
|
||||
cond = ir_emit_comp(proc, Token_CmpEq, tag, ir_build_expr(proc, expr));
|
||||
if (expr->tav.mode == Addressing_Type) {
|
||||
GB_ASSERT(is_type_typeid(ir_type(tag)));
|
||||
irValue *e = ir_typeid(proc->module, expr->tav.type);
|
||||
e = ir_emit_conv(proc, e, ir_type(tag));
|
||||
cond = ir_emit_comp(proc, Token_CmpEq, tag, e);
|
||||
} else {
|
||||
cond = ir_emit_comp(proc, Token_CmpEq, tag, ir_build_expr(proc, expr));
|
||||
}
|
||||
}
|
||||
ir_emit_if(proc, cond, body, next_cond);
|
||||
ir_start_block(proc, next_cond);
|
||||
|
||||
Reference in New Issue
Block a user