39 std::unordered_map<std::string, FuncDefAST *> generic_func_defs;
40 std::vector<std::unique_ptr<FuncDefAST>> monomorphized_defs;
41 std::set<std::string> instantiated_functions;
44 std::unordered_map<std::string, EnumDefAST *> generic_enum_defs;
45 std::vector<std::unique_ptr<EnumDefAST>> monomorphized_enum_defs;
46 std::set<std::string> instantiated_enums;
49 bool unify(
const Type &pattern,
const Type &concrete,
50 std::unordered_map<std::string, Type> &bindings);
52 const std::unordered_map<std::string, Type> &bindings)
const;
53 bool contains_type_param(
const Type &type,
const std::string ¶m_name);
55 virtual void enter_new_scope()
override {
56 id_to_type.push_context();
57 typename_to_type.push_context();
59 typename_to_type.registerNameT(
"i32", Type::I32_t());
60 typename_to_type.registerNameT(
"i64", Type::I64_t());
61 typename_to_type.registerNameT(
"u32", Type::U32_t());
62 typename_to_type.registerNameT(
"u64", Type::U64_t());
63 typename_to_type.registerNameT(
"f64", Type::F64_t());
64 typename_to_type.registerNameT(
"bool", Type::Bool());
65 typename_to_type.registerNameT(
"char", Type::Char());
66 typename_to_type.registerNameT(
"unit", Type::Unit());
68 virtual void exit_new_scope()
override {
70 typename_to_type.pop();
73 this->enter_new_scope();
76 std::optional<Type> get_type_from_id(
const std::string &str)
const {
78 const auto &id_name_top = id_to_type.top();
79 if (id_name_top.queryName(str) == nameNotFound) {
81 fmt::format(
"Name '{}' not found, this should not happen", str));
83 return id_name_top.get_from_name(str);
86 std::optional<Type> get_type_from_id_parent(
const std::string &str)
const {
88 const auto &id_name_top = *id_to_type.top().parent_scope;
89 if (id_name_top.queryName(str) == nameNotFound) {
91 fmt::format(
"Name '{}' not found, this should not happen", str));
93 return id_name_top.get_from_name(str);
96 std::optional<Type> get_typename_type(
const std::string &str)
const {
97 const auto &typename_top = typename_to_type.top();
98 if (typename_top.recursiveQueryName(str) == nameNotFound) {
101 return typename_top.recursive_get_from_name(str);
106 const auto &top = id_to_type.top();
107 if (top.recursiveQueryName(str) == nameFound)
108 return top.recursive_get_from_name(str);
114 virtual void visit(
VarDefAST *ast)
override;
115 virtual void visit(
ExternAST *ast)
override;
130 virtual void visit(
BlockAST *ast)
override;
131 virtual void visit(
IfExprAST *ast)
override;
152 std::string type_param;
153 std::vector<PrototypeAST *> methods;
157 std::string class_name;
159 std::unordered_map<std::string, sammine_util::MonomorphizedName>
160 method_mangled_names;
163 std::unordered_map<std::string, TypeClassInfo> type_class_defs;
164 std::unordered_map<std::string, TypeClassInstanceInfo> type_class_instances;
165 std::unordered_map<std::string, std::string> method_to_class;
168 std::unordered_map<std::string, std::pair<Type, size_t>> variant_constructors;
176 void register_builtin_op_instances();
179 std::optional<Type> synthesize_typeclass_call(
CallExprAST *ast);
185 const Type &rhs_type);
188 bool check_array_literal_against_annotation(
VarDefAST *ast,
194 virtual void preorder_walk(
ProgramAST *ast)
override;
195 virtual void preorder_walk(
VarDefAST *ast)
override;
196 virtual void preorder_walk(
ExternAST *ast)
override;
197 virtual void preorder_walk(
FuncDefAST *ast)
override;
199 virtual void preorder_walk(
EnumDefAST *ast)
override;
202 virtual void preorder_walk(
CallExprAST *ast)
override;
207 virtual void preorder_walk(
BoolExprAST *ast)
override;
208 virtual void preorder_walk(
CharExprAST *ast)
override;
209 virtual void preorder_walk(
UnitExprAST *ast)
override;
211 virtual void preorder_walk(
BlockAST *ast)
override;
212 virtual void preorder_walk(
IfExprAST *ast)
override;
213 virtual void preorder_walk(
TypedVarAST *ast)
override;
217 virtual void preorder_walk(
FreeExprAST *ast)
override;
220 virtual void preorder_walk(
LenExprAST *ast)
override;
224 virtual void preorder_walk(
CaseExprAST *ast)
override;
231 virtual void postorder_walk(
ProgramAST *ast)
override;
232 virtual void postorder_walk(
VarDefAST *ast)
override;
233 virtual void postorder_walk(
ExternAST *ast)
override;
234 virtual void postorder_walk(
FuncDefAST *ast)
override;
235 virtual void postorder_walk(
StructDefAST *ast)
override;
236 virtual void postorder_walk(
EnumDefAST *ast)
override;
238 virtual void postorder_walk(
PrototypeAST *ast)
override;
239 virtual void postorder_walk(
CallExprAST *ast)
override;
244 virtual void postorder_walk(
BoolExprAST *ast)
override;
245 virtual void postorder_walk(
CharExprAST *ast)
override;
246 virtual void postorder_walk(
UnitExprAST *ast)
override;
248 virtual void postorder_walk(
BlockAST *ast)
override;
249 virtual void postorder_walk(
IfExprAST *ast)
override;
250 virtual void postorder_walk(
TypedVarAST *ast)
override;
251 virtual void postorder_walk(
DerefExprAST *ast)
override;
253 virtual void postorder_walk(
AllocExprAST *ast)
override;
254 virtual void postorder_walk(
FreeExprAST *ast)
override;
256 virtual void postorder_walk(
IndexExprAST *ast)
override;
257 virtual void postorder_walk(
LenExprAST *ast)
override;
261 virtual void postorder_walk(
CaseExprAST *ast)
override;
262 virtual void postorder_walk(
WhileExprAST *ast)
override;
305 return Type::NonExistent();
307 if (
auto *simple = llvm::dyn_cast<SimpleTypeExprAST>(type_expr)) {
308 if (simple->name.is_unresolved()) {
309 this->add_error(type_expr->location,
310 fmt::format(
"Module '{}' is not imported",
311 simple->name.get_module()));
312 return Type::Poisoned();
314 auto mangled = simple->name.mangled();
315 auto get_type_opt = this->get_typename_type(mangled);
316 if (!get_type_opt.has_value()) {
317 this->add_error(type_expr->location,
318 fmt::format(
"Type '{}' not found in the current scope.",
319 simple->name.mangled()));
320 return Type::Poisoned();
322 return get_type_opt.value();
325 if (
auto *ptr = llvm::dyn_cast<PointerTypeExprAST>(type_expr)) {
326 auto pointee = resolve_type_expr(ptr->pointee.get());
327 if (pointee.is_poisoned())
return pointee;
328 auto result = Type::Pointer(pointee);
329 result.is_linear = ptr->is_linear;
333 if (
auto *arr = llvm::dyn_cast<ArrayTypeExprAST>(type_expr)) {
334 auto elem = resolve_type_expr(arr->element.get());
335 return elem.is_poisoned() ? elem : Type::Array(elem, arr->size) ;
338 if (
auto *fn = llvm::dyn_cast<FunctionTypeExprAST>(type_expr)) {
339 std::vector<Type> total_types;
340 for (
auto ¶m : fn->paramTypes) {
341 auto pt = resolve_type_expr(param.get());
342 if (pt.is_poisoned())
343 return Type::Poisoned();
344 total_types.push_back(pt);
346 auto ret = resolve_type_expr(fn->returnType.get());
347 if (ret.is_poisoned())
348 return Type::Poisoned();
349 total_types.push_back(ret);
350 return Type::Function(std::move(total_types));
353 if (
auto *tup = llvm::dyn_cast<TupleTypeExprAST>(type_expr)) {
354 std::vector<Type> elem_types;
355 for (
auto &et : tup->element_types) {
356 auto resolved = resolve_type_expr(et.get());
357 if (resolved.is_poisoned())
358 return Type::Poisoned();
359 elem_types.push_back(resolved);
361 return Type::Tuple(std::move(elem_types));
364 if (
auto *gen = llvm::dyn_cast<GenericTypeExprAST>(type_expr)) {
365 auto base_mangled = gen->base_name.mangled();
368 auto it = generic_enum_defs.find(base_mangled);
369 if (it == generic_enum_defs.end()) {
370 this->add_error(type_expr->location,
371 fmt::format(
"'{}' is not a generic type",
372 gen->base_name.mangled()));
373 return Type::Poisoned();
376 auto *generic_def = it->second;
377 if (gen->type_args.size() != generic_def->type_params.size()) {
380 fmt::format(
"Generic type '{}' expects {} type argument(s), got {}",
381 gen->base_name.mangled(),
382 generic_def->type_params.size(),
383 gen->type_args.size()));
384 return Type::Poisoned();
388 Monomorphizer::SubstitutionMap bindings;
389 std::string type_args =
"<";
390 bool has_unresolved_type_param =
false;
391 for (
size_t i = 0; i < gen->type_args.size(); i++) {
392 auto resolved = resolve_type_expr(gen->type_args[i].get());
393 if (resolved.is_poisoned())
394 return Type::Poisoned();
395 if (resolved.type_kind == TypeKind::TypeParam)
396 has_unresolved_type_param =
true;
397 bindings[generic_def->type_params[i]] = resolved;
398 if (i > 0) type_args +=
", ";
399 type_args += resolved.to_string();
403 gen->base_name, type_args);
404 auto mangled = mono.mangled();
409 if (has_unresolved_type_param) {
411 auto existing = this->get_typename_type(mangled);
412 if (existing.has_value())
413 return existing.value();
415 return Type::Poisoned();
419 if (instantiated_enums.contains(mangled)) {
420 auto existing = this->get_typename_type(mangled);
421 if (existing.has_value())
422 return existing.value();
426 auto cloned = Monomorphizer::instantiate_enum(generic_def, mono,
428 cloned->accept_vis(
this);
429 instantiated_enums.insert(mangled);
430 monomorphized_enum_defs.push_back(std::move(cloned));
432 auto result = this->get_typename_type(mangled);
433 return result.has_value() ? result.value() : Type::Poisoned();
436 return Type::NonExistent();
A simple scoping class, doesn't differentiate between different names, like variable name,...