@@ -404,6 +404,7 @@ namespace Ark
404404 &&TARGET_TO_NUM,
405405 &&TARGET_TO_STR,
406406 &&TARGET_AT,
407+ &&TARGET_AT_AT,
407408 &&TARGET_MOD,
408409 &&TARGET_TYPE,
409410 &&TARGET_HASFIELD,
@@ -1169,6 +1170,51 @@ namespace Ark
11691170 DISPATCH ();
11701171 }
11711172
1173+ TARGET (AT_AT)
1174+ {
1175+ {
1176+ Value* x = popAndResolveAsPtr (context);
1177+ Value* y = popAndResolveAsPtr (context);
1178+ Value list = *popAndResolveAsPtr (context); // be careful, it's not a pointer
1179+
1180+ if (y->valueType () != ValueType::Number || x->valueType () != ValueType::Number ||
1181+ list.valueType () != ValueType::List)
1182+ types::generateError (
1183+ " @@" ,
1184+ { { types::Contract {
1185+ { types::Typedef (" src" , ValueType::List),
1186+ types::Typedef (" y" , ValueType::Number),
1187+ types::Typedef (" x" , ValueType::Number) } } } },
1188+ { list, *y, *x });
1189+
1190+ long idx_y = static_cast <long >(y->number ());
1191+ idx_y = idx_y < 0 ? static_cast <long >(list.list ().size ()) + idx_y : idx_y;
1192+ if (std::cmp_greater_equal (idx_y, list.list ().size ()))
1193+ throwVMError (
1194+ ErrorKind::Index,
1195+ fmt::format (" @@ index ({}) out of range (list size: {})" , idx_y, list.list ().size ()));
1196+
1197+ const bool is_list = list.list ()[static_cast <std::size_t >(idx_y)].valueType () == ValueType::List;
1198+ const std::size_t size =
1199+ is_list
1200+ ? list.list ()[static_cast <std::size_t >(idx_y)].list ().size ()
1201+ : list.list ()[static_cast <std::size_t >(idx_y)].stringRef ().size ();
1202+
1203+ long idx_x = static_cast <long >(x->number ());
1204+ idx_x = idx_x < 0 ? static_cast <long >(size) + idx_x : idx_x;
1205+ if (std::cmp_greater_equal (idx_x, size))
1206+ throwVMError (
1207+ ErrorKind::Index,
1208+ fmt::format (" @@ index (x: {}) out of range (inner indexable size: {})" , idx_x, size));
1209+
1210+ if (is_list)
1211+ push (list.list ()[static_cast <std::size_t >(idx_y)].list ()[static_cast <std::size_t >(idx_x)], context);
1212+ else
1213+ push (Value (std::string (1 , list.list ()[static_cast <std::size_t >(idx_y)].stringRef ()[static_cast <std::size_t >(idx_x)])), context);
1214+ }
1215+ DISPATCH ();
1216+ }
1217+
11721218 TARGET (MOD)
11731219 {
11741220 Value *b = popAndResolveAsPtr (context), *a = popAndResolveAsPtr (context);
0 commit comments