Skip to content

Commit d77a852

Browse files
committed
patch 8.2.0508: Vim9: func and partial types not done yet
Problem: Vim9: func and partial types not done yet Solution: Fill in details about func declaration, drop a separate partial declaration.
1 parent 5259275 commit d77a852

9 files changed

Lines changed: 247 additions & 115 deletions

File tree

runtime/doc/vim9.txt

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*vim9.txt* For Vim version 8.2. Last change: 2020 Mar 01
1+
*vim9.txt* For Vim version 8.2. Last change: 2020 Apr 03
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -249,8 +249,8 @@ THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
249249
the function follows in the next lines, until the
250250
matching `:enddef`.
251251

252-
When {return-type} is omitted the function is not
253-
expected to return anything.
252+
When {return-type} is omitted or is "void" the
253+
function is not expected to return anything.
254254

255255
{arguments} is a sequence of zero or more argument
256256
declarations. There are three forms:
@@ -296,29 +296,40 @@ The following builtin types are supported:
296296
float
297297
string
298298
blob
299-
list<type>
300-
dict<type>
301-
(a: type, b: type): type
299+
list<{type}>
300+
dict<{type}>
302301
job
303302
channel
304303
func
305-
partial
304+
func({type}, ...)
305+
func({type}, ...): {type}
306306

307307
Not supported yet:
308-
tuple<a: type, b: type, ...>
308+
tuple<a: {type}, b: {type}, ...>
309309

310-
These types can be used in declarations, but no variable will have this type:
311-
type|type
310+
These types can be used in declarations, but no value will have this type:
311+
{type}|{type}
312312
void
313313
any
314314

315-
There is no array type, use list<type> instead. For a list constant an
315+
There is no array type, use list<{type}> instead. For a list constant an
316316
efficient implementation is used that avoids allocating lot of small pieces of
317317
memory.
318318

319-
A function defined with `:def` must declare the return type. If there is no
320-
type then the function doesn't return anything. "void" is used in type
321-
declarations.
319+
A partial and function can be declared in more or less specific ways:
320+
func any kind of function reference, no type
321+
checking
322+
func: {type} any number and type of arguments with specific
323+
return type
324+
func({type} ...) function with argument types, does not return
325+
a value
326+
func({type} ...): {type} function with argument types and return type
327+
328+
If the return type is "void" the function does not return a value.
329+
330+
The reference can also be a |Partial|, in which case it stores extra arguments
331+
and/or a dictionary, which are not visible to the caller. Since they are
332+
called in the same way the declaration is the same.
322333

323334
Custom types can be defined with `:type`: >
324335
:type MyList list<string>

