hoolang/src/Visitor.cpp

100 lines
3.3 KiB
C++

#include "Visitor.hpp"
#include "Node.hpp"
#include <llvm/IR/Constants.h>
#include <llvm/IR/Type.h>
#include <llvm/Support/raw_ostream.h>
Visitor::Visitor(const std::string &moduleName) : _moduleName(moduleName),
_context(std::make_shared<llvm::LLVMContext>()),
_module(std::make_shared<llvm::Module>(moduleName, *_context)),
_builder(std::make_shared<llvm::IRBuilder<>>(*_context))
{
}
std::any Visitor::visitLiteral(HooParser::LiteralContext *ctx)
{
auto value = ctx->INTEGER_LITERAL();
if (value)
{
auto decimalText = value->getText();
double decimalValue = std::stoll(decimalText);
llvm::Type *decimalType = llvm::Type::getInt64Ty(*_context);
llvm::Constant *decimalConstant = llvm::ConstantInt::getSigned(decimalType, decimalValue);
#ifdef NDEBUG
auto constantValue = llvm::dyn_cast<llvm::ConstantInt>(decimalConstant)->getValue().getSExtValue();
assert(constantValue == decimalValue);
#endif
return std::any{Node(NODE_LITERAL, DATATYPE_INTEGER, decimalConstant)};
}
value = ctx->DOUBLE_LITERAL();
if (value)
{
auto doubleText = value->getText();
auto doubleValue = std::stod(doubleText);
llvm::Constant *doubleConstant = llvm::ConstantFP::get(
llvm::Type::getDoubleTy(*_context), doubleValue);
return std::any{Node(NODE_LITERAL, DATATYPE_DOUBLE, doubleConstant)};
}
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::visitLiteralStatement(HooParser::LiteralStatementContext *ctx)
{
auto literal_context = ctx->literal();
auto result = visitLiteral(literal_context);
return result;
}
std::any Visitor::visitStatement(HooParser::StatementContext *ctx)
{
auto listeral_stmt_ctx = ctx->literalStatement();
if (listeral_stmt_ctx != nullptr)
{
auto result = visitLiteralStatement(listeral_stmt_ctx);
return result;
}
return nullptr;
}
std::any Visitor::visitUnit(HooParser::UnitContext *ctx)
{
auto stmt_ctx = ctx->statement();
if (stmt_ctx != nullptr)
{
auto result = visitStatement(stmt_ctx);
return result;
}
return nullptr;
}