Skip to content

Commit 982699a

Browse files
authored
Merge pull request #111 from diamond-lang/operator-identifiers
Improvements to the compiler
2 parents 3ca2a52 + 0c32d03 commit 982699a

File tree

16 files changed

+329
-169
lines changed

16 files changed

+329
-169
lines changed

src/codegen/codegen.cpp

Lines changed: 104 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
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
354355
codegen::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
509511
std::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

513527
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) {
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
}

src/errors.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ std::string errors::usage() {
3838
" --ast-with-types\n"
3939
" --ast-with-concrete-types\n"
4040
" --llvm-ir\n"
41-
" --obj\n";
41+
" --assembly\n"
42+
" --object-code\n";
4243
}
4344

4445
std::string errors::generic_error(Location location, std::string message) {

src/main.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ void check_usage(int argc, char *argv[]) {
5151
if (argv[1] == std::string("run") && argc < 3) {
5252
print_usage_and_exit();
5353
}
54-
if (argv[1] == std::string("emit") && (argc < 4 || !(argv[2] == std::string("--llvm-ir") || argv[2] == std::string("--ast") || argv[2] == std::string("--ast-with-types") || argv[2] == std::string("--ast-with-concrete-types") || argv[2] == std::string("--tokens") || argv[2] == std::string("--obj") || argv[2] == std::string("--asm")))) {
54+
if (argv[1] == std::string("emit") && (argc < 4 || !(argv[2] == std::string("--llvm-ir") || argv[2] == std::string("--ast") || argv[2] == std::string("--ast-with-types") || argv[2] == std::string("--ast-with-concrete-types") || argv[2] == std::string("--tokens") || argv[2] == std::string("--object-code") || argv[2] == std::string("--assembly")))) {
5555
print_usage_and_exit();
5656
}
5757
};
@@ -189,14 +189,14 @@ void emit(Command command) {
189189
}
190190

191191
// Emit asm
192-
if (command.options[0] == std::string("--asm")) {
192+
if (command.options[0] == std::string("--assembly")) {
193193
codegen::print_assembly(ast, program_name);
194194
ast.free();
195195
return;
196196
}
197197

198198
// Emit object code
199-
if (command.options[0] == std::string("--obj")) {
199+
if (command.options[0] == std::string("--object-code")) {
200200
codegen::generate_object_code(ast, program_name);
201201
ast.free();
202202
return;

0 commit comments

Comments
 (0)