88#include " ../codegen.hpp"
99#include " codegen.hpp"
1010#include " ../utilities.hpp"
11+ #include " ../semantic/intrinsics.hpp"
1112
1213// Print LLVM IR
1314// -------------
@@ -160,10 +161,10 @@ static void link(std::string executable_name, std::string object_file_name, std:
160161 " lld" ,
161162 object_file_name,
162163 name,
163- utilities::get_folder_of_executable () + " /deps/musl/libc.a" ,
164- utilities::get_folder_of_executable () + " /deps/musl/crt1.o" ,
165- utilities::get_folder_of_executable () + " /deps/musl/crti.o" ,
166- utilities::get_folder_of_executable () + " /deps/musl/crtn.o"
164+ utilities::get_folder_of_executable (). string () + " /deps/musl/libc.a" ,
165+ utilities::get_folder_of_executable (). string () + " /deps/musl/crt1.o" ,
166+ utilities::get_folder_of_executable (). string () + " /deps/musl/crti.o" ,
167+ utilities::get_folder_of_executable (). string () + " /deps/musl/crtn.o"
167168 };
168169
169170 std::string output = " " ;
@@ -353,10 +354,11 @@ static void link(std::string executable_name, std::string object_file_name, std:
353354// Constructor
354355codegen::Context::Context (ast::Ast& ast) : ast(ast) {
355356 this ->current_module = ast.module_path ;
357+ auto filename = ast.module_path .filename ().string ();
356358
357359 // Create llvm context
358360 this ->context = new llvm::LLVMContext ();
359- this ->module = new llvm::Module (" My cool jit " , *(this ->context ));
361+ this ->module = new llvm::Module (filename , *(this ->context ));
360362 this ->builder = new llvm::IRBuilder (*(this ->context ));
361363
362364 // Add function pass optimizations
@@ -507,19 +509,88 @@ codegen::Context::Binding codegen::Context::get_binding(std::string identifier)
507509
508510// Name mangling
509511std::string codegen::Context::get_mangled_type_name (std::filesystem::path module , std::string identifier) {
510- 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;
511525}
512526
513527std::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) {
514528 if (is_extern) {
515529 return identifier;
516530 }
517531
518- std::string name = module .string () + " ::" + identifier;
519- for (size_t i = 0 ; i < args.size (); i++) {
520- 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;
521593 }
522- return name + " _" + return_type.to_str ();
523594}
524595
525596
@@ -824,7 +895,11 @@ void codegen::Context::store_array_elements(ast::Node* expression, llvm::Value*
824895 }
825896 else if (expression->index () == ast::Identifier) {
826897 auto & identifier = std::get<ast::IdentifierNode>(*expression);
827- 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));
828903 }
829904 else {
830905 assert (false );
@@ -872,7 +947,7 @@ llvm::Value* codegen::Context::get_index_access_pointer(ast::CallNode& node) {
872947 return this ->builder ->CreateGEP (array_type, array_ptr, {llvm::ConstantInt::get (*(this ->context ), llvm::APInt (64 , 0 , true )), index}, " " , true );
873948 }
874949 else {
875- 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 " );
876951 llvm::Value* wrapper_ptr = this ->get_binding (std::get<ast::IdentifierNode>(*node.args [0 ]->expression ).value ).pointer ;
877952 if (((llvm::AllocaInst*) wrapper_ptr)->getAllocatedType ()->isPointerTy ()) {
878953 wrapper_ptr = this ->builder ->CreateLoad (
@@ -1025,7 +1100,12 @@ void codegen::Context::codegen(ast::Ast& ast) {
10251100
10261101 // Codegen functions
10271102 for (auto it = ast.modules .begin (); it != ast.modules .end (); it++) {
1103+ this ->current_module = it->first ;
1104+ this ->add_scope (*it->second );
10281105 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 ;
10291109 }
10301110 for (auto it = ast.modules .begin (); it != ast.modules .end (); it++) {
10311111 this ->current_module = it->first ;
@@ -1747,7 +1827,7 @@ llvm::Value* codegen::Context::codegen_print_struct_function(ast::Type arg_type,
17471827 );
17481828 }
17491829 else {
1750- std::string print_function_name = this ->get_mangled_function_name (utilities::get_folder_of_executable () + " /std/std" + " .dmd" , " printWithoutLineEnding" , {struct_type.as_nominal_type ().type_definition ->fields [i]->type }, ast::Type (" None" ), false );
1830+ std::string print_function_name = this ->get_mangled_function_name (utilities::get_folder_of_executable (). string () + " /std/std" + " .dmd" , " printWithoutLineEnding" , {struct_type.as_nominal_type ().type_definition ->fields [i]->type }, ast::Type (" None" ), false );
17511831 llvm::Function* llvm_function = this ->module ->getFunction (print_function_name);
17521832 assert (llvm_function);
17531833
@@ -1800,74 +1880,74 @@ llvm::Value* codegen::Context::codegen_call(ast::CallNode& node, std::optional<l
18001880
18011881 // Intrinsics
18021882 if (node.args .size () == 2 ) {
1803- if (node.identifier ->value == " add " ) {
1883+ if (node.identifier ->value == " + " ) {
18041884 if (args[0 ]->getType ()->isDoubleTy () && args[1 ]->getType ()->isDoubleTy ()) {
18051885 return this ->builder ->CreateFAdd (args[0 ], args[1 ], " addtmp" );
18061886 }
18071887 if (args[0 ]->getType ()->isIntegerTy () && args[1 ]->getType ()->isIntegerTy ()) {
18081888 return this ->builder ->CreateAdd (args[0 ], args[1 ], " addtmp" );
18091889 }
18101890 }
1811- if (node.identifier ->value == " subtract " ) {
1891+ if (node.identifier ->value == " - " ) {
18121892 if (args[0 ]->getType ()->isDoubleTy () && args[1 ]->getType ()->isDoubleTy ()) {
18131893 return this ->builder ->CreateFSub (args[0 ], args[1 ], " subtmp" );
18141894 }
18151895 if (args[0 ]->getType ()->isIntegerTy () && args[1 ]->getType ()->isIntegerTy ()) {
18161896 return this ->builder ->CreateSub (args[0 ], args[1 ], " addtmp" );
18171897 }
18181898 }
1819- if (node.identifier ->value == " multiply " ) {
1899+ if (node.identifier ->value == " * " ) {
18201900 if (args[0 ]->getType ()->isDoubleTy () && args[1 ]->getType ()->isDoubleTy ()) {
18211901 return this ->builder ->CreateFMul (args[0 ], args[1 ], " multmp" );
18221902 }
18231903 if (args[0 ]->getType ()->isIntegerTy () && args[1 ]->getType ()->isIntegerTy ()) {
18241904 return this ->builder ->CreateMul (args[0 ], args[1 ], " addtmp" );
18251905 }
18261906 }
1827- if (node.identifier ->value == " divide " ) {
1907+ if (node.identifier ->value == " / " ) {
18281908 if (args[0 ]->getType ()->isDoubleTy () && args[1 ]->getType ()->isDoubleTy ()) {
18291909 return this ->builder ->CreateFDiv (args[0 ], args[1 ], " divtmp" );
18301910 }
18311911 if (args[0 ]->getType ()->isIntegerTy () && args[1 ]->getType ()->isIntegerTy ()) {
18321912 return this ->builder ->CreateSDiv (args[0 ], args[1 ], " divtmp" );
18331913 }
18341914 }
1835- if (node.identifier ->value == " modulo " ) {
1915+ if (node.identifier ->value == " % " ) {
18361916 return this ->builder ->CreateSRem (args[0 ], args[1 ], " remtmp" );
18371917 }
1838- if (node.identifier ->value == " less " ) {
1918+ if (node.identifier ->value == " < " ) {
18391919 if (args[0 ]->getType ()->isDoubleTy () && args[1 ]->getType ()->isDoubleTy ()) {
18401920 return this ->builder ->CreateFCmpULT (args[0 ], args[1 ], " cmptmp" );
18411921 }
18421922 if (args[0 ]->getType ()->isIntegerTy () && args[1 ]->getType ()->isIntegerTy ()) {
18431923 return this ->builder ->CreateICmpULT (args[0 ], args[1 ], " addtmp" );
18441924 }
18451925 }
1846- if (node.identifier ->value == " lessEqual " ) {
1926+ if (node.identifier ->value == " <= " ) {
18471927 if (args[0 ]->getType ()->isDoubleTy () && args[1 ]->getType ()->isDoubleTy ()) {
18481928 return this ->builder ->CreateFCmpULE (args[0 ], args[1 ], " cmptmp" );
18491929 }
18501930 if (args[0 ]->getType ()->isIntegerTy () && args[1 ]->getType ()->isIntegerTy ()) {
18511931 return this ->builder ->CreateICmpULE (args[0 ], args[1 ], " addtmp" );
18521932 }
18531933 }
1854- if (node.identifier ->value == " greater " ) {
1934+ if (node.identifier ->value == " > " ) {
18551935 if (args[0 ]->getType ()->isDoubleTy () && args[1 ]->getType ()->isDoubleTy ()) {
18561936 return this ->builder ->CreateFCmpUGT (args[0 ], args[1 ], " cmptmp" );
18571937 }
18581938 if (args[0 ]->getType ()->isIntegerTy () && args[1 ]->getType ()->isIntegerTy ()) {
18591939 return this ->builder ->CreateICmpUGT (args[0 ], args[1 ], " addtmp" );
18601940 }
18611941 }
1862- if (node.identifier ->value == " greaterEqual " ) {
1942+ if (node.identifier ->value == " >= " ) {
18631943 if (args[0 ]->getType ()->isDoubleTy () && args[1 ]->getType ()->isDoubleTy ()) {
18641944 return this ->builder ->CreateFCmpUGE (args[0 ], args[1 ], " cmptmp" );
18651945 }
18661946 if (args[0 ]->getType ()->isIntegerTy () && args[1 ]->getType ()->isIntegerTy ()) {
18671947 return this ->builder ->CreateICmpUGE (args[0 ], args[1 ], " addtmp" );
18681948 }
18691949 }
1870- if (node.identifier ->value == " equal " ) {
1950+ if (node.identifier ->value == " == " ) {
18711951 if (args[0 ]->getType ()->isDoubleTy () && args[1 ]->getType ()->isDoubleTy ()) {
18721952 return this ->builder ->CreateFCmpUEQ (args[0 ], args[1 ], " eqtmp" );
18731953 }
@@ -1883,7 +1963,7 @@ llvm::Value* codegen::Context::codegen_call(ast::CallNode& node, std::optional<l
18831963 }
18841964 }
18851965 if (node.args .size () == 1 ) {
1886- if (node.identifier ->value == " negate " ) {
1966+ if (node.identifier ->value == " -[negation] " ) {
18871967 if (args[0 ]->getType ()->isDoubleTy ()) {
18881968 return this ->builder ->CreateFNeg (args[0 ], " negation" );
18891969 }
0 commit comments