Advertisement
Guest User

Untitled

a guest
Aug 23rd, 2019
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.54 KB | None | 0 0
  1. " Emulate function overloading.
  2. " File: overload.vim
  3. " Created: 2014 Aug 01
  4. " Last Change: 2018 Nov 18
  5. " Version: 0.9
  6. " Author: Andy Wokula <anwoku@yahoo.de>
  7. " License: Vim License, see :h license
  8.  
  9. " CallOverloaded({func-dict}, {arg-list}, {dict})
  10. "
  11. " call one of the functions from {func-dict} with arguments {arg-list}.
  12. " The types of {arg-list} values determine which function will be called.
  13. " Basically, the function name is a concatenation of detected argument
  14. " types. {dict} becomes the dict argument of the function call.
  15. "
  16. " For example, CallOverloaded(d, ['str'], {}) will attempt to call:
  17. " d.S('str') (from high to low priority)
  18. " d.S_('str') Hints: `S' = (string)
  19. " d.X('str') `_' = optional arguments
  20. " d.X_('str') `X' = (number or string)
  21. " d._('str')
  22. " The function name imposes the function signature:
  23. " d.S(str)
  24. " d.S_(str, ...)
  25. " d.X(num_or_str)
  26. " d.X_(num_or_str, ...)
  27. " d._(...)
  28. " At least one of these functions must be defined for the call to succeed.
  29. " Hint: d._(...) should be defined to catch invalid arguments.
  30. "
  31.  
  32. " OverloadToken({arg-list})
  33. "
  34. " return the function name you can use in the function dict to exactly
  35. " match the given arguments {arg-list} (list).
  36. " (helper func)
  37. "
  38. " Examples:
  39. " :echo OverloadToken(['a', 1, 2, [], {}, function('tr'), 1.2])
  40. " => SNNLDFR
  41. "
  42. " :echo OverloadToken([])
  43. " => E
  44. "
  45.  
  46. " OverloadFunc({funcnames}, {ovltoken})
  47. "
  48. " return the best match for {ovltoken} within {funcnames}.
  49. " (helper func)
  50. " {funcnames} (list of string) names of the user-defined dict
  51. " functions, assumed to be sorted (using sort())
  52. " {ovltoken} (string) result of OverloadToken()
  53. "
  54. " Example:
  55. " :echo OverloadFunc(sort(['NS_', 'NX', 'N_']), 'NN')
  56. " => NX
  57. "
  58.  
  59. " OverloadInfo()
  60. "
  61. " return a dict with overloading meta data.
  62. " (helper func)
  63. "
  64.  
  65. " Notes:
  66. " * `X' to match (number or string) is a special case. Vim often
  67. " auto-converts between number and string, in which case it was annoying
  68. " to be urged to specify different functions. Especially because each
  69. " further such argument doubles the number of additional functions.
  70. " * Can only check against basic types ... eg cannot look inside a
  71. " dictionary to do some "pattern matching" etc. Will not add pattern
  72. " matching, but: by convention, a lot of `Is*()' functions exist to check
  73. " against a specific type ...
  74.  
  75. " History:
  76. " 2017 Nov 03 extracted OverloadFunc(), pattern fix
  77. " 2017 Aug 11 added new types (untested)
  78. " (!) no longer call .Default()
  79. " 2016 Feb 16 added `X' (N => [NX], S => [SX]) ... check dict argument for
  80. " flag which specifies conversion of `S' and `N' to `X'
  81. " (number or string)
  82. " 2015 Oct 16 funcs `SSO' and `SO' => `SO' was called -- bug, must call
  83. " the most specific function => change `O' into `_'.
  84.  
  85. " Examples:
  86. " asneeded\femu\sutr-dispatch-example.vim
  87. " SearchHierarchy(), asneeded\trial\D1845.vim
  88. " asneeded\trial\D2046.vim
  89.  
  90. " Constants: {{{
  91. " Mapping of type() results to identifier chars (for use in function name)
  92. " Mnemonics: String, Number, List, Dict, Funcref, Real number
  93. if exists('v:t_number')
  94. let s:TYPEMAP = {v:t_string : 'S', v:t_number : 'N', v:t_list : 'L', v:t_dict : 'D', v:t_func : 'F', v:t_float : 'R', v:t_bool : 'B', v:t_none : 'O', v:t_job : 'J', v:t_channel : 'C'}
  95. else
  96. let s:TYPEMAP = {1: 'S', 0: 'N', 3: 'L', 4: 'D', 2: 'F', 5: 'R'}
  97. endif
  98.  
  99. " optional arguments suffix (must start with a char GT any identifier char)
  100. let s:OPTSFX = '_'
  101.  
  102. " name of the function to call when there are no arguments (not required)
  103. let s:FNEMPTY = 'E'
  104.  
  105. " identifier char for unknown type (new type not yet recognized by this script)
  106. let s:TUNKNOWN = 'U'
  107.  
  108. " identifier char for 'number or string' (must be GT 'N' and GT 'S')
  109. let s:NUMORSTR = 'X'
  110. "}}}
  111.  
  112. func! CallOverloaded(funcdict, arglist, dict) "{{{
  113. let dt = OverloadToken(a:arglist)
  114. if has_key(a:funcdict, dt)
  115. let fn = dt
  116. else
  117. let fn = OverloadFunc(sort(keys(a:funcdict)), dt)
  118. endif
  119. return call(a:funcdict[fn], a:arglist, a:dict)
  120. endfunc "}}}
  121.  
  122. func! OverloadToken(arglist) "{{{
  123. let dt = join(map(range(len(a:arglist)), 'get(s:TYPEMAP, type(a:arglist[v:val]), s:TUNKNOWN)'), "")
  124. return dt=="" ? s:FNEMPTY : dt
  125. endfunc "}}}
  126.  
  127. func! OverloadFunc(funcnames, ftoken) "{{{
  128. let gft = substitute(a:ftoken, '[NS]', '[&X]', 'g')
  129. let pat = '^\%('. gft. '\|\%['. gft. ']'. s:OPTSFX. '\)$'
  130. let dt = matchstr(a:funcnames, pat)
  131. return dt=="" ? s:OPTSFX : dt
  132. endfunc "}}}
  133.  
  134. func! OverloadInfo() "{{{
  135. return {'optsfx': s:OPTSFX, 'fnempty': s:FNEMPTY, 'typemap': copy(s:TYPEMAP), 'tunknown': s:TUNKNOWN, 'tnumorstr': s:NUMORSTR}
  136. endfunc "}}}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement