예제 #1
0
 def atom_number(self, nodelist):
     n = Transformer.atom_number(self, nodelist)
     number, lineno = nodelist[0][1:]
     if _is_integer(number):
         n = Const(long(number), lineno)
         return CallFunc(Name('Integer'), [n])
     if number.endswith('j'):
         n = Const(complex(number), lineno)
         return CallFunc(Name('sympify'), [n])
     n = Const(number, lineno)
     return CallFunc(Name('Real'), [n])
예제 #2
0
    def visit_FunctionCall(self, func_call, cfg, func, node):
        if func_call.declaration != func:
            return

        post_entry = cfg.entry.out_edges.keys()[0]

        # Assign parameters to temporaries, and then temporaries to arguments
        nodes1 = []
        nodes2 = []
        for i in range(len(func_call.args)):
            # Don't need to assign if it's variable assigned to itself
            if func_call.args[i].declaration == func.args[i]:
                continue

            target = Name(func.args[i])
            target.type = func.args[i].type

            # Don't need temporary if target isn't used in remaining args
            if target.declaration in [
                    x.declaration for x in func_call.args[i + 1:]
            ]:
                op_node1, source = assign_to_temporary(cfg, func_call.args[i])
                nodes1.append(op_node1)
            else:
                source = func_call.args[i]

            op_node2 = Operation(AssignStatement(target, source))
            nodes2.append(op_node2)

        # Link assignments into CFG
        first_assign = None
        last_assign = None
        for n in nodes1 + nodes2:
            if last_assign is not None:
                cfg.connect(last_assign, n)
            else:
                first_assign = n
            last_assign = n

        if first_assign is None:
            first_assign = post_entry
        else:
            cfg.connect(last_assign, post_entry)

        # Call node is replaced from each of its predecessors with the first assignment or target
        cfg.replace_before(node, first_assign)

        # Call node is removed from its successor
        post_call = node.out_edges.keys()[0]
        cfg.disconnect(node, post_call)
예제 #3
0
파일: tailrec.py 프로젝트: changbindu/cpu
    def visit_FunctionCall(self, func_call, cfg, func, node):
        if func_call.declaration != func:
            return
        
        post_entry = cfg.entry.out_edges.keys()[0]

        # Assign parameters to temporaries, and then temporaries to arguments
        nodes1 = []
        nodes2 = []
        for i in range(len(func_call.args)):
            # Don't need to assign if it's variable assigned to itself
            if func_call.args[i].declaration == func.args[i]:
                continue
            
            target = Name(func.args[i])
            target.type = func.args[i].type
            
            # Don't need temporary if target isn't used in remaining args
            if target.declaration in [x.declaration for x in func_call.args[i+1:]]:
                op_node1, source = assign_to_temporary(cfg, func_call.args[i])
                nodes1.append(op_node1)
            else:
                source = func_call.args[i]
        
            op_node2 = Operation(AssignStatement(target, source))
            nodes2.append(op_node2)

        # Link assignments into CFG
        first_assign = None
        last_assign = None
        for n in nodes1 + nodes2:
            if last_assign is not None:
                cfg.connect(last_assign, n)
            else:
                first_assign = n
            last_assign = n

        if first_assign is None:
            first_assign = post_entry        
        else:
            cfg.connect(last_assign, post_entry)
        
        # Call node is replaced from each of its predecessors with the first assignment or target
        cfg.replace_before(node, first_assign)
        
        # Call node is removed from its successor
        post_call = node.out_edges.keys()[0]
        cfg.disconnect(node, post_call)
    def test_ast_policy(self):
        'Policy: Keep tidy ASTs'

        a = Discard(Name('a'))
        empty = Stmt([])

        self.assertEqual(empty, Block('').ast)
        self.assertEqual(empty, Block(empty).ast)
        self.assertEqual(empty, Block(Module(None, empty)).ast)

        self.assertEqual(a, Block('a').ast)
        self.assertEqual(a, Block(a).ast)
        self.assertEqual(a, Block(Stmt([a])).ast)
        self.assertEqual(a, Block(Module(None, Stmt([a]))).ast)

        # Similar, except we don't use strings since Block does its own parsing
        b = Block()
        b.ast = empty
        self.assertEqual(b.ast, empty)
        b.ast = Module(None, empty)
        self.assertEqual(b.ast, empty)
        b.ast = a
        self.assertEqual(b.ast, a)
        b.ast = Stmt([a])
        self.assertEqual(b.ast, a)
        b.ast = Module(None, Stmt([a]))
        self.assertEqual(b.ast, a)
