예제 #1
0
파일: genrcexe.c 프로젝트: DrItanium/maya
/**************************************************************************
  NAME         : CallSpecificMethod
  DESCRIPTION  : Allows a specific method to be called without regards to
                   higher precedence methods which might also be applicable
                   However, shadowed methods can still be called.
  INPUTS       : A data object buffer to hold the method evaluation result
  RETURNS      : Nothing useful
  SIDE EFFECTS : Side-effects of method applicability tests and the
                 evaluation of methods
  NOTES        : H/L Syntax: (call-specific-method
                                <generic-function> <method-index> <args>)
 **************************************************************************/
void CallSpecificMethod(
  Environment *theEnv,
  UDFContext *context,
  UDFValue *returnValue)
  {
   UDFValue theArg;
   Defgeneric *gfunc;
   int mi;

   returnValue->lexemeValue = FalseSymbol(theEnv);

   if (! UDFFirstArgument(context,SYMBOL_BIT,&theArg)) return;

   gfunc = CheckGenericExists(theEnv,"call-specific-method",theArg.lexemeValue->contents);
   if (gfunc == NULL) return;

   if (! UDFNextArgument(context,INTEGER_BIT,&theArg)) return;

   mi = CheckMethodExists(theEnv,"call-specific-method",gfunc,(unsigned short) theArg.integerValue->contents);
   if (mi == METHOD_NOT_FOUND)
     return;
   gfunc->methods[mi].busy++;
   GenericDispatch(theEnv,gfunc,NULL,&gfunc->methods[mi],
                   GetFirstArgument()->nextArg->nextArg,returnValue);
   gfunc->methods[mi].busy--;
  }
예제 #2
0
파일: watch.c 프로젝트: DrItanium/maya
void GetWatchItemCommand(
  Environment *theEnv,
  UDFContext *context,
  UDFValue *returnValue)
  {
   UDFValue theValue;
   const char *argument;
   bool recognized;

   /*========================================*/
   /* Determine which item is to be watched. */
   /*========================================*/

   if (! UDFFirstArgument(context,SYMBOL_BIT,&theValue))
     { return; }

   argument = theValue.lexemeValue->contents;
   ValidWatchItem(theEnv,argument,&recognized);
   if (recognized == false)
     {
      SetEvaluationError(theEnv,true);
      ExpectedTypeError1(theEnv,"get-watch-item",1,"'watchable symbol'");
      returnValue->lexemeValue = FalseSymbol(theEnv);
      return;
     }

   /*===========================*/
   /* Get the watch item value. */
   /*===========================*/

   if (GetWatchItem(theEnv,argument) == 1)
     { returnValue->lexemeValue = TrueSymbol(theEnv); }
   else
     { returnValue->lexemeValue = FalseSymbol(theEnv); }
  }
예제 #3
0
/**************************************************************************
  NAME         : CallSpecificMethod
  DESCRIPTION  : Allows a specific method to be called without regards to
                   higher precedence methods which might also be applicable
                   However, shadowed methods can still be called.
  INPUTS       : A data object buffer to hold the method evaluation result
  RETURNS      : Nothing useful
  SIDE EFFECTS : Side-effects of method applicability tests and the
                 evaluation of methods
  NOTES        : H/L Syntax: (call-specific-method
                                <generic-function> <method-index> <args>)
 **************************************************************************/
void CallSpecificMethod(
  UDFContext *context,
  CLIPSValue *returnValue)
  {
   CLIPSValue theArg;
   DEFGENERIC *gfunc;
   int mi;
   Environment *theEnv = UDFContextEnvironment(context);
   
   mCVSetBoolean(returnValue,false);
   
   if (! UDFFirstArgument(context,SYMBOL_TYPE,&theArg)) return;
     
   gfunc = CheckGenericExists(theEnv,"call-specific-method",mCVToString(&theArg));
   if (gfunc == NULL) return;
   
   if (! UDFNextArgument(context,INTEGER_TYPE,&theArg)) return;

   mi = CheckMethodExists(theEnv,"call-specific-method",gfunc,(long) mCVToInteger(&theArg));
   if (mi == -1)
     return;
   gfunc->methods[mi].busy++;
   GenericDispatch(theEnv,gfunc,NULL,&gfunc->methods[mi],
                   GetFirstArgument()->nextArg->nextArg,returnValue);
   gfunc->methods[mi].busy--;
  }
예제 #4
0
파일: classexm.c 프로젝트: DrItanium/maya
/******************************************************
  NAME         : CheckTwoClasses
  DESCRIPTION  : Checks for exactly two class arguments
                    for a H/L function
  INPUTS       : 1) The function name
                 2) Caller's buffer for first class
                 3) Caller's buffer for second class
  RETURNS      : True if both found, false otherwise
  SIDE EFFECTS : Caller's buffers set
  NOTES        : Assumes exactly 2 arguments
 ******************************************************/
static bool CheckTwoClasses(
  UDFContext *context,
  const char *func,
  Defclass **c1,
  Defclass **c2)
  {
   UDFValue theArg;
   Environment *theEnv = context->environment;

   if (! UDFFirstArgument(context,SYMBOL_BIT,&theArg))
     { return false; }

   *c1 = LookupDefclassByMdlOrScope(theEnv,theArg.lexemeValue->contents);
   if (*c1 == NULL)
     {
      ClassExistError(theEnv,func,theArg.lexemeValue->contents);
      return false;
     }

   if (! UDFNextArgument(context,SYMBOL_BIT,&theArg))
     { return false; }

   *c2 = LookupDefclassByMdlOrScope(theEnv,theArg.lexemeValue->contents);
   if (*c2 == NULL)
     {
      ClassExistError(theEnv,func,theArg.lexemeValue->contents);
      return false;
     }

   return true;
  }
예제 #5
0
파일: classexm.c 프로젝트: DrItanium/maya
/****************************************************************
  NAME         : BrowseClassesCommand
  DESCRIPTION  : Displays a "graph" of the class hierarchy
  INPUTS       : None
  RETURNS      : Nothing useful
  SIDE EFFECTS : None
  NOTES        : Syntax : (browse-classes [<class>])
 ****************************************************************/
void BrowseClassesCommand(
  Environment *theEnv,
  UDFContext *context,
  UDFValue *returnValue)
  {
   Defclass *cls;

   if (UDFArgumentCount(context) == 0)
      /* ================================================
         Find the OBJECT root class (has no superclasses)
         ================================================ */
      cls = LookupDefclassByMdlOrScope(theEnv,OBJECT_TYPE_NAME);
   else
     {
      UDFValue theArg;

      if (! UDFFirstArgument(context,SYMBOL_BIT,&theArg))
        return;
      cls = LookupDefclassByMdlOrScope(theEnv,theArg.lexemeValue->contents);
      if (cls == NULL)
        {
         ClassExistError(theEnv,"browse-classes",theArg.lexemeValue->contents);
         return;
        }
     }
   BrowseClasses(cls,STDOUT);
  }
예제 #6
0
파일: classexm.c 프로젝트: DrItanium/maya
/*********************************************************
  NAME         : GetClassNameArgument
  DESCRIPTION  : Gets a class name-string
  INPUTS       : Calling function name
  RETURNS      : Class name (NULL on errors)
  SIDE EFFECTS : None
  NOTES        : Assumes only 1 argument
 *********************************************************/
static const char *GetClassNameArgument(
  UDFContext *context)
  {
   UDFValue theArg;

   if (! UDFFirstArgument(context,SYMBOL_BIT,&theArg))
     { return NULL; }

   return theArg.lexemeValue->contents;
  }
