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
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