summaryrefslogtreecommitdiffstats
path: root/include/pushdown.h
diff options
context:
space:
mode:
authorEthan Werner <mail@ethanwerner.com>2026-06-09 01:17:41 +0400
committerEthan Werner <mail@ethanwerner.com>2026-06-09 01:17:41 +0400
commit96ecf29e8be977f51f351308ef2c7c492bb829aa (patch)
treec664aa61262e6f7627a732f0e4fbb84281b99952 /include/pushdown.h
parentf6a144987cc403de8ad6bddd055f756120f8d405 (diff)
refactor
Diffstat (limited to 'include/pushdown.h')
-rw-r--r--include/pushdown.h915
1 files changed, 826 insertions, 89 deletions
diff --git a/include/pushdown.h b/include/pushdown.h
index aa7c308..5369cfc 100644
--- a/include/pushdown.h
+++ b/include/pushdown.h
@@ -1,11 +1,23 @@
+// pushdown.h — Stack-based pushdown automata with 65+ math/stack operations
+//
+// Thread safety: Not thread-safe. External synchronization required.
+// Behavior: Instructions execute sequentially until END. Invalid instruction
+// values cause immediate termination (pushdown_run) or validation failure
+// (pushdown_validate). Arithmetic on invalid input (div/0, sqrt negative,
+// log <= 0, etc.) returns 0 rather than signaling error.
+
#ifndef PUSHDOWN_H
#define PUSHDOWN_H
-typedef pushdown_value_t stack_value_t;
-#include "./stack.h"
+/* USER-DEFINED (define before including pushdown.h):
+ * typedef <type> stack_value_t; (required by stack.h)
+ * typedef <type> pushdown_value_t; (required by pushdown.h)
+ */
+
+#include "stack.h"
typedef enum {
- END,
+ NOOP,
PUSH,
POP,
SKIP,
@@ -14,12 +26,18 @@ typedef enum {
SUB,
MUL,
DIV,
+ RECIP,
+ INC,
+ DEC,
+ SIGN,
+ NEG,
SIN,
COS,
TAN,
ASIN,
ACOS,
ATAN,
+ ATAN2,
SINH,
COSH,
TANH,
@@ -27,111 +45,830 @@ typedef enum {
ACOSH,
ATANH,
EXP,
+ POW,
LOG,
SQRT,
- ABS
+ ABS,
+ CEIL,
+ FLOOR,
+ ERF,
+ GAMMA,
+ MIN,
+ MAX,
+ CLAMP,
+ ROUNDD,
+ FRACT,
+ MOD,
+ LOG10,
+ LOG2,
+ SIGNUM,
+ SWAP,
+ ROT3,
+ DEPTH,
+ OVER,
+ PICK,
+ DROP2,
+ NIP,
+ TUCK,
+ EQUAL,
+ LESS,
+ GREATER,
+ COMPARE,
+ PI_CONST,
+ E_CONST,
+ RAND,
+ SQUARE,
+ CUBE,
+ RSQRT,
+ SORT2,
+ SORT3,
+ MINMAX,
+ END
} pushdown_instruction_t;
void pushdown_run(stack_t *, stack_t *, pushdown_instruction_t *);
+u32 pushdown_instruction_count(pushdown_instruction_t *);
+int pushdown_validate(pushdown_instruction_t *);
+void pushdown_print(pushdown_instruction_t *);
#endif
#ifdef PUSHDOWN_IMPLEMENTATION
+#ifndef PUSHDOWN_IMPLEMENTED
+#define PUSHDOWN_IMPLEMENTED
#include <tgmath.h>
+static void _noop(stack_t *output, stack_t *input) { (void)output; (void)input; }
+
+static void _push(stack_t *output, stack_t *input) {
+ if (input->size < 1)
+ return;
+ pushdown_value_t x = stack_peek(input);
+ if (!stack_push(output, x))
+ return;
+ stack_pop(input);
+}
+
+static void _pop(stack_t *output, stack_t *input) { (void)input; stack_pop(output); }
+
+static void _skip(stack_t *output, stack_t *input) { (void)output; stack_pop(input); }
+
+static void _copy(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_peek(output);
+ if (!stack_push(output, x))
+ return;
+}
+
+static void _add(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 2)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ pushdown_value_t y = stack_pop(output);
+ output->data[output->size++] = x + y;
+}
+
+static void _sub(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 2)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ pushdown_value_t y = stack_pop(output);
+ output->data[output->size++] = x - y;
+}
+
+static void _mul(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 2)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ pushdown_value_t y = stack_pop(output);
+ output->data[output->size++] = x * y;
+}
+
+static void _div(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 2)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ pushdown_value_t y = stack_pop(output);
+ output->data[output->size++] = (y == 0) ? 0 : x / y;
+}
+
+static void _recip(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = (x == 0) ? 0 : 1.0 / x;
+}
+
+static void _inc(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = x + 1;
+}
+
+static void _dec(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = x - 1;
+}
+
+static void _sign(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = (x > 0) ? 1 : ((x < 0) ? -1 : 0);
+}
+
+static void _neg(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = -x;
+}
+
+static void _sin(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = sin(x);
+}
+
+static void _cos(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = cos(x);
+}
+
+static void _tan(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = tan(x);
+}
+
+static void _asin(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = (x < -1 || x > 1) ? 0 : asin(x);
+}
+
+static void _acos(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = (x < -1 || x > 1) ? 0 : acos(x);
+}
+
+static void _atan(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = atan(x);
+}
+
+static void _sinh(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = sinh(x);
+}
+
+static void _cosh(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = cosh(x);
+}
+
+static void _tanh(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = tanh(x);
+}
+
+static void _asinh(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = asinh(x);
+}
+
+static void _acosh(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = (x < 1) ? 0 : acosh(x);
+}
+
+static void _atanh(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = (x <= -1 || x >= 1) ? 0 : atanh(x);
+}
+
+static void _atan2(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 2)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ pushdown_value_t y = stack_pop(output);
+ output->data[output->size++] = atan2(x, y);
+}
+
+static void _exp(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = exp(x);
+}
+
+static void _pow(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 2)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ pushdown_value_t y = stack_pop(output);
+ output->data[output->size++] = (x < 0 && fmod(y, 1.0) != 0.0) ? 0 : pow(x, y);
+}
+
+static void _log(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = (x <= 0) ? 0 : log(x);
+}
+
+static void _sqrt(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = (x < 0) ? 0 : sqrt(x);
+}
+
+static void _abs(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = fabs(x);
+}
+
+static void _ceil(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = ceil(x);
+}
+
+static void _floor(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = floor(x);
+}
+
+static void _erf(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = erf(x);
+}
+
+static void _min(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 2)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ pushdown_value_t y = stack_pop(output);
+ output->data[output->size++] = (x < y) ? x : y;
+}
+
+static void _max(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 2)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ pushdown_value_t y = stack_pop(output);
+ output->data[output->size++] = (x > y) ? x : y;
+}
+
+static void _clamp(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 3)
+ return;
+ pushdown_value_t hi = stack_pop(output);
+ pushdown_value_t lo = stack_pop(output);
+ pushdown_value_t v = stack_pop(output);
+ output->data[output->size++] = (v < lo) ? lo : ((v > hi) ? hi : v);
+}
+
+static void _roundd(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = round(x);
+}
+
+static void _fract(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = x - floor(x);
+}
+
+static void _mod(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 2)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ pushdown_value_t y = stack_pop(output);
+ output->data[output->size++] = (y == 0) ? 0 : fmod(x, y);
+}
+
+static void _log10_fn(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = (x <= 0) ? 0 : log10(x);
+}
+
+static void _log2_fn(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = (x <= 0) ? 0 : log2(x);
+}
+
+static void _signum(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = (x > 0) ? 1 : ((x < 0) ? -1 : 0);
+}
+
+static void _swap(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 2)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ pushdown_value_t y = stack_pop(output);
+ output->data[output->size++] = x;
+ output->data[output->size++] = y;
+}
+
+static void _rot3(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 3)
+ return;
+ pushdown_value_t t1 = stack_pop(output);
+ pushdown_value_t t2 = stack_pop(output);
+ pushdown_value_t t3 = stack_pop(output);
+ output->data[output->size++] = t2;
+ output->data[output->size++] = t3;
+ output->data[output->size++] = t1;
+}
+
+static void _depth(stack_t *output, stack_t *input) {
+ (void)input;
+ pushdown_value_t d = (pushdown_value_t)output->size;
+ output->data[output->size++] = d;
+}
+
+static void _over(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 2)
+ return;
+ pushdown_value_t x = output->data[output->size - 2];
+ if (!stack_push(output, x))
+ return;
+}
+
+static void _pick(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 2)
+ return;
+ pushdown_value_t n = stack_pop(output);
+ u32 idx = (u32)n;
+ if (idx >= output->size) {
+ output->data[output->size++] = n;
+ return;
+ }
+ pushdown_value_t x = output->data[output->size - 1 - idx];
+ if (!stack_push(output, x))
+ return;
+}
+
+static void _drop2(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 2)
+ return;
+ output->size -= 2;
+}
+
+static void _nip(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 2)
+ return;
+ pushdown_value_t top = stack_pop(output);
+ stack_pop(output);
+ output->data[output->size++] = top;
+}
+
+static void _tuck(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 2)
+ return;
+ pushdown_value_t top = stack_pop(output);
+ pushdown_value_t second = output->data[output->size - 1];
+ if (!stack_push(output, top))
+ return;
+ output->data[output->size++] = second;
+ output->data[output->size++] = top;
+}
+
+static void _equal(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 2)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ pushdown_value_t y = stack_pop(output);
+ output->data[output->size++] = (x == y) ? 1 : 0;
+}
+
+static void _less(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 2)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ pushdown_value_t y = stack_pop(output);
+ output->data[output->size++] = (y < x) ? 1 : 0;
+}
+
+static void _greater(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 2)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ pushdown_value_t y = stack_pop(output);
+ output->data[output->size++] = (y > x) ? 1 : 0;
+}
+
+static void _compare(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 2)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ pushdown_value_t y = stack_pop(output);
+ output->data[output->size++] = (y > x) ? -1 : ((y < x) ? 1 : 0);
+}
+
+static void _pi_const(stack_t *output, stack_t *input) {
+ (void)input;
+ if (!stack_push(output, 3.14159265358979323846))
+ return;
+}
+
+static void _e_const(stack_t *output, stack_t *input) {
+ (void)input;
+ if (!stack_push(output, 2.71828182845904523536))
+ return;
+}
+
+static void _rand(stack_t *output, stack_t *input) {
+ (void)input;
+ if (!stack_push(output, (pushdown_value_t)((f64)rand() / RAND_MAX)))
+ return;
+}
+
+static void _square(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = x * x;
+}
+
+static void _cube(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = x * x * x;
+}
+
+static void _rsqrt(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = (x == 0) ? 0 : 1.0 / sqrt(x < 0 ? -x : x);
+}
+
+static void _sort2(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 2)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ pushdown_value_t y = stack_pop(output);
+ if (x < y) {
+ output->data[output->size++] = x;
+ output->data[output->size++] = y;
+ } else {
+ output->data[output->size++] = y;
+ output->data[output->size++] = x;
+ }
+}
+
+static void _sort3(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 3)
+ return;
+ pushdown_value_t a = stack_pop(output);
+ pushdown_value_t b = stack_pop(output);
+ pushdown_value_t c = stack_pop(output);
+ pushdown_value_t s[3] = {a, b, c};
+ for (u32 i = 0; i < 3; i++)
+ for (u32 j = i + 1; j < 3; j++)
+ if (s[j] < s[i]) {
+ pushdown_value_t tmp = s[i];
+ s[i] = s[j];
+ s[j] = tmp;
+ }
+ output->data[output->size++] = s[0];
+ output->data[output->size++] = s[1];
+ output->data[output->size++] = s[2];
+}
+
+static void _minmax(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 2)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ pushdown_value_t y = stack_pop(output);
+ output->data[output->size++] = (x < y) ? x : y;
+ output->data[output->size++] = (x > y) ? x : y;
+}
+
+static void _gamma(stack_t *output, stack_t *input) {
+ (void)input;
+ if (output->size < 1)
+ return;
+ pushdown_value_t x = stack_pop(output);
+ output->data[output->size++] = tgamma(x);
+}
+
+static void (*OPERATIONS[])(stack_t *output, stack_t *input) = {
+ [NOOP] = _noop,
+ [PUSH] = _push,
+ [POP] = _pop,
+ [SKIP] = _skip,
+ [COPY] = _copy,
+ [ADD] = _add,
+ [SUB] = _sub,
+ [MUL] = _mul,
+ [DIV] = _div,
+ [RECIP] = _recip,
+ [INC] = _inc,
+ [DEC] = _dec,
+ [SIGN] = _sign,
+ [NEG] = _neg,
+ [SIN] = _sin,
+ [COS] = _cos,
+ [TAN] = _tan,
+ [ASIN] = _asin,
+ [ACOS] = _acos,
+ [ATAN] = _atan,
+ [ATAN2] = _atan2,
+ [SINH] = _sinh,
+ [COSH] = _cosh,
+ [TANH] = _tanh,
+ [ASINH] = _asinh,
+ [ACOSH] = _acosh,
+ [ATANH] = _atanh,
+ [EXP] = _exp,
+ [POW] = _pow,
+ [LOG] = _log,
+ [SQRT] = _sqrt,
+ [ABS] = _abs,
+ [CEIL] = _ceil,
+ [FLOOR] = _floor,
+ [ERF] = _erf,
+ [GAMMA] = _gamma,
+ [MIN] = _min,
+ [MAX] = _max,
+ [CLAMP] = _clamp,
+ [ROUNDD] = _roundd,
+ [FRACT] = _fract,
+ [MOD] = _mod,
+ [LOG10] = _log10_fn,
+ [LOG2] = _log2_fn,
+ [SIGNUM] = _signum,
+ [SWAP] = _swap,
+ [ROT3] = _rot3,
+ [DEPTH] = _depth,
+ [OVER] = _over,
+ [PICK] = _pick,
+ [DROP2] = _drop2,
+ [NIP] = _nip,
+ [TUCK] = _tuck,
+ [EQUAL] = _equal,
+ [LESS] = _less,
+ [GREATER] = _greater,
+ [COMPARE] = _compare,
+ [PI_CONST] = _pi_const,
+ [E_CONST] = _e_const,
+ [RAND] = _rand,
+ [SQUARE] = _square,
+ [CUBE] = _cube,
+ [RSQRT] = _rsqrt,
+ [SORT2] = _sort2,
+ [SORT3] = _sort3,
+ [MINMAX] = _minmax,
+};
+
+// pushdown_run()
+//
+// Execute a sequence of instructions until END. Instructions operate on
+// the output stack, pulling values from the input stack via PUSH.
+
void pushdown_run(stack_t *output, stack_t *input,
- pushdown_instruction_t *instructions) {
+ pushdown_instruction_t *instructions) {
+ if (!output || !input || !instructions)
+ return;
+ pushdown_instruction_t *op = instructions;
+
+ while (*op != END) {
+ if (*op > MINMAX || *op < NOOP)
+ break;
+ OPERATIONS[*op](output, input);
+ op++;
+ }
+}
+
+// pushdown_instruction_count()
+//
+// Count the number of instructions before END marker.
+//
+// return - Instruction count, or 0 if NULL or invalid
+
+u32 pushdown_instruction_count(pushdown_instruction_t *instructions) {
+ if (!instructions)
+ return 0;
+ u32 count = 0;
+ pushdown_instruction_t *op = instructions;
+ while (*op != END) {
+ if (*op > MINMAX || *op < NOOP)
+ return count;
+ count++;
+ op++;
+ }
+ return count;
+}
+
+// pushdown_validate()
+//
+// Check that all instruction values in the sequence are valid enum members.
+//
+// return - 1 if valid, 0 if invalid
+
+int pushdown_validate(pushdown_instruction_t *instructions) {
+ if (!instructions)
+ return 0;
pushdown_instruction_t *op = instructions;
+ while (*op != END) {
+ if (*op < NOOP || *op > MINMAX)
+ return 0;
+ op++;
+ }
+ return 1;
+}
- pushdown_value_t x, y;
+// pushdown_print()
+//
+// Print the instruction sequence to stdout in readable format
- while (*op) {
+void pushdown_print(pushdown_instruction_t *instructions) {
+ if (!instructions)
+ return;
+ pushdown_instruction_t *op = instructions;
+ printf("[");
+ int first = 1;
+ while (*op != END) {
+ if (!first) printf(", ");
switch (*op) {
- case PUSH:
- stack_push(output, stack_pop(input));
- break;
- case POP:
- stack_pop(output);
- break;
- case SKIP:
- stack_pop(input);
- break;
- case COPY:
- stack_push(output, stack_peek(output));
- break;
- case ADD:
- x = stack_pop(output);
- y = stack_pop(output);
- stack_push(output, x + y);
- break;
- case SUB:
- x = stack_pop(output);
- y = stack_pop(output);
- stack_push(output, x - y);
- break;
- case MUL:
- x = stack_pop(output);
- y = stack_pop(output);
- stack_push(output, x * y);
- break;
- case DIV:
- x = stack_pop(output);
- y = stack_pop(output);
- stack_push(output, x / y);
- break;
- case SIN:
- stack_push(output, sin(stack_pop(output)));
- break;
- case COS:
- stack_push(output, cos(stack_pop(output)));
- break;
- case TAN:
- stack_push(output, tan(stack_pop(output)));
- break;
- case ASIN:
- stack_push(output, asin(stack_pop(output)));
- break;
- case ACOS:
- stack_push(output, acos(stack_pop(output)));
- break;
- case ATAN:
- stack_push(output, atan(stack_pop(output)));
- break;
- case SINH:
- stack_push(output, sinh(stack_pop(output)));
- break;
- case COSH:
- stack_push(output, cosh(stack_pop(output)));
- break;
- case TANH:
- stack_push(output, tanh(stack_pop(output)));
- break;
- case ASINH:
- stack_push(output, asinh(stack_pop(output)));
- break;
- case ACOSH:
- stack_push(output, acosh(stack_pop(output)));
- break;
- case ATANH:
- stack_push(output, atanh(stack_pop(output)));
- break;
- case EXP:
- stack_push(output, exp(stack_pop(output)));
- break;
- case LOG:
- stack_push(output, log(stack_pop(output)));
- break;
- case SQRT:
- stack_push(output, sqrt(stack_pop(output)));
- break;
- case ABS:
- stack_push(output, fabs(stack_pop(output)));
- break;
+ case NOOP: printf("NOOP"); break;
+ case PUSH: printf("PUSH"); break;
+ case POP: printf("POP"); break;
+ case SKIP: printf("SKIP"); break;
+ case COPY: printf("COPY"); break;
+ case ADD: printf("ADD"); break;
+ case SUB: printf("SUB"); break;
+ case MUL: printf("MUL"); break;
+ case DIV: printf("DIV"); break;
+ case RECIP: printf("RECIP"); break;
+ case INC: printf("INC"); break;
+ case DEC: printf("DEC"); break;
+ case SIGN: printf("SIGN"); break;
+ case NEG: printf("NEG"); break;
+ case SIN: printf("SIN"); break;
+ case COS: printf("COS"); break;
+ case TAN: printf("TAN"); break;
+ case ASIN: printf("ASIN"); break;
+ case ACOS: printf("ACOS"); break;
+ case ATAN: printf("ATAN"); break;
+ case ATAN2: printf("ATAN2"); break;
+ case SINH: printf("SINH"); break;
+ case COSH: printf("COSH"); break;
+ case TANH: printf("TANH"); break;
+ case ASINH: printf("ASINH"); break;
+ case ACOSH: printf("ACOSH"); break;
+ case ATANH: printf("ATANH"); break;
+ case EXP: printf("EXP"); break;
+ case POW: printf("POW"); break;
+ case LOG: printf("LOG"); break;
+ case SQRT: printf("SQRT"); break;
+ case ABS: printf("ABS"); break;
+ case CEIL: printf("CEIL"); break;
+ case FLOOR: printf("FLOOR"); break;
+ case ERF: printf("ERF"); break;
+ case GAMMA: printf("GAMMA"); break;
+ case MIN: printf("MIN"); break;
+ case MAX: printf("MAX"); break;
+ case CLAMP: printf("CLAMP"); break;
+ case ROUNDD: printf("ROUNDD"); break;
+ case FRACT: printf("FRACT"); break;
+ case MOD: printf("MOD"); break;
+ case LOG10: printf("LOG10"); break;
+ case LOG2: printf("LOG2"); break;
+ case SIGNUM: printf("SIGNUM"); break;
+ case SWAP: printf("SWAP"); break;
+ case ROT3: printf("ROT3"); break;
+ case DEPTH: printf("DEPTH"); break;
+ case OVER: printf("OVER"); break;
+ case PICK: printf("PICK"); break;
+ case DROP2: printf("DROP2"); break;
+ case NIP: printf("NIP"); break;
+ case TUCK: printf("TUCK"); break;
+ case EQUAL: printf("EQUAL"); break;
+ case LESS: printf("LESS"); break;
+ case GREATER: printf("GREATER"); break;
+ case COMPARE: printf("COMPARE"); break;
+ case PI_CONST: printf("PI"); break;
+ case E_CONST: printf("E"); break;
+ case RAND: printf("RAND"); break;
+ case SQUARE: printf("SQUARE"); break;
+ case CUBE: printf("CUBE"); break;
+ case RSQRT: printf("RSQRT"); break;
+ case SORT2: printf("SORT2"); break;
+ case SORT3: printf("SORT3"); break;
+ case MINMAX: printf("MINMAX"); break;
+ default: printf("?"); break;
}
-
+ first = 0;
op++;
}
+ printf(", END]\n");
}
-#endif \ No newline at end of file
+#endif /* PUSHDOWN_IMPLEMENTED */
+#endif /* PUSHDOWN_IMPLEMENTATION */ \ No newline at end of file