From 001baf4419da9c43d4ef68d7ec1eac638d6fb742 Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Thu, 29 Jun 2017 15:13:41 +0100 Subject: Add `Type` -- Runtime type for comparing types (similar to TypeInfo but simpler) --- src/check_expr.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'src/check_expr.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 465fcb15c..396a62eef 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -328,6 +328,14 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n return; } + if (operand->mode == Addressing_Type) { + if (type != NULL && is_type_type(type)) { + add_type_info_type(c, type); + add_type_info_type(c, operand->type); + return; + } + } + if (is_type_untyped(operand->type)) { Type *target_type = type; if (type == NULL || is_type_any(type)) { @@ -2604,6 +2612,7 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) { o->mode = Addressing_Value; } + void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) { if (x->mode == Addressing_Type && y->mode == Addressing_Type) { bool comp = are_types_identical(x->type, y->type); @@ -2616,6 +2625,15 @@ void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) { x->value = exact_value_bool(comp); return; } + if (x->mode == Addressing_Type && is_operand_a_type_value(*y)) { + x->mode = Addressing_Value; + x->type = t_untyped_bool; + return; + } else if (y->mode == Addressing_Type && is_operand_a_type_value(*x)) { + x->mode = Addressing_Value; + x->type = t_untyped_bool; + return; + } gbString err_str = NULL; gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena); @@ -3046,11 +3064,13 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) { check_expr_or_type(c, y, be->right); bool xt = x->mode == Addressing_Type; bool yt = y->mode == Addressing_Type; + bool xvt = is_operand_a_type_value(*x); + bool yvt = is_operand_a_type_value(*y); // If only one is a type, this is an error if (xt ^ yt) { GB_ASSERT(xt != yt); - if (xt) error_operand_not_expression(x); - if (yt) error_operand_not_expression(y); + if (xt && !yvt) error_operand_not_expression(x); + if (yt && !xvt) error_operand_not_expression(y); } } break; -- cgit v1.2.3