31
Projeto de uma Linguagem de Programa¸ c˜ao Caio C´ esar, Gabriel Vasiljevic, Jean Silva, Victor 20 de maio de 2013

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

Embed Size (px)

DESCRIPTION

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

Citation preview

Page 1: Documentação de uma linguagem de progração

Projeto de uma Linguagem de Programacao

Caio Cesar, Gabriel Vasiljevic, Jean Silva, Victor

20 de maio de 2013

Page 2: Documentação de uma linguagem de progração

Sumario

1 Principais caracterısticas da linguagem 21.1 Domınio de Aplicacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.2 Caracterısticas da linguagem . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

2 Valores, tipos e expressoes 42.1 Tipos Primitivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42.2 Tipos Compostos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.3 Sistema de tipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.4 Tipos definidos pelo usuario . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.5 Representacao dos valores de cada tipo . . . . . . . . . . . . . . . . . . . . . 6

2.5.1 Designadores dos tipos primitivos . . . . . . . . . . . . . . . . . . . . 82.5.2 Forma BNF de declaracao de um tipo na Linguagem . . . . . . . . . 8

2.6 Expressoes da linguagem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.6.1 Operadores Aritmeticos . . . . . . . . . . . . . . . . . . . . . . . . . 92.6.2 Incremento e decremento . . . . . . . . . . . . . . . . . . . . . . . . . 92.6.3 Operadores Relacionais . . . . . . . . . . . . . . . . . . . . . . . . . . 92.6.4 Operadores logicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.6.5 Operadores bit-a-bit . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

3 Variaveis e comandos 113.1 Modelo de armazenamento de valores . . . . . . . . . . . . . . . . . . . . . . 113.2 Uso de variaveis na Linguagem . . . . . . . . . . . . . . . . . . . . . . . . . 113.3 Caracterısticas dos arrays da linguagem . . . . . . . . . . . . . . . . . . . . . 123.4 Escopo e tempo de vida das variaveis . . . . . . . . . . . . . . . . . . . . . . 133.5 Comandos da linguagem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

3.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 Excecoes . . . . . . . . . . . . . . . . . . . . . . . . . 17

3.6 Alocacao de memoria das veriaveis compostas . . . . . . . . . . . . . . . . . 17

1

Page 3: Documentação de uma linguagem de progração

4 Vinculacoes e regras de escopo 184.1 Bindings da linguagem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184.2 Aliasing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184.3 Estrutura de blocos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184.4 Regras de visibilidade e resolucao de escopo . . . . . . . . . . . . . . . . . . 19

5 Subprogramas 205.1 Procedimentos e funcoes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205.2 Parametros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205.3 Formas de passagem de parametros . . . . . . . . . . . . . . . . . . . . . . . 225.4 Verificacao dos tipos de parametros . . . . . . . . . . . . . . . . . . . . . . . 225.5 Subprogramas sobrecarregados ou genericos . . . . . . . . . . . . . . . . . . 235.6 Sistema de Implementacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

6 Sistema de tipos da linguagem 246.1 Principais caracterısticas do sistema de tipos . . . . . . . . . . . . . . . . . . 246.2 Conversoes de Tipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246.3 Regras de compatibilidade de tipos . . . . . . . . . . . . . . . . . . . . . . . 24

Page 4: Documentação de uma linguagem de progração

Capıtulo 1

Definicao das diretrizes de uso ecaracterısticas principais da linguagemde programacao

1.1 Domınio de Aplicacao

A linguagem proposta e baseada em C e FORTRAN. Seu domınio de aplicacao e cientıfico,o que implica que alem das estruturas de dados simples, ela tambem dispora de estruturasque possibilitam a manipulacao de grandes quantidades de dados e de alta precisao numericapara as computacoes com numeros reais.

A linguagem tera como publico alvo matematicos e cientistas, que precisam trabalharcom numeros muito grandes, altas precisoes e boas estruturas de controle.

1.2 Caracterısticas da linguagem

Ha algumas caracterısticas que determinam o quao boa e uma linguagem de programacao,tais como:

. Legibilidade: Um dos criterios mais importantes. Os programas desenvolvidos numadeterminada linguagem de programacao devem ser faceis de serem lidos e compreen-didos. A linguagem a ser especificada e simples e dispoe de um pequeno numero decomponentes basicos, 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 confiavel se ela se comporta de acordocom suas especificacoes. A verificacao de tipos e de extrema importancia e nossalinguagem fornece essa verificacao, o que nao ocorre em linguagens nao-fortementetipadas, e.g. Phyton. A linguagem oferece tambem a capacidade de tratamento deexcecoes em tempo de execucao, o que existe em Java, C++ e C#, ao contrario de C.

3

Page 5: Documentação de uma linguagem de progração

CAPITULO 1. PRINCIPAIS CARACTERISTICAS DA LINGUAGEM 4

A linguagem C dispoe de apelidos. Um exemplo de seu uso e o union, que reserva a umamesma area de memoria para duas ou mais variaveis. Essa ferramente e amplamenteconsiderada perigosa e, portanto, nao sera contemplada na linguagem a ser projetada.

. Capacidade de escrita: A linguagem e de facil escrita e tera pouca ortogonalidade,fazendo com que a codificacao de um programa nessa linguagem seja de escrita maisobjetiva. As restricoes na combinacao dos tipos de dados e estruturas basicas devido apouca ortogonalidade evitara problemas de incompatibilidade de tipos que sao difıceisde serem percebidas tanto pelo programadores quanto pelo compilador.

Assim como em Java, C e C++, a linguagem proposta e Case Sensitive1. C nao dispoede algumas estruturas de dados mais complexas como, por exemplo, conjuntos, listas, pilhase filas enquanto a nossa oferece estes tipos como primitivos alem dos disponıveis em C.Outra novidade e o tipo primitivo bigInt que comporta um numero inteiro bem maior queo convencional.

O fator que mais influencia na eficiencia dos programas escritos na linguagem proposta e aflexibilidade de baixo nıvel herdada de C. E os fatores que mais influenciam na produtividadedo programador sao a legibilidade, a capacidade de escrita e forma como o erro se apresentaa ele durante os testes, permitindo a correcao mais rapida dos erros.

Levando em conta o domınio de aplicacao da nossa linguagem, foi escolhido o sistemade implementacao por compilacao. A razao disso e que este sistema confere uma maioreficiencia aos programas, requisito esse de alta relevancia no domınio cientıfico em funcao danecessidade de realizar computacoes de alto custo.

Para que nossa linguagem atinja o sucesso e justifique sua criacao, e necessaria umaanalise cuidadosa das necessidades de seu domınio de aplicacao. As linguagens COBOL eFORTRAN, por exemplo, atendem suficientemente bem as necessidades de seus respectivosdomınios. As linguagens posteriores nao trouxeram modificacoes realmente relevantes aosrecursos que estas ja ofereciam. Deve-se tentar suprir todas estas necessidades, tentado fazerum balanceamento entre os pontos fracos e fortes da linguagem proposta.

1 Case sensitive, do ingles “caixa alta”, significa que o sistema diferencia letras maiusculas e minusculas.Por exemplo, a palavra “variavel” e diferente de “Variavel” ou “VARIAVEL”, mesmo tendo a mesma escrita.

Page 6: Documentação de uma linguagem de progração

Capıtulo 2

Valores, tipos e expressoes

2.1 Tipos Primitivos

Tipos primitivos sao tipos que nao sao derivados de nenhum outro; sao, de certa forma,estruturas atomicas da linguagem. Abaixo listamos os tipos primitivos oferecidos pela lin-guagem, e na sessao 2.5 os detalharemos.

. char - caractere

. short - inteiro curto

. int representando o tipo inteiro

. long - inteiro de faixas maiores (dobro do int)

. bigInt - inteiro de maior faixa que long

. bool

. float - ponto flutuante

. double - precisao dupla para ponte flutuante

. string - cadeia de caracteres

. unsigned int - inteiro nao sinalizado

. unsigned long - long nao sinalizado

. unsigned bigInt - bigInt nao sinalizado

. unsigned short - short nao sinalizado

. unsigned float - float nao sinalizado

. unsigned double - double nao sinalizado

5

Page 7: Documentação de uma linguagem de progração

CAPITULO 2. VALORES, TIPOS E EXPRESSOES 6

. complex - representando um numero complexo

. < tipo > * - guarda o endereco de uma posicao de memoria;

2.2 Tipos Compostos

Tipos compostos sao aqueles construıdos a partir de tipos primitivos ou ate mesmo deoutros tipos compostos. Como exemplo de tipos compostos na nossa linguagem temos:

. Conjunto (set);

. Fila (queue);

. Pilha (stack);

. Lista (list);

. Vetor;

. Struct;

Alem desses, vale destacar um tipo composto bastante peculiar, que e o tipo recursivo.Nessa categoria, se encaixam aqueles tipos que sao compostos por elementos de mesmo tipo.Um tipo recursivo classico e a lista, onde cada elemento vai referenciar um proximo elementoda mesma natureza. Isso e possıvel com a utilizacao de ponteiros. Arvores binarias e Grafostambem seguem a mesma linha de raciocınio, mas esses ultimos nao sao suportados pelalinguagem.

A construcao de um tipo recursivo e feita da seguinte forma, segundo a forma BNF:

<declarac~ao_tipo_recursivo> -> struct <nome_do_tipo> {

<conjunto_de_declarac~oes>

<nome_do_tipo> * <nome_do_atributo>;

};

Exemplo de uso:

struct ListaT{

int info;

ListaT * prox;

};

Codigo 1: Estrutura de lista recursiva

No codigo 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 contem outra lista, que por sua veztem outra, e assim por diante, e dessa forma conseguimos fazer construcoes recursivas nalinguagem.

Page 8: Documentação de uma linguagem de progração

CAPITULO 2. VALORES, TIPOS E EXPRESSOES 7

2.3 Sistema de tipos

A linguagem proposta sera fortemente tipada. Diferentemente de C e C++, que naofazem a verificacao de tipos de parametros de uma funcao. Destarte, nao havera conversoesimplıcitas de tipo (coercao). Quanto a compatibilidade, usaremos a combinacao de doismetodos: a compatibilidade de nomes e estruturas. Escolhemos esta abordagem por acharmosmais segura e pratica, alem de mais eficiente, pois, no melhor caso, nao precisaremos compararas estruturas das variaveis, e no pior so verificamos os nomes.

Esse assunto e abordado de forma mais detalhada no capıtulo 6.

2.4 Tipos definidos pelo usuario

Muitas vezes o usuario deseja criar seus proprios tipos, e isso e possıvel usando a primitivastruct. E possıvel, ainda, a definicao de estruturas genericas, nas quais possamos declararuma variavel ora de um tipo, ora de outra, sem a necessidade de implementar mais de umestrutura de tipo (ver exemplo do codigo 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;

}

Codigo 2: Definicao de tipos e funcoes genericas atraves do uso do templates

2.5 Representacao dos valores de cada tipo

Nesta sessao 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 nao sinalizado (unsigned char) compreende uma faixa de 0 a255. Para a representacao de cada caractere usamos a tabela ASCII.

char c = ’a’;

unsigned d = ’b’;

short: E representado na base binaria por 16 bits = 2 bytes. Usamos a representacao decomplemento de 2 para permitirmos a representacao de numeros negativos. O intervalo decobertura desse e de −32768 a 32767, para o unsinged short temos de 0 a 65535.

Page 9: Documentação de uma linguagem de progração

CAPITULO 2. VALORES, TIPOS E EXPRESSOES 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("%d\n", getMax(pi));

write("%d\n", getMax(pf));

return 0;

}

Codigo 3: Uso do tipo generico 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,ja o nao sinalizado 0 a 4294967295.

int n = 50;

unsigned int m = 8;

long: Sua representacao e da mesma forma que o tipo int, porem com uma faixa devalores superior aos inteiros anteriores: 8 bytes. A faixa de representacao do tipo inteirolongo e de −263 a 263 − 1. 0 nao 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 representacao do bigInt e a seguinte −2127 a 2127−1,e nao 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 serarepresentado por todos os 8 bits do byte em 1, caso contrario todos em 0.

Page 10: Documentação de uma linguagem de progração

CAPITULO 2. VALORES, TIPOS E EXPRESSOES 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 fracionaria. 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 deprecisao (8 bytes). A faixa de valores e de ±1.7e± 308.

double a = 5.65

complex: O tipo complexo utilizara dois numeros reais, um para representar sua partereal e o outro a parte imaginaria e tera 8bytes e a faixa sera de −264 a 264 − 1.

complex c(5.5, 7.8);

string: O tipo string sera uma lista encadeada de caracteres. Para esta lista, as operacoesde concatenacao e conversao para uma cadeia de caractere estarao fundamentadas na lingua-gem.

string s = "cplusminus.com";

vetor: Como um vetor aponta para um bloco de memoria, sua implementacao se da porum ponteiro para apontar ao primeiro bloco de memoria alocado.

int v[10];

int vet[3] = {1, 2, 3};

int mat[2][2] = {1, 0;

0, 1};

set: Os conjuntos serao armazenados com uma cadeia de bits internamente. Quando em1, o bit significa que o elemento esta presente e, caso contrario, nao estara. 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:

1100010001000001

Um conjunto tera um tamanho de 4 bytes, ou seja, sera possıvel representar um conjuntocom no maximo 32 elementos.

Page 11: Documentação de uma linguagem de progração

CAPITULO 2. VALORES, TIPOS E EXPRESSOES 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 referencias sao geralmente representados por valores unicos, arma-zenados em celulas de memoria de 2 ou 4 bytes, dependendo da arquitetura do computador.Na maioria dos computadores, os microprocessadores sao baseados na arquitetura intel; as-sim, os ponteiros e as referencias sao representadas como pares de palavras de 16 bits, umapara cada uma das duas partes de um endereco (segmento e deslocamento(offset)).

int * prt;

char * pt;

short * p;

2.5.1 Designadores dos tipos primitivos

Tabela 2.1: Designadores dos tipos primitivos da linguagemNome Descricao Tamanho Faixachar Caractere 1byte −128 a 127 e unsigned: 0 a 255short Inteiro curto 2bytes −32768 a 32767 e unsigned: 0 a

65535int Inteiro 4bytes −2147483648 a 2147483647 e un-

signed: 0 a 4294967295long Inteiro longo 8bytes −263 a 263 − 1 e unsigned: 0 a

264 − 1bigInt Inteiro muito longo 16bytes −2127 a 2127 − 1 e unsigned: 0 a

2128 − 1bool Valor booleano. Pode assumir dois va-

lores: true ou false1byte true ou false

float Pronto flutuante 4bytes ±3.4e± 38double Precisao dupla do ponto flutuante 8bytes ±1.7e± 308

complex Numeros complexos 8bytes −264 a 264 − 1

Page 12: Documentação de uma linguagem de progração

CAPITULO 2. VALORES, TIPOS E EXPRESSOES 11

2.5.2 Forma BNF de declaracao 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 Expressoes da linguagem

2.6.1 Operadores Aritmeticos

Os cinco operadores se referem as seguintes, respectivas, operacoes: adicao ( + ), sub-tracao ( - ), multiplicacao ( * ), divisao ( / ) e mod ou resto ( % ). Estes operadores atuamsobre dois operandos, por este motivos, sao classificados como binarios.

2.6.2 Incremento e decremento

Os operadores (++) e (−−) respectivamente incremento, aumenta o valor da variavel em1, e decremento, diminui o valor da variavel em 1.

2.6.3 Operadores Relacionais

Estes operadores representam as seguintes relacoes:

. Igualdade ( == ): A igualdade e uma operacao booleana que retorna o valor true,caso dois operadores sejam considerados iguais, segundo um criterio de verificacao, efalse, caso contrario.

. Diferenca ( ! = ): A diferenca retorna false, nos casos em que a igualdade retornariatrue, e retorna true, nos casos contrarios.

