@@ -1229,6 +1229,21 @@ public Object visit(PropertyAccessNode node) {
12291229 }
12301230 }
12311231
1232+ if (node .right instanceof MethodCallNode ) {
1233+ MethodCallNode literalMethod = (MethodCallNode ) node .right ;
1234+ String methodName = literalMethod .name ;
1235+ if (literalRegistry .hasMethod (leftObj , methodName )) {
1236+ List <Object > evaluatedArgs = new ArrayList <Object >();
1237+ if (literalMethod .arguments != null ) {
1238+ for (ExprNode arg : literalMethod .arguments ) {
1239+ Object argValue = dispatch (arg );
1240+ evaluatedArgs .add (typeSystem .unwrap (argValue ));
1241+ }
1242+ }
1243+ return literalRegistry .handleMethod (leftObj , methodName , evaluatedArgs , ctx );
1244+ }
1245+ }
1246+
12321247 if (leftObj instanceof NaturalArray ) {
12331248 NaturalArray natural = (NaturalArray ) leftObj ;
12341249 if (natural .hasPendingUpdates ()) {
@@ -1395,23 +1410,42 @@ public Object visit(TypeCastNode node) {
13951410
13961411 @ SuppressWarnings ("unchecked" )
13971412 @ Override
1398- public Object visit (MethodCallNode node ) {
1413+ public Object visit (MethodCallNode node ) {
13991414 if (node == null ) {
14001415 throw new InternalError ("visit(MethodCallNode) called with null node" );
14011416 }
14021417
1403- try {
1404- // Handle super calls first
1405- if (node .isSuperCall ) {
1406- return handleSuperMethodCall (node );
1407- }
1408-
1409- // Evaluate all arguments first
1410- List <Object > evaluatedArgs = new ArrayList <Object >();
1411- for (ExprNode arg : node .arguments ) {
1412- Object argValue = dispatch (arg );
1413- evaluatedArgs .add (typeSystem .unwrap (argValue ));
1414- }
1418+ try {
1419+ // Handle super calls first
1420+ if (node .isSuperCall ) {
1421+ return handleSuperMethodCall (node );
1422+ }
1423+
1424+ ExecutionContext ctx = getCurrentContext ();
1425+ if (ctx != null && node .qualifiedName != null && node .qualifiedName .contains ("." )) {
1426+ String [] parts = node .qualifiedName .split ("\\ ." );
1427+ if (parts .length == 2 ) {
1428+ String receiverName = parts [0 ];
1429+ String methodName = parts [1 ];
1430+ Object receiverValue = ctx .getVariable (receiverName );
1431+ receiverValue = typeSystem .unwrap (receiverValue );
1432+ if (literalRegistry .hasMethod (receiverValue , methodName )) {
1433+ List <Object > evaluatedArgs = new ArrayList <Object >();
1434+ for (ExprNode arg : node .arguments ) {
1435+ Object argValue = dispatch (arg );
1436+ evaluatedArgs .add (typeSystem .unwrap (argValue ));
1437+ }
1438+ return literalRegistry .handleMethod (receiverValue , methodName , evaluatedArgs , ctx );
1439+ }
1440+ }
1441+ }
1442+
1443+ // Evaluate all arguments first
1444+ List <Object > evaluatedArgs = new ArrayList <Object >();
1445+ for (ExprNode arg : node .arguments ) {
1446+ Object argValue = dispatch (arg );
1447+ evaluatedArgs .add (typeSystem .unwrap (argValue ));
1448+ }
14151449
14161450 // ========== CHECK GLOBAL FUNCTIONS FIRST ==========
14171451 // This must come BEFORE any other resolution to ensure out(), in(), etc.
@@ -1425,9 +1459,7 @@ public Object visit(MethodCallNode node) {
14251459 // ========== END GLOBAL CHECK ==========
14261460
14271461 // Try to find method in current class hierarchy
1428- ExecutionContext ctx = getCurrentContext ();
14291462 MethodNode method = null ;
1430-
14311463 if (ctx .currentClass != null ) {
14321464 method = interpreter
14331465 .getConstructorResolver ()
@@ -1693,6 +1725,10 @@ public Object visit(ArrayNode node) {
16931725 return new NaturalArray (range , this , getCurrentContext ());
16941726 }
16951727 }
1728+
1729+ if (node .elements .size () > 1 && allElementsAreRanges (node .elements )) {
1730+ return buildDimensionArray (node .elements , 0 );
1731+ }
16961732
16971733 // Regular array literal handling
16981734 List <Object > result = new ArrayList <Object >();
@@ -1728,6 +1764,35 @@ public Object visit(ArrayNode node) {
17281764 throw new InternalError ("Array creation failed" , e );
17291765 }
17301766 }
1767+
1768+ private boolean allElementsAreRanges (List <ExprNode > elements ) {
1769+ if (elements == null || elements .isEmpty ()) return false ;
1770+ for (ExprNode element : elements ) {
1771+ if (!(element instanceof RangeNode )) {
1772+ return false ;
1773+ }
1774+ }
1775+ return true ;
1776+ }
1777+
1778+ private Object buildDimensionArray (List <ExprNode > ranges , int dimension ) {
1779+ RangeNode currentRange = (RangeNode ) ranges .get (dimension );
1780+ NaturalArray currentNatural = new NaturalArray (currentRange , this , getCurrentContext ());
1781+ if (dimension == ranges .size () - 1 ) {
1782+ return currentNatural ;
1783+ }
1784+
1785+ long length = currentNatural .size ();
1786+ if (length > Integer .MAX_VALUE ) {
1787+ throw new ProgramError ("Dimension size too large for nested ND array literal: " + length + " (max " + Integer .MAX_VALUE + ")" );
1788+ }
1789+
1790+ List <Object > result = new ArrayList <Object >((int ) length );
1791+ for (int i = 0 ; i < (int ) length ; i ++) {
1792+ result .add (buildDimensionArray (ranges , dimension + 1 ));
1793+ }
1794+ return result ;
1795+ }
17311796
17321797 @ SuppressWarnings ("unchecked" )
17331798 @ Override
@@ -1750,6 +1815,10 @@ public Object visit(IndexAccessNode node) {
17501815
17511816 Object indexObj = dispatch (node .index );
17521817 indexObj = typeSystem .unwrap (indexObj );
1818+
1819+ if (indexObj instanceof List ) {
1820+ return applyTupleIndices (arrayObj , (List <?>) indexObj );
1821+ }
17531822
17541823 if (indexObj instanceof RangeSpec ) {
17551824 return applyRangeIndex (arrayObj , (RangeSpec ) indexObj );
@@ -1984,6 +2053,40 @@ private Object applyMultiRangeIndex(Object array, MultiRangeSpec multiRange) {
19842053 (array != null ? array .getClass ().getSimpleName () : "null" ));
19852054 }
19862055
2056+ @ SuppressWarnings ("unchecked" )
2057+ private Object applyTupleIndices (Object array , List <?> indices ) {
2058+ Object current = array ;
2059+ for (Object rawIndex : indices ) {
2060+ Object indexObj = typeSystem .unwrap (rawIndex );
2061+ if (indexObj instanceof RangeSpec ) {
2062+ current = applyRangeIndex (current , (RangeSpec ) indexObj );
2063+ continue ;
2064+ }
2065+ if (indexObj instanceof MultiRangeSpec ) {
2066+ current = applyMultiRangeIndex (current , (MultiRangeSpec ) indexObj );
2067+ continue ;
2068+ }
2069+ if (current instanceof NaturalArray ) {
2070+ NaturalArray natural = (NaturalArray ) current ;
2071+ long idx = expressionHandler .toLongIndex (indexObj );
2072+ current = natural .needsConversion () ? natural .get (idx , true ) : natural .get (idx );
2073+ continue ;
2074+ }
2075+ if (current instanceof List ) {
2076+ List <Object > list = (List <Object >) current ;
2077+ int idx = expressionHandler .toIntIndex (indexObj );
2078+ if (idx < 0 || idx >= list .size ()) {
2079+ throw new ProgramError ("Index out of bounds: " + idx + " for array of size " + list .size ());
2080+ }
2081+ current = list .get (idx );
2082+ continue ;
2083+ }
2084+ throw new ProgramError ("Invalid array access during multidimensional indexing: expected NaturalArray or List, got "
2085+ + (current != null ? current .getClass ().getSimpleName () : "null" ));
2086+ }
2087+ return current ;
2088+ }
2089+
19872090 private List <Object > getListRange (List <Object > list , RangeSpec range ) {
19882091 try {
19892092 long start , end ;
0 commit comments