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