<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: nullen box</title>
    <description>The latest articles on DEV Community by nullen box (@nullenbox).</description>
    <link>https://dev.to/nullenbox</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1052459%2F7f63115e-8ebd-40f1-9a13-a36c6b361584.png</url>
      <title>DEV Community: nullen box</title>
      <link>https://dev.to/nullenbox</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nullenbox"/>
    <language>en</language>
    <item>
      <title>Soluções para as "procrastinações"</title>
      <dc:creator>nullen box</dc:creator>
      <pubDate>Wed, 10 Jan 2024 11:42:29 +0000</pubDate>
      <link>https://dev.to/nullenbox/solucoes-para-as-procrastinacoes-31j1</link>
      <guid>https://dev.to/nullenbox/solucoes-para-as-procrastinacoes-31j1</guid>
      <description>&lt;h3&gt;
  
  
  Porque procrastinamos?
&lt;/h3&gt;

&lt;p&gt;Isso mesmo, "procrastinação" não uma coisa só, na verdade existem vários "tipos" de procrastinação, mas antes de aprofundarmos nisso vamos entender o porque procrastinamos antes de mais nada.&lt;/p&gt;

&lt;p&gt;Procrastinação é na verdade uma solução, nosso cérebro está o tempo inteiro querendo economizar energia e procrastinar é a maneira mais eficiente de completar tarefas, afinal, porque estudar um semestre inteiro para tirar 10 se podemos estudar só na última semana e tirar a nota mínima para não sermos reprovados?&lt;/p&gt;

&lt;p&gt;A estratégia de procrastinação maximiza a variável &lt;code&gt;Valor&lt;/code&gt; que podemos definir como &lt;code&gt;Valor = Resultado / Esforço&lt;/code&gt;. Em alguns contextos como faculdade, trabalho, meio acadêmico, etc. o esperado que é que a gente maximize a &lt;code&gt;Qualidade&lt;/code&gt; e não o &lt;code&gt;Valor&lt;/code&gt;, nestes contexto a procrastinação pode se tornar inadequada.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tipos de "procrastinações"
&lt;/h3&gt;

&lt;p&gt;Podemos identificar três mecanismos diferentes que colocamos dentro da grande categoria "procrastinação":&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Idealista&lt;/li&gt;
&lt;li&gt;Evasiva&lt;/li&gt;
&lt;li&gt;Operacional&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Cada um desses mecanismos gera emoções diferentes, pensamentos diferentes e consequentemente precisaremos usar soluções diferentes para cada um.&lt;/p&gt;

&lt;h3&gt;
  
  
  Procrastinação Idealista
&lt;/h3&gt;

&lt;p&gt;Esse é o tipo de procrastinação que é relacionada a uma fantasia ou à procura da perfeição.&lt;br&gt;
A "lógica" é mais ou menos assim: "já que não consigo fazer isso, vou me preparar, fazendo outras atividades, e quando estiver confiante farei a tarefa principal".&lt;br&gt;
Por exemplo, "se eu chamar aquela pessoa pra sair, provavelmente vou escutar um 'não', então vou fazer academia e entrar no &lt;em&gt;shape&lt;/em&gt; pra que eu consiga aumentar as chances de ouvir um 'sim'".&lt;/p&gt;

&lt;p&gt;Esse tipo de procrastinação geralmente envolve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;um objetivo inalcançável, uma fantasia, um resultado perfeito esperado&lt;/li&gt;
&lt;li&gt;tentativa de influenciar o futuro para conseguir atingir o resultado inalcançável&lt;/li&gt;
&lt;li&gt;resultado idealista, fruto de imaginação e baseado em esperança excessiva&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Soluções&lt;/strong&gt;:&lt;br&gt;
Para desmantelar essa procrastinação é necessário fazer algumas coisas&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Entenda que seu objetivo é na verdade uma fantasia&lt;/li&gt;
&lt;li&gt;Desapegue desse objetivo inicial&lt;/li&gt;
&lt;li&gt;Passe pelo momento de "luto" depois de se desapegar da fantasia&lt;/li&gt;
&lt;li&gt;Defina um objetivo alcançável para sua situação atual&lt;/li&gt;
&lt;li&gt;Entenda que você NÃO desistiu do seu objetivo, você apenas aceitou que não aceitaria o objetivo inicial (fantasioso e inalcançável) e agora está seguindo em frente.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Procrastinação Evasiva
&lt;/h3&gt;

&lt;p&gt;Geralmente é baseada em emoções e se dá quando estamos tentando evitar receber um impacto emocional forte.&lt;br&gt;
As emoções evitadas são geralmente as caracterizadas como negativas, por exemplo: medo, vergonha, frustração, ansiedade, etc.&lt;/p&gt;

&lt;p&gt;Também é comum perceber que neste estado temos quase certeza absoluta que algo ruim irá acontecer se realizarmos a ação que estamos postergando.&lt;br&gt;
Além disso é comum que a gente tente "solucionar" o problema criando estratégias e usando pensamento lógico, e se falamos sobre isso com alguém, geralmente escutamos "mas é só fazer", "não vai dar nada, só vai lá e faz", o que não ajuda.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Soluções&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Entenda que pensamentos não se dão muito bem com emoções, então tentar usar pensar em razões para realizar a ação não irá ajudar&lt;/li&gt;
&lt;li&gt;Identifique a emoção

&lt;ul&gt;
&lt;li&gt;Às vezes fazer isso é difícil, tente pensar "qual emoção estou tentando evitar?" ou então "qual consequência estou tentando evitar?"&lt;/li&gt;
&lt;li&gt;Muitas pessoas têm dificuldade de reconhecer as próprias emoções, neste caso use uma estratégia diferente, pense: "se uma pessoa próxima a mim, estivesse passando por essa situação, como ela se sentiria?"&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Trabalhe com a emoção

&lt;ul&gt;
&lt;li&gt;pense: "Se eu tivesse um(a) parente sentindo , o que eu diria para ele(a)?"&lt;/li&gt;
&lt;li&gt;Diga isso que pensou para você mesmo agora&lt;/li&gt;
&lt;li&gt;Nós temos a tendência de julgar nossas próprias ações como se fossemos um juiz de nós mesmos, desenvolver a habilidade de reconhecer nossos pontos fracos sem julga-los e agir para melhorar eles é essencial. Tente para de ser seu próprio "Juiz" e tente ser seu próprio "Treinador"&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Procrastinação Operacional
&lt;/h3&gt;

&lt;p&gt;Acontece quando o cérebro não consegue "computar" os passos necessários para completar uma tarefa.&lt;br&gt;
É o tipo de tarefa que você fica deixando pra depois e quando finalmente faz pensa "nossa, isso foi bem mais fácil do que imaginei, devia ter feito antes!"&lt;/p&gt;

&lt;p&gt;Geralmente associado a tarefas abstratas ou simplesmente grandes demais, por exemplo: &lt;br&gt;
Se você pedir para uma criança de quatro anos arrumar seu quarto ela provavelmente vai conseguir entender que "arrumar o quarto" não é um tarefa em si, mas sim um conjunto de tarefas que quando completadas ao mesmo tempo são entendidas como "arrumar o quarto".&lt;br&gt;
Por outro lado se você pedir para uma criança de 2 anos e meio "arrumar o quarto" ela provavelmente não vai entender e vai ficar parada sem fazer nada, mas se você der instruções claras para cada parte do que compõem "arrumar o quarto" (guardar as canetas, colocar os livros nas prateleiras, guardar os brinquedos no cesto de brinquedos) a criança vai conseguir concluir cada sub-tarefa uma por uma, assim "arrumando o quarto".&lt;/p&gt;

&lt;p&gt;Um bom exemplo disso para a vida adulta é "arrumar um emprego". Como se arruma um emprego? O emprego está quebrado por um acaso?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Soluções&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Operacionalize a tarefa (divida em pequenos passos)&lt;/li&gt;
&lt;li&gt;Começar do fim ajuda&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Exemplo:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Aceitar a oferta de emprego&lt;/li&gt;
&lt;li&gt;Receber uma oferta de emprego&lt;/li&gt;
&lt;li&gt;Mandar mensagem pós-entrevista demonstrando agradecimento&lt;/li&gt;
&lt;li&gt;Fazer a entrevista

&lt;ol&gt;
&lt;li&gt;Vestir roupas apropriadas&lt;/li&gt;
&lt;li&gt;Tomar banho&lt;/li&gt;
&lt;li&gt;Cortar o cabelo&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;Aplicar para vagas

&lt;ol&gt;
&lt;li&gt;Quantas vagas?&lt;/li&gt;
&lt;li&gt;Quais posições?&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;Pesquisar por vagas de trabalho&lt;/li&gt;

&lt;li&gt;Decidir tipo de trabalho que vai procurar&lt;/li&gt;

&lt;/ol&gt;

&lt;h3&gt;
  
  
  Conclusão
&lt;/h3&gt;

&lt;p&gt;Entender que "procrastinação" é um termo que na verdade encapsula vários fenômenos da nossa mente nos ajuda a usar a melhor estratégia para vencer a "procrastinação" nos momentos aonde não seria apropriado utiliza-la como método de execução de tarefas eficiente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DISCLAIMER&lt;/strong&gt;&lt;br&gt;
Este resumo foi elaborado de forma independente e é fundamentado no vídeo do &lt;a href="https://en.wikipedia.org/wiki/Alok_Kanojia" rel="noopener noreferrer"&gt;Dr. Alok Kanojia&lt;/a&gt; no YouTube, intitulado: &lt;a href="https://www.youtube.com/watch?v=bavdneN9sKg" rel="noopener noreferrer"&gt;Mental Health Bootcamp: Procrastinate MORE not LESS | Healthy Gamer Webinar #3&lt;/a&gt;. Não possuo qualquer associação com o Dr. Alok ou sua marca, e meu propósito não é promover seus produtos de maneira alguma. Este resumo é uma interpretação pessoal e não substitui aconselhamento profissional. Recomenda-se verificar diretamente com fontes originais para uma compreensão completa do conteúdo discutido.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Verificando e Gerando Expressões</title>
      <dc:creator>nullen box</dc:creator>
      <pubDate>Sat, 06 Jan 2024 13:58:37 +0000</pubDate>
      <link>https://dev.to/nullenbox/verificando-e-gerando-expressoes-3oc6</link>
      <guid>https://dev.to/nullenbox/verificando-e-gerando-expressoes-3oc6</guid>
      <description>&lt;h3&gt;
  
  
  Type Checker
