Aprendendo compiladores fazendo um - Parte 1

Aprendendo compiladores fazendo um - Parte 1

Vídeo da Talk: https://youtu.be/t77ThZNCJGY

Aprender mais sobre compiladores é uma excelente forma de desmitificar o que acontece no momento entre iniciar a build do código e obter o output. Isso é ótimo para se tornar um melhor desenvolver e expandir seus horizontes; desse modo é possível entender mais sobre o funcionamento de ferramentas como Babel e máquinas virtuais, assim como outras áreas, como otimização e engenharia reversa.

Nessa primeira parte da talk "Aprendendo compiladores fazendo um" introduzo sobre design de linguagens, motivações em fazer um novo compilador e descrevendo as etapas de compilação, sempre visando como você pode desenvolver o seu próprio compilador para a sua própria linguagem.

Repositório do compilador de EventMacro: https://github.com/macabeus/macro-compiler

F380535da59d6cdd5754e2e31bda8a0e?s=128

Bruno Macabeus

July 05, 2018
Tweet

Transcript

  1. 3.
  2. 4.
  3. 5.
  4. 6.
  5. 14.

    Compilador é um software que traduz da linguagem A para

    a linguagem B Definições A pode ser igual a B!
  6. 16.

    Compilador é um software que traduz da linguagem A para

    a linguagem B Definições Mas precisa ser entre linguagens?
  7. 18.

    Compilador é um programa que transforma uma representação de dados

    em outra representação de dados de alguma forma equivalente ou relacionada à primeira. Definições
  8. 22.

    TypeScript é um superset de JS que compila
 para JS

    com o diferencial de implementar tipos
  9. 23.

    TypeScript é um superset de JS que compila
 para JS

    com o diferencial de implementar tipos // JS const createUser = (id, level) => { // code... } createUser(42, 'guest') // O ID realmente é um number? // Quais seriam todos os level? // O usuário criado é retornado pela função?
  10. 24.

    // JS const createUser = (id, level) => { //

    code... } createUser(42, 'guest') // O ID realmente é um number? // Quais seriam todos os level? // O usuário criado é retornado pela função? // TypeScript enum level { guest = 'guest', normal = 'normal', admin = 'admin', } const createUser = (id: number, level: level) => { // code... } createUser(42, level.guest) // Todas aquelas dúvidas são respondidas
 // bastando ver a assinatura da função! TypeScript é um superset de JS que compila
 para JS com o diferencial de implementar tipos
  11. 26.

    Koka é uma linguagem que separa os valores dos side-effects,

    além de inferir em tempo de compilação
  12. 27.

    // Swift func getEvenNumber() -> Int { // algum código...

    } getEvenNumber() // essa função gera IO? resultado é determinístico? // pode ser que nunca termine? Koka é uma linguagem que separa os valores dos side-effects, além de inferir em tempo de compilação
  13. 28.

    // Swift func getEvenNumber() -> Int { // algum código...

    } getEvenNumber() // essa função gera IO? resultado é determinístico? // pode ser que nunca termine? // Koka
 function getEvenNumber() : ndet int {
 // algum código...
 } function main() {
 getEvenNumber() // basta ver a assinatura da função
 // para saber que o é um número aleatório!
 } Koka é uma linguagem que separa os valores dos side-effects, além de inferir em tempo de compilação
  14. 29.

    // Koka
 function getEvenNumber() : ndet int {
 return randomInt()

    * 2
 } function main() {
 getEvenNumber() // basta ver a assinatura da função
 // para saber que o é um número aleatório!
 } // Swift func getEvenNumber() -> Int { return Int(arc4random()) * 2 } getEvenNumber() // essa função gera IO? resultado é determinístico? // pode ser que nunca termine? Koka é uma linguagem que separa os valores dos side-effects, além de inferir em tempo de compilação
  15. 37.
  16. 38.
  17. 39.
  18. 40.
  19. 41.
  20. 42.
  21. 43.
  22. 45.

    automacro ref { InInventory "Rough Oridecon" > 4 call ref-while

    } macro ref-while { log go to refiner do move prt_in 59 60 $ori = &invamount(Rough Oridecon) log I have $ori Rough Oridecons while (&invamount(Rough Oridecon) > 4) { do talk 0 pause 0.8 do talk resp 0 } } EventMacro
  23. 46.

    automacro ref { InInventory "Rough Oridecon" > 4 call ref-while

    } macro ref-while { log go to refiner do move prt_in 59 60 $ori = &invamount(Rough Oridecon) log I have $ori Rough Oridecons while (&invamount(Rough Oridecon) > 4) { do talk 0 pause 0.8 do talk resp 0 } } EventMacro
  24. 47.

    automacro ref { InInventory "Rough Oridecon" > 4 call ref-while

    } macro ref-while { log go to refiner do move prt_in 59 60 $ori = &invamount(Rough Oridecon) log I have $ori Rough Oridecons while (&invamount(Rough Oridecon) > 4) { do talk 0 pause 0.8 do talk resp 0 } } EventMacro
  25. 48.

    automacro ref { InInventory "Rough Oridecon" > 4 call ref-while

    } macro ref-while { log go to refiner do move prt_in 59 60 $ori = &invamount(Rough Oridecon) log I have $ori Rough Oridecons while (&invamount(Rough Oridecon) > 4) { do talk 0 pause 0.8 do talk resp 0 } } EventMacro
  26. 49.

    automacro ref { InInventory "Rough Oridecon" > 4 call ref-while

    } macro ref-while { log go to refiner do move prt_in 59 60 $ori = &invamount(Rough Oridecon) log I have $ori Rough Oridecons while (&invamount(Rough Oridecon) > 4) { do talk 0 pause 0.8 do talk resp 0 } } EventMacro
  27. 50.

    automacro ref { InInventory "Rough Oridecon" > 4 call ref-while

    } macro ref-while { log go to refiner do move prt_in 59 60 $ori = &invamount(Rough Oridecon) log I have $ori Rough Oridecons while (&invamount(Rough Oridecon) > 4) { do talk 0 pause 0.8 do talk resp 0 } } EventMacro
  28. 51.

    automacro ref { InInventory "Rough Oridecon" > 4 call ref-while

    } macro ref-while { log go to refiner do move prt_in 59 60 $ori = &invamount(Rough Oridecon) log I have $ori Rough Oridecons while (&invamount(Rough Oridecon) > 4) { do talk 0 pause 0.8 do talk resp 0 } } EventMacro
  29. 52.

    automacro ref { InInventory "Rough Oridecon" > 4 call ref-while

    } macro ref-while { log go to refiner do move prt_in 59 60 $ori = &invamount(Rough Oridecon) log I have $ori Rough Oridecons while (&invamount(Rough Oridecon) > 4) { do talk 0 pause 0.8 do talk resp 0 } } EventMacro
  30. 53.

    EventMacro automacro ref { InInventory "Rough Oridecon" > 4 call

    ref-while } macro ref-while { log go to refiner do move prt_in 59 60 $ori = &invamount(Rough Oridecon) log I have $ori Rough Oridecons while (&invamount(Rough Oridecon) > 4) { do talk 0 pause 0.8 do talk resp 0 } }
  31. 54.

    ' EventMacro ' automacro ref { InInventory "Rough Oridecon" >

    4 call ref-while } macro ref-while { log go to refiner do move prt_in 59 60 $ori = &invamount(Rough Oridecon) log I have $ori Rough Oridecons while (&invamount(Rough Oridecon) > 4) { do talk 0 pause 0.8 do talk resp 0 } }
  32. 57.

    EventMacro Fortemente influenciada por Perl my $scalar = 'foo'; my

    @array = (1, 2, 3); my %hash = (1 => 'foo', 2 => 'bar');
  33. 60.

    EventMacro ⛏ Desenvolvida visando facilitar a escrita de um interpretador

    regexp-based Funciona através de um plugin que interpreta o código Fortemente influenciada por Perl
  34. 61.

    Voltada para iniciantes EventMacro ⛏ Desenvolvida visando facilitar a escrita

    de um interpretador regexp-based Funciona através de um plugin que interpreta o código Fortemente influenciada por Perl
  35. 63.

    Mensagens de erro e warning em tempo de compilação MacroCompiler

    Nós podemos construir um compilador para o EventMacro!
  36. 64.

    MacroCompiler Mensagens de erro e warning em tempo de compilação

    Nós podemos construir um compilador para o EventMacro! Código final otimizado
  37. 65.

    Maior facilidade em implementar novas features MacroCompiler Código final otimizado

    Mensagens de erro e warning em tempo de compilação Nós podemos construir um compilador para o EventMacro!
  38. 68.

    Trata-se de estruturar a API pública de uma biblioteca como

    se ela fosse uma linguagem de programação eDSL (embedded domain-specific language) pode ser uma solução mais simples!
  39. 69.

    Trata-se de estruturar a API pública de uma biblioteca como

    se ela fosse uma linguagem de programação eDSL (embedded domain-specific language) pode ser uma solução mais simples! // css selector em JS + jQuery
 const element = $('#foo .bar');
  40. 70.

    Trata-se de estruturar a API pública de uma biblioteca como

    se ela fosse uma linguagem de programação eDSL (embedded domain-specific language) pode ser uma solução mais simples! // JS
 const myRegexp = /^age (\d+)/ // css selector em JS + jQuery
 const element = $('#foo .bar');
  41. 71.

    Trata-se de estruturar a API pública de uma biblioteca como

    se ela fosse uma linguagem de programação eDSL (embedded domain-specific language) pode ser uma solução mais simples! // Haskell + Functional MetaPost library
 beginfig(1)
 pair A, B, C;
 A:=(0, 0); B:=(1cm, 0); C:=(0, 1cm);
 draw A--B--C--cycle;
 endfig;
  42. 73.

    Desenvolver o design de uma linguagem é mais a respeito

    de como a pessoa vai se comunicar com o computador
  43. 74.

    Desenvolver o design de uma linguagem é mais a respeito

    de como a pessoa vai se comunicar com o computador Desenvolver um compilador é um desenvolvimento de software
  44. 78.

    macro sayHi { } $someone = Macabeus log Hi, $someone

    Parser Código fonte Análise semântica Otimização Geração de código Análise léxica
  45. 79.

    macro sayHi { } $someone = Macabeus log Hi, $someone

    [
 keyword(macro),
 identifier(sayHi),
 openBraces, newLine,
 scalarIdentifier(someone),
 equal,
 text(Macabeus), newLine,
 keyword(log),
 text(Hi, ),
 scalarIdentifier(someone),
 newLine, closeBraces
 ] Parser Código fonte Análise semântica Otimização Geração de código Análise léxica
  46. 80.

    macro sayHi { } $someone = Macabeus log Hi, $someone

    [
 keyword(macro),
 identifier(sayHi),
 openBraces, newLine,
 scalarIdentifier(someone),
 equal,
 text(Macabeus), newLine,
 keyword(log),
 text(Hi, ),
 scalarIdentifier(someone),
 newLine, closeBraces
 ] Parser Código fonte Análise semântica Otimização Geração de código Análise léxica
  47. 81.

    macro sayHi { } $someone = Macabeus log Hi, $someone

    [
 keyword(macro),
 identifier(sayHi),
 openBraces, newLine,
 scalarIdentifier(someone),
 equal,
 text(Macabeus), newLine,
 keyword(log),
 text(Hi, ),
 scalarIdentifier(someone),
 newLine, closeBraces
 ] Parser Código fonte Análise semântica Otimização Geração de código Análise léxica
  48. 82.

    macro sayHi { } $someone = Macabeus log Hi, $someone

    [
 keyword(macro),
 identifier(sayHi),
 openBraces, newLine,
 scalarIdentifier(someone),
 equal,
 text(Macabeus), newLine,
 keyword(log),
 text(Hi, ),
 scalarIdentifier(someone),
 newLine, closeBraces
 ] Parser Código fonte Análise semântica Otimização Geração de código Análise léxica
  49. 83.

    macro sayHi { } $someone = Macabeus log Hi, $someone

    [
 keyword(macro),
 identifier(sayHi),
 openBraces, newLine,
 scalarIdentifier(someone),
 equal,
 text(Macabeus), newLine,
 keyword(log),
 text(Hi, ),
 scalarIdentifier(someone),
 newLine, closeBraces
 ] Parser Código fonte Análise semântica Otimização Geração de código Análise léxica
  50. 84.

    macro sayHi { } $someone = Macabeus log Hi, $someone

    [
 keyword(macro),
 identifier(sayHi),
 openBraces, newLine,
 scalarIdentifier(someone),
 equal,
 text(Macabeus), newLine,
 keyword(log),
 text(Hi, ),
 scalarIdentifier(someone),
 newLine, closeBraces
 ] Parser Código fonte Análise semântica Otimização Geração de código Análise léxica
  51. 85.

    macro sayHi { } $someone = Macabeus log Hi, $someone

    Parser Código fonte Análise semântica Otimização Geração de código Análise léxica
  52. 86.

    macro sayHi { } $someone = Macabeus log Hi, $someone

    Parser Código fonte Análise semântica Otimização Geração de código Análise léxica
  53. 95.

    macro sayHi { } log $someone = Macabeus Hi, $someone

    Parser Código fonte Análise semântica Otimização Geração de código Análise léxica
  54. 96.

    macro sayHi { } log $someone = Macabeus Hi, $someone

    Parser Código fonte Análise semântica Otimização Geração de código Análise léxica
  55. 99.

    macro sayHi { } log $someone = Macabeus Hi, $someone

    Symbol table macro_write : sayHi
  56. 100.

    macro sayHi { } log $someone = Macabeus Hi, $someone

    Symbol table macro_write : sayHi variable_write: $someone
  57. 101.

    macro sayHi { } log $someone = Macabeus Hi, $someone

    Symbol table macro_write : sayHi variable_write: $someone variable_read : $someone
  58. 102.

    macro sayHi { } log $someone = Macabeus Hi, $someone

    Symbol table macro_write : sayHi variable_write: $someone variable_read : $someone
  59. 103.

    macro sayHi { } log $someone = Macabeus Hi, $someone

    Parser Código fonte Análise semântica Otimização Geração de código Análise léxica
  60. 104.

    macro sayHi { } log $someone = Macabeus Hi, $someone

    Parser Código fonte Análise semântica Otimização Geração de código Análise léxica
  61. 106.

    macro sayHi { } log $someone = Macabeus Hi, $someone

    Dead code strip Constant folding Otimizações
  62. 107.

    macro sayHi { } log $someone = Macabeus Hi, $someone

    Dead code strip Constant folding Otimizações
  63. 108.

    macro sayHi { } log $someone = Macabeus Hi, $someone

    Dead code strip Constant folding Otimizações
  64. 109.

    macro sayHi { } log Hi, Macabeus Dead code strip

    Constant folding Otimizações $someone = Macabeus
  65. 110.

    macro sayHi { } log Hi, Macabeus Dead code strip

    Constant folding Otimizações $someone = Macabeus
  66. 111.

    macro sayHi { } log Hi, Macabeus Dead code strip

    Constant folding Otimizações $someone = Macabeus
  67. 112.

    macro sayHi { } log Hi, Dead code strip Constant

    folding Otimizações Macabeus
  68. 113.

    macro sayHi { } log Hi, Dead code strip Constant

    folding Otimizações Macabeus
  69. 114.

    macro sayHi { } log Hi, Dead code strip Constant

    folding Otimizações Macabeus
  70. 115.

    macro sayHi { } log Hi, Dead code strip Constant

    folding Otimizações Macabeus
  71. 116.

    macro sayHi { } log Hi, Macabeus Parser Código fonte

    Análise semântica Otimização Geração de código Análise léxica
  72. 117.

    macro sayHi { } log Hi, Macabeus Parser Código fonte

    Análise semântica Otimização Geração de código Análise léxica
  73. 120.

    macro sayHi { } log Hi, Macabeus package macroCompiled; Plugins::register(

    'macroCompiled', 'Compiled version of eventMacro.txt', &on_unload ); sub on_unload { } Corpo Cabeçalho Geração de código
  74. 121.

    macro sayHi { } log Hi, Macabeus package macroCompiled; Plugins::register(

    'macroCompiled', 'Compiled version of eventMacro.txt', &on_unload ); sub on_unload { } Corpo Cabeçalho Geração de código
  75. 122.

    macro sayHi { } log Hi, Macabeus Corpo Cabeçalho Geração

    de código package macroCompiled; use Log qw(message); Plugins::register( 'macroCompiled', 'Compiled version of eventMacro.txt', &on_unload ); sub on_unload { }
  76. 123.

    macro sayHi { } log Hi, Macabeus Corpo Cabeçalho Geração

    de código package macroCompiled; use Log qw(message); Plugins::register( 'macroCompiled', 'Compiled version of eventMacro.txt', &on_unload ); sub on_unload { }
  77. 124.

    macro sayHi { } log Hi, Macabeus Corpo Cabeçalho Geração

    de código package macroCompiled; use Log qw(message); Plugins::register( 'macroCompiled', 'Compiled version of eventMacro.txt', &on_unload ); sub on_unload { }
  78. 125.

    macro sayHi { } log Hi, Macabeus Corpo Cabeçalho Geração

    de código package macroCompiled; use Log qw(message); Plugins::register( 'macroCompiled', 'Compiled version of eventMacro.txt', &on_unload ); sub on_unload { }
  79. 126.

    macro sayHi { } log Hi, Macabeus Corpo Cabeçalho Geração

    de código package macroCompiled; use Log qw(message); Plugins::register( 'macroCompiled', 'Compiled version of eventMacro.txt', &on_unload ); sub on_unload { } sub macro_sayHi { }
  80. 127.

    macro sayHi { } log Hi, Macabeus Corpo Cabeçalho Geração

    de código package macroCompiled; use Log qw(message); Plugins::register( 'macroCompiled', 'Compiled version of eventMacro.txt', &on_unload ); sub on_unload { } sub macro_sayHi { message 
 }
  81. 128.

    macro sayHi { } log Hi, Macabeus Corpo Cabeçalho Geração

    de código package macroCompiled; use Log qw(message); Plugins::register( 'macroCompiled', 'Compiled version of eventMacro.txt', &on_unload ); sub on_unload { } sub macro_sayHi { message 
 }
  82. 129.

    macro sayHi { } log Hi, Macabeus Corpo Cabeçalho Geração

    de código package macroCompiled; use Log qw(message); Plugins::register( 'macroCompiled', 'Compiled version of eventMacro.txt', &on_unload ); sub on_unload { } sub macro_sayHi { message "Hi, Macabeus" ."\n"; }
  83. 130.

    macro sayHi { } log Hi, Macabeus Corpo Cabeçalho Geração

    de código package macroCompiled; use Log qw(message); Plugins::register( 'macroCompiled', 'Compiled version of eventMacro.txt', &on_unload ); sub on_unload { } sub macro_sayHi { message "Hi, Macabeus" ."\n"; }
  84. 131.

    macro sayHi { } log Hi, Macabeus package macroCompiled; use

    Log qw(message); Plugins::register( 'macroCompiled', 'Compiled version of eventMacro.txt', &on_unload ); sub on_unload { } sub macro_sayHi { message "Hi, Macabeus" ."\n"; } Parser Código fonte Análise semântica Otimização Geração de código Análise léxica
  85. 134.

    Isso é uma simplificação! AST (pode) ter nós de metadados

    Compilador pode ter várias etapas intermediárias
  86. 135.

    Isso é uma simplificação! AST (pode) ter nós de metadados

    Compilador pode ter várias etapas intermediárias Como ele pode produzir o código alvo diretamente
  87. 137.
  88. 138.

    Créditos das imagens: - https://darkchiichan.deviantart.com/ - https://www.newgrounds.com/art/view/shidoisnthere/tree-pixel-art-2 Onde aprender mais:

    - DSL & eDSL http://bit.ly/quora-edsl - Análise léxica http://esprima.org/ - Sobre design de linguagem e compilador - http://bit.ly/quora-language-x-compiler - http://bit.ly/quora-language-x-compiler-2
  89. 139.