Mercurial > vim
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, |