src/evalfunc.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -336,11 +336,6 @@ ret_func_any(int argcount UNUSED, type_T **argtypes UNUSED)
336336
return &t_func_any;
337337
}
338338
static type_T *
339-
ret_partial_any(int argcount UNUSED, type_T **argtypes UNUSED)
340-
{
341-
return &t_partial_any;
342-
}
343-
static type_T *
344339
ret_channel(int argcount UNUSED, type_T **argtypes UNUSED)
345340
{
346341
return &t_channel;
@@ -564,7 +559,7 @@ static funcentry_T global_functions[] =
564559
{"foldtext", 0, 0, 0, ret_string, f_foldtext},
565560
{"foldtextresult", 1, 1, FEARG_1, ret_string, f_foldtextresult},
566561
{"foreground", 0, 0, 0, ret_void, f_foreground},
567-
{"funcref", 1, 3, FEARG_1, ret_partial_any, f_funcref},
562+
{"funcref", 1, 3, FEARG_1, ret_func_any, f_funcref},
568563
{"function", 1, 3, FEARG_1, ret_f_function, f_function},
569564
{"garbagecollect", 0, 1, 0, ret_void, f_garbagecollect},
570565
{"get", 2, 3, FEARG_1, ret_any, f_get},
@@ -961,7 +956,7 @@ static funcentry_T global_functions[] =
961956
{"test_null_function", 0, 0, 0, ret_func_any, f_test_null_function},
962957
{"test_null_job", 0, 0, 0, ret_job, JOB_FUNC(f_test_null_job)},
963958
{"test_null_list", 0, 0, 0, ret_list_any, f_test_null_list},
964-
{"test_null_partial", 0, 0, 0, ret_partial_any, f_test_null_partial},
959+
{"test_null_partial", 0, 0, 0, ret_func_any, f_test_null_partial},
965960
{"test_null_string", 0, 0, 0, ret_string, f_test_null_string},
966961
{"test_option_not_set", 1, 1, FEARG_1,ret_void, f_test_option_not_set},
967962
{"test_override", 2, 2, FEARG_2, ret_void, f_test_override},
@@ -2902,7 +2897,7 @@ ret_f_function(int argcount, type_T **argtypes UNUSED)
29022897
{
29032898
if (argcount == 1 && argtypes[0]->tt_type == VAR_STRING)
29042899
return &t_func_any;
2905-
return &t_partial_void;
2900+
return &t_func_void;
29062901
}
29072902

29082903
/*

src/globals.h

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -379,36 +379,39 @@ EXTERN sctx_T current_sctx INIT4(0, 0, 0, 0);
379379

380380

381381
// Commonly used types.
382-
EXTERN type_T t_any INIT4(VAR_UNKNOWN, 0, NULL, NULL);
383-
EXTERN type_T t_void INIT4(VAR_VOID, 0, NULL, NULL);
384-
EXTERN type_T t_bool INIT4(VAR_BOOL, 0, NULL, NULL);
385-
EXTERN type_T t_special INIT4(VAR_SPECIAL, 0, NULL, NULL);
386-
EXTERN type_T t_number INIT4(VAR_NUMBER, 0, NULL, NULL);
387-
EXTERN type_T t_float INIT4(VAR_FLOAT, 0, NULL, NULL);
388-
EXTERN type_T t_string INIT4(VAR_STRING, 0, NULL, NULL);
389-
EXTERN type_T t_blob INIT4(VAR_BLOB, 0, NULL, NULL);
390-
EXTERN type_T t_job INIT4(VAR_JOB, 0, NULL, NULL);
391-
EXTERN type_T t_channel INIT4(VAR_CHANNEL, 0, NULL, NULL);
392-
393-
EXTERN type_T t_func_void INIT4(VAR_FUNC, -1, &t_void, NULL);
394-
EXTERN type_T t_func_any INIT4(VAR_FUNC, -1, &t_any, NULL);
395-
396-
EXTERN type_T t_partial_void INIT4(VAR_PARTIAL, -1, &t_void, NULL);
397-
EXTERN type_T t_partial_any INIT4(VAR_PARTIAL, -1, &t_any, NULL);
398-
399-
EXTERN type_T t_list_any INIT4(VAR_LIST, 0, &t_any, NULL);
400-
EXTERN type_T t_dict_any INIT4(VAR_DICT, 0, &t_any, NULL);
401-
EXTERN type_T t_list_empty INIT4(VAR_LIST, 0, &t_void, NULL);
402-
EXTERN type_T t_dict_empty INIT4(VAR_DICT, 0, &t_void, NULL);
403-
404-
EXTERN type_T t_list_bool INIT4(VAR_LIST, 0, &t_bool, NULL);
405-
EXTERN type_T t_list_number INIT4(VAR_LIST, 0, &t_number, NULL);
406-
EXTERN type_T t_list_string INIT4(VAR_LIST, 0, &t_string, NULL);
407-
EXTERN type_T t_list_dict_any INIT4(VAR_LIST, 0, &t_dict_any, NULL);
408-
409-
EXTERN type_T t_dict_bool INIT4(VAR_DICT, 0, &t_bool, NULL);
410-
EXTERN type_T t_dict_number INIT4(VAR_DICT, 0, &t_number, NULL);
411-
EXTERN type_T t_dict_string INIT4(VAR_DICT, 0, &t_string, NULL);
382+
EXTERN type_T t_any INIT5(VAR_UNKNOWN, 0, 0, NULL, NULL);
383+
EXTERN type_T t_void INIT5(VAR_VOID, 0, 0, NULL, NULL);
384+
EXTERN type_T t_bool INIT5(VAR_BOOL, 0, 0, NULL, NULL);
385+
EXTERN type_T t_special INIT5(VAR_SPECIAL, 0, 0, NULL, NULL);
386+
EXTERN type_T t_number INIT5(VAR_NUMBER, 0, 0, NULL, NULL);
387+
EXTERN type_T t_float INIT5(VAR_FLOAT, 0, 0, NULL, NULL);
388+
EXTERN type_T t_string INIT5(VAR_STRING, 0, 0, NULL, NULL);
389+
EXTERN type_T t_blob INIT5(VAR_BLOB, 0, 0, NULL, NULL);
390+
EXTERN type_T t_job INIT5(VAR_JOB, 0, 0, NULL, NULL);
391+
EXTERN type_T t_channel INIT5(VAR_CHANNEL, 0, 0, NULL, NULL);
392+
393+
EXTERN type_T t_func_void INIT5(VAR_FUNC, -1, 0, &t_void, NULL);
394+
EXTERN type_T t_func_any INIT5(VAR_FUNC, -1, 0, &t_any, NULL);
395+
EXTERN type_T t_func_number INIT5(VAR_FUNC, -1, 0, &t_number, NULL);
396+
EXTERN type_T t_func_string INIT5(VAR_FUNC, -1, 0, &t_string, NULL);
397+
EXTERN type_T t_func_0_void INIT5(VAR_FUNC, 0, 0, &t_void, NULL);
398+
EXTERN type_T t_func_0_any INIT5(VAR_FUNC, 0, 0, &t_any, NULL);
399+
EXTERN type_T t_func_0_number INIT5(VAR_FUNC, 0, 0, &t_number, NULL);
400+
EXTERN type_T t_func_0_string INIT5(VAR_FUNC, 0, 0, &t_string, NULL);
401+
402+
EXTERN type_T t_list_any INIT5(VAR_LIST, 0, 0, &t_any, NULL);
403+
EXTERN type_T t_dict_any INIT5(VAR_DICT, 0, 0, &t_any, NULL);
404+
EXTERN type_T t_list_empty INIT5(VAR_LIST, 0, 0, &t_void, NULL);
405+
EXTERN type_T t_dict_empty INIT5(VAR_DICT, 0, 0, &t_void, NULL);
406+
407+
EXTERN type_T t_list_bool INIT5(VAR_LIST, 0, 0, &t_bool, NULL);
408+
EXTERN type_T t_list_number INIT5(VAR_LIST, 0, 0, &t_number, NULL);
409+
EXTERN type_T t_list_string INIT5(VAR_LIST, 0, 0, &t_string, NULL);
410+
EXTERN type_T t_list_dict_any INIT5(VAR_LIST, 0, 0, &t_dict_any, NULL);
411+
412+
EXTERN type_T t_dict_bool INIT5(VAR_DICT, 0, 0, &t_bool, NULL);
413+
EXTERN type_T t_dict_number INIT5(VAR_DICT, 0, 0, &t_number, NULL);
414+
EXTERN type_T t_dict_string INIT5(VAR_DICT, 0, 0, &t_string, NULL);
412415

413416

414417
#endif

src/structs.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1342,10 +1342,14 @@ typedef struct type_S type_T;
13421342
struct type_S {
13431343
vartype_T tt_type;
13441344
short tt_argcount; // for func, partial, -1 for unknown
1345+
short tt_flags; // TTFLAG_ values
13451346
type_T *tt_member; // for list, dict, func return type
1346-
type_T *tt_args; // func arguments
1347+
type_T **tt_args; // func arguments, allocated
13471348
};
13481349

1350+
#define TTFLAG_VARARGS 1 // func args ends with "..."
1351+
#define TTFLAG_OPTARG 2 // func arg type with "?"
1352+
13491353
/*
13501354
* Structure to hold an internal variable without a name.
13511355
*/

src/testdir/test_vim9_disassemble.vim

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,7 @@ enddef
362362
def WithFunc()
363363
let funky1: func
364364
let funky2: func = function("len")
365-
let party1: partial
366-
let party2: partial = funcref("UserFunc")
365+
let party2: func = funcref("UserFunc")
367366
enddef
368367

369368
def Test_disassemble_function()
@@ -376,15 +375,12 @@ def Test_disassemble_function()
376375
\ .. '2 PUSHS "len".*'
377376
\ .. '3 BCALL function(argc 1).*'
378377
\ .. '4 STORE $1.*'
379-
\ .. 'let party1: partial.*'
380-
\ .. '5 PUSHPARTIAL "\[none]".*'
381-
\ .. '6 STORE $2.*'
382-
\ .. 'let party2: partial = funcref("UserFunc").*'
383-
\ .. '7 PUSHS "UserFunc".*'
384-
\ .. '8 BCALL funcref(argc 1).*'
385-
\ .. '9 STORE $3.*'
386-
\ .. '10 PUSHNR 0.*'
387-
\ .. '11 RETURN.*'
378+
\ .. 'let party2: func = funcref("UserFunc").*'
379+
\ .. '\d PUSHS "UserFunc".*'
380+
\ .. '\d BCALL funcref(argc 1).*'
381+
\ .. '\d STORE $2.*'
382+
\ .. '\d PUSHNR 0.*'
383+
\ .. '\d RETURN.*'
388384
\, instr)
389385
enddef
390386

