From 36ec04c00fa540fcee0f2cff1f7b81dd8a98101a Mon Sep 17 00:00:00 2001
From: Ferenc Szontágh <szf@fsociety.hu>
Date: Thu, 17 Apr 2025 18:44:58 +0000
Subject: [PATCH] some refactor

---
 src/Interpreter/ExpressionBuilder.hpp |  105 ++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 93 insertions(+), 12 deletions(-)

diff --git a/src/Interpreter/ExpressionBuilder.hpp b/src/Interpreter/ExpressionBuilder.hpp
index 32b2e9b..5ee96d7 100644
--- a/src/Interpreter/ExpressionBuilder.hpp
+++ b/src/Interpreter/ExpressionBuilder.hpp
@@ -8,13 +8,13 @@
 #include "Interpreter/ExpressionNode.hpp"
 #include "Interpreter/IdentifierExpressionNode.hpp"
 #include "Interpreter/LiteralExpressionNode.hpp"
-#include "Interpreter/UnaryExpressionNode.hpp" // <-- új include
+#include "Interpreter/UnaryExpressionNode.hpp"  // <-- új include
 #include "Parser/ParsedExpression.hpp"
 
 namespace Parser {
 static std::unique_ptr<Interpreter::ExpressionNode> buildExpressionFromParsed(
-    const Parser::ParsedExpressionPtr & expr) {
-    using Kind = Parser::ParsedExpression::Kind;
+    const ParsedExpressionPtr & expr) {
+    using Kind = ParsedExpression::Kind;
 
     switch (expr->kind) {
         case Kind::Literal:
@@ -23,20 +23,101 @@
         case Kind::Variable:
             return std::make_unique<Interpreter::IdentifierExpressionNode>(expr->name);
 
-        case Kind::Binary: {
-            auto lhs = buildExpressionFromParsed(expr->lhs);
-            auto rhs = buildExpressionFromParsed(expr->rhs);
-            return std::make_unique<Interpreter::BinaryExpressionNode>(std::move(lhs), expr->op, std::move(rhs));
-        }
+        case Kind::Binary:
+            {
+                auto lhs = buildExpressionFromParsed(expr->lhs);
+                auto rhs = buildExpressionFromParsed(expr->rhs);
+                return std::make_unique<Interpreter::BinaryExpressionNode>(std::move(lhs), expr->op, std::move(rhs));
+            }
 
-        case Kind::Unary: {
-            auto operand = buildExpressionFromParsed(expr->rhs);  // rhs az operandus
-            return std::make_unique<Interpreter::UnaryExpressionNode>(expr->op, std::move(operand));
-        }
+        case Kind::Unary:
+            {
+                auto operand = buildExpressionFromParsed(expr->rhs);  // rhs az operandus
+                return std::make_unique<Interpreter::UnaryExpressionNode>(expr->op, std::move(operand));
+            }
     }
 
     throw std::runtime_error("Unknown ParsedExpression kind");
 }
+
+void typecheckParsedExpression(const ParsedExpressionPtr & expr) {
+    using Kind = ParsedExpression::Kind;
+
+    switch (expr->kind) {
+        case Kind::Literal:
+            {
+                // Literál típusának ellenőrzése - a literál típusát a value.getType() adja vissza
+                // auto type = expr->value.getType();
+                // Nem szükséges semmilyen más típusellenőrzés a literálokhoz, mivel azok fix típusúak.
+                break;
+            }
+
+        case Kind::Variable:
+            {
+                const std::string ns     = Symbols::SymbolContainer::instance()->currentScopeName() + ".variables";
+                auto              symbol = Symbols::SymbolContainer::instance()->get(ns, expr->name);
+                if (!symbol) {
+                    throw std::runtime_error("Variable not found in symbol table: " + expr->name);
+                }
+
+                // Ha a szimbólum nem egy változó, akkor hibát dobunk
+                if (symbol->getKind() == Symbols::Kind::Function) {
+                    throw std::runtime_error("Cannot use function as variable: " + expr->name);
+                }
+                break;
+            }
+
+        case Kind::Binary:
+            {
+                // Bináris kifejezés operandusainak típusellenőrzése
+                typecheckParsedExpression(expr->lhs);
+                typecheckParsedExpression(expr->rhs);
+
+                auto lhsType = expr->lhs->getType();
+                auto rhsType = expr->rhs->getType();
+
+                if (lhsType != rhsType) {
+                    throw std::runtime_error(
+                        "Type mismatch in binary expression: " + Symbols::Variables::TypeToString(lhsType) + " and " +
+                        Symbols::Variables::TypeToString(rhsType));
+                }
+
+                // Bináris operátoroknál is elvégezhetjük a típusellenőrzést:
+                // Ha numerikus operátor, akkor az operandusoknak numerikusnak kell lenniük
+                if (expr->op == "+" || expr->op == "-" || expr->op == "*" || expr->op == "/") {
+                    if (lhsType != Symbols::Variables::Type::INTEGER && lhsType != Symbols::Variables::Type::FLOAT) {
+                        throw std::runtime_error("Operands must be numeric for operator: " + expr->op);
+                    }
+                }
+                // Ha logikai operátorok, akkor boolean típus szükséges
+                else if (expr->op == "&&" || expr->op == "||") {
+                    if (lhsType != Symbols::Variables::Type::BOOLEAN) {
+                        throw std::runtime_error("Operands must be boolean for operator: " + expr->op);
+                    }
+                }
+                break;
+            }
+
+        case Kind::Unary:
+            {
+                // Unáris kifejezés operandusának típusellenőrzése
+                typecheckParsedExpression(expr->rhs);  // 'rhs' tárolja az operandust az unáris kifejezésnél
+
+                auto operandType = expr->rhs->getType();
+
+                if (expr->op == "!") {
+                    if (operandType != Symbols::Variables::Type::BOOLEAN) {
+                        throw std::runtime_error("Operand must be boolean for unary operator '!'");
+                    }
+                }
+                break;
+            }
+
+        default:
+            throw std::runtime_error("Unknown expression kind");
+    }
+}
+
 }  // namespace Parser
 
 #endif  // PARSEREXPRESSION_BUILDER_HPP

--
Gitblit v1.9.3