diff options
author | Eric Andersen <andersen@codepoet.org> | 1999-10-05 16:24:54 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 1999-10-05 16:24:54 +0000 |
commit | cc8ed39b240180b58810784f844e253263594ac3 (patch) | |
tree | 15feebbb4be9a9168209609f48f0b100f9364420 /math.c | |
download | busybox-w32-0_29alpha2.tar.gz busybox-w32-0_29alpha2.tar.bz2 busybox-w32-0_29alpha2.zip |
Initial revision0_29alpha2
Diffstat (limited to 'math.c')
-rw-r--r-- | math.c | 149 |
1 files changed, 149 insertions, 0 deletions
@@ -0,0 +1,149 @@ | |||
1 | #include "internal.h" | ||
2 | #include <stdio.h> | ||
3 | #include <stdlib.h> | ||
4 | #include <unistd.h> | ||
5 | #include <math.h> | ||
6 | |||
7 | /* Tiny RPN calculator, because "expr" didn't give me bitwise operations. */ | ||
8 | |||
9 | const char math_usage[] = "math expression ..."; | ||
10 | |||
11 | static double stack[100]; | ||
12 | static unsigned int pointer; | ||
13 | |||
14 | static void | ||
15 | push(double a) | ||
16 | { | ||
17 | if ( pointer >= (sizeof(stack) / sizeof(*stack)) ) { | ||
18 | fprintf(stderr, "math: stack overflow\n"); | ||
19 | exit(-1); | ||
20 | } | ||
21 | else | ||
22 | stack[pointer++] = a; | ||
23 | } | ||
24 | |||
25 | static double | ||
26 | pop() | ||
27 | { | ||
28 | if ( pointer == 0 ) { | ||
29 | fprintf(stderr, "math: stack underflow\n"); | ||
30 | exit(-1); | ||
31 | } | ||
32 | return stack[--pointer]; | ||
33 | } | ||
34 | |||
35 | static void | ||
36 | add() | ||
37 | { | ||
38 | push(pop() + pop()); | ||
39 | } | ||
40 | |||
41 | static void | ||
42 | sub() | ||
43 | { | ||
44 | double subtrahend = pop(); | ||
45 | |||
46 | push(pop() - subtrahend); | ||
47 | } | ||
48 | |||
49 | static void | ||
50 | mul() | ||
51 | { | ||
52 | push(pop() * pop()); | ||
53 | } | ||
54 | |||
55 | static void | ||
56 | divide() | ||
57 | { | ||
58 | double divisor = pop(); | ||
59 | push(pop() / divisor); | ||
60 | } | ||
61 | |||
62 | static void | ||
63 | and() | ||
64 | { | ||
65 | push((unsigned int)pop() & (unsigned int)pop()); | ||
66 | } | ||
67 | |||
68 | static void | ||
69 | or() | ||
70 | { | ||
71 | push((unsigned int)pop() | (unsigned int)pop()); | ||
72 | } | ||
73 | |||
74 | static void | ||
75 | eor() | ||
76 | { | ||
77 | push((unsigned int)pop() ^ (unsigned int)pop()); | ||
78 | } | ||
79 | |||
80 | static void | ||
81 | not() | ||
82 | { | ||
83 | push(~(unsigned int)pop()); | ||
84 | } | ||
85 | |||
86 | static void | ||
87 | print() | ||
88 | { | ||
89 | printf("%g\n", pop()); | ||
90 | } | ||
91 | |||
92 | struct op { | ||
93 | const char * name; | ||
94 | void (*function)(); | ||
95 | }; | ||
96 | |||
97 | static const struct op operators[] = { | ||
98 | { "add", add }, | ||
99 | { "and", and }, | ||
100 | { "div", divide }, | ||
101 | { "eor", eor }, | ||
102 | { "mul", mul }, | ||
103 | { "not", not }, | ||
104 | { "or", or }, | ||
105 | { "sub", sub }, | ||
106 | { 0, 0 } | ||
107 | }; | ||
108 | |||
109 | static void | ||
110 | stack_machine(const char * argument) | ||
111 | { | ||
112 | char * endPointer = 0; | ||
113 | double d; | ||
114 | const struct op * o = operators; | ||
115 | |||
116 | if ( argument == 0 ) { | ||
117 | print(); | ||
118 | return; | ||
119 | } | ||
120 | |||
121 | d = strtod(argument, &endPointer); | ||
122 | |||
123 | if ( endPointer != argument ) { | ||
124 | push(d); | ||
125 | return; | ||
126 | } | ||
127 | |||
128 | while ( o->name != 0 ) { | ||
129 | if ( strcmp(o->name, argument) == 0 ) { | ||
130 | (*(o->function))(); | ||
131 | return; | ||
132 | } | ||
133 | o++; | ||
134 | } | ||
135 | fprintf(stderr, "math: %s: syntax error.\n", argument); | ||
136 | exit(-1); | ||
137 | } | ||
138 | |||
139 | int | ||
140 | math_main(struct FileInfo * i, int argc, char * * argv) | ||
141 | { | ||
142 | while ( argc >= 2 ) { | ||
143 | stack_machine(argv[1]); | ||
144 | argv++; | ||
145 | argc--; | ||
146 | } | ||
147 | stack_machine(0); | ||
148 | return 0; | ||
149 | } | ||