Class AbstractEvaluator

    • Field Detail

      • fNames

        protected String[] fNames
      • FILE_OP_TEXT_WITHOUT_LIST_INI

        public static final int FILE_OP_TEXT_WITHOUT_LIST_INI
        See Also:
        Constant Field Values
      • bigArgList

        protected static int[] bigArgList
      • bigArgList0

        protected static int[] bigArgList0
      • MAX_ARG_COUNT

        public static int MAX_ARG_COUNT
    • Constructor Detail

      • AbstractEvaluator

        public AbstractEvaluator()
    • Method Detail

      • getFunctionNames

        public abstract String[] getFunctionNames()
      • getFQFunctionNames

        public String[] getFQFunctionNames()
      • isBuiltInFunction

        public boolean isBuiltInFunction​(String name)
      • evaluate

        public boolean evaluate​(Polyad polyad,
                                State state)
        Decides if a Polyad is evaluated by this evaluator and if not, returns false, if so, it evaluates it and returns true. This function actually just dispatches it to dispatch(Polyad, State) where the work is done and manages putting better trace information in if there is a failure.
        Parameters:
        polyad -
        state -
        Returns:
      • dispatch

        public abstract boolean dispatch​(Polyad polyad,
                                         State state)
        Does the actual evaluation of the Polyad.
        Parameters:
        polyad -
        state -
        Returns:
      • isStem

        public static boolean isStem​(Object obj)
      • isSet

        public static boolean isSet​(Object obj)
      • isStemList

        public static boolean isStemList​(Object obj)
      • isLong

        public static boolean isLong​(Object obj)
      • isBoolean

        public static boolean isBoolean​(Object obj)
      • areAllBoolean

        public static boolean areAllBoolean​(Object... objects)
      • areAllSets

        public static boolean areAllSets​(Object... objects)
      • areAllStems

        public static boolean areAllStems​(Object... objects)
      • areNoneStems

        public static boolean areNoneStems​(Object... objects)
      • isString

        public static boolean isString​(Object obj)
      • areAllStrings

        public static boolean areAllStrings​(Object... objects)
      • areAllLongs

        public static boolean areAllLongs​(Object... objects)
      • isNumber

        public static boolean isNumber​(Object arg)
      • isBigDecimal

        public static boolean isBigDecimal​(Object obj)
      • areAnyBigDecimals

        public static boolean areAnyBigDecimals​(Object... objects)
      • areAllBigDecimals

        public static boolean areAllBigDecimals​(Object... objects)
      • bdEquals

        protected boolean bdEquals​(BigDecimal a,
                                   BigDecimal b)
        How to compare two big decimals requires some work.
        Parameters:
        a -
        b -
        Returns:
      • areAllNumbers

        protected boolean areAllNumbers​(Object... objects)
      • processStem1

        public static void processStem1​(QDLStem outStem,
                                        QDLStem stemVariable,
                                        AbstractEvaluator.fPointer pointer)
        Processing stems for monadic functions
        Parameters:
        outStem -
        stemVariable -
        pointer -
      • process2

        public static void process2​(ExpressionImpl polyad,
                                    AbstractEvaluator.fPointer pointer,
                                    String name,
                                    State state,
                                    boolean optionalArgs)

        Note

        This (and the other processN functions) do all the magic of figuring out sets, stems, subsetting etc. You simply write a function that implements AbstractEvaluator.fPointer that operates on a single pair of numbers.

        Tip: You should check for arguments types in the fPointer, not before. Argument checks before invoking this are often a lot more work to unpack. Just let the method do the work. Besides, you can throw BadArgExceptions which are extremely exact at the point of failure.

        Tip: OptionalArguments means that the AbstractEvaluator.fPointer an take more than 2 arguments. So the basic functionality requires 2 args and there may be more.

        Caveat

        This applies subsetting! So any functions that require something more exotic cannot use this.

        Parameters:
        polyad -
        pointer -
        name -
        state -
        optionalArgs -
      • processSet2

        public static Object processSet2​(QDLSet leftSet,
                                         QDLSet rightSet,
                                         AbstractEvaluator.fPointer pointer,
                                         ExpressionImpl polyad,
                                         boolean optionalArgs)
        Operations on two sets can return either a set (e.g. intersection) or a scalar (e.g. subset of)
        Parameters:
        leftSet -
        rightSet -
        pointer -
        polyad -
        optionalArgs -
        Returns:
      • processSet2

        public static void processSet2​(QDLSet outSet,
                                       QDLSet inSet,
                                       Object scalar,
                                       boolean scalarRHS,
                                       AbstractEvaluator.fPointer pointer,
                                       ExpressionImpl polyad,
                                       boolean optionalArgs)
        Apply a scalar to every element in a set.
        Parameters:
        outSet -
        inSet -
        scalar -
        pointer -
        polyad -
        optionalArgs -
      • getOrCreateStem

        protected QDLStem getOrCreateStem​(ExpressionInterface node,
                                          State state,
                                          String informativeMessage)
        This will take an ExpressionImpl that should contain a stem, check the reference and it the stem does not exist, create and put it in the symbol table. If the stem exists, it just returns it. This lets you do things like issue:
             foo. := null
             if[
                some_condition
             ]then[
                list_append(foo., 4);
             // ... other stuff
             ];
         
        and not get a null pointer exception. This is needed especially if a the command is issued in a different scope, e.g. in a conditional block to assign the value.

        This WILL throw an exception if the argument is not a stem!! So this is invoked where there is a required stem that is missing and should be there.
        Parameters:
        node -
        state -
        informativeMessage -
        Returns:
      • resolveResourceToFile

        public VFSEntry resolveResourceToFile​(String resourceName,
                                              int type,
                                              State state)
        This will look at the resource name and decide if it is in a VFS and resolve it against that. If not, it will try to resolve it as a file name against the file system if this is not in server mode. This merely returns a null if there is no such resource. It will throw an exception if the resource refers to a virtual file and there are no providers for that namespace.
        Parameters:
        resourceName -
        state -
        Returns:
      • tempFname

        public static String tempFname​(State state)
        Create an unused name for a function. Note that this cannot produce a legal function name since the base 32 encoding slaps on trailing "=". This assures there will never be a collision with the ambient state.
        Parameters:
        state -
        Returns:
      • getFunctionReferenceNode

        public FunctionReferenceNodeInterface getFunctionReferenceNode​(State state,
                                                                       ExpressionInterface arg0,
                                                                       boolean pushNewState)
        This will take a node that is either a function reference, FunctionDefinitionStatement or perhaps a LambdaDefinitionNode and determine the right FunctionReferenceNode, updating the state (including adding local state as needed for the duration of the evaluation). It will also throw an exception if the argument is not of the right type.

        Any place you want to use a function as an argument, pass it to this and let it do the work.

        Parameters:
        state -
        arg0 -
        Returns:
      • isScalar

        public boolean isScalar​(Object arg)
      • toConstants

        protected ArrayList<ExpressionInterface> toConstants​(ArrayList<Object> objects)
        Takes a list of Java objects and converts them to QDL constants to be used as arguments to functions. Checks also that there are no illegal values first.
        Parameters:
        objects -
        Returns:
      • checkNull

        public static void checkNull​(Object arg,
                                     ExpressionInterface swri)
        If a function gets an argument which should not be a Java null, then this will try to track down the variable reference.
        Parameters:
        arg -
        swri -
      • checkNull

        public static void checkNull​(Object arg1,
                                     ExpressionInterface swri,
                                     State state)
        Check for Java nulls and logs any errors
        Parameters:
        arg1 -
        swri -
        state -
      • getBigArgList0

        protected static int[] getBigArgList0()
        returns integers [0,1,..., MAX_ARG_COUNT
        Returns:
      • convertArgsToStem

        protected QDLStem convertArgsToStem​(Polyad polyad,
                                            Object arg,
                                            State state,
                                            String component)
        Converts a couple of different arguments to the form [[a0{,b0}],[a1{,b1}],...,[an{,bn}] or (if a single argument that is a stem) can pass back:

        {key0:[[a0{,b0}], key1:[a1{,b1}],...}

        where the bk are optional. All ak, bk are strings. a,b -> [[a,b]] (pair of arguments, function is dyadic [a,b] ->[[a,b]] (simple list, convert to nested list [a0,a1,...] -> [[a0],[a1],...] allow for scalars Use in both module import and load for consistent arguments

        Parameters:
        polyad -
        state -
        component -
        Returns: