def do(self, theEnv, theFirst, *args, **kargs):
        """
        handler of the function
        @see: http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.5.html#Heading256
        """

        theFirst = self.resolve(theEnv, theFirst) if isinstance(
            theFirst, (types.FunctionCall, types.Variable)) else theFirst

        if not isinstance(theFirst, (types.Integer, types.Float)):
            raise InvalidArgTypeError(
                "Function * expected argument #1 to be of type integer or float"
            )

        theMul = theFirst.evaluate()

        for (index, theSecond) in enumerate(args):
            if isinstance(theSecond, (types.FunctionCall, types.Variable)):
                theSecond = self.resolve(theEnv, theSecond)

            if not isinstance(theSecond, (types.Integer, types.Float)):
                raise InvalidArgTypeError(
                    "Function * expected argument #%d to be of type integer or float"
                    % index + 2)

            theMul = theMul * theSecond.evaluate()

        # CLIPS documentation:
        # after all computations, if the value is still an integer, then create a new <Integer:theMul>
        # otherwise <Float:theMul>

        if isinstance(theMul, int):
            return types.Integer(theMul)
        else:
            return types.Float(theMul)
Example #2
0
    def do(self, theEnv, theFirst, *args, **kargs):
        """
        handler of the function
        @see: http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.5.html#Heading260
        """

        theFirst = self.resolve(theEnv, theFirst) if isinstance(
            theFirst, (types.FunctionCall, types.Variable)) else theFirst

        if not isinstance(theFirst, (types.Integer, types.Float)):
            raise InvalidArgTypeError(
                "Function max expected argument #1 to be of type integer or float"
            )

        theMin = theFirst

        for (index, theSecond) in enumerate(args):
            if isinstance(theSecond, (types.FunctionCall, types.Variable)):
                theSecond = self.resolve(theEnv, theSecond)

            if not isinstance(theSecond, (types.Integer, types.Float)):
                raise InvalidArgTypeError(
                    "Function max expected argument #%d to be of type integer or float"
                    % index + 2)

            theMin = theMin if theMin.evaluate() <= theSecond.evaluate(
            ) else theSecond

        return theMin
    def do(self, theEnv, theFirst, *args, **kargs):
        """
        handler of the function
        @see: http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.5.html#Heading258
        """

        theFirst = self.resolve(theEnv, theFirst) if isinstance(
            theFirst, (types.FunctionCall, types.Variable)) else theFirst

        if not isinstance(theFirst, (types.Integer, types.Float)):
            raise InvalidArgTypeError(
                "Function div expected argument #1 to be of type integer or float"
            )

        theDiv = int(theFirst.evaluate())

        for (index, theSecond) in enumerate(args):
            if isinstance(theSecond, (types.FunctionCall, types.Variable)):
                theSecond = self.resolve(theEnv, theSecond)

            if not isinstance(theSecond, (types.Integer, types.Float)):
                raise InvalidArgTypeError(
                    "Function div expected argument #%d to be of type integer or float"
                    % index + 2)

            # Division is always performed between integer values
            # and result is always casted to an integer
            theDiv = int(theDiv / int(theSecond.evaluate()))

        # WARNING:
        # this function always return an Integer!
        return types.Integer(theDiv)
Example #4
0
    def do(self, theEnv, thePath, theName, theMode=None, *args, **kargs):
        """
        handler of the function
        @see: http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.4.html#Heading244
        """

        thePath = self.resolve(theEnv, thePath) if isinstance(
            thePath, (types.FunctionCall, types.Variable)) else thePath
        theName = self.resolve(theEnv, theName) if isinstance(
            theName, (types.FunctionCall, types.Variable)) else theName
        theMode = self.resolve(theEnv, theMode) if isinstance(theMode, (types.FunctionCall, types.Variable)) \
                    else theMode if theMode is not None else types.String("r")

        if not isinstance(thePath, (types.String, types.Symbol)):
            raise InvalidArgTypeError(
                "Function open expected argument #1 to be of type string or symbol"
            )

        # normalize the string to a path. In documentation:
        # all special chars and \ in the path must be escaped
        # these means that the path is already a valid path
        # for python
        thePath = thePath.evaluate() if isinstance(
            thePath, types.Symbol) else thePath.evaluate()[1:-1]

        if not isinstance(theName, types.Symbol):
            raise InvalidArgTypeError(
                "Function open expected argument #2 to be of type symbol")

        # check if a resource with the same logical name is already used
        assert isinstance(theEnv, FunctionEnv)
        if theEnv.RESOURCES.has_key(theName.evaluate()):
            raise InvalidArgValueError(
                "Illegal logical name used for open function: %s" %
                theName.evaluate())

        if not isinstance(theMode, types.String):
            raise InvalidArgTypeError(
                "Function open expected argument #3 to be of type string")

        # normalize the mode removing quotes if <String>
        theMode = theMode.evaluate()[1:-1]

        modeMap = {"r": "rU", "r+": "rU+", "w": "w", "a": "a"}

        import myclips
        try:
            theMode = modeMap[theMode]
            fileResource = open(thePath, theMode)
            theEnv.RESOURCES[theName.evaluate()] = fileResource
            return types.Symbol("TRUE")
        except KeyError:
            myclips.logger.error("Invalid mode for Open: %s", theMode)
            return types.Symbol("FALSE")
        except IOError, e:
            myclips.logger.error("IOError in Open: %s", e)
            return types.Symbol("FALSE")
