Qual a diferença entre um compilador, um interpretador e uma máquina virtual? Estou no caminho certo?
O que eu ACHO que sei:
Compilador é um software que decodifica um arquivo texto e gera um novo arquivo contendo instruções do processador.
Interpretador é um software que decodifica um arquivo texto de comandos escritos uma linguagem X ao mesmo tempo em que executa instruções do processador com base no que foi decodificado.
Máquina Virtual é um software que decodifica um arquivo texto de instruções de um processador ficíticio ao mesmo mesmo tempo em que executa instruções do processador real com base no que foi decodificado.
Sei que estou sendo muito simplista tentando descrever esses conceitos com um parágrago e que também ocorre compilação de partes do código dentro de máquinas virtuais e interpretadores mas gostaria de saber se estou no caminho certo para entender essas três coisas, por favor me corrijam e também adicionem o que acharem que preciso saber, obrigado.
Dá uma lida: https://www.tabnews.com.br/maniero/67b181b2-065d-4553-8505-babac914f06f
A máquina virtual decodifica alguma coisa, não precisa ser texto, geralmente não é.
A grosso modo você está certo. Claro que isso é uma simplificação, como já sabe.
Farei algo que muitos pedem para aprender a programar corretamente, gratuitamente. Para saber quando, me segue nas suas plataformas preferidas. Quase não as uso, não terá infindas notificações (links aqui).
Compilador é um software que decodifica um arquivo texto e gera um novo arquivo contendo instruções do processador
O arquivo original não é necessariamente texto, assim como o resultado pode não ser específico do processador. Só para dar um exemplo rápido, escrevi aqui sobre como funciona em Java:
Inicialmente temos o código fonte (o arquivo
.java
). Ao compilá-lo, é gerado um arquivo.class
, contendo o bytecode, que não deixa de ser "binário". Lembrando que aqui o termo "binário" geralmente quer dizer que "não é texto" - porque se formos levar ao pé da letra, tudo no computador vira binário no fim das contas (até texto), mas para o caso em questão, vamos considerar que binário é "um monte de bytes que não correspondem a um texto".Ou seja, o
.class
já é um tipo de "binário". Ele contém o bytecode, que são as instruções que serão interpretadas pela máquina virtual (a JVM - Java Virtual Machine). Só que a JVM possui outro compilador (mais precisamente, um JIT - Just In Time compiler), que pode pegar trechos do bytecode e compilar novamente, gerando código de máquina específico da plataforma/sistema operacional no qual ela está rodando. Na verdade é mais complexo que isso, veja mais detalhes aqui.Ou seja, a partir do código fonte, é gerado o bytecode (um tipo de arquivo "binário"), que por sua vez pode ser transformado em código de máquina nativo (dependente da plataforma/arquitetura/processador/sistema operacional/etc), e portanto é "outro binário".
Ou seja, o compilador Java trabalha com texto (o código fonte) e transforma em bytecode (instruções da JVM - a máquina virtual Java - que não são específicas de nenhum processador). E dentro da JVM tem outro compilador que não trabalha com texto, e sim com bytecode: é ele que converte o bytecode (que não é texto) para código específico do processador.
Pra complicar um pouco mais, existe ainda o transpilador, que também é chamado de "source to source compiler", ou seja, traduz código de uma linguagem para outra (converte texto para outro texto). Não deixa de ser um tipo específico de compilador. O exemplo mais famoso hoje é o TypeScript, cujo código é transpilado para JavaScript.
E como já dito por outros, hoje em dia as coisas estão mais complicadas e misturadas, em muitos casos é difícil traçar uma linha onde começa um e termina o outro. Como muita coisa na nossa área, os termos não possuem definições "oficiais", cada um usa de um jeito, e muitas fontes acabam chamando as coisas por nomes diferentes ou fazendo distinções que nem sempre se aplicam.