new command: base
[calc.git] / parser.c
index 94f4c73fd0d752910b28d70ca02261c81446ea65..119733f9afb4e613347558d9db50cc0f367a9f06 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -62,7 +62,7 @@ keyword_t operators[NB_OPERATORS] = {
     { "|",   Or, 2, 1, -2}
 };
 
-#define NB_FUNCTIONS 51
+#define NB_FUNCTIONS 52
 keyword_t functions[NB_FUNCTIONS] = {
     { "sqrt", Sqr, 1, 4, 5},
     { "pow",  Pow, 2, 3, 5},
@@ -114,7 +114,8 @@ 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}
+    { "format", Precision, 1, 6, 9},
+    { "base", Base, 2, 4, 9}
 };
 
 #define NB_CONSTANTS 3
@@ -373,7 +374,7 @@ element_t *parser (char *str, char **next, int prio)
 
         VERBOSE (DEBUG, fprintf (stdout, "start processing value\n"));
         char *pt;
-        double value = (ibase == 10) ? strtod (str, &pt) : strtoul (str, &pt, ibase);
+        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)) {
@@ -521,6 +522,7 @@ void print_element (element_t *root, int level)
     case Sum: func = "Sum"; break;
     case Variance: func = "Variance"; break;
     case Precision: func = "Precision"; break;
+    case Base: func = "Base"; break;
     }
 
     fprintf (stdout, "Function: %s\n", func);
@@ -616,11 +618,43 @@ void help (void)
     fprintf (stdout, "stack func.:");
     fprintf (stdout, " max mean med min ord prod sum var\n");
     fprintf (stdout, "control management:");
-    fprintf (stdout, " format help quit\n");
+    fprintf (stdout, " base format help quit\n");
     fprintf (stdout, "constants:");
     fprintf (stdout, " 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;
+    }
+    return get_precision ();
+}
+
+/* base function */
+
+void base (int in, int out)
+{
+    if (in > 0) {
+        set_base (in, in);
+        if (out > 0) {
+            set_base (in, out);
+        } else if (out != - 1) {
+            VERBOSE (WARNING, fprintf (stdout, "error incorrect output base (%d)\n", out));
+        }
+    } else if (in != -1 ) {
+        VERBOSE (WARNING, fprintf (stdout, "error incorrect input base (%d)\n", in));
+    } else {
+        printf ("base (I/O): %s\n", show_base ());
+    }
+}
+
 /* evaluate element tree */
 
 #define MASK_SUB 0x1
@@ -777,6 +811,10 @@ double evaluate_element (element_t *root, char mask)
     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) {
@@ -891,14 +929,10 @@ double evaluate_element (element_t *root, char mask)
         }
         return variance ();
     case Precision:
-        if (op0 > 0) {
-            set_precision ((int)op0);
-            set_format ();
-        } else if (op0 != -1) {
-            VERBOSE (WARNING, fprintf (stdout, "error incorrect precision (%g)\n", op0));
-            return 0;
-        }
-        return get_precision();
+        return format ((int)op0);
+    case Base:
+        base (op0, op1);
+        break;
     }
 
     return 0;