Example #5
0
    def do(self, theEnv, theName=None, *args, **kargs):
        """
        handler of the function
        @see: http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.4.html#Heading245
        """

        theName = self.resolve(theEnv, theName) if isinstance(
            theName, (types.FunctionCall, types.Variable)) else theName

        if theName is None:
            toClose = theEnv.RESOURCES.keys()
        elif not isinstance(theName, types.Symbol):
            raise InvalidArgTypeError(
                "Function open expected argument #1 to be of type symbol")
        else:
            toClose = [theName.evaluate()]

        if len(toClose) > 0:
            try:
                for resourceName in toClose:
                    theEnv.RESOURCES[resourceName].close()
                    del theEnv.RESOURCES[resourceName]
                return types.Symbol("TRUE")
            except KeyError:
                return types.Symbol("FALSE")
        else:
            return types.Symbol("FALSE")
Example #6
0
    def do(self, theEnv, theName=None, *args, **kargs):
        """
        handler of the function
        @see: http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.4.html#Heading248
        """

        theName = self.resolve(theEnv, theName) if isinstance(
            theName, (types.FunctionCall, types.Variable)) else theName

        if theName is None or (isinstance(theName, types.Symbol)
                               and theName.pyEqual("t")):
            theResource = theEnv.RESOURCES["stdin"]
        elif not isinstance(theName, types.Symbol):
            raise InvalidArgTypeError(
                "Function read expected argument #1 to be of type symbol")
        else:
            theResource = theEnv.RESOURCES[theName.evaluate()]

        try:

            theString = theResource.readline()

            # python file.readline() doc:
            #    An empty string is returned only when EOF is encountered immediately
            #    @see http://docs.python.org/release/2.4.4/lib/bltin-file-objects.html
            if theString == "":
                return types.Symbol("EOF")

            return types.String(theString)

        except EOFError:
            return types.Symbol("EOF")
        except IOError:
            return types.Symbol("*** READ ERROR ***")
Example #7
0
 def do(self, theEnv, theNumber, *args, **kargs):
     """
     handler of the function
     @see: http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.5.html#Heading262
     """
     
     theNumber = self.resolve(theEnv, theNumber) if isinstance(theNumber, (types.FunctionCall, types.Variable)) else theNumber 
     
     if not isinstance(theNumber, (types.Integer, types.Float)):
         raise InvalidArgTypeError("Function float expected argument #1 to be of type integer or float")
         
     return types.Float(float(theNumber.evaluate()))
Example #8
0
 def do(self, theEnv, theString, *args, **kargs):
     """
     handler of the function
     @see: http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.3.html#Heading238
     """
     
     if isinstance(theString, (types.Variable, types.FunctionCall)):
         theString = self.resolve(theEnv, theString)
     if isinstance(theString, types.String):
         theContent = theString.evaluate()[1:-1]
     elif isinstance(theString, types.Symbol):
         theContent = theString.evaluate()
     else:
         raise InvalidArgTypeError("Function lowcase expected argument #1 to be of type string or symbol")
     
     return theString.__class__(theContent.lower())
