-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvtscript.cpp
More file actions
105 lines (101 loc) · 2.77 KB
/
vtscript.cpp
File metadata and controls
105 lines (101 loc) · 2.77 KB
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
/*
* The actual interpreter is defined here. See the comment before the
* main function for usage details.
* Happy Hacking~
*/
#include <iostream>
#include <sstream>
#include <istream>
#include <fstream>
#include "interpreter.hpp"
#include "expression.hpp"
#include "interpreter_semantic_error.hpp"
/*
* This is a little helper function for displaying expressions to the
* REPL. I'm using this instead of the << operator, because the REPL
* output must be formatted in a specific way. This should probably
* throw an exception if given an unsimplified type, TODO!
*/
void print_expression(Expression expr) {
std::cout << "(";
switch (expr.getType()) {
case NONE:
std::cout << "None";
break;
case BOOL:
if (expr.getBool()) {
std::cout << "True";
} else {
std::cout << "False";
}
break;
case NUMBER:
std::cout << expr.getNumber();
break;
default:
std::cout << "Error: bad return.";
}
std::cout << ")" << std::endl;
}
/*
* The main routine. It can run vtscript code in one of three ways
* depending on how it's called. If the program is called with no
* arguments, an interactive REPL will start. If the program is called
* with a file name, the program will attempt to run that
* file. Finally, if the program is called with '-e' and then a string
* containting vtscript code, the program will attempt to run that
* string. This last behavior is similar to 'python -c' or 'perl -e'.
*/
int main(int argc, char * argv[]) {
Interpreter interpreter;
// Interpretter case.
if (argc == 1) {
std::string line;
while (true) {
std::cout << "vtscript>";
std::getline(std::cin, line);
std::stringstream stream(line);
if (interpreter.parse(stream)) {
try {
print_expression(interpreter.eval());
} catch (InterpreterSemanticError e) {
std::cout << "Error" << std::endl;
interpreter = Interpreter();
}
} else {
std::cout << "Error" << std::endl;
return EXIT_FAILURE;
}
}
// File case.
} else if (argc == 2) {
std::ifstream stream(argv[1]);
if (!stream.good()) {
std::cout << "Error" << std::endl;
return EXIT_FAILURE;
}
std::ifstream & stream_ref = stream;
if(interpreter.parse(stream_ref)){
try {
print_expression(interpreter.eval());
} catch (InterpreterSemanticError e) {
interpreter = Interpreter();
}
}
// -e Case
} else if ((argc == 3) && (std::string(argv[1]) == "-e")) {
std::stringstream stream(argv[2]);
if (interpreter.parse(stream)) {
try {
print_expression(interpreter.eval());
} catch (InterpreterSemanticError e) {
std::cout << "Error" << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
} else {
std::cout << "Error" << std::endl;
return EXIT_FAILURE;
}
}
}