Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Succcessful generation of functions #51

Merged
merged 22 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
41609ba
Update LLVM link
wesuRage Dec 10, 2024
f66269a
Update README.md
wesuRage Dec 10, 2024
15d4dbc
feat(symbols): added symbol tracking on generation
wesuRage Dec 11, 2024
8d88bfe
refactor(add_id): created add_identifer for searching on scopes
wesuRage Dec 11, 2024
03a71c7
feat(return): added return case to the function generation
wesuRage Dec 11, 2024
842b867
fix(function): removed pre-created main function
wesuRage Dec 11, 2024
f6af7c7
feat(isDecimal): added verification for decimal values
wesuRage Dec 11, 2024
eef2307
feat(recursion): added multiple members recursion
wesuRage Dec 11, 2024
a425af8
feat(arg_count): added counter for args
wesuRage Dec 11, 2024
b8fac10
feat(tokens): added parsing for return and boolean tokens
wesuRage Dec 11, 2024
2b3828e
feat(increment): put increment inside array index
wesuRage Dec 11, 2024
8163e26
misc(comments): only comments
wesuRage Dec 11, 2024
dc9c4c6
feat(printing): added printing for return and call expr
wesuRage Dec 11, 2024
7da6801
feat(call): added call expr generation
wesuRage Dec 11, 2024
c5d1e1c
fix(logic): fixed logic for identifier look up
wesuRage Dec 11, 2024
2a926d9
feat(headers): added headers for boolean, return and call printing
wesuRage Dec 11, 2024
19955e5
feat(nodes): added boolean and return nodes
wesuRage Dec 11, 2024
285e6c6
feat(call): added call generator header
wesuRage Dec 11, 2024
b03ef38
feat(header): included map header
wesuRage Dec 11, 2024
952aa37
feat(generator): added generator to debug
wesuRage Dec 11, 2024
9a6b6c0
feat(functions): first function test successful
wesuRage Dec 11, 2024
87f9db3
Merge remote-tracking branch 'refs/remotes/origin/main'
wesuRage Dec 11, 2024
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
16 changes: 16 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,22 @@
"miDebuggerPath": "/usr/bin/gdb",
"cwd": "${workspaceFolder}",
"preLaunchTask": "Run Parser Test"
},
{
"name": "Run Generator Test",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/src/backend/generator/generator_test",
"args": [
"${workspaceFolder}/examples/a.glx"
],
"stopAtEntry": false,
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb",
"cwd": "${workspaceFolder}",
"preLaunchTask": "Run Generator Test"
}
]
}
18 changes: 18 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,24 @@
"cwd": "${workspaceFolder}"
}
},
{
"label": "Run Generator Test",
"type": "shell",
"command": "./src/backend/generator/generator_test",
"args": [
"./examples/a.glx"
],
"group": {
"kind": "test",
"isDefault": true
},
"problemMatcher": [
"$gcc"
],
"options": {
"cwd": "${workspaceFolder}"
}
},
{
"type": "cppbuild",
"label": "C/C++: gcc build active file",
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ Take a look at our [contributors guide](https://github.com/galaxy-lang/galaxy/bl

---

### Installation
### Build the project

Install all the dependencies:
```bash
sudo apt install clang cmake make llvm llvm-dev zlib1g-dev
```

Or you can [compile LLVM from source](https://github.com/llvm/llvm-project).
Or you can [download the built LLVM](https://github.com/llvm/llvm-project/releases/tag/llvmorg-18.1.8).

Clone the repo and compile the code:

Expand Down
8 changes: 7 additions & 1 deletion examples/a.glx
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
string oi := makonha == 3 ? "true" : "false";
def my_return( int i) -> int:
return i;
end;

def main( ) -> int:
return my_return( 10) ;
end;
12 changes: 12 additions & 0 deletions include/backend/generator/expressions/generate_call.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef GENERATE_CALL_H
#define GENERATE_CALL_H

extern "C" {
#include "frontend/ast/definitions.h"
}
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/IRBuilder.h>

llvm::Value *generate_call(CallNode *node, llvm::LLVMContext &Context, llvm::IRBuilder<> &Builder, llvm::Module &TheModule);

#endif // GENERATE_CALL_H
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef GENERATE_FUNCTION_DECLARATION_STMT_H
#define GENERATE_FUNCTION_DECLARATION_STMT_H

#include <map>
extern "C" {
#include "frontend/ast/definitions.h"
}
Expand Down
10 changes: 10 additions & 0 deletions include/backend/generator/symbols/function_symbol_table.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef FUNCTION_SYMBOL_TABLE_H
#define FUNCTION_SYMBOL_TABLE_H

#include <unordered_map>
#include <string>
#include <llvm/IR/Function.h>

extern std::unordered_map<std::string, llvm::Function *> function_symbol_table;

#endif // FUNCTION_SYMBOL_TABLE_H
11 changes: 11 additions & 0 deletions include/backend/generator/symbols/identifier_symbol_table.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef IDENTIFIER_SYMBOL_TABLE_H
#define IDENTIFIER_SYMBOL_TABLE_H

#include <unordered_map>
#include <string>
#include <llvm/IR/Function.h>

llvm::Value* find_identifier(const std::string &name);
void add_identifier(const std::string &name, llvm::Value *value);

#endif // IDENTIFIER_SYMBOL_TABLE_H
15 changes: 15 additions & 0 deletions include/backend/generator/symbols/symbol_stack.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef SYMBOL_STACK_H
#define SYMBOL_STACK_H

#include <string>
#include <unordered_map>
#include <stack>
#include <llvm/IR/Value.h>

using SymbolTable = std::unordered_map<std::string, llvm::Value*>;

extern std::stack<SymbolTable> symbol_stack;
void enter_scope(void);
void exit_scope(void);

#endif // SYMBOL_STACK_H
11 changes: 11 additions & 0 deletions include/frontend/ast/definitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,20 @@ typedef enum {
NODE_ARRAY_ACCESS,
NODE_TERNARY,
NODE_STRING,
NODE_RETURN,
NODE_BOOLEAN_LITERAL,
} NodeType;

typedef struct AstNode AstNode;

typedef struct {
char *value;
} BooleanLiteralNode;

typedef struct {
AstNode *value;
} ReturnNode;

typedef struct {
AstNode *condition;
AstNode *consequent;
Expand All @@ -49,6 +59,7 @@ typedef struct {
typedef struct {
AstNode *caller;
AstNode **args;
size_t arg_count;
} CallNode;

typedef struct {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef PRINT_BOOLEAN_H
#define PRINT_BOOLEAN_H

#include "frontend/ast/definitions.h"

void print_boolean(const AstNode *node, int depth);

#endif // PRINT_BOOLEAN_H
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef PRINT_CALL_H
#define PRINT_CALL_H

#include "frontend/ast/definitions.h"
#include "frontend/parser/printer/visited.h"

void print_call(const AstNode *node, int depth, VisitedNodes *visited);

#endif // PRINT_CALL_H
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef PRINT_RETURN_H
#define PRINT_RETURN_H

#include "frontend/ast/definitions.h"
#include "frontend/parser/printer/visited.h"

void print_return(const AstNode *node, int depth, VisitedNodes *visited);

#endif // PRINT_RETURN_H
50 changes: 50 additions & 0 deletions src/backend/generator/expressions/generate_call.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "backend/generator/statements/generate_function_declaration_stmt.hpp"
#include "backend/generator/statements/generate_stmt.hpp"
#include "backend/generator/expressions/generate_expr.hpp"
#include "backend/generator/types/generate_type.hpp"
#include "backend/generator/symbols/function_symbol_table.hpp"

llvm::Value *generate_call(CallNode *call_node, llvm::LLVMContext &Context, llvm::IRBuilder<> &Builder, llvm::Module &Module) {
if (!call_node || !call_node->caller) {
throw std::runtime_error("Invalid call expression: missing caller.");
}

// Assume the caller is a function name (e.g., NODE_IDENTIFIER)
IdentifierNode *identifier = static_cast<IdentifierNode *>(call_node->caller->data);
const std::string &function_name = identifier->symbol;

// Lookup the function in the symbol table
auto it = function_symbol_table.find(function_name);
if (it == function_symbol_table.end()) {
throw std::runtime_error("Function not found in symbol table: " + function_name);
}

llvm::Function *function = it->second;
llvm::FunctionType *func_type = function->getFunctionType();

// Generate arguments
std::vector<llvm::Value *> args;
for (size_t i = 0; i < call_node->arg_count; ++i) {
llvm::Value *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 {
throw std::runtime_error("Argument type mismatch.");
}
}

args.push_back(arg);
}

// Create the call instruction
return Builder.CreateCall(function, args);
}
5 changes: 5 additions & 0 deletions src/backend/generator/expressions/generate_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "backend/generator/expressions/generate_pre_increment.hpp"
#include "backend/generator/expressions/generate_pre_decrement.hpp"
#include "backend/generator/expressions/generate_assignment_expr.hpp"
#include "backend/generator/expressions/generate_call.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
Expand All @@ -17,6 +18,10 @@ llvm::Value *generate_expr(AstNode *node, llvm::LLVMContext &Context, llvm::IRBu
NumericLiteralNode *num_node = (NumericLiteralNode *)node->data;
return generate_numeric_literal(num_node, Context);
}
case NODE_CALL: {
CallNode *call_node = (CallNode *)node->data;
return generate_call(call_node, Context, Builder, Module);
}
case NODE_IDENTIFIER: {
IdentifierNode *id_node = (IdentifierNode *)node->data;
return generate_identifier(id_node);
Expand Down
20 changes: 9 additions & 11 deletions src/backend/generator/expressions/generate_identifier.cpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
#include "backend/generator/expressions/generate_identifier.hpp"

// A map that associates variable names (symbols) with their corresponding LLVM values.
std::map<std::string, llvm::Value *> NamedValues;
#include "backend/generator/symbols/identifier_symbol_table.hpp"

llvm::Value *generate_identifier(IdentifierNode *node) {
// Search for the identifier in the NamedValues map using the symbol name
auto it = NamedValues.find(node->symbol);
// If the identifier is not found in the map
if (it == NamedValues.end()) {
// TODO: Handle the case where the identifier is not found (e.g., variable not declared)
// Usa find_identifier para buscar o valor associado ao símbolo no escopo atual
llvm::Value *value = find_identifier(node->symbol);

// Verifica se o identificador foi encontrado
if (!value) {
throw std::runtime_error("Error: identifier not found!");
}

// Return the LLVM Value associated with the found identifier
return it->second;
// Retorna o LLVM Value associado ao identificador
return value;
}
11 changes: 0 additions & 11 deletions src/backend/generator/generator.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,6 @@ int main(int argc, char **argv) {
llvm::Module TheModule("GalaxyJIT", TheContext);
llvm::IRBuilder<> Builder(TheContext);

// Create the main function in the LLVM module (returns void)
llvm::FunctionType* funcType = llvm::FunctionType::get(llvm::Type::getVoidTy(TheContext), false);
llvm::Function* mainFunc = llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, "main", &TheModule);

// Create the entry basic block for the main function
llvm::BasicBlock* entry = llvm::BasicBlock::Create(TheContext, "entry", mainFunc);
Builder.SetInsertPoint(entry);

// Generate the LLVM IR from the AST
std::vector<llvm::Value*> values = generate_ir(ast, TheContext, TheModule, Builder);

Expand All @@ -98,9 +90,6 @@ int main(int argc, char **argv) {
}
}

// End the main function with a return statement (for void functions)
Builder.CreateRetVoid();

// Verify the generated module for correctness
std::string errorMsg;
llvm::raw_string_ostream errorStream(errorMsg);
Expand Down
Loading
Loading