Skip to content

Commit

Permalink
added compiler flags
Browse files Browse the repository at this point in the history
  • Loading branch information
Togira123 committed Aug 22, 2023
1 parent 6c4edbc commit 2b36354
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 20 deletions.
18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,20 @@ This will create an executable named `inslt`.

## Running

After compiling make sure you are in the `build` directory. Use `./inslt` to run the executable. It takes up to two arguments, the first one being the input file and the second one being an optional output name for the compiled program (defaults to `a.out`). For example you can run
After compiling make sure you are in the `build` directory. Use `./inslt` to run the executable. It takes one argument which is the name of the file to compile. For example you can run
```bash
./inslt ../tests/fibonacci.inslt my_output_file
./inslt ../tests/fibonacci.inslt
```
to compile the file `fibonacci.inslt` located in the `tests` directory and name the resulting file `my_output_file`. That file can now be run with `./my_output_file`.
to compile the file `fibonacci.inslt` located in the `tests` directory. The resulting file will have the default name `a.out`. That file can now be run with `./a.out`.

### Compiler flags

There are a few compiler flags which can be used to enable/disable certain features the compiler can offer. To use them just append them to the input file name, separated by spaces. Below is a list of all the currently available flags.

* __-optimize__

Using this flag will tell the compiler to perform some optimization steps in order to make the resulting executable run faster and use up less memory. Omitting this flag will **not** prevent the compiler from performing some minor changes to the input.

* __-out__ <*name*>

This flag can be used to set the name of the output file. This defaults to `a.out`. Set the name without the angle brackets.
2 changes: 1 addition & 1 deletion include/optimize.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#include "ir.h"

void optimize(intermediate_representation& ir);
void optimize(intermediate_representation& ir, bool should_optimize);
22 changes: 22 additions & 0 deletions include/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,25 @@ struct temp_expr_tree {
std::string last_assignment = "";
size_t last_assignment_ind = -1;
};

// flag is passed without the "-"
inline compiler_flag string_to_compiler_flag(const std::string& flag) {
static const std::unordered_map<std::string, compiler_flag> convert = {{"optimize", compiler_flag::OPTIMIZE},
{"optimise", compiler_flag::OPTIMIZE},
{"o", compiler_flag::OPTIMIZE},
{"output", compiler_flag::OUTPUT},
{"out", compiler_flag::OUTPUT}};
if (convert.count(flag) == 0) {
throw std::runtime_error("unknown compiler flag");
}
return convert.at(flag);
}

inline bool flag_requires_argument(compiler_flag flag) {
switch (flag) {
case compiler_flag::OUTPUT:
return true;
default:
return false;
}
}
3 changes: 2 additions & 1 deletion include/scanner.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "util.h"
#include <list>
#include <vector>

std::list<token>& scan_program(int argc, char* argv[]);
std::list<token>& scan_program(std::vector<std::string> args);
3 changes: 3 additions & 0 deletions include/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define HEADER_UTIL_H
#include "language.h"
#include <string>
#include <unordered_map>

