diff --git a/examples/a.glx b/examples/a.glx index 1960342..680c7b8 100644 --- a/examples/a.glx +++ b/examples/a.glx @@ -1,11 +1,11 @@ -extern int writeln( string) ; -extern string itos( int) ; +extern int writeln(string); +extern string itos(int); -def main( ) -> int: +def main() -> int: - for ( int i := 0; i < 100000; ++ i) : - writeln( "val" ) ; - end; + for (int i := -10; i < 10 + 1; ++i): + writeln(itos(i);); + end; - return 0; -end; \ No newline at end of file + return 0; +end; diff --git a/include/backend/generator/statements/generate_if_stmt.hpp b/include/backend/generator/statements/generate_if_stmt.hpp new file mode 100644 index 0000000..e50e4ee --- /dev/null +++ b/include/backend/generator/statements/generate_if_stmt.hpp @@ -0,0 +1,16 @@ +#ifndef GENERATE_IF_STMT_H +#define GENERATE_IF_STMT_H + +extern "C" { + #include "frontend/ast/definitions.h" +} +#include +#include +#include +#include +#include +#include + +llvm::Value* generate_if_stmt(IfNode *node, llvm::LLVMContext &Context, llvm::IRBuilder<> &Builder, llvm::Module &Module); + +#endif // GENERATE_IF_STMT_H \ No newline at end of file diff --git a/include/backend/generator/symbols/identifier_symbol_table.hpp b/include/backend/generator/symbols/identifier_symbol_table.hpp index 5cc9588..0dd998f 100644 --- a/include/backend/generator/symbols/identifier_symbol_table.hpp +++ b/include/backend/generator/symbols/identifier_symbol_table.hpp @@ -6,7 +6,7 @@ #include #include "backend/generator/symbols/symbol_stack.hpp" -const SymbolInfo *find_identifier(const std::string &name); +SymbolInfo *find_identifier(const std::string &name); void add_identifier(const std::string &name, llvm::Value* declaration, llvm::Value* value, llvm::Type* type); #endif // IDENTIFIER_SYMBOL_TABLE_H \ No newline at end of file diff --git a/include/backend/generator/symbols/iterator_stack.hpp b/include/backend/generator/symbols/iterator_stack.hpp new file mode 100644 index 0000000..e091ee4 --- /dev/null +++ b/include/backend/generator/symbols/iterator_stack.hpp @@ -0,0 +1,22 @@ +#ifndef ITERATOR_STACK_H +#define ITERATOR_STACK_H + +#include +#include +#include +#include + +struct IteratorInfo { + llvm::Value* declaration; + llvm::Value* value; + llvm::Type* type; +}; + +extern std::stack iterator_stack; +extern std::mutex iterator_stack_mutex; + +void push_iterator(llvm::Value* declaration, llvm::Value* value, llvm::Type* type); +IteratorInfo pop_iterator(); +IteratorInfo* current_iterator(); + +#endif // ITERATOR_STACK_H diff --git a/libs/lib.ll b/libs/lib.ll index dc84d9f..4e7f254 100644 --- a/libs/lib.ll +++ b/libs/lib.ll @@ -309,3 +309,119 @@ exit: ; preds = %finalize, %abort ; Return the pointer to the repeated string (or null if aborted). } +declare ptr @malloc(i64) + + +define ptr @itos(i32 %num) { +entry: + ; Alocação de variáveis + %is_negative = alloca i1 + %num_ptr = alloca i32 + %buffer = alloca ptr + %i = alloca i32 + + ; Inicializa variáveis + store i32 %num, ptr %num_ptr + store i1 0, ptr %is_negative + + ; Aloca buffer dinâmico para a string (máximo 12 bytes: "-2147483648" + '\0') + %buf = call ptr @malloc(i64 12) + store ptr %buf, ptr %buffer + store i32 0, ptr %i + + ; Verifica se o número é negativo + %num_val = load i32, ptr %num_ptr + %is_neg = icmp slt i32 %num_val, 0 + br i1 %is_neg, label %negative, label %positive + +negative: ; Bloco para números negativos + store i1 1, ptr %is_negative + %neg_num = sub i32 0, %num_val + store i32 %neg_num, ptr %num_ptr + br label %extract_digits + +positive: ; Continua o processamento + br label %extract_digits + +extract_digits: ; Extrai os dígitos + %num_val2 = load i32, ptr %num_ptr + %digit = urem i32 %num_val2, 10 + %char_digit = add i32 %digit, 48 ; Converte para caractere + %i_val = load i32, ptr %i + %buf_ptr = load ptr, ptr %buffer + %str_loc = getelementptr i8, ptr %buf_ptr, i32 %i_val + store i32 %char_digit, ptr %str_loc + + ; Atualiza número e índice + %next_num = sdiv i32 %num_val2, 10 + store i32 %next_num, ptr %num_ptr + %next_i = add i32 %i_val, 1 + store i32 %next_i, ptr %i + + ; Verifica se o número é maior que zero + %is_not_zero = icmp ne i32 %next_num, 0 + br i1 %is_not_zero, label %extract_digits, label %check_negative + +check_negative: ; Adiciona o sinal de menos se necessário + %is_neg2 = load i1, ptr %is_negative + br i1 %is_neg2, label %add_minus, label %reverse_buffer + +add_minus: ; Adiciona o sinal de menos + %i_val2 = load i32, ptr %i + %buf_ptr2 = load ptr, ptr %buffer + %str_loc2 = getelementptr i8, ptr %buf_ptr2, i32 %i_val2 + store i8 45, ptr %str_loc2 ; '-' é 45 na tabela ASCII + %next_i2 = add i32 %i_val2, 1 + store i32 %next_i2, ptr %i + br label %reverse_buffer + +reverse_buffer: ; Reverte o buffer + %buf_ptr3 = load ptr, ptr %buffer + %len = load i32, ptr %i + + ; Índices para reversão + %start = alloca i32 + %end = alloca i32 + store i32 0, ptr %start + %end_idx = sub i32 %len, 1 + store i32 %end_idx, ptr %end + + br label %reverse_loop + +reverse_loop: ; Loop para inverter os caracteres + %start_idx = load i32, ptr %start + %end_idx_initial = load i32, ptr %end + %cmp = icmp slt i32 %start_idx, %end_idx_initial + br i1 %cmp, label %swap_chars, label %finalize_string + +swap_chars: ; Troca os caracteres + %buf_ptr4 = load ptr, ptr %buffer + + ; Posições dos caracteres + %start_char_ptr = getelementptr i8, ptr %buf_ptr4, i32 %start_idx + %end_char_ptr = getelementptr i8, ptr %buf_ptr4, i32 %end_idx + + ; Carrega os valores + %start_char = load i8, ptr %start_char_ptr + %end_char = load i8, ptr %end_char_ptr + + ; Troca os valores + store i8 %end_char, ptr %start_char_ptr + store i8 %start_char, ptr %end_char_ptr + + ; Atualiza os índices + %next_start = add i32 %start_idx, 1 + %prev_end = sub i32 %end_idx, 1 + store i32 %next_start, ptr %start + store i32 %prev_end, ptr %end + + br label %reverse_loop + +finalize_string: ; Finaliza a string + %i_val3 = load i32, ptr %i + %buf_ptr5 = load ptr, ptr %buffer + %str_loc3 = getelementptr i8, ptr %buf_ptr5, i32 %i_val3 + store i8 0, ptr %str_loc3 ; Terminador nulo + %final_buf = load ptr, ptr %buffer + ret ptr %final_buf +} diff --git a/src/backend/generator/expressions/generate_assignment_expr.cpp b/src/backend/generator/expressions/generate_assignment_expr.cpp index 60c6d1f..c4f8099 100644 --- a/src/backend/generator/expressions/generate_assignment_expr.cpp +++ b/src/backend/generator/expressions/generate_assignment_expr.cpp @@ -15,8 +15,6 @@ llvm::Value *generate_assignment_expr(AssignmentNode *node, llvm::LLVMContext &C // right-hand side to the memory location of the left-hand side. Builder.CreateStore(right_value, left_value); - // Return a null value of the type of the left operand, - // as assignment expressions generally do not return a value. - return llvm::Constant::getNullValue(left_value->getType()); + return left_value; } diff --git a/src/backend/generator/expressions/generate_call.cpp b/src/backend/generator/expressions/generate_call.cpp index 95738eb..11df9bd 100644 --- a/src/backend/generator/expressions/generate_call.cpp +++ b/src/backend/generator/expressions/generate_call.cpp @@ -2,6 +2,9 @@ #include "backend/generator/expressions/generate_expr.hpp" #include "backend/generator/symbols/function_symbol_table.hpp" #include "backend/generator/utils/return_id.hpp" +#include "backend/generator/parallel/queue.hpp" +#include "backend/generator/symbols/iterator_stack.hpp" +#include llvm::Value *generate_call(CallNode *call_node, llvm::LLVMContext &Context, llvm::IRBuilder<> &Builder, llvm::Module &Module) { if (!call_node || !call_node->caller) { @@ -24,33 +27,61 @@ llvm::Value *generate_call(CallNode *call_node, llvm::LLVMContext &Context, llvm // Generate arguments std::vector args; for (size_t i = 0; i < call_node->arg_count; ++i) { - global_id_return = "declaration"; - llvm::Value *arg = generate_expr(call_node->args[i], Context, Builder, Module); + global_id_return = "value"; + + // Declare expected_type here before using it + llvm::Type* expected_type = func_type->getParamType(i); + + // Get the current iterator info + IteratorInfo* current_iter = current_iterator(); + llvm::Value *arg = nullptr; + + if (current_iter) { + // Get the current argument as an IdentifierNode + IdentifierNode* arg_identifier = static_cast(call_node->args[i]->data); + if (arg_identifier && current_iter->value && current_iter->value->getName().str() == arg_identifier->symbol) { + // If the current iterator matches the argument name, use the current iterator data + arg = current_iter->value; + expected_type = current_iter->type; // Override expected_type with current iterator's type + } + } + + if (!arg) { - throw std::runtime_error("Failed to generate call argument."); + // Otherwise, generate the argument value as usual + global_id_return = "declaration"; + arg = generate_expr(call_node->args[i], Context, Builder, Module); + if (!arg) { + throw std::runtime_error("Failed to generate call argument."); + } } - // Ensure the argument type matches the function parameter type - llvm::Type *expected_type = func_type->getParamType(i); - if (arg->getType() != expected_type) { - if (arg->getType()->isIntegerTy() && expected_type->isIntegerTy()) { - arg = Builder.CreateIntCast(arg, expected_type, true); - } else if (arg->getType()->isFloatingPointTy() && expected_type->isFloatingPointTy()) { - arg = Builder.CreateFPCast(arg, expected_type); - } else if (arg->getType()->isPointerTy() && expected_type->isIntegerTy()) { - arg = Builder.CreatePointerCast(arg, expected_type); - } else if (arg->getType()->isPointerTy() && expected_type->isFloatingPointTy()) { - arg = Builder.CreatePointerCast(arg, expected_type); + llvm::errs() << *arg << "\n"; + // Check if the argument is a pointer + if (arg->getType()->isPointerTy()) { + if (expected_type->isPointerTy()) { + args.push_back(arg); } else { - throw std::runtime_error("Argument type mismatch."); + llvm::Value *loaded_value = Builder.CreateLoad(expected_type, arg); + args.push_back(loaded_value); + } + } else { + if (arg->getType() != expected_type) { + if (arg->getType()->isIntegerTy() && expected_type->isIntegerTy()) { + arg = Builder.CreateIntCast(arg, expected_type, true); + } else if (arg->getType()->isFloatingPointTy() && expected_type->isFloatingPointTy()) { + arg = Builder.CreateFPCast(arg, expected_type); + } else if (arg->getType()->isIntegerTy() && expected_type->isFloatingPointTy()) { + arg = Builder.CreateSIToFP(arg, expected_type); + } else if (arg->getType()->isFloatingPointTy() && expected_type->isIntegerTy()) { + arg = Builder.CreateFPToSI(arg, expected_type); + } else { + throw std::runtime_error("Argument type mismatch."); + } } + args.push_back(arg); } - - args.push_back(arg); } - global_id_return = "value"; - - // Create the call instruction return Builder.CreateCall(function, args); } diff --git a/src/backend/generator/expressions/generate_identifier.cpp b/src/backend/generator/expressions/generate_identifier.cpp index 17ba025..a0fc1a2 100644 --- a/src/backend/generator/expressions/generate_identifier.cpp +++ b/src/backend/generator/expressions/generate_identifier.cpp @@ -10,5 +10,7 @@ llvm::Value *generate_identifier(IdentifierNode *node) { } else { return id->value; } + } else { + throw std::runtime_error("Identifier not found: " + std::string(node->symbol)); } -} \ No newline at end of file +} diff --git a/src/backend/generator/expressions/generate_unary_minus.cpp b/src/backend/generator/expressions/generate_unary_minus.cpp index 39bad0f..2ff013d 100644 --- a/src/backend/generator/expressions/generate_unary_minus.cpp +++ b/src/backend/generator/expressions/generate_unary_minus.cpp @@ -6,7 +6,7 @@ llvm::Value *generate_unary_minus(UnaryMinusExpr *node, llvm::LLVMContext &Conte llvm::Value *Operand = generate_expr(node->op, Context, Builder, Module); // Create a floating-point negation instruction, which negates the operand (i.e., multiplies it by -1) - llvm::Value *Negated = Builder.CreateFNeg(Operand, "negtmp"); + llvm::Value *Negated = Builder.CreateNeg(Operand, "negtmp"); // Return the result of the negation return Negated; diff --git a/src/backend/generator/statements/generate_for_stmt.cpp b/src/backend/generator/statements/generate_for_stmt.cpp index 0f9194b..27ff1b6 100644 --- a/src/backend/generator/statements/generate_for_stmt.cpp +++ b/src/backend/generator/statements/generate_for_stmt.cpp @@ -5,11 +5,12 @@ #include "backend/generator/statements/generate_variable_declaration_stmt.hpp" #include "backend/generator/statements/generate_outlined_for.hpp" #include "backend/generator/symbols/identifier_symbol_table.hpp" +#include "backend/generator/symbols/iterator_stack.hpp" +#include "backend/generator/types/generate_type.hpp" llvm::Value* generate_for_stmt(ForNode *node, llvm::LLVMContext &Context, llvm::IRBuilder<> &Builder, llvm::Module &Module) { llvm::Function *currentFunction = Builder.GetInsertBlock()->getParent(); - // Declarar e inicializar a variável do loop VariableNode iteratorVar; iteratorVar.name = node->variable; iteratorVar.varType = node->var_type; @@ -17,22 +18,31 @@ llvm::Value* generate_for_stmt(ForNode *node, llvm::LLVMContext &Context, llvm:: iteratorVar.isConst = false; iteratorVar.value = node->start; - if (node->iterator){ - generate_variable_declaration_stmt(&iteratorVar, Context, Builder, Module); + + llvm::Value *decl; + llvm::Value *iterator; + + if (node->iterator) { + iterator = generate_expr(node->iterator, Context, Builder, Module); + decl = generate_variable_declaration_stmt(&iteratorVar, Context, Builder, Module); } llvm::Value *startVal = generate_expr(node->start, Context, Builder, Module); + push_iterator(decl, iterator, iterator->getType()); + llvm::AllocaInst *loopVar = Builder.CreateAlloca(startVal->getType(), nullptr, node->variable); Builder.CreateStore(startVal, loopVar); // Inicializar a variável do loop - - llvm::Value *loopVarVal = Builder.CreateLoad(loopVar->getAllocatedType(), loopVar, node->variable); + { + std::lock_guard lock(symbol_stack_mutex); + add_identifier(node->variable, loopVar, startVal, startVal->getType()); + } + llvm::Value *stopVal = generate_stop(node->stop, Context, Builder, Module); - // Certifique-se de que ambos são do tipo i32 - if (loopVarVal->getType() != llvm::Type::getInt32Ty(Context)) { - loopVarVal = Builder.CreateSExt(loopVarVal, llvm::Type::getInt32Ty(Context)); + if (startVal->getType() != llvm::Type::getInt32Ty(Context)) { + startVal = Builder.CreateSExt(startVal, llvm::Type::getInt32Ty(Context)); } if (stopVal->getType() != llvm::Type::getInt32Ty(Context)) { @@ -41,7 +51,6 @@ llvm::Value* generate_for_stmt(ForNode *node, llvm::LLVMContext &Context, llvm:: } if (node->is_parallel) { - // Definir funções OpenMP llvm::Constant *ompString = llvm::ConstantDataArray::getString(Context, ";unknown;unknown;0;0;;", true); llvm::GlobalVariable *ompGlobalString = new llvm::GlobalVariable( @@ -64,7 +73,6 @@ llvm::Value* generate_for_stmt(ForNode *node, llvm::LLVMContext &Context, llvm:: } ); - auto create_omp_ident = [&](int flags, llvm::StringRef name) { llvm::Constant *ident = llvm::ConstantStruct::get( identTy, @@ -121,7 +129,6 @@ llvm::Value* generate_for_stmt(ForNode *node, llvm::LLVMContext &Context, llvm:: ) ); - llvm::GlobalVariable *ompIdent0 = create_omp_ident(514, "omp_ident0"); llvm::GlobalVariable *ompIdent1 = create_omp_ident(2, "omp_ident1"); @@ -147,9 +154,8 @@ llvm::Value* generate_for_stmt(ForNode *node, llvm::LLVMContext &Context, llvm:: Builder.CreateBr(condBB); Builder.SetInsertPoint(condBB); - llvm::Value *loopVarValLoad = Builder.CreateLoad(loopVarVal->getType(), loopVar, node->variable); - llvm::Value *cond = Builder.CreateICmpSLT(loopVarValLoad, stopVal, "loopcond"); - + llvm::Value *loopVarVal = Builder.CreateLoad(loopVar->getAllocatedType(), loopVar, node->variable); + llvm::Value *cond = Builder.CreateICmpSLT(loopVarVal, stopVal, "loopcond"); Builder.CreateCondBr(cond, bodyBB, endBB); Builder.SetInsertPoint(bodyBB); @@ -162,13 +168,16 @@ llvm::Value* generate_for_stmt(ForNode *node, llvm::LLVMContext &Context, llvm:: // Update loop variable Builder.SetInsertPoint(updateBB); - llvm::Value *inc = Builder.CreateAdd(loopVarValLoad, llvm::ConstantInt::get(llvm::Type::getInt32Ty(Context), 1), "inc"); - Builder.CreateStore(inc, loopVar); // Update %i + llvm::Value *inc = Builder.CreateAdd(loopVarVal, llvm::ConstantInt::get(llvm::Type::getInt32Ty(Context), 1), "inc"); + Builder.CreateStore(inc, loopVar); // Update Builder.CreateBr(condBB); // Jump back to the condition block // Finalize the loop Builder.SetInsertPoint(endBB); } + + pop_iterator(); + return nullptr; } diff --git a/src/backend/generator/statements/generate_if_stmt.cpp b/src/backend/generator/statements/generate_if_stmt.cpp new file mode 100644 index 0000000..d5b1548 --- /dev/null +++ b/src/backend/generator/statements/generate_if_stmt.cpp @@ -0,0 +1,43 @@ +#include "backend/generator/statements/generate_if_stmt.hpp" +#include "backend/generator/statements/generate_stmt.hpp" +#include "backend/generator/expressions/generate_expr.hpp" + +llvm::Value* generate_if_stmt(IfNode *node, llvm::LLVMContext &Context, llvm::IRBuilder<> &Builder, llvm::Module &Module) { + + llvm::Value *condition = generate_expr(node->condition, Context, Builder, Module); + if (!condition) { + throw std::runtime_error("Failed to generate condition for if statement."); + } + + // Criar os blocos de controle dentro da função atual + llvm::BasicBlock *currentBB = Builder.GetInsertBlock(); // Obter o bloco atual da função + llvm::Function *currentFunction = currentBB->getParent(); // Obter a função atual + + llvm::BasicBlock *thenBlock = llvm::BasicBlock::Create(Context, "then", currentFunction); + llvm::BasicBlock *elseBlock = llvm::BasicBlock::Create(Context, "else", currentFunction); + llvm::BasicBlock *mergeBlock = llvm::BasicBlock::Create(Context, "ifcont", currentFunction); + + // Instrução de desvio condicional + Builder.CreateCondBr(condition, thenBlock, elseBlock); + + // Inserir as instruções no bloco 'then' + Builder.SetInsertPoint(thenBlock); + for (size_t i = 0; i < node->consequent_count; ++i) { + generate_stmt(node->consequent[i], Context, Module, Builder); // Gerar o código para cada instrução no 'then' + } + Builder.CreateBr(mergeBlock); // Depois de executar o 'then', desvia para o bloco final + + // Inserir as instruções no bloco 'else' (caso exista) + Builder.SetInsertPoint(elseBlock); + if (node->alternate != nullptr) { + for (size_t i = 0; i < node->alternate_count; ++i) { + generate_stmt(node->alternate[i], Context, Module, Builder); // Gerar o código para cada instrução no 'else' + } + } + Builder.CreateBr(mergeBlock); // Depois de executar o 'else', desvia para o bloco final + + // Inserir o código no bloco 'merge' (final) + Builder.SetInsertPoint(mergeBlock); + + return nullptr; +} diff --git a/src/backend/generator/statements/generate_outlined_for.cpp b/src/backend/generator/statements/generate_outlined_for.cpp index d349a15..d302c98 100644 --- a/src/backend/generator/statements/generate_outlined_for.cpp +++ b/src/backend/generator/statements/generate_outlined_for.cpp @@ -3,6 +3,8 @@ #include "backend/generator/statements/generate_variable_declaration_stmt.hpp" #include "backend/generator/expressions/generate_expr.hpp" #include "backend/generator/utils/generate_stop.hpp" +#include "backend/generator/symbols/identifier_symbol_table.hpp" + llvm::Function* generate_outlined_for(ForNode *node, llvm::LLVMContext &Context, llvm::Module &Module, llvm::GlobalVariable *ompIdent, char *schedule_policy) { // Criando a assinatura da função for.omp_outlined @@ -17,6 +19,7 @@ llvm::Function* generate_outlined_for(ForNode *node, llvm::LLVMContext &Context, // Declarar e inicializar a variável do loop llvm::Value *startVal = generate_expr(node->start, Context, Builder, Module); + llvm::AllocaInst *loopVar = Builder.CreateAlloca(startVal->getType(), nullptr, node->variable); Builder.CreateStore(startVal, loopVar); // Inicializar a variável do loop @@ -139,8 +142,7 @@ llvm::Function* generate_outlined_for(ForNode *node, llvm::LLVMContext &Context, Builder.CreateBr(condBB); Builder.SetInsertPoint(condBB); - llvm::Value *loopVarValLoad = Builder.CreateLoad(loopVarVal->getType(), loopVar, node->variable); - llvm::Value *cond = Builder.CreateICmpSLT(loopVarValLoad, stopVal, "loopcond"); + llvm::Value *cond = Builder.CreateICmpSLT(loopVarVal, stopVal, "loopcond"); Builder.CreateCondBr(cond, bodyBB, endBB); @@ -154,7 +156,7 @@ llvm::Function* generate_outlined_for(ForNode *node, llvm::LLVMContext &Context, // Update loop variable Builder.SetInsertPoint(updateBB); - llvm::Value *inc = Builder.CreateAdd(loopVarValLoad, llvm::ConstantInt::get(llvm::Type::getInt32Ty(Context), 1), "inc"); + llvm::Value *inc = Builder.CreateAdd(loopVarVal, llvm::ConstantInt::get(llvm::Type::getInt32Ty(Context), 1), "inc"); Builder.CreateStore(inc, loopVar); // Update %i Builder.CreateBr(condBB); // Jump back to the condition block diff --git a/src/backend/generator/statements/generate_stmt.cpp b/src/backend/generator/statements/generate_stmt.cpp index 2264cb4..e6f52a2 100644 --- a/src/backend/generator/statements/generate_stmt.cpp +++ b/src/backend/generator/statements/generate_stmt.cpp @@ -3,6 +3,7 @@ #include "backend/generator/statements/generate_function_declaration_stmt.hpp" #include "backend/generator/statements/generate_extern_stmt.hpp" #include "backend/generator/statements/generate_for_stmt.hpp" +#include "backend/generator/statements/generate_if_stmt.hpp" #include "backend/generator/expressions/generate_expr.hpp" llvm::Value* generate_stmt(AstNode *node, llvm::LLVMContext &Context, llvm::Module &Module, llvm::IRBuilder<> &Builder) { @@ -19,6 +20,10 @@ llvm::Value* generate_stmt(AstNode *node, llvm::LLVMContext &Context, llvm::Modu ForNode *forNode = (ForNode *)node->data; return generate_for_stmt(forNode, Context, Builder, Module); } + case NODE_IF: { + IfNode *ifNode = (IfNode *)node->data; + return generate_if_stmt(ifNode, Context, Builder, Module); + } case NODE_EXTERN: { ExternNode *externNode = (ExternNode *)node->data; return generate_extern_stmt(externNode, Context, Builder, Module); diff --git a/src/backend/generator/symbols/identifier_symbol_table.cpp b/src/backend/generator/symbols/identifier_symbol_table.cpp index 2f2ca1c..fcfdd7f 100644 --- a/src/backend/generator/symbols/identifier_symbol_table.cpp +++ b/src/backend/generator/symbols/identifier_symbol_table.cpp @@ -1,21 +1,28 @@ #include "backend/generator/symbols/identifier_symbol_table.hpp" #include "backend/generator/symbols/symbol_stack.hpp" +#include -const SymbolInfo *find_identifier(const std::string &name) { - std::lock_guard lock(symbol_stack_mutex); +// Função para encontrar o identificador na pilha de símbolos +SymbolInfo *find_identifier(const std::string &name) { + if (symbol_stack.empty()) { + throw std::runtime_error("Symbol stack is empty. Cannot find identifier."); + } - for (const auto& entry : symbol_stack.top()) { + for (auto& entry : symbol_stack.top()) { if (entry.first == name) { return &entry.second; } } - + return nullptr; } +// Função para adicionar um identificador à pilha de símbolos void add_identifier(const std::string& name, llvm::Value* declaration, llvm::Value* value, llvm::Type* type) { if (symbol_stack.empty()) { throw std::runtime_error("No active scope to add identifier."); } + + // Adiciona o identificador à pilha de símbolos symbol_stack.top()[name] = SymbolInfo{declaration, value, type}; -} \ No newline at end of file +} diff --git a/src/backend/generator/symbols/iterator_stack.cpp b/src/backend/generator/symbols/iterator_stack.cpp new file mode 100644 index 0000000..7cba3b3 --- /dev/null +++ b/src/backend/generator/symbols/iterator_stack.cpp @@ -0,0 +1,28 @@ +#include "backend/generator/symbols/iterator_stack.hpp" +#include + +std::stack iterator_stack; +std::mutex iterator_stack_mutex; + +void push_iterator(llvm::Value* declaration, llvm::Value* value, llvm::Type* type) { + std::lock_guard lock(iterator_stack_mutex); + iterator_stack.push(IteratorInfo{declaration, value, type}); +} + +IteratorInfo pop_iterator() { + std::lock_guard lock(iterator_stack_mutex); + if (iterator_stack.empty()) { + throw std::runtime_error("Trying to pop from an empty iterator stack!"); + } + IteratorInfo top_info = iterator_stack.top(); + iterator_stack.pop(); + return top_info; +} + +IteratorInfo* current_iterator() { + std::lock_guard lock(iterator_stack_mutex); + if (iterator_stack.empty()) { + return nullptr; + } + return &iterator_stack.top(); +} diff --git a/src/frontend/parser/printer/nodes/expressions/print_enum.c b/src/frontend/parser/printer/nodes/statements/print_enum.c similarity index 100% rename from src/frontend/parser/printer/nodes/expressions/print_enum.c rename to src/frontend/parser/printer/nodes/statements/print_enum.c