From f52fea984d6ce717a041b19b28ec05340c034b99 Mon Sep 17 00:00:00 2001 From: David Halter Date: Tue, 21 Aug 2012 11:59:21 +0200 Subject: [PATCH] parsing.Array/parsing.Call have a start_pos attribute now --- dynamic.py | 10 +++++++++- evaluate.py | 5 +++-- helpers.py | 13 +++++++++---- parsing.py | 31 +++++++++++++++++-------------- 4 files changed, 38 insertions(+), 21 deletions(-) diff --git a/dynamic.py b/dynamic.py index a4697d3d..eabce27b 100644 --- a/dynamic.py +++ b/dynamic.py @@ -8,6 +8,7 @@ working quite good. import parsing import evaluate +import builtin import helpers import settings @@ -213,15 +214,22 @@ class ArrayInstance(parsing.Base): lists/sets are too complicated too handle that. """ items = [] + #print 'ic', self.var_args, self.var_args.parent_stmt() + stmt = self.var_args.parent_stmt() + #if stmt.get_parent_until() == builtin.Builtin.scope: + #evaluate.follow_statement.push(stmt) for array in evaluate.follow_call_list(self.var_args): if isinstance(array, evaluate.Instance) and len(array.var_args): temp = array.var_args[0][0] if isinstance(temp, ArrayInstance): - #print items, self, self.var_args, self.var_args.parent_stmt(), array + #print items, self, id(self.var_args), id(self.var_args.parent_stmt()), array items += temp.iter_content() continue items += evaluate.get_iterator_types([array]) + #if stmt.get_parent_until() == builtin.Builtin.scope: + #evaluate.follow_statement.pop() + #print 'ic finish', self.var_args module = self.var_args.parent_stmt().get_parent_until() is_list = str(self.instance.name) == 'list' items += _check_array_additions(self.instance, module, is_list) diff --git a/evaluate.py b/evaluate.py index 8563f79b..4a359ad8 100644 --- a/evaluate.py +++ b/evaluate.py @@ -492,7 +492,8 @@ class Execution(Executable): Create a param with the original scope (of varargs) as parent. """ parent_stmt = self.var_args.parent_stmt() - calls = parsing.Array(parsing.Array.NOARRAY, parent_stmt) + pos = parent_stmt.start_pos if parent_stmt else None + calls = parsing.Array(pos, parsing.Array.NOARRAY, parent_stmt) calls.values = values calls.keys = keys calls.type = array_type @@ -814,7 +815,7 @@ class Array(parsing.Base): return builtin.Builtin.scope def __getattr__(self, name): - if name not in ['type']: + if name not in ['type', 'start_pos']: raise AttributeError('Strange access: %s.' % name) return getattr(self._array, name) diff --git a/helpers.py b/helpers.py index bf2b4e09..45b8a92f 100644 --- a/helpers.py +++ b/helpers.py @@ -21,10 +21,14 @@ class RecursionDecorator(object): # The same's true for the builtins, because the builtins are really # simple. if isinstance(stmt, parsing.Param) \ - or r.script == builtin.Builtin.scope: + or (r.script == builtin.Builtin.scope and + stmt.start_pos[0] != 538000): return self.func(stmt, *args, **kwargs) + if r.script == builtin.Builtin.scope: + print 'rec_catch', stmt, stmt.parent().parent() + #print stmt - if self.check_recursion(r): + if self._check_recursion(r): debug.warning('catched recursion', stmt, args, kwargs) return [] parent, self.current = self.current, r @@ -32,7 +36,7 @@ class RecursionDecorator(object): self.current = parent return result - def check_recursion(self, new): + def _check_recursion(self, new): test = self.current while True: if new == test: @@ -138,6 +142,7 @@ def generate_param_array(args_tuple, parent_stmt=None): values.append([]) else: values.append([arg]) - arr = parsing.Array(parsing.Array.TUPLE, parent_stmt, values=values) + pos = None + arr = parsing.Array(pos, parsing.Array.TUPLE, parent_stmt, values=values) evaluate.faked_scopes.append(arr) return arr diff --git a/parsing.py b/parsing.py index f8551dfe..984eca0e 100644 --- a/parsing.py +++ b/parsing.py @@ -624,7 +624,7 @@ class Statement(Simple): if self._assignment_calls_calculated: return self._assignment_calls self._assignment_details = [] - result = Array(Array.NOARRAY, self) + result = Array(self.start_pos, Array.NOARRAY, self) top = result level = 0 is_chain = False @@ -634,11 +634,12 @@ class Statement(Simple): for i, tok_temp in tok_iter: #print 'tok', tok_temp, result try: - token_type, tok = tok_temp + token_type, tok, start_pos = tok_temp except TypeError: # the token is a Name, which has already been parsed tok = tok_temp token_type = None + start_pos = tok.start_pos except ValueError: debug.warning("unkown value, shouldn't happen", tok_temp, type(tok_temp)) @@ -652,7 +653,7 @@ class Statement(Simple): self._assignment_details.append((tok, top)) # All these calls wouldn't be important if nonlocal would # exist. -> Initialize the first item again. - result = Array(Array.NOARRAY, self) + result = Array(start_pos, Array.NOARRAY, self) top = result level = 0 close_brackets = False @@ -678,7 +679,7 @@ class Statement(Simple): if is_chain: #print 'chain', self, tok, result - call = Call(tok, c_type, parent=result) + call = Call(tok, c_type, start_pos, parent=result) result = result.set_next_chain_call(call) is_chain = False close_brackets = False @@ -689,17 +690,17 @@ class Statement(Simple): if result.__class__ == Call: result = result.parent() close_brackets = False - call = Call(tok, c_type, parent=result) + call = Call(tok, c_type, start_pos, parent=result) result.add_to_current_field(call) result = call elif tok in brackets.keys(): # brackets level += 1 if is_call_or_close(): - result = Array(brackets[tok], parent=result) + result = Array(start_pos, brackets[tok], parent=result) result = result.parent().add_execution(result) close_brackets = False else: - result = Array(brackets[tok], parent=result) + result = Array(start_pos, brackets[tok], parent=result) result.parent().add_to_current_field(result) elif tok == ':': if is_call_or_close(): @@ -782,12 +783,13 @@ class Call(object): STRING = 3 """ The statement object of functions, to """ - def __init__(self, name, type, parent_stmt=None, parent=None): + def __init__(self, name, type, start_pos, parent_stmt=None, parent=None): self.name = name # parent is not the oposite of next. The parent of c: a = [b.c] would # be an array. self.parent = weakref.ref(parent) if parent is not None else None self.type = type + self.start_pos = start_pos self.next = None self.execution = None @@ -862,9 +864,10 @@ class Array(Call): DICT = 'dict' SET = 'set' - def __init__(self, arr_type=NOARRAY, parent_stmt=None, parent=None, - values=None): - super(Array, self).__init__(None, arr_type, parent_stmt, parent) + def __init__(self, start_pos, arr_type=NOARRAY, parent_stmt=None, + parent=None, values=None): + super(Array, self).__init__(None, arr_type, start_pos, parent_stmt, + parent) self.values = values if values else [] self.keys = [] @@ -992,7 +995,7 @@ class PyFuzzyParser(object): # initialize global Scope self.module = Module(module_path) self.scope = self.module - self.current = (None, None, None) + self.current = (None, None) # Stuff to fix tokenize errors. The parser is pretty good in tolerating # any errors of tokenize and just parse ahead. @@ -1228,7 +1231,7 @@ class PyFuzzyParser(object): while not (tok in always_break or tok in breaks and level <= 0): set_string = None #print 'parse_stmt', tok, tokenize.tok_name[token_type] - tok_list.append(self.current) + tok_list.append(self.current + (self.start_pos,)) if tok == 'as': string += " %s " % tok token_type, tok = self.next() @@ -1250,7 +1253,7 @@ class PyFuzzyParser(object): # This is basically a reset of the statement. debug.warning('keyword in statement %s@%s', tok_list, self.start_pos[0]) - tok_list = [self.current] + tok_list = [self.current + (self.start_pos,)] set_vars = [] used_funcs = [] used_vars = []