예제 #5
0
 def visitFrom(self, node):
     for elem in node.modname.split("."):
         self.popWordsUpTo(elem)
         
     for name, alias in node.names:
         if name == self.targetstr:
             if alias is not None:
                 pretendNode = Name(alias)
             else:
                 pretendNode = Name(name)
             if findDefinitionFromASTNode(self.scope, pretendNode) \
                                                 == self.targetMatch:
                 self.appendMatch(name)
         self.popWordsUpTo(name)
         if alias is not None:
             self.popWordsUpTo(alias)
예제 #6
0
    def lambdef(self, nodelist):
        #this is python stdlib symbol, not SymPy symbol:
        from sympy import stdlib_symbol
        if nodelist[2][0] == stdlib_symbol.varargslist:
            names, defaults, flags = self.com_arglist(nodelist[2][1:])
        else:
            names = defaults = ()
            flags = 0

        lineno = nodelist[1][2]
        code = self.com_node(nodelist[-1])

        assert not defaults, ` defaults `  # sympy.Lambda does not support optional arguments

        if len(names) == 0:
            argument = ['x']
        else:
            argument = names

        def convert(x):
            return CallFunc(Name('sympify'), [Const(x)])

        argument = [convert(arg) for arg in argument]

        return CallFunc(Name('Lambda'), argument + [code])
    def lambdef(self, nodelist):
        if nodelist[2][0] == symbol.varargslist:
            names, defaults, flags = self.com_arglist(nodelist[2][1:])
        else:
            names = defaults = ()
            flags = 0

        lineno = nodelist[1][2]
        code = self.com_node(nodelist[-1])

        assert not defaults, ` defaults `  # sympy.Lambda does not support optional arguments

        def convert(x):
            return CallFunc(Name('sympify'), [Const(x)])

        argument = [convert(arg) for arg in names]

        return CallFunc(Name('Lambda'),
                        [CallFunc(Name('Tuple'), argument), code])
예제 #8
0
 def __const(self):
     from compiler.ast import Discard, CallFunc, Name, Const
     try:
         n = Discard(
             CallFunc(Name('__write__'), [Const(self.__tokenText(strip=0))],
                      None, None))
         t = self.__tokenPop()
         _renumber(n, t[1] - 1)
         return n
     except:
         self.__error('bad constant')
예제 #9
0
 def visitFrom(self, node):
     if self._checkModuleName(node.modname):
         return
     for name, alias in node.names:
         if self.checkIfNameMatchesColumn(name):
             assert "." not in name
             self.node = Name(name)
             return
         self.popWordsUpTo(name)
         if alias is not None:
             self.popWordsUpTo(alias)
예제 #10
0
파일: common.py 프로젝트: unnch/spell-sat
    def visitFunction(self, node):
        if self.checkIfNameMatchesColumn(node.name):
            self.node = node
        self.popWordsUpTo(node.name)

        for arg, default in self.zipArgs(node.argnames, node.defaults):
            if self.checkIfNameMatchesColumn(arg):
                self.node = Name(arg)
            self.popWordsUpTo(arg)
            if default is not None:
                self.visit(default)
        self.visit(node.code)
예제 #11
0
 def __expr(self):
     from compiler.ast import Discard, CallFunc, Name
     t = self.__tokenText()
     try:
         n = Discard(
             CallFunc(Name('__swrite__'),
                      [self._cparse(t, 'eval').getChildren()[0]], None,
                      None))
         t = self.__tokenPop()
         _renumber(n, t[1] - 1)
         return n
     except:
         self.__error('bad expression')
예제 #12
0
   def visit_FunctionCall(self, func_call, cfg, func, node):
       if isinstance(func_call.declaration, Builtin) or func_call.declaration == func:
           return
       
       try:
           other_cfg = func_call.declaration.cfg
       except AttributeError:
           return
       
       # Embed a copy of the inlined function's CFG
       isomorphism = cfg.embed(other_cfg)
       
       # Copy the inlined function's symbol table, and replace subgraph's variables with copies
       var_isomorphism = self.copy_variables(cfg, other_cfg)
       for n in isomorphism.values():
           self.replace_vars(n, var_isomorphism)
       
       # Assign parameters to inlined function's argument variables
       for i in range(len(func_call.args)):
           arg = func_call.args[i]
           orig_var = func_call.declaration.args[i]
           target_var = var_isomorphism[orig_var]
           pre_assign = Operation(AssignStatement(Name(target_var), arg))
           cfg.insert_before(node, pre_assign)
       
       # Assign return value to caller's result variable, at each of the subgraph's return nodes
       if isinstance(node.expression, AssignStatement):
           target = node.expression.target
           for subgraph_node in isomorphism.values():
               if isinstance(subgraph_node, Return):
                   ret_assign = Operation(AssignStatement(target, subgraph_node.expression))
                   cfg.replace_before(subgraph_node, ret_assign)
                   cfg.replace_after(subgraph_node, ret_assign)
 
       # Disconnect old entry and exit from inlined subgraph.
       first_node = isomorphism[other_cfg.entry].out_edges.keys()[0]
       cfg.disconnect(isomorphism[other_cfg.entry], first_node)
       cfg.replace_before(node, first_node)
       
       for ln in isomorphism[other_cfg.exit].in_edges.keys():
           cfg.disconnect(ln, isomorphism[other_cfg.exit])
           cfg.replace_after(node, ln)