. Maior ( > ): A comparacao maior retorna true, caso o primeiro operando seja maiorque o segundo, e false, quando o segundo operando e maior que o primeiro.

. Menor (< ): A comparacao menor retorna true, quando o primeiro operando e menorque o segundo, e false, quando o contrario acontece.

Page 13: Documentação de uma linguagem de progração

CAPITULO 2. VALORES, TIPOS E EXPRESSOES 12

. Maior ou igual (>=): A comparacao maior ou igual e a juncao de duas comparacoes,esta comparacao retorna true, sempre que pelo menos uma das duas return true, e false,caso contrarios.

. Menor ou igual ( <= ): A comparacao menor ou igual tem o mesmo funcionamentoda comparacao maior ou igual, retornando true, quando o primeiro operando e menorou igual ao segundo.

2.6.4 Operadores logicos

A seguir uma breve vinculacao dos operadores com seus respectivos significados booleanos.

. O operador “ ! ” representa a funcao logica NOT.

. O operador “ && ” representa a funcao logica AND.

. Por fim, o operador “||” representa a funcao logica OR.

2.6.5 Operadores bit-a-bit

Estes operadores sao caracterizados por fazer operacoes com bit e bytes (palavras de8 bit). Podemos reconhecer alguns operadores logicos 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.

Page 14: Documentação de uma linguagem de progração

Capıtulo 3

Variaveis e comandos

3.1 Modelo de armazenamento de valores

Visando permitir uma maior flexibilidade a escrita dos programadores, serao permitidosos seguintes modelos de armazenamento de valores na memoria:

(a) Estatico: Em varias situacoes, variaveis globalmente acessıveis sao de grande utilidade.O modelo de vinculacao estatica permite isso da forma mais eficiente (enderecamentodireto). Este modelo vıncula a variavel um determinado endereco de armazenamentoantes que o programa inicia, o qual permanece ate o fim do programa.

(b) Dinamico na pilha: As variaveis dinamicas na pilha sao aquelas em que o tipo evinculado estaticamente, mas a vinculacao de armazenamento e feita no momento emque o programa atinge a declaracao da variavel, em tempo de execucao. Esse modelo e orequisito basico para permitir subprogramas recursivos. Devido a sobretaxa de alocacaoe desalocacao em tempo de execucao, este modelo perde em desempenho.

(c) Dinamico no heap explıcitas: O uso de variaveis dinamicas no heap permite aoprogramador interagir em mais baixo nıvel com blocos de memoria. A alocacao e feitaatraves de operadores ou funcoes definidos(as) na linguagem e a manipulacao e feitaatraves de ponteiros ou referencias. Esse modelo se aplica perfeitamente na definicaode estruturas dinamicas, mas a manutencao dos blocos envolve riscos, que passam a serresponsabilidade do programador.

3.2 Uso de variaveis na Linguagem

Na nossa linguagem, ao se declarar uma variavel, e vinculado um valor aleatorio a ela (lixoda memoria). Isso pode ser evitado realizando-se a inicializacao da variavel no momento desua declaracao, tornando responsabilidade do programador a verificacao dessa necessidade.Alem disso, e possıvel vincular valores dinamicamente a variavel atraves de operacoes deatribuicao ou de leitura. Quanto a atribuicao de variaveis compostas, no caso dos arrays,

13

Page 15: Documentação de uma linguagem de progração

CAPITULO 3. VARIAVEIS E COMANDOS 14

devera ser especificado o ındice da posicao do array a ter seu valor atualizado. De modo que,esse ındice denota o deslocamento do ponteiro na memoria em relacao ao endereco base doarray. Dessa forma, o programador tem uma forma mais intuitiva de manipular os arrays.No caso dos tipos definidos atraves de structs, nao sera possıvel fazer uma atribuicao diretada forma < tipo composto >=< outro tipo composto >. Para este fim, a atribuicao deve serfeita campo a campo.

Na forma BNF logo abaixo, apresentamos a forma geral da declaracao de uma variavel,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 linguagem

Os elementos do array sao referenciados por meio de seu endereco base, e de um ou maisındices do tipo inteiro. A sintaxe da referencia 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 posicoes invalidas. Os arrays serao categorizados como:

(a) Estatico: a faixa de valores do ındice e a alocacao de armazenamento sao vinculadosestaticamente antes da execucao do programa (eficiente).

(b) Fixo dinamico na pilha: a faixa de valores do ındice e vinculada estaticamente, masa alocacao e feita no momento da elaboracao da declaracao (melhor uso do espaco dearmazenamento).

(c) Dinamico na pilha: a faixa de valores do ındice e o espaco de enderecamento saovinculados dinamicamente. Ocorrendo a vinculacao, sua faixa de valores do ındice e seuarmazenamento alocado permanecem os mesmos ate o fim de seu tempo de vida (maiorflexibilidade em relacao ao array fixo dinamico na pilha)

(d) Dinamico no heap: semelhante ao dinamico na pilha, exceto pela possibilidade da faixade valores do ındice e seu armazenamento alocado serem modificados qualquer numerode vezes (ainda mais flexıvel).

Para fornecer maior poder de expressao ao programador, e permitido a definicao de umalista de ındices com tamanho sem imposicao de limites de tamanho para arrays estaticos.

Page 16: Documentação de uma linguagem de progração

CAPITULO 3. VARIAVEIS E COMANDOS 15

