Interpretação e Compilação de Linguagens de Programação Sistemas de tipos

Documentos relacionados
Interpretação e Compilação de Linguagens de Programação Semântica CALCI com Ambiente

Interpretação e Compilação de Linguagens de Programação Abstração Funcional

Interpretação e Compilação de Linguagens de Programação Ligação e âmbito

ao paradigma imperativo

Introdução à Geração de Código

Linguagem de Programação e Compiladores

Trabalhos de Laboratório de Interpretação e Compilação de Linguagens de Programação

Conceitos de Linguagem de Programação - 2

Linguagens de Programação

Trabalho de Desenho de Linguagens de Programação e de Compiladores. Mini Pascal

Linguagens de Programação

SEMÂNTICA. Rogério Rocha. rode = program simples = var x : int := 3 in x := x + 5 end.

Teoria da Computação e Algoritmos. Introdução à Linguagem Pascal. ALGORITMO <Nome do algoritmo>; <definições>; INÍCIO <Comandos>; FIM.

Compiladores Ambiente de Execução

Nomes, Amarração, Verificação de Tipos, e Escopo

Conceito de Linguagens de Programação - 1

Nomes, vinculações e escopos

Sistemas de Tipos. Prof. Alberto Costa Neto Linguagens de Programação. Departamento de Computação Universidade Federal de Sergipe

FACULDADE BATISTA MINEIRA - CST Banco de Dados Estruturas de Dados - Variáveis

Compiladores Análise Semântica

Nomes, vinculações e escopos

Linguagens de Programação. Marco A L Barbosa

Expressões e sentença de atribuição

Compiladores Análise de Tipos

Análise Semântica e Representação Intermédia

Compiladores Análise de Tipos

Implementação de Linguagens

PLANO DE UNIDADE DIDÁTICA- PUD

Compiladores Geração de Código

Sistemas de Tipos. Cristiano Damiani Vasconcellos.

Introdução à Programação. Uma Abordagem Funcional

PROGRAMAÇÃO de COMPUTADORES: LINGUAGEM FORTRAN 90/95

Compiladores Análise Semântica

13 a Aula - Instruções Condicionais. Ciclos. Pré-processador. Variáveis de ambiente. Mestrado em Engenharia Física Tecnológica

Linguagens de Programação

Análise semântica. Função, interação com o compilador Tabela de símbolos Análise semântica. Prof. Thiago A. S. Pardo

Análise Semântica e Tratamento de Erros Dependentes de Contexto

MAC 0316/5754 Conceitos de Linguagens de Programação Primeiro Semestre de 2011 Terceira Prova 21 de junho de 2011

Introdução a Computação

Implementação de Linguagens

Análise Sintática (Cap. 04) Análise Sintática Ascendente Analisador Sintático LR

Tipos Algébricos. Programação Funcional. Capítulo 11. José Romildo Malaquias Departamento de Computação Universidade Federal de Ouro Preto

Trabalho de Linguagens Formais e Compilação

Lista de Linguagens de Programação 7

Capítulo 7. Expressões e Sentenças de Atribuição

Compiladores Ambiente de Execução

Análise Semântica e Representação Intermédia

02. [Sebesta, 2000] Qual é o perigo potencial dos nomes que fazem distinção entre maiúsculas e minúsculas?

Erros de Tipo em Pascal Simplifificado

Paradigmas de Programação

Pascal. -Cabeçalho do programa. - label - const - type - var - procedure - function. - integer - real - byte - boolean - char - string

Introdução à Programação uma Abordagem Funcional

Conceitos de Linguagens de Programação

Programação Funcional 14 a Aula Classes de tipos revisitadas

I1, I2 e In são instruções simples ou estruturadas da linguagem Pascal.

Linguagens de Programação Conceitos e Técnicas. Amarrações Prof. Tiago Alves de Oliveira

SEMÂNTICA 02/09/2013. Conceitos de LPs - Semântica

Capítulo 8. Estruturas de Controle no Nível de Sentença

Introdução à Programação em C

Puca Huachi Vaz Penna

Compiladores Análise de Tipos

Aula 3: Algoritmos: Formalização e Construção

