示例#1
0
def infer_Tuple_expr(tup, env):
    """
    Determine the type of AST `Tuple` expression under type environment `env`.

    `ast.Tuple`
      - `elts`: Python list of contained expr nodes
      - `ctx`: context of the expr (e.g., load, store)
    """

    assert tup.__class__ is ast.Tuple

    elts_list = tup.elts

    if all(infer_expr(e, env) != None for e in elts_list):

        # (tup) assignment rule.
        return PType.tuple([infer_expr(e, env) for e in elts_list])

    else:

        # No assignment rule found.
        return None
示例#2
0
def infer_Subscript_expr(subs, env):
    """
    Determine the type of AST `Subscript` expression under type environment
    `env`.

    `ast.Subscript`
      - `value`: the collection being subscripted
      - `slice`: `ast.Index` or `ast.Slice`
        + `value`: expr used as index (if `ast.Index`)
        + `lower`: expr used as lower bound (if `ast.Slice`)
        + `upper`: expr used as upper bound (if `ast.Slice`)
        + `step`: expr used as step (if `ast.Slice`)

    We can only subscript tuples with numeric literals because the inference
    algorithm needs to actually know the values of the subscript parameters.
    """

    assert subs.__class__ is ast.Subscript

    col = subs.value
    col_t = infer_expr(col, env)

    is_index = subs.slice.__class__ is ast.Index
    is_slice = subs.slice.__class__ is ast.Slice
    assert is_index or is_slice

    # Store the attributes of the slice.
    if is_index:
        i = subs.slice.value
    else:  # is_slice
        l = subs.slice.lower
        u = subs.slice.upper
        s = subs.slice.step

    if col_t is None:

        # If we can't assign a type to the collection, then we can't assign a
        # type to its subscript.
        return None

    # String subscripting
    elif col_t == str_t or col_t == unicode_t:

        if is_index and infer_expr(i, env) == int_t:

            # (sidx) assignment rule.
            return col_t

        elif is_slice and valid_int_slice(l, u, s, env):

            # (sslc) assignment rule.
            return col_t

        else:

            # No assignment rule found.
            return None

    # List subscripting
    elif col_t.is_list():

        if is_index and check.check_expr(i, int_t, env):

            # (lidx) assignment rule.
            return col_t.elt

        elif is_slice and valid_int_slice(l, u, s, env):

            # (lslc) assignment rule.
            return col_t

        else:

            # No assignment rule found.
            return None

    # Tuple subscripting
    elif col_t.is_tuple():

        col_ts = col_t.elts
        n = len(col_ts)

        if is_index and node_is_int(i) and -n <= i.n < n:

            # (tidx) assignment rule.
            return col_ts[i.n]

        elif is_slice:

            rng = slice_range(l, u, s, len(col_ts))

            if rng is not None:

                # (tslc) assignment rule.
                return PType.tuple([col_ts[i] for i in rng])

            else:

                # No assignment rule found.
                return None

        else:

            # No assignment rule found.
            return None

    else:

        # No assignment rule found.
        return None