Вы находитесь на странице: 1из 72

Giovani Pieri

Projeto e implementao de uma linguagem de


programao

Florianpolis SC
2007/2
Giovani Pieri

Projeto e implementao de uma linguagem de


programao

Trabalho de concluso de curso apresentado


como parte dos requisitos para obteno do grau
de Bacharel em Cincias da Computao.

Orientador:
Luiz Fernando Bier Melgarejo

BACHARELADO EM C INCIAS DA C OMPUTAO


D EPARTAMENTO DE I NFORMTICA E E STATSTICA
C ENTRO T ECNOLGICO
U NIVERSIDADE F EDERAL DE S ANTA C ATARINA

Florianpolis SC
2007/2
Projeto e implementao de uma linguagem de
programao

Trabalho de concluso de curso apresentado como parte dos requisitos para obteno do grau
de Bacharel em Cincia da Computao.

Prof. Luiz Fernando Bier Melgarejo


Orientador

Banca Examinadora

Prof. Dr. Rosvelter Coelho da Costa

Prof. Dr. Jos Mazzucco Jr.


Resumo

O estudo e desenvolvimento de linguagens de programao um ramo de estudo em Ci-


ncia da Computao. Linguagens de programao formam uma camada de abstrao sobre a
linguagem de mquina, o conjunto de instrues que a mquina oferece. Houveram diversas
geraes de linguagens de programao, em cada uma mais abstraes e conceitos foram intro-
duzidas de forma a tornar a tarefa de programar menos propensa a erros e mais escalvel, isto
, mais simples lidar com problemas grandes e complexos.
Atualmente, a indstria de hardware est abandonando a abordagem que vinha sendo utili-
zada de explorao de Instruction Level Parallelism e alta freqncia, e vem adotando a arqui-
tetura multi-core com freqncias mais baixas. Com isso, o software ter que ser paralelo para
utilizar a capacidade do hardware eficientemente.
Segundo Armstrong (2003) grande parte das linguagens de programao atuais so lin-
guagens seqenciais. O que torna a descrio de algoritmos e programas paralelos, difcil e
propenso a erros nestas linguagens. Assim ser desenvolvida uma linguagem de programao
que visa estimular o uso de concorrncia de forma natural, simples e de forma mais segura
possvel.

Palavras-chave: linguagens de programao, tipagem dinmica, mquina de pilha, parale-


lismo
Abstract

Programming languages study and development is a branch of Computer Science. Pro-


gramming languages are an abstraction layer developed on top of machine language, the ins-
truction set offered by the machine. There were several programming languages generations, in
each one more abstraction and concepts were introduced in order to make programming tasks
less error-prone and more scalable, that is, capable of dealing with larger and more complex
problems.
Nowadays, the hardware industry is abandoning the approach that has been used until now,
explore instruction level paralelism and high clock frequencies to extreme. Instead, its adopting
a multicore architecture with lower clock frequency. So, software must be parallel to efficiently
use all hardware resources and capacity.
According to Armstrong (2003) majority of nowadays programming languages are sequen-
tial languages. This way, writing parallel algorithms and programs in those languages are dif-
ficult and error-prone. So will be developped a programming language whose main point is to
stimulate use of concurrency in a natural, simple and more safety way possible.

Keywords: programming languages, dynamic typing, stack machine, parallelism


Sumrio

Lista de Figuras

1 Introduo 10

1.1 Objetivo Geral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

1.2 Objetivo Especfico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

2 Definio da Linguagem Alvo 12

2.1 Sintaxe de Telis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

2.2 Semntica de Telis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2.2.1 Conceitos bsicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2.2.2 Concorrncia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

2.2.3 Atores, modelos e agendas . . . . . . . . . . . . . . . . . . . . . . . . 17

2.2.4 Herana, moldes e princpios de orientao a objetos . . . . . . . . . . 18

2.2.5 Comunicao direta e polimorfismo . . . . . . . . . . . . . . . . . . . 20

2.2.6 Escopo de vriaveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

2.2.7 Programas Telis e o bootstrap . . . . . . . . . . . . . . . . . . . . . . 27

2.3 A nova linguagem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

2.3.1 Associao de variveis . . . . . . . . . . . . . . . . . . . . . . . . . 28

2.3.2 Blocos de comandos . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

2.3.3 Escopo de variveis e closures . . . . . . . . . . . . . . . . . . . . . . 32

2.3.4 Objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

2.3.5 Inicializao de apliques . . . . . . . . . . . . . . . . . . . . . . . . . 35


2.3.6 Ambientes de execuo . . . . . . . . . . . . . . . . . . . . . . . . . . 37

2.3.7 Definio sinttica e lxica formal da nova linguagem . . . . . . . . . 38

3 Implementao do Interpretador 40

3.1 Viso geral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

3.2 Viso geral da biblioteca de wrappers . . . . . . . . . . . . . . . . . . . . . . 41

3.3 O corao da mquina . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

3.3.1 O Parser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

3.3.2 Classes Aplique, Ator e Modelo . . . . . . . . . . . . . . . . . . . . . 48

3.3.3 Mquina de Pilha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

3.3.4 Escopo variveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

3.3.5 Criao e execuo de closures . . . . . . . . . . . . . . . . . . . . . . 54

3.3.6 Classe Programa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

3.3.7 Modelo, moldes e herana . . . . . . . . . . . . . . . . . . . . . . . . 55

3.3.8 Estmulos e comunicao direta . . . . . . . . . . . . . . . . . . . . . 57

3.4 Ambientes de execuo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

4 Definio da Linguagem Compilada 60

4.1 Sintaxe da linguagem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

4.2 Semntica da linguagem compilada . . . . . . . . . . . . . . . . . . . . . . . 62

5 Implementao do compilador 68

5.1 Parser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

5.2 Gerao de cdigo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

Referncias Bibliogrficas 71
Lista de Figuras

2.1 Pilha aps os comandos 10 20 . . . . . . . . . . . . . . . . . . . . . . . . . . 14

2.2 Grafo de herana com um modelo e dois moldes. . . . . . . . . . . . . . . . . 19

2.3 Diagrama de classes do padro de projeto Template Method. . . . . . . . . . . 19

3.1 Diagrama de camadas do sistema. . . . . . . . . . . . . . . . . . . . . . . . . 41

3.2 Diagrama de classe mostrando hierarquia dos wrappers. . . . . . . . . . . . . . 42

3.3 Diagrama de classe mostrando estrutura geral do padro builder. . . . . . . . . 42

3.4 Diagrama de estados mostrando ciclo de vida de um ConstrutorDeListas. . . . 44

3.5 Diagrama mostrando estrutura do ConstrutorDeListas e de seus Estados. . . . . 44

3.6 Diagrama de classes de AmbienteAbstrato. . . . . . . . . . . . . . . . . . . . 46

3.7 Diagrama esquemtico da entrada e sada at criao do primeiro ator. . . . . . 46

3.8 Diagrama das classes geradas pelo JavaCC. . . . . . . . . . . . . . . . . . . . 47

3.9 Diagrama de classes de Ator, Aplique e Modelo. . . . . . . . . . . . . . . . . . 49

3.10 Diagrama de estados do ciclo de vida de um Ator. . . . . . . . . . . . . . . . . 50

3.11 Diagrama de classes da MaquinaDePilha e seus colaboradores. . . . . . . . . . 51

3.12 Diagrama da execuo na MaquinaDePilha. . . . . . . . . . . . . . . . . . . . 52

3.13 Diagrama mostrando Closure e sua relao com o ControladorDeExecucaoDa-


Maquina. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

3.14 Diagrama da classe Programa e seus mtodos. . . . . . . . . . . . . . . . . . . 56

3.15 Diagrama das classes ModeloDeAtor e Molde. . . . . . . . . . . . . . . . . . 57

3.16 Diagrama da hierquia Agenda. . . . . . . . . . . . . . . . . . . . . . . . . . . 58

5.1 Diagrama dos passos do compilador at gerao do programa alvo. . . . . . . . 69


Lista de Listagens

2.1 Gramtica BNF de Telis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

2.2 Exemplo de soma em Telis . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

2.3 Exemplo de estrutura de controle de fluxo em Telis . . . . . . . . . . . . . . . 14

2.4 Exemplo de criao de variveis em Telis . . . . . . . . . . . . . . . . . . . . 15

2.5 Envio de mensagens em Java . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

2.6 Envio de mensagens sncronas em Telis . . . . . . . . . . . . . . . . . . . . . 22

2.7 Exemplo de escopo esttico em Java . . . . . . . . . . . . . . . . . . . . . . . 24

2.8 Exemplo escopo dinmico em Telis . . . . . . . . . . . . . . . . . . . . . . . 25

2.9 Fatorial escrito recursivamente . . . . . . . . . . . . . . . . . . . . . . . . . . 26

2.10 Comportamento no usual na associao de vriaveis . . . . . . . . . . . . . . 28

2.11 Exemplo de utilizao do operador $ . . . . . . . . . . . . . . . . . . . . . . . 30

2.12 Exemplo de utilizao do operador @ . . . . . . . . . . . . . . . . . . . . . . 31

2.13 Listas de dados e blocos de comandos . . . . . . . . . . . . . . . . . . . . . . 32

2.14 Exemplo uso de closures em Ruby . . . . . . . . . . . . . . . . . . . . . . . . 33

2.15 Exemplo da criao de modelos de objetos. . . . . . . . . . . . . . . . . . . . 35

2.16 Exemplo programa linguagem nova. . . . . . . . . . . . . . . . . . . . . . . . 36

2.17 Programa equivalente ao da listagem 2.16 em Telis. . . . . . . . . . . . . . . . 36

2.18 Definio lxica da nova linguagem . . . . . . . . . . . . . . . . . . . . . . . 38

2.19 Gramtica BNF da nova linguagem . . . . . . . . . . . . . . . . . . . . . . . . 39

3.1 Ilustrando criao de listas. A lista nas variveis lista e listaEquivalente so iguais. 43

4.1 Gramtica EBNF da linguagem compilada . . . . . . . . . . . . . . . . . . . . 60

4.2 Definio lxica da linguagem compilada . . . . . . . . . . . . . . . . . . . . 61


4.3 Exemplo de atribuio encadeada . . . . . . . . . . . . . . . . . . . . . . . . . 63

4.4 Exemplo de mensagens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

4.5 Exemplo com estrutura de deciso . . . . . . . . . . . . . . . . . . . . . . . . 64

4.6 Exemplo Modelo e Molde . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65


10

1 Introduo

Linguagens de programao so linguagens artificiais criadas com o intuito de descrever


algoritmos e programas passveis de execuo em mquinas reais (diretamente ou com algum
pr-processamento). Elas formam uma camada de abstrao sobre a chamada linguagem de
mquina, que nada mais que o conjunto de instrues que a mquina que se est programando
oferece.

A existncia de linguagens de programao data desde os primrdios da informtica quando


os primeiros programadores desenvolverem linguagens, mapeando as palavras binrias dos
computadores em mnemnicos. Estas linguagens receberam o nome de assembly. Com o
passar do tempo as linguagens evoluram, novos paradigmas foram criados.

Atualmente existem diversas linguagens de programao, cada uma com suas particula-
ridades, caractersticas, vantagens e desvantagens. Entretanto, estas linguagens possuem uma
sintaxe e semntica relativamente complexa. Alm disso alguns conceitos tal como paralelismo,
so tratados marginalmente tornando difcil e muitas vezes no-intuitivo trat-los.

Com isso em mente, existe uma brecha na qual poucas linguagens se encaixam surgindo a
necessidade de uma linguagem simples que seja semanticamente e sintaticamente simples, de
forma que se torne o mais natural possvel. Entretanto sem impor limitaes, sem dificultar o
desenvolvimento por parte de programadores experientes. Com esta proposta, uma linguagem
de programao ser criada.

Esta linguagem dever suportar um modelo de paralelismo de alto nvel nativamente, dever
ter sintaxe e semntica simples mas ser poderosa de modo a no limitar os desenvolvedores. As
demais caractersticas e construes da linguagem sero estudadas e debatidas sempre levando
em conta esta filosofia.
11

1.1 Objetivo Geral

Desenvolver uma linguagem de programao orientada a objetos, dinamicamente tipada.


Ela deve ser sinttica e semanticamente simples, suportar concorrncia de forma natural e in-
tuitiva.

1.2 Objetivo Especfico

Desenvolver uma linguagem de programao orientada a objetos.

Desenvolver uma linguagem interpretada intermediria, que rodar o programa compi-


lado.

Criar a sintaxe das duas linguagens

Dar semntica s duas linguagens

Estudar caractersticas e construes para adicionar s linguagens.


12

2 Definio da Linguagem Alvo

A linguagem alvo ser uma linguagem de programao interpretada baseada na linguagem


Telis. Linguagens interpretadas so aquelas que rodam sobre um interpretador, que um pro-
grama cuja entrada o cdigo fonte de um programa escrito na linguagem interpretada e aps
realizar as anlises lxica, sinttica e semntica o executa.

Telis uma linguagem madura, desenvolvida no laboratrio Edugraf, que vem sendo de-
senvolvida desde 1998. Ela fruto do estudo e desenvolvimento de vrias outras linguagens
anteriormente desenvolvidas pelo mesmo laboratrio. O objetivo desta linguagem ser sin-
ttica e semanticamente simples de tal forma que mesmo programadores iniciantes consigam
expressar-se de forma natural, mas ao mesmo tempo expor conceitos avanados como parale-
lismo, comunicao via Internet (sistemas distribudos) e princpios de orientao a objetos.

Telis vem sendo utilizado diariamente durante anos por alunos da Universidade Federal
de Santa Catarina nos cursos de Cincia da Computao e Engenharia de Automao e Siste-
mas. Por este motivo, as idia e conceitos desta linguagem sero utilizadas como base para a
linguagem alvo.

2.1 Sintaxe de Telis

Telis possui uma sintaxe bastante simples, descrita pela gramtica EBNF (Extended Backus
Normal Form) mostrada na listagem 2.1.
programa : : = t e x t o l i s t a D e A t o r e s listaDeModelosOuMoldes i n c l u i r A p l i q u e
giria ::= ( palavra | lista )
l i s t a ::= "[" ( palavra | l i s t a ) "]"
listaDeAtores ::= "[" ( identificador ) "]"
listaDeModelosOuMoldes : : = " [ " ( chamadaParaInclusaoDeModeloOuMolde ) " ] "
chamadaParaInclusaoDeModeloOuMolde : : = l i s t a t e x t o l i s t a
primitivaDeInclusaoDeModeloOuMolde
p r i m i t i v a D e I n c l u s a o D e M o d e l o O u M o l d e : : = <ID>
palavra ::= atribuicao | ( identificador | identificadorValorAtual |
13

numero | o p e r a d o r | a l c a n c e | t e x t o | o p e r a d o r P o n t o | b o o l e a n o
)
a t r i b u i c a o : : = ( <ID> ( <ASSOCIAR> ) )
i d e n t i f i c a d o r : : = <ID>
i n c l u i r A p l i q u e : : = <INCLUIR_APLIQUE>
i d e n t i f i c a d o r V a l o r A t u a l : : = ( <ID_VALORATUAL> )
numero : : = <NUMERO>
o p e r a d o r P o n t o : : = " . " <ID>
o p e r a d o r : : = ( " + " | "" | " " | " / " | " ^ " | "\\" | " <" | " >" | " <=" |
" >=" | " < >" | " = " | <ASSOCIAR> )
t e x t o : : = <TEXTO>
b o o l e a n o : : = <BOOLEANO>
a l c a n c e : : = <ALCANCE>

Listagem 2.1: Gramtica BNF de Telis

Os valores entre parnteses angulares so elementos provenientes da anlise lxica e defi-


nidos atravs de expresses regulares. A descrio destes elementos sero omitidas aqui, por
seus nomes serem em sua maioria auto-explicativos. Elementos que possam gerar dvidas sero
explanados adiante.

