Ejemplo n.º 1
0
/* Return an interpolated numeric value from a list based on a fractional
   "distance" through the list.
 */
MincFloat
_minc_interp(const MincValue args[], const int nargs)
{
	MincFloat outValue = -1;
	if (nargs != 2)
		minc_warn("interp: must have two arguments (list, fraction)");
	else {
		assert(args[1].dataType() == MincFloatType);	// must pass a float as fractional value
		if (args[0].dataType() != MincListType) {
			minc_warn("interp: first argument must be a list");
			return -1.0;
		}
		MincValue *data = ((MincList*)args[0])->data;
		int len = ((MincList*)args[0])->len;
		// Deal with degenerate cases
		if (len == 0)
			return 0.0;
		else if (len == 1)
			return (MincFloat)data[0];
		float fraction = (MincFloat)args[1];
		fraction = (fraction < 0.0) ? 0.0 : (fraction > 1.0) ? 1.0 : fraction;
		int lowIndex = (int)((len - 1) * fraction);
		int highIndex = min(len - 1, lowIndex + 1);
		if (data[lowIndex].dataType() != MincFloatType || data[highIndex].dataType() != MincFloatType) {
			minc_warn("interp: list elements to interpolate must both be floats");
			return -1;
		}
		outValue = (MincFloat)data[lowIndex] + fraction * ((MincFloat)data[highIndex] - (MincFloat)data[lowIndex]);
	}
	return outValue;
}
Ejemplo n.º 2
0
/* Print the length of the argument.  This is useful for getting the number
   of items in a list or the number of characters in a string.
*/
MincFloat
_minc_len(const MincValue args[], const int nargs)
{
   unsigned long len = 0;

   if (nargs != 1)
      minc_warn("len: must have one argument");
   else {
      switch (args[0].dataType() ) {
         case MincFloatType:
            len = 1;
            break;
         case MincStringType:
            len = strlen((MincString)args[0]);
            break;
         case MincHandleType:
            /* NB: To get length of a table, call tablelen(handle) */
            len = 1;
            break;
         case MincListType:
            len = ((MincList *)args[0])->len;
            break;
         default:
            minc_warn("len: invalid argument");
            break;
      }
   }
   return (MincFloat) len;
}
Ejemplo n.º 3
0
/* Given an item (float, string or handle), return the index of the item within
   the given list, or -1 if the item is not in the list.  Example:

      list = {1, 2, "three", 4}
      id = index(list, 2)

   <id> equals 1 after this call.
*/
MincFloat
_minc_index(const MincValue args[], const int nargs)
{
   int i, len, index = -1;
   MincDataType argtype;
   MincValue *data;

   if (nargs != 2) {
      minc_warn("index: must have two arguments (list, item_to_find)");
      return -1.0;
   }
   if (args[0].dataType() != MincListType) {
      minc_warn("index: first argument must be a list");
      return -1.0;
   }
   argtype = args[1].dataType() ;
   assert(argtype == MincFloatType || argtype == MincStringType
            || argtype == MincHandleType || argtype == MincListType);

   len = ((MincList *)args[0])->len;
   data = ((MincList *)args[0])->data;

   for (i = 0; i < len; i++) {
      if (data[i].dataType() == argtype) {
         if (argtype == MincFloatType) {
            if ((MincFloat)data[i] == (MincFloat)args[1]) {
               index = i;
               break;
            }
         }
         else if (argtype == MincStringType) {
            if (strcmp((MincString)data[i], (MincString)args[1]) == 0) {
               index = i;
               break;
            }
         }
//FIXME: should this recurse and match entire list contents??
         else if (argtype == MincListType) {
            if ((MincList*)data[i] == (MincList*)args[1]) {
               index = i;
               break;
            }
         }
         else if (argtype == MincHandleType) {
			 if ((MincHandle)data[i] == (MincHandle)args[1]) {
               index = i;
               break;
            }
         }
      }
   }

   return (MincFloat) index;
}
Ejemplo n.º 4
0
/* Return the passed in (double) argument as a string type.
 */
