testutil.lua 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. local t = require('test.unit.testutil')
  2. local ffi = t.ffi
  3. local cimport = t.cimport
  4. local kvi_new = t.kvi_new
  5. local kvi_init = t.kvi_init
  6. local conv_enum = t.conv_enum
  7. local make_enum_conv_tab = t.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(
  81. lib,
  82. {
  83. 'kExprCmpEqual',
  84. 'kExprCmpMatches',
  85. 'kExprCmpGreater',
  86. 'kExprCmpGreaterOrEqual',
  87. 'kExprCmpIdentical',
  88. },
  89. 'kExprCmp',
  90. function(ret)
  91. eltkn_cmp_type_tab = ret
  92. end
  93. )
  94. local function conv_cmp_type(typ)
  95. return conv_enum(eltkn_cmp_type_tab, typ)
  96. end
  97. local ccs_tab
  98. make_enum_conv_tab(
  99. lib,
  100. {
  101. 'kCCStrategyUseOption',
  102. 'kCCStrategyMatchCase',
  103. 'kCCStrategyIgnoreCase',
  104. },
  105. 'kCCStrategy',
  106. function(ret)
  107. ccs_tab = ret
  108. end
  109. )
  110. local function conv_ccs(ccs)
  111. return conv_enum(ccs_tab, ccs)
  112. end
  113. local expr_asgn_type_tab
  114. make_enum_conv_tab(
  115. lib,
  116. {
  117. 'kExprAsgnPlain',
  118. 'kExprAsgnAdd',
  119. 'kExprAsgnSubtract',
  120. 'kExprAsgnConcat',
  121. },
  122. 'kExprAsgn',
  123. function(ret)
  124. expr_asgn_type_tab = ret
  125. end
  126. )
  127. local function conv_expr_asgn_type(expr_asgn_type)
  128. return conv_enum(expr_asgn_type_tab, expr_asgn_type)
  129. end
  130. return {
  131. conv_ccs = conv_ccs,
  132. pline2lua = pline2lua,
  133. pstate_str = pstate_str,
  134. new_pstate = new_pstate,
  135. conv_cmp_type = conv_cmp_type,
  136. pstate_set_str = pstate_set_str,
  137. conv_expr_asgn_type = conv_expr_asgn_type,
  138. }