Implementing literal visitor

This commit is contained in:
Benoy Bose 2024-11-28 00:07:07 +05:30
parent 68cc1e7c68
commit 1b8ea9eee5
10 changed files with 181 additions and 23 deletions

2
.gitignore vendored
View File

@ -2,3 +2,5 @@ build/
CMakeCache.txt
**/CMakeCache.txt
Makefile
.antlr/

6
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,6 @@
{
"files.associations": {
"*.tcc": "cpp",
"istream": "cpp"
}
}

View File

@ -21,6 +21,8 @@ ADD_CUSTOM_TARGET(HooBaseVisitor ALL DEPENDS ${ANTLR_GENERATED_DIR}/HooBaseVisit
INCLUDE_DIRECTORIES(${ANTLR_GENERATED_DIR} ${ANTLR_INCLUDE_DIR})
ADD_LIBRARY(hoocore STATIC HooCore.cpp HooCore.hpp Node.hpp)
ADD_EXECUTABLE(hoo
Hoo.cpp Visitor.cpp
${ANTLR_GENERATED_DIR}/HooBaseVisitor.cpp

View File

@ -35,6 +35,7 @@ RUN apt-get install -y cmake clang-19
RUN apt-get install -y openjdk-21-jdk-headless maven
RUN apt-get install -y llvm llvm-dev
RUN apt-get install -y libedit-dev libzstd-dev libcurlpp-dev
RUN apt-get install -y libgtest-dev
COPY --from=build /custom/antlr4-cpp-runtime/usr/ /usr/
COPY --from=build /custom/antlr4/antlr4-4.13.2-complete.jar /usr/local/lib/antlr4-4.13.2-complete.jar
ENV CXX=/usr/bin/clang++-19

20
Hoo.g4
View File

@ -2,12 +2,16 @@ grammar Hoo;
import hoolexer;
literal:
DECIMAL_LITERAL |
FLOAT_LITERAL |
BOOL_LITERAL |
CHAR_LITERAL |
STRING_LITERAL |
TEXT_BLOCK;
statement: literalStatement;
unit: literal;
literalStatement: literal ';';
literal:
DECIMAL_LITERAL
| FLOAT_LITERAL
| BOOL_LITERAL
| CHAR_LITERAL
| STRING_LITERAL
| TEXT_BLOCK;
unit: statement;

52
HooCore.cpp Normal file
View File

@ -0,0 +1,52 @@
#include "HooCore.hpp"
#include "HooLexer.h"
#include "HooParser.h"
#include "Visitor.hpp"
std::any HooCore::compile(std::string &input, std::string &moduleName)
{
try
{
antlr4::tree::ParseTree *tree = parse(input);
if (tree == nullptr)
{
std::cout << "Parse failed" << std::endl;
}
Visitor *visitor = new Visitor(moduleName);
auto result = visitor->visit(tree);
return result;
}
catch (const std::exception &e)
{
std::cerr << "Compilation Error: " << e.what() << std::endl;
return nullptr;
}
catch (...)
{
std::cerr << "Compilation Error: Unknown exception" << std::endl;
return nullptr;
}
}
antlr4::tree::ParseTree *HooCore::parse(std::string &input)
{
try
{
antlr4::ANTLRInputStream input_stream(input);
HooLexer lexer(&input_stream);
antlr4::CommonTokenStream tokens(&lexer);
HooParser parser(&tokens);
antlr4::tree::ParseTree *tree = parser.unit();
return tree;
}
catch (const std::exception &e)
{
std::cerr << "Parse Error: " << e.what() << std::endl;
return nullptr;
}
catch (...)
{
std::cerr << "Parse Error: Unknown exception" << std::endl;
return nullptr;
}
}

16
HooCore.hpp Normal file
View File

@ -0,0 +1,16 @@
#pragma once
#include "antlr4-runtime.h"
#include <string>
class HooCore
{
public:
HooCore() {}
~HooCore() {}
public:
static std::any compile(std::string &input, std::string &moduleName);
static antlr4::tree::ParseTree *parse(std::string &input);
};

38
Node.hpp Normal file
View File

@ -0,0 +1,38 @@
#pragma once
#include <llvm/IR/Value.h>
enum NodeType
{
NODE_IGNORE,
NODE_LITERAL
};
enum DataType
{
DATATYPE_VOID,
DATATYPE_INTEGER,
DATATYPE_FLOAT,
DATATYPE_BOOL,
DATATYPE_CHAR,
DATATYPE_STRING
};
class Node
{
private:
NodeType _nodeType;
DataType _dataType;
llvm::Value *_value;
public:
Node(NodeType nodeType, DataType dataType, llvm::Value *value) : _nodeType(nodeType), _dataType(dataType), _value(value) {}
Node(const Node &other) : _nodeType(other._nodeType), _dataType(other._dataType), _value(other._value) {}
NodeType getNodeType() const { return _nodeType; }
DataType getDataType() const { return _dataType; }
llvm::Value *getValue() const { return _value; }
public:
virtual ~Node() = default;
};

View File

@ -1,4 +1,5 @@
#include "Visitor.hpp"
#include "Node.hpp"
#include <llvm/IR/Constants.h>
#include <llvm/IR/Type.h>
@ -13,24 +14,58 @@ Visitor::Visitor(std::string &moduleName) : _moduleName(moduleName),
std::any Visitor::visitLiteral(HooParser::LiteralContext *ctx)
{
// Implement your custom logic for visiting a LiteralContext here
// Example: if it's a decimal literal, return its value as a string
if (ctx->DECIMAL_LITERAL())
auto value = ctx->DECIMAL_LITERAL();
if (value)
{
return ctx->DECIMAL_LITERAL()->getText();
auto decimalText = value->getText();
double decimalValue = std::stoll(decimalText);
llvm::Type *decimalType = llvm::Type::getInt64Ty(*_context);
llvm::Constant *decimalConstant = llvm::ConstantInt::get(decimalType, decimalValue, true);
return std::any{Node(NODE_LITERAL, DATATYPE_INTEGER, decimalConstant)};
}
// Add handling for other literal types as needed
return visitChildren(ctx);
value = ctx->FLOAT_LITERAL();
if (value)
{
auto floatText = value->getText();
float floatValue = std::stof(floatText);
llvm::Type *floatType = llvm::Type::getFloatTy(*_context);
llvm::Constant *floatConstant = llvm::ConstantFP::get(floatType, floatValue);
return std::any{Node(NODE_LITERAL, DATATYPE_FLOAT, floatConstant)};
}
value = ctx->BOOL_LITERAL();
if (value)
{
auto boolText = value->getText();
auto boolValue = boolText == "true" ? 1 : 0;
llvm::Type *boolType = llvm::Type::getInt1Ty(*_context);
llvm::Constant *boolConstant = llvm::ConstantInt::get(boolType, boolValue, true);
return std::any{Node(NODE_LITERAL, DATATYPE_BOOL, boolConstant)};
}
value = ctx->CHAR_LITERAL();
if (value)
{
auto charText = value->getText();
char charValue = charText[1];
llvm::Type *charType = llvm::Type::getInt8Ty(*_context);
llvm::Constant *charConstant = llvm::ConstantInt::get(charType, charValue, true);
return std::any{Node(NODE_LITERAL, DATATYPE_CHAR, charConstant)};
}
value = ctx->STRING_LITERAL();
if (value)
{
auto stringText = value->getText();
auto stringConstant = llvm::ConstantDataArray::getString(*_context, stringText);
return std::any{Node(NODE_LITERAL, DATATYPE_STRING, stringConstant)};
}
return std::any{Node(NODE_IGNORE, DATATYPE_VOID, nullptr)};
}
std::any Visitor::visitUnit(HooParser::UnitContext *ctx)
{
// Implement your custom logic for visiting a UnitContext here
// Example: if it's a literal, return its value as a string
if (ctx->literal())
{
return visit(ctx->literal());
}
// Add handling for other unit types as needed
return visitChildren(ctx);
}

View File

@ -1,4 +1,6 @@
#include "HooVisitor.h"
#pragma once
#include "HooBaseVisitor.h"
#include <string>
#include <memory>
@ -6,7 +8,7 @@
#include <llvm/IR/Module.h>
#include <llvm/IR/IRBuilder.h>
class Visitor : public HooVisitor
class Visitor : public HooBaseVisitor
{
private:
std::string &_moduleName;