From da740317a79bffe18c3bb2a20a3a1fbc627fd10e Mon Sep 17 00:00:00 2001 From: vla5924 Date: Sat, 11 May 2024 11:22:12 +0300 Subject: [PATCH 1/2] language header --- compiler/include/compiler/utils/language.hpp | 24 +++++++++++++++++++ .../lib/backend/ast/optimizer/optimizer.cpp | 6 ++++- .../lib/backend/ast/semantizer/semantizer.cpp | 11 +++++---- .../codegen/ast_to_llvmir/ir_generator.cpp | 14 ++++++----- compiler/lib/frontend/converter/converter.cpp | 13 +++++++--- 5 files changed, 54 insertions(+), 14 deletions(-) create mode 100644 compiler/include/compiler/utils/language.hpp diff --git a/compiler/include/compiler/utils/language.hpp b/compiler/include/compiler/utils/language.hpp new file mode 100644 index 00000000..f688e2ac --- /dev/null +++ b/compiler/include/compiler/utils/language.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include + +namespace utils { +namespace language { + +// ---------------------------------------------------------------------------- +// Reserved function names +// ---------------------------------------------------------------------------- + +inline const std::string funcMain = "main"; +inline const std::string funcPrint = "print"; +inline const std::string funcInput = "input"; +inline const std::string funcRange = "range"; + +// ---------------------------------------------------------------------------- +// Reserved decorator names +// ---------------------------------------------------------------------------- + +inline const std::string atInline = "inline"; + +} // namespace language +} // namespace utils diff --git a/compiler/lib/backend/ast/optimizer/optimizer.cpp b/compiler/lib/backend/ast/optimizer/optimizer.cpp index ce465d2f..ceb055cb 100644 --- a/compiler/lib/backend/ast/optimizer/optimizer.cpp +++ b/compiler/lib/backend/ast/optimizer/optimizer.cpp @@ -3,11 +3,15 @@ #include #include +#include "compiler/utils/language.hpp" + #include "optimizer/optimizer_context.hpp" using namespace ast; using namespace optimizer; +namespace language = utils::language; + namespace { bool isLiteral(const Node::Ptr &node) { @@ -591,7 +595,7 @@ void removeEmptyBranchRoots(Node::Ptr node) { void removeUnusedFunctions(SyntaxTree &tree) { tree.root->children.remove_if([&functions = tree.functions](Node::Ptr node) { const std::string &funcName = node->firstChild()->str(); - return functions[funcName].useCount == 0 && funcName != "main"; + return functions[funcName].useCount == 0 && funcName != language::funcMain; }); } diff --git a/compiler/lib/backend/ast/semantizer/semantizer.cpp b/compiler/lib/backend/ast/semantizer/semantizer.cpp index d9f07e29..7d089d12 100644 --- a/compiler/lib/backend/ast/semantizer/semantizer.cpp +++ b/compiler/lib/backend/ast/semantizer/semantizer.cpp @@ -1,10 +1,13 @@ #include "semantizer/semantizer.hpp" #include "compiler/ast/types.hpp" +#include "compiler/utils/language.hpp" using namespace semantizer; using namespace ast; +namespace language = utils::language; + static std::vector getFunctionArguments(const std::list &functionArguments, VariablesTable &table) { std::vector result; @@ -131,7 +134,7 @@ static TypeId processUnknownTypeExpression(Node::Ptr &node, NodeType type, Seman static TypeId processFunctionCall(Node::Ptr &node, SemantizerContext &ctx) { const std::string &funcName = node->firstChild()->str(); - bool isPrintFunction = (funcName == "print"); + bool isPrintFunction = (funcName == language::funcPrint); if (isPrintFunction) { auto exprNode = node->lastChild()->lastChild(); auto child = exprNode->firstChild(); @@ -141,7 +144,7 @@ static TypeId processFunctionCall(Node::Ptr &node, SemantizerContext &ctx) { } auto funcIter = ctx.functions.find(funcName); if (funcIter == ctx.functions.cend()) { - if (funcName == "input") { + if (funcName == language::funcInput) { funcIter = ctx.functions.emplace(funcName, Function(BuiltInTypes::NoneType)).first; TypeId type = ctx.findVariable(node->parent->firstChild()); Node::Ptr returnTypeNode = std::make_shared(NodeType::FunctionReturnType, node); @@ -205,7 +208,7 @@ static void processExpression(Node::Ptr &node, TypeId var_type, SemantizerContex if (child->type == NodeType::FunctionCall) { const std::string &funcName = child->firstChild()->str(); TypeId retType = processFunctionCall(child, ctx); - if (retType != var_type && funcName != "input") { + if (retType != var_type && funcName != language::funcInput) { pushTypeConversion(node, var_type); } continue; @@ -339,7 +342,7 @@ static void parseFunctions(const std::list &children, SemantizerConte } } - if (ctx.functions.find("main") == ctx.functions.end()) + if (ctx.functions.find(language::funcMain) == ctx.functions.end()) ctx.errors.push("Function 'main' is not declared, although it has to be"); } diff --git a/compiler/lib/codegen/ast_to_llvmir/ir_generator.cpp b/compiler/lib/codegen/ast_to_llvmir/ir_generator.cpp index 4a3342dd..63dba057 100644 --- a/compiler/lib/codegen/ast_to_llvmir/ir_generator.cpp +++ b/compiler/lib/codegen/ast_to_llvmir/ir_generator.cpp @@ -4,9 +4,13 @@ #include #include +#include "compiler/utils/language.hpp" + using namespace ast; using namespace ir_generator; +namespace language = utils::language; + namespace { bool lhsRequiresPtr(BinaryOperation op) { @@ -23,8 +27,6 @@ bool isLLVMPointer(llvm::Value *value) { return value->getType()->isPointerTy(); } -constexpr const char *const PRINT_FUNCTION_NAME = "print"; -constexpr const char *const INPUT_FUNCTION_NAME = "input"; constexpr const char *const PRINTF_FUNCTION_NAME = "printf"; constexpr const char *const SCANF_FUNCTION_NAME = "scanf"; @@ -91,8 +93,8 @@ static const std::unordered_map placeholders = { }; const std::unordered_map IRGenerator::builtInFunctions = { - {PRINT_FUNCTION_NAME, &IRGenerator::visitPrintFunctionCall}, - {INPUT_FUNCTION_NAME, &IRGenerator::visitInputFunctionCall}, + {language::funcPrint, &IRGenerator::visitPrintFunctionCall}, + {language::funcInput, &IRGenerator::visitInputFunctionCall}, }; IRGenerator::IRGenerator(const std::string &moduleName, bool emitDebugInfo) @@ -405,7 +407,7 @@ llvm::Value *IRGenerator::visitVariableName(Node *node) { } llvm::Value *IRGenerator::visitPrintFunctionCall(Node *node) { - assert(node && node->type == NodeType::FunctionCall && node->firstChild()->str() == PRINT_FUNCTION_NAME); + assert(node && node->type == NodeType::FunctionCall && node->firstChild()->str() == language::funcPrint); auto argsNode = node->lastChild(); assert(argsNode->children.size() == 1u); // print requires only one argument @@ -427,7 +429,7 @@ llvm::Value *IRGenerator::visitPrintFunctionCall(Node *node) { } llvm::Value *IRGenerator::visitInputFunctionCall(Node *node) { - assert(node && node->type == NodeType::FunctionCall && node->firstChild()->str() == INPUT_FUNCTION_NAME); + assert(node && node->type == NodeType::FunctionCall && node->firstChild()->str() == language::funcInput); TypeId returnType = node->lastChild()->typeId(); llvm::Type *llvmType = createLLVMType(returnType); diff --git a/compiler/lib/frontend/converter/converter.cpp b/compiler/lib/frontend/converter/converter.cpp index fc5f30e2..0d56af68 100644 --- a/compiler/lib/frontend/converter/converter.cpp +++ b/compiler/lib/frontend/converter/converter.cpp @@ -20,6 +20,7 @@ #include "compiler/optree/types.hpp" #include "compiler/optree/value.hpp" #include "compiler/utils/helpers.hpp" +#include "compiler/utils/language.hpp" #include "compiler/utils/source_ref.hpp" #include "converter/converter_context.hpp" @@ -31,6 +32,10 @@ using ast::Node; using ast::NodeType; using ast::SyntaxTree; +namespace language = utils::language; + +namespace { + Type::Ptr convertType(ast::TypeId typeId) { switch (typeId) { case ast::IntType: @@ -83,7 +88,7 @@ bool isRhsInAssignment(const Node::Ptr &node) { } bool isFunctionCallInputNode(const Node::Ptr &node) { - return node->type == NodeType::FunctionCall && node->firstChild()->str() == "input"; + return node->type == NodeType::FunctionCall && node->firstChild()->str() == language::funcInput; } bool isAssignment(ast::BinaryOperation binOp) { @@ -332,7 +337,7 @@ Value::Ptr visitVariableName(const Node::Ptr &node, ConverterContext &ctx) { Value::Ptr visitFunctionCall(const Node::Ptr &node, ConverterContext &ctx) { const std::string &name = node->firstChild()->str(); - if (name == "print") { + if (name == language::funcPrint) { if (node->parent->type != NodeType::Expression) { ctx.pushError(node, "print() statement cannot be within an expression context"); throw ctx.errors; @@ -343,7 +348,7 @@ Value::Ptr visitFunctionCall(const Node::Ptr &node, ConverterContext &ctx) { ctx.insert(node->ref, arguments); return {}; } - if (name == "input") { + if (name == language::funcInput) { ctx.pushError(node, "input() statement must be a right-handed operand of an isolated assignment expression"); throw ctx.errors; } @@ -412,6 +417,8 @@ Value::Ptr visitNode(const Node::Ptr &node, ConverterContext &ctx) { } } +} // namespace + Program Converter::process(const SyntaxTree &syntaxTree) { ConverterContext ctx; processNode(syntaxTree.root, ctx); From b2585fc7c68657163bbe0719a69f8d31d4650f14 Mon Sep 17 00:00:00 2001 From: Maksim Vlasov Date: Sat, 11 May 2024 14:25:21 +0300 Subject: [PATCH 2/2] Update compiler/include/compiler/utils/language.hpp Co-authored-by: Maksim Shagov <43129418+MaksimShagov@users.noreply.github.com> --- compiler/include/compiler/utils/language.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/include/compiler/utils/language.hpp b/compiler/include/compiler/utils/language.hpp index f688e2ac..829fc17f 100644 --- a/compiler/include/compiler/utils/language.hpp +++ b/compiler/include/compiler/utils/language.hpp @@ -13,6 +13,7 @@ inline const std::string funcMain = "main"; inline const std::string funcPrint = "print"; inline const std::string funcInput = "input"; inline const std::string funcRange = "range"; +inline const std::string funcEnumerate = "enumerate"; // ---------------------------------------------------------------------------- // Reserved decorator names