10
10
import org .qdl_lang .state .State ;
11
11
import org .qdl_lang .statements .ExpressionInterface ;
12
12
import org .qdl_lang .statements .Statement ;
13
+ import org .qdl_lang .util .aggregate .AxisRestrictionIdentity ;
13
14
import org .qdl_lang .variables .*;
14
15
import edu .uiuc .ncsa .security .core .util .StringUtils ;
15
16
import net .sf .json .JSON ;
@@ -127,6 +128,11 @@ public String getNamespace() {
127
128
128
129
public static final String EXCISE = "excise" ;
129
130
public static final int EXCISE_TYPE = 116 + STEM_FUNCTION_BASE_VALUE ;
131
+
132
+ /* public static final String MAP = "map";
133
+ public static final int MAP_TYPE = 117 + STEM_FUNCTION_BASE_VALUE;*/
134
+
135
+
130
136
public static final String IS_LIST = "is_list" ;
131
137
public static final int IS_LIST_TYPE = 204 + STEM_FUNCTION_BASE_VALUE ;
132
138
@@ -162,6 +168,7 @@ public String getNamespace() {
162
168
public String [] getFunctionNames () {
163
169
if (fNames == null ) {
164
170
fNames = new String []{
171
+ // MAP,
165
172
EXCISE ,
166
173
HAS_KEYS ,
167
174
DISPLAY ,
@@ -202,6 +209,8 @@ public String[] getFunctionNames() {
202
209
@ Override
203
210
public int getType (String name ) {
204
211
switch (name ) {
212
+ /* case MAP:
213
+ return MAP_TYPE;*/
205
214
case EXCISE :
206
215
return EXCISE_TYPE ;
207
216
case HAS_KEYS :
@@ -281,6 +290,9 @@ public int getType(String name) {
281
290
@ Override
282
291
public boolean dispatch (Polyad polyad , State state ) {
283
292
switch (polyad .getName ()) {
293
+ /* case MAP:
294
+ doMap(polyad, state);
295
+ return true;*/
284
296
case EXCISE :
285
297
doExcise (polyad , state );
286
298
return true ;
@@ -393,6 +405,7 @@ public boolean dispatch(Polyad polyad, State state) {
393
405
return false ;
394
406
}
395
407
408
+
396
409
/**
397
410
* Removes elements from a stem by value. In general stems this is not as useful as in lists.
398
411
*
@@ -836,10 +849,18 @@ protected void doIndices(Polyad polyad, State state) {
836
849
if (!isStem (arg0 )) {
837
850
throw new BadArgException (ALL_KEYS + " requires a stem as its first argument" , polyad .getArgAt (0 ));
838
851
}
839
- QDLStem stem = ( QDLStem ) arg0 ;
840
- boolean returnAll = true ;
852
+ boolean hasAxisExpression = arg0 instanceof AxisExpression ;
853
+ QDLStem stem ;
841
854
long axis = 0L ;
842
- if (polyad .getArgCount () == 2 ) {
855
+ if (hasAxisExpression ) {
856
+ AxisExpression ae = (AxisExpression ) arg0 ;
857
+ stem = ae .getStem ();
858
+ axis = ae .getAxis ();
859
+ } else {
860
+ stem = (QDLStem ) arg0 ;
861
+ }
862
+ boolean returnAll = true ;
863
+ if (!hasAxisExpression && polyad .getArgCount () == 2 ) {
843
864
returnAll = false ;
844
865
Object arg1 = polyad .evalArg (1 , state );
845
866
checkNull (arg1 , polyad .getArgAt (1 ), state );
@@ -848,7 +869,7 @@ protected void doIndices(Polyad polyad, State state) {
848
869
}
849
870
axis = (Long ) arg1 ;
850
871
}
851
- QDLStem rc = returnAll ? stem .indices () : stem .indices (axis );
872
+ QDLStem rc = returnAll ? stem .indicesByRank () : stem .indicesByRank (axis );
852
873
polyad .setResult (rc );
853
874
polyad .setResultType (STEM_TYPE );
854
875
polyad .setEvaluated (Boolean .TRUE );
@@ -910,7 +931,7 @@ protected void doForEach(Polyad polyad, State state) {
910
931
Object arg = polyad .evalArg (i , state );
911
932
checkNull (arg , polyad .getArgAt (i ));
912
933
stems [i - 1 ] = arg ;
913
- allScalars = allScalars && (!(arg instanceof QDLStem ));
934
+ allScalars = allScalars && (!isStem (arg ));
914
935
}
915
936
ExpressionImpl f ;
916
937
try {
@@ -930,7 +951,7 @@ protected void doForEach(Polyad polyad, State state) {
930
951
QDLStem output = new QDLStem ();
931
952
932
953
// Fixes https://github.com/ncsa/qdl/issues/17
933
- forEachRecursion (output , f , state , stems , new IndexList (), new ArrayList (), 0 );
954
+ forEachRecursion2 (output , f , state , stems , new IndexList (), new ArrayList (), 0 );
934
955
polyad .setResult (output );
935
956
polyad .setResultType (STEM_TYPE );
936
957
polyad .setEvaluated (true );
@@ -960,7 +981,7 @@ protected void forEachRecursion(QDLStem output,
960
981
ArrayList values ,
961
982
int currentIndex ) {
962
983
963
- while (!(args [currentIndex ] instanceof QDLStem )) {
984
+ while (!isStem (args [currentIndex ])) {
964
985
values .add (args [currentIndex ]); // we can add scalars to the end of this, but it will recurse on the next stem
965
986
currentIndex ++;
966
987
if (currentIndex == args .length ) {
@@ -970,7 +991,8 @@ protected void forEachRecursion(QDLStem output,
970
991
}
971
992
}
972
993
QDLStem currentStem = (QDLStem ) args [currentIndex ++];
973
- ArrayList allIndices = currentStem .indices ().getQDLList ().getArrayList ();
994
+ // Next, get *every* index
995
+ ArrayList allIndices = currentStem .indicesByRank ().getQDLList ().getArrayList ();
974
996
for (Object index : allIndices ) {
975
997
IndexList currentIndexList = new IndexList ((QDLStem ) index ); // index looks like [0,0,1]
976
998
IndexList nextIndexList = new IndexList (); // index looks like [0,0,1]
@@ -988,7 +1010,80 @@ protected void forEachRecursion(QDLStem output,
988
1010
}
989
1011
}
990
1012
}
1013
+ protected void forEachRecursion2 (QDLStem output ,
1014
+ ExpressionImpl f ,
1015
+ State state ,
1016
+ Object [] args ,
1017
+ IndexList indexList ,
1018
+ ArrayList values ,
1019
+ int currentIndex ) {
1020
+
1021
+ while (!isStem (args [currentIndex ])) {
1022
+ values .add (args [currentIndex ]); // we can add scalars to the end of this, but it will recurse on the next stem
1023
+ currentIndex ++;
1024
+ if (currentIndex == args .length ) {
1025
+ // end of the line for recursion. Evaluate
1026
+ output .set (indexList , forEachEval (f , state , values ));
1027
+ return ;
1028
+ }
1029
+ }
1030
+ QDLStem currentStem ;
1031
+ Long axis = 0L ;
1032
+ ArrayList allIndices ;
1033
+ boolean isAxisExpression = args [currentIndex ] instanceof AxisExpression ;
1034
+
1035
+ if (isAxisExpression ) {
1036
+ AxisExpression ae = (AxisExpression ) args [currentIndex ];
1037
+ currentStem = ae .getStem ();
1038
+ axis = ae .getAxis ();
1039
+ //allIndices = currentStem.indicesByRank(axis+1).getQDLList().getArrayList();
1040
+ allIndices = currentStem .keysByAxis (axis ).getQDLList ().getArrayList ();
1041
+ } else {
1042
+ currentStem = (QDLStem ) args [currentIndex ];
1043
+ allIndices = currentStem .indicesByRank ().getQDLList ().getArrayList ();
1044
+ }
1045
+ currentIndex ++;
1046
+
1047
+
1048
+ for (Object index : allIndices ) {
1049
+ IndexList currentIndexList = new IndexList ((QDLStem ) index ); // index looks like [0,0,1]
1050
+ IndexList nextIndexList = new IndexList (); // index looks like [0,0,1]
1051
+ nextIndexList .addAll (indexList );
1052
+ nextIndexList .addAll (currentIndexList );
1053
+ ArrayList valuesList1 = new ArrayList ();
1054
+ valuesList1 .addAll (values );
1055
+ // valuesList1.add(currentStem.get(currentIndexList, true).get(0));
1056
+ valuesList1 .add (currentStem .get (index ));
1057
+ if (currentIndex == args .length || (isAxisExpression && args .length == axis )) {
1058
+ // end of the line for recursion. Evaluate
1059
+ output .set (nextIndexList , forEachEval (f , state , valuesList1 ));
1060
+ } else {
1061
+ forEachRecursion2 (output , f , state , args , nextIndexList , valuesList1 , currentIndex );
1062
+ }
1063
+ }
1064
+ }
1065
+ // Processor that replaces each stem at a given level with the constant "foo".
1066
+ public static class ARForEachImpl extends AxisRestrictionIdentity {
1067
+ public ARForEachImpl (ExpressionImpl f , State state , int axis ) {
1068
+ this .f = f ;
1069
+ this .state = state ;
1070
+ this .axis = axis ;
1071
+ }
1072
+ ExpressionImpl f ;
1073
+ State state ;
991
1074
1075
+ @ Override
1076
+ public Object getDefaultValue (List <Object > index ,Object key , Object value ) {
1077
+ ArgList argList1 = new ArgList ();
1078
+ argList1 .add (new ConstantNode (value ));
1079
+ f .setArguments (argList1 );
1080
+ return f .evaluate (state );
1081
+ }
1082
+ }
1083
+ /*
1084
+ f(x.)→x.0+x.1;
1085
+ @f∀[n(3,4,4,[;3*4*4])|0]
1086
+ */
992
1087
993
1088
protected Object forEachEval (ExpressionImpl f , State state , List args ) {
994
1089
if (f instanceof Monad ) {
@@ -2380,15 +2475,15 @@ protected void doRemove(Polyad polyad, State state) {
2380
2475
polyad .setResult (esn2 .remove (state ));
2381
2476
break ;
2382
2477
case ExpressionInterface .FUNCTION_REFERENCE_NODE :
2383
- if (!isFunction ){
2478
+ if (!isFunction ) {
2384
2479
throw new BadArgException (REMOVE + " requires a n argument count" , polyad );
2385
2480
}
2386
2481
FunctionReferenceNode functionReferenceNode = (FunctionReferenceNode ) polyad .getArgAt (0 );
2387
- if (argCount == -1 ){
2388
- for (FunctionRecordInterface fr : functionReferenceNode .getFunctionRecords ()){
2389
- state .getFTStack ().remove (new FKey (functionReferenceNode .getFunctionName (), fr .getArgCount ()));
2390
- }
2391
- }else {
2482
+ if (argCount == -1 ) {
2483
+ for (FunctionRecordInterface fr : functionReferenceNode .getFunctionRecords ()) {
2484
+ state .getFTStack ().remove (new FKey (functionReferenceNode .getFunctionName (), fr .getArgCount ()));
2485
+ }
2486
+ } else {
2392
2487
state .getFTStack ().remove (new FKey (functionReferenceNode .getFunctionName (), argCount .intValue ()));
2393
2488
}
2394
2489
polyad .setResult (Boolean .TRUE );
@@ -3017,7 +3112,7 @@ protected void doTransform(Polyad polyad, State state) {
3017
3112
}
3018
3113
QDLStem stem = (QDLStem ) arg0 ;
3019
3114
3020
- QDLStem oldIndices = stem .indices (-1L );
3115
+ QDLStem oldIndices = stem .indicesByRank (-1L );
3021
3116
// kludge, assume that the rank of all at the last axis is the same.
3022
3117
int rank = ((QDLStem ) oldIndices .get (0L )).size ();
3023
3118
0 commit comments