Index: /trunk/Ohana/src/opihi/lib.shell/convert_to_RPN.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/convert_to_RPN.c	(revision 4305)
+++ /trunk/Ohana/src/opihi/lib.shell/convert_to_RPN.c	(revision 4306)
@@ -23,65 +23,67 @@
     type = 0;
     /* unary operations */
-    if (!strcmp (argv[i], "abs"))    { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "int"))    { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "exp"))    { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "ten"))    { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "log"))    { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "ln"))     { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "sqrt"))   { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "erf"))    { type = 7; goto gotit; }
-
-    if (!strcmp (argv[i], "sinh"))   { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "cosh"))   { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "asinh"))  { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "acosh"))  { type = 7; goto gotit; }
-
-    if (!strcmp (argv[i], "sin"))    { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "cos"))    { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "tan"))    { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "dsin"))   { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "dcos"))   { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "dtan"))   { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "asin"))   { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "acos"))   { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "atan"))   { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "dasin"))  { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "dacos"))  { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "datan"))  { type = 7; goto gotit; }
-
-    if (!strcmp (argv[i], "lgamma")) { type = 7; goto gotit; }
-
-    if (!strcmp (argv[i], "rnd"))    { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "xramp"))  { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "yramp"))  { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "ramp"))   { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "zero"))   { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "--"))     { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "not"))    { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "isinf"))  { type = 7; goto gotit; }
-    if (!strcmp (argv[i], "isnan"))  { type = 7; goto gotit; }
+    if (!strcmp (argv[i], "abs"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "int"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "exp"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "ten"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "log"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "ln"))     { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "sqrt"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "erf"))    { type = 9; goto gotit; }
+
+    if (!strcmp (argv[i], "sinh"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "cosh"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "asinh"))  { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "acosh"))  { type = 9; goto gotit; }
+
+    if (!strcmp (argv[i], "sin"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "cos"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "tan"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "dsin"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "dcos"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "dtan"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "asin"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "acos"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "atan"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "dasin"))  { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "dacos"))  { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "datan"))  { type = 9; goto gotit; }
+
+    if (!strcmp (argv[i], "lgamma")) { type = 9; goto gotit; }
+
+    if (!strcmp (argv[i], "rnd"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "xramp"))  { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "yramp"))  { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "ramp"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "zero"))   { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "--"))     { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "not"))    { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "isinf"))  { type = 9; goto gotit; }
+    if (!strcmp (argv[i], "isnan"))  { type = 9; goto gotit; }
 
     /* binary operations */
-    if (!strcmp (argv[i], "^"))      { type = 6; goto gotit; }
-
-    if (!strcmp (argv[i], "@"))      { type = 5; goto gotit; }
-    if (!strcmp (argv[i], "/"))      { type = 5; goto gotit; }
-    if (!strcmp (argv[i], "*"))      { type = 5; goto gotit; }
-
-    if (!strcmp (argv[i], "+"))      { type = 4; goto gotit; }
-    if (!strcmp (argv[i], "-"))      { type = 4; goto gotit; }
+    if (!strcmp (argv[i], "^"))      { type = 8; goto gotit; }
+
+    if (!strcmp (argv[i], "@"))      { type = 7; goto gotit; }
+    if (!strcmp (argv[i], "/"))      { type = 7; goto gotit; }
+    if (!strcmp (argv[i], "*"))      { type = 7; goto gotit; }
+
+    if (!strcmp (argv[i], "+"))      { type = 6; goto gotit; }
+    if (!strcmp (argv[i], "-"))      { type = 6; goto gotit; }
 	
-    if (!strcmp (argv[i], "<"))      { type = 3; goto gotit; }
-    if (!strcmp (argv[i], ">"))      { type = 3; goto gotit; }
+    if (!strcmp (argv[i], "&"))      { type = 5; goto gotit; }
+    if (!strcmp (argv[i], "|"))      { type = 5; goto gotit; }
+
+    if (!strcmp (argv[i], "<"))      { type = 4; goto gotit; }
+    if (!strcmp (argv[i], ">"))      { type = 4; goto gotit; }
+    if (!strcmp (argv[i], "=="))     { type = 4; strcpy (argv[i], "E"); goto gotit; }
+    if (!strcmp (argv[i], "!="))     { type = 4; strcpy (argv[i], "N"); goto gotit; }
+    if (!strcmp (argv[i], "<="))     { type = 4; strcpy (argv[i], "L"); goto gotit; }
+    if (!strcmp (argv[i], ">="))     { type = 4; strcpy (argv[i], "G"); goto gotit; }
+    if (!strcmp (argv[i], ">>"))     { type = 4; strcpy (argv[i], "U"); goto gotit; }
+    if (!strcmp (argv[i], "<<"))     { type = 4; strcpy (argv[i], "D"); goto gotit; }
+
     if (!strcmp (argv[i], "&&"))     { type = 3; strcpy (argv[i], "A"); goto gotit; }
     if (!strcmp (argv[i], "||"))     { type = 3; strcpy (argv[i], "O"); goto gotit; }
-    if (!strcmp (argv[i], "=="))     { type = 3; strcpy (argv[i], "E"); goto gotit; }
-    if (!strcmp (argv[i], "!="))     { type = 3; strcpy (argv[i], "N"); goto gotit; }
-    if (!strcmp (argv[i], "<="))     { type = 3; strcpy (argv[i], "L"); goto gotit; }
-    if (!strcmp (argv[i], ">="))     { type = 3; strcpy (argv[i], "G"); goto gotit; }
-    if (!strcmp (argv[i], ">>"))     { type = 3; strcpy (argv[i], "U"); goto gotit; }
-    if (!strcmp (argv[i], "<<"))     { type = 3; strcpy (argv[i], "D"); goto gotit; }
-    if (!strcmp (argv[i], "&"))      { type = 3; goto gotit; }
-    if (!strcmp (argv[i], "|"))      { type = 3; goto gotit; }
 
     if (!strcmp (argv[i], "("))      { type = 2; goto gotit; }
@@ -91,61 +93,63 @@
     /* choose how to deal with object */
     switch (type) {
-    case 6:  /* exponentiation */
-      /* pop previous, higher operators from OP stack to stack */
-      for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type > type); j--) {
-	strcpy (stack[Nstack].name, op_stack[j].name);
-	stack[Nstack].type = op_stack[j].type;
+      case 8:  /* exponentiation: 2^2^3 = 64 != 256 (precedence is right-to-left, not left-to-right!) */
+	/* pop previous, higher operators from OP stack to stack */
+	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type > type); j--) {
+	  strcpy (stack[Nstack].name, op_stack[j].name);
+	  stack[Nstack].type = op_stack[j].type;
+	  Nstack ++;
+	  Nop_stack --;
+	}
+	/* push operator on OP stack */
+	strcpy (op_stack[Nop_stack].name, argv[i]);
+	op_stack[Nop_stack].type = type;
+	Nop_stack ++;
+	break;
+      case 9: /* unary OPs */
+      case 7: /* binary OPs */
+      case 6:
+      case 5: 
+      case 4: 
+      case 3: 
+	/* pop previous, higher or equal operators from OP stack to stack */
+	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type >= type); j--) {
+	  strcpy (stack[Nstack].name, op_stack[j].name);
+	  stack[Nstack].type = op_stack[j].type;
+	  Nstack ++;
+	  Nop_stack --;
+	}
+	/* push operator on OP stack */
+	strcpy (op_stack[Nop_stack].name, argv[i]);
+	op_stack[Nop_stack].type = type;
+	Nop_stack ++;
+	break;
+      case 2:  
+	/* push operator on OP stack */
+	strcpy (op_stack[Nop_stack].name, argv[i]);
+	op_stack[Nop_stack].type = type;
+	Nop_stack ++;
+	break;
+      case 1: 
+	/* pop rest of operators from OP stack to stack, looking for '(' */
+	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type != 2); j--) {
+	  strcpy (stack[Nstack].name, op_stack[j].name);
+	  stack[Nstack].type = op_stack[j].type;
+	  Nstack ++;
+	  Nop_stack --;
+	}
+	if ((j == -1) || (op_stack[j].type != 2)) {
+	  push_error ("syntax error: mismatched parenthesis");
+	  Nstack = 0;
+	  goto cleanup;
+	}
+	Nop_stack --;
+	break;
+      case 0:
+	/* place the value (number or vector/matrix name) on stack */
+	/* value of 'X' is used as sentinel until we sort out values */
+	strcpy (stack[Nstack].name, argv[i]);
+	stack[Nstack].type = 'X';
 	Nstack ++;
-	Nop_stack --;
-      }
-      /* push operator on OP stack */
-      strcpy (op_stack[Nop_stack].name, argv[i]);
-      op_stack[Nop_stack].type = type;
-      Nop_stack ++;
-      break;
-    case 7: /* unary OPs */
-    case 5: /* binary OPs */
-    case 4: 
-    case 3: 
-      /* pop previous, higher or equal operators from OP stack to stack */
-      for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type >= type); j--) {
-	strcpy (stack[Nstack].name, op_stack[j].name);
-	stack[Nstack].type = op_stack[j].type;
-	Nstack ++;
-	Nop_stack --;
-      }
-      /* push operator on OP stack */
-      strcpy (op_stack[Nop_stack].name, argv[i]);
-      op_stack[Nop_stack].type = type;
-      Nop_stack ++;
-      break;
-    case 2:  
-      /* push operator on OP stack */
-      strcpy (op_stack[Nop_stack].name, argv[i]);
-      op_stack[Nop_stack].type = type;
-      Nop_stack ++;
-      break;
-    case 1: 
-      /* pop rest of operators from OP stack to stack, looking for '(' */
-      for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type != 2); j--) {
-	strcpy (stack[Nstack].name, op_stack[j].name);
-	stack[Nstack].type = op_stack[j].type;
-	Nstack ++;
-	Nop_stack --;
-      }
-      if ((j == -1) || (op_stack[j].type != 2)) {
-	push_error ("syntax error: mismatched parenthesis");
-	Nstack = 0;
-	goto cleanup;
-      }
-      Nop_stack --;
-      break;
-    case 0:
-      /* place the value (number or vector/matrix name) on stack */
-      /* value of 'X' is used as sentinel until we sort out values */
-      strcpy (stack[Nstack].name, argv[i]);
-      stack[Nstack].type = 'X';
-      Nstack ++;
-      break;
+	break;
     }
   }
@@ -193,13 +197,13 @@
 /* here are the rules for parsing a math AOL line to RPN:
 
-   1) if object is a number, push on stack
-   2) if object is a third order operand (exp, sin, cos), push on op stack
-   3) if object is an open paren, push on op stack,
-   4) if object is a second order operand, push on stack
-   5) if object is a first order operand, pop all second order operands from stack 
-   until paren, push on stack
-   6) if object is an end paren, pop all objects from stack until paren, 
-   pop next stack, if third order op
-   7) if end of line, pop all remaining objects, second order first, etc.
+1) if object is a number, push on stack
+2) if object is a third order operand (exp, sin, cos), push on op stack
+3) if object is an open paren, push on op stack,
+4) if object is a second order operand, push on stack
+5) if object is a first order operand, pop all second order operands from stack 
+until paren, push on stack
+6) if object is an end paren, pop all objects from stack until paren, 
+pop next stack, if third order op
+7) if end of line, pop all remaining objects, second order first, etc.
    
 */
Index: /trunk/Ohana/src/opihi/lib.shell/evaluate_stack.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/evaluate_stack.c	(revision 4305)
+++ /trunk/Ohana/src/opihi/lib.shell/evaluate_stack.c	(revision 4306)
@@ -1,4 +1,12 @@
 # include "opihi.h"
 # define VERBOSE 0
+
+# define TWO_OP(A,B,FUNC) \
+  if (!strncasecmp (&stack[i - 2].type, A, 1) && !strncasecmp (&stack[i - 1].type, B, 1)) \
+    status = FUNC (&tmp_stack, &stack[i - 2], &stack[i - 1], stack[i].name); 
+
+# define ONE_OP(A,FUNC) \
+  if (!strncasecmp (&stack[i - 1].type, A, 1)) \
+    status = FUNC (&tmp_stack, &stack[i - 1], stack[i].name); 
 
 int evaluate_stack (StackVar *stack, int *Nstack) {
@@ -48,5 +56,5 @@
 
     /***** binary operators *****/
-    if ((stack[i].type == 3) || (stack[i].type == 4) || (stack[i].type == 5) || (stack[i].type == 6)) {
+    if ((stack[i].type >= 3) && (stack[i].type <= 8)) {
 
       if (i < 2) {  /* need two variables to operate on */
@@ -56,9 +64,4 @@
 	return (FALSE);
       }
-
-      /* this could be macro generated... */
-      # define TWO_OP(A,B,FUNC) \
-      if (!strncasecmp (&stack[i - 2].type, A, 1) && !strncasecmp (&stack[i - 1].type, B, 1)) \
-	status = FUNC (&tmp_stack, &stack[i - 2], &stack[i - 1], stack[i].name); 
 
       TWO_OP ("M","M",MM_binary);
@@ -91,5 +94,5 @@
 
     /***** unary operators **/
-    if (stack[i].type == 7) {
+    if (stack[i].type == 9) {
 
       if (i < 1) {  /* need one variable to operate on */
@@ -99,10 +102,7 @@
       }
       
-      if (!strncasecmp (&stack[i - 1].type, "M", 1)) 
-	M_unary (&tmp_stack, &stack[i - 1], stack[i].name);
-      if (!strncasecmp (&stack[i - 1].type, "V", 1)) 
-	V_unary (&tmp_stack, &stack[i - 1], stack[i].name);
-      if (!strncasecmp (&stack[i - 1].type, "S", 1)) 
-	S_unary (&tmp_stack, &stack[i - 1], stack[i].name);
+      ONE_OP ("M", M_unary);
+      ONE_OP ("V", V_unary);
+      ONE_OP ("S", S_unary);
 
       /* there are no valid unary string operators */