MincString
_minc_tostring(const MincValue args[], const int nargs)
{
	if (nargs != 1) {
		minc_warn("tostring: must have one argument");
		return NULL;
	}
	if (args[0].dataType() != MincFloatType) {
		minc_warn("tostring: argument must be float type");
		return NULL;
	}
	const char *convertedString = DOUBLE_TO_STRING((MincString)args[0]);
	return strdup(convertedString);
}
Ejemplo n.º 5
0
/* Print the object type of the argument: float, string, handle, list.
*/
MincString
_minc_type(const MincValue args[], const int nargs)
{
   if (nargs != 1) {
      minc_warn("type: must have one argument");
      return NULL;
   }
   return _make_type_string(args[0].dataType() );
}
Ejemplo n.º 6
0
/* Free storage for reuse.  Very closely connected to symalloc.
   TBD:  only allow a maximum freelist length
*/
static void
free_node(struct symbol *p)
{
   if (p == NULL) {
      minc_warn("free_node was called with NULL ptr ");
      return;
   }

   if (freelist == NULL)
      freelist = p;
   else {
      p->next = freelist;
      freelist = p;
   }
}
Ejemplo n.º 7
0
MincFloat
_minc_printf(const MincValue args[], const int nargs)
{
   int n;
   const char *p;

   if (get_print_option() < MMP_PRINTS) return 0.0;

   if (args[0].dataType() != MincStringType) {
      minc_warn("printf: first argument must be format string");
      goto err;
   }

   n = 1;
   p = (MincString) args[0];
   while (*p) {
      switch (*p) {
         case '%':
            p++;
            if (n >= nargs) {
               minc_warn("printf: not enough arguments for format string");
               goto err;
            }
            switch (*p) {
               case 'd':      /* print float object as integer */
                  if (args[n].dataType() != MincFloatType) {
                     minc_warn("printf: wrong argument type for format");
                     goto err;
                  }
                  RTPrintfCat("%d", (int) (MincFloat)args[n]);
                  break;
               case 'f':      /* print float object */
                  if (args[n].dataType() != MincFloatType) {
                     minc_warn("printf: wrong argument type for format");
                     goto err;
                  }
                  RTPrintfCat("%.12g", (MincFloat)args[n]);
                  break;
               case 'l':      /* print list object */
                  if (args[n].dataType() != MincListType) {
                     minc_warn("printf: wrong argument type for format");
                     goto err;
                  }
                  RTPrintfCat("[");
                  _do_print(((MincList *)args[n])->data, ((MincList *)args[n])->len);
                  RTPrintfCat("]");
                  break;
               case 's':      /* print string object */
                  if (args[n].dataType() != MincStringType) {
                     minc_warn("printf: wrong argument type for format");
                     goto err;
                  }
                  RTPrintfCat("%s", (MincString)args[n]);
                  break;
               case 't':      /* print type of object */
                  {
                     char *tstr = (char *) _make_type_string(args[n].dataType() );
                     RTPrintfCat("%s", tstr);
                     free(tstr);
                  }
                  break;
               case 'z':      /* print as appropriate for type */
                  _do_print(&args[n], 1);
                  break;
               case '\0':
                  minc_warn("printf: premature end of format string");
                  goto err;
                  break;
               default:
                  minc_warn("printf: invalid format specifier");
                  goto err;
                  break;
            }
            n++;
            p++;
            break;
         case '\\':
            p++;
            switch (*p) {
               case 'n':
                  RTPrintfCat("\n");
                  break;
               case 't':
                  RTPrintfCat("\t");
                  break;
//FIXME: currently, minc.l can't handle escaped quotes in strings
               case '\'':
                  RTPrintfCat("'");
                  break;
               case '"':
                  RTPrintfCat("\"");
                  break;
               case '\0':
                  minc_warn("printf: premature end of format string");
                  goto err;
                  break;
               default:
                  minc_warn("printf: invalid escape character");
                  goto err;
                  break;
            }
            p++;
            break;
         default:
            RTPrintfCat("%c", *p);
            p++;
            break;
      }
   }
   return 0.0;
err:
   RTPrintf("\n");
//   fflush(stdout);
   return -1.0;
}