Skip to content

Commit

Permalink
Merge pull request #31 from DanielVenturini/geração_código
Browse files Browse the repository at this point in the history
Geração código
  • Loading branch information
DanielVenturini authored Dec 11, 2018
2 parents 45c11f5 + 0a9ade3 commit 56289e3
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 13 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ main
*.tpp
syntactic/parse
*.dot
*.bc
*.s

# Prerequisites
*.d
Expand Down
Binary file removed codegenerator/geracao
Binary file not shown.
163 changes: 152 additions & 11 deletions codegenerator/geracao.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ LLVMContextRef contextoAtual;
LLVMModuleRef moduleAtual;
LLVMBuilderRef builderAtual;

TreeNode *funcaoAtual;

void salva(LLVMModuleRef module, char *fileName, char code) {

unsigned char tam = strlen(fileName);
Expand Down Expand Up @@ -66,18 +68,71 @@ void resolveNome(TreeNode *programa) {
}


void geraDecVariaveis(TreeNode *declaracao) {
LLVMTypeRef getTipoGen(TreeNode *node) {
return (node->filhos[0]->token->tokenval) == INTEIRO ? LLVMIntType(32) : LLVMFloatType();
}


TokenType tipo = declaracao->filhos[0]->tipoExpressao; // INTEIRO ou FLUTUANTE
TreeNode *lista = declaracao->filhos[1]; // LISTA_VARIAVEIS
void geraDecVariaveisGlobal(TreeNode *declaracao, LLVMTypeRef tipo, TreeNode *lista) {

LLVMTypeRef tipoLista = tipo == INTEIRO ? LLVMIntType(32) : LLVMFloatType();
unsigned char i;
for(i = 0; lista->filhos[i]; i ++) {

LLVMValueRef var = LLVMBuildAlloca(builderGlobal, tipoLista, (char *) lista->filhos[i]->token->val);
LLVMSetAlignment(var, 4);
LLVMBuildStore(builderGlobal, LLVMConstInt(tipoLista, 0, 0), var); // penúltimo parâmetro é false
TreeNode *var = lista->filhos[i];
Identificador *id = contem((TabSimb *) var->escopo, (char *) var->token->val, 0, 0);

// LLVMValueRef LLVMAddGlobal(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name);
LLVMValueRef *varLLVM = (LLVMValueRef *) malloc(sizeof(LLVMValueRef));
*varLLVM = LLVMAddGlobal(moduleGlobal, tipo, (char *) id->nome);

// void LLVMSetInitializer(LLVMValueRef GlobalVar, LLVMValueRef ConstantVal);
LLVMSetInitializer(*varLLVM, LLVMConstInt(tipo, 0, 0));

// common.
LLVMSetLinkage(*varLLVM, LLVMCommonLinkage);

// Alignment.
LLVMSetAlignment(*varLLVM, 4);

// guarda o valor no Identificador e no nó
var->llvmValueRef = (void *) varLLVM;
id->llvmValueRef = (void *) varLLVM;
}
}


void geraDecVariaveisLocal(TreeNode *declaracao, LLVMTypeRef tipo, TreeNode *lista) {

unsigned char i;
for(i = 0; lista->filhos[i]; i ++) {

TreeNode *var = lista->filhos[i];
Identificador *id = contem((TabSimb *) var->escopo, (char *) var->token->val, 0, 0);

LLVMValueRef *varLLVM = (LLVMValueRef *) malloc(sizeof(LLVMValueRef));
*varLLVM = LLVMBuildAlloca(builderGlobal, tipo, (char *) lista->filhos[i]->token->val);

LLVMSetAlignment(*varLLVM, 4);
LLVMBuildStore(builderGlobal, LLVMConstInt(tipo, 0, 0), *varLLVM); // penúltimo parâmetro é false

// guarda o valor no Identificador e no nó
var->llvmValueRef = (void *) varLLVM;
id->llvmValueRef = (void *) varLLVM;
}

}
void geraDecVariaveis(TreeNode *declaracao) {

// INTEIRO ou FLUTUANTE
LLVMTypeRef tipo = getTipoGen(declaracao);
// LISTA_VARIAVEIS
TreeNode *lista = declaracao->filhos[1];

// se estiver no escopo global
if(!funcaoAtual) {
geraDecVariaveisGlobal(declaracao, tipo, lista);
} else {
geraDecVariaveisLocal(declaracao, tipo, lista);
}
}

Expand Down Expand Up @@ -110,6 +165,50 @@ LLVMTypeRef *geraParametros(TreeNode *parametros, unsigned char *qtdParametros)
return paramns;
}


// inicializa as variáveis que estão no parametro
// mas primeiro tem que criar a função, pois isso
// essa função é desacoplada da geraDecFuncao
void inicializaParametros(TreeNode *parametros, LLVMTypeRef *paramns, unsigned char qtd) {

if(!parametros) {
return;
}

// recupera a quantidade de parametros
unsigned char i;
for(i = 0; i < qtd; i ++) {
TreeNode *parametro = parametros->filhos[i];

// recuperando a função
LLVMValueRef funcao = *(LLVMValueRef *) funcaoAtual->llvmValueRef;

// recuperando o parametro
LLVMValueRef *var = (LLVMValueRef *) malloc(sizeof(LLVMValueRef));
*var = LLVMGetParam(funcao, i);

// salvando na tabela de símbolos e no nó
Identificador *id = contem((TabSimb *) parametro->escopo, (char *) parametro->filhos[1]->token->val, 0, 0);
id->llvmValueRef = (void *) var;
parametro->filhos[i]->llvmValueRef = (void *) var;

// iniciando os parametros
// cria uma variável do tipo do parametro e inicializa com zero rhs
// soma ao parametro para inicia-lo
LLVMValueRef rhs = LLVMConstInt(getTipoGen(parametro), 0, 0);
/*if(parametro->tipoExpressao == INTEIRO)
rhs = LLVMConstInt(LLVMInt32Type(), 0, 0);
else
rhs = LLVMConstInt(LLVMFloatType(), 0, 0);*/

// parametro propriamente dito
LLVMValueRef lhs = LLVMGetParam(funcao, i);
LLVMBuildAdd(builderGlobal, lhs, rhs, id->nome);
//LLVMBuildLShr(builderGlobal, lhs, rhs, id->nome);
}
}


void geraDecFuncao(TreeNode *noFuncao) {

TokenType tipo = noFuncao->filhos[0]->token->tokenval;
Expand All @@ -135,7 +234,9 @@ void geraDecFuncao(TreeNode *noFuncao) {

// aloca um espaço para a função
LLVMValueRef *funcao = (LLVMValueRef *) malloc(sizeof(LLVMValueRef));
*funcao = LLVMAddFunction(moduleGlobal, nome, LLVMFunctionType(tipoRetorno, geraParametros(noFuncao->filhos[pos+1], &qtdParametros), qtdParametros, 0));
// já recupera a lista de parâmetros
LLVMTypeRef *paramns = geraParametros(noFuncao->filhos[pos+1], &qtdParametros);
*funcao = LLVMAddFunction(moduleGlobal, nome, LLVMFunctionType(tipoRetorno, paramns, qtdParametros, 0));

// Declara o bloco de entrada.
LLVMBasicBlockRef entryBlock = LLVMAppendBasicBlockInContext(contextoGlobal, *funcao, "entry");
Expand All @@ -149,6 +250,9 @@ void geraDecFuncao(TreeNode *noFuncao) {

// Adiciona o bloco de entrada.
LLVMPositionBuilderAtEnd(builderGlobal, entryBlock);

// recupera os parametros e insere nos nós respectivos
inicializaParametros(noFuncao->filhos[pos+1], paramns, qtdParametros);
}


Expand Down Expand Up @@ -201,19 +305,43 @@ void geraEndFuncao(TreeNode *noFuncao) {
}


void geraAtribuicao(TreeNode *node) {

// nó que vai receber o valor
TreeNode *var = node->filhos[0];
TreeNode *expressao = node->filhos[1];

LLVMTypeRef tipo = getTipoGen(node);

// recupera o identificador e o LLVMValueRef dele
Identificador *id = contem((TabSimb *) var->escopo, (char *) var->token->val, 0, 0);
LLVMValueRef *resp = (LLVMValueRef *) id->llvmValueRef;

// atribui com o tipo certo
if(var->tipoExpressao == INTEIRO) {
LLVMBuildStore(builderGlobal, LLVMConstInt(tipo, 10, 0), *resp);
} else {
LLVMBuildStore(builderGlobal, LLVMConstReal(tipo, 10.0), *resp);
}
}


void percorre(TreeNode *node) {
if(!node)
return;

// casos que precisa ser tratado antes de continuar descendo na árvore
// pois as variávies/funções já devem ter sido declaradas antes mesmo de continuar
switch(node->bnfval) {

case DECLARACAO_VARIAVEIS:
// cria os LLVMValueRef, insere na tabela de símbolos e na árvore e gera código
//geraDecVariaveis(node);
geraDecVariaveis(node);
break;

case DECLARACAO_FUNCAO:
// salva a função atual
funcaoAtual = node;
// gera o código do cabeçalho da função
geraDecFuncao(node);
break;
Expand All @@ -228,9 +356,22 @@ void percorre(TreeNode *node) {
percorre(filho);
}

// há algumas regras que devem ser computadas
// somente na volta da recursão
// se for uma função, finaliza ela
if(node->bnfval == DECLARACAO_FUNCAO) {
geraEndFuncao(node);
switch(node->bnfval) {

case DECLARACAO_FUNCAO:
geraEndFuncao(node);
funcaoAtual = NULL;
break;

case B_ATRIBUICAO:
geraAtribuicao(node);
break;

default:
printf("");
}
}

Expand Down
4 changes: 2 additions & 2 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ char flags[9]; // cada posição se refere a um tipo de flag
// inves de incluir a biblioteca geracao.h
void geraCodigo(TreeNode *, char *, char);

char *version = "6.0.0";
char *version = "6.0.1";

void qualFlag(char *flag) {

Expand Down Expand Up @@ -193,4 +193,4 @@ int main(int argc, char *argv[]) {
}

return 0;
}
}

0 comments on commit 56289e3

Please sign in to comment.