Por outro lado, para evitar maiores problemas com eficiencia e manipulacao de ponteiros, elimitado para sete o tamanho da lista de ındices para arrays dinamicos de heap. Por ultimomas nao menos importante, e permitida a inicializacao dos elementos do array no momentode sua declaracao se ele for estatico, e, para facilitar a manipulacao e melhorar o desempenhode referenciamento, os arrays poderao ser subdivididos em fatias, o que possibilita o uso demenos expressoes de ındice do que se fosse referenciado o array inteiro.

3.4 Escopo e tempo de vida das variaveis

A variavel global (estatica) quando declarada estara acessıvel desde o inıcio do programaate o final do mesmo. A vinculacao dessa variavel a um espaco de memoria e feita antes daexecucao do programa. Uma variavel local estara acessıvel somente durante a execucao dafuncao onde ela foi declarada. Nesse caso, a variavel e vinculada a um espaco de memoria emtempo de execucao, mas logo quando essa funcao e finalizada, esse espaco de memoria quefoi alocado para a variavel e desalocado. E importante nao confundirmos a acessibilidade deuma variavel com o seu escopo. Em geral, e muito comum pensarmos que o escopo de umavariavel estatica e somente durante a execucao do programa inteiro, mas isso nao e verdade;podemos declarar uma variavel estatica dentro de uma funcao com o auxılio do modificadorstatic, e a mesma nao estar acessıvel ao longo da execucao do programa inteiro. O queacontece e que a variavel e estatica e, mesmo apos o termino da funcao, ela continua alocada,mas nao permanece acessıvel.

3.5 Comandos da linguagem

Nessa sessao apresentaremos para cada comando sua forma BNF, e em seguida, umexemplo de uso do comando em questao.

3.5.1 Entrada e Saıda

3.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;

Page 17: Documentação de uma linguagem de progração

CAPITULO 3. VARIAVEIS E COMANDOS 16

write("%i\n", soma);

return 0;

}

3.5.2 Estruturas de Controle

3.5.2.1 Condicional

3.5.2.1.1 Comando if

Forma 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 positivo\n", n);

} else if(n < 0){

write("%d eh um numero negativo\n", n);

} else {

write("%d eh zero\n", n);

}

return 0;

}

3.5.2.1.2 Comando switch-case

Forma Normal

<comando_switch-case> -> switch( <var_escolha> ) {

case <op1>:

<lista_de_comandos>

break;

case <op2>:

<lista_de_comandos>

Page 18: Documentação de uma linguagem de progração

CAPITULO 3. VARIAVEIS E COMANDOS 17

break;

...

default:

<lista_de_comandos>

break;

}

import io;

function main(): int {

string op;

read("%s", &op);

switch(op) {

case "um":

write("1\n");

break;

case "dois":

write("2\n");

break;

case "tres":

write("3\n");

break;

default:

write("qwerty\n");

break;

}

return 0;

}

3.5.2.2 Repeticao

3.5.2.2.1 Comando for

Forma 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;

}

Page 19: Documentação de uma linguagem de progração

CAPITULO 3. VARIAVEIS E COMANDOS 18

3.5.2.3 Comando for-each

3.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 while

3.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-while

3.5.2.5.1 Forma Normal

Page 20: Documentação de uma linguagem de progração

CAPITULO 3. VARIAVEIS 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 sao descritos na subsecoes seguintes.

3.5.3.1 Comando break

No codigo 3.5.3.1 abaixo, que ilustra o uso do break, as linhas 4 e 5 sempre serao exe-cutadas ate que i = 10, quando a condicao da linha 5 e satisfeita e as linhas 6 e 7 seraoexecutadas. A saıda do programa sera os numeros de 1 a 10 e uma quebra de linha. Na linha7 o comando break e executado e o fluxo de execucao e desviado para a proxima instrucao,fazendo com que o programa nao entre no laco novamente.

int i = 0;

while(true) {

i++;

write("%d ", i);

if (i == 10) {

write("\n");

break;

}

}

Codigo 4: Uso do break

3.5.3.2 Comando continue

No codigo 3.5.3.2, que exibe um trecho de codigo com o emprego do comando continue,enquanto i < 10 a linha 5 sera executada. O comando continue faz com que o programavolte a condicao do loop que o engloba, (linha 1) ignorando as linhas abaixo dele (linhas 6 e7), ou seja, o programa entrara em loop mais uma vez. Quando i = 10 o programa escreveuma quebra de linha e encerra o loop com o comando break.

Page 21: Documentação de uma linguagem de progração

CAPITULO 3. VARIAVEIS E COMANDOS 20

while(true) {

i++;

write("%i ", i);

if (i < 10)

continue;

write("\n");

break;

}

Codigo 5: Trecho de codigo com o uso do continue.

3.5.4 Primitivas de saıdas dos blocos (escapes)

3.5.4.1 Comando return

O comando return serve para retornar o que uma funcao se propos a computar. Comoexemplo temos o trecho de codigo do Codigo 3.5.4.1, onde e definida uma funcao par(i:int):

bool que retorna true se i for par e false caso contrario. Se i for par a linha 3 e executada eo subprograma e finalizado. Caso contrario, a linha 4 e executada e o programa e finalizado.Veja que uma funcao pode somente retornar um valor por execucao.

function par(i: int): bool {

if (i % 2 == 0)

return true;

return false;

}

Codigo 6: Trecho de codigo com o uso do return.

3.5.4.2 Comando exit