@@ -753,10 +749,10 @@ def Test_disassemble_compare()
753749
\ ['#{a:1} is #{x:2}', 'COMPAREDICT is'],
754750
\ ['#{a:1} isnot #{x:2}', 'COMPAREDICT isnot'],
755751
\
756-
\ ['{->33} == {->44}', 'COMPAREPARTIAL =='],
757-
\ ['{->33} != {->44}', 'COMPAREPARTIAL !='],
758-
\ ['{->33} is {->44}', 'COMPAREPARTIAL is'],
759-
\ ['{->33} isnot {->44}', 'COMPAREPARTIAL isnot'],
752+
\ ['{->33} == {->44}', 'COMPAREFUNC =='],
753+
\ ['{->33} != {->44}', 'COMPAREFUNC !='],
754+
\ ['{->33} is {->44}', 'COMPAREFUNC is'],
755+
\ ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
760756
\
761757
\ ['77 == g:xx', 'COMPAREANY =='],
762758
\ ['77 != g:xx', 'COMPAREANY !='],

src/testdir/test_vim9_expr.vim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ func Test_expr4_fails()
461461
call CheckDefFailureMult(['let j: job', 'let chan: channel', 'let r = j == chan'], 'Cannot compare job with channel')
462462
call CheckDefFailureMult(['let j: job', 'let x: list<any>', 'let r = j == x'], 'Cannot compare job with list')
463463
call CheckDefFailureMult(['let j: job', 'let x: func', 'let r = j == x'], 'Cannot compare job with func')
464-
call CheckDefFailureMult(['let j: job', 'let x: partial', 'let r = j == x'], 'Cannot compare job with partial')
464+
call CheckDefFailureMult(['let j: job', 'let x: func', 'let r = j == x'], 'Cannot compare job with func')
465465
endfunc
466466

