1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
| typedef struct op_s {
unsigned opcode;
double value;
} op_t, *_op_t;
double __calc( _op_t _bcode, unsigned ops ) {
double res;
unsigned uopa,uopb, nops;
nops = ops;
for( uopa = 0, uopb = 1; uopb < ops; uopa++, uopb++ ) {
if( _bcode[uopb].opcode == OP_MUL ) do {
_bcode[uopa].value *= _bcode[uopb++].value;
nops--;
} while( _bcode[uopb].opcode == OP_MUL && uopb < ops );
if( uopa + 1 != uopb ) _bcode[uopa + 1] = _bcode[uopb];
}
for( uopa = 0, uopb = 1, ops = nops; uopb < ops; uopa++, uopb++ ) {
if( _bcode[uopb].opcode == OP_DIV ) do {
if( _bcode[uopb].value == 0.0 ) {
printf( " error: division by zero \n" );
return 0;
}
_bcode[uopa].value = _bcode[uopb++].value;
nops--;
} while( _bcode[uopb].opcode == OP_DIV && uopb < ops );
if( uopa + 1 != uopb ) _bcode[uopa + 1] = _bcode[uopb];
}
for( res = _bcode[0].value, uopb = 1; uopb < nops; res += _bcode[uopb++].value );
return res;
}
double __exec( const char *_exp ) {
op_t opstack[ST_SIZE];
unsigned top = 0;
int sign = 0;
double ac;
static const char *_c;
memset( opstack, 0, sizeof( op_t ) * ST_SIZE );
for( _c = _exp; *_c; _c++ ) switch( *_c ) {
case '+':
sign = 0;
break;
case '-':
sign = 1;
break;
case '*':
opstack[top].opcode = OP_MUL;
break;
case '/':
opstack[top].opcode = OP_DIV;
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
ac = 0.0;
do {
ac = ac * 10.0 + (double)(*_c++ - '0');
} while( *_c >='0' && *_c <= '9' );
if( *_c == '.' ) {
double div;
for(
div = 0.1, ++_c;
*_c >= '0' && *_c <= '9';
_c++, div = 10.0
) ac += (double)(*_c - '0') * div;
}
_c--; opstack[top++].value = (sign)? -ac: ac;
sign = 0;
break;
case '(':
opstack[top++].value = (sign)? - __exec( ++_c ): __exec( ++_c );
sign = 0;
break;
case ')':
return __calc( opstack, top );
break;
default:
break;
};
return __calc( opstack, top );
}
int main( int argc, const char *__argv[] ) {
char cbuf[0x400];
while( fgets( cbuf, 0x400, stdin ) ) {
if( cbuf[0] == 'x' ) return 0;
printf( " = %G\n", __exec( cbuf ) );
}
return 0;
} |