Type Checking. Outline. General properties of type systems. Types in programming languages. Notation for type rules.

Similar documents
Outline. General properties of type systems. Types in programming languages. Notation for type rules. Common type rules. Logical rules of inference

Computer Science Department Carlos III University of Madrid Leganés (Spain) David Griol Barres

The Compiler So Far. CSC 4181 Compiler Construction. Semantic Analysis. Beyond Syntax. Goals of a Semantic Analyzer.

Intermediate Code Generation Part II

Type checking. Jianguo Lu. November 27, slides adapted from Sean Treichler and Alex Aiken s. Jianguo Lu November 27, / 39

Types. Type checking. Why Do We Need Type Systems? Types and Operations. What is a type? Consensus

Passing Out Review Forms

Overview of Semantic Analysis. Lecture 9

Scoping rules match identifier uses with identifier definitions. A type is a set of values coupled with a set of operations on those values.

LECTURE 3. Compiler Phases

Static Checking and Type Systems

CMSC 330: Organization of Programming Languages. Formal Semantics of a Prog. Lang. Specifying Syntax, Semantics

Intermediate Code Generation

Semantic Analysis and Type Checking

type environment updated subtype sound

CS558 Programming Languages

Type Checking. Error Checking

Semantic Analysis. Lecture 9. February 7, 2018

SEMANTIC ANALYSIS TYPES AND DECLARATIONS

Concepts Introduced in Chapter 6

CA Compiler Construction

CS558 Programming Languages

Type Checking. Chapter 6, Section 6.3, 6.5

Type systems. Static typing

Tail Calls. CMSC 330: Organization of Programming Languages. Tail Recursion. Tail Recursion (cont d) Names and Binding. Tail Recursion (cont d)

CMSC 330: Organization of Programming Languages

Type Inference Systems. Type Judgments. Deriving a Type Judgment. Deriving a Judgment. Hypothetical Type Judgments CS412/CS413

Formal Semantics of Programming Languages

COMP 181. Agenda. Midterm topics. Today: type checking. Purpose of types. Type errors. Type checking

Concepts Introduced in Chapter 6

The compilation process is driven by the syntactic structure of the program as discovered by the parser

Formal Languages and Compilers Lecture X Intermediate Code Generation

Syntax and Grammars 1 / 21

type environment updated subtype sound

CMSC 330: Organization of Programming Languages. Operational Semantics

7. Introduction to Denotational Semantics. Oscar Nierstrasz

Formal Semantics of Programming Languages

Writing Evaluators MIF08. Laure Gonnord

Formal Languages and Compilers Lecture IX Semantic Analysis: Type Chec. Type Checking & Symbol Table

The Substitution Model

CSE 413 Languages & Implementation. Hal Perkins Winter 2019 Structs, Implementing Languages (credits: Dan Grossman, CSE 341)

CSE450. Translation of Programming Languages. Lecture 11: Semantic Analysis: Types & Type Checking

Lexical Considerations

Lecture Outline. COOL operational semantics. Operational Semantics of Cool. Motivation. Lecture 13. Notation. The rules. Evaluation Rules So Far

Type checking of statements We change the start rule from P D ; E to P D ; S and add the following rules for statements: S id := E

Compiler Theory. (Semantic Analysis and Run-Time Environments)

Anatomy of a Compiler. Overview of Semantic Analysis. The Compiler So Far. Why a Separate Semantic Analysis?

Scoping and Type Checking

G Programming Languages Spring 2010 Lecture 6. Robert Grimm, New York University

Simply-Typed Lambda Calculus

Symbol Tables. For compile-time efficiency, compilers often use a symbol table: associates lexical names (symbols) with their attributes

Principles of Programming Languages

Semantic Analysis Type Checking

The role of semantic analysis in a compiler

CSCE 314 Programming Languages. Type System

5. Semantic Analysis!

In Our Last Exciting Episode

Semantic Analysis. How to Ensure Type-Safety. What Are Types? Static vs. Dynamic Typing. Type Checking. Last time: CS412/CS413

Lexical Considerations

Lecture 7: Type Systems and Symbol Tables. CS 540 George Mason University

Specifying Syntax. An English Grammar. Components of a Grammar. Language Specification. Types of Grammars. 1. Terminal symbols or terminals, Σ

Operational Semantics of Cool

Semantic Analysis. Outline. The role of semantic analysis in a compiler. Scope. Types. Where we are. The Compiler Front-End

Lecture 14 Sections Mon, Mar 2, 2009

Types and Static Type Checking (Introducing Micro-Haskell)

Lecture #23: Conversion and Type Inference

Crafting a Compiler with C (II) Compiler V. S. Interpreter

Begin at the beginning

CS1622. Semantic Analysis. The Compiler So Far. Lecture 15 Semantic Analysis. How to build symbol tables How to use them to find

Conversion vs. Subtyping. Lecture #23: Conversion and Type Inference. Integer Conversions. Conversions: Implicit vs. Explicit. Object x = "Hello";