예제 #13
0
def deduceImportsForNewFile(refs, scope):
    importModules = {}
    for ref in refs:
        match = findDefinitionFromASTNode(scope, Name(ref))

        if match.filename == scope.module.filename:
            tgtscope = getScopeForLine(getSourceNode(match.filename),
                                       match.lineno)
            while tgtscope != scope and not isinstance(tgtscope, Module):
                tgtscope = tgtscope.getParent()

            if not isinstance(tgtscope, Module):
                continue  # was defined in this function

        mpath = filenameToModulePath(match.filename)
        if mpath in importModules:
            importModules[mpath].append(ref)
        else:
            importModules[mpath] = [ref]
    return importModules
예제 #14
0
    def __script(self, mode='script'):
        self.__tokenPop()
        text = dedent(self.__tokenText(strip=0))
        scriptMode = 'script' == mode
        if text:
            try:
                stmt = self._cparse(text, scriptMode and 'exec' or 'eval').node
            except:
                self.__error()
        t = self.__tokenPop()
        end = 'end' + mode
        try:
            assert self._tokens[self._tokenX][0] == end
            self.__tokenPop()
        except:
            self.__error(end + ' expected')
        if not text: return []
        _renumber(stmt, t[1] - 1)

        if scriptMode: return stmt.nodes
        from compiler.ast import Discard, CallFunc, Name, Const
        return Discard(
            CallFunc(Name('__swrite__'), [stmt.getChildren()[0]], None, None))
예제 #15
0
 def convert(x):
     return CallFunc(Name('sympify'), [Const(x)])
예제 #16
0
    def __get_ast(self):
        from compiler.ast import    Module, Stmt, Assign, AssName, Const, Function, For, Getattr,\
                                    TryFinally, TryExcept, If, Import, AssAttr, Name, CallFunc,\
                                    Class, Compare, Raise, And, Mod, Tuple, Pass, Not, Exec, List,\
                                    Discard, Keyword, Return, Dict, Break, AssTuple, Subscript,\
                                    Printnl, From, Lambda

        preppyNodes = self.__parse()
        if self._defSeen == 1:
            fixargs = self._fnc_argnames
            defaults = list(self._fnc_defaults)
            if self._fnc_kwargs:
                spargs = [fixargs[-1]]
                fixargs = fixargs[:-1]
            else:
                spargs = ['__kwds__']
            if self._fnc_varargs:
                spargs.insert(0, fixargs[-1])
                fixargs = fixargs[:-1]
            kwargs = fixargs[-len(defaults):]
            fixargs = fixargs[:-len(defaults)]
            flags = self._fnc_flags

            #construct the getOutput function
            nodes = [
                Assign([AssName('__lquoteFunc__', 'OP_ASSIGN')],
                       CallFunc(Getattr(Name(spargs[-1]), 'setdefault'),
                                [Const('__lquoteFunc__'),
                                 Name('str')], None, None)),
                Discard(
                    CallFunc(Getattr(Name(spargs[-1]), 'pop'),
                             [Const('__lquoteFunc__')], None, None)),
                Assign([AssName('__quoteFunc__', 'OP_ASSIGN')],
                       CallFunc(Getattr(Name(spargs[-1]), 'setdefault'),
                                [Const('__quoteFunc__'),
                                 Name('str')], None, None)),
                Discard(
                    CallFunc(Getattr(Name(spargs[-1]), 'pop'),
                             [Const('__quoteFunc__')], None, None))
            ]
            if not self._fnc_kwargs:
                nodes += [
                    If([(Name(spargs[-1]),
                         Stmt([
                             Raise(
                                 CallFunc(Name('TypeError'), [
                                     Const('get: unexpected keyword arguments')
                                 ], None, None), None, None)
                         ]))], None)
                ]
            nodes += [
                Assign([AssName('__append__', 'OP_ASSIGN')],
                       Getattr(List(()), 'append')),
                Assign([AssName('__write__', 'OP_ASSIGN')],
                       Lambda(['x'], [], 0,
                              CallFunc(Name('__append__'), [
                                  CallFunc(Name('__lquoteFunc__'), [Name('x')],
                                           None, None)
                              ], None, None))),
                Assign([AssName('__swrite__', 'OP_ASSIGN')],
                       Lambda(['x'], [], 0,
                              CallFunc(Name('__append__'), [
                                  CallFunc(Name('__quoteFunc__'), [Name('x')],
                                           None, None)
                              ], None, None)))
            ]
            for n in nodes:
                _denumber(n, self._fnc_lineno)
            preppyNodes = nodes + preppyNodes + [
                Return(
                    CallFunc(Getattr(Const(''), 'join'),
                             [Getattr(Name('__append__'), '__self__')], None,
                             None))
            ]
            argnames = list(fixargs) + list(kwargs) + list(spargs)
            FA = ('get', argnames, defaults, flags | 8, None,
                  Stmt(preppyNodes))
            global _newPreambleAst
            if not _newPreambleAst:
                _newPreambleAst = self._cparse(_newPreamble).node.nodes
                map(_denumber, _newPreambleAst)
            extraAst = _newPreambleAst
        else:
            global _preambleAst, _localizer
            if not _preambleAst:
                _preambleAst = self._cparse(_preamble).node.nodes
                map(_denumber, _preambleAst)
                _localizer = [
                    Assign([AssName('__d__', 'OP_ASSIGN')],
                           Name('dictionary')),
                    Discard(
                        CallFunc(
                            Getattr(CallFunc(Name('globals'), [], None, None),
                                    'update'), [Name('__d__')], None, None))
                ]
            preppyNodes = _localizer + preppyNodes
            FA = ('__code__', [
                'dictionary', 'outputfile', '__write__', '__swrite__',
                '__save_sys_stdout__'
            ], (), 0, None, Stmt(preppyNodes))
            extraAst = _preambleAst
        if sys.hexversion >= 0x2040000: FA = (None, ) + FA
        return Module(
            self.filename,
            Stmt([
                Assign([AssName('__checksum__', 'OP_ASSIGN')],
                       Const(getattr(self, 'sourcechecksum'))),
                Function(*FA),
            ] + extraAst))
예제 #17
0
 def createGetattr(self,fqn):
     node = Name(fqn[0])
     for name in fqn.split(".")[1:]:
         node = Getattr(node,name)
     return node
예제 #18
0
 def test_attemptToConvertGetattrToFqn_returnsNoneIfFails(self):
     ast = Getattr(CallFunc(Name("foo"),[],[],[]),"hello")
     assert attemptToConvertGetattrToFqn(ast) is None
예제 #19
0
def findDefinitionFromASTNode(scope,node):
    assert node is not None
    if isinstance(node,Name) or isinstance(node,AssName):
        while 1:
            # try scope children
            childscope = scope.getChild(node.name)
            if childscope is not None:
                return convertNodeToMatchObject(childscope,100)

            if isinstance(scope,Package):
                scope = scope.getChild("__init__")

            # try arguments and assignments
            match = scanScopeAST(scope,node.name,
                                 AssignmentAndFnArgsSearcher(node.name))
            if match is not None:
                return match
            
            # try imports
            match = searchImportedModulesForDefinition(scope,node)
            if match is not None:
                return match


            if not isinstance(scope,Module):
                # try parent scope
                scope = scope.getParent()
            else:
                break
        assert isinstance(scope,Module)

    elif isinstance(node,Getattr) or isinstance(node,AssAttr):
        exprtype = getTypeOfExpr(scope,node.expr)
        if not (exprtype is None or isinstance(exprtype,UnfoundType)):
            if isinstance(exprtype,Instance):
                exprtype = exprtype.getType()
                match = findDefinitionOfAttributeFromASTNode(exprtype,
                                                         node.attrname)
            else:
                match = findDefinitionFromASTNode(exprtype,
                                                  Name(node.attrname))
            if match is not None:
                return match

    elif isinstance(node,compiler.ast.Function) or \
             isinstance(node,compiler.ast.Class):
        if isAMethod(scope,node): 
            match = findDefinitionOfAttributeFromASTNode(scope,
                                                        node.name)
        else:
            match = findDefinitionFromASTNode(scope,Name(node.name))
        if match is not None:
            return match


    type = getTypeOfExpr(scope,node)
    if type is not None and (not isinstance(type,UnfoundType)) and \
                             (not isinstance(type,Instance)):
        return  convertNodeToMatchObject(type,100)
    else:
        return None
예제 #20
0
 def test_attemptToConvertGetattrToFqn_works(self):
     ast = Getattr(Getattr(Name("foo"),"bah"),"hello")
     assert attemptToConvertGetattrToFqn(ast) == "foo.bah.hello"
예제 #21
0
 def transform(self, node):
     if isinstance(node, Node) and node in name_for.keys():
         return Name(name_for[node])
     else:
         return super(C, self).transform(node)
예제 #22
0
파일: common.py 프로젝트: unnch/spell-sat
 def _manufactureASTNodeFromFQN(self, fqn):
     if "." in fqn:
         assert 0, "getattr not supported yet"
     else:
         return Name(fqn)