@@ -825,33 +825,71 @@ static Obj EvalElmListLevel(Expr expr)
825825{
826826 Obj lists ; // lists, left operand
827827 Obj pos ; // position, right operand
828- Obj ixs ;
829828 UInt level ; // level
830- Int narg ;
831- Int i ;
829+ Obj ixs ;
832830
833831 // evaluate lists (if this works, then <lists> is nested <level> deep,
834832 // checking it is nested <level>+1 deep is done by 'ElmListLevel')
835833 lists = EVAL_EXPR (READ_EXPR (expr , 0 ));
836- narg = SIZE_EXPR (expr )/sizeof (Expr ) - 2 ;
837- ixs = NEW_PLIST (T_PLIST , narg );
838- for (i = 1 ; i <= narg ; i ++ ) {
839- pos = EVAL_EXPR ( READ_EXPR (expr , i ));
840- SET_ELM_PLIST (ixs , i , pos );
841- CHANGED_BAG (ixs );
842- }
843- SET_LEN_PLIST (ixs , narg );
844- // get the level
845- level = READ_EXPR (expr , narg + 1 );
834+ pos = EVAL_EXPR (READ_EXPR (expr , 1 ));
835+ level = READ_EXPR (expr , 2 );
836+
837+ ixs = NEW_PLIST (T_PLIST , 1 );
838+ SET_ELM_PLIST (ixs , 1 , pos );
839+ CHANGED_BAG (ixs );
840+ SET_LEN_PLIST (ixs , 1 );
846841
847842 // select the elements from several lists (store them in <lists>)
848- ElmListLevel ( lists , ixs , level );
843+ ElmListLevel (lists , ixs , level );
849844
850845 // return the elements
851846 return lists ;
852847}
853848
854849
850+ /****************************************************************************
851+ **
852+ *F EvalElmMatLevel(<expr>) . . . . . . select elements of several matrices
853+ **
854+ ** 'EvalElmMatLevel' evaluates the matrix element expression <expr> of the
855+ ** form '<list>...{<positions>}...[<row>,<col>]', where there may actually
856+ ** be several '{<positions>}' selections between <list> and '[<position>]'.
857+ ** The number of those is called the level. 'EvalElmMatLevel' goes that
858+ ** deep into the left operand and selects the element at <row>,<col> from
859+ ** each of those matrices. For example, if the level is 1, the left operand
860+ ** must be a list of matrices and 'EvalElmMatLevel' selects the element at
861+ ** <row>,<col> from each of the matrices and returns the list of those
862+ ** values.
863+ */
864+ static Obj EvalElmMatLevel (Expr expr )
865+ {
866+ Obj matrices ; // matrices
867+ Obj row ; // row position
868+ Obj col ; // column position
869+ UInt level ; // level
870+ Obj ixs ;
871+
872+ // evaluate matrices (if this works, then <matrices> is nested <level>
873+ // deep, checking it is nested <level>+1 deep is done by 'ElmListLevel')
874+ matrices = EVAL_EXPR (READ_EXPR (expr , 0 ));
875+ row = EVAL_EXPR (READ_EXPR (expr , 1 ));
876+ col = EVAL_EXPR (READ_EXPR (expr , 2 ));
877+ level = READ_EXPR (expr , 3 );
878+
879+ ixs = NEW_PLIST (T_PLIST , 2 );
880+ SET_ELM_PLIST (ixs , 1 , row );
881+ SET_ELM_PLIST (ixs , 2 , col );
882+ CHANGED_BAG (ixs );
883+ SET_LEN_PLIST (ixs , 2 );
884+
885+ // select the elements from several matrices (store them in <matrices>)
886+ ElmListLevel (matrices , ixs , level );
887+
888+ // return the elements
889+ return matrices ;
890+ }
891+
892+
855893/****************************************************************************
856894**
857895*F EvalElmsListLevel(<expr>) . . . select several elements of several lists
@@ -1010,7 +1048,7 @@ static void PrintAsssList(Stat stat)
10101048*F ExprHasNonZeroListLevel(<expr>) . . . . . . . . . . . . . . . . . . . . .
10111049**
10121050** Every 'EXPR_ELMS_LIST' or 'EXPR_ELMS_LIST_LEV' increments the list level.
1013- ** 'EXPR_ELM_LIST_LEV' has a non-zero list level .
1051+ ** 'EXPR_ELM_LIST_LEV' and 'EXPR_ELM_MAT_LEV' have non-zero list levels .
10141052** Every other expression should have level 0.
10151053**
10161054** If a list access happens at level zero ('EXPR_ELM_LIST', 'EXPR_ELM_MAT'
@@ -1021,6 +1059,7 @@ static BOOL ExprHasNonZeroListLevel(Expr list)
10211059{
10221060 return TNUM_EXPR (list ) == EXPR_ELMS_LIST ||
10231061 TNUM_EXPR (list ) == EXPR_ELM_LIST_LEV ||
1062+ TNUM_EXPR (list ) == EXPR_ELM_MAT_LEV ||
10241063 TNUM_EXPR (list ) == EXPR_ELMS_LIST_LEV ;
10251064}
10261065
@@ -1070,16 +1109,21 @@ static void PrintElmMat(Expr expr)
10701109
10711110static void PrintElmListLevel (Expr expr )
10721111{
1073- Int i ;
1074- Int narg = SIZE_EXPR (expr )/sizeof (Expr ) - 2 ;
10751112 Pr ("%2>" , 0 , 0 );
10761113 PrintExpr (READ_EXPR (expr , 0 ));
10771114 Pr ("%<[" , 0 , 0 );
10781115 PrintExpr (READ_EXPR (expr , 1 ));
1079- for (i = 2 ; i <= narg ; i ++ ) {
1080- Pr ("%<, %>" , 0 , 0 );
1081- PrintExpr (READ_EXPR (expr , i ));
1082- }
1116+ Pr ("%<]" , 0 , 0 );
1117+ }
1118+
1119+ static void PrintElmMatLevel (Expr expr )
1120+ {
1121+ Pr ("%2>" , 0 , 0 );
1122+ PrintExpr (READ_EXPR (expr , 0 ));
1123+ Pr ("%<[" , 0 , 0 );
1124+ PrintExpr (READ_EXPR (expr , 1 ));
1125+ Pr ("%<, %>" , 0 , 0 );
1126+ PrintExpr (READ_EXPR (expr , 2 ));
10831127 Pr ("%<]" , 0 , 0 );
10841128}
10851129
@@ -2282,8 +2326,10 @@ static Int InitKernel (
22822326 // install executors, evaluators, and printers for matrix elements
22832327 InstallExecStatFunc (STAT_ASS_MAT , ExecAssMat );
22842328 InstallEvalExprFunc (EXPR_ELM_MAT , EvalElmMat );
2329+ InstallEvalExprFunc (EXPR_ELM_MAT_LEV , EvalElmMatLevel );
22852330 InstallPrintStatFunc (STAT_ASS_MAT , PrintAssMat );
22862331 InstallPrintExprFunc (EXPR_ELM_MAT , PrintElmMat );
2332+ InstallPrintExprFunc (EXPR_ELM_MAT_LEV , PrintElmMatLevel );
22872333
22882334 // install executors, evaluators, and printers for record elements
22892335 InstallExecStatFunc ( STAT_ASS_REC_NAME , ExecAssRecName );
0 commit comments