|
8 | 8 | #include "../codegen.hpp" |
9 | 9 | #include "codegen.hpp" |
10 | 10 | #include "../utilities.hpp" |
| 11 | +#include "../semantic/intrinsics.hpp" |
11 | 12 |
|
12 | 13 | // Print LLVM IR |
13 | 14 | // ------------- |
@@ -508,19 +509,88 @@ codegen::Context::Binding codegen::Context::get_binding(std::string identifier) |
508 | 509 |
|
509 | 510 | // Name mangling |
510 | 511 | std::string codegen::Context::get_mangled_type_name(std::filesystem::path module, std::string identifier) { |
511 | | - return module.string() + "::" + identifier; |
| 512 | + std::string name = ""; |
| 513 | + auto path = module; |
| 514 | + if (path == this->ast.module_path) { |
| 515 | + name = identifier; |
| 516 | + } |
| 517 | + else if (std_libs.contains(module)) { |
| 518 | + name = identifier; |
| 519 | + } |
| 520 | + else { |
| 521 | + name = std::filesystem::relative(module, this->ast.module_path.parent_path()).string() + "::" + identifier; |
| 522 | + } |
| 523 | + |
| 524 | + return name; |
512 | 525 | } |
513 | 526 |
|
514 | 527 | std::string codegen::Context::get_mangled_function_name(std::filesystem::path module, std::string identifier, std::vector<ast::Type> args, ast::Type return_type, bool is_extern) { |
515 | 528 | if (is_extern) { |
516 | 529 | return identifier; |
517 | 530 | } |
518 | 531 |
|
519 | | - std::string name = module.string() + "::" + identifier; |
520 | | - for (size_t i = 0; i < args.size(); i++) { |
521 | | - name += "_" + args[i].to_str(); |
| 532 | + std::string name = ""; |
| 533 | + auto path = module; |
| 534 | + if (path == this->ast.module_path) { |
| 535 | + name = identifier; |
| 536 | + } |
| 537 | + else if (std_libs.contains(module)) { |
| 538 | + name = identifier; |
| 539 | + } |
| 540 | + else { |
| 541 | + name = std::filesystem::relative(module, this->ast.module_path.parent_path()).string() + "::" + identifier; |
| 542 | + } |
| 543 | + |
| 544 | + auto binding = this->scopes.functions_and_types_scopes.get_binding(identifier); |
| 545 | + assert(binding); |
| 546 | + if (binding->index() == ast::Interface) { |
| 547 | + auto interface = std::get<ast::InterfaceNode>(*binding); |
| 548 | + name += "["; |
| 549 | + bool founded = false; |
| 550 | + for (size_t i = 0; i < interface.args.size(); i++) { |
| 551 | + if (interface.args[i]->type == interface.type_parameters[0].type) { |
| 552 | + name += args[i].to_str(); |
| 553 | + founded = true; |
| 554 | + break; |
| 555 | + } |
| 556 | + } |
| 557 | + if (!founded) { |
| 558 | + name += return_type.to_str(); |
| 559 | + } |
| 560 | + name += "]"; |
| 561 | + return name; |
| 562 | + |
| 563 | + } |
| 564 | + else if (binding->index() == ast::Function |
| 565 | + && std::get<ast::FunctionNode>(*binding).type_parameters.size() > 0) { |
| 566 | + auto function = std::get<ast::FunctionNode>(*binding); |
| 567 | + name += "["; |
| 568 | + for (size_t j = 0; j < function.type_parameters.size(); j++) { |
| 569 | + bool founded = false; |
| 570 | + for (size_t i = 0; i < function.args.size(); i++) { |
| 571 | + if (function.type_parameters[j].type == function.args[i]->type) { |
| 572 | + name += args[i].to_str(); |
| 573 | + founded = true; |
| 574 | + break; |
| 575 | + } |
| 576 | + } |
| 577 | + |
| 578 | + if (!founded) { |
| 579 | + if (function.return_type == function.type_parameters[j].type) { |
| 580 | + name += return_type.to_str(); |
| 581 | + } |
| 582 | + } |
| 583 | + |
| 584 | + if (j + 1 != function.type_parameters.size()) { |
| 585 | + name += ", "; |
| 586 | + } |
| 587 | + } |
| 588 | + name += "]"; |
| 589 | + return name; |
| 590 | + } |
| 591 | + else { |
| 592 | + return name; |
522 | 593 | } |
523 | | - return name + "_" + return_type.to_str(); |
524 | 594 | } |
525 | 595 |
|
526 | 596 |
|
@@ -825,7 +895,11 @@ void codegen::Context::store_array_elements(ast::Node* expression, llvm::Value* |
825 | 895 | } |
826 | 896 | else if (expression->index() == ast::Identifier) { |
827 | 897 | auto& identifier = std::get<ast::IdentifierNode>(*expression); |
828 | | - this->builder->CreateMemCpy(array_allocation, llvm::MaybeAlign(), this->get_binding(identifier.value).pointer, llvm::MaybeAlign(), this->get_type_size(array_type)); |
| 898 | + llvm::Value* array_pointer = this->get_binding(identifier.value).pointer; |
| 899 | + if (((llvm::AllocaInst*) array_pointer)->getAllocatedType()->isPointerTy()) { |
| 900 | + array_pointer = this->builder->CreateLoad(array_pointer->getType(), array_pointer); |
| 901 | + } |
| 902 | + this->builder->CreateMemCpy(array_allocation, llvm::MaybeAlign(), array_pointer, llvm::MaybeAlign(), this->get_type_size(array_type)); |
829 | 903 | } |
830 | 904 | else { |
831 | 905 | assert(false); |
@@ -873,7 +947,7 @@ llvm::Value* codegen::Context::get_index_access_pointer(ast::CallNode& node) { |
873 | 947 | return this->builder->CreateGEP(array_type, array_ptr, {llvm::ConstantInt::get(*(this->context), llvm::APInt(64, 0, true)), index}, "", true); |
874 | 948 | } |
875 | 949 | else { |
876 | | - llvm::Type* wrapper_type = this->as_llvm_type(ast::get_concrete_type(node.args[0]->expression, this->type_bindings)); |
| 950 | + llvm::Type* wrapper_type = llvm::StructType::getTypeByName(*this->context, "arrayWrapper"); |
877 | 951 | llvm::Value* wrapper_ptr = this->get_binding(std::get<ast::IdentifierNode>(*node.args[0]->expression).value).pointer; |
878 | 952 | if (((llvm::AllocaInst*) wrapper_ptr)->getAllocatedType()->isPointerTy()) { |
879 | 953 | wrapper_ptr = this->builder->CreateLoad( |
@@ -1026,7 +1100,12 @@ void codegen::Context::codegen(ast::Ast& ast) { |
1026 | 1100 |
|
1027 | 1101 | // Codegen functions |
1028 | 1102 | for (auto it = ast.modules.begin(); it != ast.modules.end(); it++) { |
| 1103 | + this->current_module = it->first; |
| 1104 | + this->add_scope(*it->second); |
1029 | 1105 | this->codegen_function_prototypes(it->second->functions); |
| 1106 | + this->scopes.variable_scopes = {}; |
| 1107 | + this->scopes.functions_and_types_scopes.scopes = {}; |
| 1108 | + this->current_module = ast.module_path; |
1030 | 1109 | } |
1031 | 1110 | for (auto it = ast.modules.begin(); it != ast.modules.end(); it++) { |
1032 | 1111 | this->current_module = it->first; |
|
0 commit comments