diff --git a/builtin.py b/builtin.py index babd7ed0..19f5e90d 100644 --- a/builtin.py +++ b/builtin.py @@ -29,7 +29,7 @@ class Parser(object): 'int': '0', 'dictionary': '{}', 'list': '[]', - 'object': '{}', + 'file object': 'file("")', # TODO things like dbg: ('not working', 'tuple of integers') } cache = {} diff --git a/evaluate.py b/evaluate.py index f9a2ccd8..e1bc75d5 100644 --- a/evaluate.py +++ b/evaluate.py @@ -6,13 +6,7 @@ follow_statement -> follow_call -> follow_paths -> follow_path TODO include super classes """ - -# python2.5 compatibility -try: - next -except NameError: - def next(obj): - return obj.next() +from _compatibility import next import itertools import copy @@ -270,7 +264,10 @@ def get_scopes_for_name(scope, name, search_global=False): if isinstance(par, parsing.Flow): # TODO get Flow data, which is defined by the loop # (or with) - pass + if par.command == 'for': + print 'for', par, par.inits + else: + debug.warning('Why are you here? %s' % par.command) elif isinstance(par, parsing.Param) \ and isinstance(par.parent.parent, parsing.Class) \ and par.position == 0: diff --git a/parsetest.py b/parsetest.py index 6908071c..bddc3fe0 100644 --- a/parsetest.py +++ b/parsetest.py @@ -142,9 +142,9 @@ c = u"asdf".join([1,2]) matrix_test = [[1,2], [1,3]] c = c1().c3().sleep() asdf = c1; asdf2 = asdf b= asdf2 - +with open('') as fi: pass c = b().c3() 1.0.fromhex(); import flask ; flsk = flask.Flask + flask.Request; abc = [1,2+3]; abc[0]. import pylab; def add(a1,b1): nana = 1; return a1+b1 -abc = datetime; return [abc][0]. ;pylab.; add(1+2,2).real +abc = datetime; return [abc][0]. ;pylab.; add(1+2,2).; for fi in [1,2]: fi. diff --git a/parsing.py b/parsing.py index 02ab5caf..c8ff3a12 100644 --- a/parsing.py +++ b/parsing.py @@ -31,6 +31,7 @@ Ignored statements: TODO take special care for future imports TODO check meta classes """ +from _compatibility import next import tokenize import cStringIO @@ -355,8 +356,8 @@ class Flow(Scope): :param command: The flow command, if, while, else, etc. :type command: str - :param statement: The statement after the flow comand -> while 'statement'. - :type statement: Statement + :param inits: The initializations of a flow -> while 'statement'. + :type inits: list(Statement) :param indent: The indent level of the flow statement. :type indent: int :param line_nr: Line number of the flow statement. @@ -364,12 +365,13 @@ class Flow(Scope): :param set_vars: Local variables used in the for loop (only there). :type set_vars: list """ - def __init__(self, command, statement, indent, line_nr, set_vars=None): + def __init__(self, command, inits, indent, line_nr, set_vars=None): super(Flow, self).__init__(indent, line_nr, '') self.command = command - self.statement = statement - if statement: - statement.parent = self + # These have to be statements, because of with, which takes multiple. + self.inits = inits + for s in inits: + s.parent = self if set_vars == None: self.set_vars = [] else: @@ -385,10 +387,10 @@ class Flow(Scope): else: vars = '' - if self.statement: - stmt = self.statement.get_code(new_line=False) - else: - stmt = '' + stmts = [] + for s in self.inits: + stmts.append(s.get_code(new_line=False)) + stmt = ', '.join(stmts) str = "%s %s%s:\n" % (self.command, vars, stmt) str += super(Flow, self).get_code(True, indention) if self.next: @@ -405,8 +407,8 @@ class Flow(Scope): """ if is_internal_call: n = list(self.set_vars) - if self.statement: - n += self.statement.set_vars + for s in self.inits: + n += s.set_vars if self.next: n += self.next.get_set_vars(is_internal_call) n += super(Flow, self).get_set_vars() @@ -549,7 +551,8 @@ class Statement(Simple): close_brackets = False debug.dbg('tok_list', self.token_list) - for i, tok_temp in enumerate(self.token_list): + tok_iter = enumerate(self.token_list) + for i, tok_temp in tok_iter: #print 'tok', tok_temp, result try: token_type, tok, indent = tok_temp @@ -562,6 +565,12 @@ class Statement(Simple): result = Array(Array.EMPTY, self) top = result continue + elif tok == 'as': + # TODO change with parser to allow multiple statements + # This is the name and can be ignored, because set_vars is + # already caring for this. + next(tok_iter) + continue except TypeError: # the token is a Name, which has already been parsed tok = tok_temp @@ -1292,36 +1301,49 @@ class PyFuzzyParser(object): if tok == 'in': statement, tok = self._parse_statement() if tok == ':': - f = Flow('for', statement, indent, self.line_nr, \ - value_list) + f = Flow('for', [statement], indent, + self.line_nr, value_list) debug.dbg("new scope: flow for@%s" % (f.line_nr)) self.scope = self.scope.add_statement(f) elif tok in ['if', 'while', 'try', 'with'] + extended_flow: added_breaks = [] command = tok - if command == 'except': - added_breaks += (',') - statement, tok = \ - self._parse_statement(added_breaks=added_breaks) - if tok in added_breaks: - # the except statement defines a var - # this is only true for python 2 - path, token_type, tok, start_indent, start_line2 = \ - self._parsedotname() - n = Name(path, start_indent, start_line2, self.line_nr) - statement.set_vars.append(n) - statement.code += ',' + n.get_code() + if command in ['except', 'with']: + added_breaks.append(',') + # multiple statements because of with + inits = [] + first = True + while first or command == 'with' and tok != ':': + statement, tok = \ + self._parse_statement(added_breaks=added_breaks) + if command == 'except' and tok in added_breaks: + # the except statement defines a var + # this is only true for python 2 + path, token_type, tok, start_indent, start_line2 = \ + self._parsedotname() + n = Name(path, start_indent, start_line2, + self.line_nr) + statement.set_vars.append(n) + statement.code += ',' + n.get_code() + if statement: + inits.append(statement) + first = False + if tok == ':': - f = Flow(command, statement, indent, self.line_nr) + f = Flow(command, inits, indent, self.line_nr) debug.dbg("new scope: flow %s@%s" % (command, self.line_nr)) if command in extended_flow: # the last statement has to be another part of - # the flow statement + # the flow statement, because a dedent releases the + # main scope, so just take the last statement. self.scope = self.scope.statements[-1].set_next(f) else: self.scope = self.scope.add_statement(f) + else: + debug.warning('syntax err, flow started @%s', + self.line_nr) # globals elif tok == 'global': stmt, tok = self._parse_statement(self.current)