diff --git a/IR-Generator/src/Generator.cpp b/IR-Generator/src/Generator.cpp index 46d1911..abde1e0 100644 --- a/IR-Generator/src/Generator.cpp +++ b/IR-Generator/src/Generator.cpp @@ -4,6 +4,8 @@ #include #include +#include + #include #include #include @@ -35,7 +37,7 @@ namespace LX } } -extern "C" int __declspec(dllexport) GenIR(const char* arg1, const char* arg2, const char* arg3) +extern "C" int __declspec(dllexport) GenIR(const char* a_inpPath, const char* a_outPath, const char* a_logPath) { // Creates the file paths outside of the try-catch so they can be used in errors // std::filesystem::path inpPath; @@ -52,8 +54,8 @@ extern "C" int __declspec(dllexport) GenIR(const char* arg1, const char* arg2, c try { // Turns the file paths into the C++ type for handling them // - inpPath = arg1; - outPath = arg2; + inpPath = a_inpPath; + outPath = a_outPath; // Checks the input file exists and opens it // LX::ThrowIf(std::filesystem::exists(inpPath) == false); @@ -72,9 +74,9 @@ extern "C" int __declspec(dllexport) GenIR(const char* arg1, const char* arg2, c outFile.close(); // Opened just to check we can // Opens the log file (if there is one specified // - if (arg3 != nullptr) + if (a_logPath != nullptr) { - logPath = arg3; + logPath = a_logPath; log = std::make_unique(logPath); LX::ThrowIf(log->is_open() == false); } @@ -85,14 +87,17 @@ extern "C" int __declspec(dllexport) GenIR(const char* arg1, const char* arg2, c // Create tokens out of the input file // std::vectortokens = LX::LexicalAnalyze(contents, len, log.get()); LX::SafeFlush(log.get()); + std::cout << "\t|- Created tokens" << std::endl; // Turns the tokens into an AST // LX::FileAST AST = LX::TurnTokensIntoAbstractSyntaxTree(tokens, log.get()); LX::SafeFlush(log.get()); + std::cout << "\t|- Created AST" << std::endl; // Turns the AST into LLVM IR // LX::GenerateIR(AST, inpPath.filename().string(), outPath); LX::SafeFlush(log.get()); + std::cout << "\t|- Generated LLVM IR" << std::endl; // Returns success return 0; @@ -202,19 +207,67 @@ extern "C" int __declspec(dllexport) GenIR(const char* arg1, const char* arg2, c return 6; } + catch (LX::Scope::VariableAlreadyExists) + { + std::cout << "Tried to create a variable that already exists\n"; + + return 7; + } + + catch (LX::Scope::VariableDoesntExist) + { + std::cout << "Tried to access a variable that doesn't exist\n"; + + return 8; + } + // Catches any std errors, there should be none // catch (std::exception& e) { + // Closes the log if it is open to get as much info as possible // + if (log != nullptr) { log->close(); } + // Prints the std exception to the console // // Any errors here are problems with the code // + std::cout << "An error occured. Please report this on the github page.\n" << std::endl; std::cout << e.what() << std::endl; + + // Exit code -1 means an undefined error // + return -1; + } + + // Catches any LLVM errors, there should be none // + catch (llvm::Error& e) + { + // Closes the log if it is open to get as much info as possible // + if (log != nullptr) { log->close(); } + + // Prints the LLVM error to the console // + std::cout << "A LLVM error occured. Please report this on the github page.\n" << std::endl; + + // Exit code -1 means an undefined error // + return -1; + } + + // Catches errors that i was too lazy to code // + catch (int) + { + // Closes the log if it is open to get as much info as possible // + if (log != nullptr) { log->close(); } + + std::cout << "An placeholder error occured. Maybe use a language that wasn't coded by a lazy person.\n" << std::endl; + + // Exit code -1 means an undefined error // + return -1; } // Default catches any non-specified errors // - catch (...) {} + catch (...) + { + // Closes the log if it is open to get as much info as possible // + if (log != nullptr) { log->close(); } - // Closes the log if it is open to get as much info as possible // - if (log != nullptr) { log->close(); } - std::cout << "An unknown error occured. Please report this on the github page.\n"; - return -1; // -1 exit code means an unknown error + // Exit code -1 means an undefined error // + return -1; + } } diff --git a/LX-Build/Main.cs b/LX-Build/Main.cs index 19ea274..28d6791 100644 --- a/LX-Build/Main.cs +++ b/LX-Build/Main.cs @@ -1,5 +1,5 @@ using System; -using System.Diagnostics; +using System.ComponentModel; namespace LX_Build { @@ -45,7 +45,13 @@ namespace LX_Build LX_API.Init(); // Generates LLVM IR with the example files // - _ = LX_API.GenIR("example/main.lx", "example/main.ll", "example/log"); + int genExitCode = LX_API.GenIR("example/main.lx", "example/main.ll", "example/log"); + if (genExitCode != 0) + { + Console.WriteLine("An error occured whilst generating LLVM IR"); + Console.WriteLine($"Error code: {genExitCode}"); + return; + } // Compilers the LLVM IR to an object file using the command line // CompileToObj("example/main.ll", "example/main.obj"); diff --git a/LX-Build/Properties/launchSettings.json b/LX-Build/Properties/launchSettings.json index 6e52371..806a62b 100644 --- a/LX-Build/Properties/launchSettings.json +++ b/LX-Build/Properties/launchSettings.json @@ -2,7 +2,8 @@ "profiles": { "LX-Build": { "commandName": "Project", - "workingDirectory": "$(SolutionDir)" + "workingDirectory": "$(SolutionDir)", + "nativeDebugging": true } } } \ No newline at end of file diff --git a/Parser/src/GenIR.cpp b/Parser/src/GenIR.cpp index 053b439..93ca827 100644 --- a/Parser/src/GenIR.cpp +++ b/Parser/src/GenIR.cpp @@ -55,6 +55,8 @@ namespace LX // Loops over the functions to generate their LLVM IR // for (auto& func : ast.functions) { + std::cout << "\t|\t|- Generating function: " << func.name << "\n"; + LLVM.scope = &func.scope; // Sets the current scope for the builder GenerateFunctionIR(func, LLVM); } diff --git a/README.md b/README.md index 1fa9995..b6de6f6 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,25 @@ This is my custom compiled language written in C++ based off of the LLVM toolchain. Do not use the language in it's current state unless you are insane. -### Planned features +### Planned features (in order) - Operations (Maths + BinOp) - Functions - More than just int as a type - References / Pointers - Structs / Classes (Polymorphism + vtables) -### Stuff I want to do later +### Codebase +- Errors + - Inherit from a common class + - All simple errors (no members) use the same type + - ThrowIf Requires an error class + - No temporary throw int; +- Logging + - Less templates + - Standard for formatting + - Choose what is logged + +### Stuff I want to do later (unordered) - I/O manager (Console, Files) - Debugger support - Extensions for vscode / vs22 @@ -17,17 +28,18 @@ This is my custom compiled language written in C++ based off of the LLVM toolcha - SSA (Static single assignment) - LX-Core (Basic Standard Lib) - SIMD (Single instruction, multiple data) -- Built in features for multi-language code (C, C++, C#, Rust...) +- Built in features for multi-language codebases (C, C++, C#, Rust...) - Custom Linker written in rust - Package manager -- Custom optimiser (+ O3 in Clang) +- Custom optimiser (as well O3 in Clang) - Complicated LX-Core: - Graphics APIs support - Networking support - WinAPI compatiability -### Stuff I might do later +### Stuff I might do later (but probably won't) - JIT (Just in time compiler) / Interpreter - Different compiler backends - Python support - Non-windows OS support +- Database support diff --git a/example/main.lx b/example/main.lx index a505872..41ab27f 100644 --- a/example/main.lx +++ b/example/main.lx @@ -1,3 +1,8 @@ +func add(int a, int b) +{ + return a + b +} + func main() { int a