tan  0.0.1
implicit_cast.cpp
1 #include "analysis/type_check.h"
2 #include "ast/type.h"
3 #include "ast/expr.h"
4 #include "ast/stmt.h"
5 #include "ast/intrinsic.h"
6 #include "ast/context.h"
7 #include "fmt/core.h"
8 #include "source_file/token.h"
9 #include <set>
10 
11 using namespace tanlang;
12 
13 bool TypeCheck::CanImplicitlyConvert(Type *from, Type *to) {
14  TAN_ASSERT(from && to);
15 
16  if (from == to) {
17  return true;
18  }
19 
20  int s1 = from->get_size_bits();
21  int s2 = to->get_size_bits();
22  if (from->is_int() && to->is_int()) {
23  bool u1 = from->is_unsigned();
24  bool u2 = to->is_unsigned();
25 
26  if (u1 == u2) { // rule #1
27  return s2 >= s1;
28  } else {
29  return s2 > s1; // rule #2 and #3
30  }
31  } else if (from->is_float() && to->is_float()) { // rule #4
32  return s2 >= s1;
33  }
34 
35  // rule #5
36  else if (from->is_int() && to->is_float()) {
37  return true;
38  }
39 
40  // # rule 6
41  else if (from->is_bool() && to->is_num()) {
42  return true;
43  }
44 
45  // # rule 7
46  else if ((from->is_num() || from->is_pointer()) && to->is_bool()) {
47  return true;
48  }
49 
50  // TODO: rule #8 and #9
51  else {
52  return false;
53  }
54 }
55 
56 Type *TypeCheck::ImplicitTypePromote(Type *t1, Type *t2) {
57  TAN_ASSERT(t1 && t2);
58 
59  if (t1 == t2) {
60  return t1;
61  }
62 
63  int s1 = t1->get_size_bits();
64  int s2 = t2->get_size_bits();
65  if (t1->is_int() && t2->is_int()) {
66  bool u1 = t1->is_unsigned();
67  bool u2 = t2->is_unsigned();
68 
69  if (u1 == u2) { // rule #1
70  return s1 >= s2 ? t1 : t2;
71  } else {
72  // let t1 be the unsigned, t2 be the signed
73  if (!u1) {
74  std::swap(t1, t2);
75  std::swap(s1, s2);
76  std::swap(u1, u2);
77  }
78 
79  if (s2 > s1) { // rule #2
80  return t2;
81  } else if (s1 > s2) { // rule #3
82  return t1;
83  } else {
84  return nullptr;
85  }
86  }
87  } else if (t1->is_float() && t2->is_float()) { // rule #4
88  return s1 >= s2 ? t1 : t2;
89  }
90 
91  // rule #5
92  else if (t1->is_float() && t2->is_int()) {
93  return t1;
94  } else if (t1->is_int() && t2->is_float()) {
95  return t2;
96  }
97 
98  // # rule 6
99  else if (t1->is_bool() && (t2->is_num() || t2->is_pointer())) {
100  return t2;
101  } else if ((t1->is_num() || t1->is_pointer()) && t2->is_bool()) {
102  return t1;
103  }
104 
105  // TODO: rule #8 and #9
106  else {
107  return nullptr;
108  }
109 }
110 
111 Cast *TypeCheck::create_implicit_conversion(Expr *from, Type *to) {
112  if (!CanImplicitlyConvert(from->get_type(), to)) {
113  error(ErrorType::TYPE_ERROR,
114  from,
115  fmt::format("Cannot implicitly convert type {} to {}", from->get_type()->get_typename(), to->get_typename()));
116  }
117 
118  auto *cast = Cast::Create(from->src());
119  cast->set_lhs(from);
120  cast->set_type(to);
121  return cast;
122 }
123 
124 Type *TypeCheck::auto_promote_bop_operand_types(BinaryOperator *bop) {
125  auto *lhs = bop->get_lhs();
126  auto *rhs = bop->get_rhs();
127  auto *lhs_type = lhs->get_type();
128  auto *rhs_type = rhs->get_type();
129 
130  auto *promoted_type = ImplicitTypePromote(lhs_type, rhs_type);
131  if (!promoted_type) {
132  error(ErrorType::TYPE_ERROR,
133  bop,
134  fmt::format("Cannot find a valid type promotion between {} and {}",
135  lhs_type->get_typename(),
136  rhs_type->get_typename()));
137  }
138 
139  TAN_ASSERT(promoted_type == lhs_type || promoted_type == rhs_type);
140  if (promoted_type != lhs_type) {
141  auto *cast = Cast::Create(bop->src());
142  cast->set_lhs(lhs);
143  cast->set_type(promoted_type);
144  bop->set_lhs(cast);
145  } else {
146  auto *cast = Cast::Create(bop->src());
147  cast->set_lhs(rhs);
148  cast->set_type(promoted_type);
149  bop->set_rhs(cast);
150  }
151 
152  return promoted_type;
153 }
Type is immutable once created. The exception is StructType. Its information is updated in multiple s...
Definition: type.h:22