Index: /trunk/Ohana/src/opihi/lib.shell/VariableOps.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/VariableOps.c	(revision 42079)
+++ /trunk/Ohana/src/opihi/lib.shell/VariableOps.c	(revision 42080)
@@ -1,3 +1,4 @@
 # include "opihi.h"
+# define USE_DEPTH 1
 
 Variable *variables;   /* variable to store the list of all variables */
@@ -27,8 +28,9 @@
 
   int i;
-  char *local, *MacroName;
-
-  /* a local variable has the form (macroname).(varname) */
-  MacroName = GetMacroName ();
+  char *local;
+
+  /* a local variable has the form (macroname).(depth).(varname) */
+  char *MacroName = GetMacroName ();
+  int   MacroDepth = GetMacroDepth ();
 
   /* need to use a mutex to prevent two threads from changing variable list simultaneously */
@@ -36,6 +38,11 @@
 
   /* look for existing local variable */
-  ALLOCATE (local, char, strlen(name) + strlen(MacroName) + 2);
-  sprintf (local, "%s.%s", MacroName, name);
+  int maxLen = strlen(name) + strlen(MacroName) + 16;
+  ALLOCATE (local, char, maxLen);
+  if (USE_DEPTH) {
+    snprintf (local, maxLen, "%s.%d.%s", MacroName, MacroDepth, name);
+  } else {
+    snprintf (local, maxLen, "%s.%s", MacroName, name);
+  }
   for (i = 0; i < Nvariables; i++) {
     if (!strcmp (local, variables[i].name)) {
@@ -59,7 +66,8 @@
 
   int i;
-  char *local, *MacroName;
-
-  MacroName = GetMacroName ();
+  char *local;
+
+  char *MacroName = GetMacroName ();
+  int   MacroDepth = GetMacroDepth ();
 
   /* need to use a mutex to prevent two threads from changing variable list simultaneously */
@@ -67,6 +75,11 @@
 
   /* look for local variable first */
-  ALLOCATE (local, char, strlen(name) + strlen(MacroName) + 2);
-  sprintf (local, "%s.%s", MacroName, name);
+  int maxLen = strlen(name) + strlen(MacroName) + 16;
+  ALLOCATE (local, char, maxLen);
+  if (USE_DEPTH) {
+    snprintf (local, maxLen, "%s.%d.%s", MacroName, MacroDepth, name);
+  } else {
+    snprintf (local, maxLen, "%s.%s", MacroName, name);
+  }
   for (i = 0; i < Nvariables; i++) {
     if (!strcmp (local, variables[i].name)) {
@@ -122,11 +135,17 @@
   
   int i;
-  char *local, *MacroName;
-
-  MacroName = GetMacroName ();
+  char *local;
+
+  char *MacroName = GetMacroName ();
+  int   MacroDepth = GetMacroDepth ();
 
   /* look for local variable first */
-  ALLOCATE (local, char, strlen(name) + strlen(MacroName) + 2);
-  sprintf (local, "%s.%s", MacroName, name);
+  int maxLen = strlen(name) + strlen(MacroName) + 16;
+  ALLOCATE (local, char, maxLen);
+  if (USE_DEPTH) {
+    snprintf (local, maxLen, "%s.%d.%s", MacroName, MacroDepth, name);
+  } else {
+    snprintf (local, maxLen, "%s.%s", MacroName, name);
+  }
 
   /* need to use a mutex to prevent another thread from misleading on size of Nvariables */
Index: /trunk/Ohana/src/opihi/lib.shell/VectorOps.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/VectorOps.c	(revision 42079)
+++ /trunk/Ohana/src/opihi/lib.shell/VectorOps.c	(revision 42080)
@@ -103,6 +103,5 @@
     if (mode == OLDVECTOR) goto error;
     // validate vector name syntax
-//    vector with ":" will be failed so I comment it out CCL
-//    if (!IsVectorNameValid(name)) { gprint (GP_ERR, "invalid vector name %s\n", name); return NULL; }
+    if (!IsVectorNameValid(name)) { gprint (GP_ERR, "invalid vector name %s\n", name); return NULL; }
     pthread_mutex_lock (&mutex);
     Nvectors ++;
Index: /trunk/Ohana/src/opihi/lib.shell/convert_to_RPN.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/convert_to_RPN.c	(revision 42079)
+++ /trunk/Ohana/src/opihi/lib.shell/convert_to_RPN.c	(revision 42080)
@@ -71,5 +71,14 @@
     if (!strcmp (argv[i], "isnan"))  { type = ST_UNARY; goto gotit; }
 
+    /* string-valid unary operations */
+    if (!strcmp (argv[i], "isword")) { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "isnum"))  { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "isint"))  { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "isflt"))  { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "length")) { type = ST_UNARY; goto gotit; }
+
     /* binary operations */
