100 lines
3.3 KiB
C++
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;
|
|
} |