Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions benchmarks/bubblesort.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include <stdio.h>
#include <stdlib.h>

#define N 10000

int main() {
int* lista = (int*)malloc(N * sizeof(int));
for (int i = 0; i < N; i++) {
lista[i] = N - i;
}

for (int i = 0; i < N - 1; i++) {
for (int j = 0; j < N - 1 - i; j++) {
if (lista[j] > lista[j + 1]) {
int temp = lista[j];
lista[j] = lista[j + 1];
lista[j + 1] = temp;
}
}
}

printf("%d\n", lista[0]);
free(lista);
return 0;
}
22 changes: 22 additions & 0 deletions benchmarks/bubblesort.delegua
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
var n: inteiro = 10000
var lista: inteiro[] = [0]

para var k: inteiro = 1; k < n; k++ {
lista.adicionar(0)
}

para var k: inteiro = 0; k < n; k++ {
lista[k] = n - k
}

para var i: inteiro = 0; i < n - 1; i++ {
para var j: inteiro = 0; j < n - 1 - i; j++ {
se lista[j] > lista[j + 1] {
var temp: inteiro = lista[j]
lista[j] = lista[j + 1]
lista[j + 1] = temp
}
}
}

escreva(lista[0])
15 changes: 15 additions & 0 deletions benchmarks/bubblesort.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const N: usize = 10000;

fn main() {
let mut lista: Vec<i32> = (0..N).map(|i| (N - i) as i32).collect();

for i in 0..N - 1 {
for j in 0..N - 1 - i {
if lista[j] > lista[j + 1] {
lista.swap(j, j + 1);
}
}
}

println!("{}", lista[0]);
}
105 changes: 105 additions & 0 deletions benchmarks/executar.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#!/bin/bash
set -e

DIR="$(cd "$(dirname "$0")" && pwd)"
ROOT="$(cd "$DIR/.." && pwd)"
OUT="$DIR/build"
RUNS=${1:-3}

mkdir -p "$OUT"

echo "========================================"
echo " Benchmark Suite: Delegua vs C vs Rust"
echo " Execuções por linguagem: $RUNS"
echo "========================================"

benchmark() {
local name="$1"
local cmd="$2"
local total=0

for i in $(seq 1 "$RUNS"); do
start=$(python3 -c "import time; print(int(time.time()*1000))")
eval "$cmd" > /dev/null
end=$(python3 -c "import time; print(int(time.time()*1000))")
elapsed=$((end - start))
total=$((total + elapsed))
done

avg=$((total / RUNS))
printf " %-25s %6dms\n" "$name" "$avg"
}

run_benchmark() {
local NOME="$1"
local ARQUIVO="$2"
local ESPERADO="$3"

echo ""
echo "----------------------------------------"
echo " $NOME"
echo "----------------------------------------"

echo ""
echo "▶ Compilando..."

clang -O2 "$DIR/${ARQUIVO}.c" -o "$OUT/${ARQUIVO}_c"
echo " C (clang -O2): ok"

rustc -C opt-level=2 "$DIR/${ARQUIVO}.rs" -o "$OUT/${ARQUIVO}_rust"
echo " Rust (-C opt-level=2): ok"

(cd "$ROOT" && yarn executar "$DIR/${ARQUIVO}.delegua" -o "${ARQUIVO}_delegua") > /dev/null 2>&1
mv "$DIR/${ARQUIVO}_delegua" "$OUT/${ARQUIVO}_delegua"
echo " Delegua (LLVM -O2): ok"

echo ""
echo "▶ Verificando corretude..."

RESULT_C=$("$OUT/${ARQUIVO}_c" | tr -d '[:space:]')
RESULT_RUST=$("$OUT/${ARQUIVO}_rust" | tr -d '[:space:]')
RESULT_DELEGUA=$("$OUT/${ARQUIVO}_delegua" | tr -d '[:space:]')

PASS=true

for LANG_NAME in C Rust Delegua; do
eval "RESULT=\$RESULT_$(echo $LANG_NAME | tr '[:upper:]' '[:lower:]' | sed 's/delegua/delegua/' | sed 's/rust/rust/')"
case "$LANG_NAME" in
C) RESULT="$RESULT_C" ;;
Rust) RESULT="$RESULT_RUST" ;;
Delegua) RESULT="$RESULT_DELEGUA" ;;
esac