467467
" test addition, subtraction, concatenation

src/testdir/test_vim9_script.vim

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,7 @@ def Test_assignment()
6868
endif
6969
let funky1: func
7070
let funky2: func = function('len')
71-
let party1: partial
72-
let party2: partial = funcref('Test_syntax')
71+
let party2: func = funcref('Test_syntax')
7372

7473
" type becomes list<any>
7574
let somelist = rand() > 0 ? [1, 2, 3] : ['a', 'b', 'c']
@@ -157,9 +156,6 @@ def Test_assignment()
157156
let thefunc: func
158157
assert_equal(test_null_function(), thefunc)
159158

160-
let thepartial: partial
161-
assert_equal(test_null_partial(), thepartial)
162-
163159
let thelist: list<any>
164160
assert_equal([], thelist)
165161

@@ -213,7 +209,7 @@ func Test_assignment_failure()
213209
call CheckDefFailure(['let var = feedkeys("0")'], 'E1031:')
214210
call CheckDefFailure(['let var: number = feedkeys("0")'], 'expected number but got void')
215211

216-
call CheckDefFailure(['let var: dict <number>'], 'E1007:')
212+
call CheckDefFailure(['let var: dict <number>'], 'E1068:')
217213
call CheckDefFailure(['let var: dict<number'], 'E1009:')
218214
endfunc
219215

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,8 @@ static char *(features[]) =
738738

739739
static int included_patches[] =
740740
{ /* Add new patch number below this line */
741+
/**/
742+
508,
741743
/**/
742744
507,
743745
/**/

0 commit comments

Comments
 (0)