From da740317a79bffe18c3bb2a20a3a1fbc627fd10e Mon Sep 17 00:00:00 2001
From: vla5924 <vla5924@gmail.com>
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 <string>
+
+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 <algorithm>
 #include <variant>
 
+#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<TypeId> getFunctionArguments(const std::list<Node::Ptr> &functionArguments, VariablesTable &table) {
     std::vector<TypeId> 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<Node>(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<Node::Ptr> &children, SemantizerConte
         }
     }
 
-    if (ctx.functions.find("main") == ctx.functions.end())
+    if (ctx.functions.find(language::funcMain) == ctx.functions.end())
         ctx.errors.push<SemantizerError>("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 <cassert>
 #include <iostream>
 
+#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<std::string, std::string> placeholders = {
 };
 
 const std::unordered_map<std::string, IRGenerator::NodeVisitor> 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<PrintOp>(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 <vla5924@gmail.com>
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