if [ "$RESULT" != "$ESPERADO" ]; then
echo " FALHA $LANG_NAME: esperado $ESPERADO, obteve $RESULT"
PASS=false
else
echo " $LANG_NAME: $RESULT ✓"
fi
done

if [ "$PASS" = false ]; then
echo " AVISO: Resultados incorretos, pulando benchmark."
return
fi

echo ""
echo "▶ Resultados:"

benchmark "C (clang -O2)" "$OUT/${ARQUIVO}_c"
benchmark "Rust (opt-level=2)" "$OUT/${ARQUIVO}_rust"
benchmark "Delegua (LLVM -O2)" "$OUT/${ARQUIVO}_delegua"
}

# --- Benchmarks ---

run_benchmark "Fibonacci Recursivo (fib 40)" "fibonacci" "102334155"
run_benchmark "Contagem de Primos (até 1M)" "primos" "78498"
run_benchmark "Bubble Sort (10000 elementos)" "bubblesort" "1"

echo ""
echo "========================================"
echo " Concluído"
echo "========================================"

rm -rf "$OUT"
11 changes: 11 additions & 0 deletions benchmarks/fibonacci.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <stdio.h>

int fib(int n) {
if (n <= 1) return n;
return fib(n - 1) + fib(n - 2);
}

int main() {
printf("%d\n", fib(40));
return 0;
}
8 changes: 8 additions & 0 deletions benchmarks/fibonacci.delegua
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
funcao fib(n: inteiro): inteiro {
se n <= 1 {
retorna n
}
retorna fib(n - 1) + fib(n - 2)
}

escreva(fib(40))
8 changes: 8 additions & 0 deletions benchmarks/fibonacci.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
fn fib(n: i32) -> i32 {
if n <= 1 { return n; }
fib(n - 1) + fib(n - 2)
}

fn main() {
println!("{}", fib(40));
}
20 changes: 20 additions & 0 deletions benchmarks/primos.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <stdio.h>

int ehPrimo(int n) {
if (n <= 1) return 0;
if (n <= 3) return 1;
if (n % 2 == 0) return 0;
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0) return 0;
}
return 1;
}

int main() {
int contagem = 0;
for (int j = 2; j < 1000000; j++) {
contagem += ehPrimo(j);
}
printf("%d\n", contagem);
return 0;
}
26 changes: 26 additions & 0 deletions benchmarks/primos.delegua
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
funcao ehPrimo(n: inteiro): inteiro {
se n <= 1 {
retorna 0
}
se n <= 3 {
retorna 1
}
se n % 2 == 0 {
retorna 0
}
var i: inteiro = 3
enquanto i * i <= n {
se n % i == 0 {
retorna 0
}
i = i + 2
}
retorna 1
}

var contagem: inteiro = 0
para var j: inteiro = 2; j < 1000000; j++ {
contagem = contagem + ehPrimo(j)
}

escreva(contagem)
19 changes: 19 additions & 0 deletions benchmarks/primos.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
fn eh_primo(n: i32) -> i32 {
if n <= 1 { return 0; }
if n <= 3 { return 1; }
if n % 2 == 0 { return 0; }
let mut i = 3;
while i * i <= n {
if n % i == 0 { return 0; }
i += 2;
}
1
}

fn main() {
let mut contagem = 0;
for j in 2..1000000 {
contagem += eh_primo(j);
}
println!("{}", contagem);
}
70 changes: 70 additions & 0 deletions fontes/bibliotecas-compilacao.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import * as path from 'path';

interface BibliotecaCompilacao {
arquivosC: string[];
flagsLink: string[];
}

const BIBLIOTECAS_NUCLEO: BibliotecaCompilacao = {
arquivosC: ['padrao.c', 'texto.c', 'vetor.c'],
flagsLink: [],
};

