Index: /branches/eam_branches/ipp-20130904/Ohana/src/opihi/include/dvomath.h
===================================================================
--- /branches/eam_branches/ipp-20130904/Ohana/src/opihi/include/dvomath.h	(revision 36150)
+++ /branches/eam_branches/ipp-20130904/Ohana/src/opihi/include/dvomath.h	(revision 36151)
@@ -55,7 +55,35 @@
 } Buffer;
 
+typedef enum {
+  ST_NONE,
+  ST_LEFT,
+  ST_RIGHT,
+  ST_COMMA,
+  ST_TRINARY,
+  ST_OR,
+  ST_AND,
+  ST_LOGIC,
+  ST_BITWISE,
+  ST_ADD,
+  ST_TIMES,
+  ST_POWER,
+  ST_UNARY,
+  ST_BINARY,
+
+  ST_VALUE,
+  ST_SCALAR_INT,
+  ST_SCALAR_FLT,
+  ST_VECTOR,
+  ST_VECTOR_TMP,
+  ST_MATRIX,
+  ST_MATRIX_TMP,
+
+  ST_STRING,
+  ST_STRING_TMP,
+} StackVarType;
+
 typedef struct {			/* math stack structure */
   char   *name;
-  char    type;
+  StackVarType type;
   Buffer *buffer;
   Vector *vector;
@@ -77,5 +105,9 @@
 void          delete_stack	    PROTO((StackVar *stack, int Nstack));
 void          clear_stack 	    PROTO((StackVar *stack));
-void          assign_stack 	    PROTO((StackVar *stack, char *name, int type));
+void          assign_stack 	    PROTO((StackVar *stack, char *name, StackVarType type));
+
+int           SSS_trinary           PROTO((StackVar *OUT, StackVar *V1, StackVar *V2, StackVar *V3, char *op));
+int           VVV_trinary           PROTO((StackVar *OUT, StackVar *V1, StackVar *V2, StackVar *V3, char *op));
+int           MMM_trinary           PROTO((StackVar *OUT, StackVar *V1, StackVar *V2, StackVar *V3, char *op));
 
 int           VV_binary             PROTO((StackVar *OUT, StackVar *V1, StackVar *V2, char *op));
Index: /branches/eam_branches/ipp-20130904/Ohana/src/opihi/lib.shell/check_stack.c
===================================================================
--- /branches/eam_branches/ipp-20130904/Ohana/src/opihi/lib.shell/check_stack.c	(revision 36150)
+++ /branches/eam_branches/ipp-20130904/Ohana/src/opihi/lib.shell/check_stack.c	(revision 36151)
@@ -12,5 +12,5 @@
 
   for (i = 0; i < Nstack; i++) {
-    if (stack[i].type == 'X') {
+    if (stack[i].type == ST_VALUE) {
 
       /** if this is a number, put it on the list of scalars and move on.  assume value is
@@ -27,13 +27,13 @@
       stack[i].IntValue = strtol (stack[i].name, &c2, 0);
       if ((fabs(stack[i].FltValue) > MAX_INT) && (c1 == stack[i].name + strlen (stack[i].name))) {
-	stack[i].type  = 'S'; // 'S' == (float)
+	stack[i].type  = ST_SCALAR_FLT; // (float)
 	continue;
       } 
       if (c2 == stack[i].name + strlen (stack[i].name)) {
-	stack[i].type  = 's'; // 's' == (int)
+	stack[i].type  = ST_SCALAR_INT; // (int)
 	continue;
       } 
       if (c1 == stack[i].name + strlen (stack[i].name)) {
-	stack[i].type  = 'S'; // 'S' == (float)
+	stack[i].type  = ST_SCALAR_FLT; // (float)
 	continue;
       } 
@@ -42,5 +42,5 @@
       if (IsBuffer (stack[i].name)) {
 	stack[i].buffer = SelectBuffer (stack[i].name, OLDBUFFER, TRUE);
-	stack[i].type   = 'M';
+	stack[i].type   = ST_MATRIX;
 	if (Nx == -1) {
 	  Nx = stack[i].buffer[0].matrix.Naxis[0];
@@ -63,5 +63,5 @@
       if (IsVector (stack[i].name)) {
 	stack[i].vector = SelectVector (stack[i].name, OLDVECTOR, FALSE);
-	stack[i].type   = 'V';
+	stack[i].type   = ST_VECTOR;
 
 	if (Nv == -1) Nv = stack[i].vector[0].Nelements;
@@ -80,5 +80,5 @@
 
       /* this is not a scalar, vector, or matrix.  must be string */
-      stack[i].type  = 'W';
+      stack[i].type  = ST_STRING;
     }
   }
Index: /branches/eam_branches/ipp-20130904/Ohana/src/opihi/lib.shell/convert_to_RPN.c
===================================================================
--- /branches/eam_branches/ipp-20130904/Ohana/src/opihi/lib.shell/convert_to_RPN.c	(revision 36150)
+++ /branches/eam_branches/ipp-20130904/Ohana/src/opihi/lib.shell/convert_to_RPN.c	(revision 36151)
@@ -4,5 +4,5 @@
 StackVar *convert_to_RPN (int argc, char **argv, int *nstack) {
   
-  int type;
+ StackVarType type;
   int i, j, Nstack, Nop_stack, NSTACK;
   StackVar *stack, *op_stack;
@@ -21,78 +21,82 @@
     
     /* decide on priority of object */
-    type = 0;
+    type = ST_NONE;
+
+    /* trinary operations */
+    if (!strcmp (argv[i], "?"))      { type = ST_TRINARY; goto gotit; }
+    if (!strcmp (argv[i], ":"))      { type = ST_COMMA; goto gotit; }
+
     /* unary operations */
-    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; }
+    if (!strcmp (argv[i], "abs"))    { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "int"))    { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "exp"))    { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "ten"))    { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "log"))    { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "ln"))     { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "sqrt"))   { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "erf"))    { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "sinh"))   { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "cosh"))   { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "asinh"))  { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "acosh"))  { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "sin"))    { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "cos"))    { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "tan"))    { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "dsin"))   { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "dcos"))   { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "dtan"))   { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "asin"))   { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "acos"))   { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "atan"))   { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "dasin"))  { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "dacos"))  { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "datan"))  { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "lgamma")) { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "rnd"))    { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "xramp"))  { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "yramp"))  { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "ramp"))   { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "zero"))   { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "--"))     { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "not"))    { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "isinf"))  { type = ST_UNARY; goto gotit; }
+    if (!strcmp (argv[i], "isnan"))  { type = ST_UNARY; goto gotit; }
 
     /* binary operations */
-    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 = 7; goto gotit; }
-
-    if (!strcmp (argv[i], "+"))      { type = 6; goto gotit; }
-    if (!strcmp (argv[i], "-"))      { type = 6; goto gotit; }
+    if (!strcmp (argv[i], "^"))      { type = ST_POWER; goto gotit; }
+
+    if (!strcmp (argv[i], "atan2"))  { type = ST_BINARY; goto gotit; }
+    if (!strcmp (argv[i], ","))      { type = ST_COMMA; goto gotit; }
+
+    if (!strcmp (argv[i], "@"))      { type = ST_TIMES; goto gotit; }
+    if (!strcmp (argv[i], "/"))      { type = ST_TIMES; goto gotit; }
+    if (!strcmp (argv[i], "*"))      { type = ST_TIMES; goto gotit; }
+    if (!strcmp (argv[i], "%"))      { type = ST_TIMES; goto gotit; }
+
+    if (!strcmp (argv[i], "+"))      { type = ST_ADD; goto gotit; }
+    if (!strcmp (argv[i], "-"))      { type = ST_ADD; 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 = 2; goto gotit; }
-    if (!strcmp (argv[i], ")"))      { type = 1; goto gotit; }
+    if (!strcmp (argv[i], "&"))      { type = ST_BITWISE; goto gotit; }
+    if (!strcmp (argv[i], "|"))      { type = ST_BITWISE; goto gotit; }
+
+    if (!strcmp (argv[i], "<"))      { type = ST_LOGIC; goto gotit; }
+    if (!strcmp (argv[i], ">"))      { type = ST_LOGIC; goto gotit; }
+    if (!strcmp (argv[i], "=="))     { type = ST_LOGIC; strcpy (argv[i], "E"); goto gotit; }
+    if (!strcmp (argv[i], "!="))     { type = ST_LOGIC; strcpy (argv[i], "N"); goto gotit; }
+    if (!strcmp (argv[i], "<="))     { type = ST_LOGIC; strcpy (argv[i], "L"); goto gotit; }
+    if (!strcmp (argv[i], ">="))     { type = ST_LOGIC; strcpy (argv[i], "G"); goto gotit; }
+    if (!strcmp (argv[i], ">>"))     { type = ST_LOGIC; strcpy (argv[i], "U"); goto gotit; }
+    if (!strcmp (argv[i], "<<"))     { type = ST_LOGIC; strcpy (argv[i], "D"); goto gotit; }
+
+    if (!strcmp (argv[i], "&&"))     { type = ST_AND; strcpy (argv[i], "A"); goto gotit; }
+    if (!strcmp (argv[i], "||"))     { type = ST_OR ; strcpy (argv[i], "O"); goto gotit; }
+
+    if (!strcmp (argv[i], "("))      { type = ST_LEFT;  goto gotit; }
+    if (!strcmp (argv[i], ")"))      { type = ST_RIGHT; goto gotit; }
 
   gotit:
     /* choose how to deal with object */
     switch (type) {
-      case 8:  /* exponentiation: 2^2^3 = 64 != 256 (precedence is right-to-left, not left-to-right!) */
+      case ST_POWER:  /* 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--) {
@@ -105,10 +109,13 @@
 	Nop_stack ++;
 	break;
-      case 9: /* unary OPs */
-      case 7: /* binary OPs */
-      case 6:
-      case 5: 
-      case 4: 
-      case 3: 
+      case ST_UNARY: 
+      case ST_BINARY: 
+      case ST_TRINARY:
+      case ST_TIMES:
+      case ST_ADD:
+      case ST_BITWISE: 
+      case ST_LOGIC: 
+      case ST_AND: 
+      case ST_OR: 
 	/* pop previous, higher or equal operators from OP stack to stack */
 	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type >= type); j--) {
@@ -121,5 +128,5 @@
 	Nop_stack ++;
 	break;
-      case 2:  
+      case ST_LEFT:  
 	/* push operator on OP stack */
 	assign_stack (&op_stack[Nop_stack], argv[i], type);
@@ -127,12 +134,12 @@
 	Nop_stack ++;
 	break;
-      case 1: 
+      case ST_RIGHT: 
 	/* pop rest of operators from OP stack to stack, looking for '(' */
-	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type != 2); j--) {
-	  move_stack (&stack[Nstack], &op_stack[j]);
-	  Nstack ++;
-	  Nop_stack --;
-	}
-	if ((j == -1) || (op_stack[j].type != 2)) {
+	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type != ST_LEFT); j--) {
+	  move_stack (&stack[Nstack], &op_stack[j]);
+	  Nstack ++;
+	  Nop_stack --;
+	}
+	if ((j == -1) || (op_stack[j].type != ST_LEFT)) {
 	  push_error ("syntax error: mismatched parenthesis");
 	  Nstack = 0;
@@ -144,16 +151,29 @@
 	Nop_stack --;
 	break;
-      case 0:
+      case ST_COMMA: 
+	/* pop rest of operators from OP stack to stack, looking for '(' (but do not pop the '(')*/
+	for (j = Nop_stack - 1; (j >= 0) && (op_stack[j].type != ST_LEFT) && (op_stack[j].type != ST_TRINARY); j--) {
+	  move_stack (&stack[Nstack], &op_stack[j]);
+	  Nstack ++;
+	  Nop_stack --;
+	}
+	break;
+      case ST_NONE:
 	/* place the value (number or vector/matrix name) on stack */
 	/* value of 'X' is used as sentinel until we sort out values */
-	assign_stack (&stack[Nstack], argv[i], 'X');
+	assign_stack (&stack[Nstack], argv[i], ST_VALUE);
 	Nstack ++;
 	break;
+
+      default:
+	push_error ("invalid stack typ");
+	Nstack = 0;
+	goto cleanup;
     }
   }
 
