Initial commit

This commit is contained in:
Wroclaw 2022-05-15 21:47:33 +02:00
commit dabf8a22f6
14 changed files with 1072 additions and 0 deletions

185
src/main.cpp Normal file
View file

@ -0,0 +1,185 @@
#include <iostream>
#include <sstream>
#include "calculator.cpp"
#include "commands.cpp"
#include "cursor.cpp"
#include "getch.h"
#include "terminal.cpp"
/**
* @brief Prints value of pressed key in top left corner.
* Additionally it can get offet to see more presses.
*
* @param _flags keypress flags.
* @param _key char that we got.
* @param offset how much column do you want to spare?
*/
void debugKey(cursor::key _key, short& offset) {
cursor::savePosition();
cursor::setPosition(1, 1);
// std::cout << " "; // clear debug corner :^)
cursor::setPosition(offset++ * 4 + 1, 1);
std::cout << "\033[31;1m";
// if control flag set
if (_key.special != 0)
std::cout << "^";
std::cout << int(_key.code);
std::cout << "\033[0m";
cursor::restorePosition();
}
/**
* @brief Prints entered keys to the console.
*
* @param keys currently typed keys.
*/
void writeInput(terminal::state keys) {
// FIXME: Do not duplicate lines when line overflows
// possible mitigation: only write one line
// FIXME: flickering
cursor::setX(1);
std::cout << "\033[0K" << "> ";
for(auto it = keys.keys.begin(); it != keys.keys.end(); it++) {
std::cout << *it;
}
cursor::setX(3+keys.cursorPos);
}
/**
* @brief Writes result line with the result while in typing mode
*
* @param string the result
* @param paranthesis missing paranthesis count, negative if misses left paranthesis
* @param calcuationValid is calculation valid
* @param inputSize the current input size (used to where display missing paranthesis)
*/
void writeResultLine(
const std::string string,
const int paranthesis = 0,
const bool calcuationValid = true,
const unsigned int inputSize = 20
) {
auto savedCursorPosition = cursor::getPosition().x;
if (paranthesis != 0) {
cursor::setX(inputSize+5);
std::cout << "\033[31m";
if (paranthesis > 4) {
std::cout << ") * " << paranthesis;
}
else if (paranthesis > 0) {
for(unsigned short i = 0; i < paranthesis; i++) std::cout << ")";
}
else if (paranthesis < 4) {
std::cout << "( * " << -paranthesis;
}
else { //paranthesis is one of -1,-2,-3,-4
for(unsigned short i = 0; i < -paranthesis; i++) std::cout << ")";
}
std::cout << "\033[0m";
}
std::cout << "\n\033[0K\033[90m";
// FIXME: line overflow handling
if (calcuationValid) std::cout << string;
else std::cout << "-";
cursor::up();
cursor::setX(savedCursorPosition);
std::cout << "\033[0m";
}
/**
* @brief Writes result line with the result while in typing mode
*
* @param result the calculation result
* @param inputSize the current input size (used to where display missing paranthesis)
*/
void writeResultLine(Calculator::parseAndCalculateResult result, const unsigned int inputSize) {
std::stringstream result_string;
result_string << result.value;
writeResultLine(result_string.str(), result.unmatchedParanthesis, result.valid, inputSize);
}
int main() {
#ifdef _WIN32
// https://stackoverflow.com/a/47158348
{ // enable virtual terminal for legacy Windows terminals
HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD consoleMode;
GetConsoleMode(console, &consoleMode);
consoleMode |= 0x0004;
SetConsoleMode(console, consoleMode);
}
#endif
std::setlocale(LC_ALL, "");
std::cout << "type :q to exit, type :h for help\n";
short debugOffset = 0; //debug
bool exit = false; //should we exit?
terminal::state keys;
while (!exit) {
writeInput(keys);
// writeResultLine("");
// background calculation
// new std::thread([keys]{
writeResultLine(Calculator::parseAndCaluclate(keys.keys), keys.keys.size());
// });
auto input = cursor::getchar();
// if speciality char
if (input.special != 0) {
switch (input.code)
{
case 75: // ARROW_LEFT
terminal::key_left(keys);
break;
case 77: // ARROW_RIGHT
terminal::key_right(keys);
break;
default:
debugKey(input, debugOffset);
break;
}
continue;
}
else switch (input.code) {
case 8: // BACKSPACE
terminal::key_backspace(keys);
break;
case 13: // ENTER
std::cout << "\n\033[2K" << Calculator::parseAndCaluclate(keys.keys, true).value << "\n";
keys.cursorPos = 0;
keys.keys.clear();
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':
terminal::key_insert(keys, input.code);
break;
case ':':
exit |= commands::loop();
break;
default:
debugKey(input, debugOffset);
break;
};
}
std::cout << "\033[0m";
return 0;
}