refactored main, added custom atof
parent
919eb0c413
commit
abbbec2116
|
@ -11,6 +11,7 @@
|
||||||
#define FULL_STACK_ERR "stack full, can't push %g"
|
#define FULL_STACK_ERR "stack full, can't push %g"
|
||||||
#define EMPTY_STACK_ERR "stack empty"
|
#define EMPTY_STACK_ERR "stack empty"
|
||||||
#define SHORT_STACK_ERR "not enough elements on stack"
|
#define SHORT_STACK_ERR "not enough elements on stack"
|
||||||
|
#define UNKNOWN_TOKEN_ERR "unknown token %s"
|
||||||
|
|
||||||
/* --------- PROMPT FORMATS */
|
/* --------- PROMPT FORMATS */
|
||||||
#define PROMPT_F ">> "
|
#define PROMPT_F ">> "
|
||||||
|
@ -130,30 +131,31 @@ double val[MAXVAL];
|
||||||
|
|
||||||
#define MAXTOKEN 100
|
#define MAXTOKEN 100
|
||||||
int gettoken(char *token, int max_t);
|
int gettoken(char *token, int max_t);
|
||||||
|
char * parsef(char *s, double *x);
|
||||||
|
|
||||||
/* reverse Polish calculator */
|
/* reverse Polish calculator */
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
char token[MAXTOKEN + 1];
|
char token[MAXTOKEN + 1];
|
||||||
double op2;
|
double x;
|
||||||
int t_len;
|
int t_len;
|
||||||
|
|
||||||
printf(PROMPT_F);
|
printf(PROMPT_F);
|
||||||
while (t_len = gettoken(token, MAXTOKEN)) {
|
while (t_len = gettoken(token, MAXTOKEN)) {
|
||||||
if (t_len < 0) { /* newline token */
|
if (t_len < 0) { /* newline token */
|
||||||
if (length())
|
length() ? printf(POP_PRINT_F, pop()) : printf(EMPTY_F);
|
||||||
printf(POP_PRINT_F, pop());
|
|
||||||
else
|
|
||||||
printf(EMPTY_F);
|
|
||||||
printf(PROMPT_F);
|
printf(PROMPT_F);
|
||||||
} else
|
} else
|
||||||
#define X(F, APPLY, ...) \
|
#define X(F, APPLY, ...) \
|
||||||
if (!strcmp(#F, token)) \
|
if (t_len == sizeof(#F) / sizeof(char) - 1 && !strcmp(#F, token)) \
|
||||||
APPLY(F, ##__VA_ARGS__); \
|
APPLY(F, ##__VA_ARGS__); \
|
||||||
else
|
else
|
||||||
TOKENS
|
TOKENS
|
||||||
#undef X
|
#undef X
|
||||||
push(atof(token));
|
if (*parsef(token, &x) == '\0')
|
||||||
|
push(x);
|
||||||
|
else
|
||||||
|
printerr(UNKNOWN_TOKEN_ERR, token);
|
||||||
}
|
}
|
||||||
if (!length())
|
if (!length())
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
|
@ -191,3 +193,49 @@ int gettoken(char *token, int t_max)
|
||||||
token[i] = '\0';
|
token[i] = '\0';
|
||||||
return i;
|
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