More work on binder type registration, support in REPL to show registered types.
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
58
repl/ResultWindow.hpp
Normal file
58
repl/ResultWindow.hpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#ifndef MALACHSCRIPT_RESULTWINDOW_HPP
|
||||
#define MALACHSCRIPT_RESULTWINDOW_HPP
|
||||
#include <ncurses.h>
|
||||
#include <sstream>
|
||||
#include "../src/Binder/BoundNamespaceStringifier.hpp"
|
||||
#include "../src/Parser/Statements/ParsedStatementStringifier.hpp"
|
||||
|
||||
namespace MalachScriptRepl {
|
||||
class ResultWindow {
|
||||
public:
|
||||
enum class View { ParseTree, TypeList };
|
||||
|
||||
ResultWindow(int height, int width, int y, int x) { _window = newwin(height, width, y, x); }
|
||||
|
||||
void SetResult(const MalachScript::Parser::ParsedStatement* statement,
|
||||
const MalachScript::Binder::BoundNamespace* ns) {
|
||||
std::stringstream parsedTreeStringStream;
|
||||
MalachScript::Parser::ParsedStatementStringifier::Stringify(statement, parsedTreeStringStream, "", true);
|
||||
_parseTree = parsedTreeStringStream.str();
|
||||
|
||||
std::stringstream boundNamespaceStringStream;
|
||||
MalachScript::Binder::BoundNamespaceStringifier::Stringify(ns, boundNamespaceStringStream);
|
||||
_boundNamespace = boundNamespaceStringStream.str();
|
||||
|
||||
switch (_view) {
|
||||
case View::ParseTree: SetParseTree(); break;
|
||||
case View::TypeList: SetTypeList(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetView(View view) {
|
||||
_view = view;
|
||||
switch (view) {
|
||||
case View::ParseTree: SetParseTree(); break;
|
||||
case View::TypeList: SetTypeList(); break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
WINDOW* _window;
|
||||
std::string _parseTree;
|
||||
std::string _boundNamespace;
|
||||
View _view;
|
||||
|
||||
inline void SetParseTree() {
|
||||
wclear(_window);
|
||||
waddstr(_window, _parseTree.c_str());
|
||||
wrefresh(_window);
|
||||
}
|
||||
inline void SetTypeList() {
|
||||
wclear(_window);
|
||||
waddstr(_window, _boundNamespace.c_str());
|
||||
wrefresh(_window);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MALACHSCRIPT_RESULTWINDOW_HPP
|
||||
225
repl/main.cpp
225
repl/main.cpp
@@ -1,129 +1,136 @@
|
||||
#include <fstream>
|
||||
#include <ncurses.h>
|
||||
#include <sstream>
|
||||
#include "../src/Binder/Binder.hpp"
|
||||
#include "../src/Diagnostics/DiagnosticTypeEN_US.hpp"
|
||||
#include "../src/Parser/Lexer/Lexer.hpp"
|
||||
#include "../src/Parser/Parser.hpp"
|
||||
#include "../src/Parser/Statements/ParsedStatementStringifier.hpp"
|
||||
#include "InputWindow.hpp"
|
||||
#include "ResultWindow.hpp"
|
||||
|
||||
void ParseAndUpdate(const std::vector<std::string>& lines, WINDOW* diagnosticsWindow, WINDOW* parsedWindow,
|
||||
MalachScriptRepl::InputWindow& inputWindow) {
|
||||
std::string script;
|
||||
for (size_t i = 0; i < lines.size(); i++) {
|
||||
script += lines[i];
|
||||
if (i != lines.size() - 1) {
|
||||
script += '\n';
|
||||
namespace MalachScriptRepl {
|
||||
void ParseAndUpdate(const std::vector<std::string>& lines, WINDOW* diagnosticsWindow, ResultWindow* parsedWindow,
|
||||
MalachScriptRepl::InputWindow& inputWindow) {
|
||||
std::string script;
|
||||
for (size_t i = 0; i < lines.size(); i++) {
|
||||
script += lines[i];
|
||||
if (i != lines.size() - 1) {
|
||||
script += '\n';
|
||||
}
|
||||
}
|
||||
|
||||
std::ofstream outfile;
|
||||
outfile.open("script.ms", std::ios::out | std::ios::trunc);
|
||||
outfile << (char*)script.data();
|
||||
outfile.close();
|
||||
|
||||
auto logger = MalachScript::Diagnostics::Logger();
|
||||
auto lexer = MalachScript::Parser::Lexer("diag", script, &logger);
|
||||
const auto* firstToken = lexer.Lex();
|
||||
const auto* parsedResult = MalachScript::Parser::Parser::Parse(firstToken, "diag", &logger);
|
||||
|
||||
auto* ns = new MalachScript::Binder::BoundNamespace();
|
||||
const MalachScript::Binder::Binder::log_func log =
|
||||
[&logger](MalachScript::Diagnostics::DiagnosticLevel level, MalachScript::Diagnostics::DiagnosticType type,
|
||||
const MalachScript::TextSpan& span,
|
||||
const std::vector<std::string>& formats) { logger.Log(level, type, "", span, formats); };
|
||||
MalachScript::Binder::Binder::Bind(ns, {parsedResult}, log);
|
||||
|
||||
const MalachScript::Diagnostics::Diagnostic* diag = nullptr;
|
||||
wclear(diagnosticsWindow);
|
||||
|
||||
if (!logger.GetMessages().empty()) {
|
||||
diag = &logger.GetMessages()[0];
|
||||
|
||||
wattron(diagnosticsWindow, COLOR_PAIR(1));
|
||||
waddch(diagnosticsWindow, '[');
|
||||
waddstr(diagnosticsWindow, "Error");
|
||||
waddch(diagnosticsWindow, ']');
|
||||
wattroff(diagnosticsWindow, COLOR_PAIR(1));
|
||||
waddch(diagnosticsWindow, ' ');
|
||||
waddstr(diagnosticsWindow, std::to_string(diag->GetSpan().GetStart() + 1).c_str());
|
||||
waddch(diagnosticsWindow, '-');
|
||||
waddstr(diagnosticsWindow, std::to_string(diag->GetSpan().GetEnd() + 1).c_str());
|
||||
waddch(diagnosticsWindow, ' ');
|
||||
|
||||
waddstr(diagnosticsWindow, MalachScript::Diagnostics::DiagnosticTypeHelper::ToEnglishString(diag).c_str());
|
||||
|
||||
waddch(diagnosticsWindow, '\n');
|
||||
}
|
||||
wrefresh(diagnosticsWindow);
|
||||
|
||||
parsedWindow->SetResult(parsedResult, ns);
|
||||
inputWindow.SetScriptWithDiagnostics(script, diag);
|
||||
delete parsedResult;
|
||||
}
|
||||
|
||||
std::ofstream outfile;
|
||||
outfile.open("script.ms", std::ios::out | std::ios::trunc);
|
||||
outfile << (char*)script.data();
|
||||
outfile.close();
|
||||
int Run() {
|
||||
setlocale(LC_ALL, "");
|
||||
initscr();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, true);
|
||||
set_tabsize(4);
|
||||
|
||||
auto logger = MalachScript::Diagnostics::Logger();
|
||||
auto lexer = MalachScript::Parser::Lexer("diag", script, &logger);
|
||||
const auto* firstToken = lexer.Lex();
|
||||
const auto* parsedResult = MalachScript::Parser::Parser::Parse(firstToken, "diag", &logger);
|
||||
start_color();
|
||||
init_pair(1, COLOR_RED, COLOR_BLACK);
|
||||
clear();
|
||||
|
||||
const MalachScript::Diagnostics::Diagnostic* diag = nullptr;
|
||||
wclear(diagnosticsWindow);
|
||||
int maxX;
|
||||
int maxY;
|
||||
getmaxyx(stdscr, maxY, maxX);
|
||||
wresize(stdscr, maxY, maxX);
|
||||
wrefresh(stdscr);
|
||||
|
||||
if (!logger.GetMessages().empty()) {
|
||||
diag = &logger.GetMessages()[0];
|
||||
const int inputFieldSize = 30;
|
||||
|
||||
wattron(diagnosticsWindow, COLOR_PAIR(1));
|
||||
waddch(diagnosticsWindow, '[');
|
||||
waddstr(diagnosticsWindow, "Error");
|
||||
waddch(diagnosticsWindow, ']');
|
||||
wattroff(diagnosticsWindow, COLOR_PAIR(1));
|
||||
waddch(diagnosticsWindow, ' ');
|
||||
waddstr(diagnosticsWindow, std::to_string(diag->GetSpan().GetStart() + 1).c_str());
|
||||
waddch(diagnosticsWindow, '-');
|
||||
waddstr(diagnosticsWindow, std::to_string(diag->GetSpan().GetEnd() + 1).c_str());
|
||||
waddch(diagnosticsWindow, ' ');
|
||||
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);
|
||||
|
||||
waddstr(diagnosticsWindow, MalachScript::Diagnostics::DiagnosticTypeHelper::ToEnglishString(diag).c_str());
|
||||
wrefresh(stdscr);
|
||||
|
||||
waddch(diagnosticsWindow, '\n');
|
||||
[[maybe_unused]] auto* diagnosticsWindow = newwin(25, (maxX - 4) / 2, 32, 2);
|
||||
|
||||
auto* parsedResultWindow = new ResultWindow(25, (maxX - 4) / 2 - 2, 32, (maxX - 4) / 2 + 4);
|
||||
|
||||
auto inputWindow = MalachScriptRepl::InputWindow(inputFieldSize, maxX - 3, 1, 2);
|
||||
inputWindow.RegisterOnChange(
|
||||
[diagnosticsWindow, parsedResultWindow, &inputWindow](const std::vector<std::string>& lines) {
|
||||
ParseAndUpdate(lines, diagnosticsWindow, parsedResultWindow, inputWindow);
|
||||
});
|
||||
|
||||
int c;
|
||||
bool running = true;
|
||||
while (running) {
|
||||
c = inputWindow.GetInput();
|
||||
switch (c) {
|
||||
case 27: running = false; break;
|
||||
|
||||
case KEY_LEFT: inputWindow.MoveCursorLeft(); break;
|
||||
case KEY_RIGHT: inputWindow.MoveCursorRight(); break;
|
||||
case KEY_UP: inputWindow.MoveCursorUp(); break;
|
||||
case KEY_DOWN: inputWindow.MoveCursorDown(); break;
|
||||
case KEY_BACKSPACE:
|
||||
case 127: inputWindow.Backspace(); break;
|
||||
case 10:
|
||||
case KEY_ENTER: inputWindow.Return(); break;
|
||||
case 9:
|
||||
case KEY_STAB: inputWindow.Tab(); break;
|
||||
case KEY_END: inputWindow.GoToEndOfLine(); break;
|
||||
case KEY_HOME: inputWindow.GoToStartOfLine(); break;
|
||||
case KEY_F(1): parsedResultWindow->SetView(ResultWindow::View::ParseTree); break;
|
||||
case KEY_F(2): parsedResultWindow->SetView(ResultWindow::View::TypeList); break;
|
||||
default: inputWindow.Input(c); break;
|
||||
}
|
||||
inputWindow.Refresh();
|
||||
}
|
||||
endwin();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
wrefresh(diagnosticsWindow);
|
||||
|
||||
wclear(parsedWindow);
|
||||
std::stringstream ss;
|
||||
MalachScript::Parser::ParsedStatementStringifier::Stringify(parsedResult, ss, "", true);
|
||||
|
||||
waddstr(parsedWindow, ss.str().c_str());
|
||||
wrefresh(parsedWindow);
|
||||
|
||||
inputWindow.SetScriptWithDiagnostics(script, diag);
|
||||
delete parsedResult;
|
||||
}
|
||||
|
||||
int main([[maybe_unused]] int argc, [[maybe_unused]] const char* argv[]) {
|
||||
setlocale(LC_ALL, "");
|
||||
initscr();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, true);
|
||||
set_tabsize(4);
|
||||
|
||||
start_color();
|
||||
init_pair(1, COLOR_RED, COLOR_BLACK);
|
||||
clear();
|
||||
|
||||
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);
|
||||
|
||||
[[maybe_unused]] auto* diagnosticsWindow = newwin(25, (maxX - 4) / 2, 32, 2);
|
||||
|
||||
auto* parsedResultWindow = newwin(25, (maxX - 4) / 2 - 2, 32, (maxX - 4) / 2 + 4);
|
||||
wrefresh(parsedResultWindow);
|
||||
|
||||
auto inputWindow = MalachScriptRepl::InputWindow(inputFieldSize, maxX - 3, 1, 2);
|
||||
inputWindow.RegisterOnChange(
|
||||
[diagnosticsWindow, parsedResultWindow, &inputWindow](const std::vector<std::string>& lines) {
|
||||
ParseAndUpdate(lines, diagnosticsWindow, parsedResultWindow, inputWindow);
|
||||
});
|
||||
|
||||
int c;
|
||||
bool running = true;
|
||||
while (running) {
|
||||
c = inputWindow.GetInput();
|
||||
switch (c) {
|
||||
case 27: running = false; break;
|
||||
|
||||
case KEY_LEFT: inputWindow.MoveCursorLeft(); break;
|
||||
case KEY_RIGHT: inputWindow.MoveCursorRight(); break;
|
||||
case KEY_UP: inputWindow.MoveCursorUp(); break;
|
||||
case KEY_DOWN: inputWindow.MoveCursorDown(); break;
|
||||
case KEY_BACKSPACE:
|
||||
case 127: inputWindow.Backspace(); break;
|
||||
case 10:
|
||||
case KEY_ENTER: inputWindow.Return(); break;
|
||||
case 9:
|
||||
case KEY_STAB: inputWindow.Tab(); break;
|
||||
case KEY_END: inputWindow.GoToEndOfLine(); break;
|
||||
case KEY_HOME: inputWindow.GoToStartOfLine(); break;
|
||||
default: inputWindow.Input(c); break;
|
||||
}
|
||||
inputWindow.Refresh();
|
||||
}
|
||||
endwin();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
int main([[maybe_unused]] int argc, [[maybe_unused]] const char* argv[]) { return MalachScriptRepl::Run(); }
|
||||
Reference in New Issue
Block a user