From 7a85dd357e8f57b6d1a0232a40f5b0147c61b846 Mon Sep 17 00:00:00 2001 From: tyru Date: Fri, 2 Aug 2019 19:49:54 +0900 Subject: [PATCH 1/5] separate let/const/unlet/lockvar/unlockvar tests --- test/test1.ok | 24 ------------------------ test/test1.vim | 24 ------------------------ test/test_letconst.ok | 24 ++++++++++++++++++++++++ test/test_letconst.vim | 24 ++++++++++++++++++++++++ 4 files changed, 48 insertions(+), 48 deletions(-) create mode 100644 test/test_letconst.ok create mode 100644 test/test_letconst.vim diff --git a/test/test1.ok b/test/test1.ok index e5f8cf24..d0a5fcf0 100644 --- a/test/test1.ok +++ b/test/test1.ok @@ -14,20 +14,6 @@ (echo a b c)) (delfunction s:foo) (call (s:foo 1 2 3)) -(let = a (dict ("x" "y"))) -(let = (a b . c) (list 1 2 3)) -(let += (a b . c) (list 1 2 3)) -(let -= (a b . c) (list 1 2 3)) -(let .= (a b . c) (list 1 2 3)) -(let = (dot (dot foo bar) baz) 123) -(let = (subscript (subscript foo (bar)) (baz)) 456) -(let = (dot (subscript foo (bar)) baz) 789) -(let = (slice foo 1 2) (list 3 4)) -(unlet a b c) -(lockvar a b c) -(lockvar 1 a b c) -(unlockvar a b c) -(unlockvar 1 a b c) (try (throw "err") catch /err/ @@ -46,14 +32,4 @@ (echo (subscript x 0) (subscript x y)) (echo (slice x 1 2) (slice x 1 nil) (slice x nil 2) (slice x nil nil)) (echo (dot x y) (dot (dot x y) z)) -(let = a 1) -(let += a 2) -(let *= a 3) -(let /= a 4) -(let %= a 5) -(let ..= a 'foo') (echo (concat (concat 'foo' 'bar') 'baz')) -(let = a '🐥') -(const = a 1) -(const = (a b) (list 1 2)) -(const = (a b . c) (list 1 2 3)) diff --git a/test/test1.vim b/test/test1.vim index 60232373..fdc3c65b 100644 --- a/test/test1.vim +++ b/test/test1.vim @@ -18,20 +18,6 @@ for [a, b; c] in d endfor delfunction s:foo call s:foo(1, 2, 3) -let a = {"x": "y"} -let [a, b; c] = [1, 2, 3] -let [a, b; c] += [1, 2, 3] -let [a, b; c] -= [1, 2, 3] -let [a, b; c] .= [1, 2, 3] -let foo.bar.baz = 123 -let foo[bar()][baz()] = 456 -let foo[bar()].baz = 789 -let foo[1:2] = [3, 4] -unlet a b c -lockvar a b c -lockvar 1 a b c -unlockvar a b c -unlockvar 1 a b c try throw "err" catch /err/ @@ -51,14 +37,4 @@ echo {} {"x":"y"} {"x":"y","z":"w",} echo x[0] x[y] echo x[1:2] x[1:] x[:2] x[:] echo x.y x.y.z -let a = 1 -let a += 2 -let a *= 3 -let a /= 4 -let a %= 5 -let a ..= 'foo' echo ('foo' .. 'bar')..'baz' -let a = '🐥' -const a = 1 -const [a, b] = [1, 2] -const [a, b; c] = [1, 2, 3] diff --git a/test/test_letconst.ok b/test/test_letconst.ok new file mode 100644 index 00000000..709a3fc5 --- /dev/null +++ b/test/test_letconst.ok @@ -0,0 +1,24 @@ +(let = a (dict ("x" "y"))) +(let = (a b . c) (list 1 2 3)) +(let += (a b . c) (list 1 2 3)) +(let -= (a b . c) (list 1 2 3)) +(let .= (a b . c) (list 1 2 3)) +(let = (dot (dot foo bar) baz) 123) +(let = (subscript (subscript foo (bar)) (baz)) 456) +(let = (dot (subscript foo (bar)) baz) 789) +(let = (slice foo 1 2) (list 3 4)) +(unlet a b c) +(lockvar a b c) +(lockvar 1 a b c) +(unlockvar a b c) +(unlockvar 1 a b c) +(let = a 1) +(let += a 2) +(let *= a 3) +(let /= a 4) +(let %= a 5) +(let ..= a 'foo') +(let = a '🐥') +(const = a 1) +(const = (a b) (list 1 2)) +(const = (a b . c) (list 1 2 3)) diff --git a/test/test_letconst.vim b/test/test_letconst.vim new file mode 100644 index 00000000..4fa9a1b9 --- /dev/null +++ b/test/test_letconst.vim @@ -0,0 +1,24 @@ +let a = {"x": "y"} +let [a, b; c] = [1, 2, 3] +let [a, b; c] += [1, 2, 3] +let [a, b; c] -= [1, 2, 3] +let [a, b; c] .= [1, 2, 3] +let foo.bar.baz = 123 +let foo[bar()][baz()] = 456 +let foo[bar()].baz = 789 +let foo[1:2] = [3, 4] +unlet a b c +lockvar a b c +lockvar 1 a b c +unlockvar a b c +unlockvar 1 a b c +let a = 1 +let a += 2 +let a *= 3 +let a /= 4 +let a %= 5 +let a ..= 'foo' +let a = '🐥' +const a = 1 +const [a, b] = [1, 2] +const [a, b; c] = [1, 2, 3] From a27e2e2bd7be1428f695b77e85991042daac5056 Mon Sep 17 00:00:00 2001 From: tyru Date: Fri, 2 Aug 2019 20:34:18 +0900 Subject: [PATCH 2/5] fix ":let [{var}]" and ":const [{var}]" parsing --- autoload/vimlparser.vim | 72 ++++++++++++++++++++++++++++------------- test/test_letconst.ok | 4 +++ test/test_letconst.vim | 4 +++ 3 files changed, 58 insertions(+), 22 deletions(-) diff --git a/autoload/vimlparser.vim b/autoload/vimlparser.vim index 7d024590..2dbe5764 100644 --- a/autoload/vimlparser.vim +++ b/autoload/vimlparser.vim @@ -1495,7 +1495,14 @@ function! s:VimLParser.parse_cmd_let() abort " :let if self.ends_excmds(self.reader.peek()) call self.reader.seek_set(pos) - call self.parse_cmd_common() + let node = s:Node(s:NODE_LET) + let node.pos = self.ea.cmdpos + let node.ea = self.ea + let node.left = s:NIL + let node.list = s:NIL + let node.rest = s:NIL + let node.right = s:NIL + call self.add_node(node) return endif @@ -1510,8 +1517,14 @@ function! s:VimLParser.parse_cmd_let() abort " :let {var-name} .. if self.ends_excmds(s1) || (s2 !=# '+=' && s2 !=# '-=' && s2 !=# '.=' && s2 !=# '..=' && s2 !=# '*=' && s2 !=# '/=' && s2 !=# '%=' && s1 !=# '=') - call self.reader.seek_set(pos) - call self.parse_cmd_common() + let node = s:Node(s:NODE_LET) + let node.pos = self.ea.cmdpos + let node.ea = self.ea + let node.left = lhs.left + let node.list = lhs.list + let node.rest = lhs.rest + let node.right = s:NIL + call self.add_node(node) return endif @@ -1543,8 +1556,14 @@ function! s:VimLParser.parse_cmd_const() abort " :const if self.ends_excmds(self.reader.peek()) - call self.reader.seek_set(pos) - call self.parse_cmd_common() + let node = s:Node(s:NODE_CONST) + let node.pos = self.ea.cmdpos + let node.ea = self.ea + let node.left = s:NIL + let node.list = s:NIL + let node.rest = s:NIL + let node.right = s:NIL + call self.add_node(node) return endif @@ -1554,8 +1573,14 @@ function! s:VimLParser.parse_cmd_const() abort " :const {var-name} if self.ends_excmds(s1) || s1 !=# '=' - call self.reader.seek_set(pos) - call self.parse_cmd_common() + let node = s:Node(s:NODE_CONST) + let node.pos = self.ea.cmdpos + let node.ea = self.ea + let node.left = lhs.left + let node.list = lhs.list + let node.rest = lhs.rest + let node.right = s:NIL + call self.add_node(node) return endif @@ -4996,23 +5021,20 @@ function! s:Compiler.compile_excall(node) abort endfunction function! s:Compiler.compile_let(node) abort - let left = '' - if a:node.left isnot# s:NIL - let left = self.compile(a:node.left) - else - let left = join(map(a:node.list, 'self.compile(v:val)'), ' ') - if a:node.rest isnot# s:NIL - let left .= ' . ' . self.compile(a:node.rest) - endif - let left = '(' . left . ')' - endif - let right = self.compile(a:node.right) - call self.out('(let %s %s %s)', a:node.op, left, right) + call self.compile_letconst(a:node, 'let') endfunction -" TODO: merge with s:Compiler.compile_let() ? function! s:Compiler.compile_const(node) abort + call self.compile_letconst(a:node, 'const') +endfunction + +function! s:Compiler.compile_letconst(node, cmd) abort let left = '' + let right = '' + if a:node.left is# s:NIL && a:node.right is# s:NIL + call self.out('(%s)', a:cmd) + return + endif if a:node.left isnot# s:NIL let left = self.compile(a:node.left) else @@ -5022,8 +5044,14 @@ function! s:Compiler.compile_const(node) abort endif let left = '(' . left . ')' endif - let right = self.compile(a:node.right) - call self.out('(const %s %s %s)', a:node.op, left, right) + if a:node.right isnot# s:NIL + let right = self.compile(a:node.right) + endif + if a:node.left isnot# s:NIL && a:node.right is# s:NIL + call self.out('(%s () %s)', a:cmd, left) + else + call self.out('(%s %s %s %s)', a:cmd, a:node.op, left, right) + endif endfunction function! s:Compiler.compile_unlet(node) abort diff --git a/test/test_letconst.ok b/test/test_letconst.ok index 709a3fc5..f4131f50 100644 --- a/test/test_letconst.ok +++ b/test/test_letconst.ok @@ -22,3 +22,7 @@ (const = a 1) (const = (a b) (list 1 2)) (const = (a b . c) (list 1 2 3)) +(let) +(let () var) +(const) +(const () var) diff --git a/test/test_letconst.vim b/test/test_letconst.vim index 4fa9a1b9..e25c8325 100644 --- a/test/test_letconst.vim +++ b/test/test_letconst.vim @@ -22,3 +22,7 @@ let a = '🐥' const a = 1 const [a, b] = [1, 2] const [a, b; c] = [1, 2, 3] +let +let var +const +const var From 02bddc846e5ae7a4d0990e4452c881d531e62232 Mon Sep 17 00:00:00 2001 From: tyru Date: Fri, 2 Aug 2019 20:39:20 +0900 Subject: [PATCH 3/5] merge parse_constlhs() to parse_letlhs() --- autoload/vimlparser.vim | 45 ++++++----------------------------------- 1 file changed, 6 insertions(+), 39 deletions(-) diff --git a/autoload/vimlparser.vim b/autoload/vimlparser.vim index 2dbe5764..3b19a63b 100644 --- a/autoload/vimlparser.vim +++ b/autoload/vimlparser.vim @@ -1506,7 +1506,7 @@ function! s:VimLParser.parse_cmd_let() abort return endif - let lhs = self.parse_letlhs() + let lhs = self.parse_letlhs(s:FALSE) call self.reader.skip_white() let s1 = self.reader.peekn(1) let s2 = self.reader.peekn(2) @@ -1567,7 +1567,7 @@ function! s:VimLParser.parse_cmd_const() abort return endif - let lhs = self.parse_constlhs() + let lhs = self.parse_letlhs(s:TRUE) call self.reader.skip_white() let s1 = self.reader.peekn(1) @@ -1721,7 +1721,7 @@ function! s:VimLParser.parse_cmd_for() abort let node.left = s:NIL let node.right = s:NIL let node.endfor = s:NIL - let lhs = self.parse_letlhs() + let lhs = self.parse_letlhs(s:FALSE) let node.left = lhs.left let node.list = lhs.list let node.rest = lhs.rest @@ -1930,7 +1930,6 @@ function! s:VimLParser.parse_lvalue() abort throw s:Err('Invalid Expression', node.pos) endfunction -" TODO: merge with s:VimLParser.parse_lvalue() function! s:VimLParser.parse_constlvalue() abort let p = s:LvalueParser.new(self.reader) let node = p.parse() @@ -1970,7 +1969,7 @@ function! s:VimLParser.parse_lvaluelist() abort endfunction " FIXME: -function! s:VimLParser.parse_letlhs() abort +function! s:VimLParser.parse_letlhs(is_const) abort let lhs = {'left': s:NIL, 'list': s:NIL, 'rest': s:NIL} let tokenizer = s:ExprTokenizer.new(self.reader) if tokenizer.peek().type ==# s:TOKEN_SQOPEN @@ -1997,46 +1996,14 @@ function! s:VimLParser.parse_letlhs() abort throw s:Err(printf('E475 Invalid argument: %s', token.value), token.pos) endif endwhile + elseif a:is_const + let lhs.left = self.parse_constlvalue() else let lhs.left = self.parse_lvalue() endif return lhs endfunction -" TODO: merge with s:VimLParser.parse_letlhs() ? -function! s:VimLParser.parse_constlhs() abort - let lhs = {'left': s:NIL, 'list': s:NIL, 'rest': s:NIL} - let tokenizer = s:ExprTokenizer.new(self.reader) - if tokenizer.peek().type ==# s:TOKEN_SQOPEN - call tokenizer.get() - let lhs.list = [] - while s:TRUE - let node = self.parse_lvalue() - call add(lhs.list, node) - let token = tokenizer.get() - if token.type ==# s:TOKEN_SQCLOSE - break - elseif token.type ==# s:TOKEN_COMMA - continue - elseif token.type ==# s:TOKEN_SEMICOLON - let node = self.parse_lvalue() - let lhs.rest = node - let token = tokenizer.get() - if token.type ==# s:TOKEN_SQCLOSE - break - else - throw s:Err(printf('E475 Invalid argument: %s', token.value), token.pos) - endif - else - throw s:Err(printf('E475 Invalid argument: %s', token.value), token.pos) - endif - endwhile - else - let lhs.left = self.parse_constlvalue() - endif - return lhs -endfunction - function! s:VimLParser.ends_excmds(c) abort return a:c ==# '' || a:c ==# '|' || a:c ==# '"' || a:c ==# '' || a:c ==# '' endfunction From 2586eb4f4c41d645ca280b8d8402f24e6d303eba Mon Sep 17 00:00:00 2001 From: tyru Date: Fri, 2 Aug 2019 20:42:43 +0900 Subject: [PATCH 4/5] gen --- js/vimlparser.js | 125 ++++++++++++++++++++++------------------------- py/vimlparser.py | 106 ++++++++++++++++++++-------------------- 2 files changed, 110 insertions(+), 121 deletions(-) diff --git a/js/vimlparser.js b/js/vimlparser.js index bd53510e..79a43cb4 100644 --- a/js/vimlparser.js +++ b/js/vimlparser.js @@ -1787,10 +1787,17 @@ VimLParser.prototype.parse_cmd_let = function() { // :let if (this.ends_excmds(this.reader.peek())) { this.reader.seek_set(pos); - this.parse_cmd_common(); + var node = Node(NODE_LET); + node.pos = this.ea.cmdpos; + node.ea = this.ea; + node.left = NIL; + node.list = NIL; + node.rest = NIL; + node.right = NIL; + this.add_node(node); return; } - var lhs = this.parse_letlhs(); + var lhs = this.parse_letlhs(FALSE); this.reader.skip_white(); var s1 = this.reader.peekn(1); var s2 = this.reader.peekn(2); @@ -1800,8 +1807,14 @@ VimLParser.prototype.parse_cmd_let = function() { } // :let {var-name} .. if (this.ends_excmds(s1) || s2 != "+=" && s2 != "-=" && s2 != ".=" && s2 != "..=" && s2 != "*=" && s2 != "/=" && s2 != "%=" && s1 != "=") { - this.reader.seek_set(pos); - this.parse_cmd_common(); + var node = Node(NODE_LET); + node.pos = this.ea.cmdpos; + node.ea = this.ea; + node.left = lhs.left; + node.list = lhs.list; + node.rest = lhs.rest; + node.right = NIL; + this.add_node(node); return; } // :let left op right @@ -1833,17 +1846,29 @@ VimLParser.prototype.parse_cmd_const = function() { this.reader.skip_white(); // :const if (this.ends_excmds(this.reader.peek())) { - this.reader.seek_set(pos); - this.parse_cmd_common(); + var node = Node(NODE_CONST); + node.pos = this.ea.cmdpos; + node.ea = this.ea; + node.left = NIL; + node.list = NIL; + node.rest = NIL; + node.right = NIL; + this.add_node(node); return; } - var lhs = this.parse_constlhs(); + var lhs = this.parse_letlhs(TRUE); this.reader.skip_white(); var s1 = this.reader.peekn(1); // :const {var-name} if (this.ends_excmds(s1) || s1 != "=") { - this.reader.seek_set(pos); - this.parse_cmd_common(); + var node = Node(NODE_CONST); + node.pos = this.ea.cmdpos; + node.ea = this.ea; + node.left = lhs.left; + node.list = lhs.list; + node.rest = lhs.rest; + node.right = NIL; + this.add_node(node); return; } // :const left op right @@ -1983,7 +2008,7 @@ VimLParser.prototype.parse_cmd_for = function() { node.left = NIL; node.right = NIL; node.endfor = NIL; - var lhs = this.parse_letlhs(); + var lhs = this.parse_letlhs(FALSE); node.left = lhs.left; node.list = lhs.list; node.rest = lhs.rest; @@ -2195,7 +2220,6 @@ VimLParser.prototype.parse_lvalue = function() { throw Err("Invalid Expression", node.pos); } -// TODO: merge with s:VimLParser.parse_lvalue() VimLParser.prototype.parse_constlvalue = function() { var p = new LvalueParser(this.reader); var node = p.parse(); @@ -2238,7 +2262,7 @@ VimLParser.prototype.parse_lvaluelist = function() { } // FIXME: -VimLParser.prototype.parse_letlhs = function() { +VimLParser.prototype.parse_letlhs = function(is_const) { var lhs = {"left":NIL, "list":NIL, "rest":NIL}; var tokenizer = new ExprTokenizer(this.reader); if (tokenizer.peek().type == TOKEN_SQOPEN) { @@ -2270,47 +2294,11 @@ VimLParser.prototype.parse_letlhs = function() { } } } - else { - lhs.left = this.parse_lvalue(); - } - return lhs; -} - -// TODO: merge with s:VimLParser.parse_letlhs() ? -VimLParser.prototype.parse_constlhs = function() { - var lhs = {"left":NIL, "list":NIL, "rest":NIL}; - var tokenizer = new ExprTokenizer(this.reader); - if (tokenizer.peek().type == TOKEN_SQOPEN) { - tokenizer.get(); - lhs.list = []; - while (TRUE) { - var node = this.parse_lvalue(); - viml_add(lhs.list, node); - var token = tokenizer.get(); - if (token.type == TOKEN_SQCLOSE) { - break; - } - else if (token.type == TOKEN_COMMA) { - continue; - } - else if (token.type == TOKEN_SEMICOLON) { - var node = this.parse_lvalue(); - lhs.rest = node; - var token = tokenizer.get(); - if (token.type == TOKEN_SQCLOSE) { - break; - } - else { - throw Err(viml_printf("E475 Invalid argument: %s", token.value), token.pos); - } - } - else { - throw Err(viml_printf("E475 Invalid argument: %s", token.value), token.pos); - } - } + else if (is_const) { + lhs.left = this.parse_constlvalue(); } else { - lhs.left = this.parse_constlvalue(); + lhs.left = this.parse_lvalue(); } return lhs; } @@ -4501,24 +4489,20 @@ Compiler.prototype.compile_excall = function(node) { } Compiler.prototype.compile_let = function(node) { - var left = ""; - if (node.left !== NIL) { - var left = this.compile(node.left); - } - else { - var left = viml_join(node.list.map((function(vval) { return this.compile(vval); }).bind(this)), " "); - if (node.rest !== NIL) { - left += " . " + this.compile(node.rest); - } - var left = "(" + left + ")"; - } - var right = this.compile(node.right); - this.out("(let %s %s %s)", node.op, left, right); + this.compile_letconst(node, "let"); } -// TODO: merge with s:Compiler.compile_let() ? Compiler.prototype.compile_const = function(node) { + this.compile_letconst(node, "const"); +} + +Compiler.prototype.compile_letconst = function(node, cmd) { var left = ""; + var right = ""; + if (node.left === NIL && node.right === NIL) { + this.out("(%s)", cmd); + return; + } if (node.left !== NIL) { var left = this.compile(node.left); } @@ -4529,8 +4513,15 @@ Compiler.prototype.compile_const = function(node) { } var left = "(" + left + ")"; } - var right = this.compile(node.right); - this.out("(const %s %s %s)", node.op, left, right); + if (node.right !== NIL) { + var right = this.compile(node.right); + } + if (node.left !== NIL && node.right === NIL) { + this.out("(%s () %s)", cmd, left); + } + else { + this.out("(%s %s %s %s)", cmd, node.op, left, right); + } } Compiler.prototype.compile_unlet = function(node) { diff --git a/py/vimlparser.py b/py/vimlparser.py index 592f1a21..89cfa1b1 100644 --- a/py/vimlparser.py +++ b/py/vimlparser.py @@ -1468,9 +1468,16 @@ def parse_cmd_let(self): # :let if self.ends_excmds(self.reader.peek()): self.reader.seek_set(pos) - self.parse_cmd_common() + node = Node(NODE_LET) + node.pos = self.ea.cmdpos + node.ea = self.ea + node.left = NIL + node.list = NIL + node.rest = NIL + node.right = NIL + self.add_node(node) return - lhs = self.parse_letlhs() + lhs = self.parse_letlhs(FALSE) self.reader.skip_white() s1 = self.reader.peekn(1) s2 = self.reader.peekn(2) @@ -1479,8 +1486,14 @@ def parse_cmd_let(self): s2 = self.reader.peekn(3) # :let {var-name} .. if self.ends_excmds(s1) or s2 != "+=" and s2 != "-=" and s2 != ".=" and s2 != "..=" and s2 != "*=" and s2 != "/=" and s2 != "%=" and s1 != "=": - self.reader.seek_set(pos) - self.parse_cmd_common() + node = Node(NODE_LET) + node.pos = self.ea.cmdpos + node.ea = self.ea + node.left = lhs.left + node.list = lhs.list + node.rest = lhs.rest + node.right = NIL + self.add_node(node) return # :let left op right node = Node(NODE_LET) @@ -1507,16 +1520,28 @@ def parse_cmd_const(self): self.reader.skip_white() # :const if self.ends_excmds(self.reader.peek()): - self.reader.seek_set(pos) - self.parse_cmd_common() + node = Node(NODE_CONST) + node.pos = self.ea.cmdpos + node.ea = self.ea + node.left = NIL + node.list = NIL + node.rest = NIL + node.right = NIL + self.add_node(node) return - lhs = self.parse_constlhs() + lhs = self.parse_letlhs(TRUE) self.reader.skip_white() s1 = self.reader.peekn(1) # :const {var-name} if self.ends_excmds(s1) or s1 != "=": - self.reader.seek_set(pos) - self.parse_cmd_common() + node = Node(NODE_CONST) + node.pos = self.ea.cmdpos + node.ea = self.ea + node.left = lhs.left + node.list = lhs.list + node.rest = lhs.rest + node.right = NIL + self.add_node(node) return # :const left op right node = Node(NODE_CONST) @@ -1636,7 +1661,7 @@ def parse_cmd_for(self): node.left = NIL node.right = NIL node.endfor = NIL - lhs = self.parse_letlhs() + lhs = self.parse_letlhs(FALSE) node.left = lhs.left node.list = lhs.list node.rest = lhs.rest @@ -1808,7 +1833,6 @@ def parse_lvalue(self): return node raise VimLParserException(Err("Invalid Expression", node.pos)) - # TODO: merge with s:VimLParser.parse_lvalue() def parse_constlvalue(self): p = LvalueParser(self.reader) node = p.parse() @@ -1840,7 +1864,7 @@ def parse_lvaluelist(self): return list # FIXME: - def parse_letlhs(self): + def parse_letlhs(self, is_const): lhs = AttributeDict({"left": NIL, "list": NIL, "rest": NIL}) tokenizer = ExprTokenizer(self.reader) if tokenizer.peek().type == TOKEN_SQOPEN: @@ -1864,39 +1888,12 @@ def parse_letlhs(self): raise VimLParserException(Err(viml_printf("E475 Invalid argument: %s", token.value), token.pos)) else: raise VimLParserException(Err(viml_printf("E475 Invalid argument: %s", token.value), token.pos)) + elif is_const: + lhs.left = self.parse_constlvalue() else: lhs.left = self.parse_lvalue() return lhs - # TODO: merge with s:VimLParser.parse_letlhs() ? - def parse_constlhs(self): - lhs = AttributeDict({"left": NIL, "list": NIL, "rest": NIL}) - tokenizer = ExprTokenizer(self.reader) - if tokenizer.peek().type == TOKEN_SQOPEN: - tokenizer.get() - lhs.list = [] - while TRUE: - node = self.parse_lvalue() - viml_add(lhs.list, node) - token = tokenizer.get() - if token.type == TOKEN_SQCLOSE: - break - elif token.type == TOKEN_COMMA: - continue - elif token.type == TOKEN_SEMICOLON: - node = self.parse_lvalue() - lhs.rest = node - token = tokenizer.get() - if token.type == TOKEN_SQCLOSE: - break - else: - raise VimLParserException(Err(viml_printf("E475 Invalid argument: %s", token.value), token.pos)) - else: - raise VimLParserException(Err(viml_printf("E475 Invalid argument: %s", token.value), token.pos)) - else: - lhs.left = self.parse_constlvalue() - return lhs - def ends_excmds(self, c): return c == "" or c == "|" or c == "\"" or c == "" or c == "" @@ -3600,20 +3597,17 @@ def compile_excall(self, node): self.out("(call %s)", self.compile(node.left)) def compile_let(self, node): - left = "" - if node.left is not NIL: - left = self.compile(node.left) - else: - left = viml_join([self.compile(vval) for vval in node.list], " ") - if node.rest is not NIL: - left += " . " + self.compile(node.rest) - left = "(" + left + ")" - right = self.compile(node.right) - self.out("(let %s %s %s)", node.op, left, right) + self.compile_letconst(node, "let") - # TODO: merge with s:Compiler.compile_let() ? def compile_const(self, node): + self.compile_letconst(node, "const") + + def compile_letconst(self, node, cmd): left = "" + right = "" + if node.left is NIL and node.right is NIL: + self.out("(%s)", cmd) + return if node.left is not NIL: left = self.compile(node.left) else: @@ -3621,8 +3615,12 @@ def compile_const(self, node): if node.rest is not NIL: left += " . " + self.compile(node.rest) left = "(" + left + ")" - right = self.compile(node.right) - self.out("(const %s %s %s)", node.op, left, right) + if node.right is not NIL: + right = self.compile(node.right) + if node.left is not NIL and node.right is NIL: + self.out("(%s () %s)", cmd, left) + else: + self.out("(%s %s %s %s)", cmd, node.op, left, right) def compile_unlet(self, node): list = [self.compile(vval) for vval in node.list] From 0844cfaf1d6004253f3308cfb06aec974bbedf35 Mon Sep 17 00:00:00 2001 From: tyru Date: Wed, 7 Aug 2019 08:29:54 +0900 Subject: [PATCH 5/5] fix unused variable error --- autoload/vimlparser.vim | 1 - js/vimlparser.js | 1 - py/vimlparser.py | 1 - 3 files changed, 3 deletions(-) diff --git a/autoload/vimlparser.vim b/autoload/vimlparser.vim index 3b19a63b..2137d864 100644 --- a/autoload/vimlparser.vim +++ b/autoload/vimlparser.vim @@ -1551,7 +1551,6 @@ function! s:VimLParser.parse_cmd_let() abort endfunction function! s:VimLParser.parse_cmd_const() abort - let pos = self.reader.tell() call self.reader.skip_white() " :const diff --git a/js/vimlparser.js b/js/vimlparser.js index 79a43cb4..aeab2885 100644 --- a/js/vimlparser.js +++ b/js/vimlparser.js @@ -1842,7 +1842,6 @@ VimLParser.prototype.parse_cmd_let = function() { } VimLParser.prototype.parse_cmd_const = function() { - var pos = this.reader.tell(); this.reader.skip_white(); // :const if (this.ends_excmds(this.reader.peek())) { diff --git a/py/vimlparser.py b/py/vimlparser.py index 89cfa1b1..973b2a43 100644 --- a/py/vimlparser.py +++ b/py/vimlparser.py @@ -1516,7 +1516,6 @@ def parse_cmd_let(self): self.add_node(node) def parse_cmd_const(self): - pos = self.reader.tell() self.reader.skip_white() # :const if self.ends_excmds(self.reader.peek()):