-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrepl.cpp
More file actions
100 lines (81 loc) · 2.83 KB
/
Copy pathrepl.cpp
File metadata and controls
100 lines (81 loc) · 2.83 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
#include "repl.hpp"
#include <iostream>
#include "lexer.hpp"
#include "parser.hpp"
#include "resolver.hpp"
namespace rs {
Repl::Repl() {
oturumKaynak_ = std::make_unique<Source>("<repl>", "");
oturumTani_ = std::make_unique<Diagnostics>(*oturumKaynak_);
yorumlayici_ = std::make_unique<Interpreter>(*oturumKaynak_, *oturumTani_);
}
// Satir bir blok aciyorsa (':' ile bitiyorsa) devam satiri isteyecegiz.
bool Repl::blokAciyorMu(const std::string& satir) {
for (auto it = satir.rbegin(); it != satir.rend(); ++it) {
if (*it == ' ' || *it == '\t' || *it == '\r') continue;
if (*it == '#') break; // yorum satiri
return *it == ':';
}
return false;
}
void Repl::degerlendir(const std::string& kaynak) {
kaynaklar_.push_back(std::make_unique<Source>("<repl>", kaynak));
Source& src = *kaynaklar_.back();
tanilar_.push_back(std::make_unique<Diagnostics>(src));
Diagnostics& tani = *tanilar_.back();
Lexer lexer(src, tani);
Parser parser(src, lexer.tokenize(), tani);
programlar_.push_back(std::make_unique<Program>(parser.parseProgram()));
Program& prog = *programlar_.back();
if (tani.hasErrors()) {
tani.print(std::cout);
return;
}
// Resolver'i REPL'de UYARISIZ kullaniyoruz: tek satirlik girdide
// "kullanilmadi" uyarisi surekli tetiklenir ve gurultu yapar.
Diagnostics cozTani(src);
Resolver resolver(src, cozTani);
resolver.resolve(prog);
if (cozTani.hasErrors()) {
cozTani.print(std::cout);
return;
}
yorumlayici_->setDiagnostics(tani);
if (!yorumlayici_->run(prog)) {
tani.print(std::cout);
return;
}
// Girdi tek bir ifade deyimiyse degerini yazdir.
if (prog.stmts.size() == 1) {
if (dynamic_cast<const ExprStmt*>(prog.stmts[0].get()) != nullptr) {
const Value v = yorumlayici_->lastValue();
if (!std::holds_alternative<Nil>(v)) {
std::cout << toRepr(v) << '\n';
}
}
}
}
int Repl::run() {
std::cout << "RaidenScript 0.0.1-faz1\n"
<< "Cikis: .cik (veya Ctrl+Z sonra Enter)\n\n";
std::string tampon;
std::string satir;
while (true) {
std::cout << (tampon.empty() ? ">>> " : "... ") << std::flush;
if (!std::getline(std::cin, satir)) break;
if (tampon.empty()) {
if (satir == ".cik" || satir == ".çık") break;
if (satir.empty()) continue;
}
tampon += satir;
tampon += '\n';
// Blok icindeysek bos satir gorene kadar okumaya devam et.
const bool blokta = blokAciyorMu(satir) || (tampon.find('\n') != tampon.rfind('\n'));
if (blokta && !satir.empty()) continue;
degerlendir(tampon);
tampon.clear();
}
std::cout << "\ngorusuruz\n";
return 0;
}
} // namespace rs