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. APRENDENDO COMPILADORES FAZENDO UM - PARTE 1

  2. Bruno Macabeus github.com/macabeus macalogs.com.br Desenvolvedor na Pagar.me

  3. None
  4. None
  5. None
  6. None
  7. COMPILADOR

  8. COMPILADOR?

  9. Definições

  10. Definições Compilador é um software que traduz da linguagem A

    para a linguagem B
  11. Definições Compilador é um software que traduz da linguagem A

    para a linguagem B A ≠ B ?
  12. Closure Compiler Babel Definições

  13. Compilador é um software que traduz da linguagem A para

    a linguagem B Definições
  14. Compilador é um software que traduz da linguagem A para

    a linguagem B Definições A pode ser igual a B!
  15. Compilador é um software que traduz da linguagem A para

    a linguagem B Definições
  16. Compilador é um software que traduz da linguagem A para

    a linguagem B Definições Mas precisa ser entre linguagens?
  17. Closure Compiler Pagedraw Pagedraw Definições

  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
  19. OK… MAS JÁ TEMOS VÁRIOS COMPILADORES E LINGUAGENS…

  20. POR QUAL RAZÃO FAZER MAIS UM?

  21. Exemplo #1 As linguagens têm problemas de design!

  22. TypeScript é um superset de JS que compila
 para JS

    com o diferencial de implementar tipos
  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?
  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
  25. Exemplo #2 Estudar um conceito

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

    além de inferir em tempo de compilação
  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
  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
  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
  30. Exemplo #3 Quando não tem problema algum para resolver,
 mas

    quer escrever código maroto
  31. Piet, uma linguagem esotérica da qual se desenvolve usando pixels!

    #
  32. Piet, uma linguagem esotérica da qual se desenvolve usando pixels!

    #
  33. Exemplo #4 Resolver um problema específico

  34. Logo, uma linguagem com propósito educacional

  35. Logo, uma linguagem com propósito educacional

  36. EventMacro, uma linguagem para desenvolver macros para o bot do

    jogo Ragnarok
  37. None
  38. None
  39. Ragnarok

  40. None
  41. None
  42. None
  43. OpenKore

  44. EventMacro

  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
  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
  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
  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
  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
  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
  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
  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
  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 } }
  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 } }
  55. EventMacro

  56. EventMacro Fortemente influenciada por Perl

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

    @array = (1, 2, 3); my %hash = (1 => 'foo', 2 => 'bar');
  58. EventMacro Fortemente influenciada por Perl my $variable = 'foo'; print

    "variable value: $variable"
  59. Funciona através de um plugin que interpreta o código EventMacro

    Fortemente influenciada por Perl
  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
  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
  62. Nós podemos construir um compilador para o EventMacro! MacroCompiler

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

    Nós podemos construir um compilador para o EventMacro!
  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
  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!
  66. NEM SEMPRE UM COMPILADOR
 É O IDEAL!

  67. eDSL (embedded domain-specific language) pode ser uma solução mais simples!

  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!
  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');
  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');
  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;
  72. DESENVOLVER UMA LINGUAGEM X UM COMPILADOR

  73. Desenvolver o design de uma linguagem é mais a respeito

    de como a pessoa vai se comunicar com o computador
  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
  75. E COMO SE DESENVOLVE UM COMPILADOR?

  76. ETAPAS DE COMPILAÇÃO

  77. Parser Código fonte Análise semântica Otimização Geração de código Análise

    léxica
  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
  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
  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
  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
  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
  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
  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
  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
  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
  87. macro sayHi { } $someone = Macabeus log Hi, $someone

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

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

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

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

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

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

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

  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
  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
  97. macro sayHi { } log $someone = Macabeus Hi, $someone

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

    Symbol table
  99. macro sayHi { } log $someone = Macabeus Hi, $someone

    Symbol table macro_write : sayHi
  100. macro sayHi { } log $someone = Macabeus Hi, $someone

    Symbol table macro_write : sayHi variable_write: $someone
  101. macro sayHi { } log $someone = Macabeus Hi, $someone

    Symbol table macro_write : sayHi variable_write: $someone variable_read : $someone
  102. macro sayHi { } log $someone = Macabeus Hi, $someone

    Symbol table macro_write : sayHi variable_write: $someone variable_read : $someone
  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
  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
  105. macro sayHi { } log $someone = Macabeus Hi, $someone

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

    Dead code strip Constant folding Otimizações
  107. macro sayHi { } log $someone = Macabeus Hi, $someone

    Dead code strip Constant folding Otimizações
  108. macro sayHi { } log $someone = Macabeus Hi, $someone

    Dead code strip Constant folding Otimizações
  109. macro sayHi { } log Hi, Macabeus Dead code strip

    Constant folding Otimizações $someone = Macabeus
  110. macro sayHi { } log Hi, Macabeus Dead code strip

    Constant folding Otimizações $someone = Macabeus
  111. macro sayHi { } log Hi, Macabeus Dead code strip

    Constant folding Otimizações $someone = Macabeus
  112. macro sayHi { } log Hi, Dead code strip Constant

    folding Otimizações Macabeus
  113. macro sayHi { } log Hi, Dead code strip Constant

    folding Otimizações Macabeus
  114. macro sayHi { } log Hi, Dead code strip Constant

    folding Otimizações Macabeus
  115. macro sayHi { } log Hi, Dead code strip Constant

    folding Otimizações Macabeus
  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
  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
  118. macro sayHi { } log Hi, Macabeus

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

    de código
  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
  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
  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 { }
  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 { }
  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 { }
  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 { }
  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 { }
  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 
 }
  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 
 }
  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"; }
  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"; }
  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
  132. Isso é uma simplificação!

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

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

    Compilador pode ter várias etapas intermediárias
  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
  136. COMO É O CÓDIGO DO MACRO COMPILER?

  137. None
  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
  139. OBRIGADO!