added help command

master
Tibor Bizjak 2023-07-09 16:12:03 +02:00
parent abbbec2116
commit c1b83c5cd4
1 changed files with 55 additions and 37 deletions

View File

@ -17,7 +17,10 @@
#define PROMPT_F ">> " #define PROMPT_F ">> "
#define POP_PRINT_F "pop -> %.8g\n" #define POP_PRINT_F "pop -> %.8g\n"
#define PEEK_PRINT_F "peek -> %.8g\n" #define PEEK_PRINT_F "peek -> %.8g\n"
#define EMPTY_F "empty\n" #define INITIAL_PROMPT_F \
"A simple calculator using polish notation.\n" \
"Type 'help' for a list of available commands\n" \
PROMPT_F
/* ------ GLOBAL VALUE STACK */ /* ------ GLOBAL VALUE STACK */
#define MAXVAL 100 /* maximum depth of val stack */ #define MAXVAL 100 /* maximum depth of val stack */
@ -82,44 +85,46 @@ double val[MAXVAL];
/* renaming macro */ /* renaming macro */
#define CALL(TOKEN, F, APPLY, ...) APPLY(F, ##__VA_ARGS__) #define CALL(TOKEN, F, APPLY, ...) APPLY(F, ##__VA_ARGS__)
void help(void);
#define COMMANDS \ #define COMMANDS \
X(print, CALL, print_peek, COMMAND) \ X(print, "print top of stack", CALL, print_peek, COMMAND) \
X(dup, COMMAND) \ X(dup, "duplicate top of stack", COMMAND) \
X(swap, COMMAND) \ X(swap, "swap top two elements of stack", COMMAND) \
X(clear, COMMAND) X(clear, "clear stack", COMMAND) \
X(help, "print all available commands", COMMAND)
#define OPERATORS \ #define OPERATORS \
X(+, COMM_OP) \ X(+, "add operands", COMM_OP) \
X(*, COMM_OP) \ X(*, "multiply operands", COMM_OP) \
X(-, NONC_OP, double) \ X(-, "substact operands", NONC_OP, double) \
X(/, NONC_OP, double, NONZ_SND_OP) \ X(/, "divide operands", NONC_OP, double, NONZ_SND_OP) \
X(%, NONC_OP, int, NONZ_SND_OP) \ X(%, "modulo operands", NONC_OP, int, NONZ_SND_OP) \
X(>, NONC_OP, double) \ X(>, "greater than", NONC_OP, double) \
X(<, NONC_OP, double) \ X(<, "less than", NONC_OP, double) \
X(<=, NONC_OP, double) \ X(<=, "less than or equal", NONC_OP, double) \
X(>=, NONC_OP, double) X(>=, "greater than or equal", NONC_OP, double)
#define MATH_H_BINDINGS \ #define MATH_H_BINDINGS \
X(sin, UNARY_FUN) \ X(sin, "sine", UNARY_FUN) \
X(cos, UNARY_FUN) \ X(cos, "cosine", UNARY_FUN) \
X(tan, UNARY_FUN) \ X(tan, "tangent", UNARY_FUN) \
X(acos, UNARY_T_FUN, double, IN_RANGE(-1, 1)) \ X(acos, "arc cosine", UNARY_T_FUN, double, IN_RANGE(-1, 1)) \
X(asin, UNARY_T_FUN, double, IN_RANGE(-1, 1)) \ X(asin, "arc sine", UNARY_T_FUN, double, IN_RANGE(-1, 1)) \
X(atan, UNARY_FUN) \ X(atan, "arc tangent", UNARY_FUN) \
X(exp, UNARY_FUN) \ X(exp, "exponentional function", UNARY_FUN) \
X(log, UNARY_T_FUN, double, NON_NEG) \ X(log, "natural logarithm", UNARY_T_FUN, double, NON_NEG) \
X(log10, UNARY_T_FUN, double, NON_NEG) \ X(log10, "logarithm of base 10", UNARY_T_FUN, double, NON_NEG) \
X(log2, UNARY_T_FUN, double, NON_NEG) \ X(log2, "logarithm of base 2", UNARY_T_FUN, double, NON_NEG) \
X(pow, NONC_FUN, double) \ X(pow, "power function", NONC_FUN, double) \
X(sqrt, UNARY_T_FUN, double, NON_NEG) \ X(sqrt, "square root", UNARY_T_FUN, double, NON_NEG) \
X(ceil, UNARY_FUN) \ X(ceil, "round up value", UNARY_FUN) \
X(floor, UNARY_FUN) \ X(floor, "round down value", UNARY_FUN) \
X(round, UNARY_FUN) \ X(round, "round to nearest", UNARY_FUN) \
X(abs, CALL, fabs, UNARY_FUN) \ X(abs, "absolute value", CALL, fabs, UNARY_FUN) \
X(max, CALL, fmax, COMM_FUN) \ X(max, "maximum value", CALL, fmax, COMM_FUN) \
X(min, CALL, fmin, COMM_FUN) \ X(min, "minimum value", CALL, fmin, COMM_FUN) \
X(pi, CALL, M_PI, VALUE) X(pi, "value of pi", CALL, M_PI, VALUE)
#define TOKENS \ #define TOKENS \
@ -127,7 +132,7 @@ double val[MAXVAL];
OPERATORS \ OPERATORS \
MATH_H_BINDINGS MATH_H_BINDINGS
/* --------- COMMAND DEFINITIONS */ /* --------- MAIN PROGRAM */
#define MAXTOKEN 100 #define MAXTOKEN 100
int gettoken(char *token, int max_t); int gettoken(char *token, int max_t);
@ -140,13 +145,14 @@ int main()
double x; double x;
int t_len; int t_len;
printf(PROMPT_F); printf(INITIAL_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 */
length() ? printf(POP_PRINT_F, pop()) : printf(EMPTY_F); if (length())
printf(POP_PRINT_F, pop());
printf(PROMPT_F); printf(PROMPT_F);
} else } else
#define X(F, APPLY, ...) \ #define X(F, DESC, APPLY, ...) \
if (t_len == sizeof(#F) / sizeof(char) - 1 && !strcmp(#F, token)) \ if (t_len == sizeof(#F) / sizeof(char) - 1 && !strcmp(#F, token)) \
APPLY(F, ##__VA_ARGS__); \ APPLY(F, ##__VA_ARGS__); \
else else
@ -165,6 +171,18 @@ int main()
return 0; return 0;
} }
#define COMMAND_W "10"
#define NEWLINE_DESC "pop top of stack and print it"
/* help: prints all available calculator functions */
void help(void)
{
printf("%-" COMMAND_W "s" NEWLINE_DESC "\n", "ENTER");
#define X(F, DESC, ...) printf("%-" COMMAND_W "s" DESC "\n", #F);
TOKENS
#undef X
}
/* -------- PARSING FUNCTIONS */ /* -------- PARSING FUNCTIONS */
#include <ctype.h> #include <ctype.h>