Como possvel verificar um programa Telis composto basicamente por textos, nmeros,
smbolos e listas. Todo programa em Telis possui um texto com o nome do aplique, uma lista
contendo o nome dos modelos que sero instanciados, uma segunda lista contendo em seu
interior as definies de modelos e moldes, e por ltimo o smbolo incluirAplique responsvel
pela criao de Apliques. Toda esta definio de um programa Telis escondida do programador
pelo Ambiente Telis, um ambiente de desenvolvimento desenvolvido tambm pelo laboratrio
Edugraf para facilitar (ainda mais) a programao em Telis.

Tambm possvel ver que praticamente qualquer cdigo (lista) sintaticamente vlido,
muitas poucas restries so impostas pela gramtica Telis.

2.2 Semntica de Telis

2.2.1 Conceitos bsicos

Telis semanticamente simples tambm, possuindo forte influncia de Forth. Segundo


Brodie (1986), em Forth, existe um local central no qual nmeros so temporariamente arma-
zenados antes de serem operados. Este local uma pilha. Nmeros so empilhados e ento
operados. De forma anloga, as operaes em Telis so definidas sobre uma pilha, sendo que a
14

passagem de parmetros e resultados so todas realizadas atravs da mesma.


10 20 +

Listagem 2.2: Exemplo de soma em Telis

O cdigo mostrado na listagem 2.2 mostra um exemplo de avaliao de expresses em


Telis, no caso, uma soma. O interpretador Telis primeiramente executa o nmero 10, coloca-o
na pilha. O mesmo ocorre com o nmero 20. Aps a execuo destes comandos a pilha est
como mostrado na figura 2.1.

Figura 2.1: Pilha aps os comandos 10 20

Quando o interpretador Telis encontra o operador + ele o executa. Para isso, dois parme-
tros da pilha so consumidos, somados e o resultado empilhado.

Smbolos em Telis so uma cadeia de caracteres separados por espaos. De forma anloga
aos operadores, sempre que a mquina Telis encontra um smbolo ela tenta execut-lo, caso no
consiga um erro de tempo de execuo gerado.

A mquina Telis possui um conjunto de smbolos, inerente mquina, sendo cada um dos
elementos denominado agenda primitiva e cada uma destas agendas primitivas possui associada
a si um determinado comportamento. Toda vez que um smbolo associado uma determinada
agenda encontrado o comportamento relacionado a esta agenda executado. Este comporta-
mento pode ser afetado por parmetros, que so obtidos da pilha e possveis resultados sero
empilhados. As primitivas so utilizadas para modelar as estruturas de controle de fluxo e repe-
tio, operaes sobre textos, listas e nmeros entre outras funcionalidades.

Listas desempenham um papel muito importante em Telis. Alm de poderem ser utilizadas
como estruturas de dados para o armazenamento e processamento de informaes, elas podem
agrupar um conjunto de instrues. Telis se aproveita deste fato para modelar, por exemplo, ex-
presses condicionais. Expresses condicionais recebem como parmetro uma lista contendo os
comandos que devero ser realizados dependendo do valor de um segundo parmetro booleano,
como mostrado na listagem 2.3.
verdadeiro
15

[
10 m o s t r a r
]
seVerdade

Listagem 2.3: Exemplo de estrutura de controle de fluxo em Telis

No cdigo da listagem 2.3, um valor booleano e uma lista contendo comandos so em-
pilhados. A primitiva seVerdade recebe estes dois parmetros e caso o valor booleano seja
verdadeiro, o que realmente ocorre neste caso, a lista de comandos executada. Neste caso, o
nmero 10 mostrado na tela.

A atribuio de variveis um caso particular e viola a poltica do interpretador de sempre


executar um smbolo assim que este encontrado. No jargo de Telis, a atribuio de um
determinado valor uma varivel chamado de associao. Variveis so associadas atravs da
primitiva associar, como mostrado na listagem 2.4. A diferena em relao a outras primitivas
que a primitiva associar pode receber um smbolo como parmetro. Na gramtica BNF de Telis,
mostrada na listagem 2.1 na pgina 12, pode-se notar que na produo palavra h um tratamento
especial em relao a primitiva associar, para o caso no qual um smbolo seja seguido de um
associar.
"um t e x t o q u a l q u e r " u m a V a r i a v e l a s s o c i a r

Listagem 2.4: Exemplo de criao de variveis em Telis

Durante a execuo do cdigo mostrado na listagem 2.4, quando a mquina Telis se de-
para com o smbolo umaVarivel, olhado um token a frente e caso este token seja um asso-
ciar, o que realmente ocorre, o valor que est na pilha associado ao smbolo atual, no caso
umaVarivel. Para empilhar o valor anteriormente atribudo uma varivel, basta executar o
smbolo ao qual a varivel foi associada.

2.2.2 Concorrncia

Telis uma linguagem inerentemente concorrente. A concorrncia, a exemplo de lingua-


gens como Erlang (ARMSTRONG, 1997), tratada diretamente por mecanismos providos pela
linguagem, diferentemente de outras linguagens nas quais so oferecidos mecanismos para a cri-
ao de threads e a sincronizao realizada atravs de semforos e/ou monitores utilizando-se
memria compartilhada.

Telis adota uma abordagem baseada em Atores. Atores so parecidos com processos no
16

que diz respeito a compartilhamento de recursos. No h memria compartilhada, conseqen-


temente a necessidade de sincronizao de reas de memria compartilhadas eliminada.

A comunicao entre atores se d atravs de troca de mensagens. O modelo de troca de


mensagens entre atores originalmente proposto diz que para um ator se comunicar com outro
ator ele deve poder identific-lo. Aps identificar com quem se deseja comunicar o envio da
mensagem pode ser realizado.

Telis adotou uma abordagem distinta. Um ator no necessita nenhum tipo de informao
a respeito de quem receber a mensagem. A mensagem enviada a todos os outros atores que
tenham se cadastrado para receb-la.

Uma tupla uma seqncia finita de objetos, cada um de um determinado tipo. Uma tupla
em Telis representada por uma lista, e a base para o sistema de troca de mensagens do Telis.
Mensagens em Telis so chamadas de estmulos ou eventos. Ao enviar uma mensagem para um
ou mais atores diz-se que um estmulo foi emitido. Ao recepcionar este estmulo diz-se que o
estmulo foi tratado.

So necessrios dois mecanismos bsicos para que atores possam se comunicar: eles devem
poder emitir estmulos e poder se cadastrar com o intuito de receber um determinado estmulo.
Logo, duas primitivas so utilizadas para realizarem a comunicao entre dois atores distintos:
dizer e seDito.

A agenda primitiva dizer responsvel pela emisso de estmulos. Seu funcionamento


bastante simples: uma tupla (lista) buscada na pilha e enviada a todos os atores com exceo
de si mesmo.

A agenda primitiva seDito responsvel pelo cadastro de um tratador de estmulos, sendo


este composto por duas partes: um filtro e uma lista de instrues. Como resultado desta ope-
rao o tratador de estmulos cadastrado e sempre que um estmulo compatvel com o filtro
for recebido o ator interrompido e o respectivo filtro passa a executar. Aps o trmino do
processamento do estmulo, o ator retoma a sua execuo normal sendo que qualquer alterao
feita na pilha pelo tratador desfeita, isto , a pilha ir possuir os mesmos dados de quando fora
interrompida.

Filtros so tuplas. Diz-se que um filtro casa com um estmulo se as condies abaixo forem
satisfeitas:

1. Filtro e estmulo possuem mesmo tamanho

2. Para todo elemento do estmulo, o elemento de mesma posio no filtro deve: ser igual
17

ou indicar o tipo do elemento do estmulo atravs dos smbolos texto, nmero ou lista.

O funcionamento do mecanismo de recepo de mensagens muito similar ao funciona-


mento de interrupes em processadores. Ao se ativar uma linha de interrupo o processador
automaticamente desvia para o endereo onde o tratador de interrupo se encontra e logo aps
o trmino do cdigo de tratamento de interrupes, todos os registradores so restaurados e
o processador devia para a instruo que seria executada caso no houvesse uma interrupo,
como se nada houvesse ocorrido.

De maneira similar o ator Telis executa os comandos at que um tratador cujo filtro case
com um estmulo que tenha sido emitido. Neste momento, o fluxo normal de execuo in-
terrompido, empilhado o estmulo que est sendo tratado e as instrues anexadas ao tratador
pela execuo da primitiva seDito executado. Aps o trmino da execuo do tratador, a pilha
restaurada ao estado inicial, isto , os elementos contidos na pilha sero iguais ao que estava
na mesma antes do estmulo ser iniciado e o fluxo de execuo normal retomado.

Uma caracterstica importante do sistema de notificao do Telis que durante o tratamento


de um estmulo dizer, novos estmulo so perdidos. Isto , o ator no capaz de tratar mais de
um estmulo emitido pelo dizer simultaneamente.

2.2.3 Atores, modelos e agendas

Atores so entidades autnomas, isto , vrios atores podem rodar simultaneamente, de


forma independente.

Quando um ator criado ele executa a agenda de nome iniciar. Agendas so anlogos
mtodos em linguagens orientadas a objetos. Diferentemente de agendas primitivas, que
so providas diretamente pela linguagem, agendas contm cdigo definido pelo programador.
Agendas so executadas quando o smbolo associado ao nome da agenda for executado pelo
interpretador Telis.

Para se criar um ator necessrio uma espcie de fbrica de atores contendo a definio dos
mesmos, isto , a definio das agendas que ele possuir. Esta fbrica de atores chamada de
modelo, e funciona de maneira similar a classes em linguagens orientada a objetos. Uma vez
definido um modelo, e conseqentemente suas agendas, um ator pode ser instanciado. Para se
instanciar um ator a partir de um modelo basta executar o smbolo correspondente ao nome do
modelo que fora definido. Neste momento, o interpretador Telis toma as seguintes aes:

1. Cria um novo ator. Este ator possui acesso a todas as agendas definidas pelo modelo.
18

2. Copia o topo da pilha do ator que est criando o novo ator para a pilha do ator recm
criado.

3. A agenda iniciar do ator original executada.

4. Uma referncia ao ator criado empilhada no ator que criou o novo ator.

A referncia a um ator pode ser utilizada posteriormente para realizar comunicao di-
reta com o ator, isto , enviar uma mensagem direcionada pedindo que o mesmo execute uma
agenda. Todo ator possui uma identidade, e h garantia que esta identidade nica. possvel
acessar a prpria identidade atravs da primitiva obterIdentidade, e obter uma referncia para
si prprio atravs da primitiva euMesmo.

2.2.4 Herana, moldes e princpios de orientao a objetos

Telis permite uma noo de herana com a utilizao de moldes. A herana de Telis
diferente da herana em linguagens como Java e C++. O intuito fornecer um mecanismo
simples de ser entendido e explicado, embora seja menos flexvel. Isto ocorre porque o ponto
onde a superclasse ser chamada pr-definida ao invs de ser indicada pelo programador.

Classes abstratas em Telis so denominadas moldes. Diz-se que um molde molda um mo-
delo, e este por sua vez moldado pelo molde. Um modelo pode ser moldado por zero ou mais
moldes, como possvel que um modelo seja moldado por mais de um molde h em Telis a
noo de herana mltipla. Alm disso, um molde tambm pode ser moldado por zero ou mais
moldes. Um modelo no pode ser utilizado como molde.

A partir dessa definio de moldado/molde possvel criar um grafo de herana G(V, A)


definido da seguinte forma:
V = { x | x um molde ou modelo}
A = { (x, y) | x molda y x um molde}

A figura 2.2 mostra um grafo de herana montado supondo a existncia de um modelo


denominado ModeloUm moldado por dois moldes, chamados de MoldeUm e MoldeDois.

Esse grafo deve possuir as seguintes propriedades:

1. No deve possuir ciclos.

2. Todos os modelos devem ser nodos folha, isto , seu grau de emisso1 igual a 0.
1O grau de emisso de um vrtice v corresponde ao nmero de arestas que partem de v.
19

Figura 2.2: Grafo de herana com um modelo e dois moldes.

Os moldes definem agendas, de forma anloga a modelos. Estas agendas podem ser utili-
zadas por quem for moldado por este molde. Caso um modelo ou molde defina uma agenda
com mesmo nome de uma agenda definida em um dos moldes que o est moldando, este ir
estender a agenda do molde. Do ponto de vista do programador, o cdigo definido pelo modelo
anexado ao fim das agendas do molde cujos nomes sejam idnticos.

importante notar que os moldes podem referenciar agendas inexistentes no molde. Isto
til para realizar implementao de alguns padres de projetos comuns tais como Template
Method. Como pode ser visto no diagrama mostrado na figura 2.3, a descrio geral de um
algoritmo definido em uma superclasse em um mtodo template, devendo este delegar tarefas
para mtodos abstratos. Cada subclasse deve preencher as lacunas no algoritmo com os detalhes
pertinentes. O diagrama de classes mostrado na figura .

Em Telis, agendas abstratas no so explicitamente definidas mas podem ento ser simula-
das atravs deste mecanismo de delegao para agendas inexistentes.

Figura 2.3: Diagrama de classes do padro de projeto Template Method.

Por definio, durante a invocao de uma agenda, as agendas definidas nos moldes so
executados anteriormente as agendas de quem est sendo moldado. Dado um grafo de herana
G e um modelo M pertencente a este grafo, definido o subgrafo X composto pelos vrtices
20

pertencentes ao fecho transitivo inverso2 de M e toda aresta definida entre dois vrtices perten-
centes a este fecho transitivo inverso. Isto :
V = { x | x FTI(G, M)}, onde FTI(G, M) o conjunto de vrtices do fecho transitivo
inverso do vrtice M do grafo G.
A = { (x, y) | (x, y) E(G) }, onde E(G) o conjunto de arestas de G.

A ordem de invocao das agendas um ordenamento topolgico do grafo X. Em teoria de


grafos, o ordenamento topolgico de um grafo direcionado acclico um ordenamento linear de
seus vrtices que compatvel com a ordem parcial R induzida nos vrtices onde x vem antes
de y (xRy) se existe um caminho de x para y no grafo. Por esta definio possvel perceber
que h diversas formas de se montar um ordenamento topolgico de X.

A ordem em que os moldes se encontram na lista de moldes utilizado para determinar


a ordem na qual as agendas dos moldes sero invocadas, isto , o ordenamento topolgico de
X. As agendas dos moldes so invocados preferencialmente na ordem em que foram listados
na lista de moldes do moldado. Caso haja necessidade, possvel que o a ordem da lista de
moldes seja desrespeitada para que o ordenamento linear de X que ser gerado continue sendo
um ordenamento topolgico, mas o algoritmo tentar manter a ordem listada.

Outro ponto importante que durante a invocao da agenda de um modelo, todas as agen-
das de mesmo nome dos moldes contidos no fecho transitivo inverso do modelo so invocadas
uma e somente uma vez.

2.2.5 Comunicao direta e polimorfismo

A comunicao entre atores em Telis se d atravs de estmulos. A forma mais simples


de realizar comunicao entre atores diferentes atravs de estmulos assncronos utilizando-
se primitivas dizer e seDito. Entretanto, esta forma de comunicao pode se tornar um tanto
incomoda de ser utilizada. Devido a sua natureza intrnseca de broadcast, isto , um estmulo
emitido pode influenciar um nmero qualquer de atores. Este comportamento pode ser uma
vantagem, como na implementao de arquiteturas Model-View-Controler (MVC) e do padro
Observer por exemplo. Entretanto pode se tornar complexo realizar comunicao entre dois
atores previamente conhecidos, principalmente se for necessrio uma troca de dados ocorrendo
nos dois sentidos, isto , os dois devem trocar dados de forma sincronizada. Isto ocorre porque
ser necessrio criar um protocolo de comunicao entre as duas partes, alm de construir um
sistema que garanta que as mensagens afetaro apenas as partes envolvidas.
2O fecho transitivo inverso (fti) de um vrtice v o conjunto de todos os vrtices a partir dos quais se pode
atingir v por algum caminho (levando em conta a orientao das arestas).
21

De forma a simplificar este tipo de comunicao, existe em Telis um tipo diferenciado de


estmulo chamado estmulo de comunicao direta. A comunicao direta encapsula toda a
complexidade de fazer dois atores se comunicarem, sincronizando-os. Para realizar a comuni-
cao direta, um ator de posse de uma referncia ao ator alvo envia um pedido, e se necessrio
um parmetro. O ator que realizou a comunicao direta ento bloqueado at que o ator alvo
termine o processamento do pedido, que ocorre utilizando o mesmo princpio de interrupo
utilizado pelo seDito. Quando o processamento do pedido finalizado caso a pilha no esteja
vazia o seu topo retornado ao ator que iniciou a comunicao direta e o ator alvo retoma o que
estava realizando, nos mesmo moldes que o tratamento convencional do seDito.

A sintaxe da comunicao direta foi inspirada em linguagens como Java e Ruby nos quais
mensagens so enviadas a objetos utilizando-se a notao do ponto, como mostrado na listagem
2.5
p u b l i c c l a s s Xpto {
p u b l i c v o i d metodo ( ) {
...
}
}

p u b l i c c l a s s Main {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
Xpto x p t o = new Xpto ( ) ;
x p t o . metodo ( ) ;
}
}

Listagem 2.5: Envio de mensagens em Java

Na notao de ponto, coloca-se a referncia ao objeto seguido do nome do mtodo que se


deseja invocar precedido por um ponto. Normalmente a referncia guardada em uma varivel,
mas isto no obrigatrio. Em Telis ocorre algo parecido, primeiro se empilha a referncia do
ator com quem se deseja comunicar, em seguida se escreve-se o nome da agenda que se deseja
pedir que o ator alvo execute. Caso a agenda invocada necessite de um parmetro ele buscado
na pilha. Apenas um parmetro est disponvel ao ator alvo, caso seja necessrio um nmero
maior de dados, possvel envi-los colocando-os em uma lista.

No cdigo da listagem 2.6 so mostrados dois modelos de atores. O primeiro, chamado


ModeloAlvo possui uma agenda chamada somarDois que pega um nmero na pilha soma o
nmero dois e retorna o resultado. Um segundo modelo, denominado MeuModelo possui um
cdigo mais interessante em sua agenda iniciar, primeiramente o modelo ModeloAlvo instan-
22

ciado e sua identidade guardada na varivel somador. Em seguida o nmero 5 e o contedo da


varivel somador (identidade do ator alvo) empilhado e, utilizando-se a notao de ponto a
agenda somarDois do ator alvo invocada. Depois que o ator alvo termina o processamento
e calcula o resultado da soma (7) o retorna. Neste ponto, o retorno (7) empilhado na pilha
do ator que iniciou a comunicao direta e este ator liberado, executando assim a primitiva
mostrar, que imprime o que est na pilha na tela, que o prprio sete.
" umAplique " [ MeuModelo ]
[
[ ] " ModeloAlvo "
[
" somarDois "
[
2 +
]
incluirAgenda
]
incluirModelo

[ ] " MeuModelo "


[
" iniciar "
[
[ ] ModeloAlvo somador a s s o c i a r
5 somador . s o m a r D o i s
mostrar
]
incluirAgenda
]
incluirModelo
]
incluirAplique

Listagem 2.6: Envio de mensagens sncronas em Telis

Permitir que um ator pea para que outro execute uma de suas agendas e retorne o resultado
pode ser bastante til, entretanto permitir que ele execute qualquer outra agenda no uma
boa pratica. Grande parte das linguagens possuem um sistema de restrio de visibilidade de
mtodos. Por exemplo Java define quatro nveis de visibilidade: public, protected, package,
private. Em Telis tambm existe nveis de visibilidade das agendas, dois mais especificamente:
pblico e privado. Agendas pblicas podem ser alvo de uma comunicao direta, enquanto
agendas privadas no. Caso tente-se fazer comunicao direta com uma agenda privada gerado
23

um erro em tempo de execuo. A diferenciao entre agendas pblicas e privadas diz respeito
ao nome. Foi convencionado que agendas cujo nome inicia com so privadas, qualquer outra
agenda pblica.

Existem algumas diferenas entre os estmulos utilizados atravs da primitiva dizer/seDito


e a comunicao direta. A comunicao direta, diferentemente dos estmulos emitidos pelo
dizer, no perdida caso um novo pedido de comunicao direta chegue enquanto um outro
estmulo est sendo tratado, ao invs disso, o pedido colocado em uma fila para ser tratado
assim que possvel. Outra diferena que atores podem tratar estmulos de dizer assim que
um tratador seja instalado utilizando a primitiva seDito, mas estmulos de comunicao direta
so enfileirados e sero tratados apenas quando o ator finalizar a execuo da agenda iniciar.
Esta ltima restrio foi imposta a fim de prover um mecanismo com o qual o programador
possa inicializar as suas variveis internas, deixando o ator em um estado consistente, antes de
fornecer servios a outros atores. Entretanto, como resultado disto, existe a possibilidade de
ocorrer deadlocks caso a agenda iniciar no retorne nunca.

Em Telis h uma hierarquia de prioridades entre os dois tipos de estmulos. Os estmulos


oriundos de comunicao direta so os menos prioritrios, enquanto os estmulos oriundos da
primitiva dizer so os mais prioritrios. Quando um ator est tratando um estmulo dizer ne-
nhum outro estmulo pode ser tratado. Caso um outro estmulo chegue ele descartado, caso
chegue um estmulo de comunicao direta este enfileirado. Estmulos de comunicao direta
so menos prioritrios. Enquanto um ator est tratando um estmulo de comunicao direta ele
pode ser interrompida para o tratamento de um estmulo dizer, entretanto se outro pedido de
comunicao direta chegar, ele enfileirado para tratamento posterior.

Telis uma linguagem dinamicamente tipada. Devido a isto, nenhum tipo de verificao
quanto a existncia de uma agenda realizada em tempo de compilao, sendo a validade da
comunicao direta verificada apenas em tempo de execuo. Devido a isto, o polimorfismo
algo natural e inerente. No necessrio, para utilizar polimorfismo, herana, interfaces ou casts
ao contrrio de linguagens estaticamente tipadas. Para utilizar polimorfismo em Telis basta
que os atores (e seus modelos) possuam o subconjunto das agendas utilizadas definidas. Ruby,
Python e outras linguagens dinamicamente tipadas possuem o mesmo comportamento. Este tipo
de polimorfismo denominado duck typing. Este termo tem origens na frase If it quacks like a
duck, walks like a duck, it must be a duck!. A origem deste termo desconhecida mas suspeita-
se que foi cunhada por Alex Martelli em uma mensagem ao newsgroup comp.lang.python.
24

2.2.6 Escopo de vriaveis

O escopo de variveis em Telis diferente do escopo de variveis em linguagens como Java.


Em Java, o escopo de vriaveis dito ser esttico ou lxico. Neste tipo de escopo, varveis livres
so amarradas a definio da varivel no escopo lxico ou sinttico mais prximo. Por exemplo
no cdigo Java da listagem 2.7, a varivel x uma varivel livre em relao ao bloco if, ento
ela amarrada a varivel x encontrada no bloco (elemento sinttico) no qual o bloco do if est
includo que a varivel x declarada pelo mtodo umMetodo.
p u b l i c c l a s s ExemploEscopo {
int x = 20;
p u b l i c v o i d umMetodo ( ) {
int x = 10;
i f ( "a" == "a" ) {
x = 20;
}
}
}

Listagem 2.7: Exemplo de escopo esttico em Java

Em Telis utilizado o que chamado de escopo dinmico. No escopo dinmico variveis


livres so associadas varivel de nome idntico encontrada primeiro na pilha de execuo.
As variveis associadas em uma agenda so mantidas at o momento no qual a agenda retorna.
Uma exceo a esta regra a agenda iniciar. As variveis associadas na agenda iniciar so con-
sideradas variveis de instncia e podem ser acessadas por tratadores de estmulos ou chamadas
de agendas feitas atravs de comunicao direta.

Algumas linguagens conhecidas tambm implementam escopo dinmico, dentre elas pode-
se citar Perl e Common Lisp.

Para descobrir a quem uma varivel deve ser amarrada, necessrio realizar uma anlise da
pilha de execuo. A primeira varivel encontrada com mesmo nome analisando o stack-trace,
isto , as variveis associadas na agenda na ordem em que as agendas iro retornar.

O fato de que utilizando-se escopo esttico as variveis livres de um mtodo so amarradas


sempre da mesma forma, a principal diferena em relao ao escopo dinmico no qual este
fato no necessariamente verdade. Caso uma mesma agenda seja chamada de duas agendas
distintas as variveis da ltima sero amarradas as variveis de mesmo nome na agenda que a
chamou sendo diferente em cada uma das duas chamadas.
25

O cdigo Telis na listagem 2.8 ilustra um exemplo onde escopo dinmico difere do escopo
esttico. Neste cdigo, apenas um ator do modelo ModeloExemplo instanciado. Sua agenda
iniciar invoca primeiro a agenda1 em seguida a agenda2. A agenda1 associa varivel x o
valor 10 e invoca a agenda mostrarX. A agenda mostrarX neste momento acessa a varivel
associada pela agenda agenda1, j que foi esta quem a invocou, mostrando na tela o valor 10.
A agenda2 funciona do mesmo modo. Primeiro associa varivel x o valor 20, em seguida
invoca a agenda mostrarX. Mas desta vez a agenda mostrarX ir acessar a varivel associada
pela agenda2 que 20, conseqentemente imprimindo o valor 20 na tela. Caso uma linguagem
com escopo esttico fosse utilizado neste caso, um erro em tempo de execuo ou compilao
ocorreria j que a varivel x no est definida lexicamente. Apenas em tempo de execuo
possvel encontrar esta varivel.
" ExemploEscopo " [ ModeloExemplo ]
[
[ ] " ModeloExemplo "
[
" iniciar "
[
agenda1
agenda2
]
incluirAgenda

" agenda1 "


[
10 x a s s o c i a r
mostrarX
]
incluirAgenda

" agenda2 "


[
20 x a s s o c i a r
mostrarX
]
incluirAgenda

" mostrarX "


[
x mostrar
]
26

incluirAgenda
]
incluirModelo
]
incluirAplique

Listagem 2.8: Exemplo escopo dinmico em Telis

A primitiva associar alm de associar um valor a uma varivel, cria uma nova varivel den-
tro do escopo da agenda atual caso esta varivel no consiga ser amarrada a nenhuma outra.
Entretanto com este comportamento do associar, pode-se tornar incomodo por exemplo para as-
sociar variveis em agendas recursivas. Como as variveis possuem o mesmo nome, a primeira
chamada a agenda recursiva cria uma varivel no escopo desta agenda. A partir da todas as
variveis de todas as agendas chamadas recursivamente acabam sendo amarradas a agenda da
primeira chamada fazendo com que as agendas compartilhem indesejavelmente a varivel. Para
resolver este problema, existe a primitiva declarar. Esta primitiva cria uma varivel na agenda
atual, sem tentar amarr-la a uma varivel. Desta forma possvel utilizar agendas recursivas
sem problemas. O cdigo da listagem 2.9 mostra o exemplo do fatorial escrito recursivamente.
" Fatorial " [ Fatorial ]
[
[] " Fatorial "
[
" iniciar "
[
20 f a t o r i a l
mostrar
]
incluirAgenda

" fatorial "


[
[ valor ] declarar
valor associar
valor 0 =
[
1
]
[
valor 1 f a t o r i a l
valor
]
27

entoSeno
]
incluirAgenda
]
incluirModelo
]
incluirAplique

Listagem 2.9: Fatorial escrito recursivamente

2.2.7 Programas Telis e o bootstrap

Programas em Telis so denominados apliques. Os atores so criados dentro de apliques.


Apliques possuem interface grfica e podem rodar tanto de forma independente quando dentro
de navegadores web.

Um aplique definido pelos seguintes parmetros:

nome

tamanho

definio dos moldes

definio de modelos

lista de modelos que sero instanciados

Ao abrir um aplique o processo de bootstrap iniciado. O interpretador inicializado, os


modelos e moldes so lidos e compilados em seguida a lista de modelos que deve ser instanciada
percorrida e atores so criados. A ordem em que os atores so instanciados na lista no
definida, podendo ser aleatria. A lista pode conter elementos repetidos, caso isto ocorre, um
mesmo modelo instanciado tantas vezes quantas o seu nome estiver na lista.

Apliques podem ser definidos atravs da prpria linguagem, como mostrado no cdigo da
listagem 2.6 na pgina 22. Mas existe uma representao alternativa tambm utilizada que
se baseia em arquivos xml (extensible mark-up language). A definio deste xml no ser
mostrado ou discutido, mas vale comentar que vrias transformaes so realizadas sobre este
xml. Desde a gerao do cdigo em linguagem Telis pura at gerao de pginas html (hyper-
text mark-up language) descrevendo o cdigo Telis.
28

2.3 A nova linguagem

A nova linguagem ser baseada em Telis. Telis foi utilizado por muito tempo, por muitos
programadores e provou ser uma linguagem simples e poderosa. Os conceitos na linguagem
permitem que sejam escritos programas bsicos, inclusive sem o uso de variveis, at programas
complexos, concorrentes e orientados a objetos.

Entretanto existem alguns pontos em Telis aos quais no foi dado muita ateno, algumas
excees que podem ser resolvidas ou funcionalidades e conceitos que ainda no foram im-
plementadas. Ento ser realizada uma anlise destes pontos nos quais Telis deixa a desejar e
propor alteraes semnticas e/ou sintticas com o objetivo de melhorar a linguagem.

2.3.1 Associao de variveis

A execuo de programas Telis pelo interpretador descrito de forma simples. Primeira-


mente o interpretador Telis busca a instruo, caso ela seja um smbolo a executa, caso no seja
empilha o valor na pilha de dados. Este procedimento um processo simples, mecnico e de
fcil compreenso. Entretanto a primitiva associar viola este processo.

A primitiva associar uma exceo. Quando um smbolo sucedido de um associar ele


no executado, ao invs disso, utilizado pela primitiva associar para nomear a varivel e
o topo da pilha o contedo desta. como se a primitiva associar causasse uma distoro
espao-temporal, executando antes dela ser buscada pelo interpretador.

Como resultado deste comportamento, no mnimo estranho, da primitiva associar h uma


srie de confuses causadas entre programadores Telis. Em situaes simples esta exceo fun-
ciona muito bem e torna a leitura do cdigo muito boa, entretanto em situaes mais complexas,
como por exemplo montagem dinmica de nome de variveis, causa vrios problemas.

O fragmento de cdigo mostrado na listagem 2.10 ilustra uma situao na qual o programa-
dor Telis normalmente espera um comportamento mas ocorre algo um tanto quanto inesperado.
O cdigo, quando lido de forma simplista, se comportaria da seguinte maneira: empilha o
20, variavel e Um, em seguida concatena variavel e Um resultando em variavelUm.
Agora a variavelUm seria associada ao nmero 20. Este pensamento, apesar de parecer coerente
no o que ocorre. Esta linha de raciocnio ignora o comportamento excepcional do associar.
O correto seria o seguinte: empilha o 20, variavel e Um, agora o smbolo concatenar se-
guido de um associar, logo o concatenar o nome da varivel e no uma agenda primitiva como
esperado. Conseqentemente, a varivel concatenar associada com o texto Um
29

20 " v a r i a v e l " "Um" c o n c a t e n a r a s s o c i a r

Listagem 2.10: Comportamento no usual na associao de vriaveis

Alm disso, este comportamento do associar causa um impacto na gramtica de Telis (mos-
trada na listagem 2.1 na pgina 12). Telis uma gramtica livre de contexto, mais especi-
ficamente uma gramtica LL. Gramticas LL so um subconjunto das linguagens livres de
contexto na qual as seguintes restries so impostas:

Se < X >< V 1 > | < V 2 > |...| < V n >, ento FIRST (Vi ) FIRST (V j ) = 0/
T

Se < Z > X, ento FIRST (X) FOLLOW (Z) = 0/


T

Recurso a esquerda no permitida

