#include #include #include #include "../src/Parser/Lexer/Lexer.hpp" #include "../src/Parser/Parser.hpp" #include "../src/Parser/Statements/ParsedStatementStringifier.hpp" #include "InputWindow.hpp" void ParseAndUpdate(const std::vector& lines, WINDOW* diagnosticsWindow, WINDOW* parsedWindow, MalachScriptRepl::InputWindow& inputWindow) { std::u8string 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(u8"diag", script, &logger); const auto* firstToken = lexer.Lex(); const auto* parsedResult = MalachScript::Parser::Parser::Parse(firstToken, u8"diag", &logger); 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->GetType()).c_str()); waddch(diagnosticsWindow, '\n'); } 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_BLACK, COLOR_RED); 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& 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; }