Mercurial > vim
comparison src/vim9compile.c @ 31396:307f68a41b03 v9.0.1031
patch 9.0.1031: Vim9 class is not implemented yet
Commit: https://github.com/vim/vim/commit/00b28d6c23d8e662cab27e461825777c0a2e387a
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Dec 8 15:32:33 2022 +0000
patch 9.0.1031: Vim9 class is not implemented yet
Problem: Vim9 class is not implemented yet.
Solution: Add very basic class support.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 08 Dec 2022 16:45:03 +0100 |
parents | 4bde058d0be7 |
children | f088f1d97eee |
comparison
equal
deleted
inserted
replaced
31395:88027ff41075 | 31396:307f68a41b03 |
---|---|
40 int idx; | 40 int idx; |
41 lvar_T *lvp; | 41 lvar_T *lvp; |
42 | 42 |
43 if (len == 0) | 43 if (len == 0) |
44 return FAIL; | 44 return FAIL; |
45 | |
46 if (len == 4 && STRNCMP(name, "this", 4) == 0 | |
47 && cctx->ctx_ufunc != NULL | |
48 && (cctx->ctx_ufunc->uf_flags & FC_OBJECT)) | |
49 { | |
50 if (lvar != NULL) | |
51 { | |
52 CLEAR_POINTER(lvar); | |
53 lvar->lv_name = (char_u *)"this"; | |
54 if (cctx->ctx_ufunc->uf_class != NULL) | |
55 lvar->lv_type = &cctx->ctx_ufunc->uf_class->class_type; | |
56 } | |
57 return OK; | |
58 } | |
45 | 59 |
46 // Find local in current function scope. | 60 // Find local in current function scope. |
47 for (idx = 0; idx < cctx->ctx_locals.ga_len; ++idx) | 61 for (idx = 0; idx < cctx->ctx_locals.ga_len; ++idx) |
48 { | 62 { |
49 lvp = ((lvar_T *)cctx->ctx_locals.ga_data) + idx; | 63 lvp = ((lvar_T *)cctx->ctx_locals.ga_data) + idx; |
294 static int | 308 static int |
295 variable_exists(char_u *name, size_t len, cctx_T *cctx) | 309 variable_exists(char_u *name, size_t len, cctx_T *cctx) |
296 { | 310 { |
297 return (cctx != NULL | 311 return (cctx != NULL |
298 && (lookup_local(name, len, NULL, cctx) == OK | 312 && (lookup_local(name, len, NULL, cctx) == OK |
299 || arg_exists(name, len, NULL, NULL, NULL, cctx) == OK)) | 313 || arg_exists(name, len, NULL, NULL, NULL, cctx) == OK |
314 || (len == 4 | |
315 && cctx->ctx_ufunc != NULL | |
316 && (cctx->ctx_ufunc->uf_flags & FC_OBJECT) | |
317 && STRNCMP(name, "this", 4) == 0))) | |
300 || script_var_exists(name, len, cctx, NULL) == OK | 318 || script_var_exists(name, len, cctx, NULL) == OK |
301 || find_imported(name, len, FALSE) != NULL; | 319 || find_imported(name, len, FALSE) != NULL; |
302 } | 320 } |
303 | 321 |
304 /* | 322 /* |
955 { | 973 { |
956 r = FAIL; | 974 r = FAIL; |
957 goto theend; | 975 goto theend; |
958 } | 976 } |
959 | 977 |
960 ufunc = define_function(eap, lambda_name, lines_to_free); | 978 ufunc = define_function(eap, lambda_name, lines_to_free, NULL); |
961 if (ufunc == NULL) | 979 if (ufunc == NULL) |
962 { | 980 { |
963 r = eap->skip ? OK : FAIL; | 981 r = eap->skip ? OK : FAIL; |
964 goto theend; | 982 goto theend; |
965 } | 983 } |
1448 | 1466 |
1449 CLEAR_POINTER(lhs); | 1467 CLEAR_POINTER(lhs); |
1450 lhs->lhs_dest = dest_local; | 1468 lhs->lhs_dest = dest_local; |
1451 lhs->lhs_vimvaridx = -1; | 1469 lhs->lhs_vimvaridx = -1; |
1452 lhs->lhs_scriptvar_idx = -1; | 1470 lhs->lhs_scriptvar_idx = -1; |
1471 lhs->lhs_member_idx = -1; | |
1453 | 1472 |
1454 // "dest_end" is the end of the destination, including "[expr]" or | 1473 // "dest_end" is the end of the destination, including "[expr]" or |
1455 // ".name". | 1474 // ".name". |
1456 // "var_end" is the end of the variable/option/etc. name. | 1475 // "var_end" is the end of the variable/option/etc. name. |
1457 lhs->lhs_dest_end = skip_var_one(var_start, FALSE); | 1476 lhs->lhs_dest_end = skip_var_one(var_start, FALSE); |
1507 declare_error = is_decl; | 1526 declare_error = is_decl; |
1508 } | 1527 } |
1509 else | 1528 else |
1510 { | 1529 { |
1511 // No specific kind of variable recognized, just a name. | 1530 // No specific kind of variable recognized, just a name. |
1512 if (check_reserved_name(lhs->lhs_name) == FAIL) | 1531 if (check_reserved_name(lhs->lhs_name, cctx) == FAIL) |
1513 return FAIL; | 1532 return FAIL; |
1514 | 1533 |
1515 if (lookup_local(var_start, lhs->lhs_varlen, | 1534 if (lookup_local(var_start, lhs->lhs_varlen, |
1516 &lhs->lhs_local_lvar, cctx) == OK) | 1535 &lhs->lhs_local_lvar, cctx) == OK) |
1517 lhs->lhs_lvar = &lhs->lhs_local_lvar; | 1536 lhs->lhs_lvar = &lhs->lhs_local_lvar; |
1755 // We don't know the type before evaluating the expression, | 1774 // We don't know the type before evaluating the expression, |
1756 // use "any" until then. | 1775 // use "any" until then. |
1757 lhs->lhs_type = &t_any; | 1776 lhs->lhs_type = &t_any; |
1758 } | 1777 } |
1759 | 1778 |
1760 if (lhs->lhs_type->tt_member == NULL) | 1779 if (lhs->lhs_type == NULL || lhs->lhs_type->tt_member == NULL) |
1761 lhs->lhs_member_type = &t_any; | 1780 lhs->lhs_member_type = &t_any; |
1781 else if (lhs->lhs_type->tt_type == VAR_CLASS | |
1782 || lhs->lhs_type->tt_type == VAR_OBJECT) | |
1783 { | |
1784 // for an object or class member get the type of the member | |
1785 class_T *cl = (class_T *)lhs->lhs_type->tt_member; | |
1786 lhs->lhs_member_type = class_member_type(cl, after + 1, | |
1787 lhs->lhs_end, &lhs->lhs_member_idx); | |
1788 } | |
1762 else | 1789 else |
1763 lhs->lhs_member_type = lhs->lhs_type->tt_member; | 1790 lhs->lhs_member_type = lhs->lhs_type->tt_member; |
1764 } | 1791 } |
1765 return OK; | 1792 return OK; |
1766 } | 1793 } |
1878 // this should not happen | 1905 // this should not happen |
1879 emsg(_(e_missing_closing_square_brace)); | 1906 emsg(_(e_missing_closing_square_brace)); |
1880 r = FAIL; | 1907 r = FAIL; |
1881 } | 1908 } |
1882 } | 1909 } |
1910 else if (lhs->lhs_member_idx >= 0) | |
1911 { | |
1912 // object member index | |
1913 r = generate_PUSHNR(cctx, lhs->lhs_member_idx); | |
1914 } | |
1883 else // if (*p == '.') | 1915 else // if (*p == '.') |
1884 { | 1916 { |
1885 char_u *key_end = to_name_end(p + 1, TRUE); | 1917 char_u *key_end = to_name_end(p + 1, TRUE); |
1886 char_u *key = vim_strnsave(p + 1, key_end - p - 1); | 1918 char_u *key = vim_strnsave(p + 1, key_end - p - 1); |
1887 | 1919 |
1994 { | 2026 { |
1995 semsg(_(e_cannot_use_range_with_assignment_str), var_start); | 2027 semsg(_(e_cannot_use_range_with_assignment_str), var_start); |
1996 return FAIL; | 2028 return FAIL; |
1997 } | 2029 } |
1998 | 2030 |
1999 if (lhs->lhs_type == &t_any) | 2031 if (lhs->lhs_type == NULL || lhs->lhs_type == &t_any) |
2000 { | 2032 { |
2001 // Index on variable of unknown type: check at runtime. | 2033 // Index on variable of unknown type: check at runtime. |
2002 dest_type = VAR_ANY; | 2034 dest_type = VAR_ANY; |
2003 } | 2035 } |
2004 else | 2036 else |
2040 // - for [a : b] second index | 2072 // - for [a : b] second index |
2041 // - variable | 2073 // - variable |
2042 if (compile_load_lhs(lhs, var_start, rhs_type, cctx) == FAIL) | 2074 if (compile_load_lhs(lhs, var_start, rhs_type, cctx) == FAIL) |
2043 return FAIL; | 2075 return FAIL; |
2044 | 2076 |
2045 if (dest_type == VAR_LIST || dest_type == VAR_DICT | 2077 if (dest_type == VAR_LIST |
2046 || dest_type == VAR_BLOB || dest_type == VAR_ANY) | 2078 || dest_type == VAR_DICT |
2079 || dest_type == VAR_BLOB | |
2080 || dest_type == VAR_CLASS | |
2081 || dest_type == VAR_OBJECT | |
2082 || dest_type == VAR_ANY) | |
2047 { | 2083 { |
2048 if (is_assign) | 2084 if (is_assign) |
2049 { | 2085 { |
2050 if (range) | 2086 if (range) |
2051 { | 2087 { |
2464 case VAR_UNKNOWN: | 2500 case VAR_UNKNOWN: |
2465 case VAR_ANY: | 2501 case VAR_ANY: |
2466 case VAR_PARTIAL: | 2502 case VAR_PARTIAL: |
2467 case VAR_VOID: | 2503 case VAR_VOID: |
2468 case VAR_INSTR: | 2504 case VAR_INSTR: |
2505 case VAR_CLASS: | |
2506 case VAR_OBJECT: | |
2469 case VAR_SPECIAL: // cannot happen | 2507 case VAR_SPECIAL: // cannot happen |
2470 // This is skipped for local variables, they are always | 2508 // This is skipped for local variables, they are always |
2471 // initialized to zero. But in a "for" or "while" loop | 2509 // initialized to zero. But in a "for" or "while" loop |
2472 // the value may have been changed. | 2510 // the value may have been changed. |
2473 if (lhs.lhs_dest == dest_local | 2511 if (lhs.lhs_dest == dest_local |
2894 estack_push_ufunc(ufunc, 1); | 2932 estack_push_ufunc(ufunc, 1); |
2895 estack_compiling = TRUE; | 2933 estack_compiling = TRUE; |
2896 | 2934 |
2897 if (check_args_shadowing(ufunc, &cctx) == FAIL) | 2935 if (check_args_shadowing(ufunc, &cctx) == FAIL) |
2898 goto erret; | 2936 goto erret; |
2937 | |
2938 // For an object method and constructor "this" is the first local variable. | |
2939 if (ufunc->uf_flags & FC_OBJECT) | |
2940 { | |
2941 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) | |
2942 + ufunc->uf_dfunc_idx; | |
2943 if (GA_GROW_FAILS(&dfunc->df_var_names, 1)) | |
2944 goto erret; | |
2945 ((char_u **)dfunc->df_var_names.ga_data)[0] = | |
2946 vim_strsave((char_u *)"this"); | |
2947 ++dfunc->df_var_names.ga_len; | |
2948 | |
2949 // In the constructor allocate memory for the object. | |
2950 if ((ufunc->uf_flags & FC_NEW) == FC_NEW) | |
2951 generate_CONSTRUCT(&cctx, ufunc->uf_class); | |
2952 } | |
2899 | 2953 |
2900 if (ufunc->uf_def_args.ga_len > 0) | 2954 if (ufunc->uf_def_args.ga_len > 0) |
2901 { | 2955 { |
2902 int count = ufunc->uf_def_args.ga_len; | 2956 int count = ufunc->uf_def_args.ga_len; |
2903 int first_def_arg = ufunc->uf_args.ga_len - count; | 2957 int first_def_arg = ufunc->uf_args.ga_len - count; |
3498 | 3552 |
3499 if (!cctx.ctx_had_return) | 3553 if (!cctx.ctx_had_return) |
3500 { | 3554 { |
3501 if (ufunc->uf_ret_type->tt_type == VAR_UNKNOWN) | 3555 if (ufunc->uf_ret_type->tt_type == VAR_UNKNOWN) |
3502 ufunc->uf_ret_type = &t_void; | 3556 ufunc->uf_ret_type = &t_void; |
3503 else if (ufunc->uf_ret_type->tt_type != VAR_VOID) | 3557 else if (ufunc->uf_ret_type->tt_type != VAR_VOID |
3558 && (ufunc->uf_flags & FC_NEW) != FC_NEW) | |
3504 { | 3559 { |
3505 emsg(_(e_missing_return_statement)); | 3560 emsg(_(e_missing_return_statement)); |
3506 goto erret; | 3561 goto erret; |
3507 } | 3562 } |
3508 | 3563 |
3509 // Return void if there is no return at the end. | 3564 // Return void if there is no return at the end. |
3510 generate_instr(&cctx, ISN_RETURN_VOID); | 3565 // For a constructor return the object. |
3566 if ((ufunc->uf_flags & FC_NEW) == FC_NEW) | |
3567 generate_instr(&cctx, ISN_RETURN_OBJECT); | |
3568 else | |
3569 generate_instr(&cctx, ISN_RETURN_VOID); | |
3511 } | 3570 } |
3512 | 3571 |
3513 // When compiled with ":silent!" and there was an error don't consider the | 3572 // When compiled with ":silent!" and there was an error don't consider the |
3514 // function compiled. | 3573 // function compiled. |
3515 if (emsg_silent == 0 || did_emsg_silent == did_emsg_silent_before) | 3574 if (emsg_silent == 0 || did_emsg_silent == did_emsg_silent_before) |