Implements very simple REPL, fixes several issues found with it.
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
180
repl/main.cpp
Normal file
180
repl/main.cpp
Normal file
@@ -0,0 +1,180 @@
|
||||
#include <iostream>
|
||||
#include <ncurses.h>
|
||||
#include <sstream>
|
||||
#include "../src/Parser/Lexer/Lexer.hpp"
|
||||
#include "../src/Parser/Parser.hpp"
|
||||
|
||||
void ParseAndUpdate(const std::vector<std::u8string> lines, WINDOW* diagnosticsWindow, WINDOW* parsedWindow) {
|
||||
std::u8string script;
|
||||
for (const auto& line : lines) {
|
||||
script += line;
|
||||
script += '\n';
|
||||
}
|
||||
auto logger = MalachScript::Diagnostics::Logger();
|
||||
auto lexer = MalachScript::Parser::Lexer(u8"diag", script, &logger);
|
||||
const auto* firstToken = lexer.Lex();
|
||||
[[maybe_unused]] const auto* parsedResult = MalachScript::Parser::Parser::Parse(firstToken, u8"diag", &logger);
|
||||
wclear(diagnosticsWindow);
|
||||
waddstr(diagnosticsWindow, (char*)script.c_str());
|
||||
|
||||
for (const auto& diag : logger.GetMessages()) {
|
||||
waddch(diagnosticsWindow, '[');
|
||||
waddstr(diagnosticsWindow, "Error");
|
||||
waddch(diagnosticsWindow, ']');
|
||||
waddch(diagnosticsWindow, ' ');
|
||||
waddstr(diagnosticsWindow,
|
||||
MalachScript::Diagnostics::DiagnosticTypeHelper::ToEnglishString(diag.GetType()).c_str());
|
||||
waddstr(diagnosticsWindow, " - ");
|
||||
auto start = diag.GetSpan().GetStart() - 3;
|
||||
if (start < 0)
|
||||
start = 0;
|
||||
if (start > script.size())
|
||||
start = script.size() - 1;
|
||||
auto end = diag.GetSpan().GetEnd() + 3;
|
||||
if (end >= script.size())
|
||||
end = script.size() - 1;
|
||||
|
||||
waddstr(diagnosticsWindow, (char*)script.substr(start, end - start).c_str());
|
||||
waddch(diagnosticsWindow, '\n');
|
||||
}
|
||||
wrefresh(diagnosticsWindow);
|
||||
|
||||
wclear(parsedWindow);
|
||||
if (logger.GetMessages().size() == 0) {
|
||||
std::stringstream ss;
|
||||
parsedResult->Stringify(ss, 0);
|
||||
|
||||
waddstr(parsedWindow, ss.str().c_str());
|
||||
}
|
||||
wrefresh(parsedWindow);
|
||||
}
|
||||
|
||||
int main([[maybe_unused]] int argc, [[maybe_unused]] const char* argv[]) {
|
||||
initscr();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, true);
|
||||
set_tabsize(4);
|
||||
|
||||
int maxX;
|
||||
int maxY;
|
||||
getmaxyx(stdscr, maxY, maxX);
|
||||
wresize(stdscr, maxY, maxX);
|
||||
wrefresh(stdscr);
|
||||
|
||||
const int inputFieldSize = 30;
|
||||
|
||||
wborder(stdscr, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
wmove(stdscr, 31, 1);
|
||||
whline(stdscr, ACS_HLINE, maxX - 2);
|
||||
wmove(stdscr, 32, maxX / 2);
|
||||
wvline(stdscr, ACS_VLINE, 25);
|
||||
|
||||
wrefresh(stdscr);
|
||||
|
||||
auto* inputWindow = newwin(inputFieldSize, maxX - 3, 1, 2);
|
||||
keypad(inputWindow, true);
|
||||
|
||||
auto* diagnosticsWindow = newwin(25, (maxX - 4) / 2, 32, 2);
|
||||
|
||||
auto* parsedResultWindow = newwin(25, (maxX - 4) / 2 - 2, 32, (maxX - 4) / 2 + 4);
|
||||
wrefresh(parsedResultWindow);
|
||||
|
||||
int row = 0;
|
||||
int col = 0;
|
||||
|
||||
std::vector<std::u8string> lines = {u8""};
|
||||
|
||||
int c;
|
||||
bool running = true;
|
||||
while (running) {
|
||||
c = wgetch(inputWindow);
|
||||
switch (c) {
|
||||
case 27: running = false; break;
|
||||
|
||||
case KEY_LEFT: {
|
||||
if (col > 0) {
|
||||
wmove(inputWindow, row, --col);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KEY_RIGHT: {
|
||||
auto& line = lines[row];
|
||||
if (col < (int)line.size()) {
|
||||
wmove(inputWindow, row, ++col);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KEY_UP:
|
||||
if (row > 0) {
|
||||
wmove(inputWindow, --row, col);
|
||||
}
|
||||
|
||||
wrefresh(stdscr);
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
if (row < (int)lines.size() - 1) {
|
||||
wmove(inputWindow, ++row, col);
|
||||
}
|
||||
break;
|
||||
case KEY_BACKSPACE:
|
||||
case 127:
|
||||
if (col > 0) {
|
||||
mvwdelch(inputWindow, row, --col);
|
||||
auto& line = lines[row];
|
||||
line = line.erase(col, 1);
|
||||
ParseAndUpdate(lines, diagnosticsWindow, parsedResultWindow);
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
case KEY_ENTER:
|
||||
lines.insert(lines.begin() + row + 1, u8"");
|
||||
row++;
|
||||
col = 0;
|
||||
for (size_t i = row - 1; i < lines.size(); i++) {
|
||||
wmove(inputWindow, i, 0);
|
||||
wclrtoeol(inputWindow);
|
||||
waddstr(inputWindow, (char*)lines[i].c_str());
|
||||
}
|
||||
wmove(inputWindow, row, col);
|
||||
|
||||
break;
|
||||
case 9:
|
||||
case KEY_STAB: {
|
||||
wmove(inputWindow, row, 0);
|
||||
wclrtoeol(inputWindow);
|
||||
auto& line = lines[row];
|
||||
if ((int)line.length() <= col) {
|
||||
line += u8" ";
|
||||
} else {
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
line.insert(line.begin() + col, u8' ');
|
||||
}
|
||||
}
|
||||
waddstr(inputWindow, (char*)line.c_str());
|
||||
col += 4;
|
||||
wmove(inputWindow, row, col);
|
||||
ParseAndUpdate(lines, diagnosticsWindow, parsedResultWindow);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
wmove(inputWindow, row, 0);
|
||||
auto& line = lines[row];
|
||||
if ((int)line.length() <= col) {
|
||||
line += (char8_t)c;
|
||||
} else {
|
||||
line.insert(line.begin() + col, c);
|
||||
}
|
||||
waddstr(inputWindow, (char*)line.c_str());
|
||||
col++;
|
||||
wmove(inputWindow, row, col);
|
||||
ParseAndUpdate(lines, diagnosticsWindow, parsedResultWindow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
wrefresh(inputWindow);
|
||||
}
|
||||
endwin();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user