// https://stackoverflow.com/a/25829233/14553195
inline std::string& ltrim(std::string& s) {
Expand All @@ -26,4 +27,6 @@ struct token {
token_type name;
std::string value;
};

enum class compiler_flag { OPTIMIZE, OUTPUT };
#endif
14 changes: 8 additions & 6 deletions src/optimize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ bool includes_function_call(intermediate_representation& ir, expression_tree& ro
return root.type == node_type::FUNCTION_CALL;
}

void rename_identifiers(identifier_scopes& scope) {
void rename_identifiers(identifier_scopes& scope, const bool should_optimize) {
static auto& ir = *scope.get_ir();
static std::unordered_map<identifier_scopes*, std::unordered_map<std::string, std::vector<std::pair<int, int>>>> new_names_assignment;
// for each identifier rename it and also rename all references
Expand Down Expand Up @@ -261,7 +261,7 @@ void rename_identifiers(identifier_scopes& scope) {
// keep parameters
references_besides_definition++;
}
if (references_besides_definition == 0) {
if (references_besides_definition == 0 && should_optimize) {
for (auto& [order_scope, order_ind] : id.order_references) {
order_scope->order[order_ind].is_comment = true;
}
Expand All @@ -272,7 +272,7 @@ void rename_identifiers(identifier_scopes& scope) {
}
scope.assignments = std::move(new_names_assignment[&scope]);
for (auto& s : scope.get_lower()) {
rename_identifiers(s);
rename_identifiers(s, should_optimize);
}
scope.identifiers = std::move(new_names);
}
Expand Down Expand Up @@ -595,8 +595,10 @@ void constant_folding(intermediate_representation& ir) {
}
}

void optimize(intermediate_representation& ir) {
void optimize(intermediate_representation& ir, bool should_optimize) {
// rename all identifiers
rename_identifiers(ir.scopes);
constant_folding(ir);
rename_identifiers(ir.scopes, should_optimize);
if (should_optimize) {
constant_folding(ir);
}
}
42 changes: 36 additions & 6 deletions src/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1223,6 +1223,37 @@ bool program() {
}

int main(int argc, char* argv[]) {
std::unordered_map<compiler_flag, std::string> flags;
std::vector<std::string> non_flag_arguments = {argv[0]};
// set to optimize as this doesn't require any arguments
compiler_flag last_flag = compiler_flag::OPTIMIZE;
for (int i = 1; i < argc; i++) {
if (*argv[i] == '-') {
try {
if (flag_requires_argument(last_flag)) {
throw std::runtime_error("flag \"" + std::string(argv[i - 1] + 1) + "\" expected argument");
}
auto flag = string_to_compiler_flag(argv[i] + 1);
flags[std::move(flag)] = "";
last_flag = flag;
} catch (std::runtime_error& e) {
std::cerr << e.what() << std::endl;
return 1;
}
} else {
if (flag_requires_argument(last_flag)) {
flags[last_flag] = argv[i];
// set to optimize as this doesn't require any arguments
last_flag = compiler_flag::OPTIMIZE;
} else {
non_flag_arguments.push_back(argv[i]);
}
}
}
if (flag_requires_argument(last_flag)) {
std::cerr << "flag \"" + std::string(argv[argc - 1] + 1) + "\" expected argument" << std::endl;
return 1;
}
std::string tmp_file = "";
std::srand(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count());
do {
Expand All @@ -1231,12 +1262,12 @@ int main(int argc, char* argv[]) {
} while (std::filesystem::exists(tmp_file));
std::ofstream outstream(tmp_file);
std::string output_file = "a.out";
if (argc >= 3) {
output_file = argv[2];
if (flags.count(compiler_flag::OUTPUT)) {
output_file = flags[compiler_flag::OUTPUT];
}
std::list<token> token_list;
try {
token_list = scan_program(argc, argv);
token_list = scan_program(non_flag_arguments);
} catch (std::runtime_error& e) {
if (std::string(e.what()) == "Specify program to compile!" || std::string(e.what()) == "There was an error trying to compile the file!") {
std::cerr << e.what() << std::endl;
Expand Down Expand Up @@ -1272,7 +1303,7 @@ int main(int argc, char* argv[]) {
std::filesystem::remove(tmp_file);
return 0;
}
optimize(ir);
optimize(ir, flags.count(compiler_flag::OPTIMIZE));
// check_ir(ir);
outstream << generate_code(ir);
} else {
Expand All @@ -1282,8 +1313,7 @@ int main(int argc, char* argv[]) {
outstream << get_random_program();
}
outstream.close();
// TODO: add "-w" flag which supresses all warnings
if (std::system(("g++ -Wall -o " + output_file + " -D_GLIBCXX_DEBUG -x c++ -std=c++17 " + tmp_file).c_str()) != 0) {
if (std::system(("g++ -w -o " + output_file + " -D_GLIBCXX_DEBUG -x c++ -std=c++17 " + tmp_file).c_str()) != 0) {
std::filesystem::remove(tmp_file);
throw std::runtime_error("gcc is required on your system to compile this program");
}
Expand Down
6 changes: 3 additions & 3 deletions src/scanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,11 +379,11 @@ std::string punctuation(std::vector<char>& buffer, int& index) {
}
}

std::list<token>& scan_program(int argc, char* argv[]) {
if (argc < 2) {
std::list<token>& scan_program(std::vector<std::string> args) {
if (args.size() < 2) {
throw std::runtime_error("Specify program to compile!");
}
file = std::ifstream(argv[1]);
file = std::ifstream(args[1]);
if (!file.good()) {
file.close();
throw std::runtime_error("There was an error trying to compile the file!");
Expand Down

0 comments on commit 2b36354

Please sign in to comment.