#include #include #include #include "../src/Binder/Binder.hpp" #include "../src/Diagnostics/DiagnosticTypeEN_US.hpp" #include "../src/Parser/Lexer/Lexer.hpp" #include "../src/Parser/Parser.hpp" #include "InputWindow.hpp" #include "ResultWindow.hpp" namespace MalachScriptRepl { void ParseAndUpdate(const std::vector& 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, &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::ScriptTextSpan& span, const std::vector& 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; } int Run() { 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 = 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& 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; } } int main([[maybe_unused]] int argc, [[maybe_unused]] const char* argv[]) { return MalachScriptRepl::Run(); }