142 bool is_mutable =
false;
143 bool is_linear =
false;
145 Type() : type_kind(TypeKind::NonExistent), type_data(std::monostate()) {}
146 static Type I32_t() {
return Type{TypeKind::I32_t, std::monostate()}; }
147 static Type I64_t() {
return Type{TypeKind::I64_t, std::monostate()}; }
148 static Type U32_t() {
return Type{TypeKind::U32_t, std::monostate()}; }
149 static Type U64_t() {
return Type{TypeKind::U64_t, std::monostate()}; }
150 static Type F64_t() {
return Type{TypeKind::F64_t, std::monostate()}; }
151 static Type Bool() {
return Type{TypeKind::Bool, std::monostate()}; }
152 static Type Char() {
return Type{TypeKind::Char, std::monostate()}; }
153 static Type Poisoned() {
return Type{TypeKind::Poisoned, std::monostate()}; }
154 static Type Unit() {
return Type{TypeKind::Unit, std::monostate()}; }
155 static Type Never() {
return Type{TypeKind::Never, std::monostate()}; }
156 static Type Integer() {
return Type{TypeKind::Integer, std::monostate()}; }
157 static Type Flt() {
return Type{TypeKind::Flt, std::monostate()}; }
158 static Type String(
const std::string &str) {
159 return Type{TypeKind::String, str};
161 static Type NonExistent() {
162 return Type{TypeKind::NonExistent, std::monostate()};
164 static Type TypeParam(
const std::string &name) {
165 return Type{TypeKind::TypeParam, name};
167 static Type Pointer(Type pointee) {
168 return Type{TypeKind::Pointer,
PointerType(pointee)};
170 static Type Array(Type element,
size_t size) {
171 return Type{TypeKind::Array,
ArrayType(element, size)};
174 std::vector<std::string> field_names,
175 std::vector<Type> field_types) {
176 return Type{TypeKind::Struct,
177 StructType(std::move(name), std::move(field_names),
178 std::move(field_types))};
181 std::vector<EnumType::VariantInfo> variants,
182 bool integer_backed =
false,
183 TypeKind backing_type = TypeKind::I32_t) {
184 return Type{TypeKind::Enum,
185 EnumType(std::move(name), std::move(variants), integer_backed,
188 static Type Tuple(std::vector<Type> element_types) {
189 return Type{TypeKind::Tuple,
TupleType(std::move(element_types))};
191 static Type Function(std::vector<Type> params,
bool var_arg =
false);
192 explicit operator bool()
const {
193 return this->type_kind != TypeKind::Poisoned;
195 bool synthesized()
const {
196 return this->type_kind != TypeKind::NonExistent ||
197 this->type_kind == TypeKind::Poisoned;
199 Type(TypeKind type_kind, TypeData type_data)
200 : type_kind(type_kind), type_data(type_data) {}
202 Type(
const Type &other);
203 Type(Type &&other)
noexcept;
204 Type &operator=(
const Type &other);
205 Type &operator=(Type &&other)
noexcept;
208 bool operator==(
const Type &other)
const;
210 bool operator!=(
const Type &other)
const;
211 bool operator<(
const Type &t)
const;
212 bool operator>(
const Type &t)
const;
214 std::string to_string()
const {
216 case TypeKind::I32_t:
218 case TypeKind::I64_t:
220 case TypeKind::U32_t:
222 case TypeKind::U64_t:
224 case TypeKind::F64_t:
228 case TypeKind::Struct:
229 return std::get<StructType>(type_data).get_name().mangled();
231 return std::get<EnumType>(type_data).get_name().mangled();
236 case TypeKind::Pointer:
237 return (is_linear ?
"'" :
"") + std::string(
"ptr<") +
238 std::get<PointerType>(type_data).get_pointee().to_string() +
">";
239 case TypeKind::Array:
240 return "[" + std::get<ArrayType>(type_data).get_element().to_string() +
241 ";" + std::to_string(std::get<ArrayType>(type_data).get_size()) +
243 case TypeKind::Function: {
244 std::string res =
"(";
245 auto fn_type = std::get<FunctionType>(type_data);
246 auto param = fn_type.get_params_types();
247 for (
size_t i = 0; i < param.size(); i++) {
248 res += param[i].to_string();
249 if (i != param.size() - 1)
253 res += fn_type.get_return_type().to_string();
257 case TypeKind::Tuple: {
258 std::string res =
"(";
259 auto &tt = std::get<TupleType>(type_data);
260 for (
size_t i = 0; i < tt.size(); i++) {
261 res += tt.get_element(i).to_string();
262 if (i != tt.size() - 1)
268 case TypeKind::Never:
270 case TypeKind::NonExistent:
272 case TypeKind::Poisoned:
274 case TypeKind::String:
275 return fmt::format(
"\"{}\"", std::get<std::string>(type_data));
276 case TypeKind::Integer:
277 return "numeric literal";
279 return "float literal";
280 case TypeKind::TypeParam:
281 return std::get<std::string>(type_data);
283 sammine_util::abort(
"Reaching the end of switch case and still cant "
284 "convert to string, blame Jasmine (badumbatish)!!!!!");
287 bool is_poisoned()
const {
return this->type_kind == TypeKind::Poisoned; }
289 bool is_literal()
const {
291 case TypeKind::I32_t:
292 case TypeKind::I64_t:
293 case TypeKind::U32_t:
294 case TypeKind::U64_t:
295 case TypeKind::F64_t:
299 case TypeKind::String:
300 case TypeKind::Integer:
303 case TypeKind::TypeParam:
310 bool is_polymorphic_numeric()
const {
311 return type_kind == TypeKind::Integer || type_kind == TypeKind::Flt;
314 bool isTypeWrapping()
const {
316 case TypeKind::Pointer:
317 case TypeKind::Array:
318 case TypeKind::Struct:
320 case TypeKind::Function:
321 case TypeKind::Tuple:
328 bool containsLinear()
const {
332 forEachInnerType([&](
const Type &inner) {
333 if (inner.containsLinear())
339 template <
typename F>
void forEachInnerType(F &&callback)
const {
341 case TypeKind::Pointer: {
342 auto &pt = std::get<PointerType>(type_data);
343 callback(pt.get_pointee());
346 case TypeKind::Array: {
347 auto &at = std::get<ArrayType>(type_data);
348 callback(at.get_element());
351 case TypeKind::Struct: {
352 auto &st = std::get<StructType>(type_data);
353 for (
auto &ft : st.get_field_types())
357 case TypeKind::Enum: {
358 auto &et = std::get<EnumType>(type_data);
359 for (
auto &variant : et.get_variants())
360 for (
auto &pt : variant.payload_types)
364 case TypeKind::Function: {
365 auto &fn = std::get<FunctionType>(type_data);
366 for (
auto &p : fn.get_params_types())
368 callback(fn.get_return_type());
371 case TypeKind::Tuple: {
372 auto &tt = std::get<TupleType>(type_data);
373 for (
auto &et : tt.get_element_types())
382 operator std::string()
const {
return to_string(); }