X-Git-Url: https://secure.softndesign.org/git/?a=blobdiff_plain;f=parser.c;h=24afb116c98f19a4a2d0e2724a4d52b6982984fb;hb=807bdeba16ea9ed816ecf7d3900f601c37ffa204;hp=f566fbe4dd905384f7d5e8ca96516e274f034d79;hpb=eadb6e8f8d73566be4b155451dcf4dd8b9e5e634;p=calc.git diff --git a/parser.c b/parser.c index f566fbe..24afb11 100644 --- a/parser.c +++ b/parser.c @@ -1,10 +1,16 @@ -#include #include #include #include #include +#include "alloc.h" +#include "argument.h" #include "debug.h" +#include "element.h" +#include "format.h" +#include "program.h" +#include "stack.h" +#include "storage.h" #include "parser.h" @@ -12,22 +18,7 @@ double answer = 0; -#define DEFAULT_STORAGE_SIZE 10 -int storage_size = -1; -double *storage = NULL; - -int argument_size = 0; -double *argument = NULL; - -int stack_size = 0; -double *stack = NULL; - -#define DEFAULT_FORMAT "=> %.6g\n" -char *format = NULL; -char *minform = NULL; - -workspace_t *programs = NULL; -int nb_programs = 0; +double anglefactor = 1; /* compare codes */ @@ -51,70 +42,6 @@ int codecmp (char *ref, char *str) return 0; } -/* calloc or die function */ - -void *callocordie (size_t count, size_t size) -{ - if (count * size == 0) { - return NULL; - } - void *new = calloc (count, size); - if (new == NULL) { - VERBOSE (ERROR, fprintf (stderr, "can't allocate memory\n")); - exit (1); - } - return new; -} - -/* allocate new element */ - -element_t *newelement (func_t function, int nbops, int prio) -{ - element_t *new = (element_t *) callocordie (1, sizeof (element_t)); - if (nbops) { - new->ops = (element_t **) callocordie (nbops, sizeof (element_t *)); - } - new->func = function; - new->nbops = nbops; - new->prio = prio; - - return new; -} - -/* desallocate element */ - -void delelement (element_t *root) -{ - if ((root != NULL) && (root != ERROR_OP)) { - int i; - for (i = 0; i < root->nbops; i++) { - delelement (root->ops[i]); - } - if (root->nbops) { - free (root->ops); - } - free (root); - } -} - -/* duplicate element */ - -element_t *dupelement (element_t *root) -{ - element_t *tmp = NULL; - int i; - - if ((root == NULL) || (root == ERROR_OP)) { - return root; - } - tmp = newelement (root->func, root->nbops, root->prio); - tmp->value = root->value; - for (i = 0; i < root->nbops; i++) { - tmp->ops[i] = dupelement (root->ops[i]); - } - return tmp; -} - /* functions */ #define MAX_ARGS 100 @@ -137,7 +64,7 @@ keyword_t operators[NB_OPERATORS] = { { "|", Or, 2, 1, -2} }; -#define NB_FUNCTIONS 50 +#define NB_FUNCTIONS 55 keyword_t functions[NB_FUNCTIONS] = { { "sqrt", Sqr, 1, 4, 5}, { "pow", Pow, 2, 3, 5}, @@ -189,6 +116,11 @@ keyword_t functions[NB_FUNCTIONS] = { { "prod", Prod, 0, 4, 5}, { "sum", Sum, 0, 3, 5}, { "var", Variance, 2, 3, 5}, + { "format", Precision, 1, 6, 9}, + { "base", Base, 2, 4, 9}, + { "deg", Deg, 0, 3, 9}, + { "grad", Grad, 0, 4, 9}, + { "rad", Rad, 0, 3, 9} }; #define NB_CONSTANTS 3 @@ -445,51 +377,48 @@ element_t *parser (char *str, char **next, int prio) /* look for number */ - if (((*str >= '0') && (*str <= '9')) || - (*str == '.') || (*str == '+') || (*str == '-')) { - VERBOSE (DEBUG, fprintf (stdout, "start processing value\n")); - char *pt; - double value = strtod (str, &pt); - VERBOSE (INFO, fprintf (stdout, "Value: %f\n", value)); - if (str != pt) { - if ((root == NULL) || (root->prio == 6)) { - new = newelement (Val, 1, 5); - new->value = value; - if (root == NULL) { - root = new; - } else { - for (i = 0; i < root->nbops; i++) { - if (root->ops[i] == NULL) { - root->ops[i] = new; - found = 1; - break; - } - } - if (!found) { - delelement (new); - delelement (root); - return ERROR_OP; + VERBOSE (DEBUG, fprintf (stdout, "start processing value\n")); + char *pt; + double value = (get_ibase () == 10) ? strtod (str, &pt) : strtoul (str, &pt, get_ibase ()); + VERBOSE (INFO, fprintf (stdout, "Value: %f\n", value)); + if (str != pt) { + if ((root == NULL) || (root->prio == 6)) { + new = newelement (Val, 1, 5); + new->value = value; + if (root == NULL) { + root = new; + } else { + for (i = 0; i < root->nbops; i++) { + if (root->ops[i] == NULL) { + root->ops[i] = new; + found = 1; + break; } } - str = pt; - } else if ((*str == '+') || (*str == '-')) { - if ((prio) && (prio > 1)) { - VERBOSE (DEBUG, fprintf (stdout, "stop because operator priority\n")); - *next = str; - return root; - } - if (subparser (&root, &str, Add, 2, 1) == ERROR_OP) { + if (!found) { + delelement (new); delelement (root); return ERROR_OP; } - } else { + } + str = pt; + } else if ((*str == '+') || (*str == '-')) { + if ((prio) && (prio > 1)) { + VERBOSE (DEBUG, fprintf (stdout, "stop because operator priority\n")); + *next = str; + return root; + } + if (subparser (&root, &str, Add, 2, 1) == ERROR_OP) { delelement (root); return ERROR_OP; } - found = 1; + } else { + delelement (root); + return ERROR_OP; } - VERBOSE (DEBUG, fprintf (stdout, "stop processing value\n")); + found = 1; } + VERBOSE (DEBUG, fprintf (stdout, "stop processing value\n")); /* error */ @@ -524,7 +453,7 @@ void print_element (element_t *root, int level) } for (i = 0; i < level; i++) { - fprintf (stdout, " "); + printf (" "); } switch (root->func) { @@ -597,15 +526,20 @@ void print_element (element_t *root, int level) case Prod: func = "Product"; break; case Sum: func = "Sum"; break; case Variance: func = "Variance"; break; + case Precision: func = "Precision"; break; + case Base: func = "Base"; break; + case Deg: func = "Degree"; break; + case Grad: func = "Gradian"; break; + case Rad: func = "Radian"; break; } - fprintf (stdout, "Function: %s\n", func); + printf ("Function: %s\n", func); if ((root->func == Val) && (root->ops[0] == NULL)) { for (i = 0; i < level; i++) { - fprintf (stdout, " "); + printf (" "); } - fprintf (stdout, "value: %f\n", root->value); + printf ("value: %f\n", root->value); } else { for (i = 0; i < root->nbops; i++) { print_element (root->ops[i], level + 1); @@ -613,104 +547,6 @@ void print_element (element_t *root, int level) } } -/* storage functions */ - -int memory (int nb) -{ - int i, l; - double *tmp = NULL; - if ((nb != -1) && (nb != storage_size)) { - l = (nb < storage_size) ? nb : storage_size; - tmp = (double *) callocordie (nb, sizeof (double)); - for (i = 0; i < l; i++) { - tmp[i] = storage[i]; - } - if (storage != NULL) { - free (storage); - } - storage = tmp; - storage_size = nb; - } - if (storage_size == -1) { - memory (DEFAULT_STORAGE_SIZE); - } - return storage_size; -} - -double store (int index, double value) -{ - 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) [%d, %d]\n", index, (storage_size) ? 1 : 0, storage_size)); - } - return value; -} - -double recall (int index) -{ - 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) [%d, %d]\n", index, (storage_size) ? 1 : 0, storage_size)); - } - return 0; -} - -double increase (int index) -{ - 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) [%d, %d]\n", index, (storage_size) ? 1 : 0, storage_size)); - } - return 0; -} - -double decrease (int index) -{ - 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) [%d, %d]\n", index, (storage_size) ? 1 : 0, storage_size)); - } - return 0; -} - -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, " "); - 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) @@ -752,554 +588,79 @@ double execute_code (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) { - fprintf (stdout, "bye\n"); + printf ("bye\n"); exit (0); } -/* program function */ - -void prog (int id, element_t *root) -{ - int i, n = -1; - - if (programs == NULL) { - - /* initial memory allocation */ - programs = (workspace_t *) callocordie (1, sizeof (workspace_t)); - nb_programs = 1; - n = 0; - - } else { - - /* look for existing program */ - for (i = 0; i < nb_programs; i++) { - if ((programs + i)->id == id) { - n = i; - break; - } - } - if (n == -1) { - - /* new program */ - n = nb_programs++; - workspace_t *tmp = (workspace_t *) callocordie (nb_programs, sizeof (workspace_t)); - memcpy (tmp, programs, (nb_programs - 1) * sizeof (workspace_t)); - free (programs); - programs = tmp; - } else { - - /* clean old program */ - if ((programs + n)->storage) { - free ((programs + n)->storage); - } - if ((programs + n)->stack) { - free ((programs + n)->stack); - } - if ((programs + n)->root) { - delelement ((programs + n)->root); - } - if ((programs + n)->string) { - free ((programs + n)->string); - (programs + n)->string = NULL; - } - } - } - - /* set program */ - (programs + n)->id = id; - (programs + n)->answer = 0; - (programs + n)->storage = NULL; - (programs + n)->storage_size = 0; - (programs + n)->stack = NULL; - (programs + n)->stack_size = 0; - (programs + n)->root = dupelement (root); -} - -double arg (int id) -{ - double ret = 0; - if ((id <= 0) || (id > argument_size)) { - VERBOSE (WARNING, fprintf (stdout, "error out of bound (%d/%d)\n", id, argument_size)); - } else { - ret = argument[id - 1]; - } - return ret; -} +/* help message */ -double call (int id, int nbargs, element_t **args) +void help (void) { - workspace_t tmp = {0}; - int i, l, n = -1; - double ret = 0; - - if (programs) { - - /* look for program */ - for (i = 0; i < nb_programs; i++) { - if ((programs + i)->id == id) { - n = i; - break; - } - } - } - if (n == -1) { - VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id)); + printf ("calc is a simple calculator\n\n"); + printf ("arithmetic op.:"); + printf (" + - * / %% ^\n"); + printf ("comparison op.:"); + printf (" == != >= <= > <\n"); + printf ("logical op.:"); + printf (" & | !\n"); + printf ("mathematic func.:"); + printf (" exp ln log pow sqrt\n"); + printf ("trigonometric func.:"); + printf (" acos asin atan cos sin tan\n"); + printf ("error functions:"); + printf (" erf erfc\n"); + printf ("miscellaneous func.:"); + printf (" abs ceil floor\n"); + printf ("storage func.:"); + printf (" clear dec disp inc mem rcl sto\n"); + printf ("control flow prim.:"); + printf (" cond print while {} ;\n"); + printf ("program management:"); + printf (" arg call del edit ls prog\n"); + printf ("stack management:"); + printf (" get len pop push put set show\n"); + printf ("stack func.:"); + printf (" max mean med min ord prod sum var\n"); + printf ("control management:"); + printf (" base deg format grad help quit rad\n"); + printf ("constants:"); + printf (" ans e pi\n"); +} + +/* format function */ + +int format (int precision) +{ + if (precision > 0) { + set_precision (precision); + set_format (); + } else if (precision != -1) { + VERBOSE (WARNING, fprintf (stdout, "error incorrect precision (%d)\n", precision)); return 0; } - - /* store context */ - tmp.answer = answer; - tmp.argument = argument; - tmp.argument_size = argument_size; - tmp.storage = storage; - tmp.storage_size = storage_size; - tmp.stack = stack; - tmp.stack_size = stack_size; - - /* change context */ - answer = 0; - storage = (programs + n)->storage; - storage_size = (programs + n)->storage_size; - argument = NULL; - argument_size = 0; - stack = (programs + n)->stack; - stack_size = (programs + n)->stack_size; - if (nbargs > 0) { - argument = (double *) callocordie (nbargs, sizeof (double)); - for (i = 0, l = 0; i < nbargs; l++) { - if (args[l]) { - argument[i++] = evaluate_element (args[l], 0); - } - } - argument_size = nbargs; - } - - /* evaluate program */ - element_t *elements = dupelement ((programs + n)->root); - ret = evaluate_element (elements, 0); - delelement (elements); - (programs + n)->answer = answer; - (programs + n)->storage = storage; - (programs + n)->storage_size = storage_size; - if (argument) { - free (argument); - } - (programs + n)->stack = stack; - (programs + n)->stack_size = stack_size; - - /* restore context */ - answer = tmp.answer; - storage = tmp.storage; - storage_size = tmp.storage_size; - argument = tmp.argument; - argument_size = tmp.argument_size; - stack = tmp.stack; - stack_size = tmp.stack_size; - - return ret; -} - -void list () -{ - int i; - fprintf (stdout, "programs:"); - for (i = 0; i < nb_programs; i++) { - fprintf (stdout, " %d", (programs + i)->id); - } - fprintf (stdout, "\n"); + return get_precision (); } -void edit (int id) -{ - int i, n = -1; - - if (programs) { +/* base function */ - /* look for program */ - for (i = 0; i < nb_programs; i++) { - if ((programs + i)->id == id) { - n = i; - break; - } - } - } - if (n == -1) { - VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id)); - return; - } - - /* set string program */ - fprintf (stdout, "edit: %s\n", (programs + n)->string); -} - -void savestring (int id, char *string) +void base (int in, int out) { - int i, n = -1; - - if (programs) { - - /* look for program */ - for (i = 0; i < nb_programs; i++) { - if ((programs + i)->id == id) { - n = i; - break; - } + if ((in > 0) && (in < 37)) { + set_base (in, in); + if ((out > 0) && (out < 37)) { + set_base (in, out); + } else if (out != - 1) { + VERBOSE (WARNING, fprintf (stdout, "error incorrect output base (%d)\n", out)); } - } - - /* unnecesary code */ - //if (n == -1) { - // VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id)); - // return; - //} - //if ((programs + n)->string) { - // free ((programs + n)->string); - //} - - if (string) { - (programs + n)->string = strdup (string); - } -} - -void del (int id) -{ - int i, j, n = -1; - - if (programs) { - - /* look for program */ - for (i = 0; i < nb_programs; i++) { - if ((programs + i)->id == id) { - n = i; - break; - } - } - } - if (n == -1) { - VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id)); - return; - } - - /* clean program */ - if ((programs + n)->storage) { - free ((programs + n)->storage); - } - if ((programs + n)->stack) { - free ((programs + n)->stack); - } - if ((programs + n)->root) { - delelement ((programs + n)->root); - } - if ((programs + n)->string) { - free ((programs + n)->string); - } - - /* remove entry */ - workspace_t *tmp = (workspace_t *) callocordie (nb_programs - 1, sizeof (workspace_t)); - for (i = 0, j = 0; i < nb_programs; i++) { - if (i != n) { - memcpy (tmp + j, programs + i, sizeof (workspace_t)); - j++; - } - } - free (programs); - programs = tmp; - nb_programs--; -} - -/* stack management */ - -double get (int n) -{ - double ret = 0; - if ((n <= 0) || (n > stack_size)) { - VERBOSE (WARNING, fprintf (stdout, "error out of bound (%d/%d)\n", n, stack_size)); - } else { - ret = stack[n - 1]; - } - return ret; -} - -double length () -{ - return stack_size; -} - -double pop () -{ - double ret = 0; - if (stack_size > 0) { - ret = stack[--stack_size]; - double *tmp = (double *) callocordie (stack_size, sizeof (double)); - memcpy (tmp, stack, stack_size * sizeof (double)); - free (stack); - stack = tmp; + } else if (in != -1 ) { + VERBOSE (WARNING, fprintf (stdout, "error incorrect input base (%d)\n", in)); } else { - VERBOSE (WARNING, fprintf (stdout, "error stack empty\n")); - } - return ret; -} - -double push (double val) -{ - double *tmp = (double *) callocordie (stack_size + 1, sizeof (double)); - memcpy (tmp, stack, stack_size * sizeof (double)); - if (stack) { - free (stack); - } - stack = tmp; - stack[stack_size++] = val; - return val; -} - -double put (int n, double val) -{ - if (n <= 0) { - VERBOSE (WARNING, fprintf (stdout, "error out of bound (%d/%d)\n", n, stack_size)); - return 0; - } - if (n > stack_size) { - double *tmp = (double *) callocordie (n, sizeof (double)); - memcpy (tmp, stack, stack_size * sizeof (double)); - free (stack); - stack = tmp; - stack_size = n; - } - stack[n - 1] = val; - return val; -} - -double set (int nbops, element_t **ops) -{ - int i; - if (stack) { - free (stack); - } - stack = NULL; - stack_size = 0; - if (nbops != 0) { - stack = (double *) callocordie (nbops, sizeof (double)); - for (i = 0; i < nbops; i++) { - stack[i] = evaluate_element (ops[i], 0); - } - stack_size = nbops; - } - return stack_size; -} - -void show (void) -{ - int i; - fprintf (stdout, "stack:"); - for (i = 0; i < stack_size; i++) { - fprintf (stdout, " "); - fprintf (stdout, minform, stack[i]); + printf ("base (I/O): %s\n", show_base ()); } - fprintf (stdout, "\n"); -} - -/* stack functions */ - -double max () -{ - double ret = 0; - int i; - if (stack_size < 1) { - VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size)); - return 0; - } - ret = stack[0]; - for (i = 1; i < stack_size; i++) { - if (stack[i] > ret) { - ret = stack[i]; - } - } - return ret; -} - -double mean () -{ - double ret = 0; - int i; - if (stack_size < 1) { - VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size)); - return 0; - } - for (i = 0; i < stack_size; i++) { - ret += stack[i]; - } - return ret / stack_size; -} - -double min () -{ - double ret = 0; - int i; - if (stack_size < 1) { - VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size)); - return 0; - } - ret = stack[0]; - for (i = 1; i < stack_size; i++) { - if (stack[i] < ret) { - ret = stack[i]; - } - } - return ret; -} - -void order () -{ - int i, j; - if (stack_size < 1) { - VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size)); - return; - } - for (i = 0; i < stack_size - 1; i++) { - int done = 0; - for (j = 0; j < stack_size - 1; j++) { - if (stack[j] > stack[j + 1]) { - double tmp = stack[j]; - stack[j] = stack[j + 1]; - stack[j + 1] = tmp; - done = 1; - } - } - if (done == 0) { - break; - } - } -} - -double median () -{ - double ret = 0; - if (stack_size < 3) { - VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size)); - return 0; - } - double *tmp = (double *) callocordie (stack_size, sizeof (double)); - memcpy (tmp, stack, stack_size * sizeof (double)); - order (); - ret = stack[(stack_size - 1)/ 2]; - memcpy (stack, tmp, stack_size * sizeof (double)); - free (tmp); - return ret; -} - -double prod () -{ - double ret = 1; - int i; - if (stack_size < 1) { - VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size)); - return 0; - } - for (i = 0; i < stack_size; i++) { - ret *= stack[i]; - } - return ret; -} - -double sum () -{ - double ret = 0; - int i; - if (stack_size < 1) { - VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size)); - return 0; - } - for (i = 0; i < stack_size; i++) { - ret += stack[i]; - } - return ret; -} - -double variance () -{ - double ret = 0; - double m = 0; - int i; - if (stack_size < 2) { - VERBOSE (WARNING, fprintf (stdout, "error not enough element in stack (%d)\n", stack_size)); - return 0; - } - m = mean (); - for (i = 0; i < stack_size; i++) { - ret += (stack[i] - m) * (stack[i] - m); - } - return ret / stack_size; -} - - -/* help message */ - -void help (void) -{ - fprintf (stdout, "calc is a simple calculator\n\n"); - fprintf (stdout, "arithmetic op.:"); - fprintf (stdout, " + - * / %% ^\n"); - fprintf (stdout, "comparison op.:"); - fprintf (stdout, " == != >= <= > <\n"); - fprintf (stdout, "logical op.:"); - fprintf (stdout, " & | !\n"); - fprintf (stdout, "mathematic func.:"); - fprintf (stdout, " exp ln log pow sqrt\n"); - fprintf (stdout, "trigonometric func.:"); - fprintf (stdout, " acos asin atan cos sin tan\n"); - fprintf (stdout, "error functions:"); - fprintf (stdout, " erf erfc\n"); - fprintf (stdout, "miscellaneous func.:"); - fprintf (stdout, " abs ceil floor\n"); - fprintf (stdout, "storage func.:"); - fprintf (stdout, " clear dec disp inc mem rcl sto\n"); - fprintf (stdout, "control flow prim.:"); - fprintf (stdout, " cond print while {} ;\n"); - fprintf (stdout, "program management:"); - fprintf (stdout, " arg call del edit ls prog\n"); - fprintf (stdout, "stack management:"); - fprintf (stdout, " get len pop push put set show\n"); - fprintf (stdout, "stack func.:"); - fprintf (stdout, " max mean med min ord prod sum var\n"); - fprintf (stdout, "control management:"); - fprintf (stdout, " help quit\n"); - fprintf (stdout, "constants:"); - fprintf (stdout, " ans e pi\n"); } /* evaluate element tree */ @@ -1414,6 +775,9 @@ double evaluate_element (element_t *root, char mask) case Order: case Prod: case Sum: + case Deg: + case Grad: + case Rad: break; case While: if (root->ops[0] == NULL) { @@ -1454,6 +818,14 @@ double evaluate_element (element_t *root, char mask) op0 = evaluate_element (root->ops[0], 0); op1 = (root->ops[1]) ? evaluate_element (root->ops[1], 0) : answer; } + break; + case Precision: + op0 = (root->ops[0]) ? evaluate_element (root->ops[0], 0) : -1; + break; + case Base: + op0 = (root->ops[0]) ? evaluate_element (root->ops[0], 0) : -1; + op1 = (root->ops[1]) ? evaluate_element (root->ops[1], 0) : -1; + break; } switch (root->func) { @@ -1466,12 +838,12 @@ double evaluate_element (element_t *root, char mask) case Mod: return fmod (op0, op1); case Pow: return pow (op0, op1); case Sqr: return sqrt (op0); - case Cos: return cos (op0); - case Sin: return sin (op0); - case Tan: return tan (op0); - case Acos: return acos (op0); - case Asin: return asin (op0); - case Atan: return atan (op0); + case Cos: return cos (op0 / anglefactor); + case Sin: return sin (op0 / anglefactor); + case Tan: return tan (op0 / anglefactor); + case Acos: return acos (op0) * anglefactor; + case Asin: return asin (op0) * anglefactor; + case Atan: return atan (op0) * anglefactor; case Ln: return log (op0); case Log: return log10 (op0); case Exp: return exp (op0); @@ -1518,7 +890,7 @@ double evaluate_element (element_t *root, char mask) break; case Arg: return arg ((int)op0); case Call: - for (i = 1, nb =0; i < root->nbops; i++) { + for (i = 1, nb = 0; i < root->nbops; i++) { if (root->ops[i]) { nb++; } @@ -1567,6 +939,20 @@ double evaluate_element (element_t *root, char mask) return op0 * op0 + op1 * op1; } return variance (); + case Precision: + return format ((int)op0); + case Base: + base ((int)op0, (int)op1); + break; + case Deg: + anglefactor = 180 / M_PI; + break; + case Grad: + anglefactor = 200 / M_PI; + break; + case Rad: + anglefactor = 1; + break; } return 0; @@ -1627,5 +1013,4 @@ void free_completion_list (char **list) } } - /* vim: set ts=4 sw=4 et: */