dc

Tiny reverse polish desk calculator
Log | Files | Refs | README | LICENSE

commit 82e950c3bfb9b1a1b95b14ec775c534a68eac0f7
parent cbb5cc555b6dcaed9f5740c33ff3d309721dfd18
Author: Byron Torres <b@torresjrjr.com>
Date:   Tue, 23 Nov 2021 19:02:08 +0000

scan decimal points, ignore blanks, add more ops

Full floating point numbers like 3.14 are scanable.
All blank characters like spaces, tabs and newlines are ignored.
Added multiplication '*', division '/', modulus '%', quit 'q'.

Diffstat:
Mdc.ha | 38+++++++++++++++++++++++++++++++++++++-
1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/dc.ha b/dc.ha @@ -4,6 +4,7 @@ use encoding::utf8; use fmt; use getopt; use io; +use math; use os; use strconv; use strings; @@ -46,6 +47,10 @@ export fn main() void = { yield r; }; + if (!ascii::isgraph(r)) { + continue; + }; + if (ascii::isdigit(r)) { bufio::unreadrune(os::stdin, r); const el = scan_number(); @@ -70,6 +75,30 @@ export fn main() void = { const a = pop(); const b = pop(); push(a - b); + case '*' => + if (len(stack) < 2) { + fmt::errorln("dc: stack has too few elements")?; + continue; + }; + const a = pop(); + const b = pop(); + push(a * b); + case '/' => + if (len(stack) < 2) { + fmt::errorln("dc: stack has too few elements")?; + continue; + }; + const a = pop(); + const b = pop(); + push(a / b); + case '%' => + if (len(stack) < 2) { + fmt::errorln("dc: stack has too few elements")?; + continue; + }; + const a = pop(); + const b = pop(); + push(math::modf64(a, b)); case 'p' => if (len(stack) == 0) { fmt::errorln("dc: stack has no elements")?; @@ -77,7 +106,10 @@ export fn main() void = { }; const el = peek(); fmt::println(el)?; + case 'q' => + os::exit(0); case => + fmt::errorfln("dc: unimplemented '{}'", r)?; continue; }; }; @@ -91,6 +123,7 @@ export fn main() void = { fn scan_number() f64 = { let num: []u8 = []; defer free(num); + let seen_decimal = false; for (true) { const r = match (bufio::scanrune(os::stdin)) { case utf8::invalid => @@ -103,8 +136,11 @@ fn scan_number() f64 = { yield r; }; - if (ascii::isdigit(r)) { + if (ascii::isdigit(r) || (!seen_decimal && r == '.')) { append(num, r: u32: u8); + if (r == '.') { + seen_decimal = true; + }; } else { bufio::unreadrune(os::stdin, r); match (strconv::stof64(strings::fromutf8(num))) {