UNIT II Structuring the Data, Computations and Program. Kainjan Sanghavi

Semantic Processing (Part 2)

Programming Languages Third Edition

The Substitution Model. Nate Foster Spring 2018

5. Syntax-Directed Definitions & Type Analysis

Informatica 3 Syntax and Semantics

Pierce Ch. 3, 8, 11, 15. Type Systems

CMSC 330: Organization of Programming Languages. Rust Basics

Induction and Semantics in Dafny

The Compiler So Far. Lexical analysis Detects inputs with illegal tokens. Overview of Semantic Analysis

Semantic Analysis. Outline. The role of semantic analysis in a compiler. Scope. Types. Where we are. The Compiler so far

G Programming Languages - Fall 2012

Operational Semantics. One-Slide Summary. Lecture Outline

Introduction to SML Getting Started

Acknowledgement. CS Compiler Design. Semantic Processing. Alternatives for semantic processing. Intro to Semantic Analysis. V.

Decaf Language Reference Manual

The PCAT Programming Language Reference Manual

Programming Languages and Compilers (CS 421)

CSE P 501 Compilers. Static Semantics Hal Perkins Winter /22/ Hal Perkins & UW CSE I-1

CMSC 330: Organization of Programming Languages. OCaml Expressions and Functions

CS 164 Handout 16. Final Examination. There are nine questions on the exam, some in multiple parts. You have 3 hours to work on the

1 Lexical Considerations

COMP520 - GoLite Type Checking Specification

Computing Fundamentals 2 Introduction to CafeOBJ

COS 320. Compiling Techniques

Lecture Overview. [Scott, chapter 7] [Sebesta, chapter 6]

CS 6353 Compiler Construction Project Assignments

Error Handling Syntax-Directed Translation Recursive Descent Parsing

Programming Languages

Outline. What is semantics? Denotational semantics. Semantics of naming. What is semantics? 2 / 21

Transcription:

Outline Type Checking General properties of type systems Types in programming languages Notation for type rules Logical rules of inference Common type rules 2 Static Checking Refers to the compile-time checking of programs in order to ensure that the semantic conditions of the language are being followed Examples of static checks include: Type checks Flow-of-control checks Uniqueness checks Name-related checks Static Checking (Cont.) Flow-of-control checks: statements that cause flow of control to leave a construct must have some place where control can be transferred; e.g., break statements in C Uniqueness checks: a language may dictate that in some contexts, an entity can be defined exactly once; e.g., identifier declarations, labels, values in case expressions Name-related checks: Sometimes the same name must appear two or more times; e.g., in Ada a loop or block can have a name that must then appear both at the beginning and at the end 3 4

Types and Type Checking A type is a set of values together with a set of operations that can be performed on them The purpose of type checking is to verify that operations performed on a value are in fact permissible Type Expressions and Type Constructors A language usually provides a set of base types that it supports together with ways to construct other types using type constructors Through type expressions we are able to represent types that are defined in a program The type of an identifier is typically available from declarations, but we may have to keep track of the type of intermediate expressions 5 6 Type Expressions A base type is a type expression A type name (e.g., a record name) is a type expression A type constructor applied to type expressions is a type expression. E.g., arrays: If T is a type expression and I is a range of integers, then array(i,t) is a type expression records: If T1,, Tn are type expressions and f1,, fn are field names, then record((f1,t1),,(fn,tn)) is a type expression pointers: If T is a type expression, then pointer(t) is a type expression functions: If T1,, Tn, and T are type expressions, then so is (T1,,Tn) T Notions of Type Equivalence Name equivalence: In many languages, e.g. Pascal, types can be given names. Name equivalence views each distinct name as a distinct type. So, two type expressions are name equivalent if and only if they are identical. Structural equivalence: Two expressions are structurally equivalent if and only if they have the same structure; i.e., if they are formed by applying the same constructor to structurally equivalent type expressions. 7 8

Example of Type Equivalence In the Pascal fragment type nextptr = ^node; prevptr = ^node; var p : nextptr; q : prevptr; p is not name equivalent to q, but p and q are structurally equivalent. Static Type Systems & their Expressiveness A static type system enables a compiler to detect many common programming errors The cost is that some correct programs are disallowed Some argue for dynamic type checking instead Others argue for more expressive static type checking But more expressive type systems are also more complex 9 10 Compile-time Representation of Types Need to represent type expressions in a way that is both easy to construct and easy to check Compile-time Representation of Types (Cont.) Example: var x, y : array[1..42] of integer; Approach 1: Type Graphs Basic types can have predefined internal values, e.g., small integer values Named types can be represented using a pointer into a hash table Composite type expressions: the node for f(t1,,tn) contains a value representing the type constructor f, and pointers to the nodes for the expressions T1,,Tn name type name type...... x y type dimensions bounds elem type array 1 integer 1 42 11 12

