Adaptação do Business-focused Inventory of Personality BIP ...
UNIVERSIDADE DO VALE DO ITAJAÍ CENTRO DE CIÊNCIAS …siaibib01.univali.br/pdf/Bruno Pereira...
Transcript of UNIVERSIDADE DO VALE DO ITAJAÍ CENTRO DE CIÊNCIAS …siaibib01.univali.br/pdf/Bruno Pereira...
UNIVERSIDADE DO VALE DO ITAJAÍ
CENTRO DE CIÊNCIAS TECNOLÓGICAS DA TERRA E DO MAR
CURSO DE CIÊNCIA DA COMPUTAÇÃO
BIPIDE WEB
CONSTRUÇÃO DE UMA VERSÃO ONLINE DO AMBIENTE DE
DESENVOLVIMENTO INTEGRADO BIPIDE
por
Bruno Pereira Peres
Itajaí (SC), 11 de 2016
UNIVERSIDADE DO VALE DO ITAJAÍ
CENTRO DE CIÊNCIAS TECNOLÓGICAS DA TERRA E DO MAR
CURSO DE CIÊNCIA DA COMPUTAÇÃO
BIPIDE WEB
CONSTRUÇÃO DE UMA VERSÃO ONLINE DO AMBIENTE DE
DESENVOLVIMENTO INTEGRADO BIPIDE
Área de Informática na Educação
por
Bruno Pereira Peres
Relatório apresentado à Banca Examinadora do
Trabalho Técnico-científico de Conclusão de Curso
do curso de Ciência da Computação para análise e
aprovação.
Orientador: Paulo Viniccius Vieira
Coorientador: Cesar Albenes Zeferino
Itajaí (SC), 11 de 2016
RESUMO
PERES, Bruno Pereira. Bipide Web – Construção de uma versão online do ambiente de
desenvolvimento integrado Bipide. Itajaí, 2016. 128 f. Trabalho Técnico-científico de
Conclusão de Curso (Graduação em Ciência da Computação) – Centro de Ciências
Tecnológicas da Terra e do Mar, Universidade do Vale do Itajaí, Itajaí, 2016.
A família de processadores BIP e o Ambiente de Desenvolvimento Integrado Bipide foram
desenvolvidos com a finalidade de facilitar o ensino de programação e conceitos de
arquitetura e organização de computadores através de uma proposta interdisciplinar. Com a
IDE Bipide, é possível simular a execução de programas escritos para a família de
processadores BIP sobre a arquitetura e organização dos mesmos por meio de animações. A
família de processadores BIP e o Ambiente de Desenvolvimento Integrado Bipide são
utilizados em várias disciplinas do curso de Ciência da Computação da Univali. As versões
anteriores da IDE Bipide foram construídas com tecnologias e linguagens de programação
proprietárias, ocasionando uma forte dependência de plataforma, o que impedia o
funcionamento da ferramenta em ambientes que não fossem Microsoft Windows.
Considerando esse problema, este trabalho apresenta a criação de uma versão web do
ambiente de desenvolvimento integrado Bipide, a qual torna a utilização da ferramenta
independente de plataforma. As estruturas de front-end e back-end desta nova versão foram
construídas de forma totalmente desacopladas, de modo a permitir a implementação de
diferentes interfaces para diferentes plataformas em trabalhos futuros.
Palavras-chave: Ensino de algoritmos e programação, Compiladores, Simulação de
Arquitetura de computadores.
ABSTRACT
The BIP family and the integrated development environment Bipide were developed to
facilitate the teaching of programming and Computer Organization & Architecture concepts
through an interdisciplinary approach. With Bipide is possible to simulate the execution of a
program written for the BIP family over your architecture and organization with animations.
The BIP family and the Integrated Development Environment Bipide are used in various
disciplines in the course of computer science at Univali. The last version of Bipide was
developed with proprietary technologies and programming languages. With this the use of
Bipide was limited to Microsoft Windows environments. Considering this problem this paper
develops web version of Bipide with the aim of make Bipide a platform-independent tool.
Also, this work built the front-end and back-end structures of Bipide in an independent way,
allowing the implementation of interfaces for different platforms, reusing the structures
provided by this work.
Keywords: Algorithms and Programming Learning. Compilers. Computer Architecture
Simulators.
LISTA DE ILUSTRAÇÕES
Figura 1. Formato de instrução dos processadores BIP ........................................................... 18
Figura 2. Implementação (a) Harvard e (b) Von Neumann do BIP I ....................................... 18
Figura 3. Ambiente de simulação do Bipide 3.0 ...................................................................... 26
Figura 4. Relação entre os elementos da interface de simulação do Bipide ............................. 27
Figura 5. Estatísticas de execução do código assembly no Bipide 3.0 ..................................... 28
Figura 6. Interface do FRISCjs ................................................................................................. 31
Figura 7. Interface de simulação do Simple 8-bit Assembler Simulator .................................. 32
Figura 8. Interface do Basic MIPS Simulator........................................................................... 33
Figura 9. Interface do Asm86 ................................................................................................... 34
Figura 10. Interface do simulador do Little Man Computer..................................................... 36
Figura 11. Processo de compilação .......................................................................................... 38
Figura 12. Estrutura de um compilador. ................................................................................... 39
Figura 13. Compilador de 3 fases. Fonte: Adaptado de Cooper; Torczon (2014). .................. 39
Figura 14. Comportamento de requisição-resposta. ................................................................. 42
Figura 15. Requisição para obtenção de documento via HTTP. .............................................. 43
Figura 16: Diagrama de componentes do Bipide Web. ............................................................ 56
Figura 17: Diagrama de Classes das Entidades do Bipide Web. .............................................. 57
Figura 18: Diagrama de classes dos compiladores do Bipide Web. ......................................... 59
Figura 19: Classes utilizadas pelos compiladores assembly e Portugol. .................................. 61
Figura 20: Diagrama de classe do visitante do compilador Portugol. ...................................... 63
Figura 21: Método translate da classe Translator.................................................................... 64
Figura 22: Criação do parser e analisador léxico. .................................................................... 66
Figura 23: ParserImp estendendo BIPASMParser ................................................................... 67
Figura 24: Módulo de edição de programa do Bipide Web. .................................................... 70
Figura 25: Módulo de simulação do Bipide Web. .................................................................... 72
Figura 26: Relação entre as instruções no simulador. .............................................................. 73
Figura 27: Representação da organização do BIP IV. .............................................................. 75
Figura 28: Registradores do processador e periféricos do BIP IV. .......................................... 76
Figura 29: Módulo de Ajuda do Bipide Web. .......................................................................... 77
Quadro 1. Exemplos de (a) declaração de função e (b) manipulação de vetor no Portugol do
Bipide 3.0 ................................................................................................................................. 24
Quadro 2. Exemplo de uma mensagem de requisição HTTP. .................................................. 46
Quadro 3. Exemplo de uma mensagem de resposta HTTP. ..................................................... 47
Quadro 4. Exemplo de cabeçalho Accept utilizado na negociação de conteúdo com o servidor.
.................................................................................................................................................. 53
Quadro 5. Requisição do mesmo recurso com diferentes representações. ............................... 54
Quadro 6: Métodos adicionados na seção members da gramática. .......................................... 66
LISTA DE TABELAS
Tabela 1. Relação entre classes de instruções e processadores da família BIP ........................ 21
Tabela 2. Subconjunto de instruções Portugol utilizado no Bipide 1.0 .................................... 23
Tabela 3. Instruções adicionadas ao subconjunto Portugol no Bipide 3.0 ............................... 23
Tabela 4. Subconjunto de instruções da linguagem C presente no Bipide 4.0 ......................... 25
Tabela 5. Relação entre versões do Bipide, versões do BIP e linguagens de programação. .... 25
Tabela 6. Resumo das funcionalidades das diferentes versões do Bipide ................................ 30
Tabela 7. Tabela comparativa das funcionalidades dos simuladores web analisados .............. 37
Tabela 8. Significado das requisições utilizadas no exemplo do Quadro 2 ............................. 47
Tabela 9. Categorias dos códigos de estado HTTP. ................................................................. 48
Tabela 10. Métodos HTTP e ações propostas em sistemas REST. .......................................... 54
Tabela 11: Propriedades do JSON retornado pelo método compile da interface Compiler. .... 60
Tabela 12: Recursos e rotas da API do Bipide Web................................................................. 68
Tabela 13: Comparativo dos resultados dos testes do compilador Portugol. ........................... 79
Tabela 14: Teste do compilador assembly com instrução RETURN. ...................................... 80
LISTA DE ABREVIATURAS E SIGLAS
ACC Accumulator
ANTLR ANother Tool for Language Recognition
API Application Programming Interface
ASCII American Standard Code for Information Interchange
ASP Active Server Pages
BIP Basic Instruction-set Processor
CGI Common Gateway Interface
CRUD Create, Retrieve, Update e Delete
CSS Cascading Style Sheets
DNS Domain Name System
HTML HiperText Markup Language
HTTP HiperText Transfer Protocol
IDE Integrated Development Environment
IP Internet Protocol
IR Intermediate Representation
JSON JavaScript Object Notation
JSP Java Server Pages
LMC Little Man Computer
LSED Laboratório de Sistemas Embarcados e Distribuídos
MIPS Microprocessor Without Interlocked Pipeline Stages
MVC Model View Controller
NASM Netwide Assembler
PC Program Counter
PHP PHP: HiperText Processor
REST Representational State Transfer
RFC Request for Comments
RISC Reduced Instruciont-Set Computer
SOAP Simple Object Accesss Protocol
TCP Transmission Control Protocol
TTC Trabalho Técnico-científico de Conclusão de Curso
UCP Unidade Central de Processamento
Univali Universidade do Vale do Itajaí
URI Uniform Resource Identifiers
URL Uniform Resource Locator
URN Uniform Resource Name
WPF Windows Presentataion Foundation
WSDL Web Service Definition Language
WWW World Wide Web
XML eXtensible Markup Language
μBIP Micro-BIP
SUMÁRIO
1 INTRODUÇÃO ..................................................................................................................... 10
1.1 Problematização ................................................................................................................. 12
1.1.1 Formulação do Problema ................................................................................................ 12
1.1.2 Solução Proposta ............................................................................................................. 13
1.2 Objetivos ............................................................................................................................. 13
1.2.1 Objetivo Geral ................................................................................................................. 13
1.2.2 Objetivos Específicos ....................................................................................................... 14
1.3 Metodologia ....................................................................................................................... 14
1.4 Estrutura do Trabalho ....................................................................................................... 15
2 FUNDAMENTAÇÃO TEÓRICA ........................................................................................ 16
2.1 PROJETO BIP .................................................................................................................. 16
2.1.1 BIP I ................................................................................................................................. 18
2.1.2 BIP II ............................................................................................................................... 19
2.1.3 BIP III .............................................................................................................................. 19
2.1.4 BIP IV .............................................................................................................................. 20
2.1.5 µBIP ................................................................................................................................. 20
2.2 AMBIENTE DE DESENVOLVIMENTO INTEGRADO BIPIDE ................................ 21
2.2.1 Suporte a linguagens de programação ............................................................................ 22
2.2.2 Módulo de Simulação ...................................................................................................... 26
2.2.3 Outros Recursos do Ambiente ......................................................................................... 28
2.3 SIMULADORES DE ARQUITETURA E ORGANIZAÇÃO .......................................... 30
2.3.1 FRISCjs ............................................................................................................................ 31
2.3.2 Simple 8-bit Assembler Simulator ................................................................................... 31
2.3.3 Basic MIPS Simulator ..................................................................................................... 33
2.3.4 Asm86 .............................................................................................................................. 34
2.3.5 Little Man Computer ....................................................................................................... 35
2.3.6 Comparação Entre os Simuladores Analisados .............................................................. 36
2.4 COMPILADORES ............................................................................................................. 37
2.4.1 Estrutura do Compilador ................................................................................................ 38
2.4.1.1 Análise Léxica .............................................................................................................. 40
2.4.1.2 Análise Sintática ........................................................................................................... 40
2.4.1.3 Análise Semântica ........................................................................................................ 41
2.4.1.4 Geração de Código ....................................................................................................... 41
2.5 SISTEMAS WEB ............................................................................................................... 42
2.5.1 Arquitetura da Web ......................................................................................................... 42
2.5.2 O Protocolo HTTP .......................................................................................................... 45
2.5.2.1 Formato de Mensagens do Protocolo HTTP ................................................................ 45
2.5.2.2 Métodos HTTP .............................................................................................................. 48
2.5.3 Serviços Web ................................................................................................................... 50
2.5.4 REST ................................................................................................................................ 51
2.5.4.1 Recursos e Identificadores de Recursos ....................................................................... 52
2.5.4.2 Representações de Recursos ......................................................................................... 53
2.5.4.3 Ações em sistemas REST .............................................................................................. 54
3 DESENVOLVIMENTO ....................................................................................................... 55
3.1 IMPLEMENTAÇÃO ......................................................................................................... 55
3.2 IMPLEMENTAÇÃO DA APLICAÇÃO SERVIDORA ................................................... 56
3.2.1 Entidades da Aplicação Servidora .................................................................................. 57
3.2.2 Implementação dos Compiladores .................................................................................. 59
3.2.2.1 Compilador Portugol .................................................................................................... 62
3.2.2.2 Compilador Assembly ................................................................................................... 65
3.2.3 API REST ......................................................................................................................... 67
3.3 IMPLEMENTAÇÃO DA APLICAÇÃO CLIENTE ........................................................ 69
3.3.1 Módulo de edição de programas ..................................................................................... 70
3.3.2 Módulo de simulação ...................................................................................................... 71
3.3.3 Módulo de ajuda .............................................................................................................. 76
3.4 VALIDAÇÃO ..................................................................................................................... 77
3.4.1 Validação do funcionamento da aplicação front-end ..................................................... 78
3.4.2 Validação do compilador Portugol ................................................................................. 78
3.4.3 Validação do compilador Assembly ................................................................................ 79
3.5 LIMITAÇÕES ................................................................................................................... 80
4 CONCLUSÕES ..................................................................................................................... 82
4.1 TRABALHOS FUTUROS ................................................................................................. 83
10
1 INTRODUÇÃO
A compreensão de alguns conceitos básicos de Arquitetura e Organização de
Computadores são de grande importância para o melhor entendimento das abstrações
utilizadas nas disciplinas de Algoritmos e Programação dos cursos de graduação em
Computação. Porém, as disciplinas que introduzem tais conceitos são, geralmente,
ministradas após as disciplinas introdutórias de Algoritmos e Programação, demostrando uma
falta de sincronia nos currículos dos mesmos. (MORANDI; RAABE; ZEFERINO, 2006).
Visando solucionar este problema, foi desenvolvido por pesquisadores da área da
Computação da Univali (Universidade do Vale do Itajaí) o projeto BIP (Basic Instruction-set
Processor). O Objetivo do projeto BIP é disponibilizar uma família de processadores com
uma arquitetura básica e com recursos incrementais, de tal forma que o sucessor estenda a
arquitetura de seu predecessor, adicionando novas funcionalidades. A utilização da família de
processadores BIP nos períodos iniciais dos cursos da área da Computação permite a
visualização mais clara por parte dos alunos dos conceitos básicos de Arquitetura e
Organização de Computadores, assim como facilita o estabelecimento de uma relação entre
esses conceitos e o conteúdo das matérias de Algoritmos e Programação. (MORANDI et al.,
2006).
A criação da família de processadores BIP difere-se de outras iniciativas similares pelo
fato de que esta propõe uma abordagem interdisciplinar, enquanto outras iniciativas mantêm
seu foco em disciplinas diretamente relacionadas. (ZEFERINO et al., 2012). Neste contexto,
Zeferino et al. (2012, p. 166) afirma que
A iniciativa de desenvolver uma família de processadores acabou permitindo que
fosse dado um enfoque interdisciplinar aos conceitos de arquitetura e organização de
computadores, vislumbrando seus desdobramentos em diferentes disciplinas
correlatas [...]. Essa característica tornou-se um diferencial desta abordagem, uma
vez que, muito frequentemente, os alunos relatam que não conseguem compreender
plenamente as relações entre as disciplinas, e, nesse sentido, a abordagem utilizada
fornece uma contribuição significativa.
A família de processadores BIP possui atualmente 5 gerações. A saber: BIP I, BIP II,
BIP III, BIP IV e μBIP (lê-se Micro-BIP).
O BIP I possui uma arquitetura RISC (Reduced Instruciont-Set Computer) baseada no
microcontrolador PIC da empresa Microchip. (MORANDI et al., 2006). Esta primeira
geração da família BIP, segundo Zeferino et al. (2012, p. 169),
11
[...] inclui apenas instruções de aritmética e de acesso à memória de dados, tendo
como foco o suporte ao entendimento de conceitos como níveis de linguagem,
constantes, variáveis, representação de dados e de instruções, conjuntos de
instruções, programação em linguagem de montagem e geração de código em
linguagem de máquina;
O BIP II estende a arquitetura de seu antecessor (BIP I), adicionando suporte a
instruções de desvio condicional e incondicional. Segundo Zeferino et al. (2012, p. 169), “[o
foco do BIP II é a] inclusão de suporte a implementação de estruturas de controle para desvios
(condicionais e incondicionais) e laços de repetição, incluindo, o suporte a operações
relacionais.”.
No BIP III, a arquitetura do BIP II foi estendida e adicionou-se suporte para instruções
de lógica e lógica bit-a-bit (VIEIRA et al., 2012).
Na quarta geração da família BIP, denominada BIP IV, a arquitetura do BIP III foi
estendida e adicionou-se suporte para entrada-e-saída, chamadas de sub-rotinas, manipulação
de vetores e deslocamento de bits. (VIEIRA et al., 2012).
Há ainda o μBIP, que estende as características do projeto BIP e agrega periférico e
funções típicas de microcontroladores, objetivando seu uso em disciplinas mais avançadas dos
cursos de graduação em Computação. (PEREIRA, 2008).
No sentido de diminuir as abstrações dos conceitos de programação de computadores,
foi desenvolvida uma IDE (Integrated Development Environment – Ambiente de
Desenvolvimento Integrado) denominada Bipide. Nesta ferramenta, é possível escrever,
compilar e simular através de animações a execução de programas escritos em linguagem
Portugol sobre a arquitetura da família de processadores BIP. A IDE Bipide possui também
um módulo de ajuda com informações sobre a arquitetura e organização da família de
processadores BIP e funcionalidades da própria IDE. (VIEIRA et al., 2009).
Em sua primeira versão, a IDE Bipide suportava programas escritos em Portugol, os
quais eram compilados para o assembly dos processadores BIP I e BIP II e simulados sobre a
arquitetura destes. (VIEIRA, 2009). Logo em seguida, adicionou-se suporte à programação
em assembly. (VIEL et al., 2014).
No trabalho de conclusão de curso realizado por Rech (2011), a arquitetura e
organização do processador BIP IV foi especificada, assim como a sua integração a IDE
Bipide. Esta integração exigiu alterações na linguagem Portugol do Bipide e em seu
12
compilador para permitir o suporte à entrada-e-saída, chamada de procedimentos e
manipulação de vetores. A interface de simulação do Bipide também foi alterada, visando
representar as novas funcionalidades. Segundo Rech (2011) as novas funcionalidades
adicionadas a IDE Bipide permitiram maior interação do aluno com a ferramenta e a
resolução de problemas mais complexos. Nesse mesmo trabalho foi feita a integração do BIP
III com o Bipide.
Mannes (2013) integrou ao Bipide o Portugol Core, núcleo do compilador Portugol
provido por Noschang (2012). Como resultado dessa integração, a sintaxe do Portugol
utilizada no Bipide igualou-se a sintaxe utilizada na ferramenta PortugolStudio (LITE-LAB,
2016). Com isso, a migração dos alunos entre as duas ferramentas tornou-se mais simples,
pois deixou de existir a necessidade de aprender duas sintaxes distintas da mesma linguagem.
(MANNES, 2013).
Oliveira (2013) descreve em seu trabalho de conclusão de curso a integração do
processador μBIP ao Bipide e a inclusão de um compilador para a linguagem C, visando uma
utilização mais ampla do ambiente nas disciplinas dos cursos de Computação.
1.1 PROBLEMATIZAÇÃO
1.1.1 Formulação do Problema
As versões anteriores do Bipide foram construídas com tecnologias e ferramentas
proprietárias, tais como a linguagem de programação C#, a linguagem de descrição de
interface WPF (Windows Presentation Foundation) e a plataforma .NET; todas elas de
propriedade da empresa Microsoft Corporation. (VIEIRA, 2009). A utilização destas
ferramentas na construção do Bipide limitava sua utilização ao ambiente Microsoft Windows,
visto que as mesmas não são totalmente ou facilmente portáveis para outros sistemas
operacionais de uso geral.
Além da limitação citada acima, a versão do Bipide anterior a apresentada neste
trabalho (4.0, em beta) não oferece a possibilidade de programação diretamente na linguagem
assembly da família BIP. Esta limitação reduzia a possibilidade de uso da IDE nas disciplinas
do curso de Ciência da Computação, considerando que algumas destas disciplinas exigem a
programação em linguagem de baixo nível como, por exemplo, na disciplina de Arquitetura e
Organização de Computadores.
13
1.1.2 Solução Proposta
Neste trabalho de conclusão de curso, foi desenvolvida uma versão web da IDE
Bipide, tornando o uso da ferramenta independente de plataforma. Nessa nova versão é
possível escrever programas nas linguagens Portugol e assembly da família BIP, assim como
simular a execução desses programas nos processadores BIP I, BIP II, BIP III, BIP IV e µBIP,
conforme já ocorre na versão desktop da ferramenta. Um módulo de ajuda contendo
informações sobre a família BIP e a IDE Bipide também foi disponibilizado.
As funcionalidades de escrever e compilar programas em linguagem C, presentes na
versão 4.0 do ambiente de desenvolvimento Bipide, não foram inclusas na elaboração deste
trabalho devido a questões relacionadas a limitação do escopo do mesmo e ao fato de que, em
paralelo, foi desenvolvida uma nova versão do compilador da linguagem C para a arquitetura
do BIP em um outro trabalho de conclusão de curso.
A criação de uma versão online do ambiente de desenvolvimento integrado Bipide
permitiu a utilização da ferramenta sem a necessidade de instalá-la. Além dessa vantagem, tal
implementação resultou na eliminação da necessidade de camadas adicionais de software para
a utilização da ferramenta, visto que esta passou a funcionar integralmente no navegador.
Igualmente, passou a existir a garantia de que o usuário está usando sempre a versão mais
recente do Bipide, sem a necessidade de atualizações manuais.
As camadas de back-end e front-end foram implementadas de forma a mantê-las
isoladas e independentes uma da outra. Esta abordagem permite que novas interfaces de
usuário sejam desenvolvidas, utilizando a estrutura de back-end disponibilizada neste
trabalho. Vislumbra-se com isso, que futuramente possam ser desenvolvidas interfaces
específicas para tablets e smartphones.
1.2 OBJETIVOS
1.2.1 Objetivo Geral
Criar uma versão web do ambiente de desenvolvimento integrado Bipide com suporte
aos processadores BIP I, BIP II, BIP III, BIP IV e µBIP, incluindo a simulação da execução
dos programas escritos através de animações.
14
1.2.2 Objetivos Específicos
Pesquisar ferramentas similares no contexto de simuladores de processadores em
ambiente web;
Analisar as versões anteriores do Bipide e documentar as funcionalidades
existentes;
Modelar a arquitetura do Bipide Web;
Avaliar a viabilidade do reaproveitamento das gramáticas e compiladores da versão
desktop do Bipide;
Implementar ou reaproveitar os compiladores necessários;
Modelar a arquitetura e implementar server-side do Bipide web;
Integrar a arquitetura server-side do Bipide Web com os compiladores
desenvolvidos ou reaproveitados;
Modelar a arquitetura e implementar client-side;
Verificar o correto funcionamento da aplicação desenvolvida.
1.3 METODOLOGIA
A metodologia adotada no desenvolvimento deste trabalho divide-se em quatro etapas:
Revisão do projeto: nesta etapa foram realizadas revisões melhorias a este projeto,
considerando sugestões e questões levantadas pela banca avaliadora do TTC I.
Desenvolvimento: a etapa de desenvolvimento compreende os seguintes itens:
- Implementação e adequação dos compiladores Portugol e assembly;
- Implementação do sistema de back-end;
- Implementação do sistema de front-end;
- Integração dos sistemas de back-end e front-end;
15
Verificação: nesta etapa, foram realizados testes e experimentos com a finalidade
de garantir o correto funcionamento do sistema, identificar e corrigir possíveis
erros.
Documentação: a etapa de documentação compreende a geração de artefatos de
engenharia de software com a finalidade de documentar a etapa de
desenvolvimento. Igualmente, nessa etapa será documentado o sistema REST do
back-end, com a finalidade de que outros desenvolvedores de sistemas front-end
possam utilizar-se do serviço provido por tal sistema. Essa etapa também
compreende testes, validação dos resultados e produção de um artigo científico.
1.4 ESTRUTURA DO TRABALHO
Este documento está estruturado em quatro capítulos. O Capítulo 1, Introdução,
apresentou uma visão geral do trabalho. No Capítulo 2, Fundamentação Teórica, é
apresentada uma revisão bibliográfica sobre o projeto BIP, assim como uma análise das
versões anteriores da IDE Bipide. Nesse capítulo também é feita uma análise de ferramentas
online para simulação de arquitetura e organização de computadores. O Capítulo 2 apresenta
também uma revisão sobre compiladores e sistemas web. O Capítulo 3 apresenta o
desenvolvimento do projeto, através da descrição do processo de desenvolvimento do back-
end e do front-end do Bipide Web, bem como os resultados obtidos pela realização de testes.
Por fim, no Capítulo 4, apresentam-se as considerações finais do autor e sugestões de
trabalhos futuros.
16
2 FUNDAMENTAÇÃO TEÓRICA
Este capítulo apresenta uma revisão bibliográfica dos temas envolvidos no
desenvolvimento deste trabalho, assim como uma análise de ferramentas similares.
2.1 PROJETO BIP
O Projeto BIP foi criado por pesquisadores do Laboratório de Sistemas Embarcados e
Distribuídos (LSED) da Universidade do Vale do Itajaí (Univali) visando desenvolver uma
família de processadores com arquitetura simplificada cujo o objetivo é auxiliar no ensino de
conceitos básicos de Arquitetura e Organização de Computadores para alunos dos períodos
iniciais dos cursos de graduação em Computação, facilitando a compreensão das abstrações
utilizadas nas disciplinas de Algoritmos e Programação. (MORANDI; RAABE; ZEFERINO,
2006; VIEIRA, 2009).
A criação de uma família de processadores básicos de arquitetura simplificada com
fins didáticos surgiu das observações de que os modelos tipicamente utilizados pelos
educadores das disciplinas introdutórias mostravam-se insuficientes no que se refere ao
entendimento, por parte dos estudantes, das relações entre as abstrações da programação de
computadores e sua implementação em hardware. Por outro lado, modelos mais completos
apresentam-se demasiadamente complexos, impedindo sua aplicação em disciplinas iniciais.
Dentro deste contexto, a família de processadores BIP apresenta-se como uma alternativa
simples o suficiente para permitir a apresentação de conceitos básicos de Arquitetura e
Organização de Computadores para alunos dos períodos iniciais. (MORANDI; RAABE;
ZEFERINO, 2006).
Os recursos dos processadores que compõem a família BIP foram especificados de
maneira incremental, de tal forma que um sucessor estende a arquitetura de seu predecessor,
adicionando novas funcionalidades. Assim, cada um dos processadores da família BIP
mantém seu foco na compreensão de alguns conceitos bem definidos de Arquitetura e
Organização de Computadores. (MORANDI et. 2006). Zeferino et al. (2012) afirmam que
essa característica permitiu a utilização do BIP com diferentes níveis de complexidade em
diferentes disciplinas do curso de Ciência da Computação da Universidade do Vale do Itajaí,
permitindo um enfoque interdisciplinar no ensino de Arquitetura e Organização de
Computadores.
17
A arquitetura dos processadores da família BIP é orientada a acumulador e de alta
regularidade arquitetural. As decisões de adotar essas características arquiteturais foram
tomadas no sentido de facilitar a implementação do processador e o entendimento da sua
arquitetura. (ZEFERINO et al., 2012). Zeferino et al. descreve os atributos arquiteturais do
BIP conforme segue:
Palavra de instruções e de dados: Tanto a palavra de dados quanto a palavra de
instrução dos processadores BIP possuem 16 bits.
Tipos de dados: Os processadores BIP trabalham unicamente com dados do tipo
inteiro de 16 bits com sinal (–32768 a +32767).
Registradores: A arquitetura dos processadores BIP não prevê banco de
registradores. Há apenas um registrador de propósito geral (ACC – do inglês
accumulator).
Modelos de execução: O BIP suporta os modelos de execução registrador-
registrador e registrador-memória.
Formato de instrução: O formato de instrução dos processadores BIP segue o
mesmo padrão para todas as instruções, independente da classe da instrução. Este
formato prevê a utilização dos 5 bits mais significativos para representar o código
da operação e os outros 11 bits para identificar um operando explícito, conforme
apresentado na Figura 1.
Espaço de endereçamento: O espaço de endereçamento é limitado pela largura do
campo de operando das instruções (11 bits). Assim, o limite é igual a 2048 posições
de memória. Este espaço de endereçamento pode ser explorado tanto com
memórias diferentes para dados e instrução (arquitetura Harvard), quanto com uma
mesma memória para dados e instrução (Arquitetura de Von Newmann).
Modos de endereçamento: O BIP possui dois modos de endereçamento: (i)
Imediato, utilizado em operações envolvendo o acumulador e o operando da
instrução; e (ii) Direto: utilizado em operações envolvendo o acumulador e uma
posição no espaço de memória indicada pelo operando da instrução. O µBIP
18
adicionou o modo de endereçamento indireto, utilizado para a manipulação de
vetores. (RECH, 2011).
Figura 1. Formato de instrução dos processadores BIP
Fonte: adaptado de Morandi et al. (2006).
Em termos de organização, a Unidade Central de Processamento (UCP) dos
processadores BIP possui os blocos de Controle e Caminho de dados. A Figura 2 mostra estes
dois elementos em duas diferentes alternativas de implementação do processador BIP I. O
bloco Controle compreende o registrador PC (program counter - contador de programa), um
somador utilizado para incrementar o PC e o decodificador de instruções. O bloco Caminho
de Dados contém o registrador ACC, uma unidade aritmética e um extensor de sinal. Vale
salientar que todas as versões da ferramenta Bipide adotam a implementação Harvad para
ilustrar a arquitetura dos processadores BIP.
Atualmente, o Projeto BIP é composto por cinco diferentes gerações de processadores:
BIP I, BIP II, BIP III, BIP IV e µBIP, descritos a seguir.
Figura 2. Implementação (a) Harvard e (b) Von Neumann do BIP I
2.1.1 BIP I
A arquitetura do BIP I é baseada na arquitetura RISC do microcontrolador PIC da
empresa Microchip. (MICROCHIP, 2016; MORANDI et al., 2006). O BIP I dá suporte a
instruções de transferência (LD, LDI e STO) e aritméticas de soma e subtração (ADD, ADDI,
19
SUB e SUBI). Conforme citado anteriormente, todas as instruções de transferência e
aritméticas envolvem o registrador acumulador (ACC). (VIEIRA, 2009).
O BIP I realiza apenas operações de soma e subtração com variáveis e constantes.
Apesar da simplicidade, essa versão do processador permite ao aluno visualizar a
implementação em hardware de muitas das abstrações envolvidas nas disciplinas de
Algoritmos e Programação. (MORANDI et al., 2006). Neste contexto, Zeferino et al. (2012)
cita que o foco do BIP I está no “entendimento dos conceitos de níveis de linguagem,
constantes, variáveis, representação de dados e de instruções, conjuntos de instruções,
programação em linguagem de montagem e geração e geração de código em linguagem de
máquina”.
2.1.2 BIP II
O BIP II é uma extensão da arquitetura do BIP I com adição de instruções de desvio
condicional e incondicional. Essas novas instruções são utilizadas para suportar as estruturas
de controle de linguagens de alto nível, tais como laços de repetição e desvios condicionais.
A adição de instruções de desvio condicional e incondicional ao BIP II fez com que
fosse necessária a inclusão de um novo registrador, denominado STATUS; e de duas flags
booleanas; Z (zero) e N (negative). Esta mudança arquitetural deve-se ao fato de que as
instruções de desvio condicional são sempre precedidas por uma subtração. O resultado desta
operação define os valores de Z e N, configurando os mesmos com os valores 0 ou 1,
indicando falso ou verdadeiro respectivamente. Os valores destas flags após a execução da
subtração definem a execução ou não do desvio condicional. (ZEFERINO et al., 2012).
2.1.3 BIP III
O BIP III estende a arquitetura do BIP II e adiciona suporte a instruções de lógica bit-
a-bit. Assim, adicionou-se no BIP III uma classe de instruções lógicas. (RECH, 2011).
Conforme Zeferino et al., a arquitetura do BIP III é muito similar a arquitetura do BIP II,
sendo que poucas modificações na mesma foram necessárias para suportar as instruções de
lógica booleana e bit-a-bit.
20
2.1.4 BIP IV
O BIP IV estende a arquitetura do BIP III e aproveita algumas instruções do µBIP. No
BIP IV é possível realizar chamadas de procedimentos, manipular vetores e escrever
programas com entrada-e-saída. Nesta versão do BIP há o modo de endereçamento indireto,
utilizado para a manipulação de vetores. O registrador INDR armazena o índice a ser acessado
no vetor. As operações de manipulação de vetores têm como operando o endereço base do
vetor. A posição correta é acessada através da soma do endereço base presente na instrução
com o valor de INDR. (VIEIRA et al. 2012).
Segundo Rech (2011) as novas funcionalidades adicionadas no BIP IV passaram a
permitir a utilização de tal processador para a resolução de problemas mais complexos. Rech
(2011) ainda cita como benefício trazido pelo BIP IV a possibilidade de o aluno conseguir
interagir com os programas que escreve, através de chamadas de E/S (entrada-e-saída).
2.1.5 µBIP
O µBIP é um processador da família BIP que agrega características típicas de
microcontroladores, tais como portas de entrada-e-saída, controlador de interrupções e
temporizador. De acordo com Pereira (2008), o µBIP fortalece a proposta interdisciplinar do
Projeto BIP, pois permite a sua utilização em disciplinas relacionadas ao ensino de sistemas
embarcados (PEREIRA, 2008).
O µBIP utiliza a estratégia de entrada-e-saída mapeada em memória, onde o
endereçamento de periféricos usa uma parte da memória existente. Segundo Pereira (2008)
esta decisão foi tomada visando simplicidade e economia de instruções. Assim, o µBIP divide
a memória de dados ao meio, destinando 1K para memória de dados e 1K para registradores
de entrada-e-saída. Desse modo, é possível identificar se um endereço refere-se à memória de
dados ou entrada-e-saída analisando apenas o primeiro bit. A parte destinada a entrada-e-saída
mapeia registradores de periféricos e mantêm informações de configuração e estado de tais
periféricos. (PEREIRA, 2008).
Referente aos registradores, foi adicionado no µBIP a flag C ao registrador STATUS.
Tal flag tem a função de indicar a ocorrência de um carry-out. A instrução RETINT foi
adicionada ao µBIP e tem a função de retornar de uma interrupção, carregando o endereço
anterior a interrupção no registrador PC.
21
Em termos de organização, o µBIP passou a ter uma unidade funcional, que acumula
as funções da unidade aritmética e unidade lógica. Há também um temporizador configurável,
sendo que o estouro do temporizador gera uma interrupção desvia a execução para o endereço
0x001, onde as interrupções devem ser tratadas. Uma interrupção também pode ser gerada
através do pino 0 da porta port0. (OLIVEIRA, 2013).
O µBIP possui ainda uma pilha para tratar chamadas de procedimentos, um hardware
específico para a manipulação de vetores, uma interface de acesso a registradores de propósito
especiais (SFR – Special Function Register) e um controlador de interrupções.
Existem 16 pinos de entrada-e-saída no µBIP, sendo que estes são configurados
individualmente em relação a sua direção (entrada ou saída) e o valor do dado a ser escrito ou
lido. Essa configuração é feita através do registrador portX_dir para a direção (1 para entrada
e zero para saída) e portX_data para dado; sendo X o identificador do pino. (RECH, 2011).
A organização do O µBIP foi aproveitada em partes pelo BIP IV, sendo a principal
diferença entre estes é que o µBIP suporta a adição de componentes periféricos.
A Tabela 1 mostra a relação entre as versões do processador BIP e as classes de
instruções suportadas pelos mesmos.
Tabela 1. Relação entre classes de instruções e processadores da família BIP
Classe de instruções Versões do Processador
BIP I BIP II BIP III BIP IV µBIP
Transferência STO, LD, LDI
Aritmética ADD, ADDI, SUB, SUBI
Controle HLT
Desvio BEQ, BNE, BGT, BGE, BLT, BLE, JMP
Lógica AND, OR, XOR, ANDI, ORI, XORI, NOT
Deslocamento lógico SLL, SRL
Manipulação de vetores LDV, STOV
Suporte a procedimentos RETURN, CALL
Suporte a interrupções RETINT
Fonte: Adaptado de Oliveira (2013).
2.2 AMBIENTE DE DESENVOLVIMENTO INTEGRADO BIPIDE
A IDE Bipide foi desenvolvida no intuito de proporcionar uma redução nas abstrações
envolvidas no ensino das disciplinas de Algoritmos e Programação dos períodos iniciais dos
22
cursos de graduação em Computação. O Bipide possibilita a criação de programas em
linguagem de alto nível, a tradução dos programas escritos para a linguagem de montagem
dos processadores da família BIP e a simulação passo-a-passo de tais programas através de
animações. (OLIVEIRA et al., 2014). Esta abordagem, segundo Vieira (2013), permite ao
aluno relacionar os conceitos de programação em alto nível com os conceitos de baixo nível.
O desenvolvimento da IDE Bipide levou em consideração as características presentes
em outros simuladores de arquitetura e organização de computadores de propósito
educacional. Estas características foram levantadas através de um estudo comparativo,
demonstrado por Vieira (2009). Tal estudo foi utilizado como referência na definição de
funcionalidades contidas no Bipide, bem como características da interface do usuário que
facilitassem o uso da ferramenta em disciplinas introdutórias de programação. (VIEIRA et al.,
2009).
2.2.1 Suporte a linguagens de programação
A primeira versão da IDE Bipide (v. 1.0) permitia ao usuário escrever programas em
linguagem Portugol, compilar os programas escritos para a linguagem de montagem dos
processadores BIP I e BIP II e simular a execução passo-a-passo desses programas. Viera
(2009) justifica a escolha da linguagem Portugol pela sua constante utilização nas disciplinas
introdutórias de Algoritmos e Programação. Um outro fator determinante para a escolha do
Portugol como linguagem de programação do ambiente Bipide é o fato de a mesma utilizar
comandos em língua portuguesa. Essa característica elimina possíveis barreiras com outros
idiomas, assim como facilita a ambientação do usuário com formalismos característicos da
programação de computadores. O subconjunto de instruções da linguagem Portugol utilizado
no Bipide 1.0 foi definido de acordo com as operações suportadas pelo hardware dos
processadores BIP I e BIP II. (VIEIRA, 2009). A Tabela 2 apresenta o subconjunto de
instruções do Portugol utilizado no Bipide a fim de dar suporte às operações em hardware dos
processadores BIP I e II.
23
Tabela 2. Subconjunto de instruções Portugol utilizado no Bipide 1.0
Instrução Portugol Descrição
programa Símbolo inicial da gramática
declarações Definição de bloco de declaração de variáveis
Defina Definição de constantes
Inicio Identifica o início do algoritmo
Fim Identifica o fim do algoritmo
Inteiro Tipo de dado numérico inteiro10
se ___ então Desvio condicional
senão Negação do ‘SE’
fimse Fim de bloco de desvio condicional
enquanto ___ faca Laço de repetição com condição no inicio
fimenquanto Fim de bloco de laço condicional
repita ___ quando Laço de repetição com condição no fim
para __ ate __ passo __ Laço condicional com repetição incremental
fimpara Fim de bloco de laço condicional com repetição incremental
<- Operador de atribuição
(,) Parênteses
+, - Operadores aritméticos
>, <, <=, >=, !=, = Operadores relacionais
Fonte: Vieira (2009)
A segunda versão do Bipide (v. 2.0) permitiu ao usuário programar diretamente em
linguagem de montagem dos processadores BIP I e BIP II. (VIEL et al., 2014).
O Bipide 3.0 introduziu o suporte aos processadores BIP III e BIP IV da família BIP.
Como consequência da inclusão desses novos processadores na IDE, o subconjunto de
instruções da linguagem Portugol utilizado nas versões anteriores do Bipide precisou ser
expandido a fim de suportar as novas operações de hardware presentes no BIP III e no BIP
IV. Assim, adicionou-se ao Portugol do Bipide 3.0: instruções de (i) entrada-e-saída, (ii)
manipulação de vetores, (iii) chamadas de sub-rotinas e (iv) operações lógicas. (RECH, 2011).
Tabela 3. Instruções adicionadas ao subconjunto Portugol no Bipide 3.0
Instrução Portugol Descrição
leia Lê da entrada do simulador
escreva Escreve na saída do simulador
!, ^, |, & Operadores lógicos
<<, >> Operadores de deslocamento de bits
retornar Retorno de função
procedimento Declaração de procedimento
24
A gramática Portugol do Bipide 3.0 também precisou ser modificada para permitir
utilização de funções e manipulação de vetores. O Quadro 1 apresenta exemplos de utilização
dessas estruturas no Portugol do Bipide 3.0.
Quadro 1. Exemplos de (a) declaração de função e (b) manipulação de vetor no Portugol do
Bipide 3.0
// declaração de função
inteiro soma(inteiro a,inteiro b)
declaracoes
inteiro r
inicio
r <- a+b
retornar r
fim
(a)
procedimento principal()
declaracoes
inteiro a,b[5]
inicio
a <- 0
enquanto (a < 5) faca
b[a] <- a
escreva(b[a])
a<-a+1
fimenquanto
fim
(b)
Fonte: adaptado de Rech (2011).
A versão do Bipide anterior a apresentada neste trabalho é a 4.0. Essa versão encontra-
se atualmente em fase beta de desenvolvimento. Em sua versão 4.0, a IDE Bipide permite ao
usuário programar em linguagem C através do compilador descrito por Oliveira (2013). A
adição do suporte da linguagem C ao Bipide justificou-se pela frequente adoção de tal
linguagem em diferentes disciplinas da matriz curricular dos cursos de graduação em
Computação da Univali. Considerando este fato, a adição de um compilador C ao Bipide veio
a fortalecer a proposta de uso interdisciplinar da ferramenta. Além da adição de um
compilador C, a versão 4.0 do Bipide passou a suportar o processador µBIP da família BIP.
(OLIVEIRA, 2011). O subconjunto de instruções da linguagem C foi definido de acordo com
as operações suportadas pelo hardware da família BIP e é apresentado na Tabela 4.
25
Tabela 4. Subconjunto de instruções da linguagem C presente no Bipide 4.0
Instrução Portugol Descrição
if, else, switch, case, default Desvio condicional
Goto Desvio incondicional
for, do, while Laços de repetição
break, continue, return Operações de controle
int, void Tipos de dados
procedimento Declaração de procedimento
++, -- Incremento e decremento posfixo
- Menos unário
~ Operador bit-a-bit Não
+, - Operadores aritméticos
<<, >> Operadores de deslocamento bit-a-bot
&, |, ^ Operadores de bit-a-bit AND, OR e XOR
=, +=, -= Operador de atribuição
>, <, >=, <=, !=, == Operadores relacionais
Fonte: adaptado de Oliveira (2013)
Oliveira (2013) também adicionou ao Bipide 4.0 algumas diretivas de pré-compilador
com o objetivo de valer-se das funcionalidades providas pela arquitetura do µBIP. Essas
diretivas são: (i) #include, (ii) #define e (iii) #asm e #endasm. Conforme pôde-se
observar através da utilização da versão 4.0 do Bipide, o suporte à programação em
linguagem de montagem dos processadores Bipide não está presente na ferramenta. Apesar
disso, ainda é possível escrever código assembly através da utilização das diretivas #asm e
#endasm do pré-compilador C.
Mannes (2013) realizou a integração do Portugol Core com a IDE Bipide, utilizando a
ASA (Árvore Sintática Abstrata) gerada pelo Portugol Core. Como resultado da integração o
Bipide passou a utilizar a sintaxe do Portugol 2.0. (MANNES, 2013).
Na Tabela 5 observa-se a relação entre as versões da IDE Bipide, versões dos
processadores BIP e suporte a linguagens de programação.
Tabela 5. Relação entre versões do Bipide, versões do BIP e linguagens de programação.
Versão do Bipide 1.0 2.0 2.5 3.0 4.0
Versão do BIP I II I II I II I II III IV
I II III IV µ
Portugol x x
x x
x x
x x x x
x x x x x
Assembly
x x
x x
x x x x
Linguagem C
x x x x x
26
2.2.2 Módulo de Simulação
A IDE Bipide possui um módulo de simulação integrado onde é possível visualizar a
execução passo-a-passo dos programas criados pelo usuário sobre a arquitetura dos
processadores da família BIP, através de animações. Durante a simulação da execução dos
programas, pode-se visualizar a representação dos registradores do processador, memória de
dados e memória de instrução junto aos seus respectivos valores. Além destes elementos,
também pode-se visualizar o código-fonte em alto nível com seu equivalente em linguagem
de montagem junto a representação visual da arquitetura correspondente ao processador
selecionado. (VIEIRA; RAABE; ZEFERINO, 2010). A Figura 3 mostra a interface de
simulação do Bipide 3.0. Nesta versão o simulador do Bipide passou a contar com elementos
utilizados para realizar entrada-e-saída devido ao suporte ao BIP IV.
Figura 3. Ambiente de simulação do Bipide 3.0
O ambiente de simulação do Bipide foi projetado de tal forma que o usuário seja capaz
de visualizar simultaneamente (i) o código do programa em alto nível, (ii) o código assembly
e (iii) a arquitetura do processador sobre o qual está sendo realizada a simulação. Essa
característica tem por objetivo permitir ao usuário criar relações e fazer comparações entre
tais elementos e, por consequência, facilitar o entendimento das abstrações envolvidas em
todo o processo. (VIEIRA; RAABE; ZEFERINO, 2010). A relação entre estes elementos é
exibida na Figura 4.
27
Figura 4. Relação entre os elementos da interface de simulação do Bipide
Fonte: Vieira (2009)
Outros elementos e funcionalidades que podem ser destacados do ambiente de
simulação do Bipide são:
Controle de execução: permitem ao usuário controlar a execução da simulação
através dos botões (i) Simular, (ii) Pausar, (iii) Repetir, (iv) Próximo, (v) Continuar
e (vi) Parar.
Seletor de velocidade: Permite ao usuário configurar a velocidade de execução da
simulação.
Seletor de processador: Permite ao usuário selecionar sobre a arquitetura de qual
processador o código-fonte deve ser simulado.
Aumentar / Diminuir fonte: Permite ao usuário configurar o tamanho da fonte.
Descrições: Exibição da descrição da instrução sendo executada no passo atual.
O módulo de simulação da versão 3.0 do Bipide conta ainda com a possibilidade de
visualizar algumas informações estatísticas sobre o código assembly executado, conforme
demonstrado na Figura 5. Esta funcionalidade é acessada através do botão Instruções no canto
superior direito. A partir da versão 3.0 do Bipide passou a ser possível a execução individual
de instruções no simulador.
28
Figura 5. Estatísticas de execução do código assembly no Bipide 3.0
2.2.3 Outros Recursos do Ambiente
O ambiente de desenvolvimento integrado Bipide conta com outros recursos,
conforme listado abaixo:
Simular uma única instrução: O Bipide permite ao usuário realizar a simulação de
uma instrução de forma isolada, sem a necessidade de escrever um programa para
tal.
Destaque de sintaxe: O editor de programas do Bipide possui o recurso de destaque
de sintaxe, presente na maioria das IDEs. Assim, o usuário visualiza construções e
palavras reservadas da linguagem com diferentes formatações. Este recurso facilita
a identificação imediata das estruturas utilizadas em diferentes partes do código-
fonte.
Exibição de erros: O editor de programas do Bipide exibe ao usuário mensagens de
erros encontradas durante o processo de compilação. Junto a mensagem de erro é
exibida a linha onde o mesmo ocorreu.
29
Módulo de ajuda: O módulo de ajuda da IDE Bipide possui informações referentes
ao ambiente de desenvolvimento, família de processadores BIP e Arquitetura e
Organização de Computadores. O módulo de ajuda também possui informações
referentes a linguagem de programação suportada pela versão correspondente da
IDE.
Exportação: A partir da versão 2.0 do Bipide, passou a ser possível exportar o
código-fonte dos programas criados pelo usuário para diferentes formatos, tais
como assembly, binário e hexadecimal.
Programas de exemplo: O Bipide oferece uma série de programas de exemplo, os
quais podem ser abertos e modificados livremente pelo usuário. Os diferentes
programas procuram utilizar-se de diferentes recursos da linguagem de
programação no intuito de demonstrar o seu uso.
Multi-idioma: A versão 3.0 do Bipide passou a permitir ao usuário selecionar o
Inglês como língua utilizada nos menus e mensagens da IDE, além da língua
portuguesa.
A Tabela 6 apresenta as funcionalidades da IDE Bipide, de acordo com suas diferentes
versões.
30
Tabela 6. Resumo das funcionalidades das diferentes versões do Bipide
Bipide 1.0 2.0 2.5 3.0 4.0 Web
Su
po
rte
aos
pro
cess
ado
res
BIP
I X X X X X X
II X X X X X X
III X X X
IV X X X
µ X X
Lin
gu
agen
s
de
pro
gra
maç
ão
Portugol X X X X X X
Assembly X X X X
Linguagem C X
Am
bie
nte
de
sim
ula
ção
Simulação de arquitetura X X X X X X
Simulação de organização X X X X X X
Relacionar instrução de alto e baixo nível X X X X X X
Execução passo-a-passo X X X X X X
Estatísticas X
Simulação de única instrução X X X X X
Ed
ito
r
de
cód
igo
Destaque de sintaxe X X X X X X
Exibição de mensagens de erro X X X X X X
Am
bie
nte
Módulo de ajuda X X X X X X
Exportação de arquivos X X X X
Programas de exemplo X X X X X X
Suporte a diferentes idiomas X X
2.3 SIMULADORES DE ARQUITETURA E ORGANIZAÇÃO
O objetivo desta seção é apresentar e comparar um conjunto de simuladores de
arquitetura e organização de computadores disponíveis no âmbito da internet. O quadro
comparativo entre os simuladores analisados, apresentado na seção 2.3.6, serviu como uma
das bases para a definição das funcionalidades que estarão disponíveis no Bipide Web.
O processo de seleção dos itens presentes nesta seção levou em consideração apenas
ferramentas disponíveis na internet, que dispõem de simuladores de arquitetura, organização
de computadores ou ambos. Igualmente, foram consideradas apenas ferramentas que
permitem ao usuário programar em linguagem de montagem ou em linguagem de alto nível.
31
2.3.1 FRISCjs
O FRISCjs é um simulador para o FRISC, um processador de 32 bits de propósito
educacional desenvolvido dentro da Universidade de Zagreb. Ele possui um conjunto de
instruções RISC e dois níveis de pipeline. (FRISC, 2016).
A interface de simulação do FRISCjs é dividida em abas. A aba Simulator (visível na
Figura 6) possui um editor de código com destaque de sintaxe para a linguagem de montagem
do processador FRISC e um console com informações sobre a execução do programa e a
atualização dos registradores. Além disso, o simulador do FRISCjs oferece uma série de
botões de controle da execução. Através do botão settings pode-se configurar a frequência do
processador e o tamanho do espaço de memória. A aba Load/Save permite ao usuário salvar e
carregar configurações previamente salvas. Informações sobre o uso do simulador podem ser
encontradas na aba Usage Instructions. Em Examples são encontrados programas de exemplo
e arquivos de configuração que podem ser carregados no simulador do FRISCjs. Por fim, a
aba About contém informações sobre a ferramenta e links.
Figura 6. Interface do FRISCjs
2.3.2 Simple 8-bit Assembler Simulator
Simple 8-bit Assembler Simulator oferece uma sintaxe simplificada de um
processador x86, baseando-se na arquitetura do processador NASM (Netwide Assembler).
32
O simulador consiste em um processador de 8 bits com 256 bytes de memória. As
instruções do Simple 8-bit Assembler Simulator ocupam 1 byte de memória, com exceção da
instrução MOV, que ocupa três. O simulador possui um conjunto de instruções bastante
completo, que inclui cópia de valores, definição de variáveis, operações matemáticas,
incremento e decremento, lógicas, movimentação de bits, comparação, desvio incondicional,
desvio condicional, chamada e retorno de função, empilhamento/desempilhamento e controle.
A interface de simulação oferece um editor de código simples onde o usuário pode
criar programas em linguagem de montagem. Ao lado direito do simulador, pode-se visualizar
a interface de saída e os valores dos registradores e memória. Uma lista dos labels utilizados
no código fonte em linguagem de montagem é apresentada abaixo da representação da
memória. Existe a possibilidade de configurar a velocidade do clock do processador. Na
Figura 7 é exibida a interface de simulação do Simple 8-bit Assembler Simulator.
Figura 7. Interface de simulação do Simple 8-bit Assembler Simulator
33
2.3.3 Basic MIPS Simulator
O Basic MIPS Simulator é um projeto experimental disponível no repositório de
compartilhamento de código Github sob uma licença open source. O projeto consiste em um
simulador para um conjunto reduzido de instruções do processador MIPS. O conjunto de
instruções disponível inclui acesso a memória, operações aritméticas, operações lógicas,
desvio incondicional, desvio condicional, e pseudo-instruções. A implementação utilizada
nesta ferramenta utiliza um pipeline de 5 etapas. (MORRISWMZ, 2016).
A interface de simulação do Basic MIPS (Microprocessor Without Interlocked
Pipeline Stages - Microprocessador Sem Estágios Intertravados de Pipeline) Simulator é
bastante simplificada, conforme pode ser visto na Figura 8. A seção Assembly Source da
interface permite ao usuário digitar as instruções em linguagem de montagem. Durante a
execução do programa, as linhas correspondentes a cada etapa do pipeline ficam em destaque.
A seção CPU Status exibe o estado atual dos registradores. Nesta mesma seção existem
botões para executar o programa, executar uma instrução, recomeçar e parar a execução.
Através do botão Pipeline pode-se visualizar o estado atual de cada um dos cinco estágios do
pipeline. A seção Memory permite a visualização do estado atual da memória. Pode-se buscar
por endereços específicos. Na seção Output a interface exibe mensagem de erro e saídas do
programa em execução.
Figura 8. Interface do Basic MIPS Simulator.
34
2.3.4 Asm86
Asm86 é um compilador e emulador de uma versão simplificada da linguagem de
montagem da arquitetura x86 escrito em JavaScript e com código-fonte disponível no
respositório de código Github sob uma licença open source. A versão da linguagem de
montagem suportada pelo Asm86 é bastante simplificada e possui limitações como: conjunto
de instruções reduzido, conjunto de flags reduzido, falta de suporte a paginação ou
segmentação e existência de apenas nove registradores. (CARLOSRAFAELGN, 2016).
A interface simplificada do Asm86 oferece ao usuário um editor de código fonte com
destaque de sintaxe. A ferramenta permite ao usuário trocar o idioma utilizado e carregar um
programa de exemplo, contendo comentários explicativos. Além disso, existem botões para
compilar o programa criado no editor de textos, iniciar a execução, pausar, executar
instruções passo-a-passo e recomeçar a execução. Através do botão Janelas é possível
personalizar parte da interface adicionando e removendo componentes da mesma, tais como
visualização de registradores, interface de entrada-e-saída e um console.
Não há documentação disponível sobre a ferramenta, porém o autor disponibiliza links
que levam o usuário para os manuais da arquitetura x86. A Figura 9 mostra a interface do
Asm86.
Figura 9. Interface do Asm86
35
2.3.5 Little Man Computer
Little Man Computer (LMC) é um modelo computacional simplificado com propósitos
educacionais criado por Stuart Madnick em 1965.
A CPU do LMC é composta por:
100 posições de memória
Uma unidade aritmética
Os registradores ACCUMULATOR, PROGRAM COUNTER, INSTRUCTION
REGISTER e ADDRESS REGISTER.
Uma interface de entrada onde pode-se trabalhar com números inteiros com sinal (-
999 até 999)
Uma interface de saída
O conjunto de instruções do LMC é composto por instruções de controle (HLT),
aritméticas (ADD, SUB), transferência (STA, STO, LDA), desvio (BRA, BRZ, BRP) e
entrada-e-saída (INP, OUT, OTC). Há ainda uma instrução fake denominada DAT que possui
a função de indicar se um dado endereço contém dados (e, consequentemente, não contêm
instruções).
O formato de instrução do LMC é composto por três dígitos, sendo o primeiro
utilizado para indicar o código da operação e os dois últimos indicam um endereço associado
com a instrução. O LMC utiliza uma arquitetura de Von Neumann, ou seja, há uma mesma
memória para dados e instruções.
A interface do simulador do LMC, apresentada na Figura 10 apresenta ao lado
esquerdo um editor simples onde o usuário pode digitar o código em linguagem de montagem
do LMC. Além de digitar o seu próprio programa, o usuário pode selecionar um programa de
exemplo em uma lista, logo abaixo do editor de código. O lado direito da interface de
simulação do LMC mostra uma representação gráfica da arquitetura e organização do
processador, onde pode-se visualizar os registradores, a memória e as interfaces de entrada e
saída de dados. O botão RUN inicia a simulação do programa, que pode ser feita passo-a-
passo. É possível controlar a velocidade de execução da simulação.
36
Figura 10. Interface do simulador do Little Man Computer
2.3.6 Comparação Entre os Simuladores Analisados
A partir da análise dos simuladores descritos, foi possível realizar a comparação entre
suas funcionalidades. A Tabela 7 apresenta as principais funcionalidades identificadas nos
simuladores analisados e as funcionalidades que devem ser implementadas no Bipide WEB.
As funcionalidades Configuração de Clock de CPU e Pesquisar por Endereço de
Memória não foram implementadas na versão online do ambiente de desenvolvimento Bipide
devido a limitação do escopo deste trabalho de conclusão de curso. Assim, tais
funcionalidades poderão ser implementadas em futuras melhorias na ferramenta.
37
Tabela 7. Tabela comparativa das funcionalidades dos simuladores web analisados
Característica FRISCjs
Simple 8-bit
Assembler
Simulator
Basic MIPS
Simulator Asm86
Little Man
Computer Bipide Web
Propósito acadêmico Sim Sim Não Sim Sim Sim
Configuração de
clock de CPU Sim Sim Não Não Não Não
Programação em alto
nível Não Não Não Não Não Sim
Programação em
assembly Sim Sim Sim Sim Sim Sim
Visualização do
assembly Sim Sim Sim Sim Sim Sim
Visualização dos
registradores Sim Sim Sim Sim Sim Sim
Execução passo-a-
passo Sim Sim Sim Sim Sim Sim
Simulação da
organização Não Não Não Não Sim Sim
Simulação da
arquitetura Sim Sim Sim Sim Sim Sim
Pesquisar por
endereço de memória Não Não Sim Não Não Não
Identificação de erros Sim Sim Sim Sim Sim Sim
Arquivos de ajuda Sim Sim Não Não Sim Sim
Programas de
exemplo Sim Sim Sim Sim Sim Sim
2.4 COMPILADORES
Para Aho et al. (2008) um compilador é um software capaz de traduzir um programa
escrito em uma determinada linguagem de programação, denominada linguagem fonte, em
um programa equivalente em outra linguagem de programação, denominada linguagem
objeto. O compilador também possui o papel de encontrar e relatar erros durante esse
processo de tradução. Cooper e Torczon (2014) complementam afirmando que um
compilador é um software de grande porte formado por vários componentes, algoritmos e
interações complexas. Ainda segundo Cooper e Torczon (2014), para cumprir com o seu
papel um compilador precisa compreender a forma e o conteúdo da linguagem de entrada
assim como as regras que controlam a forma e o conteúdo da linguagem de saída. A
Linguagem fonte costuma ser alguma linguagem de alto nível, tais como C e C++. A
linguagem alvo é tipicamente um conjunto de instruções de algum processador. A Figura 11
apresenta o processo de compilação de forma simplificada.
38
Processadores são projetados para executar sequências de operações tipicamente
especificadas em um nível de abstração muito abaixo do utilizado pelas linguagens de
programação de alto nível. A programação em linguagens de programação ditas de baixo
nível é vista como uma atividade lenta, cansativa e passível de erros. Por outro lado,
linguagens de programação de alto nível foram projetadas para que programadores consigam
expressar programas computacionais de forma mais inteligível por seres humanos. Dentro
deste contexto, compiladores permitem ao programador utilizar linguagens de programação
de alto nível ao invés das linguagens de programação de baixo nível. (AHO, 2008; COOPER;
TORCZON, 2014).
Figura 11. Processo de compilação
Adaptado de Aho (2008)
2.4.1 Estrutura do Compilador
Estruturalmente, um compilador pode ser divido em duas partes: análise e síntese.
Essas duas partes também são conhecidas como back-end e front-end, respectivamente.
Assim, o papel do front-end do compilador é compreender o programa escrito na linguagem
fonte; enquanto o papel do back-end consiste no mapeamento do programa para a máquina
alvo. A comunicação entre o front-end e o back-end do compilador se dá através de uma
representação intermediária (Intermediate Representation – IR). Esta arquitetura possibilita a
criação de diversos front-ends que conseguem comunicar-se com um mesmo back-end e vice-
versa. A Figura 12 demonstra esta estrutura. Durante o processo de compilação, o compilador
utiliza-se de várias representações intermediárias. (COOPER; TORCZON, 2014).
39
Um outro componente importante do processo de compilação é a tabela de símbolos.
Este componente consiste em uma estrutura onde são armazenadas informações sobre o
programa fonte. Tal estrutura é repassada junto a representação intermediária para a etapa de
síntese. (AHO, 2008).
Figura 12. Estrutura de um compilador.
Fonte: Adaptado de Cooper; Torczon (2014).
Cooper e Torczon (2014) descrevem ainda a existência de uma terceira etapa opcional
existente entre o front-end e o back-end do compilador. Trata-se da fase de otimização,
conforme consta na Figura 13. A fase de otimização recebe como entrada uma IR e produz
como saída outra IR (fase IR-para-IR). O objetivo desta fase da compilação é realizar
melhorias na IR que será recebida pelo back-end para que este consiga produzir um programa
melhor. As melhorias obtidas através da fase de otimização podem ser, por exemplo: a
diminuição do tamanho do programa produzido, o acréscimo da velocidade de execução do
mesmo ou ainda a diminuição na quantidade de faltas de páginas produzidas pelo programa
resultante. A otimização pode ser um bloco monolítico ou dividir-se em diversas etapas.
(COOPER; TORCZON, 2014). Aho et al. (2008) complementa afirmando que esta
otimização é independente do computador alvo. Neste mesmo contexto, Aho et al. (2008) cita
uma fase de otimização dependente da máquina alvo que ocorre após a geração do código da
máquina alvo.
Figura 13. Compilador de 3 fases.
Fonte: Adaptado de Cooper; Torczon (2014).
As subseções seguintes descrevem as fazes de análise léxica, análise sintática, análise
semântica e geração de código de um compilador.
40
2.4.1.1 Análise Léxica
A análise léxica é a primeira fase de um compilador e tem como função principal
realizar a leitura do fluxo de caracteres do programa fonte e transformá-lo em sequências com
significado para a linguagem em questão. Estas sequências recebem o nome de lexemas.
(AHO et al., 2008). Delamaro (2004) complementa afirmando que também é função da
análise léxica avisar quando é encontrado algum símbolo que não faça sentido para a
linguagem fonte. A análise léxica também pode ser referenciada pelo nome de Leitura
(scanning).
Os lexemas identificados são transformados em estruturas associativas, denominadas
tokens. A chave de cada entrada desta estrutura corresponde a um identificador genérico do
lexema. O valor referenciado por esta chave aponta para uma entrada na tabela de símbolos,
que é repassada para a fase de análise semântica. A tabela de símbolos possui papel
fundamental no processo de compilação, pois mantém todas as informações necessárias sobre
os tokens do programa fonte. O analisador léxico geralmente realiza outras tarefas além da
identificação dos lexemas, tais como a remoção de comentários e espaços em branco do
programa fonte, associação de mensagens de erro de compilação com a linha referente no
programa fonte e expansão de macros. (AHO et al., 2008).
Alguns analisadores léxicos são divididos em duas etapas, sendo a primeira
denominada escandimento e, responsável pela varredura do programa fonte; e a segunda
sendo a análise léxica propriamente dita, responsável pela geração da sequência de tokens
como saída. (AHO et al., 2008).
2.4.1.2 Análise Sintática
A segunda fase do processo de compilação é denominada análise sintática. O
analisador sintático recebe como entrada a cadeia de tokens que representa o programa fonte
produzida pelo analisador léxico. A partir dessa cadeia de tokens o analisador sintático produz
uma representação intermediária denominada árvore sintática. Tal árvore representa a
estrutura gramatical da sequência de tokens do programa fonte. (AHO et al., 2008).
É responsabilidade do analisador sintático verificar se a sequência de tokens recebida
do analisador léxico forma um programa válido para a linguagem em questão ou não. Ou seja,
o analisador sintático verifica se a ordem em que os tokens se encontram têm validade. O
analisador sintático é construído tendo como base uma gramática descritiva da linguagem
41
fonte. Tal gramática é constituída por regras que especificam quais são as construções
consideradas válidas na linguagem. Com o conhecimento destas regras, o analisador sintático
aceita os programas que as respeita e rejeita aqueles que as violam. Igualmente, é
responsabilidade do analisador sintático emitir mensagens associadas aos erros sintáticos
encontrados. (DELAMARO, 2004).
2.4.1.3 Análise Semântica
O analisador semântico recebe como entrada a árvore de sintaxe produzida pelo
analisador sintático e verifica o significado do programa fonte em relação as definições da
linguagem. (AHO et al., 2008). É de responsabilidade do analisador semântico procurar por
incoerências como tipos de operandos incompatíveis com operadores, variáveis não
declaradas ou redeclaradas, chamada de funções com número incorreto de parâmetros e
comandos fora do contexto. (DELAMARO, 2004).
Para realizar suas tarefas o analisador semântico utiliza-se das informações contidas na
tabela de símbolos, além da árvore de sintaxe. O analisador semântico também grava
informações referentes aos tipos dos tokens na tabela de símbolos. Essas informações são
utilizadas posteriormente na geração de código. (DELAMARO, 2004; AHO et al., 2008).
2.4.1.4 Geração de Código
O gerador de código recebe como entrada uma representação intermediária do
programa fonte e mapeia as instruções contidas nesta representação para uma ou mais
operações da máquina alvo. Este processo é conhecido como seleção de instruções. (AHO et
al., 2008; DELAMARO, 2004).
Usualmente há um gerador de código distinto para cada plataforma, visto que
diferentes máquinas alvo possuem conjuntos de instruções distintos. (DELAMARO, 2004). O
gerador de código também é responsável por alocar as variáveis utilizadas no programa fonte
nos registradores da máquina alvo de forma apropriada. (AHO et al., 2008).
Aspectos relacionados a otimização também podem fazer parte do processo de geração
de código. Nesta etapa, as otimizações realizadas são dependentes da máquina alvo.
(DELAMARO, 2004; AHO et al., 2008).
42
2.5 SISTEMAS WEB
Essa seção tem como objetivo revisar os conceitos de sistemas web relacionados com
a elaboração e execução deste trabalho.
2.5.1 Arquitetura da Web
No modelo cliente-servidor, um Servidor é um processo que implementa e
disponibiliza um serviço em específico, tais como sistema de arquivos ou sistema de bancos
de dados. Um Cliente é um processo que solicita um serviço para um servidor através de uma
requisição. Após o envio da solicitação, o cliente aguarda por uma resposta do servidor
(TANEMBAUM; STEEN, 2007). Essa interação é conhecida como comportamento de
requisição-resposta e é apresentada na Figura 14.
Figura 14. Comportamento de requisição-resposta.
Fonte: adaptado de Tanembaum; Steein (2007).
Ainda segundo Tanembaum e Steen (2007) muitos dos sistemas baseados na web são
construídos sobre uma arquitetura relativamente simples do tipo cliente-servidor com um
núcleo formado por um processo servidor que possui acesso a um sistema de arquivos no qual
consegue gravar e recuperar documentos.
Geralmente, um cliente interage com um servidor através de um browser (navegador).
Tal comunicação respeita ao protocolo HTTP (HiperText Transfer Protocol – Protocolo de
transferência de Hipertexto), que será revisado na subseção 2.5.2. Basicamente, a aplicação
cliente realiza solicitações HTTP através da interface socket do sistema operacional e recebe a
resposta do servidor através dessa mesma interface. O servidor, por sua vez, recebe
solicitações de clientes através de sua interface socket e, após o processamento da requisição,
envia a resposta pela mesma interface. Ao enviar uma solicitação para a interface socket esta
passa a ser responsabilidade do protocolo TCP (Transmission Control Protocol – Protocolo
de Controle de Transferência), que oferece um serviço confiável de transferência de dados de
43
forma a garantir a entrega da mensagem. Essa interação é ilustrada na Figura 15.
(TANENBAUM; WETHERALL, 2013).
Figura 15. Requisição para obtenção de documento via HTTP.
Fonte: adaptado de Tanembaum; Steein (2007).
A web utiliza a linguagem HTML (HiperText Markup Language – Linguagem de
Marcação de Hipertexto) para expressar páginas web (também conhecidas como documentos)
acessadas e interpretadas pelos navegadores. Documentos ou páginas web são compostos por
objetos, que podem ser textos, áudios, vídeos, etc. Os navegadores interpretam e apresentam o
conteúdo desses documentos ao usuário. Nos casos em que o navegador desconhece
determinado formato de objeto, pode-se utilizar aplicações independentes para realizar essa
tarefa, como por exemplo, plug-ins embutidos no navegador. Um documento expresso em
linguagem HTML pode referenciar outros documentos através de links. Assim, o usuário
pode navegar entre documentos acessando tais links. (TANENBAUM; WETHERALL, 2013;
FOROUZAN, 2006).
Páginas web são identificadas globalmente e localizadas pelas aplicações clientes
através de um URI (Uniform Resource Identifiers – Identificador Uniforme de Recurso), que
é formado por uma sequência de caracteres. Existem diferentes tipos de URIs, sendo que as
regras para a escrita de URIs estão disponíveis na RFC 3986. Geralmente, para a identificação
de objetos na web são utilizados URIs do tipo URL (Uniform Resource Locator –
Identificador Uniforme de Recurso) e URN (Uniform Resource Name – Nome Uniforme de
Recurso). Um URL indica o protocolo utilizado para acessar o documento, o nome DNS
44
(Domain Name System – Sistema de Nomes de Domínio) do servidor onde a página ou objeto
está localizado e um caminho indicando o local onde o documento ou objeto está
efetivamente localizado no servidor. A interpretação deste caminho depende da
implementação feita na aplicação servidora, portanto, nem sempre tal caminho refere-se a
uma estrutura de diretórios física. URNs possuem estrutura semelhante a URLs, porém não
especificam o protocolo para acessar o documento e o nome DNS do servidor. URNs são
úteis em cenários onde se faz necessário identificar um objeto sem especificar o local onde
este está armazenado, como por exemplo, nos casos em que múltiplos servidores armazenam
cópias de um mesmo documento com a finalidade de diminuir o tráfego na rede
(TANENBAUM; WETHERALL, 2013).
Ainda segundo Tanembaum; Wetherall (2013) e Forouzan (2006) a interação
apresentada na Figura 15 representa a busca de um documento estático. Nesse contexto, os
documentos possuem estruturas fixas criadas e armazenadas no servidor. Quando a aplicação
cliente realiza uma solicitação ao servidor, este acessa seu sistema de arquivos e entrega uma
cópia do documento solicitado ao cliente solicitante. O aprimoramento desta arquitetura
permitiu a geração de documentos com conteúdo dinâmico. A geração de conteúdo dinâmico
pode se dar no lado cliente ou no lado servidor.
Uma das primeiras formas de geração de conteúdo dinâmico do lado do servidor foi
através da utilização da tecnologia denominada CGI (Common Gateway Interface – Interface
Comum de Gateway). CGI descreve a forma como um programa armazenado no servidor web
pode ser executado tendo como entrada dados fornecidos pela aplicação cliente e devolvendo
como saída um documento gerado dinamicamente. Aplicações CGI podem ser escritas em
qualquer linguagem de programação que suporte CGI. Uma aplicação CGI pode interagir com
outras aplicações, tais como um servidor de banco de dados.
O mais comum, no entanto, é que servidores web utilizem-se de diferentes linguagens
de programação para realizar a geração de conteúdo dinâmico em detrimento ao CGI.
Linguagens como PHP (PHP: HiperText Processor), JSP (Java Server Pages) e ASP (Active
Server Pages) podem ser citadas como exemplos de linguagens de programação utilizadas no
lado servidor (TANENBAUM; WETHERALL, 2013; TANEMBAUM; STEEN, 2007).
No que se refere a geração de conteúdo dinâmico no lado cliente, é comum a
incorporação de scripts em páginas HTML. Através desses scripts é possível interagir
45
diretamente com o usuário da aplicação. Para atingir este propósito utiliza-se geralmente a
linguagem de programação JavaScript. Alternativamente, pode-se utilizar plug-ins e
aplicações auxiliares, tais como applets Java, para atingir o mesmo propósito.
2.5.2 O Protocolo HTTP
O HTTP é um protocolo de camada de aplicação amplamente utilizado por toda a
WWW (World Wide Web) e especificado no RFC (Request for Comments) 1945 e RFC 2616.
Esse protocolo especifica o formato das interações entre uma aplicação cliente e uma
aplicação servidora. A implementação de tal protocolo acontece em ambos os sistemas finais
de forma independente (sistema cliente e sistema servidor). (TANENBAUM; WETHERALL,
2013; KUROSE, 2010).
Geralmente, a comunicação da aplicação cliente com a aplicação servidora se dá via
uma conexão TCP com a porta 80 do servidor. Esta característica tem a vantagem de abstrair
o tratamento de mensagens perdidas, duplicadas ou longas demais; visto que estes
complicadores são tratados pelo protocolo TCP. Contudo, o protocolo HTTP não possui
estado (stateless). Isto é: após o envio da resposta solicitada pela aplicação cliente, o servidor
esquecerá tal cliente. Não há, por exemplo, conceitos de sessão ou autenticação no protocolo
HTTP. (FOROUZAN, 2006; TANENBAUM, 2003). Essa característica simplifica o projeto
de servidores HTTP. (KUROSE, 2010).
Este modelo de protocolo sem estado não foi mais suficiente quando a web deixou de
ser utilizada apenas para a recuperação de documentos e passou a adquirir outras
funcionalidades. Por exemplo: muitas aplicações passaram a exigir algum tipo de distinção
entre usuários autenticadas e não autenticados. Para contornar esta nova necessidade
desenvolveu-se uma técnica denominada cookie, através da qual cliente e servidor conseguem
persistir e realizar troca de informações via de cabeçalhos específicos. (TANENBAUM;
WETHERALL, 2013; BARTH, 2011)
2.5.2.1 Formato de Mensagens do Protocolo HTTP
As mensagens do protocolo HTTP são compostas unicamente por linhas em texto
ASCII (American Standard Code for Information Interchange – Código Padrão Americano
para o Intercâmbio da Informação). O protocolo HTTP especifica dois tipos de mensagens:
mensagens de requisição e mensagens de resposta. (KUROSE, 2010).
46
Uma mensagem de requisição é formada por uma linha denominada Linha de
Requisição e linhas subsequentes denominadas Linhas de Cabeçalho. A quantidade de linhas
de cabeçalho de uma mensagem de requisição HTTP pode variar de acordo com a finalidade
da requisição em questão. O cabeçalho host, porém, é obrigatório e indica o nome DNS ou
endereço IP (Internet Protocol – Protocolo de Internet) do servidor para o qual a requisição
está sendo encaminhada. O Quadro 2 apresenta um exemplo de mensagem de requisição
HTTP. (KUROSE, 2010; TANENBAUM; WETHERALL, 2013).
Quadro 2. Exemplo de uma mensagem de requisição HTTP.
GET /somedir/page.html HTTP/1.1
Host: www.someschool.edu
Connection: close
User-Agent: Mozilla/4.0
Accept-language: fr
Fonte: adaptado de Kurose (2010).
Conforme o Quadro 2, a primeira linha de uma mensagem de requisição, conhecida
como Linha de Requisição, é composta por um (i) método HTTP, (ii) uma URN e (iii) a
versão utilizada do protocolo. Esses elementos são separados por um espaço em branco. O
método utilizado pela requisição pode assumir diferentes valores. O exemplo do Quadro 2
utiliza o método GET, usado quando a aplicação cliente solicita um objeto ao servidor. O
significado dos métodos HTTP será visto de forma detalhada na subseção 2.5.2.2. A URN
identifica o objeto que está sendo requisito ao servidor pela aplicação cliente. O objeto sendo
requisitado pelo cliente ao servidor no exemplo do Quadro 2 é /somedir/page.html. No
exemplo do Quadro 2 está sendo utilizada a versão 1.1 do protocolo HTTP. (KUROSE, 2010;
TANENBAUM, 2003).
As linhas de cabeçalho utilizadas na requisição possuem informações adicionais sobre
a mesma. Elas podem ser comparadas a parâmetros em uma chamada de procedimento.
Existem cabeçalhos que podem ser utilizados apenas em mensagens de requisição e
cabeçalhos que podem ser utilizados apenas em mensagens de resposta do servidor. Há
também um terceiro grupo de cabeçalhos que podem ser utilizados em ambos os tipos de
mensagem. A Tabela 8 apresenta o significado dos cabeçalhos de requisição utilizados no
exemplo do Quadro 2. (TANENBAUM, 2003).
47
Mensagens de requisição podem ainda conter um corpo de requisição, utilizado pela
aplicação cliente quando há a necessidade de enviar dados ao servidor. Nos casos de
requisições GET o corpo da requisição não é necessário, porém, este é utilizado em
requisições PUT ou POST. O corpo da requisição é separado do restante da mensagem por
uma linha em branco. (KUROSE, 2010).
Tabela 8. Significado das requisições utilizadas no exemplo do Quadro 2
Cabeçalho Descrição
Host O nome DNS do servidor
Connection Indica se a conexão pode ser encerrada ou não após resposta
User-Agent Informações sobre navegador, sistema operacional e outros
Accept-language Indica os idiomas com os quais o cliente pode lidar
As mensagens de resposta enviadas da aplicação servidora para a aplicação cliente é
composta por uma linha de estado (primeira linha da mensagem), linhas de cabeçalho e corpo
da entidade, conforme mostra o exemplo do Quadro 3.
Quadro 3. Exemplo de uma mensagem de resposta HTTP.
HTTP/1.1 200 OK
Connection: close
Date: Sat. 07 Jul 2007 12:00:15 GMT
Server: Apache/1.3.0 (Unix)
Last-Modified: Sun, 6 May 2007 09:23:24 GMT
Content-Length: 6821
Content-Type: text/html
<!DOCTYPE html>
<html>
<body>
<h1>My First Heading</h1>
</body>
</html>
Fonte: adaptado de Kurose (2010).
A linha de estado é formada pela versão do protocolo sendo utilizada, um Código de
Estado e uma mensagem relacionada ao código de estado. Esses elementos são separados por
48
um espaço em branco. A versão da primeira linha de uma mensagem de resposta HTTP (neste
caso, HTTP/1.1) é idêntica e possui o mesmo significado da versão de mensagens de
requisição. O campo Código de Estado consiste em um código de três dígitos que indica o
status da requisição e informa se a mesma foi atendida ou não. O primeiro dígito do código de
estado indica sua categoria e pode variar do valor 1 até o valor 5. O significado de cada
categoria é apresentado na Tabela 9. A mensagem está diretamente relacionada ao código de
estado e apresenta uma mensagem textual correspondente ao estado. (TANENBAUM, 2010).
O exemplo do Quadro 3 utiliza seis linhas de cabeçalho. As linhas de cabeçalho das
mensagens de resposta possuem a mesma função que nas mensagens de requisição: prover
informações adicionais sobre a requisição. As linhas de cabeçalho do Quadro 3 informam, por
exemplo, a data de criação e de última modificação do objeto que está sendo enviado ao
cliente, assim como seu tipo (text/html). Após as linhas de cabeçalho e separado do restante
da mensagem por uma linha em branco encontra-se o corpo da entidade. Nele encontra-se
uma representação do objeto solicitado pelo cliente ao servidor. No Quadro 3 trata-se de um
documento HTML. (KUROSE, 2010).
Tabela 9. Categorias dos códigos de estado HTTP.
Código Significado Exemplo
1xx Informação 100 = server agrees to handle client's request
2xx Sucesso 200 = request succeeded
3xx Redirecionamento 301 = page moved
4xx Erro do cliente 404 = page can not found
5xx Erro do servidor 500 = internal server error
Fonte: Adaptado de Tanenbaum (2003).
2.5.2.2 Métodos HTTP
As mensagens de requisição do protocolo HTTP utilizam-se de elementos
denominados métodos para informar ao servidor a operação que este deve realizar. Portando,
métodos HTTP funcionam como comandos enviados de aplicações clientes para aplicações
servidoras. (FOROUZAN, 2006). O conjunto de métodos HTTP é expansível. A RFC 2616
lista e descreve os métodos OPTINS, GET, HEAD, POST, PUT, DELETE, TRACE e
CONNECT (FIELDING et al., 2009). Já a RFC 5789 estende o conjunto de métodos do
49
protocolo HTTP e descreve o método PATCH (DUSSEAULT; SNELL, 2010). A descrição
de tais métodos é apresentada a seguir:
OPTIONS: consulta as ações disponíveis associadas a um determinado recurso do
servidor identificado pela URI da requisição.
GET: Mensagens de requisição que utilizam o método GET recebem como resposta
uma entidade do servidor no corpo da mensagem. A entidade que deve ser
retornada é identificada pela URI da mensagem.
HEAD: O retorno de uma mensagem de requisição utilizando o método HEAD
deve ser idêntico ao retorno do método GET, porém sem o corpo da mensagem.
Este método é geralmente utilizado para a realização de testes.
POST: Utilizado para solicitar ao servidor que crie uma nova entidade baseando-se
no corpo da mensagem de requisição. Tal entidade deve ser subordinada ao recurso
identificado pela URI da requisição. Caso o resultado da mensagem de requisição
POST seja uma entidade identificável por uma URI a resposta desta deve possuir o
código de estado 201 (Created), a descrição da entidade no corpo da mensagem e o
cabeçalho Location indicando a localização da mesma. Caso contrário, deve-se
utilizar os códigos de estado 200 (OK) ou 204 (No Content).
PUT: Utilizado para solicitar ao servidor que armazene a entidade contida no corpo
da mensagem de requisição sob a URI de tal mensagem. Caso a URI requisitada já
exista no servidor, a representação contida no corpo da mensagem será considerada
uma atualização da mesma e a mensagem de resposta conterá o código de estado
200 (OK) ou 204 (No Content). Nos casos em que a URI da requisição não está
relacionada com nenhum recurso existente, o servidor tentará criar um novo recurso
associado a esta e retornara com o código de estado 201 (Created). A principal
diferença entre os métodos PUT e POST está no significado da URI da requisição.
PATCH: Semelhante ao PUT, porém realiza uma atualização parcial da entidade
especificada pela URI da requisição. Enquanto requisições PUT possuem no corpo
da mensagem uma versão modificada da entidade já existente no servidor, no
método PATCH o corpo da mensagem possui uma série de instruções descrevendo
50
como o recurso já existente no servidor deve ser modificado. O método PATH é
especificado na RFC 5789 (DUSSEAULT, L.; SNELL, 2010).
DELETE: Utilizado para solicitar ao servidor que remova o recurso identificado
pela URI da requisição. A resposta de uma requisição DELETE pode conter os
códigos de estado 200 (OK), 202 (Accepted) ou 204 (No Content).
TRACE: Utilizado para a realização de testes. Ele devolve ao cliente a mesma
requisição que foi enviada. Assim, a aplicação cliente pode verificar se existiram
mudanças feitas por servidores intermediários. O método TRACE permite ao
cliente saber o que está sendo entregue efetivamente ao servidor.
CONNECT: Método reservado para uso futuro.
Além dos citados, existem outros métodos HTTP de uso menos comum descritos em
diferentes RFCs, como por exemplo, os métodos LINK e UNLINK, descritos em Nottinghan
(2010). Alguns métodos HTTP são considerados seguros, no sentido de que a sua utilização
não resulta em modificações de recursos ou entidades no servidor. Semanticamente, os
métodos GET e HEAD são considerados seguros, por exemplo. Métodos HTTP também
podem ser idempotentes. Isso significa que o resultado de inúmeras requisições para uma
mesma URI é sempre igual. Os métodos GET, HEAD, PUT e DELETE possuem esta
propriedade. Porém, essas propriedades não podem ser garantidas, visto que as mesmas
dependem da implementação feita pelo programador da aplicação servidora. (FIELDING et
al., 2009).
2.5.3 Serviços Web
Coulouris (2013, p. 381) afirma que “um serviço web (web service) fornece uma
interface de serviço que permite aos clientes interagirem com servidores de uma maneira mais
geral do que acontece com os navegadores web”. Tanembaum e Steen (2007) complementam
afirmando que serviços web oferecem serviços gerais para aplicações remotas (tais como
serviço de nomeação ou previsão do tempo) sem a interação direta com o usuário final.
A interface de um serviço web oferece um conjunto de operações passíveis de serem
utilizadas por aplicações clientes. Devido a generalidade dos mesmos, serviços web não são
acessíveis diretamente via navegador. (COULOURIS, 2013; TANEMBAUM; STEEN, 2007).
51
Dentre outros, o estilo arquitetural REST (Representational State Transfer – Transferência de
Estado Representacional) é largamente utilizado como estratégia para a disponibilização de
serviços web. A estratégia REST será revisada na subseção 2.5.4.
Ainda segundo Coulouris (2013) muitos dos servidores web comerciais conhecidos
(Amazon, Yahoo, Google, etc.) disponibilizam interfaces com operações pelas quais seus
clientes podem manipular determinados recursos. Essa característica dos serviços web permite
que operações de diferentes interfaces possam ser combinadas e assim um novo serviço seja
gerado a partir da combinação de outros. Serviços web também auxiliam na obtenção de um
baixo acoplamento entre serviços. Nesse contexto, baixo acoplamento caracteriza-se pela
minimização da dependência entre serviços, resultando em uma arquitetura subjacente
flexível e evitando que a alteração em um serviço cause uma reação em cadeia de alterações
em outros serviços.
2.5.4 REST
REST é um estilo arquitetural híbrido para sistemas distribuídos de hipermídia,
derivado de outros estilos arquiteturais baseados em rede e combinado com restrições
adicionais. (FIELDING, 2000). Fielding (2010) define o estilo arquitetura REST através da
adição dessas restrições partindo de um estado nulo definido inicialmente. Doglio (2015)
descreve tais restrições conforme segue:
Client-Server (cliente-servidor): A primeira restrição adicionada por Fielding
(2000) ao estilo arquitetural REST é também uma das mais comum em arquiteturas
baseadas em rede. A separação dos conceitos interface com o usuário (front-end) e
armazenamento de dados ou processamento (back-end) permite a portabilidade da
interface sobre diferentes plataformas, assim como auxilia na escalabilidade do
sistema. Igualmente, essa separação de conceitos permite a evolução independente
do back-end e do front-end.
Stateless (Sem estado): Essa restrição descreve que a comunicação entre cliente e
servidor não deve possuir estrado. Ou seja: as requisições feitas da aplicação cliente
deve conter toda a informação necessária para a sua compreensão pelo servidor,
sem a necessidade de utilizar-se de qualquer tipo de dado armazenado.
52
Cache: A restrição cache determina que toda a resposta enviada para a aplicação
cliente seja implícita ou explicitamente rotulada como passível ou não-passível de
cache. Através do uso desta restrição a aplicação cliente pode eliminar parcialmente
ou completamente algumas das interações com o servidor, resultado em uma
melhora na eficiência da rede, escalabilidade e performance percebida pelo usuário.
O ponto negativo do uso desta restrição está no fato de que o dado em cache na
aplicação cliente pode ter se tornado obsoleto. O uso desta restrição depende do
tipo de sistema que está sendo implementado.
Uniform Interface (Interface uniforme): Através da definição de uma interface
uniforme entre os componentes do sistema, a arquitetura como um todo é
simplificada. A definição de uma interface padrão e uniforme através de um
conjunto de regras para seguir ajuda a manter a implementação das aplicações
clientes independentes.
Layered System (Sistema em camadas): Esta restrição procura separar os
componentes do sistema em camadas, de tal forma que cada uma dessas camadas
consiga utilizar-se dos serviços da camada abaixo e enviar sua saída para a camada
acima.
Code-on-Demand (Código sob demanda): O estilo arquitetural REST diz que
clientes podem fazer download e executar código de applets ou scripts do servidor.
Código sob demanda simplifica a implementação de clientes de servidores REST,
visto que o download de funcionalidades diminui a complexidade da
implementação de tais clientes. Código sob demanda é a única restrição opcional
imposta pele estilo arquitetural REST.
2.5.4.1 Recursos e Identificadores de Recursos
O ponto central do estilo arquitetural REST está em um conceito denominado resource
(recurso). Recursos são abstrações da informação em sistemas REST. Qualquer informação
que pode ser nomeada pode ser um recurso dentro de um sistema REST. São exemplos:
documentos, imagens, serviços de previsão do tempo, coleções de outros recursos, etc.
(FIELDING, 2000; DOGLIO, 2015).
53
Sistemas REST utilizam-se de resource indentifiers (identificadores de recurso) para
identificar recursos de forma única. Segundo Doglio (2015) um identificador de recurso deve
garantir a identificação de um recurso de forma única, assim como fornecer um caminho
completo para a localização de tal recurso. Pelo fato de sistemas REST serem geralmente
construídos sobre o protocolo HTTP, a forma mais comum de identificar unicamente um
recurso é através de uma URI.
2.5.4.2 Representações de Recursos
A representação de um recurso é formada por um conjunto de bytes somado a
metadados que descrevem tal conjunto de bytes. Um único recurso pode possuir mais de uma
representação. Na prática isso significa que mais de um formato pode ser utilizado para
representar um único recurso de um sistema REST, tais como: JSON (JavaScript Object
Notation – Notação de Objeto JavaScript), XML ou valores separados por vírgula.
(FIELDING, 2000; DOGLIO, 2015).
Para solicitar uma representação específica de um recurso que possui mais de uma
representação, a aplicação cliente pode utilizar-se do princípio denominado negociação de
conteúdo, parte integrante do protocolo HTTP. Nesse caso, a aplicação cliente deve incluir na
mensagem de requisição o cabeçalho Accept especificando os formatos desejados junto a um
indicador opcional referente a preferência que tem por cada formato. No exemplo do Quadro
4 o formato text/html possuir maior preferência por parte da aplicação cliente em relação a
outros formatos (q=1.0). (DOGLIO, 2015).
Quadro 4. Exemplo de cabeçalho Accept utilizado na negociação de conteúdo com o servidor.
Accept: text/html; q=1.0, text/*; q=0.8, image/gif; q=0.6, image/jpeg;
q=0.6, image/*; q=0.5, */*; q=0.1
Fonte: Adaptado de Doglio (2015).
Ainda segundo Doglio (2015), alternativamente, a extensão da representação desejada
pode ser adicionada ao identificador do recurso. Esta abordagem, apesar de mais fácil de ser
implementada e compreendida, não possui a flexibilidade oferecida pela negociação de
conteúdo. O exemplo do Quadro 5 apresenta o mesmo recurso sendo solicitado em duas
representações distintas.
54
Quadro 5. Requisição do mesmo recurso com diferentes representações.
GET /api/v1/books.json
GET /api/v1/books.xml
Fonte: Adaptado de Doglio (2015).
2.5.4.3 Ações em sistemas REST
O protocolo HTTP possui um conjunto de métodos que podem ser mapeados em ações
corriqueiramente realizadas sobre recursos em sistemas REST. Tais ações são conhecidas
como ações CRUD e formam um conjunto de quatro ações: Create, Retrieve, Update e
Delete. O estilo arquitetural REST, no entanto, não impõe nenhum formato rígido
padronizado de realizar este mapeamento. A Tabela 10 apresenta a relação entre os métodos
HTTP e a ação proposta para cada um em sistemas REST. O conteúdo da Tabela 10 pode ser
visto como uma padronização desenvolvida pela comunidade de desenvolvedores de sistemas
REST ao longo dos anos. As ações implementadas por clientes de sistemas REST dependem
do propósito do cliente em questão. Portanto, não há obrigatoriedade em implementar todos
os métodos disponíveis para um determinado recurso.
Os métodos HEAD e OPTIONS não compõem o conjunto de métodos geralmente
mapeados para ações CRUD em sistemas REST, porém são largamente utilizados nesses
sistemas com outras finalidades.
Tabela 10. Métodos HTTP e ações propostas em sistemas REST.
Método HTTP Ação Proposta
GET Acessar um recurso em modo somente leitura (Ação Retrieve).
POST Usado para usar um novo recurso (Ação Create).
PUT Usado para atualizar um recurso (Ação Update).
DELETE Usado para excluir um recurso (Ação Delete).
HEAD Usado para “perguntar” se um recurso existe sem retornar nenhuma representação.
OPTIONS Usado para retornar uma lista de ações possíveis sobre um determinado recurso.
Fonte: Adaptado de Doglio (2015).
55
3 DESENVOLVIMENTO
O objetivo deste capítulo é apresentar o sistema desenvolvido neste trabalho de
conclusão de curso. A seguir, é apresentado o desenvolvimento da aplicação servidora e de
seus principais componentes, dentre eles: compilador Portugol, compilador assembly e API1
(Application Programming Interface – Interface de Programação de Aplicação) REST.
Igualmente, é apresentado o desenvolvimento da aplicação cliente e dos módulos de edição de
programa, simulação e ajuda presentes na mesma. Ao final do capítulo é apresentada a
validação da ferramenta.
3.1 IMPLEMENTAÇÃO
O Bipide Web foi implementado na forma de um sistema web, respeitando a
arquitetura cliente-servidor e o protocolo de comunicação HTTP. Assim, considerando termos
mais generalizados, tal sistema é composto por uma aplicação front-end e uma aplicação
back-end. Cada uma destas aplicações possui responsabilidades bem definidas de modo que
as mesmas sejam totalmente desacopláveis. A independência entre a aplicação cliente e a
aplicação servidora desenvolvidas neste trabalho permite que as funcionalidades de criação de
conta, autenticação, criação e compilação de programas providas pela aplicação servidora
sejam reaproveitadas em trabalhos futuros.
O diagrama de componentes presente na Figura 16 apresenta uma visão geral do
sistema desenvolvido, onde visualiza-se os componentes que fazem parte da aplicação
servidora, assim como a comunicação desta com a aplicação cliente através do protocolo
HTTP. O desenvolvimento da aplicação servidor, aplicação cliente e seus respectivos
componentes serão detalhados nas seções a seguir.
1 Application Programming Interfaces são utilizadas por aplicações clientes para comunicarem-se com
web services. Uma API expõe um conjunto de dados e informações de forma a facilitar a troca de informações
entre cliente e servidor. Uma API em conformidade com o estilo arquitetural REST é dita uma API REST.
(MASSE, 2011).
56
Figura 16: Diagrama de componentes do Bipide Web.
3.2 IMPLEMENTAÇÃO DA APLICAÇÃO SERVIDORA
A aplicação servidora (server-side) do Bipide Web foi desenvolvida através da
utilização de tecnologias Java. A escolha da plataforma Java como tecnologia central do
server-side do Bipide Web deu-se pelo fato desta ser uma tecnologia open-source e
multiplataforma. Igualmente, tal escolha considerou o fato de que vários artefatos de software
produzidos em outros trabalhos e várias das ferramentas das quais se fez uso neste projeto
foram construídas sobre esta mesma plataforma, como é o caso do Núcleo do Portugol e do
ANTLR (ANother Tool for Language Recognition). Assim, o uso da plataforma Java proveu
uma melhor aderência dessas ferramentas ao projeto.
É de responsabilidade do server-side do Bipide Web: (i) permitir que a aplicação
cliente crie novos cadastros de usuários, (ii) permitir que usuários se autentiquem no sistema
através do fornecimento de credenciais, (iii) permitir a criação, (iv) recuperação e (v)
compilação de programas escritos em linguagem Portugol e assembly dos processadores da
família BIP. A manipulação destes recursos pela aplicação cliente dá-se através de uma API
57
REST, conforme é apresentado na Figura 16, a qual é detalhada na subseção 3.2.3 deste
trabalho.
3.2.1 Entidades da Aplicação Servidora
A Figura 17 apresenta o diagrama de classes das entidades presentes no sistema
server-side do Bipide Web. Nessa figura, verifica-se que o sistema é composto basicamente
por três entidades principais. A saber: (i) User, (ii) Program e (iii) Token. Há ainda uma
classe abstrata denominada BaseModel, a qual é utilizada como forma de concentrar algumas
propriedades comuns entre as classes User e Program, assim como alguns métodos internos
comuns a estas entidades. Esses métodos não estão presentes no diagrama da Figura 17 a fim
de favorecer sua clareza.
Figura 17: Diagrama de Classes das Entidades do Bipide Web.
58
A seguir, é feita uma descrição de cada uma das entidades do diagrama de classes da
Figura 17.
User: Representa um usuário do sistema. Possui as propriedades name, email e
password. As propriedades email e password formam as credenciais utilizadas pelo
usuário para autenticar-se no sistema. Por consequência, a propriedade email possui
restrição de unicidade por usuário. Assim, não podem existir no sistema dois
usuários com um mesmo endereço de e-mail. Conforme apresentado na Figura 17,
um usuário pode possuir zero ou inúmeros programas.
Program: Representa um programa criado por um usuário. Esta entidade possui as
propriedades: (i) name, que armazena o nome do programa dado pelo usuário; (ii)
source, que armazena o código-fonte do programa em Portugol ou assembly; (iii)
language, que armazena o valor “portugol” ou “assembly”, identificando o nome da
linguagem de programação utilizada na criação do programa e (iv) compiled,
responsável por armazenar o resultado da compilação em formato JSON fornecido
pelos compiladores assembly e Portugol. Tal formato é utilizado pela aplicação
cliente e interpretado pelo módulo de simulação de execução. A documentação do
formato esperado pelo simulador e que deve ser fornecido pelos compiladores
encontra-se no Apêndice B.
Token: Representa um token utilizado pela aplicação cliente para fins de
autenticação. Ao autenticar-se com sucesso no servidor através da API REST, o
usuário recebe como resposta um token que deve ser inserido em requisições
posteriores, em um cabeçalho apropriado. Assim, em todas as requisições
realizadas pela aplicação cliente que tentam acessar recursos privados do servidor,
o token da requisição é validado para garantir a autenticidade do requisitante e para
verificar se o requisitante, quando devidamente autenticado, possui autorização
para acessar o recurso solicitado.
A subseção 3.2.3 descreve a forma como as entidades listadas acima podem ser
manipuladas pela aplicação cliente.
59
3.2.2 Implementação dos Compiladores
A versão web do Ambiente de Desenvolvimento Integrado Bipide possui dois
compiladores: um compilador para a linguagem Portugol e outro para a linguagem de
montagem dos processadores da família BIP. Ambos os compiladores Portugol e assembly,
conforme o diagrama de classes da Figura 18, implementam uma interface de nome Compiler,
a qual possui apenas um método, denominado compile. Este método recebe como parâmetro
uma string representando o programa fonte da linguagem de programação em questão e dá
como retorno uma estrutura no formato JSON, representando o resultado da compilação em
linguagem de montagem dos processadores BIP. Tal estrutura contém toda a informação
necessária ao simulador de execução da aplicação cliente e deve obedecer ao formato
especificado no Apêndice B, conforme já citado anteriormente.
Figura 18: Diagrama de classes dos compiladores do Bipide Web.
De forma simplificada, a estrutura JSON retornada pelo método compile da interface
Compiler deve conter as seguintes propriedades, conforme listado na Tabela 11.
60
Tabela 11: Propriedades do JSON retornado pelo método compile da interface Compiler.
Propriedade Descrição
assembly Representação em texto simples do resultado da compilação.
dataMemoryDisposition Representação da memória de dados após alocação das variáveis
declaradas. Esta representação é atualizada pela aplicação cliente durante a
simulação.
instructions Lista de objetos representando instruções a serem simuladas pela aplicação
cliente. Cada um dos objetos desta lista possui informações como opCode
da instrução, operando, endereço de memória do operando, dentre outros.
minBipVersion Indica a versão mínima do BIP capaz de executar o algoritmo em questão.
Pode conter os valores 1 (BIP I), 2 (BIP II), 3 BIP (III), 4 BIP (IV) e 5
(µBIP).
errors Lista de erros de compilação, quando existirem.
warnings Lista de avisos de compilação, quando existirem.
A definição de um padrão de saída a ser respeitado pelos compiladores da aplicação
servidora do Bipide Web é, dentro do contexto do desenvolvimento deste trabalho, de extrema
importância, visto que tal formato facilitará a integração de outros compiladores na aplicação,
desde que estes respeitem o formato especificado.
Para construir suas saídas no formato padronizado neste trabalho, tanto o compilador
Portugol quanto o compilador assembly utilizam-se de uma estrutura de classes. Essas classes
são apresentadas no diagrama da Figura 19.
61
Figura 19: Classes utilizadas pelos compiladores assembly e Portugol.
Dentre as classes presentes no diagrama da Figura 19, destaca-se a classe denominada
BIPProgram. Uma instância da classe BIPProgram representa o programa sendo construído
em linguagem alvo durante o processo de compilação. Instancias dessa classe possuem alguns
métodos que são utilizados durante o processo de construção do programa em linguagem alvo
(no caso, em linguagem de montagem dos processadores BIP).
Assim, ao iniciar um novo processo de compilação, tanto o compilador da linguagem
Portugol quanto o compilador assembly criam uma nova instância da classe BIPProgram e a
manipulam até a finalização do processo de tradução ou até que um erro de compilação seja
encontrado. Logo, caso durante o processo de tradução da linguagem fonte para a linguagem
alvo surja a necessidade de declarar uma nova instrução o compilador em questão deve criar
uma instância da classe BIPInstruction, preencher suas propriedades (instruction, operand,
opCode, etc.) e passar tal instância como parâmetro na chamada do método addInstruction da
instância de BIPProgram que está em memória. O mesmo acontece, por exemplo, para
declarações de variáveis e rótulos.
62
Por fim, ao terminar o processo de tradução da linguagem fonte para a linguagem alvo
o método toJSON presente na instância da classe BIProgram é chamado. Esse método tem a
função de transformar a instância de BIPProgram sendo manipulada pelo compilador em
questão em um JSON no formato apresentado na Tabela 11 e detalhado no Apêndice B.
3.2.2.1 Compilador Portugol
O compilador da linguagem de programação Portugol presente no back-end da
aplicação tem a função de traduzir algoritmos escritos em tal linguagem para um equivalente
em linguagem de montagem dos processadores da família BIP, obedecendo o padrão
especificado.
O processo de desenvolvimento do Compilador Portugol seguiu a mesma estratégia
adotada por Mannes (2013), onde utilizou-se o Portugol Core, núcleo do Portugol 2.0, com a
finalidade de aproveitar a representação intermediária gerada por tal núcleo no formato de
uma ASA. Uma Árvore Sintática Abstrata é uma representação hierárquica do programa
escrito em alto nível (neste caso, linguagem Portugol), contendo toda a informação necessária
para a tradução do programa para outra linguagem. (MANNES, 2013).
Conforme já documentado em Mannes (2013), o núcleo do Portugol 2.0 utilizado para
a construção do compilador Portugol utiliza-se dos padrões de projeto Composite e Visitor
como forma de facilitar a geração da ASA e a geração de código, respectivamente. O padrão
de projeto Composite é utilizado para realizar a geração da estrutura de ASA. Através da
utilização desse padrão o código fonte em linguagem Portugol é transformado em uma
estrutura hierárquica em forma de árvore. O padrão Visitor, por sua vez, é utilizado para
percorrer a estrutura de árvore gerada através do padrão Composite.
Dessa forma, a implementação do compilador para a linguagem Portugol baseou-se na
criação de um novo visitante, capaz de percorrer a estrutura de ASA gerada pelo Portugol
Core a partir de um algoritmo em Portugol e traduzir esta estrutura em um programa
equivalente em linguagem de montagem dos processadores BIP. A possibilidade de
reutilização do visitante implementado por Mannes (2013) foi descartada devido ao fato de
que essa implementação foi feita em linguagem C# e integrada ao núcleo do Portugol (que é
escrito em Java) através de uma integração via CORBA. A implementação de um novo
visitante escrito diretamente em linguagem Java eliminou a necessidade da integração com o
63
Portugol Core via CORBA, assim como tornou o compilador independente de plataforma,
visto que a plataforma Java possui implementações para diferentes sistemas operacionais.
Devido a utilização da ASA do Portugol Core, a sintaxe do Portugol utilizada pelo
Bipide Web é a do Portugol 2.0, assim como no Bipide 4.0.
Conforme apresentado na Figura 20, a criação da classe visitante do compilador
Portugol do Bipide Web deu-se através da criação de uma classe denominada Translator que
implementa os métodos da interface VisitanteASA, parte integrante do Portugol Core. A
interface VisitanteASA do Portugol Core possui métodos específicos para realizar o
tratamento de cada um dos tipos de nós possíveis gerados durante a transformação do
programa fonte em Árvore Sintática Abstrata. Na Figura 20 estão explicitados na interface
VisitanteASA métodos responsáveis pelo tratamento de chamada de função, declaração de
função e declaração de variável. Porém, tal interface exige a implementação de vários outros
métodos responsáveis pelo tratamento de outros tipos de nós da Árvore Sintática Abstrata do
Portugol Core, sendo que estes foram suprimidos na Figura 20.
Figura 20: Diagrama de classe do visitante do compilador Portugol.
Ainda segundo a Figura 20, a classe Translator, além de implementar todos os
métodos da interface VisitanteASA, possui seu próprio construtor e um método denominado
translate. A string recebida pelo construtor da classe Translator representa o programa escrito
64
em linguagem Portugol e que será traduzido para o assembly dos processadores BIP. O
algoritmo recebido pelo construtor da classe Translator é armazenado em memória. Já o
método translate presente na classe Translator é o responsável por tentar realizar a tradução
do programa fonte recebido no construtor em um algoritmo equivalente em linguagem de
montagem dos processadores da família BIP.
A Figura 21 apresenta a sequência de passos executada pelo método translate da
classe Translator. Incialmente, é criada e armazenada em memória uma instância da classe
BIPProgram, já apresentada na Figura 19. Após, tal método solicita a geração da Árvore
Sintática Abstrata ao Portugol Core. Caso o Portugol Core encontre erros durante o processo
de geração da ASA do programa fonte, tais erros são atribuídos na instância da classe
BIPProgram. Logo, a classe BIPProgram é convertida para uma representação em string que
obedece ao formato da Tabela 11 e é retornada pelo método.
Figura 21: Método translate da classe Translator
Caso não ocorra nenhum erro durante a conversão do programa de entrada em ASA, é
verificada a existência de avisos gerados pelo Portugol Core. Caso existam, estes são
atribuídos na instância vigente de BIPProgram. Após a verificação de avisos, a classe
Translator passa a visitar cada um dos nós da ASA gerada pelo Portugol Core, invocando o
método apropriado em cada passo, de acordo com o tipo de nó sendo visitado. Enquanto
percorre a ASA gerada pelo Portugol Core, a classe Translator manipula a instância vigente
de BIPProgram, chamado os métodos presentes nesta classe conforme a necessidade. Assim,
ao terminar de percorrer a ASA, tem-se na instância da classe BIPProgram o conjunto de
65
instruções e declarações de variáveis em linguagem de montagem dos processadores da
família BIP equivalente ao programa de entrada em linguagem Portugol.
Após percorrer a ASA e gerar o programa em assembly, o método translate percorre
as instruções geradas com a finalidade de realizar a alocação de memória das instruções,
declarações de variáveis e tradução dos labels em endereços de memória. Por último, toda
essa estrutura é convertida em uma string formatada segundo a Tabela 11 e retornada pelo
método translate.
3.2.2.2 Compilador Assembly
A função do compilador assembly presente no back-end da aplicação é a de garantir
que os programas escritos em linguagem de montagem dos processadores da família BIP
estejam corretos léxica, sintática e semanticamente. Nesse compilador, a linguagem fonte e a
linguagem alvo são exatamente as mesmas (assembly dos processadores BIP). Assim, não é
realizado nenhum processo de tradução do programa fonte, conforme acontece no compilador
Portugol.
A implementação do compilador assembly foi feita através da utilização da ferramenta
ANTLR em sua versão 3.5.2 (ANTLR, 2016). A gramática do ANTLR utilizada no
compilador assembly da versão 4.0 da IDE Bipide foi reaproveitada neste trabalho. Fez-se
necessário realizar algumas modificações nesta gramática de forma a viabilizar a sua
utilização sobre a plataforma Java e prover algumas melhoras.
A principal alteração realizada na gramática do compilador assembly do Bipide 4.0 diz
respeito a criação de alguns métodos nativos em linguagem Java na seção members da
definição da gramática. Os métodos dentro na seção members de uma definição de gramática
do ANTLR são automaticamente inseridos no Parser gerado pela ferramenta e podem ser
utilizados pelo restante da definição da gramática, em suas produções. Na versão anterior do
compilador assembly tais métodos estavam presentes em uma Partial Class, recurso este que
está presente exclusivamente na linguagem C#. A Partial Class em questão era utilizada em
conjunto com o Parser gerado pelo ANTLR.
66
Quadro 6: Métodos adicionados na seção members da gramática.
@members{
public void setEscopoErro(String escopoErro) {}
public void limpaEscopoErro() {}
public void addVariavel(String nome, String valor, int linha, int coluna) {}
public void setTipoOperando(String tipo) {}
public void addInstrucao(String instrucao, String operando, int linhaInstrucao,
int colunaInstrucao, int linhaOperando, int colunaOperando) {}
public void addRotulo(String rotulo, int linha, int coluna) {}
public void fimDeclaracao() {}
public void verificarLabels() {}
}
O Quadro 6 apresenta o trecho da gramática do ANTLR onde foram adicionados os
métodos extraídos da Partial Class presente na versão anterior do compilador. Conforme
pode ser visto, tais métodos não possuem implementação. Desta forma, o Parser gerado pelo
ANTLR foi estendido e os métodos sem implementação foram sobrescritos, dando-lhes a
implementação necessária. Os métodos adicionados na seção members da gramática do
compilador assembly são utilizados em vários momentos nas produções do ANTLR,
conforme pode ser visto na gramática completa, apresentada no Apêndice A.
Na Figura 22 é apresentado o fluxo utilizado na criação do parser e do analisador
léxico do compilador assembly dos processadores BIP. Primeiramente, foram feitas as
alterações necessárias na gramática. Após, o arquivo BIPASM.g contendo a definição da
gramática foi processado pelo ANTLR, gerando como saída as classes BIPASMParser.java e
BIPASMLexer.java.
Figura 22: Criação do parser e analisador léxico.
67
Após a geração das classes BIPASMParser.java e BIPASMLexer.java pelo ANTLR,
foi criada a classe ParserImp.java, que estende da classe BIPASMParser.java e sobrescreve
seus métodos públicos, conforme mostrado na Figura 23. Os métodos públicos sobrescritos
são os apresentados no Quadro 6.
Figura 23: ParserImp estendendo BIPASMParser
Assim como o compilador da linguagem Portugol, o compilador assembly também se
utiliza da estrutura de classes apresentada na Figura 19 para construir sua saída no formato
padronizado por este trabalho. Sendo assim, a classe ParserImp.java também manipula uma
instância da classe BIPProgram.
3.2.3 API REST
A API REST presente na aplicação servidora do Bipide Web tem a função de prover
uma interface entre os recursos do server-side e a aplicação cliente, de forma que esta última
consiga manipular tais recursos através das requisições HTTP adequadas.
A implementação da API REST do Bipide deu-se através da utilização do framework
Jersey. Jersey é a implementação de referência do padrão Java API for RESTful Services
(JAX-RS), a qual descreve uma maneira padronizada e simples de criar Web Services
68
RESTful sobre a plataforma Java. O padrão JAX-RS, por sua vez, é especificado na JSR
(Java Specification Requests) 311 e na JSR 339 (JERSEY, 2016; PROJECT KENAI, 2016).
Através da utilização do framework Jersey foi possível definir o conjunto de rotas e
métodos que a API REST do Bipide Web disponibiliza para a manipulação de recursos por
parte das aplicações clientes.
Tabela 12: Recursos e rotas da API do Bipide Web.
Operação Requer
autenticação
Descrição
Token: Recurso que representa um token de autenticação, utilizado quando necessário em cabeçalhos de outras
requisições e criado com base nas credenciais do usuário.
POST /auth Não
Cria uma nova entidade do tipo token.
DELETE /auth/{token}
Não Invalida um determinado token, onde
{token} identifica o recurso a ser
invalidado.
User: Recurso que representa um usuário do sistema.
POST /users Não Cria uma nova entidade do tipo user de
acordo com o corpo da requisição.
PUT /user/{user_id}
Sim Atualiza uma entidade do tipo user
identificada por {user_id} de acordo
com o corpo da requisição.
DELETE /user/{user_id} Sim Remove a entidade do tipo user
identificada por {user_id}.
GET /user/{user_id} Sim Retorna a representação de um usuário
identificado por {user_id}
Program: Recurso que representa um programa compilado pelo usuário.
POST /programs Sim Cria um programa e associa ao usuário
autenticado.
PUT /{program_id} Sim Altera o programa identificado por
{program_id}.
GET /programs Sim Retorna a lista de programas associados
ao usuário autenticado.
PUT /programs/{program_id}/compile Sim Compila um programa, identificado por
{program_id}.
A Tabela 12 lista o conjunto de recursos expostos pela API REST do Bipide Web,
assim como as operações que podem ser realizadas sobre esses recursos através de requisições
HTTP. Uma documentação mais completa da API REST do Bipide Web pode ser encontrada
no Apêndice C.
É importante salientar que algumas das operações descritas de forma resumida na
Tabela 12 necessitam de algum nível de segurança no que diz respeito ao acesso a alguns
69
recursos. Dentro deste contexto, com a finalidade de garantir o acesso a determinados dados e
funcionalidades apenas a usuários autenticados, a aplicação cliente deverá solicitar a
aplicação servidora a criação de um token de autenticação. Para tal, a aplicação cliente deverá
fornecer credenciais de usuário válidas para a aplicação servidora. O token recebido como
resposta deverá ser inserido ao cabeçalho HTTP Authorization nas requisições seguintes.
Além das responsabilidades citadas anteriormente, também ficará a cargo do sistema
REST fazer o intermédio entre a aplicação cliente e o processo de compilação. Este
intermédio se dará através da comunicação do sistema em si com componentes compiladores.
Sendo assim, sempre que receber uma solicitação de compilação, a API REST deverá invocar
o compilador adequado.
3.3 IMPLEMENTAÇÃO DA APLICAÇÃO CLIENTE
A aplicação cliente do Bipide Web foi desenvolvido na forma de uma aplicação web,
utilizando as tecnologias HTML, CSS (Cascading Style Sheets) e JavaScript. Desta forma, o
funcionamento de tal aplicação ocorre através de um navegador. O client-side do Bipide é
composto por três módulos principais. São eles: (i) módulo de edição de programas, (ii)
módulo de simulação e (iii) módulo de ajuda. Esses módulos serão apresentados em detalhes
nas seções seguintes. Além do desenvolvimento dos módulos citados, fez-se necessária a
criação de interfaces para que novos usuários consigam cadastrar-se, assim como realizar
login na aplicação.
Durante o desenvolvimento da aplicação cliente do Bipide Web foram utilizadas
diferentes bibliotecas JavaScript como forma de facilitar determinadas implementações.
Dentre as bibliotecas utilizadas destaca-se a biblioteca JavaScript AngularJS, desenvolvida
pela empresa Google e mantida sob licença open-source. AngularJS pode ser descrito como
um framework JavaScript que permite ao programador estender as funcionalidades da
linguagem de marcação HTML. Além disso, AngularJS possibilita ao programador o
desenvolvimento de aplicações front-end organizadas em camadas, seguindo o padrão de
projeto MVC (Model View Controller). (GREEN; SESHADRI, 2016; ANGULARJS, 2016).
No que diz respeito aos componentes visuais utilizados no front-end do Bipide Web,
este trabalho utilizou a biblioteca de componentes visuais Angular Material, também
desenvolvida pela empresa Google e também mantida sob licença open-source. Angular
Material é também a implementação de referência da especificação Google Material Design.
70
Tal especificação tem como objetivo desenvolver uma linguagem visual respeitando
princípios clássicos do desing, assim como prover uma experiência unificada em diferentes
dispositivos. (GOOGLE, 2016a; Google, 2016b).
3.3.1 Módulo de edição de programas
O módulo de edição de programas do Bipide Web permite ao usuário autenticado
criar, editar e compilar programas escritos em linguagem Portugol e assembly dos
processadores da família BIP.
Conforme pode ser visto na Figura 24, a interface do módulo de edição de programas
é composta por: (i) uma listagem dos programas previamente criados pelo usuário separados
nas categorias Portugol e Assembly; (ii) uma barra de ferramentas contendo um conjunto de
botões de ações; (iii) um editor de código-fonte com destaque de sintaxe e (iv) um painel de
saída onde é apresentado ao usuário mensagens, erros e avisos gerados durante o processo de
compilação.
Figura 24: Módulo de edição de programa do Bipide Web.
A barra de ferramentas localizada acima do editor de código-fonte apresenta, além dos
botões de ação localizados na extrema direita, o nome do programa sendo editado atualmente
na extrema esquerda. Ao lado do nome do programa existem botões de ação para renomear tal
programa e excluí-lo da listagem de programas do usuário. Os botões de ação localizados no
lado direito da barra de ferramentas executam as ações: Criar novo programa, Salvar o
programa atual, Desfazer a última ação, Refazer a última ação desfeita, Copiar, Recortar e
71
Colar. Ao posicionar o mouse sobre algum botão, pode-se visualizar o nome da ação realizada
pelo mesmo na forma de uma mensagem de ajuda.
O editor de código-fonte possui destaque da sintaxe de acordo com a linguagem de
programação utilizada. A Figura 24 apresenta um exemplo de edição de código em linguagem
Portugol. Logo, o destaque de sintaxe acontece de acordo com tal linguagem, colorindo de
forma diferenciada palavras reservadas da linguagem, números inteiros, nomes de funções
especiais e comentários. Caso o usuário selecione um programa escrito em linguagem
assembly o destaque de sintaxe do editor de textos passará a considerar tal linguagem,
destacando instruções, registradores e rótulos.
O painel de saída apresenta a lista de erros e avisos de compilação gerados durante o
processo de compilação. Além da mensagem de erro, é apresentado ao usuário a linha e a
coluna correspondente ao erro ou aviso. Erros são destacados em vermelho, enquanto avisos
são destacados em amarelo. Nos casos em que o processo de compilação é finalizado com
sucesso, uma mensagem é apresentada ao usuário, da forma como consta no exemplo da
Figura 24.
3.3.2 Módulo de simulação
O módulo de simulação do Bipide Web apresentado na Figura 25 permite ao usuário
executar um programa escrito em linguagem Portugol ou assembly sobre a arquitetura e
organização dos processadores da família BIP.
Conforme a Figura 25, o módulo de simulação do Bipide Web é composto por: (i) uma
área onde são apresentadas as instruções do programa-fonte em assembly ou Portugol, de
acordo com a linguagem de programação do algoritmo selecionado; (ii) uma área onde
apresentam-se as instruções do programa compilado; (iii) uma barra de ferramentas com
botões de controle e opções do simulador; (iv) a representação da arquitetura do processador
BIP; (v) os valores atuais dos registradores do processador; (vi) os valores atuais dos
registradores de periféricos, quando estes se aplicam; (vii) uma representação da memória de
instruções e (viii) uma representação da memória de dados.
72
Figura 25: Módulo de simulação do Bipide Web.
Assim como já acontece nas versões anteriores do Bipide, a versão desenvolvida neste
trabalho permite ao usuário visualizar a relação existente entre uma instrução do programa-
fonte e as instruções correspondentes geradas por tal instrução no programa compilado.
Na Figura 26 pode-se visualizar um exemplo dessa relação - na seção referente ao
programa-fonte (Portugol) a linha 5 é destacada na cor verde, indicando que esta é a instrução
em alto nível sendo executada pelo simulador no momento. Já na seção referente ao programa
compilado (assembly), estão destacadas em azul as instruções em baixo nível geradas pela
linha 5 do programa-fonte. Além disso, nessa mesma seção, destaca-se em verde a instrução
assembly sendo executada na etapa atual. Desta forma, o usuário do ambiente de
desenvolvimento tem a possibilidade de fazer comparações e criar relações entre essas
instruções.
73
Figura 26: Relação entre as instruções no simulador.
Assim como no módulo de edição de programa, a barra de ferramentas presente no
módulo de simulação possui um conjunto de botões de ação. No lado esquerdo de tal barra
situam-se os botões de controle do processo de simulação. São eles: o botão Iniciar, utilizado
para começar o processo de simulação; Pausar, utilizado para interromper temporariamente a
simulação; Repetir, utilizado para apresentar novamente uma instrução; Pular, utilizado para
interromper a instrução atual e iniciar a próxima e Parar, utilizado para finalizar a simulação
do programa atual.
O lado direito da barra de ferramentas do módulo de simulação apresenta dois botões:
o primeiro tem a função de permitir ao usuário selecionar a velocidade da simulação. O
segundo permite que o usuário selecione a versão do processador BIP que deseja utilizar para
simular o programa atual. A representação da arquitetura e organização do BIP irá adequar-se
de acordo com a opção selecionada pelo usuário.
74
A representação visual da organização dos processadores BIP foi construída através do
elemento canvas. O canvas foi introduzido na versão 5 da linguagem de marcação HTML e
sua API permite que sejam desenhados, através da linguagem JavaScript, diferentes elementos
gráficos, como formas geométricas, textos e imagens. (FULTON; FULTON, 2013). O canvas
é suportado nativamente pelas versões mais modernas dos navegadores web, dispensando a
necessidade da instalação de plug-ins ou softwares de terceiros para o seu correto
funcionamento.
Para construir a representação gráfica da organização dos processadores BIP e as
animações de cada uma das instruções suportadas foi utilizada a biblioteca Fabric.js. Fabric.js
é uma biblioteca escrita em linguagem JavaScript com a finalidade de facilitar a manipulação
do elemento canvas. Essa biblioteca oferece ao programador uma abordagem orientada a
objetos, permitindo que os elementos criados possam ser manipulados como se fossem
objetos, cada um deles apresentando propriedades e métodos. (FABRICJS, 2016). Fabric.js
possui também suporte a animações, característica indispensável para a construção da
ferramenta resultante deste trabalho.
Além da representação visual dos componentes da organização dos processadores BIP,
o simulador desenvolvido neste trabalho também mostra o conteúdo da memória de instruções
e da memória de dados na parte inferior do simulador, na forma de uma tabela. Conforme
pode ser visto na Figura 27, onde visualiza-se a representação gráfica do processador BIP IV,
a instrução atualmente em execução recebe destaque na memória de instruções. O mesmo
acontece com a memória de dados, quando se aplica.
75
Figura 27: Representação da organização do BIP IV.
O conteúdo dos registradores do processador e dos registradores de periféricos pode
ser visualizado no painel posicionado na parte direita do módulo de simulação. O conteúdo de
tais registradores é atualizado ao final de cada instrução, de forma que o usuário pode
acompanhar as mudanças ocorridas. A Figura 28 apresenta painel com os registradores do
processador BIP IV.
76
Figura 28: Registradores do processador e periféricos do BIP IV.
Dentre os registradores apresentados na Figura 28 destacam-se os registradores de
entrada-e-saída (IN_PORT e OUT_PORT), presentes nos processadores BIP IV e µBIP. Ao
identificar uma instrução que necessite da entrada de dados por parte do usuário o simulador
interrompe a execução e ativa o botão Continuar, localizado junto ao quadro do registrador
IN_PORT. Assim, o usuário pode clicar sobre os botões que representam os bits do valor de
entrada. A cor de cada um dos botões alterna entre verde (bit ligado, 1) e cinza (bit desligado,
0). O valor convertido em notação decimal é apresentado ao lado do nome do registrador de
entrada (IN_PORT). Ao clicar no botão continuar, o processo de simulação continua de onde
parou.
Igualmente, ao identificar uma instrução que escreva um valor no registrador
OUT_PORT o simulador atualiza o valor de tal registrador no painel, assim como sua
representação em binário. No caso do registrador OUT_PORT cada um dos bits do valor atual
é representado por um ícone em formato de lâmpada. O mecanismo de entrada-e-saída do
Bipide Web foi inspirado nos mecanismos presentes no Bipide 3.0 e Bipide 4.0.
3.3.3 Módulo de ajuda
O módulo de ajuda presente no Bipide Web permite ao usuário autenticado obter
informações sobre os tópicos Arquitetura e Organização de Computado, Processadores da
Família BIP, Linguagem de programação Portugol e Ambiente de desenvolvimento Bipide
77
Web. Todo o conteúdo presente no módulo de ajuda, exceto o tópico relacionado ao ambiente
Bipide Web, foi reaproveitado da versão 4.0 da IDE Bipide.
A Figura 29 apresenta a interface do módulo de ajuda do Bipide Web. Nela, destaca-se
que tal módulo é composto por duas áreas principais: (i) uma barra lateral onde pode-se
selecionar o tópico do qual se deseja obter informações e (ii) uma área principal onde é
apresentado o conteúdo do tópico selecionado pelo usuário.
Figura 29: Módulo de Ajuda do Bipide Web.
O tópico Arquitetura e organização de Computadores apresenta ao usuário definições
básicas, tais com: conceitos de arquitetura e organização de computadores, instrução,
registrador, caminho de dados, memória, dentre outros. Já o tópico Processadores dá uma
visão geral dos processadores da família BIP, assim como apresenta as características
principais de cada um dos processadores. O tópico relacionado a linguagem de programação
Portugol apresenta a definição da linguagem e demonstra a estrutura básica de um programa
escrito em Portugol. Por fim, o tópico relacionado ao Ambiente de Desenvolvimento
Integrado Bipide Web descreve as funcionalidades de tal ambiente.
3.4 VALIDAÇÃO
Esta seção tem por objetivo apresentar os testes realizados com o intuito de validar a
ferramenta resultante deste trabalho, tendo como enfoque os compiladores desenvolvidos e o
processo de simulação. Além de garantir o funcionamento do produto final deste trabalho, a
78
execução de testes de validação serviu também para a realização de pequenas melhorias e
correções de problemas encontrados durante o processo.
3.4.1 Validação do funcionamento da aplicação front-end
Durante todo o processo de desenvolvimento da aplicação front-end do Bipide Web o
navegador Google Chrome (versão 54.0.2840.87) foi utilizado como plataforma de execução
da ferramenta. Entretanto, ao final do desenvolvimento, o Bipide Web foi executado também
nos navegadores Mozilla Firefox (versão 49.0.2) e Microsoft Edge (versão 38.14393.0.0). Foi
constatado que nos três navegadores citados foi possível executar as funcionalidades providas
pelo ambiente de desenvolvimento, incluindo criação de cadastro, edição de programas e
simulação de execução passo-a-passo.
Em contrapartida, notou-se que a aplicação apresenta alguns problemas relacionados
ao seu layout quando executada sobre os navegadores Microsoft Edge e Mozilla Firefox.
Basicamente, estes problemas dizem respeito ao alinhamento e tamanho de alguns
componentes visuais. No entanto, tais inconformidades visuais não impedem o uso da
ferramenta ou causam grande prejuízo ao usuário, ficando a correção destes problemas para
um momento póstumo ao término deste trabalho.
É importante salientar que o navegador Microsoft Edge foi utilizado no processo de
validação da ferramenta em detrimento ao navegador Microsoft Internet Explorer. Isso deve-
se ao fato de que este último, apesar de possuir uma fatia de mercado maior em comparação
ao primeiro, teve seu desenvolvimento descontinuado pela empresa Microsoft. Sendo assim, o
navegador Microsoft Edge foi selecionado por ser seu substituto. (MICROSOFT, 2016)
3.4.2 Validação do compilador Portugol
Para realizar a validação do compilador da linguagem de programação Portugol foram
utilizados os algoritmos de teste presentes em Mannes (2013). Cada um dos algoritmos foi
compilado e simulado no Bipide Web.
A Tabela 13 apresenta de forma resumida os resultados dos testes executados no
Bipide Web em comparação com os resultados obtidos por Mannes (2013). Todos os testes
executados obtiveram sucesso no processo de compilação e simulação das instruções geradas.
Ainda conforme a Tabela 13, nota-se que a grande maioria dos resultados dos testes obtidos
79
por Mannes (2013) possui um número de instruções e variáveis menor no programa
compilado resultante. Isto explica-se pelo fato de que, diferente do trabalho realizado por
Mannes (2013), o presente trabalho não implementou nenhum tipo de otimização de código,
ficando tal tarefa como sugestão para trabalhos futuros. O Apêndice D apresenta o resultado
completo dos testes realizados no Bipide Web.
Tabela 13: Comparativo dos resultados dos testes do compilador Portugol.
Bipide 4 Bipide Web
Programa Linhas Variáveis Linhas Variáveis Compilação Simulação
Teste 1 11 1 12 1 OK OK
Teste 2 15 1 16 1 OK OK
Teste 3 37 5 41 5 OK OK
Teste 4 19 2 21 2 OK OK
Teste 5 18 4 20 4 OK OK
Teste 6 12 3 14 3 OK OK
Teste 7 36 6 36 6 OK OK
Teste 8 42 7 43 7 OK OK
Teste 9 29 14 33 14 OK OK
Teste 10 64 12 61 9 OK OK
Teste 11 21 4 23 4 OK OK
Teste 12 31 3 32 3 OK OK
Teste 13 31 1 36 2 OK OK
Teste 14 18 1 19 1 OK OK
Teste 15 11 1 14 1 OK OK
Teste 16 32 11 40 12 OK OK
Teste 17 51 5 52 5 OK OK
Teste 18 36 7 42 8 OK OK
3.4.3 Validação do compilador Assembly
A validação do compilador assembly deu-se através da execução dos testes presentes
no trabalho de Rech (2011). Assim como na validação do compilador Portugol, os algoritmos
de teste escritos em assembly foram compilados e executados no Bipide Web. Após a
execução de cada um dos algoritmos, verificou-se os valores presentes nos principais
registradores e o estado final da memória de dados do programa. A Tabela 14 apresenta um
dos testes realizados, onde pode-se observar o programa em assembly utilizado para testar a
instrução RETURN e os estados finais dos registradores e memória após sua execução. O
resultado completo dos testes realizados é apresentado no Apêndice E.
80
Os resultados obtidos a partir da realização dos testes foram satisfatórios e
demonstraram o correto funcionamento do compilador desenvolvido.
Tabela 14: Teste do compilador assembly com instrução RETURN.
Instrução Sequência de instruções testadas PC ACC Z N Memória
RETURN .text
ldi 0x003
sto $14
ldi 0x002
sto $15
call __sum
addi 0x001
jmp __end
__sum:
ld $14
add $15
return
__end:
12 6 0 0 M[14] = 3
M[15] = 2
3.5 LIMITAÇÕES
Por questões relacionadas ao escopo do trabalho e ao tempo disponível para o
desenvolvimento da aplicação, o Bipide Web não conta com algumas das funcionalidades
presentes nas versões desktop do ambiente de desenvolvimento.
Dentre tais funcionalidades, destaca-se a possibilidade de criação e compilação de
programas escritos em linguagem C. Conforme já citado neste texto, uma nova versão do
compilador C para os processadores BIP está sendo desenvolvida em paralelo a este trabalho.
Acredita-se que o compilador resultante de tal trabalho poderá, em trabalhos futuros, ser
integrado ao Bipide Web.
Em relação ao editor de texto do Bipide Web, não foi implementada a funcionalidade
que permite a exportação de programas em diferentes formatos, tais como binário e
hexadecimal. Igualmente, não está presente no Bipide Web a possibilidade de aumentar e
diminuir a fonte do editor de código-fonte da ferramenta.
As funcionalidades de copiar, recortar e colar via botões de ação necessitam sofrer
melhorias em sua implementação, visto que o suporte a estas operações via JavaScript não é
totalmente atendida pelos navegadores. Atualmente, tais funcionalidades estão disponíveis
somente via atalhos de teclado.
81
O simulador de arquitetura e organização do Bipide Web não apresenta, por ora,
mensagens de ajuda referentes a instrução sendo executada no passo atual. A possibilidade de
visualizar estatísticas referentes ao programa executado e a execução individual de instruções
também não foram contempladas nesta primeira versão Web da IDE Bipide. Ainda, o Bipide
Web não possui suporte a outros idiomas. Logo, há suporte apenas ao idioma português.
Atualmente, o processo de compilação do Bipide Web mantém apenas a última versão
do código compilado. Devido a este fato, o histórico de erros e mensagens de aviso das
tentativas de compilação por parte do usuário não é mantido. Por consequência, não há a
possibilidade de realizar uma análise de tal histórico com a finalidade de, por exemplo,
identificar quais os erros mais comuns que um determinado usuário comete.
Além das funcionalidades citadas acima, o Bipide Web não passou por testes de carga
e performance. Destaca-se a importância da realização de tais testes como forma de garantir
um desempenho aceitável da aplicação, visto que, devido a sua natureza, tal aplicação está
passível a receber várias conexões simultaneamente.
As funcionalidades destacadas e discutidas nesta seção estão listadas na Seção 4.1
deste trabalho, como forma de sugestões de trabalhos futuros.
4 CONCLUSÕES
Este trabalho apresentou o desenvolvimento de uma versão online do ambiente de
desenvolvimento integrado Bipide, denominada Bipide Web. Nesta nova versão é possível
escrever algoritmos em linguagem Portugol e em linguagem de montagem dos processadores
da família BIP. A possibilidade de criação de programas em Linguagem C não foi
contemplada neste trabalho por questões de escopo e pelo fato de que, em paralelo a este
trabalho, ocorre o desenvolvimento de uma nova versão do compilador C para os
processadores BIP. Pretende-se que, em trabalhos futuros, seja realizada a integração desta
nova versão do compilador C com a aplicação resultante deste trabalho.
Todos os processadores da família BIP existentes até o momento da escrita deste
trabalho são suportados nesta versão do Bipide. Todos os objetivos específicos e o objetivo
geral deste trabalho foram atingidos.
Foi realizada uma análise de ferramentas online para simulação de arquitetura e
organização de computadores. Tal análise, além de auxiliar na definição das funcionalidades
implementadas no Bipide Web, também mostrou que, dentre as ferramentas analisadas,
nenhuma destas possibilitava ao usuário criar programas em linguagem de alto nível. Outra
constatação importante foi a de que apenas uma das ferramentas analisadas possuía um
simulador de organização. Estas duas características estão presentes no Bipide Web.
Igualmente, foi feita uma análise sobre versões anteriores da ferramenta Bipide com a
finalidade de verificar as funcionalidades existentes nessas versões e mapear as principais
funcionalidades que deveriam ser incluídas no desenvolvimento da aplicação descrita neste
trabalho.
Também foi realizado um estudo sobre os processadores da família BIP, no que diz
respeito a sua arquitetura e organização. Outros conceitos centrais para a realização deste
trabalho de conclusão também foram revisados, tais como compiladores e conceitos
relacionados à sistemas web.
Fez-se necessário realizar um estudo sobre o núcleo do Portugol Studio com a
finalidade de compreender o seu funcionamento e assim realizar a implementação de uma
classe visitante em linguagem Java, capaz de traduzir código Portugol em código assembly
dos processadores BIP. Da mesma forma, a gramática do compilador assembly da versão 4.0
da IDE Bipide foi analisada e alterada para funcionar sobre a plataforma Java. Após isso, foi
realizada a implementação de um novo parser para a linguagem assembly.
A aplicação cliente e a aplicação servidora que compõem o Bipide Web foram
construídas de forma independente. O server-side disponibiliza uma API REST, documentada
no Apêndice C deste trabalho. Tal API é consumida pela aplicação cliente por intermédio do
protocolo HTTP. O client-side da aplicação foi construído através das tecnologias HTML,
CSS e JavaScript e possui três módulos: (i) edição de programa, (ii) simulação de arquitetura
e organização e (iii) ajuda.
O correto funcionamento da ferramenta foi validado através da execução de testes, nos
quais foram compilados e simulados programas escritos em Portugol e assembly. Ao final de
cada uma das execuções, o resultado obtido nos registradores e memória de dados foi
comparado com o resultado esperado. A execução de tais algoritmos demonstrou o correto
funcionamento dos compiladores Portugol e assembly, assim como do processo de simulação.
A realização deste trabalho possibilitou a este autor aplicar e aprofundar uma série de
conhecimentos adquiridos durante o curso de Ciência da Computação, bem como ter contato
com ferramentas e tecnologias antes desconhecidas.
Acredita-se que o principal mérito deste trabalho é ter tornado o ambiente de
desenvolvimento Bipide independente de plataforma, permitindo que o mesmo possa ser
executado em diferentes sistemas operacionais, eliminando a necessidade de instalação e a
utilização de camadas adicionais de software para o seu correto funcionamento.
Outra característica que demonstra a relevância deste trabalho diz respeito a
disponibilização de um serviço web capaz de compilar e traduzir programas escritos em
Portugol para a linguagem de montagem da família BIP; bem como a possibilidade de
analisar e validar códigos escritos na linguagem de montagem do BIP. Essas funcionalidades
permitirão que outros desenvolvedores criem novas ferramentas e interfaces de usuários,
eliminando a necessidade de recriar o processo de compilação.
4.1 TRABALHOS FUTUROS
Durante a realização deste trabalho foi possível identificar uma série de oportunidades
para o desenvolvimento de trabalhos correlacionados, conforme descrito a seguir:
Implementar suporte para diferentes linguagens de programação;
Criar interfaces voltadas para dispositivos móveis;
Avaliar a utilização da ferramenta em sala de aula;
Adicionar suporte a outros idiomas;
Criar um módulo voltado aos professores, permitindo a configuração de turmas,
liberação de exercícios, etc.;
Otimizar o código gerado pelos compiladores Portugol e assembly;
Realizar avaliação usabilidade da interface de usuário e prover melhorias;
Realizar testes de carga e performance sobre a aplicação;
Possibilitar a análise de erros de compilação com a finalidade de permitir a
identificação de padrões e comportamentos por parte do aluno;
Integrar o compilador C desenvolvido em paralelo a este trabalho;
Incluir funcionalidade existentes em versões anteriores do Bipide, as quais não
foram incluídas nesta versão em função do seu escopo. Tais funcionalidades são
descritas na seção 3.5 deste trabalho.
REFERÊNCIAS
AHO, Alfred V. et al. Compiladores: princípios, técnicas e ferramentas. 2. ed. São Paulo:
Pearson Addison-Wesley, 2008.
ANGULARJS. AngularJS - Superheroic JavaScript MVW Framework. Disponível em:
<https://angularjs.org/>. Acesso em: 29 de out. 2016.
ANTLR. About The ANTLR Parser Generator. Disponível em:
<http://www.antlr.org/about.html>. Acesso em 03 de nov. 2016.
BARTH, A. HTTP State Management Mechanism, RFC 6265, DOI 10.17487/RFC6265,
April 2011, <http://www.rfc-editor.org/info/rfc6265>.
CAITANO, Alexandre; AZEVEDO, Edjane; TRINDADE, Servulla. Das Nuvens Para a Sala
de Aula. In: 5º SIMPÓSIO HIPERTEXTO E TECNOLOGIAS NA EDUCAÇÃO, 2013,
Recife. Anais Eletrônicos do Simpósio Hipertexto e Tecnologias na Educação. Recife,
2013.
CARLOSRAFAELGN. Carlosrafaelgn/Asm86 - A JavaScript assembly x86 compiler +
emulator for educational purposes. Disponível em:
<https://github.com/carlosrafaelgn/Asm86>. Acesso em 06 de abr. 2016.
COOPER, Keith D.; TORCZON, Linda. Construindo Compiladores. 2. ed. Rio de Janeiro:
Elsevier, 2014.
COULOURIS, George et al. Sistemas Distribuídos: Conceitos e Projetos. 5. Ed. Porto
Alegre: Bookman, 2013.
DELAMARO, Márcio Eduardo. Como Construir um Compilador Utilizando Ferramentas
Java. São Paulo: Novatec, 2004.
DOGLIO, Fernando. Pro REST API Development with Node.js. 1. Ed. New York, 2015.
DUSSEAULT, L.; SNELL, J. PATCH Method for HTTP, RFC 5789, DOI
10.17487/RFC5789, March 2010, <http://www.rfc-editor.org/info/rfc5789>.
FABRICJS. Fabricjs JavaScript Canvas Library. Disponível em <http://fabricjs.com/fabric-
intro-part-1>. Acesso em: 28 de out. 2016.
FIELDING, Roy Thomas et al. Hypertext Transfer Protocol - HTTP/1.1, RFC 2616, DOI
10.17487/RFC2616, June 1999, <http://www.rfc-editor.org/info/rfc2616>.
FIELDING, Roy Thomas. Architectural Styles and the Design of Network-based Software
Architectures. Doctoral dissertation, University of California, Irvine, 2000.
FOROUZAN, Behrouz A. Comunicação de Dados e Redes de Computadores. 3. Ed. Porto
Alegre: Bookman, 2006.
FRISC. FRISC | FRISC. Disponível em: <http://frisc.org/frisc/>. Acesso em 03 de abr. 2016.
FULTON, Steve; FULTON, Jeff. HTML5 canvas. " O'Reilly Media, Inc.", 2013.
GOOGLE, Angular Material – Introduction. Disponível em:
<https://material.angularjs.org/latest/>. Acesso em: 29 de out. 2016a.
GOOGLE, Introduction – Material design – Material design guidelines. Disponível em:
<https://material.google.com/>. Acesso em: 29 de out. 2016b.
GREEN, Brad; SESHADRI, Shyam. AngularJS. " O'Reilly Media, Inc.", 2013.
JERSEY. Jersey – RESTful Web Services in Java. Disponível em:
<https://jersey.java.net/>. Acesso em: 14 de out. 2016.
KUROSE, James F. Redes de Computadores e a Internet: uma abordagem top-down. 5. Ed.
São Paulo: Pearson, 2010.
LITE-LAB. Portugol Studio. Disponível em: <http://lite.acad.univali.br/portugol/>. Acesso
em: 16 de mar. 2016.
MANNES, Paula. Integração do Portugol Core com o Bipide. Itajaí, 2013. 137. Trabalho
Técnico-científico de Conclusão de Curso (Graduação em Ciência da Computação) – Centro
de Ciências Tecnológicas da Terra e do Mar, Universidade do Vale do Itajaí, Itajaí, 2013.
MANSUR, André Fernando Uebe et al. Novos rumos para a Informática na Educação pelo
uso da Computação em Nuvem (Cloud Education): Um estudo de Caso do Google Apps. Foz
do Iguaçu, 2010.
MASSE, Mark. REST API design rulebook. " O'Reilly Media, Inc.", 2011.
MICROCHIP TECHNOLOGY INC. Home - Microchip Technology Inc. Disponível em: <
http://www.microchip.com/>. Acesso em 25 de mar. 2016
MICROSOFT. Internet Explorer End of Support. Disponível em:
<https://www.microsoft.com/en-us/WindowsForBusiness/End-of-IE-support>. Acesso em: 29
de out. 2016.
MORANDI, Diana et al., Um Processador Básico para o Ensino de Conceitos de Arquitetura
e Organização de Computadores. Hífen, Uruguaiana, v.30, p. 73-80, 2006.
MORANDI, Diana; RAABE, André Luis Alice; ZEFERINO, Cesar Albenes. Processadores
para Ensino de Conceitos Básicos de Arquitetura de Computadores. In: WORKSHOP DE
EDUCAÇÃO EM ARQUITETURA DE COMPUTADORES, 1., 2006, Ouro Preto.
Proceedings of the 18th International Symposium on Computer Architecture and High
Performance Computing - Workshops. Porto Alegre: SBC, 2006. p. 17-24.
MORRISWMZ. morriswmz/SimpleMIPS.js - A very basic MIPS simulator written in
JavaScript. Disponível em: <https://github.com/morriswmz/SimpleMIPS.js>. Acesso em: 04
de abr. 2016.
NETMARKETSHARE. Browser Market share. Disponível em:
<https://www.netmarketshare.com/browser-market-share.aspx?qprid=0&qpcustomd=0>.
Acesso em: 15 de mar. 2016
NOSCHANG, Luiz Fernando. Adaptação do Portugol Core para integração com outras
ferramentas. Itajaí, 2012. 74. Trabalho Técnico-científico de Conclusão de Curso
(Graduação em Ciência da Computação) – Centro de Ciências Tecnológicas da Terra e do
Mar, Universidade do Vale do Itajaí, Itajaí, 2012.
NOTTINGHAN, M. Web Linking, RFC 5988, DOI 10.17487/RFC5988, October 2010,
<http://www.rfc-editor.org/info/rfc5988>.
OLIVEIRA et al. Implementando Suporte a Novas Linguagens de Programação e outros
Idiomas no Ambiente de Desenvolvimento Integrado Bipide. International Journal of
Computer Architecture Education, v. 3, p. 5-8, 2014.
OLIVEIRA Junior, Nereu Pires de. BIP C – Criação de um compilador C para a
arquitetura dos processadores BIP. Itajaí, 2013. 211. Trabalho Técnico-científico de
Conclusão de Curso (Graduação em Ciência da Computação) – Centro de Ciências
Tecnológicas da Terra e do Mar, Universidade do Vale do Itajaí, Itajaí, 2013.
PEREIRA, Maicon C. μBIP: Microcontrolador básico para o ensino de Sistemas
Embarcados. Itajaí, 2008. 161f. Trabalho de Conclusão de Curso (Graduação em Ciência da
Computação) – Centro de Ciências Tecnológicas da Terra e do Mar, Universidade do Vale do
Itajaí, Itajaí, 2008.
PROJECT KENAI. Java API for RESTful Services (JAX-RS). Disponível em < https://jax-rs-
spec.java.net/>. Acesso em: 14 de out. 2016.
RECH et al. BIP IV: especificação e suporte na ferramenta Bipide. In: Workshop sobre
Educação em Arquitetura de Computadores (WEAC 2011), 2011, Vitória. Proceedings of the
23rd International Symposium on Computer Architecture and High Performance
Computing, 2011.
RECH, Paulo R. M. BIP IV: Especificação e Suporte na IDE Bipide. Itajaí, 2011. 92 f.
Trabalho de Conclusão de Curso (Graduação em Ciência da Computação)–Centro de Ciências
Tecnológicas da Terra e do Mar, Universidade do Vale do Itajaí, Itajaí, 2011.
SULTAN, Nabil. Cloud computing for education: A new dawn?. International Journal of
Information Management, v. 30, n. 2, p. 109-116, 2010.
TANEMBAUM, Andrew S.; STEEN, Maarten van. Sistemas Distribuídos: princípios e
paradigmas. 2 Ed. São Paulo: Pearson Prentice Hall, 2007.
TANENBAUM, Andrew S.; WETHERALL, David J. Computer Networks: Pearson New
International Edition: University of Hertfordshire. Pearson Higher Ed, 2013.
VIEIRA, Paulo Viniccius et al. Bipide: Ambiente de Desenvolvimento Integrado para
Utilização dos Processadores BIP no Ensino de Programação. In: XX Simpósio Brasileiro de
Informática na Educação, 2009, Florianópolis. Anais do XX Simpósio Brasileiro de
Informática na Educação, 2009. v. 1.
VIEIRA, Paulo Viniccius et al. Estendendo a Arquitetura dos Processadores BIP para
Ampliar o Seu Potencial de Uso em Disciplinas de Introdução a Programação. International
Journal of Computer Architecture Education (IJCAE), v. 1, 2012.
VIEIRA, Paulo Viníccius. Avaliação Empírica da proposta interdisciplinar de uso dos
processadores BIP. Itajaí, 2013. Dissertação de Mestrado (Mestrado em Computação
Aplicada)–Centro de Ciências Tecnológicas da Terra e do Mar, Universidade do Vale do
Itajaí, Itajaí, 2013.
VIEIRA, Paulo Viníccius. Bipide - Ambiente de Desenvolvimento Integrado para a
Arquitetura dos Processadores BIP. Itajaí, 2009. 107f. Trabalho de Conclusão de Curso
(Graduação em Ciência da Computação)–Centro de Ciências Tecnológicas da Terra e do Mar,
Universidade do Vale do Itajaí, Itajaí, 2009.
VIEIRA, Paulo Viniccius; RAABE, André Luis Alice; ZEFERINO, Cesar Albenes. Bipide:
ambiente de desenvolvimento integrado para a arquitetura dos processadores BIP. Revista
Brasileira de Informática na Educação, v. 18, p. 32-43, 2010.
VIEL, Felipe et al. Introdução à programação e à implementação de processadores por
estudantes do Ensino Médio. In: WORKSHOP DE INFORMÁTICA NA ESCOLA (WIE),
20., 2014, Dourados. Anais do 3o Congresso Brasileiro de Informática na Educação.
Porto Alegre: SBC, 2014. p. 1-10.
ZEFERINO, Cesar Albenes et al. Um Enfoque Interdisciplinar no Ensino de Arquitetura de
Computadores. In: MARTINS, Carlos Augusto Paiva da Silva; NAVAUX, Philippe Olivier
Alexandre; AZEVEDO, Rodolfo Jardim de; KOFUJI, Sérgio Takeo (Org.). Arquitetura de
Computadores: educação, ensino e aprendizado. 1ed. Porto Alegre: Sociedade Brasileira de
Computação (SBC), 2012, p. 165-193.
APÊNDICE A. DEFINIÇÃO DA GRAMÁTICA ASSEMBLY
UTILIZADA NO ANTLR
grammar BIPASM;
options {
backtrack = true;
memoize=true;
}
@parser::header {
package br.bip.antlr;
}
@lexer::header {
package br.bip.antlr;
}
@members{
public void setEscopoErro(String escopoErro) {}
public void limpaEscopoErro() {}
public void addVariavel(String nome, String valor, int linha, int
coluna) throws RecognitionException {}
public void setTipoOperando(String tipo) {}
public void addInstrucao(String instrucao, String operando, int
linhaInstrucao, int colunaInstrucao, int linhaOperando, int
colunaOperando) {}
public void addRotulo(String rotulo, int linha, int coluna) {}
public void fimDeclaracao() {}
public void verificarLabels() {}
}
@rulecatch { catch (RecognitionException e) { throw e; }}
fragment A:('a'|'A');
fragment B:('b'|'B');
fragment C:('c'|'C');
fragment D:('d'|'D');
fragment E:('e'|'E');
fragment F:('f'|'F');
fragment G:('g'|'G');
fragment H:('h'|'H');
fragment I:('i'|'I');
fragment J:('j'|'J');
fragment K:('k'|'K');
fragment L:('l'|'L');
fragment M:('m'|'M');
fragment N:('n'|'N');
fragment O:('o'|'O');
fragment P:('p'|'P');
fragment Q:('q'|'Q');
fragment R:('r'|'R');
fragment S:('s'|'S');
fragment T:('t'|'T');
fragment U:('u'|'U');
fragment V:('v'|'V');
fragment W:('w'|'W');
fragment X:('x'|'X');
fragment Y:('y'|'Y');
fragment Z:('z'|'Z');
//Sections
SECTEXT: '.' T E X T;
SECDATA: '.' D A T A;
ADD: A D D;
ADDI: A D D I;
SUB: S U B;
SUBI: S U B I;
LD: L D;
LDI: L D I;
STO: S T O;
BLE: B L E;
BGE: B G E;
BLT: B L T;
BGT: B G T;
BEQ: B E Q;
BNE: B N E;
JMP: J M P;
HLT: H L T;
NOT : N O T;
AND : A N D;
ANDI : A N D I;
OR : O R;
ORI : O R I;
XOR : X O R;
XORI : X O R I;
SLL : S L L;
SRL : S R L;
STOV : S T O V;
LDV : L D V;
RETURN : R E T U R N;
RETINT : R E T I N T;
CALL : C A L L;
CHAR : ('\'')~('\'')('\'');
INT : '0'|('1'..'9')('0'..'9')* ;
INTS : ('-')('1'..'9')('0'..'9')* ;
HEX : '0x'(('0'..'9')|('A'..'F')|('a'..'f'))+;
BIN : '0b'('0'|'1')+;
CIF : '$'('0'..'9') + ;
REG : '$'('in_port' | 'out_port' | 'port'('0'..'9')+'_dir' |
'port'('0'..'9')+'_data' | 'tmr0_config' | 'tmr0_value' | 'int_config' |
'int_status' | 'mcu_config' | 'indr' | 'status' | 'uart_data' |
'uart_status');
ID : (('a'..'z')|('A'..'Z')|'_' )(('a'..'z')|('A'..'Z')|'_'|
('0'..'9') )* ;
//NEWLINE:'\r' ? '\n' ;
WS : (' ' |'\t' |'\n' |'\r' )+ {$channel=HIDDEN;} ;
WORD : '.word'{$channel=HIDDEN;} ;
COMENTARIOLINHA:'#' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;};
programa : sectionData sectionText;
sectionData @init { setEscopoErro("Erro na seção .data"); }
@after { limpaEscopoErro(); }
: SECDATA lista_decl | ;
lista_decl : decl+;
decl @init { setEscopoErro("Erro na declaração de variáel"); }
@after { fimDeclaracao(); limpaEscopoErro(); }
: ID ':' valvar {addVariavel($ID.text, $valvar.text,
$ID.getLine(), $ID.getCharPositionInLine());};
valvar : oper_vint | oper_vint ',' valvar ;
inst_vint : ADDI | SUBI | LDI | ANDI | ORI | XORI | SLL | SRL ;
inst_reg : ADD | SUB | LD | STO | AND | OR | XOR | STOV | LDV;
inst_label : BEQ | BNE | BLE | BLT | BGE | BGT | JMP | CALL;
inst_nulo : HLT | NOT | RETURN | RETINT ;
oper_vint : INT {setTipoOperando("INT");}| INTS
{setTipoOperando("INT");}| HEX {setTipoOperando("HEX");} | BIN
{setTipoOperando("BIN");} | CHAR {setTipoOperando("CHAR");};
oper_reg : INT {setTipoOperando("INT");}| HEX
{setTipoOperando("HEX");} | ID {setTipoOperando("VAR");}| REG
{setTipoOperando("REG");} | CIF {setTipoOperando("CIF");};
oper_label : INT {setTipoOperando("INT");}| HEX
{setTipoOperando("HEX");} | BIN {setTipoOperando("BIN");} | ID
{setTipoOperando("LABEL");};
oper_nulo : INT {setTipoOperando("INT");}| ;
sectionText @init { setEscopoErro("Erro na seção .text"); }
@after { limpaEscopoErro(); }
: SECTEXT lista_cmdo ;
lista_cmdo @after { verificarLabels(); } : cmdo+ ;
cmdo @init { setEscopoErro("Erro no comando"); }
@after { limpaEscopoErro(); }
: inst_vint oper_vint
{addInstrucao($inst_vint.text, $oper_vint.text,
$inst_vint.start.getLine(), $inst_vint.start.getCharPositionInLine(),
$oper_vint.start.getLine(), $oper_vint.start.getCharPositionInLine());}
| inst_reg oper_reg {addInstrucao($inst_reg.text,
$oper_reg.text, $inst_reg.start.getLine(),
$inst_reg.start.getCharPositionInLine(), $oper_reg.start.getLine(),
$oper_reg.start.getCharPositionInLine());}
| inst_label oper_label
{addInstrucao($inst_label.text,$oper_label.text,
$inst_label.start.getLine(), $inst_label.start.getCharPositionInLine(),
$oper_label.start.getLine(), $oper_label.start.getCharPositionInLine());}
| inst_nulo oper_nulo
{addInstrucao($inst_nulo.text, $oper_nulo.text,
$inst_nulo.start.getLine(), $inst_nulo.start.getCharPositionInLine(),
$oper_nulo.start.getLine(), $oper_nulo.start.getCharPositionInLine());}
| ID':' {setTipoOperando("LABEL"); addRotulo($ID.text,
$ID.getLine(), $ID.getCharPositionInLine());};
APÊNDICE B. PADRÃO DE SAÍDA DOS COMPILADORES
PORTUGOL E ASSEMBLY
O objetivo deste apêndice é documentar o formato de saída gerado pelos componentes
compiladores da aplicação Bipide Web. Ao final deste apêndice, encontra-se um exemplo de
aplicação de tal formato.
B.1.1. Estrutura base
Propriedade Tipo Descrição
assembly String Programa compilado em texto puro.
minBipVersion Inteiro Indica a versão mínima do processador BIP capaz de
executar o programa em questão. Valores possíveis 1
(BIP I), 2 (BIP II), 3 (BIP III), 4 (BIP IV) e 5 (µBIP).
dataMemoryDisposition Object Estrutura de chave-valor, onde a chave indica o
endereço na memória de dados e o valor segue o
formato apresentado em B.1.2.
instructions Array Lista de objetos representando instruções no formato
descrito em B.1.3.
errors Array Lista de Objetos representando mensagens de erro de
compilação no formato apresentado em B.1.4.
warnings Array Lista de strings representando avisos de compilação no
formato apresentado em B.1.5.
B.1.2. Formato dos valores das chaves em dataMemoryDisposition da
estrutura base
Propriedade Tipo Descrição
varName String Nome da variável correspondente a posição da
memória.
Value Inteiro Valor associado a posição da memória.
B.1.3. Formato das instruções da chave instructions da estrutura base
Propriedade Tipo Descrição
operand String Contém o operando da instrução.
instruction String Contém o nome da instrução (LD, LDI, etc.) ou o valor
“LABEL” nos casos em que a entrada representa um
rótulo.
opCode String Contém o código da operação referente à propriedade
instruction, de acordo com a arquitetura do BIP.
memoryPosition Inteiro Indica a posição da instrução na memória de
instruções.
operandMemoryPosition Inteiro Indica a posição na memória do operando. Caso não se
aplique, conterá o valor -1.
sourceLine Inteiro Indica a linha geradora da instrução no programa fonte.
line Inteiro Indica a linha onde a instrução está posicionada no
assembly gerado.
B.1.4. Formato dos erros da estrutura base
Propriedade Tipo Descrição
message String Contém a mensagem de erro.
line String Contém a linha referente ao erro.
column Inteiro Contém a coluna referente ao erro.
B.1.5. Formato dos avisos da estrutura base
Propriedade Tipo Descrição
message Inteiro Contém a mensagem de aviso.
line Inteiro Linha referente ao aviso.
column Inteiro Coluna referente ao aviso.
B.1.6. Exemplo de utilização do formato da saída gerada pelos
compiladores
Abaixo, é apresentado um exemplo de utilização do formato gerado como saída pelos
compiladores da aplicação documentada neste trabalho.
Abaixo, o quadro (a) apresenta o programa-fonte escrito em linguagem Portugol. No
quadro (b), pode-se visualizar o formato gerado pelo compilador Portugol após processar a
entrada do quadro (a). Esta saída baseia-se no formato documentado neste anexo.
programa {
inteiro x
funcao inicio () {
inteiro x = 0
leia(x)
se (x > 10)
escreva(x)
}
}
(a)Programa-fonte em linguagem Portugol.
{
"compiled":{
"assembly":".data\n_global_x : 0\n_inicio_x : 0\n.text\nJMP
_inicio\n_inicio:\nLD $in_port\nSTO _inicio_x\nLD _inicio_x\nSUBI 10\nBLE fimse0\nLD
_inicio_x\nSTO $out_port\nfimse0:\nHLT 0\n",
"minBipVersion":4,
"dataMemoryDisposition":{
"0":{
"varName":"_global_x",
"value":0
},
"1":{
"varName":"_inicio_x",
"value":0
}
},
"instructions":[
{
"operand":"_inicio",
"instruction":"JMP",
"opCode":"01110",
"memoryPosition":0,
"operandMemoryPosition":1,
"sourceLine":-1
},
{
"operand":"_inicio",
"instruction":"LABEL",
"memoryPosition":1,
"operandMemoryPosition":-1,
"sourceLine":-1
},
{
"operand":"$in_port",
"instruction":"LD",
"opCode":"00010",
"memoryPosition":2,
"operandMemoryPosition":1028,
"sourceLine":5
},
{
"operand":"_inicio_x",
"instruction":"STO",
"opCode":"00001",
"memoryPosition":3,
"operandMemoryPosition":1,
"sourceLine":5
},
{
"operand":"_inicio_x",
"instruction":"LD",
"opCode":"00010",
"memoryPosition":4,
"operandMemoryPosition":1,
"sourceLine":6
},
{
"operand":"10",
"instruction":"SUBI",
"opCode":"00111",
"memoryPosition":5,
"operandMemoryPosition":-1,
"sourceLine":6
},
{
"operand":"fimse0",
"instruction":"BLE",
"opCode":"01101",
"memoryPosition":6,
"operandMemoryPosition":9,
"sourceLine":6
},
{
"operand":"_inicio_x",
"instruction":"LD",
"opCode":"00010",
"memoryPosition":7,
"operandMemoryPosition":1,
"sourceLine":7
},
{
"operand":"$out_port",
"instruction":"STO",
"opCode":"00001",
"memoryPosition":8,
"operandMemoryPosition":1029,
"sourceLine":7
},
{
"operand":"fimse0",
"instruction":"LABEL",
"memoryPosition":9,
"operandMemoryPosition":-1,
"sourceLine":6
},
{
"operand":"0",
"instruction":"HLT",
"opCode":"00000",
"memoryPosition":10,
"operandMemoryPosition":-1,
"sourceLine":-1
}
],
"errors":[],
"warnings":[
{
"message":"A variável \"x\" está ocultando uma variável do escopo
global.",
"line":4,
"column":10
}
]
}
}
(b)Saída gerada pelo compilador Portugol, contendo as propriedades descritas em B.1.1.
APÊNDICE C. DOCUMENTAÇÃO DA API REST DO BIPIDE
WEB
O objetivo deste apêndice é documentar a API REST disponibilizada na aplicação
servidora do Bipide Web, descrevendo seus recursos, métodos, formatos de requisição e
resposta.
C.1. RECURSO TOKEN
Um token é utilizado pelo sistema de back-end do Bipide Web para fins de
autenticação e autorização. Quando criado, o token é relacionado ao usuário ao qual
pertencem as credenciais informadas no corpo da requisição.
C.1.1. Criar um novo Token no sistema
Requisição utilizada para criar um novo token de autenticação no sistema e associá-lo
ao usuário ao qual pertencem as credenciais informadas no corpo da requisição.
Método HTTP URI
POST /api/auth
A requisição deve conter os seguintes cabeçalhos:
Cabeçalho Valor
Content-Type Application/json
O corpo da requisição deve conter as seguintes propriedades:
Propriedade Restrições
email Propriedade obrigatória.
password Propriedade obrigatória.
Exemplo de corpo de requisição válido:
{
"email": "[email protected]",
"password": "mysecret123"
}
Respostas do servidor:
Status Resposta
200 Caso recurso seja criado com sucesso, corpo da resposta deve conter
representação do recurso recém-criado, conforme exemplo:
{
"createdAt": "628016400",
"token": "j17o8asr2lq2rgoo9dfmtd0s55"
}
401 Caso as propriedades email e password informados no corpo da requisição
não representem credenciais válidas, o servidor responderá com uma requisição
com código de status 401.
500 Caso ocorra algum erro interno do servidor ao tentar processar requisição,
resposta conterá código de status 500.
C.1.2. Excluir um Token do sistema
Requisição utilizada para excluir um token do sistema e, consequentemente, invalidá-
lo, fazendo com que requisições posteriores contendo tal token recebam respostas com código
de status 401 (UNAUTHORIZED). O {token} informado na URI deve ser o valor do token a
ser excluído.
Método HTTP URI
DELETE /api/auth/{token}
A requisição deve conter os seguintes cabeçalhos:
Cabeçalho Valor
Content-Type Application/json
O corpo da requisição não deve ser informado, pois requisições HTTP que se utilizam
do método DELETE devem possuir corpo vazio.
Respostas do servidor:
Status Resposta
204 Caso recurso seja excluído com sucesso, a resposta do servidor deve conter o
código 204 (NO CONTENT).
404 Caso a URI informada na requisição não identifique um token existente no
sistema, o servidor responderá com o uma requisição de código 404 (NOT
FOUDND).
500 Caso ocorra algum erro interno do servidor ao tentar processar requisição,
resposta conterá código de status 500.
C.2. RECURSO USER
O recurso User representa um usuário do sistema Bipide Web.
C.2.1. Criar novo usuário no sistema
Requisição utilizada para criar um novo recurso do tipo User no back-end do Bipide
Web.
Método HTTP URI
POST /api/users
A requisição deve conter os seguintes cabeçalhos:
Cabeçalho Valor
Content-Type Application/json
O corpo da requisição deve conter as seguintes propriedades:
Propriedade Restrições
name Propriedade obrigatória.
email Propriedade obrigatória.
Deve ser um endereço de e-mail válido.
Deve ser única.
Password Propriedade obrigatória.
Deve conter no mínimo 8 caracteres.
Exemplo de corpo de requisição válido:
{
"name": "Bruno Peres",
"email": "[email protected]",
"password": "mysecret123"
}
Respostas do servidor:
Status Resposta
201 Caso recurso seja criado com sucesso, corpo da resposta deve conter
representação do recurso recém-criado, contendo, além dos dados informados
na criação, seu identificador único e data de criação.
400 Caso o corpo da requisição contenha erros, servidor responderá com o código
400 contendo lista de restrições violadas no corpo da requisição.
500 Caso ocorra algum erro interno do servidor ao tentar processar requisição,
resposta conterá código de status 500.
C.2.2. Editar usuário autenticado
Requisição utilizada para editar o usuário autenticado no sistema, identificado pelo
token de autenticação presente no cabeçalho Authorization da requisição.
Método HTTP URI
PUT /api/me
A requisição deve conter os seguintes cabeçalhos:
Cabeçalho Valor
Content-Type Application/json
Authorization Deve conter um token de autenticação válido.
O corpo da requisição deve conter as seguintes propriedades:
Propriedade Restrições
name Propriedade obrigatória.
email Propriedade obrigatória.
Deve ser um endereço de e-mail válido.
Deve ser única.
Password Propriedade obrigatória.
Deve conter no mínimo 8 caracteres.
Exemplo de corpo de requisição válido:
{
"name": "Bruno Peres",
"email": "[email protected]",
"password": "mysecret123"
}
Respostas do servidor:
Status Resposta
200 Caso recurso seja editado com sucesso, corpo da resposta deve conter
representação do recurso recém-criado, contendo, além dos dados informados
na criação, seu identificador único e data de criação.
400 Caso o corpo da requisição contenha erros, servidor responderá com o código
400 contendo lista de restrições violadas no corpo da requisição.
401 Caso o token de autenticação do cabeçalho Authorization seja inválido ou
não tenha sido informado, o servidor retornará com o código de status 401.
500 Caso ocorra algum erro interno do servidor ao tentar processar requisição,
resposta conterá código de status 500.
C.2.3. Excluir usuário autenticado
Requisição utilizada para excluir o usuário atualmente autenticado no sistema,
identificado pelo token de autenticação presenta no cabeçalho Authorization da requisição.
Método HTTP URI
DELETE /api/me
A requisição deve conter os seguintes cabeçalhos:
Cabeçalho Valor
Content-Type Application/json
Authorization Deve conter um token de autenticação válido.
O corpo da requisição não deve ser informado, pois requisições HTTP que se utilizam
do método DELETE devem possuir corpo vazio.
Respostas do servidor:
Status Resposta
204 Caso recurso seja excluído com sucesso, a resposta do servidor deve conter o
código 204 (NO CONTENT).
401 Caso o token de autenticação do cabeçalho Authorization seja inválido ou
não tenha sido informado, o servidor retornará com o código de status 401.
500 Caso ocorra algum erro interno do servidor ao tentar processar requisição,
resposta conterá código de status 500.
C.3. RECURSO PROGRAM
Recurso que representa um programa criado por um usuário do sistema. Ao ser criado,
um programa é associado ao usuário autenticado.
C.3.1. Criar um novo programa
Requisição utilizada para criar um novo programa e associá-lo ao usuário autenticado.
Método HTTP URI
POST /api/programs
A requisição deve conter os seguintes cabeçalhos:
Cabeçalho Valor
Content-Type Application/json
Authorization Deve conter um token de autenticação válido.
O corpo da requisição deve conter as seguintes propriedades:
Propriedade Restrições
name Propriedade obrigatória.
language Propriedade obrigatória.
Restringe-se aos valores “portugol” e “assembly”.
Source Não possui
Exemplo de corpo de requisição válido:
{
"name": "Exemplo 1",
"language": "assembly",
"source": ".data\r\n a : 0\r\n .text \r\n ld a \r\n hlt 0"
}
Respostas do servidor:
Status Resposta
201 Caso recurso seja criado com sucesso, corpo da resposta deve conter
representação do recurso recém-criado, contendo, além dos dados informados
na criação, seu identificador único e data de criação.
400 Caso o corpo da requisição contenha erros, servidor responderá com o código
400 contendo lista de restrições violadas no corpo da requisição.
401 Caso o token de autenticação do cabeçalho Authorization seja inválido ou não
tenha sido informado, o servidor retornará com o código de status 401.
500 Caso ocorra algum erro interno do servidor ao tentar processar requisição,
resposta conterá código de status 500.
C.3.2. Editar um programa
Requisição utilizada para editar um programa associado ao usuário autenticado.
Método HTTP URI
PUT /api/programs
A requisição deve conter os seguintes cabeçalhos:
Cabeçalho Valor
Content-Type Application/json
Authorization Deve conter um token de autenticação válido.
O corpo da requisição deve conter as seguintes propriedades:
Propriedade Restrições
name Propriedade obrigatória.
language Propriedade obrigatória.
Restringe-se aos valores “portugol” e “assembly”.
source Não possui.
Exemplo de corpo de requisição válido:
{
"name": "Exemplo 1",
"language": "assembly",
"source": ".data\r\n a : 0\r\n .text \r\n ld a \r\n hlt 0"
}
Respostas do servidor:
Status Resposta
200 Caso recurso seja editado com sucesso, corpo da resposta deve conter
representação do recurso recém-editado, contendo a data de atualização do
mesmo.
400 Caso o corpo da requisição contenha erros, servidor responderá com o código
400 contendo lista de restrições violadas no corpo da requisição.
401 Caso o token de autenticação do cabeçalho Authorization seja inválido ou não
tenha sido informado, o servidor retornará com o código de status 401.
404 Caso a URI informada na requisição não identifique um programa associado ao
usuário autenticado o servidor responderá com o uma requisição de código 404
(NOT FOUND).
500 Caso ocorra algum erro interno do servidor ao tentar processar requisição,
resposta conterá código de status 500.
C.3.3. Listar programas do usuário autenticado
Requisição utilizada para listar os programas previamente criados pelo usuário
autenticado.
Método HTTP URI
GET /api/programs
A requisição deve conter os seguintes cabeçalhos:
Cabeçalho Valor
Content-Type Application/json
Authorization Deve conter um token de autenticação válido.
O corpo da requisição não deve ser informado, pois requisições HTTP que se utilizam
do método GET devem possuir corpo vazio.
Respostas do servidor:
Status Resposta
200 Caso a requisição seja processada com sucesso, o corpo da resposta deve conter
a lista de programas criados pelo usuário autenticado.
401 Caso o token de autenticação do cabeçalho Authorization seja inválido ou não
tenha sido informado, o servidor retornará com o código de status 401.
500 Caso ocorra algum erro interno do servidor ao tentar processar requisição,
resposta conterá código de status 500.
C.3.4. Recuperar um programa do usuário autenticado
Requisição utilizada para retornar um programa em específico associado ao usuário
autenticado, identificado por {program_id} na URI da requisição.
Método HTTP URI
GET /api/programs/{program_id}
A requisição deve conter os seguintes cabeçalhos:
Cabeçalho Valor
Content-Type Application/json
Authorization Deve conter um token de autenticação válido.
O corpo da requisição não deve ser informado, pois requisições HTTP que se utilizam
do método GET devem possuir corpo vazio.
Respostas do servidor:
Status Resposta
200 Caso a requisição seja processada com sucesso, o corpo da resposta deve conter
o programa identificado por {program_id} na URI da requisição.
401 Caso o token de autenticação do cabeçalho Authorization seja inválido ou não
tenha sido informado, o servidor retornará com o código de status 401.
404 Caso a URI informada na requisição não identifique um programa associado ao
usuário autenticado o servidor responderá com o uma requisição de código 404
(NOT FOUDND).
500 Caso ocorra algum erro interno do servidor ao tentar processar requisição,
resposta conterá código de status 500.
C.3.5. Excluir um programa
Requisição utilizada para excluir um programa associado ao usuário autenticado,
identificado por {program_id} na URI da requisição.
Método HTTP URI
DELETE /api/programs/{program_id}
A requisição deve conter os seguintes cabeçalhos:
Cabeçalho Valor
Content-Type Application/json
Authorization Deve conter um token de autenticação válido.
O corpo da requisição não deve ser informado, pois requisições HTTP que se utilizam
do método DELETE devem possuir corpo vazio.
Respostas do servidor:
Status Resposta
204 Caso o programa seja excluído com sucesso, o servidor deve responder com o
código de status 204 (NO CONTENT).
401 Caso o token de autenticação do cabeçalho Authorization seja inválido ou não
tenha sido informado, o servidor retornará com o código de status 401.
404 Caso a URI informada na requisição não identifique um programa associado ao
usuário autenticado o servidor responderá com o uma requisição de código 404
(NOT FOUDND).
500 Caso ocorra algum erro interno do servidor ao tentar processar requisição,
resposta conterá código de status 500.
C.3.6. Compilar um programa
Requisição utilizada para compilar um programa, identificado por {program_id} na
URI da requisição. É importante salientar que caso ocorra algum erro de compilação, este
deve ser identificado observando-se a propriedade errors presente no corpo da resposta.
Método HTTP URI
PUT /api/programs/{program_id}/compile
A requisição deve conter os seguintes cabeçalhos:
Cabeçalho Valor
Content-Type Application/json
Authorization Deve conter um token de autenticação válido.
O corpo da requisição não precisa ser informado.
Respostas do servidor:
Status Resposta
200 Caso a requisição seja processada com sucesso, o servidor deve responder com
o código de status 200 (OK) e o corpo da requisição deve conter o programa
identificado pelo {program_id} da URI no formato apropriado.
401 Caso o token de autenticação do cabeçalho Authorization seja inválido ou não
tenha sido informado, o servidor retornará com o código de status 401.
404 Caso a URI informada na requisição não identifique um programa associado ao
usuário autenticado o servidor responderá com o uma requisição de código 404
(NOT FOUDND).
500 Caso ocorra algum erro interno do servidor ao tentar processar requisição,
resposta conterá código de status 500.
APÊNDICE D. PROGRAMAS PORTUGOL UTILIZADOS
PARA VALIDAÇÃO DO COMPILADOR
Portugol Compilado
(assembly) PC ACC Z N Memória
//teste1
programa {
funcao inicio() {
inteiro x = 1
se (2 == 2) {
x = 30
}
}
}
.data
_inicio_x : 1
.text
JMP _inicio
_inicio:
LDI 2
SUBI 2
BNE fimse0
LDI 30
STO _inicio_x
fimse0:
HLT 0
8 30 1 0 M[0]-> x = 30
// teste2
programa {
funcao inicio() {
inteiro x = 1
se (2 == 2) {
x = 30
}
senao {
x = 60
}
}
}
.data
_inicio_x : 1
.text
JMP _inicio
_inicio:
LDI 2
SUBI 2
BNE else0
LDI 30
STO _inicio_x
JMP fimse0
else0:
LDI 60
STO _inicio_x
fimse0:
HLT 0
12 30 1 0 M[0]-> x = 30
// teste3 .data 32 1 0 0 M[0]-> fat = 120
programa {
funcao inicio () {
inteiro fat = 1, temp = 0, i
= 0, j = 0, num = 5
para (i = 2; i <= num; i++) {
temp = fat
para (j = 1; j <= i-1; j++)
{
fat = fat + temp
}
}
}
}
_inicio_fat : 1
_inicio_temp : 0
_inicio_i : 0
_inicio_j : 0
_inicio_num : 5
temp0 : 0
.text
JMP _inicio
_inicio:
LDI 2
STO _inicio_i
para0:
LD _inicio_i
SUB _inicio_num
BGT fimpara0
LD _inicio_fat
STO _inicio_temp
LDI 1
STO _inicio_j
para1:
LD _inicio_i
SUBI 1
STO temp0
LD _inicio_j
SUB temp0
BGT fimpara1
LD _inicio_fat
ADD _inicio_temp
STO _inicio_fat
LD _inicio_j
ADDI 1
STO _inicio_j
JMP para1
fimpara1:
LD _inicio_i
ADDI 1
STO _inicio_i
JMP para0
fimpara0:
HLT 0
M[1] -> temp = 24
M[2] -> i = 6
M[3] -> j = 5
M[4] -> num = 5
// teste 4
programa {
funcao inicio () {
inteiro x, y = 0
para (x = 1; x <= 5; x++)
y = 1 + x
}
}
.data
_inicio_x : 0
_inicio_y : 0
.text
JMP _inicio
_inicio:
LDI 1
STO _inicio_x
para0:
LD _inicio_x
SUBI 5
BGT fimpara0
LDI 1
ADD _inicio_x
STO _inicio_y
LD _inicio_x
ADDI 1
STO _inicio_x
JMP para0
fimpara0:
HLT 0
16 1 0 0 M[0]-> x = 6
M[1]-> y = 6
// teste 5
programa {
funcao inicio () {
inteiro a = 2,b = 3,c = 0
c = a + b << 1 & 4 | ~1
escreva(c)
}
}
.data
_inicio_a : 2
_inicio_b : 3
_inicio_c : 0
temp0 : 0
.text
JMP _inicio
_inicio:
13 -2 0 1
M[0]-> a = 2
M[1]-> b = 3
M[2]-> c = -2
M[3]-> temp = -2
$out_port = -2
LDI 1
NOT 0
STO temp0
LD _inicio_a
ADD _inicio_b
SLL 1
ANDI 4
OR temp0
STO _inicio_c
LD _inicio_c
STO $out_port
HLT 0
// teste 6
programa {
funcao inicio() {
inteiro a=2, b=3, c=0
c = (a+b) << 1
escreva(c)
}
}
.data
_inicio_a : 2
_inicio_b : 3
_inicio_c : 0
.text
JMP _inicio
_inicio:
LD _inicio_a
ADD _inicio_b
SLL 1
STO _inicio_c
LD _inicio_c
STO $out_port
HLT 0
8 10 0 0
M[0]-> a = 2
M[1]-> b = 3
M[2]-> c = 10
$out_port = 10
//teste7
programa {
função inteiro
multiplica(inteiro a, inteiro c){
inteiro i, result = 0
para (i = 1; i <= c; i++)
result = result+a
retorne result
}
funcao inicio() {
inteiro j = 2, k =3
k = multiplica(k,j)
escreva(k)
}
}
.data
_multiplica_a : 0
_multiplica_c : 0
_multiplica_i : 0
_multiplica_result
: 0
_inicio_j : 2
_inicio_k : 3
.text
JMP _inicio
_multiplica:
LDI 1
STO _multiplica_i
para0:
LD _multiplica_i
SUB _multiplica_c
BGT fimpara0
LD
_multiplica_result
ADD _multiplica_a
STO
_multiplica_result
LD _multiplica_i
ADDI 1
STO _multiplica_i
JMP para0
fimpara0:
LD
_multiplica_result
RETURN 0
_inicio:
LD _inicio_k
STO _multiplica_a
LD _inicio_j
STO _multiplica_c
CALL _multiplica
STO _inicio_k
LD _inicio_k
STO $out_port
HLT 0
27 6 0 0
M[0]-> a = 3
M[1]-> c = 2
M[2]-> i = 3
M[3]-> result = 6
M[4]-> j = 2
M[5]-> k = 6
$out_port = 6
//teste8
programa {
.data
_multiplica_a : 0
_multiplica_c : 0
27 6 0 0
M[0]-> a = 3
M[1]-> c = 3
M[2]-> i = 4
funcao inteiro multiplica
(inteiro a, inteiro c) {
inteiro i, result =0
para (i = 1; i <= c; i++)
result = result + a
retorne result
}
funcao inteiro quadrado
(inteiro n) {
retorne multiplica(n, n)
}
funcao inicio() {
inteiro j = 2,k = 3
k = quadrado(j+1)
escreva(k)
}
}
_multiplica_i : 0
_multiplica_result
: 0
_quadrado_n : 0
_inicio_j : 2
_inicio_k : 3
.text
JMP _inicio
_multiplica:
LDI 1
STO _multiplica_i
para0:
LD _multiplica_i
SUB _multiplica_c
BGT fimpara0
LD
_multiplica_result
ADD _multiplica_a
STO
_multiplica_result
LD _multiplica_i
ADDI 1
STO _multiplica_i
JMP para0
fimpara0:
LD
_multiplica_result
RETURN 0
_quadrado:
LD _quadrado_n
STO _multiplica_a
LD _quadrado_n
STO _multiplica_c
CALL _multiplica
RETURN 0
_inicio:
LD _inicio_j
ADDI 1
STO _quadrado_n
CALL _quadrado
STO _inicio_k
LD _inicio_k
STO $out_port
HLT 0
M[3]-> result = 9
M[4]-> n = 3
M[5]-> j = 2
M[6]-> k = 9
$out_port = 9
// teste 9
programa {
funcao inicio () {
inteiro atual = 1, anterior =
0, proximo, saida[10], i = 1
enquanto (i < 10) {
saida[i] = atual
i = i + 1
proximo = anterior + atual
anterior = atual
atual = proximo
}
}
}
.data
_inicio_atual : 1
_inicio_anterior :
0
_inicio_proximo :
0
_inicio_saida : 0,
0, 0, 0, 0, 0, 0,
0, 0, 0
_inicio_i : 1
temp0 : 0
.text
JMP _inicio
_inicio:
enquanto0:
LD _inicio_i
SUBI 10
BGE fimenquanto0
LD _inicio_atual
STO temp0
LD _inicio_i
STO $indr
LD temp0
STOV _inicio_saida
LD _inicio_i
ADDI 1
24 0 1 1
M[0]-> atual = 55
M[1]-> anterior =
34
M[1]-> ultimo = 55
M[2]-> saida[0] =
0
M[4]-> saida[1] =
1
M[5]-> saida[2] =
1
M[6]-> saida[3] =
2
M[7]-> saida[4] =
3
M[8]-> saida[5] =
5
M[9]-> saida[6] =
8
M[10]-> saida[7] =
13
M[11]-> saida[8] =
21
M[12]-> saida[9] =
34
M[13]-> i = 10
M[14]-> temp0 = 34
STO _inicio_i
LD
_inicio_anterior
ADD _inicio_atual
STO
_inicio_proximo
LD _inicio_atual
STO
_inicio_anterior
LD _inicio_proximo
STO _inicio_atual
JMP enquanto0
fimenquanto0:
HLT 0
// teste 10
programa {
funcao inicio () {
inteiro vetor[5] =
{5,3,4,2,1}
inteiro i, j, aux
para (i = 0; i <= 4; i++) {
para (j = i + 1; j <= 4;
j++) {
se (vetor[i] > vetor[j])
{
aux = vetor[i]
vetor[i] = vetor[j]
vetor[j] = aux
}
}
}
}
}
.data
_inicio_vetor : 5,
3, 4, 2, 1
_inicio_i : 0
_inicio_j : 0
_inicio_aux : 0
temp0 : 0
.text
JMP _inicio
_inicio:
LDI 0
STO _inicio_i
para0:
LD _inicio_i
SUBI 4
BGT fimpara0
LD _inicio_i
ADDI 1
STO _inicio_j
para1:
LD _inicio_j
SUBI 4
BGT fimpara1
LD _inicio_j
STO $indr
LDV _inicio_vetor
STO temp0
LD _inicio_i
STO $indr
LDV _inicio_vetor
SUB temp0
BLE fimse0
LD _inicio_i
STO $indr
LDV _inicio_vetor
STO _inicio_aux
LD _inicio_j
STO $indr
LDV _inicio_vetor
STO temp0
LD _inicio_i
STO $indr
LD temp0
STOV _inicio_vetor
LD _inicio_aux
STO temp0
LD _inicio_j
STO $indr
LD temp0
STOV _inicio_vetor
fimse0:
LD _inicio_j
ADDI 1
STO _inicio_j
JMP para1
53 1 0 0
M[0]-> vetor[0] =
1
M[1]-> vetor[1] =
2
M[2]-> vetor[2] =
3
M[3]-> vetor[3] =
4
M[4]-> vetor[4] =
5
M[5]-> i = 5
M[6]-> j = 5
M[7]-> aux = 5
M[8]-> temp0 = 5
fimpara1:
LD _inicio_i
ADDI 1
STO _inicio_i
JMP para0
fimpara0:
HLT 0
// teste 11
programa {
funcao inicio() {
inteiro a, b, soma, sub
leia(a,b)
soma = a+b
sub = a-b
escreva(soma)
escreva(sub)
}
}
.data
_inicio_a : 0
_inicio_b : 0
_inicio_soma : 0
_inicio_sub : 0
.text
JMP _inicio
_inicio:
LD $in_port
STO _inicio_a
LD $in_port
STO _inicio_b
LD _inicio_a
ADD _inicio_b
STO _inicio_soma
LD _inicio_a
SUB _inicio_b
STO _inicio_sub
LD _inicio_soma
STO $out_port
LD _inicio_sub
STO $out_port
HLT 0
16 0 1 0
M[0]-> a = 1
M[1]-> b = 1
M[2]-> soma = 2
M[3]-> sub = 0
$in_port = 1
$out_port = 0
// teste 12
programa {
funcao inicio(){
inteiro a,b,c
leia (a,b,c)
se (a==b)
escreva (1)
senao {
se (a==b)
escreva (2)
senao
escreva (3)
}
}
}
.data
_inicio_a : 0
_inicio_b : 0
_inicio_c : 0
.text
JMP _inicio
_inicio:
LD $in_port
STO _inicio_a
LD $in_port
STO _inicio_b
LD $in_port
STO _inicio_c
LD _inicio_a
SUB _inicio_b
BNE else0
LDI 1
STO $out_port
JMP fimse0
else0:
LD _inicio_a
SUB _inicio_b
BNE else1
LDI 2
STO $out_port
JMP fimse1
else1:
LDI 3
STO $out_port
fimse1:
fimse0:
HLT 0
26 1 1 0
M[0]-> a = 1
M[1]-> b = 1
M[2]-> c = 1
$in_port = 1
$out_port = 1
//teste13
//Desvios Condicionais
// Escolha caso
programa {
funcao inicio() {
inteiro opc
leia(opc)
.data
_inicio_opc : 0
temp0 : 0
.text
JMP _inicio
_inicio:
LD $in_port
31 1 1 0
M[0]-> opc = 1
M[1]-> temp = 1
$in_port = 1
$out_port = 1
escolha (opc) {
caso 1:
escreva (1)
pare
caso 2:
escreva (2)
pare
caso 3:
escreva (3)
pare
caso contrario:
escreva (4)
}
}
}
STO _inicio_opc
LD _inicio_opc
STO temp0
caso0:
LD temp0
SUBI 1
BNE caso1
LDI 1
STO $out_port
JMP fimescolha0
caso1:
LD temp0
SUBI 2
BNE caso2
LDI 2
STO $out_port
JMP fimescolha0
caso2:
LD temp0
SUBI 3
BNE caso3
LDI 3
STO $out_port
JMP fimescolha0
caso3:
LDI 4
STO $out_port
fimescolha0:
HLT 0
//teste14
// Decremento
programa {
funcao inicio() {
inteiro contador = 10
enquanto (contador > 0) {
escreva (contador)
contador--
}
escreva (1000)
}
}
.data
_inicio_contador :
10
.text
JMP _inicio
_inicio:
enquanto0:
LD
_inicio_contador
SUBI 0
BLE fimenquanto0
LD
_inicio_contador
STO $out_port
LD
_inicio_contador
SUBI 1
STO
_inicio_contador
JMP enquanto0
fimenquanto0:
LDI 1000
STO $out_port
HLT 0
15 1000 1 0
M[0]-> contador =
0
out_port = 1000
//teste15
//Laços de Repetição
//faca enquanto
programa {
funcao inicio() {
inteiro idade
faca {
leia (idade)
} enquanto (idade > 150)
}
}
.data
_inicio_idade : 0
.text
JMP _inicio
_inicio:
facaenquanto0:
LD $in_port
STO _inicio_idade
LD _inicio_idade
SUBI 150
BLE
fimfacaenquanto0
JMP facaenquanto0
fimfacaenquanto0:
HLT 0
10 0 1 0
M[0]-> contador =
150
out_port = 150
// teste 16 .data 34 -1 0 1 M[0]-> vet[0] = 0
programa {
funcao inicio() {
inteiro vet[10], i
para(i = 0; i < 10; i++)
vet [i] = i
para(i = 9; i >=0; i--)
escreva (vet [i])
}
}
_inicio_vet : 0,
0, 0, 0, 0, 0, 0,
0, 0, 0
_inicio_i : 0
temp0 : 0
.text
JMP _inicio
_inicio:
LDI 0
STO _inicio_i
para0:
LD _inicio_i
SUBI 10
BGE fimpara0
LD _inicio_i
STO temp0
LD _inicio_i
STO $indr
LD temp0
STOV _inicio_vet
LD _inicio_i
ADDI 1
STO _inicio_i
JMP para0
fimpara0:
LDI 9
STO _inicio_i
para1:
LD _inicio_i
SUBI 0
BLT fimpara1
LD _inicio_i
STO $indr
LDV _inicio_vet
STO $out_port
LD _inicio_i
SUBI 1
STO _inicio_i
JMP para1
fimpara1:
HLT 0
M[1]-> vet[1] = 1
M[2]-> vet[2] = 2
M[3]-> vet[3] = 3
M[4]-> vet[4] = 4
M[5]-> vet[5] = 5
M[6]-> vet[6] = 6
M[7]-> vet[7] = 7
M[8]-> vet[8] = 8
M[9]-> vet[9] = 9
M[10]-> i = -1
$out_port = 0
//teste17
programa {
funcao inicio() {
inteiro idade
faca {
leia (idade)
} enquanto (idade > 150)
}
}
.data
_inicio_idade : 0
.text
JMP _inicio
_inicio:
facaenquanto0:
LD $in_port
STO _inicio_idade
LD _inicio_idade
SUBI 150
BLE
fimfacaenquanto0
JMP facaenquanto0
fimfacaenquanto0:
HLT 0
//teste18
programa {
funcao inicio() {
const inteiro TAM = 5
inteiro c
inteiro vet[TAM]
para(c = 0; c < TAM; c++) {
se (0 ==c)
vet[c] = 1
senao
vet [c] = 0
escreva(vet[c])
}
.data
_inicio_TAM : 5
_inicio_c : 0
_inicio_vet : 0,
0, 0, 0, 0
temp0 : 0
.text
JMP _inicio
_inicio:
LDI 0
STO _inicio_c
para0:
LD _inicio_c
35 0 1 0
M[0]-> TAM = 5
M[1]-> c = 5
M[2]-> vet[0] = 1
M[3]-> vet[1] = 0
M[4]-> vet[2] = 0
M[5]-> vet[3] = 0
M[6]-> vet[4] = 0
M[7]-> temp0 = 0
}
}
SUB _inicio_TAM
BGE fimpara0
LDI 0
SUB _inicio_c
BNE else0
LDI 1
STO temp0
LD _inicio_c
STO $indr
LD temp0
STOV _inicio_vet
JMP fimse0
else0:
LDI 0
STO temp0
LD _inicio_c
STO $indr
LD temp0
STOV _inicio_vet
fimse0:
LD _inicio_c
STO $indr
LDV _inicio_vet
STO $out_port
LD _inicio_c
ADDI 1
STO _inicio_c
JMP para0
fimpara0:
HLT 0
APÊNDICE E. PROGRAMAS ASSEMBLY UTILIZADOS
PARA VALIDAÇÃO DO COMPILADOR
Instrução Sequência de instruções
testadas
PC ACC Z N Memória
ADD .text
ldi 0x001
sto $14
ldi 0x003
add $14
4 4 0 0 M[14] = 1
ADDI .text
ldi 0x003
addi 0x004
2 7 0 0
AND .text
ldi 0x00C
sto $15
ldi 0x007
and $15
4 4 0 0 M[15] = 12
ANDI .text
ldi 0x00C
andi 0x007
2 4 0 0
BEQ .text
ldi 0x004 4 0 1 0
subi 0x004
beq __end
ldi 0x055
__end:
BEQ .text
ldi 0x005
subi 0x004
beq __end
ldi 0x055
__end:
5 85 0 0
BGE .text
ldi 0x004
subi 0x004
bge __end
ldi 0x055
__end:
5 0 1 0
BGE .text
ldi 0x005
subi 0x004
bge __end
ldi 0x055
__end:
5 1 0 0
BGE .text
ldi 0x004
subi 0x005
bge __end
ldi 0x055
__end:
5 85 0 1
BGT .text
ldi 0x004
subi 0x003
bgt __end
ldi 0x055
__end:
5 1 0 0
BGT .text
ldi 0x003
subi 0x003
bgt __end
ldi 0x055
__end:
5 85 1 0
BGT .text
ldi 0x004
subi 0x005
bgt __end
ldi 0x055
__end:
5 85 0 1
BLE .text
ldi 0x004
subi 0x004
ble __end
ldi 0x055
__end:
5 0 1 0
BLE .text
ldi 0x003
subi 0x004
ble __end
ldi 0x055
__end:
5 -1 0 1
BLE .text
ldi 0x005
subi 0x004
ble __end
ldi 0x055
__end:
5 85 0 0
BLT .text
ldi 0x003
subi 0x004
blt __end
ldi 0x055
__end:
5 -1 0 1
BLT .text
ldi 0x003
subi 0x003
blt __end
ldi 0x055
__end:
5 85 1 0
BLT .text
ldi 0x005
subi 0x004
blt __end
ldi 0x055
__end:
5 85 0 0
BNE .text
ldi 0x004
subi 0x003
bne __end
ldi 0x055
__end:
5 1 0 0
BNE .text
ldi 0x003
subi 0x003
bne __end
ldi 0x055
__end:
5 85 1 0
CALL .text
ldi 0x003
sto $14
ldi 0x002
sto $15
call __sum
addi 0x001
jmp __end
__sum:
ld $14
add $15
return
__end:
12 6 0 0 M[14] = 3
M[15] = 2
HLT .text
ldi 0x004
hlt
ldi 0x055
1 4 0 0
JMP .text
ldi 0x004
jmp __end
ldi 0x055
__end:
4 4 0 0
LD .text
ldi 0x044
sto $15
ldi 0x055
sto $16
ld $15
5 68 0 0
LDI .text
ldi 0x055 2 68 0 0
LDV .text
main:
ldi 1
sto $2
sto $0
for:
subi 2
bgt endfor
ld $0
subi 1
sto $indr
ldv $2
addi 1
sto $1
ld $0
sto $indr
ld $1
stov $2
ld $0
addi 1
sto $0
jmp for
endfor:
ldi 0
sto $0
print:
subi 2
bgt endprint
ld $0
sto $indr
ldv $2
sto $port0_data
ld $0
addi 1
sto $0
jmp print
endprint:
hlt 0
endmain:
36 1 0 0
M[0] = 3
M[1] = 3
M[2] = 1
M[3] = 2
M[4] = 3
NOT .text
ldi 0x00F
not 0
2 -16 0 1
OR .text
ldi 0x008
sto $15
ldi 0x007
or $15
4 15 0 0 M[15] = 8
ORI .text
ldi 0x008
ori 0x007
2 15 0 0
RETURN .text 12 6 0 0 M[14] = 3
ldi 0x003
sto $14
ldi 0x002
sto $15
call __sum
addi 0x001
jmp __end
__sum:
ld $14
add $15
return
__end:
M[15] = 2
SLL .text
ldi 0x004
sll 0x001
2 8 0 0
SRL .text
ldi 0x004
sll 0x001
2 2 0 0
SUB .text
ldi 0x00A
sto $15
ldi 0x00A
sub $15
4 0 1 0 M[15] = 10
SUB .text
ldi 0x004
sto $15
ldi 0x003
sub $15
4 -1 0 1 M[15] = 4
SUB .text
ldi 0x004
sto $15
ldi 0x005
sub $15
4 1 0 0 M[15] = 4
SUBI .text
ldi 0x002
subi 0x005
2 -3 0 1
SUBI .text
ldi 0x005
subi 0x002
2 0 0 0
SUBI .text
ldi 0x005
subi 0x005
2 0 1 0
XOR .text
ldi 0x005
sto $15
ldi 0x00A
xor $15
4 15 0 0 M[15] = 5
XORI .text
ldi 0x005
xori 0x00A
2 15 0 0
APÊNDICE F. ARTEFATOS DE ENGENHARIA DE
SOFTWARE DO PROJETO
Este apêndice apresenta os artefatos de engenharia de software desenvolvidos durante
o período dedicado ao projeto deste trabalho.
F.1.1. Requisitos Funcionais
RF01: O sistema deverá permitir ao usuário criar um cadastro.
RF02: O sistema deverá permitir ao usuário autenticar-se através credenciais.
RF03: O sistema deverá disponibilizar ao usuário um editor de textos com
funcionalidades típicas de ambientes de desenvolvimento.
RF04: O sistema deverá permitir ao usuário escrever programas em linguagem
Portugol.
RF05: O sistema deverá gerar código em linguagem de montagem dos
processadores da família BIP equivalente aos programas escritos em Portugol.
RF06: O sistema deverá permitir ao usuário escrever programas em linguagem de
montagem dos processadores da família BIP.
RF07: O sistema deverá permitir armazenar os programas escritos pelos usuários.
RF08: O sistema deverá permitir que os usuários recuperem os programas
escritos anteriormente.
RF09: O sistema deverá permitir ao usuário simular a execução dos programas
criados sobre a arquitetura dos processadores da família BIP.
RF10: O sistema deverá permitir ao usuário simular a execução passo-a-passo dos
programas criados sobre a arquitetura dos processadores da família BIP.
RF11: O sistema deverá possuir um módulo de ajuda.
F.1.2. Requisitos Não Funcionais
RNF01: O sistema deverá funcionar corretamente nos navegadores Mozilla
Firefox, Google Chrome e Microsoft Edge em suas versões mais atuais,
considerando o momento em que este trabalho está sendo desenvolvido.
RNF02: O sistema deverá possuir uma arquitetura cliente-servidor.
RNF03: O back-end do sistema deverá disponibilizar uma API REST para ser
consumida por aplicações clientes.
RNF04: Os módulos de back-end e front-end do sistema deverão ser
desacopláveis.
RNF05: A autenticação dos usuários do sistema deverá acontecer via a utilização
de um token.
F.1.3. Modelo de Casos de Uso
Esta subseção apresenta o modelo de casos de uso desenvolvido, assim com os
cenários correspondentes.
F.1.3.1. UC01. Cria Cadastro
Permite ao usuário criar um cadastro no sistema Bipide Web.
Cenários
Cria Cadastro {Principal}
1. O usuário acessa a tela de cadastro do sistema.
2. O usuário preenche os campos solicitados.
3. O usuário clica no botão Salvar.
4. O sistema armazena os dados informados pelo usuário.
Campos obrigatórios não informados {Exceção}
1.No passo 3 do cenário principal, caso o usuário não tenha informado algum campo
obrigatório do formulário de cadastro, o sistema deverá apresentar uma mensagem
contendo a lista de campos obrigatórios não preenchidos e interromper o cenário.
F.1.3.2. UC02. Autentica-se no Sistema
Permite ao usuário, com cadastro criado previamente, autenticar-se no sistema.
Cenários
Autenticar-se no sistema {Principal}
1.O usuário acessa a tela de autenticação do sistema.
2.O usuário preenche os campos “Login” e “Senha”.
3.O Usuário clica no botão “Entrar”.
4.O sistema valida as credenciais do usuário.
5.O sistema redireciona o usuário para a tela de edição de programa.
Campo não preenchido {Erro}
1.No passo 2 do cenário principal, caso o usuário não tenha preenchido algum dos
campos solicitados, o sistema deverá apresentar mensagem adequada informando o
erro ocorrido e interromper o cenário.
Credenciais inválidas {Erro}
1.No passo 4 do cenário principal, caso as credenciais informadas pelo usuário sejam
consideradas inválidas pelo sistema, este deverá apresentar mensagem adequada
informando o erro ocorrido e interromper o cenário.
F.1.3.3. UC03. Escreve Programa em Portugol
Permite ao usuário devidamente autenticado escrever programas na linguagem
Portugol.
Cenários
Escreve Programa em Portugol {Principal}
1.O usuário, devidamente autenticado, acessa a tela do editor de código fonte do
Bipide Web.
2.O usuário cria um novo programa em Portugol.
3.O usuário digita o código-fonte do programa em Portugol.
4.O usuário salva o programa escrito.
Usuário não autenticado {Erro}
1.No passo 1 do cenário principal, caso o usuário não esteja devidamente autenticado,
o sistema deverá apresentar mensagem adequada informando o erro e executar
UC01.
F.1.3.4. UC04. Escreve Programa em Assembly
Permite ao usuário devidamente autenticado escrever programas na linguagem de
montagem dos processadores da família BIP.
Cenários
Escreve Programa em Linguagem de Montagem do BIP {Principal}
1.O usuário, devidamente autenticado, acessa a tela do editor de código fonte do
Bipide Web.
2.O usuário cria um novo programa em assembly.
3.O usuário digita o código-fonte do programa em assembly.
4.O usuário salva o programa escrito.
Usuário não autenticado {Erro}
1.No passo 1 do cenário principal, caso o usuário não esteja devidamente autenticado,
o sistema deverá apresentar mensagem adequada informando o erro e executar
UC01.
F.1.3.5. UC05. Compila Programa
Permite ao usuário compilar os programas escritos para a linguagem de montagem dos
processadores da família BIP.
Cenários
Compila Programa {Principal}
1.O usuário clica no botão Compilar.
2.O sistema realiza as etapas de análise léxica, sintática, semântica e geração de
código sobre o programa escrito pelo usuário.
3.O usuário recebe mensagem de informando o resultado da compilação.
Erro de Compilação {Erro}
1.No passo 2 do cenário principal, caso o sistema encontre algum erro em alguma das
etapas executadas, o mesmo deverá alertar o usuário através de uma mensagem
apropriada.
F.1.3.6. UC06. Simula a Execução
Permite ao usuário simular a execução dos programas compilados sobre a arquitetura e
organização dos processadores da família BIP.
Cenários
Simula a Execução {Principal}
1.Na tela de simulação de execução, o usuário seleciona a versão do BIP sobre o qual
quer executar a simulação.
2.O sistema apresenta a representação da arquitetura do BIP selecionado.
3.O usuário clica no botão Simular.
4.O sistema executa a simulação sobre a arquitetura e organização do BIP selecionado.
F.1.3.7. Utiliza Módulo de Ajuda
Permite ao usuário utilizar o módulo de ajuda para obter informações sobre a
arquitetura e organização dos processadores BIP e sobre o ambiente de desenvolvimento.
Cenários
Utiliza o Módulo de Ajuda {Principal}
1.O usuário seleciona o módulo de ajuda.
2.O sistema apresenta o módulo de ajuda, contendo informações sobre a arquitetura e
organização dos processadores da família BIP e sobre o ambiente de
desenvolvimento.
F.1.4. Protótipos de tela
Esta subseção apresenta os protótipos de tela desenvolvidos durante o projeto deste
trabalho de conclusão.
Protótipo de tela do módulo de edição de programa:
Protótipo de tela do módulo de simulação:
Protótipo de tela do módulo de ajuda: