From e258fbd124fbf0ff29bb6db80187470536a61230 Mon Sep 17 00:00:00 2001 From: Nathan Seymour Date: Fri, 29 Nov 2024 12:56:09 -0600 Subject: [PATCH] major code generation refactoring; --- CMakeLists.txt | 16 +- src/compiler/Compiler.cpp | 2 +- src/compiler/transformer/IRGenerator.cpp | 176 +++++++---------- src/compiler/transformer/IRGenerator.h | 36 ++-- src/parser/Node.cpp | 49 +++++ src/parser/Node.h | 238 ++++++++--------------- src/parser/Parser.cpp | 39 ++-- src/parser/Parser.h | 5 +- 8 files changed, 257 insertions(+), 304 deletions(-) create mode 100644 src/parser/Node.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f718f8..bb4eb92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,8 @@ add_library(unlogic STATIC src/util/io.cpp src/util/io.h src/Error.h + src/parser/Node.cpp + src/parser/Node.h src/parser/Parser.cpp src/parser/Parser.h src/compiler/transformer/IRGenerator.cpp @@ -105,23 +107,23 @@ qt_add_shaders(unlogic-calculator "shaders" PREFIX "/shaders" BASE src/calculator/resource/shaders FILES - src/calculator/resource/shaders/plot.frag - src/calculator/resource/shaders/plot.vert - src/calculator/resource/shaders/grid.frag - src/calculator/resource/shaders/grid.vert + src/calculator/resource/shaders/plot.frag + src/calculator/resource/shaders/plot.vert + src/calculator/resource/shaders/grid.frag + src/calculator/resource/shaders/grid.vert ) qt_add_resources(unlogic-calculator "fonts" PREFIX "/fonts" BASE src/calculator/resource FILES - src/calculator/resource/Roboto-Medium.ttf - src/calculator/resource/SourceCodePro.ttf + src/calculator/resource/Roboto-Medium.ttf + src/calculator/resource/SourceCodePro.ttf ) qt_add_resources(unlogic-calculator "styles" PREFIX "/styles" BASE src/calculator/resource FILES - src/calculator/resource/stylesheet.qss + src/calculator/resource/stylesheet.qss ) target_link_libraries(unlogic-calculator PRIVATE Qt6::Core Qt6::Widgets Qt6::Gui Qt6::ShaderTools Qt6::GuiPrivate unlogic) set_target_properties(unlogic-calculator PROPERTIES diff --git a/src/compiler/Compiler.cpp b/src/compiler/Compiler.cpp index 9f284aa..e547407 100644 --- a/src/compiler/Compiler.cpp +++ b/src/compiler/Compiler.cpp @@ -92,7 +92,7 @@ std::expected Compiler::Compile(std::string_view prog // Build program try { - ast_body->Accept(generator); + std::visit(generator, *ast_body); } catch (std::runtime_error &e) { diff --git a/src/compiler/transformer/IRGenerator.cpp b/src/compiler/transformer/IRGenerator.cpp index bb934d2..b6c8b35 100644 --- a/src/compiler/transformer/IRGenerator.cpp +++ b/src/compiler/transformer/IRGenerator.cpp @@ -1,134 +1,114 @@ -#include #include "IRGenerator.h" +#include +#include -void unlogic::IRGenerator::Visit(unlogic::NumericLiteralNode const *node) +llvm::Value *unlogic::IRGenerator::operator()(unlogic::NumericLiteralNode &node) { - llvm::Value *value = llvm::ConstantFP::get(this->ctx.llvm_ctx, llvm::APFloat(node->value)); - this->values.push(value); + return llvm::ConstantFP::get(this->ctx.llvm_ctx, llvm::APFloat(node.value)); } -void unlogic::IRGenerator::Visit(unlogic::StringLiteralNode const *node) {} - -void unlogic::IRGenerator::Visit(unlogic::VariableNode const *node) +llvm::Value *unlogic::IRGenerator::operator()(unlogic::StringLiteralNode &node) { - llvm::Value *value = *this->ctx.scope.Lookup(node->identifier_); - this->values.push(value); + return this->builder.CreateGlobalStringPtr(node.value); } -void unlogic::IRGenerator::Visit(unlogic::CallNode const *node) +llvm::Value *unlogic::IRGenerator::operator()(unlogic::DivisionNode &node) { - llvm::Function *function = ctx.module->getFunction(node->function_name_); + llvm::Value *lhs = std::visit(*this, *node.lhs); + llvm::Value *rhs = std::visit(*this, *node.rhs); - if (function->arg_size() < node->arguments_.size()) - { - throw std::runtime_error("Aaaaaahhhhhhh"); - } + return this->builder.CreateFDiv(lhs, rhs, "divtmp"); +} - std::vector argument_values; - argument_values.reserve(node->arguments_.size()); - for (auto const &argument: node->arguments_) +llvm::Value *unlogic::IRGenerator::operator()(unlogic::ScopedBlockNode &node) +{ + for (auto &statement: node.statements) { - argument->Accept(*this); - argument_values.push_back(this->values.top()); - this->values.pop(); + std::visit(*this, *statement); } - llvm::Value *value = this->builder.CreateCall(function, argument_values, "calltmp"); - this->values.push(value); + return nullptr; } -void unlogic::IRGenerator::Visit(unlogic::AdditionNode const *node) +llvm::Value *unlogic::IRGenerator::operator()(unlogic::VariableNode &node) { - node->lhs_->Accept(*this); - llvm::Value *lhs = this->values.top(); - this->values.pop(); - - node->rhs_->Accept(*this); - llvm::Value *rhs = this->values.top(); - this->values.pop(); - - llvm::Value *value = this->builder.CreateFAdd(lhs, rhs, "addtmp"); - this->values.push(value); + return *this->ctx.scope.Lookup(node.identifier); } -void unlogic::IRGenerator::Visit(unlogic::SubtractionNode const *node) +llvm::Value *unlogic::IRGenerator::operator()(unlogic::CallNode &node) { - node->lhs_->Accept(*this); - llvm::Value *lhs = this->values.top(); - this->values.pop(); + llvm::Function *function = ctx.module->getFunction(node.function_name); - node->rhs_->Accept(*this); - llvm::Value *rhs = this->values.top(); - this->values.pop(); + if (function->arg_size() < node.arguments.size()) + { + throw std::runtime_error("Aaaaaahhhhhhh"); + } + + std::vector argument_values; + argument_values.reserve(node.arguments.size()); + for (auto &argument: node.arguments) + { + llvm::Value *arg_value = std::visit(*this, *argument); + argument_values.push_back(arg_value); + } - llvm::Value *value = this->builder.CreateFSub(lhs, rhs, "subtmp"); - this->values.push(value); + return this->builder.CreateCall(function, argument_values, "calltmp"); } -void unlogic::IRGenerator::Visit(unlogic::MultiplicationNode const *node) +llvm::Value *unlogic::IRGenerator::operator()(unlogic::AdditionNode &node) { - node->lhs_->Accept(*this); - llvm::Value *lhs = this->values.top(); - this->values.pop(); + llvm::Value *lhs = std::visit(*this, *node.lhs); + llvm::Value *rhs = std::visit(*this, *node.rhs); - node->rhs_->Accept(*this); - llvm::Value *rhs = this->values.top(); - this->values.pop(); - - llvm::Value *value = this->builder.CreateFMul(lhs, rhs, "multmp"); - this->values.push(value); + return this->builder.CreateFAdd(lhs, rhs, "addtmp"); } -void unlogic::IRGenerator::Visit(unlogic::DivisionNode const *node) +llvm::Value *unlogic::IRGenerator::operator()(unlogic::SubtractionNode &node) { - node->lhs_->Accept(*this); - llvm::Value *lhs = this->values.top(); - this->values.pop(); - - node->rhs_->Accept(*this); - llvm::Value *rhs = this->values.top(); - this->values.pop(); + llvm::Value *lhs = std::visit(*this, *node.lhs); + llvm::Value *rhs = std::visit(*this, *node.rhs); - llvm::Value *value = this->builder.CreateFDiv(lhs, rhs, "divtmp"); - this->values.push(value); + return this->builder.CreateFSub(lhs, rhs, "subtmp"); } -void unlogic::IRGenerator::Visit(unlogic::PotentiationNode const *node) +llvm::Value *unlogic::IRGenerator::operator()(unlogic::MultiplicationNode &node) { - node->lhs_->Accept(*this); - llvm::Value *lhs = this->values.top(); - this->values.pop(); + llvm::Value *lhs = std::visit(*this, *node.lhs); + llvm::Value *rhs = std::visit(*this, *node.rhs); - node->rhs_->Accept(*this); - llvm::Value *rhs = this->values.top(); - this->values.pop(); + return this->builder.CreateFMul(lhs, rhs, "multmp"); +} + +llvm::Value *unlogic::IRGenerator::operator()(unlogic::PotentiationNode &node) +{ + llvm::Value *lhs = std::visit(*this, *node.lhs); + llvm::Value *rhs = std::visit(*this, *node.rhs); llvm::Function *std_pow = this->ctx.module->getFunction("pow"); - llvm::Value *value = this->builder.CreateCall(std_pow, {lhs, rhs}, "powtmp"); - this->values.push(value); + return this->builder.CreateCall(std_pow, {lhs, rhs}, "powtmp"); } -void unlogic::IRGenerator::Visit(unlogic::FunctionDefinitionNode const *node) +llvm::Value *unlogic::IRGenerator::operator()(unlogic::FunctionDefinitionNode &node) { // Save entry llvm::BasicBlock *parent = this->builder.GetInsertBlock(); // Generate function information - std::vector argument_types(node->args_.size(), llvm::Type::getDoubleTy(ctx.llvm_ctx)); + std::vector argument_types(node.args.size(), llvm::Type::getDoubleTy(ctx.llvm_ctx)); llvm::FunctionType *function_type = llvm::FunctionType::get(llvm::Type::getDoubleTy(ctx.llvm_ctx), argument_types, false); - llvm::Function *function = llvm::Function::Create(function_type, llvm::Function::ExternalLinkage, node->name_, *ctx.module); + llvm::Function *function = llvm::Function::Create(function_type, llvm::Function::ExternalLinkage, node.name, *ctx.module); - this->ctx.scope.Insert(node->name_, function); + this->ctx.scope.Insert(node.name, function); unsigned idx = 0; for (auto &arg: function->args()) { - arg.setName(node->args_[idx++]); + arg.setName(node.args[idx++]); } // Generate function body - llvm::BasicBlock *block = llvm::BasicBlock::Create(ctx.llvm_ctx, node->name_, function); + llvm::BasicBlock *block = llvm::BasicBlock::Create(ctx.llvm_ctx, node.name, function); this->builder.SetInsertPoint(block); ctx.scope.PushLayer(); @@ -137,9 +117,7 @@ void unlogic::IRGenerator::Visit(unlogic::FunctionDefinitionNode const *node) ctx.scope.Insert(std::string(arg.getName()), &arg); } - node->body_->Accept(*this); - llvm::Value *return_value = this->values.top(); - this->values.pop(); + llvm::Value *return_value = std::visit(*this, *node.body); this->builder.CreateRet(return_value); @@ -150,42 +128,31 @@ void unlogic::IRGenerator::Visit(unlogic::FunctionDefinitionNode const *node) throw std::runtime_error("function has errors"); } - this->values.push(function); - // Return to parent block this->builder.SetInsertPoint(parent); + + return function; } -void unlogic::IRGenerator::Visit(unlogic::PlotCommandNode const *node) +llvm::Value *unlogic::IRGenerator::operator()(unlogic::PlotCommandNode &node) { llvm::Value *scene = *this->ctx.scope.Lookup("__scene"); - llvm::Value *name = this->builder.CreateGlobalStringPtr(node->function_name); + llvm::Value *name = this->builder.CreateGlobalStringPtr(node.function_name); - auto function = this->ctx.module->getFunction(node->function_name); + auto function = this->ctx.module->getFunction(node.function_name); if (!function) { - throw std::runtime_error(std::format("Function \"{}\" could not be found!", node->function_name)); + throw std::runtime_error(std::format("Function \"{}\" could not be found!", node.function_name)); } auto scene_add_plot = this->ctx.module->getFunction("unlogic_scene_add_plot"); std::array args = {scene, name, function}; - llvm::Value *ret = this->builder.CreateCall(scene_add_plot, args); - - this->values.push(ret); + return this->builder.CreateCall(scene_add_plot, args); } -void unlogic::IRGenerator::Visit(unlogic::ScopedBlockNode const *node) -{ - for (auto &statement: node->statements_) - { - statement->Accept(*this); - this->values.pop(); - } -} - -void unlogic::IRGenerator::Visit(unlogic::ProgramEntryNode const *node) +llvm::Value *unlogic::IRGenerator::operator()(unlogic::ProgramEntryNode &node) { std::array args = { llvm::PointerType::getUnqual(this->ctx.llvm_ctx), @@ -201,7 +168,7 @@ void unlogic::IRGenerator::Visit(unlogic::ProgramEntryNode const *node) this->builder.SetInsertPoint(block); - node->body->Accept(*this); + std::visit(*this, *node.body); this->builder.CreateRetVoid(); this->ctx.scope.PopLayer(); @@ -210,4 +177,11 @@ void unlogic::IRGenerator::Visit(unlogic::ProgramEntryNode const *node) { throw std::runtime_error("function has errors"); } + + return nullptr; +} + +llvm::Value *unlogic::IRGenerator::operator()(std::monostate &node) +{ + throw std::runtime_error("Invalid Node!"); } diff --git a/src/compiler/transformer/IRGenerator.h b/src/compiler/transformer/IRGenerator.h index 5899ba0..ec9f363 100644 --- a/src/compiler/transformer/IRGenerator.h +++ b/src/compiler/transformer/IRGenerator.h @@ -1,34 +1,36 @@ #ifndef UNLOGIC_IRGENERATOR_H #define UNLOGIC_IRGENERATOR_H +#include #include -#include "parser/Node.h" #include "IRGenerationContext.h" +#include "parser/Node.h" namespace unlogic { - struct IRGenerator : public INodeVisitor + struct IRGenerator { IRGenerationContext &ctx; llvm::IRBuilder<> builder; std::stack values; - void Visit(const NumericLiteralNode *node) override; - void Visit(const StringLiteralNode *node) override; - void Visit(const DivisionNode *node) override; - void Visit(const ScopedBlockNode *node) override; - void Visit(const VariableNode *node) override; - void Visit(const CallNode *node) override; - void Visit(const AdditionNode *node) override; - void Visit(const SubtractionNode *node) override; - void Visit(const MultiplicationNode *node) override; - void Visit(const PotentiationNode *node) override; - void Visit(const FunctionDefinitionNode *node) override; - void Visit(const PlotCommandNode *node) override; - void Visit(const ProgramEntryNode *node) override; + llvm::Value *operator()(std::monostate &node); + llvm::Value *operator()(unlogic::NumericLiteralNode &node); + llvm::Value *operator()(StringLiteralNode &node); + llvm::Value *operator()(DivisionNode &node); + llvm::Value *operator()(ScopedBlockNode &node); + llvm::Value *operator()(VariableNode &node); + llvm::Value *operator()(CallNode &node); + llvm::Value *operator()(AdditionNode &node); + llvm::Value *operator()(SubtractionNode &node); + llvm::Value *operator()(MultiplicationNode &node); + llvm::Value *operator()(PotentiationNode &node); + llvm::Value *operator()(FunctionDefinitionNode &node); + llvm::Value *operator()(PlotCommandNode &node); + llvm::Value *operator()(ProgramEntryNode &node); IRGenerator(IRGenerationContext &ctx) : ctx(ctx), builder(ctx.llvm_ctx) {} }; -} +} // namespace unlogic -#endif //UNLOGIC_IRGENERATOR_H +#endif // UNLOGIC_IRGENERATOR_H diff --git a/src/parser/Node.cpp b/src/parser/Node.cpp new file mode 100644 index 0000000..35ffc39 --- /dev/null +++ b/src/parser/Node.cpp @@ -0,0 +1,49 @@ +/** + * @file Declarations for ctors and dtors of all node types in order to allow them to have unique pointers to the "Node" alias type. + */ +#include "Node.h" + +using namespace unlogic; + +NumericLiteralNode::NumericLiteralNode(double value) : Literal(value) {} +NumericLiteralNode::~NumericLiteralNode() = default; + +StringLiteralNode::StringLiteralNode(std::string value) : Literal(std::move(value)) {} +StringLiteralNode::~StringLiteralNode() = default; + +VariableNode::VariableNode(std::string identifier) : identifier(std::move(identifier)) {} +VariableNode::~VariableNode() = default; + +CallNode::CallNode(std::string function_name, std::vector arguments) : function_name(std::move(function_name)), arguments(std::move(arguments)) {} +CallNode::~CallNode() = default; + +BinaryNode::BinaryNode(UniqueNode lhs, UniqueNode rhs) : lhs(std::move(lhs)), rhs(std::move(rhs)) {} +BinaryNode::~BinaryNode() = default; + +AdditionNode::AdditionNode(UniqueNode lhs, UniqueNode rhs) : BinaryNode(std::move(lhs), std::move(rhs)) {} +AdditionNode::~AdditionNode() = default; + +SubtractionNode::SubtractionNode(UniqueNode lhs, UniqueNode rhs) : BinaryNode(std::move(lhs), std::move(rhs)) {} +SubtractionNode::~SubtractionNode() = default; + +MultiplicationNode::MultiplicationNode(UniqueNode lhs, UniqueNode rhs) : BinaryNode(std::move(lhs), std::move(rhs)) {} +MultiplicationNode::~MultiplicationNode() = default; + +DivisionNode::DivisionNode(UniqueNode lhs, UniqueNode rhs) : BinaryNode(std::move(lhs), std::move(rhs)) {} +DivisionNode::~DivisionNode() = default; + +PotentiationNode::PotentiationNode(UniqueNode lhs, UniqueNode rhs) : BinaryNode(std::move(lhs), std::move(rhs)) {} +PotentiationNode::~PotentiationNode() = default; + +FunctionDefinitionNode::FunctionDefinitionNode(std::string name, std::vector arguments, UniqueNode body) : name(std::move(name)), args(std::move(arguments)), body(std::move(body)) {} +FunctionDefinitionNode::FunctionDefinitionNode(std::string name, UniqueNode body) : name(std::move(name)), body(std::move(body)) {} +FunctionDefinitionNode::~FunctionDefinitionNode() = default; + +PlotCommandNode::PlotCommandNode(std::string function_name) : function_name(std::move(function_name)) {} +PlotCommandNode::~PlotCommandNode() = default; + +ScopedBlockNode::ScopedBlockNode(std::vector statements) : statements(std::move(statements)) {} +ScopedBlockNode::~ScopedBlockNode() = default; + +ProgramEntryNode::ProgramEntryNode(UniqueNode body) : body(std::move(body)) {} +ProgramEntryNode::~ProgramEntryNode() = default; diff --git a/src/parser/Node.h b/src/parser/Node.h index ecb7ccf..e338d26 100644 --- a/src/parser/Node.h +++ b/src/parser/Node.h @@ -1,56 +1,33 @@ #ifndef UNLOGIC_NODE_H #define UNLOGIC_NODE_H -#include -#include -#include #include +#include #include +#include +#include #include -#include -#include -#include -#include -#include namespace unlogic { - struct NumericLiteralNode; - struct StringLiteralNode; - struct VariableNode; - struct CallNode; - struct AdditionNode; - struct SubtractionNode; - struct MultiplicationNode; - struct DivisionNode; - struct PotentiationNode; - struct FunctionDefinitionNode; - struct PlotCommandNode; - struct ScopedBlockNode; - struct ProgramEntryNode; - - struct INodeVisitor - { - virtual void Visit(NumericLiteralNode const *node) = 0; - virtual void Visit(StringLiteralNode const *node) = 0; - virtual void Visit(VariableNode const *node) = 0; - virtual void Visit(CallNode const *node) = 0; - virtual void Visit(AdditionNode const *node) = 0; - virtual void Visit(SubtractionNode const *node) = 0; - virtual void Visit(MultiplicationNode const *node) = 0; - virtual void Visit(DivisionNode const *node) = 0; - virtual void Visit(PotentiationNode const *node) = 0; - virtual void Visit(FunctionDefinitionNode const *node) = 0; - virtual void Visit(PlotCommandNode const *node) = 0; - virtual void Visit(ScopedBlockNode const *node) = 0; - virtual void Visit(ProgramEntryNode const *node) = 0; - }; - - struct Node - { - virtual void Accept(INodeVisitor &visitor) = 0; - virtual ~Node() = default; - }; + using Node = std::variant< + std::monostate, + struct NumericLiteralNode, + struct StringLiteralNode, + struct VariableNode, + struct CallNode, + struct AdditionNode, + struct SubtractionNode, + struct MultiplicationNode, + struct DivisionNode, + struct PotentiationNode, + struct FunctionDefinitionNode, + struct PlotCommandNode, + struct ScopedBlockNode, + struct ProgramEntryNode + >; + + using UniqueNode = std::unique_ptr; template struct Literal @@ -61,164 +38,115 @@ namespace unlogic virtual ~Literal() = default; }; - struct NumericLiteralNode : public Node, public Literal + struct NumericLiteralNode : Literal { - void Accept(INodeVisitor &visitor) override - { - visitor.Visit(this); - } - - NumericLiteralNode(double value) : Literal(value) {} + NumericLiteralNode(double value); + ~NumericLiteralNode(); }; - struct StringLiteralNode : public Node, public Literal + struct StringLiteralNode : Literal { - void Accept(INodeVisitor &visitor) override - { - visitor.Visit(this); - } - - StringLiteralNode(std::string value) : Literal(std::move(value)) {} + StringLiteralNode(std::string value); + ~StringLiteralNode(); }; - struct VariableNode : public Node + struct VariableNode { - std::string identifier_; - - void Accept(INodeVisitor &visitor) override - { - visitor.Visit(this); - } + std::string identifier; - VariableNode(std::string identifier) : identifier_(std::move(identifier)) {} + VariableNode(std::string identifier); + ~VariableNode(); }; - struct CallNode : public Node + struct CallNode { - std::string function_name_; - std::vector> arguments_; - - void Accept(INodeVisitor &visitor) override - { - visitor.Visit(this); - } + std::string function_name; + std::vector arguments; - CallNode(std::string function_name, std::vector> arguments) : function_name_(std::move(function_name)), arguments_(std::move(arguments)) {} + CallNode(std::string function_name, std::vector arguments); + ~CallNode(); }; - struct BinaryNode : public Node + struct BinaryNode { - std::unique_ptr lhs_, rhs_; + UniqueNode lhs, rhs; - BinaryNode(std::unique_ptr lhs, std::unique_ptr rhs) : lhs_(std::move(lhs)), rhs_(std::move(rhs)) {} + BinaryNode(UniqueNode lhs, UniqueNode rhs); + ~BinaryNode(); }; - struct AdditionNode : public BinaryNode + struct AdditionNode : BinaryNode { - void Accept(INodeVisitor &visitor) override - { - visitor.Visit(this); - } - - AdditionNode(std::unique_ptr lhs, std::unique_ptr rhs) : BinaryNode(std::move(lhs), std::move(rhs)) {} + AdditionNode(UniqueNode lhs, UniqueNode rhs); + ~AdditionNode(); }; - struct SubtractionNode : public BinaryNode + struct SubtractionNode : BinaryNode { - void Accept(INodeVisitor &visitor) override - { - visitor.Visit(this); - } - - SubtractionNode(std::unique_ptr lhs, std::unique_ptr rhs) : BinaryNode(std::move(lhs), std::move(rhs)) {} + SubtractionNode(UniqueNode lhs, UniqueNode rhs); + ~SubtractionNode(); }; - struct MultiplicationNode : public BinaryNode + struct MultiplicationNode : BinaryNode { - void Accept(INodeVisitor &visitor) override - { - visitor.Visit(this); - } - - MultiplicationNode(std::unique_ptr lhs, std::unique_ptr rhs) : BinaryNode(std::move(lhs), std::move(rhs)) {} + MultiplicationNode(UniqueNode lhs, UniqueNode rhs); + ~MultiplicationNode(); }; - struct DivisionNode : public BinaryNode + struct DivisionNode : BinaryNode { - void Accept(INodeVisitor &visitor) override - { - visitor.Visit(this); - } - - DivisionNode(std::unique_ptr lhs, std::unique_ptr rhs) : BinaryNode(std::move(lhs), std::move(rhs)) {} + DivisionNode(UniqueNode lhs, UniqueNode rhs); + ~DivisionNode(); }; - struct PotentiationNode : public BinaryNode + struct PotentiationNode : BinaryNode { - void Accept(INodeVisitor &visitor) override - { - visitor.Visit(this); - } - - PotentiationNode(std::unique_ptr lhs, std::unique_ptr rhs) : BinaryNode(std::move(lhs), std::move(rhs)) {} + PotentiationNode(UniqueNode lhs, UniqueNode rhs); + ~PotentiationNode(); }; - struct FunctionDefinitionNode : public Node + struct FunctionDefinitionNode { - std::string name_; - std::vector args_; - std::unique_ptr body_; - - void Accept(INodeVisitor &visitor) override - { - visitor.Visit(this); - } + std::string name; + std::vector args; + UniqueNode body; - FunctionDefinitionNode(std::string name, std::vector arguments, std::unique_ptr body) - : name_(std::move(name)), - args_(std::move(arguments)), - body_(std::move(body)) {} - - FunctionDefinitionNode(std::string name, std::unique_ptr body) - : name_(std::move(name)), - body_(std::move(body)) {} + FunctionDefinitionNode(std::string name, std::vector arguments, UniqueNode body); + FunctionDefinitionNode(std::string name, UniqueNode body); + ~FunctionDefinitionNode(); }; - struct PlotCommandNode : public Node + struct PlotCommandNode { std::string function_name; - void Accept(INodeVisitor &visitor) override - { - visitor.Visit(this); - } - - PlotCommandNode(std::string function_name) : function_name(std::move(function_name)) {} + PlotCommandNode(std::string function_name); + ~PlotCommandNode(); }; - struct ScopedBlockNode : public Node + struct ScopedBlockNode { - std::vector> statements_; - - void Accept(INodeVisitor &visitor) override - { - visitor.Visit(this); - } + std::vector statements; - ScopedBlockNode(std::vector> statements) : statements_(std::move(statements)) {}; + ScopedBlockNode(std::vector statements); + ~ScopedBlockNode(); }; - struct ProgramEntryNode : public Node + struct ProgramEntryNode { - std::unique_ptr body; + UniqueNode body; - void Accept(INodeVisitor &visitor) override - { - visitor.Visit(this); - } - - ProgramEntryNode(std::unique_ptr body) : body(std::move(body)) {} + ProgramEntryNode(UniqueNode body); + ~ProgramEntryNode(); }; -} -#endif //UNLOGIC_NODE_H + template + UniqueNode unique_node(Args &&... args) + { + auto temp = std::make_unique(); + temp->emplace(std::forward(args)...); + return std::move(temp); + } +} // namespace unlogic + +#endif // UNLOGIC_NODE_H diff --git a/src/parser/Parser.cpp b/src/parser/Parser.cpp index 8e5924d..6488148 100644 --- a/src/parser/Parser.cpp +++ b/src/parser/Parser.cpp @@ -1,5 +1,4 @@ #include "Parser.h" -#include "Node.h" using namespace unlogic; @@ -59,7 +58,7 @@ extern bf::DefineNonTerminal> expression; bf::DefineNonTerminal>> expression_list = bf::PR(expression)<=>[](auto &$) -> ValueType { - std::vector> list; + std::vector list; list.push_back(std::move(expression($[0]))); return std::move(list); @@ -76,18 +75,18 @@ bf::DefineNonTerminal>> expression_list bf::DefineNonTerminal> function_call = (IDENTIFIER + PAR_OPEN + expression_list + PAR_CLOSE)<=>[](auto &$) -> ValueType { - return std::make_unique(IDENTIFIER($[0]), std::move(expression_list($[2]))); + return unique_node(IDENTIFIER($[0]), expression_list($[2])); } ; bf::DefineNonTerminal> expression = bf::PR(NUMBER)<=>[](auto &$) -> ValueType { - return std::make_unique(NUMBER($[0])); + return unique_node(NUMBER($[0])); } | bf::PR(IDENTIFIER)<=>[](auto &$) -> ValueType { - return std::make_unique(IDENTIFIER($[0])); + return unique_node(IDENTIFIER($[0])); } | bf::PR(function_call)<=>[](auto &$) -> ValueType { @@ -103,41 +102,41 @@ bf::DefineNonTerminal> expression } | (expression + OP_EXP + expression)<=>[](auto &$) -> ValueType { - return std::make_unique(std::move(expression($[0])), std::move(expression($[2]))); + return unique_node(expression($[0]), expression($[2])); } | (expression + OP_MUL + expression)<=>[](auto &$) -> ValueType { - return std::make_unique(std::move(expression($[0])), std::move(expression($[2]))); + return unique_node(expression($[0]), expression($[2])); } | (expression + OP_DIV + expression)<=>[](auto &$) -> ValueType { - return std::make_unique(std::move(expression($[0])), std::move(expression($[2]))); + return unique_node(expression($[0]), expression($[2])); } | (expression + OP_ADD + expression)<=>[](auto &$) -> ValueType { - return std::make_unique(std::move(expression($[0])), std::move(expression($[2]))); + return unique_node(expression($[0]), expression($[2])); } | (expression + OP_SUB + expression)<=>[](auto &$) -> ValueType { - return std::make_unique(std::move(expression($[0])), std::move(expression($[2]))); + return unique_node(expression($[0]), expression($[2])); } ; bf::DefineNonTerminal> function_definition = (KW_GIVEN + IDENTIFIER + PAR_OPEN + identifier_list + PAR_CLOSE + OP_ASN + expression)<=>[](auto &$) -> ValueType { - return std::make_unique( - std::move(IDENTIFIER($[1])), - std::move(identifier_list($[3])), - std::move(expression($[6])) + return unique_node( + IDENTIFIER($[1]), + identifier_list($[3]), + expression($[6]) ); } | (KW_GIVEN + IDENTIFIER + PAR_OPEN + PAR_CLOSE + OP_ASN + expression)<=>[](auto &$) -> ValueType { - return std::make_unique( - std::move(IDENTIFIER($[1])), + return unique_node( + IDENTIFIER($[1]), std::vector{}, - std::move(expression($[5])) + expression($[5]) ); } ; @@ -149,7 +148,7 @@ bf::DefineNonTerminal variable_definition bf::DefineNonTerminal> plot_command = (KW_PLOT + IDENTIFIER)<=>[](auto &$) -> ValueType { - return std::make_unique(IDENTIFIER($[1])); + return unique_node(IDENTIFIER($[1])); } ; @@ -184,14 +183,14 @@ bf::DefineNonTerminal>> statement_list bf::DefineNonTerminal> scoped_block = bf::PR(statement_list)<=>[](auto &$) -> ValueType { - return std::make_unique(std::move(statement_list($[0]))); + return unique_node(statement_list($[0])); } ; bf::DefineNonTerminal> program = bf::PR(scoped_block)<=>[](auto &$) -> ValueType { - return std::make_unique(std::move(scoped_block($[0]))); + return unique_node(scoped_block($[0])); } ; diff --git a/src/parser/Parser.h b/src/parser/Parser.h index 1157ee7..68e6a03 100644 --- a/src/parser/Parser.h +++ b/src/parser/Parser.h @@ -3,11 +3,10 @@ #include #include +#include "Node.h" namespace unlogic { - class Node; - enum SyntaxHighlightingGroup { SyntaxOperator, @@ -17,7 +16,7 @@ namespace unlogic SyntaxGrouper, }; - using ParserValueType = std::variant, std::vector>, std::unique_ptr>; + using ParserValueType = std::variant, UniqueNode, std::vector>; using ParserGrammarType = bf::GrammarDefinition; extern bf::NonTerminal &unlogic_program;