-
Notifications
You must be signed in to change notification settings - Fork 3
/
main.cpp
169 lines (151 loc) · 4.51 KB
/
main.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
#include "stdio.h"
#include "parser.h"
#include "functions.h"
#include "type_info.h"
#include "runtime_error.h"
#include "std.h"
#include "firstcompile.h"
#include "visitor/print_visitor.h"
#include "visitor/interpreter.h"
#include <stdint.h>
#include "asmjit/src/asmjit/asmjit.h"
using std::cin;
using std::cout;
using std::endl;
using namespace vaiven;
using namespace asmjit;
void printTokenStream(Tokenizer& tokenizer);
void printExpressionStream(Parser& tokenizer);
int main() {
Tokenizer tokenizer(cin);
Parser parser(tokenizer);
//printTokenStream(tokenizer);
printExpressionStream(parser);
}
// Error handler that just prints the error and lets AsmJit ignore it.
class PrintErrorHandler : public asmjit::ErrorHandler {
public:
// Return `true` to set last error to `err`, return `false` to do nothing.
bool handleError(asmjit::Error err, const char* message, asmjit::CodeEmitter* origin) override {
fprintf(stderr, "Error: %s\n", message);
return false;
}
};
void printExpressionStream(Parser& parser) {
Functions funcs;
init_std(funcs);
unique_ptr<ast::Node<> > cur = parser.parseLogicalGroup();
visitor::Interpreter interpreter(funcs);
while (cur.get() != NULL || parser.errors.size() > 0) {
if (parser.errors.size() > 0) {
for (vector<ParseError>::iterator it = parser.errors.begin(); it != parser.errors.end(); ++it) {
cout << "Parse Error: " << it->error << " at " << it->location << endl;
}
parser.errors.clear();
if (cur.get() == NULL) {
cur = parser.parseLogicalGroup();
continue;
}
}
if (!parser.lastLogicalGroupWasEvaluatable) {
try {
firstCompile(funcs, static_cast<ast::FuncDecl<>&>(*cur));
cur.release(); // Functions owns pointer now
} catch (DuplicateFunctionError e) {
cout << "function " << e.name << " already defined" << endl;
}
cur = parser.parseLogicalGroup();
continue;
}
int error = setjmp(errorJmpBuf);
if (error) {
defaultHandle((vaiven::ErrorCode) error);
cur = parser.parseLogicalGroup();
continue;
}
Value result;
try {
result = interpreter.interpret(*cur);
} catch(Value v) {
result = v;
}
print(result);
cur = parser.parseLogicalGroup();
}
}
void printTokenStream(Tokenizer& tokenizer) {
unique_ptr<Token> cur;
do {
cur = tokenizer.next();
switch(cur->type) {
case TOKEN_TYPE_PLUS:
cout << "+" << endl; break;
case TOKEN_TYPE_MINUS:
cout << "-" << endl; break;
case TOKEN_TYPE_OPEN_BRACE:
cout << "{" << endl; break;
case TOKEN_TYPE_CLOSE_BRACE:
cout << "}" << endl; break;
case TOKEN_TYPE_OPEN_PAREN:
cout << "(" << endl; break;
case TOKEN_TYPE_CLOSE_PAREN:
cout << ")" << endl; break;
case TOKEN_TYPE_MULTIPLY:
cout << "*" << endl; break;
case TOKEN_TYPE_DIVIDE:
cout << "/" << endl; break;
case TOKEN_TYPE_EQ:
cout << "=" << endl; break;
case TOKEN_TYPE_EQEQ:
cout << "==" << endl; break;
case TOKEN_TYPE_GT:
cout << ">" << endl; break;
case TOKEN_TYPE_COMMA:
cout << "," << endl; break;
case TOKEN_TYPE_SEMICOLON:
cout << ";" << endl; break;
case TOKEN_TYPE_FN:
cout << "fn" << endl; break;
case TOKEN_TYPE_END:
cout << "end" << endl; break;
case TOKEN_TYPE_ELSE:
cout << "else" << endl; break;
case TOKEN_TYPE_VAR:
cout << "var" << endl; break;
case TOKEN_TYPE_IS:
cout << "is" << endl; break;
case TOKEN_TYPE_IF:
cout << "if" << endl; break;
case TOKEN_TYPE_OF:
cout << "of" << endl; break;
case TOKEN_TYPE_DO:
cout << "do" << endl; break;
case TOKEN_TYPE_RET:
cout << "ret" << endl; break;
case TOKEN_TYPE_TRUE:
cout << "true" << endl; break;
case TOKEN_TYPE_FALSE:
cout << "false" << endl; break;
case TOKEN_TYPE_INTEGER:
{
IntegerToken* inttok = static_cast<IntegerToken*>(cur.get());
cout << "int" << inttok->value << endl;
}
break;
case TOKEN_TYPE_ID:
{
StringToken* strtok = static_cast<StringToken*>(cur.get());
cout << "id" << strtok->lexeme << endl;
}
break;
case TOKEN_TYPE_ERROR:
{
StringToken* strtok = static_cast<StringToken*>(cur.get());
cout << "Error: " << strtok->lexeme << endl;
}
break;
case TOKEN_TYPE_EOF:
cout << "eof" << endl; break;
}
} while(cur->type != TOKEN_TYPE_EOF);
}