O comando exit e usado para finalizar o programa como um todo. Vejamos o codigo3.5.4.2, a saıda sera:

msg de teste

Saindo ...

Na funcao f(), na linha 5 temos um comando exit(0), pontanto tudo que esta apos achamada dessa funcao na main() nao sera executado, pois o programa finaliza sua execucaoquando o comando exit(0) e usado. Se comentarmos a linha 11 do programa sua saıda seriaa seguinte:

msg de teste

Saindo ...

msg de teste 2

Page 22: Documentação de uma linguagem de progração

CAPITULO 3. VARIAVEIS E COMANDOS 21

import io;

procedure f() {

write("Saindo ... \n");

exit(0);

}

function main(): int {

write("msg de teste\n");

f();

write("msg de teste 2\n");

return 0;

}

Codigo 7: Trecho de codigo com o uso do exit.

3.5.5 Tratamento de Excecoes

Nossa linguagem usara a estrutura de try-catch como forma de tratamento de excecoes,de forma semelhante a C++. As excecoes serao definidas como os tipos presentes na lingua-gem, podendo, assim, o proprio usuario criar suas excecoes. A seguir (codigo 3.5.5), tem-seum exemplo de um codigo utilizando tratamento de excecoes.

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);

}

}

Codigo 8: Trecho de codigo com o uso do try-catch.

3.6 Alocacao de memoria das veriaveis compostas

Para as variaveis compostas homogeneas, como os vetores, sua alocacao sera em blocos dememoria sequenciais, e seu escopo sera como o de uma variavel comum. Seu referenciamentosera em relacao ao primeiro bloco de memoria alocado por ele. Ou seja, o referenciamentoda proxima variavel da sequencia sera apenas o incremento unitario da posicao da memoria.Quanto a passagem destas variaveis por parametro, sera feito por referencia. As variaveiscompostas heterogeneas (registros) tambem serao alocadas sequencialmente, mas o acesso

Page 23: Documentação de uma linguagem de progração

CAPITULO 3. VARIAVEIS E COMANDOS 22

aos campos se da atraves de um deslocamento, que e guardado junto ao campo, ja que otamanho de cada bloco nao e necessariamente igual. Seu referenciamento e feito como o deuma variavel comum, ou seja, copiando seus atributos. O mesmo vale para seu escopo - igualao de uma variavel comum.

Page 24: Documentação de uma linguagem de progração

Capıtulo 4

Vinculacoes e regras de escopo

4.1 Bindings da linguagem

Quanto a vinculacao de tipos, que esta associada a declaracao de variaveis, sera, sem-pre que possıvel, feita estaticamente devido ao sistema de implementacao escolhido, a com-pilacao, e a maior eficiencia dessa abordagem. Sendo assim, a vinculacao de tipos seraem tempo de compilacao. Quanto a vinculacao de armazenamento, temos como assunto,variaveis estaticas,stack-dinamicas e heap-dinamicas. As variaveis estaticas tem seu espacode armazenamento vinculado em tempo de compilacao. E as variaveis stack-dinamicas eheap-dinamicas tem seus epacos de armazenamento vinculados em tempo de execucao mas,nao da mesma forma. Variaveis stack-dinamicas sao armazenadas temporariamente em umapilha e sua retirada e feita pela linguagem, dependendo de seu ambiente de referenciamento.Variaveis heap-dinamica sao armazenadas numa heap e sua retirada e responsabilidade doprogramador. As caracterısticas mais basicas e elementares da linguagem, que estao sendodefinidas durante esta disciplina, estao sendo vinculadas em tempo de projeto.

4.2 Aliasing

Na linguagem havera dois casos do uso de aliasing, os quais sao explicados abaixo. Oprimeiro caso, e mais evidente em linguagens que dao suporte a aliasing, e o uso de referencia.Por exemplo, quando usamos passagem de parametros por referencia, passam a existir doisnomes vinculados ao mesmo espaco de memoria, o que caracteriza o aliasing. O uso deponteiros pode ser tambem considerado aliasing em alguns casos. Caracterizamos seu usocomo aliasing quando dois ponteiros estao referenciando um mesmo bloco de memoria. Estetipo de apelido e indireto, pois os ponteiros em si nao sao aliasing, mas sua referencia o e.

4.3 Estrutura de blocosPara definirmos os escopos das variaveis usamos blocos, que sao, por sua vez, definidos

pelas chaves, ““ e “”. Segue abaixo a forma BNF.

23

Page 25: Documentação de uma linguagem de progração

CAPITULO 4. VINCULACOES 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 declaracoes de funcoes sao comandos dalinguagem.

4.4 Regras de visibilidade e resolucao de escopo

Quanto ao escopo estatico, as variaveis declaradas nos blocos ancestrais serao visıveis atodos os blocos internos a eles. Ja o contrario nao ocorre: variaveis declaradas nos blocos maisinternos nao sao visıveis a seus ancestrais. Quando o compilador encontra um identificador deuma variavel, e necessario saber a qual variavel ele se refere. Para tanto, e preciso localizar asua instrucao de declaracao. Essa busca comeca no bloco em que foi encontrada a referencia avariavel. Caso a variavel nao seja encontrada neste bloco, a busca se segue em seu pai estatico(bloco que engloba este bloco), e assim por diante. Caso nao haja mais nenhum ancestralestatico para proceder com a busca o compilador ira retornar um erro de declaracao. Quantoao escopo dinamico, essa busca se da de maneira diferente, uma vez que no escopo estaticoa busca pela instrucao de declaracao da variavel e baseada na declaracao dos blocos, e nodinamico e baseado na ordem inversa de chamada de funcoes. Consideremos a seguintesituacao: a funcao main fm chama uma funcao f2, que por sua vez chama uma funcaof1. Consideremos tambem que o compilador encontrou uma referencia a uma variavel x emf1. Dessa forma a instrucao de declaracao de x sera buscada na ordem de chamada dessasfuncoes. Primeiro o compilador verifica se a instrucao de declaracao se encontra na f1, casocontrario, a busca continua em f2, e assim por diante. Caso nao seja encontrada, o compiladorretornara um erro de declaracao. Analizando essas duas formas de escopo, concluımos quenossa liguagem deve ser de escopo estatico.

