@@ 1,3 1,4 @@
+use ascii;
use bufio;
use encoding::utf8;
use fmt;
@@ 5,6 6,7 @@ use getopt;
use io;
use os;
use strconv;
+use strings;
let stack: []f64 = [];
@@ 44,38 46,36 @@ export fn main() void = {
yield r;
};
+ if (ascii::isdigit(r)) {
+ bufio::unreadrune(os::stdin, r);
+ const el = scan_number();
+ push(el);
+ continue;
+ };
+
switch (r) {
- case '1' =>
- const el = 1f64;
- append(stack, el);
case '+' =>
if (len(stack) < 2) {
fmt::errorln("dc: stack has too few elements")?;
continue;
};
- const a = stack[len(stack) - 2];
- const b = stack[len(stack) - 1];
- const sum = a + b;
- delete(stack[len(stack) - 1]);
- delete(stack[len(stack) - 1]);
- append(stack, sum);
+ 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 = stack[len(stack) - 2];
- const b = stack[len(stack) - 1];
- const diff = a - b;
- delete(stack[len(stack) - 1]);
- delete(stack[len(stack) - 1]);
- append(stack, diff);
+ const a = pop();
+ const b = pop();
+ push(a - b);
case 'p' =>
if (len(stack) == 0) {
fmt::errorln("dc: stack has no elements")?;
continue;
};
- const el = stack[len(stack) - 1];
+ const el = peek();
fmt::println(el)?;
case =>
continue;
@@ 87,3 87,47 @@ export fn main() void = {
getopt::printusage(os::stderr, os::args[0], help);
os::exit(1);
};
+
+fn scan_number() f64 = {
+ let num: []u8 = [];
+ defer free(num);
+ for (true) {
+ const r = match (bufio::scanrune(os::stdin)) {
+ case utf8::invalid =>
+ fmt::fatal("dc: invalid utf8 input");
+ case io::error =>
+ fmt::fatal("dc: IO error");
+ case io::EOF =>
+ yield ' ';
+ case r: rune =>
+ yield r;
+ };
+
+ if (ascii::isdigit(r)) {
+ append(num, r: u32: u8);
+ } else {
+ bufio::unreadrune(os::stdin, r);
+ match (strconv::stof64(strings::fromutf8(num))) {
+ case (strconv::invalid | strconv::overflow) =>
+ abort("dc: invalid numerical input");
+ case n: f64 =>
+ return n;
+ };
+ };
+ };
+ abort("Unreachable");
+};
+
+fn pop() f64 = {
+ const a = stack[len(stack) - 1];
+ delete(stack[len(stack) - 1]);
+ return a;
+};
+
+fn push(el: f64) void = {
+ append(stack, el);
+};
+
+fn peek() f64 = {
+ return stack[len(stack) - 1];
+};