- Lua 78.3%
- C 19.2%
- Makefile 2.5%
brazilian-software-engineering
lusotif e uma pequena linguagem interpretada implementada em Lua.
Ela foi desenhada para ser simples, leve e facil de entender, mas com sintaxe, mensagens e biblioteca padrao em portugues.
Visao Geral
A linguagem segue a mesma arquitetura classica do tif:
- Lexer - converte o codigo-fonte em tokens com rastreamento de linha e coluna
- Parser - constroi uma AST usando Pratt parsing para respeitar precedencia de operadores
- Interpreter - avalia a AST diretamente com escopos, verificacao de tipos e limites de seguranca em runtime
O lusotif funciona tanto com Lua 5.4 quanto com LuaJIT. O build padrao continua priorizando LuaJIT, enquanto Lua 5.4 permanece como opcao de compatibilidade.
Versao Estavel: v0.1-luanda
Esta versao traz para o lusotif a base moderna do tif, incluindo recursos funcionais, correspondencia de padroes, biblioteca padrao modular em C e compilacao por launcher nativo.
Destaques
- Sintaxe em portugues - palavras-chave como
funcao,var,usa,se,senao,combina,estruturaeadiar - Tipos nativos traduzidos -
real,numero,texto,bool,vazioecoisa - Expressoes lambda - funcoes anonimas como valores de primeira classe
- Closures - lambdas capturam o escopo em que foram definidas
- Funcoes de primeira classe - lambdas e funcoes nomeadas podem ser passadas, retornadas e armazenadas
- Parametros opcionais tipados - argumentos
?tiporecebem valor implicito quando omitidos - Interpolacao tipada - suporte a
#{expr}e#(tipo){expr} - Correspondencia de padroes -
combina / casoclassico e estilo=>com faixas, alternativas, capturas e guardas - Estruturas, arranjos e ponteiros - com verificacao de tipo, checagem de limites e heap real via THD
- Biblioteca padrao em portugues -
stdl,stdl/matematica,stdl/ioestdl/sistema - Compilacao com
-o- gera um launcher nativo que embute o fonte do programa - Selecao de linker para build nativo - suporte a
-B <linker>eLUSOTIF_LINKER=xld
Exemplos
Lambda simples:
vardobro=funcao(n){retornan*2}imprime(dobro(5))Lambda tipada:
varquadrado=funcao:: int(int:: x){retornax*x}varresultado=quadrado(7)Funcao de ordem superior:
varsomador=funcao:: int(int:: a){retornafuncao:: int(int:: b){retornaa+b}}varsoma5=somador(5)imprime(soma5(3))Parametro opcional tipado:
funcaofaixa(?int:: inicio,int:: fim)-> <int>[]{// se omitido, `inicio` recebe o padrao implicito do tipo
}Interpolacao tipada:
varcru="12"imprime("valor como int: #(int){cru}")imprime("modo classico: #{cru}")THD - Tif Heap Dialoguer
O THD e a extensao em C que da ao lusotif suporte real para operacoes com ponteiros. Ele e compilado como biblioteca compartilhada (thd.so) e carregado pelo interpretador em tempo de execucao.
Arquitetura
codigo lusotif
|
v
interpreter.lua
| &x -> aloca uma celula no heap do THD
| *px -> le o valor da celula em C
| *px = v -> escreve na celula e sincroniza de volta para a variavel
v
thd.so (extensao Lua em C)
|
v
arena de heap em C
Como funciona
O THD mantem duas regioes de memoria no mesmo processo:
Arena de celulas - um vetor fixo de celulas tipadas para int, float, bool e bytes crus.
Pool de bytes - uma area linear para buffers brutos usados por celulas de bytes.
Ciclo de vida de um ponteiro
varint:: x=5var*int:: px=&x&xpede ao THD uma celula para o valor dex- O interpretador cria um objeto de ponteiro com handle, tipo-base e referencia ao escopo original
*px = 10grava no heap do THD e tambem atualizaxno escopo Lua
Isso garante que imprime(*px) e imprime(x) permaneçam sincronizados.
Seguranca
- Handle invalido - o THD valida o slot antes de ler ou escrever
- Double free - acessos a ponteiros liberados falham imediatamente
- Checagem de tipo -
writevalida o tipo do valor contra o tipo da celula - Limites de byte - leituras e escritas por offset sao validadas
API exposta ao runtime
| Funcao | Descricao |
|---|---|
alloc_int(v) |
aloca uma celula inteira |
alloc_float(v) |
aloca uma celula real |
alloc_bool(v) |
aloca uma celula booleana |
alloc_bytes(n) |
aloca n bytes no pool |
free(handle) |
libera uma celula |
read(handle) |
le o valor de uma celula |
write(handle, v) |
escreve em uma celula com checagem de tipo |
read_byte(handle, i) |
le o byte i |
write_byte(handle, i, b) |
escreve o byte i |
tag(handle) |
retorna a tag do tipo |
size(handle) |
retorna o tamanho em bytes |
addr(handle) |
retorna o endereco real em memoria |
stats() |
retorna estatisticas de alocacao |
Compilando o THD
Com Lua 5.4:
gcc -shared -fPIC -O2 -o thd.so thd.c $(pkg-config --cflags --libs lua5.4)
Com LuaJIT:
gcc -shared -fPIC -O2 -o thd.so thd.c -I/usr/include/luajit-2.1 -L/usr/lib/x86_64-linux-gnu -lluajit-5.1
Biblioteca Padrao
A biblioteca padrao do lusotif e composta por modulos C instalados em /usr/local/lib/lusotif/. O interpretador carrega esses modulos automaticamente quando usa <modulo> e usado.
Layout instalado
/usr/local/lib/lusotif/
|-- *.lua
|-- *.luac
|-- thd.so
|-- stdl.so <- usa <stdl>
`-- stdl/
|-- matematica.so <- usa <stdl/matematica>
|-- io.so <- usa <stdl/io>
`-- sistema.so <- usa <stdl/sistema>
usa <stdl> - utilitarios principais
| Funcao | Descricao |
|---|---|
stdl.imprime(v) |
imprime sem quebra de linha |
stdl.imprimeln(v) |
imprime com quebra de linha |
stdl.err_imprime(v) |
imprime em stderr |
stdl.err_imprimeln(v) |
imprime em stderr com quebra |
stdl.convp_texto(v) |
converte um valor para texto |
stdl.convp_inteiro(v) |
converte para inteiro |
stdl.convp_real(v) |
converte para real |
stdl.convp_bool(v) |
converte para bool |
stdl.tipo(v) |
retorna o nome do tipo em portugues |
stdl.afirma(cond, msg) |
aborta se a condicao for falsa |
stdl.panico(msg) |
falha incondicional |
stdl.entrada(prompt?) |
le uma linha da entrada padrao |
stdl.verf_nulo(v) |
retorna verdadeiro se o valor for nulo |
usa <stdl/matematica> - matematica
| Funcao | Descricao |
|---|---|
matematica.raiz(x) |
raiz quadrada |
matematica.potencia(x, y) |
potencia |
matematica.absoluto(x) |
valor absoluto |
matematica.piso(x) |
arredonda para baixo |
matematica.teto(x) |
arredonda para cima |
matematica.arredonda(x) |
arredonda para o inteiro mais proximo |
matematica.minimo(...) |
menor valor |
matematica.maximo(...) |
maior valor |
matematica.limita(v, min, max) |
restringe um valor ao intervalo |
matematica.seno(x) |
seno |
matematica.cosseno(x) |
cosseno |
matematica.tangente(x) |
tangente |
matematica.logaritmo(x, base?) |
logaritmo natural ou em base customizada |
matematica.exponencial(x) |
e^x |
matematica.sinal(x) |
retorna -1, 0 ou 1 |
matematica.fatorial(n) |
fatorial |
matematica.mdc(a, b) |
maximo divisor comum |
matematica.e_inteiro(x) |
verifica se o numero e inteiro |
matematica.e_nan(x) |
verifica NaN |
matematica.e_infinito(x) |
verifica infinito |
matematica.PI |
constante PI |
matematica.E |
constante de Euler |
matematica.INFINITO |
infinito positivo |
usa <stdl/io> - entrada e saida
| Funcao | Descricao |
|---|---|
io.imprime(s) |
imprime string sem quebra |
io.imprimeln(s) |
imprime string com quebra |
io.err_imprime(s) |
imprime em stderr |
io.err_imprimeln(s) |
imprime em stderr com quebra |
io.descarrega() |
descarrega stdout |
io.cap_linha() |
le uma linha do stdin |
io.cap_caractere() |
le um caractere |
io.cap_inteiro() |
le um inteiro |
io.cap_real() |
le um real |
io.abre(caminho, modo) |
abre um arquivo |
io.fecha(arq) |
fecha um arquivo |
io.cap_linha_arq(arq) |
le uma linha de um arquivo aberto |
io.cap_tudo(arq) |
le todo o conteudo do arquivo |
io.escreve(arq, s) |
escreve em arquivo |
io.escreveln(arq, s) |
escreve em arquivo com quebra |
io.busca(arq, off, whence) |
reposiciona o cursor |
io.posicao(arq) |
retorna a posicao atual |
io.fim_do_arq(arq) |
verifica EOF |
io.descarrega_arq(arq) |
descarrega um arquivo aberto |
io.existe(caminho) |
verifica se o caminho existe |
io.tamanho(caminho) |
retorna o tamanho em bytes |
usa <stdl/sistema> - sistema operacional
| Funcao | Descricao |
|---|---|
sistema.tempo() |
timestamp Unix atual |
sistema.relogio() |
tempo de CPU do processo |
sistema.tempo_texto(t?) |
formata tempo como YYYY-MM-DD HH:MM:SS |
sistema.partes_tempo(t?) |
devolve ano, mes, dia, hora, minuto e segundo |
sistema.variavel_ambiente(nome) |
le uma variavel de ambiente |
sistema.define_ambiente(nome, valor) |
define uma variavel de ambiente |
sistema.sair(codigo) |
encerra o processo |
sistema.args() |
retorna os argumentos do script |
sistema.cwd() |
diretorio atual |
sistema.mkdir(caminho) |
cria diretorios recursivamente |
sistema.remove(caminho) |
remove arquivo ou diretorio vazio |
sistema.renomeia(de, para) |
renomeia ou move um arquivo |
sistema.plataforma() |
retorna linux, macos, windows ou desconhecido |
Recursos
- Declaracao de variaveis com
var, tipadas ou nao - Operadores aritmeticos, relacionais e logicos
se,senao,enquantoepara- Funcoes com checagem de tipo
- Lambdas, closures e funcoes de primeira classe
- Parametros opcionais tipados
- Arranjos tipados com checagem de limites
- Estruturas para dados compostos
combinacomcasoclassico e estilo=>- Interpolacao de strings
- Sistema de modulos e imports
- Ponteiros com memoria real via THD
- Escopos lexicos
- Protecao contra estouro de pilha
- Compilacao de binarios ELF nativos com
-o - Selecao opcional de linker via
-B
Exemplos
Ha exemplos prontos em examples/:
ola.tifpara.tifrecursao.tifargumentos.tiffuncao_arranjo.tifopcional_e_interpolacao.tifponteiros.tifcombina.tif
Compilacao para Binarios
O lusotif suporta compilar programas para executaveis usando a flag -o.
Agora o caminho de compilacao nativa do lusotif tambem gera um binario ELF nativo real, sem criar launcher dinamico nem depender do runtime Lua em tempo de execucao.
lusotif -o meu_programa meu_programa.tif
./meu_programa
Tambem e possivel escolher explicitamente o linker usado no build:
lusotif -B xld -o meu_programa meu_programa.tif
Ou via variavel de ambiente:
LUSOTIF_LINKER=xld lusotif -o meu_programa meu_programa.tif
O executavel gerado e um ELF estatico para Linux x86-64. No momento, esse backend cobre um subconjunto pratico da linguagem, priorizando:
usa <stdl>var, atribuicao,se,enquanto- funcoes de topo, recursao e parametros opcionais tipados
imprime,stdl.imprime(...)estdl.imprimeln(...)- aritmetica inteira, comparacoes booleanas e literais de texto em chamadas de impressao
Recursos como arranjos, ponteiros, estruturas, lambdas, combina, imports alem de <stdl> e numeros reais ainda nao estao disponiveis nesse backend nativo. Nesses casos, o lusotif -o falha em tempo de compilacao com diagnostico explicito.
Instalacao
O projeto possui um Makefile proprio. A compilacao e a instalacao acontecem inteiramente dentro da pasta do lusotif.
Dependencias para Lua 5.4
| Dependencia | Funcao |
|---|---|
lua5.4 |
runtime e luac |
liblua5.4-dev |
headers e linkagem |
gcc |
compilacao do launcher e dos modulos C |
pkg-config |
deteccao das flags do Lua |
No Debian/Ubuntu:
sudo apt install lua5.4 liblua5.4-dev gcc pkg-config
Dependencias para LuaJIT
| Dependencia | Funcao |
|---|---|
luajit |
runtime e compilacao de bytecode |
libluajit-5.1-dev |
headers e linkagem |
gcc |
compilacao do launcher e dos modulos C |
No Debian/Ubuntu:
sudo apt install luajit libluajit-5.1-dev gcc
Compilar
Com LuaJIT:
make all
Com Lua 5.4:
make all RUNTIME=lua
Instalar
Com LuaJIT:
sudo make install
Com Lua 5.4:
sudo make install RUNTIME=lua
Tambem e possivel trocar o prefixo:
make install PREFIX=/tmp/lusotif-local
Uso
lusotif arquivo.tif
lusotif arquivo.tif arg1 arg2
lusotif -Ilibs/ arquivo.tif
lusotif -o programa arquivo.tif
lusotif -B xld -o programa arquivo.tif
lusotif --help
lusotif --version
Rodando do Codigo-Fonte
Com LuaJIT:
luajit src/main.lua examples/ola.tif
Com Lua 5.4:
lua5.4 src/main.lua examples/ola.tif
Escrevendo Bibliotecas C para Lusotif
Qualquer biblioteca C compartilhada que exponha uma funcao luaopen_<nome> pode ser carregada pelo lusotif como modulo. O interpretador empacota a tabela Lua retornada em um namespace do lusotif.
Exemplo minimo
#include <lua5.4/lua.h>#include <lua5.4/lualib.h>#include <lua5.4/lauxlib.h>
static int l_cumprimenta(lua_State *L) {
const char *nome = luaL_checkstring(L, 1);
lua_pushfstring(L, "ola, %s!", nome);
return 1;
}
static const luaL_Reg minha_lib[] = {
{ "cumprimenta", l_cumprimenta },
{ NULL, NULL }
};
int luaopen_minhalib(lua_State *L) {
luaL_newlib(L, minha_lib);
return 1;
}
gcc -shared -fPIC -O2 -o minhalib.so minhalib.c $(pkg-config --cflags --libs lua5.4)
usa<stdl>usa"minhalib"stdl.imprimeln(minhalib.cumprimenta("lusotif"))Regras para bibliotecas compativeis
- O ponto de entrada deve se chamar
luaopen_<stem>, onde<stem>e o nome do arquivo.so - A funcao
luaopen_*deve retornar uma tabela Lua - Erros devem ser reportados com
luaL_error - Arranjos do
lusotifsao tabelas Lua com__is_array = truee campon - Ponteiros do
lusotifsao tabelas Lua com__is_ptr = true,handleebase_type
Licenca
MIT License - Copyright (c) 2026 grassleaff. All Rights Reserved.