1 pontos por GN⁺ 2024-10-07 | 1 comentários | Compartilhar no WhatsApp

A origem de '\n'

  • Ao executar o comando just foo, o justfile grava o byte 0x0A em um arquivo chamado bar
  • just é escrito em Rust, e o parser do just converte tokens de string do just que incluem sequências de escape em strings UTF-8 por meio de uma função chamada cook_string

Como o Rust lida com isso

  • rustc processa códigos de escape em uma função chamada scan_escape
  • rustc é escrito em Rust e compilado por ele mesmo, delegando ao rustc a interpretação do significado de '\n'
  • As primeiras versões do rustc eram escritas em OCaml, e a versão em OCaml do rustc processava escapes de caracteres no lexer

Como o OCaml lida com isso

  • O compilador OCaml avalia \n como \010 e insere o resultado
  • Como 0x0A é 10, ao processar \n o compilador OCaml obtém o valor de byte 0x0A

Conclusão

  • Quando há um escape de caractere \n em um justfile, o binário do just o grava na string final incluindo o byte 0x0A
  • Esse byte 0x0A foi inserido pelo rustc, e isso começou quando o compilador OCaml inseriu pela primeira vez o byte 0x0A no binário do rustc

Resumo do GN⁺

  • Este texto explica como o escape de caractere \n é convertido no byte 0x0A
  • Ele rastreia a origem do byte 0x0A por meio do contexto histórico dos compiladores Rust e OCaml
  • Oferece uma visão interessante de como compiladores de linguagens de programação processam escapes de caracteres
  • É um texto útil para entender o funcionamento dos compiladores de Rust e OCaml

1 comentários

 
GN⁺ 2024-10-07
Comentários do Hacker News
  • Um usuário menciona que a primeira vez que leu essa ideia foi no dia 42 do texto "How I wrote a self-hosting C compiler in 40 days"

    • Nesse texto, é explicado como o compilador interpreta "\n" em literais de string
    • É dito que "\n" não contém a informação real do código de caractere ASCII, e que isso é transmitido quando o compilador compila o compilador
    • Também é mencionado que o caractere de quebra de linha desse compilador se origina do GCC
  • É mencionado que, em sistemas EBCDIC, é preciso considerar que os primeiros compiladores C surgiram em sistemas que não usavam ASCII

    • O EBCDIC tinha caracteres explícitos de NextLine e LineFeed
    • É explicado que códigos simples que funcionam em ASCII podem falhar em EBCDIC
    • Em EBCDIC, letras minúsculas vêm antes das maiúsculas, e letras vêm antes de números, entre outras ordenações exatamente opostas às do ASCII
  • A única garantia sobre codificação de caracteres no padrão C é que os dígitos '0'-'9' sejam mapeados em ordem crescente e contínua

    • Em teoria, um programa C simples deve compilar o mesmo código-fonte em sistemas ASCII ou EBCDIC e produzir a mesma saída
  • Um usuário menciona a palestra de Ken Thompson ao receber o Prêmio Turing, "Reflections on Trusting Trust", e especula que este texto pode ter sido inspirado por ela

  • Perguntam se o compilador clang tem a mesma propriedade, explicando que isso está explicitamente codificado como 10 em lib/Lex/LiteralSupport.cpp

  • Um usuário questiona por que foi necessário investigar para entender por que "\n" é codificado como 10, achando que isso era esperado

  • É mencionado que este texto soa como um cruzamento entre programação literária e poesia, tentando explicar o processo pelo qual o byte 0x0A é gerado ao longo de centenas de ciclos de geração de código

  • Um usuário diz que, por causa da linguagem C, pensava que "\0???" era uma sequência de escape octal, e entendia "\012" como "\x0a" ou "0x0a", e "\010" como "0x08"

    • Ele especula que o OCaml pode ter sequências de escape decimais, e não octais
  • É levantada uma pergunta interessante sobre como nosso código seria se não existissem códigos de escape em ASCII ou em strings

  • Menciona-se uma regra da programação: quando há duas maneiras de fazer algo e a chance de uma estar certa e a outra errada é de 50/50, no começo é mais provável escolher a errada