Definição de tipos - LF3 PLP - Apresentação 1 Equipe Felype Santiago Maria Carolina Paola Accioly Rodrigo Cardoso Conceitos básicos Projeto Projeto Estender a LF3 com características de Haskell Definição de tipos Tipos enumerados Tipos complexos Tipos recursivos Tipos Enumerados Tipo definido por uma quantidade finita de construtores. Em Haskell: data Bool = True | False data Estacao = Inverno | Verao | Outono | Primavera data Temp = Frio | Quente Tipos Complexos Tipo definido através do uso de outras definições. Em Haskell: type type type type String Name Address Person = = = = [Char] String None | Addr String (Name, Address) Tipos Recursivos Tipo definido através do uso da própria definição. Em Haskell: data Tree a = Leaf a | Branch (Tree a) (Tree a) Branch :: Tree a -> Tree a -> Tree a Leaf :: a -> Tree a Apresentação – Parte 1 Projeto (parte 1) Estender a LF3 com características de Haskell Definição de tipos (estender a LF3) Tipos enumerados Tipos complexos Tipos recursivos Tipos Enumerados (LF4) Definição dos tipos type Bool = {True, False} type Temp = {Frio,Quente} type diasDaSemana = {dom, seg, ter, qua, qui, sex, sab} Type meses = {jan, fev, mar, abr, mai, jun, jul, ago, set, out, nov, dez} Tipos Enumerados (LF4) Utilização dos tipos definidos Função NEXT: retorna o elemento declarado imediatamente depois do enum passado como parâmetro. Exemplo: type diasUteis = {seg, ter, qua, qui, sex} next(ter) = qua Função PREVIOUS : retorna o elemento declarado imediatamente depois do enum passado como parâmetro. Exemplo: type diasUteis = {seg, ter, qua, qui, sex} previous(sex) = qui Tipos Enumerados (LF4) Utilização dos tipos definidos (cont.) Função ORD: retorna a posição em que o elemento passado como parâmetro foi declarado (o primeiro elemento ocupa a posição 0). Exemplo: type diasUteis = {seg, ter, qua, qui, sex} ord(qui) = 3 Algumas observações... (LF4) Nenhuma variável pode ser declarada com o nome de um instância de um tipo enumerado no mesmo escopo. E vice-versa. Tipos enumerados podem ser redefinidos em escopos mais internos As instâncias de tipos enumerados não pode ser nenhuma palavra reservada da linguagem (true, false, etc) Exemplos de programas (LF4) let type d = {dom, seg, ter, qua, qui, sex, sab} in let var y = sex in next (y) = sab let type dias = {seg, ter, qua} in let type diasAoContrario = {ter, seg, dom} in next(next(seg)) = ter Funcionamento das pilhas let var x = 1, type diasUteis = {seg, ter, qua, qui, sex} in let type primTrimestre = {jan, fev, mar}, var y = "e" in next(seg) Pilha de compilação let var x = 1, type diasUteis = {seg, ter, qua, qui, sex} in let type primTrimestre = {jan, fev, mar}, var y = "e" in next(seg) Pilha de compilação Map auxiliar Pilha de compilação let var x = 1, type diasUteis = {seg, ter, qua, qui, sex} in let type primTrimestre = {jan, fev, mar}, var y = "e" in next(seg) x <x, TipoInteiro> TipoInteiro Pilha de compilação Map auxiliar Pilha de compilação let var x = 1, type diasUteis = {seg, ter, qua, qui, sex} in let type primTrimestre = {jan, fev, mar}, var y = "e" in next(seg) <sex, TipoEnum (diasUteis)> <qui, TipoEnum (diasUteis)> <qua, TipoEnum (diasUteis)> <ter, TipoEnum (diasUteis)> <seg, TipoEnum (diasUteis)> x <x, TipoInteiro> TipoInteiro Pilha de compilação Map auxiliar Pilha de compilação let var x = 1, type diasUteis = {seg, ter, qua, qui, sex} in let type primTrimestre = {jan, fev, mar}, var y = "e" in next(seg) <sex, TipoEnum (diasUteis)> <qui, TipoEnum (diasUteis)> <qua, TipoEnum (diasUteis)> <ter, TipoEnum (diasUteis)> <seg, TipoEnum (diasUteis)> <x, TipoInteiro> Pilha de compilação Map auxiliar Pilha de compilação let var x = 1, type diasUteis = {seg, ter, qua, qui, sex} in let type primTrimestre = {jan, fev, mar}, var y = "e" in next(seg) <sex, TipoEnum (diasUteis)> <qui, TipoEnum (diasUteis)> <qua, TipoEnum (diasUteis)> <ter, TipoEnum (diasUteis)> <mar, TipoEnum (primTrimestre)> <seg, TipoEnum (diasUteis)> <fev, TipoEnum (primTrimestre)> <x, TipoInteiro> <jan, TipoEnum (primTrimestre)> Pilha de compilação Map auxiliar Pilha de compilação let var x = 1, type diasUteis = {seg, ter, qua, qui, sex} in let type primTrimestre = {jan, fev, mar}, var y = "e" in next(seg) <sex, TipoEnum (diasUteis)> <qui, TipoEnum (diasUteis)> <qua, TipoEnum (diasUteis)> <y, TipoString> <ter, TipoEnum (diasUteis)> <mar, TipoEnum (primTrimestre)> <seg, TipoEnum (diasUteis)> <fev, TipoEnum (primTrimestre)> <x, TipoInteiro> <jan, TipoEnum (primTrimestre)> Pilha de compilação Map auxiliar Pilha de compilação let var x = 1, type diasUteis = {seg, ter, qua, qui, sex} in let type primTrimestre = {jan, fev, mar}, var y = "e" in next(seg) <y, TipoString> <mar, TipoEnum (primTrimestre)> <fev, TipoEnum (primTrimestre)> <jan, TipoEnum (primTrimestre)> <sex, TipoEnum (diasUteis)> <qui, TipoEnum (diasUteis)> <qua, TipoEnum (diasUteis)> <y, TipoString> <ter, TipoEnum (diasUteis)> <mar, TipoEnum (primTrimestre)> <seg, TipoEnum (diasUteis)> <fev, TipoEnum (primTrimestre)> <x, TipoInteiro> <jan, TipoEnum (primTrimestre)> Pilha de compilação Map auxiliar Pilha de Execução let var x = 1, type diasUteis = {seg, ter, qua, qui, sex} in let type primTrimestre = {jan, fev, mar}, var y = "e" in next(seg) Pilhas de execução Maps auxiliares Pilha de Execução let var x = 1, type diasUteis = {seg, ter, qua, qui, sex} in let type primTrimestre = {jan, fev, mar}, var y = "e" in next(seg) <x, ValorInteiro(1)> Pilhas de execução Maps auxiliar Pilha de Execução let var x = 1, type diasUteis = {seg, ter, qua, qui, sex} in let type primTrimestre = {jan, fev, mar}, var y = "e" in next(seg) <diasUteis, [seg, ter, qua, qui, sex]> <sex, ValorEnum (sex, 4, Tipo(diasUteis))> <qui, ValorEnum (qui, 3, Tipo(diasUteis))> <qua, ValorEnum (qua, 2, Tipo(diasUteis))> <ter, ValorEnum (ter, 1, Tipo(diasUteis))> <seg, ValorEnum (seg, 0, Tipo(diasUteis))> <x, ValorInteiro(1)> Pilhas de execução Maps auxiliares Pilha de Execução let var x = 1, type diasUteis = {seg, ter, qua, qui, sex} in let type primTrimestre = {jan, fev, mar}, var y = "e" in next(seg) <diasUteis, [seg, ter, qua, qui, sex]> <sex, ValorEnum (sex, 4, Tipo(diasUteis))> <qui, ValorEnum (qui, 3, Tipo(diasUteis))> <qua, ValorEnum (qua, 2, Tipo(diasUteis))> <ter, ValorEnum (ter, 1, Tipo(diasUteis))> <seg, ValorEnum (seg, 0, Tipo(diasUteis))> <x, ValorInteiro(1)> Pilhas de execução Maps auxiliar Pilha de Execução let var x = 1, type diasUteis = {seg, ter, qua, qui, sex} in let type primTrimestre = {jan, fev, mar}, var y = "e" in next(seg) <diasUteis, [seg, ter, qua, qui, sex]> <sex, ValorEnum (sex, 4, Tipo(diasUteis))> <primTrimestre, [jan, fev, mar]> <qui, ValorEnum (qui, 3, Tipo(diasUteis))> <qua, ValorEnum (qua, 2, Tipo(diasUteis))> <ter, ValorEnum (ter, 1, Tipo(diasUteis))> <mar, ValorEnum(mar, 2, Tipo(primTrimestre))> <seg, ValorEnum (seg, 0, Tipo(diasUteis))> <fev, ValorEnum(fev, 1, Tipo(primTrimestre))> <x, ValorInteiro(1)> <jan, ValorEnum(jan, 0, Tipo(primTrimestre))> Pilhas de execução Maps auxiliar Pilha de Execução let var x = 1, type diasUteis = {seg, ter, qua, qui, sex} in let type primTrimestre = {jan, fev, mar}, var y = "e" in next(seg) <diasUteis, [seg, ter, qua, qui, sex]> <sex, ValorEnum (sex, 4, Tipo(diasUteis))> <primTrimestre, [jan, fev, mar]> <qui, ValorEnum (qui, 3, Tipo(diasUteis))> <qua, ValorEnum (qua, 2, Tipo(diasUteis))> <y, ValorString(“e”)> <ter, ValorEnum (ter, 1, Tipo(diasUteis))> <mar, ValorEnum(mar, 2, Tipo(primTrimestre))> <seg, ValorEnum (seg, 0, Tipo(diasUteis))> <fev, ValorEnum(fev, 1, Tipo(primTrimestre))> <x, ValorInteiro(1)> <jan, ValorEnum(jan, 0, Tipo(primTrimestre))> Pilhas de execução Maps auxiliar Pilha de Execução let var x = 1, type diasUteis = {seg, ter, qua, qui, sex} in let type primTrimestre = {jan, fev, mar}, var y = "e" in next(seg) <diasUteis, [seg, ter, qua, qui, sex]> <sex, ValorEnum (sex, 4, Tipo(diasUteis))> <primTrimestre, [jan, fev, mar]> <qui, ValorEnum (qui, 3, Tipo(diasUteis))> <qua, ValorEnum (qua, 2, Tipo(diasUteis))> <y, ValorString(“e”)> <ter, ValorEnum (ter, 1, Tipo(diasUteis))> <mar, ValorEnum(mar, 2, Tipo(primTrimestre))> <seg, ValorEnum (seg, 0, Tipo(diasUteis))> <fev, ValorEnum(fev, 1, Tipo(primTrimestre))> <x, ValorInteiro(1)> <jan, ValorEnum(jan, 0, Tipo(primTrimestre))> Pilhas de execução Maps auxiliar Pilha de Execução <y, ValorString(“e”)> <mar, ValorEnum(mar, 2, Tipo(primTrimestre))> <fev, ValorEnum(fev, 1, Tipo(primTrimestre))> <jan, ValorEnum(jan, 0, Tipo(primTrimestre))> <sex, ValorEnum (sex, 4, Tipo(diasUteis))> <qui, ValorEnum (qui, 3, Tipo(diasUteis))> <qua, ValorEnum (qua, 2, Tipo(diasUteis))> <ter, ValorEnum (ter, 1, Tipo(diasUteis))> <seg, ValorEnum (seg, 0, Tipo(diasUteis))> <x, ValorInteiro(1)> Pilhas de execução <diasUteis, [jan, fev, mar]> <diasUteis, [jan, fev, mar]> BNF ValorConcreto ::= ValorInteiro | ValorBooleano | ValorString | ValorLista | ValorEnum ExpUnaria ::= "-" Expressao | "not" Expressao | "length" Expressao | "ord" Expressao | "next" Expressao | "previous" Expressao | head(Expressao) | tail(Expressao) | ExpCompreensaoLista BNF DeclaracaoFuncional ::= DecVariavel | DecTipo | DecFuncao | DeclaracaoFuncional "," DeclaracaoFuncional DecTipo ::= "type" Id "=" "{" SeqEnum "}" SeqEnum ::= ValorEnum | ValorEnum "," SeqEnum Parser - Tokens < TYPE < NEXT < PREVIOUS < ORD : "type"> : "next" > : "previous" > : "ord" > Parser - PDeclType() DeclaracaoFuncional PDeclType() : { Id tipo; SeqEnum seqEnum; } { ( <TYPE> tipo = PId() <ASSIGN> <LBRACE> seqEnum = PSeqEnum (tipo.toString()) <RBRACE> ) { return new DecType(tipo, seqEnum); } } Parser - PSeqEnum SeqEnum PSeqEnum(String tipo) : { ValorEnum valEnum; List lista = null; int index = 0; } { ( valEnum = PValorEnum(tipo, index++) { lista = new ArrayList(); lista.add(valEnum); } ( <COMMA> valEnum = PValorEnum(tipo, index++) { lista.add(valEnum); })* ) { return new SeqEnum(lista); } } Parser - PValorEnum ValorEnum PValorEnum(String str, int index) : { Token token; } { token = <IDENTIFIER> { String tokenStr = token.toString(); return new ValorEnum(new Id(tokenStr), str, index); } } Parser - Operações Expressao PExpNext() : { Expressao retorno; } { <NEXT> retorno = PExpPrimaria() { return new ExpNext(retorno); } } Expressao PExpPrevious() : { Expressao retorno; } { <PREVIOUS> retorno = PExpPrimaria() { return new ExpPrevious(retorno); } } Expressao PExpOrd() : { Expressao retorno; } { <ORD> retorno = PExpPrimaria() { return new ExpOrd(retorno); } } Implementação Classes novas DecType SeqEnum ValorEnum TipoEnum ExpOperacoesEnum • ExpNext • ExpPrevious • ExpOrd Implementação Modificações em classes/interfaces AmbienteFuncional<DefFuncao, DecType> • AmbienteExecucaoFuncional – ContextoExecucaoFuncional Implementação Modificações em métodos ExpDeclaracao • • • • avaliar includeBindings resolveBindings resolveTypeBidings Projeto – Parte 2 Projeto (parte 2) Estender a LF3 com características de Haskell Definição de tipos (estender a LF3) Tipos enumerados Tipos complexos Tipos recursivos Para finalizar... Dúvidas/decisões de projeto Dúvidas/decisões de projeto Como declarar tipos recursivos em uma linguagem não tipada? Uma pilha auxiliar para as estruturas foi a melhor decisão? Como dar “apelidos” para tipos se eles não são explícitos? Referências Programming Language Concepts and Paradigms - David A. Watt Programming language processors in Java David A. Watt e Deryck F. Brown http://www.cin.ufpe.br/~if708 http://www.haskell.org/tutorial/goodies.html