&lt;/h3&gt;

&lt;p&gt;Continuando nosso &lt;a href="https://dev.to/lucas_ac_am/expressoes-encadeadas-e-agrupamento-14g6"&gt;capítulo de expressões na nossa linguagem&lt;/a&gt;, neste post vamos focar na parte de verificação das expressões, alterando nosso &lt;em&gt;type checker&lt;/em&gt; e também ajustando nosso &lt;em&gt;generator&lt;/em&gt; para criar transformar as ASTs em javascript válido.&lt;/p&gt;

&lt;p&gt;Atualmente nossa função &lt;code&gt;check_binary_expression&lt;/code&gt; avalia as partes &lt;em&gt;left&lt;/em&gt; e &lt;em&gt;right&lt;/em&gt; do node são numéricas, porém agora nossas expressões podem conter outras expressões inteiras uma dentro da outra de forma arbitrária.&lt;br&gt;
Nossa função &lt;code&gt;check_program&lt;/code&gt; já muda a verificação dependendo do tipo do node, portanto podemos simplesmente usar recursividade e essa nossa função para resolver esse problema.&lt;br&gt;
Nossa função &lt;code&gt;check_binary_expression&lt;/code&gt; ficará assim agora:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function check_binary_expression(node) {
  const { left, right } = node
  return check_program(left) &amp;amp;&amp;amp; check_program(right)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perceba que essa mudança é bem significativa pois antes estávamos usando a função &lt;code&gt;check_numeric&lt;/code&gt; para verificar os componentes &lt;em&gt;left&lt;/em&gt; e &lt;em&gt;right&lt;/em&gt; do node, assim tínhamos certeza que os operadores aritméticos estavam sendo usado apenas com números, porém isso não faz mais sentido, primeiro porque temos mais tipos diferentes de expressões binárias e não só aritméticas e segundo que um operador é tecnicamente uma função e ainda não temos um mecanismo definido para verificar "assinaturas" de funções comparado com os argumentos da função, só conseguiremos fazer uma verificação mais profunda quando tivermos esse mecanismo criado.&lt;br&gt;
Por enquanto vamos fazer verificação estrutural apenas, seguindo a lógica vamos alterar nossa função &lt;code&gt;check_unary_expression&lt;/code&gt; também:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function check_unary_expression(node) {
  const { argument } = node
  return check_program(argument)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;IMPORTANTE&lt;/strong&gt;: Ao fazer um teste com a função &lt;code&gt;check_program&lt;/code&gt; atual achei um erro que tinha passado despercebido, no meio da função temos a verificação &lt;code&gt;if (type === 'literal') {&lt;/code&gt; porém não existem nodes do tipo &lt;code&gt;literal&lt;/code&gt;, na verdade &lt;code&gt;literal&lt;/code&gt; representa todos os tipos de node de valores como &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;float&lt;/code&gt;, &lt;code&gt;string&lt;/code&gt;, etc. Por isso vamos alterar nossa função para corrigir esse erro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function check_program(ast) {
  const { type } = ast
  if (check_literal(ast)) {
    return true
  } else if (type === 'binary_expression') {
    return check_binary_expression(ast)
  } else if (type === 'unary_expression') {
    return check_unary_expression(ast)
  } else {
    console.log(`Invalid AST has type = ${type}`)
    return false
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesta nova versão utilizamos a função já previamente definida &lt;code&gt;check_literal&lt;/code&gt; para "pular" o caso do node to "tipo" &lt;code&gt;literal&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Agora com os novos ajustes vamos altera nosso arquivo exemplo para &lt;code&gt;2 * 3 + 4 || 3 - (3 * 1 + 3) == 1&lt;/code&gt; rodar o comando &lt;code&gt;node parser ex.ln0&lt;/code&gt; e depois o comando &lt;code&gt;node typecheck ast.json&lt;/code&gt;&lt;br&gt;
Na tela é &lt;em&gt;printado&lt;/em&gt; &lt;code&gt;true&lt;/code&gt; indicando que a AST está "correta", isso ainda não significa muita coisa, mas em breve vamos trabalhar mais nisso e implementar o sistema de validação de "assinatura" de funções, por enquanto isso já está bom o suficiente.&lt;/p&gt;
&lt;h3&gt;
  
  
  Generator
&lt;/h3&gt;

&lt;p&gt;Vamos focar agora no generator e transformar nossa AST em javascript válido contendo as várias expressões que já conseguimos &lt;em&gt;parsear&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;No nosso &lt;em&gt;generator&lt;/em&gt; temos os mesmos problemas para resolver, precisamos usar recursão e arrumar nossa função principal que também contêm a verificação do tipo &lt;code&gt;literal&lt;/code&gt; que não faz sentido.&lt;/p&gt;

&lt;p&gt;Primeiro vamos alterar nossas funções geradoras &lt;code&gt;gen_binary_expression&lt;/code&gt; e &lt;code&gt;gen_unary_expression&lt;/code&gt; usando recursão para gerar os parâmetros:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function gen_binary_expression(node) {
  const { operator, left, right } = node
  return `${gen_program(left)} ${operator.value} ${gen_program(right)}`
}

function gen_unary_expression(node) {
  const { operator, argument } = node
  return `${operator.value}${gen_program(argument)}`
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E depois alteramos nossa função principal, pra isso vamos "emprestar" nossa função &lt;code&gt;check_literal&lt;/code&gt; do módulo &lt;code&gt;typecheck&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports.check_literal = check_literal
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { check_literal } = require('./typecheck')
//...
function gen_program(ast) {
  const { type } = ast
  if (check_literal(ast)) {
    return gen_literal(ast)
  } else if (type === 'binary_expression') {
    return gen_binary_expression(ast)
  } else if (type === 'unary_expression') {
    return gen_unary_expression(ast)
  } else {
    console.log(`Invalid AST has type = ${type}`)
    return ''
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora com todas essas modificações, basta rodarmos o comando &lt;code&gt;node generator ast.json&lt;/code&gt; o nosso arquivo &lt;code&gt;output.js&lt;/code&gt; fica dessa forma: &lt;code&gt;2 * 3 + 4 || 3 - 3 * 1 + 3 == 1&lt;/code&gt;. Está quase correto, o único problema é a falta dos parênteses que estavam no arquivo original, eles sumiram porque atualmente nossa definição gramática ignora os parênteses, para arrumarmos isso precisamos alterar nossa gramática primeiro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;primary_expression
  -&amp;gt; literal {% id %}
  | %lparen term_expression %rparen {% data =&amp;gt; ({
    type: 'parenthesized_expression',
    expression: data[1],
  }) %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora introduzimos um novo &lt;em&gt;type&lt;/em&gt; de node, o &lt;code&gt;parenthesized_expression&lt;/code&gt;, com essa diferenciação conseguimos preservar a estrutura original, mas antes de continuar vamos &lt;em&gt;buidlar&lt;/em&gt; nossa gramática rodando o comando &lt;code&gt;pnpm nc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Agora precisamos adicionar os &lt;em&gt;handlers&lt;/em&gt; do tipo &lt;code&gt;parenthesized_expression&lt;/code&gt; no &lt;code&gt;typecheck.js&lt;/code&gt; e no &lt;code&gt;generator.js&lt;/code&gt;, começando com o &lt;code&gt;typecheck.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function check_program(ast) {
  const { type } = ast
  if (check_literal(ast)) {
    return true
  } else if (type === 'binary_expression') {
    return check_binary_expression(ast)
  } else if (type === 'unary_expression') {
    return check_unary_expression(ast)
  } else if (type === 'parenthesized_expression') {
    const { expression } = ast
    return check_program(expression)
  } else {
    console.log(`Invalid AST has type = ${type}`)
    return false
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por ser algo bem simples de se fazer vou deixar no meio da função mesmo, vamos fazer agora o do &lt;code&gt;generator.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function gen_program(ast) {
  const { type } = ast
  if (check_literal(ast)) {
    return gen_literal(ast)
  } else if (type === 'binary_expression') {
    return gen_binary_expression(ast)
  } else if (type === 'unary_expression') {
    return gen_unary_expression(ast)
  } else if (type === 'parenthesized_expression') {
    return gen_parenthesized_expression(ast)
  } else {
    console.log(`Invalid AST has type = ${type}`)
    return ''
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste caso vamos criar uma função separada mesmo, a função &lt;code&gt;gen_parenthesized_expression&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function gen_parenthesized_expression(node) {
  const { expression } = node
  return `(${gen_program(expression)})`
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, ao rodar o comando &lt;code&gt;node typecheck ast.json&lt;/code&gt; temos o resultado &lt;code&gt;true&lt;/code&gt;, indicando que tudo está funcionando bem e ao rodar o comando &lt;code&gt;node generator ast.json&lt;/code&gt; o resultado é: &lt;code&gt;2 * 3 + 4 || 3 - (3 * 1 + 3) == 1&lt;/code&gt; agora com os parêntesis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finalização
&lt;/h3&gt;

&lt;p&gt;Nossa linguagem agora consegue "enxergar" vários tipos de expressões com vários níveis de profundidade e depois consegue transformar tudo em javascript. Por enquanto não há nenhuma diferença pois estamos tratando apenas de expressões básicas e ainda não implementamos nosso sistema de &lt;em&gt;tipagem&lt;/em&gt; nem de funções, nem de verificação de "assinatura" de funções e é isso que vamos focar no próximo post. Até mais!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programminglanguage</category>
      <category>languagedesign</category>
      <category>compilers</category>
    </item>
    <item>
      <title>Expressões encadeadas e agrupamento</title>
      <dc:creator>nullen box</dc:creator>
      <pubDate>Sat, 30 Dec 2023 11:54:36 +0000</pubDate>
      <link>https://dev.to/nullenbox/expressoes-encadeadas-e-agrupamento-14g6</link>
      <guid>https://dev.to/nullenbox/expressoes-encadeadas-e-agrupamento-14g6</guid>
      <description>&lt;p&gt;Já temos um bom arsenal de expressões singulares preparado, nossa linguagem já "entende" expressões aritméticas binárias e unárias e agora precisamos fazer com que ela "entenda" expressões encadeadas.&lt;/p&gt;

&lt;p&gt;Pra isso vamos definir todos os tipos de expressões e usaremos a sequência de precedência para fazer as alterações necessárias.&lt;/p&gt;

&lt;p&gt;No nível mais baixo temos os valores literais e os agrupamentos, que são expressões entre parênteses, para trabalharmos com agrupamentos primeiro precisamos alterar nosso tokenizer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//...
  lparen: '(',
  rparen: ')',
//...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora podemos criar a regra &lt;code&gt;primary_expression&lt;/code&gt; que representa o primeiro nível de expressões:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;primary_expression
  -&amp;gt; literal {% id %}
  | %lparen term_expression %rparen {% data =&amp;gt; data[1] %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa regra interpreta literais ou expressões entre parênteses.&lt;/p&gt;

&lt;p&gt;A próxima na lista é a &lt;code&gt;unary_expression&lt;/code&gt; que já temos, porém precisaremos fazer alguma alterações:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;unary_expression
  -&amp;gt; primary_expression {% id %}
  | unary_operator primary_expression {% data =&amp;gt; ({
    type: 'unary_expression',
    operator: data[0],
    argument: data[1],
  }) %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perceba a alteração de &lt;code&gt;literal&lt;/code&gt; para &lt;code&gt;primary_expression&lt;/code&gt;, e a adição da variante anterior &lt;code&gt;primary_expression&lt;/code&gt; como opção de resolução, essas alterações fazem uma regra depender da outra ao mesmo tempo que evita ambiguidade, vamos continuar com essa lógica subindo a hierarquia.&lt;/p&gt;

&lt;p&gt;A próxima da lista é a &lt;code&gt;factor_expression&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;factor_expression
  -&amp;gt; unary_expression {% id %}
  | factor_expression __ factor_operator __ factor_expression {% data =&amp;gt; ({
    type: 'binary_expression',
    operator: data[2],
    left: data[0],
    right: data[4],
  }) %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E por último a &lt;code&gt;term_expression&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;term_expression
  -&amp;gt; factor_expression {% id %}
  | term_expression __ term_operator __ term_expression {% data =&amp;gt; ({
    type: 'binary_expression',
    operator: data[2],
    left: data[0],
    right: data[4],
  }) %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Testando
&lt;/h3&gt;

&lt;p&gt;Basta compilar a gramática com o comando &lt;code&gt;pnpm nc&lt;/code&gt;&lt;br&gt;
Vamos também alterar nosso arquivo &lt;code&gt;ex.ln0&lt;/code&gt; escrevendo a expressão &lt;code&gt;2 + 3 * 4&lt;/code&gt;&lt;br&gt;
Ao rodar o comando &lt;code&gt;node parser ex.ln0&lt;/code&gt;, temos a seguinte AST:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "type": "binary_expression",
  "operator": {
    "type": "plus",
    "value": "+",
    //...
  },
  "left": {
    "type": "int",
    "value": "2",
    //...
  },
  "right": {
    "type": "binary_expression",
    "operator": {
      "type": "star",
      "value": "*",
      //...
    },
    "left": {
      "type": "int",
      "value": "3",
      //...
    },
    "right": {
      "type": "int",
      "value": "4",
      //...
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O resultado é o esperado, o primeiro operador colapsado é o &lt;code&gt;+&lt;/code&gt;, e a propriedade &lt;code&gt;right&lt;/code&gt; é uma expressão binária inteira com o operador &lt;code&gt;*&lt;/code&gt; portanto a regra de precedência se faz correta visto que o símbolo de &lt;code&gt;*&lt;/code&gt; será avaliado primeiro por estar mais longe da raiz da AST.&lt;/p&gt;

&lt;p&gt;Vamos alterar nosso exemplo dessa forma &lt;code&gt;2 + -(3 * 4 + 1) / 2&lt;/code&gt;, assim podemos ver na prática todas as variações de expressões.&lt;br&gt;
Depois de rodar o comando &lt;code&gt;node parser ex.ln0&lt;/code&gt;, temos o resultado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "type": "binary_expression",
  "operator": {
    "type": "plus",
    "value": "+",
    //...
  },
  "left": {
    "type": "int",
    "value": "2",
    //...
  },
  "right": {
    "type": "binary_expression",
    "operator": {
      "type": "slash",
      "value": "/",
      //...
    },
    "left": {
      "type": "unary_expression",
      "operator": {
        "type": "dash",
        "value": "-",
        //...
      },
      "argument": {
        "type": "binary_expression",
        "operator": {
          "type": "plus",
          "value": "+",
          //...
        },
        "left": {
          "type": "binary_expression",
          "operator": {
            "type": "star",
            "value": "*",
            //...
          },
          "left": {
            "type": "int",
            "value": "3",
            //...
          },
          "right": {
            "type": "int",
            "value": "4",
            //...
          }
        },
        "right": {
          "type": "int",
          "value": "1",
          //...
        }
      }
    },
    "right": {
      "type": "int",
      "value": "2",
      //...
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por enquanto tudo parece estar dentro dos conformes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Expansão rápida
&lt;/h3&gt;

&lt;p&gt;Já possuímos um "framework" de expressões binárias e unárias agora podemos expandir para não só expressões aritméticas mas também comparativas, lógicas e &lt;em&gt;bitwise&lt;/em&gt;. Vamos aproveitar o fato de que é só copiar e colar para melhorar um pouco a nossa organização de código e fazer algumas refatorações.&lt;/p&gt;

&lt;p&gt;Primeiramente vamos criar uma função especial para compilar nossos nodes do tipo &lt;code&gt;binary_expression&lt;/code&gt; no nosso arquivo de gramática:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@{%
const tokenizer = require('./tokenizer')

function binary_expression(data) {
  return {
    type: 'binary_expression',
    operator: data[2],
    left: data[0],
    right: data[4]
  }
}
%}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa forma podemos para de copiar e colar esse pedaço de código nas expressões binárias, a &lt;em&gt;refatoração&lt;/em&gt; fica dessa forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;factor_expression
  -&amp;gt; unary_expression {% id %}
  | factor_expression __ factor_operator __ factor_expression {% binary_expression %}

term_expression
  -&amp;gt; factor_expression {% id %}
  | term_expression __ term_operator __ term_expression {% binary_expression %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Antes de continuar precisamos aumentar nosso vocabulário de tokens adicionando os items &lt;code&gt;&amp;gt;=&lt;/code&gt;, &lt;code&gt;&amp;lt;=&lt;/code&gt;, &lt;code&gt;!=&lt;/code&gt;, &lt;code&gt;==&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;=&lt;/code&gt;, &lt;code&gt;|&lt;/code&gt;, &lt;code&gt;&amp;amp;&lt;/code&gt; e &lt;code&gt;^&lt;/code&gt; (lembrando de definir os tokens duplos antes dos simples para evitar errors):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//...
  gte: '&amp;gt;=',
  lte: '&amp;lt;=',
  neq: '!=',
  eqeq: '==',
  lor: '||',
  land: '&amp;amp;&amp;amp;',
//...
  or: '|',
  gt: '&amp;gt;',
  lt: '&amp;lt;',
  eq: '=',
  and: '&amp;amp;',
  caret: '^',
//...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos agora adicionar nossas regras de operadores comparativos, lógicos e bitwise:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;comparison_operator
  -&amp;gt; %gt {% id %}
  | %gte {% id %}
  | %lt {% id %}
  | %lte {% id %}

equality_operator
  -&amp;gt; %eqeq {% id %}
  | %neq {% id %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note que não precisamos definir regras para operadores lógicos e &lt;em&gt;bitwise&lt;/em&gt; pois cada um deles possuiu um nível de precedência diferente e fazer isso seria redundante.&lt;/p&gt;

&lt;p&gt;O próximo passo é definir as regras de expressões de comparação e de igualdade :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;comparison_expression
  -&amp;gt; term_expression {% id %}
  | comparison_expression __ comparison_operator __ comparison_expression {% binary_expression %}

equality_expression
  -&amp;gt; comparison_expression {% id %}
  | equality_expression __ equality_operator __ equality_expression {% binary_expression %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E depois as regras individuais de expressões &lt;em&gt;bitwise&lt;/em&gt; e de lógica:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# bitwise start
bitwise_and_expression
  -&amp;gt; equality_expression {% id %}
  | bitwise_and_expression __ %and __ equality_expression {% binary_expression %}

bitwise_xor_expression
  -&amp;gt; bitwise_and_expression {% id %}
  | bitwise_xor_expression __ %caret __ bitwise_and_expression {% binary_expression %}

bitwise_or_expression
  -&amp;gt; bitwise_xor_expression {% id %}
  | bitwise_or_expression __ %or __ bitwise_xor_expression {% binary_expression %}
# bitwise end

# logical start
logical_and_expression
  -&amp;gt; bitwise_or_expression {% id %}
  | logical_and_expression __ %lor __ bitwise_or_expression {% binary_expression %}

logical_or_expression
  -&amp;gt; logical_and_expression {% id %}
  | logical_or_expression __ %land __ logical_and_expression {% binary_expression %}
# logical end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;por último basta trocar nossa definição de &lt;code&gt;program&lt;/code&gt; para usar a última expressão da lista a &lt;code&gt;logcal_or_expression&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;program
  -&amp;gt; logical_or_expression {% id %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depois de compilar a gramática com &lt;code&gt;pnpm nc&lt;/code&gt; e alterar nosso programa exemplo para &lt;code&gt;1 + 2 &amp;gt; 3 * 4 == 3 &amp;lt; 1 | 3 - 1&lt;/code&gt;&lt;br&gt;
Vamos rodar o comando &lt;code&gt;node parser ex.ln0&lt;/code&gt; e o resultado é:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "type": "binary_expression",
  "operator": {
    "type": "or",
    //...
  },
  "left": {
    "type": "binary_expression",
    "operator": {
      "type": "eqeq",
      //...
    },
    "left": {
      "type": "binary_expression",
      "operator": {
        "type": "gt",
        //...
      },
      "left": {
        "type": "binary_expression",
        "operator": {
          "type": "plus",
          //...
        },
        "left": {
          "type": "int",
          "value": "1",
          //...
        },
        "right": {
          "type": "int",
          "value": "2",
          //...
        }
      },
      "right": {
        "type": "binary_expression",
        "operator": {
          "type": "star",
          //...
        },
        "left": {
          "type": "int",
          "value": "3",
          //...
        },
        "right": {
          "type": "int",
          "value": "4",
          //...
        }
      }
    },
    "right": {
      "type": "binary_expression",
      "operator": {
        "type": "lt",
        //...
      },
      "left": {
        "type": "int",
        "value": "3",
        //...
      },
      "right": {
        "type": "int",
        "value": "1",
        //...
      }
    }
  },
  "right": {
    "type": "binary_expression",
    "operator": {
      "type": "dash",
      //...
    },
    "left": {
      "type": "int",
      "value": "3",
      //...
    },
    "right": {
      "type": "int",
      "value": "1",
      //...
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O que é bem impressionante!&lt;/p&gt;

&lt;h3&gt;
  
  
  Próximos Passos
&lt;/h3&gt;

&lt;p&gt;Até agora fizemos a parte da expansão gramatical, porém ainda precisamos adequar nosso &lt;em&gt;type checker&lt;/em&gt; e nosso &lt;em&gt;generator&lt;/em&gt; para que eles funcionem corretamente. Faremos isso no próximo post, até mais!&lt;/p&gt;

</description>
      <category>programminglanguage</category>
      <category>javascript</category>
      <category>languagedesign</category>
      <category>compilers</category>
    </item>
    <item>
      <title>Mais níveis de precedência e mais operadores</title>
      <dc:creator>nullen box</dc:creator>
      <pubDate>Sat, 23 Dec 2023 13:10:25 +0000</pubDate>
      <link>https://dev.to/nullenbox/mais-niveis-de-precedencia-e-mais-operadores-j2d</link>
      <guid>https://dev.to/nullenbox/mais-niveis-de-precedencia-e-mais-operadores-j2d</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/lucas_ac_am/operadores-numericos-sao-mais-complexos-do-que-parece-2f16"&gt;No último post&lt;/a&gt; adicionamos os operadores binários &lt;code&gt;+&lt;/code&gt; e &lt;code&gt;-&lt;/code&gt; em nossa linguagem, nesse post vamos adicionar os operadores binários &lt;code&gt;*&lt;/code&gt; e &lt;code&gt;/&lt;/code&gt; além dos unários &lt;code&gt;!&lt;/code&gt; e &lt;code&gt;-&lt;/code&gt;, repare que o sinal de menos poder tanto um operador binário onde realmente seria uma operação de subtração ou pode ser um operador unário indicando que o número é negativo.&lt;/p&gt;

&lt;p&gt;Olhando nas nossas definições de tokens iniciais, podemos já identificar um problema, os token incluem sinalização, teremos que alterar isso para não causar confusão no parser:&lt;br&gt;
Atualmente temos essas duas definições:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//...
  float: /[-+]?(?:\d+\.\d*|\.\d+)(?:[eE][-+]?\d+)?/,
  int: /0|[-+]?[1-9][0-9]*/,
//...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos altera-las para:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//...
  float: /(?:\d+\.\d*|\.\d+)(?:[eE][-+]?\d+)?/,
  int: /0|[1-9][0-9]*/,
//...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa forma temos controle total da nossa gramática e o &lt;em&gt;tokenizer&lt;/em&gt; não vai nos atrapalhar.&lt;/p&gt;




&lt;p&gt;Com isso resolvido vamos continuar com nossa modificação, primeiramente implementando os operadores &lt;code&gt;*&lt;/code&gt; e &lt;code&gt;/&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Adicionando os operadores &lt;code&gt;*&lt;/code&gt; e &lt;code&gt;/&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Vamos adicionar os operadores à gramática:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;factor_operator
  -&amp;gt; %star {% id %}
  | %slash {% id %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E a regra de expressão única do tipo &lt;em&gt;factor&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;factor_expression
  -&amp;gt; literal __ factor_operator __ literal {% data =&amp;gt; ({
    type: 'binary_expression',
    operator: data[2],
    left: data[0],
    right: data[4],
  }) %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;vamos também adicionar a regra &lt;code&gt;factor_expression&lt;/code&gt; como opção para definição de um &lt;code&gt;program&lt;/code&gt; válido:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;program
  -&amp;gt; literal {% id %}
  | term_expression {% id %}
  | factor_expression {% id %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lembrando mais uma vez que por enquanto a linguagem suporta apenas uma expressão por vez. Uma multi-expressão como essa &lt;code&gt;2 + 3 * 4&lt;/code&gt; ainda não é suportada pela nossa linguagem, trabalharemos nisso mais pra frente.&lt;/p&gt;

&lt;p&gt;Para prosseguirmos vamos compilar nossa gramática com o comando &lt;code&gt;pnpm nc&lt;/code&gt;.&lt;br&gt;
Também vou alterar nosso programa exemplo dessa forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2 * 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E compilar o programa: &lt;code&gt;node parser ex.ln0&lt;/code&gt;&lt;br&gt;
O resultado final é correto e fica dessa forma (omiti algumas informações por efeitos de concisão):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "type": "binary_expression",
  "operator": {
    "type": "star",
    "value": "*",
    //...
  },
  "left": {
    "type": "int",
    "value": "2",
    //...
  },
  "right": {
    "type": "int",
    "value": "2",
    //...
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como os novos operadores geram &lt;em&gt;nodes&lt;/em&gt; do tipo &lt;em&gt;binary_expression&lt;/em&gt; não precisamos alterar nosso arquivo &lt;code&gt;typecheck.js&lt;/code&gt;. Da mesma forma nossa função &lt;code&gt;gen_binary_expression&lt;/code&gt; do nosso arquivo &lt;code&gt;generator.js&lt;/code&gt; já funcionará corretamente.&lt;/p&gt;

&lt;p&gt;Para verificar vou continuar com o processo rodando o comando &lt;code&gt;node typecheck ast.json&lt;/code&gt;, o resultado é &lt;em&gt;true&lt;/em&gt;.&lt;br&gt;
E rodando o comando &lt;code&gt;node generator ast.json&lt;/code&gt;, o resultado é o arquivo &lt;code&gt;output.js&lt;/code&gt; contendo o texto &lt;code&gt;2 * 2&lt;/code&gt;, ou seja, tudo funcionando perfeitamente.&lt;/p&gt;
&lt;h3&gt;
  
  
  Adicionando operadores unários
&lt;/h3&gt;

&lt;p&gt;Operadores unário são operadores que recebem apenas um operando, os principais são o operador de negação lógica &lt;code&gt;!&lt;/code&gt; e o operador de negação aritmética &lt;code&gt;-&lt;/code&gt; repare que o o símbolo &lt;code&gt;-&lt;/code&gt; pode ser tanto o operador binário de subtração aritmética quanto a outra versão, o operador unários.&lt;/p&gt;

&lt;p&gt;Para evitar confusão vamos definir uma regra geral para a linguagem onde os operadores unário dever estar localizados imediatamente ao lado do operando, por exemplo, esse seria um código inválido &lt;code&gt;- 2&lt;/code&gt;, por causa do espaço, o correto seria &lt;code&gt;-2&lt;/code&gt; sem espaço.&lt;/p&gt;

&lt;p&gt;Para isso precisamos alterar nossa gramática e nosso tokenizer mais uma vez.&lt;/p&gt;

&lt;p&gt;Começando com alterações dos tokens, vamos adicionar o símbolo de negação lógica &lt;code&gt;!&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//...
  bang: '!',
//...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na nossa gramática vamos criar as regras para operadores e expressões unárias:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;unary_operator
  -&amp;gt; %bang {% id %}
  | %dash {% id %}

#...

unary_expression
  -&amp;gt; unary_operator literal {% data =&amp;gt; ({
    type: 'unary_expression',
    operator: data[0],
    argument: data[1],
  }) %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perceba que na definição de &lt;code&gt;unary_expression&lt;/code&gt; não há nenhuma regra de espaçamento (&lt;code&gt;_&lt;/code&gt; ou &lt;code&gt;__&lt;/code&gt;) para indicarmos que espaço entre o operador e o operando é proibido.&lt;/p&gt;

&lt;p&gt;Precisamos incluir a nova regra na definição de &lt;code&gt;program&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;program
  -&amp;gt; literal {% id %}
  | term_expression {% id %}
  | factor_expression {% id %}
  | unary_expression {% id %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora podemos compilar o arquivo de gramática usando &lt;code&gt;pnpm nc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Vamos alterar nosso exemplo agora para fazer o teste de compilação:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;rodando o comando &lt;code&gt;node parser ex.ln0&lt;/code&gt; temos como resultado a seguinte AST:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "type": "unary_expression",
  "operator": {
    "type": "dash",
    "value": "-",
    "text": "-",
    "offset": 0,
    "lineBreaks": 0,
    "line": 1,
    "col": 1
  },
  "argument": {
    "type": "int",
    "value": "3",
    "text": "3",
    "offset": 1,
    "lineBreaks": 0,
    "line": 1,
    "col": 2
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O que indica que tudo está funcionando corretamente.&lt;/p&gt;

&lt;p&gt;Para finalizar basta adicionar novas funções para expressões unárias nos arquivos &lt;code&gt;typecheck.js&lt;/code&gt; e &lt;code&gt;generator.js&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Começando com o &lt;code&gt;typecheck.js&lt;/code&gt; precisamos criar uma função &lt;code&gt;check_unary_expression&lt;/code&gt; e alterar nossa lógica principal.&lt;br&gt;
Primeiro criamos a função:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function check_unary_expression(node) {
  const { argument } = node
  return check_number(argument)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E agora alteramos a lógica principal adicionando a &lt;em&gt;branch&lt;/em&gt; de &lt;code&gt;unary_expression&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function check_program(ast) {
  const { type } = ast
  if (type === 'literal') {
    return check_literal(ast)
  } else if (type === 'binary_expression') {
    return check_binary_expression(ast)
  } else if (type === 'unary_expression') {
    return check_unary_expression(ast)
  } else {
    console.log(`Invalid AST has type = ${type}`)
    return false
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rodando o comando &lt;code&gt;node typecheck ast.json&lt;/code&gt; o resultado no console é &lt;code&gt;true&lt;/code&gt; indicando sucesso.&lt;/p&gt;

&lt;p&gt;Por último vamos criar a função no arquivo &lt;code&gt;generator.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function gen_unary_expression(node) {
  const { operator, argument } = node
  return `${operator.value}${argument.value}`
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E agora basta alterar a lógica principal também:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function gen_program(ast) {
  const { type } = ast
  if (type === 'literal') {
    return gen_literal(ast)
  } else if (type === 'binary_expression') {
    return gen_binary_expression(ast)
  } else if (type === 'unary_expression') {
    return gen_unary_expression(ast)
  } else {
    console.log(`Invalid AST has type = ${type}`)
    return ''
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rodando o comando &lt;code&gt;node generator ast.json&lt;/code&gt; o arquivo &lt;code&gt;output.js&lt;/code&gt; possuiu o texto &lt;code&gt;-3&lt;/code&gt; indicando que tudo está funcionando corretamente&lt;/p&gt;

&lt;h3&gt;
  
  
  Próximos passos
&lt;/h3&gt;

&lt;p&gt;Por enquanto nossa expressões são "únicas", ou seja, expressões encadeadas como essa &lt;code&gt;2 + 3 * 4&lt;/code&gt; simplesmente não são suportadas pela nossa linguagem ainda e é nisso que vamos trabalhar no &lt;a href="https://dev.to/lucas_ac_am/expressoes-encadeadas-e-agrupamento-14g6"&gt;próximo capítulo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>programminglanguage</category>
      <category>javascript</category>
      <category>series</category>
      <category>languagedesign</category>
    </item>
    <item>
      <title>Operadores numéricos são mais complexos do que parece</title>
      <dc:creator>nullen box</dc:creator>
      <pubDate>Wed, 20 Dec 2023 20:53:36 +0000</pubDate>
      <link>https://dev.to/nullenbox/operadores-numericos-sao-mais-complexos-do-que-parece-2f16</link>
      <guid>https://dev.to/nullenbox/operadores-numericos-sao-mais-complexos-do-que-parece-2f16</guid>
      <description>&lt;h3&gt;
  
  
  O que faremos
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://dev.to/lucas_ac_am/alem-dos-numeros-expandindo-a-linguagem-2b0j"&gt;No último post&lt;/a&gt;, expandimos nossa linguagem para "enxergar" uma única instância de qualquer um dos valores literais que definimos: &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;float&lt;/code&gt;, &lt;code&gt;bool&lt;/code&gt;, &lt;code&gt;string&lt;/code&gt; e &lt;code&gt;char&lt;/code&gt;. Nesse post nosso foco será integrar operadores aritméticos na nossa gramática. &lt;em&gt;Spoiler Alert&lt;/em&gt;: é mais difícil do que parece.&lt;/p&gt;

&lt;p&gt;Isso porque precisamos criar nossa AST corretamente, seguindo a ordem de precedência dos operadores, ou seja, os sinais &lt;code&gt;+&lt;/code&gt; e &lt;code&gt;-&lt;/code&gt; têm mais "importância" do que os de &lt;code&gt;*&lt;/code&gt; e &lt;code&gt;/&lt;/code&gt;. Isso parece ser contraditório, mas faz total sentido, pra entender melhor vamos precisar criar algumas árvores.&lt;/p&gt;

&lt;p&gt;Vamos transformar essa expressão aritmética &lt;code&gt;2 * 3 + 4&lt;/code&gt; em uma AST:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     +
    / \
   2   *
      /  \
     3    4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;perceba que a raiz da AST é a operação &lt;code&gt;+&lt;/code&gt;, isso porque esta operação tem menor precedência, ou seja, ela se "encaixa" na árvore depois, uma outra maneira de entender isso é imaginando que cada operador tem uma distância limite onde procuram os operandos, quanto maior essa distância menor a precedência do operador.&lt;/p&gt;

&lt;p&gt;Na prática, precisamos criar regras gramaticais diferentes para cada nível de precedência para que o compilador crie a AST de forma correta.&lt;/p&gt;

&lt;h3&gt;
  
  
  Alterando o tokenizer
&lt;/h3&gt;

&lt;p&gt;Como estamos introduzindo novos elementos na linguagem precisamos adicionar novas regras no nosso tokenizer, e neste caso isso é bem fácil, basta definir nomes para caracteres específicos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//...
  bool: /true|false/,
  plus: '+',
  dash: '-',
  star: '*',
  slash: '/',
  NL: { match: '\n', lineBreaks: true },
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso já é o suficiente para adicionar os operadores primários na nossa linguagem, agora o próximo passo é alterar nossa gramática para gerarmos ASTs corretas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Atualizando gramática
&lt;/h3&gt;

&lt;p&gt;Um ponto importante que não podemos ignorar é que agora temos que lidar com espaços em branco, ao escrever uma expressão matemática geralmente escrevemos com espaços em branco ao redor dos operadores, portanto o primeiro passo é definir regras para espaço em branco na nossa gramática.&lt;/p&gt;

&lt;p&gt;A princípio teremos dois tipos de espaço em branco, espaço obrigatório e espaço opcional, isso é uma prática comum de gramática &lt;em&gt;nearley&lt;/em&gt; então vamos manter, vamos ignorar a existência de quebras de linha por enquanto.&lt;/p&gt;

&lt;p&gt;Por questões de simplicidade vamos usar um único &lt;em&gt;underscore&lt;/em&gt; &lt;code&gt;_&lt;/code&gt; para a regra de espaço opcional e &lt;em&gt;underscore&lt;/em&gt; duplo &lt;code&gt;__&lt;/code&gt; para a regra de espaço obrigatório dessa forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#...

_ -&amp;gt; %WS:* {% id %}
__ -&amp;gt; %WS:+ {% id %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos agora criar a regra para os operadores de menor precedência (+, -), pois temos que seguir a hierarquia de precedência inversa (de menor precedência para maior precedência) para formarmos ASTs corretas.&lt;br&gt;
Primeiro definimos a regra de operadores e depois de expressões., a regra de expressão a princípio aceitará uma única instância de expressão, depois vamos expandir para aceitar expressões encadeadas.&lt;br&gt;
A regra para expressões também terá espaçamento obrigatório entre os termos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#...
term_operator
  -&amp;gt; %plus {% id %}
  | %dash {% id %}

term_expression
  -&amp;gt; literal __ term_operator __ literal {% data =&amp;gt; ({
    type: 'binary_expression',
    operator: data[2],
    left: data[0],
    right: data[4],
  }) %}
#...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos alterar nossa regra &lt;code&gt;program&lt;/code&gt; para aceitar agora um único valor literal (como já era antes) ou uma única expressão simples.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#...
program
  -&amp;gt; literal {% id %}
  | term_expression {% id %}
#...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos compilar nossa gramática mais uma vez rodando o comando &lt;code&gt;nearleyc lang0.ne -o lang0.js&lt;/code&gt;&lt;/p&gt;




&lt;p&gt;Nota: Nesse momento percebo que estamos rodando esse comando toda vez, portanto decidi criar um script no meu arquivo package.js para rodar esse comando automaticamente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"scripts": {
  "nc": "nearleyc lang0.ne -o lang0.js"
},
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Portanto a partir de agora vou usar o comando &lt;code&gt;pnpm nc&lt;/code&gt; para compilar minha gramática.&lt;/p&gt;




&lt;p&gt;Voltando ao que estávamos fazendo antes, precisamos testar agora essa nova regra, pra isso vou alterar nosso arquivo de teste para conter apenas um número:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rodar o comando: &lt;code&gt;node parser ex.ln0&lt;/code&gt;&lt;br&gt;
E o resultado está correto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "type": "int",
  "value": "1",
  "text": "1",
  "offset": 0,
  "lineBreaks": 0,
  "line": 1,
  "col": 1
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se alterarmos o arquivo exemplo para conter uma expressão de soma agora:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 + 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E rodarmos o comando novamente: &lt;code&gt;node parser ex.ln0&lt;/code&gt;&lt;br&gt;
O resultado é esse:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "type": "binary_expression",
  "operator": {
    "type": "plus",
    "value": "+",
    "text": "+",
    "offset": 2,
    "lineBreaks": 0,
    "line": 1,
    "col": 3
  },
  "left": {
    "type": "int",
    "value": "1",
    "text": "1",
    "offset": 0,
    "lineBreaks": 0,
    "line": 1,
    "col": 1
  },
  "right": {
    "type": "int",
    "value": "2",
    "text": "2",
    "offset": 4,
    "lineBreaks": 0,
    "line": 1,
    "col": 5
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Está correto.&lt;/p&gt;

&lt;p&gt;Vamos testar com o operador de menos: &lt;code&gt;1 - 2&lt;/code&gt;&lt;br&gt;
Resultado (omiti algumas informações pra ficar mais conciso):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "type": "binary_expression",
  "operator": {
    "type": "dash",
    "value": "-",
    //...
  },
  "left": {
    "type": "int",
    "value": "1",
    //...
  },
  "right": {
    "type": "int",
    "value": "2",
    //...
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Alterando o &lt;em&gt;type checker&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Agora temos um novo node possível, o &lt;code&gt;binary_expression&lt;/code&gt; node, por isso precisamos criar uma nova função específica para &lt;em&gt;checkar&lt;/em&gt; esse node.&lt;br&gt;
Neste começo vamos fazer com que os operadores aritméticos só funcionem com valores numéricos, por tanto, primeiro precisamos criar a função &lt;code&gt;check_number&lt;/code&gt; que retornará &lt;em&gt;true&lt;/em&gt; caso o node seja um valor numérico e &lt;em&gt;false&lt;/em&gt; caso contrário.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function check_number(node) {
  const { type } = node
  return check_int(node) || check_float(node)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora podemos criar a função &lt;code&gt;check_binary_expression&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function check_binary_expression(node) {
  const { left, right } = node
  return check_number(left) &amp;amp;&amp;amp; check_number(right)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com essa nova função em mãos precisamos apenas fazer uma função mais &lt;em&gt;high level&lt;/em&gt; que será responsável por &lt;em&gt;checkar&lt;/em&gt; o programa inteiro, visto que, como foi definido anteriormente, um programa nessa linguagem agora pode ser apenas um valor literal ou apenas uma expressão simples.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function check_program(ast) {
  const { type } = ast
  if (type === 'literal') {
    return check_literal(ast)
  } else if (type === 'binary_expression') {
    return check_binary_expression(ast)
  } else {
    console.log(`Invalid AST has type = ${type}`)
    return false
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basta alterarmos a chamada principal do programa agora:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//...
  const ast = JSON.parse(content);
  console.log(check_program(ast));
} catch(e) {
//...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos testar agora rodando o comando: &lt;code&gt;node typecheck ast.json&lt;/code&gt; e o resultado é &lt;code&gt;true&lt;/code&gt; como esperado.&lt;/p&gt;

&lt;p&gt;Vamos alterar nosso arquivo exemplo para "somar" duas &lt;em&gt;strings&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"2" + "a"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos compilar: &lt;code&gt;node parser ex.ln0&lt;/code&gt;&lt;br&gt;
E verificar: &lt;code&gt;node typecheck ast.json&lt;/code&gt;&lt;br&gt;
O resultado é &lt;code&gt;false&lt;/code&gt;, como esperado, pois definimos que os operandos dos operadores devem ser numéricos.&lt;/p&gt;
&lt;h3&gt;
  
  
  Atualizando o gerador de código
&lt;/h3&gt;

&lt;p&gt;Agora só precisamos criar a função geradora para transformarmos nossa AST de expressão binária em javascript válido.&lt;/p&gt;

&lt;p&gt;Pra isso precisamos criar a função &lt;code&gt;gen_binary_expression&lt;/code&gt;, responsável por transformar um node do tipo &lt;code&gt;binary_expression&lt;/code&gt; em string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function gen_binary_expression(node) {
  const { operator, left, right } = node
  return `${left.value} ${operator.value} ${right.value}`
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E a função &lt;code&gt;gen_program&lt;/code&gt;, que será nossa função &lt;em&gt;high level&lt;/em&gt; para decidir qual função ustilizar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function gen_program(ast) {
  const { type } = ast
  if (type === 'literal') {
    return gen_literal(ast)
  } else if (type === 'binary_expression') {
    return gen_binary_expression(ast)
  } else {
    console.log(`Invalid AST has type = ${type}`)
    return ''
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora é só alterar nossa chamada principal para executar a função &lt;code&gt;gen_program&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//...
  const ast = JSON.parse(contents);
  const output = gen_program(ast);
  fs.writeFileSync('output.js', output);
} catch(e) {
//...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Antes de testar vamos voltar nosso arquivo exemplo para algo mais coerente com nossa linguagem e passar por todas as etapas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Alterar o arquivo &lt;code&gt;ex.ln0&lt;/code&gt; para conter a expressão &lt;code&gt;42 + 1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Compilar a AST do nosso programa rodando &lt;code&gt;node parser ex.ln0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Fazer verificação de tipos rodando &lt;code&gt;node typecheck ast.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Como o resultado foi positivo vamos gerar o javascript final rodando &lt;code&gt;node generator ast.json&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Se verificarmos nosso arquivo &lt;code&gt;output.js&lt;/code&gt; agora teremos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;42 + 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E assim concluímos a primeira etapa do conceito de expressões.&lt;/p&gt;

&lt;h3&gt;
  
  
  Próximos passos
&lt;/h3&gt;

&lt;p&gt;Ainda precisamos dos outros operadores aritméticos &lt;code&gt;*&lt;/code&gt; e &lt;code&gt;/&lt;/code&gt; (que são de outro nível de precedência) para completarmos nossas expressões aritméticas simples, depois ainda temos os operadores unários, operadores de comparação, de lógica, de operações de bit, em fim, muitas coisas ainda pra termos um bom set de operadores.&lt;br&gt;
Porém tudo ficará mais fácil agora e será mais ou menos só uma questão de copiar, colar e ajustar.&lt;br&gt;
Até a próxima!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>language</category>
      <category>languagedesign</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Além dos números: expandindo a linguagem</title>
      <dc:creator>nullen box</dc:creator>
      <pubDate>Sat, 16 Dec 2023 12:11:14 +0000</pubDate>
      <link>https://dev.to/nullenbox/alem-dos-numeros-expandindo-a-linguagem-2b0j</link>
      <guid>https://dev.to/nullenbox/alem-dos-numeros-expandindo-a-linguagem-2b0j</guid>
      <description>&lt;h3&gt;
  
  
  O que faremos
&lt;/h3&gt;

&lt;p&gt;Nós já completamos a primeira parte do desafio, criamos uma gramática para uma linguagem que só reconhece números inteiros e usamos o compilador do pacote &lt;code&gt;nearley&lt;/code&gt; para transformar o arquivo em uma AST, depois fizemos uma simples verificação de &lt;em&gt;tipagem&lt;/em&gt; e por último criamos um arquivo javascript válido.&lt;br&gt;
Pode não parecer muita coisa porque nossa linguagem só "enxerga" números, mas agora temos uma ideia mais concreta de como continuar com o processo.&lt;/p&gt;

&lt;p&gt;O próximo passo é fazer nossa linguagem "enxergar" não só números inteiros, mas também os principais valores primitivos como números float, strings, etc.&lt;/p&gt;

&lt;p&gt;Mas antes de continuar com o código queria fazer uma pausa para tomar decisões de design da linguagem. Como já disse antes essa linguagem será &lt;em&gt;tipada&lt;/em&gt;, então seria como se fosse Typescript ou Rust e embora no final tudo será compilado para javascript eu acho que será um desafio interessante se fizermos algumas divergências de tipos em relação ao javascript.&lt;/p&gt;

&lt;p&gt;No javascript temos alguns tipos literais bem básicos, eles são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;boolean&lt;/li&gt;
&lt;li&gt;number&lt;/li&gt;
&lt;li&gt;string&lt;/li&gt;
&lt;li&gt;undefined&lt;/li&gt;
&lt;li&gt;null&lt;/li&gt;
&lt;li&gt;symbol&lt;/li&gt;
&lt;li&gt;bigint&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Comparado com C por exemplo quem tem 13 variações dos principais tipos de &lt;code&gt;char&lt;/code&gt; até &lt;code&gt;long double&lt;/code&gt;. JavaScript tem uma variação de tipos muito pequena, meu objetivo com essa linguagem é mirar em algo como Rust ou Go, ou seja, será uma linguagem bem simples, porém mais sofisticada do que JavaScript.&lt;/p&gt;

&lt;p&gt;Para começar podemos definir os seguintes tipos básicos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;integer (int)&lt;/li&gt;
&lt;li&gt;float&lt;/li&gt;
&lt;li&gt;char&lt;/li&gt;
&lt;li&gt;string&lt;/li&gt;
&lt;li&gt;boolean (bool)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Não vou incluir nenhum tipo como &lt;code&gt;null&lt;/code&gt; ou &lt;code&gt;undefined&lt;/code&gt; ou algo assim, pois quero usar conceitos mais funcionais. Também não pretendo usar variações de números como &lt;code&gt;octal&lt;/code&gt; ou &lt;code&gt;binary&lt;/code&gt; por enquanto, vamos focar no que é mais importante primeiro.&lt;/p&gt;
&lt;h3&gt;
  
  
  Ajustando tokenizer e testando
&lt;/h3&gt;

&lt;p&gt;Precisamos criar as RegExps dos novos tokens e alterar nosso objeto do tokenizer&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//...
const tokenizer = moo.compile({
  WS: /[ \t]+/,
  string: /"(?:\\["\\]|[^\n"\\])*"/,
  char: /'(?:[^'\\]|\\.)*'/,
  float: /[-+]?(?:\d+\.\d*|\.\d+)(?:[eE][-+]?\d+)?/,
  int: /0|[-+]?[1-9][0-9]*/,
  bool: /true|false/,
  NL: { match: '\n', lineBreaks: true },
})
//..
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lembrando que a ordem aqui importa, por exemplo, o token string deve ser o primeiro dos valores literais, pois independente do que estiver escrito dentro de uma string (números, &lt;em&gt;keywords&lt;/em&gt;, etc) ela sempre vai ser uma string.&lt;/p&gt;

&lt;p&gt;Agora vamos alterar nossa gramática, criaremos uma nova regra chamada &lt;code&gt;literal&lt;/code&gt; que representará todos os valores literais possível (os que discutimos anteriormente) e então nosso programa será definido como uma única instância de um de tais valores.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#...
program -&amp;gt; literal {% id %}

literal
  -&amp;gt; %int {% id %}
  | %float {% id %}
  | %string {% id %}
  | %char {% id %}
  | %bool {% id %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com a mudança da gramática temos que compilar a gramática javascript mais uma vez rodando o comando &lt;code&gt;nearleyc lang0.ne -o lang0.js&lt;/code&gt;&lt;br&gt;
Com a nova gramática podemos compilar nosso arquivo exemplo: &lt;code&gt;node parser ex.ln0&lt;/code&gt;&lt;br&gt;
Esperamos que tudo continue ocorrendo como antes e que o resultado seja esse:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "type": "int",
  "value": "42",
  "text": "42",
  "offset": 0,
  "lineBreaks": 0,
  "line": 1,
  "col": 1
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Porém agora podemos alterar nosso programa para qualquer um dos valores literais que definimos e tudo deve funcionar corretamente, por exemplo, temos aqui um número &lt;em&gt;float&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3.141592
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E o resultado depois de rodar o comando &lt;code&gt;node parser ex.ln0&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "type": "float",
  "value": "3.141592",
  "text": "3.141592",
  "offset": 0,
  "lineBreaks": 0,
  "line": 1,
  "col": 1
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ou a string &lt;code&gt;"3.141592"&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "type": "string",
  "value": "\"3.141592\"",
  "text": "\"3.141592\"",
  "offset": 0,
  "lineBreaks": 0,
  "line": 1,
  "col": 1
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perceba que o programa associa corretamente o "&lt;em&gt;type&lt;/em&gt;" do objeto.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ajustando type checker
&lt;/h3&gt;

&lt;p&gt;Agora que nosso partes gera vários tipos de "ASTs" precisamos criar as funções necessárias para verificar os nodes seguindo a mesma lógica de antes.&lt;/p&gt;

&lt;p&gt;Já possuíamos a função &lt;code&gt;check_int&lt;/code&gt; e vamos apenas copiar e colar, fazer algumas alterações e criar as outras funções:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//...
function check_float(node) {
  const { type } = node
  return type === 'float'
}

function check_char(node) {
  const { type } = node
  return type === 'char'
}

function check_string(node) {
  const { type } = node
  return type === 'string'
}

function check_bool(node) {
  const { type } = node
  return type === 'bool'
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perceba que notoriamente teria como criar uma abstração ou tornar o código menos repetitivo, vou propositalmente ignorar isso por enquanto e futuramente quando tivermos algo mais estável podemos voltar para refatorar.&lt;/p&gt;

&lt;p&gt;Temos agora funções específicas para cada tipo de dado, mas precisamos de uma função que vai &lt;em&gt;checkar&lt;/em&gt; se um valor é literal ou não, isso significa que se conseguirmos o valor &lt;em&gt;true&lt;/em&gt; de alguma das funções que criamos então valor é literal.&lt;br&gt;
Podemos aproveitar o fato de que todas as funções retornam &lt;em&gt;boolean&lt;/em&gt; para tornar esse processo muito fácil, nossa funções pode ser escrita assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function check_literal(node) {
  return (
    check_int(node) ||
    check_float(node) ||
    check_char(node) ||
    check_string(node) ||
    check_bool(node)
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E depois disso, basta trocar a função de &lt;em&gt;checkagem&lt;/em&gt; para ser a &lt;code&gt;check_literal&lt;/code&gt; ao invés de ser a &lt;code&gt;check_int&lt;/code&gt; que estávamos usando até então:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//...
try {
  const content = fs.readFileSync(filename, 'utf8');
  const ast = JSON.parse(content);
  console.log(check_literal(ast));
} catch(e) {
  console.error(e?.message);
  process.exit(1);
}
//...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por enquanto nosso &lt;em&gt;type checker&lt;/em&gt; apenas &lt;em&gt;printa&lt;/em&gt; na tela &lt;em&gt;true&lt;/em&gt; ou &lt;em&gt;false&lt;/em&gt; e isso não ajuda muito a gente, mas futuramente podemos usar ele de maneira mais integrada, por enquanto vamos manter dessa forma para avançarmos mais rápido.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finalizando com &lt;code&gt;generate&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;O último passo é adaptar nosso &lt;em&gt;generator&lt;/em&gt;, tecnicamente nossa função &lt;code&gt;gen_int&lt;/code&gt; já vai funcionar para todos os tipos de &lt;em&gt;node&lt;/em&gt; automaticamente, então a solução mais simples é simplesmente renomear nossa função de &lt;code&gt;gen_int&lt;/code&gt; para &lt;code&gt;gen_literal&lt;/code&gt; e pronto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//...
try {
  const contents = fs.readFileSync(filepath, 'utf8');
  const ast = JSON.parse(contents);
  const output = gen_literal(ast);
  fs.writeFileSync('output.js', output);
} catch(e) {
  console.error(e?.message);
  process.exit(1);
}

function gen_literal(node) {
  const { value } = node
  return value
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Finalização
&lt;/h3&gt;

&lt;p&gt;Nossa linguagem acaba de dar mais um passo e agora consegue "enxergar" instância únicas de &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;float&lt;/code&gt;, &lt;code&gt;bool&lt;/code&gt;, &lt;code&gt;string&lt;/code&gt; e &lt;code&gt;char&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Pensando em próximos passos, já podemos trabalhar com operadores aritméticos como &lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;, &lt;code&gt;*&lt;/code&gt; e &lt;code&gt;/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Te vejo no &lt;a href="https://dev.to/lucas_ac_am/operadores-numericos-sao-mais-complexos-do-que-parece-2f16"&gt;próximo post&lt;/a&gt; :)&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>language</category>
      <category>series</category>
    </item>
    <item>
      <title>A linguagem mais simples possível</title>
      <dc:creator>nullen box</dc:creator>
      <pubDate>Sun, 10 Dec 2023 16:02:27 +0000</pubDate>
      <link>https://dev.to/nullenbox/a-linguagem-mais-simples-possivel-405b</link>
      <guid>https://dev.to/nullenbox/a-linguagem-mais-simples-possivel-405b</guid>
      <description>&lt;p&gt;Para ler esse conteúdo é recomendado que você saiba:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;como um lexer funciona&lt;/li&gt;
&lt;li&gt;como um parser funciona&lt;/li&gt;
&lt;li&gt;o que são parser generators&lt;/li&gt;
&lt;li&gt;o que é uma AST&lt;/li&gt;
&lt;li&gt;o básico sobre type checking&lt;/li&gt;
&lt;li&gt;o básico sobre type inference&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Como nosso objetivo é criar uma linguagem pequena e focando no aprendizado, vamos fazer uma linguagem &lt;em&gt;transpilada&lt;/em&gt; para javascript, ou seja, nosso objetivo é pegar um arquivo escrito nessa nossa linguagem e gerar um arquivo javascript que produza o mesmo resultado. Além disso vamos incluir camadas de &lt;em&gt;tipagem&lt;/em&gt; para tornar o processo mais desafiador e interessante.&lt;/p&gt;

&lt;p&gt;Durante o processo inteiro estarei seguindo este dilema: "faça funcionar, faça do jeito certo, faça ser eficiente.", porém como foco maior na primeira parte para ganharmos velocidade.&lt;/p&gt;

&lt;p&gt;Criar uma linguagem de programação, mesmo que muito pequena, é uma tarefa muito grande, por tanto o primeiro passo dessa jornada será dividir o conceito de "linguagem de programação" em pequenas partes e atacar cada um deles individualmente, a famosa estratégia de dividir para conquistar&lt;/p&gt;

&lt;p&gt;Primeiro vamos refletir sobre o que compõem um linguagem de programação. A princípio podemos fazer essa reflexão em um nível mais alto de abstração, ao meu ver, os principais componentes são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sintaxe: o que e como escrever&lt;/li&gt;
&lt;li&gt;semântica: construções de código, como resolver problemas e significado&lt;/li&gt;
&lt;li&gt;ferramentas: compiladores, sugestões, relatório de erros, colorização, gerenciadores de pacotes, etc.&lt;/li&gt;
&lt;li&gt;bibliotecas: bibliotecas nativas, suporte para bibliotecas da comunidade, etc.&lt;/li&gt;
&lt;li&gt;comunidade: pessoas engajadas e interessadas na linguagem&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Como nosso objetivo é fazer uma linguagem pequena com foco maior em aprendizado, vamos focas apenas nos dois primeiros pontos: sintaxe e semântica. Obviamente precisaremos de ferramentas básicas, mas ao invés de construirmos tais ferramentas vamos usar bibliotecas prontas para acelerar nosso processo, futuramente podemos fazer um mergulho na construção dessas bibliotecas.&lt;/p&gt;

&lt;p&gt;Existem vários conceitos que precisamos definir nessa nossa linguagem, por exemplo, o que é uma função, o que é um operador binário, um objeto, uma lista, etc. Além disso existem várias etapas que precisamos passar para sair da nossa linguagem criada e chegar no javascript final, essas etapas são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tokenize: transformar o texto inicial em tokens&lt;/li&gt;
&lt;li&gt;parse: criar uma AST a partir dos tokens&lt;/li&gt;
&lt;li&gt;type-check: realizar inferência e checagem de tipos na AST gerada&lt;/li&gt;
&lt;li&gt;generate: transformar a AST em javascript válido&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Podemos enxergar isso como uma matrix, onde as colunas são as etapas e as linhas são os conceitos, existem duas estratégias possíveis, column-first ou row-first.&lt;br&gt;
Utilizando a estratégia column-first nós focamos em criar todos os conceitos de uma vez etapa por etapa, já na estratégia row-first, atravessamos todas as etapas um conceito por vez.&lt;br&gt;
Pessoalmente prefiro a última opção, pois nela conseguimos aprender mais sobre o problema que estamos resolvendo enquanto fazemos ajustes e ao mesmo tempo não precisamos nos comprometer muito em cada evolução, resumindo, é uma maneira &lt;em&gt;Agile&lt;/em&gt; de fazer isso.&lt;/p&gt;

&lt;p&gt;Já sabemos as etapas, mas falta aprofundarmos nos conceitos da linguagem, uma lista inicial seria:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;valores literais&lt;/li&gt;
&lt;li&gt;expressões matemáticas&lt;/li&gt;
&lt;li&gt;expressões lógicas&lt;/li&gt;
&lt;li&gt;variáveis&lt;/li&gt;
&lt;li&gt;funções&lt;/li&gt;
&lt;li&gt;estruturas de controle&lt;/li&gt;
&lt;li&gt;estruturas de dados&lt;/li&gt;
&lt;li&gt;comentários&lt;/li&gt;
&lt;li&gt;estruturas de tratamento de erros&lt;/li&gt;
&lt;li&gt;closures&lt;/li&gt;
&lt;li&gt;recursão&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esses são os principais conceitos da linguagem em si, mas ainda temos que pensar nos conceitos de &lt;em&gt;tipagem&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tipos primitivos, de função e de estruturas&lt;/li&gt;
&lt;li&gt;inferência de tipos&lt;/li&gt;
&lt;li&gt;anotações de tipos&lt;/li&gt;
&lt;li&gt;polimorfismo&lt;/li&gt;
&lt;li&gt;tipos criados&lt;/li&gt;
&lt;li&gt;casting&lt;/li&gt;
&lt;li&gt;covariante e contravariante&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esse parece ser um bom resumo do que precisamos fazer, então vamos começar. Pensando no programa mais simples possível, temos um programa com um único valor literal, por exemplo, um número inteiro.&lt;/p&gt;

&lt;p&gt;vamos criar nosso arquivo, ao longo de todo o processo utilizarei a extensão de arquivo &lt;code&gt;.ln0&lt;/code&gt; para denotar programas na linguagem que estamos criando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;42
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como tínhamos combinado antes, vamos passar por todas as etapas do processo agora, como é a primeira vez precisaremos criar muitas coisa&lt;/p&gt;

&lt;p&gt;A primeira etapa é "tokenize", pra isso vamos precisar de uma biblioteca chamada &lt;code&gt;moo&lt;/code&gt;. Vamos instalar a biblioteca e criar nosso arquivo tokenizer.&lt;br&gt;
Nota: estou utilizando o gerenciador de pacotes &lt;code&gt;pnpm&lt;/code&gt; provavelmente você precisará adaptar os comandos se estiver utilizando algum outro.&lt;/p&gt;

&lt;p&gt;Primeiro vamos iniciar o projeto: &lt;code&gt;pnpm init&lt;/code&gt;&lt;br&gt;
Agora instalar o pacote moo: &lt;code&gt;pnpm i moo&lt;/code&gt;&lt;br&gt;
E criar o arquivo &lt;code&gt;tokenizer.js&lt;/code&gt; (na raiz do projeto mesmo)&lt;/p&gt;

&lt;p&gt;No nosso arquivo tokenizer vamos criar uma instância do moo tokenizer e definir nosso tokens iniciais.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const moo = require('moo')

const tokenizer = moo.compile({
  WS: /[ \t]+/,
  int: /0|[-+]?[1-9][0-9]*/,
  NL: { match: '\n', lineBreaks: true },
})

module.exports = tokenizer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Primeira etapa concluída, nós temos agora um tokenizer que é capaz de gerar tokens de números inteiros (e também de espaços e de quebra de linha). A próxima etapa é a etapa de &lt;em&gt;parsing&lt;/em&gt; onde vamos transformar o token em uma AST.&lt;br&gt;
Pra isso vamos utilizar a biblioteca &lt;code&gt;nearley&lt;/code&gt;.&lt;br&gt;
Instalando nearley: &lt;code&gt;pnpm i nearley&lt;/code&gt;&lt;br&gt;
Precisamos do compilador então vamos instalar também globalmente: &lt;code&gt;pnpm i -g nearley&lt;/code&gt;&lt;br&gt;
Para utilizar essa biblioteca precisamos criar um arquivo de gramática com a extensão &lt;code&gt;.ne&lt;/code&gt;, esse arquivo será utilizado para gerar um outro arquivo de gramática em javascript que por sua vez será utilizado pelo próprio nearley para compilar nossa linaguagem.&lt;br&gt;
O primeiro passo é importar nosso tokenizer (que também pode ser chamado de lexer), fazemos isso dessa forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@{%
const tokenizer = require('./tokenizer')
%}

@lexer tokenizer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos criar nossa primeira regra gramatical que define que nosso programa consiste de um único número inteiro (recomendo dar uma olhada na documentação do nearley pra entender melhor a sintaxe)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#...
program -&amp;gt; %int {% id %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com nosso arquivo gramatical em mãos vamos usar o compilador no nearley &lt;code&gt;nearleyc&lt;/code&gt; para gerar nossa gramática em javascript, pra isso rodamos o comando &lt;code&gt;nearleyc lang0.ne -o lang0.js&lt;/code&gt;. Automaticamente um novo arquivo será gerado.&lt;/p&gt;

&lt;p&gt;O próximo passo é criar um arquivo &lt;em&gt;parser.js&lt;/em&gt;, vamos cria-lo por partes.&lt;br&gt;
Primeiramente vamos verificar os argumentos e pegar o primeiro argumento que deve ser o nome do arquivo que será compilado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const args = process.argv.slice(2);
const filepath = args[0];

if (!filepath) {
  console.error('Usage: node parser.js &amp;lt;filename&amp;gt;');
  process.exit(1);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora para rodar esse programa precisamos passar um argumento, o próximo passo é usar esse argumento &lt;code&gt;filepath&lt;/code&gt; para ler o conteúdo do arquivo, vamos ignorar os edge-cases por enquanto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fs = require('fs');

const args = process.argv.slice(2);
//...
}

const file = fs.readFileSync(filepath, 'utf8');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com a habilidade de pegarmos o conteúdo do arquivo de input, vamos agora importar nossa gramática javascript e o parser do nearley para compilar o conteúdo do arquivo e escrever a AST final&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const nearley = require('nearley')
const grammar = require('./lang0')
const fs = require('fs');
//...
const file = fs.readFileSync(filepath, 'utf8');
const parser = new nearley.Parser(nearley.Grammar.fromCompiled(grammar))
parser.feed(file)

if (parser.results.length === 0) {
  console.log('Parsing error')
} else if (parser.results.length === 1) {
  const ast = parser.results[0];
  fs.writeFileSync('ast.json', JSON.stringify(ast, null, 2));
} else {
  console.log('Ambiguous grammar')
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note que existem 3 casos finais, ao compilar o arquivo input o compilador pode encontrar algum erro e gerar nenhum resultado, pode encontrar nenhum erro e gerar um resultado (o que esperamos que aconteça) ou pode encontrar nenhum erro porém gerar mais de um resultado o que indica uma falha na nossa gramática.&lt;/p&gt;

&lt;p&gt;Para compilar nosso arquivo exemplo basta executar nosso arquivo parser: &lt;code&gt;node parser ex.ln0&lt;/code&gt;&lt;br&gt;
Ao executar o comando um novo arquivo será criado, o nosso arquivo &lt;code&gt;ast.json&lt;/code&gt; que deve estar assim&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "type": "int",
  "value": "42",
  "text": "42",
  "offset": 0,
  "lineBreaks": 0,
  "line": 1,
  "col": 1
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mais uma etapa concluída, temos apenas mais duas etapas pela frente, checagem de tipos e geração do arquivo final&lt;/p&gt;

&lt;p&gt;Checar a &lt;em&gt;tipagem&lt;/em&gt; desse nosso programa é muito simples porque temos apenas um número e um número é um valor literal, além disso como podemos notar a nossa AST possui um atributo "type" que podemos utilizar, mas antes de qualquer coisa precisamos montar a AST em memória para trabalharmos com ela, pra isso vamos iniciar nosso arquivo &lt;code&gt;typecheck.js&lt;/code&gt; dessa forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const path = require('path');
const fs = require('fs');

const args = process.argv.slice(2);
const filename = args[0];

if (!filename) {
  console.error('Usage: node typecheck.js &amp;lt;filename&amp;gt; [.json]');
  process.exit(1);
}

if (path.extname(filename) !== '.json') {
  console.error('Filename must have .json extension');
  process.exit(1);
}

try {
  const content = fs.readFileSync(filename, 'utf8');
  const ast = JSON.parse(content);
} catch(e) {
  console.error(e?.message);
  process.exit(1);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora podemos criar a função que verifica se nossa AST (node) é um número inteiro, repare que a partir de agora vou chamar os objetos de &lt;code&gt;node&lt;/code&gt; porque futuramente usaremos recursão para analisarmos estruturas mais complexas&lt;/p&gt;

&lt;p&gt;Nossa função de verificação será muito básica, dê uma olhada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function check_int(node) {
  const { type } = node
  return type === 'int'
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E agora é só verificar nossa AST de antes de &lt;em&gt;printar&lt;/em&gt; o resultado na tela&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//...
  const ast = JSON.parse(content);
  console.log(check_int(ast));
} catch(e) {
//...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por enquanto isso é o que precisamos.&lt;br&gt;
Por último vamos transformar essa AST em um arquivo javascript, para fazer isso vamos criar o arquivo &lt;code&gt;generator.js&lt;/code&gt;: Iniciamos com a mesma lógica do último arquivo para criarmos a AST em memória&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const path = require('path');

const args = process.argv.slice(2);
const filepath = args[0];

if (!filepath) {
  console.error('Usage: node generator.js &amp;lt;filename&amp;gt;');
  process.exit(1);
}

if (!path.extname(filepath) === '.json') {
  console.error('Filename must have .json extension');
  process.exit(1);
}

try {
  const contents = fs.readFileSync(filepath, 'utf8');
  const ast = JSON.parse(contents);
} catch(e) {
  console.error(e?.message);
  process.exit(1);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E agora podemos criar nossa função geradora:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function gen_int(node) {
  const { value } = node
  return value
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por fim podemos chamar essa função passando nossa  AST e salvando o resultado em um arquivo javascript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fs = require('fs');
const path = require('path');
//...
  const ast = JSON.parse(contents);
  const output = gen_int(ast);
  fs.writeFileSync('output.js', output);
} catch(e) {
//...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depois de rodar o comando &lt;code&gt;node generator ast.json&lt;/code&gt; um novo arquivo &lt;code&gt;output.js&lt;/code&gt; deve ter sido criado na raiz do projeto contendo um único número inteiro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;42
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se quiser é possível rodar esse programa javascript com &lt;code&gt;node output&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Pronto, finalizamos o menor conceito dentro do nosso escopo, começamos com um número inteiro na nossa linguagem e passamos por 4 etapas até chegar em um número inteiro em javascript.&lt;br&gt;
Como números inteiros são sempre os mesmos então isso não parece ser muita coisa, mas já temos todo o pavimento necessário para as próximas evoluções.&lt;br&gt;
Números inteiros fazem parte do grupo dos valores literais, assim como os números com ponto flutuante, strings, &lt;em&gt;chars&lt;/em&gt;, &lt;em&gt;bools&lt;/em&gt;, entre outros.&lt;br&gt;
Nosso próximo passo agora está muito claro, expandir todo o nosso sistema para que possamos criar um programa com qualquer um dos valores literais e conseguir chegar em um arquivo javascript válido no final.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>programming</category>
      <category>languagedesign</category>
      <category>languagecreation</category>
    </item>
  </channel>
</rss>
