comparison src/eval.c @ 31483:1bebc2093e6b v9.0.1074

patch 9.0.1074: class members are not supported yet Commit: https://github.com/vim/vim/commit/d505d178858434e1afef0363a9fce4bcb1bc3d06 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Dec 18 21:42:55 2022 +0000 patch 9.0.1074: class members are not supported yet Problem: Class members are not supported yet. Solution: Add initial support for class members.
author Bram Moolenaar <Bram@vim.org>
date Sun, 18 Dec 2022 22:45:04 +0100
parents 5ef28f5ff357
children aa45593ec2ca
comparison
equal deleted inserted replaced
31482:ac877632b863 31483:1bebc2093e6b
1191 */ 1191 */
1192 var1.v_type = VAR_UNKNOWN; 1192 var1.v_type = VAR_UNKNOWN;
1193 var2.v_type = VAR_UNKNOWN; 1193 var2.v_type = VAR_UNKNOWN;
1194 while (*p == '[' || (*p == '.' && p[1] != '=' && p[1] != '.')) 1194 while (*p == '[' || (*p == '.' && p[1] != '=' && p[1] != '.'))
1195 { 1195 {
1196 if (*p == '.' && lp->ll_tv->v_type != VAR_DICT 1196 vartype_T v_type = lp->ll_tv->v_type;
1197 && lp->ll_tv->v_type != VAR_OBJECT 1197
1198 && lp->ll_tv->v_type != VAR_CLASS) 1198 if (*p == '.' && v_type != VAR_DICT
1199 && v_type != VAR_OBJECT
1200 && v_type != VAR_CLASS)
1199 { 1201 {
1200 if (!quiet) 1202 if (!quiet)
1201 semsg(_(e_dot_can_only_be_used_on_dictionary_str), name); 1203 semsg(_(e_dot_can_only_be_used_on_dictionary_str), name);
1202 return NULL; 1204 return NULL;
1203 } 1205 }
1204 if (lp->ll_tv->v_type != VAR_LIST 1206 if (v_type != VAR_LIST
1205 && lp->ll_tv->v_type != VAR_DICT 1207 && v_type != VAR_DICT
1206 && lp->ll_tv->v_type != VAR_BLOB 1208 && v_type != VAR_BLOB
1207 && lp->ll_tv->v_type != VAR_OBJECT 1209 && v_type != VAR_OBJECT
1208 && lp->ll_tv->v_type != VAR_CLASS) 1210 && v_type != VAR_CLASS)
1209 { 1211 {
1210 if (!quiet) 1212 if (!quiet)
1211 emsg(_(e_can_only_index_list_dictionary_or_blob)); 1213 emsg(_(e_can_only_index_list_dictionary_or_blob));
1212 return NULL; 1214 return NULL;
1213 } 1215 }
1214 1216
1215 // A NULL list/blob works like an empty list/blob, allocate one now. 1217 // A NULL list/blob works like an empty list/blob, allocate one now.
1216 int r = OK; 1218 int r = OK;
1217 if (lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list == NULL) 1219 if (v_type == VAR_LIST && lp->ll_tv->vval.v_list == NULL)
1218 r = rettv_list_alloc(lp->ll_tv); 1220 r = rettv_list_alloc(lp->ll_tv);
1219 else if (lp->ll_tv->v_type == VAR_BLOB 1221 else if (v_type == VAR_BLOB
1220 && lp->ll_tv->vval.v_blob == NULL) 1222 && lp->ll_tv->vval.v_blob == NULL)
1221 r = rettv_blob_alloc(lp->ll_tv); 1223 r = rettv_blob_alloc(lp->ll_tv);
1222 if (r == FAIL) 1224 if (r == FAIL)
1223 return NULL; 1225 return NULL;
1224 1226
1276 } 1278 }
1277 1279
1278 // Optionally get the second index [ :expr]. 1280 // Optionally get the second index [ :expr].
1279 if (*p == ':') 1281 if (*p == ':')
1280 { 1282 {
1281 if (lp->ll_tv->v_type == VAR_DICT) 1283 if (v_type == VAR_DICT)
1282 { 1284 {
1283 if (!quiet) 1285 if (!quiet)
1284 emsg(_(e_cannot_slice_dictionary)); 1286 emsg(_(e_cannot_slice_dictionary));
1285 clear_tv(&var1); 1287 clear_tv(&var1);
1286 return NULL; 1288 return NULL;
1332 1334
1333 // Skip to past ']'. 1335 // Skip to past ']'.
1334 ++p; 1336 ++p;
1335 } 1337 }
1336 1338
1337 if (lp->ll_tv->v_type == VAR_DICT) 1339 if (v_type == VAR_DICT)
1338 { 1340 {
1339 if (len == -1) 1341 if (len == -1)
1340 { 1342 {
1341 // "[key]": get key from "var1" 1343 // "[key]": get key from "var1"
1342 key = tv_get_string_chk(&var1); // is number or string 1344 key = tv_get_string_chk(&var1); // is number or string
1433 } 1435 }
1434 1436
1435 clear_tv(&var1); 1437 clear_tv(&var1);
1436 lp->ll_tv = &lp->ll_di->di_tv; 1438 lp->ll_tv = &lp->ll_di->di_tv;
1437 } 1439 }
1438 else if (lp->ll_tv->v_type == VAR_BLOB) 1440 else if (v_type == VAR_BLOB)
1439 { 1441 {
1440 long bloblen = blob_len(lp->ll_tv->vval.v_blob); 1442 long bloblen = blob_len(lp->ll_tv->vval.v_blob);
1441 1443
1442 /* 1444 /*
1443 * Get the number and item for the only or first index of the List. 1445 * Get the number and item for the only or first index of the List.
1464 } 1466 }
1465 lp->ll_blob = lp->ll_tv->vval.v_blob; 1467 lp->ll_blob = lp->ll_tv->vval.v_blob;
1466 lp->ll_tv = NULL; 1468 lp->ll_tv = NULL;
1467 break; 1469 break;
1468 } 1470 }
1469 else if (lp->ll_tv->v_type == VAR_LIST) 1471 else if (v_type == VAR_LIST)
1470 { 1472 {
1471 /* 1473 /*
1472 * Get the number and item for the only or first index of the List. 1474 * Get the number and item for the only or first index of the List.
1473 */ 1475 */
1474 if (empty1) 1476 if (empty1)
1511 1513
1512 lp->ll_tv = &lp->ll_li->li_tv; 1514 lp->ll_tv = &lp->ll_li->li_tv;
1513 } 1515 }
1514 else // v_type == VAR_CLASS || v_type == VAR_OBJECT 1516 else // v_type == VAR_CLASS || v_type == VAR_OBJECT
1515 { 1517 {
1516 class_T *cl = (lp->ll_tv->v_type == VAR_OBJECT 1518 class_T *cl = (v_type == VAR_OBJECT
1517 && lp->ll_tv->vval.v_object != NULL) 1519 && lp->ll_tv->vval.v_object != NULL)
1518 ? lp->ll_tv->vval.v_object->obj_class 1520 ? lp->ll_tv->vval.v_object->obj_class
1519 : lp->ll_tv->vval.v_class; 1521 : lp->ll_tv->vval.v_class;
1520 // TODO: what if class is NULL? 1522 // TODO: what if class is NULL?
1521 if (cl != NULL) 1523 if (cl != NULL)
1522 { 1524 {
1523 lp->ll_valtype = NULL; 1525 lp->ll_valtype = NULL;
1524 for (int i = 0; i < cl->class_obj_member_count; ++i) 1526 int count = v_type == VAR_OBJECT ? cl->class_obj_member_count
1525 { 1527 : cl->class_class_member_count;
1526 objmember_T *om = cl->class_obj_members + i; 1528 ocmember_T *members = v_type == VAR_OBJECT
1527 if (STRNCMP(om->om_name, key, p - key) == 0 1529 ? cl->class_obj_members
1528 && om->om_name[p - key] == NUL) 1530 : cl->class_class_members;
1531 for (int i = 0; i < count; ++i)
1532 {
1533 ocmember_T *om = members + i;
1534 if (STRNCMP(om->ocm_name, key, p - key) == 0
1535 && om->ocm_name[p - key] == NUL)
1529 { 1536 {
1530 switch (om->om_access) 1537 switch (om->ocm_access)
1531 { 1538 {
1532 case ACCESS_PRIVATE: 1539 case ACCESS_PRIVATE:
1533 semsg(_(e_cannot_access_private_object_member_str), 1540 semsg(_(e_cannot_access_private_member_str),
1534 om->om_name); 1541 om->ocm_name);
1535 return NULL; 1542 return NULL;
1536 case ACCESS_READ: 1543 case ACCESS_READ:
1537 if (!(flags & GLV_READ_ONLY)) 1544 if (!(flags & GLV_READ_ONLY))
1538 { 1545 {
1539 semsg(_(e_object_member_is_not_writable_str), 1546 semsg(_(e_member_is_not_writable_str),
1540 om->om_name); 1547 om->ocm_name);
1541 return NULL; 1548 return NULL;
1542 } 1549 }
1543 break; 1550 break;
1544 case ACCESS_ALL: 1551 case ACCESS_ALL:
1545 break; 1552 break;
1546 } 1553 }
1547 1554
1548 lp->ll_valtype = om->om_type; 1555 lp->ll_valtype = om->ocm_type;
1549 1556
1550 if (lp->ll_tv->v_type == VAR_OBJECT) 1557 if (v_type == VAR_OBJECT)
1551 lp->ll_tv = ((typval_T *)( 1558 lp->ll_tv = ((typval_T *)(
1552 lp->ll_tv->vval.v_object + 1)) + i; 1559 lp->ll_tv->vval.v_object + 1)) + i;
1553 // TODO: what about a class? 1560 else
1561 lp->ll_tv = &cl->class_members_tv[i];
1554 break; 1562 break;
1555 } 1563 }
1556 } 1564 }
1557 if (lp->ll_valtype == NULL) 1565 if (lp->ll_valtype == NULL)
1558 { 1566 {
1559 semsg(_(e_object_member_not_found_str), key); 1567 if (v_type == VAR_OBJECT)
1568 semsg(_(e_object_member_not_found_str), key);
1569 else
1570 semsg(_(e_class_member_not_found_str), key);
1560 return NULL; 1571 return NULL;
1561 } 1572 }
1562 } 1573 }
1563 } 1574 }
1564 } 1575 }
5934 ga_concat(&ga, (char_u *)" {"); 5945 ga_concat(&ga, (char_u *)" {");
5935 for (int i = 0; i < cl->class_obj_member_count; ++i) 5946 for (int i = 0; i < cl->class_obj_member_count; ++i)
5936 { 5947 {
5937 if (i > 0) 5948 if (i > 0)
5938 ga_concat(&ga, (char_u *)", "); 5949 ga_concat(&ga, (char_u *)", ");
5939 objmember_T *m = &cl->class_obj_members[i]; 5950 ocmember_T *m = &cl->class_obj_members[i];
5940 ga_concat(&ga, m->om_name); 5951 ga_concat(&ga, m->ocm_name);
5941 ga_concat(&ga, (char_u *)": "); 5952 ga_concat(&ga, (char_u *)": ");
5942 char_u *tf = NULL; 5953 char_u *tf = NULL;
5943 ga_concat(&ga, echo_string_core( 5954 ga_concat(&ga, echo_string_core(
5944 (typval_T *)(obj + 1) + i, 5955 (typval_T *)(obj + 1) + i,
5945 &tf, numbuf, copyID, echo_style, 5956 &tf, numbuf, copyID, echo_style,