|
3 | 3 |
|
4 | 4 | import sys
|
5 | 5 | import re
|
| 6 | +import inspect |
6 | 7 |
|
7 | 8 | def main():
|
8 | 9 | r = StringReader(viml_readfile(sys.argv[1]))
|
@@ -155,6 +156,21 @@ def viml_has_key(obj, key):
|
155 | 156 | def viml_stridx(a, b):
|
156 | 157 | return a.find(b)
|
157 | 158 |
|
| 159 | +def viml_type(obj): |
| 160 | + if isinstance(obj, int): |
| 161 | + return 0 |
| 162 | + elif isinstance(obj, str): |
| 163 | + return 1 |
| 164 | + elif inspect.isfunction(obj): |
| 165 | + return 2 |
| 166 | + elif isinstance(obj, list): |
| 167 | + return 3 |
| 168 | + elif isinstance(obj, dict): |
| 169 | + return 4 |
| 170 | + elif isinstance(obj, float): |
| 171 | + return 5 |
| 172 | + raise Exception('Unknown Type') |
| 173 | + |
158 | 174 | NIL = []
|
159 | 175 | NODE_TOPLEVEL = 1
|
160 | 176 | NODE_COMMENT = 2
|
@@ -335,9 +351,6 @@ def isnamec(c):
|
335 | 351 | def isnamec1(c):
|
336 | 352 | return viml_eqregh(c, "^[A-Za-z_]$")
|
337 | 353 |
|
338 |
| -def isattrc(c): |
339 |
| - return viml_eqregh(c, "^[0-9A-Za-z_]$") |
340 |
| - |
341 | 354 | def isargname(s):
|
342 | 355 | return viml_eqregh(s, "^[A-Za-z_][0-9A-Za-z_]*$")
|
343 | 356 |
|
@@ -2306,14 +2319,11 @@ def parse_expr8(self):
|
2306 | 2319 | # TODO: funcname E740: Too many arguments for function: %s
|
2307 | 2320 | raise Exception(Err("E740: Too many arguments for function", node.pos))
|
2308 | 2321 | left = node
|
2309 |
| - elif not iswhite(c) and token.type == TOKEN_DOT and isattrc(self.reader.p(0)) and (left.type == NODE_IDENTIFIER or left.type == NODE_CURLYNAME or left.type == NODE_DICT or left.type == NODE_SUBSCRIPT or left.type == NODE_CALL or left.type == NODE_DOT): |
2310 |
| - # SUBSCRIPT or CONCAT |
2311 |
| - node = Node(NODE_DOT) |
2312 |
| - node.pos = token.pos |
2313 |
| - node.left = left |
2314 |
| - node.right = Node(NODE_IDENTIFIER) |
2315 |
| - node.right.pos = self.reader.getpos() |
2316 |
| - node.right.value = self.reader.read_attr() |
| 2322 | + elif not iswhite(c) and token.type == TOKEN_DOT: |
| 2323 | + node = self.parse_dot(token, left) |
| 2324 | + if node is NIL: |
| 2325 | + self.reader.seek_set(pos) |
| 2326 | + break |
2317 | 2327 | left = node
|
2318 | 2328 | else:
|
2319 | 2329 | self.reader.seek_set(pos)
|
@@ -2431,6 +2441,27 @@ def parse_expr9(self):
|
2431 | 2441 | raise Exception(Err(viml_printf("unexpected token: %s", token.value), token.pos))
|
2432 | 2442 | return node
|
2433 | 2443 |
|
| 2444 | +# SUBSCRIPT or CONCAT |
| 2445 | +# dict "." [0-9A-Za-z_]+ => (subscript dict key) |
| 2446 | +# str "." expr6 => (concat str expr6) |
| 2447 | + def parse_dot(self, token, left): |
| 2448 | + if left.type != NODE_IDENTIFIER and left.type != NODE_CURLYNAME and left.type != NODE_DICT and left.type != NODE_SUBSCRIPT and left.type != NODE_CALL and left.type != NODE_DOT: |
| 2449 | + return NIL |
| 2450 | + if not iswordc(self.reader.p(0)): |
| 2451 | + return NIL |
| 2452 | + pos = self.reader.getpos() |
| 2453 | + name = self.reader.read_word() |
| 2454 | + if isnamec(self.reader.p(0)): |
| 2455 | + # foo.s:bar or foo.bar#baz |
| 2456 | + return NIL |
| 2457 | + node = Node(NODE_DOT) |
| 2458 | + node.pos = token.pos |
| 2459 | + node.left = left |
| 2460 | + node.right = Node(NODE_IDENTIFIER) |
| 2461 | + node.right.pos = pos |
| 2462 | + node.right.value = name |
| 2463 | + return node |
| 2464 | + |
2434 | 2465 | def parse_identifier(self):
|
2435 | 2466 | id = []
|
2436 | 2467 | self.reader.skip_white()
|
@@ -2515,14 +2546,11 @@ def parse_lv8(self):
|
2515 | 2546 | if token.type != TOKEN_SQCLOSE:
|
2516 | 2547 | raise Exception(Err(viml_printf("unexpected token: %s", token.value), token.pos))
|
2517 | 2548 | left = node
|
2518 |
| - elif not iswhite(c) and token.type == TOKEN_DOT and isattrc(self.reader.p(0)) and (left.type == NODE_IDENTIFIER or left.type == NODE_CURLYNAME or left.type == NODE_DICT or left.type == NODE_SUBSCRIPT or left.type == NODE_CALL or left.type == NODE_DOT): |
2519 |
| - # SUBSCRIPT or CONCAT |
2520 |
| - node = Node(NODE_DOT) |
2521 |
| - node.pos = token.pos |
2522 |
| - node.left = left |
2523 |
| - node.right = Node(NODE_IDENTIFIER) |
2524 |
| - node.right.pos = self.reader.getpos() |
2525 |
| - node.right.value = self.reader.read_attr() |
| 2549 | + elif not iswhite(c) and token.type == TOKEN_DOT: |
| 2550 | + node = self.parse_dot(token, left) |
| 2551 | + if node is NIL: |
| 2552 | + self.reader.seek_set(pos) |
| 2553 | + break |
2526 | 2554 | left = node
|
2527 | 2555 | else:
|
2528 | 2556 | self.reader.seek_set(pos)
|
@@ -2565,7 +2593,7 @@ def parse_lv9(self):
|
2565 | 2593 |
|
2566 | 2594 | class StringReader:
|
2567 | 2595 | def __init__(self, lines):
|
2568 |
| - self.lines = lines |
| 2596 | + lines = lines if viml_type(lines) == 3 else [lines] |
2569 | 2597 | self.buf = []
|
2570 | 2598 | self.pos = []
|
2571 | 2599 | lnum = 0
|
@@ -2724,12 +2752,6 @@ def read_name(self):
|
2724 | 2752 | r += self.getn(1)
|
2725 | 2753 | return r
|
2726 | 2754 |
|
2727 |
| - def read_attr(self): |
2728 |
| - r = "" |
2729 |
| - while isattrc(self.peekn(1)): |
2730 |
| - r += self.getn(1) |
2731 |
| - return r |
2732 |
| - |
2733 | 2755 | def skip_white(self):
|
2734 | 2756 | while iswhite(self.peekn(1)):
|
2735 | 2757 | self.seek_cur(1)
|
|
0 commit comments