@@ -1603,7 +1603,7 @@ Value eval_expr(Interpreter* interp, Expr* expr, Env* env) {
16031603 if (vexpr -> type == EXPR_IDENT && vexpr -> as .ident && strcmp (vexpr -> as .ident , "SELF" ) == 0 ) {
16041604 value_map_set_self (& mv , k );
16051605 value_free (k );
1606- } else if (vexpr -> type == EXPR_INDEX && vexpr -> as .index .target && vexpr -> as .index .target -> type == EXPR_IDENT
1606+ } else if (vexpr -> type == EXPR_INDEX && vexpr -> as .index .is_map && vexpr -> as . index . target && vexpr -> as .index .target -> type == EXPR_IDENT
16071607 && vexpr -> as .index .target -> as .ident && strcmp (vexpr -> as .index .target -> as .ident , "SELF" ) == 0 ) {
16081608 // Evaluate index key(s) and perform lookup on the partially-constructed map `mv`.
16091609 ExprList * idxs = & vexpr -> as .index .indices ;
@@ -1660,8 +1660,27 @@ Value eval_expr(Interpreter* interp, Expr* expr, Env* env) {
16601660 interp -> error_col = expr -> column ;
16611661 return value_null ();
16621662 }
1663+ bool is_map_index = expr -> as .index .is_map ;
16631664
1664- if (tval .type == VAL_MAP ) {
1665+ if (is_map_index ) {
1666+ if (tval .type != VAL_MAP ) {
1667+ value_free (tval );
1668+ interp -> error = strdup ("Angle-bracket indexing '<...>' is only allowed on MAP values" );
1669+ interp -> error_line = expr -> line ;
1670+ interp -> error_col = expr -> column ;
1671+ return value_null ();
1672+ }
1673+ } else {
1674+ if (tval .type != VAL_TNS ) {
1675+ value_free (tval );
1676+ interp -> error = strdup ("Square-bracket indexing '[...]' is only allowed on TNS values" );
1677+ interp -> error_line = expr -> line ;
1678+ interp -> error_col = expr -> column ;
1679+ return value_null ();
1680+ }
1681+ }
1682+
1683+ if (is_map_index && tval .type == VAL_MAP ) {
16651684 // map indexing: support nested lookups m<k1,k2>
16661685 Value cur = tval ;
16671686 for (size_t i = 0 ; i < nidx ; i ++ ) {
@@ -1947,9 +1966,27 @@ ExecResult assign_index_chain(Interpreter* interp, Env* env, Expr* idx_expr, Val
19471966 goto cleanup ;
19481967 }
19491968
1950- // Auto-promote NULL to MAP when assigning through indexes .
1969+ // Auto-promote NULL to MAP only when angle-bracket (map) indexing is used .
19511970 if (cur -> type == VAL_NULL ) {
1952- * cur = value_map_new ();
1971+ if (node -> as .index .is_map ) {
1972+ * cur = value_map_new ();
1973+ } else {
1974+ out = make_error ("Attempted tensor indexing on uninitialized value" , node -> line , node -> column );
1975+ goto cleanup ;
1976+ }
1977+ }
1978+
1979+ /* Enforce bracket kind matches the container type: angle-brackets -> MAP, square-brackets -> TNS */
1980+ if (node -> as .index .is_map ) {
1981+ if (cur -> type != VAL_MAP ) {
1982+ out = make_error ("Angle-bracket indexing '<...>' used on non-map value" , node -> line , node -> column );
1983+ goto cleanup ;
1984+ }
1985+ } else {
1986+ if (cur -> type != VAL_TNS ) {
1987+ out = make_error ("Square-bracket indexing '[...]' used on non-tensor value" , node -> line , node -> column );
1988+ goto cleanup ;
1989+ }
19531990 }
19541991
19551992 if (cur -> type == VAL_TNS ) {
0 commit comments