Skip to content

Commit da5e24e

Browse files
committed
Parse arguments to configure debug
1 parent d61d287 commit da5e24e

6 files changed

Lines changed: 144 additions & 22 deletions

File tree

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#include "ArgumentsParser.h"
2+
#include <iostream>
3+
4+
ArgumentsParser::ArgumentsParser(int argc, char** argv)
5+
: arguments{}, flags{}, options{}, success{true}, program{} {
6+
if (argc > 0) {
7+
program = std::string(argv[0]);
8+
}
9+
10+
for (int i = 1; i < argc; ++i) {
11+
const auto& arg = std::string(argv[i]);
12+
// std::string::starts_with is C++20, so we implement it manually
13+
if (arg.size() >= 2 && arg[0] == '-' && arg[1] == '-') {
14+
auto eqPos = arg.find('=');
15+
if (eqPos != std::string::npos) {
16+
auto key = arg.substr(2, eqPos - 2);
17+
auto value = arg.substr(eqPos + 1);
18+
if (options.find(key) != options.end()) {
19+
std::cerr << "Warning: Option '" << key << "' set multiple times"
20+
<< std::endl;
21+
success = false;
22+
return;
23+
} else {
24+
options.emplace(key, value);
25+
}
26+
} else {
27+
auto key = arg.substr(2);
28+
flags.insert(key);
29+
}
30+
} else {
31+
arguments.push_back(arg);
32+
}
33+
}
34+
}
35+
36+
bool ArgumentsParser::isSuccess() const {
37+
return success;
38+
}
39+
40+
const std::vector<std::string>& ArgumentsParser::getArguments() const {
41+
return arguments;
42+
}
43+
44+
const std::set<std::string>& ArgumentsParser::getFlags() const {
45+
return flags;
46+
}
47+
48+
const std::map<std::string, std::string>& ArgumentsParser::getOptions() const {
49+
return options;
50+
}
51+
52+
const std::string& ArgumentsParser::getProgram() const {
53+
return program;
54+
}
55+
56+
bool ArgumentsParser::hasFlag(const std::string& flag) const {
57+
return flags.find(flag) != flags.end();
58+
}
59+
60+
std::string ArgumentsParser::getOption(const std::string& option,
61+
const std::string& defaultValue) const {
62+
auto it = options.find(option);
63+
if (it != options.end()) {
64+
return it->second;
65+
} else {
66+
return defaultValue;
67+
}
68+
}
69+
70+
const std::optional<std::string> ArgumentsParser::getArgument(size_t index) const {
71+
if (index < arguments.size()) {
72+
return arguments[index];
73+
} else {
74+
return std::nullopt;
75+
}
76+
}

src/application/ArgumentsParser.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#ifndef ARGUMENT_PARSER_H
2+
#define ARGUMENT_PARSER_H
3+
4+
#include <string>
5+
#include <vector>
6+
#include <set>
7+
#include <map>
8+
#include <optional>
9+
10+
class ArgumentsParser {
11+
public:
12+
ArgumentsParser(int argc, char** argv);
13+
14+
bool isSuccess() const;
15+
const std::vector<std::string>& getArguments() const;
16+
const std::set<std::string>& getFlags() const;
17+
const std::map<std::string, std::string>& getOptions() const;
18+
const std::string& getProgram() const;
19+
20+
bool hasFlag(const std::string& flag) const;
21+
std::string getOption(const std::string& option,
22+
const std::string& defaultValue = "") const;
23+
const std::optional<std::string> getArgument(size_t index) const;
24+
private:
25+
std::vector<std::string> arguments;
26+
std::set<std::string> flags;
27+
std::map<std::string, std::string> options;
28+
bool success;
29+
std::string program;
30+
};
31+
32+
#endif // ARGUMENT_PARSER_H

