refactored main, added custom atof

master
Tibor Bizjak 2023-07-09 14:59:27 +02:00
parent 919eb0c413
commit abbbec2116
1 changed files with 55 additions and 7 deletions

View File

@ -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;
}