From 818cccda9787abdf5831d5a3d78d96d94e4d4e4e Mon Sep 17 00:00:00 2001 From: wesuRage Date: Fri, 13 Dec 2024 11:50:12 -0300 Subject: [PATCH] feat(strings): added string generation --- .../generator/expressions/generate_string.hpp | 13 ++++++++ .../generator/expressions/generate_expr.cpp | 5 +++ .../generator/expressions/generate_string.cpp | 33 +++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 include/backend/generator/expressions/generate_string.hpp create mode 100644 src/backend/generator/expressions/generate_string.cpp diff --git a/include/backend/generator/expressions/generate_string.hpp b/include/backend/generator/expressions/generate_string.hpp new file mode 100644 index 0000000..55cd8d1 --- /dev/null +++ b/include/backend/generator/expressions/generate_string.hpp @@ -0,0 +1,13 @@ +#ifndef GENERATE_STRING_LITERAL_H +#define GENERATE_STRING_LITERAL_H + +extern "C" { + #include "frontend/ast/definitions.h" +} +#include +#include +#include "llvm/IR/Module.h" + +llvm::Value *generate_string_literal(StringNode *string_node, llvm::LLVMContext &Context, llvm::IRBuilder<> &Builder, llvm::Module &Module); + +#endif // GENERATE_STRING_LITERAL_H \ No newline at end of file diff --git a/src/backend/generator/expressions/generate_expr.cpp b/src/backend/generator/expressions/generate_expr.cpp index 559319f..0f49cdb 100644 --- a/src/backend/generator/expressions/generate_expr.cpp +++ b/src/backend/generator/expressions/generate_expr.cpp @@ -9,11 +9,16 @@ #include "backend/generator/expressions/generate_pre_decrement.hpp" #include "backend/generator/expressions/generate_assignment_expr.hpp" #include "backend/generator/expressions/generate_call.hpp" +#include "backend/generator/expressions/generate_string.hpp" llvm::Value *generate_expr(AstNode *node, llvm::LLVMContext &Context, llvm::IRBuilder<> &Builder, llvm::Module &Module) { // Checks the node kind, casts the node data into // the perspective node type and then generates it. switch (node->kind) { + case NODE_STRING: { + StringNode *string_node = (StringNode *)node->data; + return generate_string_literal(string_node, Context, Builder, Module); + } case NODE_NUMERIC_LITERAL: { NumericLiteralNode *num_node = (NumericLiteralNode *)node->data; return generate_numeric_literal(num_node, Context); diff --git a/src/backend/generator/expressions/generate_string.cpp b/src/backend/generator/expressions/generate_string.cpp new file mode 100644 index 0000000..4a70c5f --- /dev/null +++ b/src/backend/generator/expressions/generate_string.cpp @@ -0,0 +1,33 @@ +#include "backend/generator/expressions/generate_string.hpp" + +llvm::Value *generate_string_literal(StringNode *string_node, llvm::LLVMContext &Context, llvm::IRBuilder<> &Builder, llvm::Module &Module) { + // Ensure that the StringNode and the string data are valid + if (!string_node || !string_node->string) { + throw std::runtime_error("Invalid string node: missing string value."); + } + + // This represents the string as a constant array of characters in LLVM + llvm::Constant *string_constant = llvm::ConstantDataArray::getString(Context, string_node->string, true); + + // This global variable will hold the constant array + llvm::GlobalVariable *global_string = new llvm::GlobalVariable( + Module, // The module to which this global variable belongs + string_constant->getType(), // The type of the string constant (constant array of chars) + true, // Whether the variable is constant + llvm::GlobalValue::PrivateLinkage, // The linkage type (private to the module) + string_constant, // The actual constant value of the string + ".str" // The name of the global variable (used for debugging and identification) + ); + + // We use `getGetElementPtr` to get a pointer to the start of the array (the first character) + llvm::Constant *zero = llvm::ConstantInt::get(llvm::Type::getInt32Ty(Context), 0); // The index for the first element of the array + llvm::Constant *indices[] = {zero, zero}; // Indices for the GetElementPtr operation + llvm::Constant *string_ptr = llvm::ConstantExpr::getGetElementPtr( + string_constant->getType(), // The type of the string constant (constant array) + global_string, // The global variable holding the string + indices // The indices to access the first character + ); + + // This pointer can now be used wherever a pointer to the string is needed in the generated IR + return string_ptr; +}