From c1b83c5cd4fb9e7922ead7ccc448ec7349697cfe Mon Sep 17 00:00:00 2001 From: Tibor Bizjak Date: Sun, 9 Jul 2023 16:12:03 +0200 Subject: [PATCH] added help command --- k&r/04-funcs-and-prog-struct/04-calc.c | 92 +++++++++++++++----------- 1 file changed, 55 insertions(+), 37 deletions(-) diff --git a/k&r/04-funcs-and-prog-struct/04-calc.c b/k&r/04-funcs-and-prog-struct/04-calc.c index bb22616..83ba3aa 100644 --- a/k&r/04-funcs-and-prog-struct/04-calc.c +++ b/k&r/04-funcs-and-prog-struct/04-calc.c @@ -17,7 +17,10 @@ #define PROMPT_F ">> " #define POP_PRINT_F "pop -> %.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 */ #define MAXVAL 100 /* maximum depth of val stack */ @@ -82,44 +85,46 @@ double val[MAXVAL]; /* renaming macro */ #define CALL(TOKEN, F, APPLY, ...) APPLY(F, ##__VA_ARGS__) +void help(void); #define COMMANDS \ - X(print, CALL, print_peek, COMMAND) \ - X(dup, COMMAND) \ - X(swap, COMMAND) \ - X(clear, COMMAND) + X(print, "print top of stack", CALL, print_peek, COMMAND) \ + X(dup, "duplicate top of stack", COMMAND) \ + X(swap, "swap top two elements of stack", COMMAND) \ + X(clear, "clear stack", COMMAND) \ + X(help, "print all available commands", COMMAND) #define OPERATORS \ - X(+, COMM_OP) \ - X(*, COMM_OP) \ - X(-, NONC_OP, double) \ - X(/, NONC_OP, double, NONZ_SND_OP) \ - X(%, NONC_OP, int, NONZ_SND_OP) \ - X(>, NONC_OP, double) \ - X(<, NONC_OP, double) \ - X(<=, NONC_OP, double) \ - X(>=, NONC_OP, double) + X(+, "add operands", COMM_OP) \ + X(*, "multiply operands", COMM_OP) \ + X(-, "substact operands", NONC_OP, double) \ + X(/, "divide operands", NONC_OP, double, NONZ_SND_OP) \ + X(%, "modulo operands", NONC_OP, int, NONZ_SND_OP) \ + X(>, "greater than", NONC_OP, double) \ + X(<, "less than", NONC_OP, double) \ + X(<=, "less than or equal", NONC_OP, double) \ + X(>=, "greater than or equal", NONC_OP, double) #define MATH_H_BINDINGS \ - X(sin, UNARY_FUN) \ - X(cos, UNARY_FUN) \ - X(tan, UNARY_FUN) \ - X(acos, UNARY_T_FUN, double, IN_RANGE(-1, 1)) \ - X(asin, UNARY_T_FUN, double, IN_RANGE(-1, 1)) \ - X(atan, UNARY_FUN) \ - X(exp, UNARY_FUN) \ - X(log, UNARY_T_FUN, double, NON_NEG) \ - X(log10, UNARY_T_FUN, double, NON_NEG) \ - X(log2, UNARY_T_FUN, double, NON_NEG) \ - X(pow, NONC_FUN, double) \ - X(sqrt, UNARY_T_FUN, double, NON_NEG) \ - X(ceil, UNARY_FUN) \ - X(floor, UNARY_FUN) \ - X(round, UNARY_FUN) \ - X(abs, CALL, fabs, UNARY_FUN) \ - X(max, CALL, fmax, COMM_FUN) \ - X(min, CALL, fmin, COMM_FUN) \ - X(pi, CALL, M_PI, VALUE) + X(sin, "sine", UNARY_FUN) \ + X(cos, "cosine", UNARY_FUN) \ + X(tan, "tangent", UNARY_FUN) \ + X(acos, "arc cosine", UNARY_T_FUN, double, IN_RANGE(-1, 1)) \ + X(asin, "arc sine", UNARY_T_FUN, double, IN_RANGE(-1, 1)) \ + X(atan, "arc tangent", UNARY_FUN) \ + X(exp, "exponentional function", UNARY_FUN) \ + X(log, "natural logarithm", UNARY_T_FUN, double, NON_NEG) \ + X(log10, "logarithm of base 10", UNARY_T_FUN, double, NON_NEG) \ + X(log2, "logarithm of base 2", UNARY_T_FUN, double, NON_NEG) \ + X(pow, "power function", NONC_FUN, double) \ + X(sqrt, "square root", UNARY_T_FUN, double, NON_NEG) \ + X(ceil, "round up value", UNARY_FUN) \ + X(floor, "round down value", UNARY_FUN) \ + X(round, "round to nearest", UNARY_FUN) \ + X(abs, "absolute value", CALL, fabs, UNARY_FUN) \ + X(max, "maximum value", CALL, fmax, COMM_FUN) \ + X(min, "minimum value", CALL, fmin, COMM_FUN) \ + X(pi, "value of pi", CALL, M_PI, VALUE) #define TOKENS \ @@ -127,7 +132,7 @@ double val[MAXVAL]; OPERATORS \ MATH_H_BINDINGS -/* --------- COMMAND DEFINITIONS */ +/* --------- MAIN PROGRAM */ #define MAXTOKEN 100 int gettoken(char *token, int max_t); @@ -140,13 +145,14 @@ int main() double x; int t_len; - printf(PROMPT_F); + printf(INITIAL_PROMPT_F); while (t_len = gettoken(token, MAXTOKEN)) { 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); } else - #define X(F, APPLY, ...) \ + #define X(F, DESC, APPLY, ...) \ if (t_len == sizeof(#F) / sizeof(char) - 1 && !strcmp(#F, token)) \ APPLY(F, ##__VA_ARGS__); \ else @@ -165,6 +171,18 @@ int main() 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 */ #include