def preprocess_var_decls(tree):
    """Eliminate global variable declarations of the form
    
        S = Set()
        M = Map()
    
    and return a list of pairs of variables names and type names (i.e.,
    'Set' or 'Map').
    """
    assert isinstance(tree, P.Module)
    pat = P.Assign([P.Name(P.PatVar('_VAR'), P.Wildcard())],
                   P.Call(P.Name(P.PatVar('_KIND'), P.Load()), [], [], None,
                          None))

    decls = OrderedSet()
    body = []
    changed = False
    for stmt in tree.body:
        match = P.match(pat, stmt)
        if match is not None:
            var, kind = match['_VAR'], match['_KIND']
            if kind not in ['Set', 'Map']:
                raise L.ProgramError(
                    'Unknown declaration initializer {}'.format(kind))
            decls.add((var, kind))
            changed = True
        else:
            body.append(stmt)

    if changed:
        tree = tree._replace(body=body)
    return tree, list(decls)
    def visit_Import(self, node):
        pat = P.Import([P.alias("incoq.runtime", P.PatVar("_ALIAS"))])
        match = P.match(pat, node)
        if match is None:
            return node

        # Remove the import. Record the alias to remove its uses.
        if match["_ALIAS"] is not None:
            qual = P.Name(match["_ALIAS"], P.Load())
            self.quals.add(qual)
        return []
    def visit_Compare(self, node):
        node = self.generic_visit(node)

        # Translate multiple comparisons into conjunctions of
        # each individual comparison.
        assert len(node.ops) == len(node.comparators) > 0
        if len(node.ops) > 1:
            conds = []
            values = [node.left] + list(node.comparators)
            for i in range(len(values) - 1):
                conds.append(
                    P.Compare(values[i], [node.ops[i]], [values[i + 1]]))
            node = P.BoolOp(P.And(), conds)

        return node
 def handle_fs_SYMCONFIG(self, _func, symbol: P.Str, **kargs):
     name = symbol.s
     d = {}
     for k, v in kargs.items():
         d[k] = P.literal_eval(v)
     self.info.symconfig_info.append((name, d))
     return ()
def preprocess_var_decls(tree):
    """Eliminate global variable declarations of the form
    
        S = Set()
        M = Map()
    
    and return a list of pairs of variables names and type names (i.e.,
    'Set' or 'Map').
    """
    assert isinstance(tree, P.Module)
    pat = P.Assign(
        [P.Name(P.PatVar("_VAR"), P.Wildcard())], P.Call(P.Name(P.PatVar("_KIND"), P.Load()), [], [], None, None)
    )

    decls = OrderedSet()
    body = []
    changed = False
    for stmt in tree.body:
        match = P.match(pat, stmt)
        if match is not None:
            var, kind = match["_VAR"], match["_KIND"]
            if kind not in ["Set", "Map"]:
                raise L.ProgramError("Unknown declaration initializer {}".format(kind))
            decls.add((var, kind))
            changed = True
        else:
            body.append(stmt)

    if changed:
        tree = tree._replace(body=body)
    return tree, list(decls)
 def handle_fs_SYMCONFIG(self, _func, symbol: P.Str, **kargs):
     name = symbol.s
     d = {}
     for k, v in kargs.items():
         d[k] = P.literal_eval(v)
     self.info.symconfig_info.append((name, d))
     return ()
 def visit_Expr(self, node):
     match = P.match(self.pat, node)
     if match is not None:
         query = P.Parser.pe(node.value.args[0].s)
         call = node.value._replace(args=[query])
         node = node._replace(value=call)
     return node
 def visit_Expr(self, node):
     match = P.match(self.pat, node)
     if match is not None:
         query = P.Parser.pe(node.value.args[0].s)
         call = node.value._replace(args=[query])
         node = node._replace(value=call)
     return node
    def visit_Assign(self, node):
        node = self.generic_visit(node)

        # Translate multiple assignments as a single statement
        # (e.g. "a = b = c") into sequential single assignments.
        if len(node.targets) > 1:
            stmts = []
            values = list(node.targets) + [node.value]
            for lhs, rhs in reversed(list(pairs(values))):
                rhs_load = P.ContextSetter.run(rhs, P.Load)
                stmts.append(P.Assign([lhs], rhs_load))
            node = stmts

        return node
    def visit_Import(self, node):
        pat = P.Import([P.alias('incoq.runtime', P.PatVar('_ALIAS'))])
        match = P.match(pat, node)
        if match is None:
            return node

        # Remove the import. Record the alias to remove its uses.
        if match['_ALIAS'] is not None:
            qual = P.Name(match['_ALIAS'], P.Load())
            self.quals.add(qual)
        return []
def postprocess_var_decls(tree, decls):
    """Prepend global variable declarations to the program. Each given
    declaration is a triple of a variable name, type name (e.g., 'Set'
    or 'Map'), and a declaration comment string.
    """
    assert isinstance(tree, P.Module)
    header = ()
    for var_name, type_name, comment in decls:
        header += P.Parser.pc('''
            COMMENT(_S)
            _VAR = _TYPE()
            ''',
                              subst={
                                  '_S': P.Str(comment),
                                  '_VAR': var_name,
                                  '_TYPE': type_name
                              })
    tree = tree._replace(body=header + tree.body)
    return tree
    def visit_Attribute(self, node):
        # Note: As written, this will remove all aliases, not just the
        # prefix alias. That is, if A is an alias for the runtime in
        # quals, this will rewrite A.A...A.foo as foo. This shouldn't
        # be a problem because we shouldn't see aliases chained in this
        # manner.

        node = self.generic_visit(node)

        # Check prefix against each alias and the fully qualified path.
        # If none match, no change.
        for qual in self.quals:
            pat = P.Attribute(qual, P.PatVar("_ATTR"), P.Load())
            match = P.match(pat, node)
            if match is not None:
                break
        else:
            return node

        return P.Name(match["_ATTR"], P.Load())
class QueryDirectiveRewriter(P.NodeTransformer):
    """Take QUERY(<source>, **<kargs>) directives and replace the
    first argument with the corresponding parsed Python AST.
    """

    # We'll use NodeTransformer rather than MacroProcessor because
    # MacroProcessor makes it hard to reconstruct the node.

    pat = P.Expr(
        P.Call(P.Name('QUERY', P.Load()), [P.Str(P.PatVar('_source'))],
               P.PatVar('_keywords'), None, None))

    def visit_Expr(self, node):
        match = P.match(self.pat, node)
        if match is not None:
            query = P.Parser.pe(node.value.args[0].s)
            call = node.value._replace(args=[query])
            node = node._replace(value=call)
        return node
    def visit_Attribute(self, node):
        # Note: As written, this will remove all aliases, not just the
        # prefix alias. That is, if A is an alias for the runtime in
        # quals, this will rewrite A.A...A.foo as foo. This shouldn't
        # be a problem because we shouldn't see aliases chained in this
        # manner.

        node = self.generic_visit(node)

        # Check prefix against each alias and the fully qualified path.
        # If none match, no change.
        for qual in self.quals:
            pat = P.Attribute(qual, P.PatVar('_ATTR'), P.Load())
            match = P.match(pat, node)
            if match is not None:
                break
        else:
            return node

        return P.Name(match['_ATTR'], P.Load())
    def suite_helper(self, node):
        node = self.generic_visit(node)

        if len(node.body) == 0:
            node = node._replace(body=[P.Pass()])
        return node
 def handle_fs_QUERY(self, _func, query, **kargs):
     d = {}
     for k, v in kargs.items():
         d[k] = P.literal_eval(v)
     self.info.query_info.append((query, d))
     return ()
 def handle_fs_CONFIG(self, _func, **kargs):
     d = {}
     for k, v in kargs.items():
         d[k] = P.literal_eval(v)
     self.info.config_info.append(d)
     return ()
def postprocess_header(tree, header):
    """Add comment lines for each string in header."""
    header = tuple(
        P.Parser.ps('COMMENT(_S)', subst={'_S': P.Str(line)})
        for line in header)
    return tree._replace(body=header + tree.body)
 def handle_fs_CONFIG(self, _func, **kargs):
     d = {}
     for k, v in kargs.items():
         d[k] = P.literal_eval(v)
     self.info.config_info.append(d)
     return ()
 def handle_fs_QUERY(self, _func, query, **kargs):
     d = {}
     for k, v in kargs.items():
         d[k] = P.literal_eval(v)
     self.info.query_info.append((query, d))
     return ()