{"id":4323,"date":"2026-03-06T19:07:43","date_gmt":"2026-03-06T16:07:43","guid":{"rendered":"https:\/\/demensdeum.com\/blog\/2026\/03\/06\/interpreter-in-practice\/"},"modified":"2026-03-06T19:41:37","modified_gmt":"2026-03-06T16:41:37","slug":"interpreter-in-practice","status":"publish","type":"post","link":"https:\/\/demensdeum.com\/blog\/pt\/2026\/03\/06\/interpreter-in-practice\/","title":{"rendered":"Interpretador de padr\u00f5es na pr\u00e1tica"},"content":{"rendered":"<p>No <a href=\"https:\/\/demensdeum.com\/blog\/2022\/06\/24\/pattern-interpreter\/\">\u00faltimo artigo<\/a> examinamos a teoria do padr\u00e3o Interpreter, aprendemos o que \u00e9 uma \u00e1rvore AST e como abstrair express\u00f5es terminais e n\u00e3o terminais. Desta vez, vamos nos afastar da teoria e ver como esse padr\u00e3o \u00e9 aplicado em projetos comerciais s\u00e9rios que todos usamos todos os dias!<\/p>\n<p>Spoiler: <b>Voc\u00ea pode estar usando o padr\u00e3o Interpreter agora mesmo, apenas lendo este texto no seu navegador!<\/b><\/p>\n<p>Um dos exemplos mais marcantes e, talvez, mais importantes do uso desse padr\u00e3o na ind\u00fastria \u00e9 o <b>JavaScript<\/b>. A linguagem, que originalmente foi criada \u201cno joelho\u201d, hoje funciona em bilh\u00f5es de dispositivos justamente gra\u00e7as ao conceito de interpreta\u00e7\u00e3o.<\/p>\n<h2>10 dias que mudaram a Internet<\/h2>\n<p>A hist\u00f3ria do JavaScript est\u00e1 cheia de lendas. Em 1995, Brendan Eich, enquanto trabalhava na Netscape Communications, recebeu a tarefa de criar uma linguagem de script simples que pudesse ser executada diretamente em um navegador (Netscape Navigator) para tornar as p\u00e1ginas da web interativas. A administra\u00e7\u00e3o queria algo com uma sintaxe semelhante ao ent\u00e3o super popular Java, mas destinado n\u00e3o a engenheiros profissionais, mas a web designers.<\/p>\n<p>Eich teve apenas <b>10 dias<\/b> para escrever o primeiro prot\u00f3tipo da linguagem, que ent\u00e3o se chamava Mocha (depois LiveScript, e s\u00f3 depois JavaScript por raz\u00f5es de marketing). A pressa n\u00e3o foi acidental: a Microsoft estava logo atr\u00e1s, que ao mesmo tempo preparava ativamente sua pr\u00f3pria linguagem de script <b>VBScript<\/b> para ser incorporada no navegador Internet Explorer. A Netscape precisava liberar urgentemente sua resposta para n\u00e3o perder na iminente guerra dos navegadores.<\/p>\n<p>Simplesmente n\u00e3o havia tempo para escrever um compilador complexo em c\u00f3digo de m\u00e1quina. A solu\u00e7\u00e3o \u00f3bvia e mais r\u00e1pida para Eich foi a arquitetura do cl\u00e1ssico <b>Interpreter<\/b>.<\/p>\n<p>O primeiro int\u00e9rprete (SpiderMonkey) funcionou assim:<\/p>\n<ol>\n<li>Ele l\u00ea o c\u00f3digo-fonte do texto do script na p\u00e1gina.<\/li>\n<li>O analisador l\u00e9xico dividiu o texto em tokens.<\/li>\n<li>O analisador construiu uma <b>\u00c1rvore de Sintaxe Abstrata (AST)<\/b>. Em termos do padr\u00e3o Interpreter, esta \u00e1rvore consistia em <i>express\u00f5es terminais<\/i> (strings, n\u00fameros como 42) e <i>n\u00e3o terminais<\/i> (chamadas de fun\u00e7\u00e3o, instru\u00e7\u00f5es como If, \u200b\u200bWhile).<\/li>\n<li>Ent\u00e3o a m\u00e1quina virtual \u201catravessou\u201d esta \u00e1rvore passo a passo, executando as instru\u00e7\u00f5es embutidas nela em cada n\u00f3 (chamando um m\u00e9todo semelhante a Interpret()).<\/li>\n<\/ol>\n<h2>Contexto e Objetos<\/h2>\n<p>Lembra do objeto Context que tivemos que passar para o m\u00e9todo Interpret(Context context) na implementa\u00e7\u00e3o cl\u00e1ssica? O int\u00e9rprete precisa dele para armazenar o estado atual da mem\u00f3ria.<\/p>\n<p>No caso do JavaScript, o papel deste contexto no n\u00edvel superior \u00e9 desempenhado por um <b>objeto global<\/b> (por exemplo, uma janela em um navegador). Quando seu n\u00f3 AST tenta, digamos, escrever texto na tela via document.write(&#8220;Hello&#8221;), o interpretador acessa seu contexto (o objeto document) e chama a API interna do navegador desejada.<\/p>\n<p>\u00c9 gra\u00e7as ao interpretador que o JavaScript \u00e9 capaz de interagir t\u00e3o facilmente com o DOM (Document Object Model) &#8211; todos eles s\u00e3o apenas objetos em um contexto que s\u00e3o acessados \u200b\u200bpor n\u00f3s de \u00e1rvore.<\/p>\n<h2>Evolu\u00e7\u00e3o do int\u00e9rprete: Compila\u00e7\u00e3o JIT<\/h2>\n<p>Historicamente, JS em navegadores permaneceu por muito tempo um int\u00e9rprete \u201cpuro\u201d. E isso tinha uma grande desvantagem &#8211; velocidade lenta. Analisar a \u00e1rvore e percorrer cada n\u00f3 lentamente cada vez que o script era executado tornava aplicativos da Web complexos mais lentos.<\/p>\n<p>Com o advento do mecanismo <b>V8<\/b> do Google (integrado ao Chrome) em 2008, ocorreu uma revolu\u00e7\u00e3o. Os engenheiros perceberam que um int\u00e9rprete n\u00e3o \u00e9 suficiente para a web moderna. O mecanismo se tornou mais complexo: ele ainda constr\u00f3i a \u00e1rvore AST, mas agora usa <b>compila\u00e7\u00e3o JIT (Just-In-Time)<\/b>.<\/p>\n<p>Os mecanismos JS modernos (V8, SpiderMonkey) funcionam como um pipeline complexo:<\/p>\n<ol>\n<li>O interpretador base r\u00e1pido e burro come\u00e7a a executar seu c\u00f3digo JS instantaneamente, sem sequer esperar que ele seja compilado (o padr\u00e3o cl\u00e1ssico ainda funciona aqui).<\/li>\n<li>Paralelamente, o mecanismo monitora se\u00e7\u00f5es \u201cquentes\u201d do c\u00f3digo (loops ou fun\u00e7\u00f5es que s\u00e3o chamadas milhares de vezes).<\/li>\n<li>Essas se\u00e7\u00f5es s\u00e3o compiladas pelo compilador JIT diretamente no c\u00f3digo de m\u00e1quina otimizado, ignorando o interpretador lento.<\/li>\n<\/ol>\n<p>Foi essa combina\u00e7\u00e3o do in\u00edcio instant\u00e2neo do interpretador e do poder computacional de compila\u00e7\u00e3o que permitiu que o JavaScript dominasse o mundo, tornando-se a linguagem dos servidores (Node.js) e dos aplicativos m\u00f3veis (React Native).<\/p>\n<h2>Int\u00e9rprete na ind\u00fastria de jogos<\/h2>\n<p>Apesar do dom\u00ednio do C++ na computa\u00e7\u00e3o pesada, o padr\u00e3o Interpreter \u00e9 um padr\u00e3o da ind\u00fastria no desenvolvimento de jogos para a cria\u00e7\u00e3o de l\u00f3gica de jogos. Para que? Para que os designers de jogos possam fazer jogos sem o risco de \u201cdeixar cair\u201d o motor ou a necessidade de recompil\u00e1-lo constantemente.<\/p>\n<p>Um excelente exemplo hist\u00f3rico \u00e9 o <b>UnrealScript<\/b> &#8211; a linguagem na qual a l\u00f3gica dos jogos Unreal Tournament e Gears of War foi escrita no Unreal Engine 1, 2 e 3. O texto foi compilado em um bytecode de m\u00e1quina abstrato compacto, que foi ent\u00e3o passo a passo (interpretado) pela m\u00e1quina virtual do motor.<\/p>\n<h3>Scripts gr\u00e1ficos visuais (Blueprints)<\/h3>\n<p>Hoje, o texto foi substitu\u00eddo pela programa\u00e7\u00e3o visual &#8211; o sistema <b>Blueprints<\/b> no Unreal Engine 4 e 5.<\/p>\n<p>Se voc\u00ea j\u00e1 abriu um Blueprint no Unreal Engine, viu muitos n\u00f3s conectados por fios. Arquitetonicamente, <b>todo o gr\u00e1fico do Blueprints \u00e9 uma enorme \u00c1rvore de Sintaxe Abstrata (AST)<\/b> desenhada na tela:<\/p>\n<ol>\n<li><b>Express\u00f5es de Terminal:<\/b> N\u00f3s constantes. Por exemplo, um n\u00f3 que simplesmente armazena o n\u00famero 42 ou uma string. Eles retornam um valor espec\u00edfico quando interpretados.<\/li>\n<li><b>Express\u00f5es n\u00e3o terminais:<\/b> N\u00f3s de computa\u00e7\u00e3o (Adicionar) ou n\u00f3s de controle de fluxo (Filial). Eles t\u00eam entradas de argumentos, que o int\u00e9rprete avalia primeiro recursivamente antes de produzir o resultado como um pino de sa\u00edda.<\/li>\n<\/ol>\n<p>E o papel do contexto aqui \u00e9 desempenhado pela mem\u00f3ria de uma inst\u00e2ncia de um objeto de jogo espec\u00edfico (Ator). A M\u00e1quina Interpretadora \u201ccaminha\u201d com seguran\u00e7a por esse gr\u00e1fico, solicitando dados e realizando transi\u00e7\u00f5es.<\/p>\n<h2>Onde mais o Interpretador \u00e9 usado?<\/h2>\n<p>O padr\u00e3o de int\u00e9rprete pode ser encontrado em quase todos os sistemas complexos onde instru\u00e7\u00f5es din\u00e2micas precisam ser executadas. Aqui est\u00e3o apenas alguns exemplos de software comercial:<\/p>\n<ul>\n<li><b>Linguagens de programa\u00e7\u00e3o interpretadas (Python, Ruby, PHP).<\/b> Todo o seu tempo de execu\u00e7\u00e3o \u00e9 baseado no padr\u00e3o cl\u00e1ssico. Por exemplo, a implementa\u00e7\u00e3o de refer\u00eancia do CPython primeiro analisa seu script .py em um AST, compila-o em bytecode e, em seguida, uma enorme m\u00e1quina virtual (loop de computa\u00e7\u00e3o) interpreta esse bytecode passo a passo.<\/li>\n<li><b>Java Virtual Machine (JVM).<\/b> Inicialmente, o c\u00f3digo Java \u00e9 compilado n\u00e3o em instru\u00e7\u00f5es de m\u00e1quina, mas em bytecode. Quando voc\u00ea executa o aplicativo, a JVM atua como um int\u00e9rprete (embora com compila\u00e7\u00e3o JIT agressiva, assim como na V8).<\/li>\n<li><b>Bancos de dados e SQL<\/b> Quando voc\u00ea emite uma consulta SQL (SELECT * FROM users) no PostgreSQL ou MySQL, o mecanismo de banco de dados atua como um int\u00e9rprete. Ele realiza an\u00e1lises lexicais, constr\u00f3i uma \u00e1rvore de consulta AST, gera um plano de execu\u00e7\u00e3o e, em seguida, literalmente \u201cinterpreta\u201d esse plano iterando nas linhas das tabelas.<\/li>\n<li><b>Express\u00f5es regulares (RegEx).<\/b> Qualquer mecanismo de express\u00e3o regular analisa internamente um padr\u00e3o de string (por exemplo, ^\\d{3}-\\d{2}$) em um gr\u00e1fico de estado (NFA\/DFA Automata), pelo qual o interpretador interno passa, combinando cada caractere de entrada com os v\u00e9rtices deste gr\u00e1fico.<\/li>\n<li><b>Unity Shader Graph<\/b> \/ <b>Unreal Material Editor<\/b> &#8211; interpreta n\u00f3s visuais em c\u00f3digo de shader modular (GLSL\/HLSL).<\/li>\n<li><b>N\u00f3s de geometria do Blender<\/b> &#8211; interpreta opera\u00e7\u00f5es matem\u00e1ticas e geom\u00e9tricas para gerar modelos 3D de forma processual em tempo real.<\/li>\n<\/ul>\n<h2>Total<\/h2>\n<p>O padr\u00e3o Interpreter j\u00e1 ultrapassou o escopo de \u201cescrever sua pr\u00f3pria calculadora\u201d. Este \u00e9 o padr\u00e3o mais poderoso da ind\u00fastria. Desde mecanismos JavaScript que executam gigabytes de c\u00f3digo nos bastidores dos navegadores todos os dias at\u00e9 designers de jogos que permitem construir l\u00f3gica complexa sem conhecimento de C++, os int\u00e9rpretes continuam sendo um dos conceitos de arquitetura mais importantes no desenvolvimento de TI moderno.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>No \u00faltimo artigo examinamos a teoria do padr\u00e3o Interpreter, aprendemos o que \u00e9 uma \u00e1rvore AST e como abstrair express\u00f5es terminais e n\u00e3o terminais. Desta vez, vamos nos afastar da teoria e ver como esse padr\u00e3o \u00e9 aplicado em projetos comerciais s\u00e9rios que todos usamos todos os dias! Spoiler: Voc\u00ea pode estar usando o padr\u00e3o<a class=\"more-link\" href=\"https:\/\/demensdeum.com\/blog\/pt\/2026\/03\/06\/interpreter-in-practice\/\">Continue reading <span class=\"screen-reader-text\">&#8220;Interpretador de padr\u00f5es na pr\u00e1tica&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[61,52],"tags":[],"class_list":["post-4323","post","type-post","status-publish","format-standard","hentry","category-techie","category-tutorials","entry"],"translation":{"provider":"WPGlobus","version":"3.0.2","language":"pt","enabled_languages":["en","ru","zh","de","fr","ja","pt","hi"],"languages":{"en":{"title":true,"content":true,"excerpt":false},"ru":{"title":true,"content":true,"excerpt":false},"zh":{"title":true,"content":true,"excerpt":false},"de":{"title":true,"content":true,"excerpt":false},"fr":{"title":true,"content":true,"excerpt":false},"ja":{"title":true,"content":true,"excerpt":false},"pt":{"title":true,"content":true,"excerpt":false},"hi":{"title":false,"content":false,"excerpt":false}}},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/4323","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=4323"}],"version-history":[{"count":2,"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/4323\/revisions"}],"predecessor-version":[{"id":4325,"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/4323\/revisions\/4325"}],"wp:attachment":[{"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=4323"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=4323"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=4323"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}