FIRST(X) definido como o conjunto de todos os terminais que podem aparecer no incio
de uma sentena derivada a partir de um no terminal X. FOLLOW(Z) definido como a unio
do FIRST(V) para todas as produes na forma: X ZV .

Caso exista um parser LL que com um nmero k de tokens de lookahead 3 possa reconhecer
todas as palavras geradas por uma gramtica sem realizar backtracking, ento diz-se que esta
gramtica LL(k).

As restries feitas sobre gramticas BNF tem o objetivo de simplificar o parsing. Exis-
tem vrios algoritmos para realizar o reconhecimento de sentenas de forma eficiente e quanto
menor o valor de k da gramtica, mais eficiente este algoritmo se torna.

A produo palavra na gramtica do Telis, torna a gramtica do Telis uma gramtica LL(2).
Pois h um conflito entre as produes atribuicao e identificador. Se a gramtica for alterada e a
produo atribuicao deixar de existir a gramtica poder ser reduzido a uma gramtica LL(1).

Para resolver o problema e tentar tornar o associar uma primitiva normal, como outra qual-
quer, foi proposto que continue se utilizando um smbolo para indicar o nome de uma varivel,
entretanto este simbolo dever ser buscado na pilha. Em Telis, smbolos no podem ir para a
pilha de modo simples pois quando o interpretador Telis os encontram ele imediatamente exe-
cuta. A nica forma de fazer isso no Telis antigo colocando o smbolo dentro de uma lista e
em seguida retir-lo. A proposta para facilitar o empilhamento de smbolos utilizar um ope-
rador, que pode ser utilizado em smbolos e quando este operador executado ele empilha o
3 Lookahead define quantos dados de entradas sero levados em considerao em um passo do algoritmo. No
caso de parsers, o nmero de tokens que sero levados em conta para realizar uma transio da mquina de reco-
nhecimento.
30

smbolo que ele est marcando, de forma similar a notao de ponto. Foi proposta tambm a
utilizao do caracter $ para realizar tal operao. O fragmento de cdigo mostrado na listagem
2.11 ilustra a associao de variveis utilizando-se este operador. No exemplo, o smbolo no-
meDaVarivel marcado com o operador $ e conseqentemente no ser executado, mas sim
empilhado e consumido pelo associar da pilha.
20 $ n o m e D a V a r i v e l a s s o c i a r

Listagem 2.11: Exemplo de utilizao do operador $

Essa abordagem, apesar de tornar o cdigo um pouco menos legvel trs importantes van-
tagens. A utilizao deste operador obriga o programador a explicitar quando o smbolo que
precede o associar deve ser executado ou realmente o nome da varivel. Outro ponto o
impacto que trs a gramtica, tornando-a LL(1) ao invs de LL(2), o que trs vantagens j
que parsers para gramticas LL(1) so muito mais otimizadas e simples do que gramticas LL
com um nmero maior de lookaheads. Alm disso, com smbolos sendo facilmente empilhados
os torna mais propensos a usos tais como para enumeraes e definio de nomes no s de
variveis mas de agendas, modelos e moldes tambm tornando Telis mais padronizada.

2.3.2 Blocos de comandos

Blocos de comandos so um grupo de instrues que podero ser executados futuramente


atravs de alguma das primitivas de controle. Em Telis, estes blocos de comandos e listas de da-
dos no so diferenciados. Ambos so tratados da mesma forma, utilizam a mesma construo
sinttica (listas) e podem ser utilizados intercambiavelmente.

Esta no-diferenciao pode vir a ser til, permitindo a construo dinmica de comandos
por exemplo. Entretanto, traz alguns problemas, principalmente quando utilizadas em conjunto
com o operador valor atual (@) de Telis.

O operador valor atual utilizado dentro de listas. Sua funo realizar a avaliao de um
smbolo, colocando no lugar do mesmo o que restou no topo da pilha aps esta avaliao ocorrer.
importante salientar que a pilha limpa logo aps a avaliao ser realizada, isto , aps
cada avaliao utilizando-se o operador valor atual a pilha restaurada para o estado anterior,
na iminncia da lista ser empilhada. Os smbolo so resolvidos no escopo atual, e nenhuma
restrio posta em relao ao que este smbolo est atrelado. As duas nicas restries so:

No h passagem de parmetros;

A avaliao do smbolo dever retornar pelo menos um valor.


31

O fragmento de cdigo mostrado na listagem 2.12 mostra como o operador valor atual
pode ser utilizado no Telis, e como obter o mesmo resultado sem utiliz-lo. Primeiramente,
uma varivel criada e um valor ela associado, logo em seguida a lista empilhada mas
como esta lista possui um operador valor atual, o smbolo ser substitudo pela avaliao do
mesmo. Como o smbolo a varivel previamente criada, o valor desta varivel ser colocada
no lugar do operador e do smbolo, resultando na lista [ valor da varivel ] na pilha, que
posteriormente mostrada na tela. Na prxima linha, mostrada uma forma alternativa de
obter o mesmo resultado sem utilizar o operador valor atual.
" v a l o r da v a r i v e l " a V a r i a v e l a s s o c i a r
[ @aVariavel ] m o s t r a r
aVariavel 1 gerarLista mostrar

Listagem 2.12: Exemplo de utilizao do operador @

O problema deste operador que se espera comportamentos distintos quando encontrados


em listas de dados e em blocos de comandos. Em listas de dados, espera-se que os valores das
variveis sejam substitudos imediatamente, utilizando-se os valores das variveis no momento
em que a lista empilhada para realizar as substituies. J em blocos de comandos, espera-se
que os operadores valor atual no atuem, mas que sejam ignorados e utilizados quando o bloco
for executado. Afinal, bloco de comandos definem cdigo para ser executados posteriormente,
e o operador valor atual um elemento do cdigo Telis e portanto deve poder ser expressado
para execuo futura em blocos.

Como no existe nenhum tipo de distino sinttica entre blocos de comandos e listas, deve
ser realizada uma analise semntica para descobrir o que uma lista representa e quais aes
devero ser tomadas. Este tipo de anlise complexa de ser feita devido a prpria estrutura de
Telis, no momento em que a lista vai para a pilha no h nenhum indcio do objetivo desta pilha
estar sendo empilhada. Este conflito de comportamento causado pelo operador valor atual foi
resolvido no interpretador Telis utilizando-se um algoritmo baseado em backtrack. Assume-
se que uma lista uma lista de dados, caso mais tarde se descubra que na realidade um
bloco de comandos o backtrack realizado e o valor correto da lista utilizado. Esta abordagem
funciona para grande parte dos casos, entretanto causa alguns problemas. Como utilizada uma
heurstica para decidir qual das duas abordagens deve ser tomada h uma chance de se errar e
caso se erre h a possibilidade de que um valor que no deveria ser avaliado seja podendo
resultando em loops infinitos e alguns outros comportamentos inesperados.

Para resolver este problema foi proposta a distino sinttica entre listas de dados e blocos
de comandos. Na nova linguagem que est sendo desenvolvida, as listas de dados sero deli-
32

mitadas por colchetes pareados, da mesma forma que listas em Telis. Blocos por sua vez sero
representados atravs de chaves, tambm pareadas.

A listagem 2.13 contm um fragmento de cdigo da nova linguagem que mostra como listas
de dados e comandos sero representados.
[ 0 4 ] g e r a r A l e a t r i o umValor a s s o c i a r
umValor 2 >=
{
" v a l o r m a i o r ou i g u a l a 2" m o s t r a r
}
{
" v a l o r menor que 2" m o s t r a r
}
entoSeno

Listagem 2.13: Listas de dados e blocos de comandos

Alm da resoluo de problemas relativo ao operador de valor atual, a distino entre es-
truturas de dados e blocos de comandos forte em outras linguagens. Conseqentemente a
adoo desta distino na nova linguagem favorece a transio para estas outras linguagens e
vice-versa.

2.3.3 Escopo de variveis e closures

Como foi exposto anteriormente, o escopo das variveis em Telis so do tipo dinmico.
Apesar de relativamente simples, alguns de seus efeitos no so muito intuitivos quando com-
parados ao escopo esttico (lxico). O fato da avaliao de uma varivel depender do contexto
em que uma chamada a agenda for feita pode levar a erros difceis de detectar. Por este motivo,
resolveu-se utilizar o sistema de escopo de varivel esttico para a nova linguagem.

Em escopos estticos a definio de qual varivel est sendo referenciada pode ser realizado
em tempo de compilao, diferentemente do escopo dinmico onde s em tempo de execuo
isto ser decidido.

Em uma linguagem com escopo esttico, uma varivel A declarada em um bloco B aces-
svel a um bloco C declarados dentro de B aps a declarao de A. Note que caso exista um
bloco D declarado dentro de C, D tambm poder acessar a varivel A. Caso B e C possuam
duas variveis diferentes de mesmo nome, o bloco D ir utilizar a varivel C pois est a que
est lexicamente mais prxima a D.
33

Em Telis, os blocos de comandos (que no passam de listas comuns) so tratadas como


elementos de primeira classe, isto , podem ser passadas como parmetros ou retornadas (atra-
vs da pilha). Nenhuma restrio imposta neste sentido. Seria interessante manter blocos de
comandos elementos de primeira classe na nova linguagem tambm.

Em Telis o escopo dinmico facilita que blocos de comandos sejam elementos de primeira
classe. Como a varivel amarrada no momento em que executada no h problemas quanto
as variveis, elas sero amarradas quando o bloco for executado e fim. J com escopo esttico
no funciona deste modo. Com escopo esttico a varivel amarrada no momento em que o
bloco definido. Se o bloco for executado imediatamente, no ocorrem problemas. Entretanto,
caso o bloco seja passado para uma outra agenda ou for retornado, o escopo no qual o bloco
foi definido deve ser mantido para que as variveis definidas no bloco possam se referenciar ao
ambiente no qual se encontravam quando necessrio.

Closures so fragmentos de cdigo que mantm uma referncia ao ambiente no qual foram
criados. Desta forma, o retorno de um mtodo no necessariamente implica na destruio das
variveis locais deste j que um closure pode estar referenciando estas variveis locais. Isto
torna a pilha de execuo no mais uma pilha, mas sim uma rvore.

Closures so muito utilizados em linguagens como Ruby, Python, Lisp, entre outras. Alm
disso, closures provm uma forma elegante para a implementao de alguns padres de projetos
tais como Visitantes. O cdigo da listagem 2.14 mostra um cdigo escrito em Ruby que utiliza
um visitante para calcular o somatrio de uma lista de valores. Ao final da execuo, o valor 45
mostrado na tela.
valores = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]
somatorio = 0
v a l o r e s . e a c h do | x |
somatorio = somatorio + x
end
puts somatorio

Listagem 2.14: Exemplo uso de closures em Ruby

H linguagens nas quais no existem closures, apesar do escopo esttico, como Java4 . H
quem confunda as classes annimas de Java com closures, entretanto no so iguais. Classes
annimas, apesar de poderem ser utilizadas para algumas coisas da mesma forma que closures,
no so closures completos pois no mantm uma cpia para o contexto no qual fora criada.
4 Java ainda no possui closures, h um grupo de especialistas estudando a implementao, sintaxe e semntica

de closures na linguagem. Estima-se que closures sero incorporados a linguagens na verso 7 do Java.
34

Java permite apenas que variveis finais do escopo no qual a classe foi criada sejam acessadas,
permitindo que uma cpia da varivel externa seja feita para a classe annima.

A introduo de closures entretanto acarretam um problema ao modelo de concorrncia


dos atores. O modelo de atores, por definio, no possuem memria compartilhada sendo
toda a comunicao entre eles realizada via troca de mensagens. Closures carregam consigo o
contexto no qual foram definidos, logo se um closure definido em um ator A e posteriormente
enviado a um ator B e l executado, o ator B passa a executar operaes concorrentemente
com o ator A na rea de memria deste, causando uma condio de corrida (race condition).

Para evitar que este problema ocorra, h uma restrio em quem pode executar os closures.
Apenas o ator que criou um closure poder execut-lo. Desta forma, a condio de corrida ser
evitada, em contrapartida o potencial de utilizao de closures ser um pouco reduzido.

2.3.4 Objetos

Em Telis a unidade de execuo bsica um ator. Todo ator, por definio, roda indepen-
dentemente de qualquer outro ator, isto , possui uma linha de execuo prpria. Alm disso,
ele s destrudo quando executa a primitiva suicidar. Mesmo que termine sua agenda iniciar,
no pode simplesmente ser destrudo j que ele pode receber estmulos e ter de agir de acordo
com estes. Aps o trmino de execuo da agenda iniciar diz-se que ator entra em um estado
de hibernao, do qual pode ser acordado para tratar algum estmulo.

Atores uma boa forma de organizar o programa, mas no sempre isso que se deseja.
Muitas vezes no se quer uma entidade autnoma para resolver uma tarefa, mas sim algo mais
simples. Neste sentido, se prope o conceito de objeto.

A nova linguagem dever possuir o conceito de objeto. Objetos assim como atores so
definidos atravs de modelos que sero chamados de modelos de objetos. Modelos de objetos
so exatamente iguais modelos de atores, com a exceo de que quando instanciados no
criam um ator, mas sim um objeto. Um modelo de objetos, a exemplo de modelos de atores,
podero ser moldados por moldes e possuem uma coleo de agendas.

Objetos so passivos, ao contrrio de atores que so ativos. Objetos no possuem atrelados


a si uma linha de execuo, portanto dependem de um ator para poderem executar o seu cdigo.
Por este motivo toda e qualquer ao realizada com um objeto ser sncrona com o ator que
ocasionou a reao do objeto. Devido a isso no lhes ser permitido instalar tratadores de
estmulo dizer, j que estes possuem natureza assncrona. Note que no foram feitas restries
quanto a emisso de estmulos, estes podero ser emitidos sem problemas. A comunicao
35

direta, ao contrrio dos estmulos dizer, so inerentemente sncronos, logo esta abordagem ser
utilizada para permitir que atores possam interagir com objetos, e estes com outros objetos.

Para a criao de modelos de objetos ser utiliza a primitiva incluirModeloDeObjeto que


possuir os mesmos parmetros da primitiva incluirModelo. Isto , uma lista de moldes e um
bloco de comandos contendo a definio das agendas. Um exemplo de utilizao do incluirMo-
deloDeObjeto mostrado na listagem 2.15.
[ Molde1 Molde2 ] $NomeDoModeloDeObjeto
{
$iniciar
{
[ parametro ] a s s o c i a r
}
incluirAgenda

$somar
{
parametro +
}
incluirAgenda
}
incluirModeloDeObjeto

Listagem 2.15: Exemplo da criao de modelos de objetos.

A instanciao de objetos tambm se d de forma sncrona. De forma anloga atores,


quando instanciados objetos executam sua agenda iniciar, mas devido restrio imposta sobre
todas as operaes realizadas sobre objetos, garantido que a agenda iniciar ser executada at o
final antes do controle de fluxo retornar a quem o instanciou, ficando este bloqueado. Da mesma
forma que na instanciao de atores, o primeiro elemento da lista de quem est instanciando um
objeto passado como parmetro para a agenda iniciar do objeto.

2.3.5 Inicializao de apliques

Linguagens de programao como C++ e Java utilizam-se de uma marcao para definir as
classes que por sua vez contm mtodos que contm o cdigo. Em C/C++ o ponto de entrada de
programa descoberto atravs de uma conveno na nomenclatura de mtodo. O mtodo cha-
mado main ser o ponto de entrada do programa. Em Java a definio de pontos de entradas so
definidos por mtodos estticos chamados de main contidos em classes. O nome de uma classe
36

contendo este mtodo ento passada para a Mquina Virtual Java que inicializa o programa
invocando-o.

Este modo de inicializao no qual o ponto de entrada dado por uma conveno de no-
menclatura possui vantagens como simplicidade.

A proposta de Telis um pouco mais complexa. A inicializao de apliques em Telis se d


