Index: /branches/eam_branches/ipp-20191011/Ohana/src/opihi/lib.shell/convert_to_RPN.c
===================================================================
--- /branches/eam_branches/ipp-20191011/Ohana/src/opihi/lib.shell/convert_to_RPN.c	(revision 41140)
+++ /branches/eam_branches/ipp-20191011/Ohana/src/opihi/lib.shell/convert_to_RPN.c	(revision 41141)
@@ -79,6 +79,6 @@
     if (!strcmp (argv[i], "datan2")) { type = ST_BINARY; strcpy (argv[i], "d"); goto gotit; }
 
-    if (!strcmp (argv[i], "<-"))     { type = ST_BINARY; strcpy (argv[i], "l"); goto gotit; }
-    if (!strcmp (argv[i], "->"))     { type = ST_BINARY; strcpy (argv[i], "r"); goto gotit; }
+    if (!strcmp (argv[i], "<~"))     { type = ST_BINARY; strcpy (argv[i], "l"); goto gotit; }
+    if (!strcmp (argv[i], "~>"))     { type = ST_BINARY; strcpy (argv[i], "r"); goto gotit; }
 
     if (!strcmp (argv[i], ","))      { type = ST_COMMA; goto gotit; }
Index: /branches/eam_branches/ipp-20191011/Ohana/src/opihi/lib.shell/parse.c
===================================================================
--- /branches/eam_branches/ipp-20191011/Ohana/src/opihi/lib.shell/parse.c	(revision 41140)
+++ /branches/eam_branches/ipp-20191011/Ohana/src/opihi/lib.shell/parse.c	(revision 41141)
@@ -66,5 +66,5 @@
 	/* dvomath returns a new string, or NULL, with the result of the expression */
 	val = dvomath (1, &V1, &size, 0);
-	if (val == NULL) goto error;
+	if (val == NULL) { print_error (); goto error; }
 	fval += atof(val);
 	// save the result
@@ -88,5 +88,5 @@
 	/* dvomath returns a new string, or NULL, with the result of the expression */
 	val = dvomath (1, &V1, &size, 0);
-	if (val == NULL) goto error;
+	if (val == NULL) { print_error (); goto error; }
 	fval -= atof(val);
 	// save the result
Index: /branches/eam_branches/ipp-20191011/Ohana/src/opihi/lib.shell/stack_math.c
===================================================================
--- /branches/eam_branches/ipp-20191011/Ohana/src/opihi/lib.shell/stack_math.c	(revision 41140)
+++ /branches/eam_branches/ipp-20191011/Ohana/src/opihi/lib.shell/stack_math.c	(revision 41141)
@@ -34,5 +34,5 @@
     case '?': SSS_FUNC(M1 ? M2: M3);
     default:
-      snprintf (line, 512, "error: op %c not defined!", op[0]);
+      snprintf (line, 512, "error: op %c not defined as scalar trinary op!", op[0]);
       push_error (line);
       return (FALSE);
@@ -162,5 +162,5 @@
     case '?': VVV_FUNC(*M1 ? *M2: *M3);
     default:
-      snprintf (line, 512, "error: op %c not defined!", op[0]);
+      snprintf (line, 512, "error: op %c not defined as vector trinary op!", op[0]);
       push_error (line);
       return (FALSE);
@@ -227,5 +227,5 @@
     case '?': MMM_FUNC(*M1 ? *M2: *M3);
     default:
-      snprintf (line, 512, "error: op %c not defined!", op[0]);
+      snprintf (line, 512, "error: op %c not defined as matrix trinary op!", op[0]);
       push_error (line);
       return (FALSE);
@@ -358,8 +358,10 @@
     case 'O': VV_FUNC(ST_SCALAR_INT, (*M1 || *M2) ? 1 : 0);
 
