To: vim_dev@googlegroups.com Subject: Patch 8.2.1250 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.1250 Problem: Vim9: cannot use the g:, b:, t: and w: namespaces. Solution: Add instructions to push a dict for the namespaces. (closes #6480) Files: src/vim9.h, src/vim9compile.c, src/vim9execute.c, src/testdir/test_vim9_disassemble.vim, src/testdir/test_vim9_expr.vim *** ../vim-8.2.1249/src/vim9.h 2020-07-19 17:55:38.479675049 +0200 --- src/vim9.h 2020-07-19 18:56:52.349302198 +0200 *************** *** 26,31 **** --- 26,35 ---- ISN_LOADB, // push b: variable isn_arg.string ISN_LOADW, // push w: variable isn_arg.string ISN_LOADT, // push t: variable isn_arg.string + ISN_LOADGDICT, // push g: dict + ISN_LOADBDICT, // push b: dict + ISN_LOADWDICT, // push w: dict + ISN_LOADTDICT, // push t: dict ISN_LOADS, // push s: variable isn_arg.loadstore ISN_LOADOUTER, // push variable from outer scope isn_arg.number ISN_LOADSCRIPT, // push script-local variable isn_arg.script. *** ../vim-8.2.1249/src/vim9compile.c 2020-07-19 17:55:38.479675049 +0200 --- src/vim9compile.c 2020-07-19 19:14:16.674183837 +0200 *************** *** 147,152 **** --- 147,153 ---- static char e_syntax_at[] = N_("E1002: Syntax error at %s"); static char e_used_as_arg[] = N_("E1006: %s is used as an argument"); static char e_cannot_use_void[] = N_("E1031: Cannot use void value"); + static char e_namespace[] = N_("E1075: Namespace not supported: %s"); static void delete_def_function_contents(dfunc_T *dfunc); static void arg_type_mismatch(type_T *expected, type_T *actual, int argidx); *************** *** 2781,2787 **** compile_load(char_u **arg, char_u *end_arg, cctx_T *cctx, int error) { type_T *type; ! char_u *name; char_u *end = end_arg; int res = FAIL; int prev_called_emsg = called_emsg; --- 2782,2788 ---- compile_load(char_u **arg, char_u *end_arg, cctx_T *cctx, int error) { type_T *type; ! char_u *name = NULL; char_u *end = end_arg; int res = FAIL; int prev_called_emsg = called_emsg; *************** *** 2790,2837 **** { // load namespaced variable if (end <= *arg + 2) - name = vim_strsave((char_u *)"[empty]"); - else - name = vim_strnsave(*arg + 2, end - (*arg + 2)); - if (name == NULL) - return FAIL; - - if (**arg == 'v') - { - res = generate_LOADV(cctx, name, error); - } - else if (**arg == 'g') - { - // Global variables can be defined later, thus we don't check if it - // exists, give error at runtime. - res = generate_LOAD(cctx, ISN_LOADG, 0, name, &t_any); - } - else if (**arg == 's') - { - res = compile_load_scriptvar(cctx, name, NULL, NULL, error); - } - else if (**arg == 'b') - { - // Buffer-local variables can be defined later, thus we don't check - // if it exists, give error at runtime. - res = generate_LOAD(cctx, ISN_LOADB, 0, name, &t_any); - } - else if (**arg == 'w') - { - // Window-local variables can be defined later, thus we don't check - // if it exists, give error at runtime. - res = generate_LOAD(cctx, ISN_LOADW, 0, name, &t_any); - } - else if (**arg == 't') { ! // Tabpage-local variables can be defined later, thus we don't ! // check if it exists, give error at runtime. ! res = generate_LOAD(cctx, ISN_LOADT, 0, name, &t_any); } else { ! semsg("E1075: Namespace not supported: %s", *arg); ! goto theend; } } else --- 2791,2842 ---- { // load namespaced variable if (end <= *arg + 2) { ! isntype_T isn_type; ! ! switch (**arg) ! { ! case 'g': isn_type = ISN_LOADGDICT; break; ! case 'w': isn_type = ISN_LOADWDICT; break; ! case 't': isn_type = ISN_LOADTDICT; break; ! case 'b': isn_type = ISN_LOADBDICT; break; ! default: ! semsg(_(e_namespace), *arg); ! goto theend; ! } ! if (generate_instr_type(cctx, isn_type, &t_dict_any) == NULL) ! goto theend; ! res = OK; } else { ! isntype_T isn_type = ISN_DROP; ! ! name = vim_strnsave(*arg + 2, end - (*arg + 2)); ! if (name == NULL) ! return FAIL; ! ! switch (**arg) ! { ! case 'v': res = generate_LOADV(cctx, name, error); ! break; ! case 's': res = compile_load_scriptvar(cctx, name, ! NULL, NULL, error); ! break; ! case 'g': isn_type = ISN_LOADG; break; ! case 'w': isn_type = ISN_LOADW; break; ! case 't': isn_type = ISN_LOADT; break; ! case 'b': isn_type = ISN_LOADB; break; ! default: semsg(_(e_namespace), *arg); ! goto theend; ! } ! if (isn_type != ISN_DROP) ! { ! // Global, Buffer-local, Window-local and Tabpage-local ! // variables can be defined later, thus we don't check if it ! // exists, give error at runtime. ! res = generate_LOAD(cctx, isn_type, 0, name, &t_any); ! } } } else *************** *** 7556,7565 **** case ISN_MEMBER: case ISN_JUMP: case ISN_LOAD: case ISN_LOADOUTER: - case ISN_LOADSCRIPT: case ISN_LOADREG: case ISN_LOADV: case ISN_NEGATENR: case ISN_NEWDICT: case ISN_NEWLIST: --- 7561,7574 ---- case ISN_MEMBER: case ISN_JUMP: case ISN_LOAD: + case ISN_LOADBDICT: + case ISN_LOADGDICT: case ISN_LOADOUTER: case ISN_LOADREG: + case ISN_LOADSCRIPT: + case ISN_LOADTDICT: case ISN_LOADV: + case ISN_LOADWDICT: case ISN_NEGATENR: case ISN_NEWDICT: case ISN_NEWLIST: *** ../vim-8.2.1249/src/vim9execute.c 2020-07-19 17:55:38.483675037 +0200 --- src/vim9execute.c 2020-07-19 19:08:24.315242442 +0200 *************** *** 1089,1094 **** --- 1089,1095 ---- dictitem_T *di = NULL; hashtab_T *ht = NULL; char namespace; + switch (iptr->isn_type) { case ISN_LOADG: *************** *** 1128,1133 **** --- 1129,1161 ---- } break; + // load g:/b:/w:/t: namespace + case ISN_LOADGDICT: + case ISN_LOADBDICT: + case ISN_LOADWDICT: + case ISN_LOADTDICT: + { + dict_T *d = NULL; + + switch (iptr->isn_type) + { + case ISN_LOADG: d = get_globvar_dict(); break; + case ISN_LOADB: d = &curbuf->b_vars; break; + case ISN_LOADW: d = &curwin->w_vars; break; + case ISN_LOADT: d = &curtab->tp_vars; break; + default: // Cannot reach here + goto failed; + } + if (GA_GROW(&ectx.ec_stack, 1) == FAIL) + goto failed; + tv = STACK_TV_BOT(0); + tv->v_type = VAR_DICT; + tv->v_lock = 0; + tv->vval.v_dict = d; + ++ectx.ec_stack.ga_len; + } + break; + // load &option case ISN_LOADOPT: { *************** *** 1166,1171 **** --- 1194,1200 ---- goto failed; tv = STACK_TV_BOT(0); tv->v_type = VAR_STRING; + tv->v_lock = 0; tv->vval.v_string = get_reg_contents( iptr->isn_arg.number, GREG_EXPR_SRC); ++ectx.ec_stack.ga_len; *************** *** 1411,1416 **** --- 1440,1446 ---- if (GA_GROW(&ectx.ec_stack, 1) == FAIL) goto failed; tv = STACK_TV_BOT(0); + tv->v_lock = 0; ++ectx.ec_stack.ga_len; switch (iptr->isn_type) { *************** *** 1529,1534 **** --- 1559,1565 ---- ++ectx.ec_stack.ga_len; tv = STACK_TV_BOT(-1); tv->v_type = VAR_DICT; + tv->v_lock = 0; tv->vval.v_dict = dict; ++dict->dv_refcount; } *************** *** 1673,1678 **** --- 1704,1710 ---- ++ectx.ec_stack.ga_len; tv->vval.v_partial = pt; tv->v_type = VAR_PARTIAL; + tv->v_lock = 0; } break; *************** *** 1719,1724 **** --- 1751,1757 ---- // non-materialized range() list tv = STACK_TV_BOT(0); tv->v_type = VAR_NUMBER; + tv->v_lock = 0; tv->vval.v_number = list_find_nr( list, idxtv->vval.v_number, NULL); ++ectx.ec_stack.ga_len; *************** *** 1762,1767 **** --- 1795,1801 ---- tv = STACK_TV_BOT(0); ++ectx.ec_stack.ga_len; tv->v_type = VAR_STRING; + tv->v_lock = 0; tv->vval.v_string = vim_strsave( (char_u *)current_exception->value); break; *************** *** 2626,2631 **** --- 2660,2677 ---- case ISN_LOADT: smsg("%4d LOADT t:%s", current, iptr->isn_arg.string); break; + case ISN_LOADGDICT: + smsg("%4d LOAD g:", current); + break; + case ISN_LOADBDICT: + smsg("%4d LOAD b:", current); + break; + case ISN_LOADWDICT: + smsg("%4d LOAD w:", current); + break; + case ISN_LOADTDICT: + smsg("%4d LOAD t:", current); + break; case ISN_LOADOPT: smsg("%4d LOADOPT %s", current, iptr->isn_arg.string); break; *** ../vim-8.2.1249/src/testdir/test_vim9_disassemble.vim 2020-07-19 18:38:32.324455405 +0200 --- src/testdir/test_vim9_disassemble.vim 2020-07-19 19:46:43.009183859 +0200 *************** *** 21,29 **** --- 21,33 ---- echo v:version echo s:scriptvar echo g:globalvar + echo get(g:, "global") echo b:buffervar + echo get(b:, "buffer") echo w:windowvar + echo get(w:, "window") echo t:tabpagevar + echo get(t:, "tab") echo &tabstop echo $ENVVAR echo @z *************** *** 47,55 **** --- 51,75 ---- ' LOADV v:version.*' .. ' LOADS s:scriptvar from .*test_vim9_disassemble.vim.*' .. ' LOADG g:globalvar.*' .. + 'echo get(g:, "global")\_s*' .. + '\d\+ LOAD g:\_s*' .. + '\d\+ PUSHS "global"\_s*' .. + '\d\+ BCALL get(argc 2).*' .. ' LOADB b:buffervar.*' .. + 'echo get(b:, "buffer")\_s*' .. + '\d\+ LOAD b:\_s*' .. + '\d\+ PUSHS "buffer"\_s*' .. + '\d\+ BCALL get(argc 2).*' .. ' LOADW w:windowvar.*' .. + 'echo get(w:, "window")\_s*' .. + '\d\+ LOAD w:\_s*' .. + '\d\+ PUSHS "window"\_s*' .. + '\d\+ BCALL get(argc 2).*' .. ' LOADT t:tabpagevar.*' .. + 'echo get(t:, "tab")\_s*' .. + '\d\+ LOAD t:\_s*' .. + '\d\+ PUSHS "tab"\_s*' .. + '\d\+ BCALL get(argc 2).*' .. ' LOADENV $ENVVAR.*' .. ' LOADREG @z.*', res) *** ../vim-8.2.1249/src/testdir/test_vim9_expr.vim 2020-07-19 17:55:38.483675037 +0200 --- src/testdir/test_vim9_expr.vim 2020-07-19 19:24:39.712721372 +0200 *************** *** 1345,1350 **** --- 1345,1376 ---- assert_equal('register a', @a) enddef + def Test_expr7_namespace() + g:some_var = 'some' + assert_equal('some', get(g:, 'some_var')) + assert_equal('some', get(g:, 'some_var', 'xxx')) + assert_equal('xxx', get(g:, 'no_var', 'xxx')) + unlet g:some_var + + b:some_var = 'some' + assert_equal('some', get(b:, 'some_var')) + assert_equal('some', get(b:, 'some_var', 'xxx')) + assert_equal('xxx', get(b:, 'no_var', 'xxx')) + unlet b:some_var + + w:some_var = 'some' + assert_equal('some', get(w:, 'some_var')) + assert_equal('some', get(w:, 'some_var', 'xxx')) + assert_equal('xxx', get(w:, 'no_var', 'xxx')) + unlet w:some_var + + t:some_var = 'some' + assert_equal('some', get(t:, 'some_var')) + assert_equal('some', get(t:, 'some_var', 'xxx')) + assert_equal('xxx', get(t:, 'no_var', 'xxx')) + unlet t:some_var + enddef + def Test_expr7_parens() # (expr) assert_equal(4, (6 * 4) / 6) *** ../vim-8.2.1249/src/version.c 2020-07-19 18:38:32.324455405 +0200 --- src/version.c 2020-07-19 19:25:03.608663737 +0200 *************** *** 756,757 **** --- 756,759 ---- { /* Add new patch number below this line */ + /**/ + 1250, /**/ -- Well, you come from nothing, you go back to nothing... What have you lost? Nothing! -- Monty Python: The life of Brian /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///