Pedro Vasconcelos DCC/FCUP. Programação Funcional 14 a Aula Um verificador de tautologia

Processamento da Informação Teoria. Desvio Condicional

ENGENHARIA DE PRODUÇÃO ICC 1 TÉCNICAS DE PROGRAMAÇÃO

Introdução à Programação. Conceitos Básicos de Orientação a Objetos

Primeiro Trabalho de IA/SI: Buscas. Entrega: 03/03/2019 (2 semanas)

Paradigmas de Linguagens de Programação. Nomes, Vinculações, Verificação de Tipos e Escopos

Semântica Operacional

Compiladores Análise de Tipos

Linguagens de Programação

Sintaxe e Semântica. George Darmiton da Cunha Cavalcanti.

Linguagens de Programação Conceitos e Técnicas. Amarrações

CAP. VI ANÁLISE SEMÂNTICA

Compilação da linguagem Panda

Lista de Linguagens de Programação 16

Tipo. Tipo de uma variável: especificação de

Linguagens de Programação Funcional

Java Básico. Carga Horária: 32 horas. Pré-requisito: Lógica de Programação; JAVA. Conteúdo Programático

Teoria e Implementação de Linguagens Computacionais. Especificação do projeto da disciplina (2006.1) Versão de 23/08/2006.

PRIMEIRA AVALIAÇÃO IDENTIFICAÇÃO. Nome: ID: 25/04/2005. PARTE I Questões Objetivas

Algoritmos I Aula 13 Linguagem de Programação Java

Programação de Computadores II

Nome do aluno: Assinatura: N ō USP: 1. Preencha o cabeçalho acima. 2. Não destaque as folhas deste caderno.

Texto retirado e adaptado da apostila Curso de Linguagem Pascal, disponível no site (autor: desconhecido).

Programação em C. Variáveis e Expressões. Universidade Federal do Rio Grande do Norte Departamento de Engenharia de Computação e Automação

UNIVERSIDADE FEDERAL RURAL DO SEMI-ÁRIDO CURSO: CIÊNCIA DA COMPUTAÇÃO. Prof.ª Danielle Casillo

Analise Semântica. Simão Melo de Sousa

Linguagem Algorítmica OO. Linguagem Algorítmica

Interpretação e Compilação de Linguagens de Programação Sintaxe e Semântica

Linguagens de Programação Aula 11

Introdução à Programação Aula 03. Prof. Max Santana Rolemberg Farias Colegiado de Engenharia de Computação

Primeira Prova de Linguagens de Programação - DCC024 -

Métodos formais. Especificação Formal. Aceitação de métodos formais. O uso de métodos formais. Especificação e projeto

Processamento da Informação

Computação I. Prof. Miguel Elias Mitre Campista.

4. Constantes. Constantes pré-definidas

Programação I Aula 19 Aritmética com racionais Pedro Vasconcelos DCC/FCUP

Compiladores Análise Semântica

Transcrição:

Interpretação e Compilação de Linguagens de Programação Sistemas de tipos 26 de Abril de 2013 1 Introdução A função de interpretação de uma linguagem de programação é normalmente uma função parcial, o que quer dizer que há programas para os quais não é possível computar uma denotação. Neste caso, os programas para os quais a semântica operacional não está definida correspondem a erros de execução. Os erros de execução correspondem normalmente à aplicação de uma qualquer operação primitiva a operans que não estão no seu mínio. Por exemplo a adição inteira entre um valor inteiro e um fecho (closure), ou a conjunção entre um valor boleano e um valor inteiro, ou a divisão de um número inteiro por zero (0). As linguagens ditas tipificadas incluem na sua definição um mecanismo de verificação de programas que rejeita programas que potencialmente possam gerar uma classe de erros de execução. Numa linguagem como o Java não é possível executar um programa que por exemplo, invoque um méto não existente ou que use um valor inteiro como se fosse um vector ou um qualquer objeto. Não é possível num programa em C ou Pascal, usar um nome que não tenha antes si declara e para o qual tenha si identifica o seu tipo. Estas situações são comuns em linguagens ditas não tipificadas ou tipificadas dinamicamente, como o Ruby, Python, JavaScript entre outras. O mecanismo de que falamos é um sistema de tipos, um programa que analisa outro programa sem o executar (literalmente) e que avalia a segurança da aplicação das operações que o programa encerra. Tratam-se de ferramentas de análise estática de código, que na realidade são funções de interpretação que trabalham com mínios mais abstratos. Uma característica importante é que o seu processamento termina para tos os programas possíveis das como entrada. Se considerarmos o programa seguinte da linguagem CALCState: 1 decl 2 a = newvar (0) 1

