X-Git-Url: https://secure.softndesign.org/git/?a=blobdiff_plain;f=parser.c;h=38b7c2692fad24c3a4c9422caa92d3214ad70c3c;hb=632f0d031f6f1c0bd0b0b6a7107d0fcd542d78e1;hp=eef08464a87fa3855fa3d2abda00c9f52b4103f2;hpb=db660e6002e8834814ea9beb943dc8dd951fe21c;p=calc.git diff --git a/parser.c b/parser.c index eef0846..38b7c26 100644 --- a/parser.c +++ b/parser.c @@ -12,8 +12,14 @@ double answer = 0; -#define STORAGE_SIZE 10 -double storage[STORAGE_SIZE] = {0}; +#define DEFAULT_STORAGE_SIZE 10 +int storage_size = -1; + +double *storage = NULL; + +#define DEFAULT_FORMAT "=> %.6g\n" +char *format = NULL; +char *minform = NULL; /* compare codes */ @@ -116,7 +122,7 @@ keyword_t operators[NB_OPERATORS] = { { "|", Or, 2, 1, -2} }; -#define NB_FUNCTIONS 23 +#define NB_FUNCTIONS 26 keyword_t functions[NB_FUNCTIONS] = { { "sqrt", Sqr, 1, 4, 5}, { "pow", Pow, 2, 3, 5}, @@ -136,11 +142,14 @@ keyword_t functions[NB_FUNCTIONS] = { { "inc", Inc, 1, 3, 5}, { "dec", Dec, 1, 3, 5}, { "disp", Disp, 0, 4, 9}, + { "mem", Mem, 1, 3, 9}, + { "clr", Clear, 0, 3, 9}, { "quit", Quit, 0, 4, 9}, { "help", Help, 0, 4, 9}, { "!", Not, 1, 1, 6}, { "cond", Cond, 3, 4, 5}, - { "while", While, 2, 5, 5} + { "while", While, 2, 5, 5}, + { "print", Print, 1, 5, 5} }; #define NB_CONSTANTS 3 @@ -192,6 +201,15 @@ element_t *parser (char *str, char **next, int prio) element_t *new = NULL; VERBOSE (INFO, fprintf (stdout, "Processing: %s\n", str)); + /* end without printing */ + + if (*str == ';') { + if (root) { + root->hidden = 1; + } + break; + } + /* skip spaces and tabs */ if ((*str == ' ') || (*str == '\t')) { @@ -489,6 +507,8 @@ void print_element (element_t *root, int level) case Inc: func = "Increase"; break; case Dec: func = "Decrease"; break; case Disp: func = "Display"; break; + case Mem: func = "Memory"; break; + case Clear: func = "Clear"; break; case Quit: func = "Quit"; break; case Help: func = "Help"; break; case Ans: func = "Ans"; break; @@ -506,6 +526,7 @@ void print_element (element_t *root, int level) case Cond: func = "Condition"; break; case While: func = "While"; break; case Prog: func = "Program"; break; + case Print: func = "Print"; break; } fprintf (stdout, "Function: %s\n", func); @@ -524,42 +545,76 @@ void print_element (element_t *root, int level) /* storage functions */ +void memory (int nb) +{ + int i, l; + double *tmp = NULL; + if (nb != storage_size) { + l = (nb < storage_size) ? nb : storage_size; + tmp = (double *) calloc (nb, sizeof (double)); + if (tmp == NULL) { + VERBOSE (ERROR, fprintf (stderr, "can't allocate memory\n")); + exit (1); + } + for (i = 0; i < l; i++) { + tmp[i] = storage[i]; + } + if (storage != NULL) { + free (storage); + } + storage = tmp; + storage_size = nb; + } +} + double store (int index, double value) { - if ((index > 0) && (index <= STORAGE_SIZE)) { + if (storage_size == -1) { + memory (DEFAULT_STORAGE_SIZE); + } + if ((index > 0) && (index <= storage_size)) { storage[index - 1] = value; } else { - VERBOSE (WARNING, fprintf (stdout, "invalid index (%d) [1, %d]\n", index, STORAGE_SIZE)); + VERBOSE (WARNING, fprintf (stdout, "invalid index (%d) [%d, %d]\n", index, (storage_size) ? 1 : 0, storage_size)); } return value; } double recall (int index) { - if ((index > 0) && (index <= STORAGE_SIZE)) { + if (storage_size == -1) { + memory (DEFAULT_STORAGE_SIZE); + } + if ((index > 0) && (index <= storage_size)) { return storage[index - 1]; } else { - VERBOSE (WARNING, fprintf (stdout, "invalid index (%d) [1, %d]\n", index, STORAGE_SIZE)); + VERBOSE (WARNING, fprintf (stdout, "invalid index (%d) [%d, %d]\n", index, (storage_size) ? 1 : 0, storage_size)); } return 0; } double increase (int index) { - if ((index > 0) && (index <= STORAGE_SIZE)) { + if (storage_size == -1) { + memory (DEFAULT_STORAGE_SIZE); + } + if ((index > 0) && (index <= storage_size)) { return storage[index - 1]++; } else { - VERBOSE (WARNING, fprintf (stdout, "invalid index (%d) [1, %d]\n", index, STORAGE_SIZE)); + VERBOSE (WARNING, fprintf (stdout, "invalid index (%d) [%d, %d]\n", index, (storage_size) ? 1 : 0, storage_size)); } return 0; } double decrease (int index) { - if ((index > 0) && (index <= STORAGE_SIZE)) { + if (storage_size == -1) { + memory (DEFAULT_STORAGE_SIZE); + } + if ((index > 0) && (index <= storage_size)) { return storage[index - 1]--; } else { - VERBOSE (WARNING, fprintf (stdout, "invalid index (%d) [1, %d]\n", index, STORAGE_SIZE)); + VERBOSE (WARNING, fprintf (stdout, "invalid index (%d) [%d, %d]\n", index, (storage_size) ? 1 : 0, storage_size)); } return 0; } @@ -567,13 +622,25 @@ double decrease (int index) void display (void) { int i; + if (storage_size == -1) { + memory (DEFAULT_STORAGE_SIZE); + } fprintf (stdout, "storage:"); - for (i = 0; i < STORAGE_SIZE; i++) { - fprintf (stdout, " %g", storage[i]); + for (i = 0; i < storage_size; i++) { + fprintf (stdout, " "); + fprintf (stdout, minform, storage[i]); } fprintf (stdout, "\n"); } +void clear () +{ + int i; + for (i = 0; i < storage_size; i++) { + storage[i] = 0; + } +} + /* While do function */ double while_do (element_t *cond, element_t *action) @@ -613,6 +680,37 @@ double program_do (element_t **prog, int nbcalls) return ret; } +/* print function */ + +void set_format (char *prompt, int precision) +{ + char buffer[128] = {0}; + free_format (); + sprintf (buffer, "%s%%.%dg\n", prompt, precision); + format = strdup (buffer); + sprintf (buffer, "%%.%dg", precision); + minform = strdup (buffer); +} + +void free_format () +{ + if (format) { + free (format); + format = NULL; + } + if (minform) { + free (minform); + minform = NULL; + } +} + +double print (double value) +{ + fprintf (stdout, format ? format : DEFAULT_FORMAT, value); + fflush (stdout); + return value; +} + /* quit function */ void quit (void) @@ -634,15 +732,15 @@ void help (void) fprintf (stdout, " & | !\n"); fprintf (stdout, "mathematic functions:"); fprintf (stdout, " pow sqrt log exp\n"); - fprintf (stdout, "trigonometric functions:"); + fprintf (stdout, "trig. func.:"); fprintf (stdout, " cos sin tan acos asin atan\n"); fprintf (stdout, "supported functions:"); fprintf (stdout, " abs ceil floor\n"); fprintf (stdout, "storage functions:"); - fprintf (stdout, " sto rcl inc dec\n"); - fprintf (stdout, "conditional functions:"); - fprintf (stdout, " cond while\n"); - fprintf (stdout, "miscellaneous functions:"); + fprintf (stdout, " mem sto rcl inc dec disp\n"); + fprintf (stdout, "prog. functions:"); + fprintf (stdout, " cond while print {} ;\n"); + fprintf (stdout, "misc. functions:"); fprintf (stdout, " quit help\n"); fprintf (stdout, "supported constants:"); fprintf (stdout, " e pi\n"); @@ -726,6 +824,7 @@ double evaluate_element (element_t *root, char mask) case Inc: case Dec: case Not: + case Mem: case Cond: if (root->ops[0]) { op0 = evaluate_element (root->ops[0], 0); @@ -735,6 +834,7 @@ double evaluate_element (element_t *root, char mask) } break; case Disp: + case Clear: case Quit: case Help: case Ans: @@ -748,6 +848,9 @@ double evaluate_element (element_t *root, char mask) return 0; } break; + case Print: + op0 = (root->ops[0]) ? evaluate_element (root->ops[0], 0) : answer; + break; } switch (root->func) { @@ -776,6 +879,8 @@ double evaluate_element (element_t *root, char mask) case Inc: return increase ((int)op0); case Dec: return decrease ((int)op0); case Disp: display (); break; + case Mem: memory ((int)op0); break; + case Clear: clear (); break; case Quit: quit (); break; case Help: help (); break; case Ans: return answer; @@ -800,6 +905,7 @@ double evaluate_element (element_t *root, char mask) } case While: return while_do (root->ops[0], root->ops[1]); case Prog: return program_do (root->ops, root->nbops); + case Print: return print (op0); } return 0; @@ -821,38 +927,30 @@ char **generate_completion_list () list[i][j] = '\0'; } } - if (list[l] == NULL) { - VERBOSE (ERROR, fprintf (stderr, "can't allocate memory\n")); - exit (1); + if (list[l] != NULL) { + l++; } - l++; } for (i = 0; i < NB_FUNCTIONS; i++) { list[l] = strdup ((functions + i)->keyword); - if (list[l] == NULL) { - VERBOSE (ERROR, fprintf (stderr, "can't allocate memory\n")); - exit (1); + if (list[l] != NULL) { + l++; } - l++; } for (i = 0; i < NB_CONSTANTS; i++) { list[l] = strdup ((constants + i)->keyword); - if (list[l] == NULL) { - VERBOSE (ERROR, fprintf (stderr, "can't allocate memory\n")); - exit (1); + if (list[l] != NULL) { + l++; } - l++; } for (i = 0; i < NB_SYMBOLS; i++) { list[l] = strdup (symbols[i]); - if (list[l] == NULL) { - VERBOSE (ERROR, fprintf (stderr, "can't allocate memory\n")); - exit (1); + if (list[l] != NULL) { + l++; } - l++; } return (list);