Compile-Time Representation of Types Approach 2: Type Encodings Basic types use a predefined encoding of the low-order bits BASIC TYPE ENCODING boolean 0000 char 0001 integer 0002 The encoding of a type expression op(t) is obtained by concatenating the bits encoding op to the left of the encoding of T. E.g.: TYPE EXPRESSION ENCODING char 00 00 00 0001 array(char) 00 00 01 0001 ptr(array(char)) 00 10 01 0001 ptr(ptr(array(char))) 10 10 01 0001 Compile-Time Representation of Types: Notes Type encodings are simple and efficient On the other hand, named types and type constructors that take more than one type expression as argument are hard to represent as encodings. Also, recursive types cannot be represented directly. Recursive types (e.g. lists, trees) are not a problem for type graphs: the graph simply contains a cycle 13 14 Types in an Example Programming Language Let s assume that types are: integers & floats (base types) arrays of a base type booleans (used in conditional expressions) The user declares types for all identifiers The compiler infers types for expressions Infers a type for every expression Type Checking and Type Inference Type Checking is the process of verifying fully typed programs Type Inference is the process of filling in missing type information The two are different, but are often used interchangeably 15 16

Rules of Inference We have seen two examples of formal notation specifying parts of a compiler Regular expressions (for the lexer) Context-free grammars (for the parser) The appropriate formalism for type checking is logical rules of inference Why Rules of Inference? Inference rules have the form If Hypothesis is true, then Conclusion is true Type checking computes via reasoning If E 1 and E 2 have certain types, then E 3 has a certain type Rules of inference are a compact notation for If-Then statements 17 18 From English to an Inference Rule The notation is easy to read (with practice) Start with a simplified system and gradually add features Building blocks Symbol is and Symbol is if-then x:t is x has type T From English to an Inference Rule (2) If e 1 has type int and e 2 has type int, then e 1 + e 2 has type int (e 1 has type int e 2 has type int) e 1 + e 2 has type int (e 1 : int e 2 : int) e 1 + e 2 : int 19 20

From English to an Inference Rule (3) The statement (e 1 : int e 2 : int) e 1 + e 2 : int is a special case of Hypothesis 1... Hypothesis n Conclusion Notation for Inference Rules By tradition inference rules are written Hypothesis 1 Hypothesis n Conclusion This is an inference rule Type rules have hypotheses and conclusions of the form: e : T means it is provable that... 21 22 Two Rules Two Rules (Cont.) i is an integer i : int [Int] These rules give templates describing how to type integers and + expressions By filling in the templates, we can produce complete typings for expressions e 1 : int e 1 + e 2 : int e 2 : int [Add] 23 24

Example: 1 + 2 Soundness A type system is sound if Whenever e : T Then e evaluates to a value of type T 1 is an integer 2 is an integer 1 : int 2 : int 1 + 2 : int We only want sound rules But some sound rules are better than others: i is an integer i : number 25 26 Type Checking Proofs Type checking proves facts e: T Proof is on the structure of the AST Proof has the shape of the AST One type rule is used for each kind of AST node In the type rule used for a node e: Hypotheses are the proofs of types of e s subexpressions Conclusion is the type of e Types are computed in a bottom-up pass over the AST Rules for Constants [Bool] true : bool false : bool f is a floating point number [Float] f : float [Bool] 27 28

Two More Rules A Problem What is the type of a variable reference? e : bool not e : bool [Not] x is an identifier x :? [Var] e 1 : bool e 2 : T while e 1 do e 2 : T [While] The local, structural rule does not carry enough information to give x a type 29 30 A Solution Put more information in the rules! Type Environments Let E be a function from Identifiers to Types A type environment gives types for free variables A type environment is a function from Identifiers to Types A variable is free in an expression if it is not defined within the expression The sentence E e : T is read: Under the assumption that variables have the types given by E, it is provable that the expression e has the type T 31 32

Modified Rules The type environment is added to the earlier rules: New Rules And we can now write a rule for variables: i is an integer E i : int [Int] E(x) = T E x : T [Var] E e 1 : int E e 2 : int E e 1 + e 2 : int [Add] 33 34 Type Checking of Expressions Type Checking of Expressions (Cont.) Production E id Semantic Rules { if (declared(id.name)) then E.type := lookup(id.name).type else E.type := error(); } E int { E.type := integer; } E E1 + E2 { if (E1.type == integer AND E2.type == integer) then E.type := integer; else E.type := error(); } May have automatic type coercion, e.g. E1.type E2.type E.type integer integer integer integer float float float integer float float float float 35 36

Type Checking of Statements: Assignment Type Checking of Statements: Loops, Conditionals Semantic Rules: Semantic Rules: S Lval := Rval {check_types(lval.type,rval.type)} Loop while E do S {check_types(e.type,bool)} Note that in general Lval can be a variable or it may be a more complicated expression, e.g., a dereferenced pointer, an array element, a record field, etc. Type checking involves ensuring that: Lval is a type that can be assigned to, e.g. it is not a function or a procedure the types of Lval and Rval are compatible, i.e, that the language rules provide for coercion of the type of Rval to the type of Lval Cond if E then S1 else S2 {check_types(e.type,bool)} 37 38