especificando um aplique e suas propriedades. Isto se d atravs da declarao dos modelos e
moldes e suas respectivas agendas que por sua vez contm o cdigo da aplicao. Alm desta
definio, ainda so declarados alguns meta-dados que definem alguns outros parmetros do
aplique tal como seu nome, dimenses e atores que devero ser instanciados.

Claro que ningum escreve um aplique na mo. Programadores Telis se valem do ambiente
de desenvolvimento que torna todo o processo de definio de atributos grfico, deixando ao
programador o foco apenas no que importante.

Visando simplificar este processo, a nova linguagem dever possuir um novo sistema de ini-
cializao mais simples e menos verboso, isto , aplicaes simples devem poder ser descritas
de forma mnima. Linguagens como Python e Ruby conseguiram isto. No necessrio espe-
cificar nenhum ponto de entrada no programa. O cdigo inteiro pode ser visto como a definio
de um mtodo que ser invocado, podendo-se escrever instrues diretamente no arquivo fonte
sem a necessidade de marcar trechos de cdigo. Com a evoluo do programa, pode-se ento
criar novas classes, mtodos, entre outras coisas demarcando trechos de cdigo com palavras
chaves, mas a princpio isto no necessrio.

A nova linguagem adotar esta idia presente nestas linguagens. Um cdigo fonte nada mais
do que a definio da agenda iniciar de um modelo que ser instanciado automaticamente,
sendo criado o primeiro ator do sistema. Desta forma, o programa mostrado na listagem 2.16
ser vlido e faria exatamente a mesma coisa que o programa mostrado na listagem 2.17. Como
pode-se notar h uma grande simplificao do cdigo na linguagem nova em relao ao Telis
nos casos mais simples.
10 $x a s s o c i a r
20 $y a s s o c i a r
x y + mostrar
suicidar

Listagem 2.16: Exemplo programa linguagem nova.

[50 50] " ProgramaEquivalente " [ Mo de lo Ini ci al ]


[
[] " ModeloInicial "
37

[
" iniciar "
[
10 x a s s o c i a r
20 y a s s o c i a r
x y + mostrar
suicidar
]
incluirAgenda
]
incluirModelo
]
incluirAplique

Listagem 2.17: Programa equivalente ao da listagem 2.16 em Telis.

2.3.6 Ambientes de execuo

A linguagem que ser desenvolvida dever poder rodar em ambientes distintos, com pecu-
liaridades diferentes. Um ambiente de execuo o local no qual o aplique rodar. A princpio
sero definidos trs ambientes bsicos, mas no so limitados apenas a estes:

Aplicao textual (console)

Aplicao grfica baseada em turtle graphics

Aplicao servidor

Um aplique dever ser capaz de rodar em um destes trs ambientes. Entretanto h diferenas
muito grandes com relao ao que dever ser oferecido ao programador em cada um destes
ambientes. Em ambientes grficos deve-se oferecer formas de manipular diferentes objetos
grficos, coisa que no dever existir em aplicaes textuais e de servidor.

Linguagens como Java resolvem este tipo de problema, fazendo uma linguagem absoluta-
mente neutra e entrega APIs (Application programmers interface) e frameworks que encapsu-
lam as peculiaridades destes ambientes. Esta uma abordagem simples, que transfere a res-
ponsabilidade da linguagem para a biblioteca desta mesma linguagem. Entretanto, Telis assim
como a nova linguagem tem como principal objetivo ser simples. Toda a funcionalidade ine-
rente a um dado ambiente deve estar disponvel de forma simples sem a necessidade de utilizar
38

frameworks ou APIs complexas. Telis resolveu o problema se limitando a um ambiente apenas,


o grfico.

A nova linguagem dever ser capaz de rodar independentemente do ambiente. Note que
no foi mencionado que um mesmo aplique dever ser capaz de rodar em mais de um ambiente
simultaneamente.

O paradigma de orientao a objeto possui um princpio chamado princpio de separao


de preocupaes (separation of concerns). Este princpio diz uma classe deve possuir uma e
apenas uma responsabilidade, quando uma classe comea a ter mais responsabilidades do que
deveria, ento ela deve ser dividida em outras classes.

Aplicando este princpio, podemos dizer que a nova linguagem na verdade ser composta
por um framework comum e especializada para cada um destes diferentes ambientes de exe-
cuo. Quando o ncleo da linguagem especializado para um determinado ambiente de exe-
cuo, agendas primitivas especializadas podero ser includas, modelos/moldes definidos, a
inicializao personalizada, integrao com o ambiente em questo realizada e qualquer outra
ao que se achar necessria.

O inconveniente desta abordagem a existncia de vrios dialetos da linguagem, desta


forma um aplique escrito em um ambiente no rodar em outro e o programador dever estar
ciente disto e escolher o dialeto apropriado para o ambiente de execuo desejado. Entretanto,
em linguagens comuns, programas que funcionam em vrios ambientes de execuo sem alte-
raes so raros, gerando erros em ambientes no suportados.

2.3.7 Definio sinttica e lxica formal da nova linguagem

A definio lxica da nova linguagem intermediria mostrada na listagem 2.18. A defini-