+    // NOTE: I archically use the first character of the function name in a switch to identify the operation
+    // I should re-work this with an enum which defines the operatino
     if (!strcmp (argv[i], "^"))      { type = ST_POWER; goto gotit; }
 
Index: /trunk/Ohana/src/opihi/lib.shell/evaluate_stack.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/evaluate_stack.c	(revision 42079)
+++ /trunk/Ohana/src/opihi/lib.shell/evaluate_stack.c	(revision 42080)
@@ -124,5 +124,5 @@
 	THREE_OP (ST_SCALAR_INT,SSS_trinary);
 
-	/* there are no valid unary string operators */
+	/* there are no valid trinary string operators */
 	snprintf (line, 512, "invalid operands for trinary operator %s (mismatch types?)\n(Note that the : in a trinary operation must be protected by spaces)", stack[i].name);
 	push_error (line);
@@ -260,5 +260,6 @@
 	ONE_OP (ST_SCALAR_FLT, S_unary);
 
-	/* there are no valid unary string operators */
+	ONE_OP (ST_STRING, W_unary);
+
 	snprintf (line, 512, "invalid operand for unary operator %s (undefined value?)", stack[i].name);
 	push_error (line);
Index: /trunk/Ohana/src/opihi/lib.shell/expand_vectors.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/expand_vectors.c	(revision 42079)
+++ /trunk/Ohana/src/opihi/lib.shell/expand_vectors.c	(revision 42080)
@@ -135,7 +135,6 @@
     // include/shell.h.  A vector name cannot include a colon, while a variable name
     // cannot include a dot.
-    // temporary remove ISVEC check until ":" issue fixed CCL
-    //for (w = p - 1; (w >= line) && !OHANA_WHITESPACE(*w) && ISVEC(*w); w--);
-    for (w = p - 1; (w >= line) && !OHANA_WHITESPACE(*w); w--);
+
+    for (w = p - 1; (w >= line) && !OHANA_WHITESPACE(*w) && ISVEC(*w); w--);
     w ++;
     n = (int)(p - w);
Index: /trunk/Ohana/src/opihi/lib.shell/stack_math.c
===================================================================
--- /trunk/Ohana/src/opihi/lib.shell/stack_math.c	(revision 42079)
+++ /trunk/Ohana/src/opihi/lib.shell/stack_math.c	(revision 42080)
@@ -1500,4 +1500,25 @@
     if ((FTYPE == ST_SCALAR_INT) && (V1->type == ST_SCALAR_INT)) {	\
       opihi_int M1  = V1[0].IntValue;					\
+      OUT[0].type = ST_SCALAR_INT;					\
+      OUT[0].IntValue = OP;						\
+      clear_stack (V1);							\
+      return (TRUE);							\
+    }									\
+  }
+
+# define W_FUNC(OP,FTYPE) {						\
+    if (V1->type == ST_SCALAR_FLT) {					\
+      OUT[0].type = ST_SCALAR_FLT;					\
+      OUT[0].FltValue = OP;						\
+      clear_stack (V1);							\
+      return (TRUE);							\
+    }									\
+    if ((FTYPE == ST_SCALAR_FLT) && (V1->type == ST_SCALAR_INT)) {	\
+      OUT[0].type = ST_SCALAR_FLT;					\
+      OUT[0].FltValue = OP;						\
+      clear_stack (V1);							\
+      return (TRUE);							\
+    }									\
+    if ((FTYPE == ST_SCALAR_INT) && (V1->type == ST_SCALAR_INT)) {	\
       OUT[0].type = ST_SCALAR_INT;					\
       OUT[0].IntValue = OP;						\
@@ -1536,8 +1557,4 @@
   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);
