Projeto de uma Linguagem de Programa¸c˜aoCaio C´esar, Gabriel Vasiljevic, Jean Silva, Victor20 de maio de 2013
Sum´ario1 Principais caracter´ısticas da linguagem 21.1 Dom´ınio de Aplica¸c˜ao . . . . . . . . . . . . . . . . . . . . . ...
4 Vincula¸c˜oes e regras de escopo 184.1 Bindings da linguagem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ....
Cap´ıtulo 1Defini¸c˜ao das diretrizes de uso ecaracter´ısticas principais da linguagemde programa¸c˜ao1.1 Dom´ınio de Aplic...
CAP´ITULO 1. PRINCIPAIS CARACTER´ISTICAS DA LINGUAGEM 4A linguagem C disp˜oe de apelidos. Um exemplo de seu uso ´e o union...
Cap´ıtulo 2Valores, tipos e express˜oes2.1 Tipos PrimitivosTipos primitivos s˜ao tipos que n˜ao s˜ao derivados de nenhum o...
CAP´ITULO 2. VALORES, TIPOS E EXPRESS ˜OES 6complex - representando um n´umero complexo< tipo > * - guarda o endere¸co de ...
CAP´ITULO 2. VALORES, TIPOS E EXPRESS ˜OES 72.3 Sistema de tiposA linguagem proposta ser´a fortemente tipada. Diferentemen...
CAP´ITULO 2. VALORES, TIPOS E EXPRESS ˜OES 8 import io; import Par; function main(): int { Par<int> pi; pi.a = 2; p...
CAP´ITULO 2. VALORES, TIPOS E EXPRESS ˜OES 9 bool a = true; bool b = false;float: O ponto flutuante ´e representado por 32...
CAP´ITULO 2. VALORES, TIPOS E EXPRESS ˜OES 10 import utility.set; ... set <int> A; set < set <int> > B; B.add(A); /*...
CAP´ITULO 2. VALORES, TIPOS E EXPRESS ˜OES 112.5.2 Forma BNF de declara¸c˜ao de um tipo na Linguagem<tipo_primitivo> -> ch...
CAP´ITULO 2. VALORES, TIPOS E EXPRESS ˜OES 12Maior ou igual (>=): A compara¸c˜ao maior ou igual ´e a jun¸c˜ao de duas comp...
Cap´ıtulo 3Vari´aveis e comandos3.1 Modelo de armazenamento de valoresVisando permitir uma maior flexibilidade `a escrita d...
CAP´ITULO 3. VARI ´AVEIS E COMANDOS 14dever´a ser especificado o ´ındice da posi¸c˜ao do array a ter seu valor atualizado. ...
CAP´ITULO 3. VARI ´AVEIS E COMANDOS 15Por outro lado, para evitar maiores problemas com eficiˆencia e manipula¸c˜ao de pont...
CAP´ITULO 3. VARI ´AVEIS E COMANDOS 16 write("%in", soma); return 0; }3.5.2 Estruturas de Controle3.5.2.1 Condicional3....
CAP´ITULO 3. VARI ´AVEIS E COMANDOS 17break;...default:<lista_de_comandos>break;} import io; function main(): int { st...
CAP´ITULO 3. VARI ´AVEIS E COMANDOS 183.5.2.3 Comando for-each3.5.2.3.1 Forma Normal<comando_foreach> -> foreach (<tipo> <...
CAP´ITULO 3. VARI ´AVEIS E COMANDOS 19<comando_do-while> -> do {<lista_de_comandos>} while ( <condicao_de_parada> ); impo...
CAP´ITULO 3. VARI ´AVEIS E COMANDOS 20 while(true) { i++; write("%i ", i); if (i < 10) continue; write("n"); break;...
CAP´ITULO 3. VARI ´AVEIS E COMANDOS 21 import io; procedure f() { write("Saindo ... n"); exit(0); } function main(...
CAP´ITULO 3. VARI ´AVEIS E COMANDOS 22aos campos se d´a atrav´es de um deslocamento, que ´e guardado junto ao campo, j´a q...
Cap´ıtulo 4Vincula¸c˜oes e regras de escopo4.1 Bindings da linguagemQuanto a vincula¸c˜ao de tipos, que esta associada a d...
CAP´ITULO 4. VINCULAC¸ ˜OES E REGRAS DE ESCOPO 24<comando_da_linguagem> -> <comandos_basicos>| <comandos_basicos> <comando...
Cap´ıtulo 5SubprogramasSubprogramas s˜ao uma das formas de abstra¸c˜ao presente na linguagem, que nos for-nece abstra¸c˜ao...
CAP´ITULO 5. SUBPROGRAMAS 26Em sistemas de implementa¸c˜ao de linguagens de programa¸c˜ao ´e necess´ario incorporarm´etodo...
CAP´ITULO 5. SUBPROGRAMAS 275.3 Formas de passagem de parˆametrosDentre as formas de passagem de parˆametro existentes, a ...
CAP´ITULO 5. SUBPROGRAMAS 28que foram passados quanto seus tipos. No caso particular de uma fun¸c˜ao requisitar umn´umero ...
Cap´ıtulo 6Sistema de tipos da linguagemO sistema de tipos de uma linguagem ´e um aspecto de grande importˆancia para a es...
CAP´ITULO 6. SISTEMA DE TIPOS DA LINGUAGEM 30por estruturas. J´a as estruturas de dados criadas pelo usu´ario a compatibil...
Upcoming SlideShare
Loading in …5
×

Documentação de uma linguagem de progração

312 views

Published on

Documentação de uma linguagem de progração

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
312
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Documentação de uma linguagem de progração

  1. 1. Projeto de uma Linguagem de Programa¸c˜aoCaio C´esar, Gabriel Vasiljevic, Jean Silva, Victor20 de maio de 2013
  2. 2. Sum´ario1 Principais caracter´ısticas da linguagem 21.1 Dom´ınio de Aplica¸c˜ao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.2 Caracter´ısticas da linguagem . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 Valores, tipos e express˜oes 42.1 Tipos Primitivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42.2 Tipos Compostos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.3 Sistema de tipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.4 Tipos definidos pelo usu´ario . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.5 Representa¸c˜ao dos valores de cada tipo . . . . . . . . . . . . . . . . . . . . . 62.5.1 Designadores dos tipos primitivos . . . . . . . . . . . . . . . . . . . . 82.5.2 Forma BNF de declara¸c˜ao de um tipo na Linguagem . . . . . . . . . 82.6 Express˜oes da linguagem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.6.1 Operadores Aritm´eticos . . . . . . . . . . . . . . . . . . . . . . . . . 92.6.2 Incremento e decremento . . . . . . . . . . . . . . . . . . . . . . . . . 92.6.3 Operadores Relacionais . . . . . . . . . . . . . . . . . . . . . . . . . . 92.6.4 Operadores l´ogicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.6.5 Operadores bit-a-bit . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 Vari´aveis e comandos 113.1 Modelo de armazenamento de valores . . . . . . . . . . . . . . . . . . . . . . 113.2 Uso de vari´aveis na Linguagem . . . . . . . . . . . . . . . . . . . . . . . . . 113.3 Caracter´ısticas dos arrays da linguagem . . . . . . . . . . . . . . . . . . . . . 123.4 Escopo e tempo de vida das vari´aveis . . . . . . . . . . . . . . . . . . . . . . 133.5 Comandos da linguagem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133.5.1 Entrada e Sa´ıda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133.5.2 Estruturas de Controle . . . . . . . . . . . . . . . . . . . . . . . . . . 143.5.3 Comandos alternadores de fluxo (jumps) . . . . . . . . . . . . . . . . 163.5.4 Primitivas de sa´ıdas dos blocos (escapes) . . . . . . . . . . . . . . . . 163.5.5 Tratamento de Exce¸c˜oes . . . . . . . . . . . . . . . . . . . . . . . . . 173.6 Aloca¸c˜ao de mem´oria das veri´aveis compostas . . . . . . . . . . . . . . . . . 171
  3. 3. 4 Vincula¸c˜oes e regras de escopo 184.1 Bindings da linguagem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184.2 Aliasing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184.3 Estrutura de blocos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184.4 Regras de visibilidade e resolu¸c˜ao de escopo . . . . . . . . . . . . . . . . . . 195 Subprogramas 205.1 Procedimentos e fun¸c˜oes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205.2 Parˆametros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205.3 Formas de passagem de parˆametros . . . . . . . . . . . . . . . . . . . . . . . 225.4 Verifica¸c˜ao dos tipos de parˆametros . . . . . . . . . . . . . . . . . . . . . . . 225.5 Subprogramas sobrecarregados ou gen´ericos . . . . . . . . . . . . . . . . . . 235.6 Sistema de Implementa¸c˜ao . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 Sistema de tipos da linguagem 246.1 Principais caracter´ısticas do sistema de tipos . . . . . . . . . . . . . . . . . . 246.2 Convers˜oes de Tipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246.3 Regras de compatibilidade de tipos . . . . . . . . . . . . . . . . . . . . . . . 24
  4. 4. Cap´ıtulo 1Defini¸c˜ao das diretrizes de uso ecaracter´ısticas principais da linguagemde programa¸c˜ao1.1 Dom´ınio de Aplica¸c˜aoA linguagem proposta ´e baseada em C e FORTRAN. Seu dom´ınio de aplica¸c˜ao ´e cient´ıfico,o que implica que al´em das estruturas de dados simples, ela tamb´em dispor´a de estruturasque possibilitam a manipula¸c˜ao de grandes quantidades de dados e de alta precis˜ao num´ericapara as computa¸c˜oes com n´umeros reais.A linguagem ter´a como p´ublico alvo matem´aticos e cientistas, que precisam trabalharcom n´umeros muito grandes, altas precis˜oes e boas estruturas de controle.1.2 Caracter´ısticas da linguagemH´a algumas caracter´ısticas que determinam o qu˜ao boa ´e uma linguagem de programa¸c˜ao,tais como:Legibilidade: Um dos crit´erios mais importantes. Os programas desenvolvidos numadeterminada linguagem de programa¸c˜ao devem ser f´aceis de serem lidos e compreen-didos. A linguagem a ser especificada ´e simples e disp˜oe de um pequeno n´umero decomponentes b´asicos, o que garante a simplicidade global. Os nomes dos tipos primi-tivos e das outras palavras reservadas refletem bem suas finalidades tornando a leituramais natural.Confiabilidade: Diz-se que uma linguagem ´e confi´avel se ela se comporta de acordocom suas especifica¸c˜oes. A verifica¸c˜ao de tipos ´e de extrema importˆancia e nossalinguagem fornece essa verifica¸c˜ao, o que n˜ao ocorre em linguagens n˜ao-fortementetipadas, e.g. Phyton. A linguagem oferece tamb´em a capacidade de tratamento deexce¸c˜oes em tempo de execu¸c˜ao, o que existe em Java, C++ e C#, ao contr´ario de C.3
  5. 5. CAP´ITULO 1. PRINCIPAIS CARACTER´ISTICAS DA LINGUAGEM 4A linguagem C disp˜oe de apelidos. Um exemplo de seu uso ´e o union, que reserva a umamesma ´area de mem´oria para duas ou mais vari´aveis. Essa ferramente ´e amplamenteconsiderada perigosa e, portanto, n˜ao ser´a contemplada na linguagem a ser projetada.Capacidade de escrita: A linguagem ´e de f´acil escrita e ter´a pouca ortogonalidade,fazendo com que a codifica¸c˜ao de um programa nessa linguagem seja de escrita maisobjetiva. As restri¸c˜oes na combina¸c˜ao dos tipos de dados e estruturas b´asicas devido `apouca ortogonalidade evitar´a problemas de incompatibilidade de tipos que s˜ao dif´ıceisde serem percebidas tanto pelo programadores quanto pelo compilador.Assim como em Java, C e C++, a linguagem proposta ´e Case Sensitive1. C n˜ao disp˜oede algumas estruturas de dados mais complexas como, por exemplo, conjuntos, listas, pilhase filas enquanto a nossa oferece estes tipos como primitivos al´em dos dispon´ıveis em C.Outra novidade ´e o tipo primitivo bigInt que comporta um n´umero inteiro bem maior queo convencional.O fator que mais influencia na eficiˆencia dos programas escritos na linguagem proposta ´e aflexibilidade de baixo n´ıvel herdada de C. E os fatores que mais influenciam na produtividadedo programador s˜ao a legibilidade, a capacidade de escrita e forma como o erro se apresentaa ele durante os testes, permitindo a corre¸c˜ao mais r´apida dos erros.Levando em conta o dom´ınio de aplica¸c˜ao da nossa linguagem, foi escolhido o sistemade implementa¸c˜ao por compila¸c˜ao. A raz˜ao disso ´e que este sistema confere uma maioreficiˆencia aos programas, requisito esse de alta relevˆancia no dom´ınio cient´ıfico em fun¸c˜ao danecessidade de realizar computa¸c˜oes de alto custo.Para que nossa linguagem atinja o sucesso e justifique sua cria¸c˜ao, ´e necess´aria umaan´alise cuidadosa das necessidades de seu dom´ınio de aplica¸c˜ao. As linguagens COBOL eFORTRAN, por exemplo, atendem suficientemente bem as necessidades de seus respectivosdom´ınios. As linguagens posteriores n˜ao trouxeram modifica¸c˜oes realmente relevantes aosrecursos que estas j´a ofereciam. Deve-se tentar suprir todas estas necessidades, tentado fazerum balanceamento entre os pontos fracos e fortes da linguagem proposta.1Case sensitive, do inglˆes “caixa alta”, significa que o sistema diferencia letras mai´usculas e min´usculas.Por exemplo, a palavra “vari´avel” ´e diferente de “Vari´avel” ou “VARI´AVEL”, mesmo tendo a mesma escrita.
  6. 6. Cap´ıtulo 2Valores, tipos e express˜oes2.1 Tipos PrimitivosTipos primitivos s˜ao tipos que n˜ao s˜ao derivados de nenhum outro; s˜ao, de certa forma,estruturas atˆomicas da linguagem. Abaixo listamos os tipos primitivos oferecidos pela lin-guagem, e na sess˜ao 2.5 os detalharemos.char - caractereshort - inteiro curtoint representando o tipo inteirolong - inteiro de faixas maiores (dobro do int)bigInt - inteiro de maior faixa que longboolfloat - ponto flutuantedouble - precis˜ao dupla para ponte flutuantestring - cadeia de caracteresunsigned int - inteiro n˜ao sinalizadounsigned long - long n˜ao sinalizadounsigned bigInt - bigInt n˜ao sinalizadounsigned short - short n˜ao sinalizadounsigned float - float n˜ao sinalizadounsigned double - double n˜ao sinalizado5
  7. 7. CAP´ITULO 2. VALORES, TIPOS E EXPRESS ˜OES 6complex - representando um n´umero complexo< tipo > * - guarda o endere¸co de uma posi¸c˜ao de mem´oria;2.2 Tipos CompostosTipos compostos s˜ao aqueles constru´ıdos a partir de tipos primitivos ou at´e mesmo deoutros tipos compostos. Como exemplo de tipos compostos na nossa linguagem temos:Conjunto (set);Fila (queue);Pilha (stack);Lista (list);Vetor;Struct;Al´em desses, vale destacar um tipo composto bastante peculiar, que ´e o tipo recursivo.Nessa categoria, se encaixam aqueles tipos que s˜ao compostos por elementos de mesmo tipo.Um tipo recursivo cl´assico ´e a lista, onde cada elemento vai referenciar um pr´oximo elementoda mesma natureza. Isso ´e poss´ıvel com a utiliza¸c˜ao de ponteiros. ´Arvores bin´arias e Grafostamb´em seguem a mesma linha de racioc´ınio, mas esses ´ultimos n˜ao s˜ao suportados pelalinguagem.A constru¸c˜ao de um tipo recursivo ´e feita da seguinte forma, segundo a forma BNF:<declara¸c~ao_tipo_recursivo> -> struct <nome_do_tipo> {<conjunto_de_declara¸c~oes><nome_do_tipo> * <nome_do_atributo>;};Exemplo de uso: struct ListaT{ int info; ListaT * prox; };C´odigo 1: Estrutura de lista recursivaNo c´odigo 2.2 acima temos uma estrutura de lista recursiva. Neste caso, uma lista ´ecomposta por um campo info, onde podemos armazenar e recuperar um dado do tipo inteiro,e uma lista do mesmo tipo, ou seja, o interior da lista cont´em outra lista, que por sua veztem outra, e assim por diante, e dessa forma conseguimos fazer constru¸c˜oes recursivas nalinguagem.
  8. 8. CAP´ITULO 2. VALORES, TIPOS E EXPRESS ˜OES 72.3 Sistema de tiposA linguagem proposta ser´a fortemente tipada. Diferentemente de C e C++, que n˜aofazem a verifica¸c˜ao de tipos de parˆametros de uma fun¸c˜ao. Destarte, n˜ao haver´a convers˜oesimpl´ıcitas de tipo (coer¸c˜ao). Quanto a compatibilidade, usaremos a combina¸c˜ao de doism´etodos: a compatibilidade de nomes e estruturas. Escolhemos esta abordagem por acharmosmais segura e pr´atica, al´em de mais eficiente, pois, no melhor caso, n˜ao precisaremos compararas estruturas das vari´aveis, e no pior s´o verificamos os nomes.Esse assunto ´e abordado de forma mais detalhada no cap´ıtulo 6.2.4 Tipos definidos pelo usu´arioMuitas vezes o usu´ario deseja criar seus pr´oprios tipos, e isso ´e poss´ıvel usando a primitivastruct. ´E poss´ıvel, ainda, a defini¸c˜ao de estruturas gen´ericas, nas quais possamos declararuma vari´avel ora de um tipo, ora de outra, sem a necessidade de implementar mais de umestrutura de tipo (ver exemplo do c´odigo 2.4 e 2.4). template <typedef struct T> typedef struct Par { T a, b; }; template <typedef struct T> function getMax (Par <T> p ) : T { return p.a > p.b ? p.a : p.b; }C´odigo 2: Defini¸c˜ao de tipos e fun¸c˜oes gen´ericas atrav´es do uso do templates2.5 Representa¸c˜ao dos valores de cada tipoNesta sess˜ao apresentamos cada tipo e em seguida um exemplo do uso.char: ´E representado internamente por 1 byte, ou seja, a faixa de valores que esse tipocobre ´e −128 a 127, e quando n˜ao sinalizado (unsigned char) compreende uma faixa de 0 a255. Para a representa¸c˜ao de cada caractere usamos a tabela ASCII. char c = ’a’; unsigned d = ’b’;short: ´E representado na base bin´aria por 16 bits = 2 bytes. Usamos a representa¸c˜ao decomplemento de 2 para permitirmos a representa¸c˜ao de n´umeros negativos. O intervalo decobertura desse ´e de −32768 a 32767, para o unsinged short temos de 0 a 65535.
  9. 9. CAP´ITULO 2. VALORES, TIPOS E EXPRESS ˜OES 8 import io; import Par; function main(): int { Par<int> pi; pi.a = 2; pi.b = 7; Par <float> pf; pf.a = 2.5; pf.b = 3.1415; write("%dn", getMax(pi)); write("%dn", getMax(pf)); return 0; }C´odigo 3: Uso do tipo gen´erico Par para float short a; unsigned short b;int: ´E representado da mesma forma que o short, mas compreende uma faixa maior que omesmo (4 bytes). O tipo int sinalizado compreende uma faixa de −2147483648 a 2147483647,j´a o n˜ao sinalizado 0 a 4294967295. int n = 50; unsigned int m = 8;long: Sua representa¸c˜ao ´e da mesma forma que o tipo int, por´em com uma faixa devalores superior aos inteiros anteriores: 8 bytes. A faixa de representa¸c˜ao do tipo inteirolongo ´e de −263`a 263− 1. 0 n˜ao sinalizado vai de 0 `a 264− 1. long l = 5000; unsigned long l1 = 6000;bigInt: Da mesma forma, o bigInt ´e representado de maneira similar, mas com o dobrodo tamanho do long: 16 bytes. Assim, a representa¸c˜ao do bigInt ´e a seguinte −2127`a 2127−1,e n˜ao sinalizado vai de 0 `a 2128− 1. bigInt bi = 10000000; unsigned bigInt b = 100000000;bool: Pode assumir dois valores: true ou false e ´e representado por 1 byte. O true ser´arepresentado por todos os 8 bits do byte em 1, caso contr´ario todos em 0.
  10. 10. CAP´ITULO 2. VALORES, TIPOS E EXPRESS ˜OES 9 bool a = true; bool b = false;float: O ponto flutuante ´e representado por 32 bits, sendo 1 reservado para o sinal, 8 deexpoente e 23 para a parte fracion´aria. Isso equivale a uma faixa de valores de ±3.4e±38. float a = .2; float b = 2.5;double: O double ´e representado de forma semelhante ao float, mas com o dobro deprecis˜ao (8 bytes). A faixa de valores ´e de ±1.7e ± 308. double a = 5.65complex: O tipo complexo utilizar´a dois n´umeros reais, um para representar sua partereal e o outro a parte imagin´aria e ter´a 8bytes e a faixa ser´a de −264`a 264− 1. complex c(5.5, 7.8);string: O tipo string ser´a uma lista encadeada de caracteres. Para esta lista, as opera¸c˜oesde concatena¸c˜ao e convers˜ao para uma cadeia de caractere estar˜ao fundamentadas na lingua-gem. string s = "cplusminus.com";vetor: Como um vetor aponta para um bloco de mem´oria, sua implementa¸c˜ao se d´a porum ponteiro para apontar ao primeiro bloco de mem´oria alocado. int v[10]; int vet[3] = {1, 2, 3}; int mat[2][2] = {1, 0; 0, 1};set: Os conjuntos ser˜ao armazenados com uma cadeia de bits internamente. Quando em1, o bit significa que o elemento est´a presente e, caso contr´ario, n˜ao estar´a. Consideremos oseguinte conjunto:[ a , . . . , p ]Podemos utilizar 16 bits para representar esse conjunto. Desta forma, o conjunto [ a , b , f , j , p ]seria representado como a seguir:1100010001000001Um conjunto ter´a um tamanho de 4 bytes, ou seja, ser´a poss´ıvel representar um conjuntocom no m´aximo 32 elementos.
  11. 11. CAP´ITULO 2. VALORES, TIPOS E EXPRESS ˜OES 10 import utility.set; ... set <int> A; set < set <int> > B; B.add(A); /** * B ⊃ A */list: A lista ´e definida recursivamente - uma lista ´e composta de outra lista. import utility.list; ... list <int> a; list < list <int> > b;ponteiros: Ponteiros e referˆencias s˜ao geralmente representados por valores ´unicos, arma-zenados em c´elulas de mem´oria de 2 ou 4 bytes, dependendo da arquitetura do computador.Na maioria dos computadores, os microprocessadores s˜ao baseados na arquitetura intel; as-sim, os ponteiros e as referˆencias s˜ao representadas como pares de palavras de 16 bits, umapara cada uma das duas partes de um endere¸co (segmento e deslocamento(offset)). int * prt; char * pt; short * p;2.5.1 Designadores dos tipos primitivosTabela 2.1: Designadores dos tipos primitivos da linguagemNome Descri¸c˜ao Tamanho Faixachar Caractere 1byte −128 a 127 e unsigned: 0 a 255short Inteiro curto 2bytes −32768 a 32767 e unsigned: 0 `a65535int Inteiro 4bytes −2147483648 a 2147483647 e un-signed: 0 `a 4294967295long Inteiro longo 8bytes −263`a 263− 1 e unsigned: 0 `a264− 1bigInt Inteiro muito longo 16bytes −2127`a 2127− 1 e unsigned: 0 `a2128− 1bool Valor booleano. Pode assumir dois va-lores: true ou false1byte true ou falsefloat Pronto flutuante 4bytes ±3.4e ± 38double Precis˜ao dupla do ponto flutuante 8bytes ±1.7e ± 308complex N´umeros complexos 8bytes −264`a 264− 1
  12. 12. CAP´ITULO 2. VALORES, TIPOS E EXPRESS ˜OES 112.5.2 Forma BNF de declara¸c˜ao de um tipo na Linguagem<tipo_primitivo> -> char | short | int | long | bitInt | bool | float | double | complex | string<tipo_composto> -> vetor | set | list<tipo_vetor> -> <tipo_primitivo> | set<tipo> -> <tipo_primitivo> | <tipo_composto><definicao_tamanho> -> [<tamanho>]| <definicao_tamanho> <definicao_tamanho><declaracao_vetor> -> <tipo_vetor> <nome_variavel> <definicao_tamanho>;<tipo_list> -> list < <tipo> ><declaracao_list> -> <tipo_list> <nome_variavel>;| list < <tipo_list> > <nome_variavel>;<declaracao_set> -> <declaracao_set> <nome_variavel>;| set < <declacao_set> >;| set < <tipo> >2.6 Express˜oes da linguagem2.6.1 Operadores Aritm´eticosOs cinco operadores se referem as seguintes, respectivas, opera¸c˜oes: adi¸c˜ao ( + ), sub-tra¸c˜ao ( - ), multiplica¸c˜ao ( * ), divis˜ao ( / ) e mod ou resto ( % ). Estes operadores atuamsobre dois operandos, por este motivos, s˜ao classificados como bin´arios.2.6.2 Incremento e decrementoOs operadores (++) e (−−) respectivamente incremento, aumenta o valor da vari´avel em1, e decremento, diminui o valor da vari´avel em 1.2.6.3 Operadores RelacionaisEstes operadores representam as seguintes rela¸c˜oes:Igualdade ( == ): A igualdade ´e uma opera¸c˜ao booleana que retorna o valor true,caso dois operadores sejam considerados iguais, segundo um crit´erio de verifica¸c˜ao, efalse, caso contr´ario.Diferen¸ca ( ! = ): A diferen¸ca retorna false, nos casos em que a igualdade retornariatrue, e retorna true, nos casos contr´arios.Maior ( > ): A compara¸c˜ao maior retorna true, caso o primeiro operando seja maiorque o segundo, e false, quando o segundo operando ´e maior que o primeiro.Menor (< ): A compara¸c˜ao menor retorna true, quando o primeiro operando ´e menorque o segundo, e false, quando o contr´ario acontece.
  13. 13. CAP´ITULO 2. VALORES, TIPOS E EXPRESS ˜OES 12Maior ou igual (>=): A compara¸c˜ao maior ou igual ´e a jun¸c˜ao de duas compara¸c˜oes,esta compara¸c˜ao retorna true, sempre que pelo menos uma das duas return true, e false,caso contr´arios.Menor ou igual ( <= ): A compara¸c˜ao menor ou igual tem o mesmo funcionamentoda compara¸c˜ao maior ou igual, retornando true, quando o primeiro operando ´e menorou igual ao segundo.2.6.4 Operadores l´ogicosA seguir uma breve vincula¸c˜ao dos operadores com seus respectivos significados booleanos.O operador “ ! ” representa a fun¸c˜ao l´ogica NOT.O operador “ && ” representa a fun¸c˜ao l´ogica AND.Por fim, o operador “||” representa a fun¸c˜ao l´ogica OR.2.6.5 Operadores bit-a-bitEstes operadores s˜ao caracterizados por fazer opera¸c˜oes com bit e bytes (palavras de8 bit). Podemos reconhecer alguns operadores l´ogicos ou booleanos como o operador “ &”, representando o AND bit a bit, o operador “|”, representando o OR bit a bit, o “ ˆ ”,representando o XOR e por fim o “ ˜ ” que representa o NOT bit a bit. Os operadores dedeslocamento “>>” e “<<” de bits a direita e a esquerda respectivamente.
  14. 14. Cap´ıtulo 3Vari´aveis e comandos3.1 Modelo de armazenamento de valoresVisando permitir uma maior flexibilidade `a escrita dos programadores, ser˜ao permitidosos seguintes modelos de armazenamento de valores na mem´oria:(a) Est´atico: Em v´arias situa¸c˜oes, vari´aveis globalmente acess´ıveis s˜ao de grande utilidade.O modelo de vincula¸c˜ao est´atica permite isso da forma mais eficiente (endere¸camentodireto). Este modelo v´ıncula `a vari´avel um determinado endere¸co de armazenamentoantes que o programa inicia, o qual permanece at´e o fim do programa.(b) Dinˆamico na pilha: As vari´aveis dinˆamicas na pilha s˜ao aquelas em que o tipo ´evinculado estaticamente, mas a vincula¸c˜ao de armazenamento ´e feita no momento emque o programa atinge a declara¸c˜ao da vari´avel, em tempo de execu¸c˜ao. Esse modelo ´e orequisito b´asico para permitir subprogramas recursivos. Devido `a sobretaxa de aloca¸c˜aoe desaloca¸c˜ao em tempo de execu¸c˜ao, este modelo perde em desempenho.(c) Dinˆamico no heap expl´ıcitas: O uso de vari´aveis dinˆamicas no heap permite aoprogramador interagir em mais baixo n´ıvel com blocos de mem´oria. A aloca¸c˜ao ´e feitaatrav´es de operadores ou fun¸c˜oes definidos(as) na linguagem e a manipula¸c˜ao ´e feitaatrav´es de ponteiros ou referˆencias. Esse modelo se aplica perfeitamente na defini¸c˜aode estruturas dinˆamicas, mas a manuten¸c˜ao dos blocos envolve riscos, que passam a serresponsabilidade do programador.3.2 Uso de vari´aveis na LinguagemNa nossa linguagem, ao se declarar uma vari´avel, ´e vinculado um valor aleat´orio a ela (lixoda mem´oria). Isso pode ser evitado realizando-se a inicializa¸c˜ao da vari´avel no momento desua declara¸c˜ao, tornando responsabilidade do programador a verifica¸c˜ao dessa necessidade.Alem disso, ´e poss´ıvel vincular valores dinamicamente `a vari´avel atrav´es de opera¸c˜oes deatribui¸c˜ao ou de leitura. Quanto `a atribui¸c˜ao de vari´aveis compostas, no caso dos arrays,13
  15. 15. CAP´ITULO 3. VARI ´AVEIS E COMANDOS 14dever´a ser especificado o ´ındice da posi¸c˜ao do array a ter seu valor atualizado. De modo que,esse ´ındice denota o deslocamento do ponteiro na mem´oria em rela¸c˜ao ao endere¸co base doarray. Dessa forma, o programador tem uma forma mais intuitiva de manipular os arrays.No caso dos tipos definidos atrav´es de structs, n˜ao ser´a poss´ıvel fazer uma atribui¸c˜ao diretada forma < tipo composto >=< outro tipo composto >. Para este fim, a atribui¸c˜ao deve serfeita campo `a campo.Na forma BNF logo abaixo, apresentamos a forma geral da declara¸c˜ao de uma vari´avel,e em seguida, alguns exemplos que segue a BNF descrita.<declaracao_var> -> <tipo> <nome_var>;| <tipo> <nome_var> = <valor>;| <tipo> <lista_nomes_vars>;<lista_nomes_vars> -> <nome>| <nome>, <lista_nomes_vars> int a, b, c, d; string str = "CPlusMinus"; float f = .6;3.3 Caracter´ısticas dos arrays da linguagemOs elementos do array s˜ao referˆenciados por meio de seu endere¸co base, e de um ou mais´ındices do tipo inteiro. A sintaxe da referˆencia consiste, basicamente, no nome da estruturaseguido de uma lista de ´ındices, cada um colocado entre colchetes. Para evitar erros de faixa,´e vinculado ao array uma faixa de valores (com limite inferior no zero) de modo a evitar oacesso a posi¸c˜oes inv´alidas. Os arrays ser˜ao categorizados como:(a) Est´atico: a faixa de valores do ´ındice e a aloca¸c˜ao de armazenamento s˜ao vinculadosestaticamente antes da execu¸c˜ao do programa (eficiente).(b) Fixo dinˆamico na pilha: a faixa de valores do ´ındice ´e vinculada estaticamente, masa aloca¸c˜ao ´e feita no momento da elabora¸c˜ao da declara¸c˜ao (melhor uso do espa¸co dearmazenamento).(c) Dinˆamico na pilha: a faixa de valores do ´ındice e o espa¸co de endere¸camento s˜aovinculados dinamicamente. Ocorrendo a vincula¸c˜ao, sua faixa de valores do ´ındice e seuarmazenamento alocado permanecem os mesmos at´e o fim de seu tempo de vida (maiorflexibilidade em rela¸c˜ao ao array fixo dinˆamico na pilha)(d) Dinˆamico no heap: semelhante ao dinˆamico na pilha, exceto pela possibilidade da faixade valores do ´ındice e seu armazenamento alocado serem modificados qualquer n´umerode vezes (ainda mais flex´ıvel).Para fornecer maior poder de express˜ao ao programador, ´e permitido a defini¸c˜ao de umalista de ´ındices com tamanho sem imposi¸c˜ao de limites de tamanho para arrays est´aticos.
  16. 16. CAP´ITULO 3. VARI ´AVEIS E COMANDOS 15Por outro lado, para evitar maiores problemas com eficiˆencia e manipula¸c˜ao de ponteiros, ´elimitado para sete o tamanho da lista de ´ındices para arrays dinˆamicos de heap. Por ´ultimomas n˜ao menos importante, ´e permitida a inicializa¸c˜ao dos elementos do array no momentode sua declara¸c˜ao se ele for est´atico, e, para facilitar a manipula¸c˜ao e melhorar o desempenhode referenciamento, os arrays poder˜ao ser subdivididos em fatias, o que possibilita o uso demenos express˜oes de ´ındice do que se fosse referˆenciado o array inteiro.3.4 Escopo e tempo de vida das vari´aveisA vari´avel global (est´atica) quando declarada estar´a acess´ıvel desde o in´ıcio do programaat´e o final do mesmo. A vincula¸c˜ao dessa vari´avel a um espa¸co de mem´oria ´e feita antes daexecu¸c˜ao do programa. Uma vari´avel local estar´a acess´ıvel somente durante a execu¸c˜ao dafun¸c˜ao onde ela foi declarada. Nesse caso, a v´ari´avel ´e vinculada a um espa¸co de mem´oria emtempo de execu¸c˜ao, mas logo quando essa fun¸c˜ao ´e finalizada, esse espa¸co de mem´oria quefoi alocado para a vari´avel ´e desalocado. ´E importante n˜ao confundirmos a acessibilidade deuma vari´avel com o seu escopo. Em geral, ´e muito comum pensarmos que o escopo de umavari´avel est´atica ´e somente durante a execu¸c˜ao do programa inteiro, mas isso n˜ao ´e verdade;podemos declarar uma vari´avel est´atica dentro de uma fun¸c˜ao com o aux´ılio do modificadorstatic, e a mesma n˜ao estar acess´ıvel ao longo da execu¸c˜ao do programa inteiro. O queacontece ´e que a vari´avel ´e est´atica e, mesmo ap´os o t´ermino da fun¸c˜ao, ela continua alocada,mas n˜ao permanece acess´ıvel.3.5 Comandos da linguagemNessa sess˜ao apresentaremos para cada comando sua forma BNF, e em seguida, umexemplo de uso do comando em quest˜ao.3.5.1 Entrada e Sa´ıda3.5.1.1 Forma Normal<cod_leitura> -> "%i"|"%d"|"%s"|"%f"|"%lf"|"%bi"|"%ld"<cod_escrita> -> <string> | <cod_leitura>|<string > <cod_escrita>|<cod_leitura> <cod_escrita><lista_enderecos>-> &<variavel> | &<variavel>, <lista_enderecos><lista_vars> -> <variavel> | <variavel>, <lista_vars><comando_read> -> read(<cod_leitura>, <lista_enderecos>);<comando_write> -> write (<cod_escrita>, <lista_vars>) import io; function main(): int { int a, b; read("%i %i", &a, &b); int soma = a + b;
  17. 17. CAP´ITULO 3. VARI ´AVEIS E COMANDOS 16 write("%in", soma); return 0; }3.5.2 Estruturas de Controle3.5.2.1 Condicional3.5.2.1.1 Comando ifForma Normal<comando_if> -> if ( <condicao> ) {<comando>} else if (<condicao2>) {<lista_de_comandos>} else {<lista_de_comandos>}| if ( <condicao> ) {<lista_de_comandos>} else {<lista_de_comandos>}| if ( <condicao> ) {<lista_de_comandos>}| if ( <condicao> )<comando> import io; function main(): int { int n; read("%d", &n); if (n > 0) { write("%d eh um numero positivon", n); } else if(n < 0){ write("%d eh um numero negativon", n); } else { write("%d eh zeron", n); } return 0; }3.5.2.1.2 Comando switch-caseForma Normal<comando_switch-case> -> switch( <var_escolha> ) {case <op1>:<lista_de_comandos>break;case <op2>:<lista_de_comandos>
  18. 18. CAP´ITULO 3. VARI ´AVEIS E COMANDOS 17break;...default:<lista_de_comandos>break;} import io; function main(): int { string op; read("%s", &op); switch(op) { case "um": write("1n"); break; case "dois": write("2n"); break; case "tres": write("3n"); break; default: write("qwertyn"); break; } return 0; }3.5.2.2 Repeti¸c˜ao3.5.2.2.1 Comando forForma Normal<comando_for> -> for (<inicializacao>; <condicao_de_parada>; <incremento/decremento>) {<lista_de_comandos><comando_for>}| for (<inicializacao>; <condicao_de_parada>; <incremento/decremento>)<comando> import io; function main(): int { int n; read("%d", &n); for (int i = 0; i < n; i++) { write("%d ", 2 * (i + 1)); } write("n"); return 0; }
  19. 19. CAP´ITULO 3. VARI ´AVEIS E COMANDOS 183.5.2.3 Comando for-each3.5.2.3.1 Forma Normal<comando_foreach> -> foreach (<tipo> <nome_var> : <nome_list/nome_vetor>) {<lista_de_comandos><comando_foreach>}| foreach (<tipo> <nome_var> : <nome_list/nome_vetor>)<comando> import io; import utility.list; function main(): int { list <int> lst; lst.add(0); lst.add(2); lst.add(3); lst.add(4); foreach (int a : lst) { write("%d ", a); } write("n"); return 0; }3.5.2.4 Comando while3.5.2.4.1 Forma Normal<comando_while> -> while (<condicao_de_parada>) {<lista_de_comandos><comando_while>} import io; function main(): int { int n; read("%d", &n); int i = 0; while(i < n) { ++i; write("%d ", 2 * i); } write("n"); return 0; }3.5.2.5 Comando do-while3.5.2.5.1 Forma Normal
  20. 20. CAP´ITULO 3. VARI ´AVEIS E COMANDOS 19<comando_do-while> -> do {<lista_de_comandos>} while ( <condicao_de_parada> ); import io; function main(): int { int i = 5; do { write("%d ", i); i--; } while (i != 0); write("n"); return 0; }3.5.3 Comandos alternadores de fluxo (jumps)Os tipos de jumps (alteradores de fluxo) da linguagem s˜ao descritos na subse¸c˜oes seguintes.3.5.3.1 Comando breakNo c´odigo 3.5.3.1 abaixo, que ilustra o uso do break, as linhas 4 e 5 sempre ser˜ao exe-cutadas at´e que i = 10, quando a condi¸c˜ao da linha 5 ´e satisfeita e as linhas 6 e 7 ser˜aoexecutadas. A sa´ıda do programa ser´a os n´umeros de 1 a 10 e uma quebra de linha. Na linha7 o comando break ´e executado e o fluxo de execu¸c˜ao ´e desviado para a pr´oxima instru¸c˜ao,fazendo com que o programa n˜ao entre no la¸co novamente. int i = 0; while(true) { i++; write("%d ", i); if (i == 10) { write("n"); break; } }C´odigo 4: Uso do break3.5.3.2 Comando continueNo c´odigo 3.5.3.2, que exibe um trecho de c´odigo com o emprego do comando continue,enquanto i < 10 a linha 5 ser´a executada. O comando continue faz com que o programavolte `a condi¸c˜ao do loop que o engloba, (linha 1) ignorando as linhas abaixo dele (linhas 6 e7), ou seja, o programa entrar´a em loop mais uma vez. Quando i = 10 o programa escreveuma quebra de linha e encerra o loop com o comando break.
  21. 21. CAP´ITULO 3. VARI ´AVEIS E COMANDOS 20 while(true) { i++; write("%i ", i); if (i < 10) continue; write("n"); break; }C´odigo 5: Trecho de c´odigo com o uso do continue.3.5.4 Primitivas de sa´ıdas dos blocos (escapes)3.5.4.1 Comando returnO comando return serve para retornar o que uma fun¸c˜ao se propˆos a computar. Comoexemplo temos o trecho de c´odigo do C´odigo 3.5.4.1, onde ´e definida uma fun¸c˜ao par(i:int):bool que retorna true se i for par e false caso contr´ario. Se i for par a linha 3 ´e executada eo subprograma ´e finalizado. Caso contr´ario, a linha 4 ´e executada e o programa ´e finalizado.Veja que uma fun¸c˜ao pode somente retornar um valor por execu¸c˜ao. function par(i: int): bool { if (i % 2 == 0) return true; return false; }C´odigo 6: Trecho de c´odigo com o uso do return.3.5.4.2 Comando exitO comando exit ´e usado para finalizar o programa como um todo. Vejamos o c´odigo3.5.4.2, a sa´ıda ser´a:msg de testeSaindo ...Na fun¸c˜ao f(), na linha 5 temos um comando exit(0), pontanto tudo que est´a ap´os achamada dessa fun¸c˜ao na main() n˜ao ser´a executado, pois o programa finaliza sua execu¸c˜aoquando o comando exit(0) ´e usado. Se comentarmos a linha 11 do programa sua sa´ıda seriaa seguinte:msg de testeSaindo ...msg de teste 2
  22. 22. CAP´ITULO 3. VARI ´AVEIS E COMANDOS 21 import io; procedure f() { write("Saindo ... n"); exit(0); } function main(): int { write("msg de testen"); f(); write("msg de teste 2n"); return 0; }C´odigo 7: Trecho de c´odigo com o uso do exit.3.5.5 Tratamento de Exce¸c˜oesNossa linguagem usar´a a estrutura de try-catch como forma de tratamento de exce¸c˜oes,de forma semelhante a C++. As exce¸c˜oes ser˜ao definidas como os tipos presentes na lingua-gem, podendo, assim, o pr´oprio usu´ario criar suas exce¸c˜oes. A seguir (c´odigo 3.5.5), tem-seum exemplo de um c´odigo utilizando tratamento de exce¸c˜oes. procedure g(){ int x; write("Digite um numero positivo: n"); try{ read(x); if(x < 0){ throw x; } } catch(int erro){ write("Erro! numero negativo: %i n", erro); } }C´odigo 8: Trecho de c´odigo com o uso do try-catch.3.6 Aloca¸c˜ao de mem´oria das veri´aveis compostasPara as vari´aveis compostas homogˆeneas, como os vetores, sua aloca¸c˜ao ser´a em blocos demem´oria sequenciais, e seu escopo ser´a como o de uma vari´avel comum. Seu referenciamentoser´a em rela¸c˜ao ao primeiro bloco de mem´oria alocado por ele. Ou seja, o referenciamentoda pr´oxima vari´avel da sequˆencia ser´a apenas o incremento unit´ario da posi¸c˜ao da mem´oria.Quanto a passagem destas vari´aveis por parˆametro, ser´a feito por referˆencia. As vari´aveiscompostas heterogˆeneas (registros) tamb´em ser˜ao alocadas sequencialmente, mas o acesso
  23. 23. CAP´ITULO 3. VARI ´AVEIS E COMANDOS 22aos campos se d´a atrav´es de um deslocamento, que ´e guardado junto ao campo, j´a que otamanho de cada bloco n˜ao ´e necessariamente igual. Seu referenciamento ´e feito como o deuma vari´avel comum, ou seja, copiando seus atributos. O mesmo vale para seu escopo - igualao de uma vari´avel comum.
  24. 24. Cap´ıtulo 4Vincula¸c˜oes e regras de escopo4.1 Bindings da linguagemQuanto a vincula¸c˜ao de tipos, que esta associada a declara¸c˜ao de vari´aveis, ser´a, sem-pre que poss´ıvel, feita est´aticamente devido ao sistema de implementa¸c˜ao escolhido, a com-pila¸c˜ao, e a maior eficiˆencia dessa abordagem. Sendo assim, a vincula¸c˜ao de tipos ser´aem tempo de compila¸c˜ao. Quanto a vincula¸c˜ao de armazenamento, temos como assunto,vari´aveis est´aticas,stack-dinˆamicas e heap-dinˆamicas. As vari´aveis est´aticas tem seu espa¸code armazenamento vinculado em tempo de compila¸c˜ao. E as vari´aveis stack-dinˆamicas eheap-dinˆamicas tem seus epa¸cos de armazenamento vinculados em tempo de execu¸c˜ao mas,n˜ao da mesma forma. Vari´aveis stack-dinˆamicas s˜ao armazenadas temporariamente em umapilha e sua retirada ´e feita pela linguagem, dependendo de seu ambiente de referenciamento.Vari´aveis heap-dinˆamica s˜ao armazenadas numa heap e sua retirada ´e responsabilidade doprogramador. As caracter´ısticas mais b´asicas e elementares da linguagem, que est˜ao sendodefinidas durante esta disciplina, est˜ao sendo vinculadas em tempo de projeto.4.2 AliasingNa linguagem haver´a dois casos do uso de aliasing, os quais s˜ao explicados abaixo. Oprimeiro caso, ´e mais evidente em linguagens que d˜ao suporte a aliasing, ´e o uso de referˆencia.Por exemplo, quando usamos passagem de parˆametros por referˆencia, passam a existir doisnomes vinculados ao mesmo espa¸co de mem´oria, o que caracteriza o aliasing. O uso deponteiros pode ser tamb´em considerado aliasing em alguns casos. Caracterizamos seu usocomo aliasing quando dois ponteiros est˜ao referenciando um mesmo bloco de mem´oria. Estetipo de apelido ´e indireto, pois os ponteiros em si n˜ao s˜ao aliasing, mas sua referˆencia o ´e.4.3 Estrutura de blocosPara definirmos os escopos das vari´aveis usamos blocos, que s˜ao, por sua vez, definidospelas chaves, ““ e “”. Segue abaixo a forma BNF.23
  25. 25. CAP´ITULO 4. VINCULAC¸ ˜OES E REGRAS DE ESCOPO 24<comando_da_linguagem> -> <comandos_basicos>| <comandos_basicos> <comando_da_linguagem>| <blocos>| <blocos> <comando_da_linguagem><bloco> -> <comando_de_fluxo_ctrl> {<comandos_da_linguagem>}| <decl_func> {<comandos_da_linguagem>}Podemos usar a forma BNF acima descrita para definir blocos aninhados de forma re-cursiva, visto que comando de fluxo de controle e declara¸c˜oes de fun¸c˜oes s˜ao comandos dalinguagem.4.4 Regras de visibilidade e resolu¸c˜ao de escopoQuanto ao escopo est´atico, as vari´aveis declaradas nos blocos ancestrais ser˜ao vis´ıveis atodos os blocos internos a eles. J´a o contr´ario n˜ao ocorre: vari´aveis declaradas nos blocos maisinternos n˜ao s˜ao vis´ıveis a seus ancestrais. Quando o compilador encontra um identificador deuma vari´avel, ´e necess´ario saber a qual vari´avel ele se refere. Para tanto, ´e preciso localizar asua instru¸c˜ao de declara¸c˜ao. Essa busca come¸ca no bloco em que foi encontrada a referˆencia `avari´avel. Caso a vari´avel n˜ao seja encontrada neste bloco, a busca se segue em seu pai est´atico(bloco que engloba este bloco), e assim por diante. Caso n˜ao haja mais nenhum ancestralest´atico para proceder com a busca o compilador ir´a retornar um erro de declara¸c˜ao. Quantoao escopo dinˆamico, essa busca se d´a de maneira diferente, uma vez que no escopo est´aticoa busca pela instru¸c˜ao de declara¸c˜ao da vari´avel ´e baseada na declara¸c˜ao dos blocos, e nodinˆamico ´e baseado na ordem inversa de chamada de fun¸c˜oes. Consideremos a seguintesitua¸c˜ao: a fun¸c˜ao main fm chama uma func˜ao f2, que por sua vez chama uma fun¸c˜aof1. Consideremos tamb´em que o compilador encontrou uma referˆencia a uma vari´avel x emf1. Dessa forma a instru¸c˜ao de declara¸c˜ao de x ser´a buscada na ordem de chamada dessasfun¸c˜oes. Primeiro o compilador verifica se a instru¸c˜ao de declara¸c˜ao se encontra na f1, casocontr´ario, a busca continua em f2, e assim por diante. Caso n˜ao seja encontrada, o compiladorretornar´a um erro de declara¸c˜ao. Analizando essas duas formas de escopo, conclu´ımos quenossa liguagem deve ser de escopo est´atico.
  26. 26. Cap´ıtulo 5SubprogramasSubprogramas s˜ao uma das formas de abstra¸c˜ao presente na linguagem, que nos for-nece abstra¸c˜ao de processo, cujo conceito ´e de suma importˆancia para uma linguagem deprograma¸c˜ao, uma vez que aumenta a legibilidade. Duas categorias de subprogramas s˜aoprocedimentos e fun¸c˜oes, que ser˜ao abordadas na sess˜ao 5.1.5.1 Procedimentos e fun¸c˜oesUma fun¸c˜ao ´e uma rela¸c˜ao que mapeia um dom´ınio de entrada em um dom´ınio de sa´ıda.Ela recebe parˆametros e retorna um valor.Um procedimento n˜ao retorna valor e ´e utilizado, normalmente, para executar um blocode comandos, e.g. para imprimir um texto. O c´odigo abaixo mostra a forma BNF que definema sintaxe das fun¸c˜oes e procedimentos.Essa abordagem foi adotado pois torna mais evidente as diferen¸cas entre esses conceitos.Em C/C++, por exemplo, os procedimentos s˜ao fundamentalmente fun¸c˜oes (que retornam otipo void), o que dificulta sua diferencia¸c˜ao. Usando essa abordagem torna-se mais naturala associa¸c˜ao entre procedimentos e comandos e entre fun¸c˜oes e express˜oes.<lista_de_parametros> -> <tipo> <nome_param>| <lista_de_parametros>, <tipo> <nome_param><declaracao_funcao> -> function <nome_funcao> (<lista_de_parametros>): <tipo_retorno> {<conjunto_instrucoes>return <valor>;}<declaracao_procedimento> -> procedure <nome_procedimento> (<lista_de_parametros>) {<conjunto_de_instrucoes>}5.2 ParˆametrosOs dados que poder˜ao ser colocados como argumentos em chamadas de fun¸c˜ao s˜ao tantode tipos da linguagem, listados e descritos nos problemas anteriores. Tamb´em ser´a poss´ıvelter nomes de subprogramas utilizados como parˆametro.25
  27. 27. CAP´ITULO 5. SUBPROGRAMAS 26Em sistemas de implementa¸c˜ao de linguagens de programa¸c˜ao ´e necess´ario incorporarm´etodos de resolu¸c˜ao de nomes. As linguagens que utilizam resolu¸c˜ao de escopo est´aticas˜ao chamadas de linguagens de escopo est´atico. As que utilizam resolu¸c˜ao escopo dinˆamicos˜ao chamadas de linguagens de escopo dinˆamico. No caso de linguagens que suportam fun¸c˜oesde alta ordem (aceitam fun¸c˜oes como parˆametros de fun¸c˜oes), temos trˆes formas de resolu¸c˜aode nomes. S˜ao elas vincula¸c˜ao rasa, vincula¸c˜ao profunda e ad hoc.Introduziremos esses conceitos com base na explica¸c˜ao da Figura 5.1.1. vincula¸c˜ao profunda: Ambiente da defini¸c˜ao do subprograma passado. Quando exe-cutamos o programa da Figura 5.1, o subpprograma F1 quando ´e chamado, temos umaexpress˜ao com a vari´avel A. O compilador busca a declara¸c˜ao de A, onde encontrar´ainforma¸c˜oes de sua vinculac˜ao. Assim, a busca se dar´a no subprograma F1. Caso n˜aoseja encontrado, a busca continua no bloco que o envolve, onde finalmente a declara¸c˜ao´e encontrada. Caso a busca n˜ao obtivesse sucesso, um erro de tipo seria lan¸cado. Essem´etodo de resoluc˜ao de nome ´e semelhante ao de vincula¸c˜ao est´atica.2. vincula¸c˜ao rasa: Ambiente de defini¸c˜ao do subprograma que ordena o subprogramapassado. Usando mais um vez, o exemplo da Figura 5.1. Quando chamamos F3, quechama F2 e por sua vez chama F1. O compilador ir´a fazer uma busca em F1 pelasinforma¸c˜oes de vincula¸c˜ao de A. Como n˜ao ´e encontrado ai, ele ir´a continuar a busca emF2, e ai achar´a a declara¸c˜ao de A. Caso a busca em F2 falhasse a busca continuariaem F3, e se mais uma vez n˜ao obtivesse sucesso, o compilador lan¸caria um erro dedeclara¸c˜ao. Esse m´etodo se assemelha ao m´etodo de vincula¸c˜ao dinˆamica.3. Vincula¸c˜ao ad hoc: Ambiente da instru¸c˜ao que passou o subpprograma como parˆametroreal. Por exemplo, quando executamos o c´odigo da Figura 5.1 temos a seguinte situa¸c˜ao:quando F3 chama F2, passando como parˆametro F1, a declara¸c˜ao do A ´e encontradoem F3.Figura 5.1: C´odigo para representa¸c˜ao dos conceitos de vinculac˜ao profunda, rasa e ad hoc.
  28. 28. CAP´ITULO 5. SUBPROGRAMAS 275.3 Formas de passagem de parˆametrosDentre as formas de passagem de parˆametro existentes, a nossa linguagem implementar´aa passagem de parˆametro por valor e a passagem de parˆametro por referˆencia.Passagem de parˆametro por valor: O valor do parˆametro real ´e usado para inici-alizar o parˆametro formal correspondente, que, ent˜ao, age como uma vari´avel local nosubprograma.A passagem por valor ´e normalmente implementada pela transferˆencia de dados reais(um valor real ´e transmitido fisicamente para o chamador, para o chamado, ou ambos),mas, ao inv´es disso, pode ser implementada transmitindo-se um caminho de acesso e,neste caso, a c´elula de mem´oria que cont´em o valor deve estar protegida contra grava¸c˜ao(read-only).Na passagem por valor, ´e feita uma c´opia dos valores dos parˆametros reais no espa¸code mem´oria reservado para a fun¸c˜ao chamada ou chamadora, ou at´e mesmo fora delas.A desvantagem deste m´etodo, se forem feitas transferˆencias f´ısicas, est´a no fato queser´a necess´ario armazenamento adicional para os parˆametros formais do subprogramachamado, ou em alguma ´area fora do subprograma chamado ou chamador. Em adi¸c˜ao,as opera¸c˜oes de armazenamento e transferˆencia podem ser custosas se o parˆametro forgrande, e.g. um vetor longo.Passagem de parˆametro por referˆencia: Transmite um caminho de acesso, nor-malmente apenas um endere¸co, para a fun¸c˜ao chamada. Isso possibilita o acesso `ac´elula de mem´oria que armazena o parˆametro real.Este m´etodo ´e mais eficiente que o descrito anteriormente, uma vez que n˜ao ´e necess´arioespa¸co duplicado, nem qualquer atividade de c´opia.Suas desvantagens s˜ao as seguintes:– O acesso aos parˆametros se dar˜ao de forma mais lenta, pois mais um n´ıvel deendere¸camento indireto ´e necess´ario.– Mudan¸ca inadvertidas e errˆoneas poder˜ao ser feitas no parˆametro real, caso sejaexigido somente uma comunica¸c˜ao unidirecional com a fun¸c˜ao chamada.– Cria¸c˜ao de apelidos. A passagem de referˆencia torna dispon´ıveis caminhos deacesso aos subprogramas chamados, ampliando o acesso deles `a vari´aveis n˜ao lo-cais. Neste m´etodo ´e poss´ıvel criar um apelido de diversas maneiras. Uma dessasmaneiras foi ilustrada nos problemas anteriores, quando definimos o que era ali-sing.5.4 Verifica¸c˜ao dos tipos de parˆametrosO m´etodo de prot´otipo ser´a utilizado, onde o tipo dos parˆametros formais s˜ao inclu´ıdos naassinatura da fun¸c˜ao ou procedimento, e s˜ao verificados tanto a quantidade de parˆametros
  29. 29. CAP´ITULO 5. SUBPROGRAMAS 28que foram passados quanto seus tipos. No caso particular de uma fun¸c˜ao requisitar umn´umero real (float) e receber uma vari´avel inteira (int), a convers˜ao ser´a feita (alargamento)e n˜ao haver´a problemas, enquanto que o caso contr´ario n˜ao ser´a permitido (estreitamento),pois pode ocorrer a perda de informa¸c˜oes na convers˜ao de reais para inteiros.5.5 Subprogramas sobrecarregados ou gen´ericosA linguagem suportar´a tanto a produ¸c˜ao de subprogramas gen´ericos quanto a desubprogramas polim´orficos. Este tipo de subprograma permite que n˜ao seja necess´ariocriar duas ou mais vers˜oes do mesmo para diferentes parˆametros. Al´em disso, a linguagemtamb´em dar´a suporte a cria¸c˜ao de subprogramas sobrecarregados, tendo em vista que,h´a casos em que ´e mais conveniente escrever duas ou mais fun¸c˜oes com parˆametros, retornoou quantidade de argumentos deferentes mas, com o mesmo nome.5.6 Sistema de Implementa¸c˜aoAlgumas linguagens imperativas tem como passo primordial a compila¸c˜ao. Isso permiteque o programador desenvolva programas que executem diretamente no hardware. Esse tipode sistema de implementa¸c˜ao, na maioria dos casos, torna o programa eficiente. Por´em,quando estamos desenvolvendo grandes sistemas, torna-se necess´ario compilar o programapor completo toda vez que forem feitas altera¸c˜oes, o que pode ser muito custoso.Nesse sentido, o sistema de implementa¸c˜ao utilizado na linguagem ´e a compila¸c˜ao se-parada. Um dos fatores que justificam a escolha ´e a conveniˆencia de que, mesmo em umsistema de m´edio e baixo porte, o programador tenha a possibilidade de compilar apenas osm´odulos alterados recentemente.
  30. 30. Cap´ıtulo 6Sistema de tipos da linguagemO sistema de tipos de uma linguagem ´e um aspecto de grande importˆancia para a escolhade uma linguagem para um determinado contexto. Ele quem define se uma linguagem faztodas as verifica¸c˜oes de tipos, tanto em tempo de compila¸c˜ao quanto em tempo de execu¸c˜ao,o que determina se a linguagem ´e ou n˜ao fortemente tipada.6.1 Principais caracter´ısticas do sistema de tiposA linguagem proposta ´e fortemente tipada, em vista do alto grau de confiabilidade re-querido pelas aplica¸c˜oes de dom´ınio cient´ıfico, o qual essa caracter´ıstica provˆe. Desse modo,qualquer erro de tipo ´e detectado durante a compila¸c˜ao ou em tempo de execu¸c˜ao.Os tipos dos parˆametros de fun¸c˜oes s˜ao verificados durante o tempo de execu¸c˜ao.6.2 Convers˜oes de TiposAs convers˜oes de tipos ser˜ao permitidas s˜ao impl´ıcitas e expl´ıcitas, abaixo ambas s˜aodescritas.Impl´ıcitas: Somente convers˜oes de alargamento ser˜ao permitidas. Ou seja, o tipo sofrer´aconvers˜ao impl´ıcita somente quando o tipo para o qual esta sendo feita a convers˜ao contenhaa faixa de valores do tipo convertido.Expl´ıcitas: As convers˜oes expl´ıcitas s˜ao oferecidas pela linguagem. Elas ser˜ao usadaspelo usu´ario atrav´es de fun¸c˜oes. Como por exemplo a fun¸c˜ao stringToInt(a:string):int.6.3 Regras de compatibilidade de tiposAs regras de compatibilidade de tipos adotadas pela linguagem s˜ao compatibilidade pornome e compatibilidade por estrutura. A compatibilidade entre tipos anˆonimos (cujo tipon˜ao ´e expl´ıcito na declara¸c˜ao, por exemplo vetor) deve ser feitas atrav´es da compatibilidade29
  31. 31. CAP´ITULO 6. SISTEMA DE TIPOS DA LINGUAGEM 30por estruturas. J´a as estruturas de dados criadas pelo usu´ario a compatibilidade ´e verificadapor nome. Abaixo explicamos as regras descritas acima.Compatibilidade por nome: Duas vari´aveis s˜ao compat´ıveis por nome se tiverem omesmo nome de tipo, ou estiverem na mesma declara¸c˜ao. Essa regra de compatibilidade ´ede f´acil implementa¸c˜ao, embora seja altamente restritiva.Compatibilidade por estrutura: Duas vari´aveis s˜ao compat´ıveis estruturalmente sepossu´ırem estruturas idˆenticas. Essa regra de compatibilidade ´e mais flex´ıvel que a primeira,por´em ´e mais dif´ıcil de implementar.

×