-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathCompiler.cpp
170 lines (132 loc) · 3.85 KB
/
Compiler.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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 2013 <copyright holder> <email>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Compiler.h"
#include <visitor/SemanticCheckVisitor.h>
#include <errors/ErrorList.h>
// declare the parser and lexer variables
extern int yyparse();
extern FILE* yyin, *yyout;
extern dcpucc::astnodes::Program* program;
using namespace dcpucc;
// global variables that are used by the parser and semantic check
// visitor to add error messages
Compiler* compiler = NULL;
errors::ErrorList errorlist;
int input_type;
std::string input_str;
unsigned int input_str_ctr;
std::string m_asmOutput;
Compiler::Compiler()
: input_type(DTCC_COMPILER_INPUT_STRING), input_str(std::string("")),
input_str_ctr(0), m_asmOutput(std::string(""))
{
}
/// @brief Input function for the lexer.
bool Compiler::getInput(char* buf, size_t& result, size_t max_size)
{
if (this->input_type == DTCC_COMPILER_INPUT_STRING)
{
// read one input character at a time
if (this->input_str_ctr < this->input_str.size())
{
buf[0] = this->input_str[this->input_str_ctr++];
result = 1;
return true;
}
else
{
return false;
}
}
// TODO implement other cases
return false;
}
void Compiler::compile(std::istream& input)
{
// read stream into string
std::string str( (std::istreambuf_iterator<char>( input )),
(std::istreambuf_iterator<char>()) );
this->compile(str);
}
void Compiler::compile(std::string& input)
{
// set input string, and its options
this->input_type = DTCC_COMPILER_INPUT_STRING;
this->input_str = input;
this->input_str_ctr = 0;
// set compiler, so the lexer can use the getInput method to get input
compiler = this;
// create errorlist
errorlist = errors::ErrorList();
// disable yy output
yyout = NULL;
yyin = NULL;
// parse C AST
yyparse();
if (program == NULL)
{
// errors have been added
return;
}
// load assembler information
Assembler::loadAll();
// Do semantic checks
dcpucc::visitor::SemanticCheckVisitor* semCheck = new dcpucc::visitor::SemanticCheckVisitor();
program->accept(*semCheck);
if (errorlist.hasErrors())
{
// don't generate code in this case
return;
}
// generate code
dcpucc::codegen::DirectCodeGenVisitor* codegen = new dcpucc::codegen::DirectCodeGenVisitor();
program->accept(*codegen);
// get output
this->m_asmOutput = codegen->getAssembly();
// cleanup
delete program;
program = NULL;
}
bool Compiler::hasErrors()
{
return errorlist.hasErrors();
}
bool Compiler::hasWarnings()
{
return errorlist.hasWarnings();
}
std::list<std::string> Compiler::getWarnings()
{
return errorlist.getWarnings();
}
std::list<std::string> Compiler::getErrors()
{
return errorlist.getErrors();
}
std::list<std::string> Compiler::getWarningsAndErrors()
{
return errorlist.getWarningsAndErrors();
}
void Compiler::printErrors()
{
errorlist.printall();
}
std::string Compiler::getAssembler()
{
return this->m_asmOutput;
}
Compiler::~Compiler()
{
}