X-Git-Url: https://secure.softndesign.org/git/?a=blobdiff_plain;f=parser.c;h=395e2aea1e90642757ab4cf6fb2d891058d479a1;hb=c7cbb833c65805634f6e9832b49e4a4680a4a4a6;hp=4da6b6b64b31497d702bffba03a42135cc206e95;hpb=2a5ec9d1e2e19f934a02d0b697b01ae12ebc313f;p=calc.git diff --git a/parser.c b/parser.c index 4da6b6b..395e2ae 100644 --- a/parser.c +++ b/parser.c @@ -12,10 +12,16 @@ 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; + +workspace_t *programs = NULL; /* compare codes */ @@ -118,7 +124,7 @@ keyword_t operators[NB_OPERATORS] = { { "|", Or, 2, 1, -2} }; -#define NB_FUNCTIONS 24 +#define NB_FUNCTIONS 31 keyword_t functions[NB_FUNCTIONS] = { { "sqrt", Sqr, 1, 4, 5}, { "pow", Pow, 2, 3, 5}, @@ -138,12 +144,19 @@ 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}, - { "print", Print, 1, 5, 5} + { "print", Print, 1, 5, 5}, + { "prog", Prog, 3, 4, 9}, + { "call", Call, 10, 4, 5}, + { "ls", List, 0, 2, 9}, + { "edit", Edit, 1, 4, 9}, + { "del", Del, 1, 3, 9} }; #define NB_CONSTANTS 3 @@ -195,6 +208,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')) { @@ -492,6 +514,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; @@ -510,6 +534,11 @@ void print_element (element_t *root, int level) case While: func = "While"; break; case Prog: func = "Program"; break; case Print: func = "Print"; break; + case Prog: func = "Program"; break; + case Call: func = "Call"; break; + case List: func = "List"; break; + case Edit: func = "Edit"; break; + case Del: func = "Del"; break; } fprintf (stdout, "Function: %s\n", func); @@ -528,42 +557,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; } @@ -571,13 +634,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) @@ -622,9 +697,11 @@ double program_do (element_t **prog, int nbcalls) void set_format (char *prompt, int precision) { char buffer[128] = {0}; - sprintf (buffer, "%s%%.%dg\n", prompt, precision); free_format (); + sprintf (buffer, "%s%%.%dg\n", prompt, precision); format = strdup (buffer); + sprintf (buffer, "%%.%dg", precision); + minform = strdup (buffer); } void free_format () @@ -633,11 +710,15 @@ void free_format () free (format); format = NULL; } + if (minform) { + free (minform); + minform = NULL; + } } double print (double value) { - fprintf (stdout, format ? format : "=> %.6g\n", value); + fprintf (stdout, format ? format : DEFAULT_FORMAT, value); fflush (stdout); return value; } @@ -650,6 +731,25 @@ void quit (void) exit (0); } +/* program function */ + +void prog (int id, int nbmems, element_t *root) +{ } + +double call (int id, int nbobs, element_t **ops) +{ + return 0; +} + +void list () +{ } + +void edit (int id) +{ } + +void del (int id) +{ } + /* help message */ void help (void) @@ -663,15 +763,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 print {}\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"); @@ -732,6 +832,7 @@ double evaluate_element (element_t *root, char mask) case Lt: case And: case Or: + case Prog: if (root->ops[1]) { op1 = evaluate_element (root->ops[1], nextmask); } else if (root->func != Store) { @@ -755,7 +856,12 @@ double evaluate_element (element_t *root, char mask) case Inc: case Dec: case Not: + case Mem: case Cond: + case Call: + case List: + case Edit: + case Del: if (root->ops[0]) { op0 = evaluate_element (root->ops[0], 0); } else { @@ -764,6 +870,7 @@ double evaluate_element (element_t *root, char mask) } break; case Disp: + case Clear: case Quit: case Help: case Ans: @@ -808,6 +915,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; @@ -833,6 +942,11 @@ 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); + case Prog: prog ((int)op0, (int)op1, root->ops[2]); break; + case Call: return call ((int)op0, root->nbops + 1, root->ops + 1); + case List: list (); break; + case Edit: edit ((int)op0); break; + case Del: del (int (op0)); break; } return 0;