helpers.lua 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. local helpers = require('test.unit.helpers')(nil)
  2. local ffi = helpers.ffi
  3. local cimport = helpers.cimport
  4. local kvi_new = helpers.kvi_new
  5. local kvi_init = helpers.kvi_init
  6. local conv_enum = helpers.conv_enum
  7. local make_enum_conv_tab = helpers.make_enum_conv_tab
  8. local lib = cimport('./src/nvim/viml/parser/expressions.h')
  9. local function new_pstate(strings)
  10. local strings_idx = 0
  11. local function get_line(_, ret_pline)
  12. strings_idx = strings_idx + 1
  13. local str = strings[strings_idx]
  14. local data, size
  15. if type(str) == 'string' then
  16. data = str
  17. size = #str
  18. elseif type(str) == 'nil' then
  19. data = nil
  20. size = 0
  21. elseif type(str) == 'table' then
  22. data = str.data
  23. size = str.size
  24. elseif type(str) == 'function' then
  25. data, size = str()
  26. size = size or 0
  27. end
  28. ret_pline.data = data
  29. ret_pline.size = size
  30. ret_pline.allocated = false
  31. end
  32. local state = {
  33. reader = {
  34. get_line = get_line,
  35. cookie = nil,
  36. conv = {
  37. vc_type = 0,
  38. vc_factor = 1,
  39. vc_fail = false,
  40. },
  41. },
  42. pos = { line = 0, col = 0 },
  43. colors = kvi_new('ParserHighlight'),
  44. can_continuate = false,
  45. }
  46. local ret = ffi.new('ParserState', state)
  47. kvi_init(ret.reader.lines)
  48. kvi_init(ret.stack)
  49. return ret
  50. end
  51. local function pline2lua(pline)
  52. return ffi.string(pline.data, pline.size)
  53. end
  54. local function pstate_str(pstate, start, len)
  55. local str = nil
  56. local err = nil
  57. if start.line < pstate.reader.lines.size then
  58. local pstr = pline2lua(pstate.reader.lines.items[start.line])
  59. if start.col >= #pstr then
  60. err = 'start.col >= #pstr'
  61. else
  62. str = pstr:sub(tonumber(start.col) + 1, tonumber(start.col + len))
  63. end
  64. else
  65. err = 'start.line >= pstate.reader.lines.size'
  66. end
  67. return str, err
  68. end
  69. local function pstate_set_str(pstate, start, len, ret)
  70. ret = ret or {}
  71. ret.start = {
  72. line = tonumber(start.line),
  73. col = tonumber(start.col)
  74. }
  75. ret.len = tonumber(len)
  76. ret.str, ret.error = pstate_str(pstate, start, len)
  77. return ret
  78. end
  79. local eltkn_cmp_type_tab
  80. make_enum_conv_tab(lib, {
  81. 'kExprCmpEqual',
  82. 'kExprCmpMatches',
  83. 'kExprCmpGreater',
  84. 'kExprCmpGreaterOrEqual',
  85. 'kExprCmpIdentical',
  86. }, 'kExprCmp', function(ret) eltkn_cmp_type_tab = ret end)
  87. local function conv_cmp_type(typ)
  88. return conv_enum(eltkn_cmp_type_tab, typ)
  89. end
  90. local ccs_tab
  91. make_enum_conv_tab(lib, {
  92. 'kCCStrategyUseOption',
  93. 'kCCStrategyMatchCase',
  94. 'kCCStrategyIgnoreCase',
  95. }, 'kCCStrategy', function(ret) ccs_tab = ret end)
  96. local function conv_ccs(ccs)
  97. return conv_enum(ccs_tab, ccs)
  98. end
  99. local expr_asgn_type_tab
  100. make_enum_conv_tab(lib, {
  101. 'kExprAsgnPlain',
  102. 'kExprAsgnAdd',
  103. 'kExprAsgnSubtract',
  104. 'kExprAsgnConcat',
  105. }, 'kExprAsgn', function(ret) expr_asgn_type_tab = ret end)
  106. local function conv_expr_asgn_type(expr_asgn_type)
  107. return conv_enum(expr_asgn_type_tab, expr_asgn_type)
  108. end
  109. return {
  110. conv_ccs = conv_ccs,
  111. pline2lua = pline2lua,
  112. pstate_str = pstate_str,
  113. new_pstate = new_pstate,
  114. conv_cmp_type = conv_cmp_type,
  115. pstate_set_str = pstate_set_str,
  116. conv_expr_asgn_type = conv_expr_asgn_type,
  117. }