Por mais diversificados que sejam, existem alguns conceitos comuns que todas as linguagens de programação modernas sérias compartilham. Dois deles são o núcleo da resposta para suas perguntas acima.
Quais etapas acontecem entre eu pressionar o botão Enter e o código da máquina gerado a partir do meu código python sendo executado na minha CPU?
O código é analisado, analisado e alimentado em um intérprete. Isso é tudo sobre uma área muito importante da ciência da computação conhecida como teoria dos compiladores . Um compilador é um programa que converte código de um idioma (seu código-fonte) para outro idioma (normalmente código de máquina, embora existam "transpilers" que traduzem de um idioma de alto nível para outro). Este é um tópico realmente enorme que você poderia passar anos pesquisando, mas aqui está a versão básica:
O compilador começa com um analisador , uma rotina que lê seu código-fonte e aplica as regras de sintaxe da linguagem a ele para descobrir se faz sentido como código Python (no seu caso) válido. Caso contrário, o analisador emitirá um erro e o compilador falhará, mas, se o fizer, o analisador emitirá o que é conhecido como Árvore de Sintaxe Abstrata, ou AST, abreviado. O AST é uma estrutura de dados em árvore cujos nós contêm um elemento da sintaxe. Por exemplo, se você disser x = 5
, poderá terminar com um BinaryExpression
nó com um operator
valor de =
, um Left
valor de ReferenceExpression(x)
e um Right
valor de IntegerLiteralExpression(5)
. Todo o seu programa pode ser representado por uma grande árvore como esta.
Depois que o analisador produz um AST, a segunda fase é a análise semântica . Em inglês simples, isso significa "descobrir o que esse AST significa". Ele verifica o AST para determinar se você fez algo ilegal, embora seja uma análise válida (por exemplo, tentando chamar uma função de 1 argumento com 3 argumentos) e gera erros se você o fizer. Caso contrário, ele analisa o AST e realiza edições para facilitar a compreensão de uma máquina.
A terceira fase é a geração de código. Depois de ter um AST totalmente analisado, simplificado e válido, você o alimenta no gerador, que percorre o AST e produz código no idioma de saída. Este é o seu produto acabado.
Com o Python, ele usa um intérprete em vez de um compilador. Um intérprete funciona exatamente da mesma maneira que um compilador, com uma diferença: em vez da geração de código, ele carrega a saída na memória e a executa diretamente no seu sistema. (Os detalhes exatos de como isso acontece podem variar bastante entre diferentes idiomas e diferentes intérpretes.)
E como isso se relaciona com o sistema de tempo de execução Python e / ou biblioteca?
Todos os idiomas, exceto os mais simples, vêm com um conjunto de funções predefinidas que são importantes para uma grande porcentagem de usuários e que dificilmente seriam implementados por um motivo ou outro. O código deles pode chamar essas funções sem precisar de bibliotecas de terceiros. (Por exemplo, em Python, você print
envia uma saída para stdout
. Boa sorte implementando isso por conta própria!) Esse conjunto de funções geralmente é coletado em uma biblioteca compartilhada na qual o código pode ser chamado em tempo de execução, e é por isso que é conhecido como a biblioteca de tempo de execução do idioma ou simplesmente "o tempo de execução" para abreviar.