Branch data Line data Source code
1 : : #include "lex/Lexer.hpp"
2 : : #include "parse/ASTPrinter.hpp"
3 : : #include "parse/Parser.hpp"
4 : : #include <cerrno>
5 : : #include <cstdlib>
6 : : #include <cstring>
7 : : #include <fstream>
8 : : #include <iostream>
9 : : #include <mutable/util/ArgParser.hpp>
10 : : #include <mutable/util/Diagnostic.hpp>
11 : : #include <mutable/util/fn.hpp>
12 : :
13 : :
14 : : using namespace m;
15 : : using namespace m::ast;
16 : :
17 : :
18 : 0 : void usage(std::ostream &out, const char *name)
19 : : {
20 : 0 : out << "Performs grammatical analysis of the input.\n"
21 : 0 : << "USAGE:\n\t" << name << " <FILE>"
22 : 0 : << "\n\t" << name << " -"
23 : 0 : << std::endl;
24 : 0 : }
25 : :
26 : 0 : int main(int argc, const char **argv)
27 : : {
28 : 0 : ArgParser AP;
29 : : #define ADD(TYPE, VAR, INIT, SHORT, LONG, DESCR, CALLBACK)\
30 : : TYPE VAR = INIT;\
31 : : {\
32 : : AP.add<TYPE>(SHORT, LONG, DESCR, CALLBACK);\
33 : : }
34 [ # # ]: 0 : ADD(bool, show_help, false, /* Type, Var, Init */
35 : : "-h", "--help", /* Short, Long */
36 : : "prints this help message", /* Description */
37 : : [&](bool) { show_help = true; }); /* Callback */
38 [ # # ]: 0 : ADD(bool, color, false, /* Type, Var, Init */
39 : : nullptr, "--color", /* Short, Long */
40 : : "use colors", /* Description */
41 : : [&](bool) { color = true; }); /* Callback */
42 [ # # ]: 0 : ADD(bool, ast, false, /* Type, Var, Init */
43 : : nullptr, "--ast", /* Short, Long */
44 : : "dump the abstract syntax tree", /* Description */
45 : : [&](bool) { ast = true; }); /* Callback */
46 : : #undef ADD
47 [ # # ]: 0 : AP.parse_args(argc, argv);
48 : :
49 [ # # ]: 0 : if (show_help) {
50 [ # # ]: 0 : usage(std::cout, argv[0]);
51 [ # # # # ]: 0 : std::cout << "WHERE\n" << AP;
52 : 0 : std::exit(EXIT_SUCCESS);
53 : : }
54 : :
55 [ # # # # ]: 0 : if (AP.args().size() != 1) {
56 [ # # ]: 0 : usage(std::cerr, argv[0]);
57 [ # # # # ]: 0 : std::cerr << "WHERE\n" << AP;
58 : 0 : std::exit(EXIT_FAILURE);
59 : : }
60 : :
61 [ # # ]: 0 : const char *filename = AP.args()[0];
62 : : std::istream *in;
63 [ # # # # ]: 0 : if (streq(filename, "-")) {
64 : : /* read from stdin */
65 : 0 : in = &std::cin;
66 : 0 : } else {
67 : : /* read from file */
68 [ # # # # ]: 0 : in = new std::ifstream(filename, std::ios_base::in);
69 : : }
70 : :
71 [ # # # # ]: 0 : if (in->fail()) {
72 [ # # ]: 0 : if (in == &std::cin)
73 [ # # ]: 0 : std::cerr << "Failed to open stdin: ";
74 : 0 : else
75 [ # # # # : 0 : std::cerr << "Failed to open the file '" << filename << "': ";
# # ]
76 [ # # # # ]: 0 : std::cerr << strerror(errno) << std::endl;
77 : 0 : }
78 : :
79 [ # # ]: 0 : Diagnostic diag(color, std::cout, std::cerr);
80 : 0 : ThreadSafeStringPool pool;
81 [ # # ]: 0 : Lexer lexer(diag, pool, filename, *in);
82 [ # # ]: 0 : Parser parser(lexer);
83 [ # # ]: 0 : ASTPrinter printer(std::cout);
84 : :
85 [ # # # # : 0 : while (parser.token()) {
# # ]
86 [ # # ]: 0 : auto cmd = parser.parse();
87 [ # # ]: 0 : if (ast) {
88 [ # # ]: 0 : cmd->dump(std::cout);
89 : 0 : } else {
90 [ # # ]: 0 : printer(*cmd);
91 [ # # ]: 0 : std::cout << std::endl;
92 : : }
93 : 0 : }
94 : :
95 [ # # ]: 0 : if (in != &std::cin)
96 [ # # ]: 0 : delete in;
97 : :
98 [ # # ]: 0 : std::exit(diag.num_errors() ? EXIT_FAILURE : EXIT_SUCCESS);
99 : 0 : }
|