-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Added driver class to be used by other projects (server wink wink)
- Loading branch information
1 parent
6c47745
commit 6d1be42
Showing
5 changed files
with
157 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
#include "Driver.h" | ||
|
||
#include "plf_nanotimer.h" | ||
|
||
using namespace lesma; | ||
|
||
#define TIMEIT(debug_operation, statements) \ | ||
timer.start(); \ | ||
statements \ | ||
results = timer.get_elapsed_ms(); \ | ||
total += results; \ | ||
if (options->timer) \ | ||
print(DEBUG, "{} -> {:.2f} ms\n", debug_operation, results); | ||
|
||
|
||
int Driver::BaseCompile(Options *options, bool jit) { | ||
// Configure Timer | ||
plf::nanotimer timer; | ||
double results, total = 0; | ||
|
||
// Configure Source Manager | ||
std::shared_ptr<llvm::SourceMgr> srcMgr = std::make_shared<llvm::SourceMgr>(llvm::SourceMgr()); | ||
|
||
try { | ||
// Read Source | ||
TIMEIT("File read", | ||
if (options->sourceType == SourceType::FILE) { | ||
auto buffer = llvm::MemoryBuffer::getFile(options->source); | ||
if (buffer.getError() != std::error_code()) throw LesmaError(llvm::SMRange(), "Could not read file: {}", options->source); | ||
|
||
srcMgr->AddNewSourceBuffer(std::move(*buffer), llvm::SMLoc()); | ||
} | ||
else { | ||
auto buffer = llvm::MemoryBuffer::getMemBuffer(options->source); | ||
srcMgr->AddNewSourceBuffer(std::move(buffer), llvm::SMLoc()); | ||
}) | ||
|
||
// Lexer | ||
TIMEIT("Lexer scan", | ||
auto lexer = std::make_unique<Lexer>(srcMgr); | ||
lexer->ScanAll();) | ||
|
||
if (options->debug & LEXER) { | ||
print(DEBUG, "TOKENS: \n"); | ||
for (const auto &tok: lexer->getTokens()) | ||
print("Token: {}\n", tok->Dump(srcMgr)); | ||
} | ||
|
||
// Parser | ||
TIMEIT("Parsing", | ||
auto parser = std::make_unique<Parser>(lexer->getTokens()); | ||
parser->Parse();) | ||
|
||
if (options->debug & AST) | ||
print(DEBUG, "AST:\n{}", parser->getAST()->toString(srcMgr.get(), "", true)); | ||
|
||
// Codegen | ||
TIMEIT("Compiling", | ||
std::vector<std::string> modules; | ||
auto codegen = std::make_unique<Codegen>(std::move(parser), srcMgr, | ||
options->sourceType == FILE ? options->source : ".", | ||
modules, jit, true); | ||
codegen->Run();) | ||
|
||
if (options->debug & IR) { | ||
print(DEBUG, "LLVM IR: \n"); | ||
codegen->Dump(); | ||
} | ||
|
||
// Optimization | ||
TIMEIT("Optimizing", codegen->Optimize(llvm::PassBuilder::OptimizationLevel::O3);) | ||
|
||
int exit_code = 0; | ||
if (!jit) { | ||
// Compile to Object File | ||
TIMEIT("Writing Object File", codegen->WriteToObjectFile(options->output_filename);) | ||
|
||
// Link Object File | ||
TIMEIT("Linking Object File", codegen->LinkObjectFile(fmt::format("{}.o", options->output_filename));) | ||
} else { | ||
// Executing | ||
TIMEIT("Execution", exit_code = codegen->JIT();) | ||
} | ||
|
||
if (options->timer) | ||
print(DEBUG, "Total -> {:.2f} ms\n", total); | ||
|
||
return exit_code; | ||
} catch (const LesmaError &err) { | ||
if (!err.getSpan().isValid()) | ||
print(ERROR, err.what()); | ||
else | ||
showInline(srcMgr.get(), err.getSpan(), err.what(), options->source, true); | ||
return err.exit_code; | ||
} | ||
} | ||
|
||
int Driver::Run(lesma::Options *options) { | ||
return BaseCompile(options, true); | ||
} | ||
|
||
int Driver::Compile(Options *options) { | ||
return BaseCompile(options, false); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#pragma once | ||
|
||
#include <string> | ||
#include <vector> | ||
|
||
#include "liblesma/Backend/Codegen.h" | ||
#include "liblesma/Frontend/Lexer.h" | ||
#include "liblesma/Frontend/Parser.h" | ||
#include "liblesma/Common/Utils.h" | ||
|
||
#include "llvm/Support/SourceMgr.h" | ||
|
||
namespace lesma { | ||
enum SourceType { | ||
FILE, | ||
STRING, | ||
}; | ||
|
||
enum Debug { | ||
NONE = 0x00, // 00000000 | ||
LEXER = 0x01, // 00000001 | ||
AST = 0x02, // 00000010 | ||
IR = 0x04, // 00000100 | ||
}; | ||
|
||
struct Options { | ||
SourceType sourceType; | ||
std::string source; | ||
Debug debug = NONE; | ||
std::string output_filename = "output"; | ||
bool timer = false; | ||
}; | ||
|
||
class Driver { | ||
private: | ||
static int BaseCompile(Options *options, bool jit); | ||
public: | ||
static int Run(Options *options); | ||
static int Compile(Options *options); | ||
}; | ||
} |