Simple RPN calculator is working as a first demo.

main
Zed A. Shaw 4 days ago
parent 7847ffdcbd
commit 4d456139a5
  1. 41
      demos/calc.cpp

@ -17,11 +17,12 @@ using std::string, std::wstring;
enum class Event { enum class Event {
NUMBER, ADD, SUB, MUL, NUMBER, ADD, SUB, MUL,
DIV, CLR, NEG, EQ, PUSH, POP DIV, CLR, NEG, EQ, PUSH, DUP
}; };
const std::unordered_map<string, wstring> LABELS { const std::unordered_map<string, wstring> LABELS {
{"readout", L""}, {"clear", L"CLR"}, {"btn0", L"0"}, {"btn1", L"1"}, {"stack", L""}, {"readout", L""}, {"clear", L"CLR"},
{"btn0", L"0"}, {"btn1", L"1"},
{"btn2", L"2"}, {"btn3", L"3"}, {"btn4", L"4"}, {"btn2", L"2"}, {"btn3", L"3"}, {"btn4", L"4"},
{"btn5", L"5"}, {"btn6", L"6"}, {"btn7", L"7"}, {"btn5", L"5"}, {"btn6", L"6"}, {"btn7", L"7"},
{"btn8", L"8"}, {"btn9", L"9"}, {"mul", L"*"}, {"btn8", L"8"}, {"btn9", L"9"}, {"mul", L"*"},
@ -38,20 +39,21 @@ const std::unordered_map<wchar_t, Event> EVENTS {
{L'*', Event::MUL}, {L'-', Event::SUB}, {L'*', Event::MUL}, {L'-', Event::SUB},
{L'+', Event::ADD}, {L'/', Event::DIV}, {L'+', Event::ADD}, {L'/', Event::DIV},
{L'C', Event::CLR}, {L'^', Event::PUSH}, {L'C', Event::CLR}, {L'^', Event::PUSH},
{L'±', Event::NEG}, {L'v', Event::POP}, {L'±', Event::NEG}, {L'v', Event::DUP},
{L'=', Event::EQ} }; {L'=', Event::EQ} };
struct Calculator { struct Calculator {
wstring input; wstring input;
wstring curstack;
std::deque<double> stack; std::deque<double> stack;
double temp = 0.0; double temp = 0.0;
double result = 0.0; double result = 0.0;
void dump() { void display() {
fmt::println("STACK: "); curstack = L"";
for(auto num : stack) { for(auto num : stack) {
fmt::println("{}", num); curstack += fmt::format(L"{} ", num);
} }
} }
@ -98,11 +100,9 @@ struct Calculator {
input = L""; input = L"";
stack.clear(); stack.clear();
break; break;
case POP: case DUP:
if(!stack.empty()) { if(stack.size() > 0) {
temp = stack.back(); input = fmt::format(L"{}", stack.back());
input = fmt::format(L"{}", temp);
stack.pop_back();
} }
break; break;
case PUSH: case PUSH:
@ -119,20 +119,26 @@ struct Calculator {
} }
break; break;
case EQ: case EQ:
if(!stack.empty()) {
temp = stack.back();
input = fmt::format(L"{}", temp);
stack.pop_back();
}
break; break;
} }
dump(); display();
} }
}; };
struct CalculatorUI { struct CalculatorUI {
guecs::UI $gui; guecs::UI $gui;
Calculator $fsm; Calculator $calc;
CalculatorUI() { CalculatorUI() {
$gui.position(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); $gui.position(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
$gui.layout( $gui.layout(
"[*%(400)stack|_|_|_]"
"[*%(400)readout|_|_|_]" "[*%(400)readout|_|_|_]"
"[push|pop|clear|eq]" "[push|pop|clear|eq]"
"[add|sub|mul|div]" "[add|sub|mul|div]"
@ -154,6 +160,8 @@ struct CalculatorUI {
if(name == "readout") { if(name == "readout") {
$gui.set<guecs::Textual>(id, {L"", 40}); $gui.set<guecs::Textual>(id, {L"", 40});
} else if(name == "stack") {
$gui.set<guecs::Textual>(id, {L"", 20});
} else { } else {
$gui.set<guecs::Label>(id, { label }); $gui.set<guecs::Label>(id, { label });
wchar_t op = label[0]; wchar_t op = label[0];
@ -176,10 +184,9 @@ struct CalculatorUI {
} }
void handle_button(wchar_t op) { void handle_button(wchar_t op) {
$fsm.event(EVENTS.at(op), op); $calc.event(EVENTS.at(op), op);
auto readout = $gui.entity("readout"); $gui.show_text("readout", $calc.input);
auto& label = $gui.get<guecs::Textual>(readout); $gui.show_text("stack", $calc.curstack);
label.update($fsm.input);
} }
}; };

Loading…
Cancel
Save