Page 26: Documentação de uma linguagem de progração

Capıtulo 5

Subprogramas

Subprogramas sao uma das formas de abstracao presente na linguagem, que nos for-nece abstracao de processo, cujo conceito e de suma importancia para uma linguagem deprogramacao, uma vez que aumenta a legibilidade. Duas categorias de subprogramas saoprocedimentos e funcoes, que serao abordadas na sessao 5.1.

5.1 Procedimentos e funcoes

Uma funcao e uma relacao que mapeia um domınio de entrada em um domınio de saıda.Ela recebe parametros e retorna um valor.

Um procedimento nao retorna valor e e utilizado, normalmente, para executar um blocode comandos, e.g. para imprimir um texto. O codigo abaixo mostra a forma BNF que definema sintaxe das funcoes e procedimentos.

Essa abordagem foi adotado pois torna mais evidente as diferencas entre esses conceitos.Em C/C++, por exemplo, os procedimentos sao fundamentalmente funcoes (que retornam otipo void), o que dificulta sua diferenciacao. Usando essa abordagem torna-se mais naturala associacao entre procedimentos e comandos e entre funcoes e expressoes.

<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 Parametros

Os dados que poderao ser colocados como argumentos em chamadas de funcao sao tantode tipos da linguagem, listados e descritos nos problemas anteriores. Tambem sera possıvelter nomes de subprogramas utilizados como parametro.

25

Page 27: Documentação de uma linguagem de progração

CAPITULO 5. SUBPROGRAMAS 26

Em sistemas de implementacao de linguagens de programacao e necessario incorporarmetodos de resolucao de nomes. As linguagens que utilizam resolucao de escopo estaticasao chamadas de linguagens de escopo estatico. As que utilizam resolucao escopo dinamicosao chamadas de linguagens de escopo dinamico. No caso de linguagens que suportam funcoesde alta ordem (aceitam funcoes como parametros de funcoes), temos tres formas de resolucaode nomes. Sao elas vinculacao rasa, vinculacao profunda e ad hoc.

Introduziremos esses conceitos com base na explicacao da Figura 5.1.

1. vinculacao profunda: Ambiente da definicao do subprograma passado. Quando exe-cutamos o programa da Figura 5.1, o subpprograma F1 quando e chamado, temos umaexpressao com a variavel A. O compilador busca a declaracao de A, onde encontrarainformacoes de sua vinculacao. Assim, a busca se dara no subprograma F1. Caso naoseja encontrado, a busca continua no bloco que o envolve, onde finalmente a declaracaoe encontrada. Caso a busca nao obtivesse sucesso, um erro de tipo seria lancado. Essemetodo de resolucao de nome e semelhante ao de vinculacao estatica.

2. vinculacao rasa: Ambiente de definicao 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 ira fazer uma busca em F1 pelasinformacoes de vinculacao de A. Como nao e encontrado ai, ele ira continuar a busca emF2, e ai achara a declaracao de A. Caso a busca em F2 falhasse a busca continuariaem F3, e se mais uma vez nao obtivesse sucesso, o compilador lancaria um erro dedeclaracao. Esse metodo se assemelha ao metodo de vinculacao dinamica.

3. Vinculacao ad hoc: Ambiente da instrucao que passou o subpprograma como parametroreal. Por exemplo, quando executamos o codigo da Figura 5.1 temos a seguinte situacao:quando F3 chama F2, passando como parametro F1, a declaracao do A e encontradoem F3.

Figura 5.1: Codigo para representacao dos conceitos de vinculacao profunda, rasa e ad hoc.

Page 28: Documentação de uma linguagem de progração

CAPITULO 5. SUBPROGRAMAS 27

5.3 Formas de passagem de parametros

Dentre as formas de passagem de parametro existentes, a nossa linguagem implementaraa passagem de parametro por valor e a passagem de parametro por referencia.

. Passagem de parametro por valor: O valor do parametro real e usado para inici-alizar o parametro formal correspondente, que, entao, age como uma variavel local nosubprograma.

A passagem por valor e normalmente implementada pela transferencia de dados reais(um valor real e transmitido fisicamente para o chamador, para o chamado, ou ambos),mas, ao inves disso, pode ser implementada transmitindo-se um caminho de acesso e,neste caso, a celula de memoria que contem o valor deve estar protegida contra gravacao(read-only).

Na passagem por valor, e feita uma copia dos valores dos parametros reais no espacode memoria reservado para a funcao chamada ou chamadora, ou ate mesmo fora delas.

