Лекция 9 Cистемы типов, проверка типов. Вопросы 1) a = b ? 1.0 : 2; Какой тип имеет третий операнд ● ● в языке С? в языке Java? 2) int a, b; ... (a+1)*(b+1.0) Какой тип у этого выражения? Системы типов алгебра Система типов - алгебра < Types, =, ≤ > Types – множество (носитель) = ⊂ Types2 эквивалентность типов (симм, транзит) ≤ ⊂ Types2 - приводимость типов (частичный порядок) Должно выполнятся: = ⊆ ≤ ! отношение “=“ может быть нерефлексивным ! система типов одно из главных свойств языка Системы типов интерпретация Пусть Names – множество констант (0-местных ф. символов) Система типов задается при помощью следующих конструкций: 1. множество типовых термов TypeExpr<Names> 2. функция именования типов name: Names → TypeExpr< Names> (TypeExpr<Names> - множество термов с использованием Names ) Системы типов типовые термы Множество типовых термов TypeExpr<Names> содержит следующие подмножества: 1. базовые типы BasicTypes – конечное множество констант BasicTypes ⊂ TypeExpr<Names> Причем, BasicTypes ∩ Names = ∅ int, float, char INTEGER, REAL, CHAR Пусть TN =def TypeExpr<Names> ∪ Names Системы типов типовые термы 2. ссылочные типы pointer(t), t ∈TN {pointer(t) | t ∈TN} ⊂ TypeExpr<Names> Терм Примеры pointer(int) int*, POINTER TO INTEGER Системы типов типовые термы 3. типы массивов array(n, t) n∈ℕ – длина t ∈TN – тип элемента {array(n, t) | t ∈TN, n∈ℕ} ⊂ TypeExpr<Names> Терм Пример array (2, array (3,char)) char[2][3] Что означает array(0, t)? Системы типов типовые термы 4. типы записей record(t1, , ... , tk), k≥0 ti – типы полей, ti ∈TN {record(t1, , ... , tk) |ti ∈TN, k≥0} ⊂ TypeExpr<Names> Терм Пример record (int, char) struct { int a; char b;} Системы типов типовые термы 5. типы функций func(t1, ... , tk, tk+1), k≥0, ti ∈TN ti – типы аргументов (при k>0) tk+1 – тип возвращаемого значения поля {func(t1, , ... , tk) |ti ∈TN, k≥0} ⊂ TypeExpr<Names> Терм Пример func(int, char) char (*foo)(int) PROCEDURE (INTEGER):CHAR Системы типов типовые термы 6. типы процедур proc(t1, ... , tk), k≥0, ti ∈TN ti – типы аргументов (при k>0) {proc(t1, , ... , tk) |ti ∈TN, k≥0} ⊂ TypeExpr<Names> Терм Пример proc(MyType, char) void (*foo)(Mytype, char) PROCEDURE (MyType, CHAR) Системы типов интерпретация < Types, =, ≤ > Носитель изоморфен множеству типовых термов и имен Types ≈ TypeExpr<Names> ∪ Names Отношение “=“ индуцируется функцией name: Names → TypeExpr< Names> и определением языка Отношение “≤“ задается правилом = ⊆ ≤ и определением языка Вопрос Пусть ≡ =def {< t, t > | t ∈Types} Всегда ли выполнено ≡ ⊆ = в существующих языках программирования? Системы типов Пример 1. struct L {int v; L* next;} Names = { L } Types ⊃ {int, pointer(L), record (int, pointer(L)), L} name(L) = record (int, pointer(L)) ! Этот тип не определяется без функции именования Пример 2. Язык C int* a; int* b; Системы типов Язык Modula-2 (or any Wirth's language) VAR a :POINTER TO INTEGER; b :POINTER TO INTEGER; Интерпретация эквивалентности типов различна Язык C τ(a) = τ(b) Язык Modula-2 (or any Wirth's language) τ(a) ≠ τ(b) однако ≡ | Names ⊆ = ! Структурная и именная эквивалентности Задачи 1. Какие типы и имена задаются определением typedef struct StructD { int f; } *D; Как они связаны между собой? 2. Для каких типов используется структурная, а для каких именная эквивалентность в языках -С - Java ? Системы типов ≤ задает правила преобразования типов t1 приводИм к t2 ⇔def t1 ≤ t2 или t2≤ t1 Расширение типа t1→ t2 если t1 ≤ t2 Сужение типа t1→ t2 если t2≤ t1 Пример 3. Язык C char ≤ int Язык Modula-2 (or any Wirth's language) CHAR и INTEGER неприводимы Семантический блок Транслятор выполняет: ● назначение типов переменным, выражениям, функциям, ... int* a ● (a+b) int foo (char* p, int q) проверки совместимости (эквивалентности) типов int a = b; ● foo (str, 1) расстановку неявных преобразований типов double a = b ? 1.0 : 2 ● идентификацию переменных foo (str, 1) foo (1.0) Проверка типов ! Встроенные типы создаются заранее (таблица имен) Назначение типов делается во время синтаксического анализа (семантические действия при разборе): ● ● при успешном разборе определения нового типа или описания переменной/функции, соответствующие типы заносятся в таблицу имен при описании переменных/функций с ними связывается тип VarDecl → TypeExpr {Identifiers.i = TypeExpr.s} Identifiers ; ● при разборе выражений/операторов все вершины дерева типизируются Проверка типов Принцип проверки совместимости типов – выбор отношения эквивалентности = ⊂ Types2 Возможная реализация (структурная эквивалентность): 1. ≡ ⊂ = (графическое совпадение) 2. name* ⊂ = (симметричное замыкание именования) 3. конгруенция термов из Types: f(t1, ...., tk) = g(q1, ...., qk) ⇔def f ≡ g и ∀i. ti = qi Проверка типов Пример. typedef struct L {int a, b;} *p2L; typedef p2L* bufL; bufL qq, L** pp; pp = qq; //совместим ли bufL с L** ? Здесь определяются имена { L, p2L, bufL }: name(L) = record (int, int); name(p2L) = pointer(L); name(bufL) = pointer(p2L); Проверка bufL = pointer(pointer(L) по правилам 1-3: bufL pointer(p2L) p2L pointer(L) pointer(pointer(L)) pointer(pointer(L)) pointer(L) pointer(L) (2) (3) (2) (1) Проверка типов Расстановка неявных преобразований типов (атрибутная генерация или отдельный проход) double a = b ? 1.0 : 2 Assign a / \ cOper / | \ b 1.0 2 ! int ≤ double Assign / a \ cOper / | \ b 1.0 int2double \ 2 Системы типов заключительные замечания ! Развитие систем типов – одно из основных направлений эволюции языков программирования Актуальные проблемы разработки и реализации новых языков программирования (PLDI challenges): ● ● повышение гибкости системы типов без ущерба для надежности повышение надежности без ущерба для производительности* ____________________________________________________ *эта задача рассматривается в следующей части спецкурса Задачи 1. Как нужно расширить типовую систему для языков - с наследованием типов - с параметризованными типами ? 2. Как нужно изменить типовую систему для введения C-like типа void ? 3. Нужно ли решать задачу 2?