Index: trunk/Ohana/src/opihi/cmd.basic/run_if.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.basic/run_if.c	(revision 2774)
+++ trunk/Ohana/src/opihi/cmd.basic/run_if.c	(revision 2792)
@@ -30,22 +30,7 @@
   /* determine value of conditional expression */
   val = dvomath (1, &argv[1], &size, 0);
-  if (val == NULL) { /* try expression as string op string */
-    char **stack;
-    int Nstack;
+  if (val == NULL) return (FALSE);
+  logic = atof (val); /* warning: round-off error is a danger */ 
 
-    stack = isolate_elements (1, &argv[1], &Nstack); 
-    if (Nstack != 5) goto syntax;
-    if (strcmp (stack[0], "(")) goto syntax;
-    if (strcmp (stack[4], ")")) goto syntax;
-    equals = -1;
-    if (!strcmp (stack[2], "==")) equals = TRUE;
-    if (!strcmp (stack[2], "!=")) equals = TRUE;
-    if (equals == -1) goto syntax;
-    logic = FALSE;
-    if (equals && !strcmp (stack[1], stack[3])) logic = TRUE;
-    if (!equals && strcmp (stack[1], stack[3])) logic = TRUE;
-  } else {
-    logic = atof (val); /* warning: round-off error is a danger */ 
-  }
   if (BreakOnTrue) {
     if (logic) {
Index: trunk/Ohana/src/opihi/include/dvomath.h
===================================================================
--- trunk/Ohana/src/opihi/include/dvomath.h	(revision 2774)
+++ trunk/Ohana/src/opihi/include/dvomath.h	(revision 2792)
@@ -50,5 +50,5 @@
 char        **isolate_elements      PROTO((int argc, char **argv, int *nstack));
 StackVar     *convert_to_RPN        PROTO((int argc, char **argv, int *nstack));
-int           check_stack           PROTO((StackVar *stack, int Nstack));
+int           check_stack           PROTO((StackVar *stack, int Nstack, int validsize));
 int           evaluate_stack        PROTO((StackVar *stack, int *Nstack));
 void          init_stack            PROTO((StackVar *stack));
Index: trunk/Ohana/src/opihi/lib.shell/check_stack.c
===================================================================
--- trunk/Ohana/src/opihi/lib.shell/check_stack.c	(revision 2774)
+++ trunk/Ohana/src/opihi/lib.shell/check_stack.c	(revision 2792)
@@ -1,7 +1,7 @@
 # include "opihi.h"
 
-int check_stack (StackVar *stack, int Nstack) {
+int check_stack (StackVar *stack, int Nstack, int validsize) {
 
-  int i, Nx, Ny, Nv;
+  int i, Nx, Ny, Nv, size;
   char *c, line[128];
 
@@ -10,4 +10,5 @@
   for (i = 0; i < Nstack; i++) {
     if (stack[i].type == 'X') {
+
       /** if this is a number, put it on the list of scalers and move on **/
       stack[i].Float = strtod (stack[i].name, &c);
@@ -17,4 +18,11 @@
 	continue;
       } 
+
+      /** if we demand a scalar, interpret strings as strings */
+      if (validsize == 0) {
+	stack[i].type  = 'W';
+	continue;
+      } 
+	
       /** if this is a matrix, find the dimensions and check with existing values **/
       if (IsBuffer (stack[i].name)) {
@@ -38,4 +46,5 @@
 	continue;
       }
+
       /** if this is a vector, find the dimensions and check with existing values **/
       if (IsVector (stack[i].name)) {
@@ -63,7 +72,10 @@
   }
 
-  /* we return a value which is 1 greater than the object dimension */
-  if (Nx != -1) return (2);
-  if (Nv != -1) return (1);
-  return (0);
+  /* return object dimensions */
+  size = 0;
+  if (Nv != -1) size = 1;
+  if (Nx != -1) size = 2;
+  if (validsize == -1)   return (size);
+  if (validsize != size) return (-1);
+  return (size);
 }
Index: trunk/Ohana/src/opihi/lib.shell/dvomath.c
===================================================================
--- trunk/Ohana/src/opihi/lib.shell/dvomath.c	(revision 2774)
+++ trunk/Ohana/src/opihi/lib.shell/dvomath.c	(revision 2792)
@@ -22,6 +22,5 @@
 
   /* distinguish scalar, vector, matrix, check dimensions */
-  *size = check_stack (stack, Nstack);
-  if ((validsize != -1) && (validsize != *size)) goto error;
+  *size = check_stack (stack, Nstack, validsize);
   if (*size < 0) goto error;
 
Index: trunk/Ohana/src/opihi/lib.shell/evaluate_stack.c
===================================================================
--- trunk/Ohana/src/opihi/lib.shell/evaluate_stack.c	(revision 2774)
+++ trunk/Ohana/src/opihi/lib.shell/evaluate_stack.c	(revision 2792)
@@ -26,5 +26,5 @@
       return (TRUE);
     }
-    fprintf (stderr, "syntax error!\n");
+    push_error ("syntax error!");
     free (tmp_stack.name);
     return (FALSE);
@@ -54,4 +54,22 @@
 	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);
+      TWO_OP ("M","V",MV_binary);
+      TWO_OP ("M","S",MS_binary);
+      TWO_OP ("V","M",VM_binary);
+      TWO_OP ("V","V",VV_binary);
+      TWO_OP ("V","S",VS_binary);
+      TWO_OP ("S","M",SM_binary);
+      TWO_OP ("S","V",SV_binary);
+      TWO_OP ("S","S",SS_binary);      
+      TWO_OP ("W","W",WW_binary);      
+      
+      /*
       if (!strncasecmp (&stack[i - 2].type, "V", 1) && !strncasecmp (&stack[i - 1].type, "V", 1)) 
 	status = VV_binary (&tmp_stack, &stack[i - 2], &stack[i - 1], stack[i].name);
@@ -72,4 +90,18 @@
       if (!strncasecmp (&stack[i - 2].type, "S", 1) && !strncasecmp (&stack[i - 1].type, "S", 1)) 
 	status = SS_binary (&tmp_stack, &stack[i - 2], &stack[i - 1], stack[i].name);
+      if (!strncasecmp (&stack[i - 2].type, "X", 1) && !strncasecmp (&stack[i - 1].type, "X", 1)) 
+	status = XX_binary (&tmp_stack, &stack[i - 2], &stack[i - 1], stack[i].name);
+      */
+
+      /* string op number is not valid */
+      if (!strncasecmp (&stack[i - 2].type, "W", 1) && strncasecmp (&stack[i - 1].type, "W", 1)) {
+	free (tmp_stack.name);
+	return (FALSE);
+      }
+      if (strncasecmp (&stack[i - 2].type, "W", 1) && !strncasecmp (&stack[i - 1].type, "W", 1)) {
+	free (tmp_stack.name);
+	return (FALSE);
+      }
+
       if (!status) {
 	free (tmp_stack.name);
@@ -102,4 +134,11 @@
       if (!strncasecmp (&stack[i - 1].type, "S", 1)) 
 	S_unary (&tmp_stack, &stack[i - 1], stack[i].name);
+
+      /* there are no valid unary string operators */
+      if (!strncasecmp (&stack[i - 1].type, "W", 1)) {
+	fprintf (stderr, "syntax error\n");
+	free (tmp_stack.name);
+	return (FALSE);
+      }
 
       move_stack (&stack[i-1], &tmp_stack);
Index: trunk/Ohana/src/opihi/lib.shell/expand_vectors.c
===================================================================
--- trunk/Ohana/src/opihi/lib.shell/expand_vectors.c	(revision 2774)
+++ trunk/Ohana/src/opihi/lib.shell/expand_vectors.c	(revision 2792)
@@ -37,9 +37,11 @@
       ALLOCATE (val, char, 64);
       sprintf (val, "-1");
+      /* this choice of sentinel prevents us from using 
+	 x[-1], x[-2], and is not really needed */
     } else {
       strncpy (tmpline, p+1, n);
       tmpline[n] = 0;
       val = dvomath (1, &tmpline, &size, 0);
-      if (val == NULL) goto dumpline; /* not really a vector */
+      if (val == NULL) goto dumpline; /* not a valid vector subscript */
     }
     /* find vector name */
Index: trunk/Ohana/src/opihi/lib.shell/parse.c
===================================================================
--- trunk/Ohana/src/opihi/lib.shell/parse.c	(revision 2774)
+++ trunk/Ohana/src/opihi/lib.shell/parse.c	(revision 2792)
@@ -56,6 +56,6 @@
     if (*V1 == 0) goto error;
 
-    /* command replacement.  execute the line, place answer in val. */
     if (*V1 == '`') {
+      /* command replacement.  execute the line, place answer in val. */
 
       /* look for end of line, must be ` */
Index: trunk/Ohana/src/opihi/lib.shell/stack_math.c
===================================================================
--- trunk/Ohana/src/opihi/lib.shell/stack_math.c	(revision 2774)
+++ trunk/Ohana/src/opihi/lib.shell/stack_math.c	(revision 2792)
@@ -1043,4 +1043,28 @@
 
 }
+
+int WW_binary (StackVar *OUT, StackVar *V1, StackVar *V2, char *op) {
+
+  int value;
+  
+  switch (op[0]) { 
+  case 'E': 
+    value = strcmp (V1[0].name, V2[0].name) ? 0 : 1;
+    break; 
+  case 'N': 
+    value = strcmp (V1[0].name, V2[0].name) ? 1 : 0;
+    break; 
+  default:
+    fprintf (stderr, "error: op %c not valid\n", op[0]);
+  }
+
+  strcpy (OUT[0].name, "tmp");
+  OUT[0].Float = value;
+  OUT[0].type = 'S';
+  OUT[0].ptr = &OUT[0].Float;
+  return (TRUE);
+
+}
+
 
 int S_unary (StackVar *OUT, StackVar *V1, char *op) {
