From 13cfbda4e4ba26193b0da0481ad8866e915d517a Mon Sep 17 00:00:00 2001 From: Curtis McEnroe Date: Mon, 3 Oct 2016 23:46:20 -0400 Subject: What am I even doing? It's Monday night and I've had a lot to drink because I didn't like what Monday day was like. Ain't that just the way? --- .bin/rpn.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ install.sh | 1 + 2 files changed, 98 insertions(+) create mode 100755 .bin/rpn.c diff --git a/.bin/rpn.c b/.bin/rpn.c new file mode 100755 index 00000000..c2dc4ccf --- /dev/null +++ b/.bin/rpn.c @@ -0,0 +1,97 @@ +#if 0 +exec cc -Wall -Wextra $@ -ledit -o $(dirname $0)/rpn $0 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct { + int64_t data[1024]; + size_t len; + int radix; +} stack = { .radix = 10 }; + +static void push(int64_t val) { + stack.data[stack.len++] = val; + assert(stack.len < sizeof(stack.data)); +} + +static int64_t pop(void) { + if (stack.len == 0) return 0; + return stack.data[--stack.len]; +} + +static bool stack_op(char op) { + int64_t a, b; + switch (op) { + case '$': pop(); + break; case '\\': a = pop(); b = pop(); push(a); push(b); + break; case ':': a = pop(); push(a); push(a); + break; case '_': a = pop(); push(-a); + break; case '+': a = pop(); push(pop() + a); + break; case '-': a = pop(); push(pop() - a); + break; case '*': a = pop(); push(pop() * a); + break; case '/': a = pop(); push(pop() / a); + break; case '%': a = pop(); push(pop() % a); + break; case '~': a = pop(); push(~a); + break; case '&': a = pop(); push(pop() & a); + break; case '|': a = pop(); push(pop() | a); + break; case '^': a = pop(); push(pop() ^ a); + break; case '<': a = pop(); push(pop() << a); + break; case '>': a = pop(); push(pop() >> a); + break; case '.': a = pop(); printf("%lld\n", a); + break; case ',': a = pop(); printf("%c\n", (char) a); + break; default: return false; + } + return true; +} + +static char *prompt(EditLine *el __attribute((unused))) { + static char p[4096]; + if (stack.len == 0) return "[] "; + + size_t q = 0; + for (size_t i = 0; i < stack.len; ++i) { + q += (size_t) snprintf(&p[q], sizeof(p) - 3 - q, " %lld", stack.data[i]); + } + p[0] = '['; + p[q] = ']'; + p[++q] = ' '; + p[++q] = 0; + + return p; +} + +int main(int argc __attribute((unused)), char *argv[]) { + EditLine *el = el_init(argv[0], stdin, stdout, stderr); + el_set(el, EL_PROMPT, prompt); + + for (;;) { + int count; + const char *line = el_gets(el, &count); + if (count < 0) err(EX_IOERR, "el_gets"); + if (!line) break; + + while (*line) { + char *rest; + int64_t val = strtoll(line, &rest, stack.radix); + + while (*line) { + if (isdigit(*line)) + push(strtoll(line, (char **) &line, 0)); // XXX: ??? + else + stack_op(*line++); + } + } + putchar('\n'); + + el_end(el); + return EX_OK; +} diff --git a/install.sh b/install.sh index fd3f7192..98b4de54 100755 --- a/install.sh +++ b/install.sh @@ -25,6 +25,7 @@ link .bin/manpager link .bin/pbcopy link .bin/pbd.c link .bin/pbpaste +link .bin/rpn.c link .bin/xx.c link .config/git/config link .config/git/ignore -- cgit 1.4.1