3 b = newvar (2) 4 c = newvar (a > b) 5 in 6 if c then 7!a :=!a + 1; 8 c := 1 <!c 9 end Podemos verificar que há alguns pontos onde o programa pode incorrer num erro de execução. Linha 4, comparação de duas referências, linha 6, condição if com uma referência, linha 7, afetação de uma não referência. Sen possível a identificação antecipada destes erros, seria possível produzir o programa sem erros de execução: 1 decl 2 a = newvar (0) 3 b = newvar (2) 4 c = newvar (!a >!b) 5 in 6 if!c then 7 a :=!a + 1; 8 c := 1 <!a 9 end Definimos então uma função de interpretação de programas abertos da linguagem CALCState para denotações conjunto Type. typecheck : CALCState ENV Type Define-se o conjunto Type da seguinte maneira (recursiva): Type {IntType, BoolType} {RefType(T ) T Type} {None} Este conjunto contém o elemento IntType que representa tos os números inteiros, o elemento BoolType que representa tos os valores boleanos, e para cada tipo T, o conjunto de elementos RefType(T) que representam todas as referências que contenham valores tipo T. Assim, a expressão var(0) tem a denotação RefType(IntType) (dada pela função typecheck), e a expressão!x tem a denotação IntType, que corresponde a um valor inteiro durante a execução, num ambiente onde x tem a denotação RefType(IntType) e em tempo de execução corresponde a uma variável conten valores inteiros. A função de interpretação trabalha num mínio abstrato, de forma sincronizada com o mínio concreto da função de interpretação eval. Assim, quan a denotação de uma expressão, dada pela função typecheck é IntType, a denotação dada pela função eval é um número inteiro ( conjunto Integer). Uma condição essencial desenho da semântica operacional e semântica de tipos de uma linguagem de programação é esta sincronização. É a condição 2

data Type = IntType BoolType RefType Type deriving (Eq, Show) Figura 1: Tipo de das typecheck (Num n) env = return IntType typecheck (Add e e ) env = t <- typecheck e env case t,t of IntType, IntType -> return IntType _,_ -> return None Figura 2: Verificação de tipos que torna a linguagem (e o seu sistema de tipos) coerente. A função typecheck é uma função total, atribuín uma denotação a tos os programas da linguagem CALC (ou seja não há erros de execução na computação tipo). A denotação None corresponde a um programa para o qual não se consegue determinar de forma abstrata o tipo resulta, ou seja, que durante a sua execução poderá incorrer num erro de execução. Diz-se que a análise estática, feita pelo sistema de tipos é conservativa, o que quer dizer que há programas mal tipificas (com tipo None) cuja execução não terminará com um erro. A definição da função typecheck faz-se de maneira composicional, e para algumas construções da linguagem CALC são definidas pela listagem da Figura 2. Note-se que a tipificação da operação Add tem como condição os operares serem de tipo inteiro. Se tal não acontecer, a denotação é None. 1.1 Declaração de Identificares A semântica de tipos da linguagem com declaração de identificares é tratada da mesma forma que a semântica operacional. É usa um ambiente que mantém as denotações s nomes livres da expressão a ser tipificada. Assim, o ambiente utiliza mapeia identificares em tipos, e a assinatura Haskell da função typecheck é: typecheck :: CalcState -> Env Type -> MaybeMessage Type E a semântica para as duas construções Id e decl são as mostradas na Figura 3. 3

typecheck (Id x) env = case find x env of Just v -> Result v Nothing -> Message ("Identifier "++x++ " not found.") typecheck (Decl x e e ) env = typecheck e (assoc env x t) Figura 3: Verificação de tipos com declaração de identificares. 1.2 Variáveis A tipificação da extensão desta linguagem para a manipulação de variáveis é mostrada na Figura 4. Nestes casos é visível mais um compromisso que é toma no nível de interpretação mais abstrato, tornan a análise conservara. É considera o invariante da análise que uma variável só pode conter valores de um único tipo. Note-se que as condições impostas na verificação de tipos são as suficientes para garantir a ausência de erros de execução nestas operações. Nomeadamente que uma afetação só é feita para uma referência, em que o tipo conteú coincide com o tipo previsto para a variável; a desreferenciação também só pode ser feita a uma referência. 2 Expressões de Controlo Na tipificação das estruturas de controlo (if, while) (Figura 5) há is comentários a fazer. O primeiro é que a tipificação de uma expressão condicional (if) verifica os is ramos da expressão (em vez de visitar apenas um como na semântica operacional). Isto deve-se a ser feito sobre numa situação em que não se sabe qual s ramos vai ser avalia em tempo de execução. No caso while, é que a verificação é feita uma só vez, e não é visita um número indetermina de vezes como o pode ser na semântica operacional. No caso if, há uma condição menos óbvia a impôr, que os resultas s is ramos sejam mesmo tipo. Mais uma vez, trata-se de uma aproximação conservara aos resultas possíveis para a expressão. 3 Tipos funcionais O tipo s valores funcionais (closures) descreve quer o tipo parâmetro que o tipo resulta. O tipo de uma função funciona como um contrato, se a função for aplicada a um valor tipo parâmetro, então o resulta será garantidamente tipo de resulta atribuí. 4

typecheck (Var e) env = return (RefType t); typecheck (Deref e) env = case t of RefType t -> return t _ -> Message "Dereferencing a non-reference value." typecheck (Assign e e ) env = t <- typecheck e env case t of RefType t t == t -> return t RefType _ -> Message "Type mismatch on assignment." _ -> Message "Assigning a non-reference value." Figura 4: Verificação de tipos com variáveis. Para determinar o tipo de uma função é necessário tipificar a sua definição. Trata-se da tipificação corpo da função num ambiente onde o identificar (parâmetro) é associa ao tipo parâmetro (ver figura 6). A tipificação da aplicação resume-se a garantir que o parâmetro e o argumento coincidem em tipo. Note-se que o corpo da função é tipifica apenas uma vez, e na sua declaração. Ao contrário da semântica operacional que visita o corpo da função na aplicação. A aplicação é tipificada sem conhecer a implementação concreta da função e apenas o seu tipo. Note-se que a sintaxe abstrata da definição da função é extendida com uma anotação de tipo. A sintaxe concreta terá que incluir essa anotação, ou seja fun x : t -> e. 4 Outros Tópicos Outros tópicos ainda referis nas aulas foram a inferência de tipos, com um algoritmo de tipificação associa a um algoritmo de unificação implementa por union-find, e ainda a produção de uma AST anotada com os tipos das expressões intermédias de mo a auxiliar no processo de compilação. Os ficheiros que mostram os detalhes podem ser encontras na página da 5

typecheck (If e e e ) env = t_cond <- typecheck e env t_then <- typecheck e env t_else <- typecheck e env case t_cond of BoolType t_then == t_else -> return t_then BoolType -> Message "Type mismatch on conditional branches." _ -> Message "Not a Bool value in if condition." typecheck (While e e ) env = t_cond <- typecheck e env t_body <- typecheck e env case t_cond of BoolType -> return BoolType _ -> Message "Not a Bool value in while condition." Figura 5: Verificação de tipos com controlo. cadeira (infer.ml, e CalcStateComp.hs). 6

typecheck (Fun x t_p e) env = t_r <- typecheck e (assoc env x t_p) return (FunType t_p t_r) typecheck (Call e e ) env = t_f <- typecheck e env t_a <- typecheck e env case t_f of FunType t_p t_r t_p == t_a -> return t_r _ -> Message "Not a function type value." Figura 6: Verificação de tipos com funções. 7