🇧🇷 JLScript: criando uma linguagem de programação brasileira do zero
Em 2026 comecei um projeto que inicialmente parecia relativamente simples:
criar minha própria linguagem de programação.
O nome dela é JLScript, ou simplesmente JLS.
Os arquivos utilizam a extensão:
.jls
No começo eu queria principalmente experimentar uma sintaxe que fosse simples para mim.
Só que existe um pequeno problema quando você decide criar uma linguagem:
você começa querendo interpretar algumas linhas de código e, quando percebe, está estudando lexer, parser, AST, runtime, escopos, compiladores, bytecode, concorrência, módulos e sabe-se lá mais o quê.
Foi exatamente o que aconteceu.
O que é JLScript?
JLScript é uma linguagem de programação brasileira que estou desenvolvendo principalmente em C++.
Minha ideia é combinar três coisas:
simplicidade
+
produtividade
+
capacidade de crescer
Não quero criar simplesmente outro Python ou outro JavaScript.
Naturalmente existem ideias inspiradas em linguagens que já utilizamos, mas também estou experimentando decisões próprias.
Hoje a arquitetura do projeto já envolve:
Código .jls
│
▼
Lexer
│
▼
Parser
│
▼
AST
│
├──────────────┐
▼ ▼
Interpreter Compiler
│ │
▼ ▼
Runtime C++ / Bytecode
Português e inglês
Uma das ideias do JLScript é permitir construções em português e inglês.
Por exemplo:
se (idade >= 18) {
mostrar('Maior de idade')
} senao {
mostrar('Menor de idade')
}
Também posso escrever:
if (idade >= 18) {
mostrar('Maior de idade')
} else {
mostrar('Menor de idade')
}
Não quero que o português limite a linguagem ao Brasil.
Quero justamente que ela possa ter uma identidade brasileira e ainda permitir uma escrita familiar para desenvolvedores de outros lugares.
Variáveis
Atualmente a linguagem trabalha com formas como:
va nome = 'Lucas'
let linguagem = 'JLScript'
ins ativo = true
O runtime possui valores fundamentais como:
STRING
NUMBER
BOOLEAN
NULL
LIST
OBJECT
FUNCTION
Funções
Uma função pode ser declarada explicitamente:
func saudacao(nome) {
mostrar('Olá, ' + nome)
}
Mas também criei uma forma curta:
soma(a, b) {
retorne a + b
}
A ideia é simples:
se a estrutura já deixa claro que aquilo é uma função, por que obrigatoriamente adicionar outra palavra?
Uma decisão diferente no switch
Outra coisa que quis experimentar foi o switch.
Em várias linguagens encontramos algo parecido com:
case:
...
break
No JLScript posso fazer:
switch (opcao) {
case 1 {
mostrar('Iniciar')
}
case 2 {
mostrar('Configurações')
}
default {
mostrar('Sair')
}
}
Cada case possui seu próprio bloco.
O } já deixa claro onde aquele caso termina.
Então não preciso escrever break apenas para repetir essa informação.
Essa acabou se tornando uma das filosofias que tento seguir:
Se a própria estrutura do código já expressa claramente uma intenção, não quero adicionar sintaxe apenas porque outra linguagem faz assim.
O projeto cresceu bastante
A primeira versão oficial, JLScript 1.0.0, era muito menor.
Ela possuía principalmente:
if / else
funções
switch
for
loops
execução básica
CLI inicial
O terminal também era extremamente simples.
Um dos comandos era basicamente:
jls version
Mas aquela versão provou a coisa mais importante:
a linguagem funcionava.
Depois disso comecei a expandir o projeto.
Hoje sua estrutura envolve áreas como:
JLScript
│
├── Lexer
├── Parser
├── AST
├── Interpreter
├── Runtime
├── Execution Engine
├── Modules
├── Compiler
├── C++ Generator
├── Bytecode Compiler
├── CLI
└── Standard Library
CLI própria
A linguagem também ganhou uma CLI:
jls
Com o crescimento do projeto começaram a surgir comandos como:
jls run programa.jls
jls repl
jls build programa.jls
jls compile programa.jls
jls test
jls fmt
jls lint
jls fix
jls doctor
jls update
jls dev
Minha intenção é que o terminal seja parte importante da experiência da linguagem, e não simplesmente um executável que recebe um arquivo.
Compilação
Também comecei a experimentar compilação.
Um dos caminhos atuais utiliza geração de C++:
programa.jls
│
▼
Lexer
│
▼
Parser
│
▼
AST
│
▼
Gerador C++
│
▼
Compilador C++
│
▼
Executável
Ou seja, o código continua sendo escrito em JLScript, mas pode passar por uma etapa de geração e compilação nativa.
Bytecode
Existe também um compilador de bytecode.
Arquivos compilados podem utilizar:
.jlb
O fluxo é aproximadamente:
programa.jls
│
▼
Bytecode Compiler
│
▼
programa.jlb
Essa parte ainda faz parte da evolução da arquitetura da linguagem.
Bibliotecas
Outra área que cresceu bastante foi o sistema de bibliotecas.
Uma biblioteca pode ser importada assim:
import #json
Ou várias:
import [#api, #database, #json]
O projeto já explora diferentes áreas:
#api
#database
#json
#ui
#style
#mobile
#connector
#compiler
#thread
#time
#file
#process
...
Minha ideia é manter funcionalidades especializadas fora do núcleo sempre que fizer sentido.
Interface gráfica usando JLScript
Uma das partes que mais estou experimentando atualmente é permitir construir interfaces utilizando a própria linguagem.
Por exemplo:
import [#ui, #style]
va app = ui.janela()
app.titulo('Login')
app.ui({
div {
text = 'Bem-vindo'
button = 'Entrar'
}
})
app.style({
fundo: '#101010',
cor: '#ffffff',
largura: 800,
altura: 600
})
app.abrir()
A ideia é aproximar algumas facilidades encontradas no desenvolvimento web da criação de aplicações usando JLScript.
Ainda existe bastante trabalho nessa área, mas é uma das partes que pretendo continuar desenvolvendo.
Criar uma linguagem me obrigou a aprender muita coisa
Essa provavelmente foi a parte mais interessante do projeto.
Quando comecei, eu não precisava conhecer profundamente todas as peças de uma linguagem.
Só que cada funcionalidade nova apresentava outro problema.
O processo acabou ficando parecido com isto:
Ideia
↓
Implementação
↓
Erro
↓
"por que isso aconteceu?"
↓
Pesquisa
↓
entender uma parte nova
↓
corrigir
↓
ter outra ideia
Criar funções me fez estudar escopos.
Criar sintaxe me fez estudar lexer e parser.
Criar execução me levou ao runtime.
Criar build me levou a compiladores.
Criar bibliotecas me levou a APIs nativas.
Criar servidores me levou a sockets e concorrência.
Uma coisa vai puxando outra.
Por que o nome JLScript?
O nome também tem uma história.
J = Joicy
L = Lucas
Script = Programação
Portanto:
J + L + Script
↓
JLScript
O J não significa Java nem JavaScript.
Ele representa Joicy Costa.
O L representa Lucas Aguiel Dos Santos De Oliveira, criador da linguagem.
Joicy não participa tecnicamente do desenvolvimento. A presença dela no nome é uma homenagem e registra uma parte da minha história pessoal dentro do projeto.
JLScript e JLScripter
Também existe uma diferença entre alguns nomes que utilizo:
JLScript
↓
a linguagem
JLS
↓
abreviação
.jls
↓
extensão dos arquivos
JLScripter
↓
o ecossistema ao redor da linguagem
Então penso no JLScripter aproximadamente assim:
JLScripter
│
├── JLScript
├── Interpreter
├── Runtime
├── Compiler
├── Bytecode
├── CLI
├── Libraries
├── Developer Tools
└── Documentation
Ainda está em desenvolvimento
JLScript não é um projeto que considero terminado.
Ainda existem partes experimentais, coisas que quero redesenhar, bibliotecas que precisam amadurecer e bastante trabalho no runtime e nas ferramentas.
Mas comparar a primeira versão com o projeto atual é uma das coisas que mais me motiva a continuar.
Começou assim:
condições
funções
loops
switch
CLI simples
E está caminhando para:
linguagem
+
runtime
+
compilação
+
bytecode
+
bibliotecas
+
interfaces
+
ferramentas
Ainda tenho bastante coisa para construir.
E provavelmente bastante coisa para quebrar também. Faz parte de criar uma linguagem do zero. 😅
🇧🇷 JLScript
Uma linguagem brasileira em desenvolvimento.
Simples para começar. Estruturada para crescer.
Criada por Lucas Aguiel Dos Santos De Oliveira.
Top comments (0)