Ambiente para desenvolvimento e execução de aplicações escritas em HoloLinguagem
Published: 2024-01-02 18:15:54

Durante o seu doutorado na [UFRGS](http://www.ufrgs.br/ufrgs/inicial) o professor [Jorge Barbosa](https://www.linkedin.com/in/jorge-barbosa-a0688320b/) criou o [Holoparadigma](https://lume.ufrgs.br/handle/10183/2255), um novo [paradigma de programação](https://en.wikipedia.org/wiki/Programming_paradigm) que dava suporte ao desenvolvimento de [aplicações distribuídas](https://en.wikipedia.org/wiki/Distributed_computing). Algumas características deste paradigma (citados mais abaixo) facilitavam (e muito) o desenvolvimento de aplicações móveis, algo bem inovador para a época (ano de 2000, aproximadamente).

Como prova de conceito deste novo paradigma foi criado um ambiente de desenvolvimento e execução de aplicações (figura abaixo).

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/001sblnqd9ek8d5ozlzh.png)

Nesta figura temos os seguintes componentes:

- Programa Holo: Programa escrito em HoloLinguagem, uma [linguagem de programação](https://en.wikipedia.org/wiki/Programming_language) acadêmica que implementa o HoloParadigma
- HoloJava: [Compilador](https://en.wikipedia.org/wiki/Compiler) que traduz um programa em HoloLinguagem para código [Java](https://en.wikipedia.org/wiki/Java_(programming_language))
- [Compilador Java (JavaC)](https://en.wikipedia.org/wiki/Javac): Compilador que processa o código gerado pelo HoloJava e gera o [_bytecode_](https://en.wikipedia.org/wiki/Bytecode) para ser executado na JVM
- [Máquina Virtual Java (JVM)](https://en.wikipedia.org/wiki/Java_virtual_machine): Máquina virtual que executa o _bytecode_ gerado pelo JavaC

O principal objetivo desde ambiente era possibilitar a execução dos exemplos em HoloLinguagem.

Abaixo temos um exemplo em HoloLinguagem que demonstra como o paralelismo e a sincronia são explorados. Entes são um conceito elementar do HoloParadigma, sendo similares às classes do paradigma OO. Neste exemplo o Holo, que é o ente principal de um programa, cria dois novos entes (a partir de ente_paralelo) e aguarda que terminem sua execução. Para sincronia é utilizado um _blackboard_ (o _history_) onde cada ente insere a chave "terminei" em conjunto com o seu ID. Por sua vez, o ente Holo aguarda em _history_ o término dos entes.

```
holo() {
   holo() {
      writeln('Exemplo que demonstra paralelismo e sincronia'),
      clone(ente_paralelo(1), ente_paralelo1),
      clone(ente_paralelo(2), ente_paralelo2), 
      for X := 1 to 5 do {
         writeln('Ente holo esta na iteracao ', X)
      }
      // aguarda o término dos entes clonados
      history#terminei(#Id),
      // informa qual ente terminou
      writeln('Ente ', Id, ' terminou...'),
      // aguarda o término dos entes clonados
      history#terminei(#Id),
      // informa qual ente terminou
      writeln('Ente ', Id, ' terminou...')
   }
}

ente_paralelo() {
   ente_paralelo(Id) {
      for X := 1 to 20 do {
         writeln('Ente ', Id, ' esta na iteracao ', X)
      }
      // sinaliza na história externa que terminou
      out(history)!terminei(Id)
   }
}
```

Porém, durante o seu doutorado, não foi possível explorarem alguns recursos da HoloLinguagem, em especial alguns conceitos da computação móvel como mover aplicações em execução para outros dispositivos e o compartilhamento de dados entre aplicações distribuídas.

É neste momento que eu entro no projeto. Em 2002 o tema do meu TCC na [UNISINOS](https://www.unisinos.br/) foi sobre como criar um ambiente de desenvolvimento e execução para aplicações escritas em HoloLinguagem. Meu orientador foi o Barbosa, um professor fantástico 🙂

Na época tínhamos 3 opções para implementar estes conceitos da computação móvel e explorar ainda mais as potencialidades da HoloLinguagem:

- Implementar através de bibliotecas e usar a estrutura atual do projeto: neste caso teríamos que alterar o compilador (HoloJava) para que reconhecesse os novos comandos e criar as bibliotecas necessárias
- Implementar diretamente na JVM através de novos [_opcodes_](https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html): neste caso, além de alterar a JVM, teríamos que alterar o JavaC ou então gerar diretamente _bytecode_ para a JVM
- Criar uma nova VM com suporte a estes novos conceitos: neste caso teríamos que criar um novo compilador e uma nova VM

Entendi que seria mais interessante (e divertido) a última opção, o famoso “reinventar a roda”, e foi o que eu fiz 🙂

A figura abaixo contém a proposta do meu TCC: implementar um novo ambiente para o desenvolvimento e execução de aplicações escritas em HoloLinguagem. Seguindo alguns aprendizados de um [projeto anterior] (https://dev.to/alexgarzao/compilador-para-um-subset-de-pascal-27b1), optei por criar também o HoloAssembly, uma linguagem intermediária para facilitar os testes e a implementação do projeto.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qag12uixyi1o7sblrh29.png)

Nesta figura temos os seguintes componentes:

- Programa Holo: Programa escrito em HoloLinguagem que implementa o HoloParadigma
- HoloC: É o compilador que traduz aplicações escritas em HoloLinguagem para HoloAssembly, uma linguagem intermediária
- HoloASM: É o [montador _assembly_](https://en.wikipedia.org/wiki/Assembly_language#Assembler) responsável por traduzir HoloAssembly para o _bytecode_ que a HoloVM entende
- HoloVM: É a [máquina virtual (VM)] (https://en.wikipedia.org/wiki/Virtual_machine) capaz de dar suporte à execução das aplicações de forma distribuída

[Aqui](https://docplayer.com.br/89487224-Holovm-uma-maquina-virtual-com-suporte-a-concorrencia-mobilidade-e-blackboards.html) tem um artigo publicado no WSCAD de 2002 sobre o meu TCC.

Como [gerador de parsers](https://en.wikipedia.org/wiki/Compiler-compiler) utilizei o YAPG (_Yet Another Parser Generator_), um projeto pessoal que irei abordar em outra publicação. Basicamente o YAPG tinha como entrada uma gramática [EBNF](https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form) da HoloLinguagem contendo ações codificadas em [C++](https://en.wikipedia.org/wiki/C%2B%2B), o que resultava em um parser em C++ que entendia código escritos na HoloLinguagem e executava as ações determinadas. Este parser nada mais era que o HoloC. Da mesma forma, o HoloASM também era gerado através do YAPG.

Para exemplificar o processo de compilação do HoloC vou usar o “Hello world” em HoloLinguagem abaixo:

```
holo() {
   holo() {
      writeln('Hello world !!!')
   }
}
```

Para o código acima o HoloC gerava o seguinte código em HoloAssembly:

```
holo
    holo( )
        ;; V1 := 'Hello world !!!',
        lsb  	'Hello world !!!'
        sv   	V1
        ;; writeln(V1)
        lv   	V1
        wr   
        wrln 
    end
end
```

Por sua vez, o HoloASM gerava o seguinte _bytecode_ para a HoloVM:

```
Header
    Magic number : 0xB0 0xCA 0xBA 0xBE
    File type    : HoloVM Version 0.1
    Major version: 0
    Minor version: 1

Constant pool size: 4
    000:    Size:   4	Type: 1-->[symbol]    Info: [holo]
    001:    Size:   6	Type: 1-->[symbol]    Info: [holo/0]
    002:    Size:  15	Type: 3-->[string]    Info: [Hello world !!!]
    003:    Size:   2	Type: 3-->[string]    Info: [V1]

Static beings count: 1
    Being cpindex: [000]-->[holo]
    Action count : 1
    Action 0
        Action cpindex: [001]-->[holo/0]
        Bytecode size : 9
            000:    lsb    [002]-->[Hello world !!!]
            002:    sv     [003]-->[V1]
            004:    lv     [003]-->[V1]
            006:    wr
            007:    wrln
            008:    ret
```

Quem conhece a estrutura da JVM vai perceber as semelhanças com o _assembly_ da HoloVM. E, assim como a JVM, a HoloVM é uma [_stack based machine_](https://en.wikipedia.org/wiki/Stack_machine).

Posso dizer que foi um projeto muito divertido, mas que gerou muito trabalho, muito mesmo. Mas o resultado compensou o esforço :-)

Sei que muita coisa ficou "vaga", em especial sobre o HoloAssembly e a HoloVM. Infelizmente não tenho nada funcional para compartilhar. Encontrei parte do código destes projetos em backups antigos, mas não consegui nem rodar eles localmente. Enfim, muito do material que coloquei nesta publicação foram retirados das apresentações da época. 

Mas, para tentar compensar a falta de detalhes aqui, logo que possível vou iniciar um projeto open source de um compilador. Já adianto que este novo projeto será em [Go](https://en.wikipedia.org/wiki/Go_(programming_language)) e irei utilizar um gerador de parsers bem conhecido.

Feedbacks são muito bem-vindos :-)