예제 #7
0
void DivisionFunction(
  UDFContext *context,
  CLIPSValue *returnValue)
  {
   CLIPSFloat ftotal = 1.0;
   CLIPSFloat theNumber;
   CLIPSValue theArg;
   Environment *theEnv = UDFContextEnvironment(context);
   
   /*===================================================*/
   /* Get the first argument. This number which will be */
   /* the starting product from which all subsequent    */
   /* arguments will divide. If the auto float dividend */
   /* feature is enable, then this number is converted  */
   /* to a float if it is an integer.                   */
   /*===================================================*/

   if (! UDFFirstArgument(context,NUMBER_TYPES,&theArg))
     { return; }

   ftotal = mCVToFloat(&theArg);

   /*====================================================*/
   /* Loop through each of the arguments dividing it     */
   /* into a running product. If a floating point number */
   /* is encountered, then do all subsequent operations  */
   /* using floating point values. Each argument is      */
   /* checked to prevent a divide by zero error.         */
   /*====================================================*/

   while (UDFHasNextArgument(context))
     {
      if (! UDFNextArgument(context,NUMBER_TYPES,&theArg))
        { return; }
        
      theNumber = mCVToFloat(&theArg);
      
      if (theNumber == 0.0)
        {
         DivideByZeroErrorMessage(theEnv,"/");
         EnvSetEvaluationError(theEnv,true);
         mCVSetFloat(returnValue,1.0);
         return;
        }

      ftotal /= theNumber;
     }

   /*======================================================*/
   /* If a floating point number was in the argument list, */
   /* then return a float, otherwise return an integer.    */
   /*======================================================*/

   mCVSetFloat(returnValue,ftotal);
  }
예제 #8
0
파일: classexm.c 프로젝트: DrItanium/maya
/********************************************************
  NAME         : ClassExistPCommand
  DESCRIPTION  : Determines if a class exists
  INPUTS       : None
  RETURNS      : True if class exists, false otherwise
  SIDE EFFECTS : None
  NOTES        : H/L Syntax : (class-existp <arg>)
 ********************************************************/
void ClassExistPCommand(
  Environment *theEnv,
  UDFContext *context,
  UDFValue *returnValue)
  {
   UDFValue theArg;

   if (! UDFFirstArgument(context,SYMBOL_BIT,&theArg))
     { return; }

   returnValue->lexemeValue = CreateBoolean(theEnv,((LookupDefclassByMdlOrScope(theEnv,theArg.lexemeValue->contents) != NULL) ? true : false));
  }
예제 #9
0
void DivFunction(
  UDFContext *context,
  CLIPSValue *returnValue)
  {
   CLIPSInteger total = 1LL;
   DATA_OBJECT theArg;
   CLIPSInteger theNumber;
   void *theEnv = UDFContextEnvironment(context);

   /*===================================================*/
   /* Get the first argument. This number which will be */
   /* the starting product from which all subsequent    */
   /* arguments will divide.                            */
   /*===================================================*/

   if (! UDFFirstArgument(context,NUMBER_TYPES,&theArg))
     { return; }
   total = mCVToInteger(&theArg);

   /*=====================================================*/
   /* Loop through each of the arguments dividing it into */
   /* a running product. Floats are converted to integers */
   /* and each argument is checked to prevent a divide by */
   /* zero error.                                         */
   /*=====================================================*/

   while (UDFHasNextArgument(context))
     {
      if (! UDFNextArgument(context,NUMBER_TYPES,&theArg))
        { return; }

      theNumber = mCVToInteger(&theArg);

      if (theNumber == 0LL)
        {
         DivideByZeroErrorMessage(theEnv,"div");
         EnvSetEvaluationError(theEnv,true);
         mCVSetInteger(returnValue,1L);
         return;
        }
        
      total /= theNumber;
     }

   /*======================================================*/
   /* The result of the div function is always an integer. */
   /*======================================================*/

   mCVSetInteger(returnValue,total);
  }
예제 #10
0
파일: constrnt.c 프로젝트: DrItanium/maya
void SDCCommand(
  Environment *theEnv,
  UDFContext *context,
  UDFValue *returnValue)
  {
   UDFValue theArg;

   returnValue->lexemeValue = CreateBoolean(theEnv,GetDynamicConstraintChecking(theEnv));

   if (! UDFFirstArgument(context,ANY_TYPE_BITS,&theArg))
     { return; }

   SetDynamicConstraintChecking(theEnv,theArg.value != FalseSymbol(theEnv));
  }
