From b935a12dab17c3887db9c5fd7c90b34b2c51170f Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 29 Oct 2017 16:32:13 +0300 Subject: ex_getln: Make use of new parser to color expressions Retires g:Nvim_color_expr callback. --- test/functional/ui/cmdline_highlight_spec.lua | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'test/functional') diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua index d87ce72599..60a4a815e7 100644 --- a/test/functional/ui/cmdline_highlight_spec.lua +++ b/test/functional/ui/cmdline_highlight_spec.lua @@ -144,7 +144,9 @@ before_each(function() EOB={bold = true, foreground = Screen.colors.Blue1}, ERR={foreground = Screen.colors.Grey100, background = Screen.colors.Red}, SK={foreground = Screen.colors.Blue}, - PE={bold = true, foreground = Screen.colors.SeaGreen4} + PE={bold = true, foreground = Screen.colors.SeaGreen4}, + NUM={foreground = Screen.colors.Blue2}, + NPAR={foreground = Screen.colors.Yellow}, }) end) @@ -863,7 +865,10 @@ describe('Ex commands coloring support', function() end) describe('Expressions coloring support', function() it('works', function() - meths.set_var('Nvim_color_expr', 'RainBowParens') + meths.command('hi clear NVimNumber') + meths.command('hi clear NVimNestingParenthesis') + meths.command('hi NVimNumber guifg=Blue2') + meths.command('hi NVimNestingParenthesis guifg=Yellow') feed(':echo =(((1)))') screen:expect([[ | @@ -873,21 +878,24 @@ describe('Expressions coloring support', function() {EOB:~ }| {EOB:~ }| {EOB:~ }| - ={RBP1:(}{RBP2:(}{RBP3:(}1{RBP3:)}{RBP2:)}{RBP1:)}^ | + ={NPAR:(((}{NUM:1}{NPAR:)))}^ | ]]) end) - it('errors out when failing to get callback', function() + it('does not use Nvim_color_expr', function() meths.set_var('Nvim_color_expr', 42) + -- Used to error out due to failing to get callback. + meths.command('hi clear NVimNumber') + meths.command('hi NVimNumber guifg=Blue2') feed(':=1') screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| {EOB:~ }| {EOB:~ }| {EOB:~ }| - = | - {ERR:E5409: Unable to get g:Nvim_color_expr c}| - {ERR:allback: Vim:E6000: Argument is not a fu}| - {ERR:nction or function name} | - =1^ | + ={NUM:1}^ | ]]) end) end) -- cgit From 3ecb95298ffd9ef6ee681876f2d32553fd222b96 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 30 Oct 2017 01:48:32 +0300 Subject: tests: Fix testlint errors --- test/functional/ui/cmdline_highlight_spec.lua | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'test/functional') diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua index 60a4a815e7..b16b4a5602 100644 --- a/test/functional/ui/cmdline_highlight_spec.lua +++ b/test/functional/ui/cmdline_highlight_spec.lua @@ -898,4 +898,8 @@ describe('Expressions coloring support', function() ={NUM:1}^ | ]]) end) + -- FIXME: Test expr coloring when using -u NORC and -u NONE. + -- FIXME: Test all highlight groups, using long expression. + -- FIXME: Test different ways of triggering expression highlighting (:=, + -- i=, :e, "=). end) -- cgit From b9d5aea073521f3278bea257be306b7ac2b8d83c Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 3 Nov 2017 11:38:59 +0300 Subject: api/vim: Create part of nvim_parse_expression function --- test/functional/api/vim_spec.lua | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'test/functional') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index b849304d45..6b44698638 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -710,4 +710,9 @@ describe('api', function() ok(err:match(': Wrong type for argument 1, expecting String') ~= nil) end) + describe('nvim_parse_expression', function() + -- FIXME + -- FIXME Test error + end) + end) -- cgit From 7bc6de75263f58c6c4f999bc86a6454ae9f28b80 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 5 Nov 2017 02:41:44 +0300 Subject: api/vim,functests: Add tests for nvim_parse_expression, fix found bugs --- test/functional/api/vim_spec.lua | 6868 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 6868 insertions(+) (limited to 'test/functional') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 6b44698638..bb7785657d 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -1,5 +1,7 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') +local global_helpers = require('test.helpers') + local NIL = helpers.NIL local clear, nvim, eq, neq = helpers.clear, helpers.nvim, helpers.eq, helpers.neq local ok, nvim_async, feed = helpers.ok, helpers.nvim_async, helpers.feed @@ -10,6 +12,9 @@ local request = helpers.request local meth_pcall = helpers.meth_pcall local command = helpers.command +local intchar2lua = global_helpers.intchar2lua +local format_string = global_helpers.format_string + describe('api', function() before_each(clear) @@ -711,8 +716,6871 @@ describe('api', function() end) describe('nvim_parse_expression', function() + local function simplify_east_api_node(line, east_api_node) + if east_api_node.children then + for k, v in pairs(east_api_node.children) do + east_api_node.children[k] = simplify_east_api_node(line, v) + end + end + local typ = east_api_node.type + if typ == 'Register' then + typ = typ .. ('(name=%s)'):format( + tostring(intchar2lua(east_api_node.name))) + east_api_node.name = nil + elseif typ == 'PlainIdentifier' then + typ = typ .. ('(scope=%s,ident=%s)'):format( + tostring(intchar2lua(east_api_node.scope)), east_api_node.ident) + east_api_node.scope = nil + east_api_node.ident = nil + elseif typ == 'PlainKey' then + typ = typ .. ('(key=%s)'):format(east_api_node.ident) + east_api_node.ident = nil + elseif typ == 'Comparison' then + typ = typ .. ('(type=%s,inv=%u,ccs=%s)'):format( + east_api_node.cmp_type, east_api_node.invert and 1 or 0, + east_api_node.ccs_strategy) + east_api_node.ccs_strategy = nil + east_api_node.cmp_type = nil + east_api_node.invert = nil + elseif typ == 'Integer' then + typ = typ .. ('(val=%u)'):format(east_api_node.ivalue) + east_api_node.ivalue = nil + elseif typ == 'Float' then + typ = typ .. ('(val=%e)'):format(east_api_node.fvalue) + east_api_node.fvalue = nil + elseif typ == 'SingleQuotedString' or typ == 'DoubleQuotedString' then + typ = format_string('%s(val=%q)', typ, east_api_node.svalue) + east_api_node.svalue = nil + elseif typ == 'Option' then + typ = ('%s(scope=%s,ident=%s)'):format( + typ, + tostring(intchar2lua(east_api_node.scope)), + east_api_node.ident) + east_api_node.ident = nil + east_api_node.scope = nil + elseif typ == 'Environment' then + typ = ('%s(ident=%s)'):format(typ, east_api_node.ident) + east_api_node.ident = nil + end + typ = ('%s:%u:%u:%s'):format( + typ, east_api_node.start[1], east_api_node.start[2], + line:sub(east_api_node.start[2] + 1, + east_api_node.start[2] + 1 + east_api_node.len - 1)) + assert(east_api_node.start[2] + east_api_node.len - 1 <= #line) + for k, _ in pairs(east_api_node.start) do + assert(({true, true})[k]) + end + east_api_node.start = nil + east_api_node.type = nil + east_api_node.len = nil + local can_simplify = true + for _, _ in pairs(east_api_node) do + if can_simplify then can_simplify = false end + end + if can_simplify then + return typ + else + east_api_node[1] = typ + return east_api_node + end + end + local function simplify_east_api(line, east_api) + if east_api.error then + east_api.err = east_api.error + east_api.error = nil + east_api.err.msg = east_api.err.message + east_api.err.message = nil + end + if east_api.ast then + east_api.ast = {simplify_east_api_node(line, east_api.ast)} + end + return east_api + end + local function simplify_east_hl(line, east_hl) + for i, v in ipairs(east_hl) do + east_hl[i] = ('%s:%u:%u:%s'):format( + v[4], + v[1], + v[2], + line:sub(v[2] + 1, v[3])) + end + return east_hl + end + local function check_parsing(str, flags, exp_ast, exp_highlighting_fs) + if flags == 0 then + flags = "" + end + + local err, msg = pcall(function() + local east_api = meths.parse_expression(str, flags, true) + local east_hl = east_api.highlight + east_api.highlight = nil + local ast = simplify_east_api(str, east_api) + local hls = simplify_east_hl(str, east_hl) + eq(exp_ast, ast) + if exp_highlighting_fs then + local exp_highlighting = {} + local next_col = 0 + for i, h in ipairs(exp_highlighting_fs) do + exp_highlighting[i], next_col = h(next_col) + end + eq(exp_highlighting, hls) + end + end) + if not err then + msg = format_string('Error while processing test (%r, %s):\n%s', + str, flags, msg) + error(msg) + end + end + local function hl(group, str, shift) + return function(next_col) + local col = next_col + (shift or 0) + return (('%s:%u:%u:%s'):format( + 'NVim' .. group, + 0, + col, + str)), (col + #str) + end + end + it('works with + and @a', function() + check_parsing('@a', 0, { + ast = { + 'Register(name=a):0:0:@a', + }, + }, { + hl('Register', '@a'), + }) + check_parsing('+@a', 0, { + ast = { + { + 'UnaryPlus:0:0:+', + children = { + 'Register(name=a):0:1:@a', + }, + }, + }, + }, { + hl('UnaryPlus', '+'), + hl('Register', '@a'), + }) + check_parsing('@a+@b', 0, { + ast = { + { + 'BinaryPlus:0:2:+', + children = { + 'Register(name=a):0:0:@a', + 'Register(name=b):0:3:@b', + }, + }, + }, + }, { + hl('Register', '@a'), + hl('BinaryPlus', '+'), + hl('Register', '@b'), + }) + check_parsing('@a+@b+@c', 0, { + ast = { + { + 'BinaryPlus:0:5:+', + children = { + { + 'BinaryPlus:0:2:+', + children = { + 'Register(name=a):0:0:@a', + 'Register(name=b):0:3:@b', + }, + }, + 'Register(name=c):0:6:@c', + }, + }, + }, + }, { + hl('Register', '@a'), + hl('BinaryPlus', '+'), + hl('Register', '@b'), + hl('BinaryPlus', '+'), + hl('Register', '@c'), + }) + check_parsing('+@a+@b', 0, { + ast = { + { + 'BinaryPlus:0:3:+', + children = { + { + 'UnaryPlus:0:0:+', + children = { + 'Register(name=a):0:1:@a', + }, + }, + 'Register(name=b):0:4:@b', + }, + }, + }, + }, { + hl('UnaryPlus', '+'), + hl('Register', '@a'), + hl('BinaryPlus', '+'), + hl('Register', '@b'), + }) + check_parsing('+@a++@b', 0, { + ast = { + { + 'BinaryPlus:0:3:+', + children = { + { + 'UnaryPlus:0:0:+', + children = { + 'Register(name=a):0:1:@a', + }, + }, + { + 'UnaryPlus:0:4:+', + children = { + 'Register(name=b):0:5:@b', + }, + }, + }, + }, + }, + }, { + hl('UnaryPlus', '+'), + hl('Register', '@a'), + hl('BinaryPlus', '+'), + hl('UnaryPlus', '+'), + hl('Register', '@b'), + }) + check_parsing('@a@b', 0, { + ast = { + { + 'OpMissing:0:2:', + children = { + 'Register(name=a):0:0:@a', + 'Register(name=b):0:2:@b', + }, + }, + }, + err = { + arg = '@b', + msg = 'E15: Missing operator: %.*s', + }, + }, { + hl('Register', '@a'), + hl('InvalidRegister', '@b'), + }) + check_parsing(' @a \t @b', 0, { + ast = { + { + 'OpMissing:0:3:', + children = { + 'Register(name=a):0:0: @a', + 'Register(name=b):0:3: \t @b', + }, + }, + }, + err = { + arg = '@b', + msg = 'E15: Missing operator: %.*s', + }, + }, { + hl('Register', '@a', 1), + hl('InvalidSpacing', ' \t '), + hl('Register', '@b'), + }) + check_parsing('+', 0, { + ast = { + 'UnaryPlus:0:0:+', + }, + err = { + arg = '', + msg = 'E15: Expected value, got EOC: %.*s', + }, + }, { + hl('UnaryPlus', '+'), + }) + check_parsing(' +', 0, { + ast = { + 'UnaryPlus:0:0: +', + }, + err = { + arg = '', + msg = 'E15: Expected value, got EOC: %.*s', + }, + }, { + hl('UnaryPlus', '+', 1), + }) + check_parsing('@a+ ', 0, { + ast = { + { + 'BinaryPlus:0:2:+', + children = { + 'Register(name=a):0:0:@a', + }, + }, + }, + err = { + arg = '', + msg = 'E15: Expected value, got EOC: %.*s', + }, + }, { + hl('Register', '@a'), + hl('BinaryPlus', '+'), + }) + end) + it('works with @a, + and parenthesis', function() + check_parsing('(@a)', 0, { + ast = { + { + 'Nested:0:0:(', + children = { + 'Register(name=a):0:1:@a', + }, + }, + }, + }, { + hl('NestingParenthesis', '('), + hl('Register', '@a'), + hl('NestingParenthesis', ')'), + }) + check_parsing('()', 0, { + ast = { + { + 'Nested:0:0:(', + children = { + 'Missing:0:1:', + }, + }, + }, + err = { + arg = ')', + msg = 'E15: Expected value, got parenthesis: %.*s', + }, + }, { + hl('NestingParenthesis', '('), + hl('InvalidNestingParenthesis', ')'), + }) + check_parsing(')', 0, { + ast = { + { + 'Nested:0:0:', + children = { + 'Missing:0:0:', + }, + }, + }, + err = { + arg = ')', + msg = 'E15: Expected value, got parenthesis: %.*s', + }, + }, { + hl('InvalidNestingParenthesis', ')'), + }) + check_parsing('+)', 0, { + ast = { + { + 'Nested:0:1:', + children = { + { + 'UnaryPlus:0:0:+', + children = { + 'Missing:0:1:', + }, + }, + }, + }, + }, + err = { + arg = ')', + msg = 'E15: Expected value, got parenthesis: %.*s', + }, + }, { + hl('UnaryPlus', '+'), + hl('InvalidNestingParenthesis', ')'), + }) + check_parsing('+@a(@b)', 0, { + ast = { + { + 'UnaryPlus:0:0:+', + children = { + { + 'Call:0:3:(', + children = { + 'Register(name=a):0:1:@a', + 'Register(name=b):0:4:@b', + }, + }, + }, + }, + }, + }, { + hl('UnaryPlus', '+'), + hl('Register', '@a'), + hl('CallingParenthesis', '('), + hl('Register', '@b'), + hl('CallingParenthesis', ')'), + }) + check_parsing('@a+@b(@c)', 0, { + ast = { + { + 'BinaryPlus:0:2:+', + children = { + 'Register(name=a):0:0:@a', + { + 'Call:0:5:(', + children = { + 'Register(name=b):0:3:@b', + 'Register(name=c):0:6:@c', + }, + }, + }, + }, + }, + }, { + hl('Register', '@a'), + hl('BinaryPlus', '+'), + hl('Register', '@b'), + hl('CallingParenthesis', '('), + hl('Register', '@c'), + hl('CallingParenthesis', ')'), + }) + check_parsing('@a()', 0, { + ast = { + { + 'Call:0:2:(', + children = { + 'Register(name=a):0:0:@a', + }, + }, + }, + }, { + hl('Register', '@a'), + hl('CallingParenthesis', '('), + hl('CallingParenthesis', ')'), + }) + check_parsing('@a ()', 0, { + ast = { + { + 'OpMissing:0:2:', + children = { + 'Register(name=a):0:0:@a', + { + 'Nested:0:2: (', + children = { + 'Missing:0:4:', + }, + }, + }, + }, + }, + err = { + arg = '()', + msg = 'E15: Missing operator: %.*s', + }, + }, { + hl('Register', '@a'), + hl('InvalidSpacing', ' '), + hl('NestingParenthesis', '('), + hl('InvalidNestingParenthesis', ')'), + }) + check_parsing( + '@a + (@b)', 0, { + ast = { + { + 'BinaryPlus:0:2: +', + children = { + 'Register(name=a):0:0:@a', + { + 'Nested:0:4: (', + children = { + 'Register(name=b):0:6:@b', + }, + }, + }, + }, + }, + }, { + hl('Register', '@a'), + hl('BinaryPlus', '+', 1), + hl('NestingParenthesis', '(', 1), + hl('Register', '@b'), + hl('NestingParenthesis', ')'), + }) + check_parsing( + '@a + (+@b)', 0, { + ast = { + { + 'BinaryPlus:0:2: +', + children = { + 'Register(name=a):0:0:@a', + { + 'Nested:0:4: (', + children = { + { + 'UnaryPlus:0:6:+', + children = { + 'Register(name=b):0:7:@b', + }, + }, + }, + }, + }, + }, + }, + }, { + hl('Register', '@a'), + hl('BinaryPlus', '+', 1), + hl('NestingParenthesis', '(', 1), + hl('UnaryPlus', '+'), + hl('Register', '@b'), + hl('NestingParenthesis', ')'), + }) + check_parsing( + '@a + (@b + @c)', 0, { + ast = { + { + 'BinaryPlus:0:2: +', + children = { + 'Register(name=a):0:0:@a', + { + 'Nested:0:4: (', + children = { + { + 'BinaryPlus:0:8: +', + children = { + 'Register(name=b):0:6:@b', + 'Register(name=c):0:10: @c', + }, + }, + }, + }, + }, + }, + }, + }, { + hl('Register', '@a'), + hl('BinaryPlus', '+', 1), + hl('NestingParenthesis', '(', 1), + hl('Register', '@b'), + hl('BinaryPlus', '+', 1), + hl('Register', '@c', 1), + hl('NestingParenthesis', ')'), + }) + check_parsing('(@a)+@b', 0, { + ast = { + { + 'BinaryPlus:0:4:+', + children = { + { + 'Nested:0:0:(', + children = { + 'Register(name=a):0:1:@a', + }, + }, + 'Register(name=b):0:5:@b', + }, + }, + }, + }, { + hl('NestingParenthesis', '('), + hl('Register', '@a'), + hl('NestingParenthesis', ')'), + hl('BinaryPlus', '+'), + hl('Register', '@b'), + }) + check_parsing('@a+(@b)(@c)', 0, { + -- 01234567890 + ast = { + { + 'BinaryPlus:0:2:+', + children = { + 'Register(name=a):0:0:@a', + { + 'Call:0:7:(', + children = { + { + 'Nested:0:3:(', + children = { 'Register(name=b):0:4:@b' }, + }, + 'Register(name=c):0:8:@c', + }, + }, + }, + }, + }, + }, { + hl('Register', '@a'), + hl('BinaryPlus', '+'), + hl('NestingParenthesis', '('), + hl('Register', '@b'), + hl('NestingParenthesis', ')'), + hl('CallingParenthesis', '('), + hl('Register', '@c'), + hl('CallingParenthesis', ')'), + }) + check_parsing('@a+((@b))(@c)', 0, { + -- 01234567890123456890123456789 + -- 0 1 2 + ast = { + { + 'BinaryPlus:0:2:+', + children = { + 'Register(name=a):0:0:@a', + { + 'Call:0:9:(', + children = { + { + 'Nested:0:3:(', + children = { + { + 'Nested:0:4:(', + children = { 'Register(name=b):0:5:@b' } + }, + }, + }, + 'Register(name=c):0:10:@c', + }, + }, + }, + }, + }, + }, { + hl('Register', '@a'), + hl('BinaryPlus', '+'), + hl('NestingParenthesis', '('), + hl('NestingParenthesis', '('), + hl('Register', '@b'), + hl('NestingParenthesis', ')'), + hl('NestingParenthesis', ')'), + hl('CallingParenthesis', '('), + hl('Register', '@c'), + hl('CallingParenthesis', ')'), + }) + check_parsing('@a+((@b))+@c', 0, { + -- 01234567890123456890123456789 + -- 0 1 2 + ast = { + { + 'BinaryPlus:0:9:+', + children = { + { + 'BinaryPlus:0:2:+', + children = { + 'Register(name=a):0:0:@a', + { + 'Nested:0:3:(', + children = { + { + 'Nested:0:4:(', + children = { 'Register(name=b):0:5:@b' } + }, + }, + }, + }, + }, + 'Register(name=c):0:10:@c', + }, + }, + }, + }, { + hl('Register', '@a'), + hl('BinaryPlus', '+'), + hl('NestingParenthesis', '('), + hl('NestingParenthesis', '('), + hl('Register', '@b'), + hl('NestingParenthesis', ')'), + hl('NestingParenthesis', ')'), + hl('BinaryPlus', '+'), + hl('Register', '@c'), + }) + check_parsing( + '@a + (@b + @c) + @d(@e) + (+@f) + ((+@g(@h))(@j)(@k))(@l)', 0, {--[[ + | | | | | | | | || | | || | | ||| || || || || + 000000000011111111112222222222333333333344444444445555555 + 012345678901234567890123456789012345678901234567890123456 + ]] + ast = {{ + 'BinaryPlus:0:31: +', + children = { + { + 'BinaryPlus:0:23: +', + children = { + { + 'BinaryPlus:0:14: +', + children = { + { + 'BinaryPlus:0:2: +', + children = { + 'Register(name=a):0:0:@a', + { + 'Nested:0:4: (', + children = { + { + 'BinaryPlus:0:8: +', + children = { + 'Register(name=b):0:6:@b', + 'Register(name=c):0:10: @c', + }, + }, + }, + }, + }, + }, + { + 'Call:0:19:(', + children = { + 'Register(name=d):0:16: @d', + 'Register(name=e):0:20:@e', + }, + }, + }, + }, + { + 'Nested:0:25: (', + children = { + { + 'UnaryPlus:0:27:+', + children = { + 'Register(name=f):0:28:@f', + }, + }, + }, + }, + }, + }, + { + 'Call:0:53:(', + children = { + { + 'Nested:0:33: (', + children = { + { + 'Call:0:48:(', + children = { + { + 'Call:0:44:(', + children = { + { + 'Nested:0:35:(', + children = { + { + 'UnaryPlus:0:36:+', + children = { + { + 'Call:0:39:(', + children = { + 'Register(name=g):0:37:@g', + 'Register(name=h):0:40:@h', + }, + }, + }, + }, + }, + }, + 'Register(name=j):0:45:@j', + }, + }, + 'Register(name=k):0:49:@k', + }, + }, + }, + }, + 'Register(name=l):0:54:@l', + }, + }, + }, + }}, + }, { + hl('Register', '@a'), + hl('BinaryPlus', '+', 1), + hl('NestingParenthesis', '(', 1), + hl('Register', '@b'), + hl('BinaryPlus', '+', 1), + hl('Register', '@c', 1), + hl('NestingParenthesis', ')'), + hl('BinaryPlus', '+', 1), + hl('Register', '@d', 1), + hl('CallingParenthesis', '('), + hl('Register', '@e'), + hl('CallingParenthesis', ')'), + hl('BinaryPlus', '+', 1), + hl('NestingParenthesis', '(', 1), + hl('UnaryPlus', '+'), + hl('Register', '@f'), + hl('NestingParenthesis', ')'), + hl('BinaryPlus', '+', 1), + hl('NestingParenthesis', '(', 1), + hl('NestingParenthesis', '('), + hl('UnaryPlus', '+'), + hl('Register', '@g'), + hl('CallingParenthesis', '('), + hl('Register', '@h'), + hl('CallingParenthesis', ')'), + hl('NestingParenthesis', ')'), + hl('CallingParenthesis', '('), + hl('Register', '@j'), + hl('CallingParenthesis', ')'), + hl('CallingParenthesis', '('), + hl('Register', '@k'), + hl('CallingParenthesis', ')'), + hl('NestingParenthesis', ')'), + hl('CallingParenthesis', '('), + hl('Register', '@l'), + hl('CallingParenthesis', ')'), + }) + check_parsing('@a)', 0, { + -- 012 + ast = { + { + 'Nested:0:2:', + children = { + 'Register(name=a):0:0:@a', + }, + }, + }, + err = { + arg = ')', + msg = 'E15: Unexpected closing parenthesis: %.*s', + }, + }, { + hl('Register', '@a'), + hl('InvalidNestingParenthesis', ')'), + }) + check_parsing('(@a', 0, { + -- 012 + ast = { + { + 'Nested:0:0:(', + children = { + 'Register(name=a):0:1:@a', + }, + }, + }, + err = { + arg = '(@a', + msg = 'E110: Missing closing parenthesis for nested expression: %.*s', + }, + }, { + hl('NestingParenthesis', '('), + hl('Register', '@a'), + }) + check_parsing('@a(@b', 0, { + -- 01234 + ast = { + { + 'Call:0:2:(', + children = { + 'Register(name=a):0:0:@a', + 'Register(name=b):0:3:@b', + }, + }, + }, + err = { + arg = '(@b', + msg = 'E116: Missing closing parenthesis for function call: %.*s', + }, + }, { + hl('Register', '@a'), + hl('CallingParenthesis', '('), + hl('Register', '@b'), + }) + check_parsing('@a(@b, @c, @d, @e)', 0, { + -- 012345678901234567 + -- 0 1 + ast = { + { + 'Call:0:2:(', + children = { + 'Register(name=a):0:0:@a', + { + 'Comma:0:5:,', + children = { + 'Register(name=b):0:3:@b', + { + 'Comma:0:9:,', + children = { + 'Register(name=c):0:6: @c', + { + 'Comma:0:13:,', + children = { + 'Register(name=d):0:10: @d', + 'Register(name=e):0:14: @e', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, { + hl('Register', '@a'), + hl('CallingParenthesis', '('), + hl('Register', '@b'), + hl('Comma', ','), + hl('Register', '@c', 1), + hl('Comma', ','), + hl('Register', '@d', 1), + hl('Comma', ','), + hl('Register', '@e', 1), + hl('CallingParenthesis', ')'), + }) + check_parsing('@a(@b(@c))', 0, { + -- 01234567890123456789012345678901234567 + -- 0 1 2 3 + ast = { + { + 'Call:0:2:(', + children = { + 'Register(name=a):0:0:@a', + { + 'Call:0:5:(', + children = { + 'Register(name=b):0:3:@b', + 'Register(name=c):0:6:@c', + }, + }, + }, + }, + }, + }, { + hl('Register', '@a'), + hl('CallingParenthesis', '('), + hl('Register', '@b'), + hl('CallingParenthesis', '('), + hl('Register', '@c'), + hl('CallingParenthesis', ')'), + hl('CallingParenthesis', ')'), + }) + check_parsing('@a(@b(@c(@d(@e), @f(@g(@h), @i(@j)))))', 0, { + -- 01234567890123456789012345678901234567 + -- 0 1 2 3 + ast = { + { + 'Call:0:2:(', + children = { + 'Register(name=a):0:0:@a', + { + 'Call:0:5:(', + children = { + 'Register(name=b):0:3:@b', + { + 'Call:0:8:(', + children = { + 'Register(name=c):0:6:@c', + { + 'Comma:0:15:,', + children = { + { + 'Call:0:11:(', + children = { + 'Register(name=d):0:9:@d', + 'Register(name=e):0:12:@e', + }, + }, + { + 'Call:0:19:(', + children = { + 'Register(name=f):0:16: @f', + { + 'Comma:0:26:,', + children = { + { + 'Call:0:22:(', + children = { + 'Register(name=g):0:20:@g', + 'Register(name=h):0:23:@h', + }, + }, + { + 'Call:0:30:(', + children = { + 'Register(name=i):0:27: @i', + 'Register(name=j):0:31:@j', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, { + hl('Register', '@a'), + hl('CallingParenthesis', '('), + hl('Register', '@b'), + hl('CallingParenthesis', '('), + hl('Register', '@c'), + hl('CallingParenthesis', '('), + hl('Register', '@d'), + hl('CallingParenthesis', '('), + hl('Register', '@e'), + hl('CallingParenthesis', ')'), + hl('Comma', ','), + hl('Register', '@f', 1), + hl('CallingParenthesis', '('), + hl('Register', '@g'), + hl('CallingParenthesis', '('), + hl('Register', '@h'), + hl('CallingParenthesis', ')'), + hl('Comma', ','), + hl('Register', '@i', 1), + hl('CallingParenthesis', '('), + hl('Register', '@j'), + hl('CallingParenthesis', ')'), + hl('CallingParenthesis', ')'), + hl('CallingParenthesis', ')'), + hl('CallingParenthesis', ')'), + hl('CallingParenthesis', ')'), + }) + end) + it('works with variable names, including curly braces ones', function() + check_parsing('var', 0, { + ast = { + 'PlainIdentifier(scope=0,ident=var):0:0:var', + }, + }, { + hl('IdentifierName', 'var'), + }) + check_parsing('g:var', 0, { + ast = { + 'PlainIdentifier(scope=g,ident=var):0:0:g:var', + }, + }, { + hl('IdentifierScope', 'g'), + hl('IdentifierScopeDelimiter', ':'), + hl('IdentifierName', 'var'), + }) + check_parsing('g:', 0, { + ast = { + 'PlainIdentifier(scope=g,ident=):0:0:g:', + }, + }, { + hl('IdentifierScope', 'g'), + hl('IdentifierScopeDelimiter', ':'), + }) + check_parsing('{a}', 0, { + -- 012 + ast = { + { + 'CurlyBracesIdentifier:0:0:{', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + }, + }, + }, + }, { + hl('Curly', '{'), + hl('IdentifierName', 'a'), + hl('Curly', '}'), + }) + check_parsing('{a:b}', 0, { + -- 012 + ast = { + { + 'CurlyBracesIdentifier:0:0:{', + children = { + 'PlainIdentifier(scope=a,ident=b):0:1:a:b', + }, + }, + }, + }, { + hl('Curly', '{'), + hl('IdentifierScope', 'a'), + hl('IdentifierScopeDelimiter', ':'), + hl('IdentifierName', 'b'), + hl('Curly', '}'), + }) + check_parsing('{a:@b}', 0, { + -- 012345 + ast = { + { + 'CurlyBracesIdentifier:0:0:{', + children = { + { + 'OpMissing:0:3:', + children={ + 'PlainIdentifier(scope=a,ident=):0:1:a:', + 'Register(name=b):0:3:@b', + }, + }, + }, + }, + }, + err = { + arg = '@b}', + msg = 'E15: Missing operator: %.*s', + }, + }, { + hl('Curly', '{'), + hl('IdentifierScope', 'a'), + hl('IdentifierScopeDelimiter', ':'), + hl('InvalidRegister', '@b'), + hl('Curly', '}'), + }) + check_parsing('{@a}', 0, { + ast = { + { + 'CurlyBracesIdentifier:0:0:{', + children = { + 'Register(name=a):0:1:@a', + }, + }, + }, + }, { + hl('Curly', '{'), + hl('Register', '@a'), + hl('Curly', '}'), + }) + check_parsing('{@a}{@b}', 0, { + -- 01234567 + ast = { + { + 'ComplexIdentifier:0:4:', + children = { + { + 'CurlyBracesIdentifier:0:0:{', + children = { + 'Register(name=a):0:1:@a', + }, + }, + { + 'CurlyBracesIdentifier:0:4:{', + children = { + 'Register(name=b):0:5:@b', + }, + }, + }, + }, + }, + }, { + hl('Curly', '{'), + hl('Register', '@a'), + hl('Curly', '}'), + hl('Curly', '{'), + hl('Register', '@b'), + hl('Curly', '}'), + }) + check_parsing('g:{@a}', 0, { + -- 01234567 + ast = { + { + 'ComplexIdentifier:0:2:', + children = { + 'PlainIdentifier(scope=g,ident=):0:0:g:', + { + 'CurlyBracesIdentifier:0:2:{', + children = { + 'Register(name=a):0:3:@a', + }, + }, + }, + }, + }, + }, { + hl('IdentifierScope', 'g'), + hl('IdentifierScopeDelimiter', ':'), + hl('Curly', '{'), + hl('Register', '@a'), + hl('Curly', '}'), + }) + check_parsing('{@a}_test', 0, { + -- 012345678 + ast = { + { + 'ComplexIdentifier:0:4:', + children = { + { + 'CurlyBracesIdentifier:0:0:{', + children = { + 'Register(name=a):0:1:@a', + }, + }, + 'PlainIdentifier(scope=0,ident=_test):0:4:_test', + }, + }, + }, + }, { + hl('Curly', '{'), + hl('Register', '@a'), + hl('Curly', '}'), + hl('IdentifierName', '_test'), + }) + check_parsing('g:{@a}_test', 0, { + -- 01234567890 + ast = { + { + 'ComplexIdentifier:0:2:', + children = { + 'PlainIdentifier(scope=g,ident=):0:0:g:', + { + 'ComplexIdentifier:0:6:', + children = { + { + 'CurlyBracesIdentifier:0:2:{', + children = { + 'Register(name=a):0:3:@a', + }, + }, + 'PlainIdentifier(scope=0,ident=_test):0:6:_test', + }, + }, + }, + }, + }, + }, { + hl('IdentifierScope', 'g'), + hl('IdentifierScopeDelimiter', ':'), + hl('Curly', '{'), + hl('Register', '@a'), + hl('Curly', '}'), + hl('IdentifierName', '_test'), + }) + check_parsing('g:{@a}_test()', 0, { + -- 0123456789012 + ast = { + { + 'Call:0:11:(', + children = { + { + 'ComplexIdentifier:0:2:', + children = { + 'PlainIdentifier(scope=g,ident=):0:0:g:', + { + 'ComplexIdentifier:0:6:', + children = { + { + 'CurlyBracesIdentifier:0:2:{', + children = { + 'Register(name=a):0:3:@a', + }, + }, + 'PlainIdentifier(scope=0,ident=_test):0:6:_test', + }, + }, + }, + }, + }, + }, + }, + }, { + hl('IdentifierScope', 'g'), + hl('IdentifierScopeDelimiter', ':'), + hl('Curly', '{'), + hl('Register', '@a'), + hl('Curly', '}'), + hl('IdentifierName', '_test'), + hl('CallingParenthesis', '('), + hl('CallingParenthesis', ')'), + }) + check_parsing('{@a} ()', 0, { + -- 0123456789012 + ast = { + { + 'Call:0:4: (', + children = { + { + 'CurlyBracesIdentifier:0:0:{', + children = { + 'Register(name=a):0:1:@a', + }, + }, + }, + }, + }, + }, { + hl('Curly', '{'), + hl('Register', '@a'), + hl('Curly', '}'), + hl('CallingParenthesis', '(', 1), + hl('CallingParenthesis', ')'), + }) + check_parsing('g:{@a} ()', 0, { + -- 0123456789012 + ast = { + { + 'Call:0:6: (', + children = { + { + 'ComplexIdentifier:0:2:', + children = { + 'PlainIdentifier(scope=g,ident=):0:0:g:', + { + 'CurlyBracesIdentifier:0:2:{', + children = { + 'Register(name=a):0:3:@a', + }, + }, + }, + }, + }, + }, + }, + }, { + hl('IdentifierScope', 'g'), + hl('IdentifierScopeDelimiter', ':'), + hl('Curly', '{'), + hl('Register', '@a'), + hl('Curly', '}'), + hl('CallingParenthesis', '(', 1), + hl('CallingParenthesis', ')'), + }) + check_parsing('{@a', 0, { + -- 012 + ast = { + { + 'UnknownFigure:0:0:{', + children = { + 'Register(name=a):0:1:@a', + }, + }, + }, + err = { + arg = '{@a', + msg = 'E15: Missing closing figure brace: %.*s', + }, + }, { + hl('FigureBrace', '{'), + hl('Register', '@a'), + }) + end) + it('works with lambdas and dictionaries', function() + check_parsing('{}', 0, { + ast = { + 'DictLiteral:0:0:{', + }, + }, { + hl('Dict', '{'), + hl('Dict', '}'), + }) + check_parsing('{->@a}', 0, { + ast = { + { + 'Lambda:0:0:{', + children = { + { + 'Arrow:0:1:->', + children = { + 'Register(name=a):0:3:@a', + }, + }, + }, + }, + }, + }, { + hl('Lambda', '{'), + hl('Arrow', '->'), + hl('Register', '@a'), + hl('Lambda', '}'), + }) + check_parsing('{->@a+@b}', 0, { + -- 012345678 + ast = { + { + 'Lambda:0:0:{', + children = { + { + 'Arrow:0:1:->', + children = { + { + 'BinaryPlus:0:5:+', + children = { + 'Register(name=a):0:3:@a', + 'Register(name=b):0:6:@b', + }, + }, + }, + }, + }, + }, + }, + }, { + hl('Lambda', '{'), + hl('Arrow', '->'), + hl('Register', '@a'), + hl('BinaryPlus', '+'), + hl('Register', '@b'), + hl('Lambda', '}'), + }) + check_parsing('{a->@a}', 0, { + -- 012345678 + ast = { + { + 'Lambda:0:0:{', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + { + 'Arrow:0:2:->', + children = { + 'Register(name=a):0:4:@a', + }, + }, + }, + }, + }, + }, { + hl('Lambda', '{'), + hl('IdentifierName', 'a'), + hl('Arrow', '->'), + hl('Register', '@a'), + hl('Lambda', '}'), + }) + check_parsing('{a,b->@a}', 0, { + -- 012345678 + ast = { + { + 'Lambda:0:0:{', + children = { + { + 'Comma:0:2:,', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + 'PlainIdentifier(scope=0,ident=b):0:3:b', + }, + }, + { + 'Arrow:0:4:->', + children = { + 'Register(name=a):0:6:@a', + }, + }, + }, + }, + }, + }, { + hl('Lambda', '{'), + hl('IdentifierName', 'a'), + hl('Comma', ','), + hl('IdentifierName', 'b'), + hl('Arrow', '->'), + hl('Register', '@a'), + hl('Lambda', '}'), + }) + check_parsing('{a,b,c->@a}', 0, { + -- 01234567890 + ast = { + { + 'Lambda:0:0:{', + children = { + { + 'Comma:0:2:,', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + { + 'Comma:0:4:,', + children = { + 'PlainIdentifier(scope=0,ident=b):0:3:b', + 'PlainIdentifier(scope=0,ident=c):0:5:c', + }, + }, + }, + }, + { + 'Arrow:0:6:->', + children = { + 'Register(name=a):0:8:@a', + }, + }, + }, + }, + }, + }, { + hl('Lambda', '{'), + hl('IdentifierName', 'a'), + hl('Comma', ','), + hl('IdentifierName', 'b'), + hl('Comma', ','), + hl('IdentifierName', 'c'), + hl('Arrow', '->'), + hl('Register', '@a'), + hl('Lambda', '}'), + }) + check_parsing('{a,b,c,d->@a}', 0, { + -- 0123456789012 + ast = { + { + 'Lambda:0:0:{', + children = { + { + 'Comma:0:2:,', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + { + 'Comma:0:4:,', + children = { + 'PlainIdentifier(scope=0,ident=b):0:3:b', + { + 'Comma:0:6:,', + children = { + 'PlainIdentifier(scope=0,ident=c):0:5:c', + 'PlainIdentifier(scope=0,ident=d):0:7:d', + }, + }, + }, + }, + }, + }, + { + 'Arrow:0:8:->', + children = { + 'Register(name=a):0:10:@a', + }, + }, + }, + }, + }, + }, { + hl('Lambda', '{'), + hl('IdentifierName', 'a'), + hl('Comma', ','), + hl('IdentifierName', 'b'), + hl('Comma', ','), + hl('IdentifierName', 'c'), + hl('Comma', ','), + hl('IdentifierName', 'd'), + hl('Arrow', '->'), + hl('Register', '@a'), + hl('Lambda', '}'), + }) + check_parsing('{a,b,c,d,->@a}', 0, { + -- 01234567890123 + ast = { + { + 'Lambda:0:0:{', + children = { + { + 'Comma:0:2:,', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + { + 'Comma:0:4:,', + children = { + 'PlainIdentifier(scope=0,ident=b):0:3:b', + { + 'Comma:0:6:,', + children = { + 'PlainIdentifier(scope=0,ident=c):0:5:c', + { + 'Comma:0:8:,', + children = { + 'PlainIdentifier(scope=0,ident=d):0:7:d', + }, + }, + }, + }, + }, + }, + }, + }, + { + 'Arrow:0:9:->', + children = { + 'Register(name=a):0:11:@a', + }, + }, + }, + }, + }, + }, { + hl('Lambda', '{'), + hl('IdentifierName', 'a'), + hl('Comma', ','), + hl('IdentifierName', 'b'), + hl('Comma', ','), + hl('IdentifierName', 'c'), + hl('Comma', ','), + hl('IdentifierName', 'd'), + hl('Comma', ','), + hl('Arrow', '->'), + hl('Register', '@a'), + hl('Lambda', '}'), + }) + check_parsing('{a,b->{c,d->{e,f->@a}}}', 0, { + -- 01234567890123456789012 + -- 0 1 2 + ast = { + { + 'Lambda:0:0:{', + children = { + { + 'Comma:0:2:,', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + 'PlainIdentifier(scope=0,ident=b):0:3:b', + }, + }, + { + 'Arrow:0:4:->', + children = { + { + 'Lambda:0:6:{', + children = { + { + 'Comma:0:8:,', + children = { + 'PlainIdentifier(scope=0,ident=c):0:7:c', + 'PlainIdentifier(scope=0,ident=d):0:9:d', + }, + }, + { + 'Arrow:0:10:->', + children = { + { + 'Lambda:0:12:{', + children = { + { + 'Comma:0:14:,', + children = { + 'PlainIdentifier(scope=0,ident=e):0:13:e', + 'PlainIdentifier(scope=0,ident=f):0:15:f', + }, + }, + { + 'Arrow:0:16:->', + children = { + 'Register(name=a):0:18:@a', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, { + hl('Lambda', '{'), + hl('IdentifierName', 'a'), + hl('Comma', ','), + hl('IdentifierName', 'b'), + hl('Arrow', '->'), + hl('Lambda', '{'), + hl('IdentifierName', 'c'), + hl('Comma', ','), + hl('IdentifierName', 'd'), + hl('Arrow', '->'), + hl('Lambda', '{'), + hl('IdentifierName', 'e'), + hl('Comma', ','), + hl('IdentifierName', 'f'), + hl('Arrow', '->'), + hl('Register', '@a'), + hl('Lambda', '}'), + hl('Lambda', '}'), + hl('Lambda', '}'), + }) + check_parsing('{a,b->c,d}', 0, { + -- 0123456789 + ast = { + { + 'Lambda:0:0:{', + children = { + { + 'Comma:0:2:,', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + 'PlainIdentifier(scope=0,ident=b):0:3:b', + }, + }, + { + 'Arrow:0:4:->', + children = { + { + 'Comma:0:7:,', + children = { + 'PlainIdentifier(scope=0,ident=c):0:6:c', + 'PlainIdentifier(scope=0,ident=d):0:8:d', + }, + }, + }, + }, + }, + }, + }, + err = { + arg = ',d}', + msg = 'E15: Comma outside of call, lambda or literal: %.*s', + }, + }, { + hl('Lambda', '{'), + hl('IdentifierName', 'a'), + hl('Comma', ','), + hl('IdentifierName', 'b'), + hl('Arrow', '->'), + hl('IdentifierName', 'c'), + hl('InvalidComma', ','), + hl('IdentifierName', 'd'), + hl('Lambda', '}'), + }) + check_parsing('a,b,c,d', 0, { + -- 0123456789 + ast = { + { + 'Comma:0:1:,', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + { + 'Comma:0:3:,', + children = { + 'PlainIdentifier(scope=0,ident=b):0:2:b', + { + 'Comma:0:5:,', + children = { + 'PlainIdentifier(scope=0,ident=c):0:4:c', + 'PlainIdentifier(scope=0,ident=d):0:6:d', + }, + }, + }, + }, + }, + }, + }, + err = { + arg = ',b,c,d', + msg = 'E15: Comma outside of call, lambda or literal: %.*s', + }, + }, { + hl('IdentifierName', 'a'), + hl('InvalidComma', ','), + hl('IdentifierName', 'b'), + hl('InvalidComma', ','), + hl('IdentifierName', 'c'), + hl('InvalidComma', ','), + hl('IdentifierName', 'd'), + }) + check_parsing('a,b,c,d,', 0, { + -- 0123456789 + ast = { + { + 'Comma:0:1:,', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + { + 'Comma:0:3:,', + children = { + 'PlainIdentifier(scope=0,ident=b):0:2:b', + { + 'Comma:0:5:,', + children = { + 'PlainIdentifier(scope=0,ident=c):0:4:c', + { + 'Comma:0:7:,', + children = { + 'PlainIdentifier(scope=0,ident=d):0:6:d', + }, + }, + }, + }, + }, + }, + }, + }, + }, + err = { + arg = ',b,c,d,', + msg = 'E15: Comma outside of call, lambda or literal: %.*s', + }, + }, { + hl('IdentifierName', 'a'), + hl('InvalidComma', ','), + hl('IdentifierName', 'b'), + hl('InvalidComma', ','), + hl('IdentifierName', 'c'), + hl('InvalidComma', ','), + hl('IdentifierName', 'd'), + hl('InvalidComma', ','), + }) + check_parsing(',', 0, { + -- 0123456789 + ast = { + { + 'Comma:0:0:,', + children = { + 'Missing:0:0:', + }, + }, + }, + err = { + arg = ',', + msg = 'E15: Expected value, got comma: %.*s', + }, + }, { + hl('InvalidComma', ','), + }) + check_parsing('{,a->@a}', 0, { + -- 0123456789 + ast = { + { + 'CurlyBracesIdentifier:0:0:{', + children = { + { + 'Arrow:0:3:->', + children = { + { + 'Comma:0:1:,', + children = { + 'Missing:0:1:', + 'PlainIdentifier(scope=0,ident=a):0:2:a', + }, + }, + 'Register(name=a):0:5:@a', + }, + }, + }, + }, + }, + err = { + arg = ',a->@a}', + msg = 'E15: Expected value, got comma: %.*s', + }, + }, { + hl('Curly', '{'), + hl('InvalidComma', ','), + hl('IdentifierName', 'a'), + hl('InvalidArrow', '->'), + hl('Register', '@a'), + hl('Curly', '}'), + }) + check_parsing('}', 0, { + -- 0123456789 + ast = { + 'UnknownFigure:0:0:', + }, + err = { + arg = '}', + msg = 'E15: Unexpected closing figure brace: %.*s', + }, + }, { + hl('InvalidFigureBrace', '}'), + }) + check_parsing('{->}', 0, { + -- 0123456789 + ast = { + { + 'Lambda:0:0:{', + children = { + 'Arrow:0:1:->', + }, + }, + }, + err = { + arg = '}', + msg = 'E15: Expected value, got closing figure brace: %.*s', + }, + }, { + hl('Lambda', '{'), + hl('Arrow', '->'), + hl('InvalidLambda', '}'), + }) + check_parsing('{a,b}', 0, { + -- 0123456789 + ast = { + { + 'Lambda:0:0:{', + children = { + { + 'Comma:0:2:,', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + 'PlainIdentifier(scope=0,ident=b):0:3:b', + }, + }, + }, + }, + }, + err = { + arg = '}', + msg = 'E15: Expected lambda arguments list or arrow: %.*s', + }, + }, { + hl('Lambda', '{'), + hl('IdentifierName', 'a'), + hl('Comma', ','), + hl('IdentifierName', 'b'), + hl('InvalidLambda', '}'), + }) + check_parsing('{a,}', 0, { + -- 0123456789 + ast = { + { + 'Lambda:0:0:{', + children = { + { + 'Comma:0:2:,', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + }, + }, + }, + }, + }, + err = { + arg = '}', + msg = 'E15: Expected lambda arguments list or arrow: %.*s', + }, + }, { + hl('Lambda', '{'), + hl('IdentifierName', 'a'), + hl('Comma', ','), + hl('InvalidLambda', '}'), + }) + check_parsing('{@a:@b}', 0, { + -- 0123456789 + ast = { + { + 'DictLiteral:0:0:{', + children = { + { + 'Colon:0:3::', + children = { + 'Register(name=a):0:1:@a', + 'Register(name=b):0:4:@b', + }, + }, + }, + }, + }, + }, { + hl('Dict', '{'), + hl('Register', '@a'), + hl('Colon', ':'), + hl('Register', '@b'), + hl('Dict', '}'), + }) + check_parsing('{@a:@b,@c:@d}', 0, { + -- 0123456789012 + -- 0 1 + ast = { + { + 'DictLiteral:0:0:{', + children = { + { + 'Comma:0:6:,', + children = { + { + 'Colon:0:3::', + children = { + 'Register(name=a):0:1:@a', + 'Register(name=b):0:4:@b', + }, + }, + { + 'Colon:0:9::', + children = { + 'Register(name=c):0:7:@c', + 'Register(name=d):0:10:@d', + }, + }, + }, + }, + }, + }, + }, + }, { + hl('Dict', '{'), + hl('Register', '@a'), + hl('Colon', ':'), + hl('Register', '@b'), + hl('Comma', ','), + hl('Register', '@c'), + hl('Colon', ':'), + hl('Register', '@d'), + hl('Dict', '}'), + }) + check_parsing('{@a:@b,@c:@d,@e:@f,}', 0, { + -- 01234567890123456789 + -- 0 1 + ast = { + { + 'DictLiteral:0:0:{', + children = { + { + 'Comma:0:6:,', + children = { + { + 'Colon:0:3::', + children = { + 'Register(name=a):0:1:@a', + 'Register(name=b):0:4:@b', + }, + }, + { + 'Comma:0:12:,', + children = { + { + 'Colon:0:9::', + children = { + 'Register(name=c):0:7:@c', + 'Register(name=d):0:10:@d', + }, + }, + { + 'Comma:0:18:,', + children = { + { + 'Colon:0:15::', + children = { + 'Register(name=e):0:13:@e', + 'Register(name=f):0:16:@f', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, { + hl('Dict', '{'), + hl('Register', '@a'), + hl('Colon', ':'), + hl('Register', '@b'), + hl('Comma', ','), + hl('Register', '@c'), + hl('Colon', ':'), + hl('Register', '@d'), + hl('Comma', ','), + hl('Register', '@e'), + hl('Colon', ':'), + hl('Register', '@f'), + hl('Comma', ','), + hl('Dict', '}'), + }) + check_parsing('{@a:@b,@c:@d,@e:@f,@g:}', 0, { + -- 01234567890123456789012 + -- 0 1 2 + ast = { + { + 'DictLiteral:0:0:{', + children = { + { + 'Comma:0:6:,', + children = { + { + 'Colon:0:3::', + children = { + 'Register(name=a):0:1:@a', + 'Register(name=b):0:4:@b', + }, + }, + { + 'Comma:0:12:,', + children = { + { + 'Colon:0:9::', + children = { + 'Register(name=c):0:7:@c', + 'Register(name=d):0:10:@d', + }, + }, + { + 'Comma:0:18:,', + children = { + { + 'Colon:0:15::', + children = { + 'Register(name=e):0:13:@e', + 'Register(name=f):0:16:@f', + }, + }, + { + 'Colon:0:21::', + children = { + 'Register(name=g):0:19:@g', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + err = { + arg = '}', + msg = 'E15: Expected value, got closing figure brace: %.*s', + }, + }, { + hl('Dict', '{'), + hl('Register', '@a'), + hl('Colon', ':'), + hl('Register', '@b'), + hl('Comma', ','), + hl('Register', '@c'), + hl('Colon', ':'), + hl('Register', '@d'), + hl('Comma', ','), + hl('Register', '@e'), + hl('Colon', ':'), + hl('Register', '@f'), + hl('Comma', ','), + hl('Register', '@g'), + hl('Colon', ':'), + hl('InvalidDict', '}'), + }) + check_parsing('{@a:@b,}', 0, { + -- 01234567890123 + -- 0 1 + ast = { + { + 'DictLiteral:0:0:{', + children = { + { + 'Comma:0:6:,', + children = { + { + 'Colon:0:3::', + children = { + 'Register(name=a):0:1:@a', + 'Register(name=b):0:4:@b', + }, + }, + }, + }, + }, + }, + }, + }, { + hl('Dict', '{'), + hl('Register', '@a'), + hl('Colon', ':'), + hl('Register', '@b'), + hl('Comma', ','), + hl('Dict', '}'), + }) + check_parsing('{({f -> g})(@h)(@i)}', 0, { + -- 01234567890123456789 + -- 0 1 + ast = { + { + 'CurlyBracesIdentifier:0:0:{', + children = { + { + 'Call:0:15:(', + children = { + { + 'Call:0:11:(', + children = { + { + 'Nested:0:1:(', + children = { + { + 'Lambda:0:2:{', + children = { + 'PlainIdentifier(scope=0,ident=f):0:3:f', + { + 'Arrow:0:4: ->', + children = { + 'PlainIdentifier(scope=0,ident=g):0:7: g', + }, + }, + }, + }, + }, + }, + 'Register(name=h):0:12:@h', + }, + }, + 'Register(name=i):0:16:@i', + }, + }, + }, + }, + }, + }, { + hl('Curly', '{'), + hl('NestingParenthesis', '('), + hl('Lambda', '{'), + hl('IdentifierName', 'f'), + hl('Arrow', '->', 1), + hl('IdentifierName', 'g', 1), + hl('Lambda', '}'), + hl('NestingParenthesis', ')'), + hl('CallingParenthesis', '('), + hl('Register', '@h'), + hl('CallingParenthesis', ')'), + hl('CallingParenthesis', '('), + hl('Register', '@i'), + hl('CallingParenthesis', ')'), + hl('Curly', '}'), + }) + check_parsing('a:{b()}c', 0, { + -- 01234567 + ast = { + { + 'ComplexIdentifier:0:2:', + children = { + 'PlainIdentifier(scope=a,ident=):0:0:a:', + { + 'ComplexIdentifier:0:7:', + children = { + { + 'CurlyBracesIdentifier:0:2:{', + children = { + { + 'Call:0:4:(', + children = { + 'PlainIdentifier(scope=0,ident=b):0:3:b', + }, + }, + }, + }, + 'PlainIdentifier(scope=0,ident=c):0:7:c', + }, + }, + }, + }, + }, + }, { + hl('IdentifierScope', 'a'), + hl('IdentifierScopeDelimiter', ':'), + hl('Curly', '{'), + hl('IdentifierName', 'b'), + hl('CallingParenthesis', '('), + hl('CallingParenthesis', ')'), + hl('Curly', '}'), + hl('IdentifierName', 'c'), + }) + check_parsing('a:{{b, c -> @d + @e + ({f -> g})(@h)}(@i)}j', 0, { + -- 01234567890123456789012345678901234567890123456 + -- 0 1 2 3 4 + ast = { + { + 'ComplexIdentifier:0:2:', + children = { + 'PlainIdentifier(scope=a,ident=):0:0:a:', + { + 'ComplexIdentifier:0:42:', + children = { + { + 'CurlyBracesIdentifier:0:2:{', + children = { + { + 'Call:0:37:(', + children = { + { + 'Lambda:0:3:{', + children = { + { + 'Comma:0:5:,', + children = { + 'PlainIdentifier(scope=0,ident=b):0:4:b', + 'PlainIdentifier(scope=0,ident=c):0:6: c', + }, + }, + { + 'Arrow:0:8: ->', + children = { + { + 'BinaryPlus:0:19: +', + children = { + { + 'BinaryPlus:0:14: +', + children = { + 'Register(name=d):0:11: @d', + 'Register(name=e):0:16: @e', + }, + }, + { + 'Call:0:32:(', + children = { + { + 'Nested:0:21: (', + children = { + { + 'Lambda:0:23:{', + children = { + 'PlainIdentifier(scope=0,ident=f):0:24:f', + { + 'Arrow:0:25: ->', + children = { + 'PlainIdentifier(scope=0,ident=g):0:28: g', + }, + }, + }, + }, + }, + }, + 'Register(name=h):0:33:@h', + }, + }, + }, + }, + }, + }, + }, + }, + 'Register(name=i):0:38:@i', + }, + }, + }, + }, + 'PlainIdentifier(scope=0,ident=j):0:42:j', + }, + }, + }, + }, + }, + }, { + hl('IdentifierScope', 'a'), + hl('IdentifierScopeDelimiter', ':'), + hl('Curly', '{'), + hl('Lambda', '{'), + hl('IdentifierName', 'b'), + hl('Comma', ','), + hl('IdentifierName', 'c', 1), + hl('Arrow', '->', 1), + hl('Register', '@d', 1), + hl('BinaryPlus', '+', 1), + hl('Register', '@e', 1), + hl('BinaryPlus', '+', 1), + hl('NestingParenthesis', '(', 1), + hl('Lambda', '{'), + hl('IdentifierName', 'f'), + hl('Arrow', '->', 1), + hl('IdentifierName', 'g', 1), + hl('Lambda', '}'), + hl('NestingParenthesis', ')'), + hl('CallingParenthesis', '('), + hl('Register', '@h'), + hl('CallingParenthesis', ')'), + hl('Lambda', '}'), + hl('CallingParenthesis', '('), + hl('Register', '@i'), + hl('CallingParenthesis', ')'), + hl('Curly', '}'), + hl('IdentifierName', 'j'), + }) + check_parsing('{@a + @b : @c + @d, @e + @f : @g + @i}', 0, { + -- 01234567890123456789012345678901234567 + -- 0 1 2 3 + ast = { + { + 'DictLiteral:0:0:{', + children = { + { + 'Comma:0:18:,', + children = { + { + 'Colon:0:8: :', + children = { + { + 'BinaryPlus:0:3: +', + children = { + 'Register(name=a):0:1:@a', + 'Register(name=b):0:5: @b', + }, + }, + { + 'BinaryPlus:0:13: +', + children = { + 'Register(name=c):0:10: @c', + 'Register(name=d):0:15: @d', + }, + }, + }, + }, + { + 'Colon:0:27: :', + children = { + { + 'BinaryPlus:0:22: +', + children = { + 'Register(name=e):0:19: @e', + 'Register(name=f):0:24: @f', + }, + }, + { + 'BinaryPlus:0:32: +', + children = { + 'Register(name=g):0:29: @g', + 'Register(name=i):0:34: @i', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, { + hl('Dict', '{'), + hl('Register', '@a'), + hl('BinaryPlus', '+', 1), + hl('Register', '@b', 1), + hl('Colon', ':', 1), + hl('Register', '@c', 1), + hl('BinaryPlus', '+', 1), + hl('Register', '@d', 1), + hl('Comma', ','), + hl('Register', '@e', 1), + hl('BinaryPlus', '+', 1), + hl('Register', '@f', 1), + hl('Colon', ':', 1), + hl('Register', '@g', 1), + hl('BinaryPlus', '+', 1), + hl('Register', '@i', 1), + hl('Dict', '}'), + }) + check_parsing('-> -> ->', 0, { + -- 01234567 + ast = { + { + 'Arrow:0:0:->', + children = { + 'Missing:0:0:', + { + 'Arrow:0:2: ->', + children = { + 'Missing:0:2:', + { + 'Arrow:0:5: ->', + children = { + 'Missing:0:5:', + }, + }, + }, + }, + }, + }, + }, + err = { + arg = '-> -> ->', + msg = 'E15: Unexpected arrow: %.*s', + }, + }, { + hl('InvalidArrow', '->'), + hl('InvalidArrow', '->', 1), + hl('InvalidArrow', '->', 1), + }) + check_parsing('a -> b -> c -> d', 0, { + -- 0123456789012345 + -- 0 1 + ast = { + { + 'Arrow:0:1: ->', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + { + 'Arrow:0:6: ->', + children = { + 'PlainIdentifier(scope=0,ident=b):0:4: b', + { + 'Arrow:0:11: ->', + children = { + 'PlainIdentifier(scope=0,ident=c):0:9: c', + 'PlainIdentifier(scope=0,ident=d):0:14: d', + }, + }, + }, + }, + }, + }, + }, + err = { + arg = '-> b -> c -> d', + msg = 'E15: Arrow outside of lambda: %.*s', + }, + }, { + hl('IdentifierName', 'a'), + hl('InvalidArrow', '->', 1), + hl('IdentifierName', 'b', 1), + hl('InvalidArrow', '->', 1), + hl('IdentifierName', 'c', 1), + hl('InvalidArrow', '->', 1), + hl('IdentifierName', 'd', 1), + }) + check_parsing('{a -> b -> c}', 0, { + -- 0123456789012 + -- 0 1 + ast = { + { + 'Lambda:0:0:{', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + { + 'Arrow:0:2: ->', + children = { + { + 'Arrow:0:7: ->', + children = { + 'PlainIdentifier(scope=0,ident=b):0:5: b', + 'PlainIdentifier(scope=0,ident=c):0:10: c', + }, + }, + }, + }, + }, + }, + }, + err = { + arg = '-> c}', + msg = 'E15: Arrow outside of lambda: %.*s', + }, + }, { + hl('Lambda', '{'), + hl('IdentifierName', 'a'), + hl('Arrow', '->', 1), + hl('IdentifierName', 'b', 1), + hl('InvalidArrow', '->', 1), + hl('IdentifierName', 'c', 1), + hl('Lambda', '}'), + }) + check_parsing('{a: -> b}', 0, { + -- 012345678 + ast = { + { + 'CurlyBracesIdentifier:0:0:{', + children = { + { + 'Arrow:0:3: ->', + children = { + 'PlainIdentifier(scope=a,ident=):0:1:a:', + 'PlainIdentifier(scope=0,ident=b):0:6: b', + }, + }, + }, + }, + }, + err = { + arg = '-> b}', + msg = 'E15: Arrow outside of lambda: %.*s', + }, + }, { + hl('Curly', '{'), + hl('IdentifierScope', 'a'), + hl('IdentifierScopeDelimiter', ':'), + hl('InvalidArrow', '->', 1), + hl('IdentifierName', 'b', 1), + hl('Curly', '}'), + }) + + check_parsing('{a:b -> b}', 0, { + -- 0123456789 + ast = { + { + 'CurlyBracesIdentifier:0:0:{', + children = { + { + 'Arrow:0:4: ->', + children = { + 'PlainIdentifier(scope=a,ident=b):0:1:a:b', + 'PlainIdentifier(scope=0,ident=b):0:7: b', + }, + }, + }, + }, + }, + err = { + arg = '-> b}', + msg = 'E15: Arrow outside of lambda: %.*s', + }, + }, { + hl('Curly', '{'), + hl('IdentifierScope', 'a'), + hl('IdentifierScopeDelimiter', ':'), + hl('IdentifierName', 'b'), + hl('InvalidArrow', '->', 1), + hl('IdentifierName', 'b', 1), + hl('Curly', '}'), + }) + + check_parsing('{a#b -> b}', 0, { + -- 0123456789 + ast = { + { + 'CurlyBracesIdentifier:0:0:{', + children = { + { + 'Arrow:0:4: ->', + children = { + 'PlainIdentifier(scope=0,ident=a#b):0:1:a#b', + 'PlainIdentifier(scope=0,ident=b):0:7: b', + }, + }, + }, + }, + }, + err = { + arg = '-> b}', + msg = 'E15: Arrow outside of lambda: %.*s', + }, + }, { + hl('Curly', '{'), + hl('IdentifierName', 'a#b'), + hl('InvalidArrow', '->', 1), + hl('IdentifierName', 'b', 1), + hl('Curly', '}'), + }) + check_parsing('{a : b : c}', 0, { + -- 01234567890 + -- 0 1 + ast = { + { + 'DictLiteral:0:0:{', + children = { + { + 'Colon:0:2: :', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + { + 'Colon:0:6: :', + children = { + 'PlainIdentifier(scope=0,ident=b):0:4: b', + 'PlainIdentifier(scope=0,ident=c):0:8: c', + }, + }, + }, + }, + }, + }, + }, + err = { + arg = ': c}', + msg = 'E15: Colon outside of dictionary or ternary operator: %.*s', + }, + }, { + hl('Dict', '{'), + hl('IdentifierName', 'a'), + hl('Colon', ':', 1), + hl('IdentifierName', 'b', 1), + hl('InvalidColon', ':', 1), + hl('IdentifierName', 'c', 1), + hl('Dict', '}'), + }) + check_parsing('{', 0, { + -- 0 + ast = { + 'UnknownFigure:0:0:{', + }, + err = { + arg = '{', + msg = 'E15: Missing closing figure brace: %.*s', + }, + }, { + hl('FigureBrace', '{'), + }) + check_parsing('{a', 0, { + -- 01 + ast = { + { + 'UnknownFigure:0:0:{', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + }, + }, + }, + err = { + arg = '{a', + msg = 'E15: Missing closing figure brace: %.*s', + }, + }, { + hl('FigureBrace', '{'), + hl('IdentifierName', 'a'), + }) + check_parsing('{a,b', 0, { + -- 0123 + ast = { + { + 'Lambda:0:0:{', + children = { + { + 'Comma:0:2:,', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + 'PlainIdentifier(scope=0,ident=b):0:3:b', + }, + }, + }, + }, + }, + err = { + arg = '{a,b', + msg = 'E15: Missing closing figure brace for lambda: %.*s', + }, + }, { + hl('Lambda', '{'), + hl('IdentifierName', 'a'), + hl('Comma', ','), + hl('IdentifierName', 'b'), + }) + check_parsing('{a,b->', 0, { + -- 012345 + ast = { + { + 'Lambda:0:0:{', + children = { + { + 'Comma:0:2:,', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + 'PlainIdentifier(scope=0,ident=b):0:3:b', + }, + }, + 'Arrow:0:4:->', + }, + }, + }, + err = { + arg = '', + msg = 'E15: Expected value, got EOC: %.*s', + }, + }, { + hl('Lambda', '{'), + hl('IdentifierName', 'a'), + hl('Comma', ','), + hl('IdentifierName', 'b'), + hl('Arrow', '->'), + }) + check_parsing('{a,b->c', 0, { + -- 0123456 + ast = { + { + 'Lambda:0:0:{', + children = { + { + 'Comma:0:2:,', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + 'PlainIdentifier(scope=0,ident=b):0:3:b', + }, + }, + { + 'Arrow:0:4:->', + children = { + 'PlainIdentifier(scope=0,ident=c):0:6:c', + }, + }, + }, + }, + }, + err = { + arg = '{a,b->c', + msg = 'E15: Missing closing figure brace for lambda: %.*s', + }, + }, { + hl('Lambda', '{'), + hl('IdentifierName', 'a'), + hl('Comma', ','), + hl('IdentifierName', 'b'), + hl('Arrow', '->'), + hl('IdentifierName', 'c'), + }) + check_parsing('{a : b', 0, { + -- 012345 + ast = { + { + 'DictLiteral:0:0:{', + children = { + { + 'Colon:0:2: :', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + 'PlainIdentifier(scope=0,ident=b):0:4: b', + }, + }, + }, + }, + }, + err = { + arg = '{a : b', + msg = 'E723: Missing end of Dictionary \'}\': %.*s', + }, + }, { + hl('Dict', '{'), + hl('IdentifierName', 'a'), + hl('Colon', ':', 1), + hl('IdentifierName', 'b', 1), + }) + check_parsing('{a : b,', 0, { + -- 0123456 + ast = { + { + 'DictLiteral:0:0:{', + children = { + { + 'Comma:0:6:,', + children = { + { + 'Colon:0:2: :', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + 'PlainIdentifier(scope=0,ident=b):0:4: b', + }, + }, + }, + }, + }, + }, + }, + err = { + arg = '', + msg = 'E15: Expected value, got EOC: %.*s', + }, + }, { + hl('Dict', '{'), + hl('IdentifierName', 'a'), + hl('Colon', ':', 1), + hl('IdentifierName', 'b', 1), + hl('Comma', ','), + }) + end) + it('works with ternary operator', function() + check_parsing('a ? b : c', 0, { + -- 012345678 + ast = { + { + 'Ternary:0:1: ?', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + { + 'TernaryValue:0:5: :', + children = { + 'PlainIdentifier(scope=0,ident=b):0:3: b', + 'PlainIdentifier(scope=0,ident=c):0:7: c', + }, + }, + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('Ternary', '?', 1), + hl('IdentifierName', 'b', 1), + hl('TernaryColon', ':', 1), + hl('IdentifierName', 'c', 1), + }) + check_parsing('@a?@b?@c:@d:@e', 0, { + -- 01234567890123 + -- 0 1 + ast = { + { + 'Ternary:0:2:?', + children = { + 'Register(name=a):0:0:@a', + { + 'TernaryValue:0:11::', + children = { + { + 'Ternary:0:5:?', + children = { + 'Register(name=b):0:3:@b', + { + 'TernaryValue:0:8::', + children = { + 'Register(name=c):0:6:@c', + 'Register(name=d):0:9:@d', + }, + }, + }, + }, + 'Register(name=e):0:12:@e', + }, + }, + }, + }, + }, + }, { + hl('Register', '@a'), + hl('Ternary', '?'), + hl('Register', '@b'), + hl('Ternary', '?'), + hl('Register', '@c'), + hl('TernaryColon', ':'), + hl('Register', '@d'), + hl('TernaryColon', ':'), + hl('Register', '@e'), + }) + check_parsing('@a?@b:@c?@d:@e', 0, { + -- 01234567890123 + -- 0 1 + ast = { + { + 'Ternary:0:2:?', + children = { + 'Register(name=a):0:0:@a', + { + 'TernaryValue:0:5::', + children = { + 'Register(name=b):0:3:@b', + { + 'Ternary:0:8:?', + children = { + 'Register(name=c):0:6:@c', + { + 'TernaryValue:0:11::', + children = { + 'Register(name=d):0:9:@d', + 'Register(name=e):0:12:@e', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, { + hl('Register', '@a'), + hl('Ternary', '?'), + hl('Register', '@b'), + hl('TernaryColon', ':'), + hl('Register', '@c'), + hl('Ternary', '?'), + hl('Register', '@d'), + hl('TernaryColon', ':'), + hl('Register', '@e'), + }) + check_parsing('@a?@b?@c?@d:@e?@f:@g:@h?@i:@j:@k', 0, { + -- 01234567890123456789012345678901 + -- 0 1 2 3 + ast = { + { + 'Ternary:0:2:?', + children = { + 'Register(name=a):0:0:@a', + { + 'TernaryValue:0:29::', + children = { + { + 'Ternary:0:5:?', + children = { + 'Register(name=b):0:3:@b', + { + 'TernaryValue:0:20::', + children = { + { + 'Ternary:0:8:?', + children = { + 'Register(name=c):0:6:@c', + { + 'TernaryValue:0:11::', + children = { + 'Register(name=d):0:9:@d', + { + 'Ternary:0:14:?', + children = { + 'Register(name=e):0:12:@e', + { + 'TernaryValue:0:17::', + children = { + 'Register(name=f):0:15:@f', + 'Register(name=g):0:18:@g', + }, + }, + }, + }, + }, + }, + }, + }, + { + 'Ternary:0:23:?', + children = { + 'Register(name=h):0:21:@h', + { + 'TernaryValue:0:26::', + children = { + 'Register(name=i):0:24:@i', + 'Register(name=j):0:27:@j', + }, + }, + }, + }, + }, + }, + }, + }, + 'Register(name=k):0:30:@k', + }, + }, + }, + }, + }, + }, { + hl('Register', '@a'), + hl('Ternary', '?'), + hl('Register', '@b'), + hl('Ternary', '?'), + hl('Register', '@c'), + hl('Ternary', '?'), + hl('Register', '@d'), + hl('TernaryColon', ':'), + hl('Register', '@e'), + hl('Ternary', '?'), + hl('Register', '@f'), + hl('TernaryColon', ':'), + hl('Register', '@g'), + hl('TernaryColon', ':'), + hl('Register', '@h'), + hl('Ternary', '?'), + hl('Register', '@i'), + hl('TernaryColon', ':'), + hl('Register', '@j'), + hl('TernaryColon', ':'), + hl('Register', '@k'), + }) + check_parsing('?', 0, { + -- 0 + ast = { + { + 'Ternary:0:0:?', + children = { + 'Missing:0:0:', + 'TernaryValue:0:0:?', + }, + }, + }, + err = { + arg = '?', + msg = 'E15: Expected value, got question mark: %.*s', + }, + }, { + hl('InvalidTernary', '?'), + }) + + check_parsing('?:', 0, { + -- 01 + ast = { + { + 'Ternary:0:0:?', + children = { + 'Missing:0:0:', + { + 'TernaryValue:0:1::', + children = { + 'Missing:0:1:', + }, + }, + }, + }, + }, + err = { + arg = '?:', + msg = 'E15: Expected value, got question mark: %.*s', + }, + }, { + hl('InvalidTernary', '?'), + hl('InvalidTernaryColon', ':'), + }) + + check_parsing('?::', 0, { + -- 012 + ast = { + { + 'Colon:0:2::', + children = { + { + 'Ternary:0:0:?', + children = { + 'Missing:0:0:', + { + 'TernaryValue:0:1::', + children = { + 'Missing:0:1:', + 'Missing:0:2:', + }, + }, + }, + }, + }, + }, + }, + err = { + arg = '?::', + msg = 'E15: Expected value, got question mark: %.*s', + }, + }, { + hl('InvalidTernary', '?'), + hl('InvalidTernaryColon', ':'), + hl('InvalidColon', ':'), + }) + + check_parsing('a?b', 0, { + -- 012 + ast = { + { + 'Ternary:0:1:?', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + { + 'TernaryValue:0:1:?', + children = { + 'PlainIdentifier(scope=0,ident=b):0:2:b', + }, + }, + }, + }, + }, + err = { + arg = '?b', + msg = 'E109: Missing \':\' after \'?\': %.*s', + }, + }, { + hl('IdentifierName', 'a'), + hl('Ternary', '?'), + hl('IdentifierName', 'b'), + }) + check_parsing('a?b:', 0, { + -- 0123 + ast = { + { + 'Ternary:0:1:?', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + { + 'TernaryValue:0:1:?', + children = { + 'PlainIdentifier(scope=b,ident=):0:2:b:', + }, + }, + }, + }, + }, + err = { + arg = '?b:', + msg = 'E109: Missing \':\' after \'?\': %.*s', + }, + }, { + hl('IdentifierName', 'a'), + hl('Ternary', '?'), + hl('IdentifierScope', 'b'), + hl('IdentifierScopeDelimiter', ':'), + }) + + check_parsing('a?b::c', 0, { + -- 012345 + ast = { + { + 'Ternary:0:1:?', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + { + 'TernaryValue:0:4::', + children = { + 'PlainIdentifier(scope=b,ident=):0:2:b:', + 'PlainIdentifier(scope=0,ident=c):0:5:c', + }, + }, + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('Ternary', '?'), + hl('IdentifierScope', 'b'), + hl('IdentifierScopeDelimiter', ':'), + hl('TernaryColon', ':'), + hl('IdentifierName', 'c'), + }) + + check_parsing('a?b :', 0, { + -- 01234 + ast = { + { + 'Ternary:0:1:?', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + { + 'TernaryValue:0:3: :', + children = { + 'PlainIdentifier(scope=0,ident=b):0:2:b', + }, + }, + }, + }, + }, + err = { + arg = '', + msg = 'E15: Expected value, got EOC: %.*s', + }, + }, { + hl('IdentifierName', 'a'), + hl('Ternary', '?'), + hl('IdentifierName', 'b'), + hl('TernaryColon', ':', 1), + }) + + check_parsing('(@a?@b:@c)?@d:@e', 0, { + -- 0123456789012345 + -- 0 1 + ast = { + { + 'Ternary:0:10:?', + children = { + { + 'Nested:0:0:(', + children = { + { + 'Ternary:0:3:?', + children = { + 'Register(name=a):0:1:@a', + { + 'TernaryValue:0:6::', + children = { + 'Register(name=b):0:4:@b', + 'Register(name=c):0:7:@c', + }, + }, + }, + }, + }, + }, + { + 'TernaryValue:0:13::', + children = { + 'Register(name=d):0:11:@d', + 'Register(name=e):0:14:@e', + }, + }, + }, + }, + }, + }, { + hl('NestingParenthesis', '('), + hl('Register', '@a'), + hl('Ternary', '?'), + hl('Register', '@b'), + hl('TernaryColon', ':'), + hl('Register', '@c'), + hl('NestingParenthesis', ')'), + hl('Ternary', '?'), + hl('Register', '@d'), + hl('TernaryColon', ':'), + hl('Register', '@e'), + }) + + check_parsing('(@a?@b:@c)?(@d?@e:@f):(@g?@h:@i)', 0, { + -- 01234567890123456789012345678901 + -- 0 1 2 3 + ast = { + { + 'Ternary:0:10:?', + children = { + { + 'Nested:0:0:(', + children = { + { + 'Ternary:0:3:?', + children = { + 'Register(name=a):0:1:@a', + { + 'TernaryValue:0:6::', + children = { + 'Register(name=b):0:4:@b', + 'Register(name=c):0:7:@c', + }, + }, + }, + }, + }, + }, + { + 'TernaryValue:0:21::', + children = { + { + 'Nested:0:11:(', + children = { + { + 'Ternary:0:14:?', + children = { + 'Register(name=d):0:12:@d', + { + 'TernaryValue:0:17::', + children = { + 'Register(name=e):0:15:@e', + 'Register(name=f):0:18:@f', + }, + }, + }, + }, + }, + }, + { + 'Nested:0:22:(', + children = { + { + 'Ternary:0:25:?', + children = { + 'Register(name=g):0:23:@g', + { + 'TernaryValue:0:28::', + children = { + 'Register(name=h):0:26:@h', + 'Register(name=i):0:29:@i', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, { + hl('NestingParenthesis', '('), + hl('Register', '@a'), + hl('Ternary', '?'), + hl('Register', '@b'), + hl('TernaryColon', ':'), + hl('Register', '@c'), + hl('NestingParenthesis', ')'), + hl('Ternary', '?'), + hl('NestingParenthesis', '('), + hl('Register', '@d'), + hl('Ternary', '?'), + hl('Register', '@e'), + hl('TernaryColon', ':'), + hl('Register', '@f'), + hl('NestingParenthesis', ')'), + hl('TernaryColon', ':'), + hl('NestingParenthesis', '('), + hl('Register', '@g'), + hl('Ternary', '?'), + hl('Register', '@h'), + hl('TernaryColon', ':'), + hl('Register', '@i'), + hl('NestingParenthesis', ')'), + }) + + check_parsing('(@a?@b:@c)?@d?@e:@f:@g?@h:@i', 0, { + -- 0123456789012345678901234567 + -- 0 1 2 + ast = { + { + 'Ternary:0:10:?', + children = { + { + 'Nested:0:0:(', + children = { + { + 'Ternary:0:3:?', + children = { + 'Register(name=a):0:1:@a', + { + 'TernaryValue:0:6::', + children = { + 'Register(name=b):0:4:@b', + 'Register(name=c):0:7:@c', + }, + }, + }, + }, + }, + }, + { + 'TernaryValue:0:19::', + children = { + { + 'Ternary:0:13:?', + children = { + 'Register(name=d):0:11:@d', + { + 'TernaryValue:0:16::', + children = { + 'Register(name=e):0:14:@e', + 'Register(name=f):0:17:@f', + }, + }, + }, + }, + { + 'Ternary:0:22:?', + children = { + 'Register(name=g):0:20:@g', + { + 'TernaryValue:0:25::', + children = { + 'Register(name=h):0:23:@h', + 'Register(name=i):0:26:@i', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, { + hl('NestingParenthesis', '('), + hl('Register', '@a'), + hl('Ternary', '?'), + hl('Register', '@b'), + hl('TernaryColon', ':'), + hl('Register', '@c'), + hl('NestingParenthesis', ')'), + hl('Ternary', '?'), + hl('Register', '@d'), + hl('Ternary', '?'), + hl('Register', '@e'), + hl('TernaryColon', ':'), + hl('Register', '@f'), + hl('TernaryColon', ':'), + hl('Register', '@g'), + hl('Ternary', '?'), + hl('Register', '@h'), + hl('TernaryColon', ':'), + hl('Register', '@i'), + }) + check_parsing('a?b{cdef}g:h', 0, { + -- 012345678901 + -- 0 1 + ast = { + { + 'Ternary:0:1:?', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + { + 'TernaryValue:0:10::', + children = { + { + 'ComplexIdentifier:0:3:', + children = { + 'PlainIdentifier(scope=0,ident=b):0:2:b', + { + 'ComplexIdentifier:0:9:', + children = { + { + 'CurlyBracesIdentifier:0:3:{', + children = { + 'PlainIdentifier(scope=0,ident=cdef):0:4:cdef', + }, + }, + 'PlainIdentifier(scope=0,ident=g):0:9:g', + }, + }, + }, + }, + 'PlainIdentifier(scope=0,ident=h):0:11:h', + }, + }, + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('Ternary', '?'), + hl('IdentifierName', 'b'), + hl('Curly', '{'), + hl('IdentifierName', 'cdef'), + hl('Curly', '}'), + hl('IdentifierName', 'g'), + hl('TernaryColon', ':'), + hl('IdentifierName', 'h'), + }) + check_parsing('a ? b : c : d', 0, { + -- 0123456789012 + -- 0 1 + ast = { + { + 'Colon:0:9: :', + children = { + { + 'Ternary:0:1: ?', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + { + 'TernaryValue:0:5: :', + children = { + 'PlainIdentifier(scope=0,ident=b):0:3: b', + 'PlainIdentifier(scope=0,ident=c):0:7: c', + }, + }, + }, + }, + 'PlainIdentifier(scope=0,ident=d):0:11: d', + }, + }, + }, + err = { + arg = ': d', + msg = 'E15: Colon outside of dictionary or ternary operator: %.*s', + }, + }, { + hl('IdentifierName', 'a'), + hl('Ternary', '?', 1), + hl('IdentifierName', 'b', 1), + hl('TernaryColon', ':', 1), + hl('IdentifierName', 'c', 1), + hl('InvalidColon', ':', 1), + hl('IdentifierName', 'd', 1), + }) + end) + it('works with comparison operators', function() + check_parsing('a == b', 0, { + -- 012345 + ast = { + { + 'Comparison(type=Equal,inv=0,ccs=UseOption):0:1: ==', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + 'PlainIdentifier(scope=0,ident=b):0:4: b', + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('Comparison', '==', 1), + hl('IdentifierName', 'b', 1), + }) + + check_parsing('a ==? b', 0, { + -- 0123456 + ast = { + { + 'Comparison(type=Equal,inv=0,ccs=IgnoreCase):0:1: ==?', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + 'PlainIdentifier(scope=0,ident=b):0:5: b', + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('Comparison', '==', 1), + hl('ComparisonModifier', '?'), + hl('IdentifierName', 'b', 1), + }) + + check_parsing('a ==# b', 0, { + -- 0123456 + ast = { + { + 'Comparison(type=Equal,inv=0,ccs=MatchCase):0:1: ==#', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + 'PlainIdentifier(scope=0,ident=b):0:5: b', + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('Comparison', '==', 1), + hl('ComparisonModifier', '#'), + hl('IdentifierName', 'b', 1), + }) + + check_parsing('a !=# b', 0, { + -- 0123456 + ast = { + { + 'Comparison(type=Equal,inv=1,ccs=MatchCase):0:1: !=#', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + 'PlainIdentifier(scope=0,ident=b):0:5: b', + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('Comparison', '!=', 1), + hl('ComparisonModifier', '#'), + hl('IdentifierName', 'b', 1), + }) + + check_parsing('a <=# b', 0, { + -- 0123456 + ast = { + { + 'Comparison(type=Greater,inv=1,ccs=MatchCase):0:1: <=#', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + 'PlainIdentifier(scope=0,ident=b):0:5: b', + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('Comparison', '<=', 1), + hl('ComparisonModifier', '#'), + hl('IdentifierName', 'b', 1), + }) + + check_parsing('a >=# b', 0, { + -- 0123456 + ast = { + { + 'Comparison(type=GreaterOrEqual,inv=0,ccs=MatchCase):0:1: >=#', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + 'PlainIdentifier(scope=0,ident=b):0:5: b', + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('Comparison', '>=', 1), + hl('ComparisonModifier', '#'), + hl('IdentifierName', 'b', 1), + }) + + check_parsing('a ># b', 0, { + -- 012345 + ast = { + { + 'Comparison(type=Greater,inv=0,ccs=MatchCase):0:1: >#', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + 'PlainIdentifier(scope=0,ident=b):0:4: b', + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('Comparison', '>', 1), + hl('ComparisonModifier', '#'), + hl('IdentifierName', 'b', 1), + }) + + check_parsing('a <# b', 0, { + -- 012345 + ast = { + { + 'Comparison(type=GreaterOrEqual,inv=1,ccs=MatchCase):0:1: <#', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + 'PlainIdentifier(scope=0,ident=b):0:4: b', + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('Comparison', '<', 1), + hl('ComparisonModifier', '#'), + hl('IdentifierName', 'b', 1), + }) + + check_parsing('a is#b', 0, { + -- 012345 + ast = { + { + 'Comparison(type=Identical,inv=0,ccs=MatchCase):0:1: is#', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + 'PlainIdentifier(scope=0,ident=b):0:5:b', + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('Comparison', 'is', 1), + hl('ComparisonModifier', '#'), + hl('IdentifierName', 'b'), + }) + + check_parsing('a is?b', 0, { + -- 012345 + ast = { + { + 'Comparison(type=Identical,inv=0,ccs=IgnoreCase):0:1: is?', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + 'PlainIdentifier(scope=0,ident=b):0:5:b', + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('Comparison', 'is', 1), + hl('ComparisonModifier', '?'), + hl('IdentifierName', 'b'), + }) + + check_parsing('a isnot b', 0, { + -- 012345678 + ast = { + { + 'Comparison(type=Identical,inv=1,ccs=UseOption):0:1: isnot', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + 'PlainIdentifier(scope=0,ident=b):0:7: b', + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('Comparison', 'isnot', 1), + hl('IdentifierName', 'b', 1), + }) + + check_parsing('a < b < c', 0, { + -- 012345678 + ast = { + { + 'Comparison(type=GreaterOrEqual,inv=1,ccs=UseOption):0:1: <', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + { + 'Comparison(type=GreaterOrEqual,inv=1,ccs=UseOption):0:5: <', + children = { + 'PlainIdentifier(scope=0,ident=b):0:3: b', + 'PlainIdentifier(scope=0,ident=c):0:7: c', + }, + }, + }, + }, + }, + err = { + arg = ' < c', + msg = 'E15: Operator is not associative: %.*s', + }, + }, { + hl('IdentifierName', 'a'), + hl('Comparison', '<', 1), + hl('IdentifierName', 'b', 1), + hl('InvalidComparison', '<', 1), + hl('IdentifierName', 'c', 1), + }) + + check_parsing('a < b <# c', 0, { + -- 012345678 + ast = { + { + 'Comparison(type=GreaterOrEqual,inv=1,ccs=UseOption):0:1: <', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + { + 'Comparison(type=GreaterOrEqual,inv=1,ccs=MatchCase):0:5: <#', + children = { + 'PlainIdentifier(scope=0,ident=b):0:3: b', + 'PlainIdentifier(scope=0,ident=c):0:8: c', + }, + }, + }, + }, + }, + err = { + arg = ' <# c', + msg = 'E15: Operator is not associative: %.*s', + }, + }, { + hl('IdentifierName', 'a'), + hl('Comparison', '<', 1), + hl('IdentifierName', 'b', 1), + hl('InvalidComparison', '<', 1), + hl('InvalidComparisonModifier', '#'), + hl('IdentifierName', 'c', 1), + }) + + check_parsing('a += b', 0, { + -- 012345 + ast = { + { + 'Comparison(type=Equal,inv=0,ccs=UseOption):0:3:=', + children = { + { + 'BinaryPlus:0:1: +', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + 'Missing:0:3:', + }, + }, + 'PlainIdentifier(scope=0,ident=b):0:4: b', + }, + }, + }, + err = { + arg = '= b', + msg = 'E15: Expected == or =~: %.*s', + }, + }, { + hl('IdentifierName', 'a'), + hl('BinaryPlus', '+', 1), + hl('InvalidComparison', '='), + hl('IdentifierName', 'b', 1), + }) + check_parsing('a + b == c + d', 0, { + -- 01234567890123 + -- 0 1 + ast = { + { + 'Comparison(type=Equal,inv=0,ccs=UseOption):0:5: ==', + children = { + { + 'BinaryPlus:0:1: +', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + 'PlainIdentifier(scope=0,ident=b):0:3: b', + }, + }, + { + 'BinaryPlus:0:10: +', + children = { + 'PlainIdentifier(scope=0,ident=c):0:8: c', + 'PlainIdentifier(scope=0,ident=d):0:12: d', + }, + }, + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('BinaryPlus', '+', 1), + hl('IdentifierName', 'b', 1), + hl('Comparison', '==', 1), + hl('IdentifierName', 'c', 1), + hl('BinaryPlus', '+', 1), + hl('IdentifierName', 'd', 1), + }) + check_parsing('+ a == + b', 0, { + -- 0123456789 + ast = { + { + 'Comparison(type=Equal,inv=0,ccs=UseOption):0:3: ==', + children = { + { + 'UnaryPlus:0:0:+', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1: a', + }, + }, + { + 'UnaryPlus:0:6: +', + children = { + 'PlainIdentifier(scope=0,ident=b):0:8: b', + }, + }, + }, + }, + }, + }, { + hl('UnaryPlus', '+'), + hl('IdentifierName', 'a', 1), + hl('Comparison', '==', 1), + hl('UnaryPlus', '+', 1), + hl('IdentifierName', 'b', 1), + }) + end) + it('works with concat/subscript', function() + check_parsing('.', 0, { + -- 0 + ast = { + { + 'ConcatOrSubscript:0:0:.', + children = { + 'Missing:0:0:', + }, + }, + }, + err = { + arg = '.', + msg = 'E15: Unexpected dot: %.*s', + }, + }, { + hl('InvalidConcatOrSubscript', '.'), + }) + + check_parsing('a.', 0, { + -- 01 + ast = { + { + 'ConcatOrSubscript:0:1:.', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + }, + }, + }, + err = { + arg = '', + msg = 'E15: Expected value, got EOC: %.*s', + }, + }, { + hl('IdentifierName', 'a'), + hl('ConcatOrSubscript', '.'), + }) + + check_parsing('a.b', 0, { + -- 012 + ast = { + { + 'ConcatOrSubscript:0:1:.', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + 'PlainKey(key=b):0:2:b', + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('ConcatOrSubscript', '.'), + hl('IdentifierKey', 'b'), + }) + + check_parsing('1.2', 0, { + -- 012 + ast = { + 'Float(val=1.200000e+00):0:0:1.2', + }, + }, { + hl('Float', '1.2'), + }) + + check_parsing('1.2 + 1.3e-5', 0, { + -- 012345678901 + -- 0 1 + ast = { + { + 'BinaryPlus:0:3: +', + children = { + 'Float(val=1.200000e+00):0:0:1.2', + 'Float(val=1.300000e-05):0:5: 1.3e-5', + }, + }, + }, + }, { + hl('Float', '1.2'), + hl('BinaryPlus', '+', 1), + hl('Float', '1.3e-5', 1), + }) + + check_parsing('a . 1.2 + 1.3e-5', 0, { + -- 0123456789012345 + -- 0 1 + ast = { + { + 'BinaryPlus:0:7: +', + children = { + { + 'Concat:0:1: .', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + { + 'ConcatOrSubscript:0:5:.', + children = { + 'Integer(val=1):0:3: 1', + 'PlainKey(key=2):0:6:2', + }, + }, + }, + }, + 'Float(val=1.300000e-05):0:9: 1.3e-5', + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('Concat', '.', 1), + hl('Number', '1', 1), + hl('ConcatOrSubscript', '.'), + hl('IdentifierKey', '2'), + hl('BinaryPlus', '+', 1), + hl('Float', '1.3e-5', 1), + }) + + check_parsing('1.3e-5 + 1.2 . a', 0, { + -- 0123456789012345 + -- 0 1 + ast = { + { + 'Concat:0:12: .', + children = { + { + 'BinaryPlus:0:6: +', + children = { + 'Float(val=1.300000e-05):0:0:1.3e-5', + 'Float(val=1.200000e+00):0:8: 1.2', + }, + }, + 'PlainIdentifier(scope=0,ident=a):0:14: a', + }, + }, + }, + }, { + hl('Float', '1.3e-5'), + hl('BinaryPlus', '+', 1), + hl('Float', '1.2', 1), + hl('Concat', '.', 1), + hl('IdentifierName', 'a', 1), + }) + + check_parsing('1.3e-5 + a . 1.2', 0, { + -- 0123456789012345 + -- 0 1 + ast = { + { + 'Concat:0:10: .', + children = { + { + 'BinaryPlus:0:6: +', + children = { + 'Float(val=1.300000e-05):0:0:1.3e-5', + 'PlainIdentifier(scope=0,ident=a):0:8: a', + }, + }, + { + 'ConcatOrSubscript:0:14:.', + children = { + 'Integer(val=1):0:12: 1', + 'PlainKey(key=2):0:15:2', + }, + }, + }, + }, + }, + }, { + hl('Float', '1.3e-5'), + hl('BinaryPlus', '+', 1), + hl('IdentifierName', 'a', 1), + hl('Concat', '.', 1), + hl('Number', '1', 1), + hl('ConcatOrSubscript', '.'), + hl('IdentifierKey', '2'), + }) + + check_parsing('1.2.3', 0, { + -- 01234 + ast = { + { + 'ConcatOrSubscript:0:3:.', + children = { + { + 'ConcatOrSubscript:0:1:.', + children = { + 'Integer(val=1):0:0:1', + 'PlainKey(key=2):0:2:2', + }, + }, + 'PlainKey(key=3):0:4:3', + }, + }, + }, + }, { + hl('Number', '1'), + hl('ConcatOrSubscript', '.'), + hl('IdentifierKey', '2'), + hl('ConcatOrSubscript', '.'), + hl('IdentifierKey', '3'), + }) + + check_parsing('a.1.2', 0, { + -- 01234 + ast = { + { + 'ConcatOrSubscript:0:3:.', + children = { + { + 'ConcatOrSubscript:0:1:.', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + 'PlainKey(key=1):0:2:1', + }, + }, + 'PlainKey(key=2):0:4:2', + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('ConcatOrSubscript', '.'), + hl('IdentifierKey', '1'), + hl('ConcatOrSubscript', '.'), + hl('IdentifierKey', '2'), + }) + + check_parsing('a . 1.2', 0, { + -- 0123456 + ast = { + { + 'Concat:0:1: .', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + { + 'ConcatOrSubscript:0:5:.', + children = { + 'Integer(val=1):0:3: 1', + 'PlainKey(key=2):0:6:2', + }, + }, + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('Concat', '.', 1), + hl('Number', '1', 1), + hl('ConcatOrSubscript', '.'), + hl('IdentifierKey', '2'), + }) + + check_parsing('+a . +b', 0, { + -- 0123456 + ast = { + { + 'Concat:0:2: .', + children = { + { + 'UnaryPlus:0:0:+', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + }, + }, + { + 'UnaryPlus:0:4: +', + children = { + 'PlainIdentifier(scope=0,ident=b):0:6:b', + }, + }, + }, + }, + }, + }, { + hl('UnaryPlus', '+'), + hl('IdentifierName', 'a'), + hl('Concat', '.', 1), + hl('UnaryPlus', '+', 1), + hl('IdentifierName', 'b'), + }) + + check_parsing('a. b', 0, { + -- 0123 + ast = { + { + 'Concat:0:1:.', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + 'PlainIdentifier(scope=0,ident=b):0:2: b', + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('ConcatOrSubscript', '.'), + hl('IdentifierName', 'b', 1), + }) + + check_parsing('a. 1', 0, { + -- 0123 + ast = { + { + 'Concat:0:1:.', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + 'Integer(val=1):0:2: 1', + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('ConcatOrSubscript', '.'), + hl('Number', '1', 1), + }) + end) + it('works with bracket subscripts', function() + check_parsing(':', 0, { + -- 0 + ast = { + { + 'Colon:0:0::', + children = { + 'Missing:0:0:', + }, + }, + }, + err = { + arg = ':', + msg = 'E15: Colon outside of dictionary or ternary operator: %.*s', + }, + }, { + hl('InvalidColon', ':'), + }) + check_parsing('a[]', 0, { + -- 012 + ast = { + { + 'Subscript:0:1:[', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + }, + }, + }, + err = { + arg = ']', + msg = 'E15: Expected value, got closing bracket: %.*s', + }, + }, { + hl('IdentifierName', 'a'), + hl('SubscriptBracket', '['), + hl('InvalidSubscriptBracket', ']'), + }) + check_parsing('a[b:]', 0, { + -- 01234 + ast = { + { + 'Subscript:0:1:[', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + 'PlainIdentifier(scope=b,ident=):0:2:b:', + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('SubscriptBracket', '['), + hl('IdentifierScope', 'b'), + hl('IdentifierScopeDelimiter', ':'), + hl('SubscriptBracket', ']'), + }) + + check_parsing('a[b:c]', 0, { + -- 012345 + ast = { + { + 'Subscript:0:1:[', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + 'PlainIdentifier(scope=b,ident=c):0:2:b:c', + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('SubscriptBracket', '['), + hl('IdentifierScope', 'b'), + hl('IdentifierScopeDelimiter', ':'), + hl('IdentifierName', 'c'), + hl('SubscriptBracket', ']'), + }) + check_parsing('a[b : c]', 0, { + -- 01234567 + ast = { + { + 'Subscript:0:1:[', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + { + 'Colon:0:3: :', + children = { + 'PlainIdentifier(scope=0,ident=b):0:2:b', + 'PlainIdentifier(scope=0,ident=c):0:5: c', + }, + }, + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('SubscriptBracket', '['), + hl('IdentifierName', 'b'), + hl('SubscriptColon', ':', 1), + hl('IdentifierName', 'c', 1), + hl('SubscriptBracket', ']'), + }) + + check_parsing('a[: b]', 0, { + -- 012345 + ast = { + { + 'Subscript:0:1:[', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + { + 'Colon:0:2::', + children = { + 'Missing:0:2:', + 'PlainIdentifier(scope=0,ident=b):0:3: b', + }, + }, + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('SubscriptBracket', '['), + hl('SubscriptColon', ':'), + hl('IdentifierName', 'b', 1), + hl('SubscriptBracket', ']'), + }) + + check_parsing('a[b :]', 0, { + -- 012345 + ast = { + { + 'Subscript:0:1:[', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + { + 'Colon:0:3: :', + children = { + 'PlainIdentifier(scope=0,ident=b):0:2:b', + }, + }, + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('SubscriptBracket', '['), + hl('IdentifierName', 'b'), + hl('SubscriptColon', ':', 1), + hl('SubscriptBracket', ']'), + }) + check_parsing('a[b][c][d](e)(f)(g)', 0, { + -- 0123456789012345678 + -- 0 1 + ast = { + { + 'Call:0:16:(', + children = { + { + 'Call:0:13:(', + children = { + { + 'Call:0:10:(', + children = { + { + 'Subscript:0:7:[', + children = { + { + 'Subscript:0:4:[', + children = { + { + 'Subscript:0:1:[', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + 'PlainIdentifier(scope=0,ident=b):0:2:b', + }, + }, + 'PlainIdentifier(scope=0,ident=c):0:5:c', + }, + }, + 'PlainIdentifier(scope=0,ident=d):0:8:d', + }, + }, + 'PlainIdentifier(scope=0,ident=e):0:11:e', + }, + }, + 'PlainIdentifier(scope=0,ident=f):0:14:f', + }, + }, + 'PlainIdentifier(scope=0,ident=g):0:17:g', + }, + }, + }, + }, { + hl('IdentifierName', 'a'), + hl('SubscriptBracket', '['), + hl('IdentifierName', 'b'), + hl('SubscriptBracket', ']'), + hl('SubscriptBracket', '['), + hl('IdentifierName', 'c'), + hl('SubscriptBracket', ']'), + hl('SubscriptBracket', '['), + hl('IdentifierName', 'd'), + hl('SubscriptBracket', ']'), + hl('CallingParenthesis', '('), + hl('IdentifierName', 'e'), + hl('CallingParenthesis', ')'), + hl('CallingParenthesis', '('), + hl('IdentifierName', 'f'), + hl('CallingParenthesis', ')'), + hl('CallingParenthesis', '('), + hl('IdentifierName', 'g'), + hl('CallingParenthesis', ')'), + }) + check_parsing('{a}{b}{c}[d][e][f]', 0, { + -- 012345678901234567 + -- 0 1 + ast = { + { + 'Subscript:0:15:[', + children = { + { + 'Subscript:0:12:[', + children = { + { + 'Subscript:0:9:[', + children = { + { + 'ComplexIdentifier:0:3:', + children = { + { + 'CurlyBracesIdentifier:0:0:{', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + }, + }, + { + 'ComplexIdentifier:0:6:', + children = { + { + 'CurlyBracesIdentifier:0:3:{', + children = { + 'PlainIdentifier(scope=0,ident=b):0:4:b', + }, + }, + { + 'CurlyBracesIdentifier:0:6:{', + children = { + 'PlainIdentifier(scope=0,ident=c):0:7:c', + }, + }, + }, + }, + }, + }, + 'PlainIdentifier(scope=0,ident=d):0:10:d', + }, + }, + 'PlainIdentifier(scope=0,ident=e):0:13:e', + }, + }, + 'PlainIdentifier(scope=0,ident=f):0:16:f', + }, + }, + }, + }, { + hl('Curly', '{'), + hl('IdentifierName', 'a'), + hl('Curly', '}'), + hl('Curly', '{'), + hl('IdentifierName', 'b'), + hl('Curly', '}'), + hl('Curly', '{'), + hl('IdentifierName', 'c'), + hl('Curly', '}'), + hl('SubscriptBracket', '['), + hl('IdentifierName', 'd'), + hl('SubscriptBracket', ']'), + hl('SubscriptBracket', '['), + hl('IdentifierName', 'e'), + hl('SubscriptBracket', ']'), + hl('SubscriptBracket', '['), + hl('IdentifierName', 'f'), + hl('SubscriptBracket', ']'), + }) + end) + it('supports list literals', function() + check_parsing('[]', 0, { + -- 01 + ast = { + 'ListLiteral:0:0:[', + }, + }, { + hl('List', '['), + hl('List', ']'), + }) + + check_parsing('[a]', 0, { + -- 012 + ast = { + { + 'ListLiteral:0:0:[', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + }, + }, + }, + }, { + hl('List', '['), + hl('IdentifierName', 'a'), + hl('List', ']'), + }) + + check_parsing('[a, b]', 0, { + -- 012345 + ast = { + { + 'ListLiteral:0:0:[', + children = { + { + 'Comma:0:2:,', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + 'PlainIdentifier(scope=0,ident=b):0:3: b', + }, + }, + }, + }, + }, + }, { + hl('List', '['), + hl('IdentifierName', 'a'), + hl('Comma', ','), + hl('IdentifierName', 'b', 1), + hl('List', ']'), + }) + + check_parsing('[a, b, c]', 0, { + -- 012345678 + ast = { + { + 'ListLiteral:0:0:[', + children = { + { + 'Comma:0:2:,', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + { + 'Comma:0:5:,', + children = { + 'PlainIdentifier(scope=0,ident=b):0:3: b', + 'PlainIdentifier(scope=0,ident=c):0:6: c', + }, + }, + }, + }, + }, + }, + }, + }, { + hl('List', '['), + hl('IdentifierName', 'a'), + hl('Comma', ','), + hl('IdentifierName', 'b', 1), + hl('Comma', ','), + hl('IdentifierName', 'c', 1), + hl('List', ']'), + }) + + check_parsing('[a, b, c, ]', 0, { + -- 01234567890 + -- 0 1 + ast = { + { + 'ListLiteral:0:0:[', + children = { + { + 'Comma:0:2:,', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + { + 'Comma:0:5:,', + children = { + 'PlainIdentifier(scope=0,ident=b):0:3: b', + { + 'Comma:0:8:,', + children = { + 'PlainIdentifier(scope=0,ident=c):0:6: c', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, { + hl('List', '['), + hl('IdentifierName', 'a'), + hl('Comma', ','), + hl('IdentifierName', 'b', 1), + hl('Comma', ','), + hl('IdentifierName', 'c', 1), + hl('Comma', ','), + hl('List', ']', 1), + }) + + check_parsing('[a : b, c : d]', 0, { + -- 01234567890123 + -- 0 1 + ast = { + { + 'ListLiteral:0:0:[', + children = { + { + 'Comma:0:6:,', + children = { + { + 'Colon:0:2: :', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + 'PlainIdentifier(scope=0,ident=b):0:4: b', + }, + }, + { + 'Colon:0:9: :', + children = { + 'PlainIdentifier(scope=0,ident=c):0:7: c', + 'PlainIdentifier(scope=0,ident=d):0:11: d', + }, + }, + }, + }, + }, + }, + }, + err = { + arg = ': b, c : d]', + msg = 'E15: Colon outside of dictionary or ternary operator: %.*s', + }, + }, { + hl('List', '['), + hl('IdentifierName', 'a'), + hl('InvalidColon', ':', 1), + hl('IdentifierName', 'b', 1), + hl('Comma', ','), + hl('IdentifierName', 'c', 1), + hl('InvalidColon', ':', 1), + hl('IdentifierName', 'd', 1), + hl('List', ']'), + }) + + check_parsing(']', 0, { + -- 0 + ast = { + 'ListLiteral:0:0:', + }, + err = { + arg = ']', + msg = 'E15: Unexpected closing figure brace: %.*s', + }, + }, { + hl('InvalidList', ']'), + }) + + check_parsing('a]', 0, { + -- 01 + ast = { + { + 'ListLiteral:0:1:', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + }, + }, + }, + err = { + arg = ']', + msg = 'E15: Unexpected closing figure brace: %.*s', + }, + }, { + hl('IdentifierName', 'a'), + hl('InvalidList', ']'), + }) + + check_parsing('[] []', 0, { + -- 01234 + ast = { + { + 'OpMissing:0:2:', + children = { + 'ListLiteral:0:0:[', + 'ListLiteral:0:2: [', + }, + }, + }, + err = { + arg = '[]', + msg = 'E15: Missing operator: %.*s', + }, + }, { + hl('List', '['), + hl('List', ']'), + hl('InvalidSpacing', ' '), + hl('List', '['), + hl('List', ']'), + }) + + check_parsing('[][]', 0, { + -- 0123 + ast = { + { + 'Subscript:0:2:[', + children = { + 'ListLiteral:0:0:[', + }, + }, + }, + err = { + arg = ']', + msg = 'E15: Expected value, got closing bracket: %.*s', + }, + }, { + hl('List', '['), + hl('List', ']'), + hl('SubscriptBracket', '['), + hl('InvalidSubscriptBracket', ']'), + }) + + check_parsing('[', 0, { + -- 0 + ast = { + 'ListLiteral:0:0:[', + }, + err = { + arg = '', + msg = 'E15: Expected value, got EOC: %.*s', + }, + }, { + hl('List', '['), + }) + + check_parsing('[1', 0, { + -- 01 + ast = { + { + 'ListLiteral:0:0:[', + children = { + 'Integer(val=1):0:1:1', + }, + }, + }, + err = { + arg = '[1', + msg = 'E697: Missing end of List \']\': %.*s', + }, + }, { + hl('List', '['), + hl('Number', '1'), + }) + end) + it('works with strings', function() + check_parsing('\'abc\'', 0, { + -- 01234 + ast = { + 'SingleQuotedString(val="abc"):0:0:\'abc\'', + }, + }, { + hl('SingleQuote', '\''), + hl('SingleQuotedBody', 'abc'), + hl('SingleQuote', '\''), + }) + check_parsing('"abc"', 0, { + -- 01234 + ast = { + 'DoubleQuotedString(val="abc"):0:0:"abc"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedBody', 'abc'), + hl('DoubleQuote', '"'), + }) + check_parsing('\'\'', 0, { + -- 01 + ast = { + 'SingleQuotedString(val=""):0:0:\'\'', + }, + }, { + hl('SingleQuote', '\''), + hl('SingleQuote', '\''), + }) + check_parsing('""', 0, { + -- 01 + ast = { + 'DoubleQuotedString(val=""):0:0:""', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuote', '"'), + }) + check_parsing('"', 0, { + -- 0 + ast = { + 'DoubleQuotedString(val=""):0:0:"', + }, + err = { + arg = '"', + msg = 'E114: Missing double quote: %.*s', + }, + }, { + hl('InvalidDoubleQuote', '"'), + }) + check_parsing('\'', 0, { + -- 0 + ast = { + 'SingleQuotedString(val=""):0:0:\'', + }, + err = { + arg = '\'', + msg = 'E115: Missing single quote: %.*s', + }, + }, { + hl('InvalidSingleQuote', '\''), + }) + check_parsing('"a', 0, { + -- 01 + ast = { + 'DoubleQuotedString(val="a"):0:0:"a', + }, + err = { + arg = '"a', + msg = 'E114: Missing double quote: %.*s', + }, + }, { + hl('InvalidDoubleQuote', '"'), + hl('InvalidDoubleQuotedBody', 'a'), + }) + check_parsing('\'a', 0, { + -- 01 + ast = { + 'SingleQuotedString(val="a"):0:0:\'a', + }, + err = { + arg = '\'a', + msg = 'E115: Missing single quote: %.*s', + }, + }, { + hl('InvalidSingleQuote', '\''), + hl('InvalidSingleQuotedBody', 'a'), + }) + check_parsing('\'abc\'\'def\'', 0, { + -- 0123456789 + ast = { + 'SingleQuotedString(val="abc\'def"):0:0:\'abc\'\'def\'', + }, + }, { + hl('SingleQuote', '\''), + hl('SingleQuotedBody', 'abc'), + hl('SingleQuotedQuote', '\'\''), + hl('SingleQuotedBody', 'def'), + hl('SingleQuote', '\''), + }) + check_parsing('\'abc\'\'', 0, { + -- 012345 + ast = { + 'SingleQuotedString(val="abc\'"):0:0:\'abc\'\'', + }, + err = { + arg = '\'abc\'\'', + msg = 'E115: Missing single quote: %.*s', + }, + }, { + hl('InvalidSingleQuote', '\''), + hl('InvalidSingleQuotedBody', 'abc'), + hl('InvalidSingleQuotedQuote', '\'\''), + }) + check_parsing('\'\'\'\'\'\'\'\'', 0, { + -- 01234567 + ast = { + 'SingleQuotedString(val="\'\'\'"):0:0:\'\'\'\'\'\'\'\'', + }, + }, { + hl('SingleQuote', '\''), + hl('SingleQuotedQuote', '\'\''), + hl('SingleQuotedQuote', '\'\''), + hl('SingleQuotedQuote', '\'\''), + hl('SingleQuote', '\''), + }) + check_parsing('\'\'\'a\'\'\'\'bc\'', 0, { + -- 01234567890 + -- 0 1 + ast = { + 'SingleQuotedString(val="\'a\'\'bc"):0:0:\'\'\'a\'\'\'\'bc\'', + }, + }, { + hl('SingleQuote', '\''), + hl('SingleQuotedQuote', '\'\''), + hl('SingleQuotedBody', 'a'), + hl('SingleQuotedQuote', '\'\''), + hl('SingleQuotedQuote', '\'\''), + hl('SingleQuotedBody', 'bc'), + hl('SingleQuote', '\''), + }) + check_parsing('"\\"\\"\\"\\""', 0, { + -- 0123456789 + ast = { + 'DoubleQuotedString(val="\\"\\"\\"\\""):0:0:"\\"\\"\\"\\""', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\"'), + hl('DoubleQuotedEscape', '\\"'), + hl('DoubleQuotedEscape', '\\"'), + hl('DoubleQuotedEscape', '\\"'), + hl('DoubleQuote', '"'), + }) + check_parsing('"abc\\"def\\"ghi\\"jkl\\"mno"', 0, { + -- 0123456789012345678901234 + -- 0 1 2 + ast = { + 'DoubleQuotedString(val="abc\\"def\\"ghi\\"jkl\\"mno"):0:0:"abc\\"def\\"ghi\\"jkl\\"mno"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedBody', 'abc'), + hl('DoubleQuotedEscape', '\\"'), + hl('DoubleQuotedBody', 'def'), + hl('DoubleQuotedEscape', '\\"'), + hl('DoubleQuotedBody', 'ghi'), + hl('DoubleQuotedEscape', '\\"'), + hl('DoubleQuotedBody', 'jkl'), + hl('DoubleQuotedEscape', '\\"'), + hl('DoubleQuotedBody', 'mno'), + hl('DoubleQuote', '"'), + }) + check_parsing('"\\b\\e\\f\\r\\t\\\\"', 0, { + -- 0123456789012345 + -- 0 1 + ast = { + [[DoubleQuotedString(val="\8\27\12\13\9\\"):0:0:"\b\e\f\r\t\\"]], + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\b'), + hl('DoubleQuotedEscape', '\\e'), + hl('DoubleQuotedEscape', '\\f'), + hl('DoubleQuotedEscape', '\\r'), + hl('DoubleQuotedEscape', '\\t'), + hl('DoubleQuotedEscape', '\\\\'), + hl('DoubleQuote', '"'), + }) + check_parsing('"\\n\n"', 0, { + -- 01234 + ast = { + 'DoubleQuotedString(val="\\\n\\\n"):0:0:"\\n\n"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\n'), + hl('DoubleQuotedBody', '\n'), + hl('DoubleQuote', '"'), + }) + check_parsing('"\\x00"', 0, { + -- 012345 + ast = { + 'DoubleQuotedString(val="\\0"):0:0:"\\x00"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\x00'), + hl('DoubleQuote', '"'), + }) + check_parsing('"\\xFF"', 0, { + -- 012345 + ast = { + 'DoubleQuotedString(val="\255"):0:0:"\\xFF"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\xFF'), + hl('DoubleQuote', '"'), + }) + check_parsing('"\\xF"', 0, { + -- 012345 + ast = { + 'DoubleQuotedString(val="\\15"):0:0:"\\xF"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\xF'), + hl('DoubleQuote', '"'), + }) + check_parsing('"\\u00AB"', 0, { + -- 01234567 + ast = { + 'DoubleQuotedString(val="«"):0:0:"\\u00AB"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\u00AB'), + hl('DoubleQuote', '"'), + }) + check_parsing('"\\U000000AB"', 0, { + -- 01234567 + ast = { + 'DoubleQuotedString(val="«"):0:0:"\\U000000AB"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\U000000AB'), + hl('DoubleQuote', '"'), + }) + check_parsing('"\\x"', 0, { + -- 0123 + ast = { + 'DoubleQuotedString(val="x"):0:0:"\\x"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedUnknownEscape', '\\x'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\x', 0, { + -- 012 + ast = { + 'DoubleQuotedString(val="x"):0:0:"\\x', + }, + err = { + arg = '"\\x', + msg = 'E114: Missing double quote: %.*s', + }, + }, { + hl('InvalidDoubleQuote', '"'), + hl('InvalidDoubleQuotedUnknownEscape', '\\x'), + }) + + check_parsing('"\\xF', 0, { + -- 0123 + ast = { + 'DoubleQuotedString(val="\\15"):0:0:"\\xF', + }, + err = { + arg = '"\\xF', + msg = 'E114: Missing double quote: %.*s', + }, + }, { + hl('InvalidDoubleQuote', '"'), + hl('InvalidDoubleQuotedEscape', '\\xF'), + }) + + check_parsing('"\\u"', 0, { + -- 0123 + ast = { + 'DoubleQuotedString(val="u"):0:0:"\\u"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedUnknownEscape', '\\u'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\u', 0, { + -- 012 + ast = { + 'DoubleQuotedString(val="u"):0:0:"\\u', + }, + err = { + arg = '"\\u', + msg = 'E114: Missing double quote: %.*s', + }, + }, { + hl('InvalidDoubleQuote', '"'), + hl('InvalidDoubleQuotedUnknownEscape', '\\u'), + }) + + check_parsing('"\\U', 0, { + -- 012 + ast = { + 'DoubleQuotedString(val="U"):0:0:"\\U', + }, + err = { + arg = '"\\U', + msg = 'E114: Missing double quote: %.*s', + }, + }, { + hl('InvalidDoubleQuote', '"'), + hl('InvalidDoubleQuotedUnknownEscape', '\\U'), + }) + + check_parsing('"\\U"', 0, { + -- 0123 + ast = { + 'DoubleQuotedString(val="U"):0:0:"\\U"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedUnknownEscape', '\\U'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\xFX"', 0, { + -- 012345 + ast = { + 'DoubleQuotedString(val="\\15X"):0:0:"\\xFX"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\xF'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\XFX"', 0, { + -- 012345 + ast = { + 'DoubleQuotedString(val="\\15X"):0:0:"\\XFX"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\XF'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\xX"', 0, { + -- 01234 + ast = { + 'DoubleQuotedString(val="xX"):0:0:"\\xX"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedUnknownEscape', '\\x'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\XX"', 0, { + -- 01234 + ast = { + 'DoubleQuotedString(val="XX"):0:0:"\\XX"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedUnknownEscape', '\\X'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\uX"', 0, { + -- 01234 + ast = { + 'DoubleQuotedString(val="uX"):0:0:"\\uX"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedUnknownEscape', '\\u'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\UX"', 0, { + -- 01234 + ast = { + 'DoubleQuotedString(val="UX"):0:0:"\\UX"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedUnknownEscape', '\\U'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\x0X"', 0, { + -- 012345 + ast = { + 'DoubleQuotedString(val="\\0X"):0:0:"\\x0X"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\x0'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\X0X"', 0, { + -- 012345 + ast = { + 'DoubleQuotedString(val="\\0X"):0:0:"\\X0X"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\X0'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\u0X"', 0, { + -- 012345 + ast = { + 'DoubleQuotedString(val="\\0X"):0:0:"\\u0X"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\u0'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\U0X"', 0, { + -- 012345 + ast = { + 'DoubleQuotedString(val="\\0X"):0:0:"\\U0X"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\U0'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\x00X"', 0, { + -- 0123456 + ast = { + 'DoubleQuotedString(val="\\0X"):0:0:"\\x00X"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\x00'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\X00X"', 0, { + -- 0123456 + ast = { + 'DoubleQuotedString(val="\\0X"):0:0:"\\X00X"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\X00'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\u00X"', 0, { + -- 0123456 + ast = { + 'DoubleQuotedString(val="\\0X"):0:0:"\\u00X"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\u00'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\U00X"', 0, { + -- 0123456 + ast = { + 'DoubleQuotedString(val="\\0X"):0:0:"\\U00X"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\U00'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\u000X"', 0, { + -- 01234567 + ast = { + 'DoubleQuotedString(val="\\0X"):0:0:"\\u000X"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\u000'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\U000X"', 0, { + -- 01234567 + ast = { + 'DoubleQuotedString(val="\\0X"):0:0:"\\U000X"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\U000'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\u0000X"', 0, { + -- 012345678 + ast = { + 'DoubleQuotedString(val="\\0X"):0:0:"\\u0000X"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\u0000'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\U0000X"', 0, { + -- 012345678 + ast = { + 'DoubleQuotedString(val="\\0X"):0:0:"\\U0000X"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\U0000'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\U00000X"', 0, { + -- 0123456789 + ast = { + 'DoubleQuotedString(val="\\0X"):0:0:"\\U00000X"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\U00000'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\U000000X"', 0, { + -- 01234567890 + -- 0 1 + ast = { + 'DoubleQuotedString(val="\\0X"):0:0:"\\U000000X"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\U000000'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\U0000000X"', 0, { + -- 012345678901 + -- 0 1 + ast = { + 'DoubleQuotedString(val="\\0X"):0:0:"\\U0000000X"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\U0000000'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\U00000000X"', 0, { + -- 0123456789012 + -- 0 1 + ast = { + 'DoubleQuotedString(val="\\0X"):0:0:"\\U00000000X"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\U00000000'), + hl('DoubleQuotedBody', 'X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\x000X"', 0, { + -- 01234567 + ast = { + 'DoubleQuotedString(val="\\0000X"):0:0:"\\x000X"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\x00'), + hl('DoubleQuotedBody', '0X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\X000X"', 0, { + -- 01234567 + ast = { + 'DoubleQuotedString(val="\\0000X"):0:0:"\\X000X"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\X00'), + hl('DoubleQuotedBody', '0X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\u00000X"', 0, { + -- 0123456789 + ast = { + 'DoubleQuotedString(val="\\0000X"):0:0:"\\u00000X"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\u0000'), + hl('DoubleQuotedBody', '0X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\U000000000X"', 0, { + -- 01234567890123 + -- 0 1 + ast = { + 'DoubleQuotedString(val="\\0000X"):0:0:"\\U000000000X"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\U00000000'), + hl('DoubleQuotedBody', '0X'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\0"', 0, { + -- 0123 + ast = { + 'DoubleQuotedString(val="\\0"):0:0:"\\0"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\0'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\00"', 0, { + -- 01234 + ast = { + 'DoubleQuotedString(val="\\0"):0:0:"\\00"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\00'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\000"', 0, { + -- 012345 + ast = { + 'DoubleQuotedString(val="\\0"):0:0:"\\000"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\000'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\0000"', 0, { + -- 0123456 + ast = { + 'DoubleQuotedString(val="\\0000"):0:0:"\\0000"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\000'), + hl('DoubleQuotedBody', '0'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\8"', 0, { + -- 0123 + ast = { + 'DoubleQuotedString(val="8"):0:0:"\\8"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedUnknownEscape', '\\8'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\08"', 0, { + -- 01234 + ast = { + 'DoubleQuotedString(val="\\0008"):0:0:"\\08"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\0'), + hl('DoubleQuotedBody', '8'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\008"', 0, { + -- 012345 + ast = { + 'DoubleQuotedString(val="\\0008"):0:0:"\\008"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\00'), + hl('DoubleQuotedBody', '8'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\0008"', 0, { + -- 0123456 + ast = { + 'DoubleQuotedString(val="\\0008"):0:0:"\\0008"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\000'), + hl('DoubleQuotedBody', '8'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\777"', 0, { + -- 012345 + ast = { + 'DoubleQuotedString(val="\255"):0:0:"\\777"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\777'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\050"', 0, { + -- 012345 + ast = { + 'DoubleQuotedString(val="\40"):0:0:"\\050"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\050'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\"', 0, { + -- 012345 + ast = { + 'DoubleQuotedString(val="\\21"):0:0:"\\"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedEscape', '\\'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\<', 0, { + -- 012 + ast = { + 'DoubleQuotedString(val="<"):0:0:"\\<', + }, + err = { + arg = '"\\<', + msg = 'E114: Missing double quote: %.*s', + }, + }, { + hl('InvalidDoubleQuote', '"'), + hl('InvalidDoubleQuotedUnknownEscape', '\\<'), + }) + + check_parsing('"\\<"', 0, { + -- 0123 + ast = { + 'DoubleQuotedString(val="<"):0:0:"\\<"', + }, + }, { + hl('DoubleQuote', '"'), + hl('DoubleQuotedUnknownEscape', '\\<'), + hl('DoubleQuote', '"'), + }) + + check_parsing('"\\ Date: Sun, 5 Nov 2017 21:06:12 +0300 Subject: tests: Add missing test cases --- test/functional/api/vim_spec.lua | 1197 +++++++++++++++++++++++++------------- 1 file changed, 777 insertions(+), 420 deletions(-) (limited to 'test/functional') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index bb7785657d..b904bd2a8f 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -12,8 +12,10 @@ local request = helpers.request local meth_pcall = helpers.meth_pcall local command = helpers.command +local REMOVE_THIS = global_helpers.REMOVE_THIS local intchar2lua = global_helpers.intchar2lua local format_string = global_helpers.format_string +local mergedicts_copy = global_helpers.mergedicts_copy describe('api', function() before_each(clear) @@ -717,6 +719,9 @@ describe('api', function() describe('nvim_parse_expression', function() local function simplify_east_api_node(line, east_api_node) + if east_api_node == NIL then + return nil + end if east_api_node.children then for k, v in pairs(east_api_node.children) do east_api_node.children[k] = simplify_east_api_node(line, v) @@ -806,31 +811,53 @@ describe('api', function() end return east_hl end - local function check_parsing(str, flags, exp_ast, exp_highlighting_fs) - if flags == 0 then - flags = "" - end - - local err, msg = pcall(function() - local east_api = meths.parse_expression(str, flags, true) - local east_hl = east_api.highlight - east_api.highlight = nil - local ast = simplify_east_api(str, east_api) - local hls = simplify_east_hl(str, east_hl) - eq(exp_ast, ast) - if exp_highlighting_fs then - local exp_highlighting = {} - local next_col = 0 - for i, h in ipairs(exp_highlighting_fs) do - exp_highlighting[i], next_col = h(next_col) + local FLAGS_TO_STR = { + [0] = "", + [1] = "m", + [2] = "E", + [3] = "mE", + } + local function check_parsing(str, exp_ast, exp_highlighting_fs, + nz_flags_exps) + nz_flags_exps = nz_flags_exps or {} + for _, flags in ipairs({0, 1, 2, 3}) do + local err, msg = pcall(function() + local east_api = meths.parse_expression(str, FLAGS_TO_STR[flags], true) + local east_hl = east_api.highlight + east_api.highlight = nil + local ast = simplify_east_api(str, east_api) + local hls = simplify_east_hl(str, east_hl) + local exps = { + ast = exp_ast, + hl_fs = exp_highlighting_fs, + } + local add_exps = nz_flags_exps[flags] + if not add_exps and flags == 3 then + add_exps = nz_flags_exps[1] or nz_flags_exps[2] end - eq(exp_highlighting, hls) + if add_exps then + if add_exps.ast then + exps.ast = mergedicts_copy(exps.ast, add_exps.ast) + end + if add_exps.hl_fs then + exps.hl_fs = mergedicts_copy(exps.hl_fs, add_exps.hl_fs) + end + end + eq(exps.ast, ast) + if exp_highlighting_fs then + local exp_highlighting = {} + local next_col = 0 + for i, h in ipairs(exps.hl_fs) do + exp_highlighting[i], next_col = h(next_col) + end + eq(exp_highlighting, hls) + end + end) + if not err then + msg = format_string('Error while processing test (%r, %s):\n%s', + str, FLAGS_TO_STR[flags], msg) + error(msg) end - end) - if not err then - msg = format_string('Error while processing test (%r, %s):\n%s', - str, flags, msg) - error(msg) end end local function hl(group, str, shift) @@ -844,14 +871,14 @@ describe('api', function() end end it('works with + and @a', function() - check_parsing('@a', 0, { + check_parsing('@a', { ast = { 'Register(name=a):0:0:@a', }, }, { hl('Register', '@a'), }) - check_parsing('+@a', 0, { + check_parsing('+@a', { ast = { { 'UnaryPlus:0:0:+', @@ -864,7 +891,7 @@ describe('api', function() hl('UnaryPlus', '+'), hl('Register', '@a'), }) - check_parsing('@a+@b', 0, { + check_parsing('@a+@b', { ast = { { 'BinaryPlus:0:2:+', @@ -879,7 +906,7 @@ describe('api', function() hl('BinaryPlus', '+'), hl('Register', '@b'), }) - check_parsing('@a+@b+@c', 0, { + check_parsing('@a+@b+@c', { ast = { { 'BinaryPlus:0:5:+', @@ -902,7 +929,7 @@ describe('api', function() hl('BinaryPlus', '+'), hl('Register', '@c'), }) - check_parsing('+@a+@b', 0, { + check_parsing('+@a+@b', { ast = { { 'BinaryPlus:0:3:+', @@ -923,7 +950,7 @@ describe('api', function() hl('BinaryPlus', '+'), hl('Register', '@b'), }) - check_parsing('+@a++@b', 0, { + check_parsing('+@a++@b', { ast = { { 'BinaryPlus:0:3:+', @@ -950,7 +977,7 @@ describe('api', function() hl('UnaryPlus', '+'), hl('Register', '@b'), }) - check_parsing('@a@b', 0, { + check_parsing('@a@b', { ast = { { 'OpMissing:0:2:', @@ -967,8 +994,20 @@ describe('api', function() }, { hl('Register', '@a'), hl('InvalidRegister', '@b'), + }, { + [1] = { + ast = { + err = REMOVE_THIS, + ast = { + 'Register(name=a):0:0:@a' + }, + }, + hl_fs = { + [2] = REMOVE_THIS, + }, + }, }) - check_parsing(' @a \t @b', 0, { + check_parsing(' @a \t @b', { ast = { { 'OpMissing:0:3:', @@ -986,8 +1025,21 @@ describe('api', function() hl('Register', '@a', 1), hl('InvalidSpacing', ' \t '), hl('Register', '@b'), + }, { + [1] = { + ast = { + err = REMOVE_THIS, + ast = { + 'Register(name=a):0:0: @a' + }, + }, + hl_fs = { + [2] = REMOVE_THIS, + [3] = REMOVE_THIS, + }, + }, }) - check_parsing('+', 0, { + check_parsing('+', { ast = { 'UnaryPlus:0:0:+', }, @@ -998,7 +1050,7 @@ describe('api', function() }, { hl('UnaryPlus', '+'), }) - check_parsing(' +', 0, { + check_parsing(' +', { ast = { 'UnaryPlus:0:0: +', }, @@ -1009,7 +1061,7 @@ describe('api', function() }, { hl('UnaryPlus', '+', 1), }) - check_parsing('@a+ ', 0, { + check_parsing('@a+ ', { ast = { { 'BinaryPlus:0:2:+', @@ -1028,7 +1080,7 @@ describe('api', function() }) end) it('works with @a, + and parenthesis', function() - check_parsing('(@a)', 0, { + check_parsing('(@a)', { ast = { { 'Nested:0:0:(', @@ -1042,7 +1094,7 @@ describe('api', function() hl('Register', '@a'), hl('NestingParenthesis', ')'), }) - check_parsing('()', 0, { + check_parsing('()', { ast = { { 'Nested:0:0:(', @@ -1059,7 +1111,7 @@ describe('api', function() hl('NestingParenthesis', '('), hl('InvalidNestingParenthesis', ')'), }) - check_parsing(')', 0, { + check_parsing(')', { ast = { { 'Nested:0:0:', @@ -1075,7 +1127,7 @@ describe('api', function() }, { hl('InvalidNestingParenthesis', ')'), }) - check_parsing('+)', 0, { + check_parsing('+)', { ast = { { 'Nested:0:1:', @@ -1097,7 +1149,7 @@ describe('api', function() hl('UnaryPlus', '+'), hl('InvalidNestingParenthesis', ')'), }) - check_parsing('+@a(@b)', 0, { + check_parsing('+@a(@b)', { ast = { { 'UnaryPlus:0:0:+', @@ -1119,7 +1171,7 @@ describe('api', function() hl('Register', '@b'), hl('CallingParenthesis', ')'), }) - check_parsing('@a+@b(@c)', 0, { + check_parsing('@a+@b(@c)', { ast = { { 'BinaryPlus:0:2:+', @@ -1143,7 +1195,7 @@ describe('api', function() hl('Register', '@c'), hl('CallingParenthesis', ')'), }) - check_parsing('@a()', 0, { + check_parsing('@a()', { ast = { { 'Call:0:2:(', @@ -1157,7 +1209,7 @@ describe('api', function() hl('CallingParenthesis', '('), hl('CallingParenthesis', ')'), }) - check_parsing('@a ()', 0, { + check_parsing('@a ()', { ast = { { 'OpMissing:0:2:', @@ -1181,91 +1233,102 @@ describe('api', function() hl('InvalidSpacing', ' '), hl('NestingParenthesis', '('), hl('InvalidNestingParenthesis', ')'), - }) - check_parsing( - '@a + (@b)', 0, { + }, { + [1] = { ast = { - { - 'BinaryPlus:0:2: +', - children = { - 'Register(name=a):0:0:@a', - { - 'Nested:0:4: (', - children = { - 'Register(name=b):0:6:@b', - }, + err = REMOVE_THIS, + ast = { + 'Register(name=a):0:0:@a', + }, + }, + hl_fs = { + [2] = REMOVE_THIS, + [3] = REMOVE_THIS, + [4] = REMOVE_THIS, + }, + }, + }) + check_parsing('@a + (@b)', { + ast = { + { + 'BinaryPlus:0:2: +', + children = { + 'Register(name=a):0:0:@a', + { + 'Nested:0:4: (', + children = { + 'Register(name=b):0:6:@b', }, }, }, }, - }, { - hl('Register', '@a'), - hl('BinaryPlus', '+', 1), - hl('NestingParenthesis', '(', 1), - hl('Register', '@b'), - hl('NestingParenthesis', ')'), - }) - check_parsing( - '@a + (+@b)', 0, { - ast = { - { - 'BinaryPlus:0:2: +', - children = { - 'Register(name=a):0:0:@a', - { - 'Nested:0:4: (', - children = { - { - 'UnaryPlus:0:6:+', - children = { - 'Register(name=b):0:7:@b', - }, + }, + }, { + hl('Register', '@a'), + hl('BinaryPlus', '+', 1), + hl('NestingParenthesis', '(', 1), + hl('Register', '@b'), + hl('NestingParenthesis', ')'), + }) + check_parsing('@a + (+@b)', { + ast = { + { + 'BinaryPlus:0:2: +', + children = { + 'Register(name=a):0:0:@a', + { + 'Nested:0:4: (', + children = { + { + 'UnaryPlus:0:6:+', + children = { + 'Register(name=b):0:7:@b', }, }, }, }, }, }, - }, { - hl('Register', '@a'), - hl('BinaryPlus', '+', 1), - hl('NestingParenthesis', '(', 1), - hl('UnaryPlus', '+'), - hl('Register', '@b'), - hl('NestingParenthesis', ')'), - }) - check_parsing( - '@a + (@b + @c)', 0, { - ast = { - { - 'BinaryPlus:0:2: +', - children = { - 'Register(name=a):0:0:@a', - { - 'Nested:0:4: (', - children = { - { - 'BinaryPlus:0:8: +', - children = { - 'Register(name=b):0:6:@b', - 'Register(name=c):0:10: @c', - }, + }, + }, { + hl('Register', '@a'), + hl('BinaryPlus', '+', 1), + hl('NestingParenthesis', '(', 1), + hl('UnaryPlus', '+'), + hl('Register', '@b'), + hl('NestingParenthesis', ')'), + }) + check_parsing('@a + (@b + @c)', { + ast = { + { + 'BinaryPlus:0:2: +', + children = { + 'Register(name=a):0:0:@a', + { + 'Nested:0:4: (', + children = { + { + 'BinaryPlus:0:8: +', + children = { + 'Register(name=b):0:6:@b', + 'Register(name=c):0:10: @c', }, }, }, }, }, }, - }, { - hl('Register', '@a'), - hl('BinaryPlus', '+', 1), - hl('NestingParenthesis', '(', 1), - hl('Register', '@b'), - hl('BinaryPlus', '+', 1), - hl('Register', '@c', 1), - hl('NestingParenthesis', ')'), - }) - check_parsing('(@a)+@b', 0, { + }, + }, { + hl('Register', '@a'), + hl('BinaryPlus', '+', 1), + hl('NestingParenthesis', '(', 1), + hl('Register', '@b'), + hl('BinaryPlus', '+', 1), + hl('Register', '@c', 1), + hl('NestingParenthesis', ')'), + }) + check_parsing('(@a)+@b', { ast = { { 'BinaryPlus:0:4:+', @@ -1287,7 +1350,7 @@ describe('api', function() hl('BinaryPlus', '+'), hl('Register', '@b'), }) - check_parsing('@a+(@b)(@c)', 0, { + check_parsing('@a+(@b)(@c)', { -- 01234567890 ast = { { @@ -1317,7 +1380,7 @@ describe('api', function() hl('Register', '@c'), hl('CallingParenthesis', ')'), }) - check_parsing('@a+((@b))(@c)', 0, { + check_parsing('@a+((@b))(@c)', { -- 01234567890123456890123456789 -- 0 1 2 ast = { @@ -1355,7 +1418,7 @@ describe('api', function() hl('Register', '@c'), hl('CallingParenthesis', ')'), }) - check_parsing('@a+((@b))+@c', 0, { + check_parsing('@a+((@b))+@c', { -- 01234567890123456890123456789 -- 0 1 2 ast = { @@ -1393,7 +1456,7 @@ describe('api', function() hl('Register', '@c'), }) check_parsing( - '@a + (@b + @c) + @d(@e) + (+@f) + ((+@g(@h))(@j)(@k))(@l)', 0, {--[[ + '@a + (@b + @c) + @d(@e) + (+@f) + ((+@g(@h))(@j)(@k))(@l)', {--[[ | | | | | | | | || | | || | | ||| || || || || 000000000011111111112222222222333333333344444444445555555 012345678901234567890123456789012345678901234567890123456 @@ -1527,7 +1590,7 @@ describe('api', function() hl('Register', '@l'), hl('CallingParenthesis', ')'), }) - check_parsing('@a)', 0, { + check_parsing('@a)', { -- 012 ast = { { @@ -1545,7 +1608,7 @@ describe('api', function() hl('Register', '@a'), hl('InvalidNestingParenthesis', ')'), }) - check_parsing('(@a', 0, { + check_parsing('(@a', { -- 012 ast = { { @@ -1563,7 +1626,7 @@ describe('api', function() hl('NestingParenthesis', '('), hl('Register', '@a'), }) - check_parsing('@a(@b', 0, { + check_parsing('@a(@b', { -- 01234 ast = { { @@ -1583,7 +1646,7 @@ describe('api', function() hl('CallingParenthesis', '('), hl('Register', '@b'), }) - check_parsing('@a(@b, @c, @d, @e)', 0, { + check_parsing('@a(@b, @c, @d, @e)', { -- 012345678901234567 -- 0 1 ast = { @@ -1625,7 +1688,7 @@ describe('api', function() hl('Register', '@e', 1), hl('CallingParenthesis', ')'), }) - check_parsing('@a(@b(@c))', 0, { + check_parsing('@a(@b(@c))', { -- 01234567890123456789012345678901234567 -- 0 1 2 3 ast = { @@ -1652,7 +1715,7 @@ describe('api', function() hl('CallingParenthesis', ')'), hl('CallingParenthesis', ')'), }) - check_parsing('@a(@b(@c(@d(@e), @f(@g(@h), @i(@j)))))', 0, { + check_parsing('@a(@b(@c(@d(@e), @f(@g(@h), @i(@j)))))', { -- 01234567890123456789012345678901234567 -- 0 1 2 3 ast = { @@ -1742,14 +1805,14 @@ describe('api', function() }) end) it('works with variable names, including curly braces ones', function() - check_parsing('var', 0, { + check_parsing('var', { ast = { 'PlainIdentifier(scope=0,ident=var):0:0:var', }, }, { hl('IdentifierName', 'var'), }) - check_parsing('g:var', 0, { + check_parsing('g:var', { ast = { 'PlainIdentifier(scope=g,ident=var):0:0:g:var', }, @@ -1758,7 +1821,7 @@ describe('api', function() hl('IdentifierScopeDelimiter', ':'), hl('IdentifierName', 'var'), }) - check_parsing('g:', 0, { + check_parsing('g:', { ast = { 'PlainIdentifier(scope=g,ident=):0:0:g:', }, @@ -1766,7 +1829,7 @@ describe('api', function() hl('IdentifierScope', 'g'), hl('IdentifierScopeDelimiter', ':'), }) - check_parsing('{a}', 0, { + check_parsing('{a}', { -- 012 ast = { { @@ -1781,7 +1844,7 @@ describe('api', function() hl('IdentifierName', 'a'), hl('Curly', '}'), }) - check_parsing('{a:b}', 0, { + check_parsing('{a:b}', { -- 012 ast = { { @@ -1798,7 +1861,7 @@ describe('api', function() hl('IdentifierName', 'b'), hl('Curly', '}'), }) - check_parsing('{a:@b}', 0, { + check_parsing('{a:@b}', { -- 012345 ast = { { @@ -1825,7 +1888,7 @@ describe('api', function() hl('InvalidRegister', '@b'), hl('Curly', '}'), }) - check_parsing('{@a}', 0, { + check_parsing('{@a}', { ast = { { 'CurlyBracesIdentifier:0:0:{', @@ -1839,7 +1902,7 @@ describe('api', function() hl('Register', '@a'), hl('Curly', '}'), }) - check_parsing('{@a}{@b}', 0, { + check_parsing('{@a}{@b}', { -- 01234567 ast = { { @@ -1868,7 +1931,7 @@ describe('api', function() hl('Register', '@b'), hl('Curly', '}'), }) - check_parsing('g:{@a}', 0, { + check_parsing('g:{@a}', { -- 01234567 ast = { { @@ -1891,7 +1954,7 @@ describe('api', function() hl('Register', '@a'), hl('Curly', '}'), }) - check_parsing('{@a}_test', 0, { + check_parsing('{@a}_test', { -- 012345678 ast = { { @@ -1913,7 +1976,7 @@ describe('api', function() hl('Curly', '}'), hl('IdentifierName', '_test'), }) - check_parsing('g:{@a}_test', 0, { + check_parsing('g:{@a}_test', { -- 01234567890 ast = { { @@ -1943,7 +2006,7 @@ describe('api', function() hl('Curly', '}'), hl('IdentifierName', '_test'), }) - check_parsing('g:{@a}_test()', 0, { + check_parsing('g:{@a}_test()', { -- 0123456789012 ast = { { @@ -1980,7 +2043,7 @@ describe('api', function() hl('CallingParenthesis', '('), hl('CallingParenthesis', ')'), }) - check_parsing('{@a} ()', 0, { + check_parsing('{@a} ()', { -- 0123456789012 ast = { { @@ -2002,7 +2065,7 @@ describe('api', function() hl('CallingParenthesis', '(', 1), hl('CallingParenthesis', ')'), }) - check_parsing('g:{@a} ()', 0, { + check_parsing('g:{@a} ()', { -- 0123456789012 ast = { { @@ -2032,7 +2095,7 @@ describe('api', function() hl('CallingParenthesis', '(', 1), hl('CallingParenthesis', ')'), }) - check_parsing('{@a', 0, { + check_parsing('{@a', { -- 012 ast = { { @@ -2052,7 +2115,7 @@ describe('api', function() }) end) it('works with lambdas and dictionaries', function() - check_parsing('{}', 0, { + check_parsing('{}', { ast = { 'DictLiteral:0:0:{', }, @@ -2060,7 +2123,7 @@ describe('api', function() hl('Dict', '{'), hl('Dict', '}'), }) - check_parsing('{->@a}', 0, { + check_parsing('{->@a}', { ast = { { 'Lambda:0:0:{', @@ -2080,7 +2143,7 @@ describe('api', function() hl('Register', '@a'), hl('Lambda', '}'), }) - check_parsing('{->@a+@b}', 0, { + check_parsing('{->@a+@b}', { -- 012345678 ast = { { @@ -2109,7 +2172,7 @@ describe('api', function() hl('Register', '@b'), hl('Lambda', '}'), }) - check_parsing('{a->@a}', 0, { + check_parsing('{a->@a}', { -- 012345678 ast = { { @@ -2132,7 +2195,7 @@ describe('api', function() hl('Register', '@a'), hl('Lambda', '}'), }) - check_parsing('{a,b->@a}', 0, { + check_parsing('{a,b->@a}', { -- 012345678 ast = { { @@ -2163,7 +2226,7 @@ describe('api', function() hl('Register', '@a'), hl('Lambda', '}'), }) - check_parsing('{a,b,c->@a}', 0, { + check_parsing('{a,b,c->@a}', { -- 01234567890 ast = { { @@ -2202,7 +2265,7 @@ describe('api', function() hl('Register', '@a'), hl('Lambda', '}'), }) - check_parsing('{a,b,c,d->@a}', 0, { + check_parsing('{a,b,c,d->@a}', { -- 0123456789012 ast = { { @@ -2249,7 +2312,7 @@ describe('api', function() hl('Register', '@a'), hl('Lambda', '}'), }) - check_parsing('{a,b,c,d,->@a}', 0, { + check_parsing('{a,b,c,d,->@a}', { -- 01234567890123 ast = { { @@ -2302,7 +2365,7 @@ describe('api', function() hl('Register', '@a'), hl('Lambda', '}'), }) - check_parsing('{a,b->{c,d->{e,f->@a}}}', 0, { + check_parsing('{a,b->{c,d->{e,f->@a}}}', { -- 01234567890123456789012 -- 0 1 2 ast = { @@ -2380,7 +2443,7 @@ describe('api', function() hl('Lambda', '}'), hl('Lambda', '}'), }) - check_parsing('{a,b->c,d}', 0, { + check_parsing('{a,b->c,d}', { -- 0123456789 ast = { { @@ -2423,7 +2486,7 @@ describe('api', function() hl('IdentifierName', 'd'), hl('Lambda', '}'), }) - check_parsing('a,b,c,d', 0, { + check_parsing('a,b,c,d', { -- 0123456789 ast = { { @@ -2459,7 +2522,7 @@ describe('api', function() hl('InvalidComma', ','), hl('IdentifierName', 'd'), }) - check_parsing('a,b,c,d,', 0, { + check_parsing('a,b,c,d,', { -- 0123456789 ast = { { @@ -2501,7 +2564,7 @@ describe('api', function() hl('IdentifierName', 'd'), hl('InvalidComma', ','), }) - check_parsing(',', 0, { + check_parsing(',', { -- 0123456789 ast = { { @@ -2518,7 +2581,7 @@ describe('api', function() }, { hl('InvalidComma', ','), }) - check_parsing('{,a->@a}', 0, { + check_parsing('{,a->@a}', { -- 0123456789 ast = { { @@ -2552,7 +2615,7 @@ describe('api', function() hl('Register', '@a'), hl('Curly', '}'), }) - check_parsing('}', 0, { + check_parsing('}', { -- 0123456789 ast = { 'UnknownFigure:0:0:', @@ -2564,7 +2627,7 @@ describe('api', function() }, { hl('InvalidFigureBrace', '}'), }) - check_parsing('{->}', 0, { + check_parsing('{->}', { -- 0123456789 ast = { { @@ -2583,7 +2646,7 @@ describe('api', function() hl('Arrow', '->'), hl('InvalidLambda', '}'), }) - check_parsing('{a,b}', 0, { + check_parsing('{a,b}', { -- 0123456789 ast = { { @@ -2610,7 +2673,7 @@ describe('api', function() hl('IdentifierName', 'b'), hl('InvalidLambda', '}'), }) - check_parsing('{a,}', 0, { + check_parsing('{a,}', { -- 0123456789 ast = { { @@ -2635,7 +2698,7 @@ describe('api', function() hl('Comma', ','), hl('InvalidLambda', '}'), }) - check_parsing('{@a:@b}', 0, { + check_parsing('{@a:@b}', { -- 0123456789 ast = { { @@ -2658,7 +2721,7 @@ describe('api', function() hl('Register', '@b'), hl('Dict', '}'), }) - check_parsing('{@a:@b,@c:@d}', 0, { + check_parsing('{@a:@b,@c:@d}', { -- 0123456789012 -- 0 1 ast = { @@ -2698,7 +2761,7 @@ describe('api', function() hl('Register', '@d'), hl('Dict', '}'), }) - check_parsing('{@a:@b,@c:@d,@e:@f,}', 0, { + check_parsing('{@a:@b,@c:@d,@e:@f,}', { -- 01234567890123456789 -- 0 1 ast = { @@ -2760,7 +2823,7 @@ describe('api', function() hl('Comma', ','), hl('Dict', '}'), }) - check_parsing('{@a:@b,@c:@d,@e:@f,@g:}', 0, { + check_parsing('{@a:@b,@c:@d,@e:@f,@g:}', { -- 01234567890123456789012 -- 0 1 2 ast = { @@ -2834,7 +2897,7 @@ describe('api', function() hl('Colon', ':'), hl('InvalidDict', '}'), }) - check_parsing('{@a:@b,}', 0, { + check_parsing('{@a:@b,}', { -- 01234567890123 -- 0 1 ast = { @@ -2864,7 +2927,7 @@ describe('api', function() hl('Comma', ','), hl('Dict', '}'), }) - check_parsing('{({f -> g})(@h)(@i)}', 0, { + check_parsing('{({f -> g})(@h)(@i)}', { -- 01234567890123456789 -- 0 1 ast = { @@ -2920,7 +2983,7 @@ describe('api', function() hl('CallingParenthesis', ')'), hl('Curly', '}'), }) - check_parsing('a:{b()}c', 0, { + check_parsing('a:{b()}c', { -- 01234567 ast = { { @@ -2957,7 +3020,7 @@ describe('api', function() hl('Curly', '}'), hl('IdentifierName', 'c'), }) - check_parsing('a:{{b, c -> @d + @e + ({f -> g})(@h)}(@i)}j', 0, { + check_parsing('a:{{b, c -> @d + @e + ({f -> g})(@h)}(@i)}j', { -- 01234567890123456789012345678901234567890123456 -- 0 1 2 3 4 ast = { @@ -3067,7 +3130,7 @@ describe('api', function() hl('Curly', '}'), hl('IdentifierName', 'j'), }) - check_parsing('{@a + @b : @c + @d, @e + @f : @g + @i}', 0, { + check_parsing('{@a + @b : @c + @d, @e + @f : @g + @i}', { -- 01234567890123456789012345678901234567 -- 0 1 2 3 ast = { @@ -3139,7 +3202,7 @@ describe('api', function() hl('Register', '@i', 1), hl('Dict', '}'), }) - check_parsing('-> -> ->', 0, { + check_parsing('-> -> ->', { -- 01234567 ast = { { @@ -3170,7 +3233,7 @@ describe('api', function() hl('InvalidArrow', '->', 1), hl('InvalidArrow', '->', 1), }) - check_parsing('a -> b -> c -> d', 0, { + check_parsing('a -> b -> c -> d', { -- 0123456789012345 -- 0 1 ast = { @@ -3207,7 +3270,7 @@ describe('api', function() hl('InvalidArrow', '->', 1), hl('IdentifierName', 'd', 1), }) - check_parsing('{a -> b -> c}', 0, { + check_parsing('{a -> b -> c}', { -- 0123456789012 -- 0 1 ast = { @@ -3243,7 +3306,7 @@ describe('api', function() hl('IdentifierName', 'c', 1), hl('Lambda', '}'), }) - check_parsing('{a: -> b}', 0, { + check_parsing('{a: -> b}', { -- 012345678 ast = { { @@ -3272,7 +3335,7 @@ describe('api', function() hl('Curly', '}'), }) - check_parsing('{a:b -> b}', 0, { + check_parsing('{a:b -> b}', { -- 0123456789 ast = { { @@ -3302,7 +3365,7 @@ describe('api', function() hl('Curly', '}'), }) - check_parsing('{a#b -> b}', 0, { + check_parsing('{a#b -> b}', { -- 0123456789 ast = { { @@ -3329,7 +3392,7 @@ describe('api', function() hl('IdentifierName', 'b', 1), hl('Curly', '}'), }) - check_parsing('{a : b : c}', 0, { + check_parsing('{a : b : c}', { -- 01234567890 -- 0 1 ast = { @@ -3365,7 +3428,7 @@ describe('api', function() hl('IdentifierName', 'c', 1), hl('Dict', '}'), }) - check_parsing('{', 0, { + check_parsing('{', { -- 0 ast = { 'UnknownFigure:0:0:{', @@ -3377,7 +3440,7 @@ describe('api', function() }, { hl('FigureBrace', '{'), }) - check_parsing('{a', 0, { + check_parsing('{a', { -- 01 ast = { { @@ -3395,7 +3458,7 @@ describe('api', function() hl('FigureBrace', '{'), hl('IdentifierName', 'a'), }) - check_parsing('{a,b', 0, { + check_parsing('{a,b', { -- 0123 ast = { { @@ -3421,7 +3484,7 @@ describe('api', function() hl('Comma', ','), hl('IdentifierName', 'b'), }) - check_parsing('{a,b->', 0, { + check_parsing('{a,b->', { -- 012345 ast = { { @@ -3449,7 +3512,7 @@ describe('api', function() hl('IdentifierName', 'b'), hl('Arrow', '->'), }) - check_parsing('{a,b->c', 0, { + check_parsing('{a,b->c', { -- 0123456 ast = { { @@ -3483,7 +3546,7 @@ describe('api', function() hl('Arrow', '->'), hl('IdentifierName', 'c'), }) - check_parsing('{a : b', 0, { + check_parsing('{a : b', { -- 012345 ast = { { @@ -3509,7 +3572,7 @@ describe('api', function() hl('Colon', ':', 1), hl('IdentifierName', 'b', 1), }) - check_parsing('{a : b,', 0, { + check_parsing('{a : b,', { -- 0123456 ast = { { @@ -3543,7 +3606,7 @@ describe('api', function() }) end) it('works with ternary operator', function() - check_parsing('a ? b : c', 0, { + check_parsing('a ? b : c', { -- 012345678 ast = { { @@ -3567,7 +3630,7 @@ describe('api', function() hl('TernaryColon', ':', 1), hl('IdentifierName', 'c', 1), }) - check_parsing('@a?@b?@c:@d:@e', 0, { + check_parsing('@a?@b?@c:@d:@e', { -- 01234567890123 -- 0 1 ast = { @@ -3608,7 +3671,7 @@ describe('api', function() hl('TernaryColon', ':'), hl('Register', '@e'), }) - check_parsing('@a?@b:@c?@d:@e', 0, { + check_parsing('@a?@b:@c?@d:@e', { -- 01234567890123 -- 0 1 ast = { @@ -3649,7 +3712,7 @@ describe('api', function() hl('TernaryColon', ':'), hl('Register', '@e'), }) - check_parsing('@a?@b?@c?@d:@e?@f:@g:@h?@i:@j:@k', 0, { + check_parsing('@a?@b?@c?@d:@e?@f:@g:@h?@i:@j:@k', { -- 01234567890123456789012345678901 -- 0 1 2 3 ast = { @@ -3738,7 +3801,7 @@ describe('api', function() hl('TernaryColon', ':'), hl('Register', '@k'), }) - check_parsing('?', 0, { + check_parsing('?', { -- 0 ast = { { @@ -3757,7 +3820,7 @@ describe('api', function() hl('InvalidTernary', '?'), }) - check_parsing('?:', 0, { + check_parsing('?:', { -- 01 ast = { { @@ -3782,7 +3845,7 @@ describe('api', function() hl('InvalidTernaryColon', ':'), }) - check_parsing('?::', 0, { + check_parsing('?::', { -- 012 ast = { { @@ -3814,7 +3877,7 @@ describe('api', function() hl('InvalidColon', ':'), }) - check_parsing('a?b', 0, { + check_parsing('a?b', { -- 012 ast = { { @@ -3839,7 +3902,7 @@ describe('api', function() hl('Ternary', '?'), hl('IdentifierName', 'b'), }) - check_parsing('a?b:', 0, { + check_parsing('a?b:', { -- 0123 ast = { { @@ -3866,7 +3929,7 @@ describe('api', function() hl('IdentifierScopeDelimiter', ':'), }) - check_parsing('a?b::c', 0, { + check_parsing('a?b::c', { -- 012345 ast = { { @@ -3892,7 +3955,7 @@ describe('api', function() hl('IdentifierName', 'c'), }) - check_parsing('a?b :', 0, { + check_parsing('a?b :', { -- 01234 ast = { { @@ -3919,7 +3982,7 @@ describe('api', function() hl('TernaryColon', ':', 1), }) - check_parsing('(@a?@b:@c)?@d:@e', 0, { + check_parsing('(@a?@b:@c)?@d:@e', { -- 0123456789012345 -- 0 1 ast = { @@ -3968,7 +4031,7 @@ describe('api', function() hl('Register', '@e'), }) - check_parsing('(@a?@b:@c)?(@d?@e:@f):(@g?@h:@i)', 0, { + check_parsing('(@a?@b:@c)?(@d?@e:@f):(@g?@h:@i)', { -- 01234567890123456789012345678901 -- 0 1 2 3 ast = { @@ -4063,7 +4126,7 @@ describe('api', function() hl('NestingParenthesis', ')'), }) - check_parsing('(@a?@b:@c)?@d?@e:@f:@g?@h:@i', 0, { + check_parsing('(@a?@b:@c)?@d?@e:@f:@g?@h:@i', { -- 0123456789012345678901234567 -- 0 1 2 ast = { @@ -4143,7 +4206,7 @@ describe('api', function() hl('TernaryColon', ':'), hl('Register', '@i'), }) - check_parsing('a?b{cdef}g:h', 0, { + check_parsing('a?b{cdef}g:h', { -- 012345678901 -- 0 1 ast = { @@ -4189,7 +4252,7 @@ describe('api', function() hl('TernaryColon', ':'), hl('IdentifierName', 'h'), }) - check_parsing('a ? b : c : d', 0, { + check_parsing('a ? b : c : d', { -- 0123456789012 -- 0 1 ast = { @@ -4228,7 +4291,7 @@ describe('api', function() }) end) it('works with comparison operators', function() - check_parsing('a == b', 0, { + check_parsing('a == b', { -- 012345 ast = { { @@ -4245,7 +4308,7 @@ describe('api', function() hl('IdentifierName', 'b', 1), }) - check_parsing('a ==? b', 0, { + check_parsing('a ==? b', { -- 0123456 ast = { { @@ -4263,7 +4326,7 @@ describe('api', function() hl('IdentifierName', 'b', 1), }) - check_parsing('a ==# b', 0, { + check_parsing('a ==# b', { -- 0123456 ast = { { @@ -4281,7 +4344,7 @@ describe('api', function() hl('IdentifierName', 'b', 1), }) - check_parsing('a !=# b', 0, { + check_parsing('a !=# b', { -- 0123456 ast = { { @@ -4299,7 +4362,7 @@ describe('api', function() hl('IdentifierName', 'b', 1), }) - check_parsing('a <=# b', 0, { + check_parsing('a <=# b', { -- 0123456 ast = { { @@ -4317,7 +4380,7 @@ describe('api', function() hl('IdentifierName', 'b', 1), }) - check_parsing('a >=# b', 0, { + check_parsing('a >=# b', { -- 0123456 ast = { { @@ -4335,7 +4398,7 @@ describe('api', function() hl('IdentifierName', 'b', 1), }) - check_parsing('a ># b', 0, { + check_parsing('a ># b', { -- 012345 ast = { { @@ -4353,7 +4416,7 @@ describe('api', function() hl('IdentifierName', 'b', 1), }) - check_parsing('a <# b', 0, { + check_parsing('a <# b', { -- 012345 ast = { { @@ -4371,7 +4434,7 @@ describe('api', function() hl('IdentifierName', 'b', 1), }) - check_parsing('a is#b', 0, { + check_parsing('a is#b', { -- 012345 ast = { { @@ -4389,7 +4452,7 @@ describe('api', function() hl('IdentifierName', 'b'), }) - check_parsing('a is?b', 0, { + check_parsing('a is?b', { -- 012345 ast = { { @@ -4407,7 +4470,7 @@ describe('api', function() hl('IdentifierName', 'b'), }) - check_parsing('a isnot b', 0, { + check_parsing('a isnot b', { -- 012345678 ast = { { @@ -4424,7 +4487,7 @@ describe('api', function() hl('IdentifierName', 'b', 1), }) - check_parsing('a < b < c', 0, { + check_parsing('a < b < c', { -- 012345678 ast = { { @@ -4453,7 +4516,7 @@ describe('api', function() hl('IdentifierName', 'c', 1), }) - check_parsing('a < b <# c', 0, { + check_parsing('a < b <# c', { -- 012345678 ast = { { @@ -4483,7 +4546,7 @@ describe('api', function() hl('IdentifierName', 'c', 1), }) - check_parsing('a += b', 0, { + check_parsing('a += b', { -- 012345 ast = { { @@ -4510,7 +4573,7 @@ describe('api', function() hl('InvalidComparison', '='), hl('IdentifierName', 'b', 1), }) - check_parsing('a + b == c + d', 0, { + check_parsing('a + b == c + d', { -- 01234567890123 -- 0 1 ast = { @@ -4543,7 +4606,7 @@ describe('api', function() hl('BinaryPlus', '+', 1), hl('IdentifierName', 'd', 1), }) - check_parsing('+ a == + b', 0, { + check_parsing('+ a == + b', { -- 0123456789 ast = { { @@ -4573,7 +4636,7 @@ describe('api', function() }) end) it('works with concat/subscript', function() - check_parsing('.', 0, { + check_parsing('.', { -- 0 ast = { { @@ -4591,7 +4654,7 @@ describe('api', function() hl('InvalidConcatOrSubscript', '.'), }) - check_parsing('a.', 0, { + check_parsing('a.', { -- 01 ast = { { @@ -4610,7 +4673,7 @@ describe('api', function() hl('ConcatOrSubscript', '.'), }) - check_parsing('a.b', 0, { + check_parsing('a.b', { -- 012 ast = { { @@ -4627,7 +4690,7 @@ describe('api', function() hl('IdentifierKey', 'b'), }) - check_parsing('1.2', 0, { + check_parsing('1.2', { -- 012 ast = { 'Float(val=1.200000e+00):0:0:1.2', @@ -4636,7 +4699,7 @@ describe('api', function() hl('Float', '1.2'), }) - check_parsing('1.2 + 1.3e-5', 0, { + check_parsing('1.2 + 1.3e-5', { -- 012345678901 -- 0 1 ast = { @@ -4654,7 +4717,7 @@ describe('api', function() hl('Float', '1.3e-5', 1), }) - check_parsing('a . 1.2 + 1.3e-5', 0, { + check_parsing('a . 1.2 + 1.3e-5', { -- 0123456789012345 -- 0 1 ast = { @@ -4688,7 +4751,7 @@ describe('api', function() hl('Float', '1.3e-5', 1), }) - check_parsing('1.3e-5 + 1.2 . a', 0, { + check_parsing('1.3e-5 + 1.2 . a', { -- 0123456789012345 -- 0 1 ast = { @@ -4714,7 +4777,7 @@ describe('api', function() hl('IdentifierName', 'a', 1), }) - check_parsing('1.3e-5 + a . 1.2', 0, { + check_parsing('1.3e-5 + a . 1.2', { -- 0123456789012345 -- 0 1 ast = { @@ -4748,7 +4811,7 @@ describe('api', function() hl('IdentifierKey', '2'), }) - check_parsing('1.2.3', 0, { + check_parsing('1.2.3', { -- 01234 ast = { { @@ -4773,7 +4836,7 @@ describe('api', function() hl('IdentifierKey', '3'), }) - check_parsing('a.1.2', 0, { + check_parsing('a.1.2', { -- 01234 ast = { { @@ -4798,7 +4861,7 @@ describe('api', function() hl('IdentifierKey', '2'), }) - check_parsing('a . 1.2', 0, { + check_parsing('a . 1.2', { -- 0123456 ast = { { @@ -4823,7 +4886,7 @@ describe('api', function() hl('IdentifierKey', '2'), }) - check_parsing('+a . +b', 0, { + check_parsing('+a . +b', { -- 0123456 ast = { { @@ -4852,7 +4915,7 @@ describe('api', function() hl('IdentifierName', 'b'), }) - check_parsing('a. b', 0, { + check_parsing('a. b', { -- 0123 ast = { { @@ -4869,7 +4932,7 @@ describe('api', function() hl('IdentifierName', 'b', 1), }) - check_parsing('a. 1', 0, { + check_parsing('a. 1', { -- 0123 ast = { { @@ -4887,7 +4950,7 @@ describe('api', function() }) end) it('works with bracket subscripts', function() - check_parsing(':', 0, { + check_parsing(':', { -- 0 ast = { { @@ -4904,7 +4967,7 @@ describe('api', function() }, { hl('InvalidColon', ':'), }) - check_parsing('a[]', 0, { + check_parsing('a[]', { -- 012 ast = { { @@ -4923,7 +4986,7 @@ describe('api', function() hl('SubscriptBracket', '['), hl('InvalidSubscriptBracket', ']'), }) - check_parsing('a[b:]', 0, { + check_parsing('a[b:]', { -- 01234 ast = { { @@ -4942,7 +5005,7 @@ describe('api', function() hl('SubscriptBracket', ']'), }) - check_parsing('a[b:c]', 0, { + check_parsing('a[b:c]', { -- 012345 ast = { { @@ -4961,7 +5024,7 @@ describe('api', function() hl('IdentifierName', 'c'), hl('SubscriptBracket', ']'), }) - check_parsing('a[b : c]', 0, { + check_parsing('a[b : c]', { -- 01234567 ast = { { @@ -4987,7 +5050,7 @@ describe('api', function() hl('SubscriptBracket', ']'), }) - check_parsing('a[: b]', 0, { + check_parsing('a[: b]', { -- 012345 ast = { { @@ -5012,7 +5075,7 @@ describe('api', function() hl('SubscriptBracket', ']'), }) - check_parsing('a[b :]', 0, { + check_parsing('a[b :]', { -- 012345 ast = { { @@ -5035,7 +5098,7 @@ describe('api', function() hl('SubscriptColon', ':', 1), hl('SubscriptBracket', ']'), }) - check_parsing('a[b][c][d](e)(f)(g)', 0, { + check_parsing('a[b][c][d](e)(f)(g)', { -- 0123456789012345678 -- 0 1 ast = { @@ -5098,7 +5161,7 @@ describe('api', function() hl('IdentifierName', 'g'), hl('CallingParenthesis', ')'), }) - check_parsing('{a}{b}{c}[d][e][f]', 0, { + check_parsing('{a}{b}{c}[d][e][f]', { -- 012345678901234567 -- 0 1 ast = { @@ -5171,7 +5234,7 @@ describe('api', function() }) end) it('supports list literals', function() - check_parsing('[]', 0, { + check_parsing('[]', { -- 01 ast = { 'ListLiteral:0:0:[', @@ -5181,7 +5244,7 @@ describe('api', function() hl('List', ']'), }) - check_parsing('[a]', 0, { + check_parsing('[a]', { -- 012 ast = { { @@ -5197,7 +5260,7 @@ describe('api', function() hl('List', ']'), }) - check_parsing('[a, b]', 0, { + check_parsing('[a, b]', { -- 012345 ast = { { @@ -5221,7 +5284,7 @@ describe('api', function() hl('List', ']'), }) - check_parsing('[a, b, c]', 0, { + check_parsing('[a, b, c]', { -- 012345678 ast = { { @@ -5253,7 +5316,7 @@ describe('api', function() hl('List', ']'), }) - check_parsing('[a, b, c, ]', 0, { + check_parsing('[a, b, c, ]', { -- 01234567890 -- 0 1 ast = { @@ -5292,7 +5355,7 @@ describe('api', function() hl('List', ']', 1), }) - check_parsing('[a : b, c : d]', 0, { + check_parsing('[a : b, c : d]', { -- 01234567890123 -- 0 1 ast = { @@ -5337,7 +5400,7 @@ describe('api', function() hl('List', ']'), }) - check_parsing(']', 0, { + check_parsing(']', { -- 0 ast = { 'ListLiteral:0:0:', @@ -5350,7 +5413,7 @@ describe('api', function() hl('InvalidList', ']'), }) - check_parsing('a]', 0, { + check_parsing('a]', { -- 01 ast = { { @@ -5369,7 +5432,7 @@ describe('api', function() hl('InvalidList', ']'), }) - check_parsing('[] []', 0, { + check_parsing('[] []', { -- 01234 ast = { { @@ -5390,9 +5453,23 @@ describe('api', function() hl('InvalidSpacing', ' '), hl('List', '['), hl('List', ']'), + }, { + [1] = { + ast = { + err = REMOVE_THIS, + ast = { + 'ListLiteral:0:0:[', + }, + }, + hl_fs = { + [3] = REMOVE_THIS, + [4] = REMOVE_THIS, + [5] = REMOVE_THIS, + }, + }, }) - check_parsing('[][]', 0, { + check_parsing('[][]', { -- 0123 ast = { { @@ -5413,7 +5490,7 @@ describe('api', function() hl('InvalidSubscriptBracket', ']'), }) - check_parsing('[', 0, { + check_parsing('[', { -- 0 ast = { 'ListLiteral:0:0:[', @@ -5426,7 +5503,7 @@ describe('api', function() hl('List', '['), }) - check_parsing('[1', 0, { + check_parsing('[1', { -- 01 ast = { { @@ -5446,7 +5523,7 @@ describe('api', function() }) end) it('works with strings', function() - check_parsing('\'abc\'', 0, { + check_parsing('\'abc\'', { -- 01234 ast = { 'SingleQuotedString(val="abc"):0:0:\'abc\'', @@ -5456,7 +5533,7 @@ describe('api', function() hl('SingleQuotedBody', 'abc'), hl('SingleQuote', '\''), }) - check_parsing('"abc"', 0, { + check_parsing('"abc"', { -- 01234 ast = { 'DoubleQuotedString(val="abc"):0:0:"abc"', @@ -5466,7 +5543,7 @@ describe('api', function() hl('DoubleQuotedBody', 'abc'), hl('DoubleQuote', '"'), }) - check_parsing('\'\'', 0, { + check_parsing('\'\'', { -- 01 ast = { 'SingleQuotedString(val=""):0:0:\'\'', @@ -5475,7 +5552,7 @@ describe('api', function() hl('SingleQuote', '\''), hl('SingleQuote', '\''), }) - check_parsing('""', 0, { + check_parsing('""', { -- 01 ast = { 'DoubleQuotedString(val=""):0:0:""', @@ -5484,7 +5561,7 @@ describe('api', function() hl('DoubleQuote', '"'), hl('DoubleQuote', '"'), }) - check_parsing('"', 0, { + check_parsing('"', { -- 0 ast = { 'DoubleQuotedString(val=""):0:0:"', @@ -5496,7 +5573,7 @@ describe('api', function() }, { hl('InvalidDoubleQuote', '"'), }) - check_parsing('\'', 0, { + check_parsing('\'', { -- 0 ast = { 'SingleQuotedString(val=""):0:0:\'', @@ -5508,7 +5585,7 @@ describe('api', function() }, { hl('InvalidSingleQuote', '\''), }) - check_parsing('"a', 0, { + check_parsing('"a', { -- 01 ast = { 'DoubleQuotedString(val="a"):0:0:"a', @@ -5521,7 +5598,7 @@ describe('api', function() hl('InvalidDoubleQuote', '"'), hl('InvalidDoubleQuotedBody', 'a'), }) - check_parsing('\'a', 0, { + check_parsing('\'a', { -- 01 ast = { 'SingleQuotedString(val="a"):0:0:\'a', @@ -5534,7 +5611,7 @@ describe('api', function() hl('InvalidSingleQuote', '\''), hl('InvalidSingleQuotedBody', 'a'), }) - check_parsing('\'abc\'\'def\'', 0, { + check_parsing('\'abc\'\'def\'', { -- 0123456789 ast = { 'SingleQuotedString(val="abc\'def"):0:0:\'abc\'\'def\'', @@ -5546,7 +5623,7 @@ describe('api', function() hl('SingleQuotedBody', 'def'), hl('SingleQuote', '\''), }) - check_parsing('\'abc\'\'', 0, { + check_parsing('\'abc\'\'', { -- 012345 ast = { 'SingleQuotedString(val="abc\'"):0:0:\'abc\'\'', @@ -5560,7 +5637,7 @@ describe('api', function() hl('InvalidSingleQuotedBody', 'abc'), hl('InvalidSingleQuotedQuote', '\'\''), }) - check_parsing('\'\'\'\'\'\'\'\'', 0, { + check_parsing('\'\'\'\'\'\'\'\'', { -- 01234567 ast = { 'SingleQuotedString(val="\'\'\'"):0:0:\'\'\'\'\'\'\'\'', @@ -5572,7 +5649,7 @@ describe('api', function() hl('SingleQuotedQuote', '\'\''), hl('SingleQuote', '\''), }) - check_parsing('\'\'\'a\'\'\'\'bc\'', 0, { + check_parsing('\'\'\'a\'\'\'\'bc\'', { -- 01234567890 -- 0 1 ast = { @@ -5587,7 +5664,7 @@ describe('api', function() hl('SingleQuotedBody', 'bc'), hl('SingleQuote', '\''), }) - check_parsing('"\\"\\"\\"\\""', 0, { + check_parsing('"\\"\\"\\"\\""', { -- 0123456789 ast = { 'DoubleQuotedString(val="\\"\\"\\"\\""):0:0:"\\"\\"\\"\\""', @@ -5600,7 +5677,7 @@ describe('api', function() hl('DoubleQuotedEscape', '\\"'), hl('DoubleQuote', '"'), }) - check_parsing('"abc\\"def\\"ghi\\"jkl\\"mno"', 0, { + check_parsing('"abc\\"def\\"ghi\\"jkl\\"mno"', { -- 0123456789012345678901234 -- 0 1 2 ast = { @@ -5619,7 +5696,7 @@ describe('api', function() hl('DoubleQuotedBody', 'mno'), hl('DoubleQuote', '"'), }) - check_parsing('"\\b\\e\\f\\r\\t\\\\"', 0, { + check_parsing('"\\b\\e\\f\\r\\t\\\\"', { -- 0123456789012345 -- 0 1 ast = { @@ -5635,7 +5712,7 @@ describe('api', function() hl('DoubleQuotedEscape', '\\\\'), hl('DoubleQuote', '"'), }) - check_parsing('"\\n\n"', 0, { + check_parsing('"\\n\n"', { -- 01234 ast = { 'DoubleQuotedString(val="\\\n\\\n"):0:0:"\\n\n"', @@ -5646,7 +5723,7 @@ describe('api', function() hl('DoubleQuotedBody', '\n'), hl('DoubleQuote', '"'), }) - check_parsing('"\\x00"', 0, { + check_parsing('"\\x00"', { -- 012345 ast = { 'DoubleQuotedString(val="\\0"):0:0:"\\x00"', @@ -5656,7 +5733,7 @@ describe('api', function() hl('DoubleQuotedEscape', '\\x00'), hl('DoubleQuote', '"'), }) - check_parsing('"\\xFF"', 0, { + check_parsing('"\\xFF"', { -- 012345 ast = { 'DoubleQuotedString(val="\255"):0:0:"\\xFF"', @@ -5666,7 +5743,7 @@ describe('api', function() hl('DoubleQuotedEscape', '\\xFF'), hl('DoubleQuote', '"'), }) - check_parsing('"\\xF"', 0, { + check_parsing('"\\xF"', { -- 012345 ast = { 'DoubleQuotedString(val="\\15"):0:0:"\\xF"', @@ -5676,7 +5753,7 @@ describe('api', function() hl('DoubleQuotedEscape', '\\xF'), hl('DoubleQuote', '"'), }) - check_parsing('"\\u00AB"', 0, { + check_parsing('"\\u00AB"', { -- 01234567 ast = { 'DoubleQuotedString(val="«"):0:0:"\\u00AB"', @@ -5686,7 +5763,7 @@ describe('api', function() hl('DoubleQuotedEscape', '\\u00AB'), hl('DoubleQuote', '"'), }) - check_parsing('"\\U000000AB"', 0, { + check_parsing('"\\U000000AB"', { -- 01234567 ast = { 'DoubleQuotedString(val="«"):0:0:"\\U000000AB"', @@ -5696,7 +5773,7 @@ describe('api', function() hl('DoubleQuotedEscape', '\\U000000AB'), hl('DoubleQuote', '"'), }) - check_parsing('"\\x"', 0, { + check_parsing('"\\x"', { -- 0123 ast = { 'DoubleQuotedString(val="x"):0:0:"\\x"', @@ -5707,7 +5784,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\x', 0, { + check_parsing('"\\x', { -- 012 ast = { 'DoubleQuotedString(val="x"):0:0:"\\x', @@ -5721,7 +5798,7 @@ describe('api', function() hl('InvalidDoubleQuotedUnknownEscape', '\\x'), }) - check_parsing('"\\xF', 0, { + check_parsing('"\\xF', { -- 0123 ast = { 'DoubleQuotedString(val="\\15"):0:0:"\\xF', @@ -5735,7 +5812,7 @@ describe('api', function() hl('InvalidDoubleQuotedEscape', '\\xF'), }) - check_parsing('"\\u"', 0, { + check_parsing('"\\u"', { -- 0123 ast = { 'DoubleQuotedString(val="u"):0:0:"\\u"', @@ -5746,7 +5823,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\u', 0, { + check_parsing('"\\u', { -- 012 ast = { 'DoubleQuotedString(val="u"):0:0:"\\u', @@ -5760,7 +5837,7 @@ describe('api', function() hl('InvalidDoubleQuotedUnknownEscape', '\\u'), }) - check_parsing('"\\U', 0, { + check_parsing('"\\U', { -- 012 ast = { 'DoubleQuotedString(val="U"):0:0:"\\U', @@ -5774,7 +5851,7 @@ describe('api', function() hl('InvalidDoubleQuotedUnknownEscape', '\\U'), }) - check_parsing('"\\U"', 0, { + check_parsing('"\\U"', { -- 0123 ast = { 'DoubleQuotedString(val="U"):0:0:"\\U"', @@ -5785,7 +5862,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\xFX"', 0, { + check_parsing('"\\xFX"', { -- 012345 ast = { 'DoubleQuotedString(val="\\15X"):0:0:"\\xFX"', @@ -5797,7 +5874,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\XFX"', 0, { + check_parsing('"\\XFX"', { -- 012345 ast = { 'DoubleQuotedString(val="\\15X"):0:0:"\\XFX"', @@ -5809,7 +5886,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\xX"', 0, { + check_parsing('"\\xX"', { -- 01234 ast = { 'DoubleQuotedString(val="xX"):0:0:"\\xX"', @@ -5821,7 +5898,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\XX"', 0, { + check_parsing('"\\XX"', { -- 01234 ast = { 'DoubleQuotedString(val="XX"):0:0:"\\XX"', @@ -5833,7 +5910,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\uX"', 0, { + check_parsing('"\\uX"', { -- 01234 ast = { 'DoubleQuotedString(val="uX"):0:0:"\\uX"', @@ -5845,7 +5922,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\UX"', 0, { + check_parsing('"\\UX"', { -- 01234 ast = { 'DoubleQuotedString(val="UX"):0:0:"\\UX"', @@ -5857,7 +5934,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\x0X"', 0, { + check_parsing('"\\x0X"', { -- 012345 ast = { 'DoubleQuotedString(val="\\0X"):0:0:"\\x0X"', @@ -5869,7 +5946,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\X0X"', 0, { + check_parsing('"\\X0X"', { -- 012345 ast = { 'DoubleQuotedString(val="\\0X"):0:0:"\\X0X"', @@ -5881,7 +5958,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\u0X"', 0, { + check_parsing('"\\u0X"', { -- 012345 ast = { 'DoubleQuotedString(val="\\0X"):0:0:"\\u0X"', @@ -5893,7 +5970,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\U0X"', 0, { + check_parsing('"\\U0X"', { -- 012345 ast = { 'DoubleQuotedString(val="\\0X"):0:0:"\\U0X"', @@ -5905,7 +5982,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\x00X"', 0, { + check_parsing('"\\x00X"', { -- 0123456 ast = { 'DoubleQuotedString(val="\\0X"):0:0:"\\x00X"', @@ -5917,7 +5994,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\X00X"', 0, { + check_parsing('"\\X00X"', { -- 0123456 ast = { 'DoubleQuotedString(val="\\0X"):0:0:"\\X00X"', @@ -5929,7 +6006,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\u00X"', 0, { + check_parsing('"\\u00X"', { -- 0123456 ast = { 'DoubleQuotedString(val="\\0X"):0:0:"\\u00X"', @@ -5941,7 +6018,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\U00X"', 0, { + check_parsing('"\\U00X"', { -- 0123456 ast = { 'DoubleQuotedString(val="\\0X"):0:0:"\\U00X"', @@ -5953,7 +6030,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\u000X"', 0, { + check_parsing('"\\u000X"', { -- 01234567 ast = { 'DoubleQuotedString(val="\\0X"):0:0:"\\u000X"', @@ -5965,7 +6042,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\U000X"', 0, { + check_parsing('"\\U000X"', { -- 01234567 ast = { 'DoubleQuotedString(val="\\0X"):0:0:"\\U000X"', @@ -5977,7 +6054,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\u0000X"', 0, { + check_parsing('"\\u0000X"', { -- 012345678 ast = { 'DoubleQuotedString(val="\\0X"):0:0:"\\u0000X"', @@ -5989,7 +6066,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\U0000X"', 0, { + check_parsing('"\\U0000X"', { -- 012345678 ast = { 'DoubleQuotedString(val="\\0X"):0:0:"\\U0000X"', @@ -6001,7 +6078,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\U00000X"', 0, { + check_parsing('"\\U00000X"', { -- 0123456789 ast = { 'DoubleQuotedString(val="\\0X"):0:0:"\\U00000X"', @@ -6013,7 +6090,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\U000000X"', 0, { + check_parsing('"\\U000000X"', { -- 01234567890 -- 0 1 ast = { @@ -6026,7 +6103,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\U0000000X"', 0, { + check_parsing('"\\U0000000X"', { -- 012345678901 -- 0 1 ast = { @@ -6039,7 +6116,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\U00000000X"', 0, { + check_parsing('"\\U00000000X"', { -- 0123456789012 -- 0 1 ast = { @@ -6052,7 +6129,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\x000X"', 0, { + check_parsing('"\\x000X"', { -- 01234567 ast = { 'DoubleQuotedString(val="\\0000X"):0:0:"\\x000X"', @@ -6064,7 +6141,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\X000X"', 0, { + check_parsing('"\\X000X"', { -- 01234567 ast = { 'DoubleQuotedString(val="\\0000X"):0:0:"\\X000X"', @@ -6076,7 +6153,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\u00000X"', 0, { + check_parsing('"\\u00000X"', { -- 0123456789 ast = { 'DoubleQuotedString(val="\\0000X"):0:0:"\\u00000X"', @@ -6088,7 +6165,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\U000000000X"', 0, { + check_parsing('"\\U000000000X"', { -- 01234567890123 -- 0 1 ast = { @@ -6101,7 +6178,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\0"', 0, { + check_parsing('"\\0"', { -- 0123 ast = { 'DoubleQuotedString(val="\\0"):0:0:"\\0"', @@ -6112,7 +6189,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\00"', 0, { + check_parsing('"\\00"', { -- 01234 ast = { 'DoubleQuotedString(val="\\0"):0:0:"\\00"', @@ -6123,7 +6200,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\000"', 0, { + check_parsing('"\\000"', { -- 012345 ast = { 'DoubleQuotedString(val="\\0"):0:0:"\\000"', @@ -6134,7 +6211,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\0000"', 0, { + check_parsing('"\\0000"', { -- 0123456 ast = { 'DoubleQuotedString(val="\\0000"):0:0:"\\0000"', @@ -6146,7 +6223,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\8"', 0, { + check_parsing('"\\8"', { -- 0123 ast = { 'DoubleQuotedString(val="8"):0:0:"\\8"', @@ -6157,7 +6234,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\08"', 0, { + check_parsing('"\\08"', { -- 01234 ast = { 'DoubleQuotedString(val="\\0008"):0:0:"\\08"', @@ -6169,7 +6246,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\008"', 0, { + check_parsing('"\\008"', { -- 012345 ast = { 'DoubleQuotedString(val="\\0008"):0:0:"\\008"', @@ -6181,7 +6258,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\0008"', 0, { + check_parsing('"\\0008"', { -- 0123456 ast = { 'DoubleQuotedString(val="\\0008"):0:0:"\\0008"', @@ -6193,7 +6270,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\777"', 0, { + check_parsing('"\\777"', { -- 012345 ast = { 'DoubleQuotedString(val="\255"):0:0:"\\777"', @@ -6204,7 +6281,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\050"', 0, { + check_parsing('"\\050"', { -- 012345 ast = { 'DoubleQuotedString(val="\40"):0:0:"\\050"', @@ -6215,7 +6292,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\"', 0, { + check_parsing('"\\"', { -- 012345 ast = { 'DoubleQuotedString(val="\\21"):0:0:"\\"', @@ -6226,7 +6303,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\<', 0, { + check_parsing('"\\<', { -- 012 ast = { 'DoubleQuotedString(val="<"):0:0:"\\<', @@ -6240,7 +6317,7 @@ describe('api', function() hl('InvalidDoubleQuotedUnknownEscape', '\\<'), }) - check_parsing('"\\<"', 0, { + check_parsing('"\\<"', { -- 0123 ast = { 'DoubleQuotedString(val="<"):0:0:"\\<"', @@ -6251,7 +6328,7 @@ describe('api', function() hl('DoubleQuote', '"'), }) - check_parsing('"\\ Date: Mon, 6 Nov 2017 01:15:18 +0300 Subject: api/vim: Add “len” dictionary key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows determining where parsing ended which may be needed for e.g. parsing `:echo` with that API function. --- test/functional/api/vim_spec.lua | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'test/functional') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index b904bd2a8f..714b1988fb 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -799,6 +799,9 @@ describe('api', function() if east_api.ast then east_api.ast = {simplify_east_api_node(line, east_api.ast)} end + if east_api.len == #line then + east_api.len = nil + end return east_api end local function simplify_east_hl(line, east_hl) @@ -997,6 +1000,7 @@ describe('api', function() }, { [1] = { ast = { + len = 2, err = REMOVE_THIS, ast = { 'Register(name=a):0:0:@a' @@ -1028,6 +1032,7 @@ describe('api', function() }, { [1] = { ast = { + len = 6, err = REMOVE_THIS, ast = { 'Register(name=a):0:0: @a' @@ -1236,6 +1241,7 @@ describe('api', function() }, { [1] = { ast = { + len = 3, err = REMOVE_THIS, ast = { 'Register(name=a):0:0:@a', @@ -5456,6 +5462,7 @@ describe('api', function() }, { [1] = { ast = { + len = 3, err = REMOVE_THIS, ast = { 'ListLiteral:0:0:[', @@ -7135,6 +7142,7 @@ describe('api', function() }, { [1] = { ast = { + len = 4, err = REMOVE_THIS, ast = { 'Option(scope=0,ident=xxx):0:0:&xxx', @@ -7520,6 +7528,7 @@ describe('api', function() }, { [1] = { ast = { + len = 1, err = REMOVE_THIS, ast = { 'Integer(val=1):0:0:1', @@ -7652,6 +7661,7 @@ describe('api', function() end) it('respects highlight argument', function() eq({ + len = 1, ast = { ivalue = 1, len = 1, @@ -7660,6 +7670,7 @@ describe('api', function() }, }, meths.parse_expression('1', '', false)) eq({ + len = 1, ast = { ivalue = 1, len = 1, @@ -7674,6 +7685,7 @@ describe('api', function() it('works (KLEE tests)', function() check_parsing('\0002&A:\000', { ast = {}, + len = 0, err = { arg = '\0002&A:\0', msg = 'E15: Expected value, got EOC: %.*s', @@ -7682,6 +7694,7 @@ describe('api', function() }, { [2] = { ast = { + len = REMOVE_THIS, ast = { { 'Colon:0:4::', @@ -7711,6 +7724,7 @@ describe('api', function() }, [3] = { ast = { + len = 2, ast = { 'Integer(val=2):0:1:2', }, @@ -7754,6 +7768,7 @@ describe('api', function() check_parsing('|"\\U\\', { -- 01234 ast = {}, + len = 0, err = { arg = '|"\\U\\', msg = 'E15: Expected value, got EOC: %.*s', @@ -7762,6 +7777,7 @@ describe('api', function() }, { [2] = { ast = { + len = REMOVE_THIS, ast = { { 'Or:0:0:|', @@ -7786,6 +7802,7 @@ describe('api', function() check_parsing('|"\\e"', { -- 01234 ast = {}, + len = 0, err = { arg = '|"\\e"', msg = 'E15: Expected value, got EOC: %.*s', @@ -7794,6 +7811,7 @@ describe('api', function() }, { [2] = { ast = { + len = REMOVE_THIS, ast = { { 'Or:0:0:|', @@ -7818,6 +7836,7 @@ describe('api', function() check_parsing('|\029', { -- 01 ast = {}, + len = 0, err = { arg = '|\029', msg = 'E15: Expected value, got EOC: %.*s', @@ -7826,6 +7845,7 @@ describe('api', function() }, { [2] = { ast = { + len = REMOVE_THIS, ast = { { 'Or:0:0:|', @@ -7892,6 +7912,7 @@ describe('api', function() }, { [1] = { ast = { + len = 1, ast = { 'UnknownFigure:0:0:', }, @@ -7917,6 +7938,7 @@ describe('api', function() }, }, }, + len = 2, err = { arg = ':?\000\000\000\000\000\000\000', msg = 'E15: Colon outside of dictionary or ternary operator: %.*s', @@ -7926,6 +7948,9 @@ describe('api', function() hl('InvalidTernary', '?'), }, { [2] = { + ast = { + len = REMOVE_THIS, + }, hl_fs = { [3] = hl('InvalidSpacing', '\0'), [4] = hl('InvalidSpacing', '\0'), -- cgit From 556451a7f2fd513db33b9d7ac1b653d356b7b915 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 12 Nov 2017 16:59:36 +0300 Subject: unittests,syntax: Check for sanity of highlight_init_cmdline Also fixes some errors found. --- test/functional/ui/cmdline_highlight_spec.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'test/functional') diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua index b16b4a5602..ab195f9f1e 100644 --- a/test/functional/ui/cmdline_highlight_spec.lua +++ b/test/functional/ui/cmdline_highlight_spec.lua @@ -899,7 +899,6 @@ describe('Expressions coloring support', function() ]]) end) -- FIXME: Test expr coloring when using -u NORC and -u NONE. - -- FIXME: Test all highlight groups, using long expression. -- FIXME: Test different ways of triggering expression highlighting (:=, -- i=, :e, "=). end) -- cgit From c287893225bad586af486b37546f5982e5b1cd03 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 19 Nov 2017 19:22:54 +0300 Subject: viml/parser/expressions,unittests: Do better testing, fix found issues --- test/functional/ui/cmdline_highlight_spec.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'test/functional') diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua index ab195f9f1e..023673738d 100644 --- a/test/functional/ui/cmdline_highlight_spec.lua +++ b/test/functional/ui/cmdline_highlight_spec.lua @@ -901,4 +901,5 @@ describe('Expressions coloring support', function() -- FIXME: Test expr coloring when using -u NORC and -u NONE. -- FIXME: Test different ways of triggering expression highlighting (:=, -- i=, :e, "=). + -- FIXME: Test with various invalid unicode and multibyte characters. end) -- cgit From 53fa435a1f081e1d7e1890e3ecd978b85c39e0eb Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 19 Nov 2017 19:34:15 +0300 Subject: functests: Fix ui/cmdline test --- test/functional/ui/cmdline_spec.lua | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'test/functional') diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua index 0f8302b036..136ab09d4f 100644 --- a/test/functional/ui/cmdline_spec.lua +++ b/test/functional/ui/cmdline_spec.lua @@ -226,7 +226,11 @@ describe('external cmdline', function() prompt = "", special = {'"', true}, },{ - content = { { {}, "1+2" } }, + content = { + { {}, "1" }, + { {}, "+" }, + { {}, "2" }, + }, firstc = "=", indent = 0, pos = 3, @@ -303,7 +307,7 @@ describe('external cmdline', function() pos = 0, prompt = "", }}, cmdline) - eq({{{{}, 'function Foo()'}}}, block) + eq({ { { {}, 'function Foo()'} } }, block) end) feed('line1') @@ -314,8 +318,8 @@ describe('external cmdline', function() ~ | | ]], nil, nil, function() - eq({{{{}, 'function Foo()'}}, - {{{}, ' line1'}}}, block) + eq({ { { {}, 'function Foo()'} }, + { { {}, ' line1'} } }, block) end) block = {} @@ -327,8 +331,8 @@ describe('external cmdline', function() ~ | ^ | ]], nil, nil, function() - eq({{{{}, 'function Foo()'}}, - {{{}, ' line1'}}}, block) + eq({ { { {}, 'function Foo()'} }, + { { {}, ' line1'} } }, block) end) -- cgit From a94255a7ac22649311f858e39b217543d0d7e5e8 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 19 Nov 2017 20:20:06 +0300 Subject: tests: Use single test file for unit and functional parser tests --- test/functional/api/vim_spec.lua | 7132 +------------------------------------- 1 file changed, 37 insertions(+), 7095 deletions(-) (limited to 'test/functional') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 714b1988fb..3939bc9b52 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -766,6 +766,11 @@ describe('api', function() elseif typ == 'Environment' then typ = ('%s(ident=%s)'):format(typ, east_api_node.ident) east_api_node.ident = nil + elseif typ == 'Assignment' then + local aug = east_api_node.augmentation + if aug == '' then aug = 'Plain' end + typ = ('%s(%s)'):format(typ, aug) + east_api_node.augmentation = nil end typ = ('%s:%u:%u:%s'):format( typ, east_api_node.start[1], east_api_node.start[2], @@ -798,6 +803,9 @@ describe('api', function() end if east_api.ast then east_api.ast = {simplify_east_api_node(line, east_api.ast)} + if #east_api.ast == 0 then + east_api.ast = nil + end end if east_api.len == #line then east_api.len = nil @@ -819,11 +827,19 @@ describe('api', function() [1] = "m", [2] = "E", [3] = "mE", + [4] = "l", + [5] = "lm", + [6] = "lE", + [7] = "lmE", } - local function check_parsing(str, exp_ast, exp_highlighting_fs, - nz_flags_exps) + local function _check_parsing(opts, str, exp_ast, exp_highlighting_fs, + nz_flags_exps) + if type(str) ~= 'string' then + return + end + local zflags = opts.flags[1] nz_flags_exps = nz_flags_exps or {} - for _, flags in ipairs({0, 1, 2, 3}) do + for _, flags in ipairs(opts.flags) do local err, msg = pcall(function() local east_api = meths.parse_expression(str, FLAGS_TO_STR[flags], true) local east_hl = east_api.highlight @@ -835,8 +851,8 @@ describe('api', function() hl_fs = exp_highlighting_fs, } local add_exps = nz_flags_exps[flags] - if not add_exps and flags == 3 then - add_exps = nz_flags_exps[1] or nz_flags_exps[2] + if not add_exps and flags == 3 + zflags then + add_exps = nz_flags_exps[1 + zflags] or nz_flags_exps[2 + zflags] end if add_exps then if add_exps.ast then @@ -873,7096 +889,22 @@ describe('api', function() str)), (col + #str) end end - it('works with + and @a', function() - check_parsing('@a', { - ast = { - 'Register(name=a):0:0:@a', - }, - }, { - hl('Register', '@a'), - }) - check_parsing('+@a', { - ast = { - { - 'UnaryPlus:0:0:+', - children = { - 'Register(name=a):0:1:@a', - }, - }, - }, - }, { - hl('UnaryPlus', '+'), - hl('Register', '@a'), - }) - check_parsing('@a+@b', { - ast = { - { - 'BinaryPlus:0:2:+', - children = { - 'Register(name=a):0:0:@a', - 'Register(name=b):0:3:@b', - }, - }, - }, - }, { - hl('Register', '@a'), - hl('BinaryPlus', '+'), - hl('Register', '@b'), - }) - check_parsing('@a+@b+@c', { - ast = { - { - 'BinaryPlus:0:5:+', - children = { - { - 'BinaryPlus:0:2:+', - children = { - 'Register(name=a):0:0:@a', - 'Register(name=b):0:3:@b', - }, - }, - 'Register(name=c):0:6:@c', - }, - }, - }, - }, { - hl('Register', '@a'), - hl('BinaryPlus', '+'), - hl('Register', '@b'), - hl('BinaryPlus', '+'), - hl('Register', '@c'), - }) - check_parsing('+@a+@b', { - ast = { - { - 'BinaryPlus:0:3:+', - children = { - { - 'UnaryPlus:0:0:+', - children = { - 'Register(name=a):0:1:@a', - }, - }, - 'Register(name=b):0:4:@b', - }, - }, - }, - }, { - hl('UnaryPlus', '+'), - hl('Register', '@a'), - hl('BinaryPlus', '+'), - hl('Register', '@b'), - }) - check_parsing('+@a++@b', { - ast = { - { - 'BinaryPlus:0:3:+', - children = { - { - 'UnaryPlus:0:0:+', - children = { - 'Register(name=a):0:1:@a', - }, - }, - { - 'UnaryPlus:0:4:+', - children = { - 'Register(name=b):0:5:@b', - }, - }, - }, - }, - }, - }, { - hl('UnaryPlus', '+'), - hl('Register', '@a'), - hl('BinaryPlus', '+'), - hl('UnaryPlus', '+'), - hl('Register', '@b'), - }) - check_parsing('@a@b', { - ast = { - { - 'OpMissing:0:2:', - children = { - 'Register(name=a):0:0:@a', - 'Register(name=b):0:2:@b', - }, - }, - }, - err = { - arg = '@b', - msg = 'E15: Missing operator: %.*s', - }, - }, { - hl('Register', '@a'), - hl('InvalidRegister', '@b'), - }, { - [1] = { - ast = { - len = 2, - err = REMOVE_THIS, - ast = { - 'Register(name=a):0:0:@a' - }, - }, - hl_fs = { - [2] = REMOVE_THIS, - }, - }, - }) - check_parsing(' @a \t @b', { - ast = { - { - 'OpMissing:0:3:', - children = { - 'Register(name=a):0:0: @a', - 'Register(name=b):0:3: \t @b', - }, - }, - }, - err = { - arg = '@b', - msg = 'E15: Missing operator: %.*s', - }, - }, { - hl('Register', '@a', 1), - hl('InvalidSpacing', ' \t '), - hl('Register', '@b'), - }, { - [1] = { - ast = { - len = 6, - err = REMOVE_THIS, - ast = { - 'Register(name=a):0:0: @a' - }, - }, - hl_fs = { - [2] = REMOVE_THIS, - [3] = REMOVE_THIS, - }, - }, - }) - check_parsing('+', { - ast = { - 'UnaryPlus:0:0:+', - }, - err = { - arg = '', - msg = 'E15: Expected value, got EOC: %.*s', - }, - }, { - hl('UnaryPlus', '+'), - }) - check_parsing(' +', { - ast = { - 'UnaryPlus:0:0: +', - }, - err = { - arg = '', - msg = 'E15: Expected value, got EOC: %.*s', - }, - }, { - hl('UnaryPlus', '+', 1), - }) - check_parsing('@a+ ', { - ast = { - { - 'BinaryPlus:0:2:+', - children = { - 'Register(name=a):0:0:@a', - }, - }, - }, - err = { - arg = '', - msg = 'E15: Expected value, got EOC: %.*s', - }, - }, { - hl('Register', '@a'), - hl('BinaryPlus', '+'), - }) - end) - it('works with @a, + and parenthesis', function() - check_parsing('(@a)', { - ast = { - { - 'Nested:0:0:(', - children = { - 'Register(name=a):0:1:@a', - }, - }, - }, - }, { - hl('NestingParenthesis', '('), - hl('Register', '@a'), - hl('NestingParenthesis', ')'), - }) - check_parsing('()', { - ast = { - { - 'Nested:0:0:(', - children = { - 'Missing:0:1:', - }, - }, - }, - err = { - arg = ')', - msg = 'E15: Expected value, got parenthesis: %.*s', - }, - }, { - hl('NestingParenthesis', '('), - hl('InvalidNestingParenthesis', ')'), - }) - check_parsing(')', { - ast = { - { - 'Nested:0:0:', - children = { - 'Missing:0:0:', - }, - }, - }, - err = { - arg = ')', - msg = 'E15: Expected value, got parenthesis: %.*s', - }, - }, { - hl('InvalidNestingParenthesis', ')'), - }) - check_parsing('+)', { - ast = { - { - 'Nested:0:1:', - children = { - { - 'UnaryPlus:0:0:+', - children = { - 'Missing:0:1:', - }, - }, - }, - }, - }, - err = { - arg = ')', - msg = 'E15: Expected value, got parenthesis: %.*s', - }, - }, { - hl('UnaryPlus', '+'), - hl('InvalidNestingParenthesis', ')'), - }) - check_parsing('+@a(@b)', { - ast = { - { - 'UnaryPlus:0:0:+', - children = { - { - 'Call:0:3:(', - children = { - 'Register(name=a):0:1:@a', - 'Register(name=b):0:4:@b', - }, - }, - }, - }, - }, - }, { - hl('UnaryPlus', '+'), - hl('Register', '@a'), - hl('CallingParenthesis', '('), - hl('Register', '@b'), - hl('CallingParenthesis', ')'), - }) - check_parsing('@a+@b(@c)', { - ast = { - { - 'BinaryPlus:0:2:+', - children = { - 'Register(name=a):0:0:@a', - { - 'Call:0:5:(', - children = { - 'Register(name=b):0:3:@b', - 'Register(name=c):0:6:@c', - }, - }, - }, - }, - }, - }, { - hl('Register', '@a'), - hl('BinaryPlus', '+'), - hl('Register', '@b'), - hl('CallingParenthesis', '('), - hl('Register', '@c'), - hl('CallingParenthesis', ')'), - }) - check_parsing('@a()', { - ast = { - { - 'Call:0:2:(', - children = { - 'Register(name=a):0:0:@a', - }, - }, - }, - }, { - hl('Register', '@a'), - hl('CallingParenthesis', '('), - hl('CallingParenthesis', ')'), - }) - check_parsing('@a ()', { - ast = { - { - 'OpMissing:0:2:', - children = { - 'Register(name=a):0:0:@a', - { - 'Nested:0:2: (', - children = { - 'Missing:0:4:', - }, - }, - }, - }, - }, - err = { - arg = '()', - msg = 'E15: Missing operator: %.*s', - }, - }, { - hl('Register', '@a'), - hl('InvalidSpacing', ' '), - hl('NestingParenthesis', '('), - hl('InvalidNestingParenthesis', ')'), - }, { - [1] = { - ast = { - len = 3, - err = REMOVE_THIS, - ast = { - 'Register(name=a):0:0:@a', - }, - }, - hl_fs = { - [2] = REMOVE_THIS, - [3] = REMOVE_THIS, - [4] = REMOVE_THIS, - }, - }, - }) - check_parsing('@a + (@b)', { - ast = { - { - 'BinaryPlus:0:2: +', - children = { - 'Register(name=a):0:0:@a', - { - 'Nested:0:4: (', - children = { - 'Register(name=b):0:6:@b', - }, - }, - }, - }, - }, - }, { - hl('Register', '@a'), - hl('BinaryPlus', '+', 1), - hl('NestingParenthesis', '(', 1), - hl('Register', '@b'), - hl('NestingParenthesis', ')'), - }) - check_parsing('@a + (+@b)', { - ast = { - { - 'BinaryPlus:0:2: +', - children = { - 'Register(name=a):0:0:@a', - { - 'Nested:0:4: (', - children = { - { - 'UnaryPlus:0:6:+', - children = { - 'Register(name=b):0:7:@b', - }, - }, - }, - }, - }, - }, - }, - }, { - hl('Register', '@a'), - hl('BinaryPlus', '+', 1), - hl('NestingParenthesis', '(', 1), - hl('UnaryPlus', '+'), - hl('Register', '@b'), - hl('NestingParenthesis', ')'), - }) - check_parsing('@a + (@b + @c)', { - ast = { - { - 'BinaryPlus:0:2: +', - children = { - 'Register(name=a):0:0:@a', - { - 'Nested:0:4: (', - children = { - { - 'BinaryPlus:0:8: +', - children = { - 'Register(name=b):0:6:@b', - 'Register(name=c):0:10: @c', - }, - }, - }, - }, - }, - }, - }, - }, { - hl('Register', '@a'), - hl('BinaryPlus', '+', 1), - hl('NestingParenthesis', '(', 1), - hl('Register', '@b'), - hl('BinaryPlus', '+', 1), - hl('Register', '@c', 1), - hl('NestingParenthesis', ')'), - }) - check_parsing('(@a)+@b', { - ast = { - { - 'BinaryPlus:0:4:+', - children = { - { - 'Nested:0:0:(', - children = { - 'Register(name=a):0:1:@a', - }, - }, - 'Register(name=b):0:5:@b', - }, - }, - }, - }, { - hl('NestingParenthesis', '('), - hl('Register', '@a'), - hl('NestingParenthesis', ')'), - hl('BinaryPlus', '+'), - hl('Register', '@b'), - }) - check_parsing('@a+(@b)(@c)', { - -- 01234567890 - ast = { - { - 'BinaryPlus:0:2:+', - children = { - 'Register(name=a):0:0:@a', - { - 'Call:0:7:(', - children = { - { - 'Nested:0:3:(', - children = { 'Register(name=b):0:4:@b' }, - }, - 'Register(name=c):0:8:@c', - }, - }, - }, - }, - }, - }, { - hl('Register', '@a'), - hl('BinaryPlus', '+'), - hl('NestingParenthesis', '('), - hl('Register', '@b'), - hl('NestingParenthesis', ')'), - hl('CallingParenthesis', '('), - hl('Register', '@c'), - hl('CallingParenthesis', ')'), - }) - check_parsing('@a+((@b))(@c)', { - -- 01234567890123456890123456789 - -- 0 1 2 - ast = { - { - 'BinaryPlus:0:2:+', - children = { - 'Register(name=a):0:0:@a', - { - 'Call:0:9:(', - children = { - { - 'Nested:0:3:(', - children = { - { - 'Nested:0:4:(', - children = { 'Register(name=b):0:5:@b' } - }, - }, - }, - 'Register(name=c):0:10:@c', - }, - }, - }, - }, - }, - }, { - hl('Register', '@a'), - hl('BinaryPlus', '+'), - hl('NestingParenthesis', '('), - hl('NestingParenthesis', '('), - hl('Register', '@b'), - hl('NestingParenthesis', ')'), - hl('NestingParenthesis', ')'), - hl('CallingParenthesis', '('), - hl('Register', '@c'), - hl('CallingParenthesis', ')'), - }) - check_parsing('@a+((@b))+@c', { - -- 01234567890123456890123456789 - -- 0 1 2 - ast = { - { - 'BinaryPlus:0:9:+', - children = { - { - 'BinaryPlus:0:2:+', - children = { - 'Register(name=a):0:0:@a', - { - 'Nested:0:3:(', - children = { - { - 'Nested:0:4:(', - children = { 'Register(name=b):0:5:@b' } - }, - }, - }, - }, - }, - 'Register(name=c):0:10:@c', - }, - }, - }, - }, { - hl('Register', '@a'), - hl('BinaryPlus', '+'), - hl('NestingParenthesis', '('), - hl('NestingParenthesis', '('), - hl('Register', '@b'), - hl('NestingParenthesis', ')'), - hl('NestingParenthesis', ')'), - hl('BinaryPlus', '+'), - hl('Register', '@c'), - }) - check_parsing( - '@a + (@b + @c) + @d(@e) + (+@f) + ((+@g(@h))(@j)(@k))(@l)', {--[[ - | | | | | | | | || | | || | | ||| || || || || - 000000000011111111112222222222333333333344444444445555555 - 012345678901234567890123456789012345678901234567890123456 - ]] - ast = {{ - 'BinaryPlus:0:31: +', - children = { - { - 'BinaryPlus:0:23: +', - children = { - { - 'BinaryPlus:0:14: +', - children = { - { - 'BinaryPlus:0:2: +', - children = { - 'Register(name=a):0:0:@a', - { - 'Nested:0:4: (', - children = { - { - 'BinaryPlus:0:8: +', - children = { - 'Register(name=b):0:6:@b', - 'Register(name=c):0:10: @c', - }, - }, - }, - }, - }, - }, - { - 'Call:0:19:(', - children = { - 'Register(name=d):0:16: @d', - 'Register(name=e):0:20:@e', - }, - }, - }, - }, - { - 'Nested:0:25: (', - children = { - { - 'UnaryPlus:0:27:+', - children = { - 'Register(name=f):0:28:@f', - }, - }, - }, - }, - }, - }, - { - 'Call:0:53:(', - children = { - { - 'Nested:0:33: (', - children = { - { - 'Call:0:48:(', - children = { - { - 'Call:0:44:(', - children = { - { - 'Nested:0:35:(', - children = { - { - 'UnaryPlus:0:36:+', - children = { - { - 'Call:0:39:(', - children = { - 'Register(name=g):0:37:@g', - 'Register(name=h):0:40:@h', - }, - }, - }, - }, - }, - }, - 'Register(name=j):0:45:@j', - }, - }, - 'Register(name=k):0:49:@k', - }, - }, - }, - }, - 'Register(name=l):0:54:@l', - }, - }, - }, - }}, - }, { - hl('Register', '@a'), - hl('BinaryPlus', '+', 1), - hl('NestingParenthesis', '(', 1), - hl('Register', '@b'), - hl('BinaryPlus', '+', 1), - hl('Register', '@c', 1), - hl('NestingParenthesis', ')'), - hl('BinaryPlus', '+', 1), - hl('Register', '@d', 1), - hl('CallingParenthesis', '('), - hl('Register', '@e'), - hl('CallingParenthesis', ')'), - hl('BinaryPlus', '+', 1), - hl('NestingParenthesis', '(', 1), - hl('UnaryPlus', '+'), - hl('Register', '@f'), - hl('NestingParenthesis', ')'), - hl('BinaryPlus', '+', 1), - hl('NestingParenthesis', '(', 1), - hl('NestingParenthesis', '('), - hl('UnaryPlus', '+'), - hl('Register', '@g'), - hl('CallingParenthesis', '('), - hl('Register', '@h'), - hl('CallingParenthesis', ')'), - hl('NestingParenthesis', ')'), - hl('CallingParenthesis', '('), - hl('Register', '@j'), - hl('CallingParenthesis', ')'), - hl('CallingParenthesis', '('), - hl('Register', '@k'), - hl('CallingParenthesis', ')'), - hl('NestingParenthesis', ')'), - hl('CallingParenthesis', '('), - hl('Register', '@l'), - hl('CallingParenthesis', ')'), - }) - check_parsing('@a)', { - -- 012 - ast = { - { - 'Nested:0:2:', - children = { - 'Register(name=a):0:0:@a', - }, - }, - }, - err = { - arg = ')', - msg = 'E15: Unexpected closing parenthesis: %.*s', - }, - }, { - hl('Register', '@a'), - hl('InvalidNestingParenthesis', ')'), - }) - check_parsing('(@a', { - -- 012 - ast = { - { - 'Nested:0:0:(', - children = { - 'Register(name=a):0:1:@a', - }, - }, - }, - err = { - arg = '(@a', - msg = 'E110: Missing closing parenthesis for nested expression: %.*s', - }, - }, { - hl('NestingParenthesis', '('), - hl('Register', '@a'), - }) - check_parsing('@a(@b', { - -- 01234 - ast = { - { - 'Call:0:2:(', - children = { - 'Register(name=a):0:0:@a', - 'Register(name=b):0:3:@b', - }, - }, - }, - err = { - arg = '(@b', - msg = 'E116: Missing closing parenthesis for function call: %.*s', - }, - }, { - hl('Register', '@a'), - hl('CallingParenthesis', '('), - hl('Register', '@b'), - }) - check_parsing('@a(@b, @c, @d, @e)', { - -- 012345678901234567 - -- 0 1 - ast = { - { - 'Call:0:2:(', - children = { - 'Register(name=a):0:0:@a', - { - 'Comma:0:5:,', - children = { - 'Register(name=b):0:3:@b', - { - 'Comma:0:9:,', - children = { - 'Register(name=c):0:6: @c', - { - 'Comma:0:13:,', - children = { - 'Register(name=d):0:10: @d', - 'Register(name=e):0:14: @e', - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, { - hl('Register', '@a'), - hl('CallingParenthesis', '('), - hl('Register', '@b'), - hl('Comma', ','), - hl('Register', '@c', 1), - hl('Comma', ','), - hl('Register', '@d', 1), - hl('Comma', ','), - hl('Register', '@e', 1), - hl('CallingParenthesis', ')'), - }) - check_parsing('@a(@b(@c))', { - -- 01234567890123456789012345678901234567 - -- 0 1 2 3 - ast = { - { - 'Call:0:2:(', - children = { - 'Register(name=a):0:0:@a', - { - 'Call:0:5:(', - children = { - 'Register(name=b):0:3:@b', - 'Register(name=c):0:6:@c', - }, - }, - }, - }, - }, - }, { - hl('Register', '@a'), - hl('CallingParenthesis', '('), - hl('Register', '@b'), - hl('CallingParenthesis', '('), - hl('Register', '@c'), - hl('CallingParenthesis', ')'), - hl('CallingParenthesis', ')'), - }) - check_parsing('@a(@b(@c(@d(@e), @f(@g(@h), @i(@j)))))', { - -- 01234567890123456789012345678901234567 - -- 0 1 2 3 - ast = { - { - 'Call:0:2:(', - children = { - 'Register(name=a):0:0:@a', - { - 'Call:0:5:(', - children = { - 'Register(name=b):0:3:@b', - { - 'Call:0:8:(', - children = { - 'Register(name=c):0:6:@c', - { - 'Comma:0:15:,', - children = { - { - 'Call:0:11:(', - children = { - 'Register(name=d):0:9:@d', - 'Register(name=e):0:12:@e', - }, - }, - { - 'Call:0:19:(', - children = { - 'Register(name=f):0:16: @f', - { - 'Comma:0:26:,', - children = { - { - 'Call:0:22:(', - children = { - 'Register(name=g):0:20:@g', - 'Register(name=h):0:23:@h', - }, - }, - { - 'Call:0:30:(', - children = { - 'Register(name=i):0:27: @i', - 'Register(name=j):0:31:@j', - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, { - hl('Register', '@a'), - hl('CallingParenthesis', '('), - hl('Register', '@b'), - hl('CallingParenthesis', '('), - hl('Register', '@c'), - hl('CallingParenthesis', '('), - hl('Register', '@d'), - hl('CallingParenthesis', '('), - hl('Register', '@e'), - hl('CallingParenthesis', ')'), - hl('Comma', ','), - hl('Register', '@f', 1), - hl('CallingParenthesis', '('), - hl('Register', '@g'), - hl('CallingParenthesis', '('), - hl('Register', '@h'), - hl('CallingParenthesis', ')'), - hl('Comma', ','), - hl('Register', '@i', 1), - hl('CallingParenthesis', '('), - hl('Register', '@j'), - hl('CallingParenthesis', ')'), - hl('CallingParenthesis', ')'), - hl('CallingParenthesis', ')'), - hl('CallingParenthesis', ')'), - hl('CallingParenthesis', ')'), - }) - end) - it('works with variable names, including curly braces ones', function() - check_parsing('var', { - ast = { - 'PlainIdentifier(scope=0,ident=var):0:0:var', - }, - }, { - hl('IdentifierName', 'var'), - }) - check_parsing('g:var', { - ast = { - 'PlainIdentifier(scope=g,ident=var):0:0:g:var', - }, - }, { - hl('IdentifierScope', 'g'), - hl('IdentifierScopeDelimiter', ':'), - hl('IdentifierName', 'var'), - }) - check_parsing('g:', { - ast = { - 'PlainIdentifier(scope=g,ident=):0:0:g:', - }, - }, { - hl('IdentifierScope', 'g'), - hl('IdentifierScopeDelimiter', ':'), - }) - check_parsing('{a}', { - -- 012 - ast = { - { - 'CurlyBracesIdentifier:0:0:{', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - }, - }, - }, - }, { - hl('Curly', '{'), - hl('IdentifierName', 'a'), - hl('Curly', '}'), - }) - check_parsing('{a:b}', { - -- 012 - ast = { - { - 'CurlyBracesIdentifier:0:0:{', - children = { - 'PlainIdentifier(scope=a,ident=b):0:1:a:b', - }, - }, - }, - }, { - hl('Curly', '{'), - hl('IdentifierScope', 'a'), - hl('IdentifierScopeDelimiter', ':'), - hl('IdentifierName', 'b'), - hl('Curly', '}'), - }) - check_parsing('{a:@b}', { - -- 012345 - ast = { - { - 'CurlyBracesIdentifier:0:0:{', - children = { - { - 'OpMissing:0:3:', - children={ - 'PlainIdentifier(scope=a,ident=):0:1:a:', - 'Register(name=b):0:3:@b', - }, - }, - }, - }, - }, - err = { - arg = '@b}', - msg = 'E15: Missing operator: %.*s', - }, - }, { - hl('Curly', '{'), - hl('IdentifierScope', 'a'), - hl('IdentifierScopeDelimiter', ':'), - hl('InvalidRegister', '@b'), - hl('Curly', '}'), - }) - check_parsing('{@a}', { - ast = { - { - 'CurlyBracesIdentifier:0:0:{', - children = { - 'Register(name=a):0:1:@a', - }, - }, - }, - }, { - hl('Curly', '{'), - hl('Register', '@a'), - hl('Curly', '}'), - }) - check_parsing('{@a}{@b}', { - -- 01234567 - ast = { - { - 'ComplexIdentifier:0:4:', - children = { - { - 'CurlyBracesIdentifier:0:0:{', - children = { - 'Register(name=a):0:1:@a', - }, - }, - { - 'CurlyBracesIdentifier:0:4:{', - children = { - 'Register(name=b):0:5:@b', - }, - }, - }, - }, - }, - }, { - hl('Curly', '{'), - hl('Register', '@a'), - hl('Curly', '}'), - hl('Curly', '{'), - hl('Register', '@b'), - hl('Curly', '}'), - }) - check_parsing('g:{@a}', { - -- 01234567 - ast = { - { - 'ComplexIdentifier:0:2:', - children = { - 'PlainIdentifier(scope=g,ident=):0:0:g:', - { - 'CurlyBracesIdentifier:0:2:{', - children = { - 'Register(name=a):0:3:@a', - }, - }, - }, - }, - }, - }, { - hl('IdentifierScope', 'g'), - hl('IdentifierScopeDelimiter', ':'), - hl('Curly', '{'), - hl('Register', '@a'), - hl('Curly', '}'), - }) - check_parsing('{@a}_test', { - -- 012345678 - ast = { - { - 'ComplexIdentifier:0:4:', - children = { - { - 'CurlyBracesIdentifier:0:0:{', - children = { - 'Register(name=a):0:1:@a', - }, - }, - 'PlainIdentifier(scope=0,ident=_test):0:4:_test', - }, - }, - }, - }, { - hl('Curly', '{'), - hl('Register', '@a'), - hl('Curly', '}'), - hl('IdentifierName', '_test'), - }) - check_parsing('g:{@a}_test', { - -- 01234567890 - ast = { - { - 'ComplexIdentifier:0:2:', - children = { - 'PlainIdentifier(scope=g,ident=):0:0:g:', - { - 'ComplexIdentifier:0:6:', - children = { - { - 'CurlyBracesIdentifier:0:2:{', - children = { - 'Register(name=a):0:3:@a', - }, - }, - 'PlainIdentifier(scope=0,ident=_test):0:6:_test', - }, - }, - }, - }, - }, - }, { - hl('IdentifierScope', 'g'), - hl('IdentifierScopeDelimiter', ':'), - hl('Curly', '{'), - hl('Register', '@a'), - hl('Curly', '}'), - hl('IdentifierName', '_test'), - }) - check_parsing('g:{@a}_test()', { - -- 0123456789012 - ast = { - { - 'Call:0:11:(', - children = { - { - 'ComplexIdentifier:0:2:', - children = { - 'PlainIdentifier(scope=g,ident=):0:0:g:', - { - 'ComplexIdentifier:0:6:', - children = { - { - 'CurlyBracesIdentifier:0:2:{', - children = { - 'Register(name=a):0:3:@a', - }, - }, - 'PlainIdentifier(scope=0,ident=_test):0:6:_test', - }, - }, - }, - }, - }, - }, - }, - }, { - hl('IdentifierScope', 'g'), - hl('IdentifierScopeDelimiter', ':'), - hl('Curly', '{'), - hl('Register', '@a'), - hl('Curly', '}'), - hl('IdentifierName', '_test'), - hl('CallingParenthesis', '('), - hl('CallingParenthesis', ')'), - }) - check_parsing('{@a} ()', { - -- 0123456789012 - ast = { - { - 'Call:0:4: (', - children = { - { - 'CurlyBracesIdentifier:0:0:{', - children = { - 'Register(name=a):0:1:@a', - }, - }, - }, - }, - }, - }, { - hl('Curly', '{'), - hl('Register', '@a'), - hl('Curly', '}'), - hl('CallingParenthesis', '(', 1), - hl('CallingParenthesis', ')'), - }) - check_parsing('g:{@a} ()', { - -- 0123456789012 - ast = { - { - 'Call:0:6: (', - children = { - { - 'ComplexIdentifier:0:2:', - children = { - 'PlainIdentifier(scope=g,ident=):0:0:g:', - { - 'CurlyBracesIdentifier:0:2:{', - children = { - 'Register(name=a):0:3:@a', - }, - }, - }, - }, - }, - }, - }, - }, { - hl('IdentifierScope', 'g'), - hl('IdentifierScopeDelimiter', ':'), - hl('Curly', '{'), - hl('Register', '@a'), - hl('Curly', '}'), - hl('CallingParenthesis', '(', 1), - hl('CallingParenthesis', ')'), - }) - check_parsing('{@a', { - -- 012 - ast = { - { - 'UnknownFigure:0:0:{', - children = { - 'Register(name=a):0:1:@a', - }, - }, - }, - err = { - arg = '{@a', - msg = 'E15: Missing closing figure brace: %.*s', - }, - }, { - hl('FigureBrace', '{'), - hl('Register', '@a'), - }) - end) - it('works with lambdas and dictionaries', function() - check_parsing('{}', { - ast = { - 'DictLiteral:0:0:{', - }, - }, { - hl('Dict', '{'), - hl('Dict', '}'), - }) - check_parsing('{->@a}', { - ast = { - { - 'Lambda:0:0:{', - children = { - { - 'Arrow:0:1:->', - children = { - 'Register(name=a):0:3:@a', - }, - }, - }, - }, - }, - }, { - hl('Lambda', '{'), - hl('Arrow', '->'), - hl('Register', '@a'), - hl('Lambda', '}'), - }) - check_parsing('{->@a+@b}', { - -- 012345678 - ast = { - { - 'Lambda:0:0:{', - children = { - { - 'Arrow:0:1:->', - children = { - { - 'BinaryPlus:0:5:+', - children = { - 'Register(name=a):0:3:@a', - 'Register(name=b):0:6:@b', - }, - }, - }, - }, - }, - }, - }, - }, { - hl('Lambda', '{'), - hl('Arrow', '->'), - hl('Register', '@a'), - hl('BinaryPlus', '+'), - hl('Register', '@b'), - hl('Lambda', '}'), - }) - check_parsing('{a->@a}', { - -- 012345678 - ast = { - { - 'Lambda:0:0:{', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - { - 'Arrow:0:2:->', - children = { - 'Register(name=a):0:4:@a', - }, - }, - }, - }, - }, - }, { - hl('Lambda', '{'), - hl('IdentifierName', 'a'), - hl('Arrow', '->'), - hl('Register', '@a'), - hl('Lambda', '}'), - }) - check_parsing('{a,b->@a}', { - -- 012345678 - ast = { - { - 'Lambda:0:0:{', - children = { - { - 'Comma:0:2:,', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - 'PlainIdentifier(scope=0,ident=b):0:3:b', - }, - }, - { - 'Arrow:0:4:->', - children = { - 'Register(name=a):0:6:@a', - }, - }, - }, - }, - }, - }, { - hl('Lambda', '{'), - hl('IdentifierName', 'a'), - hl('Comma', ','), - hl('IdentifierName', 'b'), - hl('Arrow', '->'), - hl('Register', '@a'), - hl('Lambda', '}'), - }) - check_parsing('{a,b,c->@a}', { - -- 01234567890 - ast = { - { - 'Lambda:0:0:{', - children = { - { - 'Comma:0:2:,', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - { - 'Comma:0:4:,', - children = { - 'PlainIdentifier(scope=0,ident=b):0:3:b', - 'PlainIdentifier(scope=0,ident=c):0:5:c', - }, - }, - }, - }, - { - 'Arrow:0:6:->', - children = { - 'Register(name=a):0:8:@a', - }, - }, - }, - }, - }, - }, { - hl('Lambda', '{'), - hl('IdentifierName', 'a'), - hl('Comma', ','), - hl('IdentifierName', 'b'), - hl('Comma', ','), - hl('IdentifierName', 'c'), - hl('Arrow', '->'), - hl('Register', '@a'), - hl('Lambda', '}'), - }) - check_parsing('{a,b,c,d->@a}', { - -- 0123456789012 - ast = { - { - 'Lambda:0:0:{', - children = { - { - 'Comma:0:2:,', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - { - 'Comma:0:4:,', - children = { - 'PlainIdentifier(scope=0,ident=b):0:3:b', - { - 'Comma:0:6:,', - children = { - 'PlainIdentifier(scope=0,ident=c):0:5:c', - 'PlainIdentifier(scope=0,ident=d):0:7:d', - }, - }, - }, - }, - }, - }, - { - 'Arrow:0:8:->', - children = { - 'Register(name=a):0:10:@a', - }, - }, - }, - }, - }, - }, { - hl('Lambda', '{'), - hl('IdentifierName', 'a'), - hl('Comma', ','), - hl('IdentifierName', 'b'), - hl('Comma', ','), - hl('IdentifierName', 'c'), - hl('Comma', ','), - hl('IdentifierName', 'd'), - hl('Arrow', '->'), - hl('Register', '@a'), - hl('Lambda', '}'), - }) - check_parsing('{a,b,c,d,->@a}', { - -- 01234567890123 - ast = { - { - 'Lambda:0:0:{', - children = { - { - 'Comma:0:2:,', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - { - 'Comma:0:4:,', - children = { - 'PlainIdentifier(scope=0,ident=b):0:3:b', - { - 'Comma:0:6:,', - children = { - 'PlainIdentifier(scope=0,ident=c):0:5:c', - { - 'Comma:0:8:,', - children = { - 'PlainIdentifier(scope=0,ident=d):0:7:d', - }, - }, - }, - }, - }, - }, - }, - }, - { - 'Arrow:0:9:->', - children = { - 'Register(name=a):0:11:@a', - }, - }, - }, - }, - }, - }, { - hl('Lambda', '{'), - hl('IdentifierName', 'a'), - hl('Comma', ','), - hl('IdentifierName', 'b'), - hl('Comma', ','), - hl('IdentifierName', 'c'), - hl('Comma', ','), - hl('IdentifierName', 'd'), - hl('Comma', ','), - hl('Arrow', '->'), - hl('Register', '@a'), - hl('Lambda', '}'), - }) - check_parsing('{a,b->{c,d->{e,f->@a}}}', { - -- 01234567890123456789012 - -- 0 1 2 - ast = { - { - 'Lambda:0:0:{', - children = { - { - 'Comma:0:2:,', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - 'PlainIdentifier(scope=0,ident=b):0:3:b', - }, - }, - { - 'Arrow:0:4:->', - children = { - { - 'Lambda:0:6:{', - children = { - { - 'Comma:0:8:,', - children = { - 'PlainIdentifier(scope=0,ident=c):0:7:c', - 'PlainIdentifier(scope=0,ident=d):0:9:d', - }, - }, - { - 'Arrow:0:10:->', - children = { - { - 'Lambda:0:12:{', - children = { - { - 'Comma:0:14:,', - children = { - 'PlainIdentifier(scope=0,ident=e):0:13:e', - 'PlainIdentifier(scope=0,ident=f):0:15:f', - }, - }, - { - 'Arrow:0:16:->', - children = { - 'Register(name=a):0:18:@a', - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, { - hl('Lambda', '{'), - hl('IdentifierName', 'a'), - hl('Comma', ','), - hl('IdentifierName', 'b'), - hl('Arrow', '->'), - hl('Lambda', '{'), - hl('IdentifierName', 'c'), - hl('Comma', ','), - hl('IdentifierName', 'd'), - hl('Arrow', '->'), - hl('Lambda', '{'), - hl('IdentifierName', 'e'), - hl('Comma', ','), - hl('IdentifierName', 'f'), - hl('Arrow', '->'), - hl('Register', '@a'), - hl('Lambda', '}'), - hl('Lambda', '}'), - hl('Lambda', '}'), - }) - check_parsing('{a,b->c,d}', { - -- 0123456789 - ast = { - { - 'Lambda:0:0:{', - children = { - { - 'Comma:0:2:,', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - 'PlainIdentifier(scope=0,ident=b):0:3:b', - }, - }, - { - 'Arrow:0:4:->', - children = { - { - 'Comma:0:7:,', - children = { - 'PlainIdentifier(scope=0,ident=c):0:6:c', - 'PlainIdentifier(scope=0,ident=d):0:8:d', - }, - }, - }, - }, - }, - }, - }, - err = { - arg = ',d}', - msg = 'E15: Comma outside of call, lambda or literal: %.*s', - }, - }, { - hl('Lambda', '{'), - hl('IdentifierName', 'a'), - hl('Comma', ','), - hl('IdentifierName', 'b'), - hl('Arrow', '->'), - hl('IdentifierName', 'c'), - hl('InvalidComma', ','), - hl('IdentifierName', 'd'), - hl('Lambda', '}'), - }) - check_parsing('a,b,c,d', { - -- 0123456789 - ast = { - { - 'Comma:0:1:,', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - { - 'Comma:0:3:,', - children = { - 'PlainIdentifier(scope=0,ident=b):0:2:b', - { - 'Comma:0:5:,', - children = { - 'PlainIdentifier(scope=0,ident=c):0:4:c', - 'PlainIdentifier(scope=0,ident=d):0:6:d', - }, - }, - }, - }, - }, - }, - }, - err = { - arg = ',b,c,d', - msg = 'E15: Comma outside of call, lambda or literal: %.*s', - }, - }, { - hl('IdentifierName', 'a'), - hl('InvalidComma', ','), - hl('IdentifierName', 'b'), - hl('InvalidComma', ','), - hl('IdentifierName', 'c'), - hl('InvalidComma', ','), - hl('IdentifierName', 'd'), - }) - check_parsing('a,b,c,d,', { - -- 0123456789 - ast = { - { - 'Comma:0:1:,', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - { - 'Comma:0:3:,', - children = { - 'PlainIdentifier(scope=0,ident=b):0:2:b', - { - 'Comma:0:5:,', - children = { - 'PlainIdentifier(scope=0,ident=c):0:4:c', - { - 'Comma:0:7:,', - children = { - 'PlainIdentifier(scope=0,ident=d):0:6:d', - }, - }, - }, - }, - }, - }, - }, - }, - }, - err = { - arg = ',b,c,d,', - msg = 'E15: Comma outside of call, lambda or literal: %.*s', - }, - }, { - hl('IdentifierName', 'a'), - hl('InvalidComma', ','), - hl('IdentifierName', 'b'), - hl('InvalidComma', ','), - hl('IdentifierName', 'c'), - hl('InvalidComma', ','), - hl('IdentifierName', 'd'), - hl('InvalidComma', ','), - }) - check_parsing(',', { - -- 0123456789 - ast = { - { - 'Comma:0:0:,', - children = { - 'Missing:0:0:', - }, - }, - }, - err = { - arg = ',', - msg = 'E15: Expected value, got comma: %.*s', - }, - }, { - hl('InvalidComma', ','), - }) - check_parsing('{,a->@a}', { - -- 0123456789 - ast = { - { - 'CurlyBracesIdentifier:0:0:{', - children = { - { - 'Arrow:0:3:->', - children = { - { - 'Comma:0:1:,', - children = { - 'Missing:0:1:', - 'PlainIdentifier(scope=0,ident=a):0:2:a', - }, - }, - 'Register(name=a):0:5:@a', - }, - }, - }, - }, - }, - err = { - arg = ',a->@a}', - msg = 'E15: Expected value, got comma: %.*s', - }, - }, { - hl('Curly', '{'), - hl('InvalidComma', ','), - hl('IdentifierName', 'a'), - hl('InvalidArrow', '->'), - hl('Register', '@a'), - hl('Curly', '}'), - }) - check_parsing('}', { - -- 0123456789 - ast = { - 'UnknownFigure:0:0:', - }, - err = { - arg = '}', - msg = 'E15: Unexpected closing figure brace: %.*s', - }, - }, { - hl('InvalidFigureBrace', '}'), - }) - check_parsing('{->}', { - -- 0123456789 - ast = { - { - 'Lambda:0:0:{', - children = { - 'Arrow:0:1:->', - }, - }, - }, - err = { - arg = '}', - msg = 'E15: Expected value, got closing figure brace: %.*s', - }, - }, { - hl('Lambda', '{'), - hl('Arrow', '->'), - hl('InvalidLambda', '}'), - }) - check_parsing('{a,b}', { - -- 0123456789 - ast = { - { - 'Lambda:0:0:{', - children = { - { - 'Comma:0:2:,', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - 'PlainIdentifier(scope=0,ident=b):0:3:b', - }, - }, - }, - }, - }, - err = { - arg = '}', - msg = 'E15: Expected lambda arguments list or arrow: %.*s', - }, - }, { - hl('Lambda', '{'), - hl('IdentifierName', 'a'), - hl('Comma', ','), - hl('IdentifierName', 'b'), - hl('InvalidLambda', '}'), - }) - check_parsing('{a,}', { - -- 0123456789 - ast = { - { - 'Lambda:0:0:{', - children = { - { - 'Comma:0:2:,', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - }, - }, - }, - }, - }, - err = { - arg = '}', - msg = 'E15: Expected lambda arguments list or arrow: %.*s', - }, - }, { - hl('Lambda', '{'), - hl('IdentifierName', 'a'), - hl('Comma', ','), - hl('InvalidLambda', '}'), - }) - check_parsing('{@a:@b}', { - -- 0123456789 - ast = { - { - 'DictLiteral:0:0:{', - children = { - { - 'Colon:0:3::', - children = { - 'Register(name=a):0:1:@a', - 'Register(name=b):0:4:@b', - }, - }, - }, - }, - }, - }, { - hl('Dict', '{'), - hl('Register', '@a'), - hl('Colon', ':'), - hl('Register', '@b'), - hl('Dict', '}'), - }) - check_parsing('{@a:@b,@c:@d}', { - -- 0123456789012 - -- 0 1 - ast = { - { - 'DictLiteral:0:0:{', - children = { - { - 'Comma:0:6:,', - children = { - { - 'Colon:0:3::', - children = { - 'Register(name=a):0:1:@a', - 'Register(name=b):0:4:@b', - }, - }, - { - 'Colon:0:9::', - children = { - 'Register(name=c):0:7:@c', - 'Register(name=d):0:10:@d', - }, - }, - }, - }, - }, - }, - }, - }, { - hl('Dict', '{'), - hl('Register', '@a'), - hl('Colon', ':'), - hl('Register', '@b'), - hl('Comma', ','), - hl('Register', '@c'), - hl('Colon', ':'), - hl('Register', '@d'), - hl('Dict', '}'), - }) - check_parsing('{@a:@b,@c:@d,@e:@f,}', { - -- 01234567890123456789 - -- 0 1 - ast = { - { - 'DictLiteral:0:0:{', - children = { - { - 'Comma:0:6:,', - children = { - { - 'Colon:0:3::', - children = { - 'Register(name=a):0:1:@a', - 'Register(name=b):0:4:@b', - }, - }, - { - 'Comma:0:12:,', - children = { - { - 'Colon:0:9::', - children = { - 'Register(name=c):0:7:@c', - 'Register(name=d):0:10:@d', - }, - }, - { - 'Comma:0:18:,', - children = { - { - 'Colon:0:15::', - children = { - 'Register(name=e):0:13:@e', - 'Register(name=f):0:16:@f', - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, { - hl('Dict', '{'), - hl('Register', '@a'), - hl('Colon', ':'), - hl('Register', '@b'), - hl('Comma', ','), - hl('Register', '@c'), - hl('Colon', ':'), - hl('Register', '@d'), - hl('Comma', ','), - hl('Register', '@e'), - hl('Colon', ':'), - hl('Register', '@f'), - hl('Comma', ','), - hl('Dict', '}'), - }) - check_parsing('{@a:@b,@c:@d,@e:@f,@g:}', { - -- 01234567890123456789012 - -- 0 1 2 - ast = { - { - 'DictLiteral:0:0:{', - children = { - { - 'Comma:0:6:,', - children = { - { - 'Colon:0:3::', - children = { - 'Register(name=a):0:1:@a', - 'Register(name=b):0:4:@b', - }, - }, - { - 'Comma:0:12:,', - children = { - { - 'Colon:0:9::', - children = { - 'Register(name=c):0:7:@c', - 'Register(name=d):0:10:@d', - }, - }, - { - 'Comma:0:18:,', - children = { - { - 'Colon:0:15::', - children = { - 'Register(name=e):0:13:@e', - 'Register(name=f):0:16:@f', - }, - }, - { - 'Colon:0:21::', - children = { - 'Register(name=g):0:19:@g', - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - err = { - arg = '}', - msg = 'E15: Expected value, got closing figure brace: %.*s', - }, - }, { - hl('Dict', '{'), - hl('Register', '@a'), - hl('Colon', ':'), - hl('Register', '@b'), - hl('Comma', ','), - hl('Register', '@c'), - hl('Colon', ':'), - hl('Register', '@d'), - hl('Comma', ','), - hl('Register', '@e'), - hl('Colon', ':'), - hl('Register', '@f'), - hl('Comma', ','), - hl('Register', '@g'), - hl('Colon', ':'), - hl('InvalidDict', '}'), - }) - check_parsing('{@a:@b,}', { - -- 01234567890123 - -- 0 1 - ast = { - { - 'DictLiteral:0:0:{', - children = { - { - 'Comma:0:6:,', - children = { - { - 'Colon:0:3::', - children = { - 'Register(name=a):0:1:@a', - 'Register(name=b):0:4:@b', - }, - }, - }, - }, - }, - }, - }, - }, { - hl('Dict', '{'), - hl('Register', '@a'), - hl('Colon', ':'), - hl('Register', '@b'), - hl('Comma', ','), - hl('Dict', '}'), - }) - check_parsing('{({f -> g})(@h)(@i)}', { - -- 01234567890123456789 - -- 0 1 - ast = { - { - 'CurlyBracesIdentifier:0:0:{', - children = { - { - 'Call:0:15:(', - children = { - { - 'Call:0:11:(', - children = { - { - 'Nested:0:1:(', - children = { - { - 'Lambda:0:2:{', - children = { - 'PlainIdentifier(scope=0,ident=f):0:3:f', - { - 'Arrow:0:4: ->', - children = { - 'PlainIdentifier(scope=0,ident=g):0:7: g', - }, - }, - }, - }, - }, - }, - 'Register(name=h):0:12:@h', - }, - }, - 'Register(name=i):0:16:@i', - }, - }, - }, - }, - }, - }, { - hl('Curly', '{'), - hl('NestingParenthesis', '('), - hl('Lambda', '{'), - hl('IdentifierName', 'f'), - hl('Arrow', '->', 1), - hl('IdentifierName', 'g', 1), - hl('Lambda', '}'), - hl('NestingParenthesis', ')'), - hl('CallingParenthesis', '('), - hl('Register', '@h'), - hl('CallingParenthesis', ')'), - hl('CallingParenthesis', '('), - hl('Register', '@i'), - hl('CallingParenthesis', ')'), - hl('Curly', '}'), - }) - check_parsing('a:{b()}c', { - -- 01234567 - ast = { - { - 'ComplexIdentifier:0:2:', - children = { - 'PlainIdentifier(scope=a,ident=):0:0:a:', - { - 'ComplexIdentifier:0:7:', - children = { - { - 'CurlyBracesIdentifier:0:2:{', - children = { - { - 'Call:0:4:(', - children = { - 'PlainIdentifier(scope=0,ident=b):0:3:b', - }, - }, - }, - }, - 'PlainIdentifier(scope=0,ident=c):0:7:c', - }, - }, - }, - }, - }, - }, { - hl('IdentifierScope', 'a'), - hl('IdentifierScopeDelimiter', ':'), - hl('Curly', '{'), - hl('IdentifierName', 'b'), - hl('CallingParenthesis', '('), - hl('CallingParenthesis', ')'), - hl('Curly', '}'), - hl('IdentifierName', 'c'), - }) - check_parsing('a:{{b, c -> @d + @e + ({f -> g})(@h)}(@i)}j', { - -- 01234567890123456789012345678901234567890123456 - -- 0 1 2 3 4 - ast = { - { - 'ComplexIdentifier:0:2:', - children = { - 'PlainIdentifier(scope=a,ident=):0:0:a:', - { - 'ComplexIdentifier:0:42:', - children = { - { - 'CurlyBracesIdentifier:0:2:{', - children = { - { - 'Call:0:37:(', - children = { - { - 'Lambda:0:3:{', - children = { - { - 'Comma:0:5:,', - children = { - 'PlainIdentifier(scope=0,ident=b):0:4:b', - 'PlainIdentifier(scope=0,ident=c):0:6: c', - }, - }, - { - 'Arrow:0:8: ->', - children = { - { - 'BinaryPlus:0:19: +', - children = { - { - 'BinaryPlus:0:14: +', - children = { - 'Register(name=d):0:11: @d', - 'Register(name=e):0:16: @e', - }, - }, - { - 'Call:0:32:(', - children = { - { - 'Nested:0:21: (', - children = { - { - 'Lambda:0:23:{', - children = { - 'PlainIdentifier(scope=0,ident=f):0:24:f', - { - 'Arrow:0:25: ->', - children = { - 'PlainIdentifier(scope=0,ident=g):0:28: g', - }, - }, - }, - }, - }, - }, - 'Register(name=h):0:33:@h', - }, - }, - }, - }, - }, - }, - }, - }, - 'Register(name=i):0:38:@i', - }, - }, - }, - }, - 'PlainIdentifier(scope=0,ident=j):0:42:j', - }, - }, - }, - }, - }, - }, { - hl('IdentifierScope', 'a'), - hl('IdentifierScopeDelimiter', ':'), - hl('Curly', '{'), - hl('Lambda', '{'), - hl('IdentifierName', 'b'), - hl('Comma', ','), - hl('IdentifierName', 'c', 1), - hl('Arrow', '->', 1), - hl('Register', '@d', 1), - hl('BinaryPlus', '+', 1), - hl('Register', '@e', 1), - hl('BinaryPlus', '+', 1), - hl('NestingParenthesis', '(', 1), - hl('Lambda', '{'), - hl('IdentifierName', 'f'), - hl('Arrow', '->', 1), - hl('IdentifierName', 'g', 1), - hl('Lambda', '}'), - hl('NestingParenthesis', ')'), - hl('CallingParenthesis', '('), - hl('Register', '@h'), - hl('CallingParenthesis', ')'), - hl('Lambda', '}'), - hl('CallingParenthesis', '('), - hl('Register', '@i'), - hl('CallingParenthesis', ')'), - hl('Curly', '}'), - hl('IdentifierName', 'j'), - }) - check_parsing('{@a + @b : @c + @d, @e + @f : @g + @i}', { - -- 01234567890123456789012345678901234567 - -- 0 1 2 3 - ast = { - { - 'DictLiteral:0:0:{', - children = { - { - 'Comma:0:18:,', - children = { - { - 'Colon:0:8: :', - children = { - { - 'BinaryPlus:0:3: +', - children = { - 'Register(name=a):0:1:@a', - 'Register(name=b):0:5: @b', - }, - }, - { - 'BinaryPlus:0:13: +', - children = { - 'Register(name=c):0:10: @c', - 'Register(name=d):0:15: @d', - }, - }, - }, - }, - { - 'Colon:0:27: :', - children = { - { - 'BinaryPlus:0:22: +', - children = { - 'Register(name=e):0:19: @e', - 'Register(name=f):0:24: @f', - }, - }, - { - 'BinaryPlus:0:32: +', - children = { - 'Register(name=g):0:29: @g', - 'Register(name=i):0:34: @i', - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, { - hl('Dict', '{'), - hl('Register', '@a'), - hl('BinaryPlus', '+', 1), - hl('Register', '@b', 1), - hl('Colon', ':', 1), - hl('Register', '@c', 1), - hl('BinaryPlus', '+', 1), - hl('Register', '@d', 1), - hl('Comma', ','), - hl('Register', '@e', 1), - hl('BinaryPlus', '+', 1), - hl('Register', '@f', 1), - hl('Colon', ':', 1), - hl('Register', '@g', 1), - hl('BinaryPlus', '+', 1), - hl('Register', '@i', 1), - hl('Dict', '}'), - }) - check_parsing('-> -> ->', { - -- 01234567 - ast = { - { - 'Arrow:0:0:->', - children = { - 'Missing:0:0:', - { - 'Arrow:0:2: ->', - children = { - 'Missing:0:2:', - { - 'Arrow:0:5: ->', - children = { - 'Missing:0:5:', - }, - }, - }, - }, - }, - }, - }, - err = { - arg = '-> -> ->', - msg = 'E15: Unexpected arrow: %.*s', - }, - }, { - hl('InvalidArrow', '->'), - hl('InvalidArrow', '->', 1), - hl('InvalidArrow', '->', 1), - }) - check_parsing('a -> b -> c -> d', { - -- 0123456789012345 - -- 0 1 - ast = { - { - 'Arrow:0:1: ->', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - { - 'Arrow:0:6: ->', - children = { - 'PlainIdentifier(scope=0,ident=b):0:4: b', - { - 'Arrow:0:11: ->', - children = { - 'PlainIdentifier(scope=0,ident=c):0:9: c', - 'PlainIdentifier(scope=0,ident=d):0:14: d', - }, - }, - }, - }, - }, - }, - }, - err = { - arg = '-> b -> c -> d', - msg = 'E15: Arrow outside of lambda: %.*s', - }, - }, { - hl('IdentifierName', 'a'), - hl('InvalidArrow', '->', 1), - hl('IdentifierName', 'b', 1), - hl('InvalidArrow', '->', 1), - hl('IdentifierName', 'c', 1), - hl('InvalidArrow', '->', 1), - hl('IdentifierName', 'd', 1), - }) - check_parsing('{a -> b -> c}', { - -- 0123456789012 - -- 0 1 - ast = { - { - 'Lambda:0:0:{', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - { - 'Arrow:0:2: ->', - children = { - { - 'Arrow:0:7: ->', - children = { - 'PlainIdentifier(scope=0,ident=b):0:5: b', - 'PlainIdentifier(scope=0,ident=c):0:10: c', - }, - }, - }, - }, - }, - }, - }, - err = { - arg = '-> c}', - msg = 'E15: Arrow outside of lambda: %.*s', - }, - }, { - hl('Lambda', '{'), - hl('IdentifierName', 'a'), - hl('Arrow', '->', 1), - hl('IdentifierName', 'b', 1), - hl('InvalidArrow', '->', 1), - hl('IdentifierName', 'c', 1), - hl('Lambda', '}'), - }) - check_parsing('{a: -> b}', { - -- 012345678 - ast = { - { - 'CurlyBracesIdentifier:0:0:{', - children = { - { - 'Arrow:0:3: ->', - children = { - 'PlainIdentifier(scope=a,ident=):0:1:a:', - 'PlainIdentifier(scope=0,ident=b):0:6: b', - }, - }, - }, - }, - }, - err = { - arg = '-> b}', - msg = 'E15: Arrow outside of lambda: %.*s', - }, - }, { - hl('Curly', '{'), - hl('IdentifierScope', 'a'), - hl('IdentifierScopeDelimiter', ':'), - hl('InvalidArrow', '->', 1), - hl('IdentifierName', 'b', 1), - hl('Curly', '}'), - }) - - check_parsing('{a:b -> b}', { - -- 0123456789 - ast = { - { - 'CurlyBracesIdentifier:0:0:{', - children = { - { - 'Arrow:0:4: ->', - children = { - 'PlainIdentifier(scope=a,ident=b):0:1:a:b', - 'PlainIdentifier(scope=0,ident=b):0:7: b', - }, - }, - }, - }, - }, - err = { - arg = '-> b}', - msg = 'E15: Arrow outside of lambda: %.*s', - }, - }, { - hl('Curly', '{'), - hl('IdentifierScope', 'a'), - hl('IdentifierScopeDelimiter', ':'), - hl('IdentifierName', 'b'), - hl('InvalidArrow', '->', 1), - hl('IdentifierName', 'b', 1), - hl('Curly', '}'), - }) - - check_parsing('{a#b -> b}', { - -- 0123456789 - ast = { - { - 'CurlyBracesIdentifier:0:0:{', - children = { - { - 'Arrow:0:4: ->', - children = { - 'PlainIdentifier(scope=0,ident=a#b):0:1:a#b', - 'PlainIdentifier(scope=0,ident=b):0:7: b', - }, - }, - }, - }, - }, - err = { - arg = '-> b}', - msg = 'E15: Arrow outside of lambda: %.*s', - }, - }, { - hl('Curly', '{'), - hl('IdentifierName', 'a#b'), - hl('InvalidArrow', '->', 1), - hl('IdentifierName', 'b', 1), - hl('Curly', '}'), - }) - check_parsing('{a : b : c}', { - -- 01234567890 - -- 0 1 - ast = { - { - 'DictLiteral:0:0:{', - children = { - { - 'Colon:0:2: :', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - { - 'Colon:0:6: :', - children = { - 'PlainIdentifier(scope=0,ident=b):0:4: b', - 'PlainIdentifier(scope=0,ident=c):0:8: c', - }, - }, - }, - }, - }, - }, - }, - err = { - arg = ': c}', - msg = 'E15: Colon outside of dictionary or ternary operator: %.*s', - }, - }, { - hl('Dict', '{'), - hl('IdentifierName', 'a'), - hl('Colon', ':', 1), - hl('IdentifierName', 'b', 1), - hl('InvalidColon', ':', 1), - hl('IdentifierName', 'c', 1), - hl('Dict', '}'), - }) - check_parsing('{', { - -- 0 - ast = { - 'UnknownFigure:0:0:{', - }, - err = { - arg = '{', - msg = 'E15: Missing closing figure brace: %.*s', - }, - }, { - hl('FigureBrace', '{'), - }) - check_parsing('{a', { - -- 01 - ast = { - { - 'UnknownFigure:0:0:{', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - }, - }, - }, - err = { - arg = '{a', - msg = 'E15: Missing closing figure brace: %.*s', - }, - }, { - hl('FigureBrace', '{'), - hl('IdentifierName', 'a'), - }) - check_parsing('{a,b', { - -- 0123 - ast = { - { - 'Lambda:0:0:{', - children = { - { - 'Comma:0:2:,', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - 'PlainIdentifier(scope=0,ident=b):0:3:b', - }, - }, - }, - }, - }, - err = { - arg = '{a,b', - msg = 'E15: Missing closing figure brace for lambda: %.*s', - }, - }, { - hl('Lambda', '{'), - hl('IdentifierName', 'a'), - hl('Comma', ','), - hl('IdentifierName', 'b'), - }) - check_parsing('{a,b->', { - -- 012345 - ast = { - { - 'Lambda:0:0:{', - children = { - { - 'Comma:0:2:,', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - 'PlainIdentifier(scope=0,ident=b):0:3:b', - }, - }, - 'Arrow:0:4:->', - }, - }, - }, - err = { - arg = '', - msg = 'E15: Expected value, got EOC: %.*s', - }, - }, { - hl('Lambda', '{'), - hl('IdentifierName', 'a'), - hl('Comma', ','), - hl('IdentifierName', 'b'), - hl('Arrow', '->'), - }) - check_parsing('{a,b->c', { - -- 0123456 - ast = { - { - 'Lambda:0:0:{', - children = { - { - 'Comma:0:2:,', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - 'PlainIdentifier(scope=0,ident=b):0:3:b', - }, - }, - { - 'Arrow:0:4:->', - children = { - 'PlainIdentifier(scope=0,ident=c):0:6:c', - }, - }, - }, - }, - }, - err = { - arg = '{a,b->c', - msg = 'E15: Missing closing figure brace for lambda: %.*s', - }, - }, { - hl('Lambda', '{'), - hl('IdentifierName', 'a'), - hl('Comma', ','), - hl('IdentifierName', 'b'), - hl('Arrow', '->'), - hl('IdentifierName', 'c'), - }) - check_parsing('{a : b', { - -- 012345 - ast = { - { - 'DictLiteral:0:0:{', - children = { - { - 'Colon:0:2: :', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - 'PlainIdentifier(scope=0,ident=b):0:4: b', - }, - }, - }, - }, - }, - err = { - arg = '{a : b', - msg = 'E723: Missing end of Dictionary \'}\': %.*s', - }, - }, { - hl('Dict', '{'), - hl('IdentifierName', 'a'), - hl('Colon', ':', 1), - hl('IdentifierName', 'b', 1), - }) - check_parsing('{a : b,', { - -- 0123456 - ast = { - { - 'DictLiteral:0:0:{', - children = { - { - 'Comma:0:6:,', - children = { - { - 'Colon:0:2: :', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - 'PlainIdentifier(scope=0,ident=b):0:4: b', - }, - }, - }, - }, - }, - }, - }, - err = { - arg = '', - msg = 'E15: Expected value, got EOC: %.*s', - }, - }, { - hl('Dict', '{'), - hl('IdentifierName', 'a'), - hl('Colon', ':', 1), - hl('IdentifierName', 'b', 1), - hl('Comma', ','), - }) - end) - it('works with ternary operator', function() - check_parsing('a ? b : c', { - -- 012345678 - ast = { - { - 'Ternary:0:1: ?', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - { - 'TernaryValue:0:5: :', - children = { - 'PlainIdentifier(scope=0,ident=b):0:3: b', - 'PlainIdentifier(scope=0,ident=c):0:7: c', - }, - }, - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('Ternary', '?', 1), - hl('IdentifierName', 'b', 1), - hl('TernaryColon', ':', 1), - hl('IdentifierName', 'c', 1), - }) - check_parsing('@a?@b?@c:@d:@e', { - -- 01234567890123 - -- 0 1 - ast = { - { - 'Ternary:0:2:?', - children = { - 'Register(name=a):0:0:@a', - { - 'TernaryValue:0:11::', - children = { - { - 'Ternary:0:5:?', - children = { - 'Register(name=b):0:3:@b', - { - 'TernaryValue:0:8::', - children = { - 'Register(name=c):0:6:@c', - 'Register(name=d):0:9:@d', - }, - }, - }, - }, - 'Register(name=e):0:12:@e', - }, - }, - }, - }, - }, - }, { - hl('Register', '@a'), - hl('Ternary', '?'), - hl('Register', '@b'), - hl('Ternary', '?'), - hl('Register', '@c'), - hl('TernaryColon', ':'), - hl('Register', '@d'), - hl('TernaryColon', ':'), - hl('Register', '@e'), - }) - check_parsing('@a?@b:@c?@d:@e', { - -- 01234567890123 - -- 0 1 - ast = { - { - 'Ternary:0:2:?', - children = { - 'Register(name=a):0:0:@a', - { - 'TernaryValue:0:5::', - children = { - 'Register(name=b):0:3:@b', - { - 'Ternary:0:8:?', - children = { - 'Register(name=c):0:6:@c', - { - 'TernaryValue:0:11::', - children = { - 'Register(name=d):0:9:@d', - 'Register(name=e):0:12:@e', - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, { - hl('Register', '@a'), - hl('Ternary', '?'), - hl('Register', '@b'), - hl('TernaryColon', ':'), - hl('Register', '@c'), - hl('Ternary', '?'), - hl('Register', '@d'), - hl('TernaryColon', ':'), - hl('Register', '@e'), - }) - check_parsing('@a?@b?@c?@d:@e?@f:@g:@h?@i:@j:@k', { - -- 01234567890123456789012345678901 - -- 0 1 2 3 - ast = { - { - 'Ternary:0:2:?', - children = { - 'Register(name=a):0:0:@a', - { - 'TernaryValue:0:29::', - children = { - { - 'Ternary:0:5:?', - children = { - 'Register(name=b):0:3:@b', - { - 'TernaryValue:0:20::', - children = { - { - 'Ternary:0:8:?', - children = { - 'Register(name=c):0:6:@c', - { - 'TernaryValue:0:11::', - children = { - 'Register(name=d):0:9:@d', - { - 'Ternary:0:14:?', - children = { - 'Register(name=e):0:12:@e', - { - 'TernaryValue:0:17::', - children = { - 'Register(name=f):0:15:@f', - 'Register(name=g):0:18:@g', - }, - }, - }, - }, - }, - }, - }, - }, - { - 'Ternary:0:23:?', - children = { - 'Register(name=h):0:21:@h', - { - 'TernaryValue:0:26::', - children = { - 'Register(name=i):0:24:@i', - 'Register(name=j):0:27:@j', - }, - }, - }, - }, - }, - }, - }, - }, - 'Register(name=k):0:30:@k', - }, - }, - }, - }, - }, - }, { - hl('Register', '@a'), - hl('Ternary', '?'), - hl('Register', '@b'), - hl('Ternary', '?'), - hl('Register', '@c'), - hl('Ternary', '?'), - hl('Register', '@d'), - hl('TernaryColon', ':'), - hl('Register', '@e'), - hl('Ternary', '?'), - hl('Register', '@f'), - hl('TernaryColon', ':'), - hl('Register', '@g'), - hl('TernaryColon', ':'), - hl('Register', '@h'), - hl('Ternary', '?'), - hl('Register', '@i'), - hl('TernaryColon', ':'), - hl('Register', '@j'), - hl('TernaryColon', ':'), - hl('Register', '@k'), - }) - check_parsing('?', { - -- 0 - ast = { - { - 'Ternary:0:0:?', - children = { - 'Missing:0:0:', - 'TernaryValue:0:0:?', - }, - }, - }, - err = { - arg = '?', - msg = 'E15: Expected value, got question mark: %.*s', - }, - }, { - hl('InvalidTernary', '?'), - }) - - check_parsing('?:', { - -- 01 - ast = { - { - 'Ternary:0:0:?', - children = { - 'Missing:0:0:', - { - 'TernaryValue:0:1::', - children = { - 'Missing:0:1:', - }, - }, - }, - }, - }, - err = { - arg = '?:', - msg = 'E15: Expected value, got question mark: %.*s', - }, - }, { - hl('InvalidTernary', '?'), - hl('InvalidTernaryColon', ':'), - }) - - check_parsing('?::', { - -- 012 - ast = { - { - 'Colon:0:2::', - children = { - { - 'Ternary:0:0:?', - children = { - 'Missing:0:0:', - { - 'TernaryValue:0:1::', - children = { - 'Missing:0:1:', - 'Missing:0:2:', - }, - }, - }, - }, - }, - }, - }, - err = { - arg = '?::', - msg = 'E15: Expected value, got question mark: %.*s', - }, - }, { - hl('InvalidTernary', '?'), - hl('InvalidTernaryColon', ':'), - hl('InvalidColon', ':'), - }) - - check_parsing('a?b', { - -- 012 - ast = { - { - 'Ternary:0:1:?', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - { - 'TernaryValue:0:1:?', - children = { - 'PlainIdentifier(scope=0,ident=b):0:2:b', - }, - }, - }, - }, - }, - err = { - arg = '?b', - msg = 'E109: Missing \':\' after \'?\': %.*s', - }, - }, { - hl('IdentifierName', 'a'), - hl('Ternary', '?'), - hl('IdentifierName', 'b'), - }) - check_parsing('a?b:', { - -- 0123 - ast = { - { - 'Ternary:0:1:?', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - { - 'TernaryValue:0:1:?', - children = { - 'PlainIdentifier(scope=b,ident=):0:2:b:', - }, - }, - }, - }, - }, - err = { - arg = '?b:', - msg = 'E109: Missing \':\' after \'?\': %.*s', - }, - }, { - hl('IdentifierName', 'a'), - hl('Ternary', '?'), - hl('IdentifierScope', 'b'), - hl('IdentifierScopeDelimiter', ':'), - }) - - check_parsing('a?b::c', { - -- 012345 - ast = { - { - 'Ternary:0:1:?', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - { - 'TernaryValue:0:4::', - children = { - 'PlainIdentifier(scope=b,ident=):0:2:b:', - 'PlainIdentifier(scope=0,ident=c):0:5:c', - }, - }, - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('Ternary', '?'), - hl('IdentifierScope', 'b'), - hl('IdentifierScopeDelimiter', ':'), - hl('TernaryColon', ':'), - hl('IdentifierName', 'c'), - }) - - check_parsing('a?b :', { - -- 01234 - ast = { - { - 'Ternary:0:1:?', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - { - 'TernaryValue:0:3: :', - children = { - 'PlainIdentifier(scope=0,ident=b):0:2:b', - }, - }, - }, - }, - }, - err = { - arg = '', - msg = 'E15: Expected value, got EOC: %.*s', - }, - }, { - hl('IdentifierName', 'a'), - hl('Ternary', '?'), - hl('IdentifierName', 'b'), - hl('TernaryColon', ':', 1), - }) - - check_parsing('(@a?@b:@c)?@d:@e', { - -- 0123456789012345 - -- 0 1 - ast = { - { - 'Ternary:0:10:?', - children = { - { - 'Nested:0:0:(', - children = { - { - 'Ternary:0:3:?', - children = { - 'Register(name=a):0:1:@a', - { - 'TernaryValue:0:6::', - children = { - 'Register(name=b):0:4:@b', - 'Register(name=c):0:7:@c', - }, - }, - }, - }, - }, - }, - { - 'TernaryValue:0:13::', - children = { - 'Register(name=d):0:11:@d', - 'Register(name=e):0:14:@e', - }, - }, - }, - }, - }, - }, { - hl('NestingParenthesis', '('), - hl('Register', '@a'), - hl('Ternary', '?'), - hl('Register', '@b'), - hl('TernaryColon', ':'), - hl('Register', '@c'), - hl('NestingParenthesis', ')'), - hl('Ternary', '?'), - hl('Register', '@d'), - hl('TernaryColon', ':'), - hl('Register', '@e'), - }) - - check_parsing('(@a?@b:@c)?(@d?@e:@f):(@g?@h:@i)', { - -- 01234567890123456789012345678901 - -- 0 1 2 3 - ast = { - { - 'Ternary:0:10:?', - children = { - { - 'Nested:0:0:(', - children = { - { - 'Ternary:0:3:?', - children = { - 'Register(name=a):0:1:@a', - { - 'TernaryValue:0:6::', - children = { - 'Register(name=b):0:4:@b', - 'Register(name=c):0:7:@c', - }, - }, - }, - }, - }, - }, - { - 'TernaryValue:0:21::', - children = { - { - 'Nested:0:11:(', - children = { - { - 'Ternary:0:14:?', - children = { - 'Register(name=d):0:12:@d', - { - 'TernaryValue:0:17::', - children = { - 'Register(name=e):0:15:@e', - 'Register(name=f):0:18:@f', - }, - }, - }, - }, - }, - }, - { - 'Nested:0:22:(', - children = { - { - 'Ternary:0:25:?', - children = { - 'Register(name=g):0:23:@g', - { - 'TernaryValue:0:28::', - children = { - 'Register(name=h):0:26:@h', - 'Register(name=i):0:29:@i', - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, { - hl('NestingParenthesis', '('), - hl('Register', '@a'), - hl('Ternary', '?'), - hl('Register', '@b'), - hl('TernaryColon', ':'), - hl('Register', '@c'), - hl('NestingParenthesis', ')'), - hl('Ternary', '?'), - hl('NestingParenthesis', '('), - hl('Register', '@d'), - hl('Ternary', '?'), - hl('Register', '@e'), - hl('TernaryColon', ':'), - hl('Register', '@f'), - hl('NestingParenthesis', ')'), - hl('TernaryColon', ':'), - hl('NestingParenthesis', '('), - hl('Register', '@g'), - hl('Ternary', '?'), - hl('Register', '@h'), - hl('TernaryColon', ':'), - hl('Register', '@i'), - hl('NestingParenthesis', ')'), - }) - - check_parsing('(@a?@b:@c)?@d?@e:@f:@g?@h:@i', { - -- 0123456789012345678901234567 - -- 0 1 2 - ast = { - { - 'Ternary:0:10:?', - children = { - { - 'Nested:0:0:(', - children = { - { - 'Ternary:0:3:?', - children = { - 'Register(name=a):0:1:@a', - { - 'TernaryValue:0:6::', - children = { - 'Register(name=b):0:4:@b', - 'Register(name=c):0:7:@c', - }, - }, - }, - }, - }, - }, - { - 'TernaryValue:0:19::', - children = { - { - 'Ternary:0:13:?', - children = { - 'Register(name=d):0:11:@d', - { - 'TernaryValue:0:16::', - children = { - 'Register(name=e):0:14:@e', - 'Register(name=f):0:17:@f', - }, - }, - }, - }, - { - 'Ternary:0:22:?', - children = { - 'Register(name=g):0:20:@g', - { - 'TernaryValue:0:25::', - children = { - 'Register(name=h):0:23:@h', - 'Register(name=i):0:26:@i', - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, { - hl('NestingParenthesis', '('), - hl('Register', '@a'), - hl('Ternary', '?'), - hl('Register', '@b'), - hl('TernaryColon', ':'), - hl('Register', '@c'), - hl('NestingParenthesis', ')'), - hl('Ternary', '?'), - hl('Register', '@d'), - hl('Ternary', '?'), - hl('Register', '@e'), - hl('TernaryColon', ':'), - hl('Register', '@f'), - hl('TernaryColon', ':'), - hl('Register', '@g'), - hl('Ternary', '?'), - hl('Register', '@h'), - hl('TernaryColon', ':'), - hl('Register', '@i'), - }) - check_parsing('a?b{cdef}g:h', { - -- 012345678901 - -- 0 1 - ast = { - { - 'Ternary:0:1:?', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - { - 'TernaryValue:0:10::', - children = { - { - 'ComplexIdentifier:0:3:', - children = { - 'PlainIdentifier(scope=0,ident=b):0:2:b', - { - 'ComplexIdentifier:0:9:', - children = { - { - 'CurlyBracesIdentifier:0:3:{', - children = { - 'PlainIdentifier(scope=0,ident=cdef):0:4:cdef', - }, - }, - 'PlainIdentifier(scope=0,ident=g):0:9:g', - }, - }, - }, - }, - 'PlainIdentifier(scope=0,ident=h):0:11:h', - }, - }, - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('Ternary', '?'), - hl('IdentifierName', 'b'), - hl('Curly', '{'), - hl('IdentifierName', 'cdef'), - hl('Curly', '}'), - hl('IdentifierName', 'g'), - hl('TernaryColon', ':'), - hl('IdentifierName', 'h'), - }) - check_parsing('a ? b : c : d', { - -- 0123456789012 - -- 0 1 - ast = { - { - 'Colon:0:9: :', - children = { - { - 'Ternary:0:1: ?', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - { - 'TernaryValue:0:5: :', - children = { - 'PlainIdentifier(scope=0,ident=b):0:3: b', - 'PlainIdentifier(scope=0,ident=c):0:7: c', - }, - }, - }, - }, - 'PlainIdentifier(scope=0,ident=d):0:11: d', - }, - }, - }, - err = { - arg = ': d', - msg = 'E15: Colon outside of dictionary or ternary operator: %.*s', - }, - }, { - hl('IdentifierName', 'a'), - hl('Ternary', '?', 1), - hl('IdentifierName', 'b', 1), - hl('TernaryColon', ':', 1), - hl('IdentifierName', 'c', 1), - hl('InvalidColon', ':', 1), - hl('IdentifierName', 'd', 1), - }) - end) - it('works with comparison operators', function() - check_parsing('a == b', { - -- 012345 - ast = { - { - 'Comparison(type=Equal,inv=0,ccs=UseOption):0:1: ==', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - 'PlainIdentifier(scope=0,ident=b):0:4: b', - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('Comparison', '==', 1), - hl('IdentifierName', 'b', 1), - }) - - check_parsing('a ==? b', { - -- 0123456 - ast = { - { - 'Comparison(type=Equal,inv=0,ccs=IgnoreCase):0:1: ==?', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - 'PlainIdentifier(scope=0,ident=b):0:5: b', - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('Comparison', '==', 1), - hl('ComparisonModifier', '?'), - hl('IdentifierName', 'b', 1), - }) - - check_parsing('a ==# b', { - -- 0123456 - ast = { - { - 'Comparison(type=Equal,inv=0,ccs=MatchCase):0:1: ==#', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - 'PlainIdentifier(scope=0,ident=b):0:5: b', - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('Comparison', '==', 1), - hl('ComparisonModifier', '#'), - hl('IdentifierName', 'b', 1), - }) - - check_parsing('a !=# b', { - -- 0123456 - ast = { - { - 'Comparison(type=Equal,inv=1,ccs=MatchCase):0:1: !=#', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - 'PlainIdentifier(scope=0,ident=b):0:5: b', - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('Comparison', '!=', 1), - hl('ComparisonModifier', '#'), - hl('IdentifierName', 'b', 1), - }) - - check_parsing('a <=# b', { - -- 0123456 - ast = { - { - 'Comparison(type=Greater,inv=1,ccs=MatchCase):0:1: <=#', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - 'PlainIdentifier(scope=0,ident=b):0:5: b', - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('Comparison', '<=', 1), - hl('ComparisonModifier', '#'), - hl('IdentifierName', 'b', 1), - }) - - check_parsing('a >=# b', { - -- 0123456 - ast = { - { - 'Comparison(type=GreaterOrEqual,inv=0,ccs=MatchCase):0:1: >=#', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - 'PlainIdentifier(scope=0,ident=b):0:5: b', - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('Comparison', '>=', 1), - hl('ComparisonModifier', '#'), - hl('IdentifierName', 'b', 1), - }) - - check_parsing('a ># b', { - -- 012345 - ast = { - { - 'Comparison(type=Greater,inv=0,ccs=MatchCase):0:1: >#', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - 'PlainIdentifier(scope=0,ident=b):0:4: b', - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('Comparison', '>', 1), - hl('ComparisonModifier', '#'), - hl('IdentifierName', 'b', 1), - }) - - check_parsing('a <# b', { - -- 012345 - ast = { - { - 'Comparison(type=GreaterOrEqual,inv=1,ccs=MatchCase):0:1: <#', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - 'PlainIdentifier(scope=0,ident=b):0:4: b', - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('Comparison', '<', 1), - hl('ComparisonModifier', '#'), - hl('IdentifierName', 'b', 1), - }) - - check_parsing('a is#b', { - -- 012345 - ast = { - { - 'Comparison(type=Identical,inv=0,ccs=MatchCase):0:1: is#', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - 'PlainIdentifier(scope=0,ident=b):0:5:b', - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('Comparison', 'is', 1), - hl('ComparisonModifier', '#'), - hl('IdentifierName', 'b'), - }) - - check_parsing('a is?b', { - -- 012345 - ast = { - { - 'Comparison(type=Identical,inv=0,ccs=IgnoreCase):0:1: is?', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - 'PlainIdentifier(scope=0,ident=b):0:5:b', - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('Comparison', 'is', 1), - hl('ComparisonModifier', '?'), - hl('IdentifierName', 'b'), - }) - - check_parsing('a isnot b', { - -- 012345678 - ast = { - { - 'Comparison(type=Identical,inv=1,ccs=UseOption):0:1: isnot', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - 'PlainIdentifier(scope=0,ident=b):0:7: b', - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('Comparison', 'isnot', 1), - hl('IdentifierName', 'b', 1), - }) - - check_parsing('a < b < c', { - -- 012345678 - ast = { - { - 'Comparison(type=GreaterOrEqual,inv=1,ccs=UseOption):0:1: <', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - { - 'Comparison(type=GreaterOrEqual,inv=1,ccs=UseOption):0:5: <', - children = { - 'PlainIdentifier(scope=0,ident=b):0:3: b', - 'PlainIdentifier(scope=0,ident=c):0:7: c', - }, - }, - }, - }, - }, - err = { - arg = ' < c', - msg = 'E15: Operator is not associative: %.*s', - }, - }, { - hl('IdentifierName', 'a'), - hl('Comparison', '<', 1), - hl('IdentifierName', 'b', 1), - hl('InvalidComparison', '<', 1), - hl('IdentifierName', 'c', 1), - }) - - check_parsing('a < b <# c', { - -- 012345678 - ast = { - { - 'Comparison(type=GreaterOrEqual,inv=1,ccs=UseOption):0:1: <', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - { - 'Comparison(type=GreaterOrEqual,inv=1,ccs=MatchCase):0:5: <#', - children = { - 'PlainIdentifier(scope=0,ident=b):0:3: b', - 'PlainIdentifier(scope=0,ident=c):0:8: c', - }, - }, - }, - }, - }, - err = { - arg = ' <# c', - msg = 'E15: Operator is not associative: %.*s', - }, - }, { - hl('IdentifierName', 'a'), - hl('Comparison', '<', 1), - hl('IdentifierName', 'b', 1), - hl('InvalidComparison', '<', 1), - hl('InvalidComparisonModifier', '#'), - hl('IdentifierName', 'c', 1), - }) - - check_parsing('a += b', { - -- 012345 - ast = { - { - 'Comparison(type=Equal,inv=0,ccs=UseOption):0:3:=', - children = { - { - 'BinaryPlus:0:1: +', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - 'Missing:0:3:', - }, - }, - 'PlainIdentifier(scope=0,ident=b):0:4: b', - }, - }, - }, - err = { - arg = '= b', - msg = 'E15: Expected == or =~: %.*s', - }, - }, { - hl('IdentifierName', 'a'), - hl('BinaryPlus', '+', 1), - hl('InvalidComparison', '='), - hl('IdentifierName', 'b', 1), - }) - check_parsing('a + b == c + d', { - -- 01234567890123 - -- 0 1 - ast = { - { - 'Comparison(type=Equal,inv=0,ccs=UseOption):0:5: ==', - children = { - { - 'BinaryPlus:0:1: +', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - 'PlainIdentifier(scope=0,ident=b):0:3: b', - }, - }, - { - 'BinaryPlus:0:10: +', - children = { - 'PlainIdentifier(scope=0,ident=c):0:8: c', - 'PlainIdentifier(scope=0,ident=d):0:12: d', - }, - }, - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('BinaryPlus', '+', 1), - hl('IdentifierName', 'b', 1), - hl('Comparison', '==', 1), - hl('IdentifierName', 'c', 1), - hl('BinaryPlus', '+', 1), - hl('IdentifierName', 'd', 1), - }) - check_parsing('+ a == + b', { - -- 0123456789 - ast = { - { - 'Comparison(type=Equal,inv=0,ccs=UseOption):0:3: ==', - children = { - { - 'UnaryPlus:0:0:+', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1: a', - }, - }, - { - 'UnaryPlus:0:6: +', - children = { - 'PlainIdentifier(scope=0,ident=b):0:8: b', - }, - }, - }, - }, - }, - }, { - hl('UnaryPlus', '+'), - hl('IdentifierName', 'a', 1), - hl('Comparison', '==', 1), - hl('UnaryPlus', '+', 1), - hl('IdentifierName', 'b', 1), - }) - end) - it('works with concat/subscript', function() - check_parsing('.', { - -- 0 - ast = { - { - 'ConcatOrSubscript:0:0:.', - children = { - 'Missing:0:0:', - }, - }, - }, - err = { - arg = '.', - msg = 'E15: Unexpected dot: %.*s', - }, - }, { - hl('InvalidConcatOrSubscript', '.'), - }) - - check_parsing('a.', { - -- 01 - ast = { - { - 'ConcatOrSubscript:0:1:.', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - }, - }, - }, - err = { - arg = '', - msg = 'E15: Expected value, got EOC: %.*s', - }, - }, { - hl('IdentifierName', 'a'), - hl('ConcatOrSubscript', '.'), - }) - - check_parsing('a.b', { - -- 012 - ast = { - { - 'ConcatOrSubscript:0:1:.', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - 'PlainKey(key=b):0:2:b', - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('ConcatOrSubscript', '.'), - hl('IdentifierKey', 'b'), - }) - - check_parsing('1.2', { - -- 012 - ast = { - 'Float(val=1.200000e+00):0:0:1.2', - }, - }, { - hl('Float', '1.2'), - }) - - check_parsing('1.2 + 1.3e-5', { - -- 012345678901 - -- 0 1 - ast = { - { - 'BinaryPlus:0:3: +', - children = { - 'Float(val=1.200000e+00):0:0:1.2', - 'Float(val=1.300000e-05):0:5: 1.3e-5', - }, - }, - }, - }, { - hl('Float', '1.2'), - hl('BinaryPlus', '+', 1), - hl('Float', '1.3e-5', 1), - }) - - check_parsing('a . 1.2 + 1.3e-5', { - -- 0123456789012345 - -- 0 1 - ast = { - { - 'BinaryPlus:0:7: +', - children = { - { - 'Concat:0:1: .', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - { - 'ConcatOrSubscript:0:5:.', - children = { - 'Integer(val=1):0:3: 1', - 'PlainKey(key=2):0:6:2', - }, - }, - }, - }, - 'Float(val=1.300000e-05):0:9: 1.3e-5', - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('Concat', '.', 1), - hl('Number', '1', 1), - hl('ConcatOrSubscript', '.'), - hl('IdentifierKey', '2'), - hl('BinaryPlus', '+', 1), - hl('Float', '1.3e-5', 1), - }) - - check_parsing('1.3e-5 + 1.2 . a', { - -- 0123456789012345 - -- 0 1 - ast = { - { - 'Concat:0:12: .', - children = { - { - 'BinaryPlus:0:6: +', - children = { - 'Float(val=1.300000e-05):0:0:1.3e-5', - 'Float(val=1.200000e+00):0:8: 1.2', - }, - }, - 'PlainIdentifier(scope=0,ident=a):0:14: a', - }, - }, - }, - }, { - hl('Float', '1.3e-5'), - hl('BinaryPlus', '+', 1), - hl('Float', '1.2', 1), - hl('Concat', '.', 1), - hl('IdentifierName', 'a', 1), - }) - - check_parsing('1.3e-5 + a . 1.2', { - -- 0123456789012345 - -- 0 1 - ast = { - { - 'Concat:0:10: .', - children = { - { - 'BinaryPlus:0:6: +', - children = { - 'Float(val=1.300000e-05):0:0:1.3e-5', - 'PlainIdentifier(scope=0,ident=a):0:8: a', - }, - }, - { - 'ConcatOrSubscript:0:14:.', - children = { - 'Integer(val=1):0:12: 1', - 'PlainKey(key=2):0:15:2', - }, - }, - }, - }, - }, - }, { - hl('Float', '1.3e-5'), - hl('BinaryPlus', '+', 1), - hl('IdentifierName', 'a', 1), - hl('Concat', '.', 1), - hl('Number', '1', 1), - hl('ConcatOrSubscript', '.'), - hl('IdentifierKey', '2'), - }) - - check_parsing('1.2.3', { - -- 01234 - ast = { - { - 'ConcatOrSubscript:0:3:.', - children = { - { - 'ConcatOrSubscript:0:1:.', - children = { - 'Integer(val=1):0:0:1', - 'PlainKey(key=2):0:2:2', - }, - }, - 'PlainKey(key=3):0:4:3', - }, - }, - }, - }, { - hl('Number', '1'), - hl('ConcatOrSubscript', '.'), - hl('IdentifierKey', '2'), - hl('ConcatOrSubscript', '.'), - hl('IdentifierKey', '3'), - }) - - check_parsing('a.1.2', { - -- 01234 - ast = { - { - 'ConcatOrSubscript:0:3:.', - children = { - { - 'ConcatOrSubscript:0:1:.', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - 'PlainKey(key=1):0:2:1', - }, - }, - 'PlainKey(key=2):0:4:2', - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('ConcatOrSubscript', '.'), - hl('IdentifierKey', '1'), - hl('ConcatOrSubscript', '.'), - hl('IdentifierKey', '2'), - }) - - check_parsing('a . 1.2', { - -- 0123456 - ast = { - { - 'Concat:0:1: .', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - { - 'ConcatOrSubscript:0:5:.', - children = { - 'Integer(val=1):0:3: 1', - 'PlainKey(key=2):0:6:2', - }, - }, - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('Concat', '.', 1), - hl('Number', '1', 1), - hl('ConcatOrSubscript', '.'), - hl('IdentifierKey', '2'), - }) - - check_parsing('+a . +b', { - -- 0123456 - ast = { - { - 'Concat:0:2: .', - children = { - { - 'UnaryPlus:0:0:+', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - }, - }, - { - 'UnaryPlus:0:4: +', - children = { - 'PlainIdentifier(scope=0,ident=b):0:6:b', - }, - }, - }, - }, - }, - }, { - hl('UnaryPlus', '+'), - hl('IdentifierName', 'a'), - hl('Concat', '.', 1), - hl('UnaryPlus', '+', 1), - hl('IdentifierName', 'b'), - }) - - check_parsing('a. b', { - -- 0123 - ast = { - { - 'Concat:0:1:.', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - 'PlainIdentifier(scope=0,ident=b):0:2: b', - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('ConcatOrSubscript', '.'), - hl('IdentifierName', 'b', 1), - }) - - check_parsing('a. 1', { - -- 0123 - ast = { - { - 'Concat:0:1:.', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - 'Integer(val=1):0:2: 1', - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('ConcatOrSubscript', '.'), - hl('Number', '1', 1), - }) - end) - it('works with bracket subscripts', function() - check_parsing(':', { - -- 0 - ast = { - { - 'Colon:0:0::', - children = { - 'Missing:0:0:', - }, - }, - }, - err = { - arg = ':', - msg = 'E15: Colon outside of dictionary or ternary operator: %.*s', - }, - }, { - hl('InvalidColon', ':'), - }) - check_parsing('a[]', { - -- 012 - ast = { - { - 'Subscript:0:1:[', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - }, - }, - }, - err = { - arg = ']', - msg = 'E15: Expected value, got closing bracket: %.*s', - }, - }, { - hl('IdentifierName', 'a'), - hl('SubscriptBracket', '['), - hl('InvalidSubscriptBracket', ']'), - }) - check_parsing('a[b:]', { - -- 01234 - ast = { - { - 'Subscript:0:1:[', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - 'PlainIdentifier(scope=b,ident=):0:2:b:', - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('SubscriptBracket', '['), - hl('IdentifierScope', 'b'), - hl('IdentifierScopeDelimiter', ':'), - hl('SubscriptBracket', ']'), - }) - - check_parsing('a[b:c]', { - -- 012345 - ast = { - { - 'Subscript:0:1:[', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - 'PlainIdentifier(scope=b,ident=c):0:2:b:c', - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('SubscriptBracket', '['), - hl('IdentifierScope', 'b'), - hl('IdentifierScopeDelimiter', ':'), - hl('IdentifierName', 'c'), - hl('SubscriptBracket', ']'), - }) - check_parsing('a[b : c]', { - -- 01234567 - ast = { - { - 'Subscript:0:1:[', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - { - 'Colon:0:3: :', - children = { - 'PlainIdentifier(scope=0,ident=b):0:2:b', - 'PlainIdentifier(scope=0,ident=c):0:5: c', - }, - }, - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('SubscriptBracket', '['), - hl('IdentifierName', 'b'), - hl('SubscriptColon', ':', 1), - hl('IdentifierName', 'c', 1), - hl('SubscriptBracket', ']'), - }) - - check_parsing('a[: b]', { - -- 012345 - ast = { - { - 'Subscript:0:1:[', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - { - 'Colon:0:2::', - children = { - 'Missing:0:2:', - 'PlainIdentifier(scope=0,ident=b):0:3: b', - }, - }, - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('SubscriptBracket', '['), - hl('SubscriptColon', ':'), - hl('IdentifierName', 'b', 1), - hl('SubscriptBracket', ']'), - }) - - check_parsing('a[b :]', { - -- 012345 - ast = { - { - 'Subscript:0:1:[', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - { - 'Colon:0:3: :', - children = { - 'PlainIdentifier(scope=0,ident=b):0:2:b', - }, - }, - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('SubscriptBracket', '['), - hl('IdentifierName', 'b'), - hl('SubscriptColon', ':', 1), - hl('SubscriptBracket', ']'), - }) - check_parsing('a[b][c][d](e)(f)(g)', { - -- 0123456789012345678 - -- 0 1 - ast = { - { - 'Call:0:16:(', - children = { - { - 'Call:0:13:(', - children = { - { - 'Call:0:10:(', - children = { - { - 'Subscript:0:7:[', - children = { - { - 'Subscript:0:4:[', - children = { - { - 'Subscript:0:1:[', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - 'PlainIdentifier(scope=0,ident=b):0:2:b', - }, - }, - 'PlainIdentifier(scope=0,ident=c):0:5:c', - }, - }, - 'PlainIdentifier(scope=0,ident=d):0:8:d', - }, - }, - 'PlainIdentifier(scope=0,ident=e):0:11:e', - }, - }, - 'PlainIdentifier(scope=0,ident=f):0:14:f', - }, - }, - 'PlainIdentifier(scope=0,ident=g):0:17:g', - }, - }, - }, - }, { - hl('IdentifierName', 'a'), - hl('SubscriptBracket', '['), - hl('IdentifierName', 'b'), - hl('SubscriptBracket', ']'), - hl('SubscriptBracket', '['), - hl('IdentifierName', 'c'), - hl('SubscriptBracket', ']'), - hl('SubscriptBracket', '['), - hl('IdentifierName', 'd'), - hl('SubscriptBracket', ']'), - hl('CallingParenthesis', '('), - hl('IdentifierName', 'e'), - hl('CallingParenthesis', ')'), - hl('CallingParenthesis', '('), - hl('IdentifierName', 'f'), - hl('CallingParenthesis', ')'), - hl('CallingParenthesis', '('), - hl('IdentifierName', 'g'), - hl('CallingParenthesis', ')'), - }) - check_parsing('{a}{b}{c}[d][e][f]', { - -- 012345678901234567 - -- 0 1 - ast = { - { - 'Subscript:0:15:[', - children = { - { - 'Subscript:0:12:[', - children = { - { - 'Subscript:0:9:[', - children = { - { - 'ComplexIdentifier:0:3:', - children = { - { - 'CurlyBracesIdentifier:0:0:{', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - }, - }, - { - 'ComplexIdentifier:0:6:', - children = { - { - 'CurlyBracesIdentifier:0:3:{', - children = { - 'PlainIdentifier(scope=0,ident=b):0:4:b', - }, - }, - { - 'CurlyBracesIdentifier:0:6:{', - children = { - 'PlainIdentifier(scope=0,ident=c):0:7:c', - }, - }, - }, - }, - }, - }, - 'PlainIdentifier(scope=0,ident=d):0:10:d', - }, - }, - 'PlainIdentifier(scope=0,ident=e):0:13:e', - }, - }, - 'PlainIdentifier(scope=0,ident=f):0:16:f', - }, - }, - }, - }, { - hl('Curly', '{'), - hl('IdentifierName', 'a'), - hl('Curly', '}'), - hl('Curly', '{'), - hl('IdentifierName', 'b'), - hl('Curly', '}'), - hl('Curly', '{'), - hl('IdentifierName', 'c'), - hl('Curly', '}'), - hl('SubscriptBracket', '['), - hl('IdentifierName', 'd'), - hl('SubscriptBracket', ']'), - hl('SubscriptBracket', '['), - hl('IdentifierName', 'e'), - hl('SubscriptBracket', ']'), - hl('SubscriptBracket', '['), - hl('IdentifierName', 'f'), - hl('SubscriptBracket', ']'), - }) - end) - it('supports list literals', function() - check_parsing('[]', { - -- 01 - ast = { - 'ListLiteral:0:0:[', - }, - }, { - hl('List', '['), - hl('List', ']'), - }) - - check_parsing('[a]', { - -- 012 - ast = { - { - 'ListLiteral:0:0:[', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - }, - }, - }, - }, { - hl('List', '['), - hl('IdentifierName', 'a'), - hl('List', ']'), - }) - - check_parsing('[a, b]', { - -- 012345 - ast = { - { - 'ListLiteral:0:0:[', - children = { - { - 'Comma:0:2:,', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - 'PlainIdentifier(scope=0,ident=b):0:3: b', - }, - }, - }, - }, - }, - }, { - hl('List', '['), - hl('IdentifierName', 'a'), - hl('Comma', ','), - hl('IdentifierName', 'b', 1), - hl('List', ']'), - }) - - check_parsing('[a, b, c]', { - -- 012345678 - ast = { - { - 'ListLiteral:0:0:[', - children = { - { - 'Comma:0:2:,', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - { - 'Comma:0:5:,', - children = { - 'PlainIdentifier(scope=0,ident=b):0:3: b', - 'PlainIdentifier(scope=0,ident=c):0:6: c', - }, - }, - }, - }, - }, - }, - }, - }, { - hl('List', '['), - hl('IdentifierName', 'a'), - hl('Comma', ','), - hl('IdentifierName', 'b', 1), - hl('Comma', ','), - hl('IdentifierName', 'c', 1), - hl('List', ']'), - }) - - check_parsing('[a, b, c, ]', { - -- 01234567890 - -- 0 1 - ast = { - { - 'ListLiteral:0:0:[', - children = { - { - 'Comma:0:2:,', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - { - 'Comma:0:5:,', - children = { - 'PlainIdentifier(scope=0,ident=b):0:3: b', - { - 'Comma:0:8:,', - children = { - 'PlainIdentifier(scope=0,ident=c):0:6: c', - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, { - hl('List', '['), - hl('IdentifierName', 'a'), - hl('Comma', ','), - hl('IdentifierName', 'b', 1), - hl('Comma', ','), - hl('IdentifierName', 'c', 1), - hl('Comma', ','), - hl('List', ']', 1), - }) - - check_parsing('[a : b, c : d]', { - -- 01234567890123 - -- 0 1 - ast = { - { - 'ListLiteral:0:0:[', - children = { - { - 'Comma:0:6:,', - children = { - { - 'Colon:0:2: :', - children = { - 'PlainIdentifier(scope=0,ident=a):0:1:a', - 'PlainIdentifier(scope=0,ident=b):0:4: b', - }, - }, - { - 'Colon:0:9: :', - children = { - 'PlainIdentifier(scope=0,ident=c):0:7: c', - 'PlainIdentifier(scope=0,ident=d):0:11: d', - }, - }, - }, - }, - }, - }, - }, - err = { - arg = ': b, c : d]', - msg = 'E15: Colon outside of dictionary or ternary operator: %.*s', - }, - }, { - hl('List', '['), - hl('IdentifierName', 'a'), - hl('InvalidColon', ':', 1), - hl('IdentifierName', 'b', 1), - hl('Comma', ','), - hl('IdentifierName', 'c', 1), - hl('InvalidColon', ':', 1), - hl('IdentifierName', 'd', 1), - hl('List', ']'), - }) - - check_parsing(']', { - -- 0 - ast = { - 'ListLiteral:0:0:', - }, - err = { - arg = ']', - msg = 'E15: Unexpected closing figure brace: %.*s', - }, - }, { - hl('InvalidList', ']'), - }) - - check_parsing('a]', { - -- 01 - ast = { - { - 'ListLiteral:0:1:', - children = { - 'PlainIdentifier(scope=0,ident=a):0:0:a', - }, - }, - }, - err = { - arg = ']', - msg = 'E15: Unexpected closing figure brace: %.*s', - }, - }, { - hl('IdentifierName', 'a'), - hl('InvalidList', ']'), - }) - - check_parsing('[] []', { - -- 01234 - ast = { - { - 'OpMissing:0:2:', - children = { - 'ListLiteral:0:0:[', - 'ListLiteral:0:2: [', - }, - }, - }, - err = { - arg = '[]', - msg = 'E15: Missing operator: %.*s', - }, - }, { - hl('List', '['), - hl('List', ']'), - hl('InvalidSpacing', ' '), - hl('List', '['), - hl('List', ']'), - }, { - [1] = { - ast = { - len = 3, - err = REMOVE_THIS, - ast = { - 'ListLiteral:0:0:[', - }, - }, - hl_fs = { - [3] = REMOVE_THIS, - [4] = REMOVE_THIS, - [5] = REMOVE_THIS, - }, - }, - }) - - check_parsing('[][]', { - -- 0123 - ast = { - { - 'Subscript:0:2:[', - children = { - 'ListLiteral:0:0:[', - }, - }, - }, - err = { - arg = ']', - msg = 'E15: Expected value, got closing bracket: %.*s', - }, - }, { - hl('List', '['), - hl('List', ']'), - hl('SubscriptBracket', '['), - hl('InvalidSubscriptBracket', ']'), - }) - - check_parsing('[', { - -- 0 - ast = { - 'ListLiteral:0:0:[', - }, - err = { - arg = '', - msg = 'E15: Expected value, got EOC: %.*s', - }, - }, { - hl('List', '['), - }) - - check_parsing('[1', { - -- 01 - ast = { - { - 'ListLiteral:0:0:[', - children = { - 'Integer(val=1):0:1:1', - }, - }, - }, - err = { - arg = '[1', - msg = 'E697: Missing end of List \']\': %.*s', - }, - }, { - hl('List', '['), - hl('Number', '1'), - }) - end) - it('works with strings', function() - check_parsing('\'abc\'', { - -- 01234 - ast = { - 'SingleQuotedString(val="abc"):0:0:\'abc\'', - }, - }, { - hl('SingleQuote', '\''), - hl('SingleQuotedBody', 'abc'), - hl('SingleQuote', '\''), - }) - check_parsing('"abc"', { - -- 01234 - ast = { - 'DoubleQuotedString(val="abc"):0:0:"abc"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedBody', 'abc'), - hl('DoubleQuote', '"'), - }) - check_parsing('\'\'', { - -- 01 - ast = { - 'SingleQuotedString(val=""):0:0:\'\'', - }, - }, { - hl('SingleQuote', '\''), - hl('SingleQuote', '\''), - }) - check_parsing('""', { - -- 01 - ast = { - 'DoubleQuotedString(val=""):0:0:""', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuote', '"'), - }) - check_parsing('"', { - -- 0 - ast = { - 'DoubleQuotedString(val=""):0:0:"', - }, - err = { - arg = '"', - msg = 'E114: Missing double quote: %.*s', - }, - }, { - hl('InvalidDoubleQuote', '"'), - }) - check_parsing('\'', { - -- 0 - ast = { - 'SingleQuotedString(val=""):0:0:\'', - }, - err = { - arg = '\'', - msg = 'E115: Missing single quote: %.*s', - }, - }, { - hl('InvalidSingleQuote', '\''), - }) - check_parsing('"a', { - -- 01 - ast = { - 'DoubleQuotedString(val="a"):0:0:"a', - }, - err = { - arg = '"a', - msg = 'E114: Missing double quote: %.*s', - }, - }, { - hl('InvalidDoubleQuote', '"'), - hl('InvalidDoubleQuotedBody', 'a'), - }) - check_parsing('\'a', { - -- 01 - ast = { - 'SingleQuotedString(val="a"):0:0:\'a', - }, - err = { - arg = '\'a', - msg = 'E115: Missing single quote: %.*s', - }, - }, { - hl('InvalidSingleQuote', '\''), - hl('InvalidSingleQuotedBody', 'a'), - }) - check_parsing('\'abc\'\'def\'', { - -- 0123456789 - ast = { - 'SingleQuotedString(val="abc\'def"):0:0:\'abc\'\'def\'', - }, - }, { - hl('SingleQuote', '\''), - hl('SingleQuotedBody', 'abc'), - hl('SingleQuotedQuote', '\'\''), - hl('SingleQuotedBody', 'def'), - hl('SingleQuote', '\''), - }) - check_parsing('\'abc\'\'', { - -- 012345 - ast = { - 'SingleQuotedString(val="abc\'"):0:0:\'abc\'\'', - }, - err = { - arg = '\'abc\'\'', - msg = 'E115: Missing single quote: %.*s', - }, - }, { - hl('InvalidSingleQuote', '\''), - hl('InvalidSingleQuotedBody', 'abc'), - hl('InvalidSingleQuotedQuote', '\'\''), - }) - check_parsing('\'\'\'\'\'\'\'\'', { - -- 01234567 - ast = { - 'SingleQuotedString(val="\'\'\'"):0:0:\'\'\'\'\'\'\'\'', - }, - }, { - hl('SingleQuote', '\''), - hl('SingleQuotedQuote', '\'\''), - hl('SingleQuotedQuote', '\'\''), - hl('SingleQuotedQuote', '\'\''), - hl('SingleQuote', '\''), - }) - check_parsing('\'\'\'a\'\'\'\'bc\'', { - -- 01234567890 - -- 0 1 - ast = { - 'SingleQuotedString(val="\'a\'\'bc"):0:0:\'\'\'a\'\'\'\'bc\'', - }, - }, { - hl('SingleQuote', '\''), - hl('SingleQuotedQuote', '\'\''), - hl('SingleQuotedBody', 'a'), - hl('SingleQuotedQuote', '\'\''), - hl('SingleQuotedQuote', '\'\''), - hl('SingleQuotedBody', 'bc'), - hl('SingleQuote', '\''), - }) - check_parsing('"\\"\\"\\"\\""', { - -- 0123456789 - ast = { - 'DoubleQuotedString(val="\\"\\"\\"\\""):0:0:"\\"\\"\\"\\""', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\"'), - hl('DoubleQuotedEscape', '\\"'), - hl('DoubleQuotedEscape', '\\"'), - hl('DoubleQuotedEscape', '\\"'), - hl('DoubleQuote', '"'), - }) - check_parsing('"abc\\"def\\"ghi\\"jkl\\"mno"', { - -- 0123456789012345678901234 - -- 0 1 2 - ast = { - 'DoubleQuotedString(val="abc\\"def\\"ghi\\"jkl\\"mno"):0:0:"abc\\"def\\"ghi\\"jkl\\"mno"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedBody', 'abc'), - hl('DoubleQuotedEscape', '\\"'), - hl('DoubleQuotedBody', 'def'), - hl('DoubleQuotedEscape', '\\"'), - hl('DoubleQuotedBody', 'ghi'), - hl('DoubleQuotedEscape', '\\"'), - hl('DoubleQuotedBody', 'jkl'), - hl('DoubleQuotedEscape', '\\"'), - hl('DoubleQuotedBody', 'mno'), - hl('DoubleQuote', '"'), - }) - check_parsing('"\\b\\e\\f\\r\\t\\\\"', { - -- 0123456789012345 - -- 0 1 - ast = { - [[DoubleQuotedString(val="\8\27\12\13\9\\"):0:0:"\b\e\f\r\t\\"]], - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\b'), - hl('DoubleQuotedEscape', '\\e'), - hl('DoubleQuotedEscape', '\\f'), - hl('DoubleQuotedEscape', '\\r'), - hl('DoubleQuotedEscape', '\\t'), - hl('DoubleQuotedEscape', '\\\\'), - hl('DoubleQuote', '"'), - }) - check_parsing('"\\n\n"', { - -- 01234 - ast = { - 'DoubleQuotedString(val="\\\n\\\n"):0:0:"\\n\n"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\n'), - hl('DoubleQuotedBody', '\n'), - hl('DoubleQuote', '"'), - }) - check_parsing('"\\x00"', { - -- 012345 - ast = { - 'DoubleQuotedString(val="\\0"):0:0:"\\x00"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\x00'), - hl('DoubleQuote', '"'), - }) - check_parsing('"\\xFF"', { - -- 012345 - ast = { - 'DoubleQuotedString(val="\255"):0:0:"\\xFF"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\xFF'), - hl('DoubleQuote', '"'), - }) - check_parsing('"\\xF"', { - -- 012345 - ast = { - 'DoubleQuotedString(val="\\15"):0:0:"\\xF"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\xF'), - hl('DoubleQuote', '"'), - }) - check_parsing('"\\u00AB"', { - -- 01234567 - ast = { - 'DoubleQuotedString(val="«"):0:0:"\\u00AB"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\u00AB'), - hl('DoubleQuote', '"'), - }) - check_parsing('"\\U000000AB"', { - -- 01234567 - ast = { - 'DoubleQuotedString(val="«"):0:0:"\\U000000AB"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\U000000AB'), - hl('DoubleQuote', '"'), - }) - check_parsing('"\\x"', { - -- 0123 - ast = { - 'DoubleQuotedString(val="x"):0:0:"\\x"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedUnknownEscape', '\\x'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\x', { - -- 012 - ast = { - 'DoubleQuotedString(val="x"):0:0:"\\x', - }, - err = { - arg = '"\\x', - msg = 'E114: Missing double quote: %.*s', - }, - }, { - hl('InvalidDoubleQuote', '"'), - hl('InvalidDoubleQuotedUnknownEscape', '\\x'), - }) - - check_parsing('"\\xF', { - -- 0123 - ast = { - 'DoubleQuotedString(val="\\15"):0:0:"\\xF', - }, - err = { - arg = '"\\xF', - msg = 'E114: Missing double quote: %.*s', - }, - }, { - hl('InvalidDoubleQuote', '"'), - hl('InvalidDoubleQuotedEscape', '\\xF'), - }) - - check_parsing('"\\u"', { - -- 0123 - ast = { - 'DoubleQuotedString(val="u"):0:0:"\\u"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedUnknownEscape', '\\u'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\u', { - -- 012 - ast = { - 'DoubleQuotedString(val="u"):0:0:"\\u', - }, - err = { - arg = '"\\u', - msg = 'E114: Missing double quote: %.*s', - }, - }, { - hl('InvalidDoubleQuote', '"'), - hl('InvalidDoubleQuotedUnknownEscape', '\\u'), - }) - - check_parsing('"\\U', { - -- 012 - ast = { - 'DoubleQuotedString(val="U"):0:0:"\\U', - }, - err = { - arg = '"\\U', - msg = 'E114: Missing double quote: %.*s', - }, - }, { - hl('InvalidDoubleQuote', '"'), - hl('InvalidDoubleQuotedUnknownEscape', '\\U'), - }) - - check_parsing('"\\U"', { - -- 0123 - ast = { - 'DoubleQuotedString(val="U"):0:0:"\\U"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedUnknownEscape', '\\U'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\xFX"', { - -- 012345 - ast = { - 'DoubleQuotedString(val="\\15X"):0:0:"\\xFX"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\xF'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\XFX"', { - -- 012345 - ast = { - 'DoubleQuotedString(val="\\15X"):0:0:"\\XFX"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\XF'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\xX"', { - -- 01234 - ast = { - 'DoubleQuotedString(val="xX"):0:0:"\\xX"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedUnknownEscape', '\\x'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\XX"', { - -- 01234 - ast = { - 'DoubleQuotedString(val="XX"):0:0:"\\XX"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedUnknownEscape', '\\X'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\uX"', { - -- 01234 - ast = { - 'DoubleQuotedString(val="uX"):0:0:"\\uX"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedUnknownEscape', '\\u'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\UX"', { - -- 01234 - ast = { - 'DoubleQuotedString(val="UX"):0:0:"\\UX"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedUnknownEscape', '\\U'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\x0X"', { - -- 012345 - ast = { - 'DoubleQuotedString(val="\\0X"):0:0:"\\x0X"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\x0'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\X0X"', { - -- 012345 - ast = { - 'DoubleQuotedString(val="\\0X"):0:0:"\\X0X"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\X0'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\u0X"', { - -- 012345 - ast = { - 'DoubleQuotedString(val="\\0X"):0:0:"\\u0X"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\u0'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\U0X"', { - -- 012345 - ast = { - 'DoubleQuotedString(val="\\0X"):0:0:"\\U0X"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\U0'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\x00X"', { - -- 0123456 - ast = { - 'DoubleQuotedString(val="\\0X"):0:0:"\\x00X"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\x00'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\X00X"', { - -- 0123456 - ast = { - 'DoubleQuotedString(val="\\0X"):0:0:"\\X00X"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\X00'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\u00X"', { - -- 0123456 - ast = { - 'DoubleQuotedString(val="\\0X"):0:0:"\\u00X"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\u00'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\U00X"', { - -- 0123456 - ast = { - 'DoubleQuotedString(val="\\0X"):0:0:"\\U00X"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\U00'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\u000X"', { - -- 01234567 - ast = { - 'DoubleQuotedString(val="\\0X"):0:0:"\\u000X"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\u000'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\U000X"', { - -- 01234567 - ast = { - 'DoubleQuotedString(val="\\0X"):0:0:"\\U000X"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\U000'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\u0000X"', { - -- 012345678 - ast = { - 'DoubleQuotedString(val="\\0X"):0:0:"\\u0000X"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\u0000'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\U0000X"', { - -- 012345678 - ast = { - 'DoubleQuotedString(val="\\0X"):0:0:"\\U0000X"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\U0000'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\U00000X"', { - -- 0123456789 - ast = { - 'DoubleQuotedString(val="\\0X"):0:0:"\\U00000X"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\U00000'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\U000000X"', { - -- 01234567890 - -- 0 1 - ast = { - 'DoubleQuotedString(val="\\0X"):0:0:"\\U000000X"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\U000000'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\U0000000X"', { - -- 012345678901 - -- 0 1 - ast = { - 'DoubleQuotedString(val="\\0X"):0:0:"\\U0000000X"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\U0000000'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\U00000000X"', { - -- 0123456789012 - -- 0 1 - ast = { - 'DoubleQuotedString(val="\\0X"):0:0:"\\U00000000X"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\U00000000'), - hl('DoubleQuotedBody', 'X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\x000X"', { - -- 01234567 - ast = { - 'DoubleQuotedString(val="\\0000X"):0:0:"\\x000X"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\x00'), - hl('DoubleQuotedBody', '0X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\X000X"', { - -- 01234567 - ast = { - 'DoubleQuotedString(val="\\0000X"):0:0:"\\X000X"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\X00'), - hl('DoubleQuotedBody', '0X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\u00000X"', { - -- 0123456789 - ast = { - 'DoubleQuotedString(val="\\0000X"):0:0:"\\u00000X"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\u0000'), - hl('DoubleQuotedBody', '0X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\U000000000X"', { - -- 01234567890123 - -- 0 1 - ast = { - 'DoubleQuotedString(val="\\0000X"):0:0:"\\U000000000X"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\U00000000'), - hl('DoubleQuotedBody', '0X'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\0"', { - -- 0123 - ast = { - 'DoubleQuotedString(val="\\0"):0:0:"\\0"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\0'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\00"', { - -- 01234 - ast = { - 'DoubleQuotedString(val="\\0"):0:0:"\\00"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\00'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\000"', { - -- 012345 - ast = { - 'DoubleQuotedString(val="\\0"):0:0:"\\000"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\000'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\0000"', { - -- 0123456 - ast = { - 'DoubleQuotedString(val="\\0000"):0:0:"\\0000"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\000'), - hl('DoubleQuotedBody', '0'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\8"', { - -- 0123 - ast = { - 'DoubleQuotedString(val="8"):0:0:"\\8"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedUnknownEscape', '\\8'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\08"', { - -- 01234 - ast = { - 'DoubleQuotedString(val="\\0008"):0:0:"\\08"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\0'), - hl('DoubleQuotedBody', '8'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\008"', { - -- 012345 - ast = { - 'DoubleQuotedString(val="\\0008"):0:0:"\\008"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\00'), - hl('DoubleQuotedBody', '8'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\0008"', { - -- 0123456 - ast = { - 'DoubleQuotedString(val="\\0008"):0:0:"\\0008"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\000'), - hl('DoubleQuotedBody', '8'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\777"', { - -- 012345 - ast = { - 'DoubleQuotedString(val="\255"):0:0:"\\777"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\777'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\050"', { - -- 012345 - ast = { - 'DoubleQuotedString(val="\40"):0:0:"\\050"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\050'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\"', { - -- 012345 - ast = { - 'DoubleQuotedString(val="\\21"):0:0:"\\"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedEscape', '\\'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\<', { - -- 012 - ast = { - 'DoubleQuotedString(val="<"):0:0:"\\<', - }, - err = { - arg = '"\\<', - msg = 'E114: Missing double quote: %.*s', - }, - }, { - hl('InvalidDoubleQuote', '"'), - hl('InvalidDoubleQuotedUnknownEscape', '\\<'), - }) - - check_parsing('"\\<"', { - -- 0123 - ast = { - 'DoubleQuotedString(val="<"):0:0:"\\<"', - }, - }, { - hl('DoubleQuote', '"'), - hl('DoubleQuotedUnknownEscape', '\\<'), - hl('DoubleQuote', '"'), - }) - - check_parsing('"\\ Date: Sun, 19 Nov 2017 21:13:27 +0300 Subject: *: Fix linter errors --- test/functional/api/vim_spec.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'test/functional') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 3939bc9b52..2572675a58 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -12,7 +12,6 @@ local request = helpers.request local meth_pcall = helpers.meth_pcall local command = helpers.command -local REMOVE_THIS = global_helpers.REMOVE_THIS local intchar2lua = global_helpers.intchar2lua local format_string = global_helpers.format_string local mergedicts_copy = global_helpers.mergedicts_copy -- cgit From ebb33eddd9ad0e9cec5013be2e37c8f9b0546c77 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 19 Nov 2017 21:40:34 +0300 Subject: tests: Stabilize float format and %e in format_luav and format_string --- test/functional/api/vim_spec.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/functional') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 2572675a58..5b5340d9e2 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -750,7 +750,7 @@ describe('api', function() typ = typ .. ('(val=%u)'):format(east_api_node.ivalue) east_api_node.ivalue = nil elseif typ == 'Float' then - typ = typ .. ('(val=%e)'):format(east_api_node.fvalue) + typ = typ .. format_string('(val=%e)', east_api_node.fvalue) east_api_node.fvalue = nil elseif typ == 'SingleQuotedString' or typ == 'DoubleQuotedString' then typ = format_string('%s(val=%q)', typ, east_api_node.svalue) -- cgit From 17077b68133a62d0dc1b84cb48779464c117e028 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 26 Nov 2017 16:08:53 +0300 Subject: viml/parser/expressions: Make $ENV not depend on &isident --- test/functional/api/vim_spec.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'test/functional') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 5b5340d9e2..841b7a584a 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -717,6 +717,9 @@ describe('api', function() end) describe('nvim_parse_expression', function() + before_each(function() + meths.set_option('isident', '') + end) local function simplify_east_api_node(line, east_api_node) if east_api_node == NIL then return nil -- cgit From cddf84c3982b8225f1592b6a61b63f8d1883ca94 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 26 Nov 2017 16:45:29 +0300 Subject: functests: Add some more tests --- test/functional/ui/cmdline_highlight_spec.lua | 87 +++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 4 deletions(-) (limited to 'test/functional') diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua index 023673738d..54d27723f0 100644 --- a/test/functional/ui/cmdline_highlight_spec.lua +++ b/test/functional/ui/cmdline_highlight_spec.lua @@ -147,6 +147,10 @@ before_each(function() PE={bold = true, foreground = Screen.colors.SeaGreen4}, NUM={foreground = Screen.colors.Blue2}, NPAR={foreground = Screen.colors.Yellow}, + SQ={foreground = Screen.colors.Blue3}, + SB={foreground = Screen.colors.Blue4}, + E={foreground = Screen.colors.Red, background = Screen.colors.Blue}, + M={bold = true}, }) end) @@ -898,8 +902,83 @@ describe('Expressions coloring support', function() ={NUM:1}^ | ]]) end) - -- FIXME: Test expr coloring when using -u NORC and -u NONE. - -- FIXME: Test different ways of triggering expression highlighting (:=, - -- i=, :e, "=). - -- FIXME: Test with various invalid unicode and multibyte characters. + it('works correctly with non-ASCII and control characters', function() + meths.command('hi clear NVimStringBody') + meths.command('hi clear NVimStringQuote') + meths.command('hi clear NVimInvalid') + meths.command('hi NVimStringQuote guifg=Blue3') + meths.command('hi NVimStringBody guifg=Blue4') + meths.command('hi NVimInvalid guifg=Red guibg=Blue') + feed('i="«»"«»') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + ={SQ:"}{SB:«»}{SQ:"}{E:«»}^ | + ]]) + feed('') + screen:expect([[ + ^ | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {M:-- INSERT --} | + ]]) + feed('') + screen:expect([[ + ^ | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + | + ]]) + feed(':e""') + -- TODO(ZyX-I): Parser highlighting should not override special character + -- highlighting. + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + ={SQ:"}{SB:^X}{SQ:"}{ERR:^X}^ | + ]]) + feed('') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + :^ | + ]]) + funcs.setreg('a', {'\192'}) + feed('="a"a"foo"') + -- TODO(ZyX-I): Parser highlighting should not override special character + -- highlighting. + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + ={SQ:"}{SB:}{SQ:"}{E:"}{SB:foo}{E:"}^ | + ]]) + end) end) -- cgit From de45ec0146486c49719ff6f6dcceb4914b471c7a Mon Sep 17 00:00:00 2001 From: ZyX Date: Thu, 30 Nov 2017 02:01:49 +0300 Subject: keymap: Do not use vim_isIDc in keymap.c Note: there are three changes to ascii_isident. Reverting first two (in find_special_key and first in get_special_key_code) normally fails the new test with empty &isident, but reverting the third does not. Hence adding `>` to &isident. Ref vim/vim#2389. --- test/functional/ex_cmds/map_spec.lua | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 test/functional/ex_cmds/map_spec.lua (limited to 'test/functional') diff --git a/test/functional/ex_cmds/map_spec.lua b/test/functional/ex_cmds/map_spec.lua new file mode 100644 index 0000000000..b46f83405e --- /dev/null +++ b/test/functional/ex_cmds/map_spec.lua @@ -0,0 +1,21 @@ +local helpers = require("test.functional.helpers")(after_each) + +local eq = helpers.eq +local feed = helpers.feed +local meths = helpers.meths +local clear = helpers.clear +local command = helpers.command + +describe(':*map', function() + before_each(clear) + + it('are not affected by &isident', function() + meths.set_var('counter', 0) + command('nnoremap :let counter+=1') + meths.set_option('isident', ('%u'):format(('>'):byte())) + command('nnoremap :let counter+=1') + -- &isident used to disable keycode parsing here as well + feed('\24\25') + eq(4, meths.get_var('counter')) + end) +end) -- cgit From 5ab0f988caffad5e8c87a075cbd3f91f0f7e002c Mon Sep 17 00:00:00 2001 From: ZyX Date: Thu, 30 Nov 2017 11:53:25 +0300 Subject: *: Replace all occurrences of NVim with Nvim --- test/functional/api/vim_spec.lua | 2 +- test/functional/ui/cmdline_highlight_spec.lua | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) (limited to 'test/functional') diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 841b7a584a..ff28e3d133 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -885,7 +885,7 @@ describe('api', function() return function(next_col) local col = next_col + (shift or 0) return (('%s:%u:%u:%s'):format( - 'NVim' .. group, + 'Nvim' .. group, 0, col, str)), (col + #str) diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua index 54d27723f0..73fe94c056 100644 --- a/test/functional/ui/cmdline_highlight_spec.lua +++ b/test/functional/ui/cmdline_highlight_spec.lua @@ -869,10 +869,10 @@ describe('Ex commands coloring support', function() end) describe('Expressions coloring support', function() it('works', function() - meths.command('hi clear NVimNumber') - meths.command('hi clear NVimNestingParenthesis') - meths.command('hi NVimNumber guifg=Blue2') - meths.command('hi NVimNestingParenthesis guifg=Yellow') + meths.command('hi clear NvimNumber') + meths.command('hi clear NvimNestingParenthesis') + meths.command('hi NvimNumber guifg=Blue2') + meths.command('hi NvimNestingParenthesis guifg=Yellow') feed(':echo =(((1)))') screen:expect([[ | @@ -888,8 +888,8 @@ describe('Expressions coloring support', function() it('does not use Nvim_color_expr', function() meths.set_var('Nvim_color_expr', 42) -- Used to error out due to failing to get callback. - meths.command('hi clear NVimNumber') - meths.command('hi NVimNumber guifg=Blue2') + meths.command('hi clear NvimNumber') + meths.command('hi NvimNumber guifg=Blue2') feed(':=1') screen:expect([[ | @@ -903,12 +903,12 @@ describe('Expressions coloring support', function() ]]) end) it('works correctly with non-ASCII and control characters', function() - meths.command('hi clear NVimStringBody') - meths.command('hi clear NVimStringQuote') - meths.command('hi clear NVimInvalid') - meths.command('hi NVimStringQuote guifg=Blue3') - meths.command('hi NVimStringBody guifg=Blue4') - meths.command('hi NVimInvalid guifg=Red guibg=Blue') + meths.command('hi clear NvimStringBody') + meths.command('hi clear NvimStringQuote') + meths.command('hi clear NvimInvalid') + meths.command('hi NvimStringQuote guifg=Blue3') + meths.command('hi NvimStringBody guifg=Blue4') + meths.command('hi NvimInvalid guifg=Red guibg=Blue') feed('i="«»"«»') screen:expect([[ | -- cgit