-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsc.cpp
146 lines (123 loc) · 2.37 KB
/
sc.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include <iostream>
#include <cstdlib>
#include <exception>
#include <string>
#include <fstream>
#include <vector>
#include <algorithm>
#include <stdexcept>
#include "scanner.hpp"
#include "parser.hpp"
#include "p_printers.hpp"
#include "AST.hpp"
#include "s_printer.hpp"
#include "backend.hpp"
using std::vector;
using std::cout;
using std::endl;
using std::cerr;
using std::exception;
using std::string;
using std::istream;
using std::ifstream;
using std::runtime_error;
void fillFile(string& str, string& fName)
{
istream* file = (fName != "") ? new ifstream(fName) : (&std::cin);
if(!file->good())
{
delete file;
throw runtime_error("error opening file.");
}
int c = file->get();
while(c != EOF)
{
str += c;
c = file->get();
}
if(fName != "")
delete file;
}
int main(int argc, char* argv[])
{
try
{
int pos = 1;
char flag = '\0';
//flag
if (pos < argc && argv[1][0] == '-')
{
if(argv[1][1] == '\0' || argv[1][2] != '\0')
throw runtime_error("strange flag encountered");
flag = argv[1][1];
pos++;
}
char validFlags[] =
{'\0', 'a', 'c', 'i', 's', 't', 'x'};
if(!std::binary_search(validFlags, validFlags+7, flag))
throw runtime_error("invalid flag.");
if (pos + 1 < argc)
throw runtime_error("too many inputs");
string fName = pos < argc ? argv[pos] : "";
string file;
fillFile(file, fName);
//actual compiling
scanner* s = new scanner(file);
if(flag == 's')
{
s->printAllTokens();
return 0;
}
vector<token> toks;
try {
toks = s->all();
} catch (runtime_error& e) {
delete s;
throw e;
}
delete s;
parser* p = new parser(toks);
if(flag == 'c')
{
p_printer* pr = new p_printer();
p->attach(pr);
p->parse();
delete pr;
delete p;
return 0;
}
p->parse();
if(!p->good())
return 0;
AST* a = p->ast;
STable* st = p->symbols;
if(flag == 't')
{
s_printer* pr = new s_printer();
pr->print(st);
delete pr;
return 0;
}
if(flag == 'a')
{
a_printer* pr = new a_printer();
a->root->accept(pr);
delete pr;
return 0;
}
if(flag == 'i')
{
cout << "Sorry, I gave up on the interpreter." << endl
<< "At least I used that time wisely;" << endl
<< "my AST is (hopefully) solid now." << endl;
return 0;
}
backend(a, fName);
return 0;
}
catch(runtime_error& e)
{
cerr << "error: " << e.what() << endl;
return 1;
}
}