Example #9
0
    def do(self, theEnv, theName=None, *args, **kargs):
        """
        handler of the function
        @see: http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.4.html#Heading247
        """

        theName = self.resolve(theEnv, theName) if isinstance(
            theName, (types.FunctionCall, types.Variable)) else theName

        if theName is None or (isinstance(theName, types.Symbol)
                               and theName.pyEqual("t")):
            theResource = theEnv.RESOURCES["stdin"]
            needSeek = False
        elif not isinstance(theName, types.Symbol):
            raise InvalidArgTypeError(
                "Function read expected argument #1 to be of type symbol")
        else:
            theResource = theEnv.RESOURCES[theName.evaluate()]
            needSeek = True

        # get a ConstantParser: it will read 1 single Lexeme|Number from a string
        constantParser = theEnv.network.getParser().getSParser(
            'ConstantParser')

        quoteGuard = None

        try:

            theString = theResource.readline()

            # python file.readline() doc:
            #    An empty string is returned only when EOF is encountered immediately
            #    @see http://docs.python.org/release/2.4.4/lib/bltin-file-objects.html
            if theString == "":
                return types.Symbol("EOF")

            quoteGuard = theString[0] == '"'

            if quoteGuard:
                # need to read a <String>
                while True:

                    theToken = constantParser.scanString(theString).next()
                    theResult = theToken[0][0]

                    # check if the Result is a String
                    if isinstance(theResult, types.String):
                        # <String> found, continue
                        break
                    else:
                        # i've not found a string
                        # this means i've not read enoght to find
                        # the end quote for the string and the parser
                        # read a symbol instead
                        theOtherString = theResource.readline()
                        if theOtherString == "":
                            raise InvalidArgValueError(
                                "Encountered End-Of-File while scanning a string: %s"
                                % theString)
                        theString += theOtherString

            else:
                # anything is ok
                # read only the first one
                theToken = constantParser.scanString(theString).next()
                theResult = theToken[0][0]

            if needSeek:
                # need to seek the resource read pointer
                # to the first not read char
                endPosition = theToken[2]
                theResource.seek(endPosition - len(theString) + 1,
                                 1)  # 1 == relative to the position

            return theResult

        except (StopIteration, EOFError):
            return types.Symbol("EOF")
        except IOError:
            return types.Symbol("*** READ ERROR ***")
Example #10
0
    def do(self, theEnv, theExpression, *args, **kargs):
        """
        handler of the Switch function:
            regroup a list of case functions and execute the right one
            for the theCondition value. Execute a default case
            if not case cases match if a default case exists,
            otherwise return None
        @see: http://www.comp.rgu.ac.uk/staff/smc/teaching/clips/vol1/vol1-12.6.html#Heading287
        """
        
        # theExpression have to be evaluated and compared to each case
        # if expression value match the case, it's executed
        # and its return value returned
        # if no expression match and a default is provided, default is executed
        
        # phase 1:
        # filter/check case function in args
        # and isolate the last default function (if any)
        
        theCases = []
        theDefault = None
        if len(args) > 0:
            for index in range(0, len(args)):
                caseFunc = args[index]
                if isinstance(caseFunc, types.FunctionCall) and caseFunc.funcName == "case":
                    theCases.append(caseFunc)
                elif isinstance(caseFunc, types.FunctionCall) and caseFunc.funcName == "default":
                    if index == len(args) - 1:
                        theDefault = caseFunc
                    else:
                        raise InvalidArgValueError("Default clause for a switch function have to be the last one")
                else:
                    raise InvalidArgTypeError("Invalid argument for a switch function: %s"%str(caseFunc))
                
        
        # phase 2:
        # calculate the value for the theExpression
        if isinstance(theExpression, (types.FunctionCall, types.Variable) ):
            theResult = self.resolve(theEnv, theExpression)
        else:
            theResult = theExpression

        returnValue = None
        
        # phase 3:
        # evaluate the "case function" arguments
        for caseFunc in theCases:
            # execute the case Function
            # if it return something not None, it's ok
            # if return is None = it's not the right case
            # (maybe it's better and exception)
            try:
                returnValue = caseFunc.funcDefinition.linkedType.__class__.execute(caseFunc.funcDefinition.linkedType, 
                                                                                   theEnv, theResult, *(caseFunc.funcArgs))
                break # break the for at the first positive case clause executed
            except InvalidCaseException:
                pass

        # phase 4:
        # if returnValue == None, then no case match
        # try to execute the default if any
        # otherwise return None
            
        if returnValue is None and theDefault is not None:
            return theDefault.funcDefinition.linkedType.__class__.execute(theDefault.funcDefinition.linkedType, 
                                                                          theEnv, theResult, *(theDefault.funcArgs))
        else:
            return returnValue if returnValue is not None else types.Symbol("FALSE")