refactored main, added custom atof
parent
919eb0c413
commit
abbbec2116
|
@ -11,6 +11,7 @@
|
|||
#define FULL_STACK_ERR "stack full, can't push %g"
|
||||
#define EMPTY_STACK_ERR "stack empty"
|
||||
#define SHORT_STACK_ERR "not enough elements on stack"
|
||||
#define UNKNOWN_TOKEN_ERR "unknown token %s"
|
||||
|
||||
/* --------- PROMPT FORMATS */
|
||||
#define PROMPT_F ">> "
|
||||
|
@ -130,30 +131,31 @@ double val[MAXVAL];
|
|||
|
||||
#define MAXTOKEN 100
|
||||
int gettoken(char *token, int max_t);
|
||||
char * parsef(char *s, double *x);
|
||||
|
||||
/* reverse Polish calculator */
|
||||
int main()
|
||||
{
|
||||
char token[MAXTOKEN + 1];
|
||||
double op2;
|
||||
double x;
|
||||
int t_len;
|
||||
|
||||
printf(PROMPT_F);
|
||||
while (t_len = gettoken(token, MAXTOKEN)) {
|
||||
if (t_len < 0) { /* newline token */
|
||||
if (length())
|
||||
printf(POP_PRINT_F, pop());
|
||||
else
|
||||
printf(EMPTY_F);
|
||||
length() ? printf(POP_PRINT_F, pop()) : printf(EMPTY_F);
|
||||
printf(PROMPT_F);
|
||||
} else
|
||||
#define X(F, APPLY, ...) \
|
||||
if (!strcmp(#F, token)) \
|
||||
if (t_len == sizeof(#F) / sizeof(char) - 1 && !strcmp(#F, token)) \
|
||||
APPLY(F, ##__VA_ARGS__); \
|
||||
else
|
||||
TOKENS
|
||||
#undef X
|
||||
push(atof(token));
|
||||
if (*parsef(token, &x) == '\0')
|
||||
push(x);
|
||||
else
|
||||
printerr(UNKNOWN_TOKEN_ERR, token);
|
||||
}
|
||||
if (!length())
|
||||
putchar('\n');
|
||||
|
@ -191,3 +193,49 @@ int gettoken(char *token, int t_max)
|
|||
token[i] = '\0';
|
||||
return i;
|
||||
}
|
||||
|
||||
/* ---------- CUSTOM ATOF */
|
||||
#define DEC_SEP X('.') X(',')
|
||||
#define EXP_SEP X('e') X('E')
|
||||
|
||||
|
||||
/* macros for parsef*/
|
||||
#define SIGN(s) \
|
||||
((*s == '-') ? (s++, -1) : ((*s == '+') ? (s++, 1) : 1))
|
||||
#define ATOI(s, x, ...) \
|
||||
for (; isdigit(*s); s++, ##__VA_ARGS__) \
|
||||
(x) = 10 * (x) + (*s - '0')
|
||||
|
||||
/* parsef: convert string s to double, write it to *x
|
||||
* return pointer of last read char in s */
|
||||
char * parsef(char s[], double *x)
|
||||
{
|
||||
*x = 0;
|
||||
/* integer part */
|
||||
int sign = SIGN(s);
|
||||
ATOI(s, *x);
|
||||
|
||||
#define X(sep) *s != sep &&
|
||||
if (DEC_SEP 1) {
|
||||
*x *= sign;
|
||||
return s;
|
||||
}
|
||||
#undef X
|
||||
s++;
|
||||
/* fractional part */
|
||||
int exp = 0;
|
||||
ATOI(s, *x, exp--);
|
||||
*x *= sign * pow(10, exp);
|
||||
|
||||
#define X(sep) *s != sep &&
|
||||
if (EXP_SEP 1)
|
||||
return s;
|
||||
#undef X
|
||||
s++;
|
||||
/* exponent */
|
||||
sign = SIGN(s);
|
||||
exp = 0;
|
||||
ATOI(s, exp);
|
||||
*x *= pow(10, sign * exp);
|
||||
return s;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue