'Return a CodeBlock with topologically sorted assignments so that
variables are assigned before they are used.
The existing order of assignments is preserved as much as possible.
This function assumes that variables are assigned to only once.
This is a class constructor so that the default constructor for
CodeBlock can error when variables are used before they are assigned.
Example
>>> from sympy import symbols
>>> from sympy.codegen.ast import CodeBlock, Assignment
>>> x, y, z = symbols(\'x y z\')
>>> assignments = [
...     Assignment(x, y + z),
...     Assignment(y, z + 1),
...     Assignment(z, 2),
>>> CodeBlock.topological_sort(assignments)
CodeBlock(Assignment(z, 2), Assignment(y, z + 1), Assignment(x, y + z))'

@classmethod
def topological_sort(cls, assignments):

    from sympy.utilities.iterables import topological_sort
    A = list(enumerate(assignments))
    var_map = {}
    E = []
    for i in A:
        if (i[1].lhs in var_map):
            E.append((var_map[i[1].lhs], i))
        var_map[i[1].lhs] = i
    for i in A:
        for x in i[1].rhs.free_symbols:
            if (x not in var_map):
                raise ValueError(('Undefined    variable    %s' % x))
            E.append((var_map[x], i))
    ordered_assignments = topological_sort([A, E])
    return cls(*list(zip(*ordered_assignments))[1])