-  if (!strcmp (op, "lrnd"))   S_FUNC(0*M1 + lrand48(), ST_SCALAR_INT);
-  if (!strcmp (op, "mrnd"))   S_FUNC(0*M1 + mrand48(), ST_SCALAR_INT);
   if (!strcmp (op, "not"))    S_FUNC(!(M1), ST_SCALAR_INT);
   if (!strcmp (op, "--"))     S_FUNC(-1*M1, ST_SCALAR_INT); // NOTE: opihi_int is signed, 
@@ -1545,10 +1562,49 @@
   if (!strcmp (op, "isnan"))  S_FUNC(isnan((opihi_flt)(M1)), ST_SCALAR_FLT); // XXX modify in future   
 
+  // these ops do not use the V1 value (W_FUNC does define a temp variable M1)
+  if (!strcmp (op, "rnd"))    W_FUNC(drand48(), ST_SCALAR_FLT);
+  if (!strcmp (op, "drnd"))   W_FUNC(drand48(), ST_SCALAR_FLT);
+  if (!strcmp (op, "lrnd"))   W_FUNC(lrand48(), ST_SCALAR_INT);
+  if (!strcmp (op, "mrnd"))   W_FUNC(mrand48(), ST_SCALAR_INT);
+
+  // these are also valid for string values
+  if (!strcmp (op, "isword")) W_FUNC(FALSE, ST_SCALAR_INT);
+  if (!strcmp (op, "isnum"))  W_FUNC(TRUE,  ST_SCALAR_INT);
+  if (!strcmp (op, "isint"))  W_FUNC((V1->type == ST_SCALAR_INT), ST_SCALAR_INT);
+  if (!strcmp (op, "isflt"))  W_FUNC((V1->type == ST_SCALAR_FLT), ST_SCALAR_INT);
+
 # undef S_FUNC
-
-  clear_stack (V1);
-
-  char line[512]; // this is only used to report an error 
-  snprintf (line, 512, "error: op %s not defined as unary scalar op!", op);
+# undef W_FUNC
+
+  clear_stack (V1);
+
+  char line[512]; // this is only used to report an error 
+  snprintf (line, 512, "error: op %s not defined as unary scalar op for a numerical value!", op);
+  push_error (line);
+  return (FALSE);
+}
+
+int W_unary (StackVar *OUT, StackVar *V1, char *op) {
+
+# define W_FUNC(VALUE) {						\
+    OUT[0].type = ST_SCALAR_INT;					\
+    OUT[0].IntValue = VALUE;						\
+    clear_stack (V1);							\
+    return (TRUE);							\
+  }
+
+  // string unary functions (all result in int output values)
+  if (!strcmp (op, "isword")) W_FUNC(TRUE);
+  if (!strcmp (op, "isnum"))  W_FUNC(FALSE);
+  if (!strcmp (op, "isint"))  W_FUNC(FALSE);
+  if (!strcmp (op, "isflt"))  W_FUNC(FALSE);
+  if (!strcmp (op, "length")) W_FUNC(strlen(V1[0].name));
+
+# undef W_FUNC
+
+  clear_stack (V1);
+
+  char line[512]; // this is only used to report an error 
+  snprintf (line, 512, "error: op %s not defined as unary scalar op for a string value!", op);
   push_error (line);
   return (FALSE);