예제 #11
0
파일: moduldef.c 프로젝트: DrItanium/maya
void SetCurrentModuleCommand(
  Environment *theEnv,
  UDFContext *context,
  UDFValue *returnValue)
  {
   UDFValue theArg;
   const char *argument;
   Defmodule *theModule;
   CLIPSLexeme *oldModuleName;

   /*=======================*/
   /* Set the return value. */
   /*=======================*/

   theModule = GetCurrentModule(theEnv);
   if (theModule == NULL)
     {
      returnValue->lexemeValue = FalseSymbol(theEnv);
      return;
     }

   oldModuleName = theModule->header.name;
   returnValue->value = oldModuleName;

   /*=====================================================*/
   /* Check for the correct number and type of arguments. */
   /*=====================================================*/

   if (! UDFFirstArgument(context,SYMBOL_BIT,&theArg))
     { return; }

   argument = theArg.lexemeValue->contents;

   /*================================================*/
   /* Set the current module to the specified value. */
   /*================================================*/

   theModule = FindDefmodule(theEnv,argument);

   if (theModule == NULL)
     {
      CantFindItemErrorMessage(theEnv,"defmodule",argument,true);
      return;
     }

   SetCurrentModule(theEnv,theModule);
  }
예제 #12
0
파일: watch.c 프로젝트: DrItanium/maya
void UnwatchCommand(
  Environment *theEnv,
  UDFContext *context,
  UDFValue *returnValue)
  {
   UDFValue theValue;
   const char *argument;
   bool recognized;
   WatchItemRecord *wPtr;

   /*==========================================*/
   /* Determine which item is to be unwatched. */
   /*==========================================*/

   if (! UDFFirstArgument(context,SYMBOL_BIT,&theValue)) return;

   argument = theValue.lexemeValue->contents;
   wPtr = ValidWatchItem(theEnv,argument,&recognized);
   if (recognized == false)
     {
      SetEvaluationError(theEnv,true);
      UDFInvalidArgumentMessage(context,"watchable symbol");
      return;
     }

   /*=================================================*/
   /* Check to make sure extra arguments are allowed. */
   /*=================================================*/

   if (GetNextArgument(GetFirstArgument()) != NULL)
     {
      if ((wPtr == NULL) ? true : (wPtr->accessFunc == NULL))
        {
         SetEvaluationError(theEnv,true);
         ExpectedCountError(theEnv,"unwatch",EXACTLY,1);
         return;
        }
     }

   /*=====================*/
   /* Set the watch item. */
   /*=====================*/

   SetWatchItem(theEnv,argument,false,GetNextArgument(GetFirstArgument()));
  }
예제 #13
0
파일: argacces.c 프로젝트: DrItanium/maya
const char *GetConstructName(
  UDFContext *context,
  const char *functionName,
  const char *constructType)
  {
   UDFValue returnValue;

   if (! UDFFirstArgument(context,ANY_TYPE_BITS,&returnValue))
     { return NULL; }

   if (! CVIsType(&returnValue,SYMBOL_BIT))
     {
      UDFInvalidArgumentMessage(context,constructType);
      return NULL;
     }

   return(returnValue.lexemeValue->contents);
  }
예제 #14
0
파일: classexm.c 프로젝트: DrItanium/maya
/************************************************************************************
  NAME         : MessageHandlerExistPCommand
  DESCRIPTION  : Determines if a message-handler is present in a class
  INPUTS       : None
  RETURNS      : True if the message header is present, false otherwise
  SIDE EFFECTS : None
  NOTES        : H/L Syntax : (message-handler-existp <class> <hnd> [<type>])
 ************************************************************************************/
void MessageHandlerExistPCommand(
  Environment *theEnv,
  UDFContext *context,
  UDFValue *returnValue)
  {
   Defclass *cls;
   CLIPSLexeme *mname;
   UDFValue theArg;
   unsigned mtype = MPRIMARY;

   if (! UDFFirstArgument(context,SYMBOL_BIT,&theArg))
     { return; }
   cls = LookupDefclassByMdlOrScope(theEnv,theArg.lexemeValue->contents);
   if (cls == NULL)
     {
      ClassExistError(theEnv,"message-handler-existp",theArg.lexemeValue->contents);
      returnValue->lexemeValue = FalseSymbol(theEnv);
      return;
     }

   if (! UDFNextArgument(context,SYMBOL_BIT,&theArg))
        { return; }

   mname = theArg.lexemeValue;
   if (UDFHasNextArgument(context))
     {
      if (! UDFNextArgument(context,SYMBOL_BIT,&theArg))
        { return; }

      mtype = HandlerType(theEnv,"message-handler-existp",true,theArg.lexemeValue->contents);
      if (mtype == MERROR)
        {
         SetEvaluationError(theEnv,true);
         returnValue->lexemeValue = FalseSymbol(theEnv);
         return;
        }
     }

   if (FindHandlerByAddress(cls,mname,mtype) != NULL)
     { returnValue->lexemeValue = TrueSymbol(theEnv); }
   else
     { returnValue->lexemeValue = FalseSymbol(theEnv); }
  }
예제 #15
0
파일: proflfun.c 프로젝트: DrItanium/maya
void ProfileCommand(
  Environment *theEnv,
  UDFContext *context,
  UDFValue *returnValue)
  {
   const char *argument;
   UDFValue theValue;

   if (! UDFFirstArgument(context,SYMBOL_BIT,&theValue)) return;
   argument = theValue.lexemeValue->contents;

   if (! Profile(theEnv,argument))
     {
      UDFInvalidArgumentMessage(context,"symbol with value constructs, user-functions, or off");
      return;
     }

   return;
  }
예제 #16
0
void MaxFunction(
  UDFContext *context,
  CLIPSValue *returnValue)
  {
   CLIPSValue nextPossible;
   
   /*============================================*/
   /* Check that the first argument is a number. */
   /*============================================*/

   if (! UDFFirstArgument(context,NUMBER_TYPES,returnValue))
     { return; }

   /*===========================================================*/
   /* Loop through the remaining arguments, first checking each */
   /* argument to see that it is a number, and then determining */
   /* if the argument is greater than the previous arguments    */
   /* and is thus the maximum value.                            */
   /*===========================================================*/

   while (UDFHasNextArgument(context))
     {
      if (! UDFNextArgument(context,NUMBER_TYPES,&nextPossible))
        { return; }
      
      /*=============================================*/
      /* If either argument is a float, convert both */
      /* to floats. Otherwise compare two integers.  */
      /*=============================================*/
      
      if (mCVIsType(returnValue,FLOAT_TYPE) || mCVIsType(&nextPossible,FLOAT_TYPE))
        {
         if (mCVToFloat(returnValue) < mCVToFloat(&nextPossible))
           { CVSetCLIPSValue(returnValue,&nextPossible); }
        }
      else
        {
         if (mCVToInteger(returnValue) < mCVToInteger(&nextPossible))
           { CVSetCLIPSValue(returnValue,&nextPossible); }
        }
     }
  }
예제 #17
0
파일: proflfun.c 프로젝트: DrItanium/maya
void SetProfilePercentThresholdCommand(
  Environment *theEnv,
  UDFContext *context,
  UDFValue *returnValue)
  {
   UDFValue theValue;
   double newThreshold;

   if (! UDFFirstArgument(context,NUMBER_BITS,&theValue))
     { return; }

   newThreshold = CVCoerceToFloat(&theValue);

   if ((newThreshold < 0.0) || (newThreshold > 100.0))
     {
      UDFInvalidArgumentMessage(context,"number in the range 0 to 100");
      returnValue->floatValue = CreateFloat(theEnv,-1.0);
     }
   else
     { returnValue->floatValue = CreateFloat(theEnv,SetProfilePercentThreshold(theEnv,newThreshold)); }
  }
예제 #18
0
void ExitCommand(
  UDFContext *context,
  CLIPSValue *returnValue)
  {
   int argCnt;
   int status;
   CLIPSValue value;
   Environment *theEnv = UDFContextEnvironment(context);

   argCnt = UDFArgumentCount(context);
   if (argCnt == 0)
     { EnvExitRouter(theEnv,EXIT_SUCCESS); }
   else
    {
     if (! UDFFirstArgument(context,INTEGER_TYPE,&value))
       { EnvExitRouter(theEnv,EXIT_SUCCESS); }
     status = (int) mCVToInteger(&value);
     if (EnvGetEvaluationError(theEnv)) return;
     EnvExitRouter(theEnv,status);
    }

   return;
  }
예제 #19
0
void SubtractionFunction(
  UDFContext *context,
  CLIPSValue *returnValue)
  {
   CLIPSFloat ftotal = 0.0;
   CLIPSInteger ltotal = 0LL;
   bool useFloatTotal = false;
   CLIPSValue theArg;

   /*=================================================*/
   /* Get the first argument. This number which will  */
   /* be the starting total from which all subsequent */
   /* arguments will subtracted.                      */
   /*=================================================*/

   if (! UDFFirstArgument(context,NUMBER_TYPES,&theArg))
     { return; }

   if (mCVIsType(&theArg,INTEGER_TYPE))
     { ltotal = mCVToInteger(&theArg); }
   else
     {
      ftotal = mCVToFloat(&theArg);
      useFloatTotal = true;
     }

   /*===================================================*/
   /* Loop through each of the arguments subtracting it */
   /* from a running total. If a floating point number  */
   /* is encountered, then do all subsequent operations */
   /* using floating point values.                      */
   /*===================================================*/

   while (UDFHasNextArgument(context))
     {
      if (! UDFNextArgument(context,NUMBER_TYPES,&theArg))
        { return; }

      if (useFloatTotal)
        { ftotal -= mCVToFloat(&theArg); }
      else
        {
         if (mCVIsType(&theArg,INTEGER_TYPE))
           { ltotal -= mCVToInteger(&theArg); }
         else
           {
            ftotal = ((CLIPSFloat) ltotal) - mCVToFloat(&theArg);
            useFloatTotal = true;
           }
        }
     }

   /*======================================================*/
   /* If a floating point number was in the argument list, */
   /* then return a float, otherwise return an integer.    */
   /*======================================================*/

   if (useFloatTotal)
     { mCVSetFloat(returnValue,ftotal); }
   else
     { mCVSetInteger(returnValue,ltotal); }
  }
예제 #20
0
파일: watch.c 프로젝트: DrItanium/maya
void ListWatchItemsCommand(
  Environment *theEnv,
  UDFContext *context,
  UDFValue *returnValue)
  {
   WatchItemRecord *wPtr;
   UDFValue theValue;
   bool recognized;

   /*=======================*/
   /* List the watch items. */
   /*=======================*/

   if (GetFirstArgument() == NULL)
     {
      for (wPtr = WatchData(theEnv)->ListOfWatchItems; wPtr != NULL; wPtr = wPtr->next)
        {
         WriteString(theEnv,STDOUT,wPtr->name);
         if (*(wPtr->flag)) WriteString(theEnv,STDOUT," = on\n");
         else WriteString(theEnv,STDOUT," = off\n");
        }
      return;
     }

   /*=======================================*/
   /* Determine which item is to be listed. */
   /*=======================================*/

   if (! UDFFirstArgument(context,SYMBOL_BIT,&theValue)) return;
   wPtr = ValidWatchItem(theEnv,theValue.lexemeValue->contents,&recognized);
   if ((recognized == false) || (wPtr == NULL))
     {
      SetEvaluationError(theEnv,true);
      ExpectedTypeError1(theEnv,"list-watch-items",1,"'watchable symbol'");
      return;
     }

   /*=================================================*/
   /* Check to make sure extra arguments are allowed. */
   /*=================================================*/

   if ((wPtr->printFunc == NULL) &&
       (GetNextArgument(GetFirstArgument()) != NULL))
     {
      SetEvaluationError(theEnv,true);
      ExpectedCountError(theEnv,"list-watch-items",EXACTLY,1);
      return;
     }

   /*====================================*/
   /* List the status of the watch item. */
   /*====================================*/

   WriteString(theEnv,STDOUT,wPtr->name);
   if (*(wPtr->flag)) WriteString(theEnv,STDOUT," = on\n");
   else WriteString(theEnv,STDOUT," = off\n");

   /*============================================*/
   /* List the status of individual watch items. */
   /*============================================*/

   if (wPtr->printFunc != NULL)
     {
      if ((*wPtr->printFunc)(theEnv,STDOUT,wPtr->code,
                             GetNextArgument(GetFirstArgument())) == false)
        { SetEvaluationError(theEnv,true); }
     }
  }