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
43 changes: 15 additions & 28 deletions fontes/compilador-llvm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ export class CompiladorLLVM implements VisitanteDeleguaInterface {
funcaoPuts: llvm.Function;

printfFormatos: Map<string, string> = new Map<string, string>([
['inteiro', '%d\n'],
['número', '%g\n'],
['texto', '%s\n'],
['inteiro', '%d'],
['número', '%g'],
['texto', '%s'],
]);

scanfFormatos: Map<string, string> = new Map<string, string>([
Expand All @@ -51,7 +51,6 @@ export class CompiladorLLVM implements VisitanteDeleguaInterface {
['texto', '%s'],
]);

printFormatosCarregados: Map<string, llvm.Constant> = new Map<string, llvm.Constant>();
scanfFormatosCarregados: Map<string, llvm.Constant> = new Map<string, llvm.Constant>();

private readonly NOMES_BLOCOS = {
Expand Down Expand Up @@ -831,9 +830,14 @@ export class CompiladorLLVM implements VisitanteDeleguaInterface {

async visitarDeclaracaoEscreva(declaracao: Escreva): Promise<any> {
const argumentosResolvidos: llvm.Value[] = [];

const formatosTexto: string[] = []

for (const argumento of declaracao.argumentos) {
const argumentoResolvido = await argumento.aceitar(this);

formatosTexto.push(this.printfFormatos.get(argumento.tipo))

// Se for VariavelEscopo, precisa carregar o valor
if (argumentoResolvido instanceof VariavelEscopo) {
const tipoArgumento = this.obterTipoLlvm(argumento.tipo);
Expand All @@ -848,10 +852,14 @@ export class CompiladorLLVM implements VisitanteDeleguaInterface {
}
}

const tipoPrimeiroArgumento = declaracao.argumentos[0].tipo;
const fmt = this.montador.CreateGlobalStringPtr(
formatosTexto.concat("\n").join(" "), // String formatada ex: "%s %i"
"fmt",
0,
this.modulo
)

const formatoPrintf = this.buscarFormatoPrintf(tipoPrimeiroArgumento);
argumentosResolvidos.unshift(formatoPrintf);
argumentosResolvidos.unshift(fmt)

this.montador.CreateCall(this.funcaoPrintf, argumentosResolvidos, "printf");
return Promise.resolve();
Expand Down Expand Up @@ -1310,27 +1318,6 @@ export class CompiladorLLVM implements VisitanteDeleguaInterface {
}
}





protected buscarFormatoPrintf(tipoDelegua: string): llvm.Constant {
let formatoPrintf = this.printFormatosCarregados.get(tipoDelegua);

if (!formatoPrintf) {
const formatoString = this.printfFormatos.get(tipoDelegua);
formatoPrintf = this.montador.CreateGlobalStringPtr(
formatoString,
`formato_printf_${tipoDelegua}`,
0,
this.modulo
);
this.printFormatosCarregados.set(tipoDelegua, formatoPrintf);
}

return formatoPrintf;
}

protected buscarFormatoScanf(tipoDelegua: string): llvm.Constant {
let formatoScanf = this.scanfFormatosCarregados.get(tipoDelegua);

Expand Down
9 changes: 8 additions & 1 deletion testes/compilador-llvm.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ describe('Compilador', () => {
const compilador = new CompiladorLLVM();
const resultado = await compilador.compilar(['escreva(123)']);
expect(resultado).toBeTruthy();
expect(resultado).toContain('%printf = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @\"formato_printf_n\\C3\\BAmero\", i32 0, i32 0), double 1.230000e+02)');
expect(resultado).toContain('%printf = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @fmt, i32 0, i32 0), double 1.230000e+02)');
});

it('Escreva', async () => {
const compilador = new CompiladorLLVM();
const resultado = await compilador.compilar(['escreva(123, "teste")']);
expect(resultado).toBeTruthy();
expect(resultado).toContain('@fmt = private unnamed_addr constant [8 x i8] c"%g %s')
});

describe('Funções', () => {
Expand Down