diff --git a/autoload/vimlparser.vim b/autoload/vimlparser.vim index 2c0c4c56..c4f258af 100644 --- a/autoload/vimlparser.vim +++ b/autoload/vimlparser.vim @@ -137,6 +137,7 @@ let s:NODE_REG = 89 let s:NODE_CURLYNAMEPART = 90 let s:NODE_CURLYNAMEEXPR = 91 let s:NODE_LAMBDA = 92 +let s:NODE_PARENEXPR = 93 let s:TOKEN_EOF = 1 let s:TOKEN_EOL = 2 @@ -403,6 +404,7 @@ endfunction " CURLYNAMEPART .value " CURLYNAMEEXPR .value " LAMBDA .rlist .left +" PARENEXPR .value function! s:Node(type) return {'type': a:type} endfunction @@ -3521,7 +3523,9 @@ function! s:ExprParser.parse_expr9() endwhile return node elseif token.type == s:TOKEN_POPEN - let node = self.parse_expr1() + let node = s:Node(s:NODE_PARENEXPR) + let node.pos = token.pos + let node.value = self.parse_expr1() let token = self.tokenizer.get() if token.type != s:TOKEN_PCLOSE throw s:Err(printf('unexpected token: %s', token.value), token.pos) @@ -4222,6 +4226,8 @@ function! s:Compiler.compile(node) return self.compile_curlynameexpr(a:node) elseif a:node.type == s:NODE_LAMBDA return self.compile_lambda(a:node) + elseif a:node.type == s:NODE_PARENEXPR + return self.compile_parenexpr(a:node) else throw printf('Compiler: unknown node: %s', string(a:node)) endif @@ -4685,6 +4691,10 @@ function! s:Compiler.compile_lambda(node) return printf('(lambda (%s) %s)', join(rlist, ' '), self.compile(a:node.left)) endfunction +function! s:Compiler.compile_parenexpr(node) + return self.compile(a:node.value) +endfunction + " TODO: under construction let s:RegexpParser = {} diff --git a/js/jscompiler.vim b/js/jscompiler.vim index da90892b..e188f2b0 100644 --- a/js/jscompiler.vim +++ b/js/jscompiler.vim @@ -3,6 +3,7 @@ call extend(s:, vimlparser#import()) let s:opprec = {} let s:opprec[s:NODE_TERNARY] = 1 +let s:opprec[s:NODE_PARENEXPR] = 1 let s:opprec[s:NODE_OR] = 2 let s:opprec[s:NODE_AND] = 3 let s:opprec[s:NODE_EQUAL] = 4 @@ -254,6 +255,8 @@ function s:JavascriptCompiler.compile(node) return self.compile_env(a:node) elseif a:node.type == s:NODE_REG return self.compile_reg(a:node) + elseif a:node.type == s:NODE_PARENEXPR + return self.compile_parenexpr(a:node) else throw self.err('Compiler: unknown node: %s', string(a:node)) endif @@ -818,6 +821,10 @@ function s:JavascriptCompiler.compile_reg(node) throw 'NotImplemented: reg' endfunction +function s:JavascriptCompiler.compile_parenexpr(node) + return self.compile(a:node.value) +endfunction + function s:JavascriptCompiler.compile_op1(node, op) let left = self.compile(a:node.left) if s:opprec[a:node.type] > s:opprec[a:node.left.type] diff --git a/js/vimlparser.js b/js/vimlparser.js index 58a4e15e..994e338e 100644 --- a/js/vimlparser.js +++ b/js/vimlparser.js @@ -327,6 +327,7 @@ var NODE_REG = 89; var NODE_CURLYNAMEPART = 90; var NODE_CURLYNAMEEXPR = 91; var NODE_LAMBDA = 92; +var NODE_PARENEXPR = 93; var TOKEN_EOF = 1; var TOKEN_EOL = 2; var TOKEN_SPACE = 3; @@ -590,6 +591,7 @@ function ExArg() { // CURLYNAMEPART .value // CURLYNAMEEXPR .value // LAMBDA .rlist .left +// PARENEXPR .value function Node(type) { return {"type":type}; } @@ -1436,7 +1438,7 @@ VimLParser.prototype.separate_nextcmd = function() { } this.reader.getn(1); } - else if (c == "|" || c == "\n" || c == "\"" && !viml_eqregh(this.ea.cmd.flags, "\\") && (this.ea.cmd.name != "@" && this.ea.cmd.name != "*" || this.reader.getpos() != this.ea.argpos) && (this.ea.cmd.name != "redir" || this.reader.getpos().i != this.ea.argpos.i + 1 || pc != "@")) { + else if (c == "|" || c == "\n" || (c == "\"" && !viml_eqregh(this.ea.cmd.flags, "\\") && ((this.ea.cmd.name != "@" && this.ea.cmd.name != "*") || this.reader.getpos() != this.ea.argpos) && (this.ea.cmd.name != "redir" || this.reader.getpos().i != this.ea.argpos.i + 1 || pc != "@"))) { var has_cpo_bar = FALSE; // &cpoptions =~ 'b' if ((!has_cpo_bar || !viml_eqregh(this.ea.cmd.flags, "\\")) && pc == "\\") { @@ -1793,7 +1795,7 @@ VimLParser.prototype.parse_cmd_let = function() { var s1 = this.reader.peekn(1); var s2 = this.reader.peekn(2); // :let {var-name} .. - if (this.ends_excmds(s1) || s2 != "+=" && s2 != "-=" && s2 != ".=" && s1 != "=") { + if (this.ends_excmds(s1) || (s2 != "+=" && s2 != "-=" && s2 != ".=" && s1 != "=")) { this.reader.seek_set(pos); this.parse_cmd_common(); return; @@ -2328,7 +2330,7 @@ ExprTokenizer.prototype.get2 = function() { if (r.p(0) == "." && isdigit(r.p(1))) { s += r.getn(1); s += r.read_digit(); - if ((r.p(0) == "E" || r.p(0) == "e") && (isdigit(r.p(1)) || (r.p(1) == "-" || r.p(1) == "+") && isdigit(r.p(2)))) { + if ((r.p(0) == "E" || r.p(0) == "e") && (isdigit(r.p(1)) || ((r.p(1) == "-" || r.p(1) == "+") && isdigit(r.p(2))))) { s += r.getn(2); s += r.read_digit(); } @@ -3398,7 +3400,9 @@ ExprParser.prototype.parse_expr9 = function() { return node; } else if (token.type == TOKEN_POPEN) { - var node = this.parse_expr1(); + var node = Node(NODE_PARENEXPR); + node.pos = token.pos; + node.value = this.parse_expr1(); var token = this.tokenizer.get(); if (token.type != TOKEN_PCLOSE) { throw Err(viml_printf("unexpected token: %s", token.value), token.pos); @@ -4204,6 +4208,9 @@ Compiler.prototype.compile = function(node) { else if (node.type == NODE_LAMBDA) { return this.compile_lambda(node); } + else if (node.type == NODE_PARENEXPR) { + return this.compile_parenexpr(node); + } else { throw viml_printf("Compiler: unknown node: %s", viml_string(node)); } @@ -4683,6 +4690,10 @@ Compiler.prototype.compile_lambda = function(node) { return viml_printf("(lambda (%s) %s)", viml_join(rlist, " "), this.compile(node.left)); } +Compiler.prototype.compile_parenexpr = function(node) { + return this.compile(node.value); +} + // TODO: under construction function RegexpParser() { this.__init__.apply(this, arguments); } RegexpParser.prototype.RE_VERY_NOMAGIC = 1; diff --git a/py/pycompiler.vim b/py/pycompiler.vim index 8e387d99..717a9720 100644 --- a/py/pycompiler.vim +++ b/py/pycompiler.vim @@ -3,6 +3,7 @@ call extend(s:, vimlparser#import()) let s:opprec = {} let s:opprec[s:NODE_TERNARY] = 1 +let s:opprec[s:NODE_PARENEXPR] = 1 let s:opprec[s:NODE_OR] = 2 let s:opprec[s:NODE_AND] = 3 let s:opprec[s:NODE_EQUAL] = 4 @@ -290,6 +291,8 @@ function s:PythonCompiler.compile(node) return self.compile_env(a:node) elseif a:node.type == s:NODE_REG return self.compile_reg(a:node) + elseif a:node.type == s:NODE_PARENEXPR + return self.compile_parenexpr(a:node) else throw self.err('Compiler: unknown node: %s', string(a:node)) endif @@ -799,6 +802,10 @@ function s:PythonCompiler.compile_reg(node) throw 'NotImplemented: reg' endfunction +function s:PythonCompiler.compile_parenexpr(node) + return self.compile(a:node.value) +endfunction + function s:PythonCompiler.compile_op1(node, op) let left = self.compile(a:node.left) if s:opprec[a:node.type] > s:opprec[a:node.left.type] diff --git a/py/vimlparser.py b/py/vimlparser.py index 89c517d1..23a72706 100644 --- a/py/vimlparser.py +++ b/py/vimlparser.py @@ -281,6 +281,7 @@ def viml_type(obj): NODE_CURLYNAMEPART = 90 NODE_CURLYNAMEEXPR = 91 NODE_LAMBDA = 92 +NODE_PARENEXPR = 93 TOKEN_EOF = 1 TOKEN_EOL = 2 TOKEN_SPACE = 3 @@ -528,6 +529,7 @@ def ExArg(): # CURLYNAMEPART .value # CURLYNAMEEXPR .value # LAMBDA .rlist .left +# PARENEXPR .value def Node(type): return AttributeDict({"type":type}) @@ -1140,7 +1142,7 @@ def separate_nextcmd(self): if c != "`": raise VimLParserException(Err(viml_printf("unexpected character: %s", c), self.reader.getpos())) self.reader.getn(1) - elif c == "|" or c == "\n" or c == "\"" and not viml_eqregh(self.ea.cmd.flags, "\\") and (self.ea.cmd.name != "@" and self.ea.cmd.name != "*" or self.reader.getpos() != self.ea.argpos) and (self.ea.cmd.name != "redir" or self.reader.getpos().i != self.ea.argpos.i + 1 or pc != "@"): + elif c == "|" or c == "\n" or (c == "\"" and not viml_eqregh(self.ea.cmd.flags, "\\") and ((self.ea.cmd.name != "@" and self.ea.cmd.name != "*") or self.reader.getpos() != self.ea.argpos) and (self.ea.cmd.name != "redir" or self.reader.getpos().i != self.ea.argpos.i + 1 or pc != "@")): has_cpo_bar = FALSE # &cpoptions =~ 'b' if (not has_cpo_bar or not viml_eqregh(self.ea.cmd.flags, "\\")) and pc == "\\": @@ -1421,7 +1423,7 @@ def parse_cmd_let(self): s1 = self.reader.peekn(1) s2 = self.reader.peekn(2) # :let {var-name} .. - if self.ends_excmds(s1) or s2 != "+=" and s2 != "-=" and s2 != ".=" and s1 != "=": + if self.ends_excmds(s1) or (s2 != "+=" and s2 != "-=" and s2 != ".=" and s1 != "="): self.reader.seek_set(pos) self.parse_cmd_common() return @@ -1860,7 +1862,7 @@ def get2(self): if r.p(0) == "." and isdigit(r.p(1)): s += r.getn(1) s += r.read_digit() - if (r.p(0) == "E" or r.p(0) == "e") and (isdigit(r.p(1)) or (r.p(1) == "-" or r.p(1) == "+") and isdigit(r.p(2))): + if (r.p(0) == "E" or r.p(0) == "e") and (isdigit(r.p(1)) or ((r.p(1) == "-" or r.p(1) == "+") and isdigit(r.p(2)))): s += r.getn(2) s += r.read_digit() return self.token(TOKEN_NUMBER, s, pos) @@ -2708,7 +2710,9 @@ def parse_expr9(self): raise VimLParserException(Err(viml_printf("unexpected token: %s", token.value), token.pos)) return node elif token.type == TOKEN_POPEN: - node = self.parse_expr1() + node = Node(NODE_PARENEXPR) + node.pos = token.pos + node.value = self.parse_expr1() token = self.tokenizer.get() if token.type != TOKEN_PCLOSE: raise VimLParserException(Err(viml_printf("unexpected token: %s", token.value), token.pos)) @@ -3308,6 +3312,8 @@ def compile(self, node): return self.compile_curlynameexpr(node) elif node.type == NODE_LAMBDA: return self.compile_lambda(node) + elif node.type == NODE_PARENEXPR: + return self.compile_parenexpr(node) else: raise VimLParserException(viml_printf("Compiler: unknown node: %s", viml_string(node))) return NIL @@ -3668,6 +3674,9 @@ def compile_lambda(self, node): rlist = [self.compile(vval) for vval in node.rlist] return viml_printf("(lambda (%s) %s)", viml_join(rlist, " "), self.compile(node.left)) + def compile_parenexpr(self, node): + return self.compile(node.value) + # TODO: under construction class RegexpParser: RE_VERY_NOMAGIC = 1