A desvantagem deste metodo, se forem feitas transferencias fısicas, esta no fato quesera necessario armazenamento adicional para os parametros formais do subprogramachamado, ou em alguma area fora do subprograma chamado ou chamador. Em adicao,as operacoes de armazenamento e transferencia podem ser custosas se o parametro forgrande, e.g. um vetor longo.

. Passagem de parametro por referencia: Transmite um caminho de acesso, nor-malmente apenas um endereco, para a funcao chamada. Isso possibilita o acesso acelula de memoria que armazena o parametro real.

Este metodo e mais eficiente que o descrito anteriormente, uma vez que nao e necessarioespaco duplicado, nem qualquer atividade de copia.

Suas desvantagens sao as seguintes:

– O acesso aos parametros se darao de forma mais lenta, pois mais um nıvel deenderecamento indireto e necessario.

– Mudanca inadvertidas e erroneas poderao ser feitas no parametro real, caso sejaexigido somente uma comunicacao unidirecional com a funcao chamada.

– Criacao de apelidos. A passagem de referencia torna disponıveis caminhos deacesso aos subprogramas chamados, ampliando o acesso deles a variaveis nao lo-cais. Neste metodo 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 Verificacao dos tipos de parametros

O metodo de prototipo sera utilizado, onde o tipo dos parametros formais sao incluıdos naassinatura da funcao ou procedimento, e sao verificados tanto a quantidade de parametros

Page 29: Documentação de uma linguagem de progração

CAPITULO 5. SUBPROGRAMAS 28

que foram passados quanto seus tipos. No caso particular de uma funcao requisitar umnumero real (float) e receber uma variavel inteira (int), a conversao sera feita (alargamento)e nao havera problemas, enquanto que o caso contrario nao sera permitido (estreitamento),pois pode ocorrer a perda de informacoes na conversao de reais para inteiros.

5.5 Subprogramas sobrecarregados ou genericos

A linguagem suportara tanto a producao de subprogramas genericos quanto a desubprogramas polimorficos. Este tipo de subprograma permite que nao seja necessariocriar duas ou mais versoes do mesmo para diferentes parametros. Alem disso, a linguagemtambem dara suporte a criacao de subprogramas sobrecarregados, tendo em vista que,ha casos em que e mais conveniente escrever duas ou mais funcoes com parametros, retornoou quantidade de argumentos deferentes mas, com o mesmo nome.

5.6 Sistema de Implementacao

Algumas linguagens imperativas tem como passo primordial a compilacao. Isso permiteque o programador desenvolva programas que executem diretamente no hardware. Esse tipode sistema de implementacao, na maioria dos casos, torna o programa eficiente. Porem,quando estamos desenvolvendo grandes sistemas, torna-se necessario compilar o programapor completo toda vez que forem feitas alteracoes, o que pode ser muito custoso.

Nesse sentido, o sistema de implementacao utilizado na linguagem e a compilacao se-parada. Um dos fatores que justificam a escolha e a conveniencia de que, mesmo em umsistema de medio e baixo porte, o programador tenha a possibilidade de compilar apenas osmodulos alterados recentemente.

Page 30: Documentação de uma linguagem de progração

Capıtulo 6

Sistema de tipos da linguagem

O sistema de tipos de uma linguagem e um aspecto de grande importancia para a escolhade uma linguagem para um determinado contexto. Ele quem define se uma linguagem faztodas as verificacoes de tipos, tanto em tempo de compilacao quanto em tempo de execucao,o que determina se a linguagem e ou nao fortemente tipada.

6.1 Principais caracterısticas do sistema de tipos

A linguagem proposta e fortemente tipada, em vista do alto grau de confiabilidade re-querido pelas aplicacoes de domınio cientıfico, o qual essa caracterıstica prove. Desse modo,qualquer erro de tipo e detectado durante a compilacao ou em tempo de execucao.

Os tipos dos parametros de funcoes sao verificados durante o tempo de execucao.

6.2 Conversoes de Tipos

As conversoes de tipos serao permitidas sao implıcitas e explıcitas, abaixo ambas saodescritas.

Implıcitas: Somente conversoes de alargamento serao permitidas. Ou seja, o tipo sofreraconversao implıcita somente quando o tipo para o qual esta sendo feita a conversao contenhaa faixa de valores do tipo convertido.

Explıcitas: As conversoes explıcitas sao oferecidas pela linguagem. Elas serao usadaspelo usuario atraves de funcoes. Como por exemplo a funcao stringToInt(a:string):int.

6.3 Regras de compatibilidade de tipos

As regras de compatibilidade de tipos adotadas pela linguagem sao compatibilidade pornome e compatibilidade por estrutura. A compatibilidade entre tipos anonimos (cujo tiponao e explıcito na declaracao, por exemplo vetor) deve ser feitas atraves da compatibilidade

29

Page 31: Documentação de uma linguagem de progração

CAPITULO 6. SISTEMA DE TIPOS DA LINGUAGEM 30

por estruturas. Ja as estruturas de dados criadas pelo usuario a compatibilidade e verificadapor nome. Abaixo explicamos as regras descritas acima.

Compatibilidade por nome: Duas variaveis sao compatıveis por nome se tiverem omesmo nome de tipo, ou estiverem na mesma declaracao. Essa regra de compatibilidade ede facil implementacao, embora seja altamente restritiva.

Compatibilidade por estrutura: Duas variaveis sao compatıveis estruturalmente sepossuırem estruturas identicas. Essa regra de compatibilidade e mais flexıvel que a primeira,porem e mais difıcil de implementar.