const MAPA_MODULOS: Map<string, BibliotecaCompilacao> = new Map([
['matematica', { arquivosC: ['matematica.c'], flagsLink: ['-lm'] }],
['fisica', { arquivosC: ['fisica.c'], flagsLink: ['-lm'] }],
['estatistica', { arquivosC: ['estatistica.c'], flagsLink: ['-lm'] }],
['arquivos', { arquivosC: ['arquivos.c'], flagsLink: [] }],
['csv', { arquivosC: ['csv.c'], flagsLink: [] }],
['json', { arquivosC: ['json.c'], flagsLink: [] }],
['http', { arquivosC: ['http.c'], flagsLink: ['-lcurl'] }],
['criptografia', {
arquivosC: ['criptografia.c', 'criptografia-hashes.c', 'criptografia-aes-rsa.c'],
flagsLink: ['-lssl', '-lcrypto'],
}],
['dados', { arquivosC: ['dados.c'], flagsLink: [] }],
]);

export function detectarModulosImportados(linhasCodigo: string[]): string[] {
const modulos: Set<string> = new Set();
const regex = /importar\s*\(\s*['"](\w+)['"]\s*\)/;
const regexDe = /importar\s+.*\s+de\s+['"](\w+)['"]/;

for (const linha of linhasCodigo) {
const match = regex.exec(linha) || regexDe.exec(linha);
if (match) {
modulos.add(match[1]);
}
}

return Array.from(modulos);
}

export function obterBibliotecasParaCompilacao(
modulos: string[],
diretorioBibliotecas: string
): { arquivosC: string[]; flagsLink: string[] } {
const arquivosC: Set<string> = new Set();
const flagsLink: Set<string> = new Set();

for (const arquivo of BIBLIOTECAS_NUCLEO.arquivosC) {
arquivosC.add(path.join(diretorioBibliotecas, arquivo));
}

for (const modulo of modulos) {
const biblioteca = MAPA_MODULOS.get(modulo);
if (biblioteca) {
for (const arquivo of biblioteca.arquivosC) {
arquivosC.add(path.join(diretorioBibliotecas, arquivo));
}
for (const flag of biblioteca.flagsLink) {
flagsLink.add(flag);
}
}
}

return {
arquivosC: Array.from(arquivosC),
flagsLink: Array.from(flagsLink),
};
}
14 changes: 14 additions & 0 deletions fontes/bibliotecas/vetor.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,3 +335,17 @@ void delegua_vetor_mapear_numero(Vetor* v, double (*fn)(double), Vetor* saida) {
for (int i = 0; i < v->tamanho; i++) { resultado[i] = fn(elems[i]); }
saida->ptr = resultado; saida->tamanho = v->tamanho;
}

// Mapeia elementos texto (char*→char*) — cria novo vetor em *saida.
void delegua_vetor_mapear_texto(Vetor* v, char* (*fn)(char*), Vetor* saida) {
if (!v || v->tamanho == 0) { saida->ptr = NULL; saida->tamanho = 0; return; }
char** elems = (char**)v->ptr;
char** resultado = (char**)calloc((size_t)v->tamanho, sizeof(char*));
if (!resultado) { saida->ptr = NULL; saida->tamanho = 0; return; }
for (int i = 0; i < v->tamanho; i++) { resultado[i] = fn(elems[i]); }
saida->ptr = resultado; saida->tamanho = v->tamanho;
}

int delegua_vetor_tamanho(Vetor* v) {
return v ? v->tamanho : 0;
}
6 changes: 6 additions & 0 deletions fontes/bibliotecas/vetor.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ typedef struct {
int tamanho;
} Vetor;

// Retorna o número de elementos no vetor.
int delegua_vetor_tamanho(Vetor* v);

// Mapeia elementos texto (char*→char*) — cria novo vetor em *saida.
void delegua_vetor_mapear_texto(Vetor* v, char* (*fn)(char*), Vetor* saida);

// Adiciona um elemento ao final do vetor. Retorna o novo tamanho.
int delegua_vetor_adicionar(Vetor* v, void* elem, int tam_elem);

Expand Down
Loading
Loading