~torresjrjr/dc

cbb5cc555b6dcaed9f5740c33ff3d309721dfd18 — Byron Torres 3 years ago 44c38c2
scan numbers
1 files changed, 60 insertions(+), 16 deletions(-)

M dc.ha
M dc.ha => dc.ha +60 -16
@@ 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];
};