diff --git a/src/diagnostic/diagnostic.hpp b/src/diagnostic/diagnostic.hpp index 43e296b..c9e3e9a 100644 --- a/src/diagnostic/diagnostic.hpp +++ b/src/diagnostic/diagnostic.hpp @@ -37,6 +37,7 @@ #include #include #include "core/location.hpp" +#include "tools.hpp" // jsonEscape — TEK tanım (tools.hpp); çakışmayı önler // ============================================================================ // DiagLevel — Tanı seviyesi @@ -65,22 +66,7 @@ inline const char* diagLevelNameTr(DiagLevel l) { return "?"; } -// JSON string kaçışı (mesaj/ipucu tırnak veya satır sonu içerebilir) -inline std::string jsonEscape(const std::string& s) { - std::string out; - out.reserve(s.size() + 8); - for (char c : s) { - switch (c) { - case '"': out += "\\\""; break; - case '\\': out += "\\\\"; break; - case '\n': out += "\\n"; break; - case '\r': out += "\\r"; break; - case '\t': out += "\\t"; break; - default: out += c; break; - } - } - return out; -} +// NOT: jsonEscape() tools.hpp'de tanımlıdır (tek tanım — ODR çakışması olmaz). // ============================================================================ // Diagnostic — Tek bir tanı (hata/uyarı/not/ipucu) diff --git a/src/parser/ast_node.hpp b/src/parser/ast_node.hpp index 3739c70..d41053a 100644 --- a/src/parser/ast_node.hpp +++ b/src/parser/ast_node.hpp @@ -31,6 +31,7 @@ #include #include #include "core/location.hpp" +#include "core/type.hpp" #include "parser/token.hpp" #include "tools.hpp" @@ -247,6 +248,47 @@ protected: std::vector children; }; +// ============================================================================ +// ExpressionNode — Değer Üreten Düğümlerin Tabanı (Faz 1, ADR-012) +// ============================================================================ +// +// Bir DEĞER üreten her düğüm (Literal, Identifier, BinaryExpression, Call, +// Postfix, MemberAccess, IndexExpression) buradan türer. Bir ifadenin bir +// TİPİ vardır; analiz/optimizasyon alanları burada toplanır. +// +class ExpressionNode : public ASTNode { +public: + // TODO(faz-3): tip denetleyici doldurur. Şimdilik Error = "henüz çözülmedi". + Type resolvedType; + + // TODO(faz-4): sabit katlama (constant folding) bayrağı. + bool isConstant = false; + // TODO(faz-4): foldedValue — katlanmış sabit değer (temsil Faz 4'te netleşir). + + // resolvedType'ın JSON karşılığı (henüz çözülmemişse null gösterilir). + std::string resolvedTypeJson() const { + return resolvedType.isError() ? std::string("null") : resolvedType.toJson(); + } +}; + +// ============================================================================ +// StatementNode — Eylem/Kontrol Akışı Yürüten Düğümlerin Tabanı (Faz 1) +// ============================================================================ +// +// Değer üretmeyen, bir iş/kontrol akışı yürüten her düğüm (Block, If, For, +// While, DoWhile, Return, Break, Continue, ExpressionStatement ve şimdilik +// VariableDecl) buradan türer. Tipi yoktur; akış-analizi alanları taşır. +// +// TODO(faz-1 gözden geçirme): VariableDecl/FunctionDecl/StructDecl'in tam +// sınıflandırması provizyonel — VariableDecl burada (blok içinde erişilebilirliğe +// tabi), Function/StructDecl doğrudan ASTNode altında kaldı. +// +class StatementNode : public ASTNode { +public: + // TODO(faz-3/4): erişilebilirlik (dead-code) analizi günceller. + bool isReachable = true; +}; + // ============================================================================ // childrenToJson — Düğümün çocuklarını JSON array olarak yaz // ============================================================================ diff --git a/src/parser/nodes/binary_expr.cpp b/src/parser/nodes/binary_expr.cpp index d15731b..fc3daa9 100644 --- a/src/parser/nodes/binary_expr.cpp +++ b/src/parser/nodes/binary_expr.cpp @@ -18,6 +18,7 @@ std::string BinaryExpressionNode::toJson(int depth) { obj.add("operator", std::string(OPERATOR_MAP_REV.count(Operator) ? OPERATOR_MAP_REV.at(Operator) : "?")); if (Left) obj.addRaw("left", Left->toJson(depth + 1)); if (Right) obj.addRaw("right", Right->toJson(depth + 1)); + obj.addRaw("resolvedType", resolvedTypeJson()); obj.addRaw("location", loc.toJson()); return obj.str(); } diff --git a/src/parser/nodes/binary_expr.hpp b/src/parser/nodes/binary_expr.hpp index c760937..b67ee35 100644 --- a/src/parser/nodes/binary_expr.hpp +++ b/src/parser/nodes/binary_expr.hpp @@ -3,7 +3,7 @@ #include "parser/ast_node.hpp" -class BinaryExpressionNode : public ASTNode { +class BinaryExpressionNode : public ExpressionNode { public: TokenType Operator; ASTNode* Left = nullptr; diff --git a/src/parser/nodes/declarations.cpp b/src/parser/nodes/declarations.cpp index 4edc7d2..e4357fb 100644 --- a/src/parser/nodes/declarations.cpp +++ b/src/parser/nodes/declarations.cpp @@ -30,6 +30,7 @@ std::string VariableDeclNode::toJson(int depth) { obj.add("kind", "VariableDecl"); obj.add("name", name); obj.add("varType", varType); + obj.add("isReachable", isReachable); if (initExpr) obj.addRaw("init", initExpr->toJson(depth + 1)); obj.addRaw("location", loc.toJson()); return obj.str(); diff --git a/src/parser/nodes/declarations.hpp b/src/parser/nodes/declarations.hpp index 2638eda..20bf751 100644 --- a/src/parser/nodes/declarations.hpp +++ b/src/parser/nodes/declarations.hpp @@ -12,7 +12,7 @@ public: std::string toJson(int depth = 0) override; }; -class VariableDeclNode : public ASTNode { +class VariableDeclNode : public StatementNode { public: std::string varType; std::string name; diff --git a/src/parser/nodes/expressions.cpp b/src/parser/nodes/expressions.cpp index 5cab82a..9c68517 100644 --- a/src/parser/nodes/expressions.cpp +++ b/src/parser/nodes/expressions.cpp @@ -12,6 +12,7 @@ std::string PostfixNode::toJson(int depth) { obj.add("kind", "Postfix"); obj.add("operator", std::string(OPERATOR_MAP_REV.count(Operator) ? OPERATOR_MAP_REV.at(Operator) : "?")); if (operand) obj.addRaw("operand", operand->toJson(depth + 1)); + obj.addRaw("resolvedType", resolvedTypeJson()); obj.addRaw("location", loc.toJson()); return obj.str(); } @@ -30,6 +31,7 @@ std::string CallExpressionNode::toJson(int depth) { obj.addArray("arguments", [&]() { for (auto* arg : arguments) obj.addItem(arg->toJson(depth + 2)); }); + obj.addRaw("resolvedType", resolvedTypeJson()); obj.addRaw("location", loc.toJson()); return obj.str(); } @@ -46,6 +48,7 @@ std::string MemberAccessNode::toJson(int depth) { obj.add("member", member); obj.add("arrow", arrow); if (object) obj.addRaw("object", object->toJson(depth + 1)); + obj.addRaw("resolvedType", resolvedTypeJson()); obj.addRaw("location", loc.toJson()); return obj.str(); } @@ -62,6 +65,7 @@ std::string IndexExpressionNode::toJson(int depth) { obj.add("kind", "IndexExpression"); if (object) obj.addRaw("object", object->toJson(depth + 1)); if (index) obj.addRaw("index", index->toJson(depth + 1)); + obj.addRaw("resolvedType", resolvedTypeJson()); obj.addRaw("location", loc.toJson()); return obj.str(); } diff --git a/src/parser/nodes/expressions.hpp b/src/parser/nodes/expressions.hpp index 0efae4f..731a6a3 100644 --- a/src/parser/nodes/expressions.hpp +++ b/src/parser/nodes/expressions.hpp @@ -3,7 +3,7 @@ #include "parser/ast_node.hpp" -class PostfixNode : public ASTNode { +class PostfixNode : public ExpressionNode { public: ASTNode* operand = nullptr; TokenType Operator; @@ -12,7 +12,7 @@ public: std::string toJson(int depth = 0) override; }; -class CallExpressionNode : public ASTNode { +class CallExpressionNode : public ExpressionNode { public: ASTNode* callee = nullptr; std::vector arguments; @@ -21,7 +21,7 @@ public: std::string toJson(int depth = 0) override; }; -class MemberAccessNode : public ASTNode { +class MemberAccessNode : public ExpressionNode { public: ASTNode* object = nullptr; std::string member; @@ -31,7 +31,7 @@ public: std::string toJson(int depth = 0) override; }; -class IndexExpressionNode : public ASTNode { +class IndexExpressionNode : public ExpressionNode { public: ASTNode* object = nullptr; ASTNode* index = nullptr; diff --git a/src/parser/nodes/identifier.cpp b/src/parser/nodes/identifier.cpp index 55e3df4..f2286de 100644 --- a/src/parser/nodes/identifier.cpp +++ b/src/parser/nodes/identifier.cpp @@ -17,6 +17,7 @@ std::string IdentifierNode::toJson(int depth) { ss << "{\n" << in << " \"kind\": \"Identifier\",\n" << in << " \"name\": \"" << jsonEscape(name) << "\",\n" + << in << " \"resolvedType\": " << resolvedTypeJson() << ",\n" << in << " \"location\": " << loc.toJson() << "\n" << in << "}"; return ss.str(); diff --git a/src/parser/nodes/identifier.hpp b/src/parser/nodes/identifier.hpp index f993096..4d4b80d 100644 --- a/src/parser/nodes/identifier.hpp +++ b/src/parser/nodes/identifier.hpp @@ -3,11 +3,16 @@ #include "parser/ast_node.hpp" -class IdentifierNode : public ASTNode { +struct Symbol; // TODO(faz-2): sembol tablosu (Symbol) tanımlandığında bağlanacak + +class IdentifierNode : public ExpressionNode { public: Token* lexerToken = nullptr; ParserToken parserToken; + // TODO(faz-2): isim çözümlemede sembol tablosundaki tanıma bağlanır. + Symbol* resolvedSymbol = nullptr; + IdentifierNode(); void log(int indent = 0) override; std::string toJson(int depth = 0) override; diff --git a/src/parser/nodes/literal.cpp b/src/parser/nodes/literal.cpp index 94e32b8..1cd578f 100644 --- a/src/parser/nodes/literal.cpp +++ b/src/parser/nodes/literal.cpp @@ -28,6 +28,7 @@ std::string LiteralNode::toJson(int depth) { if (literalType == LiteralType::FLOAT) { ss << ",\n" << in << " \"isFloat\": true"; } + ss << ",\n" << in << " \"resolvedType\": " << resolvedTypeJson(); ss << ",\n" << in << " \"location\": " << loc.toJson() << "\n" << in << "}"; return ss.str(); diff --git a/src/parser/nodes/literal.hpp b/src/parser/nodes/literal.hpp index 850dc5a..dee1207 100644 --- a/src/parser/nodes/literal.hpp +++ b/src/parser/nodes/literal.hpp @@ -3,7 +3,7 @@ #include "parser/ast_node.hpp" -class LiteralNode : public ASTNode { +class LiteralNode : public ExpressionNode { public: Token* lexerToken = nullptr; ParserToken parserToken; diff --git a/src/parser/nodes/statements.cpp b/src/parser/nodes/statements.cpp index 99e2038..a395bbe 100644 --- a/src/parser/nodes/statements.cpp +++ b/src/parser/nodes/statements.cpp @@ -13,6 +13,7 @@ std::string BlockNode::toJson(int depth) { obj.addArray("children", [&]() { for (auto* child : children) obj.addItem(child->toJson(depth + 2)); }); + obj.add("isReachable", isReachable); obj.addRaw("location", loc.toJson()); return obj.str(); } @@ -31,6 +32,7 @@ std::string IfStatementNode::toJson(int depth) { if (condition) obj.addRaw("condition", condition->toJson(depth + 1)); if (thenBranch) obj.addRaw("then", thenBranch->toJson(depth + 1)); if (elseBranch) obj.addRaw("else", elseBranch->toJson(depth + 1)); + obj.add("isReachable", isReachable); obj.addRaw("location", loc.toJson()); return obj.str(); } @@ -47,6 +49,7 @@ std::string WhileStatementNode::toJson(int depth) { obj.add("kind", "WhileStatement"); if (condition) obj.addRaw("condition", condition->toJson(depth + 1)); if (body) obj.addRaw("body", body->toJson(depth + 1)); + obj.add("isReachable", isReachable); obj.addRaw("location", loc.toJson()); return obj.str(); } @@ -67,6 +70,7 @@ std::string ForStatementNode::toJson(int depth) { if (condition) obj.addRaw("condition", condition->toJson(depth + 1)); if (update) obj.addRaw("update", update->toJson(depth + 1)); if (body) obj.addRaw("body", body->toJson(depth + 1)); + obj.add("isReachable", isReachable); obj.addRaw("location", loc.toJson()); return obj.str(); } @@ -83,6 +87,7 @@ std::string DoWhileStatementNode::toJson(int depth) { obj.add("kind", "DoWhileStatement"); if (condition) obj.addRaw("condition", condition->toJson(depth + 1)); if (body) obj.addRaw("body", body->toJson(depth + 1)); + obj.add("isReachable", isReachable); obj.addRaw("location", loc.toJson()); return obj.str(); } @@ -97,6 +102,7 @@ std::string ReturnStatementNode::toJson(int depth) { JsonObject obj(depth); obj.add("kind", "ReturnStatement"); if (value) obj.addRaw("value", value->toJson(depth + 1)); + obj.add("isReachable", isReachable); obj.addRaw("location", loc.toJson()); return obj.str(); } @@ -109,6 +115,7 @@ void BreakStatementNode::log(int indent) { std::string BreakStatementNode::toJson(int depth) { JsonObject obj(depth); obj.add("kind", "BreakStatement"); + obj.add("isReachable", isReachable); obj.addRaw("location", loc.toJson()); return obj.str(); } @@ -121,6 +128,7 @@ void ContinueStatementNode::log(int indent) { std::string ContinueStatementNode::toJson(int depth) { JsonObject obj(depth); obj.add("kind", "ContinueStatement"); + obj.add("isReachable", isReachable); obj.addRaw("location", loc.toJson()); return obj.str(); } @@ -135,6 +143,7 @@ std::string ExpressionStatementNode::toJson(int depth) { JsonObject obj(depth); obj.add("kind", "ExpressionStatement"); if (expression) obj.addRaw("expression", expression->toJson(depth + 1)); + obj.add("isReachable", isReachable); obj.addRaw("location", loc.toJson()); return obj.str(); } diff --git a/src/parser/nodes/statements.hpp b/src/parser/nodes/statements.hpp index 9ec9662..5b68b49 100644 --- a/src/parser/nodes/statements.hpp +++ b/src/parser/nodes/statements.hpp @@ -3,14 +3,14 @@ #include "parser/ast_node.hpp" -class BlockNode : public ASTNode { +class BlockNode : public StatementNode { public: BlockNode(); void log(int indent = 0) override; std::string toJson(int depth = 0) override; }; -class IfStatementNode : public ASTNode { +class IfStatementNode : public StatementNode { public: ASTNode* condition = nullptr; ASTNode* thenBranch = nullptr; @@ -20,7 +20,7 @@ public: std::string toJson(int depth = 0) override; }; -class WhileStatementNode : public ASTNode { +class WhileStatementNode : public StatementNode { public: ASTNode* condition = nullptr; ASTNode* body = nullptr; @@ -29,7 +29,7 @@ public: std::string toJson(int depth = 0) override; }; -class ForStatementNode : public ASTNode { +class ForStatementNode : public StatementNode { public: ASTNode* init = nullptr; ASTNode* condition = nullptr; @@ -40,7 +40,7 @@ public: std::string toJson(int depth = 0) override; }; -class DoWhileStatementNode : public ASTNode { +class DoWhileStatementNode : public StatementNode { public: ASTNode* condition = nullptr; ASTNode* body = nullptr; @@ -49,7 +49,7 @@ public: std::string toJson(int depth = 0) override; }; -class ReturnStatementNode : public ASTNode { +class ReturnStatementNode : public StatementNode { public: ASTNode* value = nullptr; ReturnStatementNode(); @@ -57,21 +57,21 @@ public: std::string toJson(int depth = 0) override; }; -class BreakStatementNode : public ASTNode { +class BreakStatementNode : public StatementNode { public: BreakStatementNode(); void log(int indent = 0) override; std::string toJson(int depth = 0) override; }; -class ContinueStatementNode : public ASTNode { +class ContinueStatementNode : public StatementNode { public: ContinueStatementNode(); void log(int indent = 0) override; std::string toJson(int depth = 0) override; }; -class ExpressionStatementNode : public ASTNode { +class ExpressionStatementNode : public StatementNode { public: ASTNode* expression = nullptr; ExpressionStatementNode();