src/core/Mlang.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,15 @@ Mlang::Result Mlang::execute(const std::string& theFile,
3838
const std::string& theCode) {
3939
Tokenizer tokenizer(theFile, theCode);
4040

41+
std::cout << "Tokens:" << std::endl;
4142
auto tokens = tokenizer.getTokens();
4243
if (settings.showTokens) {
4344
for (auto token : tokens) {
4445
std::cout << token << " ";
4546
}
4647
std::cout << std::endl;
4748
}
49+
std::cout << std::endl;
4850

4951
Parser parser(std::move(tokens));
5052
auto ast = parser.getAst();
@@ -55,8 +57,9 @@ Mlang::Result Mlang::execute(const std::string& theFile,
5557
.addError(parser.getError(theCode));
5658
}
5759

58-
if (settings.showAbastractSyntaxTree) {
59-
std::cout << ast->toString() << std::endl;
60+
if (settings.showAbstractSyntaxTree) {
61+
std::cout << "Abstract Syntax Tree:" << std::endl;
62+
std::cout << ast->toString() << std::endl << std::endl;
6063
}
6164

6265
{
@@ -90,7 +93,7 @@ Mlang::Result Mlang::execute(const std::string& theFile,
9093

9194
if(settings.showTypeInference) {
9295
std::cout << "After InfereIdentifierTypes: " << std::endl;
93-
std::cout << ast->toString() << std::endl;
96+
std::cout << ast->toString() << std::endl << std::endl;
9497
}
9598

9699
// Function types / params
@@ -99,7 +102,7 @@ Mlang::Result Mlang::execute(const std::string& theFile,
99102

100103
if(settings.showTypeInference) {
101104
std::cout << "After InfereParameterTypes: " << std::endl;
102-
std::cout << ast->toString() << std::endl;
105+
std::cout << ast->toString() << std::endl << std::endl;
103106
}
104107

105108
validator.process(ast);
@@ -111,6 +114,9 @@ Mlang::Result Mlang::execute(const std::string& theFile,
111114
break;
112115
} else {
113116
lastUnresolved = validator.getNumUnresolved();
117+
if(settings.showTypeInference) {
118+
std::cout << "After round of type inference we have " << lastUnresolved << " unresolved types" << std::endl << std::endl;
119+
}
114120
validator.reset();
115121
}
116122
}
@@ -136,7 +142,7 @@ Mlang::Result Mlang::execute(const std::string& theFile,
136142
}
137143

138144
if (settings.showInferedTypes) {
139-
std::cout << ast->toString() << std::endl;
145+
std::cout << ast->toString() << std::endl << std::endl;
140146
}
141147
}
142148

src/core/Mlang.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class Mlang {
3939
bool showTokens = false;
4040
bool showFileContent = false;
4141
bool showResult = false;
42-
bool showAbastractSyntaxTree = false;
42+
bool showAbstractSyntaxTree = false;
4343
bool showInferedTypes = false;
4444
bool showFunctions = false;
4545
bool showEmission = false;

src/mains/MLang.cpp

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,37 @@
33

44
#include "../core/Mlang.h"
55
#include "../error/Exceptions.h"
6+
#include "../application/ArgumentsParser.h"
67

78
int main(int argc, char** argv) {
8-
if (argc != 2) {
9-
std::cout << "Expected 1 argument but got " << std::to_string(argc - 1)
10-
<< std::endl;
11-
return 2;
9+
ArgumentsParser args(argc, argv);
10+
if (!args.isSuccess()) {
11+
std::cerr << "Failed to parse arguments" << std::endl;
12+
return 1;
13+
}
14+
15+
const auto& scriptFileOpt = args.getArgument(0);
16+
if (!scriptFileOpt) {
17+
std::cerr << "No script file provided" << std::endl;
18+
return 1;
1219
}
1320

14-
std::string scriptFile(argv[1]);
21+
std::string scriptFile = *scriptFileOpt;
1522

1623
core::Mlang mlang;
1724

18-
mlang.settings.showTokens = false;
19-
mlang.settings.showFileContent = false;
20-
mlang.settings.showResult = false;
21-
mlang.settings.showAbastractSyntaxTree = false;
22-
mlang.settings.showTypeInference = false;
23-
mlang.settings.showInferedTypes = false;
24-
mlang.settings.showFunctions = false;
25-
mlang.settings.showEmission = false;
26-
mlang.settings.showExecution = false;
25+
bool showAll = args.hasFlag("debug");
26+
27+
mlang.settings.showTokens = args.hasFlag("show-tokens") || showAll;
28+
mlang.settings.showFileContent = args.hasFlag("show-file-content") || showAll;
29+
mlang.settings.showResult = args.hasFlag("show-result") || showAll;
30+
mlang.settings.showAbstractSyntaxTree = args.hasFlag("show-ast") || showAll;
31+
mlang.settings.showTypeInference = args.hasFlag("show-type-inference") || showAll;
32+
mlang.settings.showInferedTypes = args.hasFlag("show-inferred-types") || showAll;
33+
mlang.settings.showFunctions = args.hasFlag("show-functions") || showAll;
34+
mlang.settings.showEmission = args.hasFlag("show-emission") || showAll;
35+
mlang.settings.showExecution = args.hasFlag("show-execution") || showAll;
2736
mlang.settings.maxInstructions = 0; // 0 means no limit
28-
// TODO: Config params from cmd
2937

3038
int exitCode = 0;
3139
try {

src/mains/Tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ void testFile(std::string path){
112112
mlang.settings.showTokens = true;
113113
mlang.settings.showFileContent = true;
114114
mlang.settings.showResult = true;
115-
mlang.settings.showAbastractSyntaxTree = true;
115+
mlang.settings.showAbstractSyntaxTree = true;
116116
mlang.settings.showInferedTypes = true;
117117
mlang.settings.showFunctions = true;
118118
mlang.settings.showEmission = true;

0 commit comments

Comments
 (0)