def valid_tar(t): if t.__class__ is ast.Subscript: col_t = infer_expr(t.value, env) sub_of_tup = col_t and col_t.is_tuple() else: sub_of_tup = False t_t = infer_expr(t, env) return t_t and check_expr(v, t_t, env) and not sub_of_tup
def _check_AugAssign_stmt(stmt, env): """Augmented Assignment.""" assert stmt.__class__ is ast.AugAssign e0 = stmt.target op = stmt.op e1 = stmt.value e0_t = infer_expr(e0, env) # (Aug-Assmt) assignment rule. -- restricted by type inference return e0_t and check_expr(ast.BinOp(e0, op, e1), e0_t, env)
def _check_Subscript_expr(subs, t, env): """Subscription.""" assert subs.__class__ is ast.Subscript c = subs.value s = subs.slice # Type inference is necessary off the bat; these rules are the polar # opposite of syntax direction. c_t = infer_expr(c, env) if not c_t: return False # Indexing. if s.__class__ is ast.Index: e = s.value # (Str-Idx) assignment rule. if c_t == str_t or c_t == unicode_t: return c_t == t and check_expr(e, int_t, env) # (Lst-Idx) assignment rule. elif c_t.is_list(): return t == c_t.elt and check_expr(e, int_t, env) # (Tup-Idx) assignment rule. elif c_t.is_tuple(): n = len(c_t.elts) return node_is_int(e) and -n <= e.n < n and c_t.elts[e.n] == t # Slicing. elif s.__class__ is ast.Slice: e0, e1, e2 = s.lower, s.upper, s.step # (Flat-Slc) assignment rule. if c_t == str_t or c_t == unicode_t or c_t.is_list(): return c_t == t and valid_int_slice(e0, e1, e2, env) # (Tup-Slc) assignment rule. elif c_t.is_tuple() and ((not e0 or node_is_int(e0)) and (not e1 or node_is_int(e1)) and (not e2 or node_is_None(e2) or node_is_int(e2))): rng = slice_range(e0, e1, e2, c_t.tuple_len()) return (t.is_tuple() and rng and len(rng) == t.tuple_len() and all(c_t.elts[j] == t.elts[i] for (i,j) in enumerate(rng))) # No assignment rule found return False
def _check_For_stmt(stmt, env): """For Loop.""" assert stmt.__class__ is ast.For x = stmt.target e = stmt.iter b0 = stmt.body b1 = stmt.orelse x_t = infer_expr(x, env) # (For) assignment rule. -- restricted by type inference return (x_t and check_expr(e, PType.list(x_t), env) and check_stmt_list(b0, env) and check_stmt_list(b1, env))
# FIXME: this is copied from unit_test_core, should be abstracted # away somewhere, but don't know the best way to deal with logging. with open(file_name, 'r') as f: text = f.read() untyped_ast = ast.parse(text) typedecs = parse_type_decs(file_name) typed_ast = TypeDecASTModule(untyped_ast, typedecs) if check_mod(typed_ast.tree): print "Typechecked correctly!" else: print "Did not typecheck." except IOError as e: print "File not found: %s" % e.filename elif opt.expr and opt.type and not opt.filename and not opt.infer_expr: e = ast.parse(opt.expr).body[0].value t = PType.from_str(opt.type) template = ("YES! -- %s typechecks as type %s" if check_expr(e, t, {}) else "NO! --- %s does not typecheck as type %s") print template % (opt.expr, t) elif opt.infer_expr and not opt.filename and not opt.expr and not opt.type: e = ast.parse(opt.infer_expr).body[0].value print "%s -- is the inferred type of %s" % (infer_expr(e, {}), opt.infer_expr) else: parser.print_help()
try: # FIXME: this is copied from unit_test_core, should be abstracted # away somewhere, but don't know the best way to deal with logging. with open(file_name, 'r') as f: text = f.read() untyped_ast = ast.parse(text) typedecs = parse_type_decs(file_name) typed_ast = TypeDecASTModule(untyped_ast, typedecs) if check_mod(typed_ast.tree): print "Typechecked correctly!" else: print "Did not typecheck." except IOError as e: print "File not found: %s" % e.filename elif opt.expr and opt.type and not opt.filename and not opt.infer_expr: e = ast.parse(opt.expr).body[0].value t = PType.from_str(opt.type) template = ("YES! -- %s typechecks as type %s" if check_expr(e, t, {}) else "NO! --- %s does not typecheck as type %s") print template % (opt.expr, t) elif opt.infer_expr and not opt.filename and not opt.expr and not opt.type: e = ast.parse(opt.infer_expr).body[0].value print "%s -- is the inferred type of %s" % (infer_expr(e, {}), opt.infer_expr) else: parser.print_help()