Package org.qdl_lang.evaluate
Class AbstractEvaluator
- java.lang.Object
-
- org.qdl_lang.evaluate.AbstractEvaluator
-
- All Implemented Interfaces:
Serializable
,EvaluatorInterface
- Direct Known Subclasses:
FunctionEvaluator
,IOEvaluator
,ListEvaluator
,MathEvaluator
,MetaEvaluator
,ModuleEvaluator
,OpEvaluator
,StemEvaluator
,StringEvaluator
,SystemEvaluator
,TMathEvaluator
public abstract class AbstractEvaluator extends Object implements EvaluatorInterface
Top level. All evaluators should extend this.Created by Jeff Gaynor
on 1/16/20 at 10:59 AM- See Also:
- Serialized Form
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description class
AbstractEvaluator.CommonKeyIterator
static class
AbstractEvaluator.fPointer
Function pointer class since this ishow youdo that in Java.static class
AbstractEvaluator.fpResult
-
Field Summary
Fields Modifier and Type Field Description protected static int[]
bigArgList
protected static int[]
bigArgList0
static int
FILE_OP_AUTO
static int
FILE_OP_BINARY
static int
FILE_OP_INPUT_STREAM
static int
FILE_OP_TEXT_INI
static int
FILE_OP_TEXT_STEM
static int
FILE_OP_TEXT_STRING
static int
FILE_OP_TEXT_WITHOUT_LIST_INI
protected String[]
fNames
static int
MAX_ARG_COUNT
-
Fields inherited from interface org.qdl_lang.evaluate.EvaluatorInterface
UNKNOWN_VALUE
-
-
Constructor Summary
Constructors Constructor Description AbstractEvaluator()
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description protected boolean
areAllBigDecimals(Object... objects)
protected boolean
areAllBoolean(Object... objects)
protected boolean
areAllLongs(Object... objects)
protected boolean
areAllNumbers(Object... objects)
protected boolean
areAllSets(Object... objects)
protected boolean
areAllStems(Object... objects)
protected boolean
areAllStrings(Object... objects)
protected boolean
areAnyBigDecimals(Object... objects)
protected boolean
areNoneStems(Object... objects)
protected boolean
bdEquals(BigDecimal a, BigDecimal b)
How to compare two big decimals requires some work.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.static void
checkNull(Object arg1, ExpressionInterface swri, State state)
Check for Java nulls and logs any errorsprotected 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:abstract boolean
dispatch(Polyad polyad, State state)
Does the actual evaluation of thePolyad
.boolean
evaluate(String alias, Polyad polyad, State state)
boolean
evaluate(Polyad polyad, State state)
Decides if aPolyad
is evaluated by this evaluator and if not, returns false, if so, it evaluates it and returns true.protected void
finishExpr(ExpressionImpl node, AbstractEvaluator.fpResult r)
protected static int[]
getBigArgList()
Used in arg count queries.protected static int[]
getBigArgList0()
returns integers [0,1,...,MAX_ARG_COUNT
protected AbstractEvaluator.CommonKeyIterator
getCommonKeys(QDLStem... stems)
String[]
getFQFunctionNames()
abstract String[]
getFunctionNames()
protected FunctionReferenceNodeInterface
getFunctionReferenceNode(State state, ExpressionInterface arg0)
FunctionReferenceNodeInterface
getFunctionReferenceNode(State state, ExpressionInterface arg0, boolean pushNewState)
This will take a node that is either a function reference,FunctionDefinitionStatement
or perhaps aLambdaDefinitionNode
and determine the rightFunctionReferenceNode
, updating the state (including adding local state as needed for the duration of the evaluation).static ExpressionImpl
getOperator(State state, FunctionReferenceNodeInterface frNode, int nAry)
get a polyad or dyad (for the operator) from theFunctionReferenceNode
.protected QDLStem
getOrCreateStem(ExpressionInterface node, State state, String informativeMessage)
This will take anExpressionImpl
that should contain a stem, check the reference and it the stem does not exist, create and put it in the symbol table.protected boolean
isBigDecimal(Object obj)
protected boolean
isBoolean(Object obj)
boolean
isBuiltInFunction(String name)
boolean
isFunctionRef(ExpressionInterface arg0)
Checks if the argument is some form of a function reference.protected boolean
isLong(Object obj)
protected boolean
isNumber(Object arg)
boolean
isScalar(Object arg)
protected boolean
isSet(Object obj)
protected boolean
isStem(Object obj)
protected boolean
isStemList(Object obj)
protected boolean
isString(Object obj)
TreeSet<String>
listFunctions(boolean listFQ)
protected void
process1(ExpressionImpl polyad, AbstractEvaluator.fPointer pointer, String name, State state)
Main workhorse for monadic system functions.protected void
process2(ExpressionImpl polyad, AbstractEvaluator.fPointer pointer, String name, State state)
Main workhorse method of evaluating a QDL dyadic system function.protected void
process2(ExpressionImpl polyad, AbstractEvaluator.fPointer pointer, String name, State state, boolean optionalArgs)
Noteprotected void
process3(ExpressionImpl polyad, AbstractEvaluator.fPointer pointer, String name, State state, boolean optionalArguments)
Main workhorse for evaluating QDL system valence 3 functions.protected void
processSet1(QDLSet outSet, QDLSet arg, AbstractEvaluator.fPointer pointer)
protected 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.protected Object
processSet2(QDLSet leftSet, QDLSet rightSet, AbstractEvaluator.fPointer pointer, ExpressionImpl polyad, boolean optionalArgs)
Operations on two sets can return either a set (e.g.protected void
processStem1(QDLStem outStem, QDLStem stemVariable, AbstractEvaluator.fPointer pointer)
Processing stems for monadic functionsprotected void
processStem2(QDLStem outStem, QDLStem stem1, QDLStem stem2, AbstractEvaluator.fPointer pointer, ExpressionImpl polyad, boolean optionalArgs)
protected void
processStem3(QDLStem outStem, QDLStem stem1, QDLStem stem2, QDLStem stem3, AbstractEvaluator.fPointer pointer, ExpressionImpl polyad, boolean optionalArgs)
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.static String
tempFname(State state)
Create an unused name for a function.protected BigDecimal
toBD(Object obj)
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.protected QDLStem
toStem(Object object)
-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface org.qdl_lang.evaluate.EvaluatorInterface
getNamespace, getType
-
-
-
-
Field Detail
-
fNames
protected String[] fNames
-
FILE_OP_AUTO
public static final int FILE_OP_AUTO
- See Also:
- Constant Field Values
-
FILE_OP_BINARY
public static final int FILE_OP_BINARY
- See Also:
- Constant Field Values
-
FILE_OP_TEXT_STEM
public static final int FILE_OP_TEXT_STEM
- See Also:
- Constant Field Values
-
FILE_OP_TEXT_INI
public static final int FILE_OP_TEXT_INI
- See Also:
- Constant Field Values
-
FILE_OP_TEXT_WITHOUT_LIST_INI
public static final int FILE_OP_TEXT_WITHOUT_LIST_INI
- See Also:
- Constant Field Values
-
FILE_OP_TEXT_STRING
public static final int FILE_OP_TEXT_STRING
- See Also:
- Constant Field Values
-
FILE_OP_INPUT_STREAM
public static final int FILE_OP_INPUT_STREAM
- See Also:
- Constant Field Values
-
bigArgList
protected static int[] bigArgList
-
bigArgList0
protected static int[] bigArgList0
-
MAX_ARG_COUNT
public static int MAX_ARG_COUNT
-
-
Method Detail
-
getFunctionNames
public abstract String[] getFunctionNames()
-
getFQFunctionNames
public String[] getFQFunctionNames()
-
listFunctions
public TreeSet<String> listFunctions(boolean listFQ)
- Specified by:
listFunctions
in interfaceEvaluatorInterface
-
isBuiltInFunction
public boolean isBuiltInFunction(String name)
-
evaluate
public boolean evaluate(Polyad polyad, State state)
Decides if aPolyad
is evaluated by this evaluator and if not, returns false, if so, it evaluates it and returns true. This function actually just dispatches it todispatch(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 thePolyad
.- Parameters:
polyad
-state
-- Returns:
-
isStem
protected boolean isStem(Object obj)
-
isSet
protected boolean isSet(Object obj)
-
isStemList
protected boolean isStemList(Object obj)
-
isLong
protected boolean isLong(Object obj)
-
isBoolean
protected boolean isBoolean(Object obj)
-
areAllBoolean
protected boolean areAllBoolean(Object... objects)
-
areAllSets
protected boolean areAllSets(Object... objects)
-
areAllStems
protected boolean areAllStems(Object... objects)
-
areNoneStems
protected boolean areNoneStems(Object... objects)
-
isString
protected boolean isString(Object obj)
-
areAllStrings
protected boolean areAllStrings(Object... objects)
-
areAllLongs
protected boolean areAllLongs(Object... objects)
-
isNumber
protected boolean isNumber(Object arg)
-
isBigDecimal
protected boolean isBigDecimal(Object obj)
-
areAnyBigDecimals
protected boolean areAnyBigDecimals(Object... objects)
-
areAllBigDecimals
protected 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)
-
toBD
protected BigDecimal toBD(Object obj)
-
finishExpr
protected void finishExpr(ExpressionImpl node, AbstractEvaluator.fpResult r)
-
process1
protected void process1(ExpressionImpl polyad, AbstractEvaluator.fPointer pointer, String name, State state)
Main workhorse for monadic system functions. See the note inprocess2(ExpressionImpl, fPointer, String, State, boolean)
!- Parameters:
polyad
-pointer
-name
-state
-
-
processStem1
protected void processStem1(QDLStem outStem, QDLStem stemVariable, AbstractEvaluator.fPointer pointer)
Processing stems for monadic functions- Parameters:
outStem
-stemVariable
-pointer
-
-
processSet1
protected void processSet1(QDLSet outSet, QDLSet arg, AbstractEvaluator.fPointer pointer)
-
process2
protected void process2(ExpressionImpl polyad, AbstractEvaluator.fPointer pointer, String name, State state)
Main workhorse method of evaluating a QDL dyadic system function. See note forprocess2(ExpressionImpl, fPointer, String, State, boolean)
)}- Parameters:
polyad
-pointer
-name
-state
-
-
process2
protected 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 implementsAbstractEvaluator.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 throwBadArgException
s which are extremely exact at the point of failure.
Tip: OptionalArguments means that theAbstractEvaluator.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
protected 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
protected 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
-
-
processStem2
protected void processStem2(QDLStem outStem, QDLStem stem1, QDLStem stem2, AbstractEvaluator.fPointer pointer, ExpressionImpl polyad, boolean optionalArgs)
-
process3
protected void process3(ExpressionImpl polyad, AbstractEvaluator.fPointer pointer, String name, State state, boolean optionalArguments)
Main workhorse for evaluating QDL system valence 3 functions. See the note atprocess2(ExpressionImpl, fPointer, String, State, boolean)
!- Parameters:
polyad
-pointer
-name
-state
-optionalArguments
-
-
processStem3
protected void processStem3(QDLStem outStem, QDLStem stem1, QDLStem stem2, QDLStem stem3, AbstractEvaluator.fPointer pointer, ExpressionImpl polyad, boolean optionalArgs)
-
getCommonKeys
protected AbstractEvaluator.CommonKeyIterator getCommonKeys(QDLStem... stems)
-
getOrCreateStem
protected QDLStem getOrCreateStem(ExpressionInterface node, State state, String informativeMessage)
This will take anExpressionImpl
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:
-
getOperator
public static ExpressionImpl getOperator(State state, FunctionReferenceNodeInterface frNode, int nAry)
get a polyad or dyad (for the operator) from theFunctionReferenceNode
. You must still set any arguments, but the type and name should be correctly set.- Parameters:
state
-frNode
-- 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:
-
isFunctionRef
public boolean isFunctionRef(ExpressionInterface arg0)
Checks if the argument is some form of a function reference. This lets you test for overloading before invoking one ofgetFunctionReferenceNode(State, ExpressionInterface)
- Parameters:
arg0
-- 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 aLambdaDefinitionNode
and determine the rightFunctionReferenceNode
, 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:
-
getFunctionReferenceNode
protected FunctionReferenceNodeInterface getFunctionReferenceNode(State state, ExpressionInterface arg0)
-
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
-
-
getBigArgList
protected static int[] getBigArgList()
Used in arg count queries. Returns [1,2,...MAX_ARG_COUNT
]. Note that this does not limit argument lists, but it used in dereferencing function references. SeeFunctionEvaluator.resolveArguments(FunctionRecordInterface, Polyad, State, State)
.- Returns:
-
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:
-
-