#include #include #include #include "../src/Parser/Lexer/Lexer.hpp" #include "../src/Parser/Parser.hpp" void ParseAndUpdate(const std::vector 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 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; }