o lxica bastante simples, sendo definidos os terminais para comentrios, nmeros, textos,
smbolos e operadores. O operador de pr-avaliao de Telis no ser implementado na nova
linguagem, mas poder ser integrado futuramente.
<COMENTARIO> = " ( " ( ~ [ " } " ] ) " ) "
<TEXTO> = " \ " " ( ~ [ " \ \ " , " \ n " , " \ r " , " \ " " ] | ( " \ \ " [" n " ," t " , " \ \ " , " \ " " ] ) )
"\""
<NUMERO> = ( " " ) ? ( <FLOAT> | <FLOAT> ( [ " e " , " E " ] ( [ " " , " + " ] ) ? <INTEIRO> ) ? )
<FLOAT> = <INTEIRO> | <INTEIRO> ( [ " , " ] <INTEIRO> ) ?
<INTEIRO> = [ " 0 " " 9 " ] +
<SIMBOLO> = ( <LETRA> | " _ " ) + ( <DIGITO> | <LETRA> | " _ " )
<LETRA> = [ " a "" z " , "A""Z " ] | " " | " " | " " | " " | " " |
"" | "" | "" | "" | "" | " " | " " | " " | " " |
39

"" | "" | "" | "" | " " | " " | " " | " " |
" " | " " | " " | " " | "" | "" | "" | "" | "" |
"" | "" | "" | "" | "" | " " | " " | " " | " " |
"" | "" | "" | "" | " " | ""
<OPERADOR> = ( " + " | "" | " " | " / " | "\\" | " ^ " | " = " | "~=" | " <" | " >" |
" <=" | " > = " )

Listagem 2.18: Definio lxica da nova linguagem

A gramtica da nova linguagem mostrada na listagem 2.19. Como possvel notar, em


comparao com a gramtica do Telis mostrada na listagem 2.1 na pgina 12 a gramtica da
nova linguagem est muito mais simples. Grande parte da simplificao ocorre devido a nova
abordagem de lanamento adotada na linguagem nova.
i n s t r u c o e s : : = ( i n s t r u c a o ) <EOF>
i n s t r u c a o : : = t e x t o | operador | operadorDeEmpilhamento |
operadorDeComunicacaoDireta
| numero | s i m b o l o | lista | bloco
t e x t o : : = <TEXTO>
numero : : = <NUMERO>
s i m b o l o : : = <SIMBOLO>
o p e r a d o r : : = <OPERADOR>
o p e r a d o r D e E m p i l h a m e n t o : : = " $ " <SIMBOLO>
o p e r a d o r D e C o m u n i c a c a o D i r e t a : : = " . " <SIMBOLO>
l i s t a ::= "[" ( instrucao ) "]"
bloco : : = "{" ( i n s t r u c a o ) "}"

Listagem 2.19: Gramtica BNF da nova linguagem


40

3 Implementao do Interpretador

A implementao do interpretador foi realizado utilizando-se a linguagem de programao


Java. Java uma linguagem moderna, surgida em meados da dcada de 90 muito utilizada nos
dias de hoje para programao profissional. uma linguagem orientada a objetos, fortemente
tipada.

3.1 Viso geral

O interpretador foi desenvolvido utilizando-se o paradigma de orientao a objetos. E foi


subdividido em diversos mdulos, tendo cada um uma responsabilidade dentro do sistema.

O diagrama de classes completo ser omitido devido ao seu tamanho. O sistema com-
pleto composto por algumas centenas de classes e se torna impraticvel coloc-lo na integra.
Entretanto os pontos mais interessantes sero abordados.

O interpretador dividido em trs grandes reas como ilustrado na figura 3.1. Os wrappers
so uma biblioteca que implementa uma hierarquia de tipos responsveis por encapsular os tipos
de dados primitivos de Java, como por exemplo Strings, nmeros(double) nome, alm de repre-
sentar os tipos de dados nicos em Telis, como os smbolos, e fornecer operaes sobre estes
que ainda no existem nativamente na linguagem. Alm disso, possuem uma superclasse co-
mum permitindo que sejam criadas estruturas de dados parametrizadas. O corao da mquina
responsvel pela maior parte da funcionalidade do interpretador, ele implementa a estrutura
bsica da linguagem, as aes semnticas independentes do ambiente, o parser da linguagem, a
estrutura de concorrncia e sincronizao, etc.. Por fim, o ambiente ser responsvel em adaptar
o corao da mquina para cada um dos ambientes suportados, implementando primitivas de-
pendente do ambiente, realizando a inicializao da mquina e do ambiente no qual se encontra
entre outras funes. Para este trabalho sero desenvolvidos dois ambientes de execuo distin-
tos. O primeiro baseado em console, o segundo ser grfico sendo disponibilizadas agendas
primitivas para efetuar operaes tpicas de Turtle Graphics, de Logo.
41

Figura 3.1: Diagrama de camadas do sistema.

3.2 Viso geral da biblioteca de wrappers

A biblioteca de wrappers, como j foi comentado, encapsula os tipos de dados primitivos


de Java com o objetivo de:

1. Diferentes tipos de dados pertencerem a uma mesma hierarquia de classes

2. Definir operaes comuns sobre tipos fora do corao da mquina

O primeiro objetivo se deve ao fato de melhor utilizar os tipos genricos introduzidos na


verso 5 de Java. Alm disso, permite a definio de mtodos abstratos na raiz da hierarquia de
classes e a utilizao de polimorfismo.

O segundo objetivo visa aumentar a coeso, removendo cdigo de manipulao dos dados
das classes pertencentes ao corao da mquina e movendo-o para classes especializadas.

Os mdulos e classes de um sistema orientados devem apresentar alta coeso, isto , cada
classe e mtodo deve possuir uma nica responsabilidade. Mdulos e classes no coesas acarre-
tam problemas de manutenibilidade de cdigo, j que se torna difcil localizar onde determinada
funcionalidade dever ser encontrada e quando encontrada, ela normalmente est misturada com
cdigo responsvel por outras funcionalidades fazendo com que mudanas possam acarretar
conseqncias no previstas.

A figura 3.2 mostra o diagrama de classes da hierarquia de wrappers. Nota-se que h


algumas classes como OperadorDeComunicacaoDireta, ListaDeComandos e OperadorDeEm-
pilhamento que representam estruturas e particularidades do prprio cdigo Telis. Estas classes
existem pois o interpretador mantm internamente os dados e o cdigo da mesma forma, uti-
lizando listas de palavras. A primeira linguagem a possuir esta caracterstica foi Lisp, esta
propriedade chamada de homoiconic.
42

Figura 3.2: Diagrama de classe mostrando hierarquia dos wrappers.

Alm destas classes, existe ainda mais uma classe adicional junto esta estrutura. uma
instncia do padro de projeto Builder, cujo nome ConstrutorDeListas. O objetivo do padro
de projeto Builder separar a construo de um objeto complexo de sua representao. A figura
3.3 mostra a estrutura tpica de um Builder.

Figura 3.3: Diagrama de classe mostrando estrutura geral do padro builder.

O padro builder, conforme descrito por Gamma et al. (1995), possui os seguintes elementos
com suas respectivas responsabilidades:

director: constri um objeto utilizando a interface do builder


43

builder: especifica uma interface para um construtor de partes do objeto product

concrete builder: define uma implementao da interface builder

product: o objeto complexo em construo

Optou-se em utilizar o padro Builder para permitir a criao de listas e a definio de seu
contedo sem a necessidade de conhecimento da hierarquia mostrada na figura 3.2. A listagem
3.1 mostra um fragmento de cdigo Java criando uma lista com e sem a utilizao do Builder.
Nota-se que o cdigo que utiliza o builder no precisa ter conhecimento sobre os detalhes de
construo dos objetos, pois estes detalhes esto encapsuladas no ConstrutorDeListas.
/ / Utilizando Builder
C o n s t r u t o r D e L i s t a s c o n s t r u t o r = new C o n s t r u t o r D e L i s t a s ( ) ;
L i s t a < P a l a v r a > l i s t a = c o n s t r u t o r . a d i c i o n a r T e x t o ( "umTexto" )
. iniciarLista ()
. adicionarNmero (10)
. terminarLista ()
. obterSaidaComoLista ( ) ;
/ / Sem u t i l i z a r B u i l d e r
L i s t < P a l a v r a > c o n t e u d o = new A r r a y L i s t < P a l a v r a > ( ) ;
c o n t e u d o . add ( new T e x t o ( "umTexto" ) ) ;
L i s t < P a l a v r a > p r i m e i r o E l e m e n t o = new A r r a y L i s t < P a l a v r a > ( ) ;
p r i m e i r o E l e m e n t o . add ( new Numero ( 1 0 ) ) ;
c o n t e u d o . add ( new L i s t a < P a l a v r a > ( p r i m e i r o E l e m e n t o ) ) ;
L i s t a < P a l a v r a > l i s t a E q u i v a l e n t e = new L i s t a < P a l a v r a > ( c o n t e u d o ) ;

Listagem 3.1: Ilustrando criao de listas. A lista nas variveis lista e listaEquivalente so
iguais.

O ConstrutorDeListas possui um ciclo de vida representado pela mquina de estados mos-


trado na figura 3.4. Quando criado, o ConstrutorDeListas se encontra no estado Aberto e espera
que a descrio da lista seja feita. Aps a lista (que faz o papel de product) ser retirada do
ConstrutorDeListas atravs dos mtodos obterLista ou obterListaDeDados ocorre a transio
para o estado Fechado. Neste estado o objeto para de responder as mensagens, devendo ser
descartado. Caso alguma mensagem seja enviada este objeto uma exceo ser lanada. Para
implementar este comportamento utilizou-se o padro de projeto Estado.

O diagrama da figura 3.5 mostra a classe ConstrutorDeListas e o padro Estado responsvel


pela gerncia do ciclo de vida do objeto.
44

Figura 3.4: Diagrama de estados mostrando ciclo de vida de um ConstrutorDeListas.

Figura 3.5: Diagrama mostrando estrutura do ConstrutorDeListas e de seus Estados.

3.3 O corao da mquina

O corao da mquina o cerne do interpretador. Ela um framework cuja responsabili-


dade oferecer a infreestrutura bsica da linguagem de forma que cada um dos ambientes de
execuo possa personalizar este framework da forma que for necessria.

O corao da mquina responsvel por:

Realizar o parsing da entrada

Possuir infraestrutura para a interpretao

Oferecer primitivas bsicas como, por exemplo, primitivas de controle de fluxo


45

Oferecer mecanismos de herana, isto , moldes e modelos

Implementar closures

Implementar detalhes bsicos da linguagem como vriaveis e escopos

Implementar Atores, incluindo os seus mecanismos de comunicao

Alm destes detalhes que o corao da mquina deve implementar h uma srie de outras
caractersticas desejveis:

Oferecer mecanismo simples para incluso de novas primitivas

Oferecer mecanismos para simplificar a configurao e criao de novos ambientes

Como pode-se notar o corao da mquina a parte mais complexa da implementao e


ainda deve ser flexvel o bastante para que possa atuar em diversos ambientes. Para explicar o
funcionamento e organizao do interpretador ser explicado o que ocorre a partir da classe Am-
bienteAbstrato. A classe AmbienteAbstrato uma classe abstrata que deve ser estendida pelos
ambientes. Ela responsvel por simplificar o desenvolvimento de novos ambientes realizando
tarefas comuns a todos os ambientes de execuo como a inicializao dos subsistemas, confi-
gurao da mquina (interpretador) e a criao do ator inicial. Esta classe uma instncia do
padro Method Template, descrevendo o algoritmo de inicializao da mquina de forma geral,
deixando detalhes especficos para implementao nas subclasses atravs de mtodos abstratos.
Neste caso, as subclasses so implementadas pelos utilizadores do framework.

A classe AmbienteAbstrato possui os mtodos mostrados no diagrama de classe mostrado


na figura 3.6. Seu construtor recebe um Reader, abstrao de um fluxo de caracteres implemen-
tado na biblioteca padro de Java, com o cdigo fonte que dever ser executado pelo interpreta-
dor. Ento o mtodo iniciarAplique deve ser invocado pelo ambiente de execuo. Este mtodo
tem quatro passos bsicos:

configurar ambiente de execuo

enviar cdigo do programa para o parser

criar um ator para executar o programa

iniciar a execuo do ator


46

Figura 3.6: Diagrama de classes de AmbienteAbstrato.

Daqui pode-se perceber como ocorre o incio da interpretao. responsabilidade do am-


biente de execuo obter um Reader com o cdigo fonte e pass-lo ao AmbienteAbstrato. O
AmbienteAbstrato ir redirecionar ao parser. O parser ir por sua vez gerar uma estrutura de
dados representando o programa e o texto pode ento ser descartado. Depois disso, os subsiste-
mas necessrios so inicializados e um ator criado e lhe passado o programa para execuo.
O diagrama da figura 3.7 mostra esquematicamente o que cada mdulo recebe como entrada
e produz at que o ator possa ser iniciado. Neste diagrama, quadrados representam mdulos
enquanto paraleleppedos representam os dados/produtos que cada um dos mdulos consomem
ou produzem. As partes acinzentadas indicam quais passos so dependentes do ambiente. Este
diagrama mostra apenas o fluxo de dados, partindo do cdigo fonte e chegando ao primeiro ator
do sistema, entretanto a inicializao no se restringe apenas a isto. Toda uma configurao
dependente de ambiente realizada e omitida do diagrama.

Figura 3.7: Diagrama esquemtico da entrada e sada at criao do primeiro ator.


47

3.3.1 O Parser

Para criar o parser do interpretador foi utilizado um compiler-compiler chamado JavaCC.


Um compiler-compiler um compilador que recebe como entrada uma especificao formal,
normalmente uma gramtica baseada em EBNF, e gera um parser em uma linguagem de pro-
gramao convencional. JavaCC gera um parser LL(k) na linguagem Java.

Existem vrios outros compiler-compilers para Java, mas uma das principais vantagens do
JavaCC que o cdigo gerado por ele no depende de nenhuma outra biblioteca como comum
em outras aplicaes. As classes geradas pelo JavaCC so mostradas no diagrama da figura 3.8.

Figura 3.8: Diagrama das classes geradas pelo JavaCC.

O JavaCC permite que aes sejam realizadas quando uma sentena da linguagem reco-
nhecida. Estas aes so fragmentos de cdigo que podem realizar aes arbitrrias. No caso
do interpretador da nossa linguagem, estas aes so utilizadas para gerar uma estrutura de
48

dados intermediria representando o programa. A estrutura gerada durante o parsing pelo in-
terpretador uma Lista, e esta lista pode possuir qualquer elemento do tipo Palavra (hierarquia
mostrada na figura 3.2).

Para facilitar a gerao e diminuir a quantidade de cdigo dentro do parser gerado pelo
JavaCC utilizado sistema de callback, isto , toda vez que uma determinada seqncia reco-
nhecida pelo interpretador uma mensagem enviada a um objeto previamente cadastrado. Este
objeto uma instncia da classe ConstrutorRepresentacaoInterna. Esta classe uma instancia
do padro de projeto Adapter. Um adapter adapta a interface de um objeto para uma segunda in-
terface esperada pelo cliente, sendo responsabilidade dele transformar os parmetros recebidos
para os esperados. A classe ConstrutorRepresentacaoInterna adapta a classe ConstrutorDeLis-
tas para a interface de notificao esperada pelo parser.

Vrias classes so geradas pelo JavaCC, cada uma responsvel por uma parte do processo de
parsing. A classe ParserTelisTokenManager responsvel por realizar a analise lxica, gerando
tokens para a classe ParserTelis que implementa o analisador sinttico. As demais classes so
classes auxiliares utilizadas como estruturas de dados (Token por exemplo), classes utilitrias
(como JavaCharStream) ou classes para reportar erros.

3.3.2 Classes Aplique, Ator e Modelo

Aps o parsing ter sido concludo, e a representao interna do programa gerada o prximo
passo tomado pelo algoritmo de inicializao implementado em AmbienteAbstrato a criao
de um ator e o incio de sua execuo.

A classe Ator a abstrao de atores no interpretador. O diagrama de classes da figura 3.9


mostra a classe Ator e a sua relao com as classes Modelo e Aplique.

A classe Aplique uma instncia do padro de projeto Method Factory. Ela responsvel
pela criao de novos atores, durante a criao de um ator, o mtodo fbrica alm de cri-lo
deve passar para o ator o seu parmetro inicial, o modelo a qual o Ator pertence e fornecer
ele uma identidade nica. Alm destas responsabilidades, a classe Aplique deve manter uma
coleo contendo todos os atores criados no sistema, para que, por exemplo, atores possam ser
notificados de estmulos emitidos. Alm de usar o padro Method Factory, o padro Singleton
tambm usado nesta classe, pois o interpretador deve possui um e apenas um Aplique criando
e mantendo referencias para os Atores.

A classe Aplique ainda oferece a possibilidade de uso do padro de projeto Visitor para que
um visitante visite todos os atores instanciados, de forma que durante o processamento nenhum
49

Figura 3.9: Diagrama de classes de Ator, Aplique e Modelo.

ator novo seja criado ou destrudo, evitando problemas de concorrncia.

A classe Modelo guarda a descrio do ator, isto , a descrio de suas agendas (nome e
cdigo) e moldes. Oferece mtodos para acesso a descrio e para a alterao da mesma. Todo
Ator est atrelado a um Modelo, e este deve ser informado durante a construo do Ator.

O ator possui o ciclo de vida mostrado no diagrama de estados da figura 3.10. Quando o
ator instanciado ele se encontra no estado Criado. Aps o mtodo iniciarExecuo da classe
Ator ser invocado, o ator em questo transita para o estado Executando. Aps a transio, a
execuo de sua agenda iniciar realizada em uma linha de execuo (Thread ) prpria. Aps a
agenda iniciar ter sido concluda e retornado, o ator entra no estado Hibernando. Neste estado
o ator apenas espera por eventos. Um evento pode ser a chegada de um estmulo emitido por
um dizer ou uma comunicao direta, e em decorrncia destes estmulos o ator pode realizar
algum processamento novamente. O ator fica neste estado indefinidamente at que ele seja
destrudo, transitando para o estado Morto. Neste estado, o ator est se preparando para ser
destrudo tomando as medidas necessrias antes disso tais como: desregistrar-se de qualquer
lugar que tenha se inscrito para callback, sair da lista de atores do Aplique, finalizar a sua linha
de execuo.

Um objeto Ator uma instncia do padro de projeto Observer. Em cada uma das transies
do seu ciclo de vida, eventos so gerados e os observadores cadastrados no ator so notificados.
Desta forma oferecido ganchos para subsistemas realizarem aes dependendo do estado do
ator. Por exemplo, o subsistema de estmulos observa o ator e s o deixa receber estmulos de
50

Figura 3.10: Diagrama de estados do ciclo de vida de um Ator.

comunicao direta aps ele ter entrado no estado de hibernao.

3.3.3 Mquina de Pilha

A classe Ator mantm as referncias para o modelo e oferece mecanismos para o controle de
ciclo de vida de um ator, entretanto no responsvel diretamente pela execuo. Este trabalho
delegado para a classe MaquinaDePilha. A classe mquina de pilha quem realmente executa
o cdigo.

O ciclo de execuo de um cdigo bastante simples, e ilustrado no diagrama da figura


3.12. A MaquinaDePilha ir receber uma lista de Palavras para executar. Com a lista em
mos, tudo que a MaquinaDePilha faz iterar sobre esta lista e tomar as medidas cabveis
para cada um dos elementos. Existem trs possveis caminhos para um dado elemento. Caso o
elemento a ser executado seja uma ListaDeComandos, a mquina de pilha cria um novo Closure
e o empilha. Caso o elemento seja uma simbolo Resolvivel, isto , implemente a interface
Resolvivel, o smbolo ser submetido a uma pesquisa em busca de um Executavel (instncia do
padro Command) e ento o Executavel ser executado. Caso nenhum dos casos acima ocorra,
o elemento empilhado. As palavras que implementam a interface Resolvvel so:

Simbolo

Operador
51

Figura 3.11: Diagrama de classes da MaquinaDePilha e seus colaboradores.

OperadorComunicacaoDireta

OperadorEmpilhamento

A separao da busca de um Executavel para um Resolvivel do algoritmo de execuo o


que traz a flexibilidade ao interpretador permitindo que primitivas diferentes sejam mapeadas
para aes diferentes dependendo do ambiente de execuo. Quando a MaquinaDePilha en-
contra uma Palavra que implementa a interface Resolvivel, ela delega para um Resolvedor. O
Resolvedor um interface contendo um nico mtodo que recebe como parmetro um Resol-
vivel e retornando um Executavel. Caso nenhum Executavel seja encontrado retornado null,
e a MaquinaDePilha gera um erro em tempo de execuo caso contrrio o mtodo executar do
Executavel retornado invocado.

A MaquinaDePilha ao ser criada possui um ResolvedorNulo. Objetos nulos so um padro


52

Figura 3.12: Diagrama da execuo na MaquinaDePilha.

de projeto, apesar de no estarem entre os definidos por Gamma et al. (1995), e fornecem um
comportamento padro quando um objeto de determinado tipo no existe, substituindo assim o
null. O ResolvedorNulo no capaz de realizar nenhuma transformao de Resolvivel em Exe-
cutavel, portanto a MaquinaDePilha ir gerar erros de execuo para todo e qualquer Resolvivel
que for encontrado. O resolvedor pode ser alterado utilizando-se IoC, sigla para Inversion of
control. Neste estilo de programao os colaboradores de um objeto so injetados no mesmo
por algum responsvel por criar e gerenciar as dependncias entre estes objetos. No caso da
mquina de pilha, quem responsvel por gerenciar estas dependncias a classe Ator. Ela
cria, configura e injeta os colaboradores da MaquinaDePilha.

Para garantir flexibilidade e tornar simples e configurvel o Resolvedor, que quem real-
mente conhece as primitivas e como execut-las, utilizou-se o padro Composite. A classe que
implementa o padro composite chamada de ResolvedorComposto. O padro de projeto Com-
posite cria uma interface nica para colees de objetos e objetos propriamente dito. No caso
do Resolvedor, este comportamento se torna bastante til pois a MaquinaDePilha no precisa
de lgica adicional para tratar com colees de Resolvedores, e torna os resolvedores extre-
mamente flexveis pois cada subsistema pode criar um Resolvedor prprio contendo apenas os
seus prprios mapeamentos e uma entidade separada ser responsvel por coletar todos os resol-
vedores desejados. E isto mesmo que feito. Cada subsistema fornece um resolvedor (que
por sua vez pode ser um outro Composite) e um objeto separado configura um ResolvedorCom-
posto contendo referencia para todos os outros resolvedores. Este ltimo objeto implementa a
interface InstaladorDeModulos que deve ser implementado pelos ambientes de execuo, ele
53

armazenado junto classe Aplique e passado para as instancias de Ator que a utilizam para
configurar um resolvedor composto antes de injet-lo na MaquinaDePilha.

Uma instncia do padro Composite, como o caso do ResolvedorComposto, traz uma srie
de benifcios mas traz uma definincia muito importante para o interpretador: a ordem. A
ordem em que os resolvedores filhos sero invocados para a busca de um Executavel no
definida pelo padro. Isto um problema pois caso dois subsistemas definam dois Executaveis
diferentes para um mesmo Resolvivel, cria-se um problema. A linguagem deve fornecer um
esquema de prioridades para resolver este tipo de questo. Por este motivo, criou-se uma verso
um pouco alterada do ResolvedorComposto, chamado de ResolvedorPorCastas. A idia por trs
do ResolvedorPorCastas criar um Composite que leve em considerao os tipos essenciais
de resolvedores estipulando um ordem entre eles. Desta forma, o problema de prioridades
resolvido.

3.3.4 Escopo variveis

O escopo de variveis a rea de cdigo na qual as variveis declaradas so visveis. No


interpretador, foi criada uma classe Escopo. A classe Escopo possui um mapeamento entre
nomes de variveis e valores. Alm disso, esta classe uma instncia do padro de projeto Chain
of Responsability. Possuindo assim uma referncia a um segundo Escopo que utilizado se o
escopo atual no possuir a varivel declarada. Neste caso, a ao delegada ao segundo escopo.
Com isso se torna fcil implementar cadeias de escopos. Por exemplo, um Ator possui variveis
de instncias que so visveis em todo cdigo do ator. Ao realizar a chamada a uma agenda
qualquer, criado um novo escopo e o escopo do ator colocado no Chain of Responsability.
Desta forma as variveis do ator continuaro a ser visveis na agenda mas a agenda ainda poder
referenciar as variveis do escopo do ator.

O escopo de variveis esta atrelado chamadas de agendas. Toda mquina de pilha possui
atrelada a si um GerenteDeEscopo. Toda vez que uma agenda invocada, o gerente de escopo
cria um novo escopo, e sempre que a agenda retorna, o escopo anterior restaurado.

Quem far uma chamada de agenda o subsistema que cuida de agendas, modelos e moldes.
Mas a mquina quem deve oferecer a infra-estrutura bsica para que este subsistema possa
controlar a mquina de pilha fazendo com que ela altere seu fluxo de execuo. Para isso
utilizada uma classe interna a mquina de pilha chamada ControladorDaMaquinaDePilha. Ela
classe interna privada, mas implementa uma interface pblica e passada como parmetro
para o Executavel. A classe ControladorDaMaquinaDePilha oferece mtodos para a execuo
de uma agenda, quando este mtodo invocado o ControladorDaMaquinaDePilha ir criar um
54

novo escopo com o escopo do ator como sendo o prximo escopo na cadeia de responsabilidade,
como explicado anteriormente. Ento realizada uma chamada MaquinaDePilha para que ela
execute o cdigo da agenda, como o escopo atual foi trocado no GerenteDeEscopo, a agenda
executar no novo escopo. Aps terminar a execuo da agenda, o fluxo de execuo retorna
ao ControladorDaMaquinaDePilha e o escopo que estava sendo utilizado antes da agenda ser
invocada restaurado e a MaquinaDePilha ir continuar a executar do ponto onde havia parado.

3.3.5 Criao e execuo de closures

Closures so uma lista de comandos mais as variveis e primitivas disponveis no escopo


no qual ele foi declarado. Desta forma, variveis e primitivas encontradas em uma lista de
comandos continuam sendo acessveis mesmo depois que o escopo onde o closure foi definido
tenha sido destrudo.

Para a implementao de closures, foi criada no interpretador a classe Closure. A classe


Closure uma classe contendo referncias para uma ListaDeComandos, que define os coman-
dos a serem executados, para uma MaquinaDePilha, indicando o local onde foi declarado e
para o escopo onde o Closure foi criado. No momento em que a MaquinaDePilha processa uma
ListaDeComandos, um Closure criado e empilhado.

Closures podem ser executados posteriormente a sua declarao pela primitiva executar.
Esta primitiva envia uma mensagem ao ControladorDeMaquinaDePilha informando que se de-
seja executar o closure. Neste momento, a MaquinaDePilha troca o escopo que ela est utili-
zando para o escopo referenciado pelo Closure, executa a ListaDeComandos atrelado ao closure
e em seguida restaura o escopo que estava sendo utilizado anteriormente. O diagrama de classes
da figura 3.13 mostra o Closure, a interface ControladorDeExecucaoDaMaquina e sua imple-
mentao Controlador. Como pode-se ver, o Controlador possui os mtodos executar(Closure),
para realizar a execuo de um closure, e o mtodo avaliarExpresso(Closure, Palavras) que
permite que um closure seja avaliada e o que permanecer no topo da sua pilha ir ser retornado.
Importante ressaltar que avaliarExpresso no modifica a pilha que a MaquinaDePilha est uti-
lizando, uma nova pilha criada e as palavras passadas como parmetros empilhadas nesta
pilha temporria. Aps o termino de execuo do closure a pilha que estava sendo utilizada
restaurada e o fluxo de execuo retomado.

Existem outras primitivas que podem implicar na execuo de um closure como as pri-
mitivas de deciso (seVerdade, seFalso) e iterao (enquantoVerdadeiro, vezesRepetir). Outra
utilidade importante do closure que ele utilizado para definir o que deve ser feito em resposta
a um determinado evento, isto , definir as aes a serem tomadas mediante a chegada de um
55

evento.

Figura 3.13: Diagrama mostrando Closure e sua relao com o ControladorDeExecucaoDaMa-


quina.

3.3.6 Classe Programa

A classe Programa responsvel por armazenar e fornecer um ponto de acesso a estruturas


que descrevam modelos e moldes definidos pelos usurios. Esta classe uma instncia do pa-
dro Singleton, da mesma forma como Aplique. Todos os modelos que podem ser instanciados
e moldes que podem ser referenciados durante a execuo do programa deve estar armazenado
aqui.

A classe Programa descreve estaticamente a estrutura do programa, e est intimamente


relacionada a classe Aplique. O subsistema da classe Programa responsvel por fornecer
primitivas de criao de modelos, moldes e agendas. Alm disso, deve trabalhar em conjunto
com a classe Aplique para permitir a instanciao de Modelos previamente criados. O diagrama
de classes da figura 3.14 mostra a classe Programa e seus mtodos.

3.3.7 Modelo, moldes e herana

Como visto anteriormente, o programa armazena os modelos e moldes e fornece um ponto


de acesso global aos mesmo atravs do padro de projeto Singleton. Os moldes e modelos por
sua vez so um conjunto de agendas e lista de moldes que o moldam. Modelos e moldes so
representadas pelas classes ModeloDeAtor e Molde respectivamente. O diagrama de classes da
figura 3.15 mostra as classes ModeloDeAtor e Moldes e sua hierarquia de classes.

A classe Molde herda de ConteinerAbstrato, responsvel por implementar funes bsi-


cas comuns a moldes e modelos, como manuteno dos moldes e agendas, com mtodos para
56

Figura 3.14: Diagrama da classe Programa e seus mtodos.

adicionar, remover e acessar as estes elementos. Alm disso, implementada nesta classe o
algoritmo para o clculo do ordenamento topolgico sobre o grafo de herana, que define a
ordem em que as agendas herdadas sero invocadas.

Para percorrer o grafo de herana na ordem em que as agendas sero invocadas utilizado
o padro de projeto Visitor. O padro Visitor utilizado para separar o algoritmo utilizado para
percorrer uma estrutura de dados do algoritmo que operar sobre os dados contidos nesta estru-
tura. A principal vantagem da utilizao deste padro que se torna simples adicionar ou trocar
os algoritmos que iro operar sobre os dados. Outro padro que normalmente utilizado nestes
casos o padro Iterator. A principal diferena entre os dois padres que responsabilidade
de quem utiliza o Iterator verificar se h mais dados e peg-los do Iterator. No caso do Visitor,
quem faz isso o prpria classe da estruturas de dados. Logo o padro Visitor melhor, neste
caso, pois encapsula mais detalhes do que o Iterator tornando o cdigo do usurio mais simples
do que o equivalente utilizando Iterator.

Quando uma agenda invocada deve ser calculada todas as agendas que devero ser in-
vocadas, isto , as agendas de toda a hierarquia do modelo. Para isto, utilizado um visitante
que percorre a hierarquia de moldes em ordem e cria um objeto da classe AgendaComposta,
que uma instncia do padro de projeto Composite. O diagrama de classes pode ser visto no
diagrama da figura 3.16. A classe Agenda , na nomenclatura do padro Composite um Leaf
enquanto a classe AgendaComposta um Composite e a interface IAgenda um Component.
57

Figura 3.15: Diagrama das classes ModeloDeAtor e Molde.

3.3.8 Estmulos e comunicao direta

Estmulos e comunicao direta so os mecanismos que so oferecidos pela linguagem para


permitir que dois ou mais atores se sincronizem, troquem dados, se comuniquem. Assim sendo,
so importantssimos. A diferena entre ambos, como j explanado, que um sncrono e di-
recionado - comunicao direta - enquanto outro assncrono e segue um sistema de broadcast.

Estes mecanismos foram implementados por um subsistema de estmulos que fornece um


Executavel s primitivas dizer e seDito, alm de fornecer um Executavel para o Resolvivel
OperadorDeComunicacaoDireta. A classe responsvel por armazenar pedidos pendentes de
comunicao direta, verificar a disponibilidade de um tratador e verificar se possvel tratar
interrupes (prioridades entre atores) a classe MaquinaDeEstimulos. As mquinas de es-
tmulos necessitam realizar comunicao entre si, para isto foi utilizado o padro de projeto
Mediator. O objetivo do padro Mediator encapsular a iterao entre objetos em um nico
objeto. A classe que usa este padro o MediadorDeMaquinasDeEstimulos.

A MaquinaDePilha possui um sistema bsico para suportar tratamento de estmulos. Diz-


58

Figura 3.16: Diagrama da hierquia Agenda.

se que uma MaquinaDePilha sofre uma interrupo quando deve parar o que est executando
para executar um tratador. A MaquinaDePilha permite o agendamento de uma interrupo e
um sistema de callback utilizado para notificar MaquinaDeEstimulos quando a interrup-
o finalizou o seu tratamento. Na MaquinaDePilha no h nenhum esquema de prioridade, o
estmulo agendado na MaquinaDePilha ir interromper a mquina independente do que a Ma-
quinaDePilha est fazendo no momento. A responsabilidade de implementar prioridades da
MaquinaDeEstmulos.

3.4 Ambientes de execuo

Os Ambientes de Execuo so responsveis pela especializao do corao da mquina


para cada ambiente especfico que a linguagem ir suportar. O corao da mquina fornece ao
ambiente de execuo vrios pontos nos quais o ambiente poder modificar, contribuir e perso-
nalizar, sendo os mais importantes a criao de novas primitivas, alterao do comportamento
de primitivas j existentes baseado no contedo da pilha. Alm disso possvel criar novos
tipos de dados, adicionando novas palavras a hierarquia Palavra tornando simples por exemplo
que um ambiente grfico por exemplo crie dados do tipo Imagem e Som que em um ambiente
outro ambiente no fazem muito sentido.

Como j mencionando anteriormente o corao da mquina oferece aos ambientes de exe-


cuo a classe abstrata AmbienteAbstrato que o ambiente de execuo deve implementar. A
classe AmbienteAbstrato responsvel por realizar a inicializao do corao da mquina, mas
deixa alguns mtodos abstratos em aberto para o ambiente realizar a personalizao da corao
da mquina.

Ao iniciar o interpretador, o fluxo de execuo vai para o ambiente de execuo. Ento o


ambiente de execuo dever realizar qualquer tipo de inicializao e configurao do ambiente
59

de execuo e em seguida iniciar o corao da mquina. A inicializao do corao da mquina


realizado criando-se a classe que estende AmbienteAbstrato do ambiente em questo e invo-
cando o mtodo inicializar, passando um fluxo de caracteres com o cdigo fonte. A obteno
deste fluxo dependente da plataforma de execuo.

Foram implementados dois ambientes de execuo. O ambiente console e ambiente gr-


fico. O ambiente console oferece primitivas para leitura e escrita no console e no h nenhuma
dependncia com ambiente grficos. O ambiente grfico oferece algumas primitivas de dese-
nho, sendo estas primitivas baseadas nas idia de TurtleGraphics. Neste ambiente, cada ator se
comporta como um pintor e responde a primitivas tpicas de TurtleGraphics para movimentos
relativos para movimentar o cone representativo do ator.
60

4 Definio da Linguagem Compilada

Linguagens compilada so aquelas na qual h um passo intermedirio entre o cdigo fonte


e a execuo, este passo justamente a gerao de um arquivo intermedirio em alguma outra
linguagem - desde linguagem de mquina at linguagens de alto nvel - que poder ser execu-
tada.

A sintaxe desta linguagem fortemente inspirada em Smalltalk e na idia de linguagens


orientada a objetos puras, isto , tudo objeto incluindo as classes e tipos como nmeros intei-
ros e caracteres que em outras linguagens no so. A sintaxe de Smalltalk muito simples e
praticamente no h excees na linguagem, alm disso a legibilidade dela muito grande por
isso foi escolhida como base para esta linguagem.

As principais caractersticas da linguagem interpretada estaro presentes na linguagem


compilada, como por exemplo closure, atores, estmulos, comunicao direta, entre outras.

4.1 Sintaxe da linguagem

A gramtica da linguagem compilada, como dita anteriormente, baseada em Smalltalk. A


gramtica bastante simples, a exemplo de Smalltalk, quando comparada a outras linguagens
utilizadas atualmente como Ruby, Java ou Python. A gramtica EBNF mostrada na listagem
4.1.
Agora : : = S e n t e n c a s <EOF>
S e n t e n c a s : : = ( ( R e t o r n o | E x p r e s s a o | DeclaracaoDeModeloOuMolde ) " . " )
DeclaracaoDeModeloOuMolde : : = <PALAVRA_CHAVE> S i m b o l o ( <PALAVRA_CHAVE>
L i s t a ) ? ListaDeAgendas
ListaDeAgendas : : = " [ " ( DeclaracaoUnaria | D e c l a r a c a o B i n a r i a |
DeclaracaoPorPalavraChave ) "]"
DeclaracaoUnaria ::= I d e n t i f i c a d o r "[" Sentencas "]"
DeclaracaoBinaria ::= Seletor I d e n t i f i c a d o r "[" Sentencas "]"
DeclaracaoPorPalavraChave : : = ( PalavraChave I d e n t i f i c a d o r )+ "[" Sentencas
"]"
61

Retorno : : = "^" Expressao


Expressao : : = Atribuicao | ExpressaoBasica
Atribuicao : : = I d e n t i f i c a d o r ":=" Expressao
E x p r e s s a o B a s i c a : : = P r i m i t i v a O u E x p r e s s a o ( Mensagem MensagemEmCascata ) ?
PrimitivaOuExpressao : : = Pr i m it i va | "(" Expressao ") "
Primitiva ::= Identificador
| Numero
| String
| Booleano
| Simbolo
| Bloco
| Lista
Bloco : : = " [ " P a r a m e t r o s S e n t e n c a s " ] "
Parametros ::= ( ( " : " I d e n t i f i c a d o r )+ " | " ) ?
Lista ::= "#[" ( Primitiva ) "]"
Mensagem : : = ( MensagemUnaria + M e n s a g e m B i n a r i a M e n s a g e m P o r P a l a v r a C h a v e ?
| MensagemBinaria+ MensagemPorPalavraChave ?
| MensagemPorPalavraChave
MensagemUnaria : : = I d e n t i f i c a d o r
M e n s a g e m B i n a r i a : : = S e l e t o r P r i m i t i v a O u E x p r e s s a o MensagemUnaria
M e n s a g e m P o r P a l a v r a C h a v e : : = ( P a l a v r a C h a v e Argumento ) +
Argumento : : = P r i m i t i v a O u E x p r e s s a o MensagemUnaria M e n s a g e m B i n a r i a
MensagemEmCascata : : = ( " ; " Mensagem )
I d e n t i f i c a d o r : : = <IDENTIFICADOR>
Numero : : = <NUMERO>
B o o l e a n o : : = <BOOLEANO>
S t r i n g : : = <STRING>
S i m b o l o : : = " # " <IDENTIFICADOR>
S e l e t o r : : = <SELETOR>
P a l a v r a C h a v e : : = <PALAVRA_CHAVE>

Listagem 4.1: Gramtica EBNF da linguagem compilada

Os valores entre parnteses angulares so elementos provenientes da anlise lxica e defi-


nidos atravs de expresses regulares, e esto descritos na listagem 4.2.
<COMENTARIO_UMA_LINHA> = " / / " ( ~ [ " \ n " , " \ r " ] ) ( " \ n " | " \ r " | " \ r \ n " )
<COMENTARIO_VARIAS_LINHAS> = " / " ( ~ [ " " ] ) " " ( ~ [ " / " ] ( ~ [ " " ] ) " " ) " / "
<STRING> = " \ " " ( ~ [ " \ \ " , " \ n " , " \ r " , " \ " " ] | ( " \ \ " [" n " ," t " , " \ \ " , " \ " " ] ) )
"\""
<NUMERO> = ( " + " | " ") ? ( <FLOAT> | <FLOAT> ( [ " e " , " E " ] ( [ " " , " + " ] ) ? <
INTEIRO> ) ? )
<PALAVRA_CHAVE> = <IDENTIFICADOR> " : "
<FLOAT> = <INTEIRO> | <INTEIRO> ( [ " , " ] <INTEIRO> ) ?
62

<INTEIRO> = [ " 0 " " 9 " ] +


<SIMBOLO> = ( <LETRA> | " _ " ) + ( <DIGITO> | <LETRA> | " _ " )
<LETRA> = [ " a "" z " , "A""Z " ] | " " | " " | " " | " " | " " |
"" | "" | "" | "" | "" | " " | " " | " " | " " |
"" | "" | "" | "" | " " | " " | " " | " " |
" " | " " | " " | " " | "" | "" | "" | "" | "" |
"" | "" | "" | "" | "" | " " | " " | " " | " " |
"" | "" | "" | "" | " " | ""
<SELETOR> : (" " | " , " | " + " | " / " | "\\" | " " | " ~ " | " <" | " >" | " = " |
"@" | "%" | "&" | " ? " | " ! " )

Listagem 4.2: Definio lxica da linguagem compilada

Como possvel observar, um programa nesta linguagem um conjunto de sentenas sendo


que uma sentena ou uma atribuio de varivel ou envio de uma mensagem ou declarao de
modelo/molde. O operador de atribuio :=.

O terminador de sentenas nesta linguagem ser o ponto final (.). O ponto final dever
ser colocado ao final de toda a sentena escrita nesta linguagem. Outro operador interessante
o operador ponto-e-vrgula. O operador ponto e vrgula possui o intuito de enviar diversas
mensagens a um mesmo objeto. Este operador utilizado aps uma mensagem ser enviada para
que a prxima mensagem opere sobre o mesmo objeto que havia recebido a mensagem anterior.

O que interessante notar na gramtica a precedncia dos seletores, que em outras lin-
guagens so chamados de operadores. Nota-se que no h uma precedncia, tudo avaliado da
esquerda para a direita. O motivo disso ficar mais claro quando a semntica da linguagem for
explicada.

4.2 Semntica da linguagem compilada

O objetivo da linguagem compilada que ela seja semanticamente simples, com o mnimo
de excees possvel. Na linguagem basicamente o que h so trocas de mensagens. Um ator
envia mensagens a outros atores e objetos para que a computao se realize.

Ao encontrar um elemento sinttico descrevendo um tipo de dado, como por exemplo uma
String, um nmero ou uma lista, o compilador ir gerar cdigo para a criao de um modelo de
objeto previamente definido. Este modelo de objeto como qualquer outro e possui agendas
previamente definidas, sendo portanto capaz de responder as mensagens ele enviado.

As variveis no precisam ser previamente declaradas. De forma anloga a linguagem


63

alvo, as variveis so criadas automaticamente e so sempre locais, com exceo das variveis
declaradas na agenda iniciar de um modelo ou molde. Estas ltimas sero variveis de instncia
do modelo. possvel utilizar encademeamento de atribuies, como mostrado na listagem 4.3.
Como tudo na linguagem atribuies tambm retornam um valor, que o valor que acabara de
ser atribudo a ele. Assim sendo, todas as variveis em uma atribuio em cascata iro receber
o mesmo valor.
umNumero : = n u m e r o V i n t e : = 2 0 .

Listagem 4.3: Exemplo de atribuio encadeada

Existem trs tipos de mensagens diferentes como possvel ver na gramtica EBNF da
listagem 4.1, so elas:

Mensagem unria utilizado para enviar uma mensagem um destino sem realizar
passagem de parmetros. a mensagem mais prioritria.

Mensagem binria utilizado para enviar uma mensagem um destino passando um


nico parmetro utilizando-se os seletores (operadores, em outras linguagens).

Mensagem por palavra chave utilizado para enviar uma mensagem um destino
passando no mnimo um parmetro.

H pequenas diferenas sintticas entre cada uma dessas mensagens. Na listagem 4.4
mostrado um exemplo contendo todos os tipos de mensagens.

Na primeira linha do exemplo um objeto do modelo Texto criado e enviado a mensagem


comoNmero, que uma mensagem unria. O resultado desta mensagem armazenado na
varivel numeroVinte. Nota-se que o nome desta mensagem composto somente por uma
seqncia de letras, isto , um token SIMBOLO descrito na listagem 4.2.

Na segunda linha do exemplo enviada a mensagem + com o objeto que est armazenado
na varivel numeroVinte e o objeto 10 enviado como parmetro. O valor retornado pelo m-
todo ser armazenado na varivel somatorio. Este exemplo da mensagem binria primeiro
colocado o objeto que ir receber a mensagem, assim como em todos os tipos de mensagens,
sendo seguido pelo seletor, um token SELETOR descrito na listagem 4.2 e por fim o parmetro.

Na terceira linha do exemplo enviada a mensagem mostrar: com o objeto que est
armazenado na varivel devo e o objeto armazenado na varivel somatorio enviado como
parmetro. Este exemplo da mensagem por palavra chave, primeiro colocado o objeto que
ir receber a mensagem seguido pelo primeiro fragmento do nome do mtodo (at o dois pontos)
64

seguido pelo parmetro, sendo seguido pelo segundo fragmento do nome do mtodo, seguido
por outro parmetro e assim por diante. O nmero de parmetros determinado pelo nmero
de fragmentos. Para cada fragmento h um parmetro. A palavra-chave devo utilizada para
dizer que o prprio ator deve receber a mensagem, isto , uma referncia para o prprio ator
que est executado.
n u m e r o V i n t e : = " 2 0 " comoNmero .
somatorio := numeroVinte + 10.
devo m o s t r a r : s o m a t o r i o .

Listagem 4.4: Exemplo de mensagens

interessante notar que estruturas de controle de fluxo pode ser explicado pelo tica de
mensagens e troca de mensagens. No fragmento de cdigo listagem 4.5 mostrado um exem-
plo de estrutura de escolha, no qual realizado um teste para verificar a igualdade entre dois
valores e mostrar um valor qualquer em cada um dos casos. A comparao entre umNumero
e outroNumero no nada mais do que a mensagem binria = enviada umNumero. Ao
valor retornado por esta mensagem enviado a mensagem seVerdade:seFalso:. Espera-se,
por conveno, que o valor retornado pela mensagem = seja um valor booleano, ou instncia
do modelo Verdadeiro ou do modelo Falso. Por polimorfismo ento a escolha feita. Caso
seja uma instncia de Verdadeiro, o primeiro parmetro avaliado. Caso seja uma instncia de
Falso, o segundo parmetro avaliado. Resumindo, possvel implementar estrutura de deciso
baseando-se somente as ferramentas oferecidas pela linguagem, ou seja, mensagens e closures.

Closures, como explanado na definio da linguagem alvo, so fragmentos de cdigo atrela-


dos ao contexto no qual fora criado. Closures na linguagem compilada possuem comportamento
idntico a closures na linguagem interpretada, mas a sintaxe diferente. Ao invs da utilizao
de chaves para denotar o incio e fim da declarao de um closure, utiliza-se colchetes. Assim
como na linguagem alvo, closures so elementos de primeira classe, podendo por tanto serem
passados como parmetros para outras agendas, serem retornados de agendas, resumindo um
objeto como outro qualquer. Pelas mesmas razes j expostas na descrio da linguagem alvo,
closures criados em um ator s podem ser executados pelo prprio para se evitar condies de
corrida.
umNumero : = 1 0 .
outroNumero := 2 0 .

umNumero = o u t r o N u m e r o
s e V e r d a d e : [ devo m o s t r a r : " i g u a l " . ]
s e F a l s o : [ devo m o s t r a r : " d i f e r e n t e " . ] .
65

Listagem 4.5: Exemplo com estrutura de deciso

A concorrncia na linguagem compilada utilizar a semntica de atores da linguagem alvo.


Todas as caractersticas dos atores e as formas de comunicao sero mantidas. A troca de
mensagem entre atores na linguagem compilada ir utilizar a mesma semntica da comunicao
direta da linguagem interpretada. Todas as caractersticas, vantagens e desvantagens discutidas
anteriormente iro continuar a existir nesta linguagem.

Assim como na linguagem interpretada atores iro rodar simultaneamente de forma inde-
pendente, sendo que quando criados eles executam a agenda de nome iniciar.

A nomenclatura da linguagem original em respeito a orientao a objetos ser mantida.


Logo, a linguagem compilada tambm possuir os conceitos de modelo, molde e herana exa-
tamente da mesma forma que a linguagem interpretada. A sintaxe ser adaptada para refletir as
caractersticas da nova linguagem. O fragmento de cdigo da listagem 4.6 mostra como ocorre
a declarao de um molde, com nome UmMolde, e um modelo, com nome UmModelo, que
modelado pelo molde UmMolde. Para se criar um molde basicamente se escreve molde:,
seguido pelo nome e por uma lista com as definies das agendas. O nome precedido por
cerquilha. A cerquilha denota um smbolo, cuja semntica idntica a semntica da lingua-
gem alvo. Para se instanciar um ator, ao invs de molde: utiliza-se modelo. Ambas as
declaraes podem possuir, opcionalmente a lista de moldes que o moldam, colocando-se logo
aps o nome a palavra-chave moldadoPor: seguida por uma lista de dados, isto , uma lista
precedida por cerquilha contendo os nomes dos moldes.

Na listagem 4.6, v-se tambm como ocorre a declarao das agendas que respondem a
cada um dos trs tipos de mensagens. A primeira, e mais simples, a agenda da mensagem
unria, exemplificada pela agenda iniciar, que declarada simplesmente escrevendo-se o nome
da agenda seguida pela lista contendo a declarao da agenda. Aps temos a agenda que res-
pondem a mensagens por palavra chave, exemplificada pela mensagem somar: valor. As
mensagens por palavra chave so declaradas colocando-se as partes do nome da agenda entrela-
adas com os nomes dos parmetros. No caso da agenda somar:, valor o nome do parmetro
formal da agenda. Pode-se declarar agendas com maior nmero de parmetros. Por exemplo,
pode-se criar uma agenda com a assinatura: somar: valor com: valor2, neste caso o nome da
agenda somar:com: e os parmetros formais so valor e valor2. Por ltimo, a declarao de
uma agenda que responde a agendas binrias, exemplificado pela agenda +. Essas agendas
so criadas colocando-se o seletor, no caso +, seguido do nome do parmetro formal.
molde : #UmMolde
66

[
iniciar
[
var := 10.
]

somar : v a l o r
[
var := var + v a l o r .
]
].

modelo : #MeuModelo m o l d a d o P o r : # [ UmMolde ]


[
iniciar
[
devo m o s t r a r : " ok " .
]
+ algo
[
^ var + algo .
]
].
x p t o : = MeuModelo novo .
x p t o somar : 1 0 .
devo m o s t r a r : x p t o + 2 0 ;
suicidar .

Listagem 4.6: Exemplo Modelo e Molde

As ltimas duas linhas do exemplo mostrado na listagem 4.6 mostram um exemplo do uso
do operador ponto-e-vrgula. Primeiramente, a mensagem mostrar: enviada ao prprio ob-
jeto (atravs da palavra chave devo). Em seguida, o operador utilizado para que a prxima
mensagem, que no caso suicidar, seja enviada para o mesmo objeto que a mensagem ante-
rior, isto , o prprio objeto.

Um outro aspecto importante que nesta linguagem tudo retorna algum valor. Caso uma
agenda no possua nenhum retorno, automaticamente ser retornado uma referncia ao objeto
ao qual a agenda pertence. No caso de closures, o valor retornado pela avaliao do mesmo
igual ao valor da ltima expresso do closure.

Linguagem orientada domnio ou DSL (Domain Specific Language) uma abordagem


67

antiga em desenvolvimento de software que est ganhando muita ateno. DSLs so basi-
camente linguagens especficas particularizadas para um determinado domnio de aplicao.
Como exemplo de uma DSL pode-se citar JavaCC, compiler-compiler aqui utilizado. Existem
dois tipos de DSLs, as chamadas externas so escritas em uma linguagem diferente da lingua-
gem de programao principal utilizada para desenvolver o programa, as internas so escritas
na mesma linguagem de programao. Existem diversas vantagens e desvantagens em cada um
destes tipos de DSLs.

Devido a sua sintaxe, esta linguagem favorece muito o desenvolvimento de DSLs internas.
Como DSLs internas so limitadas pela linguagem e devem ser sintaticamente e semantica-
mente vlidas, quanto menor o impacto causado pela sintaxe melhor ser para desenvolver
DSL. A ausncia de parnteses para a passagem de parmetros, o entrelaamento do nome do
mtodo e parmetros, a ausncia de pontos para realizar a troca de mensagens entre objetos.
Tudo isso faz com que a estrutura de uma sentena se assemelhe muito a uma frase escrita em
uma linguagem natural, facilitando assim o desenvolvimento destes tipos de linguagens.
68

5 Implementao do compilador

Como opo de implementao, optou-se por tornar o compilador o mais simples poss-
vel sendo a maior parte da complexidade referente semntica da linguagem implementada
pelo interpretador. O sistema de herana, concorrncia, comunicao entre atores, entre outros
detalhes, so todos implementados pelo interpretador.

O compilador divido em duas partes bsicas: o sistema de runtime e o tradutor. res-


ponsabilidade do tradutor ler o cdigo fonte e gerar cdigo na linguagem alvo semanticamente
equivalente. O sistema de runtime um sistema de apoio escrito na linguagem alvo que o
cdigo gerado pelo tradutor depende. Estas funcionalidades so modelos, atores, classes de
biblioteca que so expostas ao programador entre outras coisas que necessitam ser escritas na
linguagem alvo.

Quando o compilador executado lhe fornecido o arquivo no qual o cdigo fonte que se
deseja compilar est escrito e o arquivo no qual a sada do compilador dever ser escrita. Ento,
como ilustrado esquematicamente na figura 5.1, o compilador l o cdigo fonte e o envia ao
parser, responsvel por realizar a anlise lxica e sinttica gerando uma Abstract Syntax Tree
(AST) representando hierarquicamente a entrada. A AST gerada ento processada, sendo
realizada aqui a analise semntica (que muito limitada, no realizada quase nenhuma analise
semntica) e a gerao de cdigo. Por ltimo o cdigo gerado mesclado com o cdigo do
sistema de runtime e escrito no arquivo de sada.

5.1 Parser

O parser do compilador no foi escrito manualmente, exemplo do que foi feito no inter-
pretador. Foi utilizado tambm o compiler-compiler JavaCC para gerar o parser. Entretanto,
no foi utilizado apenas o JavaCC, foi utilizado uma ferramenta que acompanha a distribuio
do JavaCC chamada JJTree.

O JJTree uma ferramenta com um nvel de abstrao mais alto quando comparada ao
69

Figura 5.1: Diagrama dos passos do compilador at gerao do programa alvo.

JavaCC. Com o JavaCC, possvel descrever o parser atravs de uma sintaxe semelhante a
EBNF, com uma extenso para descrever aes semnticas a serem tomadas. O JJTree um
pr-processador para o JavaCC que adiciona mais uma extenso a gramtica original do JavaCC
na qual possvel descrever a forma da AST que se quer gerar, sendo o cdigo responsvel pela
montagem da AST gerado automaticamente. Alm disto, uma classe gerada para cada tipo de
n diferente dentro da rvore.

As classes geradas pelo JJTree so muito semelhantes as que foram geradas pelo JavaCC
para o interpretador, e por este motivo ser omitida. A principal diferena entre as duas que
o JJTree alm de gerar o parser, gera uma interface Node e uma classe que implementa Node
para cada produo que ir gerar um n na AST.
70

5.2 Gerao de cdigo

Aps o parsing estar completo e a AST ter sido completamente gerada o compilador co-
mea a fase de anlise semntica e gerao de cdigo. Como dito anteriormente, a anlise
semntica bastante limitada sendo que poucas verificaes e testes so realizados, como
comum em linguagens dinamicamente tipadas.

Toda a anlise e gerao de cdigo realizada utilizando-se o padro de projeto Visitor. O


padro de projeto Visitor muito utilizado para percorrer uma estrutura de dados, no caso uma
rvore, tornando possvel separar a forma como se percorre os dados do algoritmo. Alm disto,
visitor simula um sistema de double-dispatching em uma linguagem single-dispatching. Uma
linguagem que utiliza single-dispatching permite que vrios mtodos possuam mesmo nome e
difiram quanto aos parmetros, mas a escolha de qual o mtodo que ser invocado decidido
em tempo de compilao. Em linguagens que utilizam double-dispatching o mtodo que ser
invocado ser decidido em tempo de execuo, baseando-se nos tipos em tempo de execuo.

Foram criados vrios visitantes, cada um responsvel pela anlise e gerao do cdigo em
um determinado contexto. Isto ocorre porque um mesmo nodo, dependendo do local no qual
utilizado, pode requerer aes semnticas e/ou gerao de cdigos diferentes. Quando se est
processando o nodo e sabe-se que o prximo nodo exigir um novo visitante, um criado e a
troca de visitante realizada.

O tradutor, isto , a parte do compilador responsvel pela gerao de cdigo subdivida em


trs partes: parser, os visitantes e a descrio de cdigo. Como j explanado, o parser ir gerar
uma AST que ir ser processada pelos visitantes. Os visitantes ento realizam a anlise semn-
tica, preenchem estruturas de dados com informaes necessrias para o seu prprio processa-
mento e informam que algum cdigo deve ser gerado. Esta notificao feita ao subsistema
responsvel pela descrio do cdigo em linguagem alvo. Este subsistema recebe notificaes
e armazena o cdigo que dever ser escrito em memria serializando-o no fim do processo de
traduo.

Aps o processo de gerao ter sido concludo, o compilador pegar o cdigo fonte equiva-
lente escrito na linguagem alvo e o mesclar ao cdigo do sistema de runtime. Isto realizado
utilizando um sistema de templates chamado Velocity. Um sistema de template caracteri-
zado por processar um documento escrito em uma linguagem prpria definido pelo sistema de
template e gerar uma sada alterando vriaveis e dados do template por valores fornecidos pelo
usurio. O sistema de runtime escrito em forma de template, demarcando como e onde o
cdigo gerado dever ser inserido.
71

Referncias Bibliogrficas

ARMSTRONG, J. The development of erlang. SIGPLAN Not., ACM Press, New York, NY,
USA, v. 32, n. 8, p. 196203, 1997. ISSN 0362-1340.

ARMSTRONG, J. Concurrency oriented programming in erlang. Swedish Institute of


Computer Science, 2003.

BRODIE, L. Starting FORTH. Upper Saddle River, NJ, USA: Prentice-Hall, Inc., 1986. ISBN
0-13-843087-X.

GAMMA, E. et al. Design Patterns. Boston: Addison-Wesley, 1995. ISBN 0201633612.

Вам также может понравиться