-  /* dump remaining operators on stack, checking for ')' */
+  /* dump remaining operators on stack, checking for '(' */
   for (j = Nop_stack - 1; j >= 0; j--) {
-    if (op_stack[j].type == 2) {
+    if (op_stack[j].type == ST_LEFT) {
       push_error ("syntax error: mismatched parenthesis");
       Nstack = 0;
Index: /branches/eam_branches/ipp-20130904/Ohana/src/opihi/lib.shell/dvomath.c
===================================================================
--- /branches/eam_branches/ipp-20130904/Ohana/src/opihi/lib.shell/dvomath.c	(revision 36150)
+++ /branches/eam_branches/ipp-20130904/Ohana/src/opihi/lib.shell/dvomath.c	(revision 36151)
@@ -80,5 +80,5 @@
 	sprintf (outname, "%s", stack[0].name);
       } else {
-	if (stack[0].type == 's') {
+	if (stack[0].type == ST_SCALAR_INT) {
 	  sprintf (outname, "%d", stack[0].IntValue);
 	} else {
Index: /branches/eam_branches/ipp-20130904/Ohana/src/opihi/lib.shell/evaluate_stack.c
===================================================================
--- /branches/eam_branches/ipp-20130904/Ohana/src/opihi/lib.shell/evaluate_stack.c	(revision 36150)
+++ /branches/eam_branches/ipp-20130904/Ohana/src/opihi/lib.shell/evaluate_stack.c	(revision 36151)
@@ -2,11 +2,51 @@
 # 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); 
+// all three operands must have the same type
+# define THREE_OP(A,FUNC) 						\
+  if ((stack[i - 3].type == A) && (stack[i - 2].type == A) && (stack[i - 1].type == A)) { \
+    status = FUNC (&tmp_stack, &stack[i - 3], &stack[i - 2], &stack[i - 1], stack[i].name); \
+    goto got_three_op; } \
+  if ((stack[i - 3].type == A+1) && (stack[i - 2].type == A) && (stack[i - 1].type == A)) { \
+    status = FUNC (&tmp_stack, &stack[i - 3], &stack[i - 2], &stack[i - 1], stack[i].name); \
+    goto got_three_op; } \
+  if ((stack[i - 3].type == A) && (stack[i - 2].type == A+1) && (stack[i - 1].type == A)) { \
+    status = FUNC (&tmp_stack, &stack[i - 3], &stack[i - 2], &stack[i - 1], stack[i].name); \
+    goto got_three_op; } \
+  if ((stack[i - 3].type == A+1) && (stack[i - 2].type == A+1) && (stack[i - 1].type == A)) { \
+    status = FUNC (&tmp_stack, &stack[i - 3], &stack[i - 2], &stack[i - 1], stack[i].name); \
+    goto got_three_op; } \
+  if ((stack[i - 3].type == A) && (stack[i - 2].type == A) && (stack[i - 1].type == A+1)) { \
+    status = FUNC (&tmp_stack, &stack[i - 3], &stack[i - 2], &stack[i - 1], stack[i].name); \
+    goto got_three_op; } \
+  if ((stack[i - 3].type == A+1) && (stack[i - 2].type == A) && (stack[i - 1].type == A+1)) { \
+    status = FUNC (&tmp_stack, &stack[i - 3], &stack[i - 2], &stack[i - 1], stack[i].name); \
+    goto got_three_op; } \
+  if ((stack[i - 3].type == A) && (stack[i - 2].type == A+1) && (stack[i - 1].type == A+1)) { \
+    status = FUNC (&tmp_stack, &stack[i - 3], &stack[i - 2], &stack[i - 1], stack[i].name); \
+    goto got_three_op; } \
+  if ((stack[i - 3].type == A+1) && (stack[i - 2].type == A+1) && (stack[i - 1].type == A+1)) { \
+    status = FUNC (&tmp_stack, &stack[i - 3], &stack[i - 2], &stack[i - 1], stack[i].name); \
+    goto got_three_op; } \
+
+// A & B value types all have 2 possible values
+# define TWO_OP(A,B,FUNC) {						\
+    if ((stack[i - 2].type == A) && (stack[i - 1].type == B)) {		\
+      status = FUNC (&tmp_stack, &stack[i - 2], &stack[i - 1], stack[i].name); \
+      goto got_two_op; }						\
+    if ((stack[i - 2].type == A+1) && (stack[i - 1].type == B)) {	\
+      status = FUNC (&tmp_stack, &stack[i - 2], &stack[i - 1], stack[i].name); \
+      goto got_two_op; }						\
+    if ((stack[i - 2].type == A) && (stack[i - 1].type == B+1)) {	\
+      status = FUNC (&tmp_stack, &stack[i - 2], &stack[i - 1], stack[i].name); \
+      goto got_two_op; }						\
+    if ((stack[i - 2].type == A+1) && (stack[i - 1].type == B+1)) {	\
+      status = FUNC (&tmp_stack, &stack[i - 2], &stack[i - 1], stack[i].name); \
+      goto got_two_op; } \
+  }
+
+# define ONE_OP(A,FUNC)						\
+  if (stack[i - 1].type == A) {					\
+    status = FUNC (&tmp_stack, &stack[i - 1], stack[i].name);   \
+    goto got_one_op; }
 
 int evaluate_stack (StackVar *stack, int *Nstack) {
@@ -20,9 +60,9 @@
 
   if (*Nstack == 1) {
-    if ((stack[0].type == 'S') || (stack[0].type == 's')) {
+    if ((stack[0].type == ST_SCALAR_INT) || (stack[0].type == ST_SCALAR_FLT)) {
       clear_stack (&tmp_stack);
       return (TRUE);
     }
-    if (stack[0].type == 'V') {
+    if (stack[0].type == ST_VECTOR) {
       /* need to make a copy so we set output value? */
       V_unary (&tmp_stack, &stack[0], "=");
@@ -30,5 +70,5 @@
       return (TRUE);
     }
-    if (stack[0].type == 'M') {
+    if (stack[0].type == ST_MATRIX) {
       /* need to make a copy so we set output value? */
       M_unary (&tmp_stack, &stack[0], "=");
@@ -56,75 +96,148 @@
     }
 
-    /***** binary operators *****/
-    if ((stack[i].type >= 3) && (stack[i].type <= 8)) {
-
-      if (i < 2) {  /* need two variables to operate on */
-	sprintf (line, "syntax error: binary operator with one operand: %s\n", stack[i].name);
+    /***** trinary operators *****/
+    switch (stack[i].type) {
+      case ST_TRINARY:
+
+	if (i < 3) {  /* need two variables to operate on */
+	  snprintf (line, 512, "syntax error: trinary operator without three operands: %s\n", stack[i].name);
+	  push_error (line);
+	  clear_stack (&tmp_stack);
+	  return (FALSE);
+	}
+
+	status = FALSE;
+	THREE_OP (ST_MATRIX,MMM_trinary);
+	THREE_OP (ST_VECTOR,VVV_trinary);
+
+	THREE_OP (ST_SCALAR_FLT,SSS_trinary);
+	THREE_OP (ST_SCALAR_INT,SSS_trinary);
+
+	/* there are no valid unary string operators */
+	push_error ("invalid operands for trinary operator (mismatch types?)");
+	clear_stack (&tmp_stack);
+	return (FALSE);
+
+      got_three_op:
+	if (!status) {
+	  snprintf (line, 512, "syntax error: invalid operand for binary operation: %s or %s or %s\n", stack[i-1].name, stack[i-2].name, stack[i-3].name);
+	  push_error (line);
+	  clear_stack (&tmp_stack);
+	  return (FALSE);
+	}
+	move_stack (&stack[i-3], &tmp_stack);
+	delete_stack (&stack[i-2], 3);
+	for (j = i + 1; j < *Nstack; j++) {
+	  move_stack (&stack[j-3], &stack[j]);
+	}
+	*Nstack -= 3;
+	i -= 3;
+	init_stack (&tmp_stack);
+	continue;
+
+	/***** binary operators *****/
+      case ST_OR:
+      case ST_AND:
+      case ST_LOGIC:
+      case ST_BITWISE:
+      case ST_ADD:
+      case ST_TIMES:
+      case ST_POWER:
+      case ST_BINARY:
+
+	if (i < 2) {  /* need two variables to operate on */
+	  snprintf (line, 512, "syntax error: binary operator with one operand: %s\n", stack[i].name);
+	  push_error (line);
+	  clear_stack (&tmp_stack);
+	  return (FALSE);
+	}
+
+	status = FALSE;
+	TWO_OP (ST_MATRIX,ST_MATRIX,MM_binary);
+	TWO_OP (ST_MATRIX,ST_VECTOR,MV_binary);
+	TWO_OP (ST_MATRIX,ST_SCALAR_INT,MS_binary);
+
+	TWO_OP (ST_VECTOR,ST_MATRIX,VM_binary);
+	TWO_OP (ST_VECTOR,ST_VECTOR,VV_binary);
+	TWO_OP (ST_VECTOR,ST_SCALAR_INT,VS_binary);
+
+	TWO_OP (ST_SCALAR_INT,ST_MATRIX,SM_binary);
+	TWO_OP (ST_SCALAR_INT,ST_VECTOR,SV_binary);
+	TWO_OP (ST_SCALAR_INT,ST_SCALAR_INT,SS_binary);      
+
+	TWO_OP (ST_SCALAR_FLT,ST_MATRIX,SM_binary);
+	TWO_OP (ST_SCALAR_FLT,ST_VECTOR,SV_binary);
+	TWO_OP (ST_SCALAR_FLT,ST_SCALAR_INT,SS_binary);      
+
+	TWO_OP (ST_STRING,ST_STRING,WW_binary);      
+	TWO_OP (ST_STRING,ST_SCALAR_INT,WW_binary);      
+	TWO_OP (ST_SCALAR_INT,ST_STRING,WW_binary);      
+      
+      got_two_op:
+	if (!status) {
+	  snprintf (line, 512, "syntax error: invalid operand for binary operation: %s or %s\n", stack[i-1].name, stack[i-2].name);
+	  push_error (line);
+	  clear_stack (&tmp_stack);
+	  return (FALSE);
+	}
+	move_stack (&stack[i-2], &tmp_stack);
+	delete_stack (&stack[i-1], 2);
+	for (j = i + 1; j < *Nstack; j++) {
+	  move_stack (&stack[j - 2], &stack[j]);
+	}
+	*Nstack -= 2;
+	i -= 2;
+	init_stack (&tmp_stack);
+	continue;
+
+	/***** unary operators **/
+      case ST_UNARY:
+
+	if (i < 1) {  /* need one variable to operate on */
+	  push_error ("syntax error: unary operator with no operand");
+	  clear_stack (&tmp_stack);
+	  return (FALSE);
+	}
+
+	ONE_OP (ST_MATRIX, M_unary);
+	ONE_OP (ST_MATRIX_TMP, M_unary);
+
+	ONE_OP (ST_VECTOR, V_unary);
+	ONE_OP (ST_VECTOR_TMP, V_unary);
+
+	ONE_OP (ST_SCALAR_INT, S_unary);
+	ONE_OP (ST_SCALAR_FLT, S_unary);
+
+	/* there are no valid unary string operators */
+	push_error ("syntax error: no valid string unary ops");
+	clear_stack (&tmp_stack);
+	return (FALSE);
+
+      got_one_op:
+	move_stack (&stack[i-1], &tmp_stack);
+	delete_stack (&stack[i], 1);
+	for (j = i + 1; j < *Nstack; j++) {
+	  move_stack (&stack[j - 1], &stack[j]);
+	}
+	init_stack (&tmp_stack);
+	*Nstack -= 1;
+	i -= 1;
+	continue;
+
+      case ST_SCALAR_INT:
+      case ST_SCALAR_FLT:
+      case ST_VECTOR:
+      case ST_VECTOR_TMP:
+      case ST_MATRIX:
+      case ST_MATRIX_TMP:
+      case ST_STRING:
+	continue;
+
+      default:
+	snprintf (line, 512, "syntax error: unexpected operator type %s", stack[i].name);
 	push_error (line);
 	clear_stack (&tmp_stack);
 	return (FALSE);
-      }
-
-      status = FALSE;
-      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);      
-      TWO_OP ("W","S",WW_binary);      
-      TWO_OP ("S","W",WW_binary);      
-      
-      if (!status) {
-	sprintf (line, "syntax error: invalid operand for binary operation: %s or %s\n", stack[i-1].name, stack[i-2].name);
-	push_error (line);
-	clear_stack (&tmp_stack);
-	return (FALSE);
-      }
-      move_stack (&stack[i-2], &tmp_stack);
-      delete_stack (&stack[i-1], 2);
-      for (j = i + 1; j < *Nstack; j++) {
-	move_stack (&stack[j - 2], &stack[j]);
-      }
-      *Nstack -= 2;
-      i -= 2;
-      init_stack (&tmp_stack);
-      continue;
-    }
-
-    /***** unary operators **/
-    if (stack[i].type == 9) {
-
-      if (i < 1) {  /* need one variable to operate on */
-	push_error ("syntax error: unary operator with no operand");
-	clear_stack (&tmp_stack);
-	return (FALSE);
-      }
-
-      ONE_OP ("M", M_unary);
-      ONE_OP ("V", V_unary);
-      ONE_OP ("S", S_unary);
-
-      /* there are no valid unary string operators */
-      if (!strncasecmp (&stack[i - 1].type, "W", 1)) {
-	push_error ("syntax error: no valid string unary ops");
-	clear_stack (&tmp_stack);
-	return (FALSE);
-      }
-
-      move_stack (&stack[i-1], &tmp_stack);
-      delete_stack (&stack[i], 1);
-      for (j = i + 1; j < *Nstack; j++) {
-	move_stack (&stack[j - 1], &stack[j]);
-      }
-      init_stack (&tmp_stack);
-      *Nstack -= 1;
-      i -= 1;
-      continue;
-    } 
+    }
   }
   clear_stack (&tmp_stack);
@@ -160,5 +273,5 @@
 
   for (i = 0; i < Nstack; i++) {
-    if (IsBufferPtr (stack[i].buffer) && (stack[i].type == 'm')) {
+    if (IsBufferPtr (stack[i].buffer) && (stack[i].type == ST_MATRIX_TMP)) {
       if (VERBOSE) gprint (GP_ERR, "free %s (buff) (%lx)\n", stack[i].name, (long) stack[i].buffer);
       free (stack[i].buffer[0].header.buffer);
@@ -167,5 +280,5 @@
       stack[i].buffer = NULL;
     }	
-    if (IsVectorPtr (stack[i].vector) && (stack[i].type == 'v')) {
+    if (IsVectorPtr (stack[i].vector) && (stack[i].type == ST_VECTOR_TMP)) {
       if (VERBOSE) gprint (GP_ERR, "free %s (vect) (%lx)\n", stack[i].name, (long) stack[i].vector);
       free (stack[i].vector[0].elements.Ptr);
@@ -193,5 +306,5 @@
 }
 
-void assign_stack (StackVar *stack, char *name, int type) {
+void assign_stack (StackVar *stack, char *name, StackVarType type) {
   stack->name = strcreate (name);
   stack->type = type;
Index: /branches/eam_branches/ipp-20130904/Ohana/src/opihi/lib.shell/stack_math.c
===================================================================
--- /branches/eam_branches/ipp-20130904/Ohana/src/opihi/lib.shell/stack_math.c	(revision 36150)
+++ /branches/eam_branches/ipp-20130904/Ohana/src/opihi/lib.shell/stack_math.c	(revision 36151)
@@ -6,9 +6,46 @@
 */
 
-// XXX we temporarily drop the concept of using one of the temporary input vectors for 
-// the output vector (thus saving an ALLOC): we have to juggle the size of the input vectors 
-// as well as their temporary state
-
-int VV_binary (StackVar *OUT, StackVar *V1, StackVar *V2, char *op) {
+int SSS_trinary (StackVar *OUT, StackVar *V1, StackVar *V2, StackVar *V3, char *op) {
+
+  char line[512]; // this is only used to report an error 
+  
+  // set up the possible operations : int OP int -> int, all else yield float
+  // OP is the operation performed on *M1 and *M2
+# define SSS_FUNC(OP) {						\
+    if ((V1->type == ST_SCALAR_FLT) && (V2->type == ST_SCALAR_FLT) && (V3->type == ST_SCALAR_FLT)) { \
+      opihi_flt M1  =  V1[0].FltValue;			\
+      opihi_flt M2  =  V2[0].FltValue;			\
+      opihi_flt M3  =  V3[0].FltValue;			\
+      OUT[0].type = ST_SCALAR_FLT;			\
+      OUT[0].FltValue = OP;							\
+      break;								\
+    }									\
+    if ((V1->type == ST_SCALAR_INT) && (V2->type == ST_SCALAR_INT) && (V3->type == ST_SCALAR_INT)) { \
+      opihi_int M1  =  V1[0].IntValue;			\
+      opihi_int M2  =  V2[0].IntValue;			\
+      opihi_int M3  =  V3[0].IntValue;			\
+      OUT[0].type = ST_SCALAR_INT;			\
+      OUT[0].IntValue = OP;							\
+      break;								\
+    }									\
+  }
+
+  switch (op[0]) {
+    case '?': SSS_FUNC(M1 ? M2: M3);
+    default:
+      snprintf (line, 512, "error: op %c not defined!", op[0]);
+      push_error (line);
+      return (FALSE);
+  }
+# undef SSS_FUNC
+
+  clear_stack (V1);
+  clear_stack (V2);
+  clear_stack (V3);
+  return (TRUE);
+
+}
+
+int VVV_trinary (StackVar *OUT, StackVar *V1, StackVar *V2, StackVar *V3, char *op) {
 
   int i, Nx;
@@ -19,4 +56,7 @@
     return (FALSE);
   }
+  if (V1[0].vector[0].Nelements != V3[0].vector[0].Nelements) {
+    return (FALSE);
+  }
 
   Nx = V1[0].vector[0].Nelements;
@@ -24,5 +64,154 @@
   // create the output vector guaranteed to be temporary until the very end
   OUT[0].vector = InitVector ();
-  OUT[0].type = 'v';
+  OUT[0].type = ST_VECTOR_TMP;
+
+  // set up the possible operations : int OP int -> int, all else yield float
+  // OP is the operation performed on *M1 and *M2
+# define VVV_FUNC(OP) {						\
+    if ((V1->vector->type == OPIHI_FLT) && (V2->vector->type == OPIHI_FLT) && (V3->vector->type == OPIHI_FLT)) { \
+      CopyVector (OUT[0].vector, V1[0].vector);				\
+      opihi_flt *M1  =  V1[0].vector[0].elements.Flt;			\
+      opihi_flt *M2  =  V2[0].vector[0].elements.Flt;			\
+      opihi_flt *M3  =  V3[0].vector[0].elements.Flt;			\
+      opihi_flt *out = OUT[0].vector[0].elements.Flt;			\
+      for (i = 0; i < Nx; i++, out++, M1++, M2++, M3++) {		\
+  	*out = OP;							\
+      }									\
+      break;								\
+    }									\
+    if ((V1->vector->type == OPIHI_INT) && (V2->vector->type == OPIHI_INT) && (V3->vector->type == OPIHI_INT)) { \
+      CopyVector (OUT[0].vector, V1[0].vector);				\
+      opihi_int *M1  =  V1[0].vector[0].elements.Int;			\
+      opihi_int *M2  =  V2[0].vector[0].elements.Int;			\
+      opihi_int *M3  =  V3[0].vector[0].elements.Int;			\
+      opihi_int *out = OUT[0].vector[0].elements.Int;			\
+      for (i = 0; i < Nx; i++, out++, M1++, M2++, M3++) {		\
+  	*out = OP;							\
+      }									\
+      break;								\
+    }									\
+  }
+
+  switch (op[0]) {
+    case '?': VVV_FUNC(*M1 ? *M2: *M3);
+    default:
+      snprintf (line, 512, "error: op %c not defined!", op[0]);
+      push_error (line);
+      return (FALSE);
+  }
+# undef VVV_FUNC
+
+  /** free up any temporary buffers: **/
+
+  if (V1[0].type == ST_VECTOR_TMP) {
+    free (V1[0].vector[0].elements.Ptr);
+    free (V1[0].vector);
+  }
+  if (V2[0].type == ST_VECTOR_TMP) {
+    free (V2[0].vector[0].elements.Ptr);
+    free (V2[0].vector);
+  }
+  if (V3[0].type == ST_VECTOR_TMP) {
+    free (V3[0].vector[0].elements.Ptr);
+    free (V3[0].vector);
+  }
+  /* at the end, V1 and V2 are deleted only if they were temporary */
+
+  clear_stack (V1);
+  clear_stack (V2);
+  clear_stack (V3);
+  return (TRUE);
+
+}
+
+int MMM_trinary (StackVar *OUT, StackVar *V1, StackVar *V2, StackVar *V3, char *op) {
+
+  int i, Nx, Ny;
+  float *out, *M1, *M2, *M3;
+  char line[512]; // this is only used to report an error 
+  
+  Nx = V1[0].buffer[0].matrix.Naxis[0];
+  Ny = V1[0].buffer[0].matrix.Naxis[1];
+
+  if (V1[0].type == ST_MATRIX_TMP) {  /** use V1 as temp buffer **/
+    OUT[0].buffer = V1[0].buffer;
+    V1[0].type = ST_MATRIX; /* prevent it from being freed below */
+  } else {
+    if (V2[0].type == ST_MATRIX_TMP) { /** use V2 as temp buffer, but header of V1 **/
+      OUT[0].buffer = V2[0].buffer;
+      V2[0].type = ST_MATRIX; /* prevent it from being freed below */
+    } else {  /* no spare temp buffer */
+      OUT[0].buffer = InitBuffer ();
+      CopyBuffer (OUT[0].buffer, V1[0].buffer);
+    }
+  }
+  OUT[0].type = ST_MATRIX_TMP; /*** <<--- says this is a temporary matrix ***/
+
+  M1  = (float *)V1[0].buffer[0].matrix.buffer;
+  M2  = (float *)V2[0].buffer[0].matrix.buffer;
+  M3  = (float *)V3[0].buffer[0].matrix.buffer;
+  out = (float *)OUT[0].buffer[0].matrix.buffer;
+
+# define MMM_FUNC(OP)					\
+  for (i = 0; i < Nx*Ny; i++, out++, M1++, M2++, M3++) {	\
+    *out = OP;						\
+  }							\
+  break; 
+
+  switch (op[0]) {
+    case '?': MMM_FUNC(*M1 ? *M2: *M3);
+    default:
+      snprintf (line, 512, "error: op %c not defined!", op[0]);
+      push_error (line);
+      return (FALSE);
+  }
+# undef MMM_FUNC
+
+  /** free up any temporary buffers: **/
+
+  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);
+  }
+  if (V2[0].type == ST_MATRIX_TMP) {
+    free (V2[0].buffer[0].header.buffer);
+    free (V2[0].buffer[0].matrix.buffer);
+    free (V2[0].buffer);
+  }
+  if (V3[0].type == ST_MATRIX_TMP) {
+    free (V3[0].buffer[0].header.buffer);
+    free (V3[0].buffer[0].matrix.buffer);
+    free (V3[0].buffer);
+  }
+
+  /* at the end, V1 and V2 are deleted only if they were temporary */
+
+  clear_stack (V1);
+  clear_stack (V2);
+  clear_stack (V3);
+  return (TRUE);
+
+}
+
+// XXX we temporarily drop the concept of using one of the temporary input vectors for 
+// the output vector (thus saving an ALLOC): we have to juggle the size of the input vectors 
+// as well as their temporary state
+
+int VV_binary (StackVar *OUT, StackVar *V1, StackVar *V2, char *op) {
+
+  int i, Nx;
+  char line[512]; // this is only used to report an error 
+  
+  // the vectors have to match in length
+  if (V1[0].vector[0].Nelements != V2[0].vector[0].Nelements) {
+    return (FALSE);
+  }
+
+  Nx = V1[0].vector[0].Nelements;
+
+  // create the output vector guaranteed to be temporary until the very end
+  OUT[0].vector = InitVector ();
+  OUT[0].type = ST_VECTOR_TMP;
 
   // set up the possible operations : int OP int -> int, all else yield float
@@ -59,5 +248,5 @@
       break;								\
     }									\
-    if ((FTYPE == 'S') && (V1->vector->type != OPIHI_FLT) && (V2->vector->type != OPIHI_FLT)) { \
+    if ((FTYPE == ST_SCALAR_FLT) && (V1->vector->type != OPIHI_FLT) && (V2->vector->type != OPIHI_FLT)) { \
       MatchVector (OUT[0].vector, V1[0].vector, OPIHI_FLT);		\
       opihi_int *M1  =  V1[0].vector[0].elements.Int;			\
@@ -82,25 +271,26 @@
 
   switch (op[0]) {
-    case '+': VV_FUNC('s', *M1 + *M2);
-    case '-': VV_FUNC('s', *M1 - *M2);
-    case '*': VV_FUNC('s', *M1 * *M2);
-    case '/': VV_FUNC('S', *M1 / (opihi_flt) *M2);
-    case '%': VV_FUNC('s', (long long)*M1 % (long long)*M2);
-    case '^': VV_FUNC('S', pow (*M1, *M2));
-    case '@': VV_FUNC('S', DEG_RAD*atan2 (*M1, *M2));
-    case 'D': VV_FUNC('s', MIN (*M1, *M2));
-    case 'U': VV_FUNC('s', MAX (*M1, *M2));
-    case '<': VV_FUNC('s', (*M1 < *M2) ? 1 : 0);
-    case '>': VV_FUNC('s', (*M1 > *M2) ? 1 : 0);
-    case '&': VV_FUNC('s', ((long long)*M1 & (long long)*M2));
-    case '|': VV_FUNC('s', ((long long)*M1 | (long long)*M2));
-    case 'E': VV_FUNC('s', (*M1 == *M2) ? 1 : 0);
-    case 'N': VV_FUNC('s', (*M1 != *M2) ? 1 : 0);
-    case 'L': VV_FUNC('s', (*M1 <= *M2) ? 1 : 0);
-    case 'G': VV_FUNC('s', (*M1 >= *M2) ? 1 : 0);
-    case 'A': VV_FUNC('s', (*M1 && *M2) ? 1 : 0);
-    case 'O': VV_FUNC('s', (*M1 || *M2) ? 1 : 0);
+    case '+': VV_FUNC(ST_SCALAR_INT, *M1 + *M2);
+    case '-': VV_FUNC(ST_SCALAR_INT, *M1 - *M2);
+    case '*': VV_FUNC(ST_SCALAR_INT, *M1 * *M2);
+    case '/': VV_FUNC(ST_SCALAR_FLT, *M1 / (opihi_flt) *M2);
+    case '%': VV_FUNC(ST_SCALAR_INT, (long long)*M1 % (long long)*M2);
+    case '^': VV_FUNC(ST_SCALAR_FLT, pow (*M1, *M2));
+    case '@': VV_FUNC(ST_SCALAR_FLT, DEG_RAD*atan2 (*M1, *M2));
+    case 'a': VV_FUNC(ST_SCALAR_FLT, DEG_RAD*atan2 (*M1, *M2));
+    case 'D': VV_FUNC(ST_SCALAR_INT, MIN (*M1, *M2));
+    case 'U': VV_FUNC(ST_SCALAR_INT, MAX (*M1, *M2));
+    case '<': VV_FUNC(ST_SCALAR_INT, (*M1 < *M2) ? 1 : 0);
+    case '>': VV_FUNC(ST_SCALAR_INT, (*M1 > *M2) ? 1 : 0);
+    case '&': VV_FUNC(ST_SCALAR_INT, ((long long)*M1 & (long long)*M2));
+    case '|': VV_FUNC(ST_SCALAR_INT, ((long long)*M1 | (long long)*M2));
+    case 'E': VV_FUNC(ST_SCALAR_INT, (*M1 == *M2) ? 1 : 0);
+    case 'N': VV_FUNC(ST_SCALAR_INT, (*M1 != *M2) ? 1 : 0);
+    case 'L': VV_FUNC(ST_SCALAR_INT, (*M1 <= *M2) ? 1 : 0);
+    case 'G': VV_FUNC(ST_SCALAR_INT, (*M1 >= *M2) ? 1 : 0);
+    case 'A': VV_FUNC(ST_SCALAR_INT, (*M1 && *M2) ? 1 : 0);
+    case 'O': VV_FUNC(ST_SCALAR_INT, (*M1 || *M2) ? 1 : 0);
     default:
-      sprintf (line, "error: op %c not defined!", op[0]);
+      snprintf (line, 512, "error: op %c not defined!", op[0]);
       push_error (line);
       return (FALSE);
@@ -110,9 +300,9 @@
   /** free up any temporary buffers: **/
 
-  if (V1[0].type == 'v') {
+  if (V1[0].type == ST_VECTOR_TMP) {
     free (V1[0].vector[0].elements.Ptr);
     free (V1[0].vector);
   }
-  if (V2[0].type == 'v') {
+  if (V2[0].type == ST_VECTOR_TMP) {
     free (V2[0].vector[0].elements.Ptr);
     free (V2[0].vector);
@@ -134,10 +324,10 @@
 
   OUT[0].vector = InitVector ();
-  OUT[0].type = 'v';   /*** <<--- says this is a temporary matrix ***/
+  OUT[0].type = ST_VECTOR_TMP;   /*** <<--- says this is a temporary matrix ***/
 
   // set up the possible operations : int OP int -> int, all else yield float
   // OP is the operation performed on *M1 and *M2
 # define SV_FUNC(FTYPE,OP) {						\
-    if ((V1->type == 'S') && (V2->vector->type == OPIHI_FLT)) {		\
+    if ((V1->type == ST_SCALAR_FLT) && (V2->vector->type == OPIHI_FLT)) {		\
       CopyVector (OUT[0].vector, V2[0].vector);				\
       opihi_flt  M1  =  V1[0].FltValue;					\
@@ -149,5 +339,5 @@
       break;								\
     }									\
-    if ((V1->type == 'S') && (V2->vector->type != OPIHI_FLT)) {		\
+    if ((V1->type == ST_SCALAR_FLT) && (V2->vector->type != OPIHI_FLT)) {		\
       MatchVector (OUT[0].vector, V2[0].vector, OPIHI_FLT);		\
       opihi_flt  M1  =  V1[0].FltValue;					\
@@ -159,5 +349,5 @@
       break;								\
     }									\
-    if ((V1->type == 's') && (V2->vector->type == OPIHI_FLT)) {		\
+    if ((V1->type == ST_SCALAR_INT) && (V2->vector->type == OPIHI_FLT)) {		\
       CopyVector (OUT[0].vector, V2[0].vector);				\
       opihi_int  M1  =  V1[0].IntValue;					\
@@ -169,5 +359,5 @@
       break;								\
     }									\
-    if ((FTYPE == 'S') && (V1->type == 's') && (V2->vector->type != OPIHI_FLT)) { \
+    if ((FTYPE == ST_SCALAR_FLT) && (V1->type == ST_SCALAR_INT) && (V2->vector->type != OPIHI_FLT)) { \
       MatchVector (OUT[0].vector, V2[0].vector, OPIHI_FLT);		\
       opihi_int  M1  =  V1[0].IntValue;					\
@@ -179,5 +369,5 @@
       break;								\
     }									\
-    if ((V1->type == 's') && (V2->vector->type != OPIHI_FLT)) {		\
+    if ((V1->type == ST_SCALAR_INT) && (V2->vector->type != OPIHI_FLT)) {		\
       CopyVector (OUT[0].vector, V2[0].vector);				\
       opihi_int  M1  =  V1[0].IntValue;					\
@@ -192,25 +382,26 @@
 
   switch (op[0]) { 
-    case '+': SV_FUNC('s', M1 + *M2);
-    case '-': SV_FUNC('s', M1 - *M2);
-    case '*': SV_FUNC('s', M1 * *M2);
-    case '/': SV_FUNC('S', M1 / (opihi_flt) *M2);
-    case '%': SV_FUNC('s', (long long) M1 % (long long) *M2);
-    case '^': SV_FUNC('S', pow (M1, *M2));
-    case '@': SV_FUNC('S', DEG_RAD*atan2 (M1, *M2));
-    case 'D': SV_FUNC('s', MIN (M1, *M2));
-    case 'U': SV_FUNC('s', MAX (M1, *M2));
-    case '<': SV_FUNC('s', (M1 < *M2) ? 1 : 0);
-    case '>': SV_FUNC('s', (M1 > *M2) ? 1 : 0);
-    case '&': SV_FUNC('s', ((long long)M1 & (long long)*M2));
-    case '|': SV_FUNC('s', ((long long)M1 | (long long)*M2));
-    case 'E': SV_FUNC('s', (M1 == *M2) ? 1 : 0);
-    case 'N': SV_FUNC('s', (M1 != *M2) ? 1 : 0);
-    case 'L': SV_FUNC('s', (M1 <= *M2) ? 1 : 0);
-    case 'G': SV_FUNC('s', (M1 >= *M2) ? 1 : 0);
-    case 'A': SV_FUNC('s', (M1 && *M2) ? 1 : 0);
-    case 'O': SV_FUNC('s', (M1 || *M2) ? 1 : 0);
+    case '+': SV_FUNC(ST_SCALAR_INT, M1 + *M2);
+    case '-': SV_FUNC(ST_SCALAR_INT, M1 - *M2);
+    case '*': SV_FUNC(ST_SCALAR_INT, M1 * *M2);
+    case '/': SV_FUNC(ST_SCALAR_FLT, M1 / (opihi_flt) *M2);
+    case '%': SV_FUNC(ST_SCALAR_INT, (long long) M1 % (long long) *M2);
+    case '^': SV_FUNC(ST_SCALAR_FLT, pow (M1, *M2));
+    case '@': SV_FUNC(ST_SCALAR_FLT, DEG_RAD*atan2 (M1, *M2));
+    case 'a': SV_FUNC(ST_SCALAR_FLT, DEG_RAD*atan2 (M1, *M2));
+    case 'D': SV_FUNC(ST_SCALAR_INT, MIN (M1, *M2));
+    case 'U': SV_FUNC(ST_SCALAR_INT, MAX (M1, *M2));
+    case '<': SV_FUNC(ST_SCALAR_INT, (M1 < *M2) ? 1 : 0);
+    case '>': SV_FUNC(ST_SCALAR_INT, (M1 > *M2) ? 1 : 0);
+    case '&': SV_FUNC(ST_SCALAR_INT, ((long long)M1 & (long long)*M2));
+    case '|': SV_FUNC(ST_SCALAR_INT, ((long long)M1 | (long long)*M2));
+    case 'E': SV_FUNC(ST_SCALAR_INT, (M1 == *M2) ? 1 : 0);
+    case 'N': SV_FUNC(ST_SCALAR_INT, (M1 != *M2) ? 1 : 0);
+    case 'L': SV_FUNC(ST_SCALAR_INT, (M1 <= *M2) ? 1 : 0);
+    case 'G': SV_FUNC(ST_SCALAR_INT, (M1 >= *M2) ? 1 : 0);
+    case 'A': SV_FUNC(ST_SCALAR_INT, (M1 && *M2) ? 1 : 0);
+    case 'O': SV_FUNC(ST_SCALAR_INT, (M1 || *M2) ? 1 : 0);
     default:
-      sprintf (line, "error: op %c not defined!", op[0]);
+      snprintf (line, 512, "error: op %c not defined!", op[0]);
       push_error (line);
       return (FALSE);
@@ -219,5 +410,5 @@
 
   /** free up any temporary buffers: **/
-  if (V2[0].type == 'v') {
+  if (V2[0].type == ST_VECTOR_TMP) {
     free (V2[0].vector[0].elements.Ptr);
     free (V2[0].vector);
@@ -240,10 +431,10 @@
 
   OUT[0].vector = InitVector ();
-  OUT[0].type = 'v';   /*** <<--- says this is a temporary matrix ***/
+  OUT[0].type = ST_VECTOR_TMP;   /*** <<--- says this is a temporary matrix ***/
 
   // set up the possible operations : int OP int -> int, all else yield float
   // OP is the operation performed on *M1 and *M2
 # define VS_FUNC(FTYPE,OP) {						\
-    if ((V2->type == 'S') && (V1->vector->type == OPIHI_FLT)) {		\
+    if ((V2->type == ST_SCALAR_FLT) && (V1->vector->type == OPIHI_FLT)) {		\
       CopyVector (OUT[0].vector, V1[0].vector);				\
       opihi_flt *M1  =  V1[0].vector[0].elements.Flt;			\
@@ -255,5 +446,5 @@
       break;								\
     }									\
-    if ((V2->type == 'S') && (V1->vector->type != OPIHI_FLT)) {		\
+    if ((V2->type == ST_SCALAR_FLT) && (V1->vector->type != OPIHI_FLT)) {		\
       MatchVector (OUT[0].vector, V1[0].vector, OPIHI_FLT);		\
       opihi_int *M1  =  V1[0].vector[0].elements.Int;			\
@@ -265,5 +456,5 @@
       break;								\
     }									\
-    if ((V2->type == 's') && (V1->vector->type == OPIHI_FLT)) {		\
+    if ((V2->type == ST_SCALAR_INT) && (V1->vector->type == OPIHI_FLT)) {		\
       CopyVector (OUT[0].vector, V1[0].vector);				\
       opihi_flt *M1  =  V1[0].vector[0].elements.Flt;			\
@@ -275,5 +466,5 @@
       break;								\
     }									\
-    if ((FTYPE == 'S') && (V2->type == 's') && (V1->vector->type != OPIHI_FLT)) { \
+    if ((FTYPE == ST_SCALAR_FLT) && (V2->type == ST_SCALAR_INT) && (V1->vector->type != OPIHI_FLT)) { \
       CopyVector (OUT[0].vector, V1[0].vector);				\
       opihi_int *M1  =  V1[0].vector[0].elements.Int;			\
@@ -285,5 +476,5 @@
       break;								\
     }									\
-    if ((V2->type == 's') && (V1->vector->type != OPIHI_FLT)) {		\
+    if ((V2->type == ST_SCALAR_INT) && (V1->vector->type != OPIHI_FLT)) {		\
       CopyVector (OUT[0].vector, V1[0].vector);				\
       opihi_int *M1  =  V1[0].vector[0].elements.Int;			\
@@ -298,25 +489,26 @@
 
   switch (op[0]) { 
-    case '+': VS_FUNC('s', *M1 + M2);
-    case '-': VS_FUNC('s', *M1 - M2);
-    case '*': VS_FUNC('s', *M1 * M2);
-    case '/': VS_FUNC('S', *M1 / (opihi_flt) M2);
-    case '%': VS_FUNC('s', (long long) *M1 % (long long) M2);
-    case '^': VS_FUNC('S', pow (*M1, M2));
-    case '@': VS_FUNC('S', DEG_RAD*atan2 (*M1, M2));
-    case 'D': VS_FUNC('s', MIN (*M1, M2));
-    case 'U': VS_FUNC('s', MAX (*M1, M2));
-    case '<': VS_FUNC('s', (*M1 < M2) ? 1 : 0);
-    case '>': VS_FUNC('s', (*M1 > M2) ? 1 : 0);
-    case '&': VS_FUNC('s', ((long long)*M1 & (long long)M2));
-    case '|': VS_FUNC('s', ((long long)*M1 | (long long)M2));
-    case 'E': VS_FUNC('s', (*M1 == M2) ? 1 : 0);
-    case 'N': VS_FUNC('s', (*M1 != M2) ? 1 : 0);
-    case 'L': VS_FUNC('s', (*M1 <= M2) ? 1 : 0);
-    case 'G': VS_FUNC('s', (*M1 >= M2) ? 1 : 0);
-    case 'A': VS_FUNC('s', (*M1 && M2) ? 1 : 0);
-    case 'O': VS_FUNC('s', (*M1 || M2) ? 1 : 0);
+    case '+': VS_FUNC(ST_SCALAR_INT, *M1 + M2);
+    case '-': VS_FUNC(ST_SCALAR_INT, *M1 - M2);
+    case '*': VS_FUNC(ST_SCALAR_INT, *M1 * M2);
+    case '/': VS_FUNC(ST_SCALAR_FLT, *M1 / (opihi_flt) M2);
+    case '%': VS_FUNC(ST_SCALAR_INT, (long long) *M1 % (long long) M2);
+    case '^': VS_FUNC(ST_SCALAR_FLT, pow (*M1, M2));
+    case '@': VS_FUNC(ST_SCALAR_FLT, DEG_RAD*atan2 (*M1, M2));
+    case 'a': VS_FUNC(ST_SCALAR_FLT, DEG_RAD*atan2 (*M1, M2));
+    case 'D': VS_FUNC(ST_SCALAR_INT, MIN (*M1, M2));
+    case 'U': VS_FUNC(ST_SCALAR_INT, MAX (*M1, M2));
+    case '<': VS_FUNC(ST_SCALAR_INT, (*M1 < M2) ? 1 : 0);
+    case '>': VS_FUNC(ST_SCALAR_INT, (*M1 > M2) ? 1 : 0);
+    case '&': VS_FUNC(ST_SCALAR_INT, ((long long)*M1 & (long long)M2));
+    case '|': VS_FUNC(ST_SCALAR_INT, ((long long)*M1 | (long long)M2));
+    case 'E': VS_FUNC(ST_SCALAR_INT, (*M1 == M2) ? 1 : 0);
+    case 'N': VS_FUNC(ST_SCALAR_INT, (*M1 != M2) ? 1 : 0);
+    case 'L': VS_FUNC(ST_SCALAR_INT, (*M1 <= M2) ? 1 : 0);
+    case 'G': VS_FUNC(ST_SCALAR_INT, (*M1 >= M2) ? 1 : 0);
+    case 'A': VS_FUNC(ST_SCALAR_INT, (*M1 && M2) ? 1 : 0);
+    case 'O': VS_FUNC(ST_SCALAR_INT, (*M1 || M2) ? 1 : 0);
     default:
-      sprintf (line, "error: op %c not defined!", op[0]);
+      snprintf (line, 512, "error: op %c not defined!", op[0]);
       push_error (line);
       return (FALSE);
@@ -326,5 +518,5 @@
   /** free up any temporary buffers: **/
 
-  if (V1[0].type == 'v') {
+  if (V1[0].type == ST_VECTOR_TMP) {
     free (V1[0].vector[0].elements.Ptr);
     free (V1[0].vector);
@@ -353,7 +545,7 @@
 
   /* if possible, use V1 as temp buffer, otherwise create new one */
-  if (V1[0].type == 'm') {  
+  if (V1[0].type == ST_MATRIX_TMP) {  
     OUT[0].buffer = V1[0].buffer;
-    V1[0].type = 'M'; /* prevent it from being freed below */
+    V1[0].type = ST_MATRIX; /* prevent it from being freed below */
   } else {  
     /* do buffer.matrix.buffer and buffer.header.buffer get correctly zeroed? */
@@ -361,5 +553,5 @@
     CopyBuffer (OUT[0].buffer, V1[0].buffer);
   }
-  OUT[0].type = 'm'; /*** <<--- says this is a temporary matrix ***/
+  OUT[0].type = ST_MATRIX_TMP; /*** <<--- says this is a temporary matrix ***/
 
   float     *M1  = (float *) V1[0].buffer[0].matrix.buffer;
@@ -395,4 +587,5 @@
     case '^': MV_FUNC(pow (*M1, *M2));
     case '@': MV_FUNC(DEG_RAD*atan2 (*M1, *M2));
+    case 'a': MV_FUNC(DEG_RAD*atan2 (*M1, *M2));
     case 'D': MV_FUNC(MIN (*M1, *M2));
     case 'U': MV_FUNC(MAX (*M1, *M2));
@@ -408,5 +601,5 @@
     case 'O': MV_FUNC((*M1 || *M2) ? 1 : 0);
     default:
-      sprintf (line, "error: op %c not defined!", op[0]);
+      snprintf (line, 512, "error: op %c not defined!", op[0]);
       push_error (line);
       return (FALSE);
@@ -416,10 +609,10 @@
   /** free up any temporary buffers: **/
 
-  if (V1[0].type == 'm') {
+  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);
   }
-  if (V2[0].type == 'v') {
+  if (V2[0].type == ST_VECTOR_TMP) {
     free (V2[0].vector[0].elements.Ptr);
     free (V2[0].vector);
@@ -446,12 +639,12 @@
 
   /* if possible, use V2 as temp buffer, otherwise create new one */
-  if (V2[0].type == 'm') {
+  if (V2[0].type == ST_MATRIX_TMP) {
     OUT[0].buffer = V2[0].buffer;
-    V2[0].type = 'M'; /* prevent it from being freed below */
+    V2[0].type = ST_MATRIX; /* prevent it from being freed below */
   } else {  /* no spare temp buffer */
     OUT[0].buffer = InitBuffer ();
     CopyBuffer (OUT[0].buffer, V2[0].buffer);
   }
-  OUT[0].type = 'm'; /*** <<--- says this is a temporary matrix ***/
+  OUT[0].type = ST_MATRIX_TMP; /*** <<--- says this is a temporary matrix ***/
 
   float     *M2  = (float *) V2[0].buffer[0].matrix.buffer;
@@ -487,4 +680,5 @@
     case '^': VM_FUNC(pow (*M1, *M2));
     case '@': VM_FUNC(DEG_RAD*atan2 (*M1, *M2));
+    case 'a': VM_FUNC(DEG_RAD*atan2 (*M1, *M2));
     case 'D': VM_FUNC(MIN (*M1, *M2));
     case 'U': VM_FUNC(MAX (*M1, *M2));
@@ -500,5 +694,5 @@
     case 'O': VM_FUNC((*M1 || *M2) ? 1 : 0);
     default:
-      sprintf (line, "error: op %c not defined!", op[0]);
+      snprintf (line, 512, "error: op %c not defined!", op[0]);
       push_error (line);
       return (FALSE);
@@ -508,9 +702,9 @@
   /** free up any temporary buffers: **/
 
-  if (V1[0].type == 'v') {
+  if (V1[0].type == ST_VECTOR_TMP) {
     free (V1[0].vector[0].elements.Ptr);
     free (V1[0].vector);
   }
-  if (V2[0].type == 'm') {
+  if (V2[0].type == ST_MATRIX_TMP) {
     free (V2[0].buffer[0].header.buffer);
     free (V2[0].buffer[0].matrix.buffer);
@@ -535,11 +729,11 @@
   Ny = V1[0].buffer[0].matrix.Naxis[1];
 
-  if (V1[0].type == 'm') {  /** use V1 as temp buffer **/
+  if (V1[0].type == ST_MATRIX_TMP) {  /** use V1 as temp buffer **/
     OUT[0].buffer = V1[0].buffer;
-    V1[0].type = 'M'; /* prevent it from being freed below */
+    V1[0].type = ST_MATRIX; /* prevent it from being freed below */
   } else {
-    if (V2[0].type == 'm') { /** use V2 as temp buffer, but header of V1 **/
+    if (V2[0].type == ST_MATRIX_TMP) { /** use V2 as temp buffer, but header of V1 **/
       OUT[0].buffer = V2[0].buffer;
-      V2[0].type = 'M'; /* prevent it from being freed below */
+      V2[0].type = ST_MATRIX; /* prevent it from being freed below */
     } else {  /* no spare temp buffer */
       OUT[0].buffer = InitBuffer ();
@@ -547,5 +741,5 @@
     }
   }
-  OUT[0].type = 'm'; /*** <<--- says this is a temporary matrix ***/
+  OUT[0].type = ST_MATRIX_TMP; /*** <<--- says this is a temporary matrix ***/
 
   M1  = (float *)V1[0].buffer[0].matrix.buffer;
@@ -567,4 +761,5 @@
     case '^': MM_FUNC(pow (*M1, *M2));
     case '@': MM_FUNC(DEG_RAD*atan2 (*M1, *M2));
+    case 'a': MM_FUNC(DEG_RAD*atan2 (*M1, *M2));
     case 'D': MM_FUNC(MIN (*M1, *M2));
     case 'U': MM_FUNC(MAX (*M1, *M2));
@@ -580,5 +775,5 @@
     case 'O': MM_FUNC((*M1 || *M2) ? 1 : 0);
     default:
-      sprintf (line, "error: op %c not defined!", op[0]);
+      snprintf (line, 512, "error: op %c not defined!", op[0]);
       push_error (line);
       return (FALSE);
@@ -588,10 +783,10 @@
   /** free up any temporary buffers: **/
 
-  if (V1[0].type == 'm') {
+  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);
   }
-  if (V2[0].type == 'm') {
+  if (V2[0].type == ST_MATRIX_TMP) {
     free (V2[0].buffer[0].header.buffer);
     free (V2[0].buffer[0].matrix.buffer);
@@ -615,12 +810,12 @@
 
   /* if possible, use V1 as temp buffer, otherwise create new one */
-  if (V1[0].type == 'm') {
+  if (V1[0].type == ST_MATRIX_TMP) {
     OUT[0].buffer = V1[0].buffer;
-    V1[0].type = 'M'; /* prevent it from being freed below */
+    V1[0].type = ST_MATRIX; /* prevent it from being freed below */
   } else {
     OUT[0].buffer = InitBuffer ();
     CopyBuffer (OUT[0].buffer, V1[0].buffer);
   }
-  OUT[0].type = 'm';      /*** <<--- says this is a temporary matrix ***/
+  OUT[0].type = ST_MATRIX_TMP;      /*** <<--- says this is a temporary matrix ***/
 
   float *M1    = (float *)V1[0].buffer[0].matrix.buffer;
@@ -628,5 +823,5 @@
 
 # define MS_FUNC(OP) {					\
-    if (V2->type == 'S')  {				\
+    if (V2->type == ST_SCALAR_FLT)  {				\
       opihi_flt M2 = V2[0].FltValue;			\
       for (i = 0; i < Nx*Ny; i++, out++, M1++) {	\
@@ -635,5 +830,5 @@
       break;						\
     }							\
-    if (V2->type == 's')  {				\
+    if (V2->type == ST_SCALAR_INT)  {				\
       opihi_int M2 = V2[0].IntValue;			\
       for (i = 0; i < Nx*Ny; i++, out++, M1++) {	\
@@ -652,4 +847,5 @@
     case '^': MS_FUNC(pow (*M1, M2));
     case '@': MS_FUNC(DEG_RAD*atan2 (*M1, M2));
+    case 'a': MS_FUNC(DEG_RAD*atan2 (*M1, M2));
     case 'D': MS_FUNC(MIN (*M1, M2));
     case 'U': MS_FUNC(MAX (*M1, M2));
@@ -665,5 +861,5 @@
     case 'O': MS_FUNC((*M1 || M2) ? 1 : 0);
     default:
-      sprintf (line, "error: op %c not defined!", op[0]);
+      snprintf (line, 512, "error: op %c not defined!", op[0]);
       push_error (line);
       return (FALSE);
@@ -671,5 +867,5 @@
 # undef MS_FUNC
 
-  if (V1[0].type == 'm') {
+  if (V1[0].type == ST_MATRIX_TMP) {
     free (V1[0].buffer[0].header.buffer);
     free (V1[0].buffer[0].matrix.buffer);
@@ -691,12 +887,12 @@
   Ny = V2[0].buffer[0].matrix.Naxis[1];
 
-  if (V2[0].type == 'm') {  /* V2[0] is NOT temporary, we can't use it for storage */
+  if (V2[0].type == ST_MATRIX_TMP) {  /* V2[0] is NOT temporary, we can't use it for storage */
     OUT[0].buffer = V2[0].buffer;
-    V2[0].type = 'M'; /* prevent it from being freed below */
+    V2[0].type = ST_MATRIX; /* prevent it from being freed below */
   } else {
     OUT[0].buffer = InitBuffer ();
     CopyBuffer (OUT[0].buffer, V2[0].buffer);
   }
-  OUT[0].type = 'm'; /*** <<--- says this is a temporary matrix ***/
+  OUT[0].type = ST_MATRIX_TMP; /*** <<--- says this is a temporary matrix ***/
 
   float *M2    = (float *)V2[0].buffer[0].matrix.buffer;
@@ -704,5 +900,5 @@
 
 # define SM_FUNC(OP) {					\
-    if (V1->type == 'S')  {				\
+    if (V1->type == ST_SCALAR_FLT)  {				\
       opihi_flt M1 = V1[0].FltValue;			\
       for (i = 0; i < Nx*Ny; i++, out++, M2++) {	\
@@ -711,5 +907,5 @@
       break;						\
     }							\
-    if (V1->type == 's')  {				\
+    if (V1->type == ST_SCALAR_INT)  {				\
       opihi_int M1 = V1[0].IntValue;			\
       for (i = 0; i < Nx*Ny; i++, out++, M2++) {	\
@@ -728,4 +924,5 @@
     case '^': SM_FUNC(pow (M1, *M2));
     case '@': SM_FUNC(DEG_RAD*atan2 (M1, *M2));
+    case 'a': SM_FUNC(DEG_RAD*atan2 (M1, *M2));
     case 'D': SM_FUNC(MIN (M1, *M2));
     case 'U': SM_FUNC(MAX (M1, *M2));
@@ -741,5 +938,5 @@
     case 'O': SM_FUNC((M1 || *M2) ? 1 : 0);
     default:
-      sprintf (line, "error: op %c not defined!", op[0]);
+      snprintf (line, 512, "error: op %c not defined!", op[0]);
       push_error (line);
       return (FALSE);
@@ -747,5 +944,5 @@
 # undef SM_FUNC
 
-  if (V2[0].type == 'm') {
+  if (V2[0].type == ST_MATRIX_TMP) {
     free (V2[0].buffer[0].header.buffer);
     free (V2[0].buffer[0].matrix.buffer);
@@ -764,36 +961,36 @@
 
 # define SS_FUNC(FTYPE,OP) {						\
-    if ((V1->type == 'S') && (V2->type == 'S')) {			\
+    if ((V1->type == ST_SCALAR_FLT) && (V2->type == ST_SCALAR_FLT)) {			\
       opihi_flt M1 = V1[0].FltValue;					\
       opihi_flt M2 = V2[0].FltValue;					\
-      OUT[0].type = 'S';						\
+      OUT[0].type = ST_SCALAR_FLT;						\
       OUT[0].FltValue = OP;						\
       break;								\
     }									\
-    if ((V1->type == 'S') && (V2->type == 's')) {			\
+    if ((V1->type == ST_SCALAR_FLT) && (V2->type == ST_SCALAR_INT)) {			\
       opihi_flt M1 = V1[0].FltValue;					\
       opihi_int M2 = V2[0].IntValue;					\
-      OUT[0].type = 'S';						\
+      OUT[0].type = ST_SCALAR_FLT;						\
       OUT[0].FltValue = OP;						\
       break;								\
     }									\
-    if ((V1->type == 's') && (V2->type == 'S')) {			\
+    if ((V1->type == ST_SCALAR_INT) && (V2->type == ST_SCALAR_FLT)) {			\
       opihi_int M1 = V1[0].IntValue;					\
       opihi_flt M2 = V2[0].FltValue;					\
-      OUT[0].type = 'S';						\
+      OUT[0].type = ST_SCALAR_FLT;						\
       OUT[0].FltValue = OP;						\
       break;								\
     }									\
-    if ((FTYPE == 'S') && (V1->type == 's') && (V2->type == 's')) {	\
+    if ((FTYPE == ST_SCALAR_FLT) && (V1->type == ST_SCALAR_INT) && (V2->type == ST_SCALAR_INT)) {	\
       opihi_int M1 = V1[0].IntValue;					\
       opihi_int M2 = V2[0].IntValue;					\
-      OUT[0].type = 'S';						\
+      OUT[0].type = ST_SCALAR_FLT;						\
       OUT[0].FltValue = OP;						\
       break;								\
     }									\
-    if ((V1->type == 's') && (V2->type == 's')) {			\
+    if ((V1->type == ST_SCALAR_INT) && (V2->type == ST_SCALAR_INT)) {			\
       opihi_int M1 = V1[0].IntValue;					\
       opihi_int M2 = V2[0].IntValue;					\
-      OUT[0].type = 's';						\
+      OUT[0].type = ST_SCALAR_INT;						\
       OUT[0].IntValue = OP;						\
       break;								\
@@ -802,25 +999,26 @@
 
   switch (op[0]) { 
-    case '+': SS_FUNC('s', M1 + M2);
-    case '-': SS_FUNC('s', M1 - M2);
-    case '*': SS_FUNC('s', M1 * M2);
-    case '/': SS_FUNC('S', M1 / (opihi_flt) M2);
-    case '%': SS_FUNC('s', (long long) M1 % (long long) M2);
-    case '^': SS_FUNC('S', pow (M1, M2));
-    case '@': SS_FUNC('S', DEG_RAD*atan2 (M1, M2));
-    case 'D': SS_FUNC('s', MIN (M1, M2));
-    case 'U': SS_FUNC('s', MAX (M1, M2));
-    case '<': SS_FUNC('s', (M1 < M2) ? 1 : 0);
-    case '>': SS_FUNC('s', (M1 > M2) ? 1 : 0);
-    case '&': SS_FUNC('s', ((long long)M1 & (long long)M2));
-    case '|': SS_FUNC('s', ((long long)M1 | (long long)M2));
-    case 'E': SS_FUNC('s', (M1 == M2) ? 1 : 0);
-    case 'N': SS_FUNC('s', (M1 != M2) ? 1 : 0);
-    case 'L': SS_FUNC('s', (M1 <= M2) ? 1 : 0);
-    case 'G': SS_FUNC('s', (M1 >= M2) ? 1 : 0);
-    case 'A': SS_FUNC('s', (M1 && M2) ? 1 : 0);
-    case 'O': SS_FUNC('s', (M1 || M2) ? 1 : 0);
+    case '+': SS_FUNC(ST_SCALAR_INT, M1 + M2);
+    case '-': SS_FUNC(ST_SCALAR_INT, M1 - M2);
+    case '*': SS_FUNC(ST_SCALAR_INT, M1 * M2);
+    case '/': SS_FUNC(ST_SCALAR_FLT, M1 / (opihi_flt) M2);
+    case '%': SS_FUNC(ST_SCALAR_INT, (long long) M1 % (long long) M2);
+    case '^': SS_FUNC(ST_SCALAR_FLT, pow (M1, M2));
+    case '@': SS_FUNC(ST_SCALAR_FLT, DEG_RAD*atan2 (M1, M2));
+    case 'a': SS_FUNC(ST_SCALAR_FLT, DEG_RAD*atan2 (M1, M2));
+    case 'D': SS_FUNC(ST_SCALAR_INT, MIN (M1, M2));
+    case 'U': SS_FUNC(ST_SCALAR_INT, MAX (M1, M2));
+    case '<': SS_FUNC(ST_SCALAR_INT, (M1 < M2) ? 1 : 0);
+    case '>': SS_FUNC(ST_SCALAR_INT, (M1 > M2) ? 1 : 0);
+    case '&': SS_FUNC(ST_SCALAR_INT, ((long long)M1 & (long long)M2));
+    case '|': SS_FUNC(ST_SCALAR_INT, ((long long)M1 | (long long)M2));
+    case 'E': SS_FUNC(ST_SCALAR_INT, (M1 == M2) ? 1 : 0);
+    case 'N': SS_FUNC(ST_SCALAR_INT, (M1 != M2) ? 1 : 0);
+    case 'L': SS_FUNC(ST_SCALAR_INT, (M1 <= M2) ? 1 : 0);
+    case 'G': SS_FUNC(ST_SCALAR_INT, (M1 >= M2) ? 1 : 0);
+    case 'A': SS_FUNC(ST_SCALAR_INT, (M1 && M2) ? 1 : 0);
+    case 'O': SS_FUNC(ST_SCALAR_INT, (M1 || M2) ? 1 : 0);
     default:
-      sprintf (line, "error: op %c not defined!", op[0]);
+      snprintf (line, 512, "error: op %c not defined!", op[0]);
       push_error (line);
       return (FALSE);
@@ -844,5 +1042,5 @@
 
   if ((op[0] != 'N') && (op[0] != 'E')) {
-    sprintf (line, "error: op %c not defined for string operations!", op[0]);
+    snprintf (line, 512, "error: op %c not defined for string operations!", op[0]);
     push_error (line);
     return (FALSE);
@@ -853,9 +1051,17 @@
      thus: string == number -> false */
 
-  if (!strncasecmp (&V1[0].type, "S", 1)) {
+  if (V1[0].type == ST_SCALAR_INT) {
     value = (op[0] == 'N');
     goto escape;
   }
-  if (!strncasecmp (&V2[0].type, "S", 1)) {
+  if (V1[0].type == ST_SCALAR_FLT) {
+    value = (op[0] == 'N');
+    goto escape;
+  }
+  if (V2[0].type == ST_SCALAR_INT) {
+    value = (op[0] == 'N');
+    goto escape;
+  }
+  if (V2[0].type == ST_SCALAR_FLT) {
     value = (op[0] == 'N');
     goto escape;
@@ -870,5 +1076,5 @@
     break; 
     default:
-      sprintf (line, "error: op %c not defined for string operations!", op[0]);
+      snprintf (line, 512, "error: op %c not defined for string operations!", op[0]);
       push_error (line);
       return (FALSE);
@@ -877,5 +1083,5 @@
 escape:
   OUT[0].FltValue = value;
-  OUT[0].type = 'S';
+  OUT[0].type = ST_SCALAR_FLT;
 
   clear_stack (V1);
@@ -891,21 +1097,21 @@
   
 # define S_FUNC(OP,FTYPE) {			\
-    if (V1->type == 'S') {			\
+    if (V1->type == ST_SCALAR_FLT) {			\
       opihi_flt M1  = V1[0].FltValue;		\
-      OUT[0].type = 'S';			\
+      OUT[0].type = ST_SCALAR_FLT;			\
       OUT[0].FltValue = OP;			\
       clear_stack (V1);				\
       return (TRUE);				\
     }						\
-    if ((FTYPE == 'S') && (V1->type == 's')) {	\
+    if ((FTYPE == ST_SCALAR_FLT) && (V1->type == ST_SCALAR_INT)) {	\
       opihi_int M1  = V1[0].IntValue;		\
-      OUT[0].type = 'S';			\
+      OUT[0].type = ST_SCALAR_FLT;			\
       OUT[0].FltValue = OP;			\
       clear_stack (V1);				\
       return (TRUE);				\
     }						\
-    if ((FTYPE == 's') && (V1->type == 's')) {	\
+    if ((FTYPE == ST_SCALAR_INT) && (V1->type == ST_SCALAR_INT)) {	\
       opihi_int M1  = V1[0].IntValue;		\
-      OUT[0].type = 's';			\
+      OUT[0].type = ST_SCALAR_INT;			\
       OUT[0].IntValue = OP;			\
       clear_stack (V1);				\
@@ -914,40 +1120,40 @@
   }
 
-  if (!strcmp (op, "="))      S_FUNC(M1, 's');
-  if (!strcmp (op, "abs"))    S_FUNC(fabs(M1), 's');
-  if (!strcmp (op, "int"))    S_FUNC((long long)(M1), 's');
-  if (!strcmp (op, "exp"))    S_FUNC(exp (M1), 'S');
-  if (!strcmp (op, "ten"))    S_FUNC(pow (10.0,M1), 'S');
-  if (!strcmp (op, "log"))    S_FUNC(log10 (M1), 'S');
-  if (!strcmp (op, "ln"))     S_FUNC(log (M1), 'S');
-  if (!strcmp (op, "sqrt"))   S_FUNC(sqrt (M1), 'S');
-  if (!strcmp (op, "erf"))    S_FUNC(erf (M1), 'S');
-  if (!strcmp (op, "sinh"))   S_FUNC(sinh (M1), 'S');
-  if (!strcmp (op, "cosh"))   S_FUNC(cosh (M1), 'S');
-  if (!strcmp (op, "asinh"))  S_FUNC(asinh (M1), 'S');
-  if (!strcmp (op, "acosh"))  S_FUNC(acosh (M1), 'S');
-  if (!strcmp (op, "lgamma")) S_FUNC(lgamma (M1), 'S');
-  if (!strcmp (op, "sin"))    S_FUNC(sin (M1), 'S');
-  if (!strcmp (op, "cos"))    S_FUNC(cos (M1), 'S');
-  if (!strcmp (op, "tan"))    S_FUNC(tan (M1), 'S');
-  if (!strcmp (op, "dsin"))   S_FUNC(sin (M1*RAD_DEG), 'S');
-  if (!strcmp (op, "dcos"))   S_FUNC(cos (M1*RAD_DEG), 'S');
-  if (!strcmp (op, "dtan"))   S_FUNC(tan (M1*RAD_DEG), 'S');
-  if (!strcmp (op, "asin"))   S_FUNC(asin (M1), 'S');
-  if (!strcmp (op, "acos"))   S_FUNC(acos (M1), 'S');
-  if (!strcmp (op, "atan"))   S_FUNC(atan (M1), 'S');
-  if (!strcmp (op, "dasin"))  S_FUNC(asin (M1)*DEG_RAD, 'S');
-  if (!strcmp (op, "dacos"))  S_FUNC(acos (M1)*DEG_RAD, 'S');
-  if (!strcmp (op, "datan"))  S_FUNC(atan (M1)*DEG_RAD, 'S');
-  if (!strcmp (op, "rnd"))    S_FUNC(M1*0.0 + drand48(), 'S');
-  if (!strcmp (op, "not"))    S_FUNC(!(M1), 's');
-  if (!strcmp (op, "--"))     S_FUNC(-1*M1, 's'); // NOTE: opihi_int is signed, 
-  if (!strcmp (op, "isinf"))  S_FUNC(!finite(M1), 'S'); // XXX modify in future 
-  if (!strcmp (op, "isnan"))  S_FUNC(isnan(M1), 'S'); // XXX modify in future   
+  if (!strcmp (op, "="))      S_FUNC(M1, ST_SCALAR_INT);
+  if (!strcmp (op, "abs"))    S_FUNC(fabs(M1), ST_SCALAR_INT);
+  if (!strcmp (op, "int"))    S_FUNC((long long)(M1), ST_SCALAR_INT);
+  if (!strcmp (op, "exp"))    S_FUNC(exp (M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "ten"))    S_FUNC(pow (10.0,M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "log"))    S_FUNC(log10 (M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "ln"))     S_FUNC(log (M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "sqrt"))   S_FUNC(sqrt (M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "erf"))    S_FUNC(erf (M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "sinh"))   S_FUNC(sinh (M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "cosh"))   S_FUNC(cosh (M1), ST_SCALAR_FLT);
+  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);
+  if (!strcmp (op, "tan"))    S_FUNC(tan (M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "dsin"))   S_FUNC(sin (M1*RAD_DEG), ST_SCALAR_FLT);
+  if (!strcmp (op, "dcos"))   S_FUNC(cos (M1*RAD_DEG), ST_SCALAR_FLT);
+  if (!strcmp (op, "dtan"))   S_FUNC(tan (M1*RAD_DEG), ST_SCALAR_FLT);
+  if (!strcmp (op, "asin"))   S_FUNC(asin (M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "acos"))   S_FUNC(acos (M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "atan"))   S_FUNC(atan (M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "dasin"))  S_FUNC(asin (M1)*DEG_RAD, ST_SCALAR_FLT);
+  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, "rnd"))    S_FUNC(M1*0.0 + drand48(), ST_SCALAR_FLT);
+  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, 
+  if (!strcmp (op, "isinf"))  S_FUNC(!finite(M1), ST_SCALAR_FLT); // XXX modify in future 
+  if (!strcmp (op, "isnan"))  S_FUNC(isnan(M1), ST_SCALAR_FLT); // XXX modify in future   
 
 # undef S_FUNC
 
   clear_stack (V1);
-  sprintf (line, "error: op %s not defined!", op);
+  snprintf (line, 512, "error: op %s not defined!", op);
   push_error (line);
   return (FALSE);
@@ -962,5 +1168,5 @@
 
   OUT[0].vector = InitVector ();
-  OUT[0].type = 'v'; /*** <<--- says this is a temporary matrix ***/
+  OUT[0].type = ST_VECTOR_TMP; /*** <<--- says this is a temporary matrix ***/
 
 # define V_FUNC(OP,FTYPE) {					\
@@ -974,5 +1180,5 @@
       goto escape;						\
     }								\
-    if ((V1->vector->type == OPIHI_INT) && (FTYPE == 'S')) {	\
+    if ((V1->vector->type == OPIHI_INT) && (FTYPE == ST_SCALAR_FLT)) {	\
       MatchVector (OUT[0].vector, V1[0].vector, OPIHI_FLT);	\
       opihi_int *M1  = V1[0].vector[0].elements.Int;		\
@@ -983,5 +1189,5 @@
       goto escape;						\
     }								\
-    if ((V1->vector->type == OPIHI_INT) && (FTYPE == 's')) {	\
+    if ((V1->vector->type == OPIHI_INT) && (FTYPE == ST_SCALAR_INT)) {	\
       CopyVector (OUT[0].vector, V1[0].vector);			\
       opihi_int *M1  = V1[0].vector[0].elements.Int;		\
@@ -993,39 +1199,39 @@
     } }							
 
-  if (!strcmp (op, "="))      V_FUNC(*M1, 's');
-  if (!strcmp (op, "abs"))    V_FUNC(fabs(*M1), 's');
-  if (!strcmp (op, "int"))    V_FUNC((long long)(*M1), 's');
-  if (!strcmp (op, "exp"))    V_FUNC(exp(*M1), 'S');
-  if (!strcmp (op, "ten"))    V_FUNC(pow(10.0,*M1), 'S');
-  if (!strcmp (op, "log"))    V_FUNC(log10(*M1), 'S');
-  if (!strcmp (op, "ln"))     V_FUNC(log(*M1), 'S');
-  if (!strcmp (op, "sqrt"))   V_FUNC(sqrt(*M1), 'S');
-  if (!strcmp (op, "erf"))    V_FUNC(erf(*M1), 'S');
-  if (!strcmp (op, "sinh"))   V_FUNC(sinh(*M1), 'S');
-  if (!strcmp (op, "cosh"))   V_FUNC(cosh(*M1), 'S');
-  if (!strcmp (op, "asinh"))  V_FUNC(asinh(*M1), 'S');
-  if (!strcmp (op, "acosh"))  V_FUNC(acosh(*M1), 'S');
-  if (!strcmp (op, "lgamma")) V_FUNC(lgamma(*M1), 'S');
-  if (!strcmp (op, "sin"))    V_FUNC(sin(*M1), 'S');
-  if (!strcmp (op, "cos"))    V_FUNC(cos(*M1), 'S');
-  if (!strcmp (op, "tan"))    V_FUNC(tan(*M1), 'S');
-  if (!strcmp (op, "dsin"))   V_FUNC(sin(*M1*RAD_DEG), 'S');
-  if (!strcmp (op, "dcos"))   V_FUNC(cos(*M1*RAD_DEG), 'S');
-  if (!strcmp (op, "dtan"))   V_FUNC(tan(*M1*RAD_DEG), 'S');
-  if (!strcmp (op, "asin"))   V_FUNC(asin(*M1), 'S');
-  if (!strcmp (op, "acos"))   V_FUNC(acos(*M1), 'S');
-  if (!strcmp (op, "atan"))   V_FUNC(atan(*M1), 'S');
-  if (!strcmp (op, "dasin"))  V_FUNC(asin(*M1)*DEG_RAD, 'S');
-  if (!strcmp (op, "dacos"))  V_FUNC(acos(*M1)*DEG_RAD, 'S');
-  if (!strcmp (op, "datan"))  V_FUNC(atan(*M1)*DEG_RAD, 'S');
-  if (!strcmp (op, "rnd"))    V_FUNC(drand48(), 'S');
-  if (!strcmp (op, "ramp"))   V_FUNC(i, 's');
-  if (!strcmp (op, "zero"))   V_FUNC(0, 's');
-  if (!strcmp (op, "not"))    V_FUNC(!(*M1), 's');
-  if (!strcmp (op, "--"))     V_FUNC(-1*(*M1), 's'); // NOTE: opihi_int is signed
-  if (!strcmp (op, "isinf"))  V_FUNC(!finite(*M1), 'S');
-  if (!strcmp (op, "isnan"))  V_FUNC(isnan(*M1), 'S');
-  if (!strcmp (op, "xramp"))  V_FUNC(i, 's');
-  if (!strcmp (op, "yramp"))  V_FUNC(0, 's');
+  if (!strcmp (op, "="))      V_FUNC(*M1, ST_SCALAR_INT);
+  if (!strcmp (op, "abs"))    V_FUNC(fabs(*M1), ST_SCALAR_INT);
+  if (!strcmp (op, "int"))    V_FUNC((long long)(*M1), ST_SCALAR_INT);
+  if (!strcmp (op, "exp"))    V_FUNC(exp(*M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "ten"))    V_FUNC(pow(10.0,*M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "log"))    V_FUNC(log10(*M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "ln"))     V_FUNC(log(*M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "sqrt"))   V_FUNC(sqrt(*M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "erf"))    V_FUNC(erf(*M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "sinh"))   V_FUNC(sinh(*M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "cosh"))   V_FUNC(cosh(*M1), ST_SCALAR_FLT);
+  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);
+  if (!strcmp (op, "tan"))    V_FUNC(tan(*M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "dsin"))   V_FUNC(sin(*M1*RAD_DEG), ST_SCALAR_FLT);
+  if (!strcmp (op, "dcos"))   V_FUNC(cos(*M1*RAD_DEG), ST_SCALAR_FLT);
+  if (!strcmp (op, "dtan"))   V_FUNC(tan(*M1*RAD_DEG), ST_SCALAR_FLT);
+  if (!strcmp (op, "asin"))   V_FUNC(asin(*M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "acos"))   V_FUNC(acos(*M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "atan"))   V_FUNC(atan(*M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "dasin"))  V_FUNC(asin(*M1)*DEG_RAD, ST_SCALAR_FLT);
+  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, "rnd"))    V_FUNC(drand48(), ST_SCALAR_FLT);
+  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(*M1), ST_SCALAR_FLT);
+  if (!strcmp (op, "xramp"))  V_FUNC(i, ST_SCALAR_INT);
+  if (!strcmp (op, "yramp"))  V_FUNC(0, ST_SCALAR_INT);
   /* xramp and yramp above only make sense for matrices. for vectors, xramp = ramp, yramp = zero */
 
@@ -1034,5 +1240,5 @@
 escape:
 
-  if (V1[0].type == 'v') {
+  if (V1[0].type == ST_VECTOR_TMP) {
     free (V1[0].vector[0].elements.Ptr);
     free (V1[0].vector);
@@ -1053,12 +1259,12 @@
   Ny = V1[0].buffer[0].matrix.Naxis[1];
 
-  if (V1[0].type == 'm') {
+  if (V1[0].type == ST_MATRIX_TMP) {
     OUT[0].buffer = V1[0].buffer;
-    V1[0].type = 'M'; /* prevent it from being freed below */
+    V1[0].type = ST_MATRIX; /* prevent it from being freed below */
   } else {
     OUT[0].buffer = InitBuffer ();
     CopyBuffer (OUT[0].buffer, V1[0].buffer);
   }
-  OUT[0].type = 'm';      /*** <<--- says this is a temporary matrix ***/
+  OUT[0].type = ST_MATRIX_TMP;      /*** <<--- says this is a temporary matrix ***/
   M1  = (float *) V1[0].buffer[0].matrix.buffer;
   out = (float *)OUT[0].buffer[0].matrix.buffer;
@@ -1116,5 +1322,5 @@
   }
   
-  if (V1[0].type == 'm') {
+  if (V1[0].type == ST_MATRIX_TMP) {
     free (V1[0].buffer[0].header.buffer);
     free (V1[0].buffer[0].matrix.buffer);
