
Swift não é apenas uma linguagem de programação. Este é um projeto que, além do compilador, inclui muitos outros componentes. E o compilador em si não é uma caixa grande e terrível, que com a ajuda da magia transforma seu código em um conjunto de instruções compreensíveis para a máquina. Também pode ser dividido em componentes. Se você está interessado em quais, bem-vindo ao gato.
Não sou especialista em compiladores e não tenho experiência nessa área. Mas imaginei como isso funcionaria e comecei a estudar o compilador Swift. Como o artigo acabou sendo muito grande, eu tive que dividi-lo em 4 partes:
- visão geral geral dos componentes
- analisando o arquivo de origem,
- Linguagem intermediária rápida,
- LLVM IR e geração de código.
Swift
Swift é um projeto de código aberto há mais de dois anos. Durante esse período, muitas melhorias da comunidade foram adicionadas a ele. Você pode segui-los em um site especial e também no fórum . Lá você pode discutir sugestões para melhorar o idioma ou expor suas idéias. Mas, para fazer isso, primeiro você precisa descobrir como o projeto funciona.
Biblioteca padrão Swift

As principais partes do Swift, é claro, são o compilador e a biblioteca de funções padrão. Eles se desenvolvem em paralelo e são praticamente inseparáveis um do outro.
O compilador é escrito em C ++, e a parte principal do stdlib está no Swift. No entanto, o idioma usado possui vários recursos:
- A biblioteca padrão através do módulo Builtin tem acesso direto às funções do compilador. Isso permite que ela acesse representações de idioma de baixo nível e ponteiros brutos.
- A biblioteca padrão não usa o modificador de acesso privado. Em vez disso, nomes de entidades não públicas começam com um sublinhado. Leia mais aqui .
- Ele usa a geração de código usando o utilitário GYB ( Generate Your Boilerplate ) para reduzir a repetição no código da biblioteca padrão.
A biblioteca padrão geralmente é associada a contêineres e funções úteis que simplificam a vida do desenvolvedor, mas essa é apenas uma parte. No total, podemos distinguir os 3 componentes mais interessantes:
- Core Um kernel com todos os seus protocolos, tipos de dados e funções. Fontes .
- Tempo de execução Uma camada intermediária entre a biblioteca padrão e o compilador. Ele é responsável pela conversão de tipos, trabalhando com memória, reflexão e outros recursos dinâmicos da linguagem. Escrito em C ++ e Objective-C. Fontes .
- Sobreposições do SDK. Invólucros sobre o Foundation e outras estruturas de sistema que tornam o acesso a partir do Swift mais conveniente. Fontes .
Outros subprojetos

Além do compilador e da biblioteca padrão, existem muitos outros subprojetos no domínio público. Alguns deles estão listados abaixo.
Sourcekit
Estrutura de suporte do IDE : indexação, destaque de sintaxe, conclusão de código e assim por diante.
SourceKit-LSP
Uma implementação do LSP para Swift , com base no SourceKit. Você pode ler sobre o que é aqui .
Gerenciador de pacotes Swift
Gerente de pacotes para projetos no Swift.
Fundação
Porta da biblioteca da Foundation , que é um dos principais do SO da Apple para plataformas de terceiros.
libdispatch (gcd)
GCD para plataformas de terceiros.
XCTest
XCTest para plataformas de terceiros.
LLDB
LLDB com suporte Swift e REPL.
Suporte para parque infantil
O projeto inclui duas estruturas - PlaygroundSupport e PlaygroundLogger. Eles fornecem interação com o Xcode e uma bela exibição de dados, respectivamente.
llbuild
Construa o sistema .
gyb
Utilitário para geração de código.
libcxx
Implementação da biblioteca C ++ padrão.
Compilador Swift

Um compilador no sentido mais amplo é um programa que converte código de um idioma para outro. Mas, na maioria das vezes, a compilação se refere à conversão do código-fonte em código de máquina (ou em outra representação de baixo nível), que pode ser usada para criar um arquivo executável.
O compilador geralmente é dividido em três partes: frontend, middlend, backend. O primeiro é responsável por converter o código fonte em uma representação intermediária, o que é conveniente para o compilador trabalhar. Middlend realiza a otimização, e o back-end gera código de máquina a partir da representação intermediária otimizada.
No entanto, no Swift, a otimização é realizada no front-end e (a maioria) no back-end. Portanto, a etapa intermediária no diagrama não é mostrada.
LLVM

O compilador Swift usa LLVM como back-end. O LLVM é um grande projeto que inclui muitas tecnologias. É baseado na representação intermediária (IR). Essa é uma representação de código intermediário universal que pode ser convertida em código executável em qualquer plataforma suportada pelo LLVM.
Se uma nova arquitetura aparecer, será suficiente adicionar no LLVM a geração de código de máquina do IR para esta plataforma. Depois disso, todos os idiomas para os quais existe um compilador com geração de IR oferecerão suporte a essa arquitetura.
Por outro lado, para criar um compilador para uma nova linguagem de programação, basta escrever uma tradução do código fonte no IR, e o LLVM cuidará das várias arquiteturas.
Outra vantagem desse sistema é que o LLVM pode otimizar a apresentação intermediária e o front-end pode não estar envolvido na otimização. Isso simplifica bastante o desenvolvimento do compilador.
O IR possui três tipos de exibição:
- Uma árvore de objetos na memória. Cada objeto corresponde a uma determinada entidade no código-fonte: função, operador, linha, ponteiro e assim por diante. Essa árvore é criada pelo frontend no estágio de geração do IR.
- Visualização de texto. O IR pode ser inferido como código-fonte de baixo nível. Ele pode ser salvo em um arquivo e executado usando o intérprete.
- O formato de bit serializado é "código de bit" (não deve ser confundido com o bytecode usado, por exemplo, em Java). Ele pode ser usado como resultado final do back-end e transferido para o vinculador para otimização no nível do link. A conversão em código de máquina, neste caso, será realizada pelo vinculador.
Linker é um programa que gera um arquivo executável. Sua descrição está além do escopo do artigo.
O código fonte da versão LLVM usada no Swift pode ser encontrado aqui e a documentação no site oficial.
Como você pode ver, a Apple publicou muitos projetos interessantes em acesso aberto. Na próxima parte , falarei sobre a análise do arquivo de origem e a geração do AST.