diff options
-rwxr-xr-x | .bin/rpn.c | 150 | ||||
-rwxr-xr-x | install.sh | 1 |
2 files changed, 0 insertions, 151 deletions
diff --git a/.bin/rpn.c b/.bin/rpn.c deleted file mode 100755 index 1d3bdaea..00000000 --- a/.bin/rpn.c +++ /dev/null @@ -1,150 +0,0 @@ -#if 0 -exec cc -Wall -Wextra $@ -ledit -o $(dirname $0)/rpn $0 -#endif - -#include <assert.h> -#include <err.h> -#include <histedit.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <sysexits.h> - -static char *fmt(int radix, long val) { - static char buf[65]; - if (radix == 2) { - unsigned long u = val; - int i = sizeof(buf); - do { - buf[--i] = '0' + (u & 1); - } while (u >>= 1); - return &buf[i]; - } else if (radix == 8) { - snprintf(buf, sizeof(buf), "%lo", val); - } else if (radix == 10) { - snprintf(buf, sizeof(buf), "%ld", val); - } else if (radix == 16) { - snprintf(buf, sizeof(buf), "%lx", val); - } else abort(); - return buf; -} - -static struct { - long data[1024]; - size_t len; - int radix; - char op; -} stack = { .radix = 10 }; - -static void push(long val) { - stack.data[stack.len++] = val; - assert(stack.len < sizeof(stack.data)); -} - -static long pop(void) { - if (stack.len == 0) return 0; - return stack.data[--stack.len]; -} - -static bool stack_op(char op) { - if (stack.op == '@') { - stack.op = 0; - while (stack.len > 1) - stack_op(op); - return true; - } - if (stack.op == '\'') { - stack.op = 0; - push(op); - return true; - } - if (stack.op == '"') { - if (op == '"') stack.op = 0; - else push(op); - return true; - } - - long a, b; - switch (op) { - case '@': case '\'': case '"': stack.op = op; - break; case 'b': stack.radix = 2; - break; case 'o': stack.radix = 8; - break; case 'd': stack.radix = 10; - break; case 'x': stack.radix = 16; - break; case ';': a = pop(); - break; case ':': a = pop(); push(a); push(a); - break; case '\\': a = pop(); b = pop(); push(a); push(b); - 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(~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((unsigned long) pop() << a); - break; case '>': a = pop(); push((unsigned long) pop() >> a); - break; case '.': a = pop(); printf("%s\n", fmt(stack.radix, a)); - break; case ',': a = pop(); printf("%c\n", (char) a); - break; case ' ': - break; default: return false; - } - return true; -} - -static void process(const char *input) { - while (*input) { - if (stack_op(*input)) { - input++; - } else { - char *rest; - long val = strtol(input, &rest, stack.radix); - if (rest != input) { - input = rest; - push(val); - } else input++; - } - } -} - -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) - 2 - q, " %s", fmt(stack.radix, stack.data[i])); - } - p[0] = '['; - p[q] = ']'; - p[++q] = ' '; - p[++q] = 0; - - return p; -} - -int main(int argc, char *argv[]) { - if (argc > 1) { - for (int i = 1; i < argc; ++i) - process(argv[i]); - return EX_OK; - } - - EditLine *el = el_init(argv[0], stdin, stdout, stderr); - el_set(el, EL_PROMPT, prompt); - el_set(el, EL_SIGNAL, true); - - for (;;) { - int count; - const char *line = el_gets(el, &count); - if (count < 0) err(EX_IOERR, "el_gets"); - if (!line) break; - process(line); - } - - el_end(el); - return EX_OK; -} diff --git a/install.sh b/install.sh index fd0010c2..6e9a22ba 100755 --- a/install.sh +++ b/install.sh @@ -26,7 +26,6 @@ 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 |