Skip to content

Commit

Permalink
gen
Browse files Browse the repository at this point in the history
  • Loading branch information
tyru committed Aug 2, 2019
1 parent a74f173 commit 4a60bcb
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 121 deletions.
125 changes: 58 additions & 67 deletions js/vimlparser.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
}
Expand All @@ -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) {
Expand Down
106 changes: 52 additions & 54 deletions py/vimlparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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:
Expand All @@ -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 == "<EOF>" or c == "<EOL>"

Expand Down Expand Up @@ -3600,29 +3597,30 @@ 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:
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("(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]
Expand Down

0 comments on commit 4a60bcb

Please sign in to comment.