+    // for the bitshift operators, we have to treat the INT and FLT values differently
+    // this makes the operator incompatible with the macros used above
     case 'l': {
+      CopyVector (OUT[0].vector, V1[0].vector);
       if ((V1->vector->type == OPIHI_FLT) || (V2->vector->type == OPIHI_FLT)) {
 	// bitshift is not valid with float valuess
-	CopyVector (OUT[0].vector, V1[0].vector);
 	for (i = 0; i < Nx; i++) {
 	  OUT[0].vector[0].elements.Flt[i] = NAN;
@@ -378,4 +380,5 @@
 
     case 'r': {
+      CopyVector (OUT[0].vector, V1[0].vector);
       if ((V1->vector->type == OPIHI_FLT) || (V2->vector->type == OPIHI_FLT)) {
 	// bitshift is not valid with float valuess
@@ -397,5 +400,5 @@
 
     default:
-      snprintf (line, 512, "error: op %c not defined!", op[0]);
+      snprintf (line, 512, "error: op %c not defined for (vector OP vector)!", op[0]);
       push_error (line);
       return (FALSE);
@@ -509,8 +512,10 @@
     case 'O': SV_FUNC(ST_SCALAR_INT, (M1 || *M2) ? 1 : 0);
 
+    // for the bitshift operators, we have to treat the INT and FLT values differently
+    // this makes the operator incompatible with the macros used above
     case 'l': {
-      if (V2->vector->type == OPIHI_FLT) {
+      CopyVector (OUT[0].vector, V2[0].vector);
+      if ((V1->type == ST_SCALAR_FLT) || (V2->vector->type == OPIHI_FLT)) {
 	// bitshift is not valid with float valuess
-	CopyVector (OUT[0].vector, V2[0].vector);
 	for (i = 0; i < Nx; i++) {
 	  OUT[0].vector[0].elements.Flt[i] = NAN;
@@ -528,7 +533,7 @@
 
     case 'r': {
-      if (V2->vector->type == OPIHI_FLT) {
+      CopyVector (OUT[0].vector, V2[0].vector);
+      if ((V1->type == ST_SCALAR_FLT) || (V2->vector->type == OPIHI_FLT)) {
 	// bitshift is not valid with float valuess
-	CopyVector (OUT[0].vector, V2[0].vector);
 	for (i = 0; i < Nx; i++) {
 	  OUT[0].vector[0].elements.Flt[i] = NAN;
@@ -546,5 +551,5 @@
 
     default:
-      snprintf (line, 512, "error: op %c not defined!", op[0]);
+      snprintf (line, 512, "error: op %c not defined for (scalar OP vector)!", op[0]);
       push_error (line);
       return (FALSE);
@@ -655,7 +660,7 @@
 
     case 'l': {
-      if (V1->vector->type == OPIHI_FLT) {
+      CopyVector (OUT[0].vector, V1[0].vector);
+      if ((V1->vector->type == OPIHI_FLT) || (V2->type == ST_SCALAR_FLT)) {
 	// bitshift is not valid with float valuess
-	CopyVector (OUT[0].vector, V1[0].vector);
 	for (i = 0; i < Nx; i++) {
 	  OUT[0].vector[0].elements.Flt[i] = NAN;
@@ -673,5 +678,6 @@
 
     case 'r': {
-      if (V1->vector->type == OPIHI_FLT) {
+      CopyVector (OUT[0].vector, V1[0].vector);
+      if ((V1->vector->type == OPIHI_FLT) || (V2->type == ST_SCALAR_FLT)) {
 	// bitshift is not valid with float valuess
 	CopyVector (OUT[0].vector, V1[0].vector);
@@ -691,5 +697,5 @@
 
     default:
-      snprintf (line, 512, "error: op %c not defined!", op[0]);
+      snprintf (line, 512, "error: op %c not defined for (vector OP scalar)!", op[0]);
       push_error (line);
       return (FALSE);
@@ -784,42 +790,6 @@
     case 'O': MV_FUNC((*M1 || *M2) ? 1 : 0);
 
-    case 'l': {
-      if (V1->vector->type == OPIHI_FLT) {
-	// bitshift is not valid with float valuess
-	CopyVector (OUT[0].vector, V1[0].vector);
-	for (i = 0; i < Nx; i++) {
-	  OUT[0].vector[0].elements.Flt[i] = NAN;
-	}
-	break;
-      }
-      opihi_int *M1  =  V1[0].vector[0].elements.Int;
-      opihi_int  M2  =  V2[0].IntValue;					\
-      opihi_int *out = OUT[0].vector[0].elements.Int;
-      for (i = 0; i < Nx; i++, out++, M1++) {
-  	*out = *M1 << M2;
-      }
-      break;
-    }
-
-    case 'r': {
-      if (V1->vector->type == OPIHI_FLT) {
-	// bitshift is not valid with float valuess
-	CopyVector (OUT[0].vector, V1[0].vector);
-	for (i = 0; i < Nx; i++) {
-	  OUT[0].vector[0].elements.Flt[i] = NAN;
-	}
-	break;
-      }
-      opihi_int *M1  =  V1[0].vector[0].elements.Int;
-      opihi_int  M2  =  V2[0].IntValue;					\
-      opihi_int *out = OUT[0].vector[0].elements.Int;
-      for (i = 0; i < Nx; i++, out++, M1++) {
-  	*out = *M1 >> M2;
-      }
-      break;
-    }
-
     default:
-      snprintf (line, 512, "error: op %c not defined!", op[0]);
+      snprintf (line, 512, "error: op %c not defined for (matrix OP vector)!", op[0]);
       push_error (line);
       return (FALSE);
@@ -918,5 +888,5 @@
     case 'O': VM_FUNC((*M1 || *M2) ? 1 : 0);
     default:
-      snprintf (line, 512, "error: op %c not defined!", op[0]);
+      snprintf (line, 512, "error: op %c not defined for (vector OP matrix)!", op[0]);
       push_error (line);
       return (FALSE);
@@ -999,5 +969,5 @@
     case 'O': MM_FUNC((*M1 || *M2) ? 1 : 0);
     default:
-      snprintf (line, 512, "error: op %c not defined!", op[0]);
+      snprintf (line, 512, "error: op %c not defined for (matrix OP matrix)!", op[0]);
       push_error (line);
       return (FALSE);
@@ -1085,5 +1055,5 @@
     case 'O': MS_FUNC((*M1 || M2) ? 1 : 0);
     default:
-      snprintf (line, 512, "error: op %c not defined!", op[0]);
+      snprintf (line, 512, "error: op %c not defined for (matrix OP scalar)!", op[0]);
       push_error (line);
       return (FALSE);
@@ -1162,5 +1132,5 @@
     case 'O': SM_FUNC((M1 || *M2) ? 1 : 0);
     default:
-      snprintf (line, 512, "error: op %c not defined!", op[0]);
+      snprintf (line, 512, "error: op %c not defined for (scalar OP matrix)!", op[0]);
       push_error (line);
       return (FALSE);
@@ -1244,6 +1214,37 @@
     case 'A': SS_FUNC(ST_SCALAR_INT, (M1 && M2) ? 1 : 0);
     case 'O': SS_FUNC(ST_SCALAR_INT, (M1 || M2) ? 1 : 0);
+
+    // for the bitshift operators, we have to treat the INT and FLT values differently
+    // this makes the operator incompatible with the macros used above
+    case 'l': {
+      if ((V1->type == ST_SCALAR_FLT) || (V2->type == ST_SCALAR_FLT)) {
+	// bitshift is not valid with float valuess
+	OUT[0].type = ST_SCALAR_FLT;
+	OUT[0].FltValue = NAN;
+	break;
+      }
+      opihi_int M1 = V1[0].IntValue;
+      opihi_int M2 = V2[0].IntValue;
+      OUT[0].type = ST_SCALAR_INT;
+      OUT[0].IntValue = M1 << M2;
+      break;
+    }
+
+    case 'r': {
+      if ((V1->type == ST_SCALAR_FLT) || (V2->type == ST_SCALAR_FLT)) {
+	// bitshift is not valid with float valuess
+	OUT[0].type = ST_SCALAR_FLT;
+	OUT[0].FltValue = NAN;
+	break;
+      }
+      opihi_int M1 = V1[0].IntValue;
+      opihi_int M2 = V2[0].IntValue;
+      OUT[0].type = ST_SCALAR_INT;
+      OUT[0].IntValue = M1 >> M2;
+      break;
+    }
+
     default:
-      snprintf (line, 512, "error: op %c not defined!", op[0]);
+      snprintf (line, 512, "error: op %c not defined for (scalar OP scalar)!", op[0]);
       push_error (line);
       return (FALSE);
@@ -1318,6 +1319,4 @@
 int S_unary (StackVar *OUT, StackVar *V1, char *op) {
 
-  char line[512]; // this is only used to report an error 
-  
 # define S_FUNC(OP,FTYPE) {						\
     if (V1->type == ST_SCALAR_FLT) {					\
@@ -1360,5 +1359,4 @@
   if (!strcmp (op, "asinh"))  S_FUNC(asinh (M1), ST_SCALAR_FLT);
   if (!strcmp (op, "acosh"))  S_FUNC(acosh (M1), ST_SCALAR_FLT);
-  if (!strcmp (op, "lgamma")) S_FUNC(lgamma (M1), ST_SCALAR_FLT);
   if (!strcmp (op, "sin"))    S_FUNC(sin (M1), ST_SCALAR_FLT);
   if (!strcmp (op, "cos"))    S_FUNC(cos (M1), ST_SCALAR_FLT);
@@ -1373,4 +1371,5 @@
   if (!strcmp (op, "dacos"))  S_FUNC(acos (M1)*DEG_RAD, ST_SCALAR_FLT);
   if (!strcmp (op, "datan"))  S_FUNC(atan (M1)*DEG_RAD, ST_SCALAR_FLT);
+  if (!strcmp (op, "lgamma")) S_FUNC(lgamma (M1), ST_SCALAR_FLT);
   if (!strcmp (op, "rnd"))    S_FUNC(0.0*M1 + drand48(), ST_SCALAR_FLT);
   if (!strcmp (op, "drnd"))   S_FUNC(0.0*M1 + drand48(), ST_SCALAR_FLT);
@@ -1385,8 +1384,9 @@
 
   clear_stack (V1);
-  snprintf (line, 512, "error: op %s not defined!", op);
+
+  char line[512]; // this is only used to report an error 
+  snprintf (line, 512, "error: op %s not defined as unary scalar op!", op);
   push_error (line);
   return (FALSE);
-
 }
 
@@ -1445,5 +1445,4 @@
   if (!strcmp (op, "asinh"))  V_FUNC(asinh(*M1), ST_SCALAR_FLT);
   if (!strcmp (op, "acosh"))  V_FUNC(acosh(*M1), ST_SCALAR_FLT);
-  if (!strcmp (op, "lgamma")) V_FUNC(lgamma(*M1), ST_SCALAR_FLT);
   if (!strcmp (op, "sin"))    V_FUNC(sin(*M1), ST_SCALAR_FLT);
   if (!strcmp (op, "cos"))    V_FUNC(cos(*M1), ST_SCALAR_FLT);
@@ -1458,23 +1457,23 @@
   if (!strcmp (op, "dacos"))  V_FUNC(acos(*M1)*DEG_RAD, ST_SCALAR_FLT);
   if (!strcmp (op, "datan"))  V_FUNC(atan(*M1)*DEG_RAD, ST_SCALAR_FLT);
+  if (!strcmp (op, "lgamma")) V_FUNC(lgamma(*M1), ST_SCALAR_FLT);
   if (!strcmp (op, "rnd"))    V_FUNC(drand48(), ST_SCALAR_FLT);
   if (!strcmp (op, "drnd"))   V_FUNC(drand48(), ST_SCALAR_FLT);
   if (!strcmp (op, "lrnd"))   V_FUNC(lrand48(), ST_SCALAR_INT);
   if (!strcmp (op, "mrnd"))   V_FUNC(mrand48(), ST_SCALAR_INT);
-  if (!strcmp (op, "ramp"))   V_FUNC(i, ST_SCALAR_INT);
-  if (!strcmp (op, "zero"))   V_FUNC(0, ST_SCALAR_INT);
   if (!strcmp (op, "not"))    V_FUNC(!(*M1), ST_SCALAR_INT);
   if (!strcmp (op, "--"))     V_FUNC(-1*(*M1), ST_SCALAR_INT); // NOTE: opihi_int is signed
   if (!strcmp (op, "isinf"))  V_FUNC(!finite(*M1), ST_SCALAR_FLT);
   if (!strcmp (op, "isnan"))  V_FUNC(isnan((opihi_flt)(*M1)), ST_SCALAR_FLT);
+  if (!strcmp (op, "ramp"))   V_FUNC(i, ST_SCALAR_INT);
   if (!strcmp (op, "xramp"))  V_FUNC(i, ST_SCALAR_INT);
   if (!strcmp (op, "yramp"))  V_FUNC(0, ST_SCALAR_INT);
   if (!strcmp (op, "zramp"))  V_FUNC(0, ST_SCALAR_INT);
+  if (!strcmp (op, "zero"))   V_FUNC(0, ST_SCALAR_INT);
   /* xramp, yramp, zramp above only make sense for matrices. for vectors, xramp = ramp, yramp = zero */
 
 # undef V_FUNC
 
-escape:
-
+  // free the temp vector if needed
   if (V1[0].type == ST_VECTOR_TMP) {
     free (V1[0].vector[0].elements.Ptr);
@@ -1484,9 +1483,24 @@
 
   clear_stack (V1);
+
+  char line[512]; // this is only used to report an error 
+  snprintf (line, 512, "error: op %s not defined as unary vector op!", op);
+  push_error (line);
+  return (FALSE);
+
+escape:
+
+  if (V1[0].type == ST_VECTOR_TMP) {
+    free (V1[0].vector[0].elements.Ptr);
+    free (V1[0].vector);
+    V1[0].vector = NULL;
+  }  
+
+  clear_stack (V1);
   return (TRUE);
 
 }
 
-# define M_FUNC(OP) { for (i = 0; i < Npix; i++, out++, M1++) { *out = (OP); }}
+# define M_FUNC(OP) { for (i = 0; i < Npix; i++, out++, M1++) { *out = (OP); } goto escape; }
 
 int M_unary (StackVar *OUT, StackVar *V1, char *op) {
@@ -1510,5 +1524,5 @@
 // if (!strcmp (op, "rint"))  { for (i = 0; i < Npix; i++, out++, M1++) { *out = nearbyint (*M1); }}
   
-  if (!strcmp (op, "="))     { }
+  if (!strcmp (op, "="))      { goto escape; }
   if (!strcmp (op, "abs"))    M_FUNC(fabs(*M1));
   if (!strcmp (op, "int"))    M_FUNC((opihi_flt)(long long)(*M1));
@@ -1525,5 +1539,4 @@
   if (!strcmp (op, "asinh"))  M_FUNC(asinh(*M1));
   if (!strcmp (op, "acosh"))  M_FUNC(acosh(*M1));
-  if (!strcmp (op, "lgamma")) M_FUNC(lgamma(*M1));
   if (!strcmp (op, "sin"))    M_FUNC(sin(*M1));
   if (!strcmp (op, "cos"))    M_FUNC(cos(*M1));
@@ -1538,14 +1551,15 @@
   if (!strcmp (op, "dacos"))  M_FUNC(acos(*M1)*DEG_RAD);
   if (!strcmp (op, "datan"))  M_FUNC(atan(*M1)*DEG_RAD);
-  if (!strcmp (op, "not"))    M_FUNC(!(*M1));
-  if (!strcmp (op, "--"))     M_FUNC(-(*M1));
+  if (!strcmp (op, "lgamma")) M_FUNC(lgamma(*M1));
   if (!strcmp (op, "rnd"))    M_FUNC(drand48());
   if (!strcmp (op, "drnd"))   M_FUNC(drand48());
   if (!strcmp (op, "lrnd"))   M_FUNC(lrand48());
   if (!strcmp (op, "mrnd"))   M_FUNC(mrand48());
+  if (!strcmp (op, "not"))    M_FUNC(!(*M1));
+  if (!strcmp (op, "--"))     M_FUNC(-(*M1));
   if (!strcmp (op, "ramp"))   M_FUNC(i);
-  if (!strcmp (op, "zero"))   M_FUNC(0);
   if (!strcmp (op, "isinf"))  M_FUNC(!finite(*M1));
   if (!strcmp (op, "isnan"))  M_FUNC(isnan(*M1));
+  if (!strcmp (op, "zero"))   M_FUNC(0);
 
   /* xrm and yrm only make sense for 2D matrices. see special meaning for vectors */
@@ -1561,4 +1575,5 @@
       }
     }
+    goto escape; 
   }
   if (!strcmp (op, "yramp")) {
@@ -1573,4 +1588,5 @@
       }
     }
+    goto escape; 
   }
   if (!strcmp (op, "zramp")) {
@@ -1585,6 +1601,22 @@
       }
     }
-  }
-  
+    goto escape; 
+  }
+  
+  if (V1[0].type == ST_MATRIX_TMP) {
+    free (V1[0].buffer[0].header.buffer);
+    free (V1[0].buffer[0].matrix.buffer);
+    free (V1[0].buffer);
+  }
+
+  clear_stack (V1);
+
+  char line[512]; // this is only used to report an error 
+  snprintf (line, 512, "error: op %s not defined as unary matrix op!", op);
+  push_error (line);
+  return (FALSE);
+
+ escape:
+
   if (V1[0].type == ST_MATRIX_TMP) {
     free (V1[0].buffer[0].header.buffer);
