Implemented arithmetic operators and file input
This commit is contained in:
parent
e93945f63a
commit
e7a2a1940a
@ -2,7 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.30 FATAL_ERROR)
|
|||||||
PROJECT(HOOLANG)
|
PROJECT(HOOLANG)
|
||||||
|
|
||||||
SET (CMAKE_CXX_STANDARD 17)
|
SET (CMAKE_CXX_STANDARD 17)
|
||||||
SET (ANTLR_JAR /usr/local/lib/antlr4-4.13.2-complete.jar)
|
SET (ANTLR_JAR "${CMAKE_SOURCE_DIR}/antlr4-4.13.2-complete.jar")
|
||||||
SET (ANTLR_INCLUDE_DIR /usr/local/include/antlr4-runtime/)
|
SET (ANTLR_INCLUDE_DIR /usr/local/include/antlr4-runtime/)
|
||||||
SET (ANTLR_GENERATED_DIR "${CMAKE_BINARY_DIR}/antlr4/generated")
|
SET (ANTLR_GENERATED_DIR "${CMAKE_BINARY_DIR}/antlr4/generated")
|
||||||
SET (GRAMMAR_FILE "${CMAKE_SOURCE_DIR}/Hoo.g4")
|
SET (GRAMMAR_FILE "${CMAKE_SOURCE_DIR}/Hoo.g4")
|
||||||
|
|||||||
27
src/Hoo.cpp
27
src/Hoo.cpp
@ -1,3 +1,30 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include "Compiler.hpp"
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
|
if (argc != 2) {
|
||||||
|
std::cerr << "Usage: " << argv[0] << " <file>" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ifstream file(argv[1]);
|
||||||
|
if (!file.is_open()) {
|
||||||
|
std::cerr << "Error: could not open file " << argv[1] << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream buffer;
|
||||||
|
buffer << file.rdbuf();
|
||||||
|
std::string input = buffer.str();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Compiler compiler(input, "hoo_module");
|
||||||
|
compiler.compile();
|
||||||
|
} catch (...) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
147
src/Visitor.cpp
147
src/Visitor.cpp
@ -7,6 +7,7 @@
|
|||||||
#include <llvm/IR/Constants.h>
|
#include <llvm/IR/Constants.h>
|
||||||
#include <llvm/IR/Type.h>
|
#include <llvm/IR/Type.h>
|
||||||
#include <llvm/Support/raw_ostream.h>
|
#include <llvm/Support/raw_ostream.h>
|
||||||
|
#include <llvm/IR/Instructions.h>
|
||||||
|
|
||||||
Visitor::Visitor(const std::string &moduleName) : _moduleName(moduleName),
|
Visitor::Visitor(const std::string &moduleName) : _moduleName(moduleName),
|
||||||
_context(std::make_shared<llvm::LLVMContext>()),
|
_context(std::make_shared<llvm::LLVMContext>()),
|
||||||
@ -15,7 +16,7 @@ Visitor::Visitor(const std::string &moduleName) : _moduleName(moduleName),
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::any Visitor::visitLiteral(HooParser::LiteralContext *ctx)
|
llvm::Value *Visitor::visitLiteral(HooParser::LiteralContext *ctx)
|
||||||
{
|
{
|
||||||
auto value = ctx->INTEGER_LITERAL();
|
auto value = ctx->INTEGER_LITERAL();
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
@ -33,7 +34,7 @@ std::any Visitor::visitLiteral(HooParser::LiteralContext *ctx)
|
|||||||
auto constantValue = llvm::dyn_cast<llvm::ConstantInt>(decimalConstant)->getValue().getSExtValue();
|
auto constantValue = llvm::dyn_cast<llvm::ConstantInt>(decimalConstant)->getValue().getSExtValue();
|
||||||
assert(constantValue == decimalValue);
|
assert(constantValue == decimalValue);
|
||||||
#endif
|
#endif
|
||||||
return std::any{Node(NODE_LITERAL, DATATYPE_INTEGER, decimalConstant)};
|
return decimalConstant;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = ctx->DOUBLE_LITERAL();
|
value = ctx->DOUBLE_LITERAL();
|
||||||
@ -43,7 +44,7 @@ std::any Visitor::visitLiteral(HooParser::LiteralContext *ctx)
|
|||||||
auto doubleValue = std::stod(doubleText);
|
auto doubleValue = std::stod(doubleText);
|
||||||
llvm::Constant *doubleConstant = llvm::ConstantFP::get(
|
llvm::Constant *doubleConstant = llvm::ConstantFP::get(
|
||||||
llvm::Type::getDoubleTy(*_context), doubleValue);
|
llvm::Type::getDoubleTy(*_context), doubleValue);
|
||||||
return std::any{Node(NODE_LITERAL, DATATYPE_DOUBLE, doubleConstant)};
|
return doubleConstant;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = ctx->BOOL_LITERAL();
|
value = ctx->BOOL_LITERAL();
|
||||||
@ -53,7 +54,7 @@ std::any Visitor::visitLiteral(HooParser::LiteralContext *ctx)
|
|||||||
auto boolValue = boolText == "true" ? 1 : 0;
|
auto boolValue = boolText == "true" ? 1 : 0;
|
||||||
llvm::Type *boolType = llvm::Type::getInt1Ty(*_context);
|
llvm::Type *boolType = llvm::Type::getInt1Ty(*_context);
|
||||||
llvm::Constant *boolConstant = llvm::ConstantInt::get(boolType, boolValue, true);
|
llvm::Constant *boolConstant = llvm::ConstantInt::get(boolType, boolValue, true);
|
||||||
return std::any{Node(NODE_LITERAL, DATATYPE_BOOL, boolConstant)};
|
return boolConstant;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = ctx->CHAR_LITERAL();
|
value = ctx->CHAR_LITERAL();
|
||||||
@ -73,7 +74,7 @@ std::any Visitor::visitLiteral(HooParser::LiteralContext *ctx)
|
|||||||
llvm::ConstantInt::get(byteType, charValue.bytes[0]),
|
llvm::ConstantInt::get(byteType, charValue.bytes[0]),
|
||||||
llvm::ConstantInt::get(byteType, charValue.bytes[1]),
|
llvm::ConstantInt::get(byteType, charValue.bytes[1]),
|
||||||
})});
|
})});
|
||||||
return std::any{Node(NODE_LITERAL, DATATYPE_CHAR, charConstant)};
|
return charConstant;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = ctx->STRING_LITERAL();
|
value = ctx->STRING_LITERAL();
|
||||||
@ -81,7 +82,7 @@ std::any Visitor::visitLiteral(HooParser::LiteralContext *ctx)
|
|||||||
{
|
{
|
||||||
auto stringText = value->getText();
|
auto stringText = value->getText();
|
||||||
auto stringConstant = llvm::ConstantDataArray::getString(*_context, stringText);
|
auto stringConstant = llvm::ConstantDataArray::getString(*_context, stringText);
|
||||||
return std::any{Node(NODE_LITERAL, DATATYPE_STRING, stringConstant)};
|
return stringConstant;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto line_no = ctx->getStart()->getLine();
|
auto line_no = ctx->getStart()->getLine();
|
||||||
@ -93,7 +94,7 @@ std::any Visitor::visitLiteral(HooParser::LiteralContext *ctx)
|
|||||||
throw ParseErrorException(_moduleName, line_no, char_pos, message);
|
throw ParseErrorException(_moduleName, line_no, char_pos, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::any Visitor::visitPrimaryLiteral(HooParser::PrimaryLiteralContext *ctx)
|
llvm::Value *Visitor::visitPrimaryLiteral(HooParser::PrimaryLiteralContext *ctx)
|
||||||
{
|
{
|
||||||
auto literal = ctx->literal();
|
auto literal = ctx->literal();
|
||||||
if (literal != nullptr)
|
if (literal != nullptr)
|
||||||
@ -101,17 +102,17 @@ std::any Visitor::visitPrimaryLiteral(HooParser::PrimaryLiteralContext *ctx)
|
|||||||
auto node = visitLiteral(literal);
|
auto node = visitLiteral(literal);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
return std::any();
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::any Visitor::visitNestedExpression(HooParser::NestedExpressionContext *ctx)
|
llvm::Value *Visitor::visitNestedExpression(HooParser::NestedExpressionContext *ctx)
|
||||||
{
|
{
|
||||||
auto expr_ctx = ctx->expression();
|
auto expr_ctx = ctx->expression();
|
||||||
auto node = visit(expr_ctx);
|
auto node = visit(expr_ctx);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::any Visitor::visitExpressionStatement(HooParser::ExpressionStatementContext *ctx)
|
llvm::Value *Visitor::visitExpressionStatement(HooParser::ExpressionStatementContext *ctx)
|
||||||
{
|
{
|
||||||
auto expressionCtx = ctx->expression();
|
auto expressionCtx = ctx->expression();
|
||||||
if (expressionCtx != nullptr)
|
if (expressionCtx != nullptr)
|
||||||
@ -119,10 +120,10 @@ std::any Visitor::visitExpressionStatement(HooParser::ExpressionStatementContext
|
|||||||
auto node = visit(expressionCtx);
|
auto node = visit(expressionCtx);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
return std::any();
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::any Visitor::visitStatement(HooParser::StatementContext *ctx)
|
llvm::Value *Visitor::visitStatement(HooParser::StatementContext *ctx)
|
||||||
{
|
{
|
||||||
auto expr_stmt_ctx = ctx->expressionStatement();
|
auto expr_stmt_ctx = ctx->expressionStatement();
|
||||||
if (expr_stmt_ctx != nullptr)
|
if (expr_stmt_ctx != nullptr)
|
||||||
@ -130,16 +131,130 @@ std::any Visitor::visitStatement(HooParser::StatementContext *ctx)
|
|||||||
auto node = visitExpressionStatement(expr_stmt_ctx);
|
auto node = visitExpressionStatement(expr_stmt_ctx);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
return std::any();
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::any Visitor::visitUnit(HooParser::UnitContext *ctx)
|
llvm::Value *Visitor::visitUnit(HooParser::UnitContext *ctx)
|
||||||
{
|
{
|
||||||
|
llvm::FunctionType* funcType = llvm::FunctionType::get(_builder->getInt32Ty(), false);
|
||||||
|
llvm::Function* mainFunc = llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, "main", _module.get());
|
||||||
|
llvm::BasicBlock* entry = llvm::BasicBlock::Create(*_context, "entry", mainFunc);
|
||||||
|
_builder->SetInsertPoint(entry);
|
||||||
|
|
||||||
auto stmt_ctx = ctx->statement();
|
auto stmt_ctx = ctx->statement();
|
||||||
if (stmt_ctx != nullptr)
|
if (stmt_ctx != nullptr)
|
||||||
{
|
{
|
||||||
auto result = visitStatement(stmt_ctx);
|
visitStatement(stmt_ctx);
|
||||||
return result;
|
}
|
||||||
|
|
||||||
|
_builder->CreateRet(llvm::ConstantInt::get(*_context, llvm::APInt(32, 0)));
|
||||||
|
|
||||||
|
_module->print(llvm::outs(), nullptr);
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::Value *Visitor::visitMultiplicationExpression(HooParser::MultiplicationExpressionContext *ctx)
|
||||||
|
{
|
||||||
|
auto left = visit(ctx->expression(0));
|
||||||
|
auto right = visit(ctx->expression(1));
|
||||||
|
if (left->getType() != right->getType())
|
||||||
|
{
|
||||||
|
// TODO: handle type mismatch
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (left->getType()->isIntegerTy())
|
||||||
|
{
|
||||||
|
return _builder->CreateMul(left, right, "multmp");
|
||||||
|
}
|
||||||
|
if (left->getType()->isDoubleTy())
|
||||||
|
{
|
||||||
|
return _builder->CreateFMul(left, right, "multmp");
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
llvm::Value *Visitor::visitDivisionExpression(HooParser::DivisionExpressionContext *ctx)
|
||||||
|
{
|
||||||
|
auto left = visit(ctx->expression(0));
|
||||||
|
auto right = visit(ctx->expression(1));
|
||||||
|
if (left->getType() != right->getType())
|
||||||
|
{
|
||||||
|
// TODO: handle type mismatch
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (left->getType()->isIntegerTy())
|
||||||
|
{
|
||||||
|
return _builder->CreateSDiv(left, right, "divtmp");
|
||||||
|
}
|
||||||
|
if (left->getType()->isDoubleTy())
|
||||||
|
{
|
||||||
|
return _builder->CreateFDiv(left, right, "divtmp");
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::Value *Visitor::visitReminderExpression(HooParser::ReminderExpressionContext *ctx)
|
||||||
|
{
|
||||||
|
auto left = visit(ctx->expression(0));
|
||||||
|
auto right = visit(ctx->expression(1));
|
||||||
|
if (left->getType() != right->getType())
|
||||||
|
{
|
||||||
|
// TODO: handle type mismatch
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (left->getType()->isIntegerTy())
|
||||||
|
{
|
||||||
|
return _builder->CreateSRem(left, right, "remtmp");
|
||||||
|
}
|
||||||
|
if (left->getType()->isDoubleTy())
|
||||||
|
{
|
||||||
|
return _builder->CreateFRem(left, right, "remtmp");
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::Value *Visitor::visitAdditiveExpression(HooParser::AdditiveExpressionContext *ctx)
|
||||||
|
{
|
||||||
|
auto left = visit(ctx->expression(0));
|
||||||
|
auto right = visit(ctx->expression(1));
|
||||||
|
if (left->getType() != right->getType())
|
||||||
|
{
|
||||||
|
// TODO: handle type mismatch
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (left->getType()->isIntegerTy())
|
||||||
|
{
|
||||||
|
return _builder->CreateAdd(left, right, "addtmp");
|
||||||
|
}
|
||||||
|
if (left->getType()->isDoubleTy())
|
||||||
|
{
|
||||||
|
return _builder->CreateFAdd(left, right, "addtmp");
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::Value *Visitor::visitSubtractExpression(HooParser::SubtractExpressionContext *ctx)
|
||||||
|
{
|
||||||
|
auto left = visit(ctx->expression(0));
|
||||||
|
auto right = visit(ctx->expression(1));
|
||||||
|
if (left->getType() != right->getType())
|
||||||
|
{
|
||||||
|
// TODO: handle type mismatch
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (left->getType()->isIntegerTy())
|
||||||
|
{
|
||||||
|
return _builder->CreateSub(left, right, "subtmp");
|
||||||
|
}
|
||||||
|
if (left->getType()->isDoubleTy())
|
||||||
|
{
|
||||||
|
return _builder->CreateFSub(left, right, "subtmp");
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::Value *Visitor::visitPrimaryExpression(HooParser::PrimaryExpressionContext *ctx)
|
||||||
|
{
|
||||||
|
return visit(ctx->primary());
|
||||||
|
}
|
||||||
@ -20,12 +20,18 @@ public:
|
|||||||
Visitor(const std::string &moduleName);
|
Visitor(const std::string &moduleName);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::any visitLiteral(HooParser::LiteralContext *ctx) override;
|
llvm::Value *visitLiteral(HooParser::LiteralContext *ctx) override;
|
||||||
std::any visitPrimaryLiteral(HooParser::PrimaryLiteralContext *ctx) override;
|
llvm::Value *visitPrimaryLiteral(HooParser::PrimaryLiteralContext *ctx) override;
|
||||||
std::any visitNestedExpression(HooParser::NestedExpressionContext *ctx) override;
|
llvm::Value *visitNestedExpression(HooParser::NestedExpressionContext *ctx) override;
|
||||||
std::any visitExpressionStatement(HooParser::ExpressionStatementContext *ctx) override;
|
llvm::Value *visitExpressionStatement(HooParser::ExpressionStatementContext *ctx) override;
|
||||||
std::any visitStatement(HooParser::StatementContext *ctx) override;
|
llvm::Value *visitStatement(HooParser::StatementContext *ctx) override;
|
||||||
std::any visitUnit(HooParser::UnitContext *ctx) override;
|
llvm::Value *visitUnit(HooParser::UnitContext *ctx) override;
|
||||||
|
llvm::Value *visitMultiplicationExpression(HooParser::MultiplicationExpressionContext *ctx) override;
|
||||||
|
llvm::Value *visitDivisionExpression(HooParser::DivisionExpressionContext *ctx) override;
|
||||||
|
llvm::Value *visitReminderExpression(HooParser::ReminderExpressionContext *ctx) override;
|
||||||
|
llvm::Value *visitAdditiveExpression(HooParser::AdditiveExpressionContext *ctx) override;
|
||||||
|
llvm::Value *visitSubtractExpression(HooParser::SubtractExpressionContext *ctx) override;
|
||||||
|
llvm::Value *visitPrimaryExpression(HooParser::PrimaryExpressionContext *ctx) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::shared_ptr<llvm::LLVMContext> getContext() const { return _context; }
|
std::shared_ptr<llvm::LLVMContext> getContext() const { return _context; }
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user